| 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 |
| 11 // with the distribution. | 11 // with the distribution. |
| 12 // * Neither the name of Google Inc. nor the names of its | 12 // * Neither the name of Google Inc. nor the names of its |
| 13 // contributors may be used to endorse or promote products derived | 13 // contributors may be used to endorse or promote products derived |
| 14 // from this software without specific prior written permission. | 14 // from this software without specific prior written permission. |
| 15 // | 15 // |
| 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 | 28 |
| 29 #include <stdlib.h> |
| 30 |
| 29 #include "v8.h" | 31 #include "v8.h" |
| 30 | 32 |
| 31 #include "cctest.h" | 33 #include "cctest.h" |
| 32 #include "zone-inl.h" | 34 #include "zone-inl.h" |
| 33 #include "parser.h" | 35 #include "parser.h" |
| 34 #include "ast.h" | 36 #include "ast.h" |
| 35 #include "jsregexp.h" | 37 #include "jsregexp-inl.h" |
| 36 | 38 |
| 37 | 39 |
| 38 using namespace v8::internal; | 40 using namespace v8::internal; |
| 39 | 41 |
| 40 | 42 |
| 41 class RegExpTestCase { | 43 class RegExpTestCase { |
| 42 public: | 44 public: |
| 43 RegExpTestCase() | 45 RegExpTestCase() |
| 44 : pattern_(NULL), | 46 : pattern_(NULL), |
| 45 flags_(NULL), | 47 flags_(NULL), |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 261 CHECK(node == NULL); | 263 CHECK(node == NULL); |
| 262 CHECK(!error.is_null()); | 264 CHECK(!error.is_null()); |
| 263 } else { | 265 } else { |
| 264 CHECK(node != NULL); | 266 CHECK(node != NULL); |
| 265 CHECK(error.is_null()); | 267 CHECK(error.is_null()); |
| 266 } | 268 } |
| 267 } | 269 } |
| 268 } | 270 } |
| 269 | 271 |
| 270 | 272 |
| 271 // "123456789abcdb".match(/(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(\11)/) | 273 TEST(SingletonField) { |
| 272 // 123456789abcdb,1,2,3,4,5,6,7,8,9,a,b,c,d,b | 274 // Test all bits from 0 to 256 |
| 275 for (int i = 0; i < 256; i++) { |
| 276 CharacterClass entry = CharacterClass::SingletonField(i); |
| 277 for (int j = 0; j < 256; j++) { |
| 278 CHECK_EQ(i == j, entry.Contains(j)); |
| 279 } |
| 280 } |
| 281 // Test upwards through the data range |
| 282 static const uint32_t kMax = 1 << 16; |
| 283 for (uint32_t i = 0; i < kMax; i = 1 + static_cast<uint32_t>(i * 1.2)) { |
| 284 CharacterClass entry = CharacterClass::SingletonField(i); |
| 285 for (uint32_t j = 0; j < kMax; j = 1 + static_cast<uint32_t>(j * 1.2)) { |
| 286 CHECK_EQ(i == j, entry.Contains(j)); |
| 287 } |
| 288 } |
| 289 } |
| 290 |
| 291 |
| 292 TEST(RangeField) { |
| 293 // Test bitfields containing a single range. |
| 294 for (int i = 256; i < 320; i++) { |
| 295 for (int j = i; j < 320; j++) { |
| 296 CharacterClass::Range range(i, j); |
| 297 CharacterClass entry = CharacterClass::RangeField(range); |
| 298 for (int k = 256; k < 320; k++) { |
| 299 CHECK_EQ(i <= k && k <= j, entry.Contains(k)); |
| 300 } |
| 301 } |
| 302 } |
| 303 } |
| 304 |
| 305 |
| 306 static void TestBuiltins(CharacterClass klass, bool (pred)(uc16)) { |
| 307 for (int i = 0; i < (1 << 16); i++) |
| 308 CHECK_EQ(pred(i), klass.Contains(i)); |
| 309 } |
| 310 |
| 311 |
| 312 static bool IsDigit(uc16 c) { |
| 313 return ('0' <= c && c <= '9'); |
| 314 } |
| 315 |
| 316 |
| 317 static bool IsWhiteSpace(uc16 c) { |
| 318 switch (c) { |
| 319 case 0x09: case 0x0B: case 0x0C: case 0x20: case 0xA0: |
| 320 return true; |
| 321 default: |
| 322 return unibrow::Space::Is(c); |
| 323 } |
| 324 } |
| 325 |
| 326 |
| 327 static bool IsWord(uc16 c) { |
| 328 return ('a' <= c && c <= 'z') |
| 329 || ('A' <= c && c <= 'Z') |
| 330 || ('0' <= c && c <= '9') |
| 331 || (c == '_'); |
| 332 } |
| 333 |
| 334 |
| 335 TEST(Builtins) { |
| 336 TestBuiltins(*CharacterClass::GetCharacterClass('d'), IsDigit); |
| 337 TestBuiltins(*CharacterClass::GetCharacterClass('s'), IsWhiteSpace); |
| 338 TestBuiltins(*CharacterClass::GetCharacterClass('w'), IsWord); |
| 339 } |
| 340 |
| 341 |
| 342 TEST(SimpleRanges) { |
| 343 // Test range classes containing a single range. |
| 344 for (int i = 365; i < 730; i += 3) { |
| 345 for (int j = i; j < 1095; j += 3) { |
| 346 EmbeddedVector<CharacterClass::Range, 1> entries; |
| 347 entries[0] = CharacterClass::Range(i, j); |
| 348 CharacterClass klass = CharacterClass::Ranges(entries, NULL); |
| 349 for (int k = 0; k < 1095; k += 3) { |
| 350 CHECK_EQ(i <= k && k <= j, klass.Contains(k)); |
| 351 } |
| 352 } |
| 353 } |
| 354 } |
| 355 |
| 356 |
| 357 static unsigned PseudoRandom(int i, int j) { |
| 358 return (~((i * 781) ^ (j * 329))); |
| 359 } |
| 360 |
| 361 |
| 362 // Generates pseudo-random character-class with kCount pseudo-random |
| 363 // ranges set. |
| 364 template <int kCount> |
| 365 class SimpleRangeGenerator { |
| 366 public: |
| 367 SimpleRangeGenerator() : i_(0) { } |
| 368 |
| 369 // Returns the next character class and sets the ranges vector. The |
| 370 // returned value will not have any ranges that extend beyond the 'max' |
| 371 // value. |
| 372 CharacterClass Next(int max) { |
| 373 for (int j = 0; j < 2 * kCount; j++) { |
| 374 entries_[j] = PseudoRandom(i_, j) % max; |
| 375 } |
| 376 i_++; |
| 377 qsort(entries_.start(), 2 * kCount, sizeof(uc16), Compare); |
| 378 for (int j = 0; j < kCount; j++) { |
| 379 ranges_[j] = CharacterClass::Range(entries_[2 * j], |
| 380 entries_[2 * j + 1]); |
| 381 } |
| 382 return CharacterClass::Ranges(ranges_, NULL); |
| 383 } |
| 384 |
| 385 // Returns the ranges of the last range that was returned. Note that |
| 386 // the returned vector will be clobbered the next time Next() is called. |
| 387 Vector<CharacterClass::Range> ranges() { return ranges_; } |
| 388 private: |
| 389 |
| 390 static int Compare(const void* a, const void* b) { |
| 391 return *static_cast<const uc16*>(a) - *static_cast<const uc16*>(b); |
| 392 } |
| 393 |
| 394 int i_; |
| 395 EmbeddedVector<uc16, 2 * kCount> entries_; |
| 396 EmbeddedVector<CharacterClass::Range, kCount> ranges_; |
| 397 }; |
| 398 |
| 399 |
| 400 TEST(LessSimpleRanges) { |
| 401 // Tests range character classes containing 3 pseudo-random ranges. |
| 402 SimpleRangeGenerator<3> gen; |
| 403 for (int i = 0; i < 1024; i++) { |
| 404 CharacterClass klass = gen.Next(256); |
| 405 Vector<CharacterClass::Range> entries = gen.ranges(); |
| 406 for (int j = 0; j < 256; j++) { |
| 407 bool is_on = false; |
| 408 for (int k = 0; !is_on && k < 3; k++) |
| 409 is_on = (entries[k].from() <= j && j <= entries[k].to()); |
| 410 CHECK_EQ(is_on, klass.Contains(j)); |
| 411 } |
| 412 } |
| 413 } |
| 414 |
| 415 |
| 416 TEST(Unions) { |
| 417 SimpleRangeGenerator<3> gen1; |
| 418 SimpleRangeGenerator<3> gen2; |
| 419 for (int i = 0; i < 1024; i++) { |
| 420 CharacterClass klass1 = gen1.Next(256); |
| 421 CharacterClass klass2 = gen2.Next(256); |
| 422 CharacterClass uhnion = CharacterClass::Union(&klass1, &klass2); |
| 423 for (int j = 0; j < 256; j++) |
| 424 CHECK_EQ(klass1.Contains(j) || klass2.Contains(j), uhnion.Contains(j)); |
| 425 } |
| 426 } |
| OLD | NEW |