| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 | 302 |
| 303 | 303 |
| 304 Handle<Object> RegExpImpl::Exec(Handle<JSRegExp> regexp, | 304 Handle<Object> RegExpImpl::Exec(Handle<JSRegExp> regexp, |
| 305 Handle<String> subject, | 305 Handle<String> subject, |
| 306 Handle<Object> index) { | 306 Handle<Object> index) { |
| 307 switch (regexp->TypeTag()) { | 307 switch (regexp->TypeTag()) { |
| 308 case JSRegExp::ATOM: | 308 case JSRegExp::ATOM: |
| 309 return AtomExec(regexp, subject, index); | 309 return AtomExec(regexp, subject, index); |
| 310 case JSRegExp::IRREGEXP: { | 310 case JSRegExp::IRREGEXP: { |
| 311 Handle<Object> result = IrregexpExec(regexp, subject, index); | 311 Handle<Object> result = IrregexpExec(regexp, subject, index); |
| 312 if (!result.is_null()) { | 312 if (!result.is_null() || Top::has_pending_exception()) { |
| 313 return result; | 313 return result; |
| 314 } | 314 } |
| 315 // We couldn't handle the regexp using Irregexp, so fall back | 315 // We couldn't handle the regexp using Irregexp, so fall back |
| 316 // on JSCRE. | 316 // on JSCRE. |
| 317 // Reset the JSRegExp to use JSCRE. | 317 // Reset the JSRegExp to use JSCRE. |
| 318 JscrePrepare(regexp, | 318 JscrePrepare(regexp, |
| 319 Handle<String>(regexp->Pattern()), | 319 Handle<String>(regexp->Pattern()), |
| 320 regexp->GetFlags()); | 320 regexp->GetFlags()); |
| 321 // Fall-through to JSCRE. | 321 // Fall-through to JSCRE. |
| 322 } | 322 } |
| 323 case JSRegExp::JSCRE: | 323 case JSRegExp::JSCRE: |
| 324 if (FLAG_disable_jscre) { | 324 if (FLAG_disable_jscre) { |
| 325 UNIMPLEMENTED(); | 325 UNIMPLEMENTED(); |
| 326 } | 326 } |
| 327 return JscreExec(regexp, subject, index); | 327 return JscreExec(regexp, subject, index); |
| 328 default: | 328 default: |
| 329 UNREACHABLE(); | 329 UNREACHABLE(); |
| 330 return Handle<Object>::null(); | 330 return Handle<Object>::null(); |
| 331 } | 331 } |
| 332 } | 332 } |
| 333 | 333 |
| 334 | 334 |
| 335 Handle<Object> RegExpImpl::ExecGlobal(Handle<JSRegExp> regexp, | 335 Handle<Object> RegExpImpl::ExecGlobal(Handle<JSRegExp> regexp, |
| 336 Handle<String> subject) { | 336 Handle<String> subject) { |
| 337 switch (regexp->TypeTag()) { | 337 switch (regexp->TypeTag()) { |
| 338 case JSRegExp::ATOM: | 338 case JSRegExp::ATOM: |
| 339 return AtomExecGlobal(regexp, subject); | 339 return AtomExecGlobal(regexp, subject); |
| 340 case JSRegExp::IRREGEXP: { | 340 case JSRegExp::IRREGEXP: { |
| 341 Handle<Object> result = IrregexpExecGlobal(regexp, subject); | 341 Handle<Object> result = IrregexpExecGlobal(regexp, subject); |
| 342 if (!result.is_null()) { | 342 if (!result.is_null() || Top::has_pending_exception()) { |
| 343 return result; | 343 return result; |
| 344 } | 344 } |
| 345 // We couldn't handle the regexp using Irregexp, so fall back | 345 // Empty handle as result but no exception thrown means that |
| 346 // on JSCRE. | 346 // the regexp contains features not yet handled by the irregexp |
| 347 // Reset the JSRegExp to use JSCRE. | 347 // compiler. |
| 348 // We have to fall back on JSCRE. Reset the JSRegExp to use JSCRE. |
| 348 JscrePrepare(regexp, | 349 JscrePrepare(regexp, |
| 349 Handle<String>(regexp->Pattern()), | 350 Handle<String>(regexp->Pattern()), |
| 350 regexp->GetFlags()); | 351 regexp->GetFlags()); |
| 351 // Fall-through to JSCRE. | 352 // Fall-through to JSCRE. |
| 352 } | 353 } |
| 353 case JSRegExp::JSCRE: | 354 case JSRegExp::JSCRE: |
| 354 if (FLAG_disable_jscre) { | 355 if (FLAG_disable_jscre) { |
| 355 UNIMPLEMENTED(); | 356 UNIMPLEMENTED(); |
| 356 } | 357 } |
| 357 return JscreExecGlobal(regexp, subject); | 358 return JscreExecGlobal(regexp, subject); |
| (...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 676 } else { | 677 } else { |
| 677 // Exited loop with the exception in matches. | 678 // Exited loop with the exception in matches. |
| 678 return matches; | 679 return matches; |
| 679 } | 680 } |
| 680 } | 681 } |
| 681 | 682 |
| 682 | 683 |
| 683 // Irregexp implementation. | 684 // Irregexp implementation. |
| 684 | 685 |
| 685 | 686 |
| 687 // Retrieves a compiled version of the regexp for either ASCII or non-ASCII |
| 688 // strings. If the compiled version doesn't already exist, it is compiled |
| 689 // from the source pattern. |
| 690 // Irregexp is not feature complete yet. If there is something in the |
| 691 // regexp that the compiler cannot currently handle, an empty |
| 692 // handle is returned, but no exception is thrown. |
| 686 static Handle<FixedArray> GetCompiledIrregexp(Handle<JSRegExp> re, | 693 static Handle<FixedArray> GetCompiledIrregexp(Handle<JSRegExp> re, |
| 687 bool is_ascii) { | 694 bool is_ascii) { |
| 688 ASSERT(re->DataAt(JSRegExp::kIrregexpDataIndex)->IsFixedArray()); | 695 ASSERT(re->DataAt(JSRegExp::kIrregexpDataIndex)->IsFixedArray()); |
| 689 Handle<FixedArray> alternatives( | 696 Handle<FixedArray> alternatives( |
| 690 FixedArray::cast(re->DataAt(JSRegExp::kIrregexpDataIndex))); | 697 FixedArray::cast(re->DataAt(JSRegExp::kIrregexpDataIndex))); |
| 691 ASSERT_EQ(2, alternatives->length()); | 698 ASSERT_EQ(2, alternatives->length()); |
| 692 | 699 |
| 693 int index = is_ascii ? 0 : 1; | 700 int index = is_ascii ? 0 : 1; |
| 694 Object* entry = alternatives->get(index); | 701 Object* entry = alternatives->get(index); |
| 695 if (!entry->IsNull()) { | 702 if (!entry->IsNull()) { |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 905 start_offset += slice->start(); | 912 start_offset += slice->start(); |
| 906 end_offset += slice->start(); | 913 end_offset += slice->start(); |
| 907 subject = Handle<String>(slice->buffer()); | 914 subject = Handle<String>(slice->buffer()); |
| 908 } | 915 } |
| 909 | 916 |
| 910 // String is now either Sequential or External | 917 // String is now either Sequential or External |
| 911 StringShape flatshape(*subject); | 918 StringShape flatshape(*subject); |
| 912 bool is_ascii = flatshape.IsAsciiRepresentation(); | 919 bool is_ascii = flatshape.IsAsciiRepresentation(); |
| 913 int char_size_shift = is_ascii ? 0 : 1; | 920 int char_size_shift = is_ascii ? 0 : 1; |
| 914 | 921 |
| 922 RegExpMacroAssemblerIA32::Result res; |
| 923 |
| 915 if (flatshape.IsExternal()) { | 924 if (flatshape.IsExternal()) { |
| 916 const byte* address; | 925 const byte* address; |
| 917 if (is_ascii) { | 926 if (is_ascii) { |
| 918 ExternalAsciiString* ext = ExternalAsciiString::cast(*subject); | 927 ExternalAsciiString* ext = ExternalAsciiString::cast(*subject); |
| 919 address = reinterpret_cast<const byte*>(ext->resource()->data()); | 928 address = reinterpret_cast<const byte*>(ext->resource()->data()); |
| 920 } else { | 929 } else { |
| 921 ExternalTwoByteString* ext = ExternalTwoByteString::cast(*subject); | 930 ExternalTwoByteString* ext = ExternalTwoByteString::cast(*subject); |
| 922 address = reinterpret_cast<const byte*>(ext->resource()->data()); | 931 address = reinterpret_cast<const byte*>(ext->resource()->data()); |
| 923 } | 932 } |
| 924 rc = RegExpMacroAssemblerIA32::Execute( | 933 res = RegExpMacroAssemblerIA32::Execute( |
| 925 *code, | 934 *code, |
| 926 &address, | 935 &address, |
| 927 start_offset << char_size_shift, | 936 start_offset << char_size_shift, |
| 928 end_offset << char_size_shift, | 937 end_offset << char_size_shift, |
| 929 offsets_vector, | 938 offsets_vector, |
| 930 previous_index == 0); | 939 previous_index == 0); |
| 931 } else { // Sequential string | 940 } else { // Sequential string |
| 932 Address char_address = | 941 Address char_address = |
| 933 is_ascii ? SeqAsciiString::cast(*subject)->GetCharsAddress() | 942 is_ascii ? SeqAsciiString::cast(*subject)->GetCharsAddress() |
| 934 : SeqTwoByteString::cast(*subject)->GetCharsAddress(); | 943 : SeqTwoByteString::cast(*subject)->GetCharsAddress(); |
| 935 int byte_offset = char_address - reinterpret_cast<Address>(*subject); | 944 int byte_offset = char_address - reinterpret_cast<Address>(*subject); |
| 936 rc = RegExpMacroAssemblerIA32::Execute( | 945 res = RegExpMacroAssemblerIA32::Execute( |
| 937 *code, | 946 *code, |
| 938 subject.location(), | 947 subject.location(), |
| 939 byte_offset + (start_offset << char_size_shift), | 948 byte_offset + (start_offset << char_size_shift), |
| 940 byte_offset + (end_offset << char_size_shift), | 949 byte_offset + (end_offset << char_size_shift), |
| 941 offsets_vector, | 950 offsets_vector, |
| 942 previous_index == 0); | 951 previous_index == 0); |
| 943 } | 952 } |
| 944 | 953 |
| 954 if (res == RegExpMacroAssemblerIA32::EXCEPTION) { |
| 955 ASSERT(Top::has_pending_exception()); |
| 956 return Handle<Object>::null(); |
| 957 } |
| 958 rc = (res == RegExpMacroAssemblerIA32::SUCCESS); |
| 959 |
| 945 if (rc) { | 960 if (rc) { |
| 946 // Capture values are relative to start_offset only. | 961 // Capture values are relative to start_offset only. |
| 947 for (int i = 0; i < offsets_vector_length; i++) { | 962 for (int i = 0; i < offsets_vector_length; i++) { |
| 948 if (offsets_vector[i] >= 0) { | 963 if (offsets_vector[i] >= 0) { |
| 949 offsets_vector[i] += previous_index; | 964 offsets_vector[i] += previous_index; |
| 950 } | 965 } |
| 951 } | 966 } |
| 952 } | 967 } |
| 953 break; | 968 break; |
| 954 #else | 969 #else |
| (...skipping 2877 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3832 EmbeddedVector<byte, 1024> codes; | 3847 EmbeddedVector<byte, 1024> codes; |
| 3833 RegExpMacroAssemblerIrregexp macro_assembler(codes); | 3848 RegExpMacroAssemblerIrregexp macro_assembler(codes); |
| 3834 return compiler.Assemble(¯o_assembler, | 3849 return compiler.Assemble(¯o_assembler, |
| 3835 node, | 3850 node, |
| 3836 data->capture_count, | 3851 data->capture_count, |
| 3837 pattern); | 3852 pattern); |
| 3838 } | 3853 } |
| 3839 | 3854 |
| 3840 | 3855 |
| 3841 }} // namespace v8::internal | 3856 }} // namespace v8::internal |
| OLD | NEW |