Showing the changes to src/exec/main.cpp (1 of 24 files). Show all
Unified · Split
| @@ -11,7 +11,7 @@ · 10 unmodified lines | |||
| 11 | #include <builtin_module.h> | 11 | #include <builtin_module.h> |
| 12 | #include <debug.h> | 12 | #include <debug.h> |
| 13 | #include <exceptions.h> | 13 | #include <exceptions.h> |
| 14 | #include <vm_asm.h> | 14 | #include <vm_asm_sigkind.h> |
| 15 | #include <vm_version.h> | 15 | #include <vm_version.h> |
| 16 | #include "exec.h" | 16 | #include "exec.h" |
| 17 | 17 | ||
| @@ -21,6 +21,12 @@ using namespace disvm::assembly::sigkind; · 3 unmodified lines | |||
| 21 | 21 | ||
| 22 | namespace | 22 | namespace |
| 23 | { | 23 | { |
| 24 | template<int L> | ||
| 25 | std::unique_ptr<vm_string_t> create_string_from_const(const char(&ca)[L]) | ||
| 26 | { | ||
| 27 | return std::make_unique<vm_string_t>(L - 1, reinterpret_cast<const uint8_t*>(ca)); | ||
| 28 | } | ||
| 29 | |||
| 24 | // Entry frame layout | 30 | // Entry frame layout |
| 25 | struct vm_entry_frame_t final : public vm_frame_base_alloc_t | 31 | struct vm_entry_frame_t final : public vm_frame_base_alloc_t |
| 26 | { | 32 | { |
| @@ -35,24 +41,17 @@ namespace · 8 unmodified lines | |||
| 35 | 41 | ||
| 36 | std::unique_ptr<vm_module_t> create_entry_module(vm_t &vm, const std::vector<char *> &vm_args) | 42 | std::unique_ptr<vm_module_t> create_entry_module(vm_t &vm, const std::vector<char *> &vm_args) |
| 37 | { | 43 | { |
| 38 | if (vm_args.size() == 0) | ||
| 39 | throw vm_user_exception{ "Entry module not supplied" }; | ||
| 40 | |||
| 41 | // Convert arguments to a list | 44 | // Convert arguments to a list |
| 42 | vm_string_t *command_module_path = nullptr; | 45 | vm_string_t *command_module_path = nullptr; |
| 43 | vm_list_t *args = nullptr; | 46 | vm_list_t *mod_args = new vm_list_t{ intrinsic_type_desc::type<vm_string_t>() }; |
| 44 | vm_list_t *last = nullptr; | 47 | vm_list_t *last = mod_args; |
| 45 | for (auto i = std::size_t{ 0 }; i < vm_args.size(); ++i) | 48 | for (auto raw_arg : vm_args) |
| 46 | { | 49 | { |
| 47 | auto tmp = vm_args[i]; | 50 | auto curr_arg = new vm_string_t{ std::strlen(raw_arg), reinterpret_cast<uint8_t *>(raw_arg) }; |
| 48 | auto arg = new vm_string_t{ std::strlen(tmp), reinterpret_cast<uint8_t *>(tmp) }; | 51 | if (command_module_path == nullptr) |
| 49 | if (args == nullptr) | ||
| 50 | { | 52 | { |
| 51 | // First argument is the module to load | 53 | // First argument is the module to load |
| 52 | command_module_path = arg; | 54 | command_module_path = curr_arg; |
| 53 | assert(last == nullptr); | ||
| 54 | args = new vm_list_t{ intrinsic_type_desc::type<vm_string_t>() }; | ||
| 55 | last = args; | ||
| 56 | } | 55 | } |
| 57 | else | 56 | else |
| 58 | { | 57 | { |
| @@ -63,10 +62,11 @@ namespace · 4 unmodified lines | |||
| 63 | last = new_tail; | 62 | last = new_tail; |
| 64 | } | 63 | } |
| 65 | 64 | ||
| 66 | pt_ref(last->value()) = arg->get_allocation(); | 65 | pt_ref(last->value()) = curr_arg->get_allocation(); |
| 67 | } | 66 | } |
| 68 | 67 | ||
| 69 | assert(args != nullptr); | 68 | if (command_module_path == nullptr) |
| 69 | throw vm_user_exception{ "Entry module not supplied" }; | ||
| 70 | 70 | ||
| 71 | // Pre-load the command module in the VM. | 71 | // Pre-load the command module in the VM. |
| 72 | command_module = vm.load_module(command_module_path->str()); | 72 | command_module = vm.load_module(command_module_path->str()); |
| @@ -79,9 +79,7 @@ namespace · 6 unmodified lines | |||
| 79 | e.header.entry_pc = 0; | 79 | e.header.entry_pc = 0; |
| 80 | e.header.entry_type = 0; | 80 | e.header.entry_type = 0; |
| 81 | e.header.runtime_flag = (runtime_flags_t::has_import); | 81 | e.header.runtime_flag = (runtime_flags_t::has_import); |
| 82 | 82 | e.module_name = create_string_from_const("_entry_"); | |
| 83 | std::array<uint8_t, 8> mod_name = { "_entry_" }; | ||
| 84 | e.module_name = std::make_unique<vm_string_t>(mod_name.size() - 1, mod_name.data()); | ||
| 85 | 83 | ||
| 86 | // Inherit the stack extent from the command module and add the entry frame size. | 84 | // Inherit the stack extent from the command module and add the entry frame size. |
| 87 | e.header.stack_extent = command_module->header.stack_extent + sizeof(vm_entry_frame_t); | 85 | e.header.stack_extent = command_module->header.stack_extent + sizeof(vm_entry_frame_t); |
| @@ -99,7 +97,7 @@ namespace · 11 unmodified lines | |||
| 99 | // Take a reference on the command module path and store it on the entry frame | 97 | // Take a reference on the command module path and store it on the entry frame |
| 100 | command_module_path->add_ref(); | 98 | command_module_path->add_ref(); |
| 101 | mp_base[0] = command_module_path->get_allocation(); | 99 | mp_base[0] = command_module_path->get_allocation(); |
| 102 | mp_base[1] = args->get_allocation(); | 100 | mp_base[1] = mod_args->get_allocation(); |
| 103 | 101 | ||
| 104 | // Define the frame offset for the argument | 102 | // Define the frame offset for the argument |
| 105 | const auto first_arg_offset = vm_frame_constants::limbo_first_arg_register_offset(); | 103 | const auto first_arg_offset = vm_frame_constants::limbo_first_arg_register_offset(); |
| @@ -168,9 +166,7 @@ namespace · 62 unmodified lines | |||
| 168 | assert(exec_init_sig == sig_stream_t::compute_signature_hash("f(Ls)n")); | 166 | assert(exec_init_sig == sig_stream_t::compute_signature_hash("f(Ls)n")); |
| 169 | #endif | 167 | #endif |
| 170 | func.sig = exec_init_sig; | 168 | func.sig = exec_init_sig; |
| 171 | 169 | func.name = create_string_from_const("init"); | |
| 172 | std::array<uint8_t, 5> func_name = { "init" }; | ||
| 173 | func.name = std::make_unique<vm_string_t>(func_name.size() - 1, func_name.data()); | ||
| 174 | 170 | ||
| 175 | import_vm_module_t import{}; | 171 | import_vm_module_t import{}; |
| 176 | import.functions.push_back(std::move(func)); | 172 | import.functions.push_back(std::move(func)); |