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 |