JintBlockStatement.cs 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. using Esprima.Ast;
  2. using Jint.Runtime.Environments;
  3. namespace Jint.Runtime.Interpreter.Statements
  4. {
  5. internal sealed class JintBlockStatement : JintStatement<BlockStatement>
  6. {
  7. private JintStatementList _statementList = null!;
  8. private List<Declaration>? _lexicalDeclarations;
  9. public JintBlockStatement(BlockStatement blockStatement) : base(blockStatement)
  10. {
  11. }
  12. protected override void Initialize(EvaluationContext context)
  13. {
  14. _statementList = new JintStatementList(_statement, _statement.Body);
  15. _lexicalDeclarations = HoistingScope.GetLexicalDeclarations(_statement);
  16. }
  17. /// <summary>
  18. /// Optimized for direct access without virtual dispatch.
  19. /// </summary>
  20. public Completion ExecuteBlock(EvaluationContext context)
  21. {
  22. if (_statementList is null)
  23. {
  24. _statementList = new JintStatementList(_statement, _statement.Body);
  25. _lexicalDeclarations = HoistingScope.GetLexicalDeclarations(_statement);
  26. }
  27. EnvironmentRecord? oldEnv = null;
  28. var engine = context.Engine;
  29. if (_lexicalDeclarations != null)
  30. {
  31. oldEnv = engine.ExecutionContext.LexicalEnvironment;
  32. var blockEnv = JintEnvironment.NewDeclarativeEnvironment(engine, engine.ExecutionContext.LexicalEnvironment);
  33. JintStatementList.BlockDeclarationInstantiation(engine, blockEnv, _lexicalDeclarations);
  34. engine.UpdateLexicalEnvironment(blockEnv);
  35. }
  36. var blockValue = _statementList.Execute(context);
  37. if (oldEnv is not null)
  38. {
  39. engine.UpdateLexicalEnvironment(oldEnv);
  40. }
  41. return blockValue;
  42. }
  43. protected override Completion ExecuteInternal(EvaluationContext context)
  44. {
  45. return ExecuteBlock(context);
  46. }
  47. }
  48. }