BindFunctionInstance.cs 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. using Jint.Native.Object;
  2. using Jint.Runtime;
  3. namespace Jint.Native.Function
  4. {
  5. public sealed class BindFunctionInstance : FunctionInstance, IConstructor
  6. {
  7. public BindFunctionInstance(Engine engine)
  8. : base(engine, name: null, thisMode: FunctionThisMode.Strict)
  9. {
  10. }
  11. public JsValue TargetFunction { get; set; }
  12. public JsValue BoundThis { get; set; }
  13. public JsValue[] BoundArgs { get; set; }
  14. public override JsValue Call(JsValue thisObject, JsValue[] arguments)
  15. {
  16. if (!(TargetFunction is FunctionInstance f))
  17. {
  18. return ExceptionHelper.ThrowTypeError<ObjectInstance>(Engine);
  19. }
  20. var args = CreateArguments(arguments);
  21. var value = f.Call(BoundThis, args);
  22. _engine._jsValueArrayPool.ReturnArray(args);
  23. return value;
  24. }
  25. public ObjectInstance Construct(JsValue[] arguments, JsValue newTarget)
  26. {
  27. if (!(TargetFunction is IConstructor target))
  28. {
  29. return ExceptionHelper.ThrowTypeError<ObjectInstance>(Engine);
  30. }
  31. var args = CreateArguments(arguments);
  32. var value = target.Construct(args, newTarget);
  33. _engine._jsValueArrayPool.ReturnArray(args);
  34. return value;
  35. }
  36. public override bool HasInstance(JsValue v)
  37. {
  38. var f = TargetFunction.TryCast<FunctionInstance>(x =>
  39. {
  40. ExceptionHelper.ThrowTypeError(Engine);
  41. });
  42. return f.HasInstance(v);
  43. }
  44. private JsValue[] CreateArguments(JsValue[] arguments)
  45. {
  46. var combined = _engine._jsValueArrayPool.RentArray(BoundArgs.Length + arguments.Length);
  47. System.Array.Copy(BoundArgs, combined, BoundArgs.Length);
  48. System.Array.Copy(arguments, 0, combined, BoundArgs.Length, arguments.Length);
  49. return combined;
  50. }
  51. internal override bool IsConstructor => TargetFunction is IConstructor;
  52. public override string ToString() => "function () { [native code] }";
  53. }
  54. }