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

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

Issue 2440893003: [regexp] Extract implementation of RE.prototype.exec (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 | « no previous file | no next file » | 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/regexp/regexp-utils.h" 10 #include "src/regexp/regexp-utils.h"
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 a->Bind(&next_iter); 316 a->Bind(&next_iter);
317 var_from_cursor.Bind(a->IntPtrAdd(from_cursor, a->IntPtrConstant(2))); 317 var_from_cursor.Bind(a->IntPtrAdd(from_cursor, a->IntPtrConstant(2)));
318 var_to_cursor.Bind(a->IntPtrAdd(to_cursor, a->IntPtrConstant(1))); 318 var_to_cursor.Bind(a->IntPtrAdd(to_cursor, a->IntPtrConstant(1)));
319 a->Branch(a->UintPtrLessThan(var_from_cursor.value(), limit), &loop, &out); 319 a->Branch(a->UintPtrLessThan(var_from_cursor.value(), limit), &loop, &out);
320 } 320 }
321 321
322 a->Bind(&out); 322 a->Bind(&out);
323 return result; 323 return result;
324 } 324 }
325 325
326 } // namespace
327
328 // ES#sec-regexp.prototype.exec 326 // ES#sec-regexp.prototype.exec
329 // RegExp.prototype.exec ( string ) 327 // RegExp.prototype.exec ( string )
330 void Builtins::Generate_RegExpPrototypeExec(CodeStubAssembler* a) { 328 compiler::Node* RegExpPrototypeExecInternal(CodeStubAssembler* a,
329 compiler::Node* context,
330 compiler::Node* maybe_receiver,
331 compiler::Node* maybe_string) {
331 typedef CodeStubAssembler::Variable Variable; 332 typedef CodeStubAssembler::Variable Variable;
332 typedef CodeStubAssembler::Label Label; 333 typedef CodeStubAssembler::Label Label;
333 typedef compiler::Node Node; 334 typedef compiler::Node Node;
334 335
335 Isolate* const isolate = a->isolate(); 336 Isolate* const isolate = a->isolate();
336 337
337 Node* const receiver = a->Parameter(0);
338 Node* const maybe_string = a->Parameter(1);
339 Node* const context = a->Parameter(4);
340
341 Node* const null = a->NullConstant(); 338 Node* const null = a->NullConstant();
342 Node* const int_zero = a->IntPtrConstant(0); 339 Node* const int_zero = a->IntPtrConstant(0);
343 Node* const smi_zero = a->SmiConstant(Smi::kZero); 340 Node* const smi_zero = a->SmiConstant(Smi::kZero);
344 341
345 // Ensure {receiver} is a JSRegExp. 342 Variable var_result(a, MachineRepresentation::kTagged);
343 Label out(a);
344
345 // Ensure {maybe_receiver} is a JSRegExp.
346 Node* const regexp_map = a->ThrowIfNotInstanceType( 346 Node* const regexp_map = a->ThrowIfNotInstanceType(
347 context, receiver, JS_REGEXP_TYPE, "RegExp.prototype.exec"); 347 context, maybe_receiver, JS_REGEXP_TYPE, "RegExp.prototype.exec");
348 Node* const regexp = receiver; 348 Node* const regexp = maybe_receiver;
349 349
350 // Check whether the regexp instance is unmodified. 350 // Check whether the regexp instance is unmodified.
351 Node* const native_context = a->LoadNativeContext(context); 351 Node* const native_context = a->LoadNativeContext(context);
352 Node* const regexp_fun = 352 Node* const regexp_fun =
353 a->LoadContextElement(native_context, Context::REGEXP_FUNCTION_INDEX); 353 a->LoadContextElement(native_context, Context::REGEXP_FUNCTION_INDEX);
354 Node* const initial_map = 354 Node* const initial_map =
355 a->LoadObjectField(regexp_fun, JSFunction::kPrototypeOrInitialMapOffset); 355 a->LoadObjectField(regexp_fun, JSFunction::kPrototypeOrInitialMapOffset);
356 Node* const has_initialmap = a->WordEqual(regexp_map, initial_map); 356 Node* const has_initialmap = a->WordEqual(regexp_map, initial_map);
357 357
358 // Convert {maybe_string} to a string. 358 // Convert {maybe_string} to a string.
(...skipping 28 matching lines...) Expand all
387 var_lastindex.Bind(lastindex); 387 var_lastindex.Bind(lastindex);
388 388
389 Label if_isoob(a, Label::kDeferred); 389 Label if_isoob(a, Label::kDeferred);
390 a->GotoUnless(a->TaggedIsSmi(lastindex), &if_isoob); 390 a->GotoUnless(a->TaggedIsSmi(lastindex), &if_isoob);
391 a->GotoUnless(a->SmiLessThanOrEqual(lastindex, string_length), &if_isoob); 391 a->GotoUnless(a->SmiLessThanOrEqual(lastindex, string_length), &if_isoob);
392 a->Goto(&run_exec); 392 a->Goto(&run_exec);
393 393
394 a->Bind(&if_isoob); 394 a->Bind(&if_isoob);
395 { 395 {
396 StoreLastIndex(a, context, has_initialmap, regexp, smi_zero); 396 StoreLastIndex(a, context, has_initialmap, regexp, smi_zero);
397 a->Return(null); 397 var_result.Bind(null);
398 a->Goto(&out);
398 } 399 }
399 } 400 }
400 401
401 a->Bind(&if_dontupdate); 402 a->Bind(&if_dontupdate);
402 { 403 {
403 var_lastindex.Bind(smi_zero); 404 var_lastindex.Bind(smi_zero);
404 a->Goto(&run_exec); 405 a->Goto(&run_exec);
405 } 406 }
406 } 407 }
407 408
(...skipping 14 matching lines...) Expand all
422 // Return early if exec failed, possibly updating last index. 423 // Return early if exec failed, possibly updating last index.
423 a->GotoUnless(a->WordEqual(match_indices, null), &successful_match); 424 a->GotoUnless(a->WordEqual(match_indices, null), &successful_match);
424 425
425 Label return_null(a); 426 Label return_null(a);
426 a->GotoUnless(should_update_last_index, &return_null); 427 a->GotoUnless(should_update_last_index, &return_null);
427 428
428 StoreLastIndex(a, context, has_initialmap, regexp, smi_zero); 429 StoreLastIndex(a, context, has_initialmap, regexp, smi_zero);
429 a->Goto(&return_null); 430 a->Goto(&return_null);
430 431
431 a->Bind(&return_null); 432 a->Bind(&return_null);
432 a->Return(null); 433 var_result.Bind(null);
434 a->Goto(&out);
433 } 435 }
434 436
435 Label construct_result(a); 437 Label construct_result(a);
436 a->Bind(&successful_match); 438 a->Bind(&successful_match);
437 { 439 {
438 a->GotoUnless(should_update_last_index, &construct_result); 440 a->GotoUnless(should_update_last_index, &construct_result);
439 441
440 // Update the new last index from {match_indices}. 442 // Update the new last index from {match_indices}.
441 Node* const new_lastindex = a->LoadFixedArrayElement( 443 Node* const new_lastindex = a->LoadFixedArrayElement(
442 match_indices, 444 match_indices,
443 a->IntPtrConstant(RegExpMatchInfo::kFirstCaptureIndex + 1)); 445 a->IntPtrConstant(RegExpMatchInfo::kFirstCaptureIndex + 1));
444 446
445 StoreLastIndex(a, context, has_initialmap, regexp, new_lastindex); 447 StoreLastIndex(a, context, has_initialmap, regexp, new_lastindex);
446 a->Goto(&construct_result); 448 a->Goto(&construct_result);
447 449
448 a->Bind(&construct_result); 450 a->Bind(&construct_result);
449 { 451 {
450 Node* result = ConstructNewResultFromMatchInfo(isolate, a, context, 452 Node* result = ConstructNewResultFromMatchInfo(isolate, a, context,
451 match_indices, string); 453 match_indices, string);
452 a->Return(result); 454 var_result.Bind(result);
455 a->Goto(&out);
453 } 456 }
454 } 457 }
458
459 a->Bind(&out);
460 return var_result.value();
461 }
462
463 } // namespace
464
465 // ES#sec-regexp.prototype.exec
466 // RegExp.prototype.exec ( string )
467 void Builtins::Generate_RegExpPrototypeExec(CodeStubAssembler* a) {
468 typedef compiler::Node Node;
469
470 Node* const maybe_receiver = a->Parameter(0);
471 Node* const maybe_string = a->Parameter(1);
472 Node* const context = a->Parameter(4);
473
474 Node* const result =
475 RegExpPrototypeExecInternal(a, context, maybe_receiver, maybe_string);
476 a->Return(result);
455 } 477 }
456 478
457 namespace { 479 namespace {
458 480
459 compiler::Node* ThrowIfNotJSReceiver(CodeStubAssembler* a, Isolate* isolate, 481 compiler::Node* ThrowIfNotJSReceiver(CodeStubAssembler* a, Isolate* isolate,
460 compiler::Node* context, 482 compiler::Node* context,
461 compiler::Node* value, 483 compiler::Node* value,
462 MessageTemplate::Template msg_template, 484 MessageTemplate::Template msg_template,
463 char const* method_name) { 485 char const* method_name) {
464 typedef compiler::Node Node; 486 typedef compiler::Node Node;
(...skipping 1442 matching lines...) Expand 10 before | Expand all | Expand 10 after
1907 a->Bind(&if_matched); 1929 a->Bind(&if_matched);
1908 { 1930 {
1909 Node* result = ConstructNewResultFromMatchInfo(isolate, a, context, 1931 Node* result = ConstructNewResultFromMatchInfo(isolate, a, context,
1910 match_indices, string); 1932 match_indices, string);
1911 a->Return(result); 1933 a->Return(result);
1912 } 1934 }
1913 } 1935 }
1914 1936
1915 } // namespace internal 1937 } // namespace internal
1916 } // namespace v8 1938 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698