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/array.cpp (1 of 40 files). Show all

Unified · Split

src/vm/array.cpp+188−0
@@ -0,0 +1,188 @@
1+//
2+// Dis VM
3+// File: array.cpp
4+// Author: arr
5+//
6+
7+#include <runtime.h>
8+#include <vm_memory.h>
9+#include <debug.h>
10+#include <exceptions.h>
11+
12+using namespace disvm;
13+using namespace disvm::runtime;
14+
15+std::shared_ptr<const type_descriptor_t> vm_array_t::type_desc()
16+{
17+ return intrinsic_type_desc::type<vm_array_t>();
18+}
19+
20+vm_array_t::vm_array_t(std::shared_ptr<const type_descriptor_t> td, word_t count)
21+ : vm_alloc_t(vm_array_t::type_desc())
22+ , _arr{ nullptr }
23+ , _element_type{ td }
24+ , _length{ count }
25+ , _original{ nullptr }
26+{
27+ assert(_element_type != nullptr);
28+ assert(_length >= 0);
29+ _arr = alloc_memory<byte_t>(_length * _element_type->size_in_bytes);
30+ debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "init: vm array: %d\n", _length);
31+
32+ // Initialize the array
33+ auto arr_local = _arr;
34+ const auto array_len = _length;
35+ const auto &element_type = *_element_type;
36+ debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "begin: init: elements: %d\n", array_len);
37+ for (word_t i = 0; i < array_len; ++i)
38+ {
39+ init_memory(element_type, arr_local);
40+ arr_local += element_type.size_in_bytes;
41+ }
42+
43+ debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "end: init: elements: %d\n", array_len);
44+}
45+
46+vm_array_t::vm_array_t(std::shared_ptr<const type_descriptor_t> td, word_t count, const zero_memory_t&)
47+ : vm_alloc_t(vm_array_t::type_desc())
48+ , _arr{ nullptr }
49+ , _element_type{ td }
50+ , _length{ count }
51+ , _original{ nullptr }
52+{
53+ assert(_element_type != nullptr);
54+ assert(_length >= 0);
55+ _arr = calloc_memory<byte_t>(_length * _element_type->size_in_bytes);
56+ debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "initz: vm array: %d\n", _length);
57+}
58+
59+vm_array_t::vm_array_t(vm_array_t *original, word_t begin_index, word_t count)
60+ : vm_alloc_t(vm_array_t::type_desc())
61+ , _arr{ nullptr }
62+ , _element_type{ original->get_element_type() }
63+ , _length{ count }
64+ , _original{ original }
65+{
66+ assert(_original != nullptr);
67+ assert(0 <= begin_index && begin_index < _original->get_length());
68+ assert(_length >= 0 && (count - begin_index) < _original->get_length());
69+
70+ if (debug::is_component_tracing_enabled<debug::component_trace_t::memory>())
71+ debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "init: vm array: slice: %d %d\n", begin_index, _length);
72+
73+ // Set the data to reference the original array
74+ _arr = _original->_arr + (begin_index * _element_type->size_in_bytes);
75+
76+ // Check if this is a slice of a slice.
77+ if (_original->_original != nullptr)
78+ {
79+ auto actual_original = _original->_original;
80+ dec_ref_count_and_free(_original);
81+
82+ _original = actual_original;
83+ _original->add_ref();
84+ }
85+}
86+
87+vm_array_t::vm_array_t(const vm_string_t *s)
88+ : vm_alloc_t(vm_array_t::type_desc())
89+ , _arr{ nullptr }
90+ , _element_type{ intrinsic_type_desc::type<byte_t>() }
91+ , _length{ 0 }
92+ , _original{ nullptr }
93+{
94+ if (s != nullptr && s->get_length() > 0)
95+ {
96+ auto str = s->str();
97+
98+ // Ignoring the null terminator.
99+ _length = std::strlen(str);
100+ _arr = alloc_memory<byte_t>(_length);
101+ static_assert(sizeof(byte_t) == sizeof(char), "String characters should be byte size");
102+
103+ std::memcpy(_arr, str, _length);
104+ }
105+
106+ if (debug::is_component_tracing_enabled<debug::component_trace_t::memory>())
107+ debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "init: vm array: vm string: %d\n", _length);
108+}
109+
110+vm_array_t::~vm_array_t()
111+{
112+ if (_original != nullptr)
113+ {
114+ // If the array is a sliced (based off of another array) then the
115+ // inner pointer simply points into the original array.
116+ debug::assign_debug_pointer(&_arr);
117+
118+ dec_ref_count_and_free(_original);
119+ debug::assign_debug_pointer(&_original);
120+
121+ debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "destroy: vm array: slice\n");
122+ }
123+ else
124+ {
125+ // Free the array
126+ auto arr_local = _arr;
127+ const auto array_len = _length;
128+ const auto &element_type = *_element_type;
129+ debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "begin: destroy: elements: %d\n", array_len);
130+ for (word_t i = 0; i < array_len; ++i)
131+ {
132+ destroy_memory(element_type, arr_local);
133+ arr_local += element_type.size_in_bytes;
134+ }
135+ debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "end: destroy: elements: %d\n", array_len);
136+
137+ // Free array memory
138+ free_memory(_arr);
139+
140+ debug::assign_debug_pointer(&_arr);
141+ debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "destroy: vm array\n");
142+ }
143+
144+}
145+
146+std::shared_ptr<const type_descriptor_t> vm_array_t::get_element_type() const
147+{
148+ return _element_type;
149+}
150+
151+word_t vm_array_t::get_length() const
152+{
153+ return _length;
154+}
155+
156+pointer_t vm_array_t::at(word_t index) const
157+{
158+ if (index < 0 || _length <= index)
159+ throw out_of_range_memory{ 0, _length - 1, index };
160+
161+ return reinterpret_cast<pointer_t>(_arr + (index * _element_type->size_in_bytes));
162+}
163+
164+void vm_array_t::copy_from(const vm_array_t &source, word_t this_begin_index)
165+{
166+ if (this_begin_index < 0 || _length < (this_begin_index + source._length))
167+ throw out_of_range_memory{};
168+
169+ if (source._element_type != _element_type)
170+ throw type_violation{};
171+
172+ auto dest_arr = _arr + (this_begin_index * _element_type->size_in_bytes);
173+
174+ // Increment all pointers if we have reference types.
175+ if (_element_type->map_in_bytes != 0)
176+ {
177+ assert(false && "Not implemented");
178+ //auto &type_desc = *_element_type;
179+ //auto source_array_element = source->_arr;
180+ //for (word_t i = 0; i < source->_length; ++i)
181+ //{
182+ // source_array_element += (i * type_desc.size_in_bytes);
183+ // inc_ref_count_in_alloc(type_desc, source_array_element);
184+ //}
185+ }
186+
187+ std::memcpy(dest_arr, source._arr, (source._length * _element_type->size_in_bytes));
188+}