aboutsummaryrefslogtreecommitdiff
path: root/src/openvic-simulation/vm/Builtin.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/openvic-simulation/vm/Builtin.cpp')
-rw-r--r--src/openvic-simulation/vm/Builtin.cpp153
1 files changed, 153 insertions, 0 deletions
diff --git a/src/openvic-simulation/vm/Builtin.cpp b/src/openvic-simulation/vm/Builtin.cpp
new file mode 100644
index 0000000..c5c62e9
--- /dev/null
+++ b/src/openvic-simulation/vm/Builtin.cpp
@@ -0,0 +1,153 @@
+#include "vm/Builtin.hpp"
+
+#include "InstanceManager.hpp"
+#include "vm/Codegen.hpp"
+#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
+ return nullptr;
+}
+
+bool execute_effect(
+ OpenVic::InstanceManager* instance_manager, const char* effect_id, OpenVic::Asm::scope_variant& scope,
+ OpenVic::Asm::argument* arguments, std::size_t arg_count
+) {
+ // TODO: execute effect based on id, scope, and arguments
+ return true;
+}
+
+bool execute_trigger(
+ OpenVic::InstanceManager* instance_manager, const char* trigger_id, OpenVic::Asm::scope_variant& scope,
+ OpenVic::Asm::argument* arguments, std::size_t arg_count, bool* result
+) {
+ // TODO: execute trigger based on id, scope, and arguments
+ return true;
+}
+
+LAUF_RUNTIME_BUILTIN(call_effect, 3, 0, LAUF_RUNTIME_BUILTIN_DEFAULT, "call_effect", nullptr) {
+ 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 effect_name_addr = vstack_ptr[0].as_address;
+ auto scope_ptr = static_cast<OpenVic::Asm::scope_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);
+ if (effect_name == nullptr) {
+ return lauf_runtime_panic(process, "invalid effect name address");
+ }
+
+ lauf_runtime_allocation array_allocation;
+ if (!lauf_runtime_get_allocation(process, argument_array_addr, &array_allocation)) {
+ return lauf_runtime_panic(process, "invalid arguments address");
+ }
+
+ std::size_t count = array_allocation.size / lauf_asm_type_value.layout.size;
+
+ 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)) {
+ return lauf_runtime_panic(process, "effect could not be found");
+ }
+
+ vstack_ptr += 3;
+ LAUF_RUNTIME_BUILTIN_DISPATCH;
+}
+
+LAUF_RUNTIME_BUILTIN(call_trigger, 3, 1, LAUF_RUNTIME_BUILTIN_DEFAULT, "call_trigger", &call_effect) {
+ 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 trigger_name_addr = vstack_ptr[0].as_address;
+ auto scope_ptr = vstack_ptr[1].as_native_ptr;
+ auto argument_array_addr = vstack_ptr[2].as_address;
+
+ auto effect_name = lauf_runtime_get_cstr(process, trigger_name_addr);
+ if (effect_name == nullptr) {
+ return lauf_runtime_panic(process, "invalid trigger name address");
+ }
+
+ lauf_runtime_allocation array_allocation;
+ if (!lauf_runtime_get_allocation(process, argument_array_addr, &array_allocation)) {
+ return lauf_runtime_panic(process, "invalid arguments address");
+ }
+
+ std::size_t count = array_allocation.size / lauf_asm_type_value.layout.size;
+
+ auto argument_array =
+ static_cast<OpenVic::Asm::argument*>(lauf_runtime_get_mut_ptr(process, argument_array_addr, { 1, 1 }));
+
+ 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
+ )) {
+ return lauf_runtime_panic(process, "trigger could not be found");
+ }
+
+ vstack_ptr += 2;
+
+ vstack_ptr[0].as_sint = trigger_result;
+
+ LAUF_RUNTIME_BUILTIN_DISPATCH;
+}
+
+LAUF_RUNTIME_BUILTIN(
+ translate_address_to_pointer, 1, 1, LAUF_RUNTIME_BUILTIN_DEFAULT, "translate_address_to_pointer", &call_trigger
+) {
+ auto address = vstack_ptr[0].as_address;
+
+ auto ptr = lauf_runtime_get_const_ptr(process, address, { 0, 1 });
+ if (ptr == nullptr) {
+ return lauf_runtime_panic(process, "invalid address");
+ }
+ vstack_ptr[0].as_native_ptr = (void*)ptr;
+
+ LAUF_RUNTIME_BUILTIN_DISPATCH;
+}
+
+LAUF_RUNTIME_BUILTIN(
+ translate_address_to_string, 1, 1, LAUF_RUNTIME_BUILTIN_DEFAULT, "translate_address_to_string",
+ &translate_address_to_pointer
+) {
+ auto address = vstack_ptr[0].as_address;
+
+ auto ptr = lauf_runtime_get_cstr(process, address);
+ if (ptr == nullptr) {
+ return lauf_runtime_panic(process, "invalid address");
+ }
+ vstack_ptr[0].as_native_ptr = (void*)ptr;
+
+ LAUF_RUNTIME_BUILTIN_DISPATCH;
+}
+
+LAUF_RUNTIME_BUILTIN(load_scope_ptr, 1, 1, LAUF_RUNTIME_BUILTIN_DEFAULT, "load_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");
+ }
+ auto vm_data = static_cast<OpenVic::Vm::VmUserData*>(user_data);
+
+ auto scope_ref_position = vstack_ptr[0].as_uint;
+
+ if (scope_ref_position >= vm_data->scope_references.size()) {
+ return lauf_runtime_panic(process, "invalid scope reference value");
+ }
+
+ vstack_ptr[0].as_native_ptr = &vm_data->scope_references[scope_ref_position];
+
+ LAUF_RUNTIME_BUILTIN_DISPATCH;
+}