2
0

JintEnvironment.cs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. #nullable enable
  2. using Jint.Native;
  3. using Jint.Native.Function;
  4. using Jint.Native.Object;
  5. namespace Jint.Runtime.Environments
  6. {
  7. internal static class JintEnvironment
  8. {
  9. internal static bool TryGetIdentifierEnvironmentWithBinding(
  10. EnvironmentRecord env,
  11. in EnvironmentRecord.BindingName name,
  12. out EnvironmentRecord? record)
  13. {
  14. record = env;
  15. var keyName = name.Key.Name;
  16. if (env._outerEnv is null)
  17. {
  18. return env.HasBinding(keyName);
  19. }
  20. while (!ReferenceEquals(record, null))
  21. {
  22. if (record.HasBinding(keyName))
  23. {
  24. return true;
  25. }
  26. record = record._outerEnv;
  27. }
  28. return false;
  29. }
  30. internal static bool TryGetIdentifierEnvironmentWithBindingValue(
  31. EnvironmentRecord env,
  32. in EnvironmentRecord.BindingName name,
  33. bool strict,
  34. out EnvironmentRecord? record,
  35. out JsValue? value)
  36. {
  37. record = env;
  38. value = default;
  39. if (env._outerEnv is null)
  40. {
  41. return env.TryGetBinding(name, strict, out _, out value);
  42. }
  43. while (!ReferenceEquals(record, null))
  44. {
  45. if (record.TryGetBinding(
  46. name,
  47. strict,
  48. out _,
  49. out value))
  50. {
  51. return true;
  52. }
  53. record = record._outerEnv;
  54. }
  55. return false;
  56. }
  57. /// <summary>
  58. /// https://tc39.es/ecma262/#sec-newdeclarativeenvironment
  59. /// </summary>
  60. internal static DeclarativeEnvironmentRecord NewDeclarativeEnvironment(Engine engine, EnvironmentRecord outer, bool catchEnvironment = false)
  61. {
  62. return new DeclarativeEnvironmentRecord(engine, catchEnvironment)
  63. {
  64. _outerEnv = outer
  65. };
  66. }
  67. /// <summary>
  68. /// https://tc39.es/ecma262/#sec-newfunctionenvironment
  69. /// </summary>
  70. internal static FunctionEnvironmentRecord NewFunctionEnvironment(Engine engine, FunctionInstance f, JsValue newTarget)
  71. {
  72. return new FunctionEnvironmentRecord(engine, f, newTarget)
  73. {
  74. _outerEnv = f._environment
  75. };
  76. }
  77. /// <summary>
  78. /// https://tc39.es/ecma262/#sec-newglobalenvironment
  79. /// </summary>
  80. internal static GlobalEnvironmentRecord NewGlobalEnvironment(Engine engine, ObjectInstance objectInstance, JsValue thisValue)
  81. {
  82. return new GlobalEnvironmentRecord(engine, objectInstance)
  83. {
  84. _outerEnv = null
  85. };
  86. }
  87. /// <summary>
  88. /// https://tc39.es/ecma262/#sec-newobjectenvironment
  89. /// </summary>
  90. internal static ObjectEnvironmentRecord NewObjectEnvironment(Engine engine, ObjectInstance objectInstance, EnvironmentRecord outer, bool provideThis, bool withEnvironment = false)
  91. {
  92. return new ObjectEnvironmentRecord(engine, objectInstance, provideThis, withEnvironment)
  93. {
  94. _outerEnv = outer
  95. };
  96. }
  97. /// <summary>
  98. /// https://tc39.es/ecma262/#sec-newprivateenvironment
  99. /// </summary>
  100. internal static PrivateEnvironmentRecord NewPrivateEnvironment(Engine engine, PrivateEnvironmentRecord? outerPriv)
  101. {
  102. return new PrivateEnvironmentRecord(outerPriv);
  103. }
  104. /// <summary>
  105. /// https://tc39.es/ecma262/#sec-newmoduleenvironment
  106. /// </summary>
  107. internal static ModuleEnvironmentRecord NewModuleEnvironment(Engine engine, EnvironmentRecord outer)
  108. {
  109. return new ModuleEnvironmentRecord(engine)
  110. {
  111. _outerEnv = outer
  112. };
  113. }
  114. }
  115. }