Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(21)

Side by Side Diff: src/builtins/builtins-regexp.cc

Issue 2384613004: [regexp] Port RegExpConstructor to C++ (Closed)
Patch Set: Rebase Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/builtins/builtins.h ('k') | src/heap-symbols.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/builtins/builtins-utils.h" 5 #include "src/builtins/builtins-utils.h"
6 #include "src/builtins/builtins.h" 6 #include "src/builtins/builtins.h"
7 7
8 #include "src/code-factory.h" 8 #include "src/code-factory.h"
9 #include "src/regexp/jsregexp.h" 9 #include "src/regexp/jsregexp.h"
10 10
11 namespace v8 { 11 namespace v8 {
12 namespace internal { 12 namespace internal {
13 13
14 // -----------------------------------------------------------------------------
15 // ES6 section 21.2 RegExp Objects
16
17 namespace {
18
19 // ES#sec-isregexp IsRegExp ( argument )
20 Maybe<bool> IsRegExp(Isolate* isolate, Handle<Object> object) {
21 if (!object->IsJSReceiver()) return Just(false);
22
23 Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(object);
24
25 if (isolate->regexp_function()->initial_map() == receiver->map()) {
26 // Fast-path for unmodified JSRegExp instances.
27 return Just(true);
28 }
29
30 Handle<Object> match;
31 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
32 isolate, match,
33 JSObject::GetProperty(receiver, isolate->factory()->match_symbol()),
34 Nothing<bool>());
35
36 if (!match->IsUndefined(isolate)) return Just(match->BooleanValue());
37 return Just(object->IsJSRegExp());
38 }
39
40 Handle<String> PatternFlags(Isolate* isolate, Handle<JSRegExp> regexp) {
41 static const int kMaxFlagsLength = 5 + 1; // 5 flags and '\0';
42 char flags_string[kMaxFlagsLength];
43 int i = 0;
44
45 const JSRegExp::Flags flags = regexp->GetFlags();
46
47 if ((flags & JSRegExp::kGlobal) != 0) flags_string[i++] = 'g';
48 if ((flags & JSRegExp::kIgnoreCase) != 0) flags_string[i++] = 'i';
49 if ((flags & JSRegExp::kMultiline) != 0) flags_string[i++] = 'm';
50 if ((flags & JSRegExp::kUnicode) != 0) flags_string[i++] = 'u';
51 if ((flags & JSRegExp::kSticky) != 0) flags_string[i++] = 'y';
52
53 DCHECK_LT(i, kMaxFlagsLength);
54 memset(&flags_string[i], '\0', kMaxFlagsLength - i);
55
56 return isolate->factory()->NewStringFromAsciiChecked(flags_string);
57 }
58
59 // ES#sec-regexpinitialize
60 // Runtime Semantics: RegExpInitialize ( obj, pattern, flags )
61 MaybeHandle<JSRegExp> RegExpInitialize(Isolate* isolate,
62 Handle<JSRegExp> regexp,
63 Handle<Object> pattern,
64 Handle<Object> flags) {
65 Handle<String> pattern_string;
66 if (pattern->IsUndefined(isolate)) {
67 pattern_string = isolate->factory()->empty_string();
68 } else {
69 ASSIGN_RETURN_ON_EXCEPTION(isolate, pattern_string,
70 Object::ToString(isolate, pattern), JSRegExp);
71 }
72
73 Handle<String> flags_string;
74 if (flags->IsUndefined(isolate)) {
75 flags_string = isolate->factory()->empty_string();
76 } else {
77 ASSIGN_RETURN_ON_EXCEPTION(isolate, flags_string,
78 Object::ToString(isolate, flags), JSRegExp);
79 }
80
81 // TODO(jgruber): We could avoid the flags back and forth conversions.
82 RETURN_RESULT(isolate,
83 JSRegExp::Initialize(regexp, pattern_string, flags_string),
84 JSRegExp);
85 }
86
87 } // namespace
88
89 // ES#sec-regexp-pattern-flags
90 // RegExp ( pattern, flags )
91 BUILTIN(RegExpConstructor) {
92 HandleScope scope(isolate);
93
94 Handle<HeapObject> new_target = args.new_target();
95 Handle<Object> pattern = args.atOrUndefined(isolate, 1);
96 Handle<Object> flags = args.atOrUndefined(isolate, 2);
97
98 Handle<JSFunction> target = isolate->regexp_function();
99
100 bool pattern_is_regexp;
101 {
102 Maybe<bool> maybe_pattern_is_regexp = IsRegExp(isolate, pattern);
103 if (maybe_pattern_is_regexp.IsNothing()) {
104 DCHECK(isolate->has_pending_exception());
105 return isolate->heap()->exception();
106 }
107 pattern_is_regexp = maybe_pattern_is_regexp.FromJust();
108 }
109
110 if (new_target->IsUndefined(isolate)) {
111 new_target = target;
112
113 // ES6 section 21.2.3.1 step 3.b
114 if (pattern_is_regexp && flags->IsUndefined(isolate)) {
115 Handle<Object> pattern_constructor;
116 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
117 isolate, pattern_constructor,
118 Object::GetProperty(pattern,
119 isolate->factory()->constructor_string()));
120
121 if (pattern_constructor.is_identical_to(new_target)) {
122 return *pattern;
123 }
124 }
125 }
126
127 if (pattern->IsJSRegExp()) {
128 Handle<JSRegExp> regexp_pattern = Handle<JSRegExp>::cast(pattern);
129
130 if (flags->IsUndefined(isolate)) {
131 flags = PatternFlags(isolate, regexp_pattern);
132 }
133 pattern = handle(regexp_pattern->source(), isolate);
134 } else if (pattern_is_regexp) {
135 Handle<Object> pattern_source;
136 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
137 isolate, pattern_source,
138 Object::GetProperty(pattern, isolate->factory()->source_string()));
139
140 if (flags->IsUndefined(isolate)) {
141 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
142 isolate, flags,
143 Object::GetProperty(pattern, isolate->factory()->flags_string()));
144 }
145 pattern = pattern_source;
146 }
147
148 Handle<JSReceiver> new_target_receiver = Handle<JSReceiver>::cast(new_target);
149
150 // TODO(jgruber): Fast-path for target == new_target == unmodified JSRegExp.
151
152 Handle<JSObject> object;
153 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
154 isolate, object, JSObject::New(target, new_target_receiver));
155 Handle<JSRegExp> regexp = Handle<JSRegExp>::cast(object);
156
157 RETURN_RESULT_OR_FAILURE(isolate,
158 RegExpInitialize(isolate, regexp, pattern, flags));
159 }
160
14 namespace { 161 namespace {
15 162
16 compiler::Node* LoadLastIndex(CodeStubAssembler* a, compiler::Node* context, 163 compiler::Node* LoadLastIndex(CodeStubAssembler* a, compiler::Node* context,
17 compiler::Node* has_initialmap, 164 compiler::Node* has_initialmap,
18 compiler::Node* regexp) { 165 compiler::Node* regexp) {
19 typedef CodeStubAssembler::Variable Variable; 166 typedef CodeStubAssembler::Variable Variable;
20 typedef CodeStubAssembler::Label Label; 167 typedef CodeStubAssembler::Label Label;
21 typedef compiler::Node Node; 168 typedef compiler::Node Node;
22 169
23 Variable var_value(a, MachineRepresentation::kTagged); 170 Variable var_value(a, MachineRepresentation::kTagged);
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 { 432 {
286 Node* result = ConstructNewResultFromMatchInfo(isolate, a, context, 433 Node* result = ConstructNewResultFromMatchInfo(isolate, a, context,
287 match_elements, string); 434 match_elements, string);
288 a->Return(result); 435 a->Return(result);
289 } 436 }
290 } 437 }
291 } 438 }
292 439
293 } // namespace internal 440 } // namespace internal
294 } // namespace v8 441 } // namespace v8
OLDNEW
« no previous file with comments | « src/builtins/builtins.h ('k') | src/heap-symbols.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698