diff options
Diffstat (limited to 'modules/gdscript/gdscript_byte_codegen.cpp')
-rw-r--r-- | modules/gdscript/gdscript_byte_codegen.cpp | 69 |
1 files changed, 51 insertions, 18 deletions
diff --git a/modules/gdscript/gdscript_byte_codegen.cpp b/modules/gdscript/gdscript_byte_codegen.cpp index 5f1c738207..a81b3298ef 100644 --- a/modules/gdscript/gdscript_byte_codegen.cpp +++ b/modules/gdscript/gdscript_byte_codegen.cpp @@ -77,11 +77,22 @@ uint32_t GDScriptByteCodeGenerator::add_or_get_name(const StringName &p_name) { uint32_t GDScriptByteCodeGenerator::add_temporary() { current_temporaries++; - return increase_stack(); + int idx = increase_stack(); +#ifdef DEBUG_ENABLED + temp_stack.push_back(idx); +#endif + return idx; } void GDScriptByteCodeGenerator::pop_temporary() { + ERR_FAIL_COND(current_temporaries == 0); current_stack_size--; +#ifdef DEBUG_ENABLED + if (temp_stack.back()->get() != current_stack_size) { + ERR_PRINT("Mismatched popping of temporary value"); + } + temp_stack.pop_back(); +#endif current_temporaries--; } @@ -111,6 +122,11 @@ void GDScriptByteCodeGenerator::write_start(GDScript *p_script, const StringName } GDScriptFunction *GDScriptByteCodeGenerator::write_end() { +#ifdef DEBUG_ENABLED + if (current_temporaries != 0) { + ERR_PRINT("Non-zero temporary variables at end of function: " + itos(current_temporaries)); + } +#endif append(GDScriptFunction::OPCODE_END, 0); if (constant_map.size()) { @@ -905,23 +921,39 @@ void GDScriptByteCodeGenerator::write_endif() { if_jmp_addrs.pop_back(); } -void GDScriptByteCodeGenerator::write_for(const Address &p_variable, const Address &p_list) { - int counter_pos = add_temporary() | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS); - int container_pos = add_temporary() | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS); +void GDScriptByteCodeGenerator::start_for(const GDScriptDataType &p_iterator_type, const GDScriptDataType &p_list_type) { + Address counter(Address::LOCAL_VARIABLE, add_local("@counter_pos", p_iterator_type), p_iterator_type); + Address container(Address::LOCAL_VARIABLE, add_local("@container_pos", p_list_type), p_list_type); - current_breaks_to_patch.push_back(List<int>()); + // Store state. + for_counter_variables.push_back(counter); + for_container_variables.push_back(container); +} + +void GDScriptByteCodeGenerator::write_for_assignment(const Address &p_variable, const Address &p_list) { + const Address &container = for_container_variables.back()->get(); // Assign container. append(GDScriptFunction::OPCODE_ASSIGN, 2); - append(container_pos); + append(container); append(p_list); + for_iterator_variables.push_back(p_variable); +} + +void GDScriptByteCodeGenerator::write_for() { + const Address &iterator = for_iterator_variables.back()->get(); + const Address &counter = for_counter_variables.back()->get(); + const Address &container = for_container_variables.back()->get(); + + current_breaks_to_patch.push_back(List<int>()); + GDScriptFunction::Opcode begin_opcode = GDScriptFunction::OPCODE_ITERATE_BEGIN; GDScriptFunction::Opcode iterate_opcode = GDScriptFunction::OPCODE_ITERATE; - if (p_list.type.has_type) { - if (p_list.type.kind == GDScriptDataType::BUILTIN) { - switch (p_list.type.builtin_type) { + if (container.type.has_type) { + if (container.type.kind == GDScriptDataType::BUILTIN) { + switch (container.type.builtin_type) { case Variant::INT: begin_opcode = GDScriptFunction::OPCODE_ITERATE_BEGIN_INT; iterate_opcode = GDScriptFunction::OPCODE_ITERATE_INT; @@ -1005,9 +1037,9 @@ void GDScriptByteCodeGenerator::write_for(const Address &p_variable, const Addre // Begin loop. append(begin_opcode, 3); - append(counter_pos); - append(container_pos); - append(p_variable); + append(counter); + append(container); + append(iterator); for_jmp_addrs.push_back(opcodes.size()); append(0); // End of loop address, will be patched. append(GDScriptFunction::OPCODE_JUMP, 0); @@ -1017,9 +1049,9 @@ void GDScriptByteCodeGenerator::write_for(const Address &p_variable, const Addre int continue_addr = opcodes.size(); continue_addrs.push_back(continue_addr); append(iterate_opcode, 3); - append(counter_pos); - append(container_pos); - append(p_variable); + append(counter); + append(container); + append(iterator); for_jmp_addrs.push_back(opcodes.size()); append(0); // Jump destination, will be patched. } @@ -1042,9 +1074,10 @@ void GDScriptByteCodeGenerator::write_endfor() { } current_breaks_to_patch.pop_back(); - // Remove loop temporaries. - pop_temporary(); - pop_temporary(); + // Pop state. + for_iterator_variables.pop_back(); + for_counter_variables.pop_back(); + for_container_variables.pop_back(); } void GDScriptByteCodeGenerator::start_while_condition() { |