EvalFunctionInstance.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. using Esprima;
  2. using Esprima.Ast;
  3. using Jint.Runtime;
  4. using Jint.Runtime.Descriptors;
  5. using Jint.Runtime.Environments;
  6. using Jint.Runtime.Interpreter.Statements;
  7. namespace Jint.Native.Function
  8. {
  9. public sealed class EvalFunctionInstance : FunctionInstance
  10. {
  11. private static readonly ParserOptions ParserOptions = new ParserOptions { AdaptRegexp = true, Tolerant = false };
  12. private static readonly JsString _functionName = new JsString("eval");
  13. public EvalFunctionInstance(Engine engine)
  14. : base(engine, _functionName, StrictModeScope.IsStrictModeCode ? FunctionThisMode.Strict : FunctionThisMode.Global)
  15. {
  16. _prototype = Engine.Function.PrototypeObject;
  17. _length = PropertyDescriptor.AllForbiddenDescriptor.NumberOne;
  18. }
  19. public override JsValue Call(JsValue thisObject, JsValue[] arguments)
  20. {
  21. return PerformEval(arguments, false);
  22. }
  23. /// <summary>
  24. /// https://tc39.es/ecma262/#sec-performeval
  25. /// </summary>
  26. public JsValue PerformEval(JsValue[] arguments, bool direct)
  27. {
  28. if (!(arguments.At(0) is JsString x))
  29. {
  30. return arguments.At(0);
  31. }
  32. var inFunction = false;
  33. var inMethod = false;
  34. var inDerivedConstructor = false;
  35. if (direct)
  36. {
  37. var thisEnvRec = _engine.GetThisEnvironment();
  38. if (thisEnvRec is FunctionEnvironmentRecord functionEnvironmentRecord)
  39. {
  40. var F = functionEnvironmentRecord._functionObject;
  41. inFunction = true;
  42. inMethod = thisEnvRec.HasSuperBinding();
  43. if (F._constructorKind == ConstructorKind.Derived)
  44. {
  45. inDerivedConstructor = true;
  46. }
  47. }
  48. }
  49. var parser = new JavaScriptParser(x.ToString(), ParserOptions);
  50. Script script;
  51. try
  52. {
  53. script = parser.ParseScript(StrictModeScope.IsStrictModeCode);
  54. }
  55. catch (ParserException e)
  56. {
  57. return e.Description == Messages.InvalidLHSInAssignment
  58. ? ExceptionHelper.ThrowReferenceError<JsValue>(_engine)
  59. : ExceptionHelper.ThrowSyntaxError<JsValue>(_engine);
  60. }
  61. var body = script.Body;
  62. if (body.Count == 0)
  63. {
  64. return Undefined;
  65. }
  66. if (!inFunction)
  67. {
  68. // if body Contains NewTarget, throw a SyntaxError exception.
  69. }
  70. if (!inMethod)
  71. {
  72. // if body Contains SuperProperty, throw a SyntaxError exception.
  73. }
  74. if (!inDerivedConstructor)
  75. {
  76. // if body Contains SuperCall, throw a SyntaxError exception.
  77. }
  78. var strictEval = script.Strict || _engine._isStrict;
  79. var ctx = _engine.ExecutionContext;
  80. using (new StrictModeScope(strictEval))
  81. {
  82. LexicalEnvironment lexEnv;
  83. LexicalEnvironment varEnv;
  84. if (direct)
  85. {
  86. lexEnv = LexicalEnvironment.NewDeclarativeEnvironment(_engine, ctx.LexicalEnvironment);
  87. varEnv = ctx.VariableEnvironment;
  88. }
  89. else
  90. {
  91. lexEnv = LexicalEnvironment.NewDeclarativeEnvironment(_engine, Engine.GlobalEnvironment);
  92. varEnv = Engine.GlobalEnvironment;
  93. }
  94. if (strictEval)
  95. {
  96. varEnv = lexEnv;
  97. }
  98. // If ctx is not already suspended, suspend ctx.
  99. Engine.EnterExecutionContext(lexEnv, varEnv);
  100. try
  101. {
  102. Engine.EvalDeclarationInstantiation(script, varEnv, lexEnv, strictEval);
  103. var statement = new JintScript(_engine, script);
  104. var result = statement.Execute();
  105. var value = result.GetValueOrDefault();
  106. if (result.Type == CompletionType.Throw)
  107. {
  108. var ex = new JavaScriptException(value).SetCallstack(_engine, result.Location);
  109. throw ex;
  110. }
  111. else
  112. {
  113. return value;
  114. }
  115. }
  116. finally
  117. {
  118. Engine.LeaveExecutionContext();
  119. }
  120. }
  121. }
  122. }
  123. }