2
0

FunctionConstructor.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  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. /// <summary>
  9. /// https://tc39.es/ecma262/#sec-function-constructor
  10. /// </summary>
  11. public sealed class FunctionConstructor : Constructor
  12. {
  13. private static readonly JsString _functionName = new JsString("Function");
  14. internal FunctionConstructor(
  15. Engine engine,
  16. Realm realm,
  17. ObjectPrototype objectPrototype)
  18. : base(engine, realm, _functionName)
  19. {
  20. PrototypeObject = new FunctionPrototype(engine, realm, objectPrototype);
  21. _prototype = PrototypeObject;
  22. _prototypeDescriptor = new PropertyDescriptor(PrototypeObject, PropertyFlag.AllForbidden);
  23. _length = new PropertyDescriptor(JsNumber.PositiveOne, PropertyFlag.Configurable);
  24. }
  25. internal FunctionPrototype PrototypeObject { get; }
  26. protected internal override JsValue Call(JsValue thisObject, JsCallArguments arguments)
  27. {
  28. return Construct(arguments, thisObject);
  29. }
  30. public override ObjectInstance Construct(JsCallArguments arguments, JsValue newTarget)
  31. {
  32. var function = CreateDynamicFunction(
  33. this,
  34. newTarget,
  35. FunctionKind.Normal,
  36. arguments);
  37. return function;
  38. }
  39. /// <summary>
  40. /// https://tc39.es/ecma262/#sec-runtime-semantics-instantiatefunctionobject
  41. /// </summary>
  42. internal Function InstantiateFunctionObject(
  43. JintFunctionDefinition functionDeclaration,
  44. Environment scope,
  45. PrivateEnvironment? privateEnv)
  46. {
  47. var function = functionDeclaration.Function;
  48. if (!function.Generator)
  49. {
  50. return function.Async
  51. ? InstantiateAsyncFunctionObject(functionDeclaration, scope, privateEnv)
  52. : InstantiateOrdinaryFunctionObject(functionDeclaration, scope, privateEnv);
  53. }
  54. else
  55. {
  56. return InstantiateGeneratorFunctionObject(functionDeclaration, scope, privateEnv);
  57. }
  58. }
  59. /// <summary>
  60. /// https://tc39.es/ecma262/#sec-runtime-semantics-instantiateasyncfunctionobject
  61. /// </summary>
  62. private ScriptFunction InstantiateAsyncFunctionObject(
  63. JintFunctionDefinition functionDeclaration,
  64. Environment env,
  65. PrivateEnvironment? privateEnv)
  66. {
  67. var F = OrdinaryFunctionCreate(
  68. _realm.Intrinsics.AsyncFunction.PrototypeObject,
  69. functionDeclaration,
  70. functionDeclaration.ThisMode,
  71. env,
  72. privateEnv);
  73. F.SetFunctionName(functionDeclaration.Name ?? "default");
  74. return F;
  75. }
  76. /// <summary>
  77. /// https://tc39.es/ecma262/#sec-runtime-semantics-instantiateordinaryfunctionobject
  78. /// </summary>
  79. private ScriptFunction InstantiateOrdinaryFunctionObject(
  80. JintFunctionDefinition functionDeclaration,
  81. Environment env,
  82. PrivateEnvironment? privateEnv)
  83. {
  84. var F = OrdinaryFunctionCreate(
  85. _realm.Intrinsics.Function.PrototypeObject,
  86. functionDeclaration,
  87. functionDeclaration.ThisMode,
  88. env,
  89. privateEnv);
  90. var name = functionDeclaration.Name ?? "default";
  91. F.SetFunctionName(name);
  92. F.MakeConstructor();
  93. return F;
  94. }
  95. /// <summary>
  96. /// https://tc39.es/ecma262/#sec-runtime-semantics-instantiategeneratorfunctionobject
  97. /// </summary>
  98. private ScriptFunction InstantiateGeneratorFunctionObject(
  99. JintFunctionDefinition functionDeclaration,
  100. Environment scope,
  101. PrivateEnvironment? privateScope)
  102. {
  103. var thisMode = functionDeclaration.Strict || _engine._isStrict
  104. ? FunctionThisMode.Strict
  105. : FunctionThisMode.Global;
  106. var name = functionDeclaration.Function.Id?.Name ?? "default";
  107. var F = OrdinaryFunctionCreate(
  108. _realm.Intrinsics.GeneratorFunction.PrototypeObject,
  109. functionDeclaration,
  110. thisMode,
  111. scope,
  112. privateScope);
  113. F.SetFunctionName(name);
  114. var prototype = OrdinaryObjectCreate(_engine, _realm.Intrinsics.GeneratorFunction.PrototypeObject.PrototypeObject);
  115. F.DefinePropertyOrThrow(CommonProperties.Prototype, new PropertyDescriptor(prototype, PropertyFlag.Writable));
  116. return F;
  117. }
  118. }