JintBlockStatement.cs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. using Esprima.Ast;
  2. using Jint.Runtime.Environments;
  3. using Environment = Jint.Runtime.Environments.Environment;
  4. namespace Jint.Runtime.Interpreter.Statements
  5. {
  6. internal sealed class JintBlockStatement : JintStatement<BlockStatement>
  7. {
  8. private JintStatementList? _statementList;
  9. private JintStatement? _singleStatement;
  10. private List<Declaration>? _lexicalDeclarations;
  11. public JintBlockStatement(BlockStatement blockStatement) : base(blockStatement)
  12. {
  13. }
  14. protected override void Initialize(EvaluationContext context)
  15. {
  16. _lexicalDeclarations = HoistingScope.GetLexicalDeclarations(_statement);
  17. if (_statement.Body.Count == 1)
  18. {
  19. _singleStatement = Build(_statement.Body[0]);
  20. }
  21. else
  22. {
  23. _statementList = new JintStatementList(_statement, _statement.Body);
  24. }
  25. }
  26. /// <summary>
  27. /// Optimized for direct access without virtual dispatch.
  28. /// </summary>
  29. public Completion ExecuteBlock(EvaluationContext context)
  30. {
  31. if (_statementList is null && _singleStatement is null)
  32. {
  33. Initialize(context);
  34. }
  35. Environment? oldEnv = null;
  36. var engine = context.Engine;
  37. if (_lexicalDeclarations != null)
  38. {
  39. oldEnv = engine.ExecutionContext.LexicalEnvironment;
  40. var blockEnv = JintEnvironment.NewDeclarativeEnvironment(engine, engine.ExecutionContext.LexicalEnvironment);
  41. JintStatementList.BlockDeclarationInstantiation(blockEnv, _lexicalDeclarations);
  42. engine.UpdateLexicalEnvironment(blockEnv);
  43. }
  44. Completion blockValue;
  45. if (_singleStatement is not null)
  46. {
  47. blockValue = ExecuteSingle(context);
  48. }
  49. else
  50. {
  51. blockValue = _statementList!.Execute(context);
  52. }
  53. if (oldEnv is not null)
  54. {
  55. engine.UpdateLexicalEnvironment(oldEnv);
  56. }
  57. return blockValue;
  58. }
  59. private Completion ExecuteSingle(EvaluationContext context)
  60. {
  61. Completion blockValue;
  62. try
  63. {
  64. blockValue = _singleStatement!.Execute(context);
  65. if (context.Engine._error is not null)
  66. {
  67. blockValue = JintStatementList.HandleError(context.Engine, _singleStatement);
  68. }
  69. }
  70. catch (Exception ex)
  71. {
  72. if (ex is JintException)
  73. {
  74. blockValue = JintStatementList.HandleException(context, ex, _singleStatement);
  75. }
  76. else
  77. {
  78. throw;
  79. }
  80. }
  81. return blockValue;
  82. }
  83. protected override Completion ExecuteInternal(EvaluationContext context)
  84. {
  85. return ExecuteBlock(context);
  86. }
  87. }
  88. }