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
169169 // Length + 1 (null) + space for string expansion
170170 return (current_length + 1 + (current_length / 4));
171171 }
172+
173+ template<typename T, word_t S>
174+ constexpr word_t compute_max_length(const T(&)[S])
175+ {
176+ return S - 1;
177+ }
172178 }
173179
174180 vm_string_t::vm_string_t()
@@ -177,7 +183,7 @@ vm_string_t::vm_string_t() · 2 unmodified lines
177183 , _encoded_str{ nullptr }
178184 , _is_alloc{ false }
179185 , _length{ 0 }
180− , _length_max{ sizeof(_mem.local) }
186+ , _length_max{ compute_max_length(_mem.local) }
181187 , _mem{}
182188 { }
183189
@@ -187,7 +193,7 @@ vm_string_t::vm_string_t(std::size_t encoded_str_len, const uint8_t *encoded_str · 3 unmodified lines
187193 , _encoded_str{ nullptr }
188194 , _is_alloc{ false }
189195 , _length{ 0 }
190− , _length_max{ sizeof(_mem.local) }
196+ , _length_max{ compute_max_length(_mem.local) }
191197 , _mem{}
192198 {
193199 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
203209 _character_size = (encoded_str_len != utf8_length.codepoint_count) ? sizeof(rune_t) : sizeof(char);
204210
205211 _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;
207213
208214 // Allocate memory based on character count and size
209215 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)))
211217 {
212218 // If we are going to allocate, make sure it is larger than needed.
213219 _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
268274 , _length_max{ compute_max_length(end_index - begin_index) }
269275 , _mem{}
270276 {
271− if (end_index <= begin_index)
277+ if (end_index < begin_index)
272278 throw out_of_range_memory{};
273279
274280 if (begin_index < 0)
@@ -346,7 +352,7 @@ vm_string_t &vm_string_t::append(const vm_string_t &other) · 71 unmodified lines
346352
347353 // Define the values for the appended string
348354 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);
350356 const auto new_is_rune = local_is_rune || other_is_rune;
351357 uint8_t *new_source = nullptr;
352358
@@ -442,7 +448,7 @@ void vm_string_t::set_rune(word_t index, rune_t value) · 89 unmodified lines
442448 _character_size = static_cast<uint8_t>(new_character_size);
443449 assert(_character_size == sizeof(rune_t));
444450
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);
446452 auto new_alloc = calloc_memory<rune_t>(_length_max * _character_size);
447453
448454 // 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
460466 }
461467 else if (static_cast<word_t>(_length_max) <= index) // Check if string can accomodate the new character.
462468 {
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);
464470 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);
466472
467473 // Free memory, if allocated
468474 if (_is_alloc)
@@ -503,7 +509,7 @@ const char *vm_string_t::str() const · 34 unmodified lines
503509 if (_encoded_str != nullptr)
504510 return _encoded_str;
505511
506− // If the string is ASCII then just return the memory
512+ // If the string is ASCII then return the memory
507513 if (_character_size == sizeof(char))
508514 {
509515 _encoded_str = (_is_alloc) ? reinterpret_cast<char *>(_mem.alloc) : reinterpret_cast<char *>(_mem.local);