JintBlockStatement.cs 3.0 KB

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