Represents a scope where the variables are statically known.
상속: Scope
 /// <summary>
 /// Creates a new FunctionContext instance.
 /// </summary>
 /// <param name="engine"> The script engine. </param>
 /// <param name="scope"> The function scope. </param>
 /// <param name="functionName"> The name of the function. </param>
 /// <param name="argumentNames"> The names of the arguments. </param>
 /// <param name="body"> The source code for the body of the function. </param>
 /// <param name="options"> Options that influence the compiler. </param>
 public FunctionMethodGenerator(ScriptEngine engine, DeclarativeScope scope, string functionName, IList <string> argumentNames, string body, CompilerOptions options)
     : base(engine, scope, new StringScriptSource(body), options)
 {
     this.Name          = functionName;
     this.ArgumentNames = argumentNames;
     this.BodyText      = body;
 }
예제 #2
0
 /// <summary>
 /// Creates a new FunctionContext instance.
 /// </summary>
 /// <param name="engine"> The script engine. </param>
 /// <param name="scope"> The function scope. </param>
 /// <param name="functionName"> The name of the function. </param>
 /// <param name="argumentNames"> The names of the arguments. </param>
 /// <param name="body"> The source code for the body of the function. </param>
 /// <param name="options"> Options that influence the compiler. </param>
 public FunctionMethodGenerator(ScriptEngine engine, DeclarativeScope scope, string functionName, IList<string> argumentNames, string body, CompilerOptions options)
     : base(engine, scope, new StringScriptSource(body), options)
 {
     this.Name = functionName;
     this.ArgumentNames = argumentNames;
     this.BodyText = body;
 }
예제 #3
0
        /// <summary>
        /// Creates a new declarative scope for use inside a function body (and within function
        /// argument default values).
        /// </summary>
        /// <param name="parentScope"> A reference to the parent scope.  Can not be <c>null</c>. </param>
        /// <param name="functionName"> The name of the function.  Can be empty for an anonymous function. </param>
        /// <param name="argumentNames"> The names of each of the function arguments.  Can be <c>null</c>. </param>
        /// <returns> A new DeclarativeScope instance. </returns>
        internal static DeclarativeScope CreateFunctionScope(Scope parentScope, string functionName, IEnumerable <string> argumentNames)
        {
            if (parentScope == null)
            {
                throw new ArgumentNullException("parentScope", "Function scopes must have a parent scope.");
            }
            if (functionName == null)
            {
                throw new ArgumentNullException(nameof(functionName));
            }
            var result = new DeclarativeScope(parentScope, 0);

            if (string.IsNullOrEmpty(functionName) == false)
            {
                result.DeclareVariable(functionName);
            }
            result.DeclareVariable("this");
            result.DeclareVariable("arguments");
            if (argumentNames != null)
            {
                foreach (var argumentName in argumentNames)
                {
                    result.DeclareVariable(argumentName);
                }
            }
            return(result);
        }
 /// <summary>
 /// Creates a new FunctionContext instance.
 /// </summary>
 /// <param name="scope"> The function scope. </param>
 /// <param name="functionName"> The name of the function. </param>
 /// <param name="argumentsText"> A comma-separated list of arguments. </param>
 /// <param name="body"> The source code for the body of the function. </param>
 /// <param name="options"> Options that influence the compiler. </param>
 public FunctionMethodGenerator(DeclarativeScope scope, string functionName,
                                string argumentsText, string body, CompilerOptions options)
     : base(scope, new StringScriptSource(body), options)
 {
     this.Name          = functionName;
     this.ArgumentsText = argumentsText;
     this.BodyText      = body;
 }
예제 #5
0
 /// <summary>
 /// Creates a new FunctionMethodGenerator instance.
 /// </summary>
 /// <param name="engine"> The script engine. </param>
 /// <param name="scope"> The function scope. </param>
 /// <param name="name"> The name of the function. </param>
 /// <param name="argumentNames"> The names of the arguments. </param>
 /// <param name="bodyText"> The source code of the function. </param>
 /// <param name="body"> The root of the abstract syntax tree for the body of the function. </param>
 /// <param name="scriptPath"> The URL or file system path that the script was sourced from. </param>
 /// <param name="options"> Options that influence the compiler. </param>
 public FunctionMethodGenerator(ScriptEngine engine, DeclarativeScope scope, string functionName, IList<string> argumentNames, string bodyText, Statement body, string scriptPath, CompilerOptions options)
     : base(engine, scope, new DummyScriptSource(scriptPath), options)
 {
     this.Name = functionName;
     this.ArgumentNames = argumentNames;
     this.BodyRoot = body;
     this.BodyText = bodyText;
     Validate();
 }
예제 #6
0
 /// <summary>
 /// Creates a new FunctionMethodGenerator instance.
 /// </summary>
 /// <param name="engine"> The script engine. </param>
 /// <param name="scope"> The function scope. </param>
 /// <param name="name"> The name of the function. </param>
 /// <param name="argumentNames"> The names of the arguments. </param>
 /// <param name="bodyText"> The source code of the function. </param>
 /// <param name="body"> The root of the abstract syntax tree for the body of the function. </param>
 /// <param name="scriptPath"> The URL or file system path that the script was sourced from. </param>
 /// <param name="options"> Options that influence the compiler. </param>
 public FunctionMethodGenerator(ScriptEngine engine, DeclarativeScope scope, string functionName, IList <string> argumentNames, string bodyText, Statement body, string scriptPath, CompilerOptions options)
     : base(engine, scope, new DummyScriptSource(scriptPath), options)
 {
     this.Name          = functionName;
     this.ArgumentNames = argumentNames;
     this.BodyRoot      = body;
     this.BodyText      = bodyText;
     Validate();
 }
예제 #7
0
 /// <summary>
 /// Creates a new declarative scope for use inside a catch statement.
 /// </summary>
 /// <param name="parentScope"> A reference to the parent scope.  Can not be <c>null</c>. </param>
 /// <param name="catchVariableName"> The name of the catch variable. </param>
 /// <returns> A new DeclarativeScope instance. </returns>
 internal static DeclarativeScope CreateCatchScope(Scope parentScope, string catchVariableName)
 {
     if (parentScope == null)
         throw new ArgumentNullException("parentScope", "Catch scopes must have a parent scope.");
     if (catchVariableName == null)
         throw new ArgumentNullException("catchVariableName");
     var result = new DeclarativeScope(parentScope, 0);
     result.DeclareVariable(catchVariableName);
     result.CanDeclareVariables = false;    // Only the catch variable can be declared in this scope.
     return result;
 }
예제 #8
0
 /// <summary>
 /// Creates a new declarative scope for use at runtime.
 /// </summary>
 /// <param name="parentScope"> A reference to the parent scope.  Can not be <c>null</c>. </param>
 /// <param name="declaredVariableNames"> The names of variables that were declared in this scope. </param>
 /// <returns> A new DeclarativeScope instance. </returns>
 public static DeclarativeScope CreateRuntimeScope(Scope parentScope, string[] declaredVariableNames)
 {
     if (parentScope == null)
         throw new ArgumentNullException("parentScope", "Function scopes must have a parent scope.");
     if (declaredVariableNames == null)
         throw new ArgumentNullException("declaredVariableNames");
     var result = new DeclarativeScope(parentScope, declaredVariableNames.Length);
     foreach (string variableName in declaredVariableNames)
         result.DeclareVariable(variableName);
     result.values = new object[result.DeclaredVariableCount];
     return result;
 }
 /// <summary>
 /// Creates a new FunctionMethodGenerator instance.
 /// </summary>
 /// <param name="scope"> The function scope. </param>
 /// <param name="functionName"> The name of the function. </param>
 /// <param name="declarationType"> Indicates how the function was declared. </param>
 /// <param name="arguments"> The names and default values of the arguments. </param>
 /// <param name="bodyText"> The source code of the function. </param>
 /// <param name="body"> The root of the abstract syntax tree for the body of the function. </param>
 /// <param name="scriptPath"> The URL or file system path that the script was sourced from. </param>
 /// <param name="span"> The extent of the function in the source code. </param>
 /// <param name="options"> Options that influence the compiler. </param>
 public FunctionMethodGenerator(DeclarativeScope scope, string functionName, FunctionDeclarationType declarationType,
                                IList <FunctionArgument> arguments, string bodyText, Statement body, string scriptPath, SourceCodeSpan span,
                                CompilerOptions options)
     : base(scope, new DummyScriptSource(scriptPath), options)
 {
     this.Name            = functionName;
     this.DeclarationType = declarationType;
     this.Arguments       = arguments;
     this.BodyRoot        = body;
     this.BodyText        = bodyText;
     Validate(span.StartLine, scriptPath);
 }
예제 #10
0
        /// <summary>
        /// Creates a new declarative scope for use inside a catch statement.
        /// </summary>
        /// <param name="parentScope"> A reference to the parent scope.  Can not be <c>null</c>. </param>
        /// <param name="catchVariableName"> The name of the catch variable. </param>
        /// <returns> A new DeclarativeScope instance. </returns>
        internal static DeclarativeScope CreateCatchScope(Scope parentScope, string catchVariableName)
        {
            if (parentScope == null)
            {
                throw new ArgumentNullException("parentScope", "Catch scopes must have a parent scope.");
            }
            if (catchVariableName == null)
            {
                throw new ArgumentNullException(nameof(catchVariableName));
            }
            var result = new DeclarativeScope(parentScope, 0);

            result.DeclareVariable(catchVariableName);
            result.CanDeclareVariables = false;    // Only the catch variable can be declared in this scope.
            return(result);
        }
예제 #11
0
 /// <summary>
 /// Creates a new declarative scope for use inside a function body.
 /// </summary>
 /// <param name="parentScope"> A reference to the parent scope.  Can not be <c>null</c>. </param>
 /// <param name="functionName"> The name of the function.  Can be empty for an anonymous function. </param>
 /// <param name="argumentNames"> The names of each of the function arguments. </param>
 /// <returns> A new DeclarativeScope instance. </returns>
 internal static DeclarativeScope CreateFunctionScope(Scope parentScope, string functionName, IEnumerable<string> argumentNames)
 {
     if (parentScope == null)
         throw new ArgumentNullException("parentScope", "Function scopes must have a parent scope.");
     if (functionName == null)
         throw new ArgumentNullException("functionName");
     if (argumentNames == null)
         throw new ArgumentNullException("argumentNames");
     var result = new DeclarativeScope(parentScope, 0);
     if (string.IsNullOrEmpty(functionName) == false)
         result.DeclareVariable(functionName);
     result.DeclareVariable("this");
     result.DeclareVariable("arguments");
     foreach (var argumentName in argumentNames)
         result.DeclareVariable(argumentName);
     return result;
 }
예제 #12
0
        /// <summary>
        /// Creates a new declarative scope for use at runtime.
        /// </summary>
        /// <param name="parentScope"> A reference to the parent scope.  Can not be <c>null</c>. </param>
        /// <param name="declaredVariableNames"> The names of variables that were declared in this scope. </param>
        /// <returns> A new DeclarativeScope instance. </returns>
        public static DeclarativeScope CreateRuntimeScope(Scope parentScope, string[] declaredVariableNames)
        {
            if (parentScope == null)
            {
                throw new ArgumentNullException("parentScope", "Function scopes must have a parent scope.");
            }
            if (declaredVariableNames == null)
            {
                throw new ArgumentNullException(nameof(declaredVariableNames));
            }
            var result = new DeclarativeScope(parentScope, declaredVariableNames.Length);

            foreach (string variableName in declaredVariableNames)
            {
                result.DeclareVariable(variableName);
            }
            result.values = new object[result.DeclaredVariableCount];
            return(result);
        }
예제 #13
0
        /// <summary>
        /// Parses the source text into an abstract syntax tree.
        /// </summary>
        public override void Parse()
        {
            var lexer  = new Lexer(this.Engine, this.Source);
            var parser = new Parser(this.Engine, lexer, this.InitialScope, this.Options, CodeContext.Eval);

            // If the eval() is running strict mode, create a new scope.
            parser.DirectivePrologueProcessedCallback = parser2 =>
            {
                if (parser2.StrictMode == true)
                {
                    parser2.InitialScope = parser2.Scope = DeclarativeScope.CreateEvalScope(parser2.Scope);
                }
            };

            this.AbstractSyntaxTree = parser.Parse();

            this.StrictMode              = parser.StrictMode;
            this.InitialScope            = parser.Scope;
            this.MethodOptimizationHints = parser.MethodOptimizationHints;
        }
예제 #14
0
        //     INITIALIZATION
        //_________________________________________________________________________________________

        /// <summary>
        /// Creates a new Arguments instance.
        /// </summary>
        /// <param name="prototype"> The next object in the prototype chain. </param>
        /// <param name="callee"> The function that was called. </param>
        /// <param name="scope"> The function scope. </param>
        /// <param name="argumentValues"> The argument values that were passed to the function. </param>
        public ArgumentsInstance(ObjectInstance prototype, UserDefinedFunction callee, DeclarativeScope scope, object[] argumentValues)
            : base(prototype)
        {
            if (callee == null)
                throw new ArgumentNullException("callee");
            if (scope == null)
                throw new ArgumentNullException("scope");
            if (argumentValues == null)
                throw new ArgumentNullException("argumentValues");
            this.callee = callee;
            this.scope = scope;
            this.FastSetProperty("length", argumentValues.Length, PropertyAttributes.NonEnumerable);

            if (this.callee.StrictMode == false)
            {
                this.FastSetProperty("callee", callee, PropertyAttributes.NonEnumerable);


                // Create an array mappedArguments where mappedArguments[i] = true means a mapping is
                // maintained between arguments[i] and the corresponding variable.
                this.mappedArguments = new bool[argumentValues.Length];
                var mappedNames = new Dictionary<string, int>();    // maps argument name -> index
                for (int i = 0; i < argumentValues.Length; i++)
                {
                    if (i < callee.ArgumentNames.Count)
                    {
                        // Check if the argument name appeared previously in the argument list.
                        int previousIndex;
                        if (mappedNames.TryGetValue(callee.ArgumentNames[i], out previousIndex) == true)
                        {
                            // The argument name has appeared before.  Remove the getter/setter.
                            this.DefineProperty(previousIndex.ToString(), new PropertyDescriptor(argumentValues[previousIndex], PropertyAttributes.FullAccess), false);

                            // The argument is no longer mapped.
                            this.mappedArguments[previousIndex] = false;
                        }

                        // Add the argument name and index to the hashtable.
                        mappedNames[callee.ArgumentNames[i]] = i;

                        // The argument is mapped by default.
                        this.mappedArguments[i] = true;

                        // Define a getter and setter so that the property value reflects that of the argument.
                        var getter = new UserDefinedFunction(this.Engine.Function.InstancePrototype, "ArgumentGetter", new string[0], this.scope, "return " + callee.ArgumentNames[i], ArgumentGetter, true);
                        getter.SetPropertyValue("argumentIndex", i, false);
                        var setter = new UserDefinedFunction(this.Engine.Function.InstancePrototype, "ArgumentSetter", new string[] { "value" }, this.scope, callee.ArgumentNames[i] + " = value", ArgumentSetter, true);
                        setter.SetPropertyValue("argumentIndex", i, false);
                        this.DefineProperty(i.ToString(), new PropertyDescriptor(getter, setter, PropertyAttributes.FullAccess), false);
                    }
                    else
                    {
                        // This argument is unnamed - no mapping needs to happen.
                        this[(uint)i] = argumentValues[i];
                    }
                }
            }
            else
            {
                // In strict mode, arguments items are not connected to the variables.
                for (int i = 0; i < argumentValues.Length; i++)
                    this[(uint)i] = argumentValues[i];

                // In strict mode, accessing caller or callee is illegal.
                var throwErrorFunction = new ThrowTypeErrorFunction(this.Engine.Function.InstancePrototype);
                this.DefineProperty("caller", new PropertyDescriptor(throwErrorFunction, throwErrorFunction, PropertyAttributes.Sealed), false);
                this.DefineProperty("callee", new PropertyDescriptor(throwErrorFunction, throwErrorFunction, PropertyAttributes.Sealed), false);
            }
        }