예제 #1
0
        private JsValue Bind(JsValue thisObj, JsValue[] arguments)
        {
            var target = thisObj.TryCast <ICallable>(x =>
            {
                ExceptionHelper.ThrowTypeError(Engine);
            });

            var thisArg = arguments.At(0);
            var f       = new BindFunctionInstance(Engine)
            {
                TargetFunction = thisObj,
                BoundThis      = thisArg,
                BoundArgs      = arguments.Skip(1),
                _prototype     = Engine.Function.PrototypeObject
            };

            if (target is FunctionInstance functionInstance)
            {
                var l = TypeConverter.ToNumber(functionInstance.Get(CommonProperties.Length, functionInstance)) - (arguments.Length - 1);
                f.SetOwnProperty(CommonProperties.Length, new PropertyDescriptor(System.Math.Max(l, 0), PropertyFlag.AllForbidden));
            }
            else
            {
                f.SetOwnProperty(CommonProperties.Length, PropertyDescriptor.AllForbiddenDescriptor.NumberZero);
            }

            f.DefineOwnProperty(CommonProperties.Caller, _engine._getSetThrower);
            f.DefineOwnProperty(CommonProperties.Arguments, _engine._getSetThrower);

            return(f);
        }
예제 #2
0
        private JsValue Bind(JsValue thisObj, JsValue[] arguments)
        {
            var target = thisObj.TryCast<ICallable>(x =>
            {
                throw new JavaScriptException(Engine.TypeError);
            });
            
            var thisArg = arguments.At(0);
            var f = new BindFunctionInstance(Engine) {Extensible = true};
            f.TargetFunction = thisObj;
            f.BoundThis = thisArg;
            f.BoundArgs = arguments.Skip(1).ToArray();
            f.Prototype = Engine.Function.PrototypeObject;

            var o = target as FunctionInstance;
            if (o != null)
            {
                var l = TypeConverter.ToNumber(o.Get("length")) - (arguments.Length - 1);
                f.FastAddProperty("length", System.Math.Max(l, 0), false, false, false); 
            }
            else
            {
                f.FastAddProperty("length", 0, false, false, false); 
            }
            

            var thrower = Engine.Function.ThrowTypeError;
            f.DefineOwnProperty("caller", new PropertyDescriptor(thrower, thrower, false, false), false);
            f.DefineOwnProperty("arguments", new PropertyDescriptor(thrower, thrower, false, false), false);


            return f;
        }
예제 #3
0
        private JsValue Bind(JsValue thisObj, JsValue[] arguments)
        {
            if (!(thisObj is ICallable))
            {
                ExceptionHelper.ThrowTypeError(Engine, "Bind must be called on a function");
            }

            var thisArg = arguments.At(0);
            var f       = new BindFunctionInstance(Engine)
            {
                TargetFunction = thisObj,
                BoundThis      = thisObj is ArrowFunctionInstance ? Undefined : thisArg,
                BoundArgs      = arguments.Skip(1),
                _prototype     = Engine.Function.PrototypeObject,
            };

            JsNumber l;
            var      targetHasLength = thisObj.HasOwnProperty(CommonProperties.Length);

            if (targetHasLength)
            {
                var targetLen = thisObj.Get(CommonProperties.Length);
                if (!targetLen.IsNumber())
                {
                    l = JsNumber.PositiveZero;
                }
                else
                {
                    targetLen = TypeConverter.ToInteger(targetLen);
                    // first argument is target
                    var argumentsLength = System.Math.Max(0, arguments.Length - 1);
                    l = JsNumber.Create((uint)System.Math.Max(((JsNumber)targetLen)._value - argumentsLength, 0));
                }
            }
            else
            {
                l = JsNumber.PositiveZero;
            }

            f._length = new PropertyDescriptor(l, PropertyFlag.Configurable);

            var targetName = thisObj.Get(CommonProperties.Name);

            if (!targetName.IsString())
            {
                targetName = JsString.Empty;
            }

            f.SetFunctionName(targetName, "bound");

            return(f);
        }
예제 #4
0
        private JsValue Bind(JsValue thisObj, JsValue[] arguments)
        {
            var target = thisObj.TryCast <ICallable>(x =>
            {
                throw new JavaScriptException(Engine.TypeError);
            });

            var thisArg = arguments.At(0);
            var f       = new BindFunctionInstance(Engine)
            {
                Extensible = true
            };

            f.TargetFunction = thisObj;
            f.BoundThis      = thisArg;
            f.BoundArgs      = arguments.Skip(1).ToArray();
            f.Prototype      = Engine.Function.PrototypeObject;
            f.FastAddProperty("name", thisObj.AsObject().Get("name"), false, false, true);

            var o = target as FunctionInstance;

            if (o != null)
            {
                var l = TypeConverter.ToNumber(o.Get("length")) - (arguments.Length - 1);
                f.FastAddProperty("length", System.Math.Max(l, 0), false, false, false);
            }
            else
            {
                f.FastAddProperty("length", 0, false, false, false);
            }


            var thrower = Engine.Function.ThrowTypeError;

            f.DefineOwnProperty("caller", new PropertyDescriptor(thrower, thrower, false, false), false);
            f.DefineOwnProperty("arguments", new PropertyDescriptor(thrower, thrower, false, false), false);


            return(f);
        }
예제 #5
0
        private JsValue Bind(JsValue thisObj, JsValue[] arguments)
        {
            var target = thisObj.TryCast <ICallable>(x =>
            {
                ExceptionHelper.ThrowTypeError(Engine);
            });

            var thisArg = arguments.At(0);
            var f       = new BindFunctionInstance(Engine)
            {
                Extensible = true
            };

            f.TargetFunction = thisObj;
            f.BoundThis      = thisArg;
            f.BoundArgs      = arguments.Skip(1);
            f.Prototype      = Engine.Function.PrototypeObject;

            var o = target as FunctionInstance;

            if (!ReferenceEquals(o, null))
            {
                var l = TypeConverter.ToNumber(o.Get("length")) - (arguments.Length - 1);
                f.SetOwnProperty("length", new PropertyDescriptor(System.Math.Max(l, 0), PropertyFlag.AllForbidden));
            }
            else
            {
                f.SetOwnProperty("length", new PropertyDescriptor(0, PropertyFlag.AllForbidden));
            }


            var thrower = Engine.Function.ThrowTypeError;
            const PropertyFlag flags = PropertyFlag.EnumerableSet | PropertyFlag.ConfigurableSet;

            f.DefineOwnProperty("caller", new GetSetPropertyDescriptor(thrower, thrower, flags), false);
            f.DefineOwnProperty("arguments", new GetSetPropertyDescriptor(thrower, thrower, flags), false);

            return(f);
        }