Flutter Engine
The Flutter Engine
regexp_assembler.cc
Go to the documentation of this file.
1// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
6
7#include "unicode/uchar.h"
8
9#include "platform/unicode.h"
10
11#include "vm/flags.h"
12#include "vm/regexp.h"
13#include "vm/runtime_entry.h"
14#include "vm/unibrow-inl.h"
15
16namespace dart {
17
18void PrintUtf16(uint16_t c) {
19 const char* format = (0x20 <= c && c <= 0x7F) ? "%c"
20 : (c <= 0xff) ? "\\x%02x"
21 : "\\u%04x";
23}
24
25uword /*BoolPtr*/ CaseInsensitiveCompareUCS2(uword /*StringPtr*/ str_raw,
26 uword /*SmiPtr*/ lhs_index_raw,
27 uword /*SmiPtr*/ rhs_index_raw,
28 uword /*SmiPtr*/ length_raw) {
29 const String& str = String::Handle(static_cast<StringPtr>(str_raw));
30 const Smi& lhs_index = Smi::Handle(static_cast<SmiPtr>(lhs_index_raw));
31 const Smi& rhs_index = Smi::Handle(static_cast<SmiPtr>(rhs_index_raw));
32 const Smi& length = Smi::Handle(static_cast<SmiPtr>(length_raw));
33
34 // TODO(zerny): Optimize as single instance. V8 has this as an
35 // isolate member.
37
38 for (intptr_t i = 0; i < length.Value(); i++) {
39 int32_t c1 = str.CharAt(lhs_index.Value() + i);
40 int32_t c2 = str.CharAt(rhs_index.Value() + i);
41 if (c1 != c2) {
42 int32_t s1[1] = {c1};
43 canonicalize.get(c1, '\0', s1);
44 if (s1[0] != c2) {
45 int32_t s2[1] = {c2};
46 canonicalize.get(c2, '\0', s2);
47 if (s1[0] != s2[0]) {
48 return static_cast<uword>(Bool::False().ptr());
49 }
50 }
51 }
52 }
53 return static_cast<uword>(Bool::True().ptr());
54}
55
56uword /*BoolPtr*/ CaseInsensitiveCompareUTF16(uword /*StringPtr*/ str_raw,
57 uword /*SmiPtr*/ lhs_index_raw,
58 uword /*SmiPtr*/ rhs_index_raw,
59 uword /*SmiPtr*/ length_raw) {
60 const String& str = String::Handle(static_cast<StringPtr>(str_raw));
61 const Smi& lhs_index = Smi::Handle(static_cast<SmiPtr>(lhs_index_raw));
62 const Smi& rhs_index = Smi::Handle(static_cast<SmiPtr>(rhs_index_raw));
63 const Smi& length = Smi::Handle(static_cast<SmiPtr>(length_raw));
64
65 for (intptr_t i = 0; i < length.Value(); i++) {
66 int32_t c1 = str.CharAt(lhs_index.Value() + i);
67 int32_t c2 = str.CharAt(rhs_index.Value() + i);
68 if (Utf16::IsLeadSurrogate(c1)) {
69 // Non-BMP characters do not have case-equivalents in the BMP.
70 // Both have to be non-BMP for them to be able to match.
72 return static_cast<uword>(Bool::False().ptr());
73 if (i + 1 < length.Value()) {
74 uint16_t c1t = str.CharAt(lhs_index.Value() + i + 1);
75 uint16_t c2t = str.CharAt(rhs_index.Value() + i + 1);
77 c1 = Utf16::Decode(c1, c1t);
78 c2 = Utf16::Decode(c2, c2t);
79 i++;
80 }
81 }
82 }
83 c1 = u_foldCase(c1, U_FOLD_CASE_DEFAULT);
84 c2 = u_foldCase(c2, U_FOLD_CASE_DEFAULT);
85 if (c1 != c2) return static_cast<uword>(Bool::False().ptr());
86 }
87 return static_cast<uword>(Bool::True().ptr());
88}
89
91 /*argument_count=*/4,
92 /*is_float=*/false,
94
96 /*argument_count=*/4,
97 /*is_float=*/false,
99
101#if !defined(DART_PRECOMPILED_RUNTIME)
102 if (!FLAG_interpret_irregexp) {
103 // Only needed by the compiled IR backend.
104 block_ =
105 new JoinEntryInstr(-1, -1, CompilerState::Current().GetNextDeoptId());
106 }
107#endif
108}
109
111 : slow_safe_compiler_(false), global_mode_(NOT_GLOBAL), zone_(zone) {}
112
114
116 BlockLabel* on_failure) {
118 // Check that current character is not a trail surrogate.
119 LoadCurrentCharacter(cp_offset, &ok);
122 // Check that previous character is not a lead surrogate.
123 LoadCurrentCharacter(cp_offset - 1, &ok);
125 on_failure);
126 BindBlock(&ok);
127}
128
129} // namespace dart
static bool ok(int result)
Convenience wrapper around a BlockEntryInstr pointer.
static const Bool & False()
Definition: object.h:10799
static const Bool & True()
Definition: object.h:10797
static CompilerState & Current()
static void static void PrintErr(const char *format,...) PRINTF_ATTRIBUTE(1
ObjectPtr ptr() const
Definition: object.h:332
static Object & Handle()
Definition: object.h:407
virtual void CheckCharacterInRange(uint16_t from, uint16_t to, BlockLabel *on_in_range)=0
virtual void CheckCharacterNotInRange(uint16_t from, uint16_t to, BlockLabel *on_not_in_range)=0
virtual void BindBlock(BlockLabel *label)=0
void CheckNotInSurrogatePair(intptr_t cp_offset, BlockLabel *on_failure)
virtual void LoadCurrentCharacter(intptr_t cp_offset, BlockLabel *on_end_of_input, bool check_bounds=true, intptr_t characters=1)=0
intptr_t Value() const
Definition: object.h:9990
uint16_t CharAt(intptr_t index) const
Definition: object.h:10259
static constexpr int32_t kLeadSurrogateStart
Definition: unicode.h:159
static int32_t Decode(uint16_t lead, uint16_t trail)
Definition: unicode.h:151
static constexpr int32_t kTrailSurrogateStart
Definition: unicode.h:161
static bool IsLeadSurrogate(uint32_t ch)
Definition: unicode.h:126
static bool IsTrailSurrogate(uint32_t ch)
Definition: unicode.h:131
static constexpr int32_t kTrailSurrogateEnd
Definition: unicode.h:162
static constexpr int32_t kLeadSurrogateEnd
Definition: unicode.h:160
intptr_t get(int32_t c, int32_t n, int32_t *result)
Definition: unibrow-inl.h:15
uint32_t uint32_t * format
size_t length
Definition: dart_vm.cc:33
uword CaseInsensitiveCompareUTF16(uword str_raw, uword lhs_index_raw, uword rhs_index_raw, uword length_raw)
void PrintUtf16(uint16_t c)
uintptr_t uword
Definition: globals.h:501
DEFINE_RAW_LEAF_RUNTIME_ENTRY(CaseInsensitiveCompareUCS2, 4, false, CaseInsensitiveCompareUCS2)
uword CaseInsensitiveCompareUCS2(uword str_raw, uword lhs_index_raw, uword rhs_index_raw, uword length_raw)