private JsValue Construct(JsValue thisObject, JsValue[] arguments) { var targetArgument = arguments.At(0); var target = AssertConstructor(_engine, targetArgument); var newTargetArgument = arguments.At(2, arguments[0]); AssertConstructor(_engine, newTargetArgument); var args = FunctionPrototype.CreateListFromArrayLike(_realm, arguments.At(1)); return(target.Construct(args, newTargetArgument)); }
private JsValue Apply(JsValue thisObject, JsValue[] arguments) { var target = arguments.At(0); var thisArgument = arguments.At(1); var argumentsList = arguments.At(2); if (!target.IsCallable) { ExceptionHelper.ThrowTypeError(_realm); } var args = FunctionPrototype.CreateListFromArrayLike(_realm, argumentsList); // 3. Perform PrepareForTailCall(). return(((ICallable)target).Call(thisArgument, args)); }
/// <summary> /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys /// </summary> public override List <JsValue> GetOwnPropertyKeys(Types types = Types.None | Types.String | Types.Symbol) { if (!TryCallHandler(TrapOwnKeys, new JsValue[] { _target }, out var result)) { return(_target.GetOwnPropertyKeys(types)); } var trapResult = new List <JsValue>(FunctionPrototype.CreateListFromArrayLike(_engine.Realm, result, Types.String | Types.Symbol)); if (trapResult.Count != new HashSet <JsValue>(trapResult).Count) { ExceptionHelper.ThrowTypeError(_engine.Realm); } var extensibleTarget = _target.Extensible; var targetKeys = _target.GetOwnPropertyKeys(); var targetConfigurableKeys = new List <JsValue>(); var targetNonconfigurableKeys = new List <JsValue>(); foreach (var property in targetKeys) { var desc = _target.GetOwnProperty(property); if (desc != PropertyDescriptor.Undefined && !desc.Configurable) { targetNonconfigurableKeys.Add(property); } else { targetConfigurableKeys.Add(property); } } var uncheckedResultKeys = new HashSet <JsValue>(trapResult); for (var i = 0; i < targetNonconfigurableKeys.Count; i++) { var key = targetNonconfigurableKeys[i]; if (!uncheckedResultKeys.Remove(key)) { ExceptionHelper.ThrowTypeError(_engine.Realm); } } if (extensibleTarget) { return(trapResult); } for (var i = 0; i < targetConfigurableKeys.Count; i++) { var key = targetConfigurableKeys[i]; if (!uncheckedResultKeys.Remove(key)) { ExceptionHelper.ThrowTypeError(_engine.Realm); } } if (uncheckedResultKeys.Count > 0) { ExceptionHelper.ThrowTypeError(_engine.Realm); } return(trapResult); }