| Index: test/cctest/test-strings.cc
|
| ===================================================================
|
| --- test/cctest/test-strings.cc (revision 1687)
|
| +++ test/cctest/test-strings.cc (working copy)
|
| @@ -387,3 +387,60 @@
|
| CHECK_EQ(kNoChar, buffer[j]);
|
| }
|
| }
|
| +
|
| +
|
| +class TwoByteResource: public v8::String::ExternalStringResource {
|
| + public:
|
| + explicit TwoByteResource(const uint16_t* data, size_t length)
|
| + : data_(data), length_(length) { }
|
| + virtual ~TwoByteResource() { }
|
| +
|
| + const uint16_t* data() const { return data_; }
|
| + size_t length() const { return length_; }
|
| +
|
| + private:
|
| + const uint16_t* data_;
|
| + size_t length_;
|
| +};
|
| +
|
| +
|
| +TEST(ExternalCrBug9746) {
|
| + InitializeVM();
|
| + v8::HandleScope handle_scope;
|
| +
|
| + // This set of tests verifies that the workaround for Chromium bug 9746
|
| + // works correctly. In certain situations the external resource of a symbol
|
| + // is collected while the symbol is still part of the symbol table.
|
| + static uint16_t two_byte_data[] = {
|
| + 't', 'w', 'o', '-', 'b', 'y', 't', 'e', ' ', 'd', 'a', 't', 'a'
|
| + };
|
| + static size_t two_byte_length =
|
| + sizeof(two_byte_data) / sizeof(two_byte_data[0]);
|
| + static const char* one_byte_data = "two-byte data";
|
| +
|
| + // Allocate an external string resource and external string.
|
| + TwoByteResource* resource = new TwoByteResource(two_byte_data,
|
| + two_byte_length);
|
| + Handle<String> string = Factory::NewExternalStringFromTwoByte(resource);
|
| + Vector<const char> one_byte_vec = CStrVector(one_byte_data);
|
| + Handle<String> compare = Factory::NewStringFromAscii(one_byte_vec);
|
| +
|
| + // Verify the correct behaviour before "collecting" the external resource.
|
| + CHECK(string->IsEqualTo(one_byte_vec));
|
| + CHECK(string->Equals(*compare));
|
| +
|
| + // "Collect" the external resource manually by setting the external resource
|
| + // pointer to NULL. Then redo the comparisons, they should not match AND
|
| + // not crash.
|
| + Handle<ExternalTwoByteString> external(ExternalTwoByteString::cast(*string));
|
| + external->set_resource(NULL);
|
| + CHECK_EQ(false, string->IsEqualTo(one_byte_vec));
|
| +#if !defined(DEBUG)
|
| + // These tests only work in non-debug as there are ASSERTs in the code that
|
| + // do prevent the ability to even get into the broken code when running the
|
| + // debug version of V8.
|
| + CHECK_EQ(false, string->Equals(*compare));
|
| + CHECK_EQ(false, compare->Equals(*string));
|
| + CHECK_EQ(false, string->Equals(Heap::empty_string()));
|
| +#endif // !defined(DEBUG)
|
| +}
|
|
|