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

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

Issue 2302773002: [regexp] Port RegExpConstructor (Closed)
Patch Set: Tweaks Created 4 years, 3 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "src/builtins/builtins.h"
6 #include "src/builtins/builtins-utils.h"
7
8 #include "src/string-builder.h"
9
10 namespace v8 {
11 namespace internal {
12
13 // -----------------------------------------------------------------------------
14 // ES6 section 21.2 RegExp Objects
15
16 namespace {
17
18 // ES#sec-isregexp IsRegExp ( argument )
19 Maybe<bool> IsRegExp(Isolate* isolate, Handle<Object> object) {
20 if (!object->IsJSReceiver()) return Just(false);
21
22 Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(object);
23
24 Handle<Object> match;
25 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
26 isolate, match,
27 JSObject::GetProperty(receiver, isolate->factory()->match_symbol()),
28 Nothing<bool>());
29
30 if (!match->IsUndefined(isolate)) return Just(match->BooleanValue());
31 return Just(object->IsJSRegExp());
32 }
33
34 Handle<String> PatternFlags(Isolate* isolate, Handle<JSRegExp> regexp) {
35 IncrementalStringBuilder builder(isolate);
36 const JSRegExp::Flags flags = regexp->GetFlags();
37
38 if ((flags & JSRegExp::kGlobal) != 0) builder.AppendCharacter('g');
39 if ((flags & JSRegExp::kIgnoreCase) != 0) builder.AppendCharacter('i');
40 if ((flags & JSRegExp::kMultiline) != 0) builder.AppendCharacter('m');
41 if ((flags & JSRegExp::kUnicode) != 0) builder.AppendCharacter('u');
42 if ((flags & JSRegExp::kSticky) != 0) builder.AppendCharacter('y');
43
44 return builder.Finish().ToHandleChecked();
45 }
46
47 // ES#sec-regexpinitialize
48 // Runtime Semantics: RegExpInitialize ( obj, pattern, flags )
49 MaybeHandle<JSRegExp> RegExpInitialize(Isolate* isolate,
50 Handle<JSRegExp> regexp,
51 Handle<Object> pattern,
52 Handle<Object> flags) {
53 Handle<String> pattern_string;
54 if (pattern->IsUndefined(isolate)) {
55 pattern_string = isolate->factory()->empty_string();
56 } else {
57 ASSIGN_RETURN_ON_EXCEPTION(isolate, pattern_string,
58 Object::ToString(isolate, pattern), JSRegExp);
59 }
60
61 Handle<String> flags_string;
62 if (flags->IsUndefined(isolate)) {
63 flags_string = isolate->factory()->empty_string();
64 } else {
65 ASSIGN_RETURN_ON_EXCEPTION(isolate, flags_string,
66 Object::ToString(isolate, flags), JSRegExp);
67 }
68
69 // TODO(jgruber): We could avoid the flags back and forth conversions.
70 RETURN_RESULT(isolate,
71 JSRegExp::Initialize(regexp, pattern_string, flags_string),
72 JSRegExp);
73 }
74
75 } // namespace
76
77 // ES#sec-regexp-pattern-flags
78 // RegExp ( pattern, flags )
79 BUILTIN(RegExpConstructor) {
80 HandleScope scope(isolate);
81
82 Handle<HeapObject> new_target = args.new_target();
83 Handle<Object> pattern = args.atOrUndefined(isolate, 1);
84 Handle<Object> flags = args.atOrUndefined(isolate, 2);
85
86 Handle<JSFunction> target =
87 handle(isolate->native_context()->regexp_function(), isolate);
88
89 bool pattern_is_regexp;
90 {
91 Maybe<bool> maybe_pattern_is_regexp = IsRegExp(isolate, pattern);
92 if (maybe_pattern_is_regexp.IsNothing()) {
93 DCHECK(isolate->has_pending_exception());
94 return isolate->heap()->exception();
95 }
96 pattern_is_regexp = maybe_pattern_is_regexp.FromJust();
97 }
98
99 if (new_target->IsUndefined(isolate)) {
100 new_target = target;
101
102 // ES6 section 21.2.3.1 step 3.b
103 if (pattern_is_regexp && flags->IsUndefined(isolate)) {
104 Handle<Object> pattern_constructor;
105 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
106 isolate, pattern_constructor,
107 Object::GetProperty(pattern,
108 isolate->factory()->constructor_string()));
109
110 if (*pattern_constructor == *new_target) {
111 return *pattern;
112 }
113 }
114 } else if (!new_target->IsJSReceiver()) {
115 // TODO(jgruber): Better error message.
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
151 } // namespace internal
152 } // 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