FunctionConstructor.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. using Jint.Native.Object;
  2. using Jint.Runtime;
  3. using Jint.Runtime.Descriptors;
  4. using Jint.Runtime.Environments;
  5. using Jint.Runtime.Interpreter;
  6. using Environment = Jint.Runtime.Environments.Environment;
  7. namespace Jint.Native.Function
  8. {
  9. /// <summary>
  10. /// https://tc39.es/ecma262/#sec-function-constructor
  11. /// </summary>
  12. public sealed class FunctionConstructor : Constructor
  13. {
  14. private static readonly JsString _functionName = new JsString("Function");
  15. internal FunctionConstructor(
  16. Engine engine,
  17. Realm realm,
  18. ObjectPrototype objectPrototype)
  19. : base(engine, realm, _functionName)
  20. {
  21. PrototypeObject = new FunctionPrototype(engine, realm, objectPrototype);
  22. _prototype = PrototypeObject;
  23. _prototypeDescriptor = new PropertyDescriptor(PrototypeObject, PropertyFlag.AllForbidden);
  24. _length = new PropertyDescriptor(JsNumber.PositiveOne, PropertyFlag.Configurable);
  25. }
  26. internal FunctionPrototype PrototypeObject { get; }
  27. protected internal override JsValue Call(JsValue thisObject, JsValue[] arguments)
  28. {
  29. return Construct(arguments, thisObject);
  30. }
  31. public override ObjectInstance Construct(JsValue[] arguments, JsValue newTarget)
  32. {
  33. var function = CreateDynamicFunction(
  34. this,
  35. newTarget,
  36. FunctionKind.Normal,
  37. arguments);
  38. return function;
  39. }
  40. /// <summary>
  41. /// https://tc39.es/ecma262/#sec-runtime-semantics-instantiatefunctionobject
  42. /// </summary>
  43. internal FunctionInstance InstantiateFunctionObject(
  44. JintFunctionDefinition functionDeclaration,
  45. Environment scope,
  46. PrivateEnvironment? privateEnv)
  47. {
  48. var function = functionDeclaration.Function;
  49. if (!function.Generator)
  50. {
  51. return function.Async
  52. ? InstantiateAsyncFunctionObject(functionDeclaration, scope, privateEnv)
  53. : InstantiateOrdinaryFunctionObject(functionDeclaration, scope, privateEnv);
  54. }
  55. else
  56. {
  57. return InstantiateGeneratorFunctionObject(functionDeclaration, scope, privateEnv);
  58. }
  59. }
  60. /// <summary>
  61. /// https://tc39.es/ecma262/#sec-runtime-semantics-instantiateasyncfunctionobject
  62. /// </summary>
  63. private ScriptFunctionInstance InstantiateAsyncFunctionObject(
  64. JintFunctionDefinition functionDeclaration,
  65. Environment env,
  66. PrivateEnvironment? privateEnv)
  67. {
  68. var F = OrdinaryFunctionCreate(
  69. _realm.Intrinsics.AsyncFunction.PrototypeObject,
  70. functionDeclaration,
  71. functionDeclaration.ThisMode,
  72. env,
  73. privateEnv);
  74. F.SetFunctionName(functionDeclaration.Name ?? "default");
  75. return F;
  76. }
  77. /// <summary>
  78. /// https://tc39.es/ecma262/#sec-runtime-semantics-instantiateordinaryfunctionobject
  79. /// </summary>
  80. private ScriptFunctionInstance InstantiateOrdinaryFunctionObject(
  81. JintFunctionDefinition functionDeclaration,
  82. Environment env,
  83. PrivateEnvironment? privateEnv)
  84. {
  85. var F = OrdinaryFunctionCreate(
  86. _realm.Intrinsics.Function.PrototypeObject,
  87. functionDeclaration,
  88. functionDeclaration.ThisMode,
  89. env,
  90. privateEnv);
  91. var name = functionDeclaration.Name ?? "default";
  92. F.SetFunctionName(name);
  93. F.MakeConstructor();
  94. return F;
  95. }
  96. /// <summary>
  97. /// https://tc39.es/ecma262/#sec-runtime-semantics-instantiategeneratorfunctionobject
  98. /// </summary>
  99. private ScriptFunctionInstance InstantiateGeneratorFunctionObject(
  100. JintFunctionDefinition functionDeclaration,
  101. Environment scope,
  102. PrivateEnvironment? privateScope)
  103. {
  104. // TODO generators
  105. return InstantiateOrdinaryFunctionObject(functionDeclaration, scope, privateScope);
  106. }
  107. }
  108. }