JintMemberExpression.cs 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. using Esprima.Ast;
  2. using Jint.Native;
  3. using Jint.Runtime.References;
  4. namespace Jint.Runtime.Interpreter.Expressions
  5. {
  6. /// <summary>
  7. /// http://www.ecma-international.org/ecma-262/5.1/#sec-11.2.1
  8. /// </summary>
  9. internal sealed class JintMemberExpression : JintExpression
  10. {
  11. private readonly JintExpression _objectExpression;
  12. private readonly JintIdentifierExpression _objectIdentifierExpression;
  13. private readonly JintThisExpression _objectThisExpression;
  14. private readonly JintExpression _propertyExpression;
  15. private readonly Key _determinedPropertyName;
  16. public JintMemberExpression(Engine engine, MemberExpression expression) : base(engine, expression)
  17. {
  18. _objectExpression = Build(engine, expression.Object);
  19. _objectIdentifierExpression = _objectExpression as JintIdentifierExpression;
  20. _objectThisExpression = _objectExpression as JintThisExpression;
  21. if (!expression.Computed)
  22. {
  23. _determinedPropertyName = ((Esprima.Ast.Identifier) expression.Property).Name;
  24. }
  25. else
  26. {
  27. _determinedPropertyName = "";
  28. _propertyExpression = Build(engine, expression.Property);
  29. }
  30. }
  31. protected override object EvaluateInternal()
  32. {
  33. string baseReferenceName = null;
  34. JsValue baseValue = null;
  35. var isStrictModeCode = StrictModeScope.IsStrictModeCode;
  36. if (_objectIdentifierExpression != null)
  37. {
  38. baseReferenceName = _objectIdentifierExpression.ExpressionName;
  39. var strict = isStrictModeCode;
  40. TryGetIdentifierEnvironmentWithBindingValue(
  41. strict,
  42. _objectIdentifierExpression.ExpressionName,
  43. out _,
  44. out baseValue);
  45. }
  46. else if (_objectThisExpression != null)
  47. {
  48. baseValue = _objectThisExpression.GetValue();
  49. }
  50. if (baseValue is null)
  51. {
  52. // fast checks failed
  53. var baseReference = _objectExpression.Evaluate();
  54. if (baseReference is Reference reference)
  55. {
  56. baseReferenceName = reference.GetReferencedName();
  57. baseValue = _engine.GetValue(reference, false);
  58. _engine._referencePool.Return(reference);
  59. }
  60. else
  61. {
  62. baseValue = _engine.GetValue(baseReference, false);
  63. }
  64. }
  65. var propertyName = !string.IsNullOrEmpty(_determinedPropertyName.Name)
  66. ? _determinedPropertyName
  67. : (Key) TypeConverter.ToPropertyKey(_propertyExpression.GetValue());
  68. TypeConverter.CheckObjectCoercible(_engine, baseValue, (MemberExpression) _expression, baseReferenceName);
  69. return _engine._referencePool.Rent(baseValue, propertyName, isStrictModeCode);
  70. }
  71. }
  72. }