123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- using Jint.Native.Object;
- using Jint.Runtime;
- namespace Jint.Native.Function;
- /// <summary>
- /// https://tc39.es/ecma262/#sec-bound-function-exotic-objects
- /// </summary>
- public sealed class BindFunction : ObjectInstance, IConstructor, ICallable
- {
- private readonly Realm _realm;
- public BindFunction(Engine engine,
- Realm realm,
- ObjectInstance? proto,
- ObjectInstance targetFunction,
- JsValue boundThis,
- JsValue[] boundArgs)
- : base(engine, ObjectClass.Function)
- {
- _realm = realm;
- _prototype = proto;
- BoundTargetFunction = targetFunction;
- BoundThis = boundThis;
- BoundArguments = boundArgs;
- }
- /// <summary>
- /// The wrapped function object.
- /// </summary>
- public JsValue BoundTargetFunction { get; }
- /// <summary>
- /// The value that is always passed as the this value when calling the wrapped function.
- /// </summary>
- public JsValue BoundThis { get; }
- /// <summary>
- /// A list of values whose elements are used as the first arguments to any call to the wrapped function.
- /// </summary>
- public JsValue[] BoundArguments { get; }
- JsValue ICallable.Call(JsValue thisObject, params JsCallArguments arguments)
- {
- var f = BoundTargetFunction as Function;
- if (f is null)
- {
- Throw.TypeError(_realm);
- }
- var args = CreateArguments(arguments);
- var value = f.Call(BoundThis, args);
- _engine._jsValueArrayPool.ReturnArray(args);
- return value;
- }
- ObjectInstance IConstructor.Construct(JsCallArguments arguments, JsValue newTarget)
- {
- var target = BoundTargetFunction as IConstructor;
- if (target is null)
- {
- Throw.TypeError(_realm);
- }
- var args = CreateArguments(arguments);
- if (ReferenceEquals(this, newTarget))
- {
- newTarget = BoundTargetFunction;
- }
- var value = target.Construct(args, newTarget);
- _engine._jsValueArrayPool.ReturnArray(args);
- return value;
- }
- internal override bool OrdinaryHasInstance(JsValue v)
- {
- var f = BoundTargetFunction as Function;
- if (f is null)
- {
- Throw.TypeError(_realm);
- }
- return f.OrdinaryHasInstance(v);
- }
- private JsValue[] CreateArguments(JsCallArguments arguments)
- {
- var combined = _engine._jsValueArrayPool.RentArray(BoundArguments.Length + arguments.Length);
- System.Array.Copy(BoundArguments, combined, BoundArguments.Length);
- System.Array.Copy(arguments, 0, combined, BoundArguments.Length, arguments.Length);
- return combined;
- }
- internal override bool IsConstructor => BoundTargetFunction.IsConstructor;
- public override string ToString() => "function () { [native code] }";
- }
|