123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- using System.Runtime.CompilerServices;
- using Jint.Native;
- using Jint.Runtime.Interpreter.Expressions;
- namespace Jint.Runtime.Interpreter.Statements
- {
- internal abstract class JintStatement<T> : JintStatement where T : Statement
- {
- internal new readonly T _statement;
- protected JintStatement(T statement) : base(statement)
- {
- _statement = statement;
- }
- }
- internal abstract class JintStatement
- {
- internal readonly Statement _statement;
- private bool _initialized;
- protected JintStatement(Statement statement)
- {
- _statement = statement;
- }
- [MethodImpl(MethodImplOptions.AggressiveInlining | (MethodImplOptions) 512)]
- public Completion Execute(EvaluationContext context)
- {
- if (_statement.Type != NodeType.BlockStatement)
- {
- context.PrepareFor(_statement);
- context.RunBeforeExecuteStatementChecks(_statement);
- }
- if (!_initialized)
- {
- Initialize(context);
- _initialized = true;
- }
- return ExecuteInternal(context);
- }
- protected abstract Completion ExecuteInternal(EvaluationContext context);
- public ref readonly SourceLocation Location => ref _statement.LocationRef;
- /// <summary>
- /// Opportunity to build one-time structures and caching based on lexical context.
- /// </summary>
- /// <param name="context"></param>
- protected virtual void Initialize(EvaluationContext context)
- {
- }
- protected internal static JintStatement Build(Statement statement)
- {
- if (statement.UserData is JintStatement preparedStatement)
- {
- return preparedStatement;
- }
- JintStatement? result = statement.Type switch
- {
- NodeType.BlockStatement => new JintBlockStatement((NestedBlockStatement) statement),
- NodeType.ReturnStatement => new JintReturnStatement((ReturnStatement) statement),
- NodeType.VariableDeclaration => new JintVariableDeclaration((VariableDeclaration) statement),
- NodeType.BreakStatement => new JintBreakStatement((BreakStatement) statement),
- NodeType.ContinueStatement => new JintContinueStatement((ContinueStatement) statement),
- NodeType.DoWhileStatement => new JintDoWhileStatement((DoWhileStatement) statement),
- NodeType.EmptyStatement => new JintEmptyStatement((EmptyStatement) statement),
- NodeType.ExpressionStatement => new JintExpressionStatement((ExpressionStatement) statement),
- NodeType.ForStatement => new JintForStatement((ForStatement) statement),
- NodeType.ForInStatement => new JintForInForOfStatement((ForInStatement) statement),
- NodeType.ForOfStatement => new JintForInForOfStatement((ForOfStatement) statement),
- NodeType.IfStatement => new JintIfStatement((IfStatement) statement),
- NodeType.LabeledStatement => new JintLabeledStatement((LabeledStatement) statement),
- NodeType.SwitchStatement => new JintSwitchStatement((SwitchStatement) statement),
- NodeType.FunctionDeclaration => new JintFunctionDeclarationStatement((FunctionDeclaration) statement),
- NodeType.ThrowStatement => new JintThrowStatement((ThrowStatement) statement),
- NodeType.TryStatement => new JintTryStatement((TryStatement) statement),
- NodeType.WhileStatement => new JintWhileStatement((WhileStatement) statement),
- NodeType.WithStatement => new JintWithStatement((WithStatement) statement),
- NodeType.DebuggerStatement => new JintDebuggerStatement((DebuggerStatement) statement),
- NodeType.ClassDeclaration => new JintClassDeclarationStatement((ClassDeclaration) statement),
- NodeType.ExportNamedDeclaration => new JintExportNamedDeclaration((ExportNamedDeclaration) statement),
- NodeType.ExportAllDeclaration => new JintExportAllDeclaration((ExportAllDeclaration) statement),
- NodeType.ExportDefaultDeclaration => new JintExportDefaultDeclaration((ExportDefaultDeclaration) statement),
- NodeType.ImportDeclaration => new JintImportDeclaration((ImportDeclaration) statement),
- _ => null
- };
- if (result is null)
- {
- ExceptionHelper.ThrowArgumentOutOfRangeException(nameof(statement.Type), $"unsupported statement type '{statement.Type}'");
- }
- return result;
- }
- internal static JsValue? FastResolve(StatementOrExpression statement)
- {
- if (statement is ReturnStatement rs && rs.Argument is Literal l)
- {
- return JintLiteralExpression.ConvertToJsValue(l);
- }
- return null;
- }
- }
- }
|