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

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

Issue 2752143004: [refactor] Separate generated builtins and C++ builtins into separate files (Closed)
Patch Set: tentative gcmole fix Created 3 years, 9 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-regexp-gen.h ('k') | src/builtins/builtins-sharedarraybuffer.cc » ('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 2017 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-regexp.h" 5 #include "src/builtins/builtins-regexp-gen.h"
6 6
7 #include "src/builtins/builtins-constructor.h" 7 #include "src/builtins/builtins-constructor.h"
8 #include "src/builtins/builtins-utils.h" 8 #include "src/builtins/builtins-utils-gen.h"
9 #include "src/builtins/builtins.h" 9 #include "src/builtins/builtins.h"
10 #include "src/code-factory.h" 10 #include "src/code-factory.h"
11 #include "src/code-stub-assembler.h" 11 #include "src/code-stub-assembler.h"
12 #include "src/counters.h"
13 #include "src/objects-inl.h"
14 #include "src/objects/regexp-match-info.h" 12 #include "src/objects/regexp-match-info.h"
15 #include "src/regexp/jsregexp.h" 13 #include "src/regexp/regexp-macro-assembler.h"
16 #include "src/regexp/regexp-utils.h"
17 #include "src/string-builder.h"
18 14
19 namespace v8 { 15 namespace v8 {
20 namespace internal { 16 namespace internal {
21 17
22 typedef CodeStubAssembler::ParameterMode ParameterMode; 18 using compiler::Node;
23
24 19
25 // ----------------------------------------------------------------------------- 20 // -----------------------------------------------------------------------------
26 // ES6 section 21.2 RegExp Objects 21 // ES6 section 21.2 RegExp Objects
27 22
28 Node* RegExpBuiltinsAssembler::FastLoadLastIndex(Node* regexp) { 23 Node* RegExpBuiltinsAssembler::FastLoadLastIndex(Node* regexp) {
29 // Load the in-object field. 24 // Load the in-object field.
30 static const int field_offset = 25 static const int field_offset =
31 JSRegExp::kSize + JSRegExp::kLastIndexFieldIndex * kPointerSize; 26 JSRegExp::kSize + JSRegExp::kLastIndexFieldIndex * kPointerSize;
32 return LoadObjectField(regexp, field_offset); 27 return LoadObjectField(regexp, field_offset);
33 } 28 }
(...skipping 1134 matching lines...) Expand 10 before | Expand all | Expand 10 after
1168 SmiConstant(Smi::FromInt(MessageTemplate::kRegExpNonRegExp)); 1163 SmiConstant(Smi::FromInt(MessageTemplate::kRegExpNonRegExp));
1169 Node* const method_name_str = 1164 Node* const method_name_str =
1170 HeapConstant(isolate->factory()->NewStringFromAsciiChecked( 1165 HeapConstant(isolate->factory()->NewStringFromAsciiChecked(
1171 "RegExp.prototype.source")); 1166 "RegExp.prototype.source"));
1172 TailCallRuntime(Runtime::kThrowTypeError, context, message_id, 1167 TailCallRuntime(Runtime::kThrowTypeError, context, message_id,
1173 method_name_str); 1168 method_name_str);
1174 } 1169 }
1175 } 1170 }
1176 } 1171 }
1177 1172
1178 BUILTIN(RegExpPrototypeToString) {
1179 HandleScope scope(isolate);
1180 CHECK_RECEIVER(JSReceiver, recv, "RegExp.prototype.toString");
1181
1182 if (*recv == isolate->regexp_function()->prototype()) {
1183 isolate->CountUsage(v8::Isolate::kRegExpPrototypeToString);
1184 }
1185
1186 IncrementalStringBuilder builder(isolate);
1187
1188 builder.AppendCharacter('/');
1189 {
1190 Handle<Object> source;
1191 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
1192 isolate, source,
1193 JSReceiver::GetProperty(recv, isolate->factory()->source_string()));
1194 Handle<String> source_str;
1195 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, source_str,
1196 Object::ToString(isolate, source));
1197 builder.AppendString(source_str);
1198 }
1199
1200 builder.AppendCharacter('/');
1201 {
1202 Handle<Object> flags;
1203 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
1204 isolate, flags,
1205 JSReceiver::GetProperty(recv, isolate->factory()->flags_string()));
1206 Handle<String> flags_str;
1207 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, flags_str,
1208 Object::ToString(isolate, flags));
1209 builder.AppendString(flags_str);
1210 }
1211
1212 RETURN_RESULT_OR_FAILURE(isolate, builder.Finish());
1213 }
1214
1215 // Fast-path implementation for flag checks on an unmodified JSRegExp instance. 1173 // Fast-path implementation for flag checks on an unmodified JSRegExp instance.
1216 Node* RegExpBuiltinsAssembler::FastFlagGetter(Node* const regexp, 1174 Node* RegExpBuiltinsAssembler::FastFlagGetter(Node* const regexp,
1217 JSRegExp::Flag flag) { 1175 JSRegExp::Flag flag) {
1218 Node* const smi_zero = SmiConstant(Smi::kZero); 1176 Node* const smi_zero = SmiConstant(Smi::kZero);
1219 Node* const flags = LoadObjectField(regexp, JSRegExp::kFlagsOffset); 1177 Node* const flags = LoadObjectField(regexp, JSRegExp::kFlagsOffset);
1220 Node* const mask = SmiConstant(Smi::FromInt(flag)); 1178 Node* const mask = SmiConstant(Smi::FromInt(flag));
1221 Node* const is_flag_set = WordNotEqual(SmiAnd(flags, mask), smi_zero); 1179 Node* const is_flag_set = WordNotEqual(SmiAnd(flags, mask), smi_zero);
1222 1180
1223 return is_flag_set; 1181 return is_flag_set;
1224 } 1182 }
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
1365 FlagGetter(JSRegExp::kSticky, v8::Isolate::kRegExpPrototypeStickyGetter, 1323 FlagGetter(JSRegExp::kSticky, v8::Isolate::kRegExpPrototypeStickyGetter,
1366 "RegExp.prototype.sticky"); 1324 "RegExp.prototype.sticky");
1367 } 1325 }
1368 1326
1369 // ES6 21.2.5.15. 1327 // ES6 21.2.5.15.
1370 TF_BUILTIN(RegExpPrototypeUnicodeGetter, RegExpBuiltinsAssembler) { 1328 TF_BUILTIN(RegExpPrototypeUnicodeGetter, RegExpBuiltinsAssembler) {
1371 FlagGetter(JSRegExp::kUnicode, v8::Isolate::kRegExpPrototypeUnicodeGetter, 1329 FlagGetter(JSRegExp::kUnicode, v8::Isolate::kRegExpPrototypeUnicodeGetter,
1372 "RegExp.prototype.unicode"); 1330 "RegExp.prototype.unicode");
1373 } 1331 }
1374 1332
1375 // The properties $1..$9 are the first nine capturing substrings of the last
1376 // successful match, or ''. The function RegExpMakeCaptureGetter will be
1377 // called with indices from 1 to 9.
1378 #define DEFINE_CAPTURE_GETTER(i) \
1379 BUILTIN(RegExpCapture##i##Getter) { \
1380 HandleScope scope(isolate); \
1381 return *RegExpUtils::GenericCaptureGetter( \
1382 isolate, isolate->regexp_last_match_info(), i); \
1383 }
1384 DEFINE_CAPTURE_GETTER(1)
1385 DEFINE_CAPTURE_GETTER(2)
1386 DEFINE_CAPTURE_GETTER(3)
1387 DEFINE_CAPTURE_GETTER(4)
1388 DEFINE_CAPTURE_GETTER(5)
1389 DEFINE_CAPTURE_GETTER(6)
1390 DEFINE_CAPTURE_GETTER(7)
1391 DEFINE_CAPTURE_GETTER(8)
1392 DEFINE_CAPTURE_GETTER(9)
1393 #undef DEFINE_CAPTURE_GETTER
1394
1395 // The properties `input` and `$_` are aliases for each other. When this
1396 // value is set, the value it is set to is coerced to a string.
1397 // Getter and setter for the input.
1398
1399 BUILTIN(RegExpInputGetter) {
1400 HandleScope scope(isolate);
1401 Handle<Object> obj(isolate->regexp_last_match_info()->LastInput(), isolate);
1402 return obj->IsUndefined(isolate) ? isolate->heap()->empty_string()
1403 : String::cast(*obj);
1404 }
1405
1406 BUILTIN(RegExpInputSetter) {
1407 HandleScope scope(isolate);
1408 Handle<Object> value = args.atOrUndefined(isolate, 1);
1409 Handle<String> str;
1410 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, str,
1411 Object::ToString(isolate, value));
1412 isolate->regexp_last_match_info()->SetLastInput(*str);
1413 return isolate->heap()->undefined_value();
1414 }
1415
1416 // Getters for the static properties lastMatch, lastParen, leftContext, and
1417 // rightContext of the RegExp constructor. The properties are computed based
1418 // on the captures array of the last successful match and the subject string
1419 // of the last successful match.
1420 BUILTIN(RegExpLastMatchGetter) {
1421 HandleScope scope(isolate);
1422 return *RegExpUtils::GenericCaptureGetter(
1423 isolate, isolate->regexp_last_match_info(), 0);
1424 }
1425
1426 BUILTIN(RegExpLastParenGetter) {
1427 HandleScope scope(isolate);
1428 Handle<RegExpMatchInfo> match_info = isolate->regexp_last_match_info();
1429 const int length = match_info->NumberOfCaptureRegisters();
1430 if (length <= 2) return isolate->heap()->empty_string(); // No captures.
1431
1432 DCHECK_EQ(0, length % 2);
1433 const int last_capture = (length / 2) - 1;
1434
1435 // We match the SpiderMonkey behavior: return the substring defined by the
1436 // last pair (after the first pair) of elements of the capture array even if
1437 // it is empty.
1438 return *RegExpUtils::GenericCaptureGetter(isolate, match_info, last_capture);
1439 }
1440
1441 BUILTIN(RegExpLeftContextGetter) {
1442 HandleScope scope(isolate);
1443 Handle<RegExpMatchInfo> match_info = isolate->regexp_last_match_info();
1444 const int start_index = match_info->Capture(0);
1445 Handle<String> last_subject(match_info->LastSubject());
1446 return *isolate->factory()->NewSubString(last_subject, 0, start_index);
1447 }
1448
1449 BUILTIN(RegExpRightContextGetter) {
1450 HandleScope scope(isolate);
1451 Handle<RegExpMatchInfo> match_info = isolate->regexp_last_match_info();
1452 const int start_index = match_info->Capture(1);
1453 Handle<String> last_subject(match_info->LastSubject());
1454 const int len = last_subject->length();
1455 return *isolate->factory()->NewSubString(last_subject, start_index, len);
1456 }
1457
1458 // ES#sec-regexpexec Runtime Semantics: RegExpExec ( R, S ) 1333 // ES#sec-regexpexec Runtime Semantics: RegExpExec ( R, S )
1459 Node* RegExpBuiltinsAssembler::RegExpExec(Node* context, Node* regexp, 1334 Node* RegExpBuiltinsAssembler::RegExpExec(Node* context, Node* regexp,
1460 Node* string) { 1335 Node* string) {
1461 Isolate* isolate = this->isolate(); 1336 Isolate* isolate = this->isolate();
1462 1337
1463 Node* const null = NullConstant(); 1338 Node* const null = NullConstant();
1464 1339
1465 Variable var_result(this, MachineRepresentation::kTagged); 1340 Variable var_result(this, MachineRepresentation::kTagged);
1466 Label out(this), if_isfastpath(this), if_isslowpath(this); 1341 Label out(this), if_isfastpath(this), if_isslowpath(this);
1467 1342
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
1722 // {element_count} elements from the current array. 1597 // {element_count} elements from the current array.
1723 Node* ResizeFixedArray(Node* const element_count, Node* const new_capacity) { 1598 Node* ResizeFixedArray(Node* const element_count, Node* const new_capacity) {
1724 CodeStubAssembler* a = assembler_; 1599 CodeStubAssembler* a = assembler_;
1725 1600
1726 CSA_ASSERT(a, a->IntPtrGreaterThan(element_count, a->IntPtrConstant(0))); 1601 CSA_ASSERT(a, a->IntPtrGreaterThan(element_count, a->IntPtrConstant(0)));
1727 CSA_ASSERT(a, a->IntPtrGreaterThan(new_capacity, a->IntPtrConstant(0))); 1602 CSA_ASSERT(a, a->IntPtrGreaterThan(new_capacity, a->IntPtrConstant(0)));
1728 CSA_ASSERT(a, a->IntPtrGreaterThanOrEqual(new_capacity, element_count)); 1603 CSA_ASSERT(a, a->IntPtrGreaterThanOrEqual(new_capacity, element_count));
1729 1604
1730 const ElementsKind kind = FAST_ELEMENTS; 1605 const ElementsKind kind = FAST_ELEMENTS;
1731 const WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER; 1606 const WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER;
1732 const ParameterMode mode = CodeStubAssembler::INTPTR_PARAMETERS; 1607 const CodeStubAssembler::ParameterMode mode =
1608 CodeStubAssembler::INTPTR_PARAMETERS;
1733 const CodeStubAssembler::AllocationFlags flags = 1609 const CodeStubAssembler::AllocationFlags flags =
1734 CodeStubAssembler::kAllowLargeObjectAllocation; 1610 CodeStubAssembler::kAllowLargeObjectAllocation;
1735 1611
1736 Node* const from_array = var_array_.value(); 1612 Node* const from_array = var_array_.value();
1737 Node* const to_array = 1613 Node* const to_array =
1738 a->AllocateFixedArray(kind, new_capacity, mode, flags); 1614 a->AllocateFixedArray(kind, new_capacity, mode, flags);
1739 a->CopyFixedArrayElements(kind, from_array, kind, to_array, element_count, 1615 a->CopyFixedArrayElements(kind, from_array, kind, to_array, element_count,
1740 new_capacity, barrier_mode, mode); 1616 new_capacity, barrier_mode, mode);
1741 1617
1742 return to_array; 1618 return to_array;
(...skipping 764 matching lines...) Expand 10 before | Expand all | Expand 10 after
2507 } 2383 }
2508 } 2384 }
2509 } 2385 }
2510 2386
2511 Bind(&if_hasexplicitcaptures); 2387 Bind(&if_hasexplicitcaptures);
2512 { 2388 {
2513 Node* const from = int_zero; 2389 Node* const from = int_zero;
2514 Node* const to = SmiUntag(res_length); 2390 Node* const to = SmiUntag(res_length);
2515 const int increment = 1; 2391 const int increment = 1;
2516 2392
2517 BuildFastLoop( 2393 BuildFastLoop(from, to,
2518 from, to, 2394 [this, res_elems, isolate, native_context, context, undefined,
2519 [this, res_elems, isolate, native_context, context, undefined, 2395 replace_callable](Node* index) {
2520 replace_callable](Node* index) { 2396 Node* const elem = LoadFixedArrayElement(res_elems, index);
2521 Node* const elem = LoadFixedArrayElement(res_elems, index);
2522 2397
2523 Label do_continue(this); 2398 Label do_continue(this);
2524 GotoIf(TaggedIsSmi(elem), &do_continue); 2399 GotoIf(TaggedIsSmi(elem), &do_continue);
2525 2400
2526 // elem must be an Array. 2401 // elem must be an Array.
2527 // Use the apply argument as backing for global RegExp properties. 2402 // Use the apply argument as backing for global RegExp
2403 // properties.
2528 2404
2529 CSA_ASSERT(this, HasInstanceType(elem, JS_ARRAY_TYPE)); 2405 CSA_ASSERT(this, HasInstanceType(elem, JS_ARRAY_TYPE));
2530 2406
2531 // TODO(jgruber): Remove indirection through Call->ReflectApply. 2407 // TODO(jgruber): Remove indirection through
2532 Callable call_callable = CodeFactory::Call(isolate); 2408 // Call->ReflectApply.
2533 Node* const reflect_apply = 2409 Callable call_callable = CodeFactory::Call(isolate);
2534 LoadContextElement(native_context, Context::REFLECT_APPLY_INDEX); 2410 Node* const reflect_apply = LoadContextElement(
2411 native_context, Context::REFLECT_APPLY_INDEX);
2535 2412
2536 Node* const replacement_obj = 2413 Node* const replacement_obj =
2537 CallJS(call_callable, context, reflect_apply, undefined, 2414 CallJS(call_callable, context, reflect_apply, undefined,
2538 replace_callable, undefined, elem); 2415 replace_callable, undefined, elem);
2539 2416
2540 // Overwrite the i'th element in the results with the string we got 2417 // Overwrite the i'th element in the results with the string
2541 // back from the callback function. 2418 // we got back from the callback function.
2542 2419
2543 Node* const replacement_str = ToString(context, replacement_obj); 2420 Node* const replacement_str =
2544 StoreFixedArrayElement(res_elems, index, replacement_str); 2421 ToString(context, replacement_obj);
2422 StoreFixedArrayElement(res_elems, index, replacement_str);
2545 2423
2546 Goto(&do_continue); 2424 Goto(&do_continue);
2547 Bind(&do_continue); 2425 Bind(&do_continue);
2548 }, 2426 },
2549 increment, CodeStubAssembler::INTPTR_PARAMETERS, 2427 increment, CodeStubAssembler::INTPTR_PARAMETERS,
2550 CodeStubAssembler::IndexAdvanceMode::kPost); 2428 CodeStubAssembler::IndexAdvanceMode::kPost);
2551 2429
2552 Goto(&create_result); 2430 Goto(&create_result);
2553 } 2431 }
2554 2432
2555 Bind(&create_result); 2433 Bind(&create_result);
2556 { 2434 {
2557 Node* const result = CallRuntime(Runtime::kStringBuilderConcat, context, 2435 Node* const result = CallRuntime(Runtime::kStringBuilderConcat, context,
2558 res, res_length, string); 2436 res, res_length, string);
2559 var_result.Bind(result); 2437 var_result.Bind(result);
2560 Goto(&out); 2438 Goto(&out);
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
2800 Bind(&if_matched); 2678 Bind(&if_matched);
2801 { 2679 {
2802 Node* result = 2680 Node* result =
2803 ConstructNewResultFromMatchInfo(context, regexp, match_indices, string); 2681 ConstructNewResultFromMatchInfo(context, regexp, match_indices, string);
2804 Return(result); 2682 Return(result);
2805 } 2683 }
2806 } 2684 }
2807 2685
2808 } // namespace internal 2686 } // namespace internal
2809 } // namespace v8 2687 } // namespace v8
OLDNEW
« no previous file with comments | « src/builtins/builtins-regexp-gen.h ('k') | src/builtins/builtins-sharedarraybuffer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698