Landing for miket@chromium.org: Add an optional source length field to the Extension constructor.

Original code review: http://codereview.chromium.org/7889046/
Review URL: http://codereview.chromium.org/7978028

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9365 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 6c8472bd
...@@ -1171,7 +1171,8 @@ class String : public Primitive { ...@@ -1171,7 +1171,8 @@ class String : public Primitive {
* Get the ExternalAsciiStringResource for an external ASCII string. * Get the ExternalAsciiStringResource for an external ASCII string.
* Returns NULL if IsExternalAscii() doesn't return true. * Returns NULL if IsExternalAscii() doesn't return true.
*/ */
V8EXPORT ExternalAsciiStringResource* GetExternalAsciiStringResource() const; V8EXPORT const ExternalAsciiStringResource* GetExternalAsciiStringResource()
const;
static inline String* Cast(v8::Value* obj); static inline String* Cast(v8::Value* obj);
...@@ -2451,24 +2452,42 @@ class V8EXPORT TypeSwitch : public Data { ...@@ -2451,24 +2452,42 @@ class V8EXPORT TypeSwitch : public Data {
// --- Extensions --- // --- Extensions ---
class ExternalAsciiStringResourceImpl
: public String::ExternalAsciiStringResource {
public:
ExternalAsciiStringResourceImpl() : data_(0), length_(0) {}
ExternalAsciiStringResourceImpl(const char* data, size_t length)
: data_(data), length_(length) {}
const char* data() const { return data_; }
size_t length() const { return length_; }
private:
const char* data_;
size_t length_;
};
/** /**
* Ignore * Ignore
*/ */
class V8EXPORT Extension { // NOLINT class V8EXPORT Extension { // NOLINT
public: public:
// Note that the strings passed into this constructor must live as long
// as the Extension itself.
Extension(const char* name, Extension(const char* name,
const char* source = 0, const char* source = 0,
int dep_count = 0, int dep_count = 0,
const char** deps = 0); const char** deps = 0,
int source_length = -1);
virtual ~Extension() { } virtual ~Extension() { }
virtual v8::Handle<v8::FunctionTemplate> virtual v8::Handle<v8::FunctionTemplate>
GetNativeFunction(v8::Handle<v8::String> name) { GetNativeFunction(v8::Handle<v8::String> name) {
return v8::Handle<v8::FunctionTemplate>(); return v8::Handle<v8::FunctionTemplate>();
} }
const char* name() { return name_; } const char* name() const { return name_; }
const char* source() { return source_; } size_t source_length() const { return source_length_; }
const String::ExternalAsciiStringResource* source() const {
return &source_; }
int dependency_count() { return dep_count_; } int dependency_count() { return dep_count_; }
const char** dependencies() { return deps_; } const char** dependencies() { return deps_; }
void set_auto_enable(bool value) { auto_enable_ = value; } void set_auto_enable(bool value) { auto_enable_ = value; }
...@@ -2476,7 +2495,8 @@ class V8EXPORT Extension { // NOLINT ...@@ -2476,7 +2495,8 @@ class V8EXPORT Extension { // NOLINT
private: private:
const char* name_; const char* name_;
const char* source_; size_t source_length_; // expected to initialize before source_
ExternalAsciiStringResourceImpl source_;
int dep_count_; int dep_count_;
const char** deps_; const char** deps_;
bool auto_enable_; bool auto_enable_;
......
...@@ -501,9 +501,12 @@ void RegisterExtension(Extension* that) { ...@@ -501,9 +501,12 @@ void RegisterExtension(Extension* that) {
Extension::Extension(const char* name, Extension::Extension(const char* name,
const char* source, const char* source,
int dep_count, int dep_count,
const char** deps) const char** deps,
int source_length)
: name_(name), : name_(name),
source_(source), source_length_(source_length >= 0 ?
source_length : (source ? strlen(source) : 0)),
source_(source, source_length_),
dep_count_(dep_count), dep_count_(dep_count),
deps_(deps), deps_(deps),
auto_enable_(false) { } auto_enable_(false) { }
...@@ -3789,10 +3792,11 @@ bool v8::String::IsExternalAscii() const { ...@@ -3789,10 +3792,11 @@ bool v8::String::IsExternalAscii() const {
void v8::String::VerifyExternalStringResource( void v8::String::VerifyExternalStringResource(
v8::String::ExternalStringResource* value) const { v8::String::ExternalStringResource* value) const {
i::Handle<i::String> str = Utils::OpenHandle(this); i::Handle<i::String> str = Utils::OpenHandle(this);
v8::String::ExternalStringResource* expected; const v8::String::ExternalStringResource* expected;
if (i::StringShape(*str).IsExternalTwoByte()) { if (i::StringShape(*str).IsExternalTwoByte()) {
void* resource = i::Handle<i::ExternalTwoByteString>::cast(str)->resource(); const void* resource =
expected = reinterpret_cast<ExternalStringResource*>(resource); i::Handle<i::ExternalTwoByteString>::cast(str)->resource();
expected = reinterpret_cast<const ExternalStringResource*>(resource);
} else { } else {
expected = NULL; expected = NULL;
} }
...@@ -3800,7 +3804,7 @@ void v8::String::VerifyExternalStringResource( ...@@ -3800,7 +3804,7 @@ void v8::String::VerifyExternalStringResource(
} }
v8::String::ExternalAsciiStringResource* const v8::String::ExternalAsciiStringResource*
v8::String::GetExternalAsciiStringResource() const { v8::String::GetExternalAsciiStringResource() const {
i::Handle<i::String> str = Utils::OpenHandle(this); i::Handle<i::String> str = Utils::OpenHandle(this);
if (IsDeadCheck(str->GetIsolate(), if (IsDeadCheck(str->GetIsolate(),
...@@ -3808,8 +3812,9 @@ v8::String::ExternalAsciiStringResource* ...@@ -3808,8 +3812,9 @@ v8::String::ExternalAsciiStringResource*
return NULL; return NULL;
} }
if (i::StringShape(*str).IsExternalAscii()) { if (i::StringShape(*str).IsExternalAscii()) {
void* resource = i::Handle<i::ExternalAsciiString>::cast(str)->resource(); const void* resource =
return reinterpret_cast<ExternalAsciiStringResource*>(resource); i::Handle<i::ExternalAsciiString>::cast(str)->resource();
return reinterpret_cast<const ExternalAsciiStringResource*>(resource);
} else { } else {
return NULL; return NULL;
} }
......
...@@ -1940,14 +1940,13 @@ bool Genesis::InstallExtension(v8::RegisteredExtension* current) { ...@@ -1940,14 +1940,13 @@ bool Genesis::InstallExtension(v8::RegisteredExtension* current) {
if (!InstallExtension(extension->dependencies()[i])) return false; if (!InstallExtension(extension->dependencies()[i])) return false;
} }
Isolate* isolate = Isolate::Current(); Isolate* isolate = Isolate::Current();
Vector<const char> source = CStrVector(extension->source()); bool result = CompileScriptCached(
Handle<String> source_code = isolate->factory()->NewStringFromAscii(source); CStrVector(extension->name()),
bool result = CompileScriptCached(CStrVector(extension->name()), isolate->factory()->NewExternalStringFromAscii(extension->source()),
source_code, isolate->bootstrapper()->extensions_cache(),
isolate->bootstrapper()->extensions_cache(), extension,
extension, Handle<Context>(isolate->context()),
Handle<Context>(isolate->context()), false);
false);
ASSERT(isolate->has_pending_exception() != result); ASSERT(isolate->has_pending_exception() != result);
if (!result) { if (!result) {
isolate->clear_pending_exception(); isolate->clear_pending_exception();
......
...@@ -234,7 +234,7 @@ Handle<String> Factory::NewProperSubString(Handle<String> str, ...@@ -234,7 +234,7 @@ Handle<String> Factory::NewProperSubString(Handle<String> str,
Handle<String> Factory::NewExternalStringFromAscii( Handle<String> Factory::NewExternalStringFromAscii(
ExternalAsciiString::Resource* resource) { const ExternalAsciiString::Resource* resource) {
CALL_HEAP_FUNCTION( CALL_HEAP_FUNCTION(
isolate(), isolate(),
isolate()->heap()->AllocateExternalStringFromAscii(resource), isolate()->heap()->AllocateExternalStringFromAscii(resource),
...@@ -243,7 +243,7 @@ Handle<String> Factory::NewExternalStringFromAscii( ...@@ -243,7 +243,7 @@ Handle<String> Factory::NewExternalStringFromAscii(
Handle<String> Factory::NewExternalStringFromTwoByte( Handle<String> Factory::NewExternalStringFromTwoByte(
ExternalTwoByteString::Resource* resource) { const ExternalTwoByteString::Resource* resource) {
CALL_HEAP_FUNCTION( CALL_HEAP_FUNCTION(
isolate(), isolate(),
isolate()->heap()->AllocateExternalStringFromTwoByte(resource), isolate()->heap()->AllocateExternalStringFromTwoByte(resource),
......
...@@ -145,9 +145,9 @@ class Factory { ...@@ -145,9 +145,9 @@ class Factory {
// not make sense to have a UTF-8 factory function for external strings, // not make sense to have a UTF-8 factory function for external strings,
// because we cannot change the underlying buffer. // because we cannot change the underlying buffer.
Handle<String> NewExternalStringFromAscii( Handle<String> NewExternalStringFromAscii(
ExternalAsciiString::Resource* resource); const ExternalAsciiString::Resource* resource);
Handle<String> NewExternalStringFromTwoByte( Handle<String> NewExternalStringFromTwoByte(
ExternalTwoByteString::Resource* resource); const ExternalTwoByteString::Resource* resource);
// Create a global (but otherwise uninitialized) context. // Create a global (but otherwise uninitialized) context.
Handle<Context> NewGlobalContext(); Handle<Context> NewGlobalContext();
......
...@@ -2919,7 +2919,7 @@ MaybeObject* Heap::AllocateSubString(String* buffer, ...@@ -2919,7 +2919,7 @@ MaybeObject* Heap::AllocateSubString(String* buffer,
MaybeObject* Heap::AllocateExternalStringFromAscii( MaybeObject* Heap::AllocateExternalStringFromAscii(
ExternalAsciiString::Resource* resource) { const ExternalAsciiString::Resource* resource) {
size_t length = resource->length(); size_t length = resource->length();
if (length > static_cast<size_t>(String::kMaxLength)) { if (length > static_cast<size_t>(String::kMaxLength)) {
isolate()->context()->mark_out_of_memory(); isolate()->context()->mark_out_of_memory();
...@@ -2942,7 +2942,7 @@ MaybeObject* Heap::AllocateExternalStringFromAscii( ...@@ -2942,7 +2942,7 @@ MaybeObject* Heap::AllocateExternalStringFromAscii(
MaybeObject* Heap::AllocateExternalStringFromTwoByte( MaybeObject* Heap::AllocateExternalStringFromTwoByte(
ExternalTwoByteString::Resource* resource) { const ExternalTwoByteString::Resource* resource) {
size_t length = resource->length(); size_t length = resource->length();
if (length > static_cast<size_t>(String::kMaxLength)) { if (length > static_cast<size_t>(String::kMaxLength)) {
isolate()->context()->mark_out_of_memory(); isolate()->context()->mark_out_of_memory();
......
...@@ -835,9 +835,9 @@ class Heap { ...@@ -835,9 +835,9 @@ class Heap {
// failed. // failed.
// Please note this does not perform a garbage collection. // Please note this does not perform a garbage collection.
MUST_USE_RESULT MaybeObject* AllocateExternalStringFromAscii( MUST_USE_RESULT MaybeObject* AllocateExternalStringFromAscii(
ExternalAsciiString::Resource* resource); const ExternalAsciiString::Resource* resource);
MUST_USE_RESULT MaybeObject* AllocateExternalStringFromTwoByte( MUST_USE_RESULT MaybeObject* AllocateExternalStringFromTwoByte(
ExternalTwoByteString::Resource* resource); const ExternalTwoByteString::Resource* resource);
// Finalizes an external string by deleting the associated external // Finalizes an external string by deleting the associated external
// data and clearing the resource pointer. // data and clearing the resource pointer.
......
...@@ -2299,25 +2299,27 @@ void ConsString::set_second(String* value, WriteBarrierMode mode) { ...@@ -2299,25 +2299,27 @@ void ConsString::set_second(String* value, WriteBarrierMode mode) {
} }
ExternalAsciiString::Resource* ExternalAsciiString::resource() { const ExternalAsciiString::Resource* ExternalAsciiString::resource() {
return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)); return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
} }
void ExternalAsciiString::set_resource( void ExternalAsciiString::set_resource(
ExternalAsciiString::Resource* resource) { const ExternalAsciiString::Resource* resource) {
*reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource; *reinterpret_cast<const Resource**>(
FIELD_ADDR(this, kResourceOffset)) = resource;
} }
ExternalTwoByteString::Resource* ExternalTwoByteString::resource() { const ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)); return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
} }
void ExternalTwoByteString::set_resource( void ExternalTwoByteString::set_resource(
ExternalTwoByteString::Resource* resource) { const ExternalTwoByteString::Resource* resource) {
*reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource; *reinterpret_cast<const Resource**>(
FIELD_ADDR(this, kResourceOffset)) = resource;
} }
......
...@@ -6379,8 +6379,8 @@ class ExternalAsciiString: public ExternalString { ...@@ -6379,8 +6379,8 @@ class ExternalAsciiString: public ExternalString {
typedef v8::String::ExternalAsciiStringResource Resource; typedef v8::String::ExternalAsciiStringResource Resource;
// The underlying resource. // The underlying resource.
inline Resource* resource(); inline const Resource* resource();
inline void set_resource(Resource* buffer); inline void set_resource(const Resource* buffer);
// Dispatched behavior. // Dispatched behavior.
uint16_t ExternalAsciiStringGet(int index); uint16_t ExternalAsciiStringGet(int index);
...@@ -6416,8 +6416,8 @@ class ExternalTwoByteString: public ExternalString { ...@@ -6416,8 +6416,8 @@ class ExternalTwoByteString: public ExternalString {
typedef v8::String::ExternalStringResource Resource; typedef v8::String::ExternalStringResource Resource;
// The underlying string resource. // The underlying string resource.
inline Resource* resource(); inline const Resource* resource();
inline void set_resource(Resource* buffer); inline void set_resource(const Resource* buffer);
// Dispatched behavior. // Dispatched behavior.
uint16_t ExternalTwoByteStringGet(int index); uint16_t ExternalTwoByteStringGet(int index);
......
...@@ -1453,7 +1453,7 @@ void Serializer::ObjectSerializer::VisitExternalAsciiString( ...@@ -1453,7 +1453,7 @@ void Serializer::ObjectSerializer::VisitExternalAsciiString(
if (!source->IsUndefined()) { if (!source->IsUndefined()) {
ExternalAsciiString* string = ExternalAsciiString::cast(source); ExternalAsciiString* string = ExternalAsciiString::cast(source);
typedef v8::String::ExternalAsciiStringResource Resource; typedef v8::String::ExternalAsciiStringResource Resource;
Resource* resource = string->resource(); const Resource* resource = string->resource();
if (resource == *resource_pointer) { if (resource == *resource_pointer) {
sink_->Put(kNativesStringResource, "NativesStringResource"); sink_->Put(kNativesStringResource, "NativesStringResource");
sink_->PutSection(i, "NativesStringResourceEnd"); sink_->PutSection(i, "NativesStringResourceEnd");
......
...@@ -4293,6 +4293,47 @@ THREADED_TEST(SimpleExtensions) { ...@@ -4293,6 +4293,47 @@ THREADED_TEST(SimpleExtensions) {
} }
static const char* kEmbeddedExtensionSource =
"function Ret54321(){return 54321;}~~@@$"
"$%% THIS IS A SERIES OF NON-NULL-TERMINATED STRINGS.";
static const int kEmbeddedExtensionSourceValidLen = 34;
THREADED_TEST(ExtensionMissingSourceLength) {
v8::HandleScope handle_scope;
v8::RegisterExtension(new Extension("srclentest_fail",
kEmbeddedExtensionSource));
const char* extension_names[] = { "srclentest_fail" };
v8::ExtensionConfiguration extensions(1, extension_names);
v8::Handle<Context> context = Context::New(&extensions);
CHECK_EQ(0, *context);
}
THREADED_TEST(ExtensionWithSourceLength) {
for (int source_len = kEmbeddedExtensionSourceValidLen - 1;
source_len <= kEmbeddedExtensionSourceValidLen + 1; ++source_len) {
v8::HandleScope handle_scope;
char extension_name[32];
snprintf(extension_name, sizeof(extension_name), "ext #%d", source_len);
v8::RegisterExtension(new Extension(extension_name,
kEmbeddedExtensionSource, 0, 0,
source_len));
const char* extension_names[1] = { extension_name };
v8::ExtensionConfiguration extensions(1, extension_names);
v8::Handle<Context> context = Context::New(&extensions);
if (source_len == kEmbeddedExtensionSourceValidLen) {
Context::Scope lock(context);
v8::Handle<Value> result = Script::Compile(v8_str("Ret54321()"))->Run();
CHECK_EQ(v8::Integer::New(54321), result);
} else {
// Anything but exactly the right length should fail to compile.
CHECK_EQ(0, *context);
}
}
}
static const char* kEvalExtensionSource1 = static const char* kEvalExtensionSource1 =
"function UseEval1() {" "function UseEval1() {"
" var x = 42;" " var x = 42;"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment