4
4
5
5
#include " platform/assert.h"
6
6
#include " vm/bootstrap_natives.h"
7
+ #include " vm/canonical_tables.h"
7
8
#include " vm/exceptions.h"
8
9
#include " vm/native_entry.h"
9
10
#include " vm/object.h"
11
+ #include " vm/object_store.h"
10
12
#include " vm/regexp_assembler_bytecode.h"
11
13
#include " vm/regexp_parser.h"
14
+ #include " vm/reusable_handles.h"
12
15
#include " vm/thread.h"
13
16
14
17
#if !defined(DART_PRECOMPILED_RUNTIME)
@@ -21,34 +24,54 @@ DEFINE_NATIVE_ENTRY(RegExp_factory, 0, 6) {
21
24
ASSERT (
22
25
TypeArguments::CheckedHandle (zone, arguments->NativeArgAt (0 )).IsNull ());
23
26
GET_NON_NULL_NATIVE_ARGUMENT (String, pattern, arguments->NativeArgAt (1 ));
24
- GET_NON_NULL_NATIVE_ARGUMENT (Instance, handle_multi_line,
25
- arguments->NativeArgAt (2 ));
26
- GET_NON_NULL_NATIVE_ARGUMENT (Instance, handle_case_sensitive,
27
- arguments->NativeArgAt (3 ));
28
- GET_NON_NULL_NATIVE_ARGUMENT (Instance, handle_unicode,
29
- arguments->NativeArgAt (4 ));
30
- GET_NON_NULL_NATIVE_ARGUMENT (Instance, handle_dot_all,
31
- arguments->NativeArgAt (5 ));
32
- bool ignore_case = handle_case_sensitive.ptr () != Bool::True ().ptr ();
33
- bool multi_line = handle_multi_line.ptr () == Bool::True ().ptr ();
34
- bool unicode = handle_unicode.ptr () == Bool::True ().ptr ();
35
- bool dot_all = handle_dot_all.ptr () == Bool::True ().ptr ();
36
27
37
- RegExpFlags flags;
28
+ bool multi_line = arguments->NativeArgAt (2 ) == Bool::True ().ptr ();
29
+ bool ignore_case = arguments->NativeArgAt (3 ) != Bool::True ().ptr ();
30
+ bool unicode = arguments->NativeArgAt (4 ) == Bool::True ().ptr ();
31
+ bool dot_all = arguments->NativeArgAt (5 ) == Bool::True ().ptr ();
38
32
33
+ RegExpFlags flags;
34
+ flags.SetGlobal (); // All dart regexps are global.
39
35
if (ignore_case) flags.SetIgnoreCase ();
40
36
if (multi_line) flags.SetMultiLine ();
41
37
if (unicode) flags.SetUnicode ();
42
38
if (dot_all) flags.SetDotAll ();
43
39
40
+ RegExpKey lookup_key (pattern, flags);
41
+ RegExp& regexp = RegExp::Handle (thread->zone ());
42
+ {
43
+ REUSABLE_OBJECT_HANDLESCOPE (thread);
44
+ REUSABLE_SMI_HANDLESCOPE (thread);
45
+ REUSABLE_WEAK_ARRAY_HANDLESCOPE (thread);
46
+ Object& key = thread->ObjectHandle ();
47
+ Smi& value = thread->SmiHandle ();
48
+ WeakArray& data = thread->WeakArrayHandle ();
49
+ data = thread->isolate_group ()->object_store ()->regexp_table ();
50
+ CanonicalRegExpSet table (&key, &value, &data);
51
+ regexp ^= table.GetOrNull (lookup_key);
52
+ table.Release ();
53
+ if (!regexp.IsNull ()) {
54
+ return regexp.ptr ();
55
+ }
56
+ }
57
+
44
58
// Parse the pattern once in order to throw any format exceptions within
45
59
// the factory constructor. It is parsed again upon compilation.
46
60
RegExpCompileData compileData;
47
61
// Throws an exception on parsing failure.
48
62
RegExpParser::ParseRegExp (pattern, flags, &compileData);
49
63
50
- // Create a RegExp object containing only the initial parameters.
51
- return RegExpEngine::CreateRegExp (thread, pattern, flags);
64
+ {
65
+ SafepointMutexLocker ml (thread->isolate_group ()->symbols_mutex ());
66
+ CanonicalRegExpSet table (
67
+ thread->zone (),
68
+ thread->isolate_group ()->object_store ()->regexp_table ());
69
+ regexp ^= table.InsertNewOrGet (lookup_key);
70
+ thread->isolate_group ()->object_store ()->set_regexp_table (table.Release ());
71
+ }
72
+
73
+ ASSERT (regexp.flags () == flags);
74
+ return regexp.ptr ();
52
75
}
53
76
54
77
DEFINE_NATIVE_ENTRY (RegExp_getPattern, 0 , 1 ) {
0 commit comments