Index: runtime/vm/regexp_assembler.cc |
diff --git a/runtime/vm/regexp_assembler.cc b/runtime/vm/regexp_assembler.cc |
index 588fa8702f1797f5aa5893a80530d4903be0b401..e6d0f7a0297b6ac4ca91f38724df1554a9b928d5 100644 |
--- a/runtime/vm/regexp_assembler.cc |
+++ b/runtime/vm/regexp_assembler.cc |
@@ -6,15 +6,64 @@ |
#include "vm/flags.h" |
#include "vm/regexp.h" |
+#include "vm/unibrow-inl.h" |
namespace dart { |
+void PrintUtf16(uint16_t c) { |
+ const char* format = |
+ (0x20 <= c && c <= 0x7F) ? "%c" : (c <= 0xff) ? "\\x%02x" : "\\u%04x"; |
+ OS::Print(format, c); |
+} |
+ |
+ |
+static RawBool* CaseInsensitiveCompareUC16(RawString* str_raw, |
+ RawSmi* lhs_index_raw, |
+ RawSmi* rhs_index_raw, |
+ RawSmi* length_raw) { |
+ const String& str = String::Handle(str_raw); |
+ const Smi& lhs_index = Smi::Handle(lhs_index_raw); |
+ const Smi& rhs_index = Smi::Handle(rhs_index_raw); |
+ const Smi& length = Smi::Handle(length_raw); |
+ |
+ // TODO(zerny): Optimize as single instance. V8 has this as an |
+ // isolate member. |
+ unibrow::Mapping<unibrow::Ecma262Canonicalize> canonicalize; |
+ |
+ for (intptr_t i = 0; i < length.Value(); i++) { |
+ int32_t c1 = str.CharAt(lhs_index.Value() + i); |
+ int32_t c2 = str.CharAt(rhs_index.Value() + i); |
+ if (c1 != c2) { |
+ int32_t s1[1] = {c1}; |
+ canonicalize.get(c1, '\0', s1); |
+ if (s1[0] != c2) { |
+ int32_t s2[1] = {c2}; |
+ canonicalize.get(c2, '\0', s2); |
+ if (s1[0] != s2[0]) { |
+ return Bool::False().raw(); |
+ } |
+ } |
+ } |
+ } |
+ return Bool::True().raw(); |
+} |
+ |
+ |
+DEFINE_RAW_LEAF_RUNTIME_ENTRY( |
+ CaseInsensitiveCompareUC16, |
+ 4, |
+ false /* is_float */, |
+ reinterpret_cast<RuntimeFunction>(&CaseInsensitiveCompareUC16)); |
+ |
+ |
BlockLabel::BlockLabel() |
: block_(NULL), is_bound_(false), is_linked_(false), pos_(-1) { |
+#if !defined(DART_PRECOMPILED_RUNTIME) |
if (!FLAG_interpret_irregexp) { |
// Only needed by the compiled IR backend. |
block_ = new JoinEntryInstr(-1, -1, Thread::Current()->GetNextDeoptId()); |
} |
+#endif |
} |