Reference.cs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. using System;
  2. using System.Runtime.CompilerServices;
  3. using Jint.Native;
  4. using Jint.Runtime.Environments;
  5. namespace Jint.Runtime.References;
  6. /// <summary>
  7. /// https://tc39.es/ecma262/#sec-reference-record-specification-type
  8. /// </summary>
  9. public sealed class Reference
  10. {
  11. private JsValue _base;
  12. private JsValue _referencedName;
  13. internal bool _strict;
  14. private JsValue? _thisValue;
  15. internal Reference(JsValue baseValue, JsValue referencedName, bool strict, JsValue? thisValue = null)
  16. {
  17. _base = baseValue;
  18. _referencedName = referencedName;
  19. _thisValue = thisValue;
  20. }
  21. /// <summary>
  22. /// The value or Environment Record which holds the binding. A [[Base]] of unresolvable indicates that the binding could not be resolved.
  23. /// </summary>
  24. public JsValue Base
  25. {
  26. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  27. get => _base;
  28. }
  29. /// <summary>
  30. /// The value or Environment Record which holds the binding. A [[Base]] of unresolvable indicates that the binding could not be resolved.
  31. /// </summary>
  32. public JsValue ReferencedName
  33. {
  34. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  35. get => _referencedName;
  36. }
  37. /// <summary>
  38. /// true if the Reference Record originated in strict mode code, false otherwise.
  39. /// </summary>
  40. public bool Strict
  41. {
  42. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  43. get => _strict;
  44. }
  45. public bool HasPrimitiveBase
  46. {
  47. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  48. get => (_base._type & InternalTypes.Primitive) != InternalTypes.Empty;
  49. }
  50. public bool IsUnresolvableReference
  51. {
  52. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  53. get => _base._type == InternalTypes.Undefined;
  54. }
  55. public bool IsSuperReference => _thisValue is not null;
  56. // https://tc39.es/ecma262/#sec-ispropertyreference
  57. public bool IsPropertyReference
  58. {
  59. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  60. get => (_base._type & (InternalTypes.Primitive | InternalTypes.Object)) != InternalTypes.Empty;
  61. }
  62. public JsValue ThisValue
  63. {
  64. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  65. get => IsSuperReference ? _thisValue! : Base;
  66. }
  67. public bool IsPrivateReference
  68. {
  69. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  70. get => _referencedName._type == InternalTypes.PrivateName;
  71. }
  72. internal Reference Reassign(JsValue baseValue, JsValue name, bool strict, JsValue? thisValue)
  73. {
  74. _base = baseValue;
  75. _referencedName = name;
  76. _strict = strict;
  77. _thisValue = thisValue;
  78. return this;
  79. }
  80. internal void AssertValid(Realm realm)
  81. {
  82. if (_strict
  83. && (_base._type & InternalTypes.ObjectEnvironmentRecord) != InternalTypes.Empty
  84. && (CommonProperties.Eval.Equals(_referencedName) || CommonProperties.Arguments.Equals(_referencedName)))
  85. {
  86. ExceptionHelper.ThrowSyntaxError(realm);
  87. }
  88. }
  89. internal void InitializeReferencedBinding(JsValue value)
  90. {
  91. ((EnvironmentRecord) _base).InitializeBinding(TypeConverter.ToString(_referencedName), value);
  92. }
  93. }