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+
13+using namespace disvm;
14+using namespace disvm::runtime;
15+
16+namespace
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+
66+std::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+
71+vm_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+
86+vm_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+
103+vm_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+
114+bool vm_module_ref_t::is_builtin_module() const
115+{
116+ return _builtin_module;
117+}
118+
119+const 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+