| 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 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 213 Handle<String> needle(String::cast(re->data())); | 213 Handle<String> needle(String::cast(re->data())); |
| 214 | 214 |
| 215 uint32_t start_index; | 215 uint32_t start_index; |
| 216 if (!Array::IndexFromObject(*index, &start_index)) { | 216 if (!Array::IndexFromObject(*index, &start_index)) { |
| 217 return Handle<Smi>(Smi::FromInt(-1)); | 217 return Handle<Smi>(Smi::FromInt(-1)); |
| 218 } | 218 } |
| 219 | 219 |
| 220 LOG(RegExpExecEvent(re, start_index, subject)); | 220 LOG(RegExpExecEvent(re, start_index, subject)); |
| 221 int value = Runtime::StringMatch(subject, needle, start_index); | 221 int value = Runtime::StringMatch(subject, needle, start_index); |
| 222 if (value == -1) return Factory::null_value(); | 222 if (value == -1) return Factory::null_value(); |
| 223 Handle<JSArray> result = Factory::NewJSArray(2); | 223 |
| 224 SetElement(result, 0, Handle<Smi>(Smi::FromInt(value))); | 224 Handle<FixedArray> array = Factory::NewFixedArray(2); |
| 225 SetElement(result, 1, Handle<Smi>(Smi::FromInt(value + needle->length()))); | 225 array->set(0, Smi::FromInt(value)); |
| 226 return result; | 226 array->set(1, Smi::FromInt(value + needle->length())); |
| 227 return Factory::NewJSArrayWithElements(array); |
| 227 } | 228 } |
| 228 | 229 |
| 229 | 230 |
| 230 Handle<Object> RegExpImpl::AtomExecGlobal(Handle<JSRegExp> re, | 231 Handle<Object> RegExpImpl::AtomExecGlobal(Handle<JSRegExp> re, |
| 231 Handle<String> subject) { | 232 Handle<String> subject) { |
| 232 Handle<String> needle(String::cast(re->data())); | 233 Handle<String> needle(String::cast(re->data())); |
| 233 Handle<JSArray> result = Factory::NewJSArray(1); | 234 Handle<JSArray> result = Factory::NewJSArray(1); |
| 234 int index = 0; | 235 int index = 0; |
| 235 int match_count = 0; | 236 int match_count = 0; |
| 236 int subject_length = subject->length(); | 237 int subject_length = subject->length(); |
| 237 int needle_length = needle->length(); | 238 int needle_length = needle->length(); |
| 238 while (true) { | 239 while (true) { |
| 239 LOG(RegExpExecEvent(re, index, subject)); | 240 LOG(RegExpExecEvent(re, index, subject)); |
| 240 int value = -1; | 241 int value = -1; |
| 241 if (index + needle_length <= subject_length) { | 242 if (index + needle_length <= subject_length) { |
| 242 value = Runtime::StringMatch(subject, needle, index); | 243 value = Runtime::StringMatch(subject, needle, index); |
| 243 } | 244 } |
| 244 if (value == -1) break; | 245 if (value == -1) break; |
| 245 HandleScope scope; | 246 HandleScope scope; |
| 246 int end = value + needle_length; | 247 int end = value + needle_length; |
| 247 Handle<JSArray> pair = Factory::NewJSArray(2); | 248 |
| 248 SetElement(pair, 0, Handle<Smi>(Smi::FromInt(value))); | 249 Handle<FixedArray> array = Factory::NewFixedArray(2); |
| 249 SetElement(pair, 1, Handle<Smi>(Smi::FromInt(end))); | 250 array->set(0, Smi::FromInt(value)); |
| 251 array->set(1, Smi::FromInt(end)); |
| 252 Handle<JSArray> pair = Factory::NewJSArrayWithElements(array); |
| 250 SetElement(result, match_count, pair); | 253 SetElement(result, match_count, pair); |
| 251 match_count++; | 254 match_count++; |
| 252 index = end; | 255 index = end; |
| 253 if (needle_length == 0) | 256 if (needle_length == 0) index++; |
| 254 index++; | |
| 255 } | 257 } |
| 256 return result; | 258 return result; |
| 257 } | 259 } |
| 258 | 260 |
| 259 | 261 |
| 260 Handle<Object> RegExpImpl::JsreCompile(Handle<JSRegExp> re, | 262 Handle<Object> RegExpImpl::JsreCompile(Handle<JSRegExp> re, |
| 261 Handle<String> pattern, | 263 Handle<String> pattern, |
| 262 Handle<String> flags) { | 264 Handle<String> flags) { |
| 263 JSRegExpIgnoreCaseOption case_option = JSRegExpDoNotIgnoreCase; | 265 JSRegExpIgnoreCaseOption case_option = JSRegExpDoNotIgnoreCase; |
| 264 JSRegExpMultilineOption multiline_option = JSRegExpSingleLine; | 266 JSRegExpMultilineOption multiline_option = JSRegExpSingleLine; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 304 SetElement(array, 0, pattern); | 306 SetElement(array, 0, pattern); |
| 305 SetElement(array, 1, Factory::NewStringFromUtf8(CStrVector( | 307 SetElement(array, 1, Factory::NewStringFromUtf8(CStrVector( |
| 306 (error_message == NULL) ? "Unknown regexp error" : error_message))); | 308 (error_message == NULL) ? "Unknown regexp error" : error_message))); |
| 307 Handle<Object> regexp_err = | 309 Handle<Object> regexp_err = |
| 308 Factory::NewSyntaxError("malformed_regexp", array); | 310 Factory::NewSyntaxError("malformed_regexp", array); |
| 309 return Handle<Object>(Top::Throw(*regexp_err)); | 311 return Handle<Object>(Top::Throw(*regexp_err)); |
| 310 } | 312 } |
| 311 } | 313 } |
| 312 | 314 |
| 313 ASSERT(code != NULL); | 315 ASSERT(code != NULL); |
| 314 | |
| 315 // Convert the return address to a ByteArray pointer. | 316 // Convert the return address to a ByteArray pointer. |
| 316 Handle<ByteArray> internal( | 317 Handle<ByteArray> internal( |
| 317 ByteArray::FromDataStartAddress(reinterpret_cast<Address>(code))); | 318 ByteArray::FromDataStartAddress(reinterpret_cast<Address>(code))); |
| 318 | 319 |
| 319 Handle<FixedArray> value = Factory::NewFixedArray(2); | 320 Handle<FixedArray> value = Factory::NewFixedArray(2); |
| 320 value->set(CAPTURE_INDEX, Smi::FromInt(number_of_captures)); | 321 value->set(CAPTURE_INDEX, Smi::FromInt(number_of_captures)); |
| 321 value->set(INTERNAL_INDEX, *internal); | 322 value->set(INTERNAL_INDEX, *internal); |
| 322 re->set_type_tag(JSRegExp::JSCRE); | 323 re->set_type_tag(JSRegExp::JSCRE); |
| 323 re->set_data(*value); | 324 re->set_data(*value); |
| 324 | 325 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 361 // Other JSRE errors: | 362 // Other JSRE errors: |
| 362 if (rc < 0) { | 363 if (rc < 0) { |
| 363 // Throw an exception. | 364 // Throw an exception. |
| 364 Handle<Object> code(Smi::FromInt(rc)); | 365 Handle<Object> code(Smi::FromInt(rc)); |
| 365 Handle<Object> args[2] = { Factory::LookupAsciiSymbol("jsre_exec"), code }; | 366 Handle<Object> args[2] = { Factory::LookupAsciiSymbol("jsre_exec"), code }; |
| 366 Handle<Object> regexp_err( | 367 Handle<Object> regexp_err( |
| 367 Factory::NewTypeError("jsre_error", HandleVector(args, 2))); | 368 Factory::NewTypeError("jsre_error", HandleVector(args, 2))); |
| 368 return Handle<Object>(Top::Throw(*regexp_err)); | 369 return Handle<Object>(Top::Throw(*regexp_err)); |
| 369 } | 370 } |
| 370 | 371 |
| 371 Handle<JSArray> result = Factory::NewJSArray(2 * (num_captures+1)); | 372 Handle<FixedArray> array = Factory::NewFixedArray(2 * (num_captures+1)); |
| 372 | |
| 373 // The captures come in (start, end+1) pairs. | 373 // The captures come in (start, end+1) pairs. |
| 374 for (int i = 0; i < 2 * (num_captures+1); i += 2) { | 374 for (int i = 0; i < 2 * (num_captures+1); i += 2) { |
| 375 SetElement(result, i, Handle<Object>(Smi::FromInt(offsets_vector[i]))); | 375 array->set(i, Smi::FromInt(offsets_vector[i])); |
| 376 SetElement(result, i+1, Handle<Object>(Smi::FromInt(offsets_vector[i+1]))); | 376 array->set(i+1, Smi::FromInt(offsets_vector[i+1])); |
| 377 } | 377 } |
| 378 return result; | 378 return Factory::NewJSArrayWithElements(array); |
| 379 } | 379 } |
| 380 | 380 |
| 381 | 381 |
| 382 class OffsetsVector { | 382 class OffsetsVector { |
| 383 public: | 383 public: |
| 384 inline OffsetsVector(int num_captures) { | 384 inline OffsetsVector(int num_captures) { |
| 385 offsets_vector_length_ = (num_captures + 1) * 3; | 385 offsets_vector_length_ = (num_captures + 1) * 3; |
| 386 if (offsets_vector_length_ > kStaticOffsetsVectorSize) { | 386 if (offsets_vector_length_ > kStaticOffsetsVectorSize) { |
| 387 vector_ = NewArray<int>(offsets_vector_length_); | 387 vector_ = NewArray<int>(offsets_vector_length_); |
| 388 } else { | 388 } else { |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 443 | 443 |
| 444 Handle<Object> RegExpImpl::JsreExecGlobal(Handle<JSRegExp> regexp, | 444 Handle<Object> RegExpImpl::JsreExecGlobal(Handle<JSRegExp> regexp, |
| 445 Handle<String> subject) { | 445 Handle<String> subject) { |
| 446 // Prepare space for the return values. | 446 // Prepare space for the return values. |
| 447 int num_captures = JsreCapture(regexp); | 447 int num_captures = JsreCapture(regexp); |
| 448 | 448 |
| 449 OffsetsVector offsets(num_captures); | 449 OffsetsVector offsets(num_captures); |
| 450 | 450 |
| 451 int previous_index = 0; | 451 int previous_index = 0; |
| 452 | 452 |
| 453 Handle<JSArray> result = Factory::NewJSArray(0); | 453 Handle<JSArray> result = Factory::NewJSArray(0); |
| 454 int i = 0; | 454 int i = 0; |
| 455 Handle<Object> matches; | 455 Handle<Object> matches; |
| 456 | 456 |
| 457 Handle<String> subject16 = CachedStringToTwoByte(subject); | 457 Handle<String> subject16 = CachedStringToTwoByte(subject); |
| 458 | 458 |
| 459 do { | 459 do { |
| 460 if (previous_index > subject->length() || previous_index < 0) { | 460 if (previous_index > subject->length() || previous_index < 0) { |
| 461 // Per ECMA-262 15.10.6.2, if the previous index is greater than the | 461 // Per ECMA-262 15.10.6.2, if the previous index is greater than the |
| 462 // string length, there is no match. | 462 // string length, there is no match. |
| 463 matches = Factory::null_value(); | 463 matches = Factory::null_value(); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 493 } | 493 } |
| 494 | 494 |
| 495 | 495 |
| 496 ByteArray* RegExpImpl::JsreInternal(Handle<JSRegExp> re) { | 496 ByteArray* RegExpImpl::JsreInternal(Handle<JSRegExp> re) { |
| 497 Object* value = re->data(); | 497 Object* value = re->data(); |
| 498 ASSERT(value->IsFixedArray()); | 498 ASSERT(value->IsFixedArray()); |
| 499 return ByteArray::cast(FixedArray::cast(value)->get(INTERNAL_INDEX)); | 499 return ByteArray::cast(FixedArray::cast(value)->get(INTERNAL_INDEX)); |
| 500 } | 500 } |
| 501 | 501 |
| 502 }} // namespace v8::internal | 502 }} // namespace v8::internal |
| OLD | NEW |