JintTryStatement.cs 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. using Esprima.Ast;
  2. using Jint.Runtime.Environments;
  3. namespace Jint.Runtime.Interpreter.Statements
  4. {
  5. /// <summary>
  6. /// http://www.ecma-international.org/ecma-262/5.1/#sec-12.14
  7. /// </summary>
  8. internal sealed class JintTryStatement : JintStatement<TryStatement>
  9. {
  10. private readonly JintStatement _block;
  11. private readonly JintStatement _catch;
  12. private readonly string _catchParamName;
  13. private readonly JintStatement _finalizer;
  14. public JintTryStatement(Engine engine, TryStatement statement) : base(engine, statement)
  15. {
  16. _block = Build(engine, statement.Block);
  17. if (_statement.Handler != null)
  18. {
  19. _catch = Build(engine, _statement.Handler.Body);
  20. _catchParamName = ((Identifier) _statement.Handler.Param).Name;
  21. }
  22. if (statement.Finalizer != null)
  23. {
  24. _finalizer = Build(engine, _statement.Finalizer);
  25. }
  26. }
  27. protected override Completion ExecuteInternal()
  28. {
  29. var b = _block.Execute();
  30. if (b.Type == CompletionType.Throw)
  31. {
  32. // execute catch
  33. if (_catch != null)
  34. {
  35. var c = b.Value;
  36. var oldEnv = _engine.ExecutionContext.LexicalEnvironment;
  37. var catchEnv = LexicalEnvironment.NewDeclarativeEnvironment(_engine, oldEnv);
  38. catchEnv._record.CreateMutableBinding(_catchParamName, c);
  39. _engine.UpdateLexicalEnvironment(catchEnv);
  40. b = _catch.Execute();
  41. _engine.UpdateLexicalEnvironment(oldEnv);
  42. }
  43. }
  44. if (_finalizer != null)
  45. {
  46. var f = _finalizer.Execute();
  47. if (f.Type == CompletionType.Normal)
  48. {
  49. return b;
  50. }
  51. return f;
  52. }
  53. return b;
  54. }
  55. }
  56. }