Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 302 pattern, | 302 pattern, |
| 303 flags, | 303 flags, |
| 304 match_pattern); | 304 match_pattern); |
| 305 } | 305 } |
| 306 | 306 |
| 307 | 307 |
| 308 static void SetAtomLastCapture(FixedArray* array, | 308 static void SetAtomLastCapture(FixedArray* array, |
| 309 String* subject, | 309 String* subject, |
| 310 int from, | 310 int from, |
| 311 int to) { | 311 int to) { |
| 312 NoHandleAllocation no_handles; | |
| 312 RegExpImpl::SetLastCaptureCount(array, 2); | 313 RegExpImpl::SetLastCaptureCount(array, 2); |
| 313 RegExpImpl::SetLastSubject(array, subject); | 314 RegExpImpl::SetLastSubject(array, subject); |
| 314 RegExpImpl::SetLastInput(array, subject); | 315 RegExpImpl::SetLastInput(array, subject); |
| 315 RegExpImpl::SetCapture(array, 0, from); | 316 RegExpImpl::SetCapture(array, 0, from); |
| 316 RegExpImpl::SetCapture(array, 1, to); | 317 RegExpImpl::SetCapture(array, 1, to); |
| 317 } | 318 } |
| 318 | 319 |
| 319 | 320 |
| 320 Handle<Object> RegExpImpl::AtomExec(Handle<JSRegExp> re, | 321 Handle<Object> RegExpImpl::AtomExec(Handle<JSRegExp> re, |
| 321 Handle<String> subject, | 322 Handle<String> subject, |
| 322 int index, | 323 int index, |
| 323 Handle<JSArray> last_match_info) { | 324 Handle<JSArray> last_match_info) { |
| 324 Handle<String> needle(String::cast(re->DataAt(JSRegExp::kAtomPatternIndex))); | 325 Handle<String> needle(String::cast(re->DataAt(JSRegExp::kAtomPatternIndex))); |
| 325 | 326 |
| 326 uint32_t start_index = index; | 327 uint32_t start_index = index; |
| 327 | 328 |
| 328 int value = Runtime::StringMatch(subject, needle, start_index); | 329 int value = Runtime::StringMatch(subject, needle, start_index); |
| 329 if (value == -1) return Factory::null_value(); | 330 if (value == -1) return Factory::null_value(); |
| 330 ASSERT(last_match_info->HasFastElements()); | 331 ASSERT(last_match_info->HasFastElements()); |
| 331 | 332 |
|
Erik Corry
2009/03/03 10:44:13
Add a NoHandleAllocation here.
| |
| 332 Handle<FixedArray> array(last_match_info->elements()); | 333 FixedArray* array = last_match_info->elements(); |
| 333 SetAtomLastCapture(*array, *subject, value, value + needle->length()); | 334 SetAtomLastCapture(array, *subject, value, value + needle->length()); |
| 334 return last_match_info; | 335 return last_match_info; |
| 335 } | 336 } |
| 336 | 337 |
| 337 | 338 |
| 338 Handle<Object> RegExpImpl::AtomExecGlobal(Handle<JSRegExp> re, | 339 Handle<Object> RegExpImpl::AtomExecGlobal(Handle<JSRegExp> re, |
| 339 Handle<String> subject, | 340 Handle<String> subject, |
| 340 Handle<JSArray> last_match_info) { | 341 Handle<JSArray> last_match_info) { |
| 341 Handle<String> needle(String::cast(re->DataAt(JSRegExp::kAtomPatternIndex))); | 342 Handle<String> needle(String::cast(re->DataAt(JSRegExp::kAtomPatternIndex))); |
| 342 ASSERT(last_match_info->HasFastElements()); | 343 ASSERT(last_match_info->HasFastElements()); |
| 343 Handle<JSArray> result = Factory::NewJSArray(1); | 344 Handle<JSArray> result = Factory::NewJSArray(1); |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 445 SetElement(array, | 446 SetElement(array, |
| 446 1, | 447 1, |
| 447 Factory::NewStringFromUtf8(CStrVector(result.error_message))); | 448 Factory::NewStringFromUtf8(CStrVector(result.error_message))); |
| 448 Handle<Object> regexp_err = | 449 Handle<Object> regexp_err = |
| 449 Factory::NewSyntaxError("malformed_regexp", array); | 450 Factory::NewSyntaxError("malformed_regexp", array); |
| 450 Top::Throw(*regexp_err); | 451 Top::Throw(*regexp_err); |
| 451 re->SetDataAt(index, *regexp_err); | 452 re->SetDataAt(index, *regexp_err); |
| 452 return false; | 453 return false; |
| 453 } | 454 } |
| 454 | 455 |
| 455 Handle<FixedArray> data(FixedArray::cast(re->data())); | 456 FixedArray* data = FixedArray::cast(re->data()); |
|
Erik Corry
2009/03/03 10:44:13
NoHandleAllocation
| |
| 456 data->set(index, result.code); | 457 data->set(index, result.code); |
| 457 int register_max = IrregexpMaxRegisterCount(data); | 458 int register_max = IrregexpMaxRegisterCount(data); |
| 458 if (result.num_registers > register_max) { | 459 if (result.num_registers > register_max) { |
| 459 SetIrregexpMaxRegisterCount(data, result.num_registers); | 460 SetIrregexpMaxRegisterCount(data, result.num_registers); |
| 460 } | 461 } |
| 461 | 462 |
| 462 return true; | 463 return true; |
| 463 } | 464 } |
| 464 | 465 |
| 465 | 466 |
| 466 int RegExpImpl::IrregexpMaxRegisterCount(Handle<FixedArray> re) { | 467 int RegExpImpl::IrregexpMaxRegisterCount(FixedArray* re) { |
| 467 return Smi::cast( | 468 return Smi::cast( |
| 468 re->get(JSRegExp::kIrregexpMaxRegisterCountIndex))->value(); | 469 re->get(JSRegExp::kIrregexpMaxRegisterCountIndex))->value(); |
| 469 } | 470 } |
| 470 | 471 |
| 471 | 472 |
| 472 void RegExpImpl::SetIrregexpMaxRegisterCount(Handle<FixedArray> re, int value) { | 473 void RegExpImpl::SetIrregexpMaxRegisterCount(FixedArray* re, int value) { |
| 473 re->set(JSRegExp::kIrregexpMaxRegisterCountIndex, | 474 re->set(JSRegExp::kIrregexpMaxRegisterCountIndex, Smi::FromInt(value)); |
| 474 Smi::FromInt(value)); | |
| 475 } | 475 } |
| 476 | 476 |
| 477 | 477 |
| 478 int RegExpImpl::IrregexpNumberOfCaptures(Handle<FixedArray> re) { | 478 int RegExpImpl::IrregexpNumberOfCaptures(FixedArray* re) { |
| 479 return Smi::cast( | 479 return Smi::cast(re->get(JSRegExp::kIrregexpCaptureCountIndex))->value(); |
| 480 re->get(JSRegExp::kIrregexpCaptureCountIndex))->value(); | |
| 481 } | 480 } |
| 482 | 481 |
| 483 | 482 |
| 484 int RegExpImpl::IrregexpNumberOfRegisters(Handle<FixedArray> re) { | 483 int RegExpImpl::IrregexpNumberOfRegisters(FixedArray* re) { |
| 485 return Smi::cast( | 484 return Smi::cast(re->get(JSRegExp::kIrregexpMaxRegisterCountIndex))->value(); |
| 486 re->get(JSRegExp::kIrregexpMaxRegisterCountIndex))->value(); | |
| 487 } | 485 } |
| 488 | 486 |
| 489 | 487 |
| 490 Handle<ByteArray> RegExpImpl::IrregexpByteCode(Handle<FixedArray> re, | 488 ByteArray* RegExpImpl::IrregexpByteCode(FixedArray* re, bool is_ascii) { |
| 491 bool is_ascii) { | |
| 492 int index; | 489 int index; |
| 493 if (is_ascii) { | 490 if (is_ascii) { |
| 494 index = JSRegExp::kIrregexpASCIICodeIndex; | 491 index = JSRegExp::kIrregexpASCIICodeIndex; |
| 495 } else { | 492 } else { |
| 496 index = JSRegExp::kIrregexpUC16CodeIndex; | 493 index = JSRegExp::kIrregexpUC16CodeIndex; |
| 497 } | 494 } |
| 498 Object* value = re->get(index); | 495 return ByteArray::cast(re->get(index)); |
| 499 ASSERT(value->IsByteArray()); | |
| 500 return Handle<ByteArray>(ByteArray::cast(value)); | |
| 501 } | 496 } |
| 502 | 497 |
| 503 | 498 |
| 504 Handle<Code> RegExpImpl::IrregexpNativeCode(Handle<FixedArray> re, | 499 Code* RegExpImpl::IrregexpNativeCode(FixedArray* re, bool is_ascii) { |
| 505 bool is_ascii) { | |
| 506 int index; | 500 int index; |
| 507 if (is_ascii) { | 501 if (is_ascii) { |
| 508 index = JSRegExp::kIrregexpASCIICodeIndex; | 502 index = JSRegExp::kIrregexpASCIICodeIndex; |
| 509 } else { | 503 } else { |
| 510 index = JSRegExp::kIrregexpUC16CodeIndex; | 504 index = JSRegExp::kIrregexpUC16CodeIndex; |
| 511 } | 505 } |
| 512 Object* value = re->get(index); | 506 return Code::cast(re->get(index)); |
| 513 ASSERT(value->IsCode()); | |
| 514 return Handle<Code>(Code::cast(value)); | |
| 515 } | 507 } |
| 516 | 508 |
| 517 | 509 |
| 518 void RegExpImpl::IrregexpPrepare(Handle<JSRegExp> re, | 510 void RegExpImpl::IrregexpPrepare(Handle<JSRegExp> re, |
| 519 Handle<String> pattern, | 511 Handle<String> pattern, |
| 520 JSRegExp::Flags flags, | 512 JSRegExp::Flags flags, |
| 521 int capture_count) { | 513 int capture_count) { |
| 522 // Initialize compiled code entries to null. | 514 // Initialize compiled code entries to null. |
| 523 Factory::SetRegExpIrregexpData(re, | 515 Factory::SetRegExpIrregexpData(re, |
| 524 JSRegExp::IRREGEXP, | 516 JSRegExp::IRREGEXP, |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 535 ASSERT_EQ(regexp->TypeTag(), JSRegExp::IRREGEXP); | 527 ASSERT_EQ(regexp->TypeTag(), JSRegExp::IRREGEXP); |
| 536 | 528 |
| 537 bool is_ascii = StringShape(*subject).IsAsciiRepresentation(); | 529 bool is_ascii = StringShape(*subject).IsAsciiRepresentation(); |
| 538 if (!EnsureCompiledIrregexp(regexp, is_ascii)) { | 530 if (!EnsureCompiledIrregexp(regexp, is_ascii)) { |
| 539 return Handle<Object>::null(); | 531 return Handle<Object>::null(); |
| 540 } | 532 } |
| 541 | 533 |
| 542 // Prepare space for the return values. | 534 // Prepare space for the return values. |
| 543 Handle<FixedArray> re_data(FixedArray::cast(regexp->data())); | 535 Handle<FixedArray> re_data(FixedArray::cast(regexp->data())); |
| 544 int number_of_capture_registers = | 536 int number_of_capture_registers = |
| 545 (IrregexpNumberOfCaptures(re_data) + 1) * 2; | 537 (IrregexpNumberOfCaptures(*re_data) + 1) * 2; |
| 546 OffsetsVector offsets(number_of_capture_registers); | 538 OffsetsVector offsets(number_of_capture_registers); |
| 547 | 539 |
| 548 int previous_index = index; | 540 int previous_index = index; |
| 549 | 541 |
| 550 #ifdef DEBUG | 542 #ifdef DEBUG |
| 551 if (FLAG_trace_regexp_bytecodes) { | 543 if (FLAG_trace_regexp_bytecodes) { |
| 552 String* pattern = regexp->Pattern(); | 544 String* pattern = regexp->Pattern(); |
| 553 PrintF("\n\nRegexp match: /%s/\n\n", *(pattern->ToCString())); | 545 PrintF("\n\nRegexp match: /%s/\n\n", *(pattern->ToCString())); |
| 554 PrintF("\n\nSubject string: '%s'\n\n", *(subject->ToCString())); | 546 PrintF("\n\nSubject string: '%s'\n\n", *(subject->ToCString())); |
| 555 } | 547 } |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 577 ASSERT_EQ(regexp->TypeTag(), JSRegExp::IRREGEXP); | 569 ASSERT_EQ(regexp->TypeTag(), JSRegExp::IRREGEXP); |
| 578 Handle<FixedArray> irregexp(FixedArray::cast(regexp->data())); | 570 Handle<FixedArray> irregexp(FixedArray::cast(regexp->data())); |
| 579 | 571 |
| 580 bool is_ascii = StringShape(*subject).IsAsciiRepresentation(); | 572 bool is_ascii = StringShape(*subject).IsAsciiRepresentation(); |
| 581 if (!EnsureCompiledIrregexp(regexp, is_ascii)) { | 573 if (!EnsureCompiledIrregexp(regexp, is_ascii)) { |
| 582 return Handle<Object>::null(); | 574 return Handle<Object>::null(); |
| 583 } | 575 } |
| 584 | 576 |
| 585 // Prepare space for the return values. | 577 // Prepare space for the return values. |
| 586 int number_of_capture_registers = | 578 int number_of_capture_registers = |
| 587 (IrregexpNumberOfCaptures(irregexp) + 1) * 2; | 579 (IrregexpNumberOfCaptures(*irregexp) + 1) * 2; |
| 588 OffsetsVector offsets(number_of_capture_registers); | 580 OffsetsVector offsets(number_of_capture_registers); |
| 589 | 581 |
| 590 int previous_index = 0; | 582 int previous_index = 0; |
| 591 | 583 |
| 592 Handle<JSArray> result = Factory::NewJSArray(0); | 584 Handle<JSArray> result = Factory::NewJSArray(0); |
| 593 int result_length = 0; | 585 int result_length = 0; |
| 594 Handle<Object> matches; | 586 Handle<Object> matches; |
| 595 | 587 |
| 596 if (!subject->IsFlat(StringShape(*subject))) { | 588 if (!subject->IsFlat(StringShape(*subject))) { |
| 597 FlattenString(subject); | 589 FlattenString(subject); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 663 int previous_index, | 655 int previous_index, |
| 664 int* offsets_vector, | 656 int* offsets_vector, |
| 665 int offsets_vector_length) { | 657 int offsets_vector_length) { |
| 666 StringShape shape(*subject); | 658 StringShape shape(*subject); |
| 667 ASSERT(subject->IsFlat(shape)); | 659 ASSERT(subject->IsFlat(shape)); |
| 668 bool is_ascii = shape.IsAsciiRepresentation(); | 660 bool is_ascii = shape.IsAsciiRepresentation(); |
| 669 bool rc; | 661 bool rc; |
| 670 | 662 |
| 671 if (FLAG_regexp_native) { | 663 if (FLAG_regexp_native) { |
| 672 #ifndef ARM | 664 #ifndef ARM |
| 673 Handle<Code> code(IrregexpNativeCode(regexp, is_ascii)); | 665 Handle<Code> code(IrregexpNativeCode(*regexp, is_ascii)); |
| 674 | 666 |
| 675 // Character offsets into string. | 667 // Character offsets into string. |
| 676 int start_offset = previous_index; | 668 int start_offset = previous_index; |
| 677 int end_offset = subject->length(shape); | 669 int end_offset = subject->length(shape); |
| 678 | 670 |
| 679 if (shape.IsCons()) { | 671 if (shape.IsCons()) { |
| 680 subject = Handle<String>(ConsString::cast(*subject)->first()); | 672 subject = Handle<String>(ConsString::cast(*subject)->first()); |
| 681 } else if (shape.IsSliced()) { | 673 } else if (shape.IsSliced()) { |
| 682 SlicedString* slice = SlicedString::cast(*subject); | 674 SlicedString* slice = SlicedString::cast(*subject); |
| 683 start_offset += slice->start(); | 675 start_offset += slice->start(); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 739 } | 731 } |
| 740 } else { | 732 } else { |
| 741 #else | 733 #else |
| 742 // Unimplemented on ARM, fall through to bytecode. | 734 // Unimplemented on ARM, fall through to bytecode. |
| 743 } | 735 } |
| 744 { | 736 { |
| 745 #endif | 737 #endif |
| 746 for (int i = number_of_capture_registers - 1; i >= 0; i--) { | 738 for (int i = number_of_capture_registers - 1; i >= 0; i--) { |
| 747 offsets_vector[i] = -1; | 739 offsets_vector[i] = -1; |
| 748 } | 740 } |
| 749 Handle<ByteArray> byte_codes = IrregexpByteCode(regexp, is_ascii); | 741 Handle<ByteArray> byte_codes(IrregexpByteCode(*regexp, is_ascii)); |
| 750 | 742 |
| 751 rc = IrregexpInterpreter::Match(byte_codes, | 743 rc = IrregexpInterpreter::Match(byte_codes, |
| 752 subject, | 744 subject, |
| 753 offsets_vector, | 745 offsets_vector, |
| 754 previous_index); | 746 previous_index); |
| 755 } | 747 } |
| 756 | 748 |
| 757 if (!rc) { | 749 if (!rc) { |
| 758 return Factory::null_value(); | 750 return Factory::null_value(); |
| 759 } | 751 } |
| (...skipping 3979 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4739 EmbeddedVector<byte, 1024> codes; | 4731 EmbeddedVector<byte, 1024> codes; |
| 4740 RegExpMacroAssemblerIrregexp macro_assembler(codes); | 4732 RegExpMacroAssemblerIrregexp macro_assembler(codes); |
| 4741 return compiler.Assemble(¯o_assembler, | 4733 return compiler.Assemble(¯o_assembler, |
| 4742 node, | 4734 node, |
| 4743 data->capture_count, | 4735 data->capture_count, |
| 4744 pattern); | 4736 pattern); |
| 4745 } | 4737 } |
| 4746 | 4738 |
| 4747 | 4739 |
| 4748 }} // namespace v8::internal | 4740 }} // namespace v8::internal |
| OLD | NEW |