Update V8 to version 4.1.0.21
This is a cherry-pick of all commits up to and including the
4.1.0.21 cherry-pick in Chromium.
Original commit message:
Version 4.1.0.21 (cherry-pick)
Merged 206e9136bde0f2b5ae8cb77afbb1e7833e5bd412
Unlink pages from the space page list after evacuation.
BUG=430201
LOG=N
R=jkummerow@chromium.org
Review URL: https://codereview.chromium.org/953813002
Cr-Commit-Position: refs/branch-heads/4.1@{#22}
Cr-Branched-From: 2e08d2a7aa9d65d269d8c57aba82eb38a8cb0a18-refs/heads/candidates@{#25353}
---
FPIIM-449
Change-Id: I8c23c7bbb70772b4858fe8a47b64fa97ee0d1f8c
diff --git a/src/api.cc b/src/api.cc
index e11d140..a459076 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -14,6 +14,7 @@
#include "include/v8-testing.h"
#include "src/assert-scope.h"
#include "src/background-parsing-task.h"
+#include "src/base/functional.h"
#include "src/base/platform/platform.h"
#include "src/base/platform/time.h"
#include "src/base/utils/random-number-generator.h"
@@ -38,8 +39,9 @@
#include "src/property.h"
#include "src/property-details.h"
#include "src/prototype.h"
-#include "src/runtime.h"
+#include "src/runtime/runtime.h"
#include "src/runtime-profiler.h"
+#include "src/sampler.h"
#include "src/scanner-character-streams.h"
#include "src/simulator.h"
#include "src/snapshot.h"
@@ -51,9 +53,8 @@
#define LOG_API(isolate, expr) LOG(isolate, ApiEntryCall(expr))
-#define ENTER_V8(isolate) \
- DCHECK((isolate)->IsInitialized()); \
- i::VMState<i::OTHER> __state__((isolate))
+#define ENTER_V8(isolate) \
+ i::VMState<v8::OTHER> __state__((isolate))
namespace v8 {
@@ -186,14 +187,7 @@
}
-bool V8::IsDead() {
- i::Isolate* isolate = i::Isolate::Current();
- return isolate->IsDead();
-}
-
-
static inline bool IsExecutionTerminatingCheck(i::Isolate* isolate) {
- if (!isolate->IsInitialized()) return false;
if (isolate->has_scheduled_exception()) {
return isolate->scheduled_exception() ==
isolate->heap()->termination_exception();
@@ -202,162 +196,60 @@
}
-StartupDataDecompressor::StartupDataDecompressor()
- : raw_data(i::NewArray<char*>(V8::GetCompressedStartupDataCount())) {
- for (int i = 0; i < V8::GetCompressedStartupDataCount(); ++i) {
- raw_data[i] = NULL;
- }
-}
-
-
-StartupDataDecompressor::~StartupDataDecompressor() {
- for (int i = 0; i < V8::GetCompressedStartupDataCount(); ++i) {
- i::DeleteArray(raw_data[i]);
- }
- i::DeleteArray(raw_data);
-}
-
-
-int StartupDataDecompressor::Decompress() {
- int compressed_data_count = V8::GetCompressedStartupDataCount();
- StartupData* compressed_data =
- i::NewArray<StartupData>(compressed_data_count);
- V8::GetCompressedStartupData(compressed_data);
- for (int i = 0; i < compressed_data_count; ++i) {
- char* decompressed = raw_data[i] =
- i::NewArray<char>(compressed_data[i].raw_size);
- if (compressed_data[i].compressed_size != 0) {
- int result = DecompressData(decompressed,
- &compressed_data[i].raw_size,
- compressed_data[i].data,
- compressed_data[i].compressed_size);
- if (result != 0) return result;
- } else {
- DCHECK_EQ(0, compressed_data[i].raw_size);
- }
- compressed_data[i].data = decompressed;
- }
- V8::SetDecompressedStartupData(compressed_data);
- i::DeleteArray(compressed_data);
- return 0;
-}
-
-
-StartupData::CompressionAlgorithm V8::GetCompressedStartupDataAlgorithm() {
-#ifdef COMPRESS_STARTUP_DATA_BZ2
- return StartupData::kBZip2;
-#else
- return StartupData::kUncompressed;
-#endif
-}
-
-
-enum CompressedStartupDataItems {
- kSnapshot = 0,
- kSnapshotContext,
- kLibraries,
- kExperimentalLibraries,
- 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();
-
- i::Vector<const i::byte> libraries_source = i::Natives::GetScriptsSource();
- compressed_data[kLibraries].data =
- reinterpret_cast<const char*>(libraries_source.start());
- compressed_data[kLibraries].compressed_size = libraries_source.length();
- compressed_data[kLibraries].raw_size = i::Natives::GetRawScriptsSize();
-
- i::Vector<const i::byte> exp_libraries_source =
- i::ExperimentalNatives::GetScriptsSource();
- compressed_data[kExperimentalLibraries].data =
- reinterpret_cast<const char*>(exp_libraries_source.start());
- compressed_data[kExperimentalLibraries].compressed_size =
- exp_libraries_source.length();
- compressed_data[kExperimentalLibraries].raw_size =
- i::ExperimentalNatives::GetRawScriptsSize();
-#endif
-}
-
-
-void V8::SetDecompressedStartupData(StartupData* decompressed_data) {
-#ifdef COMPRESS_STARTUP_DATA_BZ2
- DCHECK_EQ(i::Snapshot::raw_size(), decompressed_data[kSnapshot].raw_size);
- i::Snapshot::set_raw_data(
- reinterpret_cast<const i::byte*>(decompressed_data[kSnapshot].data));
-
- DCHECK_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));
-
- DCHECK_EQ(i::Natives::GetRawScriptsSize(),
- decompressed_data[kLibraries].raw_size);
- i::Vector<const char> libraries_source(
- decompressed_data[kLibraries].data,
- decompressed_data[kLibraries].raw_size);
- i::Natives::SetRawScriptsSource(libraries_source);
-
- DCHECK_EQ(i::ExperimentalNatives::GetRawScriptsSize(),
- decompressed_data[kExperimentalLibraries].raw_size);
- i::Vector<const char> exp_libraries_source(
- decompressed_data[kExperimentalLibraries].data,
- decompressed_data[kExperimentalLibraries].raw_size);
- i::ExperimentalNatives::SetRawScriptsSource(exp_libraries_source);
-#endif
-}
-
-
void V8::SetNativesDataBlob(StartupData* natives_blob) {
-#ifdef V8_USE_EXTERNAL_STARTUP_DATA
- i::SetNativesFromFile(natives_blob);
-#else
- CHECK(false);
-#endif
+ i::V8::SetNativesBlob(natives_blob);
}
void V8::SetSnapshotDataBlob(StartupData* snapshot_blob) {
-#ifdef V8_USE_EXTERNAL_STARTUP_DATA
- i::SetSnapshotFromFile(snapshot_blob);
-#else
- CHECK(false);
-#endif
+ i::V8::SetSnapshotBlob(snapshot_blob);
}
-void V8::SetFatalErrorHandler(FatalErrorCallback that) {
- i::Isolate* isolate = i::Isolate::Current();
- isolate->set_exception_behavior(that);
-}
+StartupData V8::CreateSnapshotDataBlob() {
+ Isolate::CreateParams params;
+ params.enable_serializer = true;
+ Isolate* isolate = v8::Isolate::New(params);
+ StartupData result = {NULL, 0};
+ {
+ Isolate::Scope isolate_scope(isolate);
+ i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ Persistent<Context> context;
+ {
+ HandleScope handle_scope(isolate);
+ context.Reset(isolate, Context::New(isolate));
+ }
+ if (!context.IsEmpty()) {
+ // Make sure all builtin scripts are cached.
+ {
+ HandleScope scope(isolate);
+ for (int i = 0; i < i::Natives::GetBuiltinsCount(); i++) {
+ internal_isolate->bootstrapper()->NativesSourceLookup(i);
+ }
+ }
+ // If we don't do this then we end up with a stray root pointing at the
+ // context even after we have disposed of the context.
+ internal_isolate->heap()->CollectAllAvailableGarbage("mksnapshot");
+ i::Object* raw_context = *v8::Utils::OpenPersistent(context);
+ context.Reset();
+ i::SnapshotByteSink snapshot_sink;
+ i::StartupSerializer ser(internal_isolate, &snapshot_sink);
+ ser.SerializeStrongReferences();
-void V8::SetAllowCodeGenerationFromStringsCallback(
- AllowCodeGenerationFromStringsCallback callback) {
- i::Isolate* isolate = i::Isolate::Current();
- isolate->set_allow_code_gen_callback(callback);
+ i::SnapshotByteSink context_sink;
+ i::PartialSerializer context_ser(internal_isolate, &ser, &context_sink);
+ context_ser.Serialize(&raw_context);
+ ser.SerializeWeakReferences();
+
+ i::SnapshotData sd(snapshot_sink, ser);
+ i::SnapshotData csd(context_sink, context_ser);
+
+ result = i::Snapshot::CreateSnapshotBlob(sd.RawData(), csd.RawData());
+ }
+ }
+ isolate->Dispose();
+ return result;
}
@@ -494,26 +386,40 @@
i::Object** V8::GlobalizeReference(i::Isolate* isolate, i::Object** obj) {
LOG_API(isolate, "Persistent::New");
i::Handle<i::Object> result = isolate->global_handles()->Create(*obj);
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
(*obj)->ObjectVerify();
-#endif // DEBUG
+#endif // VERIFY_HEAP
return result.location();
}
i::Object** V8::CopyPersistent(i::Object** obj) {
i::Handle<i::Object> result = i::GlobalHandles::CopyGlobal(obj);
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
(*obj)->ObjectVerify();
-#endif // DEBUG
+#endif // VERIFY_HEAP
return result.location();
}
-void V8::MakeWeak(i::Object** object,
- void* parameters,
+void V8::MakeWeak(i::Object** object, void* parameter,
WeakCallback weak_callback) {
- i::GlobalHandles::MakeWeak(object, parameters, weak_callback);
+ i::GlobalHandles::MakeWeak(object, parameter, weak_callback);
+}
+
+
+void V8::MakePhantom(i::Object** object, void* parameter,
+ PhantomCallbackData<void>::Callback weak_callback) {
+ i::GlobalHandles::MakePhantom(object, parameter, weak_callback);
+}
+
+
+void V8::MakePhantom(
+ i::Object** object,
+ InternalFieldsCallbackData<void, void>::Callback weak_callback,
+ int internal_field_index1, int internal_field_index2) {
+ i::GlobalHandles::MakePhantom(object, weak_callback, internal_field_index1,
+ internal_field_index2);
}
@@ -750,11 +656,11 @@
// about this there is no HandleScope in this method. When you add one to the
// site calling this method you should check that you ensured the VM was not
// dead first.
-void NeanderArray::add(i::Handle<i::Object> value) {
+void NeanderArray::add(i::Isolate* isolate, i::Handle<i::Object> value) {
int length = this->length();
int size = obj_.size();
if (length == size - 1) {
- i::Factory* factory = i::Isolate::Current()->factory();
+ i::Factory* factory = isolate->factory();
i::Handle<i::FixedArray> new_elms = factory->NewFixedArray(2 * size);
for (int i = 0; i < length; i++)
new_elms->set(i + 1, get(i));
@@ -789,12 +695,12 @@
Utils::OpenHandle(templ)->set_property_list(*list);
}
NeanderArray array(list);
- array.add(isolate->factory()->NewNumberFromInt(length));
+ array.add(isolate, isolate->factory()->NewNumberFromInt(length));
for (int i = 0; i < length; i++) {
i::Handle<i::Object> value = data[i].IsEmpty() ?
i::Handle<i::Object>(isolate->factory()->undefined_value()) :
Utils::OpenHandle(*data[i]);
- array.add(value);
+ array.add(isolate, value);
}
}
@@ -802,7 +708,7 @@
void Template::Set(v8::Handle<Name> name,
v8::Handle<Data> value,
v8::PropertyAttribute attribute) {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ENTER_V8(isolate);
i::HandleScope scope(isolate);
const int kSize = 3;
@@ -908,6 +814,9 @@
v8::Handle<Signature> signature,
int length) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ // Changes to the environment cannot be captured in the snapshot. Expect no
+ // function templates when the isolate is created for serialization.
+ DCHECK(!i_isolate->serializer_enabled());
LOG_API(i_isolate, "FunctionTemplate::New");
ENTER_V8(i_isolate);
return FunctionTemplateNew(
@@ -1084,11 +993,9 @@
int TypeSwitch::match(v8::Handle<Value> value) {
- i::Isolate* isolate = i::Isolate::Current();
- LOG_API(isolate, "TypeSwitch::match");
- USE(isolate);
- i::Handle<i::Object> obj = Utils::OpenHandle(*value);
i::Handle<i::TypeSwitchInfo> info = Utils::OpenHandle(this);
+ LOG_API(info->GetIsolate(), "TypeSwitch::match");
+ i::Handle<i::Object> obj = Utils::OpenHandle(*value);
i::FixedArray* types = i::FixedArray::cast(info->types());
for (int i = 0; i < types->length(); i++) {
if (i::FunctionTemplateInfo::cast(types->get(i))->IsTemplateFor(*obj))
@@ -1249,6 +1156,9 @@
Local<ObjectTemplate> ObjectTemplate::New(
i::Isolate* isolate,
v8::Handle<FunctionTemplate> constructor) {
+ // Changes to the environment cannot be captured in the snapshot. Expect no
+ // object templates when the isolate is created for serialization.
+ DCHECK(!isolate->serializer_enabled());
LOG_API(isolate, "ObjectTemplate::New");
ENTER_V8(isolate);
i::Handle<i::Struct> struct_obj =
@@ -1292,7 +1202,7 @@
info->set_property_accessors(*list);
}
NeanderArray array(list);
- array.add(obj);
+ array.add(isolate, obj);
}
@@ -1394,30 +1304,31 @@
}
-void ObjectTemplate::SetNamedPropertyHandler(
- NamedPropertyGetterCallback getter,
- NamedPropertySetterCallback setter,
- NamedPropertyQueryCallback query,
- NamedPropertyDeleterCallback remover,
- NamedPropertyEnumeratorCallback enumerator,
- Handle<Value> data) {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+template <typename Getter, typename Setter, typename Query, typename Deleter,
+ typename Enumerator>
+static void ObjectTemplateSetNamedPropertyHandler(
+ ObjectTemplate* templ, Getter getter, Setter setter, Query query,
+ Deleter remover, Enumerator enumerator, Handle<Value> data,
+ bool can_intercept_symbols, PropertyHandlerFlags flags) {
+ i::Isolate* isolate = Utils::OpenHandle(templ)->GetIsolate();
ENTER_V8(isolate);
i::HandleScope scope(isolate);
- EnsureConstructor(isolate, this);
- i::FunctionTemplateInfo* constructor = i::FunctionTemplateInfo::cast(
- Utils::OpenHandle(this)->constructor());
+ EnsureConstructor(isolate, templ);
+ i::FunctionTemplateInfo* constructor =
+ i::FunctionTemplateInfo::cast(Utils::OpenHandle(templ)->constructor());
i::Handle<i::FunctionTemplateInfo> cons(constructor);
- i::Handle<i::Struct> struct_obj =
- isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
- i::Handle<i::InterceptorInfo> obj =
- i::Handle<i::InterceptorInfo>::cast(struct_obj);
+ auto obj = i::Handle<i::InterceptorInfo>::cast(
+ isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE));
if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
+ obj->set_flags(0);
+ obj->set_can_intercept_symbols(can_intercept_symbols);
+ obj->set_all_can_read(static_cast<int>(flags) &
+ static_cast<int>(PropertyHandlerFlags::kAllCanRead));
if (data.IsEmpty()) {
data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
@@ -1427,6 +1338,24 @@
}
+void ObjectTemplate::SetNamedPropertyHandler(
+ NamedPropertyGetterCallback getter, NamedPropertySetterCallback setter,
+ NamedPropertyQueryCallback query, NamedPropertyDeleterCallback remover,
+ NamedPropertyEnumeratorCallback enumerator, Handle<Value> data) {
+ ObjectTemplateSetNamedPropertyHandler(this, getter, setter, query, remover,
+ enumerator, data, false,
+ PropertyHandlerFlags::kNone);
+}
+
+
+void ObjectTemplate::SetHandler(
+ const NamedPropertyHandlerConfiguration& config) {
+ ObjectTemplateSetNamedPropertyHandler(
+ this, config.getter, config.setter, config.query, config.deleter,
+ config.enumerator, config.data, true, config.flags);
+}
+
+
void ObjectTemplate::MarkAsUndetectable() {
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ENTER_V8(isolate);
@@ -1470,13 +1399,8 @@
}
-void ObjectTemplate::SetIndexedPropertyHandler(
- IndexedPropertyGetterCallback getter,
- IndexedPropertySetterCallback setter,
- IndexedPropertyQueryCallback query,
- IndexedPropertyDeleterCallback remover,
- IndexedPropertyEnumeratorCallback enumerator,
- Handle<Value> data) {
+void ObjectTemplate::SetHandler(
+ const IndexedPropertyHandlerConfiguration& config) {
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ENTER_V8(isolate);
i::HandleScope scope(isolate);
@@ -1484,17 +1408,21 @@
i::FunctionTemplateInfo* constructor = i::FunctionTemplateInfo::cast(
Utils::OpenHandle(this)->constructor());
i::Handle<i::FunctionTemplateInfo> cons(constructor);
- i::Handle<i::Struct> struct_obj =
- isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
- i::Handle<i::InterceptorInfo> obj =
- i::Handle<i::InterceptorInfo>::cast(struct_obj);
+ auto obj = i::Handle<i::InterceptorInfo>::cast(
+ isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE));
- if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
- if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
- if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
- if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
- if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
+ if (config.getter != 0) SET_FIELD_WRAPPED(obj, set_getter, config.getter);
+ if (config.setter != 0) SET_FIELD_WRAPPED(obj, set_setter, config.setter);
+ if (config.query != 0) SET_FIELD_WRAPPED(obj, set_query, config.query);
+ if (config.deleter != 0) SET_FIELD_WRAPPED(obj, set_deleter, config.deleter);
+ if (config.enumerator != 0) {
+ SET_FIELD_WRAPPED(obj, set_enumerator, config.enumerator);
+ }
+ obj->set_flags(0);
+ obj->set_all_can_read(static_cast<int>(config.flags) &
+ static_cast<int>(PropertyHandlerFlags::kAllCanRead));
+ v8::Local<v8::Value> data = config.data;
if (data.IsEmpty()) {
data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
}
@@ -1556,7 +1484,10 @@
ScriptCompiler::CachedData::CachedData(const uint8_t* data_, int length_,
BufferPolicy buffer_policy_)
- : data(data_), length(length_), buffer_policy(buffer_policy_) {}
+ : data(data_),
+ length(length_),
+ rejected(false),
+ buffer_policy(buffer_policy_) {}
ScriptCompiler::CachedData::~CachedData() {
@@ -1587,7 +1518,7 @@
function_info(i::SharedFunctionInfo::cast(*obj), obj->GetIsolate());
i::Handle<i::JSFunction> function =
obj->GetIsolate()->factory()->NewFunctionFromSharedFunctionInfo(
- function_info, obj->GetIsolate()->global_context());
+ function_info, obj->GetIsolate()->native_context());
return ToApiHandle<Script>(function);
}
@@ -1717,6 +1648,12 @@
options = kConsumeParserCache;
}
+ // Don't try to produce any kind of cache when the debugger is loaded.
+ if (isolate->debug()->is_loaded() &&
+ (options == kProduceParserCache || options == kProduceCodeCache)) {
+ options = kNoCompileOptions;
+ }
+
i::ScriptData* script_data = NULL;
if (options == kConsumeParserCache || options == kConsumeCodeCache) {
DCHECK(source->cached_data);
@@ -1752,7 +1689,7 @@
EXCEPTION_PREAMBLE(isolate);
i::Handle<i::SharedFunctionInfo> result = i::Compiler::CompileScript(
str, name_obj, line_offset, column_offset, is_shared_cross_origin,
- isolate->global_context(), NULL, &script_data, options,
+ isolate->native_context(), NULL, &script_data, options,
i::NOT_NATIVES_CODE);
has_pending_exception = result.is_null();
if (has_pending_exception && script_data != NULL) {
@@ -1772,6 +1709,8 @@
source->cached_data = new CachedData(
script_data->data(), script_data->length(), CachedData::BufferOwned);
script_data->ReleaseDataOwnership();
+ } else if (options == kConsumeParserCache || options == kConsumeCodeCache) {
+ source->cached_data->rejected = script_data->rejected();
}
delete script_data;
}
@@ -1797,17 +1736,6 @@
ScriptCompiler::ScriptStreamingTask* ScriptCompiler::StartStreamingScript(
Isolate* v8_isolate, StreamedSource* source, CompileOptions options) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
- if (!isolate->global_context().is_null() &&
- !isolate->global_context()->IsNativeContext()) {
- // The context chain is non-trivial, and constructing the corresponding
- // non-trivial Scope chain outside the V8 heap is not implemented. Don't
- // stream the script. This will only occur if Harmony scoping is enabled and
- // a previous script has introduced "let" or "const" variables. TODO(marja):
- // Implement externalizing ScopeInfos and constructing non-trivial Scope
- // chains independent of the V8 heap so that we can stream also in this
- // case.
- return NULL;
- }
return new i::BackgroundParsingTask(source->impl(), options,
i::FLAG_stack_size, isolate);
}
@@ -1844,13 +1772,14 @@
v8::True(v8_isolate));
}
source->info->set_script(script);
- source->info->SetContext(isolate->global_context());
+ source->info->SetContext(isolate->native_context());
EXCEPTION_PREAMBLE(isolate);
// Do the parsing tasks which need to be done on the main thread. This will
// also handle parse errors.
source->parser->Internalize();
+ source->parser->HandleSourceURLComments();
i::Handle<i::SharedFunctionInfo> result =
i::Handle<i::SharedFunctionInfo>::null();
@@ -1877,6 +1806,13 @@
}
+uint32_t ScriptCompiler::CachedDataVersionTag() {
+ return static_cast<uint32_t>(base::hash_combine(
+ internal::Version::Hash(), internal::FlagList::Hash(),
+ static_cast<uint32_t>(internal::CpuFeatures::SupportedFeatures())));
+}
+
+
Local<Script> Script::Compile(v8::Handle<String> source,
v8::ScriptOrigin* origin) {
i::Handle<i::String> str = Utils::OpenHandle(*source);
@@ -1920,8 +1856,24 @@
}
+v8::TryCatch::TryCatch(v8::Isolate* isolate)
+ : isolate_(reinterpret_cast<i::Isolate*>(isolate)),
+ next_(isolate_->try_catch_handler()),
+ is_verbose_(false),
+ can_continue_(true),
+ capture_message_(true),
+ rethrow_(false),
+ has_terminated_(false) {
+ ResetInternal();
+ // Special handling for simulators which have a separate JS stack.
+ js_stack_comparable_address_ =
+ reinterpret_cast<void*>(v8::internal::SimulatorStack::RegisterCTryCatch(
+ v8::internal::GetCurrentStackPosition()));
+ isolate_->RegisterTryCatchHandler(this);
+}
+
+
v8::TryCatch::~TryCatch() {
- DCHECK(isolate_ == i::Isolate::Current());
if (rethrow_) {
v8::Isolate* isolate = reinterpret_cast<Isolate*>(isolate_);
v8::HandleScope scope(isolate);
@@ -1974,7 +1926,6 @@
v8::Local<Value> v8::TryCatch::Exception() const {
- DCHECK(isolate_ == i::Isolate::Current());
if (HasCaught()) {
// Check for out of memory exception.
i::Object* exception = reinterpret_cast<i::Object*>(exception_);
@@ -1986,7 +1937,6 @@
v8::Local<Value> v8::TryCatch::StackTrace() const {
- DCHECK(isolate_ == i::Isolate::Current());
if (HasCaught()) {
i::Object* raw_obj = reinterpret_cast<i::Object*>(exception_);
if (!raw_obj->IsJSObject()) return v8::Local<Value>();
@@ -2010,7 +1960,6 @@
v8::Local<v8::Message> v8::TryCatch::Message() const {
- DCHECK(isolate_ == i::Isolate::Current());
i::Object* message = reinterpret_cast<i::Object*>(message_obj_);
DCHECK(message->IsJSMessageObject() || message->IsTheHole());
if (HasCaught() && !message->IsTheHole()) {
@@ -2022,7 +1971,6 @@
void v8::TryCatch::Reset() {
- DCHECK(isolate_ == i::Isolate::Current());
if (!rethrow_ && HasCaught() && isolate_->has_scheduled_exception()) {
// If an exception was caught but is still scheduled because no API call
// promoted it, then it is canceled to prevent it from being propagated.
@@ -2110,11 +2058,8 @@
MUST_USE_RESULT static i::MaybeHandle<i::Object> CallV8HeapFunction(
- const char* name,
- i::Handle<i::Object> recv,
- int argc,
+ i::Isolate* isolate, const char* name, i::Handle<i::Object> recv, int argc,
i::Handle<i::Object> argv[]) {
- i::Isolate* isolate = i::Isolate::Current();
i::Handle<i::Object> object_fun =
i::Object::GetProperty(
isolate, isolate->js_builtins_object(), name).ToHandleChecked();
@@ -2124,13 +2069,10 @@
MUST_USE_RESULT static i::MaybeHandle<i::Object> CallV8HeapFunction(
- const char* name,
- i::Handle<i::Object> data) {
+ i::Isolate* isolate, const char* name, i::Handle<i::Object> data) {
i::Handle<i::Object> argv[] = { data };
- return CallV8HeapFunction(name,
- i::Isolate::Current()->js_builtins_object(),
- arraysize(argv),
- argv);
+ return CallV8HeapFunction(isolate, name, isolate->js_builtins_object(),
+ arraysize(argv), argv);
}
@@ -2142,8 +2084,9 @@
EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> result;
- has_pending_exception = !CallV8HeapFunction(
- "GetLineNumber", Utils::OpenHandle(this)).ToHandle(&result);
+ has_pending_exception =
+ !CallV8HeapFunction(isolate, "GetLineNumber", Utils::OpenHandle(this))
+ .ToHandle(&result);
EXCEPTION_BAILOUT_CHECK(isolate, 0);
return static_cast<int>(result->Number());
}
@@ -2177,8 +2120,9 @@
i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> start_col_obj;
- has_pending_exception = !CallV8HeapFunction(
- "GetPositionInLine", data_obj).ToHandle(&start_col_obj);
+ has_pending_exception =
+ !CallV8HeapFunction(isolate, "GetPositionInLine", data_obj)
+ .ToHandle(&start_col_obj);
EXCEPTION_BAILOUT_CHECK(isolate, 0);
return static_cast<int>(start_col_obj->Number());
}
@@ -2192,8 +2136,9 @@
i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> start_col_obj;
- has_pending_exception = !CallV8HeapFunction(
- "GetPositionInLine", data_obj).ToHandle(&start_col_obj);
+ has_pending_exception =
+ !CallV8HeapFunction(isolate, "GetPositionInLine", data_obj)
+ .ToHandle(&start_col_obj);
EXCEPTION_BAILOUT_CHECK(isolate, 0);
i::Handle<i::JSMessageObject> message =
i::Handle<i::JSMessageObject>::cast(data_obj);
@@ -2223,8 +2168,9 @@
EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> result;
- has_pending_exception = !CallV8HeapFunction(
- "GetSourceLine", Utils::OpenHandle(this)).ToHandle(&result);
+ has_pending_exception =
+ !CallV8HeapFunction(isolate, "GetSourceLine", Utils::OpenHandle(this))
+ .ToHandle(&result);
EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::String>());
if (result->IsString()) {
return scope.Escape(Utils::ToLocal(i::Handle<i::String>::cast(result)));
@@ -2568,13 +2514,36 @@
}
-Local<String> Value::ToString() const {
+bool Value::IsGeneratorFunction() const {
+ i::Handle<i::Object> obj = Utils::OpenHandle(this);
+ if (!obj->IsJSFunction()) return false;
+ i::Handle<i::JSFunction> func = i::Handle<i::JSFunction>::cast(obj);
+ return func->shared()->is_generator();
+}
+
+
+bool Value::IsGeneratorObject() const {
+ return Utils::OpenHandle(this)->IsJSGeneratorObject();
+}
+
+
+bool Value::IsMapIterator() const {
+ return Utils::OpenHandle(this)->IsJSMapIterator();
+}
+
+
+bool Value::IsSetIterator() const {
+ return Utils::OpenHandle(this)->IsJSSetIterator();
+}
+
+
+Local<String> Value::ToString(Isolate* v8_isolate) const {
i::Handle<i::Object> obj = Utils::OpenHandle(this);
i::Handle<i::Object> str;
if (obj->IsString()) {
str = obj;
} else {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
LOG_API(isolate, "ToString");
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
@@ -2586,13 +2555,13 @@
}
-Local<String> Value::ToDetailString() const {
+Local<String> Value::ToDetailString(Isolate* v8_isolate) const {
i::Handle<i::Object> obj = Utils::OpenHandle(this);
i::Handle<i::Object> str;
if (obj->IsString()) {
str = obj;
} else {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
LOG_API(isolate, "ToDetailString");
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
@@ -2604,13 +2573,13 @@
}
-Local<v8::Object> Value::ToObject() const {
+Local<v8::Object> Value::ToObject(Isolate* v8_isolate) const {
i::Handle<i::Object> obj = Utils::OpenHandle(this);
i::Handle<i::Object> val;
if (obj->IsJSObject()) {
val = obj;
} else {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
LOG_API(isolate, "ToObject");
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
@@ -2622,12 +2591,12 @@
}
-Local<Boolean> Value::ToBoolean() const {
+Local<Boolean> Value::ToBoolean(Isolate* v8_isolate) const {
i::Handle<i::Object> obj = Utils::OpenHandle(this);
if (obj->IsBoolean()) {
return ToApiHandle<Boolean>(obj);
} else {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
LOG_API(isolate, "ToBoolean");
ENTER_V8(isolate);
i::Handle<i::Object> val =
@@ -2637,13 +2606,13 @@
}
-Local<Number> Value::ToNumber() const {
+Local<Number> Value::ToNumber(Isolate* v8_isolate) const {
i::Handle<i::Object> obj = Utils::OpenHandle(this);
i::Handle<i::Object> num;
if (obj->IsNumber()) {
num = obj;
} else {
- i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
LOG_API(isolate, "ToNumber");
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
@@ -2655,13 +2624,13 @@
}
-Local<Integer> Value::ToInteger() const {
+Local<Integer> Value::ToInteger(Isolate* v8_isolate) const {
i::Handle<i::Object> obj = Utils::OpenHandle(this);
i::Handle<i::Object> num;
if (obj->IsSmi()) {
num = obj;
} else {
- i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
LOG_API(isolate, "ToInteger");
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
@@ -2676,7 +2645,6 @@
void i::Internals::CheckInitializedImpl(v8::Isolate* external_isolate) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
Utils::ApiCheck(isolate != NULL &&
- isolate->IsInitialized() &&
!isolate->IsDead(),
"v8::internal::Internals::CheckInitialized()",
"Isolate is not initialized or V8 has died");
@@ -2924,13 +2892,13 @@
}
-Local<Int32> Value::ToInt32() const {
+Local<Int32> Value::ToInt32(Isolate* v8_isolate) const {
i::Handle<i::Object> obj = Utils::OpenHandle(this);
i::Handle<i::Object> num;
if (obj->IsSmi()) {
num = obj;
} else {
- i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
LOG_API(isolate, "ToInt32");
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
@@ -2941,13 +2909,13 @@
}
-Local<Uint32> Value::ToUint32() const {
+Local<Uint32> Value::ToUint32(Isolate* v8_isolate) const {
i::Handle<i::Object> obj = Utils::OpenHandle(this);
i::Handle<i::Object> num;
if (obj->IsSmi()) {
num = obj;
} else {
- i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
LOG_API(isolate, "ToUInt32");
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
@@ -3010,8 +2978,13 @@
bool Value::Equals(Handle<Value> that) const {
- i::Isolate* isolate = i::Isolate::Current();
i::Handle<i::Object> obj = Utils::OpenHandle(this, true);
+ i::Handle<i::Object> other = Utils::OpenHandle(*that);
+ if (obj->IsSmi() && other->IsSmi()) {
+ return obj->Number() == other->Number();
+ }
+ i::Object* ho = obj->IsSmi() ? *other : *obj;
+ i::Isolate* isolate = i::HeapObject::cast(ho)->GetIsolate();
if (!Utils::ApiCheck(!obj.is_null() && !that.IsEmpty(),
"v8::Value::Equals()",
"Reading from empty handle")) {
@@ -3019,7 +2992,6 @@
}
LOG_API(isolate, "Equals");
ENTER_V8(isolate);
- i::Handle<i::Object> other = Utils::OpenHandle(*that);
// If both obj and other are JSObjects, we'd better compare by identity
// immediately when going into JS builtin. The reason is Invoke
// would overwrite global object receiver with global proxy.
@@ -3029,23 +3001,27 @@
i::Handle<i::Object> args[] = { other };
EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> result;
- has_pending_exception = !CallV8HeapFunction(
- "EQUALS", obj, arraysize(args), args).ToHandle(&result);
+ has_pending_exception =
+ !CallV8HeapFunction(isolate, "EQUALS", obj, arraysize(args), args)
+ .ToHandle(&result);
EXCEPTION_BAILOUT_CHECK(isolate, false);
return *result == i::Smi::FromInt(i::EQUAL);
}
bool Value::StrictEquals(Handle<Value> that) const {
- i::Isolate* isolate = i::Isolate::Current();
i::Handle<i::Object> obj = Utils::OpenHandle(this, true);
+ i::Handle<i::Object> other = Utils::OpenHandle(*that);
+ if (obj->IsSmi()) {
+ return other->IsNumber() && obj->Number() == other->Number();
+ }
+ i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
if (!Utils::ApiCheck(!obj.is_null() && !that.IsEmpty(),
"v8::Value::StrictEquals()",
"Reading from empty handle")) {
return false;
}
LOG_API(isolate, "StrictEquals");
- i::Handle<i::Object> other = Utils::OpenHandle(*that);
// Must check HeapNumber first, since NaN !== NaN.
if (obj->IsHeapNumber()) {
if (!other->IsNumber()) return false;
@@ -3162,6 +3138,44 @@
}
+i::MaybeHandle<i::Object> DeleteObjectProperty(
+ i::Isolate* isolate, i::Handle<i::JSReceiver> receiver,
+ i::Handle<i::Object> key, i::JSReceiver::DeleteMode mode) {
+ // Check if the given key is an array index.
+ uint32_t index;
+ if (key->ToArrayIndex(&index)) {
+ // In Firefox/SpiderMonkey, Safari and Opera you can access the
+ // characters of a string using [] notation. In the case of a
+ // String object we just need to redirect the deletion to the
+ // underlying string if the index is in range. Since the
+ // underlying string does nothing with the deletion, we can ignore
+ // such deletions.
+ if (receiver->IsStringObjectWithCharacterAt(index)) {
+ return isolate->factory()->true_value();
+ }
+
+ return i::JSReceiver::DeleteElement(receiver, index, mode);
+ }
+
+ i::Handle<i::Name> name;
+ if (key->IsName()) {
+ name = i::Handle<i::Name>::cast(key);
+ } else {
+ // Call-back into JavaScript to convert the key to a string.
+ i::Handle<i::Object> converted;
+ if (!i::Execution::ToString(isolate, key).ToHandle(&converted)) {
+ return i::MaybeHandle<i::Object>();
+ }
+ name = i::Handle<i::String>::cast(converted);
+ }
+
+ if (name->IsString()) {
+ name = i::String::Flatten(i::Handle<i::String>::cast(name));
+ }
+ return i::JSReceiver::DeleteProperty(receiver, name, mode);
+}
+
+
bool v8::Object::ForceDelete(v8::Handle<Value> key) {
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ON_BAILOUT(isolate, "v8::Object::ForceDelete()", return false);
@@ -3180,8 +3194,9 @@
EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> obj;
- has_pending_exception = !i::Runtime::DeleteObjectProperty(
- isolate, self, key_obj, i::JSReceiver::FORCE_DELETION).ToHandle(&obj);
+ has_pending_exception =
+ !DeleteObjectProperty(isolate, self, key_obj,
+ i::JSReceiver::FORCE_DELETION).ToHandle(&obj);
EXCEPTION_BAILOUT_CHECK(isolate, false);
return obj->IsTrue();
}
@@ -3256,11 +3271,10 @@
i::Handle<i::Object> args[] = { obj, key_name };
EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> result;
- has_pending_exception = !CallV8HeapFunction(
- "ObjectGetOwnPropertyDescriptor",
- isolate->factory()->undefined_value(),
- arraysize(args),
- args).ToHandle(&result);
+ has_pending_exception =
+ !CallV8HeapFunction(isolate, "ObjectGetOwnPropertyDescriptor",
+ isolate->factory()->undefined_value(),
+ arraysize(args), args).ToHandle(&result);
EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
return Utils::ToLocal(result);
}
@@ -3359,6 +3373,37 @@
}
+static bool GetPredefinedToString(i::Handle<i::String> tag,
+ Local<String>* result) {
+ i::Isolate* i_isolate = tag->GetIsolate();
+ Isolate* isolate = reinterpret_cast<Isolate*>(i_isolate);
+ i::Factory* factory = i_isolate->factory();
+
+ if (i::String::Equals(tag, factory->Arguments_string())) {
+ *result = v8::String::NewFromUtf8(isolate, "[object ~Arguments]");
+ } else if (i::String::Equals(tag, factory->Array_string())) {
+ *result = v8::String::NewFromUtf8(isolate, "[object ~Array]");
+ } else if (i::String::Equals(tag, factory->Boolean_string())) {
+ *result = v8::String::NewFromUtf8(isolate, "[object ~Boolean]");
+ } else if (i::String::Equals(tag, factory->Date_string())) {
+ *result = v8::String::NewFromUtf8(isolate, "[object ~Date]");
+ } else if (i::String::Equals(tag, factory->Error_string())) {
+ *result = v8::String::NewFromUtf8(isolate, "[object ~Error]");
+ } else if (i::String::Equals(tag, factory->Function_string())) {
+ *result = v8::String::NewFromUtf8(isolate, "[object ~Function]");
+ } else if (i::String::Equals(tag, factory->Number_string())) {
+ *result = v8::String::NewFromUtf8(isolate, "[object ~Number]");
+ } else if (i::String::Equals(tag, factory->RegExp_string())) {
+ *result = v8::String::NewFromUtf8(isolate, "[object ~RegExp]");
+ } else if (i::String::Equals(tag, factory->String_string())) {
+ *result = v8::String::NewFromUtf8(isolate, "[object ~String]");
+ } else {
+ return false;
+ }
+ return true;
+}
+
+
Local<String> v8::Object::ObjectProtoToString() {
i::Isolate* i_isolate = Utils::OpenHandle(this)->GetIsolate();
Isolate* isolate = reinterpret_cast<Isolate*>(i_isolate);
@@ -3368,6 +3413,7 @@
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
i::Handle<i::Object> name(self->class_name(), i_isolate);
+ i::Handle<i::Object> tag;
// Native implementation of Object.prototype.toString (v8natives.js):
// var c = %_ClassOf(this);
@@ -3382,6 +3428,27 @@
i_isolate->factory()->Arguments_string())) {
return v8::String::NewFromUtf8(isolate, "[object Object]");
} else {
+ if (internal::FLAG_harmony_tostring) {
+ i::Handle<i::Symbol> toStringTag =
+ Utils::OpenHandle(*Symbol::GetToStringTag(isolate));
+ EXCEPTION_PREAMBLE(i_isolate);
+ has_pending_exception =
+ !i::Runtime::GetObjectProperty(i_isolate, self, toStringTag)
+ .ToHandle(&tag);
+ EXCEPTION_BAILOUT_CHECK(i_isolate, Local<v8::String>());
+
+ if (!tag->IsUndefined()) {
+ if (!tag->IsString())
+ return v8::String::NewFromUtf8(isolate, "[object ???]");
+ i::Handle<i::String> tag_name = i::Handle<i::String>::cast(tag);
+ if (!i::String::Equals(class_name, tag_name)) {
+ Local<String> result;
+ if (GetPredefinedToString(tag_name, &result)) return result;
+
+ class_name = tag_name;
+ }
+ }
+ }
const char* prefix = "[object ";
Local<String> str = Utils::ToLocal(class_name);
const char* postfix = "]";
@@ -3434,8 +3501,9 @@
i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> obj;
- has_pending_exception = !i::Runtime::DeleteObjectProperty(
- isolate, self, key_obj, i::JSReceiver::NORMAL_DELETION).ToHandle(&obj);
+ has_pending_exception =
+ !DeleteObjectProperty(isolate, self, key_obj,
+ i::JSReceiver::NORMAL_DELETION).ToHandle(&obj);
EXCEPTION_BAILOUT_CHECK(isolate, false);
return obj->IsTrue();
}
@@ -3453,11 +3521,22 @@
i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> obj;
- has_pending_exception = !i::Runtime::HasObjectProperty(
- isolate, self, key_obj).ToHandle(&obj);
+ Maybe<bool> maybe;
+ // Check if the given key is an array index.
+ uint32_t index;
+ if (key_obj->ToArrayIndex(&index)) {
+ maybe = i::JSReceiver::HasElement(self, index);
+ } else {
+ // Convert the key to a name - possibly by calling back into JavaScript.
+ i::Handle<i::Name> name;
+ if (i::Runtime::ToName(isolate, key_obj).ToHandle(&name)) {
+ maybe = i::JSReceiver::HasProperty(self, name);
+ }
+ }
+ if (!maybe.has_value) has_pending_exception = true;
EXCEPTION_BAILOUT_CHECK(isolate, false);
- return obj->IsTrue();
+ DCHECK(maybe.has_value);
+ return maybe.value;
}
@@ -3520,7 +3599,9 @@
i::JSObject::SetAccessor(Utils::OpenHandle(obj), info),
false);
if (result->IsUndefined()) return false;
- if (fast) i::JSObject::MigrateSlowToFast(Utils::OpenHandle(obj), 0);
+ if (fast) {
+ i::JSObject::MigrateSlowToFast(Utils::OpenHandle(obj), 0, "APISetAccessor");
+ }
return true;
}
@@ -3706,17 +3787,13 @@
// as optimized code does not always handle access checks.
i::Deoptimizer::DeoptimizeGlobalObject(*obj);
- i::Handle<i::Map> new_map = i::Map::Copy(i::Handle<i::Map>(obj->map()));
+ i::Handle<i::Map> new_map =
+ i::Map::Copy(i::Handle<i::Map>(obj->map()), "APITurnOnAccessCheck");
new_map->set_is_access_check_needed(true);
i::JSObject::MigrateToMap(obj, new_map);
}
-bool v8::Object::IsDirty() {
- return Utils::OpenHandle(this)->IsDirty();
-}
-
-
Local<v8::Object> v8::Object::Clone() {
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ON_BAILOUT(isolate, "v8::Object::Clone()", return Local<Object>());
@@ -4223,6 +4300,16 @@
}
+int Name::GetIdentityHash() {
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+ ON_BAILOUT(isolate, "v8::Name::GetIdentityHash()", return 0);
+ ENTER_V8(isolate);
+ i::HandleScope scope(isolate);
+ i::Handle<i::Name> self = Utils::OpenHandle(this);
+ return static_cast<int>(self->Hash());
+}
+
+
int String::Length() const {
i::Handle<i::String> str = Utils::OpenHandle(this);
return str->length();
@@ -5041,6 +5128,9 @@
i::V8::ShutdownPlatform();
}
+v8::Platform* v8::V8::GetCurrentPlatform() {
+ return i::V8::GetCurrentPlatform();
+}
bool v8::V8::Initialize() {
i::V8::Initialize();
@@ -5081,50 +5171,6 @@
heap_size_limit_(0) { }
-void v8::V8::VisitExternalResources(ExternalResourceVisitor* visitor) {
- i::Isolate* isolate = i::Isolate::Current();
- isolate->heap()->VisitExternalResources(visitor);
-}
-
-
-class VisitorAdapter : public i::ObjectVisitor {
- public:
- explicit VisitorAdapter(PersistentHandleVisitor* visitor)
- : visitor_(visitor) {}
- virtual void VisitPointers(i::Object** start, i::Object** end) {
- UNREACHABLE();
- }
- virtual void VisitEmbedderReference(i::Object** p, uint16_t class_id) {
- Value* value = ToApi<Value>(i::Handle<i::Object>(p));
- visitor_->VisitPersistentHandle(
- reinterpret_cast<Persistent<Value>*>(&value), class_id);
- }
- private:
- PersistentHandleVisitor* visitor_;
-};
-
-
-void v8::V8::VisitHandlesWithClassIds(PersistentHandleVisitor* visitor) {
- i::Isolate* isolate = i::Isolate::Current();
- i::DisallowHeapAllocation no_allocation;
-
- VisitorAdapter visitor_adapter(visitor);
- isolate->global_handles()->IterateAllRootsWithClassIds(&visitor_adapter);
-}
-
-
-void v8::V8::VisitHandlesForPartialDependence(
- Isolate* exported_isolate, PersistentHandleVisitor* visitor) {
- i::Isolate* isolate = reinterpret_cast<i::Isolate*>(exported_isolate);
- DCHECK(isolate == i::Isolate::Current());
- i::DisallowHeapAllocation no_allocation;
-
- VisitorAdapter visitor_adapter(visitor);
- isolate->global_handles()->IterateAllRootsInNewSpaceWithClassIds(
- &visitor_adapter);
-}
-
-
bool v8::V8::InitializeICU(const char* icu_data_file) {
return i::InitializeICU(icu_data_file);
}
@@ -5220,25 +5266,25 @@
void v8::Context::SetSecurityToken(Handle<Value> token) {
- i::Isolate* isolate = i::Isolate::Current();
- ENTER_V8(isolate);
i::Handle<i::Context> env = Utils::OpenHandle(this);
+ i::Isolate* isolate = env->GetIsolate();
+ ENTER_V8(isolate);
i::Handle<i::Object> token_handle = Utils::OpenHandle(*token);
env->set_security_token(*token_handle);
}
void v8::Context::UseDefaultSecurityToken() {
- i::Isolate* isolate = i::Isolate::Current();
- ENTER_V8(isolate);
i::Handle<i::Context> env = Utils::OpenHandle(this);
+ i::Isolate* isolate = env->GetIsolate();
+ ENTER_V8(isolate);
env->set_security_token(env->global_object());
}
Handle<Value> v8::Context::GetSecurityToken() {
- i::Isolate* isolate = i::Isolate::Current();
i::Handle<i::Context> env = Utils::OpenHandle(this);
+ i::Isolate* isolate = env->GetIsolate();
i::Object* security_token = env->security_token();
i::Handle<i::Object> token_handle(security_token, isolate);
return Utils::ToLocal(token_handle);
@@ -5297,40 +5343,42 @@
Local<v8::Object> ObjectTemplate::NewInstance() {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Handle<i::ObjectTemplateInfo> info = Utils::OpenHandle(this);
+ i::Isolate* isolate = info->GetIsolate();
ON_BAILOUT(isolate, "v8::ObjectTemplate::NewInstance()",
return Local<v8::Object>());
LOG_API(isolate, "ObjectTemplate::NewInstance");
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> obj;
- has_pending_exception = !i::Execution::InstantiateObject(
- Utils::OpenHandle(this)).ToHandle(&obj);
+ has_pending_exception = !i::Execution::InstantiateObject(info).ToHandle(&obj);
EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
return Utils::ToLocal(i::Handle<i::JSObject>::cast(obj));
}
Local<v8::Function> FunctionTemplate::GetFunction() {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Handle<i::FunctionTemplateInfo> info = Utils::OpenHandle(this);
+ i::Isolate* isolate = info->GetIsolate();
ON_BAILOUT(isolate, "v8::FunctionTemplate::GetFunction()",
return Local<v8::Function>());
LOG_API(isolate, "FunctionTemplate::GetFunction");
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> obj;
- has_pending_exception = !i::Execution::InstantiateFunction(
- Utils::OpenHandle(this)).ToHandle(&obj);
+ has_pending_exception =
+ !i::Execution::InstantiateFunction(info).ToHandle(&obj);
EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Function>());
return Utils::ToLocal(i::Handle<i::JSFunction>::cast(obj));
}
bool FunctionTemplate::HasInstance(v8::Handle<v8::Value> value) {
- ON_BAILOUT(i::Isolate::Current(), "v8::FunctionTemplate::HasInstanceOf()",
- return false);
+ i::Handle<i::FunctionTemplateInfo> info = Utils::OpenHandle(this);
+ i::Isolate* isolate = info->GetIsolate();
+ ON_BAILOUT(isolate, "v8::FunctionTemplate::HasInstanceOf()", return false);
i::Object* obj = *Utils::OpenHandle(*value);
- return Utils::OpenHandle(this)->IsTemplateFor(obj);
+ return info->IsTemplateFor(obj);
}
@@ -5476,28 +5524,26 @@
LOG_API(isolate, "String::New(char)");
ENTER_V8(isolate);
i::Handle<i::String> right_string = Utils::OpenHandle(*right);
- // We do not expect this to fail. Change this if it does.
+ // If we are steering towards a range error, do not wait for the error to be
+ // thrown, and return the null handle instead.
+ if (left_string->length() + right_string->length() > i::String::kMaxLength) {
+ return Local<String>();
+ }
i::Handle<i::String> result = isolate->factory()->NewConsString(
left_string, right_string).ToHandleChecked();
return Utils::ToLocal(result);
}
-static i::Handle<i::String> NewExternalStringHandle(
- i::Isolate* isolate,
- v8::String::ExternalStringResource* resource) {
- // We do not expect this to fail. Change this if it does.
- return isolate->factory()->NewExternalStringFromTwoByte(
- resource).ToHandleChecked();
+static i::MaybeHandle<i::String> NewExternalStringHandle(
+ i::Isolate* isolate, v8::String::ExternalStringResource* resource) {
+ return isolate->factory()->NewExternalStringFromTwoByte(resource);
}
-static i::Handle<i::String> NewExternalOneByteStringHandle(
+static i::MaybeHandle<i::String> NewExternalOneByteStringHandle(
i::Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) {
- // We do not expect this to fail. Change this if it does.
- return isolate->factory()
- ->NewExternalStringFromOneByte(resource)
- .ToHandleChecked();
+ return isolate->factory()->NewExternalStringFromOneByte(resource);
}
@@ -5508,9 +5554,13 @@
LOG_API(i_isolate, "String::NewExternal");
ENTER_V8(i_isolate);
CHECK(resource && resource->data());
- i::Handle<i::String> result = NewExternalStringHandle(i_isolate, resource);
- i_isolate->heap()->external_string_table()->AddString(*result);
- return Utils::ToLocal(result);
+ EXCEPTION_PREAMBLE(i_isolate);
+ i::Handle<i::String> string;
+ has_pending_exception =
+ !NewExternalStringHandle(i_isolate, resource).ToHandle(&string);
+ EXCEPTION_BAILOUT_CHECK(i_isolate, Local<String>());
+ i_isolate->heap()->external_string_table()->AddString(*string);
+ return Utils::ToLocal(string);
}
@@ -5546,10 +5596,13 @@
LOG_API(i_isolate, "String::NewExternal");
ENTER_V8(i_isolate);
CHECK(resource && resource->data());
- i::Handle<i::String> result =
- NewExternalOneByteStringHandle(i_isolate, resource);
- i_isolate->heap()->external_string_table()->AddString(*result);
- return Utils::ToLocal(result);
+ EXCEPTION_PREAMBLE(i_isolate);
+ i::Handle<i::String> string;
+ has_pending_exception =
+ !NewExternalOneByteStringHandle(i_isolate, resource).ToHandle(&string);
+ EXCEPTION_BAILOUT_CHECK(i_isolate, Local<String>());
+ i_isolate->heap()->external_string_table()->AddString(*string);
+ return Utils::ToLocal(string);
}
@@ -5581,7 +5634,6 @@
bool v8::String::CanMakeExternal() {
- if (!internal::FLAG_clever_optimizations) return false;
i::Handle<i::String> obj = Utils::OpenHandle(this);
i::Isolate* isolate = obj->GetIsolate();
@@ -5593,6 +5645,12 @@
}
+Isolate* v8::Object::GetIsolate() {
+ i::Isolate* i_isolate = Utils::OpenHandle(this)->GetIsolate();
+ return reinterpret_cast<Isolate*>(i_isolate);
+}
+
+
Local<v8::Object> v8::Object::New(Isolate* isolate) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
LOG_API(i_isolate, "Object::New");
@@ -5715,7 +5773,6 @@
void v8::Date::DateTimeConfigurationChangeNotification(Isolate* isolate) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
- if (!i_isolate->IsInitialized()) return;
ON_BAILOUT(i_isolate, "v8::Date::DateTimeConfigurationChangeNotification()",
return);
LOG_API(i_isolate, "Date::DateTimeConfigurationChangeNotification");
@@ -5970,11 +6027,26 @@
}
+bool Promise::HasHandler() {
+ i::Handle<i::JSObject> promise = Utils::OpenHandle(this);
+ i::Isolate* isolate = promise->GetIsolate();
+ LOG_API(isolate, "Promise::HasRejectHandler");
+ ENTER_V8(isolate);
+ i::Handle<i::Symbol> key = isolate->factory()->promise_has_handler_symbol();
+ return i::JSObject::GetDataProperty(promise, key)->IsTrue();
+}
+
+
bool v8::ArrayBuffer::IsExternal() const {
return Utils::OpenHandle(this)->is_external();
}
+bool v8::ArrayBuffer::IsNeuterable() const {
+ return Utils::OpenHandle(this)->is_neuterable();
+}
+
+
v8::ArrayBuffer::Contents v8::ArrayBuffer::Externalize() {
i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
Utils::ApiCheck(!obj->is_external(),
@@ -5995,6 +6067,8 @@
Utils::ApiCheck(obj->is_external(),
"v8::ArrayBuffer::Neuter",
"Only externalized ArrayBuffers can be neutered");
+ Utils::ApiCheck(obj->is_neuterable(), "v8::ArrayBuffer::Neuter",
+ "Only neuterable ArrayBuffers can be neutered");
LOG_API(obj->GetIsolate(), "v8::ArrayBuffer::Neuter()");
ENTER_V8(isolate);
i::Runtime::NeuterArrayBuffer(obj);
@@ -6063,78 +6137,22 @@
}
-static inline void SetupArrayBufferView(
- i::Isolate* isolate,
- i::Handle<i::JSArrayBufferView> obj,
- i::Handle<i::JSArrayBuffer> buffer,
- size_t byte_offset,
- size_t byte_length) {
- DCHECK(byte_offset + byte_length <=
- static_cast<size_t>(buffer->byte_length()->Number()));
-
- obj->set_buffer(*buffer);
-
- obj->set_weak_next(buffer->weak_first_view());
- buffer->set_weak_first_view(*obj);
-
- i::Handle<i::Object> byte_offset_object =
- isolate->factory()->NewNumberFromSize(byte_offset);
- obj->set_byte_offset(*byte_offset_object);
-
- i::Handle<i::Object> byte_length_object =
- isolate->factory()->NewNumberFromSize(byte_length);
- obj->set_byte_length(*byte_length_object);
-}
-
-template<typename ElementType,
- ExternalArrayType array_type,
- i::ElementsKind elements_kind>
-i::Handle<i::JSTypedArray> NewTypedArray(
- i::Isolate* isolate,
- Handle<ArrayBuffer> array_buffer, size_t byte_offset, size_t length) {
- i::Handle<i::JSTypedArray> obj =
- isolate->factory()->NewJSTypedArray(array_type);
- i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer);
-
- DCHECK(byte_offset % sizeof(ElementType) == 0);
-
- CHECK(length <= (std::numeric_limits<size_t>::max() / sizeof(ElementType)));
- CHECK(length <= static_cast<size_t>(i::Smi::kMaxValue));
- size_t byte_length = length * sizeof(ElementType);
- SetupArrayBufferView(
- isolate, obj, buffer, byte_offset, byte_length);
-
- i::Handle<i::Object> length_object =
- isolate->factory()->NewNumberFromSize(length);
- obj->set_length(*length_object);
-
- i::Handle<i::ExternalArray> elements =
- isolate->factory()->NewExternalArray(
- static_cast<int>(length), array_type,
- static_cast<uint8_t*>(buffer->backing_store()) + byte_offset);
- i::Handle<i::Map> map =
- i::JSObject::GetElementsTransitionMap(obj, elements_kind);
- i::JSObject::SetMapAndElements(obj, map, elements);
- return obj;
-}
-
-
#define TYPED_ARRAY_NEW(Type, type, TYPE, ctype, size) \
Local<Type##Array> Type##Array::New(Handle<ArrayBuffer> array_buffer, \
- size_t byte_offset, size_t length) { \
+ size_t byte_offset, size_t length) { \
i::Isolate* isolate = Utils::OpenHandle(*array_buffer)->GetIsolate(); \
LOG_API(isolate, \
- "v8::" #Type "Array::New(Handle<ArrayBuffer>, size_t, size_t)"); \
+ "v8::" #Type "Array::New(Handle<ArrayBuffer>, size_t, size_t)"); \
ENTER_V8(isolate); \
if (!Utils::ApiCheck(length <= static_cast<size_t>(i::Smi::kMaxValue), \
- "v8::" #Type "Array::New(Handle<ArrayBuffer>, size_t, size_t)", \
- "length exceeds max allowed value")) { \
- return Local<Type##Array>(); \
+ "v8::" #Type \
+ "Array::New(Handle<ArrayBuffer>, size_t, size_t)", \
+ "length exceeds max allowed value")) { \
+ return Local<Type##Array>(); \
} \
- i::Handle<i::JSTypedArray> obj = \
- NewTypedArray<ctype, v8::kExternal##Type##Array, \
- i::EXTERNAL_##TYPE##_ELEMENTS>( \
- isolate, array_buffer, byte_offset, length); \
+ i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer); \
+ i::Handle<i::JSTypedArray> obj = isolate->factory()->NewJSTypedArray( \
+ v8::kExternal##Type##Array, buffer, byte_offset, length); \
return Utils::ToLocal##Type##Array(obj); \
}
@@ -6148,9 +6166,8 @@
i::Isolate* isolate = buffer->GetIsolate();
LOG_API(isolate, "v8::DataView::New(void*, size_t, size_t)");
ENTER_V8(isolate);
- i::Handle<i::JSDataView> obj = isolate->factory()->NewJSDataView();
- SetupArrayBufferView(
- isolate, obj, buffer, byte_offset, byte_length);
+ i::Handle<i::JSDataView> obj =
+ isolate->factory()->NewJSDataView(buffer, byte_offset, byte_length);
return Utils::ToLocal(obj);
}
@@ -6200,22 +6217,21 @@
}
-static Local<Symbol> GetWellKnownSymbol(Isolate* isolate, const char* name) {
- i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
- i::Handle<i::String> i_name =
- Utils::OpenHandle(*String::NewFromUtf8(isolate, name));
- i::Handle<i::String> part = i_isolate->factory()->for_intern_string();
- return Utils::ToLocal(SymbolFor(i_isolate, i_name, part));
-}
-
-
Local<Symbol> v8::Symbol::GetIterator(Isolate* isolate) {
- return GetWellKnownSymbol(isolate, "Symbol.iterator");
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ return Utils::ToLocal(i_isolate->factory()->iterator_symbol());
}
Local<Symbol> v8::Symbol::GetUnscopables(Isolate* isolate) {
- return GetWellKnownSymbol(isolate, "Symbol.unscopables");
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ return Utils::ToLocal(i_isolate->factory()->unscopables_symbol());
+}
+
+
+Local<Symbol> v8::Symbol::GetToStringTag(Isolate* isolate) {
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ return Utils::ToLocal(i_isolate->factory()->to_string_tag_symbol());
}
@@ -6253,7 +6269,6 @@
Local<Number> v8::Number::New(Isolate* isolate, double value) {
i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
- DCHECK(internal_isolate->IsInitialized());
if (std::isnan(value)) {
// Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
value = base::OS::nan_value();
@@ -6266,7 +6281,6 @@
Local<Integer> v8::Integer::New(Isolate* isolate, int32_t value) {
i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
- DCHECK(internal_isolate->IsInitialized());
if (i::Smi::IsValid(value)) {
return Utils::IntegerToLocal(i::Handle<i::Object>(i::Smi::FromInt(value),
internal_isolate));
@@ -6279,7 +6293,6 @@
Local<Integer> v8::Integer::NewFromUnsigned(Isolate* isolate, uint32_t value) {
i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
- DCHECK(internal_isolate->IsInitialized());
bool fits_into_int32_t = (value & (1 << 31)) == 0;
if (fits_into_int32_t) {
return Integer::New(isolate, static_cast<int32_t>(value));
@@ -6290,57 +6303,6 @@
}
-bool V8::AddMessageListener(MessageCallback that, Handle<Value> data) {
- i::Isolate* isolate = i::Isolate::Current();
- ON_BAILOUT(isolate, "v8::V8::AddMessageListener()", return false);
- ENTER_V8(isolate);
- i::HandleScope scope(isolate);
- NeanderArray listeners(isolate->factory()->message_listeners());
- NeanderObject obj(isolate, 2);
- obj.set(0, *isolate->factory()->NewForeign(FUNCTION_ADDR(that)));
- obj.set(1, data.IsEmpty() ? isolate->heap()->undefined_value()
- : *Utils::OpenHandle(*data));
- listeners.add(obj.value());
- return true;
-}
-
-
-void V8::RemoveMessageListeners(MessageCallback that) {
- i::Isolate* isolate = i::Isolate::Current();
- ON_BAILOUT(isolate, "v8::V8::RemoveMessageListeners()", return);
- ENTER_V8(isolate);
- i::HandleScope scope(isolate);
- NeanderArray listeners(isolate->factory()->message_listeners());
- for (int i = 0; i < listeners.length(); i++) {
- if (listeners.get(i)->IsUndefined()) continue; // skip deleted ones
-
- NeanderObject listener(i::JSObject::cast(listeners.get(i)));
- i::Handle<i::Foreign> callback_obj(i::Foreign::cast(listener.get(0)));
- if (callback_obj->foreign_address() == FUNCTION_ADDR(that)) {
- listeners.set(i, isolate->heap()->undefined_value());
- }
- }
-}
-
-
-void V8::SetCaptureStackTraceForUncaughtExceptions(
- bool capture,
- int frame_limit,
- StackTrace::StackTraceOptions options) {
- i::Isolate::Current()->SetCaptureStackTraceForUncaughtExceptions(
- capture,
- frame_limit,
- options);
-}
-
-
-void V8::SetFailedAccessCheckCallbackFunction(
- FailedAccessCheckCallback callback) {
- i::Isolate* isolate = i::Isolate::Current();
- isolate->SetFailedAccessCheckCallback(callback);
-}
-
-
void Isolate::CollectAllGarbage(const char* gc_reason) {
reinterpret_cast<i::Isolate*>(this)->heap()->CollectAllGarbage(
i::Heap::kNoGCFlags, gc_reason);
@@ -6470,13 +6432,6 @@
}
-void V8::RemoveGCPrologueCallback(GCPrologueCallback callback) {
- i::Isolate* isolate = i::Isolate::Current();
- isolate->heap()->RemoveGCPrologueCallback(
- reinterpret_cast<v8::Isolate::GCPrologueCallback>(callback));
-}
-
-
void V8::AddGCEpilogueCallback(GCEpilogueCallback callback, GCType gc_type) {
i::Isolate* isolate = i::Isolate::Current();
isolate->heap()->AddGCEpilogueCallback(
@@ -6486,62 +6441,49 @@
}
-void V8::RemoveGCEpilogueCallback(GCEpilogueCallback callback) {
- i::Isolate* isolate = i::Isolate::Current();
- isolate->heap()->RemoveGCEpilogueCallback(
- reinterpret_cast<v8::Isolate::GCEpilogueCallback>(callback));
-}
-
-
-void V8::AddMemoryAllocationCallback(MemoryAllocationCallback callback,
- ObjectSpace space,
- AllocationAction action) {
- i::Isolate* isolate = i::Isolate::Current();
+void Isolate::AddMemoryAllocationCallback(MemoryAllocationCallback callback,
+ ObjectSpace space,
+ AllocationAction action) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
isolate->memory_allocator()->AddMemoryAllocationCallback(
callback, space, action);
}
-void V8::RemoveMemoryAllocationCallback(MemoryAllocationCallback callback) {
- i::Isolate* isolate = i::Isolate::Current();
+void Isolate::RemoveMemoryAllocationCallback(
+ MemoryAllocationCallback callback) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
isolate->memory_allocator()->RemoveMemoryAllocationCallback(
callback);
}
-void V8::TerminateExecution(Isolate* isolate) {
- i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
- i_isolate->stack_guard()->RequestTerminateExecution();
+void Isolate::TerminateExecution() {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+ isolate->stack_guard()->RequestTerminateExecution();
}
-bool V8::IsExecutionTerminating(Isolate* isolate) {
- i::Isolate* i_isolate = isolate != NULL ?
- reinterpret_cast<i::Isolate*>(isolate) : i::Isolate::Current();
- return IsExecutionTerminatingCheck(i_isolate);
+bool Isolate::IsExecutionTerminating() {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+ return IsExecutionTerminatingCheck(isolate);
}
-void V8::CancelTerminateExecution(Isolate* isolate) {
- i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
- i_isolate->stack_guard()->ClearTerminateExecution();
- i_isolate->CancelTerminateExecution();
+void Isolate::CancelTerminateExecution() {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+ isolate->stack_guard()->ClearTerminateExecution();
+ isolate->CancelTerminateExecution();
}
void Isolate::RequestInterrupt(InterruptCallback callback, void* data) {
- i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this);
- i_isolate->set_api_interrupt_callback(callback);
- i_isolate->set_api_interrupt_callback_data(data);
- i_isolate->stack_guard()->RequestApiInterrupt();
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+ isolate->RequestInterrupt(callback, data);
}
void Isolate::ClearInterrupt() {
- i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this);
- i_isolate->stack_guard()->ClearApiInterrupt();
- i_isolate->set_api_interrupt_callback(NULL);
- i_isolate->set_api_interrupt_callback_data(NULL);
}
@@ -6567,7 +6509,7 @@
Isolate* Isolate::New(const Isolate::CreateParams& params) {
- i::Isolate* isolate = new i::Isolate();
+ i::Isolate* isolate = new i::Isolate(params.enable_serializer);
Isolate* v8_isolate = reinterpret_cast<Isolate*>(isolate);
if (params.entry_hook) {
isolate->set_function_entry_hook(params.entry_hook);
@@ -6578,9 +6520,6 @@
params.code_event_handler);
}
SetResourceConstraints(isolate, params.constraints);
- if (params.enable_serializer) {
- isolate->enable_serializer();
- }
// TODO(jochen): Once we got rid of Isolate::Current(), we can remove this.
Isolate::Scope isolate_scope(v8_isolate);
if (params.entry_hook || !i::Snapshot::Initialize(isolate)) {
@@ -6670,14 +6609,6 @@
void Isolate::GetHeapStatistics(HeapStatistics* heap_statistics) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
- if (!isolate->IsInitialized()) {
- heap_statistics->total_heap_size_ = 0;
- heap_statistics->total_heap_size_executable_ = 0;
- heap_statistics->total_physical_size_ = 0;
- heap_statistics->used_heap_size_ = 0;
- heap_statistics->heap_size_limit_ = 0;
- return;
- }
i::Heap* heap = isolate->heap();
heap_statistics->total_heap_size_ = heap->CommittedMemory();
heap_statistics->total_heap_size_executable_ =
@@ -6688,9 +6619,17 @@
}
+void Isolate::GetStackSample(const RegisterState& state, void** frames,
+ size_t frames_limit, SampleInfo* sample_info) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+ i::TickSample::GetStackSample(isolate, state, i::TickSample::kSkipCEntryFrame,
+ frames, frames_limit, sample_info);
+}
+
+
void Isolate::SetEventLogger(LogEventCallback that) {
// Do not overwrite the event logger if we want to log explicitly.
- if (i::FLAG_log_timer_events) return;
+ if (i::FLAG_log_internal_timer_events) return;
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
isolate->set_event_logger(that);
}
@@ -6709,6 +6648,13 @@
}
+void Isolate::SetPromiseRejectCallback(PromiseRejectCallback callback) {
+ if (callback == NULL) return;
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+ isolate->SetPromiseRejectCallback(callback);
+}
+
+
void Isolate::RunMicrotasks() {
reinterpret_cast<i::Isolate*>(this)->RunMicrotasks();
}
@@ -6771,7 +6717,7 @@
}
-bool v8::Isolate::IdleNotification(int idle_time_in_ms) {
+bool Isolate::IdleNotification(int idle_time_in_ms) {
// Returning true tells the caller that it need not
// continue to call IdleNotification.
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
@@ -6780,7 +6726,16 @@
}
-void v8::Isolate::LowMemoryNotification() {
+bool Isolate::IdleNotificationDeadline(double deadline_in_seconds) {
+ // Returning true tells the caller that it need not
+ // continue to call IdleNotification.
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+ if (!i::FLAG_use_idle_notification) return true;
+ return isolate->heap()->IdleNotification(deadline_in_seconds);
+}
+
+
+void Isolate::LowMemoryNotification() {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
{
i::HistogramTimerScope idle_notification_scope(
@@ -6790,14 +6745,14 @@
}
-int v8::Isolate::ContextDisposedNotification() {
+int Isolate::ContextDisposedNotification(bool dependant_context) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
- return isolate->heap()->NotifyContextDisposed();
+ return isolate->heap()->NotifyContextDisposed(dependant_context);
}
-void v8::Isolate::SetJitCodeEventHandler(JitCodeEventOptions options,
- JitCodeEventHandler event_handler) {
+void Isolate::SetJitCodeEventHandler(JitCodeEventOptions options,
+ JitCodeEventHandler event_handler) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
// Ensure that logging is initialized for our isolate.
isolate->InitializeLoggingAndCounters();
@@ -6805,13 +6760,134 @@
}
-void v8::Isolate::SetStackLimit(uintptr_t stack_limit) {
+void Isolate::SetStackLimit(uintptr_t stack_limit) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
CHECK(stack_limit);
isolate->stack_guard()->SetStackLimit(stack_limit);
}
+void Isolate::GetCodeRange(void** start, size_t* length_in_bytes) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+ if (isolate->code_range()->valid()) {
+ *start = isolate->code_range()->start();
+ *length_in_bytes = isolate->code_range()->size();
+ } else {
+ *start = NULL;
+ *length_in_bytes = 0;
+ }
+}
+
+
+void Isolate::SetFatalErrorHandler(FatalErrorCallback that) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+ isolate->set_exception_behavior(that);
+}
+
+
+void Isolate::SetAllowCodeGenerationFromStringsCallback(
+ AllowCodeGenerationFromStringsCallback callback) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+ isolate->set_allow_code_gen_callback(callback);
+}
+
+
+bool Isolate::IsDead() {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+ return isolate->IsDead();
+}
+
+
+bool Isolate::AddMessageListener(MessageCallback that, Handle<Value> data) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+ ON_BAILOUT(isolate, "v8::V8::AddMessageListener()", return false);
+ ENTER_V8(isolate);
+ i::HandleScope scope(isolate);
+ NeanderArray listeners(isolate->factory()->message_listeners());
+ NeanderObject obj(isolate, 2);
+ obj.set(0, *isolate->factory()->NewForeign(FUNCTION_ADDR(that)));
+ obj.set(1, data.IsEmpty() ? isolate->heap()->undefined_value()
+ : *Utils::OpenHandle(*data));
+ listeners.add(isolate, obj.value());
+ return true;
+}
+
+
+void Isolate::RemoveMessageListeners(MessageCallback that) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+ ON_BAILOUT(isolate, "v8::V8::RemoveMessageListeners()", return);
+ ENTER_V8(isolate);
+ i::HandleScope scope(isolate);
+ NeanderArray listeners(isolate->factory()->message_listeners());
+ for (int i = 0; i < listeners.length(); i++) {
+ if (listeners.get(i)->IsUndefined()) continue; // skip deleted ones
+
+ NeanderObject listener(i::JSObject::cast(listeners.get(i)));
+ i::Handle<i::Foreign> callback_obj(i::Foreign::cast(listener.get(0)));
+ if (callback_obj->foreign_address() == FUNCTION_ADDR(that)) {
+ listeners.set(i, isolate->heap()->undefined_value());
+ }
+ }
+}
+
+
+void Isolate::SetFailedAccessCheckCallbackFunction(
+ FailedAccessCheckCallback callback) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+ isolate->SetFailedAccessCheckCallback(callback);
+}
+
+
+void Isolate::SetCaptureStackTraceForUncaughtExceptions(
+ bool capture, int frame_limit, StackTrace::StackTraceOptions options) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+ isolate->SetCaptureStackTraceForUncaughtExceptions(capture, frame_limit,
+ options);
+}
+
+
+void Isolate::VisitExternalResources(ExternalResourceVisitor* visitor) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+ isolate->heap()->VisitExternalResources(visitor);
+}
+
+
+class VisitorAdapter : public i::ObjectVisitor {
+ public:
+ explicit VisitorAdapter(PersistentHandleVisitor* visitor)
+ : visitor_(visitor) {}
+ virtual void VisitPointers(i::Object** start, i::Object** end) {
+ UNREACHABLE();
+ }
+ virtual void VisitEmbedderReference(i::Object** p, uint16_t class_id) {
+ Value* value = ToApi<Value>(i::Handle<i::Object>(p));
+ visitor_->VisitPersistentHandle(
+ reinterpret_cast<Persistent<Value>*>(&value), class_id);
+ }
+
+ private:
+ PersistentHandleVisitor* visitor_;
+};
+
+
+void Isolate::VisitHandlesWithClassIds(PersistentHandleVisitor* visitor) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+ i::DisallowHeapAllocation no_allocation;
+ VisitorAdapter visitor_adapter(visitor);
+ isolate->global_handles()->IterateAllRootsWithClassIds(&visitor_adapter);
+}
+
+
+void Isolate::VisitHandlesForPartialDependence(
+ PersistentHandleVisitor* visitor) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+ i::DisallowHeapAllocation no_allocation;
+ VisitorAdapter visitor_adapter(visitor);
+ isolate->global_handles()->IterateAllRootsInNewSpaceWithClassIds(
+ &visitor_adapter);
+}
+
+
String::Utf8Value::Utf8Value(v8::Handle<v8::Value> obj)
: str_(NULL), length_(0) {
i::Isolate* isolate = i::Isolate::Current();
@@ -6819,7 +6895,7 @@
ENTER_V8(isolate);
i::HandleScope scope(isolate);
TryCatch try_catch;
- Handle<String> str = obj->ToString();
+ Handle<String> str = obj->ToString(reinterpret_cast<v8::Isolate*>(isolate));
if (str.IsEmpty()) return;
i::Handle<i::String> i_str = Utils::OpenHandle(*str);
length_ = v8::Utf8Length(*i_str, isolate);
@@ -6840,7 +6916,7 @@
ENTER_V8(isolate);
i::HandleScope scope(isolate);
TryCatch try_catch;
- Handle<String> str = obj->ToString();
+ Handle<String> str = obj->ToString(reinterpret_cast<v8::Isolate*>(isolate));
if (str.IsEmpty()) return;
length_ = str->Length();
str_ = i::NewArray<uint16_t>(length_ + 1);
@@ -6886,6 +6962,27 @@
#undef DEFINE_ERROR
+Local<Message> Exception::CreateMessage(Handle<Value> exception) {
+ i::Handle<i::Object> obj = Utils::OpenHandle(*exception);
+ if (!obj->IsHeapObject()) return Local<Message>();
+ i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
+ ENTER_V8(isolate);
+ i::HandleScope scope(isolate);
+ return Utils::MessageToLocal(
+ scope.CloseAndEscape(isolate->CreateMessage(obj, NULL)));
+}
+
+
+Local<StackTrace> Exception::GetStackTrace(Handle<Value> exception) {
+ i::Handle<i::Object> obj = Utils::OpenHandle(*exception);
+ if (!obj->IsJSObject()) return Local<StackTrace>();
+ i::Handle<i::JSObject> js_obj = i::Handle<i::JSObject>::cast(obj);
+ i::Isolate* isolate = js_obj->GetIsolate();
+ ENTER_V8(isolate);
+ return Utils::StackTraceToLocal(isolate->GetDetailedStackTrace(js_obj));
+}
+
+
// --- D e b u g S u p p o r t ---
bool Debug::SetDebugEventListener(EventCallback that, Handle<Value> data) {
@@ -6946,7 +7043,6 @@
Local<Value> Debug::Call(v8::Handle<v8::Function> fun,
v8::Handle<v8::Value> data) {
i::Isolate* isolate = i::Isolate::Current();
- if (!isolate->IsInitialized()) return Local<Value>();
ON_BAILOUT(isolate, "v8::Debug::Call()", return Local<Value>());
ENTER_V8(isolate);
i::MaybeHandle<i::Object> maybe_result;
@@ -6967,7 +7063,6 @@
Local<Value> Debug::GetMirror(v8::Handle<v8::Value> obj) {
i::Isolate* isolate = i::Isolate::Current();
- if (!isolate->IsInitialized()) return Local<Value>();
ON_BAILOUT(isolate, "v8::Debug::GetMirror()", return Local<Value>());
ENTER_V8(isolate);
v8::EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
@@ -7056,6 +7151,19 @@
}
+unsigned int CpuProfileNode::GetHitLineCount() const {
+ const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
+ return node->GetHitLineCount();
+}
+
+
+bool CpuProfileNode::GetLineTicks(LineTick* entries,
+ unsigned int length) const {
+ const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
+ return node->GetLineTicks(entries, length);
+}
+
+
const char* CpuProfileNode::GetBailoutReason() const {
const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
return node->entry()->bailout_reason();
@@ -7173,13 +7281,13 @@
void CpuProfiler::SetIdle(bool is_idle) {
i::Isolate* isolate = reinterpret_cast<i::CpuProfiler*>(this)->isolate();
- i::StateTag state = isolate->current_vm_state();
- DCHECK(state == i::EXTERNAL || state == i::IDLE);
+ v8::StateTag state = isolate->current_vm_state();
+ DCHECK(state == v8::EXTERNAL || state == v8::IDLE);
if (isolate->js_entry_sp() != NULL) return;
if (is_idle) {
- isolate->set_current_vm_state(i::IDLE);
- } else if (state == i::IDLE) {
- isolate->set_current_vm_state(i::EXTERNAL);
+ isolate->set_current_vm_state(v8::IDLE);
+ } else if (state == v8::IDLE) {
+ isolate->set_current_vm_state(v8::EXTERNAL);
}
}