Index: runtime/vm/kernel_to_il.cc |
diff --git a/runtime/vm/kernel_to_il.cc b/runtime/vm/kernel_to_il.cc |
index 91a4f82656902e7560e2a80a02969f6faf3ae1c2..a0272e9293d83aa120e665481a1c9bf9f1d80402 100644 |
--- a/runtime/vm/kernel_to_il.cc |
+++ b/runtime/vm/kernel_to_il.cc |
@@ -136,13 +136,26 @@ uint8_t TranslationHelper::CharacterAt(StringIndex string_index, |
return string_data_.GetUint8(StringOffset(string_index) + index); |
} |
+uint8_t* TranslationHelper::StringBuffer(StringIndex string_index) const { |
+ // Though this implementation appears like it could be replaced by |
+ // string_data_.DataAddr(StringOffset(string_index)), it can't quite. If the |
+ // last string in the string table is a zero length string, then the latter |
+ // expression will try to return the address that is one past the backing |
+ // store of the string_data_ table. Though this is safe in C++ as long as the |
+ // address is not dereferenced, it will trigger the assert in |
+ // TypedData::DataAddr. |
+ ASSERT(Thread::Current()->no_safepoint_scope_depth() > 0); |
+ return reinterpret_cast<uint8_t*>(string_data_.DataAddr(0)) + |
+ StringOffset(string_index); |
+} |
+ |
bool TranslationHelper::StringEquals(StringIndex string_index, |
const char* other) { |
- NoSafepointScope no_safepoint; |
intptr_t length = strlen(other); |
- return (length == StringSize(string_index)) && |
- (memcmp(string_data_.DataAddr(StringOffset(string_index)), other, |
- length) == 0); |
+ if (length != StringSize(string_index)) return false; |
+ |
+ NoSafepointScope no_safepoint; |
+ return memcmp(StringBuffer(string_index), other, length) == 0; |
} |
NameIndex TranslationHelper::CanonicalNameParent(NameIndex name) { |
@@ -311,7 +324,7 @@ String& TranslationHelper::DartString(StringIndex string_index, |
uint8_t* buffer = Z->Alloc<uint8_t>(length); |
{ |
NoSafepointScope no_safepoint; |
- memmove(buffer, string_data_.DataAddr(StringOffset(string_index)), length); |
+ memmove(buffer, StringBuffer(string_index), length); |
} |
return String::ZoneHandle(Z, String::FromUTF8(buffer, length, space)); |
} |
@@ -331,7 +344,7 @@ String& TranslationHelper::DartSymbol(StringIndex string_index) const { |
uint8_t* buffer = Z->Alloc<uint8_t>(length); |
{ |
NoSafepointScope no_safepoint; |
- memmove(buffer, string_data_.DataAddr(StringOffset(string_index)), length); |
+ memmove(buffer, StringBuffer(string_index), length); |
} |
return String::ZoneHandle(Z, Symbols::FromUTF8(thread_, buffer, length)); |
} |
@@ -388,7 +401,7 @@ const String& TranslationHelper::DartSetterName(NameIndex parent, |
uint8_t* buffer = Z->Alloc<uint8_t>(size); |
{ |
NoSafepointScope no_safepoint; |
- memmove(buffer, string_data_.DataAddr(StringOffset(setter)), size); |
+ memmove(buffer, StringBuffer(setter), size); |
} |
String& name = |
String::ZoneHandle(Z, String::FromUTF8(buffer, size, allocation_space_)); |