Chromium Code Reviews| Index: test/cctest/test-api.cc | 
| =================================================================== | 
| --- test/cctest/test-api.cc (revision 1807) | 
| +++ test/cctest/test-api.cc (working copy) | 
| @@ -420,7 +420,7 @@ | 
| public: | 
| static int dispose_count; | 
| - explicit TestAsciiResource(char* data) | 
| + explicit TestAsciiResource(const char* data) | 
| : data_(data), | 
| length_(strlen(data)) { } | 
| @@ -437,7 +437,7 @@ | 
| return length_; | 
| } | 
| private: | 
| - char* data_; | 
| + const char* data_; | 
| size_t length_; | 
| }; | 
| @@ -6153,6 +6153,111 @@ | 
| } | 
| +class AsciiVectorResource : public v8::String::ExternalAsciiStringResource { | 
| + public: | 
| + explicit AsciiVectorResource(i::Vector<const char> vector) | 
| + : data_(vector) {} | 
| + virtual ~AsciiVectorResource() {} | 
| + virtual size_t length() const { return data_.length(); } | 
| + virtual const char* data() const { return data_.start(); } | 
| + private: | 
| + i::Vector<const char> data_; | 
| +}; | 
| + | 
| + | 
| +class UC16VectorResource : public v8::String::ExternalStringResource { | 
| + public: | 
| + explicit UC16VectorResource(i::Vector<const i::uc16> vector) | 
| + : data_(vector) {} | 
| + virtual ~UC16VectorResource() {} | 
| + virtual size_t length() const { return data_.length(); } | 
| + virtual const i::uc16* data() const { return data_.start(); } | 
| + private: | 
| + i::Vector<const i::uc16> data_; | 
| +}; | 
| + | 
| + | 
| +static void MorphAString(i::String* string, | 
| + AsciiVectorResource* ascii_resource, | 
| + UC16VectorResource* uc16_resource) { | 
| + CHECK(i::StringShape(string).IsExternal()); | 
| + if (string->IsAsciiRepresentation()) { | 
| + // Check old map is not symbol or long. | 
| + CHECK(string->map() == i::Heap::short_external_ascii_string_map() || | 
| + string->map() == i::Heap::medium_external_ascii_string_map()); | 
| + // Morph external string to be TwoByte string. | 
| + if (string->length() <= i::String::kMaxShortStringSize) { | 
| + string->set_map(i::Heap::short_external_string_map()); | 
| + } else { | 
| + string->set_map(i::Heap::medium_external_string_map()); | 
| + } | 
| + i::ExternalTwoByteString* morphed = | 
| + i::ExternalTwoByteString::cast(string); | 
| + morphed->set_resource(uc16_resource); | 
| + } else { | 
| + // Check old map is not symbol or long. | 
| + CHECK(string->map() == i::Heap::short_external_string_map() || | 
| + string->map() == i::Heap::medium_external_string_map()); | 
| + // Morph external string to be ASCII string. | 
| + if (string->length() <= i::String::kMaxShortStringSize) { | 
| + string->set_map(i::Heap::short_external_ascii_string_map()); | 
| + } else { | 
| + string->set_map(i::Heap::medium_external_ascii_string_map()); | 
| + } | 
| + i::ExternalAsciiString* morphed = | 
| + i::ExternalAsciiString::cast(string); | 
| + morphed->set_resource(ascii_resource); | 
| + } | 
| +} | 
| + | 
| + | 
| +THREADED_TEST(MorphCompositeStringTest) { | 
| + const char* c_string = "Now is the time for all good men" | 
| + " to come to the aid of the party"; | 
| + uint16_t* two_byte_string = AsciiToTwoByteString(c_string); | 
| + { | 
| + v8::HandleScope scope; | 
| + LocalContext env; | 
| + AsciiVectorResource ascii_resource(i::Vector<const char>(c_string, strlen(c_string))); | 
| + UC16VectorResource uc16_resource(i::Vector<const uint16_t>(two_byte_string, strlen(c_string))); | 
| + | 
| + Local<String> lhs(v8::Utils::ToLocal(i::Factory::NewExternalStringFromAscii(&ascii_resource))); | 
| + Local<String> rhs(v8::Utils::ToLocal(i::Factory::NewExternalStringFromAscii(&ascii_resource))); | 
| + | 
| + env->Global()->Set(v8_str("lhs"), lhs); | 
| + env->Global()->Set(v8_str("rhs"), rhs); | 
| + | 
| + CompileRun( | 
| + "var cons = lhs + rhs;" | 
| + "var slice = lhs.substring(1, lhs.length - 1);" | 
| + "var slice_on_cons = (lhs + rhs).substring(1, lhs.length *2 - 1);"); | 
| + | 
| + MorphAString(*v8::Utils::OpenHandle(*lhs), &ascii_resource, &uc16_resource); | 
| + MorphAString(*v8::Utils::OpenHandle(*rhs), &ascii_resource, &uc16_resource); | 
| + | 
| + // Now do some stuff to make sure the strings are flattened, etc. | 
| + CompileRun( | 
| + "/[^a-z]/.test(cons);" | 
| + "/[^a-z]/.test(slice);" | 
| + "/[^a-z]/.test(slice_on_cons);"); | 
| 
 
Lasse Reichstein
2009/05/01 09:47:01
Perhaps add a comment stating what is being tested
 
 | 
| + const char* expected_cons = | 
| + "Now is the time for all good men to come to the aid of the party" | 
| + "Now is the time for all good men to come to the aid of the party"; | 
| + const char* expected_slice = | 
| + "ow is the time for all good men to come to the aid of the part"; | 
| + const char* expected_slice_on_cons = | 
| + "ow is the time for all good men to come to the aid of the party" | 
| + "Now is the time for all good men to come to the aid of the part"; | 
| + CHECK_EQ(String::New(expected_cons), | 
| + env->Global()->Get(v8_str("cons"))); | 
| + CHECK_EQ(String::New(expected_slice), | 
| + env->Global()->Get(v8_str("slice"))); | 
| + CHECK_EQ(String::New(expected_slice_on_cons), | 
| + env->Global()->Get(v8_str("slice_on_cons"))); | 
| + } | 
| +} | 
| + | 
| + | 
| class RegExpStringModificationTest { | 
| public: | 
| RegExpStringModificationTest() | 
| @@ -6197,26 +6302,6 @@ | 
| } | 
| private: | 
| - class AsciiVectorResource : public v8::String::ExternalAsciiStringResource { | 
| - public: | 
| - explicit AsciiVectorResource(i::Vector<const char> vector) | 
| - : data_(vector) {} | 
| - virtual ~AsciiVectorResource() {} | 
| - virtual size_t length() const { return data_.length(); } | 
| - virtual const char* data() const { return data_.start(); } | 
| - private: | 
| - i::Vector<const char> data_; | 
| - }; | 
| - class UC16VectorResource : public v8::String::ExternalStringResource { | 
| - public: | 
| - explicit UC16VectorResource(i::Vector<const i::uc16> vector) | 
| - : data_(vector) {} | 
| - virtual ~UC16VectorResource() {} | 
| - virtual size_t length() const { return data_.length(); } | 
| - virtual const i::uc16* data() const { return data_.start(); } | 
| - private: | 
| - i::Vector<const i::uc16> data_; | 
| - }; | 
| // Number of string modifications required. | 
| static const int kRequiredModifications = 5; | 
| static const int kMaxModifications = 100; | 
| @@ -6240,25 +6325,7 @@ | 
| v8::Locker lock; | 
| // Swap string between ascii and two-byte representation. | 
| i::String* string = *input_; | 
| - CHECK(i::StringShape(string).IsExternal()); | 
| - if (i::StringShape(string).IsAsciiRepresentation()) { | 
| - // Morph external string to be TwoByte string. | 
| - i::ExternalAsciiString* ext_string = | 
| - i::ExternalAsciiString::cast(string); | 
| - i::ExternalTwoByteString* morphed = | 
| - reinterpret_cast<i::ExternalTwoByteString*>(ext_string); | 
| - morphed->map()->set_instance_type(i::SHORT_EXTERNAL_STRING_TYPE); | 
| - morphed->set_resource(&uc16_resource_); | 
| - } else { | 
| - // Morph external string to be ASCII string. | 
| - i::ExternalTwoByteString* ext_string = | 
| - i::ExternalTwoByteString::cast(string); | 
| - i::ExternalAsciiString* morphed = | 
| - reinterpret_cast<i::ExternalAsciiString*>(ext_string); | 
| - morphed->map()->set_instance_type( | 
| - i::SHORT_EXTERNAL_ASCII_STRING_TYPE); | 
| - morphed->set_resource(&ascii_resource_); | 
| - } | 
| + MorphAString(string, &ascii_resource_, &uc16_resource_); | 
| morphs_++; | 
| } | 
| i::OS::Sleep(1); |