History

Initial public commit for Dis VM

arr committed 10 years ago

Commit f95902eNo parent (first commit)40 files · +9358 −0Browse files

Showing the changes to src/vm/module_ref.cpp (1 of 40 files). Show all

Unified · Split

src/vm/module_ref.cpp+128−0
@@ -0,0 +1,128 @@
1//
2// Dis VM
3// File: module_ref.cpp
4// Author: arr
5//
6
7#include <runtime.h>
8#include <exceptions.h>
9#include <vm_memory.h>
10#include <utils.h>
11#include <debug.h>
12
13using namespace disvm;
14using namespace disvm::runtime;
15
16namespace
17{
18 std::unique_ptr<vm_array_t> resolve_imports(const export_section_t &exports, const import_vm_module_t &imports)
19 {
20 static auto function_ref_type_desc = type_descriptor_t::create(sizeof(vm_module_function_ref_t), std::vector<byte_t>{});
21 auto refs = std::make_unique<vm_array_t>(function_ref_type_desc, imports.functions.size());
22
23 for (auto index = std::size_t{ 0 }; index < imports.functions.size(); ++index)
24 {
25 const auto &import = imports.functions[index];
26
27 const auto exports_with_sig = exports.equal_range(import.sig);
28 if (exports_with_sig.first == exports.cend() && exports_with_sig.second == exports.cend())
29 throw vm_user_exception{ "Module does not export a function with expected signature" };
30
31 auto export_match = exports_with_sig.first;
32 while (export_match != exports_with_sig.second)
33 {
34 // Look for the matching function name in those with matching signature
35 if (0 == vm_string_t::compare(export_match->second.name.get(), import.name.get()))
36 break;
37
38 ++export_match;
39 }
40
41 if (export_match == exports_with_sig.second)
42 throw vm_user_exception{ "Type check failure for exported function" };
43
44 const auto &export_entry = export_match->second;
45
46 auto &ref = refs->at<vm_module_function_ref_t>(index);
47 ref.entry_pc = export_entry.pc;
48 ref.frame_type = export_entry.frame_type;
49
50 if (debug::is_component_tracing_enabled<debug::component_trace_t::module>())
51 {
52 debug::log_msg(
53 debug::component_trace_t::module,
54 debug::log_level_t::debug,
55 "export: %d %#08x >>%s<<\n",
56 index,
57 export_entry.sig,
58 export_entry.name->str());
59 }
60 }
61
62 return refs;
63 }
64}
65
66std::shared_ptr<const type_descriptor_t> vm_module_ref_t::type_desc()
67{
68 return intrinsic_type_desc::type<vm_module_ref_t>();
69}
70
71vm_module_ref_t::vm_module_ref_t(std::shared_ptr<const vm_module_t> module)
72 : vm_alloc_t(vm_module_ref_t::type_desc())
73 , code_section{ module->code_section }
74 , module{ module }
75 , mp_base{ nullptr }
76 , type_section{ module->type_section }
77 , _builtin_module{ util::has_flag(module->header.runtime_flag, runtime_flags_t::builtin) }
78{
79 if (module->original_mp != nullptr)
80 mp_base = vm_alloc_t::copy(*module->original_mp);
81
82 if (debug::is_component_tracing_enabled<debug::component_trace_t::memory>())
83 debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "init: vm module ref\n");
84}
85
86vm_module_ref_t::vm_module_ref_t(std::shared_ptr<const vm_module_t> module, const import_vm_module_t &imports)
87 : vm_alloc_t(vm_module_ref_t::type_desc())
88 , code_section{ module->code_section }
89 , module{ module }
90 , type_section{ module->type_section }
91 , _function_refs{ resolve_imports(module->export_section, imports) }
92 , _builtin_module{ util::has_flag(module->header.runtime_flag, runtime_flags_t::builtin) }
93{
94 assert(module->header.data_size == 0 || module->original_mp != nullptr);
95
96 if (module->original_mp != nullptr)
97 mp_base = vm_alloc_t::copy(*module->original_mp);
98
99 if (debug::is_component_tracing_enabled<debug::component_trace_t::memory>())
100 debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "init: vm module ref: exported %d\n", _function_refs->get_length());
101}
102
103vm_module_ref_t::~vm_module_ref_t()
104{
105 dec_ref_count_and_free(mp_base);
106
107 if (_function_refs != nullptr)
108 _function_refs->release();
109
110 if (debug::is_component_tracing_enabled<debug::component_trace_t::memory>())
111 debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "destroy: vm module ref\n");
112}
113
114bool vm_module_ref_t::is_builtin_module() const
115{
116 return _builtin_module;
117}
118
119const vm_module_function_ref_t& vm_module_ref_t::get_function_ref(word_t index) const
120{
121 assert(_function_refs != nullptr);
122
123 if (index < 0 || _function_refs->get_length() <= index)
124 throw vm_system_exception{ "Invalid function reference index into module reference functions" };
125
126 return _function_refs->at<vm_module_function_ref_t>(index);
127}
128