Revision: 12488
Author: [email protected]
Date: Wed Sep 12 04:29:50 2012
Log: Introduce new API to expose external string resource regardless
of encoding.
BUG=
Review URL: https://chromiumcodereview.appspot.com/10917211
http://code.google.com/p/v8/source/detail?r=12488
Modified:
/branches/bleeding_edge/include/v8.h
/branches/bleeding_edge/src/api.cc
/branches/bleeding_edge/src/objects-inl.h
/branches/bleeding_edge/test/cctest/test-api.cc
=======================================
--- /branches/bleeding_edge/include/v8.h Fri Sep 7 02:01:54 2012
+++ /branches/bleeding_edge/include/v8.h Wed Sep 12 04:29:50 2012
@@ -1018,6 +1018,11 @@
*/
class String : public Primitive {
public:
+ enum Encoding {
+ UNKNOWN_ENCODING = 0x1,
+ TWO_BYTE_ENCODING = 0x0,
+ ASCII_ENCODING = 0x4
+ };
/**
* Returns the number of characters in this string.
*/
@@ -1180,6 +1185,14 @@
ExternalAsciiStringResource() {}
};
+ /**
+ * If the string is an external string, return the
ExternalStringResourceBase
+ * regardless of the encoding, otherwise return NULL. The encoding of
the
+ * string is returned in encoding_out.
+ */
+ inline ExternalStringResourceBase* GetExternalStringResourceBase(
+ Encoding* encoding_out) const;
+
/**
* Get the ExternalStringResource for an external string. Returns
* NULL if IsExternal() doesn't return true.
@@ -1343,6 +1356,8 @@
};
private:
+ V8EXPORT void
VerifyExternalStringResourceBase(ExternalStringResourceBase* v,
+ Encoding encoding) const;
V8EXPORT void VerifyExternalStringResource(ExternalStringResource* val)
const;
V8EXPORT static void CheckCast(v8::Value* obj);
};
@@ -4033,7 +4048,9 @@
static const int kForeignAddressOffset = kApiPointerSize;
static const int kJSObjectHeaderSize = 3 * kApiPointerSize;
static const int kFullStringRepresentationMask = 0x07;
+ static const int kStringEncodingMask = 0x4;
static const int kExternalTwoByteRepresentationTag = 0x02;
+ static const int kExternalAsciiRepresentationTag = 0x06;
static const int kIsolateStateOffset = 0;
static const int kIsolateEmbedderDataOffset = 1 * kApiPointerSize;
@@ -4386,6 +4403,26 @@
#endif
return result;
}
+
+
+String::ExternalStringResourceBase* String::GetExternalStringResourceBase(
+ String::Encoding* encoding_out) const {
+ typedef internal::Object O;
+ typedef internal::Internals I;
+ O* obj = *reinterpret_cast<O**>(const_cast<String*>(this));
+ int type = I::GetInstanceType(obj) & I::kFullStringRepresentationMask;
+ *encoding_out = static_cast<Encoding>(type & I::kStringEncodingMask);
+ ExternalStringResourceBase* resource = NULL;
+ if (type == I::kExternalAsciiRepresentationTag ||
+ type == I::kExternalTwoByteRepresentationTag) {
+ void* value = I::ReadField<void*>(obj, I::kStringResourceOffset);
+ resource = static_cast<ExternalStringResourceBase*>(value);
+ }
+#ifdef V8_ENABLE_CHECKS
+ VerifyExternalStringResourceBase(resource, *encoding_out);
+#endif
+ return resource;
+}
bool Value::IsUndefined() const {
=======================================
--- /branches/bleeding_edge/src/api.cc Tue Sep 11 07:16:56 2012
+++ /branches/bleeding_edge/src/api.cc Wed Sep 12 04:29:50 2012
@@ -4089,6 +4089,29 @@
CHECK_EQ(expected, value);
}
+void v8::String::VerifyExternalStringResourceBase(
+ v8::String::ExternalStringResourceBase* value, Encoding encoding)
const {
+ i::Handle<i::String> str = Utils::OpenHandle(this);
+ const v8::String::ExternalStringResourceBase* expected;
+ Encoding expectedEncoding;
+ if (i::StringShape(*str).IsExternalAscii()) {
+ const void* resource =
+ i::Handle<i::ExternalAsciiString>::cast(str)->resource();
+ expected = reinterpret_cast<const
ExternalStringResourceBase*>(resource);
+ expectedEncoding = ASCII_ENCODING;
+ } else if (i::StringShape(*str).IsExternalTwoByte()) {
+ const void* resource =
+ i::Handle<i::ExternalTwoByteString>::cast(str)->resource();
+ expected = reinterpret_cast<const
ExternalStringResourceBase*>(resource);
+ expectedEncoding = TWO_BYTE_ENCODING;
+ } else {
+ expected = NULL;
+ expectedEncoding = str->IsAsciiRepresentation() ? ASCII_ENCODING
+ : TWO_BYTE_ENCODING;
+ }
+ CHECK_EQ(expected, value);
+ CHECK_EQ(expectedEncoding, encoding);
+}
const v8::String::ExternalAsciiStringResource*
v8::String::GetExternalAsciiStringResource() const {
=======================================
--- /branches/bleeding_edge/src/objects-inl.h Mon Sep 10 06:38:21 2012
+++ /branches/bleeding_edge/src/objects-inl.h Wed Sep 12 04:29:50 2012
@@ -382,6 +382,9 @@
STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) ==
Internals::kFullStringRepresentationMask);
+STATIC_CHECK(static_cast<uint32_t>(kStringEncodingMask) ==
+ Internals::kStringEncodingMask);
+
bool StringShape::IsSequentialAscii() {
return full_representation_tag() == (kSeqStringTag | kAsciiStringTag);
@@ -396,6 +399,12 @@
bool StringShape::IsExternalAscii() {
return full_representation_tag() == (kExternalStringTag |
kAsciiStringTag);
}
+
+
+STATIC_CHECK((kExternalStringTag | kAsciiStringTag) ==
+ Internals::kExternalAsciiRepresentationTag);
+
+STATIC_CHECK(v8::String::ASCII_ENCODING == kAsciiStringTag);
bool StringShape::IsExternalTwoByte() {
@@ -406,6 +415,7 @@
STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) ==
Internals::kExternalTwoByteRepresentationTag);
+STATIC_CHECK(v8::String::TWO_BYTE_ENCODING == kTwoByteStringTag);
uc32 FlatStringReader::Get(int index) {
ASSERT(0 <= index && index <= length_);
=======================================
--- /branches/bleeding_edge/test/cctest/test-api.cc Tue Sep 11 07:16:56 2012
+++ /branches/bleeding_edge/test/cctest/test-api.cc Wed Sep 12 04:29:50 2012
@@ -404,6 +404,10 @@
CHECK(source->IsExternal());
CHECK_EQ(resource,
static_cast<TestResource*>(source->GetExternalStringResource()));
+ String::Encoding encoding = String::UNKNOWN_ENCODING;
+ CHECK_EQ(static_cast<const
String::ExternalStringResourceBase*>(resource),
+ source->GetExternalStringResourceBase(&encoding));
+ CHECK_EQ(String::TWO_BYTE_ENCODING, encoding);
HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
CHECK_EQ(0, dispose_count);
}
@@ -419,9 +423,16 @@
{
v8::HandleScope scope;
LocalContext env;
- Local<String> source =
- String::NewExternal(new TestAsciiResource(i::StrDup(c_source),
- &dispose_count));
+ TestAsciiResource* resource = new
TestAsciiResource(i::StrDup(c_source),
+ &dispose_count);
+ Local<String> source = String::NewExternal(resource);
+ CHECK(source->IsExternalAscii());
+ CHECK_EQ(static_cast<const
String::ExternalStringResourceBase*>(resource),
+ source->GetExternalAsciiStringResource());
+ String::Encoding encoding = String::UNKNOWN_ENCODING;
+ CHECK_EQ(static_cast<const
String::ExternalStringResourceBase*>(resource),
+ source->GetExternalStringResourceBase(&encoding));
+ CHECK_EQ(String::ASCII_ENCODING, encoding);
Local<Script> script = Script::Compile(source);
Local<Value> value = script->Run();
CHECK(value->IsNumber());
@@ -445,6 +456,11 @@
// Trigger GCs so that the newly allocated string moves to old gen.
HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now
HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now
+ CHECK_EQ(source->IsExternal(), false);
+ CHECK_EQ(source->IsExternalAscii(), false);
+ String::Encoding encoding = String::UNKNOWN_ENCODING;
+ CHECK_EQ(NULL, source->GetExternalStringResourceBase(&encoding));
+ CHECK_EQ(String::ASCII_ENCODING, encoding);
bool success = source->MakeExternal(new TestResource(two_byte_source,
&dispose_count));
CHECK(success);
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev