using System.Runtime.CompilerServices; using Jint.Collections; using Jint.Native.Generator; using Jint.Runtime.Environments; using Environment = Jint.Runtime.Environments.Environment; namespace Jint.Runtime; internal sealed class ExecutionContextStack { private readonly RefStack _stack; public ExecutionContextStack(int capacity) { _stack = new RefStack(capacity); } public void ReplaceTopLexicalEnvironment(Environment newEnv) { var array = _stack._array; var size = _stack._size; ref var executionContext = ref array[size - 1]; executionContext = executionContext.UpdateLexicalEnvironment(newEnv); } public void ReplaceTopVariableEnvironment(Environment newEnv) { var array = _stack._array; var size = _stack._size; ref var executionContext = ref array[size - 1]; executionContext = executionContext.UpdateVariableEnvironment(newEnv); } public void ReplaceTopPrivateEnvironment(PrivateEnvironment? newEnv) { var array = _stack._array; var size = _stack._size; ref var executionContext = ref array[size - 1]; executionContext = executionContext.UpdatePrivateEnvironment(newEnv); } public ref readonly ExecutionContext ReplaceTopGenerator(GeneratorInstance newEnv) { var array = _stack._array; var size = _stack._size; ref var executionContext = ref array[size - 1]; executionContext = executionContext.UpdateGenerator(newEnv); return ref executionContext; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ref readonly ExecutionContext Peek() => ref _stack.Peek(); [MethodImpl(MethodImplOptions.AggressiveInlining)] public ref readonly ExecutionContext Peek(int fromTop) => ref _stack.Peek(fromTop); [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Push(in ExecutionContext context) => _stack.Push(in context); [MethodImpl(MethodImplOptions.AggressiveInlining)] public ref readonly ExecutionContext Pop() => ref _stack.Pop(); public IScriptOrModule? GetActiveScriptOrModule() { var array = _stack._array; var size = _stack._size; for (var i = size - 1; i > -1; --i) { ref readonly var context = ref array[i]; if (context.ScriptOrModule is not null) { return context.ScriptOrModule; } } return null; } public ParserOptions? GetActiveParserOptions() { var array = _stack._array; var size = _stack._size; for (var i = size - 1; i > -1; --i) { ref readonly var context = ref array[i]; if (context.ParserOptions is not null) { return context.ParserOptions; } } return null; } }