| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |