| Index: test/cctest/test-strings.cc
|
| ===================================================================
|
| --- test/cctest/test-strings.cc (revision 3396)
|
| +++ test/cctest/test-strings.cc (working copy)
|
| @@ -63,6 +63,21 @@
|
| };
|
|
|
|
|
| +class AsciiResource: public v8::String::ExternalAsciiStringResource,
|
| + public ZoneObject {
|
| + public:
|
| + explicit AsciiResource(Vector<const char> string): data_(string.start()) {
|
| + length_ = string.length();
|
| + }
|
| + virtual const char* data() const { return data_; }
|
| + virtual size_t length() const { return length_; }
|
| +
|
| + private:
|
| + const char* data_;
|
| + size_t length_;
|
| +};
|
| +
|
| +
|
| static void InitializeBuildingBlocks(
|
| Handle<String> building_blocks[NUMBER_OF_BUILDING_BLOCKS]) {
|
| // A list of pointers that we don't have any interest in cleaning up.
|
| @@ -329,25 +344,65 @@
|
| }
|
|
|
|
|
| -class TwoByteResource: public v8::String::ExternalStringResource {
|
| - public:
|
| - TwoByteResource(const uint16_t* data, size_t length, bool* destructed)
|
| - : data_(data), length_(length), destructed_(destructed) {
|
| - CHECK_NE(destructed, NULL);
|
| - *destructed_ = false;
|
| - }
|
| +TEST(ExternalShortStringAdd) {
|
| + ZoneScope zone(DELETE_ON_EXIT);
|
|
|
| - virtual ~TwoByteResource() {
|
| - CHECK_NE(destructed_, NULL);
|
| - CHECK(!*destructed_);
|
| - *destructed_ = true;
|
| + InitializeVM();
|
| + v8::HandleScope handle_scope;
|
| +
|
| + // Make sure we cover all always-flat lengths and at least one above.
|
| + static const int kMaxLength = 20;
|
| + CHECK_GT(kMaxLength, i::String::kMinNonFlatLength);
|
| +
|
| + // Allocate two JavaScript arrays for holding short strings.
|
| + v8::Handle<v8::Array> ascii_external_strings =
|
| + v8::Array::New(kMaxLength + 1);
|
| + v8::Handle<v8::Array> non_ascii_external_strings =
|
| + v8::Array::New(kMaxLength + 1);
|
| +
|
| + // Generate short ascii and non-ascii external strings.
|
| + for (int i = 0; i <= kMaxLength; i++) {
|
| + char* ascii = Zone::NewArray<char>(i + 1);
|
| + for (int j = 0; j < i; j++) {
|
| + ascii[j] = 'a';
|
| + }
|
| + // Terminating '\0' is left out on purpose. It is not required for external
|
| + // string data.
|
| + AsciiResource* ascii_resource =
|
| + new AsciiResource(Vector<const char>(ascii, i));
|
| + v8::Local<v8::String> ascii_external_string =
|
| + v8::String::NewExternal(ascii_resource);
|
| +
|
| + ascii_external_strings->Set(v8::Integer::New(i), ascii_external_string);
|
| + uc16* non_ascii = Zone::NewArray<uc16>(i + 1);
|
| + for (int j = 0; j < i; j++) {
|
| + non_ascii[j] = 1234;
|
| + }
|
| + // Terminating '\0' is left out on purpose. It is not required for external
|
| + // string data.
|
| + Resource* resource = new Resource(Vector<const uc16>(non_ascii, i));
|
| + v8::Local<v8::String> non_ascii_external_string =
|
| + v8::String::NewExternal(resource);
|
| + non_ascii_external_strings->Set(v8::Integer::New(i),
|
| + non_ascii_external_string);
|
| }
|
|
|
| - const uint16_t* data() const { return data_; }
|
| - size_t length() const { return length_; }
|
| + // Add the arrays with the short external strings in the global object.
|
| + v8::Handle<v8::Object> global = env->Global();
|
| + global->Set(v8_str("ascii"), ascii_external_strings);
|
| + global->Set(v8_str("non_ascii"), non_ascii_external_strings);
|
|
|
| - private:
|
| - const uint16_t* data_;
|
| - size_t length_;
|
| - bool* destructed_;
|
| -};
|
| + // Add short external ascii and non-ascii strings checking the result.
|
| + static const char* source =
|
| + "function test() {"
|
| + " for (var i = 0; i <= 20; i++) {"
|
| + " for (var j = 0; j < i; j++) {"
|
| + " if (non_ascii[i] != (non_ascii[j] + non_ascii[i - j])) return false;"
|
| + " if (ascii[i] != (ascii[j] + ascii[i - j])) return false;"
|
| + " }"
|
| + " }"
|
| + " return true;"
|
| + "};"
|
| + "test()";
|
| + CHECK(v8::Script::Compile(v8::String::New(source))->Run()->BooleanValue());
|
| +}
|
|
|