ExecutionContext.cs 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. using System.Runtime.InteropServices;
  2. using Jint.Native.Function;
  3. namespace Jint.Runtime.Environments;
  4. [StructLayout(LayoutKind.Auto)]
  5. internal readonly struct ExecutionContext
  6. {
  7. internal ExecutionContext(
  8. IScriptOrModule? scriptOrModule,
  9. EnvironmentRecord lexicalEnvironment,
  10. EnvironmentRecord variableEnvironment,
  11. PrivateEnvironmentRecord? privateEnvironment,
  12. Realm realm,
  13. FunctionInstance? function = null)
  14. {
  15. ScriptOrModule = scriptOrModule;
  16. LexicalEnvironment = lexicalEnvironment;
  17. VariableEnvironment = variableEnvironment;
  18. PrivateEnvironment = privateEnvironment;
  19. Realm = realm;
  20. Function = function;
  21. }
  22. public readonly IScriptOrModule? ScriptOrModule;
  23. public readonly EnvironmentRecord LexicalEnvironment;
  24. public readonly EnvironmentRecord VariableEnvironment;
  25. public readonly PrivateEnvironmentRecord? PrivateEnvironment;
  26. public readonly Realm Realm;
  27. public readonly FunctionInstance? Function;
  28. public ExecutionContext UpdateLexicalEnvironment(EnvironmentRecord lexicalEnvironment)
  29. {
  30. return new ExecutionContext(ScriptOrModule, lexicalEnvironment, VariableEnvironment, PrivateEnvironment, Realm, Function);
  31. }
  32. public ExecutionContext UpdateVariableEnvironment(EnvironmentRecord variableEnvironment)
  33. {
  34. return new ExecutionContext(ScriptOrModule, LexicalEnvironment, variableEnvironment, PrivateEnvironment, Realm, Function);
  35. }
  36. public ExecutionContext UpdatePrivateEnvironment(PrivateEnvironmentRecord? privateEnvironment)
  37. {
  38. return new ExecutionContext(ScriptOrModule, LexicalEnvironment, VariableEnvironment, privateEnvironment, Realm, Function);
  39. }
  40. /// <summary>
  41. /// https://tc39.es/ecma262/#sec-getthisenvironment
  42. /// </summary>
  43. internal EnvironmentRecord GetThisEnvironment()
  44. {
  45. // The loop will always terminate because the list of environments always
  46. // ends with the global environment which has a this binding.
  47. var lex = LexicalEnvironment;
  48. while (true)
  49. {
  50. if (lex is not null)
  51. {
  52. if (lex.HasThisBinding())
  53. {
  54. return lex;
  55. }
  56. lex = lex._outerEnv;
  57. }
  58. }
  59. }
  60. }