OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 5420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5431 if (n-- == 0) return 0; | 5431 if (n-- == 0) return 0; |
5432 if (*a == 0 && *b == 0) return 0; | 5432 if (*a == 0 && *b == 0) return 0; |
5433 if (*a != *b) return 0 + *a - *b; | 5433 if (*a != *b) return 0 + *a - *b; |
5434 a++; | 5434 a++; |
5435 b++; | 5435 b++; |
5436 } | 5436 } |
5437 } | 5437 } |
5438 | 5438 |
5439 | 5439 |
5440 THREADED_TEST(StringWrite) { | 5440 THREADED_TEST(StringWrite) { |
| 5441 LocalContext context; |
5441 v8::HandleScope scope; | 5442 v8::HandleScope scope; |
5442 v8::Handle<String> str = v8_str("abcde"); | 5443 v8::Handle<String> str = v8_str("abcde"); |
5443 // abc<Icelandic eth><Unicode snowman>. | 5444 // abc<Icelandic eth><Unicode snowman>. |
5444 v8::Handle<String> str2 = v8_str("abc\303\260\342\230\203"); | 5445 v8::Handle<String> str2 = v8_str("abc\303\260\342\230\203"); |
| 5446 const int kStride = 4; // Must match stride in for loops in JS below. |
| 5447 CompileRun( |
| 5448 "var left = '';" |
| 5449 "for (var i = 0; i < 0xd800; i += 4) {" |
| 5450 " left = left + String.fromCharCode(i);" |
| 5451 "}"); |
| 5452 CompileRun( |
| 5453 "var right = '';" |
| 5454 "for (var i = 0; i < 0xd800; i += 4) {" |
| 5455 " right = String.fromCharCode(i) + right;" |
| 5456 "}"); |
| 5457 v8::Handle<v8::Object> global = Context::GetCurrent()->Global(); |
| 5458 Handle<String> left_tree = global->Get(v8_str("left")).As<String>(); |
| 5459 Handle<String> right_tree = global->Get(v8_str("right")).As<String>(); |
5445 | 5460 |
5446 CHECK_EQ(5, str2->Length()); | 5461 CHECK_EQ(5, str2->Length()); |
| 5462 CHECK_EQ(0xd800 / kStride, left_tree->Length()); |
| 5463 CHECK_EQ(0xd800 / kStride, right_tree->Length()); |
5447 | 5464 |
5448 char buf[100]; | 5465 char buf[100]; |
5449 char utf8buf[100]; | 5466 char utf8buf[0xd800 * 3]; |
5450 uint16_t wbuf[100]; | 5467 uint16_t wbuf[100]; |
5451 int len; | 5468 int len; |
5452 int charlen; | 5469 int charlen; |
5453 | 5470 |
5454 memset(utf8buf, 0x1, sizeof(utf8buf)); | 5471 memset(utf8buf, 0x1, 1000); |
5455 len = str2->WriteUtf8(utf8buf, sizeof(utf8buf), &charlen); | 5472 len = str2->WriteUtf8(utf8buf, sizeof(utf8buf), &charlen); |
5456 CHECK_EQ(9, len); | 5473 CHECK_EQ(9, len); |
5457 CHECK_EQ(5, charlen); | 5474 CHECK_EQ(5, charlen); |
5458 CHECK_EQ(0, strcmp(utf8buf, "abc\303\260\342\230\203")); | 5475 CHECK_EQ(0, strcmp(utf8buf, "abc\303\260\342\230\203")); |
5459 | 5476 |
5460 memset(utf8buf, 0x1, sizeof(utf8buf)); | 5477 memset(utf8buf, 0x1, 1000); |
5461 len = str2->WriteUtf8(utf8buf, 8, &charlen); | 5478 len = str2->WriteUtf8(utf8buf, 8, &charlen); |
5462 CHECK_EQ(8, len); | 5479 CHECK_EQ(8, len); |
5463 CHECK_EQ(5, charlen); | 5480 CHECK_EQ(5, charlen); |
5464 CHECK_EQ(0, strncmp(utf8buf, "abc\303\260\342\230\203\1", 9)); | 5481 CHECK_EQ(0, strncmp(utf8buf, "abc\303\260\342\230\203\1", 9)); |
5465 | 5482 |
5466 memset(utf8buf, 0x1, sizeof(utf8buf)); | 5483 memset(utf8buf, 0x1, 1000); |
5467 len = str2->WriteUtf8(utf8buf, 7, &charlen); | 5484 len = str2->WriteUtf8(utf8buf, 7, &charlen); |
5468 CHECK_EQ(5, len); | 5485 CHECK_EQ(5, len); |
5469 CHECK_EQ(4, charlen); | 5486 CHECK_EQ(4, charlen); |
5470 CHECK_EQ(0, strncmp(utf8buf, "abc\303\260\1", 5)); | 5487 CHECK_EQ(0, strncmp(utf8buf, "abc\303\260\1", 5)); |
5471 | 5488 |
5472 memset(utf8buf, 0x1, sizeof(utf8buf)); | 5489 memset(utf8buf, 0x1, 1000); |
5473 len = str2->WriteUtf8(utf8buf, 6, &charlen); | 5490 len = str2->WriteUtf8(utf8buf, 6, &charlen); |
5474 CHECK_EQ(5, len); | 5491 CHECK_EQ(5, len); |
5475 CHECK_EQ(4, charlen); | 5492 CHECK_EQ(4, charlen); |
5476 CHECK_EQ(0, strncmp(utf8buf, "abc\303\260\1", 5)); | 5493 CHECK_EQ(0, strncmp(utf8buf, "abc\303\260\1", 5)); |
5477 | 5494 |
5478 memset(utf8buf, 0x1, sizeof(utf8buf)); | 5495 memset(utf8buf, 0x1, 1000); |
5479 len = str2->WriteUtf8(utf8buf, 5, &charlen); | 5496 len = str2->WriteUtf8(utf8buf, 5, &charlen); |
5480 CHECK_EQ(5, len); | 5497 CHECK_EQ(5, len); |
5481 CHECK_EQ(4, charlen); | 5498 CHECK_EQ(4, charlen); |
5482 CHECK_EQ(0, strncmp(utf8buf, "abc\303\260\1", 5)); | 5499 CHECK_EQ(0, strncmp(utf8buf, "abc\303\260\1", 5)); |
5483 | 5500 |
5484 memset(utf8buf, 0x1, sizeof(utf8buf)); | 5501 memset(utf8buf, 0x1, 1000); |
5485 len = str2->WriteUtf8(utf8buf, 4, &charlen); | 5502 len = str2->WriteUtf8(utf8buf, 4, &charlen); |
5486 CHECK_EQ(3, len); | 5503 CHECK_EQ(3, len); |
5487 CHECK_EQ(3, charlen); | 5504 CHECK_EQ(3, charlen); |
5488 CHECK_EQ(0, strncmp(utf8buf, "abc\1", 4)); | 5505 CHECK_EQ(0, strncmp(utf8buf, "abc\1", 4)); |
5489 | 5506 |
5490 memset(utf8buf, 0x1, sizeof(utf8buf)); | 5507 memset(utf8buf, 0x1, 1000); |
5491 len = str2->WriteUtf8(utf8buf, 3, &charlen); | 5508 len = str2->WriteUtf8(utf8buf, 3, &charlen); |
5492 CHECK_EQ(3, len); | 5509 CHECK_EQ(3, len); |
5493 CHECK_EQ(3, charlen); | 5510 CHECK_EQ(3, charlen); |
5494 CHECK_EQ(0, strncmp(utf8buf, "abc\1", 4)); | 5511 CHECK_EQ(0, strncmp(utf8buf, "abc\1", 4)); |
5495 | 5512 |
5496 memset(utf8buf, 0x1, sizeof(utf8buf)); | 5513 memset(utf8buf, 0x1, 1000); |
5497 len = str2->WriteUtf8(utf8buf, 2, &charlen); | 5514 len = str2->WriteUtf8(utf8buf, 2, &charlen); |
5498 CHECK_EQ(2, len); | 5515 CHECK_EQ(2, len); |
5499 CHECK_EQ(2, charlen); | 5516 CHECK_EQ(2, charlen); |
5500 CHECK_EQ(0, strncmp(utf8buf, "ab\1", 3)); | 5517 CHECK_EQ(0, strncmp(utf8buf, "ab\1", 3)); |
5501 | 5518 |
| 5519 memset(utf8buf, 0x1, sizeof(utf8buf)); |
| 5520 len = left_tree->Utf8Length(); |
| 5521 int utf8_expected = |
| 5522 (0x80 + (0x800 - 0x80) * 2 + (0xd800 - 0x800) * 3) / kStride; |
| 5523 CHECK_EQ(utf8_expected, len); |
| 5524 len = left_tree->WriteUtf8(utf8buf, utf8_expected, &charlen); |
| 5525 CHECK_EQ(utf8_expected, len); |
| 5526 CHECK_EQ(0xd800 / kStride, charlen); |
| 5527 CHECK_EQ(0xed, static_cast<unsigned char>(utf8buf[utf8_expected - 3])); |
| 5528 CHECK_EQ(0x9f, static_cast<unsigned char>(utf8buf[utf8_expected - 2])); |
| 5529 CHECK_EQ(0xc0 - kStride, |
| 5530 static_cast<unsigned char>(utf8buf[utf8_expected - 1])); |
| 5531 CHECK_EQ(1, utf8buf[utf8_expected]); |
| 5532 |
| 5533 memset(utf8buf, 0x1, sizeof(utf8buf)); |
| 5534 len = right_tree->Utf8Length(); |
| 5535 CHECK_EQ(utf8_expected, len); |
| 5536 len = right_tree->WriteUtf8(utf8buf, utf8_expected, &charlen); |
| 5537 CHECK_EQ(utf8_expected, len); |
| 5538 CHECK_EQ(0xd800 / kStride, charlen); |
| 5539 CHECK_EQ(0xed, static_cast<unsigned char>(utf8buf[0])); |
| 5540 CHECK_EQ(0x9f, static_cast<unsigned char>(utf8buf[1])); |
| 5541 CHECK_EQ(0xc0 - kStride, static_cast<unsigned char>(utf8buf[2])); |
| 5542 CHECK_EQ(1, utf8buf[utf8_expected]); |
| 5543 |
5502 memset(buf, 0x1, sizeof(buf)); | 5544 memset(buf, 0x1, sizeof(buf)); |
5503 memset(wbuf, 0x1, sizeof(wbuf)); | 5545 memset(wbuf, 0x1, sizeof(wbuf)); |
5504 len = str->WriteAscii(buf); | 5546 len = str->WriteAscii(buf); |
5505 CHECK_EQ(5, len); | 5547 CHECK_EQ(5, len); |
5506 len = str->Write(wbuf); | 5548 len = str->Write(wbuf); |
5507 CHECK_EQ(5, len); | 5549 CHECK_EQ(5, len); |
5508 CHECK_EQ(0, strcmp("abcde", buf)); | 5550 CHECK_EQ(0, strcmp("abcde", buf)); |
5509 uint16_t answer1[] = {'a', 'b', 'c', 'd', 'e', '\0'}; | 5551 uint16_t answer1[] = {'a', 'b', 'c', 'd', 'e', '\0'}; |
5510 CHECK_EQ(0, StrCmp16(answer1, wbuf)); | 5552 CHECK_EQ(0, StrCmp16(answer1, wbuf)); |
5511 | 5553 |
(...skipping 5921 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11433 i::ExternalAsciiString* morphed = | 11475 i::ExternalAsciiString* morphed = |
11434 i::ExternalAsciiString::cast(string); | 11476 i::ExternalAsciiString::cast(string); |
11435 morphed->set_resource(ascii_resource); | 11477 morphed->set_resource(ascii_resource); |
11436 } | 11478 } |
11437 } | 11479 } |
11438 | 11480 |
11439 | 11481 |
11440 // Test that we can still flatten a string if the components it is built up | 11482 // Test that we can still flatten a string if the components it is built up |
11441 // from have been turned into 16 bit strings in the mean time. | 11483 // from have been turned into 16 bit strings in the mean time. |
11442 THREADED_TEST(MorphCompositeStringTest) { | 11484 THREADED_TEST(MorphCompositeStringTest) { |
| 11485 char utf_buffer[129]; |
11443 const char* c_string = "Now is the time for all good men" | 11486 const char* c_string = "Now is the time for all good men" |
11444 " to come to the aid of the party"; | 11487 " to come to the aid of the party"; |
11445 uint16_t* two_byte_string = AsciiToTwoByteString(c_string); | 11488 uint16_t* two_byte_string = AsciiToTwoByteString(c_string); |
11446 { | 11489 { |
11447 v8::HandleScope scope; | 11490 v8::HandleScope scope; |
11448 LocalContext env; | 11491 LocalContext env; |
11449 AsciiVectorResource ascii_resource( | 11492 AsciiVectorResource ascii_resource( |
11450 i::Vector<const char>(c_string, i::StrLength(c_string))); | 11493 i::Vector<const char>(c_string, i::StrLength(c_string))); |
11451 UC16VectorResource uc16_resource( | 11494 UC16VectorResource uc16_resource( |
11452 i::Vector<const uint16_t>(two_byte_string, | 11495 i::Vector<const uint16_t>(two_byte_string, |
11453 i::StrLength(c_string))); | 11496 i::StrLength(c_string))); |
11454 | 11497 |
11455 Local<String> lhs(v8::Utils::ToLocal( | 11498 Local<String> lhs(v8::Utils::ToLocal( |
11456 FACTORY->NewExternalStringFromAscii(&ascii_resource))); | 11499 FACTORY->NewExternalStringFromAscii(&ascii_resource))); |
11457 Local<String> rhs(v8::Utils::ToLocal( | 11500 Local<String> rhs(v8::Utils::ToLocal( |
11458 FACTORY->NewExternalStringFromAscii(&ascii_resource))); | 11501 FACTORY->NewExternalStringFromAscii(&ascii_resource))); |
11459 | 11502 |
11460 env->Global()->Set(v8_str("lhs"), lhs); | 11503 env->Global()->Set(v8_str("lhs"), lhs); |
11461 env->Global()->Set(v8_str("rhs"), rhs); | 11504 env->Global()->Set(v8_str("rhs"), rhs); |
11462 | 11505 |
11463 CompileRun( | 11506 CompileRun( |
11464 "var cons = lhs + rhs;" | 11507 "var cons = lhs + rhs;" |
11465 "var slice = lhs.substring(1, lhs.length - 1);" | 11508 "var slice = lhs.substring(1, lhs.length - 1);" |
11466 "var slice_on_cons = (lhs + rhs).substring(1, lhs.length *2 - 1);"); | 11509 "var slice_on_cons = (lhs + rhs).substring(1, lhs.length *2 - 1);"); |
11467 | 11510 |
11468 MorphAString(*v8::Utils::OpenHandle(*lhs), &ascii_resource, &uc16_resource); | 11511 MorphAString(*v8::Utils::OpenHandle(*lhs), &ascii_resource, &uc16_resource); |
11469 MorphAString(*v8::Utils::OpenHandle(*rhs), &ascii_resource, &uc16_resource); | 11512 MorphAString(*v8::Utils::OpenHandle(*rhs), &ascii_resource, &uc16_resource); |
11470 | 11513 |
| 11514 // This should UTF-8 without flattening, since everything is ASCII. |
| 11515 Handle<String> cons = v8_compile("cons")->Run().As<String>(); |
| 11516 CHECK_EQ(128, cons->Utf8Length()); |
| 11517 int nchars = -1; |
| 11518 CHECK_EQ(129, cons->WriteUtf8(utf_buffer, -1, &nchars)); |
| 11519 CHECK_EQ(128, nchars); |
| 11520 CHECK_EQ(0, strcmp( |
| 11521 utf_buffer, |
| 11522 "Now is the time for all good men to come to the aid of the party" |
| 11523 "Now is the time for all good men to come to the aid of the party")); |
| 11524 |
11471 // Now do some stuff to make sure the strings are flattened, etc. | 11525 // Now do some stuff to make sure the strings are flattened, etc. |
11472 CompileRun( | 11526 CompileRun( |
11473 "/[^a-z]/.test(cons);" | 11527 "/[^a-z]/.test(cons);" |
11474 "/[^a-z]/.test(slice);" | 11528 "/[^a-z]/.test(slice);" |
11475 "/[^a-z]/.test(slice_on_cons);"); | 11529 "/[^a-z]/.test(slice_on_cons);"); |
11476 const char* expected_cons = | 11530 const char* expected_cons = |
11477 "Now is the time for all good men to come to the aid of the party" | 11531 "Now is the time for all good men to come to the aid of the party" |
11478 "Now is the time for all good men to come to the aid of the party"; | 11532 "Now is the time for all good men to come to the aid of the party"; |
11479 const char* expected_slice = | 11533 const char* expected_slice = |
11480 "ow is the time for all good men to come to the aid of the part"; | 11534 "ow is the time for all good men to come to the aid of the part"; |
(...skipping 3952 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15433 CHECK(i->Equals(CompileRun("'abcbd'.replace(/b/g,func)[3]"))); | 15487 CHECK(i->Equals(CompileRun("'abcbd'.replace(/b/g,func)[3]"))); |
15434 | 15488 |
15435 // TODO(1547): Make the following also return "i". | 15489 // TODO(1547): Make the following also return "i". |
15436 // Calling with environment record as base. | 15490 // Calling with environment record as base. |
15437 TestReceiver(o, context->Global(), "func()"); | 15491 TestReceiver(o, context->Global(), "func()"); |
15438 // Calling with no base. | 15492 // Calling with no base. |
15439 TestReceiver(o, context->Global(), "(1,func)()"); | 15493 TestReceiver(o, context->Global(), "(1,func)()"); |
15440 | 15494 |
15441 foreign_context.Dispose(); | 15495 foreign_context.Dispose(); |
15442 } | 15496 } |
OLD | NEW |