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 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
397 | 397 |
398 | 398 |
399 Handle<Object> RegExpImpl::IrregexpExec(Handle<JSRegExp> jsregexp, | 399 Handle<Object> RegExpImpl::IrregexpExec(Handle<JSRegExp> jsregexp, |
400 Handle<String> subject, | 400 Handle<String> subject, |
401 int previous_index, | 401 int previous_index, |
402 Handle<JSArray> last_match_info) { | 402 Handle<JSArray> last_match_info) { |
403 ASSERT_EQ(jsregexp->TypeTag(), JSRegExp::IRREGEXP); | 403 ASSERT_EQ(jsregexp->TypeTag(), JSRegExp::IRREGEXP); |
404 | 404 |
405 // Prepare space for the return values. | 405 // Prepare space for the return values. |
406 int number_of_capture_registers = | 406 int number_of_capture_registers = |
407 UseNativeRegexp() ? | 407 (IrregexpNumberOfCaptures(FixedArray::cast(jsregexp->data())) + 1) * 2; |
408 (IrregexpNumberOfCaptures(FixedArray::cast(jsregexp->data())) + 1) * 2 : | |
409 IrregexpNumberOfRegisters(FixedArray::cast(jsregexp->data())); | |
410 OffsetsVector offsets(number_of_capture_registers); | |
411 | 408 |
412 #ifdef DEBUG | 409 #ifdef DEBUG |
413 if (FLAG_trace_regexp_bytecodes) { | 410 if (FLAG_trace_regexp_bytecodes) { |
414 String* pattern = jsregexp->Pattern(); | 411 String* pattern = jsregexp->Pattern(); |
415 PrintF("\n\nRegexp match: /%s/\n\n", *(pattern->ToCString())); | 412 PrintF("\n\nRegexp match: /%s/\n\n", *(pattern->ToCString())); |
416 PrintF("\n\nSubject string: '%s'\n\n", *(subject->ToCString())); | 413 PrintF("\n\nSubject string: '%s'\n\n", *(subject->ToCString())); |
417 } | 414 } |
418 #endif | 415 #endif |
419 | 416 |
420 if (!subject->IsFlat()) { | 417 if (!subject->IsFlat()) { |
421 FlattenString(subject); | 418 FlattenString(subject); |
422 } | 419 } |
423 | 420 |
424 last_match_info->EnsureSize(number_of_capture_registers + kLastMatchOverhead); | 421 last_match_info->EnsureSize(number_of_capture_registers + kLastMatchOverhead); |
425 | 422 |
426 int* offsets_vector = offsets.vector(); | |
427 bool rc; | 423 bool rc; |
| 424 FixedArray* array; |
428 | 425 |
429 // Dispatch to the correct RegExp implementation. | 426 // Dispatch to the correct RegExp implementation. |
430 | |
431 Handle<String> original_subject = subject; | 427 Handle<String> original_subject = subject; |
432 Handle<FixedArray> regexp(FixedArray::cast(jsregexp->data())); | 428 Handle<FixedArray> regexp(FixedArray::cast(jsregexp->data())); |
433 if (UseNativeRegexp()) { | 429 if (UseNativeRegexp()) { |
434 #if V8_TARGET_ARCH_IA32 | 430 #if V8_TARGET_ARCH_IA32 |
| 431 OffsetsVector captures(number_of_capture_registers); |
| 432 int* captures_vector = captures.vector(); |
435 RegExpMacroAssemblerIA32::Result res; | 433 RegExpMacroAssemblerIA32::Result res; |
436 do { | 434 do { |
437 bool is_ascii = subject->IsAsciiRepresentation(); | 435 bool is_ascii = subject->IsAsciiRepresentation(); |
438 if (!EnsureCompiledIrregexp(jsregexp, is_ascii)) { | 436 if (!EnsureCompiledIrregexp(jsregexp, is_ascii)) { |
439 return Handle<Object>::null(); | 437 return Handle<Object>::null(); |
440 } | 438 } |
441 Handle<Code> code(RegExpImpl::IrregexpNativeCode(*regexp, is_ascii)); | 439 Handle<Code> code(RegExpImpl::IrregexpNativeCode(*regexp, is_ascii)); |
442 res = RegExpMacroAssemblerIA32::Match(code, | 440 res = RegExpMacroAssemblerIA32::Match(code, |
443 subject, | 441 subject, |
444 offsets_vector, | 442 captures_vector, |
445 offsets.length(), | 443 captures.length(), |
446 previous_index); | 444 previous_index); |
447 // If result is RETRY, the string have changed representation, and we | 445 // If result is RETRY, the string have changed representation, and we |
448 // must restart from scratch. | 446 // must restart from scratch. |
449 } while (res == RegExpMacroAssemblerIA32::RETRY); | 447 } while (res == RegExpMacroAssemblerIA32::RETRY); |
450 if (res == RegExpMacroAssemblerIA32::EXCEPTION) { | 448 if (res == RegExpMacroAssemblerIA32::EXCEPTION) { |
451 ASSERT(Top::has_pending_exception()); | 449 ASSERT(Top::has_pending_exception()); |
452 return Handle<Object>::null(); | 450 return Handle<Object>::null(); |
453 } | 451 } |
454 ASSERT(res == RegExpMacroAssemblerIA32::SUCCESS | 452 ASSERT(res == RegExpMacroAssemblerIA32::SUCCESS |
455 || res == RegExpMacroAssemblerIA32::FAILURE); | 453 || res == RegExpMacroAssemblerIA32::FAILURE); |
456 | 454 |
457 rc = (res == RegExpMacroAssemblerIA32::SUCCESS); | 455 rc = (res == RegExpMacroAssemblerIA32::SUCCESS); |
458 #else | 456 if (!rc) return Factory::null_value(); |
| 457 |
| 458 array = last_match_info->elements(); |
| 459 ASSERT(array->length() >= number_of_capture_registers + kLastMatchOverhead); |
| 460 // The captures come in (start, end+1) pairs. |
| 461 for (int i = 0; i < number_of_capture_registers; i += 2) { |
| 462 SetCapture(array, i, captures_vector[i]); |
| 463 SetCapture(array, i + 1, captures_vector[i + 1]); |
| 464 } |
| 465 #else // !V8_TARGET_ARCH_IA32 |
459 UNREACHABLE(); | 466 UNREACHABLE(); |
460 #endif | 467 #endif |
461 } else { | 468 } else { |
462 bool is_ascii = subject->IsAsciiRepresentation(); | 469 bool is_ascii = subject->IsAsciiRepresentation(); |
463 if (!EnsureCompiledIrregexp(jsregexp, is_ascii)) { | 470 if (!EnsureCompiledIrregexp(jsregexp, is_ascii)) { |
464 return Handle<Object>::null(); | 471 return Handle<Object>::null(); |
465 } | 472 } |
| 473 // Now that we have done EnsureCompiledIrregexp we can get the number of |
| 474 // registers. |
| 475 int number_of_registers = |
| 476 IrregexpNumberOfRegisters(FixedArray::cast(jsregexp->data())); |
| 477 OffsetsVector registers(number_of_registers); |
| 478 int* register_vector = registers.vector(); |
466 for (int i = number_of_capture_registers - 1; i >= 0; i--) { | 479 for (int i = number_of_capture_registers - 1; i >= 0; i--) { |
467 offsets_vector[i] = -1; | 480 register_vector[i] = -1; |
468 } | 481 } |
469 Handle<ByteArray> byte_codes(IrregexpByteCode(*regexp, is_ascii)); | 482 Handle<ByteArray> byte_codes(IrregexpByteCode(*regexp, is_ascii)); |
470 | 483 |
471 rc = IrregexpInterpreter::Match(byte_codes, | 484 rc = IrregexpInterpreter::Match(byte_codes, |
472 subject, | 485 subject, |
473 offsets_vector, | 486 register_vector, |
474 previous_index); | 487 previous_index); |
| 488 if (!rc) return Factory::null_value(); |
| 489 |
| 490 array = last_match_info->elements(); |
| 491 ASSERT(array->length() >= number_of_capture_registers + kLastMatchOverhead); |
| 492 // The captures come in (start, end+1) pairs. |
| 493 for (int i = 0; i < number_of_capture_registers; i += 2) { |
| 494 SetCapture(array, i, register_vector[i]); |
| 495 SetCapture(array, i + 1, register_vector[i + 1]); |
| 496 } |
475 } | 497 } |
476 | 498 |
477 // Handle results from RegExp implementation. | |
478 | |
479 if (!rc) { | |
480 return Factory::null_value(); | |
481 } | |
482 | |
483 FixedArray* array = last_match_info->elements(); | |
484 ASSERT(array->length() >= number_of_capture_registers + kLastMatchOverhead); | |
485 // The captures come in (start, end+1) pairs. | |
486 SetLastCaptureCount(array, number_of_capture_registers); | 499 SetLastCaptureCount(array, number_of_capture_registers); |
487 SetLastSubject(array, *original_subject); | 500 SetLastSubject(array, *original_subject); |
488 SetLastInput(array, *original_subject); | 501 SetLastInput(array, *original_subject); |
489 for (int i = 0; i < number_of_capture_registers; i+=2) { | 502 |
490 SetCapture(array, i, offsets_vector[i]); | |
491 SetCapture(array, i + 1, offsets_vector[i + 1]); | |
492 } | |
493 return last_match_info; | 503 return last_match_info; |
494 } | 504 } |
495 | 505 |
496 | 506 |
497 // ------------------------------------------------------------------- | 507 // ------------------------------------------------------------------- |
498 // Implementation of the Irregexp regular expression engine. | 508 // Implementation of the Irregexp regular expression engine. |
499 // | 509 // |
500 // The Irregexp regular expression engine is intended to be a complete | 510 // The Irregexp regular expression engine is intended to be a complete |
501 // implementation of ECMAScript regular expressions. It generates either | 511 // implementation of ECMAScript regular expressions. It generates either |
502 // bytecodes or native code. | 512 // bytecodes or native code. |
(...skipping 3981 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4484 EmbeddedVector<byte, 1024> codes; | 4494 EmbeddedVector<byte, 1024> codes; |
4485 RegExpMacroAssemblerIrregexp macro_assembler(codes); | 4495 RegExpMacroAssemblerIrregexp macro_assembler(codes); |
4486 return compiler.Assemble(¯o_assembler, | 4496 return compiler.Assemble(¯o_assembler, |
4487 node, | 4497 node, |
4488 data->capture_count, | 4498 data->capture_count, |
4489 pattern); | 4499 pattern); |
4490 } | 4500 } |
4491 | 4501 |
4492 | 4502 |
4493 }} // namespace v8::internal | 4503 }} // namespace v8::internal |
OLD | NEW |