History

Bugs found during limbo compiler work - Ref counting mistakes in vm_array copy_from() - document perf opportunity - Multiple bugs in addc instruction - set_rune() on vm_string was creating non-null terminated strings - Add support for '*', 'c', and 'u' flags in print formatting

arr committed 9 years ago

Commit 57e9d241 parent 3f81a2c4 files · +86 −44Browse files

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

Unified · Split

src/vm/string.cpp+16−10
@@ -169,6 +169,12 @@ namespace · 168 unmodified lines
169 // Length + 1 (null) + space for string expansion169 // Length + 1 (null) + space for string expansion
170 return (current_length + 1 + (current_length / 4));170 return (current_length + 1 + (current_length / 4));
171 }171 }
172
173 template<typename T, word_t S>
174 constexpr word_t compute_max_length(const T(&)[S])
175 {
176 return S - 1;
177 }
172}178}
173 179
174vm_string_t::vm_string_t()180vm_string_t::vm_string_t()
@@ -177,7 +183,7 @@ vm_string_t::vm_string_t() · 2 unmodified lines
177 , _encoded_str{ nullptr }183 , _encoded_str{ nullptr }
178 , _is_alloc{ false }184 , _is_alloc{ false }
179 , _length{ 0 }185 , _length{ 0 }
180 , _length_max{ sizeof(_mem.local) }186 , _length_max{ compute_max_length(_mem.local) }
181 , _mem{}187 , _mem{}
182{ }188{ }
183 189
@@ -187,7 +193,7 @@ vm_string_t::vm_string_t(std::size_t encoded_str_len, const uint8_t *encoded_str · 3 unmodified lines
187 , _encoded_str{ nullptr }193 , _encoded_str{ nullptr }
188 , _is_alloc{ false }194 , _is_alloc{ false }
189 , _length{ 0 }195 , _length{ 0 }
190 , _length_max{ sizeof(_mem.local) }196 , _length_max{ compute_max_length(_mem.local) }
191 , _mem{}197 , _mem{}
192{198{
193 assert((encoded_str_len > 0 && encoded_str != nullptr) || encoded_str_len == 0);199 assert((encoded_str_len > 0 && encoded_str != nullptr) || encoded_str_len == 0);
@@ -203,11 +209,11 @@ vm_string_t::vm_string_t(std::size_t encoded_str_len, const uint8_t *encoded_str · 9 unmodified lines
203 _character_size = (encoded_str_len != utf8_length.codepoint_count) ? sizeof(rune_t) : sizeof(char);209 _character_size = (encoded_str_len != utf8_length.codepoint_count) ? sizeof(rune_t) : sizeof(char);
204 210
205 _length = static_cast<word_t>(utf8_length.codepoint_count);211 _length = static_cast<word_t>(utf8_length.codepoint_count);
206 _length_max = sizeof(_mem.local) / _character_size;212 _length_max = compute_max_length(_mem.local) / _character_size;
207 213
208 // Allocate memory based on character count and size214 // Allocate memory based on character count and size
209 auto dest = _mem.local;215 auto dest = _mem.local;
210 if ((encoded_str_len + 1) > sizeof(_mem.local))216 if (encoded_str_len > static_cast<std::size_t>(compute_max_length(_mem.local)))
211 {217 {
212 // If we are going to allocate, make sure it is larger than needed.218 // If we are going to allocate, make sure it is larger than needed.
213 _length_max = compute_max_length(_length);219 _length_max = compute_max_length(_length);
@@ -268,7 +274,7 @@ vm_string_t::vm_string_t(const vm_string_t &other, word_t begin_index, word_t en · 54 unmodified lines
268 , _length_max{ compute_max_length(end_index - begin_index) }274 , _length_max{ compute_max_length(end_index - begin_index) }
269 , _mem{}275 , _mem{}
270{276{
271 if (end_index <= begin_index)277 if (end_index < begin_index)
272 throw out_of_range_memory{};278 throw out_of_range_memory{};
273 279
274 if (begin_index < 0)280 if (begin_index < 0)
@@ -346,7 +352,7 @@ vm_string_t &vm_string_t::append(const vm_string_t &other) · 71 unmodified lines
346 352
347 // Define the values for the appended string353 // Define the values for the appended string
348 const auto new_length = local_length + other_length;354 const auto new_length = local_length + other_length;
349 const auto new_length_max = (new_length == 0) ? static_cast<word_t>(sizeof(_mem.local)) : compute_max_length(new_length);355 const auto new_length_max = (new_length == 0) ? static_cast<word_t>(compute_max_length(_mem.local)) : compute_max_length(new_length);
350 const auto new_is_rune = local_is_rune || other_is_rune;356 const auto new_is_rune = local_is_rune || other_is_rune;
351 uint8_t *new_source = nullptr;357 uint8_t *new_source = nullptr;
352 358
@@ -442,7 +448,7 @@ void vm_string_t::set_rune(word_t index, rune_t value) · 89 unmodified lines
442 _character_size = static_cast<uint8_t>(new_character_size);448 _character_size = static_cast<uint8_t>(new_character_size);
443 assert(_character_size == sizeof(rune_t));449 assert(_character_size == sizeof(rune_t));
444 450
445 _length_max = (_length == 0) ? static_cast<word_t>(sizeof(_mem.local)) : compute_max_length(_length);451 _length_max = (_length == 0) ? static_cast<word_t>(compute_max_length(_mem.local)) : compute_max_length(_length);
446 auto new_alloc = calloc_memory<rune_t>(_length_max * _character_size);452 auto new_alloc = calloc_memory<rune_t>(_length_max * _character_size);
447 453
448 // Copy source into the new alloc.454 // Copy source into the new alloc.
@@ -460,9 +466,9 @@ void vm_string_t::set_rune(word_t index, rune_t value) · 11 unmodified lines
460 }466 }
461 else if (static_cast<word_t>(_length_max) <= index) // Check if string can accomodate the new character.467 else if (static_cast<word_t>(_length_max) <= index) // Check if string can accomodate the new character.
462 {468 {
463 _length_max = (_length == 0) ? static_cast<word_t>(sizeof(_mem.local)) : compute_max_length(_length);469 _length_max = (_length == 0) ? static_cast<word_t>(compute_max_length(_mem.local)) : compute_max_length(_length);
464 auto new_alloc = calloc_memory<uint8_t>(_length_max * _character_size);470 auto new_alloc = calloc_memory<uint8_t>(_length_max * _character_size);
465 ::memcpy(new_alloc, source, _length * _character_size);471 std::memcpy(new_alloc, source, _length * _character_size);
466 472
467 // Free memory, if allocated473 // Free memory, if allocated
468 if (_is_alloc)474 if (_is_alloc)
@@ -503,7 +509,7 @@ const char *vm_string_t::str() const · 34 unmodified lines
503 if (_encoded_str != nullptr)509 if (_encoded_str != nullptr)
504 return _encoded_str;510 return _encoded_str;
505 511
506 // If the string is ASCII then just return the memory512 // If the string is ASCII then return the memory
507 if (_character_size == sizeof(char))513 if (_character_size == sizeof(char))
508 {514 {
509 _encoded_str = (_is_alloc) ? reinterpret_cast<char *>(_mem.alloc) : reinterpret_cast<char *>(_mem.local);515 _encoded_str = (_is_alloc) ? reinterpret_cast<char *>(_mem.alloc) : reinterpret_cast<char *>(_mem.local);