/// <summary> /// Optimized version for function calls. /// </summary> internal void AddFunctionParameters( FunctionInstance functionInstance, JsValue[] arguments, ArgumentsInstance argumentsInstance) { var parameters = functionInstance._formalParameters; bool empty = _dictionary == null && !_set; if (empty && parameters.Length == 1 && parameters[0].Length != BindingNameArguments.Length) { var jsValue = arguments.Length == 0 ? Undefined : arguments[0]; var binding = new Binding(jsValue, false, true); _set = true; _key = parameters[0]; _value = binding; } else { AddMultipleParameters(arguments, parameters); } if (ReferenceEquals(_argumentsBinding.Value, null)) { _argumentsBinding = new Binding(argumentsInstance, canBeDeleted: false, mutable: true); } }
public void Return(ArgumentsInstance instance) { if (ReferenceEquals(instance, null)) { return; } _pool.Free(instance);; }
// 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); } } } }