EvalFunctionInstance.cs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  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. var callerRealm = (object) null;
  22. return PerformEval(arguments.At(0), callerRealm, StrictModeScope.IsStrictModeCode, false);
  23. }
  24. /// <summary>
  25. /// https://tc39.es/ecma262/#sec-performeval
  26. /// </summary>
  27. public JsValue PerformEval(JsValue x, object callerRealm, bool strictCaller, bool direct)
  28. {
  29. if (!x.IsString())
  30. {
  31. return x;
  32. }
  33. var inFunction = false;
  34. var inMethod = false;
  35. var inDerivedConstructor = false;
  36. if (direct)
  37. {
  38. var thisEnvRec = _engine.ExecutionContext.GetThisEnvironment();
  39. if (thisEnvRec is FunctionEnvironmentRecord functionEnvironmentRecord)
  40. {
  41. var F = functionEnvironmentRecord._functionObject;
  42. inFunction = true;
  43. inMethod = thisEnvRec.HasSuperBinding();
  44. if (F._constructorKind == ConstructorKind.Derived)
  45. {
  46. inDerivedConstructor = true;
  47. }
  48. }
  49. }
  50. var parser = new JavaScriptParser(x.ToString(), ParserOptions);
  51. Script script;
  52. try
  53. {
  54. script = parser.ParseScript(strictCaller);
  55. }
  56. catch (ParserException e)
  57. {
  58. return e.Description == Messages.InvalidLHSInAssignment
  59. ? ExceptionHelper.ThrowReferenceError<JsValue>(_engine)
  60. : ExceptionHelper.ThrowSyntaxError<JsValue>(_engine);
  61. }
  62. var body = script.Body;
  63. if (body.Count == 0)
  64. {
  65. return Undefined;
  66. }
  67. if (!inFunction)
  68. {
  69. // if body Contains NewTarget, throw a SyntaxError exception.
  70. }
  71. if (!inMethod)
  72. {
  73. // if body Contains SuperProperty, throw a SyntaxError exception.
  74. }
  75. if (!inDerivedConstructor)
  76. {
  77. // if body Contains SuperCall, throw a SyntaxError exception.
  78. }
  79. var strictEval = script.Strict || _engine._isStrict;
  80. var ctx = _engine.ExecutionContext;
  81. using (new StrictModeScope(strictEval))
  82. {
  83. EnvironmentRecord lexEnv;
  84. EnvironmentRecord varEnv;
  85. if (direct)
  86. {
  87. lexEnv = JintEnvironment.NewDeclarativeEnvironment(_engine, ctx.LexicalEnvironment);
  88. varEnv = ctx.VariableEnvironment;
  89. }
  90. else
  91. {
  92. lexEnv = JintEnvironment.NewDeclarativeEnvironment(_engine, Engine.GlobalEnvironment);
  93. varEnv = Engine.GlobalEnvironment;
  94. }
  95. if (strictEval)
  96. {
  97. varEnv = lexEnv;
  98. }
  99. // If ctx is not already suspended, suspend ctx.
  100. Engine.EnterExecutionContext(lexEnv, varEnv);
  101. try
  102. {
  103. Engine.EvalDeclarationInstantiation(script, varEnv, lexEnv, strictEval);
  104. var statement = new JintScript(_engine, script);
  105. var result = statement.Execute();
  106. var value = result.GetValueOrDefault();
  107. if (result.Type == CompletionType.Throw)
  108. {
  109. var ex = new JavaScriptException(value).SetCallstack(_engine, result.Location);
  110. throw ex;
  111. }
  112. else
  113. {
  114. return value;
  115. }
  116. }
  117. finally
  118. {
  119. Engine.LeaveExecutionContext();
  120. }
  121. }
  122. }
  123. }
  124. }