Upgrade to V8 3.3
Merge V8 at 3.3.10.39
Simple merge required updates to makefiles only.
Bug: 5688872
Change-Id: I14703f418235f5ce6013b9b3e2e502407a9f6dfd
diff --git a/src/api.cc b/src/api.cc
index 3ae6304..5980854 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -53,7 +53,6 @@
#define LOG_API(isolate, expr) LOG(isolate, ApiEntryCall(expr))
-// TODO(isolates): avoid repeated TLS reads in function prologues.
#ifdef ENABLE_VMSTATE_TRACKING
#define ENTER_V8(isolate) \
ASSERT((isolate)->IsInitialized()); \
@@ -89,7 +88,7 @@
if (has_pending_exception) { \
if (handle_scope_implementer->CallDepthIsZero() && \
(isolate)->is_out_of_memory()) { \
- if (!(isolate)->ignore_out_of_memory()) \
+ if (!handle_scope_implementer->ignore_out_of_memory()) \
i::V8::FatalProcessOutOfMemory(NULL); \
} \
bool call_depth_is_zero = handle_scope_implementer->CallDepthIsZero(); \
@@ -290,6 +289,7 @@
if (isolate != NULL) {
if (isolate->IsInitialized()) return true;
}
+ ASSERT(isolate == i::Isolate::Current());
return ApiCheck(InitializeHelper(), location, "Error initializing V8");
}
@@ -311,12 +311,74 @@
}
+StartupData::CompressionAlgorithm V8::GetCompressedStartupDataAlgorithm() {
+#ifdef COMPRESS_STARTUP_DATA_BZ2
+ return StartupData::kBZip2;
+#else
+ return StartupData::kUncompressed;
+#endif
+}
+
+
+enum CompressedStartupDataItems {
+ kSnapshot = 0,
+ kSnapshotContext,
+ kCompressedStartupDataCount
+};
+
+int V8::GetCompressedStartupDataCount() {
+#ifdef COMPRESS_STARTUP_DATA_BZ2
+ return kCompressedStartupDataCount;
+#else
+ return 0;
+#endif
+}
+
+
+void V8::GetCompressedStartupData(StartupData* compressed_data) {
+#ifdef COMPRESS_STARTUP_DATA_BZ2
+ compressed_data[kSnapshot].data =
+ reinterpret_cast<const char*>(i::Snapshot::data());
+ compressed_data[kSnapshot].compressed_size = i::Snapshot::size();
+ compressed_data[kSnapshot].raw_size = i::Snapshot::raw_size();
+
+ compressed_data[kSnapshotContext].data =
+ reinterpret_cast<const char*>(i::Snapshot::context_data());
+ compressed_data[kSnapshotContext].compressed_size =
+ i::Snapshot::context_size();
+ compressed_data[kSnapshotContext].raw_size = i::Snapshot::context_raw_size();
+#endif
+}
+
+
+void V8::SetDecompressedStartupData(StartupData* decompressed_data) {
+#ifdef COMPRESS_STARTUP_DATA_BZ2
+ ASSERT_EQ(i::Snapshot::raw_size(), decompressed_data[kSnapshot].raw_size);
+ i::Snapshot::set_raw_data(
+ reinterpret_cast<const i::byte*>(decompressed_data[kSnapshot].data));
+
+ ASSERT_EQ(i::Snapshot::context_raw_size(),
+ decompressed_data[kSnapshotContext].raw_size);
+ i::Snapshot::set_context_raw_data(
+ reinterpret_cast<const i::byte*>(
+ decompressed_data[kSnapshotContext].data));
+#endif
+}
+
+
void V8::SetFatalErrorHandler(FatalErrorCallback that) {
i::Isolate* isolate = EnterIsolateIfNeeded();
isolate->set_exception_behavior(that);
}
+void V8::SetAllowCodeGenerationFromStringsCallback(
+ AllowCodeGenerationFromStringsCallback callback) {
+ i::Isolate* isolate = EnterIsolateIfNeeded();
+ isolate->set_allow_code_gen_callback(callback);
+}
+
+
#ifdef DEBUG
void ImplementationUtilities::ZapHandleRange(i::Object** begin,
i::Object** end) {
@@ -477,6 +539,13 @@
}
+void V8::MarkIndependent(i::Object** object) {
+ i::Isolate* isolate = i::Isolate::Current();
+ LOG_API(isolate, "MakeIndependent");
+ isolate->global_handles()->MarkIndependent(object);
+}
+
+
bool V8::IsGlobalNearDeath(i::Object** obj) {
i::Isolate* isolate = i::Isolate::Current();
LOG_API(isolate, "IsGlobalNearDeath");
@@ -867,9 +936,9 @@
}
-#define SET_FIELD_WRAPPED(obj, setter, cdata) do { \
- i::Handle<i::Object> proxy = FromCData(cdata); \
- (obj)->setter(*proxy); \
+#define SET_FIELD_WRAPPED(obj, setter, cdata) do { \
+ i::Handle<i::Object> foreign = FromCData(cdata); \
+ (obj)->setter(*foreign); \
} while (false)
@@ -1989,7 +2058,7 @@
if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsExternal()")) {
return false;
}
- return Utils::OpenHandle(this)->IsProxy();
+ return Utils::OpenHandle(this)->IsForeign();
}
@@ -2150,7 +2219,7 @@
void External::CheckCast(v8::Value* that) {
if (IsDeadCheck(i::Isolate::Current(), "v8::External::Cast()")) return;
i::Handle<i::Object> obj = Utils::OpenHandle(that);
- ApiCheck(obj->IsProxy(),
+ ApiCheck(obj->IsForeign(),
"v8::External::Cast()",
"Could not convert to external");
}
@@ -2751,6 +2820,15 @@
}
+bool v8::Object::HasOwnProperty(Handle<String> key) {
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+ ON_BAILOUT(isolate, "v8::Object::HasOwnProperty()",
+ return false);
+ return Utils::OpenHandle(this)->HasLocalProperty(
+ *Utils::OpenHandle(*key));
+}
+
+
bool v8::Object::HasRealNamedProperty(Handle<String> key) {
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ON_BAILOUT(isolate, "v8::Object::HasRealNamedProperty()",
@@ -3161,6 +3239,8 @@
return kExternalUnsignedIntArray;
case i::EXTERNAL_FLOAT_ARRAY_TYPE:
return kExternalFloatArray;
+ case i::EXTERNAL_DOUBLE_ARRAY_TYPE:
+ return kExternalDoubleArray;
case i::EXTERNAL_PIXEL_ARRAY_TYPE:
return kExternalPixelArray;
default:
@@ -3182,6 +3262,85 @@
}
+bool v8::Object::IsCallable() {
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+ ON_BAILOUT(isolate, "v8::Object::IsCallable()", return false);
+ ENTER_V8(isolate);
+ i::HandleScope scope(isolate);
+ i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
+ if (obj->IsJSFunction()) return true;
+ return i::Execution::GetFunctionDelegate(obj)->IsJSFunction();
+}
+
+
+Local<v8::Value> Object::CallAsFunction(v8::Handle<v8::Object> recv, int argc,
+ v8::Handle<v8::Value> argv[]) {
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+ ON_BAILOUT(isolate, "v8::Object::CallAsFunction()",
+ return Local<v8::Value>());
+ LOG_API(isolate, "Object::CallAsFunction");
+ ENTER_V8(isolate);
+ i::HandleScope scope(isolate);
+ i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
+ i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
+ STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
+ i::Object*** args = reinterpret_cast<i::Object***>(argv);
+ i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>();
+ if (obj->IsJSFunction()) {
+ fun = i::Handle<i::JSFunction>::cast(obj);
+ } else {
+ EXCEPTION_PREAMBLE(isolate);
+ i::Handle<i::Object> delegate =
+ i::Execution::TryGetFunctionDelegate(obj, &has_pending_exception);
+ EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
+ fun = i::Handle<i::JSFunction>::cast(delegate);
+ recv_obj = obj;
+ }
+ EXCEPTION_PREAMBLE(isolate);
+ i::Handle<i::Object> returned =
+ i::Execution::Call(fun, recv_obj, argc, args, &has_pending_exception);
+ EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
+ return Utils::ToLocal(scope.CloseAndEscape(returned));
+}
+
+
+Local<v8::Value> Object::CallAsConstructor(int argc,
+ v8::Handle<v8::Value> argv[]) {
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+ ON_BAILOUT(isolate, "v8::Object::CallAsConstructor()",
+ return Local<v8::Object>());
+ LOG_API(isolate, "Object::CallAsConstructor");
+ ENTER_V8(isolate);
+ i::HandleScope scope(isolate);
+ i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
+ STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
+ i::Object*** args = reinterpret_cast<i::Object***>(argv);
+ if (obj->IsJSFunction()) {
+ i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(obj);
+ EXCEPTION_PREAMBLE(isolate);
+ i::Handle<i::Object> returned =
+ i::Execution::New(fun, argc, args, &has_pending_exception);
+ EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
+ return Utils::ToLocal(scope.CloseAndEscape(
+ i::Handle<i::JSObject>::cast(returned)));
+ }
+ EXCEPTION_PREAMBLE(isolate);
+ i::Handle<i::Object> delegate =
+ i::Execution::TryGetConstructorDelegate(obj, &has_pending_exception);
+ EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
+ if (!delegate->IsUndefined()) {
+ i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(delegate);
+ EXCEPTION_PREAMBLE(isolate);
+ i::Handle<i::Object> returned =
+ i::Execution::Call(fun, obj, argc, args, &has_pending_exception);
+ EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
+ ASSERT(!delegate->IsUndefined());
+ return Utils::ToLocal(scope.CloseAndEscape(returned));
+ }
+ return Local<v8::Object>();
+}
+
+
Local<v8::Object> Function::NewInstance() const {
return NewInstance(0, NULL);
}
@@ -3570,11 +3729,11 @@
Utils::OpenHandle(this)->SetInternalField(index, EncodeAsSmi(value));
} else {
HandleScope scope;
- i::Handle<i::Proxy> proxy =
- isolate->factory()->NewProxy(
+ i::Handle<i::Foreign> foreign =
+ isolate->factory()->NewForeign(
reinterpret_cast<i::Address>(value), i::TENURED);
- if (!proxy.is_null())
- Utils::OpenHandle(this)->SetInternalField(index, *proxy);
+ if (!foreign.is_null())
+ Utils::OpenHandle(this)->SetInternalField(index, *foreign);
}
ASSERT_EQ(value, GetPointerFromInternalField(index));
}
@@ -3707,6 +3866,7 @@
// Create the environment.
env = isolate->bootstrapper()->CreateEnvironment(
+ isolate,
Utils::OpenHandle(*global_object),
proxy_template,
extensions);
@@ -3779,7 +3939,7 @@
v8::Local<v8::Context> Context::GetEntered() {
i::Isolate* isolate = i::Isolate::Current();
- if (!EnsureInitializedForIsolate(isolate, "v8::Context::GetEntered()")) {
+ if (IsDeadCheck(isolate, "v8::Context::GetEntered()")) {
return Local<Context>();
}
i::Handle<i::Object> last =
@@ -3851,6 +4011,20 @@
}
+void Context::AllowCodeGenerationFromStrings(bool allow) {
+ i::Isolate* isolate = i::Isolate::Current();
+ if (IsDeadCheck(isolate, "v8::Context::AllowCodeGenerationFromStrings()")) {
+ return;
+ }
+ ENTER_V8(isolate);
+ i::Object** ctx = reinterpret_cast<i::Object**>(this);
+ i::Handle<i::Context> context =
+ i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
+ context->set_allow_code_gen_from_strings(
+ allow ? isolate->heap()->true_value() : isolate->heap()->false_value());
+}
+
+
void V8::SetWrapperClassId(i::Object** global_handle, uint16_t class_id) {
i::GlobalHandles::SetWrapperClassId(global_handle, class_id);
}
@@ -3895,19 +4069,19 @@
static Local<External> ExternalNewImpl(void* data) {
- return Utils::ToLocal(FACTORY->NewProxy(static_cast<i::Address>(data)));
+ return Utils::ToLocal(FACTORY->NewForeign(static_cast<i::Address>(data)));
}
static void* ExternalValueImpl(i::Handle<i::Object> obj) {
- return reinterpret_cast<void*>(i::Proxy::cast(*obj)->proxy());
+ return reinterpret_cast<void*>(i::Foreign::cast(*obj)->address());
}
Local<Value> v8::External::Wrap(void* data) {
i::Isolate* isolate = i::Isolate::Current();
STATIC_ASSERT(sizeof(data) == sizeof(i::Address));
- EnsureInitializedForIsolate(isolate, "v8::External::Wrap()");
LOG_API(isolate, "External::Wrap");
+ EnsureInitializedForIsolate(isolate, "v8::External::Wrap()");
ENTER_V8(isolate);
v8::Local<v8::Value> result = CanBeEncodedAsSmi(data)
@@ -3924,8 +4098,8 @@
i::Object* value = obj->GetInternalField(index);
if (value->IsSmi()) {
return i::Internals::GetExternalPointerFromSmi(value);
- } else if (value->IsProxy()) {
- return reinterpret_cast<void*>(i::Proxy::cast(value)->proxy());
+ } else if (value->IsForeign()) {
+ return reinterpret_cast<void*>(i::Foreign::cast(value)->address());
} else {
return NULL;
}
@@ -3938,7 +4112,7 @@
void* result;
if (obj->IsSmi()) {
result = i::Internals::GetExternalPointerFromSmi(*obj);
- } else if (obj->IsProxy()) {
+ } else if (obj->IsForeign()) {
result = ExternalValueImpl(obj);
} else {
result = NULL;
@@ -3951,8 +4125,8 @@
Local<External> v8::External::New(void* data) {
STATIC_ASSERT(sizeof(data) == sizeof(i::Address));
i::Isolate* isolate = i::Isolate::Current();
- EnsureInitializedForIsolate(isolate, "v8::External::New()");
LOG_API(isolate, "External::New");
+ EnsureInitializedForIsolate(isolate, "v8::External::New()");
ENTER_V8(isolate);
return ExternalNewImpl(data);
}
@@ -4371,7 +4545,8 @@
void V8::IgnoreOutOfMemoryException() {
- EnterIsolateIfNeeded()->set_ignore_out_of_memory(true);
+ EnterIsolateIfNeeded()->handle_scope_implementer()->set_ignore_out_of_memory(
+ true);
}
@@ -4383,7 +4558,7 @@
i::HandleScope scope(isolate);
NeanderArray listeners(isolate->factory()->message_listeners());
NeanderObject obj(2);
- obj.set(0, *isolate->factory()->NewProxy(FUNCTION_ADDR(that)));
+ obj.set(0, *isolate->factory()->NewForeign(FUNCTION_ADDR(that)));
obj.set(1, data.IsEmpty() ?
isolate->heap()->undefined_value() :
*Utils::OpenHandle(*data));
@@ -4403,8 +4578,8 @@
if (listeners.get(i)->IsUndefined()) continue; // skip deleted ones
NeanderObject listener(i::JSObject::cast(listeners.get(i)));
- i::Handle<i::Proxy> callback_obj(i::Proxy::cast(listener.get(0)));
- if (callback_obj->proxy() == FUNCTION_ADDR(that)) {
+ i::Handle<i::Foreign> callback_obj(i::Foreign::cast(listener.get(0)));
+ if (callback_obj->address() == FUNCTION_ADDR(that)) {
listeners.set(i, isolate->heap()->undefined_value());
}
}
@@ -4695,26 +4870,30 @@
}
-String::Utf8Value::Utf8Value(v8::Handle<v8::Value> obj) {
+void Isolate::SetData(void* data) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+ isolate->SetData(data);
+}
+
+void* Isolate::GetData() {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+ return isolate->GetData();
+}
+
+
+String::Utf8Value::Utf8Value(v8::Handle<v8::Value> obj)
+ : str_(NULL), length_(0) {
i::Isolate* isolate = i::Isolate::Current();
if (IsDeadCheck(isolate, "v8::String::Utf8Value::Utf8Value()")) return;
- if (obj.IsEmpty()) {
- str_ = NULL;
- length_ = 0;
- return;
- }
+ if (obj.IsEmpty()) return;
ENTER_V8(isolate);
i::HandleScope scope(isolate);
TryCatch try_catch;
Handle<String> str = obj->ToString();
- if (str.IsEmpty()) {
- str_ = NULL;
- length_ = 0;
- } else {
- length_ = str->Utf8Length();
- str_ = i::NewArray<char>(length_ + 1);
- str->WriteUtf8(str_);
- }
+ if (str.IsEmpty()) return;
+ length_ = str->Utf8Length();
+ str_ = i::NewArray<char>(length_ + 1);
+ str->WriteUtf8(str_);
}
@@ -4723,26 +4902,19 @@
}
-String::AsciiValue::AsciiValue(v8::Handle<v8::Value> obj) {
+String::AsciiValue::AsciiValue(v8::Handle<v8::Value> obj)
+ : str_(NULL), length_(0) {
i::Isolate* isolate = i::Isolate::Current();
if (IsDeadCheck(isolate, "v8::String::AsciiValue::AsciiValue()")) return;
- if (obj.IsEmpty()) {
- str_ = NULL;
- length_ = 0;
- return;
- }
+ if (obj.IsEmpty()) return;
ENTER_V8(isolate);
i::HandleScope scope(isolate);
TryCatch try_catch;
Handle<String> str = obj->ToString();
- if (str.IsEmpty()) {
- str_ = NULL;
- length_ = 0;
- } else {
- length_ = str->Length();
- str_ = i::NewArray<char>(length_ + 1);
- str->WriteAscii(str_);
- }
+ if (str.IsEmpty()) return;
+ length_ = str->Length();
+ str_ = i::NewArray<char>(length_ + 1);
+ str->WriteAscii(str_);
}
@@ -4751,26 +4923,19 @@
}
-String::Value::Value(v8::Handle<v8::Value> obj) {
+String::Value::Value(v8::Handle<v8::Value> obj)
+ : str_(NULL), length_(0) {
i::Isolate* isolate = i::Isolate::Current();
if (IsDeadCheck(isolate, "v8::String::Value::Value()")) return;
- if (obj.IsEmpty()) {
- str_ = NULL;
- length_ = 0;
- return;
- }
+ if (obj.IsEmpty()) return;
ENTER_V8(isolate);
i::HandleScope scope(isolate);
TryCatch try_catch;
Handle<String> str = obj->ToString();
- if (str.IsEmpty()) {
- str_ = NULL;
- length_ = 0;
- } else {
- length_ = str->Length();
- str_ = i::NewArray<uint16_t>(length_ + 1);
- str->Write(str_);
- }
+ if (str.IsEmpty()) return;
+ length_ = str->Length();
+ str_ = i::NewArray<uint16_t>(length_ + 1);
+ str->Write(str_);
}
@@ -4884,11 +5049,12 @@
isolate->set_debug_event_callback(that);
i::HandleScope scope(isolate);
- i::Handle<i::Object> proxy = isolate->factory()->undefined_value();
+ i::Handle<i::Object> foreign = isolate->factory()->undefined_value();
if (that != NULL) {
- proxy = isolate->factory()->NewProxy(FUNCTION_ADDR(EventCallbackWrapper));
+ foreign =
+ isolate->factory()->NewForeign(FUNCTION_ADDR(EventCallbackWrapper));
}
- isolate->debugger()->SetEventListener(proxy, Utils::OpenHandle(*data));
+ isolate->debugger()->SetEventListener(foreign, Utils::OpenHandle(*data));
return true;
}
@@ -4899,12 +5065,11 @@
ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener2()", return false);
ENTER_V8(isolate);
i::HandleScope scope(isolate);
- i::Handle<i::Object> proxy = isolate->factory()->undefined_value();
+ i::Handle<i::Object> foreign = isolate->factory()->undefined_value();
if (that != NULL) {
- proxy = isolate->factory()->NewProxy(FUNCTION_ADDR(that));
+ foreign = isolate->factory()->NewForeign(FUNCTION_ADDR(that));
}
- isolate->debugger()->SetEventListener(proxy,
- Utils::OpenHandle(*data));
+ isolate->debugger()->SetEventListener(foreign, Utils::OpenHandle(*data));
return true;
}
@@ -5619,9 +5784,8 @@
char* HandleScopeImplementer::ArchiveThread(char* storage) {
- Isolate* isolate = Isolate::Current();
v8::ImplementationUtilities::HandleScopeData* current =
- isolate->handle_scope_data();
+ isolate_->handle_scope_data();
handle_scope_data_ = *current;
memcpy(storage, this, sizeof(*this));
@@ -5639,7 +5803,7 @@
char* HandleScopeImplementer::RestoreThread(char* storage) {
memcpy(this, storage, sizeof(*this));
- *Isolate::Current()->handle_scope_data() = handle_scope_data_;
+ *isolate_->handle_scope_data() = handle_scope_data_;
return storage + ArchiveSpacePerThread();
}
@@ -5665,7 +5829,7 @@
void HandleScopeImplementer::Iterate(ObjectVisitor* v) {
v8::ImplementationUtilities::HandleScopeData* current =
- Isolate::Current()->handle_scope_data();
+ isolate_->handle_scope_data();
handle_scope_data_ = *current;
IterateThis(v);
}