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; }
private JsValue Splice(JsValue thisObj, JsValue[] arguments) { var start = arguments.At(0); var deleteCount = arguments.At(1); var o = TypeConverter.ToObject(Engine, thisObj); var a = Engine.Array.Construct(Arguments.Empty); var lenVal = o.Get("length"); var len = TypeConverter.ToUint32(lenVal); var relativeStart = TypeConverter.ToInteger(start); uint actualStart; if (relativeStart < 0) { actualStart = (uint)System.Math.Max(len + relativeStart, 0); } else { actualStart = (uint)System.Math.Min(relativeStart, len); } var actualDeleteCount = System.Math.Min(System.Math.Max(TypeConverter.ToInteger(deleteCount), 0), len - actualStart); for (var k = 0; k < actualDeleteCount; k++) { var from = (actualStart + k).ToString(); var fromPresent = o.HasProperty(from); if (fromPresent) { var fromValue = o.Get(from); a.DefineOwnProperty(k.ToString(), new PropertyDescriptor(fromValue, true, true, true), false); } } var items = arguments.Skip(2).ToArray(); if (items.Length < actualDeleteCount) { for (var k = actualStart; k < len - actualDeleteCount; k++) { var from = (k + actualDeleteCount).ToString(); var to = (k + items.Length).ToString(); var fromPresent = o.HasProperty(from); if (fromPresent) { var fromValue = o.Get(from); o.Put(to, fromValue, true); } else { o.Delete(to, true); } } for (var k = len; k > len - actualDeleteCount + items.Length; k-- ) { o.Delete((k - 1).ToString(), true); } } else if (items.Length > actualDeleteCount) { for (var k = len - actualDeleteCount; k > actualStart; k--) { var from = (k + actualDeleteCount - 1).ToString(); var to = (k + items.Length - 1).ToString(); var fromPresent = o.HasProperty(from); if (fromPresent) { var fromValue = o.Get(from); o.Put(to, fromValue, true); } else { o.Delete(to, true); } } } for(var k = 0; k< items.Length; k++) { var e = items[k]; o.Put((k+actualStart).ToString(), e, true); } o.Put("length", len - actualDeleteCount + items.Length, true); return a; }
public JsValue CallImpl(JsValue thisObject, JsValue[] arguments) { var func = thisObject.TryCast<ICallable>(); if (func == null) { throw new JavaScriptException(Engine.TypeError); } return func.Call(arguments.At(0), arguments.Length == 0 ? arguments : arguments.Skip(1).ToArray()); }