2
0

JintMemberExpression.cs 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  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 JintExpression _objectExpression;
  12. private JintIdentifierExpression _objectIdentifierExpression;
  13. private JintThisExpression _objectThisExpression;
  14. private JintExpression _propertyExpression;
  15. private JsValue _determinedProperty;
  16. public JintMemberExpression(Engine engine, MemberExpression expression) : base(engine, expression)
  17. {
  18. _initialized = false;
  19. }
  20. protected override void Initialize()
  21. {
  22. var expression = (MemberExpression) _expression;
  23. _objectExpression = Build(_engine, expression.Object);
  24. _objectIdentifierExpression = _objectExpression as JintIdentifierExpression;
  25. _objectThisExpression = _objectExpression as JintThisExpression;
  26. if (!expression.Computed)
  27. {
  28. _determinedProperty = ((Identifier) expression.Property).Name;
  29. }
  30. else if (expression.Property.Type == Nodes.Literal)
  31. {
  32. _determinedProperty = JintLiteralExpression.ConvertToJsValue((Literal) expression.Property);
  33. }
  34. if (_determinedProperty is null)
  35. {
  36. _propertyExpression = Build(_engine, expression.Property);
  37. }
  38. }
  39. protected override object EvaluateInternal()
  40. {
  41. string baseReferenceName = null;
  42. JsValue baseValue = null;
  43. var isStrictModeCode = StrictModeScope.IsStrictModeCode;
  44. if (_objectIdentifierExpression != null)
  45. {
  46. baseReferenceName = _objectIdentifierExpression._expressionName.Key.Name;
  47. var strict = isStrictModeCode;
  48. TryGetIdentifierEnvironmentWithBindingValue(
  49. strict,
  50. _objectIdentifierExpression._expressionName,
  51. out _,
  52. out baseValue);
  53. }
  54. else if (_objectThisExpression != null)
  55. {
  56. baseValue = _objectThisExpression.GetValue();
  57. }
  58. if (baseValue is null)
  59. {
  60. // fast checks failed
  61. var baseReference = _objectExpression.Evaluate();
  62. if (baseReference is Reference reference)
  63. {
  64. baseReferenceName = reference.GetReferencedName().ToString();
  65. baseValue = _engine.GetValue(reference, false);
  66. _engine._referencePool.Return(reference);
  67. }
  68. else
  69. {
  70. baseValue = _engine.GetValue(baseReference, false);
  71. }
  72. }
  73. var property = _determinedProperty ?? _propertyExpression.GetValue();
  74. TypeConverter.CheckObjectCoercible(_engine, baseValue, (MemberExpression) _expression, baseReferenceName);
  75. return _engine._referencePool.Rent(baseValue, TypeConverter.ToPropertyKey(property), isStrictModeCode);
  76. }
  77. }
  78. }