diff --git a/src/cs_ident.cc b/src/cs_ident.cc index 73002aa..3dba1a1 100644 --- a/src/cs_ident.cc +++ b/src/cs_ident.cc @@ -71,8 +71,7 @@ svar_impl::svar_impl( alias_impl::alias_impl( state &cs, string_ref name, string_ref a, int fl ): - ident_impl{ident_type::ALIAS, name, fl}, - p_initial{cs}, p_astack{&p_initial} + ident_impl{ident_type::ALIAS, name, fl}, p_initial{cs} { p_initial.val_s.set_str(a); } @@ -80,36 +79,31 @@ alias_impl::alias_impl( alias_impl::alias_impl( state &cs, string_ref name, std::string_view a, int fl ): - ident_impl{ident_type::ALIAS, name, fl}, - p_initial{cs}, p_astack{&p_initial} + ident_impl{ident_type::ALIAS, name, fl}, p_initial{cs} { p_initial.val_s.set_str(a); } alias_impl::alias_impl(state &cs, string_ref name, integer_type a, int fl): - ident_impl{ident_type::ALIAS, name, fl}, - p_initial{cs}, p_astack{&p_initial} + ident_impl{ident_type::ALIAS, name, fl}, p_initial{cs} { p_initial.val_s.set_int(a); } alias_impl::alias_impl(state &cs, string_ref name, float_type a, int fl): - ident_impl{ident_type::ALIAS, name, fl}, - p_initial{cs}, p_astack{&p_initial} + ident_impl{ident_type::ALIAS, name, fl}, p_initial{cs} { p_initial.val_s.set_float(a); } alias_impl::alias_impl(state &cs, string_ref name, int fl): - ident_impl{ident_type::ALIAS, name, fl}, - p_initial{cs}, p_astack{&p_initial} + ident_impl{ident_type::ALIAS, name, fl}, p_initial{cs} { p_initial.val_s.set_none(); } alias_impl::alias_impl(state &cs, string_ref name, any_value v, int fl): - ident_impl{ident_type::ALIAS, name, fl}, - p_initial{cs}, p_astack{&p_initial} + ident_impl{ident_type::ALIAS, name, fl}, p_initial{cs} { p_initial.val_s = v; } diff --git a/src/cs_ident.hh b/src/cs_ident.hh index 7be2021..3223c7e 100644 --- a/src/cs_ident.hh +++ b/src/cs_ident.hh @@ -104,7 +104,6 @@ struct alias_impl: ident_impl, alias { alias_impl(state &cs, string_ref n, any_value v, int flags); ident_stack p_initial; - alias_stack p_astack; }; struct command_impl: ident_impl, command { diff --git a/src/cs_thread.cc b/src/cs_thread.cc index 6d004ec..ccc3f48 100644 --- a/src/cs_thread.cc +++ b/src/cs_thread.cc @@ -5,7 +5,7 @@ namespace cubescript { thread_state::thread_state(internal_state *cs): - vmstack{cs}, idstack{cs}, errbuf{cs} + vmstack{cs}, idstack{cs}, astacks{cs}, errbuf{cs} { vmstack.reserve(32); idstack.reserve(MAX_ARGUMENTS); @@ -18,7 +18,11 @@ hook_func thread_state::set_hook(hook_func f) { } alias_stack &thread_state::get_astack(alias *a) { - return static_cast(a)->p_astack; + auto it = astacks.try_emplace(a->get_index()); + if (it.second) { + it.first->second.node = &static_cast(a)->p_initial; + } + return it.first->second; } } /* namespace cubescript */ diff --git a/src/cs_thread.hh b/src/cs_thread.hh index 68de1a1..e4642d9 100644 --- a/src/cs_thread.hh +++ b/src/cs_thread.hh @@ -14,6 +14,7 @@ namespace cubescript { struct codegen_state; struct thread_state { + using astack_allocator = std_allocator>; /* thread call stack */ ident_link *callstack{}; /* the shared state pointer */ @@ -24,8 +25,12 @@ struct thread_state { codegen_state *cstate{}; /* VM stack */ valbuf vmstack; - /* alias stack */ + /* ident stack */ valbuf idstack; + /* per-alias stack pointer */ + std::unordered_map< + int, alias_stack, std::hash, std::equal_to, astack_allocator + > astacks; /* per-thread storage buffer for error messages */ charbuf errbuf; /* we can attach a hook to vm events */