OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS 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 | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/regexp_assembler_ir.h" | 5 #include "vm/regexp_assembler_ir.h" |
6 | 6 |
7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
8 #include "vm/compiler.h" | 8 #include "vm/compiler.h" |
9 #include "vm/dart_entry.h" | 9 #include "vm/dart_entry.h" |
10 #include "vm/flow_graph_builder.h" | 10 #include "vm/flow_graph_builder.h" |
11 #include "vm/il_printer.h" | 11 #include "vm/il_printer.h" |
12 #include "vm/object_store.h" | 12 #include "vm/object_store.h" |
13 #include "vm/regexp.h" | 13 #include "vm/regexp.h" |
14 #include "vm/resolver.h" | 14 #include "vm/resolver.h" |
15 #include "vm/runtime_entry.h" | 15 #include "vm/runtime_entry.h" |
16 #include "vm/stack_frame.h" | 16 #include "vm/stack_frame.h" |
17 #include "vm/unibrow-inl.h" | |
18 #include "vm/unicode.h" | 17 #include "vm/unicode.h" |
19 | 18 |
20 #define Z zone() | 19 #define Z zone() |
21 | 20 |
22 // Debugging output macros. TAG() is called at the head of each interesting | 21 // Debugging output macros. TAG() is called at the head of each interesting |
23 // function and prints its name during execution if irregexp tracing is enabled. | 22 // function and prints its name during execution if irregexp tracing is enabled. |
24 #define TAG() \ | 23 #define TAG() \ |
25 if (FLAG_trace_irregexp) { \ | 24 if (FLAG_trace_irregexp) { \ |
26 TAG_(); \ | 25 TAG_(); \ |
27 } | 26 } |
28 #define TAG_() \ | 27 #define TAG_() \ |
29 Print(PushArgument(Bind(new (Z) ConstantInstr(String::ZoneHandle( \ | 28 Print(PushArgument(Bind(new (Z) ConstantInstr(String::ZoneHandle( \ |
30 Z, String::Concat(String::Handle(String::New("TAG: ")), \ | 29 Z, String::Concat(String::Handle(String::New("TAG: ")), \ |
31 String::Handle(String::New(__FUNCTION__)), \ | 30 String::Handle(String::New(__FUNCTION__)), \ |
32 Heap::kOld)))))); | 31 Heap::kOld)))))); |
33 | 32 |
34 #define PRINT(arg) \ | 33 #define PRINT(arg) \ |
35 if (FLAG_trace_irregexp) { \ | 34 if (FLAG_trace_irregexp) { \ |
36 Print(arg); \ | 35 Print(arg); \ |
37 } | 36 } |
38 | 37 |
39 namespace dart { | 38 namespace dart { |
40 | 39 |
41 DEFINE_FLAG(bool, trace_irregexp, false, "Trace irregexps"); | |
42 | |
43 | |
44 static const intptr_t kInvalidTryIndex = CatchClauseNode::kInvalidTryIndex; | 40 static const intptr_t kInvalidTryIndex = CatchClauseNode::kInvalidTryIndex; |
45 static const intptr_t kMinStackSize = 512; | 41 static const intptr_t kMinStackSize = 512; |
46 | 42 |
47 | 43 |
48 void PrintUtf16(uint16_t c) { | |
49 const char* format = | |
50 (0x20 <= c && c <= 0x7F) ? "%c" : (c <= 0xff) ? "\\x%02x" : "\\u%04x"; | |
51 OS::Print(format, c); | |
52 } | |
53 | |
54 | |
55 /* | 44 /* |
56 * This assembler uses the following main local variables: | 45 * This assembler uses the following main local variables: |
57 * - stack_: A pointer to a growable list which we use as an all-purpose stack | 46 * - stack_: A pointer to a growable list which we use as an all-purpose stack |
58 * storing backtracking offsets, positions & stored register values. | 47 * storing backtracking offsets, positions & stored register values. |
59 * - current_character_: Stores the currently loaded characters (possibly more | 48 * - current_character_: Stores the currently loaded characters (possibly more |
60 * than one). | 49 * than one). |
61 * - current_position_: The current position within the string, stored as a | 50 * - current_position_: The current position within the string, stored as a |
62 * negative offset from the end of the string (i.e. the | 51 * negative offset from the end of the string (i.e. the |
63 * position corresponding to str[0] is -str.length). | 52 * position corresponding to str[0] is -str.length). |
64 * Note that current_position_ is *not* byte-based, unlike | 53 * Note that current_position_ is *not* byte-based, unlike |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 | 337 |
349 if (retval.IsNull()) { | 338 if (retval.IsNull()) { |
350 return Array::null(); | 339 return Array::null(); |
351 } | 340 } |
352 | 341 |
353 ASSERT(retval.IsArray()); | 342 ASSERT(retval.IsArray()); |
354 return Array::Cast(retval).raw(); | 343 return Array::Cast(retval).raw(); |
355 } | 344 } |
356 | 345 |
357 | 346 |
358 static RawBool* CaseInsensitiveCompareUC16(RawString* str_raw, | |
359 RawSmi* lhs_index_raw, | |
360 RawSmi* rhs_index_raw, | |
361 RawSmi* length_raw) { | |
362 const String& str = String::Handle(str_raw); | |
363 const Smi& lhs_index = Smi::Handle(lhs_index_raw); | |
364 const Smi& rhs_index = Smi::Handle(rhs_index_raw); | |
365 const Smi& length = Smi::Handle(length_raw); | |
366 | |
367 // TODO(zerny): Optimize as single instance. V8 has this as an | |
368 // isolate member. | |
369 unibrow::Mapping<unibrow::Ecma262Canonicalize> canonicalize; | |
370 | |
371 for (intptr_t i = 0; i < length.Value(); i++) { | |
372 int32_t c1 = str.CharAt(lhs_index.Value() + i); | |
373 int32_t c2 = str.CharAt(rhs_index.Value() + i); | |
374 if (c1 != c2) { | |
375 int32_t s1[1] = {c1}; | |
376 canonicalize.get(c1, '\0', s1); | |
377 if (s1[0] != c2) { | |
378 int32_t s2[1] = {c2}; | |
379 canonicalize.get(c2, '\0', s2); | |
380 if (s1[0] != s2[0]) { | |
381 return Bool::False().raw(); | |
382 } | |
383 } | |
384 } | |
385 } | |
386 return Bool::True().raw(); | |
387 } | |
388 | |
389 | |
390 DEFINE_RAW_LEAF_RUNTIME_ENTRY( | |
391 CaseInsensitiveCompareUC16, | |
392 4, | |
393 false /* is_float */, | |
394 reinterpret_cast<RuntimeFunction>(&CaseInsensitiveCompareUC16)); | |
395 | |
396 | |
397 LocalVariable* IRRegExpMacroAssembler::Parameter(const String& name, | 347 LocalVariable* IRRegExpMacroAssembler::Parameter(const String& name, |
398 intptr_t index) const { | 348 intptr_t index) const { |
399 LocalVariable* local = | 349 LocalVariable* local = |
400 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, | 350 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
401 name, Object::dynamic_type()); | 351 name, Object::dynamic_type()); |
402 | 352 |
403 intptr_t param_frame_index = kParamEndSlotFromFp + kParamCount - index; | 353 intptr_t param_frame_index = kParamEndSlotFromFp + kParamCount - index; |
404 local->set_index(param_frame_index); | 354 local->set_index(param_frame_index); |
405 | 355 |
406 return local; | 356 return local; |
(...skipping 1468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1875 | 1825 |
1876 return Bind(new (Z) LoadCodeUnitsInstr(pattern_val, index_val, characters, | 1826 return Bind(new (Z) LoadCodeUnitsInstr(pattern_val, index_val, characters, |
1877 specialization_cid_, | 1827 specialization_cid_, |
1878 TokenPosition::kNoSource)); | 1828 TokenPosition::kNoSource)); |
1879 } | 1829 } |
1880 | 1830 |
1881 | 1831 |
1882 #undef __ | 1832 #undef __ |
1883 | 1833 |
1884 } // namespace dart | 1834 } // namespace dart |
OLD | NEW |