diff options
Diffstat (limited to 'src/openvic-simulation/vm/Builtin.cpp')
-rw-r--r-- | src/openvic-simulation/vm/Builtin.cpp | 117 |
1 files changed, 103 insertions, 14 deletions
diff --git a/src/openvic-simulation/vm/Builtin.cpp b/src/openvic-simulation/vm/Builtin.cpp index c5c62e9..2ba8457 100644 --- a/src/openvic-simulation/vm/Builtin.cpp +++ b/src/openvic-simulation/vm/Builtin.cpp @@ -1,20 +1,21 @@ #include "vm/Builtin.hpp" -#include "InstanceManager.hpp" -#include "vm/Codegen.hpp" +#include "GameManager.hpp" +#include <lauf/asm/type.h> #include <lauf/runtime/builtin.h> #include <lauf/runtime/memory.h> #include <lauf/runtime/process.h> #include <lauf/runtime/value.h> -OpenVic::Asm::scope_variant* -get_keyword_scope(OpenVic::InstanceManager* instance_manager, const char* keyword, OpenVic::Vm::Codegen::scope_type type) { - // TODO: get scope native pointer from name and type +OpenVic::Asm::scope_store_variant* create_scope( // + OpenVic::GameManager* instance_manager, const char* scope_name, OpenVic::Asm::scope_store_variant* relative_scope +) { + // TODO: create scope based on scope_name and relative_scope return nullptr; } bool execute_effect( - OpenVic::InstanceManager* instance_manager, const char* effect_id, OpenVic::Asm::scope_variant& scope, + OpenVic::GameManager* instance_manager, const char* effect_id, OpenVic::Asm::scope_store_variant& scope, OpenVic::Asm::argument* arguments, std::size_t arg_count ) { // TODO: execute effect based on id, scope, and arguments @@ -22,7 +23,7 @@ bool execute_effect( } bool execute_trigger( - OpenVic::InstanceManager* instance_manager, const char* trigger_id, OpenVic::Asm::scope_variant& scope, + OpenVic::GameManager* instance_manager, const char* trigger_id, OpenVic::Asm::scope_store_variant& scope, OpenVic::Asm::argument* arguments, std::size_t arg_count, bool* result ) { // TODO: execute trigger based on id, scope, and arguments @@ -37,7 +38,7 @@ LAUF_RUNTIME_BUILTIN(call_effect, 3, 0, LAUF_RUNTIME_BUILTIN_DEFAULT, "call_effe auto vm_data = static_cast<OpenVic::Vm::VmUserData*>(user_data); auto effect_name_addr = vstack_ptr[0].as_address; - auto scope_ptr = static_cast<OpenVic::Asm::scope_variant*>(vstack_ptr[1].as_native_ptr); + auto scope_def_ptr = static_cast<OpenVic::Asm::scope_store_variant*>(vstack_ptr[1].as_native_ptr); auto argument_array_addr = vstack_ptr[2].as_address; auto effect_name = lauf_runtime_get_cstr(process, effect_name_addr); @@ -55,7 +56,7 @@ LAUF_RUNTIME_BUILTIN(call_effect, 3, 0, LAUF_RUNTIME_BUILTIN_DEFAULT, "call_effe auto argument_array = static_cast<OpenVic::Asm::argument*>(lauf_runtime_get_mut_ptr(process, argument_array_addr, { 1, 1 })); - if (!execute_effect(vm_data->instance_manager, effect_name, *scope_ptr, argument_array, count)) { + if (!execute_effect(vm_data->game_manager, effect_name, *scope_def_ptr, argument_array, count)) { return lauf_runtime_panic(process, "effect could not be found"); } @@ -92,8 +93,8 @@ LAUF_RUNTIME_BUILTIN(call_trigger, 3, 1, LAUF_RUNTIME_BUILTIN_DEFAULT, "call_tri bool trigger_result; if (!execute_trigger( - static_cast<OpenVic::InstanceManager*>(user_data), effect_name, - *static_cast<OpenVic::Asm::scope_variant*>(scope_ptr), argument_array, count, &trigger_result + vm_data->game_manager, effect_name, *static_cast<OpenVic::Asm::scope_store_variant*>(scope_ptr), argument_array, + count, &trigger_result )) { return lauf_runtime_panic(process, "trigger could not be found"); } @@ -134,7 +135,9 @@ LAUF_RUNTIME_BUILTIN( LAUF_RUNTIME_BUILTIN_DISPATCH; } -LAUF_RUNTIME_BUILTIN(load_scope_ptr, 1, 1, LAUF_RUNTIME_BUILTIN_DEFAULT, "load_scope_ptr", &translate_address_to_string) { +LAUF_RUNTIME_BUILTIN( + load_static_scope_ptr, 1, 1, LAUF_RUNTIME_BUILTIN_DEFAULT, "load_static_scope_ptr", &translate_address_to_string +) { auto user_data = lauf_runtime_get_vm_user_data(process); if (user_data == nullptr) { return lauf_runtime_panic(process, "invalid user data"); @@ -143,11 +146,97 @@ LAUF_RUNTIME_BUILTIN(load_scope_ptr, 1, 1, LAUF_RUNTIME_BUILTIN_DEFAULT, "load_s auto scope_ref_position = vstack_ptr[0].as_uint; - if (scope_ref_position >= vm_data->scope_references.size()) { + if (scope_ref_position >= vm_data->scope_refs.size()) { return lauf_runtime_panic(process, "invalid scope reference value"); } - vstack_ptr[0].as_native_ptr = &vm_data->scope_references[scope_ref_position]; + vstack_ptr[0].as_native_ptr = &vm_data->scope_refs[scope_ref_position]; + + LAUF_RUNTIME_BUILTIN_DISPATCH; +} + +LAUF_RUNTIME_BUILTIN( + load_relative_scope_ptr, 2, 1, LAUF_RUNTIME_BUILTIN_DEFAULT, "load_relative_scope_ptr", &load_static_scope_ptr +) { + auto user_data = lauf_runtime_get_vm_user_data(process); + if (user_data == nullptr) { + return lauf_runtime_panic(process, "invalid user data"); + } + auto vm_data = static_cast<OpenVic::Vm::VmUserData*>(user_data); + + auto scope_name_addr = vstack_ptr[0].as_address; + auto vstack_1 = vstack_ptr[1]; + auto relative_scope = static_cast<OpenVic::Asm::scope_store_variant*>(vstack_ptr[1].as_native_ptr); + + auto scope_name = lauf_runtime_get_cstr(process, scope_name_addr); + if (scope_name == nullptr) { + return lauf_runtime_panic(process, "invalid scope name address"); + } + + vstack_ptr++; + + auto scope = create_scope(vm_data->game_manager, scope_name, relative_scope); + + if (scope == nullptr) { + return lauf_runtime_panic(process, "could not create scope"); + } + + vm_data->scope_refs.emplace_back(std::move(*scope)); + delete scope; + + vstack_ptr[0].as_native_ptr = &vm_data->scope_refs.back(); + + LAUF_RUNTIME_BUILTIN_DISPATCH; +} + +LAUF_RUNTIME_BUILTIN(push_current_scope, 1, 0, LAUF_RUNTIME_BUILTIN_DEFAULT, "push_current_scope", &load_relative_scope_ptr) { + auto user_data = lauf_runtime_get_vm_user_data(process); + if (user_data == nullptr) { + return lauf_runtime_panic(process, "invalid user data"); + } + auto vm_data = static_cast<OpenVic::Vm::VmUserData*>(user_data); + + auto current_scope = static_cast<OpenVic::Asm::scope_store_variant*>(vstack_ptr[0].as_native_ptr); + + vm_data->scope_stack.push(current_scope); + + vstack_ptr++; + LAUF_RUNTIME_BUILTIN_DISPATCH; +} + +LAUF_RUNTIME_BUILTIN(pop_current_scope, 0, 0, LAUF_RUNTIME_BUILTIN_DEFAULT, "pop_current_scope", &push_current_scope) { + auto user_data = lauf_runtime_get_vm_user_data(process); + if (user_data == nullptr) { + return lauf_runtime_panic(process, "invalid user data"); + } + auto vm_data = static_cast<OpenVic::Vm::VmUserData*>(user_data); + + if (vm_data->scope_stack.empty()) { + return lauf_runtime_panic(process, "scope stack empty"); + } + + if (vm_data->scope_stack.size() == 1) { + return lauf_runtime_panic(process, "attempt to pop last scope in stack"); + } + + vm_data->scope_stack.pop(); + + LAUF_RUNTIME_BUILTIN_DISPATCH; +} + +LAUF_RUNTIME_BUILTIN(load_current_scope, 0, 1, LAUF_RUNTIME_BUILTIN_DEFAULT, "load_current_scope", &pop_current_scope) { + auto user_data = lauf_runtime_get_vm_user_data(process); + if (user_data == nullptr) { + return lauf_runtime_panic(process, "invalid user data"); + } + auto vm_data = static_cast<OpenVic::Vm::VmUserData*>(user_data); + + if (vm_data->scope_stack.empty()) { + return lauf_runtime_panic(process, "scope stack empty"); + } + + vstack_ptr--; + vstack_ptr[0].as_native_ptr = vm_data->scope_stack.top(); LAUF_RUNTIME_BUILTIN_DISPATCH; } |