123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- using Esprima.Ast;
- using Jint.Native;
- using Jint.Runtime.Environments;
- namespace Jint.Runtime.Interpreter.Statements
- {
- /// <summary>
- /// https://tc39.es/ecma262/#sec-try-statement
- /// </summary>
- internal sealed class JintTryStatement : JintStatement<TryStatement>
- {
- private JintBlockStatement _block = null!;
- private JintBlockStatement? _catch;
- private JintBlockStatement? _finalizer;
- public JintTryStatement(TryStatement statement) : base(statement)
- {
- }
- protected override void Initialize(EvaluationContext context)
- {
- _block = new JintBlockStatement(_statement.Block);
- if (_statement.Finalizer != null)
- {
- _finalizer = new JintBlockStatement(_statement.Finalizer);
- }
- }
- protected override Completion ExecuteInternal(EvaluationContext context)
- {
- var engine = context.Engine;
- var b = _block.Execute(context);
- if (b.Type == CompletionType.Throw)
- {
- b = ExecuteCatch(context, b, engine);
- }
- if (_finalizer != null)
- {
- var f = _finalizer.Execute(context);
- if (f.Type == CompletionType.Normal)
- {
- return b;
- }
- return f.UpdateEmpty(JsValue.Undefined);
- }
- return b.UpdateEmpty(JsValue.Undefined);
- }
- private Completion ExecuteCatch(EvaluationContext context, Completion b, Engine engine)
- {
- // execute catch
- if (_statement.Handler is not null)
- {
- // initialize lazily
- if (_catch is null)
- {
- _catch = new JintBlockStatement(_statement.Handler.Body);
- }
- // https://tc39.es/ecma262/#sec-runtime-semantics-catchclauseevaluation
- var thrownValue = b.Value;
- var oldEnv = engine.ExecutionContext.LexicalEnvironment;
- var catchEnv = JintEnvironment.NewDeclarativeEnvironment(engine, oldEnv, catchEnvironment: true);
- var boundNames = new List<Key>();
- _statement.Handler.Param.GetBoundNames(boundNames);
- for (var i = 0; i < boundNames.Count; i++)
- {
- catchEnv.CreateMutableBinding(boundNames[i]);
- }
- engine.UpdateLexicalEnvironment(catchEnv);
- var catchParam = _statement.Handler?.Param;
- catchParam.BindingInitialization(context, thrownValue, catchEnv);
- b = _catch.Execute(context);
- engine.UpdateLexicalEnvironment(oldEnv);
- }
- return b;
- }
- }
- }
|