// 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); } } }
// 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); } } } }
// 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); }