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

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

Issue 2384613004: [regexp] Port RegExpConstructor to C++ (Closed)
Patch Set: 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 #include "src/string-builder.h"
10 11
11 namespace v8 { 12 namespace v8 {
12 namespace internal { 13 namespace internal {
13 14
15 // -----------------------------------------------------------------------------
16 // ES6 section 21.2 RegExp Objects
17
18 namespace {
19
20 // ES#sec-isregexp IsRegExp ( argument )
21 Maybe<bool> IsRegExp(Isolate* isolate, Handle<Object> object) {
22 if (!object->IsJSReceiver()) return Just(false);
23
24 Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(object);
25
26 Handle<Object> match;
27 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
28 isolate, match,
29 JSObject::GetProperty(receiver, isolate->factory()->match_symbol()),
30 Nothing<bool>());
31
32 if (!match->IsUndefined(isolate)) return Just(match->BooleanValue());
33 return Just(object->IsJSRegExp());
34 }
35
36 Handle<String> PatternFlags(Isolate* isolate, Handle<JSRegExp> regexp) {
37 IncrementalStringBuilder builder(isolate);
38 const JSRegExp::Flags flags = regexp->GetFlags();
39
40 if ((flags & JSRegExp::kGlobal) != 0) builder.AppendCharacter('g');
41 if ((flags & JSRegExp::kIgnoreCase) != 0) builder.AppendCharacter('i');
42 if ((flags & JSRegExp::kMultiline) != 0) builder.AppendCharacter('m');
43 if ((flags & JSRegExp::kUnicode) != 0) builder.AppendCharacter('u');
44 if ((flags & JSRegExp::kSticky) != 0) builder.AppendCharacter('y');
45
46 return builder.Finish().ToHandleChecked();
47 }
48
49 // ES#sec-regexpinitialize
50 // Runtime Semantics: RegExpInitialize ( obj, pattern, flags )
51 MaybeHandle<JSRegExp> RegExpInitialize(Isolate* isolate,
52 Handle<JSRegExp> regexp,
53 Handle<Object> pattern,
54 Handle<Object> flags) {
55 Handle<String> pattern_string;
56 if (pattern->IsUndefined(isolate)) {
57 pattern_string = isolate->factory()->empty_string();
58 } else {
59 ASSIGN_RETURN_ON_EXCEPTION(isolate, pattern_string,
60 Object::ToString(isolate, pattern), JSRegExp);
61 }
62
63 Handle<String> flags_string;
64 if (flags->IsUndefined(isolate)) {
65 flags_string = isolate->factory()->empty_string();
66 } else {
67 ASSIGN_RETURN_ON_EXCEPTION(isolate, flags_string,
68 Object::ToString(isolate, flags), JSRegExp);
69 }
70
71 // TODO(jgruber): We could avoid the flags back and forth conversions.
72 RETURN_RESULT(isolate,
73 JSRegExp::Initialize(regexp, pattern_string, flags_string),
74 JSRegExp);
75 }
76
77 } // namespace
78
79 // ES#sec-regexp-pattern-flags
80 // RegExp ( pattern, flags )
81 BUILTIN(RegExpConstructor) {
82 HandleScope scope(isolate);
83
84 Handle<HeapObject> new_target = args.new_target();
85 Handle<Object> pattern = args.atOrUndefined(isolate, 1);
86 Handle<Object> flags = args.atOrUndefined(isolate, 2);
87
88 Handle<JSFunction> target = isolate->regexp_function();
89
90 bool pattern_is_regexp;
91 {
92 Maybe<bool> maybe_pattern_is_regexp = IsRegExp(isolate, pattern);
93 if (maybe_pattern_is_regexp.IsNothing()) {
94 DCHECK(isolate->has_pending_exception());
95 return isolate->heap()->exception();
96 }
97 pattern_is_regexp = maybe_pattern_is_regexp.FromJust();
98 }
99
100 if (new_target->IsUndefined(isolate)) {
101 new_target = target;
102
103 // ES6 section 21.2.3.1 step 3.b
104 if (pattern_is_regexp && flags->IsUndefined(isolate)) {
105 Handle<Object> pattern_constructor;
106 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
107 isolate, pattern_constructor,
108 Object::GetProperty(pattern,
109 isolate->factory()->constructor_string()));
110
111 if (*pattern_constructor == *new_target) {
Benedikt Meurer 2016/09/30 11:25:24 Nit: use is_identical_to here
jgruber 2016/10/04 12:25:22 Done.
112 return *pattern;
113 }
114 }
115 } else if (!new_target->IsJSReceiver()) {
Benedikt Meurer 2016/09/30 11:25:24 Shouldn't this be IsCallable? Because new_target c
jgruber 2016/10/04 12:25:22 I had a response to this all written out saying ne
116 THROW_NEW_ERROR_RETURN_FAILURE(
117 isolate, NewTypeError(MessageTemplate::kCalledNonCallable, new_target));
118 }
119 Handle<JSReceiver> new_target_receiver = Handle<JSReceiver>::cast(new_target);
120
121 if (pattern->IsJSRegExp()) {
122 Handle<JSRegExp> regexp_pattern = Handle<JSRegExp>::cast(pattern);
123
124 if (flags->IsUndefined(isolate)) {
125 flags = PatternFlags(isolate, regexp_pattern);
126 }
127 pattern = handle(regexp_pattern->source(), isolate);
128 } else if (pattern_is_regexp) {
129 Handle<Object> pattern_source;
130 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
131 isolate, pattern_source,
132 Object::GetProperty(pattern, isolate->factory()->source_string()));
133
134 if (flags->IsUndefined(isolate)) {
135 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
136 isolate, flags,
137 Object::GetProperty(pattern, isolate->factory()->flags_string()));
138 }
139 pattern = pattern_source;
140 }
141
142 Handle<JSObject> object;
143 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
144 isolate, object, JSObject::New(target, new_target_receiver));
145 Handle<JSRegExp> regexp = Handle<JSRegExp>::cast(object);
146
147 RETURN_RESULT_OR_FAILURE(isolate,
148 RegExpInitialize(isolate, regexp, pattern, flags));
149 }
150
14 namespace { 151 namespace {
15 152
16 compiler::Node* LoadLastIndex(CodeStubAssembler* a, compiler::Node* context, 153 compiler::Node* LoadLastIndex(CodeStubAssembler* a, compiler::Node* context,
17 compiler::Node* has_initialmap, 154 compiler::Node* has_initialmap,
18 compiler::Node* regexp) { 155 compiler::Node* regexp) {
19 typedef CodeStubAssembler::Variable Variable; 156 typedef CodeStubAssembler::Variable Variable;
20 typedef CodeStubAssembler::Label Label; 157 typedef CodeStubAssembler::Label Label;
21 typedef compiler::Node Node; 158 typedef compiler::Node Node;
22 159
23 Variable var_value(a, MachineRepresentation::kTagged); 160 Variable var_value(a, MachineRepresentation::kTagged);
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 { 425 {
289 Node* result = ConstructNewResultFromMatchInfo(isolate, a, context, 426 Node* result = ConstructNewResultFromMatchInfo(isolate, a, context,
290 match_elements, string); 427 match_elements, string);
291 a->Return(result); 428 a->Return(result);
292 } 429 }
293 } 430 }
294 } 431 }
295 432
296 } // namespace internal 433 } // namespace internal
297 } // namespace v8 434 } // 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