Switch parser_t::execution_contexts to only storing one

We only ever need the topmost (currently executing) context. We can
store the stack via the C stack rather than an explicit std::vector.
This commit is contained in:
ridiculousfish 2018-02-11 22:00:17 -08:00
parent 92d5c28730
commit 4eb73862fc
2 changed files with 14 additions and 20 deletions

View file

@ -483,8 +483,8 @@ const wchar_t *parser_t::get_function_name(int level) {
int parser_t::get_lineno() const {
int lineno = -1;
if (!execution_contexts.empty()) {
lineno = execution_contexts.back()->get_current_line_number();
if (execution_context) {
lineno = execution_context->get_current_line_number();
// If we are executing a function, we have to add in its offset.
const wchar_t *function_name = is_function();
@ -518,13 +518,10 @@ const wchar_t *parser_t::current_filename() const {
}
wcstring parser_t::current_line() {
if (execution_contexts.empty()) {
if (!execution_context) {
return wcstring();
}
const parse_execution_context_t *context = execution_contexts.back().get();
assert(context != NULL);
int source_offset = context->get_current_source_offset();
int source_offset = execution_context->get_current_source_offset();
if (source_offset < 0) {
return wcstring();
}
@ -554,8 +551,8 @@ wcstring parser_t::current_line() {
parse_error_t empty_error = {};
empty_error.source_start = source_offset;
wcstring line_info =
empty_error.describe_with_prefix(context->get_source(), prefix, is_interactive, skip_caret);
wcstring line_info = empty_error.describe_with_prefix(execution_context->get_source(), prefix,
is_interactive, skip_caret);
if (!line_info.empty()) {
line_info.push_back(L'\n');
}
@ -695,17 +692,14 @@ int parser_t::eval_node(parsed_source_ref_t ps, tnode_t<T> node, const io_chain_
// Start it up
scope_block_t *scope_block = this->push_block<scope_block_t>(block_type);
// Append to the execution context stack.
execution_contexts.push_back(make_unique<parse_execution_context_t>(ps, this));
parse_execution_context_t *ctx = execution_contexts.back().get();
int result = ctx->eval_node(node, scope_block, io);
// Create and set a new execution context.
using exc_ctx_ref_t = std::unique_ptr<parse_execution_context_t>;
scoped_push<exc_ctx_ref_t> exc(&execution_context,
make_unique<parse_execution_context_t>(ps, this));
int result = execution_context->eval_node(node, scope_block, io);
exc.restore();
this->pop_block(scope_block);
// Clean up the execution context stack.
assert(!execution_contexts.empty() && execution_contexts.back().get() == ctx);
execution_contexts.pop_back();
job_reap(0); // reap again
return result;
}

View file

@ -177,8 +177,8 @@ class parser_t {
volatile sig_atomic_t cancellation_requested;
/// Indicates that we are within the process of initializing fish.
bool is_within_fish_initialization;
/// Stack of execution contexts.
std::vector<std::unique_ptr<parse_execution_context_t>> execution_contexts;
/// The current execution context.
std::unique_ptr<parse_execution_context_t> execution_context;
/// List of called functions, used to help prevent infinite recursion.
wcstring_list_t forbidden_function;
/// The jobs associated with this parser.