예제 #1
0
        internal static Completion IteratorBindingInitializationSingleNameBinding(Identifier identifier, AbstractAssignmentExpression?initializer, LexicalEnvironment?env, ArgumentIterator arguments)
        {
            var lhsComp = Interpreter.Instance().ResolveBinding(identifier.name, identifier.IsStrictMode, env);

            if (lhsComp.IsAbrupt())
            {
                return(lhsComp);
            }
            var    lhs = (lhsComp.value as ReferenceValue) !;
            IValue v;

            if (!arguments.Done)
            {
                v = arguments.Next();
            }
            else
            {
                v = UndefinedValue.Instance;
            }
            if (initializer != null && v == UndefinedValue.Instance)
            {
                if (initializer is FunctionExpression f && f.isAnonymous)
                {
                    var comp = f.NamedEvaluate(Interpreter.Instance(), identifier.name);
                    if (comp.IsAbrupt())
                    {
                        return(comp);
                    }
                    v = comp.value !;
                }
                else
                {
                    var comp = initializer.Evaluate(Interpreter.Instance()).GetValue();
                    if (comp.IsAbrupt())
                    {
                        return(comp);
                    }
                    v = comp.value !;
                }
            }
예제 #2
0
        public Completion FunctionDeclarationInstantiation(IReadOnlyList <IValue> arguments)
        {
            var calleeContext           = Interpreter.Instance().RunningExecutionContext();
            var env                     = calleeContext.LexicalEnvironment;
            var envRec                  = env.EnvironmentRecord;
            var parameterNames          = FormalParameters.BoundNames();
            var hasDuplicates           = parameterNames.Distinct().Count() < parameterNames.Count;
            var simpleParameterList     = FormalParameters.IsSimpleParameterList();
            var hasParameterExpressions = FormalParameters.formalParameters.Any(p => p.hasInitializer);
            var varNames                = Code.VarDeclaredNames();
            var varDeclarations         = Code.VarScopedDeclarations();
            var functionNames           = new LinkedList <string>();
            var functionsToInitialize   = new LinkedList <FunctionDeclaration>();

            foreach (var d in varDeclarations.Reverse())
            {
                if (d is FunctionDeclaration functionDeclaration)
                {
                    var fn = functionDeclaration.BoundNames()[0];
                    if (!functionNames.Contains(fn))
                    {
                        functionNames.AddFirst(fn);
                        functionsToInitialize.AddFirst(functionDeclaration);
                    }
                }
            }
            var argumentsObjectNeeded = true;

            if (ThisMode == ThisMode.Lexical)
            {
                argumentsObjectNeeded = false;
            }
            else if (parameterNames.Contains("arguments"))
            {
                argumentsObjectNeeded = false;
            }
            else if (!hasParameterExpressions)
            {
                if (functionNames.Contains("arguments"))
                {
                    argumentsObjectNeeded = false;
                }
            }
            foreach (var paramName in parameterNames)
            {
                var alreadyDeclared = envRec.HasBinding(paramName).Other == true;
                if (!alreadyDeclared)
                {
                    envRec.CreateMutableBinding(paramName, false);
                    if (hasDuplicates)
                    {
                        envRec.InitializeBinding(paramName, UndefinedValue.Instance);
                    }
                }
            }
            IReadOnlyList <string> parameterBindings;

            if (argumentsObjectNeeded)
            {
                Object ao;
                if (Strict || !simpleParameterList)
                {
                    ao = CreateUnmappedArgumentsObject(arguments);
                }
                else
                {
                    ao = CreateMappedArgumentsObject(FormalParameters, arguments, envRec);
                }
                if (Strict)
                {
                    envRec.CreateImmutableBinding("arguments", false);
                }
                else
                {
                    envRec.CreateMutableBinding("arguments", false);
                }
                envRec.InitializeBinding("arguments", ao);
                parameterBindings = parameterNames.Concat(new[] { "arguments" }).ToList();
            }
            else
            {
                parameterBindings = parameterNames;
            }
            var        iterator = new ArgumentIterator(arguments);
            Completion comp;

            if (hasDuplicates)
            {
                comp = FormalParameters.IteratorBindingInitialization(null, iterator);
            }
            else
            {
                comp = FormalParameters.IteratorBindingInitialization(env, iterator);
            }
            if (comp.IsAbrupt())
            {
                return(comp);
            }

            LexicalEnvironment varEnv;
            EnvironmentRecord  varEnvRec;

            if (!hasParameterExpressions)
            {
                var instantiatedVarNames = new List <string>(parameterNames);
                foreach (var n in varNames)
                {
                    if (!instantiatedVarNames.Contains(n))
                    {
                        instantiatedVarNames.Add(n);
                        envRec.CreateMutableBinding(n, false);
                        envRec.InitializeBinding(n, UndefinedValue.Instance);
                    }
                }
                varEnv    = env;
                varEnvRec = envRec;
            }
            else
            {
                varEnv    = env.NewDeclarativeEnvironment();
                varEnvRec = varEnv.EnvironmentRecord;
                calleeContext.VariableEnvironment = varEnv;
                var instantiatedVarNames = new List <string>();
                foreach (var n in varNames)
                {
                    if (!instantiatedVarNames.Contains(n))
                    {
                        instantiatedVarNames.Add(n);
                        varEnvRec.CreateMutableBinding(n, false);
                        IValue initialValue;
                        if (!parameterBindings.Contains(n) || functionNames.Contains(n))
                        {
                            initialValue = UndefinedValue.Instance;
                        }
                        else
                        {
                            initialValue = envRec.GetBindingValue(n, false).value !;
                        }
                        varEnvRec.InitializeBinding(n, initialValue);
                    }
                }
            }
            var lexEnv = !Strict?varEnv.NewDeclarativeEnvironment() : varEnv;

            var lexEnvRec = lexEnv.EnvironmentRecord;

            calleeContext.LexicalEnvironment = lexEnv;
            var lexDeclarations = Code.LexicallyScopedDeclarations();

            foreach (var d in lexDeclarations)
            {
                foreach (var dn in d.BoundNames())
                {
                    if (d.IsConstantDeclaration())
                    {
                        lexEnvRec.CreateImmutableBinding(dn, true);
                    }
                    else
                    {
                        lexEnvRec.CreateMutableBinding(dn, false);
                    }
                }
            }
            foreach (var f in functionsToInitialize)
            {
                var            fn = f.BoundNames()[0];
                FunctionObject fo = f.InstantiateFunctionObject(lexEnv);
                varEnvRec.SetMutableBinding(fn, fo, false);
            }

            return(Completion.NormalCompletion());
        }
예제 #3
0
        internal static Completion IteratorBindingInitializationBindingRestIdentifier(Identifier restParameterIdentifier, LexicalEnvironment?env, ArgumentIterator arguments)
        {
            var lhsComp = Interpreter.Instance().ResolveBinding(restParameterIdentifier.name, restParameterIdentifier.IsStrictMode, env);

            if (lhsComp.IsAbrupt())
            {
                return(lhsComp);
            }
            var lhs = (lhsComp.value as ReferenceValue) !;
            var A   = ArrayObject.ArrayCreate(0);
            int n   = 0;

            for (; ; n++)
            {
                if (arguments.Done)
                {
                    if (env == null)
                    {
                        return(lhs.PutValue(A));
                    }
                    return(lhs.InitializeReferencedBinding(A));
                }
                var nextValue = arguments.Next();
                var status    = Utils.CreateDataProperty(A, n.ToString(System.Globalization.CultureInfo.InvariantCulture), nextValue);
                if (!status.Other)
                {
                    throw new InvalidOperationException("BindingRestElement IteratorBindingInitialization: assert step 4g");
                }
            }
        }