Flutter Engine
The Flutter Engine
regexp.cc
Go to the documentation of this file.
1// Copyright (c) 2012, 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
5#include "platform/assert.h"
8#include "vm/exceptions.h"
9#include "vm/native_entry.h"
10#include "vm/object.h"
11#include "vm/object_store.h"
13#include "vm/regexp_parser.h"
14#include "vm/reusable_handles.h"
15#include "vm/symbols.h"
16#include "vm/thread.h"
17
18#if !defined(DART_PRECOMPILED_RUNTIME)
20#endif // !defined(DART_PRECOMPILED_RUNTIME)
21
22namespace dart {
23
24DEFINE_NATIVE_ENTRY(RegExp_factory, 0, 6) {
25 ASSERT(
26 TypeArguments::CheckedHandle(zone, arguments->NativeArgAt(0)).IsNull());
27 GET_NON_NULL_NATIVE_ARGUMENT(String, pattern, arguments->NativeArgAt(1));
28
29 bool multi_line = arguments->NativeArgAt(2) == Bool::True().ptr();
30 bool ignore_case = arguments->NativeArgAt(3) != Bool::True().ptr();
31 bool unicode = arguments->NativeArgAt(4) == Bool::True().ptr();
32 bool dot_all = arguments->NativeArgAt(5) == Bool::True().ptr();
33
35 flags.SetGlobal(); // All dart regexps are global.
36 if (ignore_case) flags.SetIgnoreCase();
37 if (multi_line) flags.SetMultiLine();
38 if (unicode) flags.SetUnicode();
39 if (dot_all) flags.SetDotAll();
40
41 RegExpKey lookup_key(pattern, flags);
42 RegExp& regexp = RegExp::Handle(thread->zone());
43 {
47 Object& key = thread->ObjectHandle();
48 Smi& value = thread->SmiHandle();
49 WeakArray& data = thread->WeakArrayHandle();
50 data = thread->isolate_group()->object_store()->regexp_table();
52 regexp ^= table.GetOrNull(lookup_key);
53 table.Release();
54 if (!regexp.IsNull()) {
55 return regexp.ptr();
56 }
57 }
58
59 // Parse the pattern once in order to throw any format exceptions within
60 // the factory constructor. It is parsed again upon compilation.
61 RegExpCompileData compileData;
62 // Throws an exception on parsing failure.
63 RegExpParser::ParseRegExp(pattern, flags, &compileData);
64
65 {
66 RegExpKey lookup_symbol_key(String::Handle(Symbols::New(thread, pattern)),
67 flags);
68 SafepointMutexLocker ml(thread->isolate_group()->symbols_mutex());
70 thread->zone(),
71 thread->isolate_group()->object_store()->regexp_table());
72 regexp ^= table.InsertNewOrGet(lookup_symbol_key);
73 thread->isolate_group()->object_store()->set_regexp_table(table.Release());
74 }
75
76 ASSERT(regexp.flags() == flags);
77 return regexp.ptr();
78}
79
80DEFINE_NATIVE_ENTRY(RegExp_getPattern, 0, 1) {
81 const RegExp& regexp = RegExp::CheckedHandle(zone, arguments->NativeArgAt(0));
82 ASSERT(!regexp.IsNull());
83 return regexp.pattern();
84}
85
86DEFINE_NATIVE_ENTRY(RegExp_getIsMultiLine, 0, 1) {
87 const RegExp& regexp = RegExp::CheckedHandle(zone, arguments->NativeArgAt(0));
88 ASSERT(!regexp.IsNull());
89 return Bool::Get(regexp.flags().IsMultiLine()).ptr();
90}
91
92DEFINE_NATIVE_ENTRY(RegExp_getIsUnicode, 0, 1) {
93 const RegExp& regexp = RegExp::CheckedHandle(zone, arguments->NativeArgAt(0));
94 ASSERT(!regexp.IsNull());
95 return Bool::Get(regexp.flags().IsUnicode()).ptr();
96}
97
98DEFINE_NATIVE_ENTRY(RegExp_getIsDotAll, 0, 1) {
99 const RegExp& regexp = RegExp::CheckedHandle(zone, arguments->NativeArgAt(0));
100 ASSERT(!regexp.IsNull());
101 return Bool::Get(regexp.flags().IsDotAll()).ptr();
102}
103
104DEFINE_NATIVE_ENTRY(RegExp_getIsCaseSensitive, 0, 1) {
105 const RegExp& regexp = RegExp::CheckedHandle(zone, arguments->NativeArgAt(0));
106 ASSERT(!regexp.IsNull());
107 return Bool::Get(!regexp.flags().IgnoreCase()).ptr();
108}
109
110DEFINE_NATIVE_ENTRY(RegExp_getGroupCount, 0, 1) {
111 const RegExp& regexp = RegExp::CheckedHandle(zone, arguments->NativeArgAt(0));
112 ASSERT(!regexp.IsNull());
113 if (regexp.is_initialized()) {
114 return Smi::New(regexp.num_bracket_expressions());
115 }
116 const String& pattern = String::Handle(regexp.pattern());
117 const String& errmsg =
118 String::Handle(String::New("Regular expression is not initialized yet."));
119 const String& message = String::Handle(String::Concat(errmsg, pattern));
120 const Array& args = Array::Handle(Array::New(1));
121 args.SetAt(0, message);
123 return Object::null();
124}
125
126DEFINE_NATIVE_ENTRY(RegExp_getGroupNameMap, 0, 1) {
127 const RegExp& regexp = RegExp::CheckedHandle(zone, arguments->NativeArgAt(0));
128 ASSERT(!regexp.IsNull());
129 if (regexp.is_initialized()) {
130 return regexp.capture_name_map();
131 }
132 const String& pattern = String::Handle(regexp.pattern());
133 const String& errmsg = String::Handle(
134 String::New("Regular expression is not initialized yet. "));
135 const String& message = String::Handle(String::Concat(errmsg, pattern));
136 const Array& args = Array::Handle(Array::New(1));
137 args.SetAt(0, message);
139 return Object::null();
140}
141
143 NativeArguments* arguments,
144 bool sticky) {
145 const RegExp& regexp = RegExp::CheckedHandle(zone, arguments->NativeArgAt(0));
146 ASSERT(!regexp.IsNull());
147 GET_NON_NULL_NATIVE_ARGUMENT(String, subject, arguments->NativeArgAt(1));
148 GET_NON_NULL_NATIVE_ARGUMENT(Smi, start_index, arguments->NativeArgAt(2));
149
150 // Both generated code and the interpreter are using 32-bit registers and
151 // 32-bit backtracking stack so they can't work with strings which are
152 // larger than that. Validate these assumptions before running the regexp.
153 if (!Utils::IsInt(32, subject.Length())) {
155 Integer::Handle(Integer::New(subject.Length())),
156 0, kMaxInt32);
157 }
158 if (!Utils::IsInt(32, start_index.Value())) {
159 Exceptions::ThrowRangeError("start_index", Integer::Cast(start_index),
161 }
162
163#if !defined(DART_PRECOMPILED_RUNTIME)
164 if (!FLAG_interpret_irregexp) {
165 return IRRegExpMacroAssembler::Execute(regexp, subject, start_index,
166 /*sticky=*/sticky, zone);
167 }
168#endif
169 return BytecodeRegExpMacroAssembler::Interpret(regexp, subject, start_index,
170 /*sticky=*/sticky, zone);
171}
172
173DEFINE_NATIVE_ENTRY(RegExp_ExecuteMatch, 0, 3) {
174 // This function is intrinsified. See Intrinsifier::RegExp_ExecuteMatch.
175 return ExecuteMatch(zone, arguments, /*sticky=*/false);
176}
177
178DEFINE_NATIVE_ENTRY(RegExp_ExecuteMatchSticky, 0, 3) {
179 // This function is intrinsified. See Intrinsifier::RegExp_ExecuteMatchSticky.
180 return ExecuteMatch(zone, arguments, /*sticky=*/true);
181}
182
183} // namespace dart
SI F table(const skcms_Curve *curve, F v)
static ArrayPtr New(intptr_t len, Heap::Space space=Heap::kNew)
Definition: object.h:10959
static const Bool & Get(bool value)
Definition: object.h:10801
static const Bool & True()
Definition: object.h:10797
static ObjectPtr Interpret(const RegExp &regexp, const String &str, const Smi &start_index, bool is_sticky, Zone *zone)
static DART_NORETURN void ThrowByType(ExceptionType type, const Array &arguments)
Definition: exceptions.cc:1052
static DART_NORETURN void ThrowRangeError(const char *argument_name, const Integer &argument_value, intptr_t expected_from, intptr_t expected_to)
Definition: exceptions.cc:1094
static ArrayPtr Execute(const RegExp &regexp, const String &input, const Smi &start_offset, bool sticky, Zone *zone)
static IntegerPtr New(const String &str, Heap::Space space=Heap::kNew)
Definition: object.cc:22984
ObjectPtr NativeArgAt(int index) const
static ObjectPtr null()
Definition: object.h:433
ObjectPtr ptr() const
Definition: object.h:332
bool IsNull() const
Definition: object.h:363
static Object & Handle()
Definition: object.h:407
bool IsMultiLine() const
Definition: object.h:12724
bool IsUnicode() const
Definition: object.h:12725
bool IsDotAll() const
Definition: object.h:12726
bool IgnoreCase() const
Definition: object.h:12723
static void ParseRegExp(const String &input, RegExpFlags regexp_flags, RegExpCompileData *result)
StringPtr pattern() const
Definition: object.h:12797
bool is_initialized() const
Definition: object.h:12787
ArrayPtr capture_name_map() const
Definition: object.h:12801
intptr_t num_bracket_expressions() const
Definition: object.h:12798
RegExpFlags flags() const
Definition: object.h:12891
static SmiPtr New(intptr_t value)
Definition: object.h:10006
static StringPtr New(const char *cstr, Heap::Space space=Heap::kNew)
Definition: object.cc:23698
static StringPtr Concat(const String &str1, const String &str2, Heap::Space space=Heap::kNew)
Definition: object.cc:24037
static StringPtr New(Thread *thread, const char *cstr)
Definition: symbols.h:723
static bool IsInt(intptr_t N, T value)
Definition: utils.h:313
#define ASSERT(E)
FlutterSemanticsFlag flags
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
uint8_t value
Win32Message message
Definition: dart_vm.cc:33
constexpr int32_t kMinInt32
Definition: globals.h:482
static ObjectPtr ExecuteMatch(Zone *zone, NativeArguments *arguments, bool sticky)
Definition: regexp.cc:142
constexpr int32_t kMaxInt32
Definition: globals.h:483
DEFINE_NATIVE_ENTRY(List_allocate, 0, 2)
Definition: array.cc:13
static int8_t data[kExtLength]
#define GET_NON_NULL_NATIVE_ARGUMENT(type, name, value)
Definition: native_entry.h:74
#define REUSABLE_SMI_HANDLESCOPE(thread)
#define REUSABLE_WEAK_ARRAY_HANDLESCOPE(thread)
#define REUSABLE_OBJECT_HANDLESCOPE(thread)