Stop initializing principal parser at global scope

Avoid the risk of global constructors by making this a function-level
static.
This commit is contained in:
ridiculousfish 2022-06-20 11:11:09 -07:00
parent 06de0f79a1
commit 0230420983
2 changed files with 10 additions and 12 deletions

View File

@ -36,7 +36,8 @@ static wcstring user_presentable_path(const wcstring &path, const environment_t
return replace_home_directory_with_tilde(path, vars);
}
parser_t::parser_t(std::shared_ptr<env_stack_t> vars) : variables(std::move(vars)) {
parser_t::parser_t(std::shared_ptr<env_stack_t> vars, bool is_principal)
: variables(std::move(vars)), is_principal_(is_principal) {
assert(variables.get() && "Null variables in parser initializer");
int cwd = open_cloexec(".", O_RDONLY);
if (cwd < 0) {
@ -46,14 +47,12 @@ parser_t::parser_t(std::shared_ptr<env_stack_t> vars) : variables(std::move(vars
libdata().cwd_fd = std::make_shared<const autoclose_fd_t>(cwd);
}
parser_t::parser_t() : parser_t(env_stack_t::principal_ref()) {}
// Out of line destructor to enable forward declaration of parse_execution_context_t
parser_t::~parser_t() = default;
const std::shared_ptr<parser_t> parser_t::principal{new parser_t()};
parser_t &parser_t::principal_parser() {
static const std::shared_ptr<parser_t> principal{
new parser_t(env_stack_t::principal_ref(), true)};
principal->assert_can_execute();
return *principal;
}
@ -549,7 +548,7 @@ eval_res_t parser_t::eval_node(const parsed_source_ref_t &ps, const T &node,
// Note this only happens in interactive sessions. In non-interactive sessions, SIGINT will
// cause fish to exit.
if (int sig = signal_check_cancel()) {
if (this == principal.get() && block_list.empty()) {
if (is_principal_ && block_list.empty()) {
signal_clear_cancel();
} else {
return proc_status_t::from_signal(sig);

View File

@ -273,6 +273,9 @@ class parser_t : public std::enable_shared_from_this<parser_t> {
/// including sending on-variable change events.
bool syncs_uvars_{false};
/// If set, we are the principal parser.
bool is_principal_{false};
/// List of profile items.
/// This must be a deque because we return pointers to them to callers,
/// who may hold them across blocks (which would cause reallocations internal
@ -288,12 +291,8 @@ class parser_t : public std::enable_shared_from_this<parser_t> {
/// \return whether we are currently evaluating a command substitution.
bool is_command_substitution() const;
/// Create a parser.
parser_t();
parser_t(std::shared_ptr<env_stack_t> vars);
/// The main parser.
static const std::shared_ptr<parser_t> principal;
/// Create a parser
parser_t(std::shared_ptr<env_stack_t> vars, bool is_principal = false);
public:
// No copying allowed.