JintIdentifierExpression.cs 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. using Esprima.Ast;
  2. using Jint.Native;
  3. using Jint.Runtime.Environments;
  4. namespace Jint.Runtime.Interpreter.Expressions
  5. {
  6. internal sealed class JintIdentifierExpression : JintExpression
  7. {
  8. internal readonly EnvironmentRecord.BindingName _expressionName;
  9. private readonly JsValue _calculatedValue;
  10. public JintIdentifierExpression(Engine engine, Identifier expression) : base(engine, expression)
  11. {
  12. _expressionName = new EnvironmentRecord.BindingName(expression.Name);
  13. if (expression.Name == "undefined")
  14. {
  15. _calculatedValue = JsValue.Undefined;
  16. }
  17. }
  18. public bool HasEvalOrArguments
  19. => _expressionName.StringValue._value == KnownKeys.Eval || _expressionName.Key == KnownKeys.Arguments;
  20. protected override object EvaluateInternal()
  21. {
  22. var env = _engine.ExecutionContext.LexicalEnvironment;
  23. var strict = StrictModeScope.IsStrictModeCode;
  24. var identifierEnvironment = LexicalEnvironment.TryGetIdentifierEnvironmentWithBindingValue(env, _expressionName, strict, out var temp, out _)
  25. ? temp
  26. : JsValue.Undefined;
  27. return _engine._referencePool.Rent(identifierEnvironment, _expressionName.StringValue, strict);
  28. }
  29. public override JsValue GetValue()
  30. {
  31. // need to notify correct node when taking shortcut
  32. _engine._lastSyntaxNode = _expression;
  33. if (!(_calculatedValue is null))
  34. {
  35. return _calculatedValue;
  36. }
  37. var strict = StrictModeScope.IsStrictModeCode;
  38. return TryGetIdentifierEnvironmentWithBindingValue(strict, _expressionName, out _, out var value)
  39. ? value ?? ExceptionHelper.ThrowReferenceError<JsValue>(_engine, _expressionName.Key.Name + " has not been initialized")
  40. : _engine.GetValue(_engine._referencePool.Rent(JsValue.Undefined, _expressionName.StringValue, strict), true);
  41. }
  42. }
  43. }