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 !; } }
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()); }
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"); } } }