JintTryStatement.cs 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  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 Key _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. var catchEnvRecord = (DeclarativeEnvironmentRecord) catchEnv._record;
  39. catchEnvRecord.CreateMutableBindingAndInitialize(_catchParamName, canBeDeleted: false, c);
  40. _engine.UpdateLexicalEnvironment(catchEnv);
  41. b = _catch.Execute();
  42. _engine.UpdateLexicalEnvironment(oldEnv);
  43. }
  44. }
  45. if (_finalizer != null)
  46. {
  47. var f = _finalizer.Execute();
  48. if (f.Type == CompletionType.Normal)
  49. {
  50. return b;
  51. }
  52. return f;
  53. }
  54. return b;
  55. }
  56. }
  57. }