Index: runtime/vm/regexp_assembler.cc |
diff --git a/runtime/vm/regexp_assembler.cc b/runtime/vm/regexp_assembler.cc |
index fa666ae3e55f77a89a0fefa3d1117b628693ded0..5784506aa7d52aabb89011b4fc28a0a7ff7db189 100644 |
--- a/runtime/vm/regexp_assembler.cc |
+++ b/runtime/vm/regexp_assembler.cc |
@@ -613,6 +613,32 @@ Value* IRRegExpMacroAssembler::BindLoadLocal(const LocalVariable& local) { |
} |
+Value* IRRegExpMacroAssembler::BindUntaggedExternalString( |
+ const LocalVariable& str) { |
+ Value* str_val = BindLoadLocal(str); |
+ if (!RawObject::IsExternalStringClassId(specialization_cid_)) { |
+ return str_val; |
+ } |
+ // The data of an external string is stored through two indirections. |
+ intptr_t external_offset; |
+ intptr_t data_offset; |
+ if (specialization_cid_ == kExternalOneByteStringCid) { |
+ external_offset = RawExternalOneByteString::data_offset(); |
+ data_offset = RawExternalOneByteString::ExternalData::data_offset(); |
+ } else if (specialization_cid_ == kExternalTwoByteStringCid) { |
+ external_offset = RawExternalTwoByteString::data_offset(); |
+ data_offset = RawExternalTwoByteString::ExternalData::data_offset(); |
+ } else { |
+ UNREACHABLE(); |
+ } |
+ Value* external_val = |
+ Bind(new(I) LoadUntaggedInstr(str_val, external_offset)); |
+ Value* data_val = |
+ Bind(new(I) LoadUntaggedInstr(external_val, data_offset)); |
+ return data_val; |
+} |
+ |
+ |
// In some cases, the V8 irregexp engine generates unreachable code by emitting |
// a jmp not followed by a bind. We cannot do the same, since it is impossible |
// to append to a block following a jmp. In such cases, assume that we are doing |
@@ -1766,7 +1792,7 @@ void IRRegExpMacroAssembler::LoadCurrentCharacterUnchecked( |
} |
// Bind the pattern as the load receiver. |
- Value* pattern = BindLoadLocal(*string_param_); |
+ Value* pattern = BindUntaggedExternalString(*string_param_); |
// Calculate the addressed string index as: |
// cp_offset + current_position_ + string_param_length_ |
@@ -1789,7 +1815,7 @@ void IRRegExpMacroAssembler::LoadCurrentCharacterUnchecked( |
Value* IRRegExpMacroAssembler::CharacterAt(Definition* index) { |
- Value* pattern_val = BindLoadLocal(*string_param_); |
+ Value* pattern_val = BindUntaggedExternalString(*string_param_); |
Value* index_val = Bind(index); |
return LoadCodeUnitsAt(pattern_val, index_val, 1); |
} |