Пример #1
0
        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));
        }
Пример #2
0
        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));
        }
Пример #3
0
        /// <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);
        }