@@ -77,6 +77,8 @@ namespace zenkit {
7777
7878 DaedalusVm::DaedalusVm (DaedalusScript&& scr, std::uint8_t flags) : DaedalusScript(std::move(scr)), _m_flags(flags) {
7979 _m_temporary_strings = add_temporary_strings_symbol ();
80+ _m_temporary_strings_free.push (0 );
81+
8082 _m_self_sym = find_symbol_by_name (" SELF" );
8183 _m_other_sym = find_symbol_by_name (" OTHER" );
8284 _m_victim_sym = find_symbol_by_name (" VICTIM" );
@@ -508,8 +510,12 @@ namespace zenkit {
508510 }
509511
510512 void DaedalusVm::push_string (std::string_view value) {
511- _m_temporary_strings->set_string (value);
512- push_reference (_m_temporary_strings);
513+ // We need to push strings without an explicitly attached variable to a
514+ // virtual string container variable.
515+ auto index = this ->get_free_string ();
516+
517+ _m_temporary_strings->set_string (value, index);
518+ push_reference (_m_temporary_strings, index);
513519 }
514520
515521 void DaedalusVm::push_float (float value) {
@@ -584,6 +590,13 @@ namespace zenkit {
584590 throw DaedalusVmException {" tried to pop_reference but frame does not contain a reference." };
585591 }
586592
593+ auto sym = std::get<DaedalusSymbol*>(v.value );
594+ if (sym->index () == _m_temporary_strings->index ()) {
595+ // For virtual strings, we'll mark this string as free when it's popped.
596+ // This is likely unreliable but until it causes issues, it'll stay as-is.
597+ this ->mark_free_string (v.index );
598+ }
599+
587600 return {std::get<DaedalusSymbol*>(v.value ), v.index , v.context };
588601 }
589602
@@ -981,4 +994,25 @@ namespace zenkit {
981994 ZKLOGE (" DaedalusVm" , " Accessing member \" %s\" without an instance set" , ref->name ().c_str ());
982995 }
983996 }
997+
998+ void DaedalusVm::mark_free_string (uint32_t index) {
999+ this ->_m_temporary_strings_free .push (index);
1000+ }
1001+
1002+ uint32_t DaedalusVm::get_free_string () {
1003+ if (_m_temporary_strings_free.size () == 0 ) {
1004+ // Like a normal array, we'll grow exponentially.
1005+ auto prev_size = _m_temporary_strings->count ();
1006+ _m_temporary_strings->grow (prev_size * 2 );
1007+
1008+ // Mark new strings as unused.
1009+ for (uint32_t i = prev_size; i < _m_temporary_strings->count (); ++i) {
1010+ _m_temporary_strings_free.push (i);
1011+ }
1012+ }
1013+
1014+ auto index = this ->_m_temporary_strings_free .top ();
1015+ this ->_m_temporary_strings_free .pop ();
1016+ return index;
1017+ }
9841018} // namespace zenkit
0 commit comments