예제 #1
0
파일: Engine.cs 프로젝트: skipme/jint
        //  http://www.ecma-international.org/ecma-262/5.1/#sec-10.5
        public void DeclarationBindingInstantiation(DeclarationBindingType declarationBindingType, IList<FunctionDeclaration> functionDeclarations, IList<VariableDeclaration> variableDeclarations, FunctionInstance functionInstance, JsValue[] arguments)
        {
            var env = ExecutionContext.VariableEnvironment.Record;
            bool configurableBindings = declarationBindingType == DeclarationBindingType.EvalCode;
            var strict = StrictModeScope.IsStrictModeCode;

            if (declarationBindingType == DeclarationBindingType.FunctionCode)
            {
                var argCount = arguments.Length;
                var n = 0;
                foreach (var argName in functionInstance.FormalParameters)
                {
                    n++;
                    var v = n > argCount ? Undefined.Instance : arguments[n - 1];
                    var argAlreadyDeclared = env.HasBinding(argName);
                    if (!argAlreadyDeclared)
                    {
                        env.CreateMutableBinding(argName);
                    }

                    env.SetMutableBinding(argName, v, strict);
                }
            }

            foreach (var f in functionDeclarations)
            {
                var fn = f.Id.Name;
                var fo = Function.CreateFunctionObject(f);
                var funcAlreadyDeclared = env.HasBinding(fn);
                if (!funcAlreadyDeclared)
                {
                    env.CreateMutableBinding(fn, configurableBindings);
                }
                else
                {
                    if (env == GlobalEnvironment.Record)
                    {
                        var go = Global;
                        var existingProp = go.GetProperty(fn);
                        if (existingProp.Configurable.Value.AsBoolean())
                        {
                            go.DefineOwnProperty(fn,
                                                 new PropertyDescriptor(
                                                     value: Undefined.Instance,
                                                     writable: true,
                                                     enumerable: true,
                                                     configurable: configurableBindings
                                                     ), true);
                        }
                        else
                        {
                            if (existingProp.IsAccessorDescriptor() || (!existingProp.Enumerable.Value.AsBoolean()))
                            {
                                throw new JavaScriptException(TypeError);
                            }
                        }
                    }
                }

                env.SetMutableBinding(fn, fo, strict);
            }

            var argumentsAlreadyDeclared = env.HasBinding("arguments");

            if (declarationBindingType == DeclarationBindingType.FunctionCode && !argumentsAlreadyDeclared)
            {
                var argsObj = ArgumentsInstance.CreateArgumentsObject(this, functionInstance, functionInstance.FormalParameters, arguments, env, strict);

                if (strict)
                {
                    var declEnv = env as DeclarativeEnvironmentRecord;

                    if (declEnv == null)
                    {
                        throw new ArgumentException();
                    }

                    declEnv.CreateImmutableBinding("arguments");
                    declEnv.InitializeImmutableBinding("arguments", argsObj);
                }
                else
                {
                    env.CreateMutableBinding("arguments");
                    env.SetMutableBinding("arguments", argsObj, false);
                }
            }

            // process all variable declarations in the current parser scope
            foreach (var d in variableDeclarations.SelectMany(x => x.Declarations))
            {
                var dn = d.Id.Name;
                var varAlreadyDeclared = env.HasBinding(dn);
                if (!varAlreadyDeclared)
                {
                    env.CreateMutableBinding(dn, configurableBindings);
                    env.SetMutableBinding(dn, Undefined.Instance, strict);
                }
            }
        }
예제 #2
0
        //  http://www.ecma-international.org/ecma-262/5.1/#sec-10.5
        public void DeclarationBindingInstantiation(DeclarationBindingType declarationBindingType, IList <FunctionDeclaration> functionDeclarations, IList <VariableDeclaration> variableDeclarations, FunctionInstance functionInstance, JsValue[] arguments)
        {
            var  env = ExecutionContext.VariableEnvironment.Record;
            bool configurableBindings = declarationBindingType == DeclarationBindingType.EvalCode;
            var  strict = StrictModeScope.IsStrictModeCode;

            if (declarationBindingType == DeclarationBindingType.FunctionCode)
            {
                var argCount = arguments.Length;
                var n        = 0;
                for (int i = 0, len = functionInstance.FormalParameters.Length; i < len; i++)
                {
                    var argName = functionInstance.FormalParameters[i];

                    n++;
                    var v = n > argCount ? Undefined.Instance : arguments[n - 1];
                    var argAlreadyDeclared = env.HasBinding(argName);
                    if (!argAlreadyDeclared)
                    {
                        env.CreateMutableBinding(argName);
                    }

                    env.SetMutableBinding(argName, v, strict);
                }
            }

            for (int i = 0, len = functionDeclarations.Count; i < len; i++)
            {
                var f  = functionDeclarations[i];
                var fn = f.Id.Name;
                var fo = Function.CreateFunctionObject(f);
                var funcAlreadyDeclared = env.HasBinding(fn);
                if (!funcAlreadyDeclared)
                {
                    env.CreateMutableBinding(fn, configurableBindings);
                }
                else
                {
                    if (env == GlobalEnvironment.Record)
                    {
                        var go           = Global;
                        var existingProp = go.GetProperty(fn);
                        if (existingProp.Configurable.Value)
                        {
                            go.DefineOwnProperty(fn,
                                                 new PropertyDescriptor(
                                                     value: Undefined.Instance,
                                                     writable: true,
                                                     enumerable: true,
                                                     configurable: configurableBindings
                                                     ), true);
                        }
                        else
                        {
                            if (existingProp.IsAccessorDescriptor() || (!existingProp.Enumerable.Value))
                            {
                                throw new JavaScriptException(TypeError);
                            }
                        }
                    }
                }

                env.SetMutableBinding(fn, fo, strict);
            }

            var argumentsAlreadyDeclared = env.HasBinding("arguments");

            if (declarationBindingType == DeclarationBindingType.FunctionCode && !argumentsAlreadyDeclared)
            {
                var argsObj = ArgumentsInstance.CreateArgumentsObject(this, functionInstance, functionInstance.FormalParameters, arguments, env, strict);

                if (strict)
                {
                    var declEnv = env as DeclarativeEnvironmentRecord;

                    if (declEnv == null)
                    {
                        throw new ArgumentException();
                    }

                    declEnv.CreateImmutableBinding("arguments");
                    declEnv.InitializeImmutableBinding("arguments", argsObj);
                }
                else
                {
                    env.CreateMutableBinding("arguments");
                    env.SetMutableBinding("arguments", argsObj, false);
                }
            }

            // process all variable declarations in the current parser scope
            for (int i = 0, ilen = variableDeclarations.Count; i < ilen; i++)
            {
                var varDeclations = variableDeclarations[i];
                for (int j = 0, jlen = varDeclations.Declarations.Count; j < jlen; j++)
                {
                    var d  = varDeclations.Declarations[j];
                    var dn = d.Id.Name;
                    var varAlreadyDeclared = env.HasBinding(dn);
                    if (!varAlreadyDeclared)
                    {
                        env.CreateMutableBinding(dn, configurableBindings);
                        env.SetMutableBinding(dn, Undefined.Instance, strict);
                    }
                }
            }
        }
예제 #3
0
파일: Engine.cs 프로젝트: rockyjvec/SpaceJS
        //  http://www.ecma-international.org/ecma-262/5.1/#sec-10.5
        internal bool DeclarationBindingInstantiation(
            DeclarationBindingType declarationBindingType,
            List <FunctionDeclaration> functionDeclarations,
            List <VariableDeclaration> variableDeclarations,
            FunctionInstance functionInstance,
            JsValue[] arguments)
        {
            var  env = ExecutionContext.VariableEnvironment._record;
            bool configurableBindings = declarationBindingType == DeclarationBindingType.EvalCode;
            var  strict = StrictModeScope.IsStrictModeCode;

            var  der = env as DeclarativeEnvironmentRecord;
            bool canReleaseArgumentsInstance = false;

            if (declarationBindingType == DeclarationBindingType.FunctionCode)
            {
                var argsObj = _argumentsInstancePool.Rent(functionInstance, functionInstance._formalParameters, arguments, env, strict);
                canReleaseArgumentsInstance = true;

                if (!ReferenceEquals(der, null))
                {
                    der.AddFunctionParameters(functionInstance, arguments, argsObj);
                }
                else
                {
                    // slow path
                    var parameters = functionInstance._formalParameters;
                    for (var i = 0; i < parameters.Length; i++)
                    {
                        var argName            = parameters[i];
                        var v                  = i + 1 > arguments.Length ? Undefined.Instance : arguments[i];
                        var argAlreadyDeclared = env.HasBinding(argName);
                        if (!argAlreadyDeclared)
                        {
                            env.CreateMutableBinding(argName, v);
                        }

                        env.SetMutableBinding(argName, v, strict);
                    }
                    env.CreateMutableBinding("arguments", argsObj);
                }
            }

            if (functionDeclarations.Count > 0)
            {
                AddFunctionDeclarations(functionDeclarations, env, configurableBindings, strict);
            }

            if (variableDeclarations.Count == 0)
            {
                return(canReleaseArgumentsInstance);
            }

            // process all variable declarations in the current parser scope
            if (!ReferenceEquals(der, null))
            {
                der.AddVariableDeclarations(variableDeclarations);
            }
            else
            {
                // slow path
                var variableDeclarationsCount = variableDeclarations.Count;
                for (var i = 0; i < variableDeclarationsCount; i++)
                {
                    var variableDeclaration = variableDeclarations[i];
                    var declarationsCount   = variableDeclaration.Declarations.Count;
                    for (var j = 0; j < declarationsCount; j++)
                    {
                        var d  = variableDeclaration.Declarations[j];
                        var dn = ((Identifier)d.Id).Name;
                        var varAlreadyDeclared = env.HasBinding(dn);
                        if (!varAlreadyDeclared)
                        {
                            env.CreateMutableBinding(dn, Undefined.Instance);
                        }
                    }
                }
            }

            return(canReleaseArgumentsInstance);
        }