summaryrefslogtreecommitdiff
path: root/deps/v8/src/api.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/api.cc')
-rw-r--r--deps/v8/src/api.cc2122
1 files changed, 1144 insertions, 978 deletions
diff --git a/deps/v8/src/api.cc b/deps/v8/src/api.cc
index bf35154843..6858a325c4 100644
--- a/deps/v8/src/api.cc
+++ b/deps/v8/src/api.cc
@@ -15,6 +15,7 @@
#include "include/v8-experimental.h"
#include "include/v8-profiler.h"
#include "include/v8-testing.h"
+#include "include/v8-util.h"
#include "src/accessors.h"
#include "src/api-experimental.h"
#include "src/api-natives.h"
@@ -35,11 +36,14 @@
#include "src/debug/debug.h"
#include "src/deoptimizer.h"
#include "src/execution.h"
+#include "src/frames-inl.h"
#include "src/gdb-jit.h"
#include "src/global-handles.h"
+#include "src/globals.h"
#include "src/icu_util.h"
#include "src/isolate-inl.h"
#include "src/json-parser.h"
+#include "src/json-stringifier.h"
#include "src/messages.h"
#include "src/parsing/parser.h"
#include "src/parsing/scanner-character-streams.h"
@@ -48,14 +52,15 @@
#include "src/profiler/heap-profiler.h"
#include "src/profiler/heap-snapshot-generator-inl.h"
#include "src/profiler/profile-generator-inl.h"
-#include "src/profiler/sampler.h"
-#include "src/property.h"
+#include "src/profiler/tick-sample.h"
#include "src/property-descriptor.h"
#include "src/property-details.h"
+#include "src/property.h"
#include "src/prototype.h"
-#include "src/runtime/runtime.h"
#include "src/runtime-profiler.h"
+#include "src/runtime/runtime.h"
#include "src/simulator.h"
+#include "src/snapshot/code-serializer.h"
#include "src/snapshot/natives.h"
#include "src/snapshot/snapshot.h"
#include "src/startup-data-util.h"
@@ -65,58 +70,61 @@
#include "src/v8threads.h"
#include "src/version.h"
#include "src/vm-state-inl.h"
-
+#include "src/wasm/wasm-module.h"
namespace v8 {
-#define LOG_API(isolate, expr) LOG(isolate, ApiEntryCall(expr))
-
+#define LOG_API(isolate, class_name, function_name) \
+ i::RuntimeCallTimerScope _runtime_timer( \
+ isolate, &i::RuntimeCallStats::API_##class_name##_##function_name); \
+ TRACE_EVENT_RUNTIME_CALL_STATS_TRACING_SCOPED( \
+ isolate, &internal::tracing::TraceEventStatsTable:: \
+ API_##class_name##_##function_name); \
+ LOG(isolate, ApiEntryCall("v8::" #class_name "::" #function_name))
#define ENTER_V8(isolate) i::VMState<v8::OTHER> __state__((isolate))
-
-#define PREPARE_FOR_EXECUTION_GENERIC(isolate, context, function_name, \
- bailout_value, HandleScopeClass, \
- do_callback) \
- if (IsExecutionTerminatingCheck(isolate)) { \
- return bailout_value; \
- } \
- HandleScopeClass handle_scope(isolate); \
- CallDepthScope call_depth_scope(isolate, context, do_callback); \
- LOG_API(isolate, function_name); \
- ENTER_V8(isolate); \
+#define PREPARE_FOR_EXECUTION_GENERIC(isolate, context, class_name, \
+ function_name, bailout_value, \
+ HandleScopeClass, do_callback) \
+ if (IsExecutionTerminatingCheck(isolate)) { \
+ return bailout_value; \
+ } \
+ HandleScopeClass handle_scope(isolate); \
+ CallDepthScope<do_callback> call_depth_scope(isolate, context); \
+ LOG_API(isolate, class_name, function_name); \
+ ENTER_V8(isolate); \
bool has_pending_exception = false
-
-#define PREPARE_FOR_EXECUTION_WITH_CONTEXT( \
- context, function_name, bailout_value, HandleScopeClass, do_callback) \
- auto isolate = context.IsEmpty() \
- ? i::Isolate::Current() \
- : reinterpret_cast<i::Isolate*>(context->GetIsolate()); \
- PREPARE_FOR_EXECUTION_GENERIC(isolate, context, function_name, \
+#define PREPARE_FOR_EXECUTION_WITH_CONTEXT(context, class_name, function_name, \
+ bailout_value, HandleScopeClass, \
+ do_callback) \
+ auto isolate = context.IsEmpty() \
+ ? i::Isolate::Current() \
+ : reinterpret_cast<i::Isolate*>(context->GetIsolate()); \
+ PREPARE_FOR_EXECUTION_GENERIC(isolate, context, class_name, function_name, \
bailout_value, HandleScopeClass, do_callback);
+#define PREPARE_FOR_EXECUTION_WITH_ISOLATE(isolate, class_name, function_name, \
+ T) \
+ PREPARE_FOR_EXECUTION_GENERIC(isolate, Local<Context>(), class_name, \
+ function_name, MaybeLocal<T>(), \
+ InternalEscapableScope, false);
-#define PREPARE_FOR_EXECUTION_WITH_ISOLATE(isolate, function_name, T) \
- PREPARE_FOR_EXECUTION_GENERIC(isolate, Local<Context>(), function_name, \
- MaybeLocal<T>(), InternalEscapableScope, \
- false);
+#define PREPARE_FOR_EXECUTION(context, class_name, function_name, T) \
+ PREPARE_FOR_EXECUTION_WITH_CONTEXT(context, class_name, function_name, \
+ MaybeLocal<T>(), InternalEscapableScope, \
+ false)
+#define PREPARE_FOR_EXECUTION_WITH_CALLBACK(context, class_name, \
+ function_name, T) \
+ PREPARE_FOR_EXECUTION_WITH_CONTEXT(context, class_name, function_name, \
+ MaybeLocal<T>(), InternalEscapableScope, \
+ true)
-#define PREPARE_FOR_EXECUTION(context, function_name, T) \
- PREPARE_FOR_EXECUTION_WITH_CONTEXT(context, function_name, MaybeLocal<T>(), \
- InternalEscapableScope, false)
-
-
-#define PREPARE_FOR_EXECUTION_WITH_CALLBACK(context, function_name, T) \
- PREPARE_FOR_EXECUTION_WITH_CONTEXT(context, function_name, MaybeLocal<T>(), \
- InternalEscapableScope, true)
-
-
-#define PREPARE_FOR_EXECUTION_PRIMITIVE(context, function_name, T) \
- PREPARE_FOR_EXECUTION_WITH_CONTEXT(context, function_name, Nothing<T>(), \
- i::HandleScope, false)
-
+#define PREPARE_FOR_EXECUTION_PRIMITIVE(context, class_name, function_name, T) \
+ PREPARE_FOR_EXECUTION_WITH_CONTEXT(context, class_name, function_name, \
+ Nothing<T>(), i::HandleScope, false)
#define EXCEPTION_BAILOUT_CHECK_SCOPED(isolate, value) \
do { \
@@ -167,28 +175,34 @@ void CheckMicrotasksScopesConsistency(i::Isolate* isolate) {
}
#endif
-
+template <bool do_callback>
class CallDepthScope {
public:
- explicit CallDepthScope(i::Isolate* isolate, Local<Context> context,
- bool do_callback)
- : isolate_(isolate),
- context_(context),
- escaped_(false),
- do_callback_(do_callback) {
+ explicit CallDepthScope(i::Isolate* isolate, Local<Context> context)
+ : isolate_(isolate), context_(context), escaped_(false) {
// TODO(dcarney): remove this when blink stops crashing.
DCHECK(!isolate_->external_caught_exception());
isolate_->IncrementJsCallsFromApiCounter();
isolate_->handle_scope_implementer()->IncrementCallDepth();
- if (!context_.IsEmpty()) context_->Enter();
- if (do_callback_) isolate_->FireBeforeCallEnteredCallback();
+ if (!context.IsEmpty()) {
+ i::Handle<i::Context> env = Utils::OpenHandle(*context);
+ i::HandleScopeImplementer* impl = isolate->handle_scope_implementer();
+ if (isolate->context() != nullptr &&
+ isolate->context()->native_context() == env->native_context() &&
+ impl->LastEnteredContextWas(env)) {
+ context_ = Local<Context>();
+ } else {
+ context_->Enter();
+ }
+ }
+ if (do_callback) isolate_->FireBeforeCallEnteredCallback();
}
~CallDepthScope() {
if (!context_.IsEmpty()) context_->Exit();
if (!escaped_) isolate_->handle_scope_implementer()->DecrementCallDepth();
- if (do_callback_) isolate_->FireCallCompletedCallback();
+ if (do_callback) isolate_->FireCallCompletedCallback();
#ifdef DEBUG
- if (do_callback_) CheckMicrotasksScopesConsistency(isolate_);
+ if (do_callback) CheckMicrotasksScopesConsistency(isolate_);
#endif
}
@@ -238,9 +252,8 @@ void i::FatalProcessOutOfMemory(const char* location) {
i::V8::FatalProcessOutOfMemory(location, false);
}
-
-// When V8 cannot allocated memory FatalProcessOutOfMemory is called.
-// The default fatal error handler is called and execution is stopped.
+// When V8 cannot allocate memory FatalProcessOutOfMemory is called. The default
+// OOM error handler is called and execution is stopped.
void i::V8::FatalProcessOutOfMemory(const char* location, bool is_heap_oom) {
i::Isolate* isolate = i::Isolate::Current();
char last_few_messages[Heap::kTraceRingBufferSize + 1];
@@ -249,49 +262,53 @@ void i::V8::FatalProcessOutOfMemory(const char* location, bool is_heap_oom) {
memset(js_stacktrace, 0, Heap::kStacktraceBufferSize + 1);
i::HeapStats heap_stats;
- int start_marker;
+ intptr_t start_marker;
heap_stats.start_marker = &start_marker;
- int new_space_size;
+ size_t new_space_size;
heap_stats.new_space_size = &new_space_size;
- int new_space_capacity;
+ size_t new_space_capacity;
heap_stats.new_space_capacity = &new_space_capacity;
- intptr_t old_space_size;
+ size_t old_space_size;
heap_stats.old_space_size = &old_space_size;
- intptr_t old_space_capacity;
+ size_t old_space_capacity;
heap_stats.old_space_capacity = &old_space_capacity;
- intptr_t code_space_size;
+ size_t code_space_size;
heap_stats.code_space_size = &code_space_size;
- intptr_t code_space_capacity;
+ size_t code_space_capacity;
heap_stats.code_space_capacity = &code_space_capacity;
- intptr_t map_space_size;
+ size_t map_space_size;
heap_stats.map_space_size = &map_space_size;
- intptr_t map_space_capacity;
+ size_t map_space_capacity;
heap_stats.map_space_capacity = &map_space_capacity;
- intptr_t lo_space_size;
+ size_t lo_space_size;
heap_stats.lo_space_size = &lo_space_size;
- int global_handle_count;
+ size_t global_handle_count;
heap_stats.global_handle_count = &global_handle_count;
- int weak_global_handle_count;
+ size_t weak_global_handle_count;
heap_stats.weak_global_handle_count = &weak_global_handle_count;
- int pending_global_handle_count;
+ size_t pending_global_handle_count;
heap_stats.pending_global_handle_count = &pending_global_handle_count;
- int near_death_global_handle_count;
+ size_t near_death_global_handle_count;
heap_stats.near_death_global_handle_count = &near_death_global_handle_count;
- int free_global_handle_count;
+ size_t free_global_handle_count;
heap_stats.free_global_handle_count = &free_global_handle_count;
- intptr_t memory_allocator_size;
+ size_t memory_allocator_size;
heap_stats.memory_allocator_size = &memory_allocator_size;
- intptr_t memory_allocator_capacity;
+ size_t memory_allocator_capacity;
heap_stats.memory_allocator_capacity = &memory_allocator_capacity;
- int objects_per_type[LAST_TYPE + 1] = {0};
+ size_t malloced_memory;
+ heap_stats.malloced_memory = &malloced_memory;
+ size_t malloced_peak_memory;
+ heap_stats.malloced_peak_memory = &malloced_peak_memory;
+ size_t objects_per_type[LAST_TYPE + 1] = {0};
heap_stats.objects_per_type = objects_per_type;
- int size_per_type[LAST_TYPE + 1] = {0};
+ size_t size_per_type[LAST_TYPE + 1] = {0};
heap_stats.size_per_type = size_per_type;
int os_error;
heap_stats.os_error = &os_error;
heap_stats.last_few_messages = last_few_messages;
heap_stats.js_stacktrace = js_stacktrace;
- int end_marker;
+ intptr_t end_marker;
heap_stats.end_marker = &end_marker;
if (isolate->heap()->HasBeenSetUp()) {
// BUG(1718): Don't use the take_snapshot since we don't support
@@ -303,9 +320,7 @@ void i::V8::FatalProcessOutOfMemory(const char* location, bool is_heap_oom) {
PrintF("\n<--- Last few GCs --->\n%s\n", first_newline);
PrintF("\n<--- JS stacktrace --->\n%s\n", js_stacktrace);
}
- Utils::ApiCheck(false, location, is_heap_oom
- ? "Allocation failed - JavaScript heap out of memory"
- : "Allocation failed - process out of memory");
+ Utils::ReportOOMFailure(location, is_heap_oom);
// If the fatal error handler returns, we stop execution.
FATAL("API fatal error handler returned after process out of memory");
}
@@ -314,7 +329,7 @@ void i::V8::FatalProcessOutOfMemory(const char* location, bool is_heap_oom) {
void Utils::ReportApiFailure(const char* location, const char* message) {
i::Isolate* isolate = i::Isolate::Current();
FatalErrorCallback callback = isolate->exception_behavior();
- if (callback == NULL) {
+ if (callback == nullptr) {
base::OS::PrintError("\n#\n# Fatal error in %s\n# %s\n#\n\n", location,
message);
base::OS::Abort();
@@ -324,6 +339,28 @@ void Utils::ReportApiFailure(const char* location, const char* message) {
isolate->SignalFatalError();
}
+void Utils::ReportOOMFailure(const char* location, bool is_heap_oom) {
+ i::Isolate* isolate = i::Isolate::Current();
+ OOMErrorCallback oom_callback = isolate->oom_behavior();
+ if (oom_callback == nullptr) {
+ // TODO(wfh): Remove this fallback once Blink is setting OOM handler. See
+ // crbug.com/614440.
+ FatalErrorCallback fatal_callback = isolate->exception_behavior();
+ if (fatal_callback == nullptr) {
+ base::OS::PrintError("\n#\n# Fatal %s OOM in %s\n#\n\n",
+ is_heap_oom ? "javascript" : "process", location);
+ base::OS::Abort();
+ } else {
+ fatal_callback(location,
+ is_heap_oom
+ ? "Allocation failed - JavaScript heap out of memory"
+ : "Allocation failed - process out of memory");
+ }
+ } else {
+ oom_callback(location, is_heap_oom);
+ }
+ isolate->SignalFatalError();
+}
static inline bool IsExecutionTerminatingCheck(i::Isolate* isolate) {
if (isolate->has_scheduled_exception()) {
@@ -383,91 +420,159 @@ bool RunExtraCode(Isolate* isolate, Local<Context> context,
return true;
}
-StartupData SerializeIsolateAndContext(
- Isolate* isolate, Persistent<Context>* context,
- i::Snapshot::Metadata metadata,
- i::StartupSerializer::FunctionCodeHandling function_code_handling) {
- if (context->IsEmpty()) return {NULL, 0};
+struct SnapshotCreatorData {
+ explicit SnapshotCreatorData(Isolate* isolate)
+ : isolate_(isolate),
+ contexts_(isolate),
+ templates_(isolate),
+ created_(false) {}
- i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ static SnapshotCreatorData* cast(void* data) {
+ return reinterpret_cast<SnapshotCreatorData*>(data);
+ }
+
+ ArrayBufferAllocator allocator_;
+ Isolate* isolate_;
+ PersistentValueVector<Context> contexts_;
+ PersistentValueVector<Template> templates_;
+ bool created_;
+};
+
+} // namespace
+
+SnapshotCreator::SnapshotCreator(intptr_t* external_references,
+ StartupData* existing_snapshot) {
+ i::Isolate* internal_isolate = new i::Isolate(true);
+ Isolate* isolate = reinterpret_cast<Isolate*>(internal_isolate);
+ SnapshotCreatorData* data = new SnapshotCreatorData(isolate);
+ data->isolate_ = isolate;
+ internal_isolate->set_array_buffer_allocator(&data->allocator_);
+ internal_isolate->set_api_external_references(external_references);
+ isolate->Enter();
+ if (existing_snapshot) {
+ internal_isolate->set_snapshot_blob(existing_snapshot);
+ i::Snapshot::Initialize(internal_isolate);
+ } else {
+ internal_isolate->Init(nullptr);
+ }
+ data_ = data;
+}
+
+SnapshotCreator::~SnapshotCreator() {
+ SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
+ DCHECK(data->created_);
+ Isolate* isolate = data->isolate_;
+ isolate->Exit();
+ isolate->Dispose();
+ delete data;
+}
+
+Isolate* SnapshotCreator::GetIsolate() {
+ return SnapshotCreatorData::cast(data_)->isolate_;
+}
+
+size_t SnapshotCreator::AddContext(Local<Context> context) {
+ DCHECK(!context.IsEmpty());
+ SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
+ DCHECK(!data->created_);
+ Isolate* isolate = data->isolate_;
+ CHECK_EQ(isolate, context->GetIsolate());
+ size_t index = static_cast<int>(data->contexts_.Size());
+ data->contexts_.Append(context);
+ return index;
+}
+
+size_t SnapshotCreator::AddTemplate(Local<Template> template_obj) {
+ DCHECK(!template_obj.IsEmpty());
+ SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
+ DCHECK(!data->created_);
+ DCHECK_EQ(reinterpret_cast<i::Isolate*>(data->isolate_),
+ Utils::OpenHandle(*template_obj)->GetIsolate());
+ size_t index = static_cast<int>(data->templates_.Size());
+ data->templates_.Append(template_obj);
+ return index;
+}
+
+StartupData SnapshotCreator::CreateBlob(
+ SnapshotCreator::FunctionCodeHandling function_code_handling) {
+ SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(data->isolate_);
+ DCHECK(!data->created_);
+
+ {
+ int num_templates = static_cast<int>(data->templates_.Size());
+ i::HandleScope scope(isolate);
+ i::Handle<i::FixedArray> templates =
+ isolate->factory()->NewFixedArray(num_templates, i::TENURED);
+ for (int i = 0; i < num_templates; i++) {
+ templates->set(i, *v8::Utils::OpenHandle(*data->templates_.Get(i)));
+ }
+ isolate->heap()->SetSerializedTemplates(*templates);
+ data->templates_.Clear();
+ }
// 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");
-
- // GC may have cleared weak cells, so compact any WeakFixedArrays
- // found on the heap.
- i::HeapIterator iterator(internal_isolate->heap(),
- i::HeapIterator::kFilterUnreachable);
- for (i::HeapObject* o = iterator.next(); o != NULL; o = iterator.next()) {
- if (o->IsPrototypeInfo()) {
- i::Object* prototype_users = i::PrototypeInfo::cast(o)->prototype_users();
- if (prototype_users->IsWeakFixedArray()) {
- i::WeakFixedArray* array = i::WeakFixedArray::cast(prototype_users);
- array->Compact<i::JSObject::PrototypeRegistryCompactionCallback>();
- }
- } else if (o->IsScript()) {
- i::Object* shared_list = i::Script::cast(o)->shared_function_infos();
- if (shared_list->IsWeakFixedArray()) {
- i::WeakFixedArray* array = i::WeakFixedArray::cast(shared_list);
- array->Compact<i::WeakFixedArray::NullCallback>();
- }
- }
+ isolate->heap()->CollectAllAvailableGarbage("mksnapshot");
+ isolate->heap()->CompactWeakFixedArrays();
+
+ i::DisallowHeapAllocation no_gc_from_here_on;
+
+ int num_contexts = static_cast<int>(data->contexts_.Size());
+ i::List<i::Object*> contexts(num_contexts);
+ for (int i = 0; i < num_contexts; i++) {
+ i::HandleScope scope(isolate);
+ i::Handle<i::Context> context =
+ v8::Utils::OpenHandle(*data->contexts_.Get(i));
+ contexts.Add(*context);
}
+ data->contexts_.Clear();
- i::Object* raw_context = *v8::Utils::OpenPersistent(*context);
- context->Reset();
+ i::StartupSerializer startup_serializer(isolate, function_code_handling);
+ startup_serializer.SerializeStrongReferences();
- i::SnapshotByteSink snapshot_sink;
- i::StartupSerializer ser(internal_isolate, &snapshot_sink,
- function_code_handling);
- ser.SerializeStrongReferences();
+ // Serialize each context with a new partial serializer.
+ i::List<i::SnapshotData*> context_snapshots(num_contexts);
+ for (int i = 0; i < num_contexts; i++) {
+ i::PartialSerializer partial_serializer(isolate, &startup_serializer);
+ partial_serializer.Serialize(&contexts[i]);
+ context_snapshots.Add(new i::SnapshotData(&partial_serializer));
+ }
- i::SnapshotByteSink context_sink;
- i::PartialSerializer context_ser(internal_isolate, &ser, &context_sink);
- context_ser.Serialize(&raw_context);
- ser.SerializeWeakReferencesAndDeferred();
+ startup_serializer.SerializeWeakReferencesAndDeferred();
+ i::SnapshotData startup_snapshot(&startup_serializer);
+ StartupData result =
+ i::Snapshot::CreateSnapshotBlob(&startup_snapshot, &context_snapshots);
- return i::Snapshot::CreateSnapshotBlob(ser, context_ser, metadata);
+ // Delete heap-allocated context snapshot instances.
+ for (const auto& context_snapshot : context_snapshots) {
+ delete context_snapshot;
+ }
+ data->created_ = true;
+ return result;
}
-} // namespace
-
StartupData V8::CreateSnapshotDataBlob(const char* embedded_source) {
// Create a new isolate and a new context from scratch, optionally run
// a script to embed, and serialize to create a snapshot blob.
- StartupData result = {NULL, 0};
-
+ StartupData result = {nullptr, 0};
base::ElapsedTimer timer;
timer.Start();
-
- ArrayBufferAllocator allocator;
- i::Isolate* internal_isolate = new i::Isolate(true);
- internal_isolate->set_array_buffer_allocator(&allocator);
- Isolate* isolate = reinterpret_cast<Isolate*>(internal_isolate);
-
{
- Isolate::Scope isolate_scope(isolate);
- internal_isolate->Init(NULL);
- Persistent<Context> context;
+ SnapshotCreator snapshot_creator;
+ Isolate* isolate = snapshot_creator.GetIsolate();
{
- HandleScope handle_scope(isolate);
- Local<Context> new_context = Context::New(isolate);
- context.Reset(isolate, new_context);
+ HandleScope scope(isolate);
+ Local<Context> context = Context::New(isolate);
if (embedded_source != NULL &&
- !RunExtraCode(isolate, new_context, embedded_source, "<embedded>")) {
- context.Reset();
+ !RunExtraCode(isolate, context, embedded_source, "<embedded>")) {
+ return result;
}
+ snapshot_creator.AddContext(context);
}
-
- i::Snapshot::Metadata metadata;
- metadata.set_embeds_script(embedded_source != NULL);
-
- result = SerializeIsolateAndContext(
- isolate, &context, metadata, i::StartupSerializer::CLEAR_FUNCTION_CODE);
- DCHECK(context.IsEmpty());
+ result = snapshot_creator.CreateBlob(
+ SnapshotCreator::FunctionCodeHandling::kClear);
}
- isolate->Dispose();
if (i::FLAG_profile_deserialization) {
i::PrintF("Creating snapshot took %0.3f ms\n",
@@ -487,42 +592,28 @@ StartupData V8::WarmUpSnapshotDataBlob(StartupData cold_snapshot_blob,
// compilation of executed functions.
// - Create a new context. This context will be unpolluted.
// - Serialize the isolate and the second context into a new snapshot blob.
- StartupData result = {NULL, 0};
-
+ StartupData result = {nullptr, 0};
base::ElapsedTimer timer;
timer.Start();
-
- ArrayBufferAllocator allocator;
- i::Isolate* internal_isolate = new i::Isolate(true);
- internal_isolate->set_array_buffer_allocator(&allocator);
- internal_isolate->set_snapshot_blob(&cold_snapshot_blob);
- Isolate* isolate = reinterpret_cast<Isolate*>(internal_isolate);
-
{
- Isolate::Scope isolate_scope(isolate);
- i::Snapshot::Initialize(internal_isolate);
- Persistent<Context> context;
- bool success;
+ SnapshotCreator snapshot_creator(nullptr, &cold_snapshot_blob);
+ Isolate* isolate = snapshot_creator.GetIsolate();
{
- HandleScope handle_scope(isolate);
- Local<Context> new_context = Context::New(isolate);
- success = RunExtraCode(isolate, new_context, warmup_source, "<warm-up>");
+ HandleScope scope(isolate);
+ Local<Context> context = Context::New(isolate);
+ if (!RunExtraCode(isolate, context, warmup_source, "<warm-up>")) {
+ return result;
+ }
}
- if (success) {
+ {
HandleScope handle_scope(isolate);
isolate->ContextDisposedNotification(false);
- Local<Context> new_context = Context::New(isolate);
- context.Reset(isolate, new_context);
+ Local<Context> context = Context::New(isolate);
+ snapshot_creator.AddContext(context);
}
-
- i::Snapshot::Metadata metadata;
- metadata.set_embeds_script(i::Snapshot::EmbedsScript(internal_isolate));
-
- result = SerializeIsolateAndContext(
- isolate, &context, metadata, i::StartupSerializer::KEEP_FUNCTION_CODE);
- DCHECK(context.IsEmpty());
+ result = snapshot_creator.CreateBlob(
+ SnapshotCreator::FunctionCodeHandling::kKeep);
}
- isolate->Dispose();
if (i::FLAG_profile_deserialization) {
i::PrintF("Warming up snapshot took %0.3f ms\n",
@@ -658,7 +749,7 @@ void SetResourceConstraints(i::Isolate* isolate,
i::Object** V8::GlobalizeReference(i::Isolate* isolate, i::Object** obj) {
- LOG_API(isolate, "Persistent::New");
+ LOG_API(isolate, Persistent, New);
i::Handle<i::Object> result = isolate->global_handles()->Create(*obj);
#ifdef VERIFY_HEAP
if (i::FLAG_verify_heap) {
@@ -684,13 +775,7 @@ void V8::RegisterExternallyReferencedObject(i::Object** object,
isolate->heap()->RegisterExternallyReferencedObject(object);
}
-void V8::MakeWeak(i::Object** object, void* parameter,
- WeakCallback weak_callback) {
- i::GlobalHandles::MakeWeak(object, parameter, weak_callback);
-}
-
-
-void V8::MakeWeak(i::Object** object, void* parameter,
+void V8::MakeWeak(i::Object** location, void* parameter,
int internal_field_index1, int internal_field_index2,
WeakCallbackInfo<void>::Callback weak_callback) {
WeakCallbackType type = WeakCallbackType::kParameter;
@@ -705,24 +790,25 @@ void V8::MakeWeak(i::Object** object, void* parameter,
DCHECK_EQ(internal_field_index1, -1);
DCHECK_EQ(internal_field_index2, -1);
}
- i::GlobalHandles::MakeWeak(object, parameter, weak_callback, type);
+ i::GlobalHandles::MakeWeak(location, parameter, weak_callback, type);
}
-
-void V8::MakeWeak(i::Object** object, void* parameter,
+void V8::MakeWeak(i::Object** location, void* parameter,
WeakCallbackInfo<void>::Callback weak_callback,
WeakCallbackType type) {
- i::GlobalHandles::MakeWeak(object, parameter, weak_callback, type);
+ i::GlobalHandles::MakeWeak(location, parameter, weak_callback, type);
}
-
-void* V8::ClearWeak(i::Object** obj) {
- return i::GlobalHandles::ClearWeakness(obj);
+void V8::MakeWeak(i::Object*** location_addr) {
+ i::GlobalHandles::MakeWeak(location_addr);
}
+void* V8::ClearWeak(i::Object** location) {
+ return i::GlobalHandles::ClearWeakness(location);
+}
-void V8::DisposeGlobal(i::Object** obj) {
- i::GlobalHandles::Destroy(obj);
+void V8::DisposeGlobal(i::Object** location) {
+ i::GlobalHandles::Destroy(location);
}
@@ -817,9 +903,8 @@ EscapableHandleScope::EscapableHandleScope(Isolate* v8_isolate) {
i::Object** EscapableHandleScope::Escape(i::Object** escape_value) {
i::Heap* heap = reinterpret_cast<i::Isolate*>(GetIsolate())->heap();
- Utils::ApiCheck(*escape_slot_ == heap->the_hole_value(),
- "EscapeableHandleScope::Escape",
- "Escape value set twice");
+ Utils::ApiCheck((*escape_slot_)->IsTheHole(heap->isolate()),
+ "EscapableHandleScope::Escape", "Escape value set twice");
if (escape_value == NULL) {
*escape_slot_ = heap->undefined_value();
return NULL;
@@ -828,12 +913,9 @@ i::Object** EscapableHandleScope::Escape(i::Object** escape_value) {
return escape_slot_;
}
-
-SealHandleScope::SealHandleScope(Isolate* isolate) {
- i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
-
- isolate_ = internal_isolate;
- i::HandleScopeData* current = internal_isolate->handle_scope_data();
+SealHandleScope::SealHandleScope(Isolate* isolate)
+ : isolate_(reinterpret_cast<i::Isolate*>(isolate)) {
+ i::HandleScopeData* current = isolate_->handle_scope_data();
prev_limit_ = current->limit;
current->limit = current->next;
prev_sealed_level_ = current->sealed_level;
@@ -950,70 +1032,6 @@ void Context::SetAlignedPointerInEmbedderData(int index, void* value) {
}
-// --- N e a n d e r ---
-
-
-// A constructor cannot easily return an error value, therefore it is necessary
-// to check for a dead VM with ON_BAILOUT before constructing any Neander
-// objects. To remind you about this there is no HandleScope in the
-// NeanderObject constructor. When you add one to the site calling the
-// constructor you should check that you ensured the VM was not dead first.
-NeanderObject::NeanderObject(v8::internal::Isolate* isolate, int size) {
- ENTER_V8(isolate);
- value_ = isolate->factory()->NewNeanderObject();
- i::Handle<i::FixedArray> elements = isolate->factory()->NewFixedArray(size);
- value_->set_elements(*elements);
-}
-
-
-int NeanderObject::size() {
- return i::FixedArray::cast(value_->elements())->length();
-}
-
-
-NeanderArray::NeanderArray(v8::internal::Isolate* isolate) : obj_(isolate, 2) {
- obj_.set(0, i::Smi::FromInt(0));
-}
-
-
-int NeanderArray::length() {
- return i::Smi::cast(obj_.get(0))->value();
-}
-
-
-i::Object* NeanderArray::get(int offset) {
- DCHECK_LE(0, offset);
- DCHECK_LT(offset, length());
- return obj_.get(offset + 1);
-}
-
-
-// This method cannot easily return an error value, therefore it is necessary
-// to check for a dead VM with ON_BAILOUT before calling it. To remind you
-// 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::Isolate* isolate, i::Handle<i::Object> value) {
- int length = this->length();
- int size = obj_.size();
- if (length == size - 1) {
- 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));
- obj_.value()->set_elements(*new_elms);
- }
- obj_.set(length + 1, *value);
- obj_.set(0, i::Smi::FromInt(length + 1));
-}
-
-
-void NeanderArray::set(int index, i::Object* value) {
- if (index < 0 || index >= this->length()) return;
- obj_.set(index + 1, value);
-}
-
-
// --- T e m p l a t e ---
@@ -1030,23 +1048,13 @@ void Template::Set(v8::Local<Name> name, v8::Local<Data> value,
ENTER_V8(isolate);
i::HandleScope scope(isolate);
auto value_obj = Utils::OpenHandle(*value);
+ CHECK(!value_obj->IsJSReceiver() || value_obj->IsTemplateInfo());
if (value_obj->IsObjectTemplateInfo()) {
templ->set_serial_number(i::Smi::FromInt(0));
if (templ->IsFunctionTemplateInfo()) {
i::Handle<i::FunctionTemplateInfo>::cast(templ)->set_do_not_cache(true);
}
}
- if (i::FLAG_warn_template_set &&
- value_obj->IsJSReceiver() &&
- !value_obj->IsTemplateInfo()) {
- base::OS::PrintError(
- "(node) v8::%sTemplate::Set() with non-primitive values is deprecated\n"
- "(node) and will stop working in the next major release.\n",
- templ->IsFunctionTemplateInfo() ? "Function" : "Object");
- isolate->PrintStack(stderr, i::Isolate::kPrintStackConcise);
- base::DumpBacktrace();
- }
- // TODO(dcarney): split api to allow values of v8::Value or v8::TemplateInfo.
i::ApiNatives::AddDataProperty(isolate, templ, Utils::OpenHandle(*name),
value_obj,
static_cast<i::PropertyAttributes>(attribute));
@@ -1090,7 +1098,7 @@ Local<ObjectTemplate> FunctionTemplate::PrototypeTemplate() {
ENTER_V8(i_isolate);
i::Handle<i::Object> result(Utils::OpenHandle(this)->prototype_template(),
i_isolate);
- if (result->IsUndefined()) {
+ if (result->IsUndefined(i_isolate)) {
// Do not cache prototype objects.
result = Utils::OpenHandle(
*ObjectTemplateNew(i_isolate, Local<FunctionTemplate>(), true));
@@ -1128,8 +1136,7 @@ static Local<FunctionTemplate> FunctionTemplateNew(
obj->set_do_not_cache(do_not_cache);
int next_serial_number = 0;
if (!do_not_cache) {
- next_serial_number = isolate->next_serial_number() + 1;
- isolate->set_next_serial_number(next_serial_number);
+ next_serial_number = isolate->heap()->GetNextTemplateSerialNumber();
}
obj->set_serial_number(i::Smi::FromInt(next_serial_number));
if (callback != 0) {
@@ -1147,34 +1154,34 @@ static Local<FunctionTemplate> FunctionTemplateNew(
return Utils::ToLocal(obj);
}
-
-Local<FunctionTemplate> FunctionTemplate::New(Isolate* isolate,
- FunctionCallback callback,
- v8::Local<Value> data,
- v8::Local<Signature> signature,
- int length) {
- return New(
- isolate, callback, data, signature, length, ConstructorBehavior::kAllow);
-}
-
-Local<FunctionTemplate> FunctionTemplate::New(Isolate* isolate,
- FunctionCallback callback,
- v8::Local<Value> data,
- v8::Local<Signature> signature,
- int length,
- ConstructorBehavior behavior) {
+Local<FunctionTemplate> FunctionTemplate::New(
+ Isolate* isolate, FunctionCallback callback, v8::Local<Value> data,
+ v8::Local<Signature> signature, int length, ConstructorBehavior behavior) {
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");
+ LOG_API(i_isolate, FunctionTemplate, New);
ENTER_V8(i_isolate);
- auto tmpl = FunctionTemplateNew(i_isolate, callback, nullptr, data, signature,
- length, false);
- if (behavior == ConstructorBehavior::kThrow) tmpl->RemovePrototype();
- return tmpl;
+ auto templ = FunctionTemplateNew(i_isolate, callback, nullptr, data,
+ signature, length, false);
+ if (behavior == ConstructorBehavior::kThrow) templ->RemovePrototype();
+ return templ;
}
+MaybeLocal<FunctionTemplate> FunctionTemplate::FromSnapshot(Isolate* isolate,
+ size_t index) {
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ i::FixedArray* templates = i_isolate->heap()->serialized_templates();
+ int int_index = static_cast<int>(index);
+ if (int_index < templates->length()) {
+ i::Object* info = templates->get(int_index);
+ if (info->IsFunctionTemplateInfo()) {
+ return Utils::ToLocal(i::Handle<i::FunctionTemplateInfo>(
+ i::FunctionTemplateInfo::cast(info)));
+ }
+ }
+ return Local<FunctionTemplate>();
+}
Local<FunctionTemplate> FunctionTemplate::NewWithFastHandler(
Isolate* isolate, FunctionCallback callback,
@@ -1182,7 +1189,7 @@ Local<FunctionTemplate> FunctionTemplate::NewWithFastHandler(
v8::Local<Signature> signature, int length) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
DCHECK(!i_isolate->serializer_enabled());
- LOG_API(i_isolate, "FunctionTemplate::NewWithFastHandler");
+ LOG_API(i_isolate, FunctionTemplate, NewWithFastHandler);
ENTER_V8(i_isolate);
return FunctionTemplateNew(i_isolate, callback, fast_handler, data, signature,
length, false);
@@ -1247,8 +1254,10 @@ static i::Handle<i::AccessorInfo> SetAccessorInfoProperties(
return obj;
}
+namespace {
+
template <typename Getter, typename Setter>
-static i::Handle<i::AccessorInfo> MakeAccessorInfo(
+i::Handle<i::AccessorInfo> MakeAccessorInfo(
v8::Local<Name> name, Getter getter, Setter setter, v8::Local<Value> data,
v8::AccessControl settings, v8::PropertyAttribute attributes,
v8::Local<AccessorSignature> signature, bool is_special_data_property) {
@@ -1259,6 +1268,8 @@ static i::Handle<i::AccessorInfo> MakeAccessorInfo(
setter = reinterpret_cast<Setter>(&i::Accessors::ReconfigureToDataProperty);
}
SET_FIELD_WRAPPED(obj, set_setter, setter);
+ i::Address redirected = obj->redirected_getter();
+ if (redirected != nullptr) SET_FIELD_WRAPPED(obj, set_js_getter, redirected);
if (data.IsEmpty()) {
data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
}
@@ -1267,6 +1278,7 @@ static i::Handle<i::AccessorInfo> MakeAccessorInfo(
return SetAccessorInfoProperties(obj, name, settings, attributes, signature);
}
+} // namespace
Local<ObjectTemplate> FunctionTemplate::InstanceTemplate() {
i::Handle<i::FunctionTemplateInfo> handle = Utils::OpenHandle(this, true);
@@ -1277,7 +1289,7 @@ Local<ObjectTemplate> FunctionTemplate::InstanceTemplate() {
}
i::Isolate* isolate = handle->GetIsolate();
ENTER_V8(isolate);
- if (handle->instance_template()->IsUndefined()) {
+ if (handle->instance_template()->IsUndefined(isolate)) {
Local<ObjectTemplate> templ =
ObjectTemplate::New(isolate, ToApiHandle<FunctionTemplate>(handle));
handle->set_instance_template(*Utils::OpenHandle(*templ));
@@ -1358,10 +1370,7 @@ Local<ObjectTemplate> ObjectTemplate::New() {
static Local<ObjectTemplate> ObjectTemplateNew(
i::Isolate* isolate, v8::Local<FunctionTemplate> constructor,
bool do_not_cache) {
- // 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");
+ LOG_API(isolate, ObjectTemplate, New);
ENTER_V8(isolate);
i::Handle<i::Struct> struct_obj =
isolate->factory()->NewStruct(i::OBJECT_TEMPLATE_INFO_TYPE);
@@ -1370,13 +1379,12 @@ static Local<ObjectTemplate> ObjectTemplateNew(
InitializeTemplate(obj, Consts::OBJECT_TEMPLATE);
int next_serial_number = 0;
if (!do_not_cache) {
- next_serial_number = isolate->next_serial_number() + 1;
- isolate->set_next_serial_number(next_serial_number);
+ next_serial_number = isolate->heap()->GetNextTemplateSerialNumber();
}
obj->set_serial_number(i::Smi::FromInt(next_serial_number));
if (!constructor.IsEmpty())
obj->set_constructor(*Utils::OpenHandle(*constructor));
- obj->set_internal_field_count(i::Smi::FromInt(0));
+ obj->set_data(i::Smi::FromInt(0));
return Utils::ToLocal(obj);
}
@@ -1385,13 +1393,28 @@ Local<ObjectTemplate> ObjectTemplate::New(
return ObjectTemplateNew(isolate, constructor, false);
}
+MaybeLocal<ObjectTemplate> ObjectTemplate::FromSnapshot(Isolate* isolate,
+ size_t index) {
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ i::FixedArray* templates = i_isolate->heap()->serialized_templates();
+ int int_index = static_cast<int>(index);
+ if (int_index < templates->length()) {
+ i::Object* info = templates->get(int_index);
+ if (info->IsObjectTemplateInfo()) {
+ return Utils::ToLocal(
+ i::Handle<i::ObjectTemplateInfo>(i::ObjectTemplateInfo::cast(info)));
+ }
+ }
+ return Local<ObjectTemplate>();
+}
+
// Ensure that the object template has a constructor. If no
// constructor is available we create one.
static i::Handle<i::FunctionTemplateInfo> EnsureConstructor(
i::Isolate* isolate,
ObjectTemplate* object_template) {
i::Object* obj = Utils::OpenHandle(object_template)->constructor();
- if (!obj ->IsUndefined()) {
+ if (!obj->IsUndefined(isolate)) {
i::FunctionTemplateInfo* info = i::FunctionTemplateInfo::cast(obj);
return i::Handle<i::FunctionTemplateInfo>(info, isolate);
}
@@ -1480,20 +1503,12 @@ void ObjectTemplate::SetAccessor(v8::Local<Name> name,
signature, i::FLAG_disable_old_api_accessors);
}
-
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,
- Local<Value> data,
- PropertyHandlerFlags flags) {
- i::Isolate* isolate = Utils::OpenHandle(templ)->GetIsolate();
- ENTER_V8(isolate);
- i::HandleScope scope(isolate);
- auto cons = EnsureConstructor(isolate, templ);
- EnsureNotInstantiated(cons, "ObjectTemplateSetNamedPropertyHandler");
+static i::Handle<i::InterceptorInfo> CreateInterceptorInfo(
+ i::Isolate* isolate, Getter getter, Setter setter, Query query,
+ Deleter remover, Enumerator enumerator, Local<Value> data,
+ PropertyHandlerFlags flags) {
auto obj = i::Handle<i::InterceptorInfo>::cast(
isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE));
obj->set_flags(0);
@@ -1515,6 +1530,24 @@ static void ObjectTemplateSetNamedPropertyHandler(ObjectTemplate* templ,
data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
}
obj->set_data(*Utils::OpenHandle(*data));
+ return obj;
+}
+
+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,
+ Local<Value> data,
+ PropertyHandlerFlags flags) {
+ i::Isolate* isolate = Utils::OpenHandle(templ)->GetIsolate();
+ ENTER_V8(isolate);
+ i::HandleScope scope(isolate);
+ auto cons = EnsureConstructor(isolate, templ);
+ EnsureNotInstantiated(cons, "ObjectTemplateSetNamedPropertyHandler");
+ auto obj = CreateInterceptorInfo(isolate, getter, setter, query, remover,
+ enumerator, data, flags);
cons->set_named_property_handler(*obj);
}
@@ -1561,8 +1594,8 @@ void ObjectTemplate::SetAccessCheckCallback(AccessCheckCallback callback,
i::Handle<i::AccessCheckInfo>::cast(struct_info);
SET_FIELD_WRAPPED(info, set_callback, callback);
- SET_FIELD_WRAPPED(info, set_named_callback, nullptr);
- SET_FIELD_WRAPPED(info, set_indexed_callback, nullptr);
+ info->set_named_interceptor(nullptr);
+ info->set_indexed_interceptor(nullptr);
if (data.IsEmpty()) {
data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
@@ -1573,28 +1606,34 @@ void ObjectTemplate::SetAccessCheckCallback(AccessCheckCallback callback,
cons->set_needs_access_check(true);
}
-void ObjectTemplate::SetAccessCheckCallback(
- DeprecatedAccessCheckCallback callback, Local<Value> data) {
- SetAccessCheckCallback(reinterpret_cast<AccessCheckCallback>(callback), data);
-}
-
-void ObjectTemplate::SetAccessCheckCallbacks(
- NamedSecurityCallback named_callback,
- IndexedSecurityCallback indexed_callback, Local<Value> data) {
+void ObjectTemplate::SetAccessCheckCallbackAndHandler(
+ AccessCheckCallback callback,
+ const NamedPropertyHandlerConfiguration& named_handler,
+ const IndexedPropertyHandlerConfiguration& indexed_handler,
+ Local<Value> data) {
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ENTER_V8(isolate);
i::HandleScope scope(isolate);
auto cons = EnsureConstructor(isolate, this);
- EnsureNotInstantiated(cons, "v8::ObjectTemplate::SetAccessCheckCallbacks");
+ EnsureNotInstantiated(
+ cons, "v8::ObjectTemplate::SetAccessCheckCallbackWithHandler");
i::Handle<i::Struct> struct_info =
isolate->factory()->NewStruct(i::ACCESS_CHECK_INFO_TYPE);
i::Handle<i::AccessCheckInfo> info =
i::Handle<i::AccessCheckInfo>::cast(struct_info);
- SET_FIELD_WRAPPED(info, set_callback, nullptr);
- SET_FIELD_WRAPPED(info, set_named_callback, named_callback);
- SET_FIELD_WRAPPED(info, set_indexed_callback, indexed_callback);
+ SET_FIELD_WRAPPED(info, set_callback, callback);
+ auto named_interceptor = CreateInterceptorInfo(
+ isolate, named_handler.getter, named_handler.setter, named_handler.query,
+ named_handler.deleter, named_handler.enumerator, named_handler.data,
+ named_handler.flags);
+ info->set_named_interceptor(*named_interceptor);
+ auto indexed_interceptor = CreateInterceptorInfo(
+ isolate, indexed_handler.getter, indexed_handler.setter,
+ indexed_handler.query, indexed_handler.deleter,
+ indexed_handler.enumerator, indexed_handler.data, indexed_handler.flags);
+ info->set_indexed_interceptor(*indexed_interceptor);
if (data.IsEmpty()) {
data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
@@ -1605,7 +1644,6 @@ void ObjectTemplate::SetAccessCheckCallbacks(
cons->set_needs_access_check(true);
}
-
void ObjectTemplate::SetHandler(
const IndexedPropertyHandlerConfiguration& config) {
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
@@ -1613,25 +1651,9 @@ void ObjectTemplate::SetHandler(
i::HandleScope scope(isolate);
auto cons = EnsureConstructor(isolate, this);
EnsureNotInstantiated(cons, "v8::ObjectTemplate::SetHandler");
- auto obj = i::Handle<i::InterceptorInfo>::cast(
- isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE));
- obj->set_flags(0);
-
- 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_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));
- }
- obj->set_data(*Utils::OpenHandle(*data));
+ auto obj = CreateInterceptorInfo(
+ isolate, config.getter, config.setter, config.query, config.deleter,
+ config.enumerator, config.data, config.flags);
cons->set_indexed_property_handler(*obj);
}
@@ -1657,7 +1679,7 @@ void ObjectTemplate::SetCallAsFunctionHandler(FunctionCallback callback,
int ObjectTemplate::InternalFieldCount() {
- return i::Smi::cast(Utils::OpenHandle(this)->internal_field_count())->value();
+ return Utils::OpenHandle(this)->internal_field_count();
}
@@ -1675,9 +1697,18 @@ void ObjectTemplate::SetInternalFieldCount(int value) {
// function to do the setting.
EnsureConstructor(isolate, this);
}
- Utils::OpenHandle(this)->set_internal_field_count(i::Smi::FromInt(value));
+ Utils::OpenHandle(this)->set_internal_field_count(value);
+}
+
+bool ObjectTemplate::IsImmutableProto() {
+ return Utils::OpenHandle(this)->immutable_proto();
}
+void ObjectTemplate::SetImmutableProto() {
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+ ENTER_V8(isolate);
+ Utils::OpenHandle(this)->set_immutable_proto(true);
+}
// --- S c r i p t s ---
@@ -1723,13 +1754,11 @@ ScriptCompiler::StreamedSource::GetCachedData() const {
Local<Script> UnboundScript::BindToCurrentContext() {
i::Handle<i::HeapObject> obj =
i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this));
- i::Handle<i::SharedFunctionInfo>
- function_info(i::SharedFunctionInfo::cast(*obj), obj->GetIsolate());
i::Isolate* isolate = obj->GetIsolate();
-
- i::Handle<i::JSReceiver> global(isolate->native_context()->global_object());
+ i::Handle<i::SharedFunctionInfo> function_info(
+ i::SharedFunctionInfo::cast(*obj), isolate);
i::Handle<i::JSFunction> function =
- obj->GetIsolate()->factory()->NewFunctionFromSharedFunctionInfo(
+ isolate->factory()->NewFunctionFromSharedFunctionInfo(
function_info, isolate->native_context());
return ToApiHandle<Script>(function);
}
@@ -1739,7 +1768,7 @@ int UnboundScript::GetId() {
i::Handle<i::HeapObject> obj =
i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this));
i::Isolate* isolate = obj->GetIsolate();
- LOG_API(isolate, "v8::UnboundScript::GetId");
+ LOG_API(isolate, UnboundScript, GetId);
i::HandleScope scope(isolate);
i::Handle<i::SharedFunctionInfo> function_info(
i::SharedFunctionInfo::cast(*obj));
@@ -1752,7 +1781,7 @@ int UnboundScript::GetLineNumber(int code_pos) {
i::Handle<i::SharedFunctionInfo> obj =
i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
i::Isolate* isolate = obj->GetIsolate();
- LOG_API(isolate, "UnboundScript::GetLineNumber");
+ LOG_API(isolate, UnboundScript, GetLineNumber);
if (obj->script()->IsScript()) {
i::Handle<i::Script> script(i::Script::cast(obj->script()));
return i::Script::GetLineNumber(script, code_pos);
@@ -1766,7 +1795,7 @@ Local<Value> UnboundScript::GetScriptName() {
i::Handle<i::SharedFunctionInfo> obj =
i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
i::Isolate* isolate = obj->GetIsolate();
- LOG_API(isolate, "UnboundScript::GetName");
+ LOG_API(isolate, UnboundScript, GetName);
if (obj->script()->IsScript()) {
i::Object* name = i::Script::cast(obj->script())->name();
return Utils::ToLocal(i::Handle<i::Object>(name, isolate));
@@ -1780,7 +1809,7 @@ Local<Value> UnboundScript::GetSourceURL() {
i::Handle<i::SharedFunctionInfo> obj =
i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
i::Isolate* isolate = obj->GetIsolate();
- LOG_API(isolate, "UnboundScript::GetSourceURL");
+ LOG_API(isolate, UnboundScript, GetSourceURL);
if (obj->script()->IsScript()) {
i::Object* url = i::Script::cast(obj->script())->source_url();
return Utils::ToLocal(i::Handle<i::Object>(url, isolate));
@@ -1794,7 +1823,7 @@ Local<Value> UnboundScript::GetSourceMappingURL() {
i::Handle<i::SharedFunctionInfo> obj =
i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
i::Isolate* isolate = obj->GetIsolate();
- LOG_API(isolate, "UnboundScript::GetSourceMappingURL");
+ LOG_API(isolate, UnboundScript, GetSourceMappingURL);
if (obj->script()->IsScript()) {
i::Object* url = i::Script::cast(obj->script())->source_mapping_url();
return Utils::ToLocal(i::Handle<i::Object>(url, isolate));
@@ -1805,12 +1834,13 @@ Local<Value> UnboundScript::GetSourceMappingURL() {
MaybeLocal<Value> Script::Run(Local<Context> context) {
- PREPARE_FOR_EXECUTION_WITH_CALLBACK(context, "v8::Script::Run()", Value)
+ PREPARE_FOR_EXECUTION_WITH_CALLBACK(context, Script, Run, Value)
+ i::HistogramTimerScope execute_timer(isolate->counters()->execute(), true);
i::AggregatingHistogramTimerScope timer(isolate->counters()->compile_lazy());
i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
- TRACE_EVENT0("v8", "V8.Execute");
+ TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
auto fun = i::Handle<i::JSFunction>::cast(Utils::OpenHandle(this));
- i::Handle<i::Object> receiver(isolate->global_proxy(), isolate);
+ i::Handle<i::Object> receiver = isolate->global_proxy();
Local<Value> result;
has_pending_exception =
!ToLocal<Value>(i::Execution::Call(isolate, fun, receiver, 0, NULL),
@@ -1841,8 +1871,9 @@ MaybeLocal<UnboundScript> ScriptCompiler::CompileUnboundInternal(
Isolate* v8_isolate, Source* source, CompileOptions options,
bool is_module) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
- PREPARE_FOR_EXECUTION_WITH_ISOLATE(
- isolate, "v8::ScriptCompiler::CompileUnbound()", UnboundScript);
+ PREPARE_FOR_EXECUTION_WITH_ISOLATE(isolate, ScriptCompiler, CompileUnbound,
+ UnboundScript);
+ TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.ScriptCompiler");
// Don't try to produce any kind of cache when the debugger is loaded.
if (isolate->debug()->is_loaded() &&
@@ -1862,7 +1893,7 @@ MaybeLocal<UnboundScript> ScriptCompiler::CompileUnboundInternal(
i::Handle<i::SharedFunctionInfo> result;
{
i::HistogramTimerScope total(isolate->counters()->compile_script(), true);
- TRACE_EVENT0("v8", "V8.CompileScript");
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.CompileScript");
i::Handle<i::Object> name_obj;
i::Handle<i::Object> source_map_url;
int line_offset = 0;
@@ -2001,8 +2032,9 @@ MaybeLocal<Function> ScriptCompiler::CompileFunctionInContext(
Local<Context> v8_context, Source* source, size_t arguments_count,
Local<String> arguments[], size_t context_extension_count,
Local<Object> context_extensions[]) {
- PREPARE_FOR_EXECUTION(
- v8_context, "v8::ScriptCompiler::CompileFunctionInContext()", Function);
+ PREPARE_FOR_EXECUTION(v8_context, ScriptCompiler, CompileFunctionInContext,
+ Function);
+ TRACE_EVENT0("v8", "V8.ScriptCompiler");
i::Handle<i::String> source_string;
auto factory = isolate->factory();
if (arguments_count) {
@@ -2056,6 +2088,8 @@ MaybeLocal<Function> ScriptCompiler::CompileFunctionInContext(
}
i::Handle<i::Object> name_obj;
+ int eval_scope_position = 0;
+ int eval_position = i::kNoSourcePosition;
int line_offset = 0;
int column_offset = 0;
if (!source->resource_name.IsEmpty()) {
@@ -2068,11 +2102,13 @@ MaybeLocal<Function> ScriptCompiler::CompileFunctionInContext(
column_offset = static_cast<int>(source->resource_column_offset->Value());
}
i::Handle<i::JSFunction> fun;
- has_pending_exception = !i::Compiler::GetFunctionFromEval(
- source_string, outer_info, context, i::SLOPPY,
- i::ONLY_SINGLE_FUNCTION_LITERAL, line_offset,
- column_offset - scope_position, name_obj,
- source->resource_options).ToHandle(&fun);
+ has_pending_exception =
+ !i::Compiler::GetFunctionFromEval(
+ source_string, outer_info, context, i::SLOPPY,
+ i::ONLY_SINGLE_FUNCTION_LITERAL, eval_scope_position, eval_position,
+ line_offset, column_offset - scope_position, name_obj,
+ source->resource_options)
+ .ToHandle(&fun);
if (has_pending_exception) {
isolate->ReportPendingMessages();
}
@@ -2112,7 +2148,8 @@ MaybeLocal<Script> ScriptCompiler::Compile(Local<Context> context,
StreamedSource* v8_source,
Local<String> full_source_string,
const ScriptOrigin& origin) {
- PREPARE_FOR_EXECUTION(context, "v8::ScriptCompiler::Compile()", Script);
+ PREPARE_FOR_EXECUTION(context, ScriptCompiler, Compile, Script);
+ TRACE_EVENT0("v8", "V8.ScriptCompiler");
i::StreamedSource* source = v8_source->impl();
i::Handle<i::String> str = Utils::OpenHandle(*(full_source_string));
i::Handle<i::Script> script = isolate->factory()->NewScript(str);
@@ -2136,6 +2173,11 @@ MaybeLocal<Script> ScriptCompiler::Compile(Local<Context> context,
source->info->set_script(script);
source->info->set_context(isolate->native_context());
+ // Create a canonical handle scope before internalizing parsed values if
+ // compiling bytecode. This is required for off-thread bytecode generation.
+ std::unique_ptr<i::CanonicalHandleScope> canonical;
+ if (i::FLAG_ignition) canonical.reset(new i::CanonicalHandleScope(isolate));
+
// Do the parsing tasks which need to be done on the main thread. This will
// also handle parse errors.
source->parser->Internalize(isolate, script,
@@ -2275,7 +2317,7 @@ v8::TryCatch::~TryCatch() {
bool v8::TryCatch::HasCaught() const {
- return !reinterpret_cast<i::Object*>(exception_)->IsTheHole();
+ return !reinterpret_cast<i::Object*>(exception_)->IsTheHole(isolate_);
}
@@ -2311,7 +2353,7 @@ MaybeLocal<Value> v8::TryCatch::StackTrace(Local<Context> context) const {
if (!HasCaught()) return v8::Local<Value>();
i::Object* raw_obj = reinterpret_cast<i::Object*>(exception_);
if (!raw_obj->IsJSObject()) return v8::Local<Value>();
- PREPARE_FOR_EXECUTION(context, "v8::TryCatch::StackTrace", Value);
+ PREPARE_FOR_EXECUTION(context, TryCatch, StackTrace, Value);
i::Handle<i::JSObject> obj(i::JSObject::cast(raw_obj), isolate_);
i::Handle<i::String> name = isolate->factory()->stack_string();
Maybe<bool> maybe = i::JSReceiver::HasProperty(obj, name);
@@ -2334,8 +2376,8 @@ v8::Local<Value> v8::TryCatch::StackTrace() const {
v8::Local<v8::Message> v8::TryCatch::Message() const {
i::Object* message = reinterpret_cast<i::Object*>(message_obj_);
- DCHECK(message->IsJSMessageObject() || message->IsTheHole());
- if (HasCaught() && !message->IsTheHole()) {
+ DCHECK(message->IsJSMessageObject() || message->IsTheHole(isolate_));
+ if (HasCaught() && !message->IsTheHole(isolate_)) {
return v8::Utils::MessageToLocal(i::Handle<i::Object>(message, isolate_));
} else {
return v8::Local<v8::Message>();
@@ -2413,16 +2455,12 @@ v8::Local<v8::StackTrace> Message::GetStackTrace() const {
Maybe<int> Message::GetLineNumber(Local<Context> context) const {
- PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Message::GetLineNumber()", int);
- i::Handle<i::JSFunction> fun = isolate->message_get_line_number();
- i::Handle<i::Object> undefined = isolate->factory()->undefined_value();
- i::Handle<i::Object> args[] = {Utils::OpenHandle(this)};
- i::Handle<i::Object> result;
- has_pending_exception =
- !i::Execution::Call(isolate, fun, undefined, arraysize(args), args)
- .ToHandle(&result);
- RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int);
- return Just(static_cast<int>(result->Number()));
+ auto self = Utils::OpenHandle(this);
+ i::Isolate* isolate = self->GetIsolate();
+ ENTER_V8(isolate);
+ EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
+ auto msg = i::Handle<i::JSMessageObject>::cast(self);
+ return Just(msg->GetLineNumber());
}
@@ -2445,17 +2483,12 @@ int Message::GetEndPosition() const {
Maybe<int> Message::GetStartColumn(Local<Context> context) const {
- PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Message::GetStartColumn()",
- int);
- i::Handle<i::JSFunction> fun = isolate->message_get_column_number();
- i::Handle<i::Object> undefined = isolate->factory()->undefined_value();
- i::Handle<i::Object> args[] = {Utils::OpenHandle(this)};
- i::Handle<i::Object> result;
- has_pending_exception =
- !i::Execution::Call(isolate, fun, undefined, arraysize(args), args)
- .ToHandle(&result);
- RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int);
- return Just(static_cast<int>(result->Number()));
+ auto self = Utils::OpenHandle(this);
+ i::Isolate* isolate = self->GetIsolate();
+ ENTER_V8(isolate);
+ EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
+ auto msg = i::Handle<i::JSMessageObject>::cast(self);
+ return Just(msg->GetColumnNumber());
}
@@ -2468,18 +2501,15 @@ int Message::GetStartColumn() const {
Maybe<int> Message::GetEndColumn(Local<Context> context) const {
auto self = Utils::OpenHandle(this);
- PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Message::GetEndColumn()", int);
- i::Handle<i::JSFunction> fun = isolate->message_get_column_number();
- i::Handle<i::Object> undefined = isolate->factory()->undefined_value();
- i::Handle<i::Object> args[] = {self};
- i::Handle<i::Object> result;
- has_pending_exception =
- !i::Execution::Call(isolate, fun, undefined, arraysize(args), args)
- .ToHandle(&result);
- RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int);
- int start = self->start_position();
- int end = self->end_position();
- return Just(static_cast<int>(result->Number()) + (end - start));
+ i::Isolate* isolate = self->GetIsolate();
+ ENTER_V8(isolate);
+ EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
+ auto msg = i::Handle<i::JSMessageObject>::cast(self);
+ const int column_number = msg->GetColumnNumber();
+ if (column_number == -1) return Just(-1);
+ const int start = self->start_position();
+ const int end = self->end_position();
+ return Just(column_number + (end - start));
}
@@ -2512,20 +2542,12 @@ bool Message::IsOpaque() const {
MaybeLocal<String> Message::GetSourceLine(Local<Context> context) const {
- PREPARE_FOR_EXECUTION(context, "v8::Message::GetSourceLine()", String);
- i::Handle<i::JSFunction> fun = isolate->message_get_source_line();
- i::Handle<i::Object> undefined = isolate->factory()->undefined_value();
- i::Handle<i::Object> args[] = {Utils::OpenHandle(this)};
- i::Handle<i::Object> result;
- has_pending_exception =
- !i::Execution::Call(isolate, fun, undefined, arraysize(args), args)
- .ToHandle(&result);
- RETURN_ON_FAILED_EXECUTION(String);
- Local<String> str;
- if (result->IsString()) {
- str = Utils::ToLocal(i::Handle<i::String>::cast(result));
- }
- RETURN_ESCAPED(str);
+ auto self = Utils::OpenHandle(this);
+ i::Isolate* isolate = self->GetIsolate();
+ ENTER_V8(isolate);
+ EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
+ auto msg = i::Handle<i::JSMessageObject>::cast(self);
+ RETURN_ESCAPED(Utils::ToLocal(msg->GetSourceLine()));
}
@@ -2645,7 +2667,7 @@ static bool getBoolProperty(const StackFrame* f, const char* propertyName) {
i::Handle<i::JSObject> self = Utils::OpenHandle(f);
i::Handle<i::Object> obj =
i::JSReceiver::GetProperty(isolate, self, propertyName).ToHandleChecked();
- return obj->IsTrue();
+ return obj->IsTrue(isolate);
}
bool StackFrame::IsEval() const { return getBoolProperty(this, "isEval"); }
@@ -2680,7 +2702,7 @@ void NativeWeakMap::Set(Local<Value> v8_key, Local<Value> v8_value) {
}
i::Handle<i::ObjectHashTable> table(
i::ObjectHashTable::cast(weak_collection->table()));
- if (!table->IsKey(*key)) {
+ if (!table->IsKey(isolate, *key)) {
DCHECK(false);
return;
}
@@ -2700,12 +2722,12 @@ Local<Value> NativeWeakMap::Get(Local<Value> v8_key) {
}
i::Handle<i::ObjectHashTable> table(
i::ObjectHashTable::cast(weak_collection->table()));
- if (!table->IsKey(*key)) {
+ if (!table->IsKey(isolate, *key)) {
DCHECK(false);
return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
}
i::Handle<i::Object> lookup(table->Lookup(key), isolate);
- if (lookup->IsTheHole())
+ if (lookup->IsTheHole(isolate))
return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
return Utils::ToLocal(lookup);
}
@@ -2723,12 +2745,12 @@ bool NativeWeakMap::Has(Local<Value> v8_key) {
}
i::Handle<i::ObjectHashTable> table(
i::ObjectHashTable::cast(weak_collection->table()));
- if (!table->IsKey(*key)) {
+ if (!table->IsKey(isolate, *key)) {
DCHECK(false);
return false;
}
i::Handle<i::Object> lookup(table->Lookup(key), isolate);
- return !lookup->IsTheHole();
+ return !lookup->IsTheHole(isolate);
}
@@ -2744,7 +2766,7 @@ bool NativeWeakMap::Delete(Local<Value> v8_key) {
}
i::Handle<i::ObjectHashTable> table(
i::ObjectHashTable::cast(weak_collection->table()));
- if (!table->IsKey(*key)) {
+ if (!table->IsKey(isolate, *key)) {
DCHECK(false);
return false;
}
@@ -2757,49 +2779,94 @@ bool NativeWeakMap::Delete(Local<Value> v8_key) {
MaybeLocal<Value> JSON::Parse(Isolate* v8_isolate, Local<String> json_string) {
auto isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
- PREPARE_FOR_EXECUTION_WITH_ISOLATE(isolate, "JSON::Parse", Value);
+ PREPARE_FOR_EXECUTION_WITH_ISOLATE(isolate, JSON, Parse, Value);
i::Handle<i::String> string = Utils::OpenHandle(*json_string);
i::Handle<i::String> source = i::String::Flatten(string);
+ i::Handle<i::Object> undefined = isolate->factory()->undefined_value();
auto maybe = source->IsSeqOneByteString()
- ? i::JsonParser<true>::Parse(source)
- : i::JsonParser<false>::Parse(source);
+ ? i::JsonParser<true>::Parse(isolate, source, undefined)
+ : i::JsonParser<false>::Parse(isolate, source, undefined);
Local<Value> result;
has_pending_exception = !ToLocal<Value>(maybe, &result);
RETURN_ON_FAILED_EXECUTION(Value);
RETURN_ESCAPED(result);
}
+MaybeLocal<Value> JSON::Parse(Local<Context> context,
+ Local<String> json_string) {
+ PREPARE_FOR_EXECUTION(context, JSON, Parse, Value);
+ i::Handle<i::String> string = Utils::OpenHandle(*json_string);
+ i::Handle<i::String> source = i::String::Flatten(string);
+ i::Handle<i::Object> undefined = isolate->factory()->undefined_value();
+ auto maybe = source->IsSeqOneByteString()
+ ? i::JsonParser<true>::Parse(isolate, source, undefined)
+ : i::JsonParser<false>::Parse(isolate, source, undefined);
+ Local<Value> result;
+ has_pending_exception = !ToLocal<Value>(maybe, &result);
+ RETURN_ON_FAILED_EXECUTION(Value);
+ RETURN_ESCAPED(result);
+}
Local<Value> JSON::Parse(Local<String> json_string) {
- auto isolate = reinterpret_cast<v8::Isolate*>(
- Utils::OpenHandle(*json_string)->GetIsolate());
- RETURN_TO_LOCAL_UNCHECKED(Parse(isolate, json_string), Value);
+ RETURN_TO_LOCAL_UNCHECKED(Parse(Local<Context>(), json_string), Value);
+}
+
+MaybeLocal<String> JSON::Stringify(Local<Context> context,
+ Local<Object> json_object,
+ Local<String> gap) {
+ PREPARE_FOR_EXECUTION(context, JSON, Stringify, String);
+ i::Handle<i::Object> object = Utils::OpenHandle(*json_object);
+ i::Handle<i::Object> replacer = isolate->factory()->undefined_value();
+ i::Handle<i::String> gap_string = gap.IsEmpty()
+ ? isolate->factory()->empty_string()
+ : Utils::OpenHandle(*gap);
+ i::Handle<i::Object> maybe;
+ has_pending_exception = !i::JsonStringifier(isolate)
+ .Stringify(object, replacer, gap_string)
+ .ToHandle(&maybe);
+ RETURN_ON_FAILED_EXECUTION(String);
+ Local<String> result;
+ has_pending_exception =
+ !ToLocal<String>(i::Object::ToString(isolate, maybe), &result);
+ RETURN_ON_FAILED_EXECUTION(String);
+ RETURN_ESCAPED(result);
}
-
// --- D a t a ---
bool Value::FullIsUndefined() const {
- bool result = Utils::OpenHandle(this)->IsUndefined();
+ i::Handle<i::Object> object = Utils::OpenHandle(this);
+ bool result = false;
+ if (!object->IsSmi()) {
+ result = object->IsUndefined(i::HeapObject::cast(*object)->GetIsolate());
+ }
DCHECK_EQ(result, QuickIsUndefined());
return result;
}
bool Value::FullIsNull() const {
- bool result = Utils::OpenHandle(this)->IsNull();
+ i::Handle<i::Object> object = Utils::OpenHandle(this);
+ bool result = false;
+ if (!object->IsSmi()) {
+ result = object->IsNull(i::HeapObject::cast(*object)->GetIsolate());
+ }
DCHECK_EQ(result, QuickIsNull());
return result;
}
bool Value::IsTrue() const {
- return Utils::OpenHandle(this)->IsTrue();
+ i::Handle<i::Object> object = Utils::OpenHandle(this);
+ if (object->IsSmi()) return false;
+ return object->IsTrue(i::HeapObject::cast(*object)->GetIsolate());
}
bool Value::IsFalse() const {
- return Utils::OpenHandle(this)->IsFalse();
+ i::Handle<i::Object> object = Utils::OpenHandle(this);
+ if (object->IsSmi()) return false;
+ return object->IsFalse(i::HeapObject::cast(*object)->GetIsolate());
}
@@ -2878,6 +2945,13 @@ bool Value::IsNumber() const {
bool Value::IsProxy() const { return Utils::OpenHandle(this)->IsJSProxy(); }
+bool Value::IsWebAssemblyCompiledModule() const {
+ i::Handle<i::Object> obj = Utils::OpenHandle(this);
+ if (!obj->IsJSObject()) return false;
+ i::Handle<i::JSObject> js_obj = i::Handle<i::JSObject>::cast(obj);
+ return js_obj->GetIsolate()->native_context()->wasm_module_constructor() ==
+ js_obj->map()->GetConstructor();
+}
#define VALUE_IS_SPECIFIC_TYPE(Type, Class) \
bool Value::Is##Type() const { \
@@ -2936,22 +3010,7 @@ bool Value::IsUint32() const {
bool Value::IsNativeError() const {
- i::Handle<i::Object> obj = Utils::OpenHandle(this);
- if (!obj->IsJSObject()) return false;
- i::Handle<i::JSObject> js_obj = i::Handle<i::JSObject>::cast(obj);
- i::Isolate* isolate = js_obj->GetIsolate();
- i::Handle<i::Object> constructor(js_obj->map()->GetConstructor(), isolate);
- if (!constructor->IsJSFunction()) return false;
- i::Handle<i::JSFunction> function =
- i::Handle<i::JSFunction>::cast(constructor);
- if (!function->shared()->native()) return false;
- return function.is_identical_to(isolate->error_function()) ||
- function.is_identical_to(isolate->eval_error_function()) ||
- function.is_identical_to(isolate->range_error_function()) ||
- function.is_identical_to(isolate->reference_error_function()) ||
- function.is_identical_to(isolate->syntax_error_function()) ||
- function.is_identical_to(isolate->type_error_function()) ||
- function.is_identical_to(isolate->uri_error_function());
+ return Utils::OpenHandle(this)->IsJSError();
}
@@ -2983,17 +3042,12 @@ bool Value::IsSetIterator() const {
return Utils::OpenHandle(this)->IsJSSetIterator();
}
-
-bool Value::IsPromise() const {
- auto self = Utils::OpenHandle(this);
- return i::Object::IsPromise(self);
-}
-
+bool Value::IsPromise() const { return Utils::OpenHandle(this)->IsJSPromise(); }
MaybeLocal<String> Value::ToString(Local<Context> context) const {
auto obj = Utils::OpenHandle(this);
if (obj->IsString()) return ToApiHandle<String>(obj);
- PREPARE_FOR_EXECUTION(context, "ToString", String);
+ PREPARE_FOR_EXECUTION(context, Object, ToString, String);
Local<String> result;
has_pending_exception =
!ToLocal<String>(i::Object::ToString(isolate, obj), &result);
@@ -3010,14 +3064,9 @@ Local<String> Value::ToString(Isolate* isolate) const {
MaybeLocal<String> Value::ToDetailString(Local<Context> context) const {
i::Handle<i::Object> obj = Utils::OpenHandle(this);
if (obj->IsString()) return ToApiHandle<String>(obj);
- PREPARE_FOR_EXECUTION(context, "ToDetailString", String);
- Local<String> result;
- i::Handle<i::Object> args[] = {obj};
- has_pending_exception = !ToLocal<String>(
- i::Execution::TryCall(isolate, isolate->no_side_effects_to_string_fun(),
- isolate->factory()->undefined_value(),
- arraysize(args), args),
- &result);
+ PREPARE_FOR_EXECUTION(context, Object, ToDetailString, String);
+ Local<String> result =
+ Utils::ToLocal(i::Object::NoSideEffectsToString(isolate, obj));
RETURN_ON_FAILED_EXECUTION(String);
RETURN_ESCAPED(result);
}
@@ -3032,7 +3081,7 @@ Local<String> Value::ToDetailString(Isolate* isolate) const {
MaybeLocal<Object> Value::ToObject(Local<Context> context) const {
auto obj = Utils::OpenHandle(this);
if (obj->IsJSReceiver()) return ToApiHandle<Object>(obj);
- PREPARE_FOR_EXECUTION(context, "ToObject", Object);
+ PREPARE_FOR_EXECUTION(context, Object, ToObject, Object);
Local<Object> result;
has_pending_exception =
!ToLocal<Object>(i::Object::ToObject(isolate, obj), &result);
@@ -3063,7 +3112,7 @@ Local<Boolean> Value::ToBoolean(Isolate* v8_isolate) const {
MaybeLocal<Number> Value::ToNumber(Local<Context> context) const {
auto obj = Utils::OpenHandle(this);
if (obj->IsNumber()) return ToApiHandle<Number>(obj);
- PREPARE_FOR_EXECUTION(context, "ToNumber", Number);
+ PREPARE_FOR_EXECUTION(context, Object, ToNumber, Number);
Local<Number> result;
has_pending_exception = !ToLocal<Number>(i::Object::ToNumber(obj), &result);
RETURN_ON_FAILED_EXECUTION(Number);
@@ -3079,7 +3128,7 @@ Local<Number> Value::ToNumber(Isolate* isolate) const {
MaybeLocal<Integer> Value::ToInteger(Local<Context> context) const {
auto obj = Utils::OpenHandle(this);
if (obj->IsSmi()) return ToApiHandle<Integer>(obj);
- PREPARE_FOR_EXECUTION(context, "ToInteger", Integer);
+ PREPARE_FOR_EXECUTION(context, Object, ToInteger, Integer);
Local<Integer> result;
has_pending_exception =
!ToLocal<Integer>(i::Object::ToInteger(isolate, obj), &result);
@@ -3097,7 +3146,7 @@ MaybeLocal<Int32> Value::ToInt32(Local<Context> context) const {
auto obj = Utils::OpenHandle(this);
if (obj->IsSmi()) return ToApiHandle<Int32>(obj);
Local<Int32> result;
- PREPARE_FOR_EXECUTION(context, "ToInt32", Int32);
+ PREPARE_FOR_EXECUTION(context, Object, ToInt32, Int32);
has_pending_exception =
!ToLocal<Int32>(i::Object::ToInt32(isolate, obj), &result);
RETURN_ON_FAILED_EXECUTION(Int32);
@@ -3114,7 +3163,7 @@ MaybeLocal<Uint32> Value::ToUint32(Local<Context> context) const {
auto obj = Utils::OpenHandle(this);
if (obj->IsSmi()) return ToApiHandle<Uint32>(obj);
Local<Uint32> result;
- PREPARE_FOR_EXECUTION(context, "ToUint32", Uint32);
+ PREPARE_FOR_EXECUTION(context, Object, ToUint32, Uint32);
has_pending_exception =
!ToLocal<Uint32>(i::Object::ToUint32(isolate, obj), &result);
RETURN_ON_FAILED_EXECUTION(Uint32);
@@ -3129,62 +3178,55 @@ Local<Uint32> Value::ToUint32(Isolate* isolate) const {
void i::Internals::CheckInitializedImpl(v8::Isolate* external_isolate) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
- Utils::ApiCheck(isolate != NULL &&
- !isolate->IsDead(),
- "v8::internal::Internals::CheckInitialized()",
+ Utils::ApiCheck(isolate != NULL && !isolate->IsDead(),
+ "v8::internal::Internals::CheckInitialized",
"Isolate is not initialized or V8 has died");
}
void External::CheckCast(v8::Value* that) {
- Utils::ApiCheck(Utils::OpenHandle(that)->IsExternal(),
- "v8::External::Cast()",
+ Utils::ApiCheck(Utils::OpenHandle(that)->IsExternal(), "v8::External::Cast",
"Could not convert to external");
}
void v8::Object::CheckCast(Value* that) {
i::Handle<i::Object> obj = Utils::OpenHandle(that);
- Utils::ApiCheck(obj->IsJSReceiver(), "v8::Object::Cast()",
+ Utils::ApiCheck(obj->IsJSReceiver(), "v8::Object::Cast",
"Could not convert to object");
}
void v8::Function::CheckCast(Value* that) {
i::Handle<i::Object> obj = Utils::OpenHandle(that);
- Utils::ApiCheck(obj->IsCallable(), "v8::Function::Cast()",
+ Utils::ApiCheck(obj->IsCallable(), "v8::Function::Cast",
"Could not convert to function");
}
void v8::Boolean::CheckCast(v8::Value* that) {
i::Handle<i::Object> obj = Utils::OpenHandle(that);
- Utils::ApiCheck(obj->IsBoolean(),
- "v8::Boolean::Cast()",
+ Utils::ApiCheck(obj->IsBoolean(), "v8::Boolean::Cast",
"Could not convert to boolean");
}
void v8::Name::CheckCast(v8::Value* that) {
i::Handle<i::Object> obj = Utils::OpenHandle(that);
- Utils::ApiCheck(obj->IsName(),
- "v8::Name::Cast()",
- "Could not convert to name");
+ Utils::ApiCheck(obj->IsName(), "v8::Name::Cast", "Could not convert to name");
}
void v8::String::CheckCast(v8::Value* that) {
i::Handle<i::Object> obj = Utils::OpenHandle(that);
- Utils::ApiCheck(obj->IsString(),
- "v8::String::Cast()",
+ Utils::ApiCheck(obj->IsString(), "v8::String::Cast",
"Could not convert to string");
}
void v8::Symbol::CheckCast(v8::Value* that) {
i::Handle<i::Object> obj = Utils::OpenHandle(that);
- Utils::ApiCheck(obj->IsSymbol(),
- "v8::Symbol::Cast()",
+ Utils::ApiCheck(obj->IsSymbol(), "v8::Symbol::Cast",
"Could not convert to symbol");
}
@@ -3199,65 +3241,64 @@ void v8::Number::CheckCast(v8::Value* that) {
void v8::Integer::CheckCast(v8::Value* that) {
i::Handle<i::Object> obj = Utils::OpenHandle(that);
- Utils::ApiCheck(obj->IsNumber(),
- "v8::Integer::Cast()",
+ Utils::ApiCheck(obj->IsNumber(), "v8::Integer::Cast",
"Could not convert to number");
}
void v8::Int32::CheckCast(v8::Value* that) {
- Utils::ApiCheck(that->IsInt32(), "v8::Int32::Cast()",
+ Utils::ApiCheck(that->IsInt32(), "v8::Int32::Cast",
"Could not convert to 32-bit signed integer");
}
void v8::Uint32::CheckCast(v8::Value* that) {
- Utils::ApiCheck(that->IsUint32(), "v8::Uint32::Cast()",
+ Utils::ApiCheck(that->IsUint32(), "v8::Uint32::Cast",
"Could not convert to 32-bit unsigned integer");
}
void v8::Array::CheckCast(Value* that) {
i::Handle<i::Object> obj = Utils::OpenHandle(that);
- Utils::ApiCheck(obj->IsJSArray(),
- "v8::Array::Cast()",
+ Utils::ApiCheck(obj->IsJSArray(), "v8::Array::Cast",
"Could not convert to array");
}
void v8::Map::CheckCast(Value* that) {
i::Handle<i::Object> obj = Utils::OpenHandle(that);
- Utils::ApiCheck(obj->IsJSMap(), "v8::Map::Cast()",
- "Could not convert to Map");
+ Utils::ApiCheck(obj->IsJSMap(), "v8::Map::Cast", "Could not convert to Map");
}
void v8::Set::CheckCast(Value* that) {
i::Handle<i::Object> obj = Utils::OpenHandle(that);
- Utils::ApiCheck(obj->IsJSSet(), "v8::Set::Cast()",
- "Could not convert to Set");
+ Utils::ApiCheck(obj->IsJSSet(), "v8_Set_Cast", "Could not convert to Set");
}
void v8::Promise::CheckCast(Value* that) {
- Utils::ApiCheck(that->IsPromise(),
- "v8::Promise::Cast()",
+ Utils::ApiCheck(that->IsPromise(), "v8::Promise::Cast",
"Could not convert to promise");
}
void v8::Promise::Resolver::CheckCast(Value* that) {
- Utils::ApiCheck(that->IsPromise(),
- "v8::Promise::Resolver::Cast()",
+ Utils::ApiCheck(that->IsPromise(), "v8::Promise::Resolver::Cast",
"Could not convert to promise resolver");
}
void v8::Proxy::CheckCast(Value* that) {
- Utils::ApiCheck(that->IsProxy(), "v8::Proxy::Cast()",
+ Utils::ApiCheck(that->IsProxy(), "v8::Proxy::Cast",
"Could not convert to proxy");
}
+void v8::WasmCompiledModule::CheckCast(Value* that) {
+ Utils::ApiCheck(that->IsWebAssemblyCompiledModule(),
+ "v8::WasmCompiledModule::Cast",
+ "Could not convert to wasm compiled module");
+}
void v8::ArrayBuffer::CheckCast(Value* that) {
i::Handle<i::Object> obj = Utils::OpenHandle(that);
@@ -3391,7 +3432,7 @@ bool Value::BooleanValue() const {
Maybe<double> Value::NumberValue(Local<Context> context) const {
auto obj = Utils::OpenHandle(this);
if (obj->IsNumber()) return Just(obj->Number());
- PREPARE_FOR_EXECUTION_PRIMITIVE(context, "NumberValue", double);
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, NumberValue, double);
i::Handle<i::Object> num;
has_pending_exception = !i::Object::ToNumber(obj).ToHandle(&num);
RETURN_ON_FAILED_EXECUTION_PRIMITIVE(double);
@@ -3412,7 +3453,7 @@ Maybe<int64_t> Value::IntegerValue(Local<Context> context) const {
if (obj->IsNumber()) {
return Just(NumberToInt64(*obj));
}
- PREPARE_FOR_EXECUTION_PRIMITIVE(context, "IntegerValue", int64_t);
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, IntegerValue, int64_t);
i::Handle<i::Object> num;
has_pending_exception = !i::Object::ToInteger(isolate, obj).ToHandle(&num);
RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int64_t);
@@ -3436,7 +3477,7 @@ int64_t Value::IntegerValue() const {
Maybe<int32_t> Value::Int32Value(Local<Context> context) const {
auto obj = Utils::OpenHandle(this);
if (obj->IsNumber()) return Just(NumberToInt32(*obj));
- PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Int32Value", int32_t);
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, Int32Value, int32_t);
i::Handle<i::Object> num;
has_pending_exception = !i::Object::ToInt32(isolate, obj).ToHandle(&num);
RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int32_t);
@@ -3455,7 +3496,7 @@ int32_t Value::Int32Value() const {
Maybe<uint32_t> Value::Uint32Value(Local<Context> context) const {
auto obj = Utils::OpenHandle(this);
if (obj->IsNumber()) return Just(NumberToUint32(*obj));
- PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Uint32Value", uint32_t);
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, Uint32Value, uint32_t);
i::Handle<i::Object> num;
has_pending_exception = !i::Object::ToUint32(isolate, obj).ToHandle(&num);
RETURN_ON_FAILED_EXECUTION_PRIMITIVE(uint32_t);
@@ -3477,7 +3518,7 @@ MaybeLocal<Uint32> Value::ToArrayIndex(Local<Context> context) const {
if (i::Smi::cast(*self)->value() >= 0) return Utils::Uint32ToLocal(self);
return Local<Uint32>();
}
- PREPARE_FOR_EXECUTION(context, "ToArrayIndex", Uint32);
+ PREPARE_FOR_EXECUTION(context, Object, ToArrayIndex, Uint32);
i::Handle<i::Object> string_obj;
has_pending_exception =
!i::Object::ToString(isolate, self).ToHandle(&string_obj);
@@ -3543,10 +3584,16 @@ bool Value::SameValue(Local<Value> that) const {
return self->SameValue(*other);
}
+Local<String> Value::TypeOf(v8::Isolate* external_isolate) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
+ ENTER_V8(isolate);
+ LOG_API(isolate, Value, TypeOf);
+ return Utils::ToLocal(i::Object::TypeOf(isolate, Utils::OpenHandle(this)));
+}
Maybe<bool> v8::Object::Set(v8::Local<v8::Context> context,
v8::Local<Value> key, v8::Local<Value> value) {
- PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::Set()", bool);
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, Set, bool);
auto self = Utils::OpenHandle(this);
auto key_obj = Utils::OpenHandle(*key);
auto value_obj = Utils::OpenHandle(*value);
@@ -3566,7 +3613,7 @@ bool v8::Object::Set(v8::Local<Value> key, v8::Local<Value> value) {
Maybe<bool> v8::Object::Set(v8::Local<v8::Context> context, uint32_t index,
v8::Local<Value> value) {
- PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::Set()", bool);
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, Set, bool);
auto self = Utils::OpenHandle(this);
auto value_obj = Utils::OpenHandle(*value);
has_pending_exception = i::Object::SetElement(isolate, self, index, value_obj,
@@ -3585,8 +3632,7 @@ bool v8::Object::Set(uint32_t index, v8::Local<Value> value) {
Maybe<bool> v8::Object::CreateDataProperty(v8::Local<v8::Context> context,
v8::Local<Name> key,
v8::Local<Value> value) {
- PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::CreateDataProperty()",
- bool);
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, CreateDataProperty, bool);
i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
@@ -3604,8 +3650,7 @@ Maybe<bool> v8::Object::CreateDataProperty(v8::Local<v8::Context> context,
Maybe<bool> v8::Object::CreateDataProperty(v8::Local<v8::Context> context,
uint32_t index,
v8::Local<Value> value) {
- PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::CreateDataProperty()",
- bool);
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, CreateDataProperty, bool);
i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
@@ -3622,8 +3667,7 @@ Maybe<bool> v8::Object::DefineOwnProperty(v8::Local<v8::Context> context,
v8::Local<Name> key,
v8::Local<Value> value,
v8::PropertyAttribute attributes) {
- PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::DefineOwnProperty()",
- bool);
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, DefineOwnProperty, bool);
i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
@@ -3666,7 +3710,7 @@ static i::MaybeHandle<i::Object> DefineObjectProperty(
Maybe<bool> v8::Object::ForceSet(v8::Local<v8::Context> context,
v8::Local<Value> key, v8::Local<Value> value,
v8::PropertyAttribute attribs) {
- PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::ForceSet()", bool);
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, ForceSet, bool);
auto self = i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
auto key_obj = Utils::OpenHandle(*key);
auto value_obj = Utils::OpenHandle(*value);
@@ -3682,9 +3726,8 @@ Maybe<bool> v8::Object::ForceSet(v8::Local<v8::Context> context,
bool v8::Object::ForceSet(v8::Local<Value> key, v8::Local<Value> value,
v8::PropertyAttribute attribs) {
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- PREPARE_FOR_EXECUTION_GENERIC(isolate, Local<Context>(),
- "v8::Object::ForceSet", false, i::HandleScope,
- false);
+ PREPARE_FOR_EXECUTION_GENERIC(isolate, Local<Context>(), Object, ForceSet,
+ false, i::HandleScope, false);
i::Handle<i::JSObject> self =
i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
@@ -3700,7 +3743,7 @@ bool v8::Object::ForceSet(v8::Local<Value> key, v8::Local<Value> value,
Maybe<bool> v8::Object::SetPrivate(Local<Context> context, Local<Private> key,
Local<Value> value) {
- PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::SetPrivate()", bool);
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, SetPrivate, bool);
auto self = Utils::OpenHandle(this);
auto key_obj = Utils::OpenHandle(reinterpret_cast<Name*>(*key));
auto value_obj = Utils::OpenHandle(*value);
@@ -3726,7 +3769,7 @@ Maybe<bool> v8::Object::SetPrivate(Local<Context> context, Local<Private> key,
MaybeLocal<Value> v8::Object::Get(Local<v8::Context> context,
Local<Value> key) {
- PREPARE_FOR_EXECUTION(context, "v8::Object::Get()", Value);
+ PREPARE_FOR_EXECUTION(context, Object, Get, Value);
auto self = Utils::OpenHandle(this);
auto key_obj = Utils::OpenHandle(*key);
i::Handle<i::Object> result;
@@ -3744,7 +3787,7 @@ Local<Value> v8::Object::Get(v8::Local<Value> key) {
MaybeLocal<Value> v8::Object::Get(Local<Context> context, uint32_t index) {
- PREPARE_FOR_EXECUTION(context, "v8::Object::Get()", Value);
+ PREPARE_FOR_EXECUTION(context, Object, Get, Value);
auto self = Utils::OpenHandle(this);
i::Handle<i::Object> result;
has_pending_exception =
@@ -3768,8 +3811,8 @@ MaybeLocal<Value> v8::Object::GetPrivate(Local<Context> context,
Maybe<PropertyAttribute> v8::Object::GetPropertyAttributes(
Local<Context> context, Local<Value> key) {
- PREPARE_FOR_EXECUTION_PRIMITIVE(
- context, "v8::Object::GetPropertyAttributes()", PropertyAttribute);
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, GetPropertyAttributes,
+ PropertyAttribute);
auto self = Utils::OpenHandle(this);
auto key_obj = Utils::OpenHandle(*key);
if (!key_obj->IsName()) {
@@ -3797,8 +3840,7 @@ PropertyAttribute v8::Object::GetPropertyAttributes(v8::Local<Value> key) {
MaybeLocal<Value> v8::Object::GetOwnPropertyDescriptor(Local<Context> context,
Local<String> key) {
- PREPARE_FOR_EXECUTION(context, "v8::Object::GetOwnPropertyDescriptor()",
- Value);
+ PREPARE_FOR_EXECUTION(context, Object, GetOwnPropertyDescriptor, Value);
i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
i::Handle<i::String> key_name = Utils::OpenHandle(*key);
@@ -3830,7 +3872,7 @@ Local<Value> v8::Object::GetPrototype() {
Maybe<bool> v8::Object::SetPrototype(Local<Context> context,
Local<Value> value) {
- PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::SetPrototype()", bool);
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, SetPrototype, bool);
auto self = Utils::OpenHandle(this);
auto value_obj = Utils::OpenHandle(*value);
// We do not allow exceptions thrown while setting the prototype
@@ -3854,27 +3896,38 @@ Local<Object> v8::Object::FindInstanceInPrototypeChain(
v8::Local<FunctionTemplate> tmpl) {
auto isolate = Utils::OpenHandle(this)->GetIsolate();
i::PrototypeIterator iter(isolate, *Utils::OpenHandle(this),
- i::PrototypeIterator::START_AT_RECEIVER);
+ i::kStartAtReceiver);
auto tmpl_info = *Utils::OpenHandle(*tmpl);
- while (!tmpl_info->IsTemplateFor(iter.GetCurrent())) {
+ while (!tmpl_info->IsTemplateFor(iter.GetCurrent<i::JSObject>())) {
iter.Advance();
- if (iter.IsAtEnd()) {
- return Local<Object>();
- }
+ if (iter.IsAtEnd()) return Local<Object>();
+ if (!iter.GetCurrent()->IsJSObject()) return Local<Object>();
}
// IsTemplateFor() ensures that iter.GetCurrent() can't be a Proxy here.
return Utils::ToLocal(i::handle(iter.GetCurrent<i::JSObject>(), isolate));
}
-
MaybeLocal<Array> v8::Object::GetPropertyNames(Local<Context> context) {
- PREPARE_FOR_EXECUTION(context, "v8::Object::GetPropertyNames()", Array);
+ return GetPropertyNames(
+ context, v8::KeyCollectionMode::kIncludePrototypes,
+ static_cast<v8::PropertyFilter>(ONLY_ENUMERABLE | SKIP_SYMBOLS),
+ v8::IndexFilter::kIncludeIndices);
+}
+
+MaybeLocal<Array> v8::Object::GetPropertyNames(Local<Context> context,
+ KeyCollectionMode mode,
+ PropertyFilter property_filter,
+ IndexFilter index_filter) {
+ PREPARE_FOR_EXECUTION(context, Object, GetPropertyNames, Array);
auto self = Utils::OpenHandle(this);
i::Handle<i::FixedArray> value;
- has_pending_exception =
- !i::JSReceiver::GetKeys(self, i::INCLUDE_PROTOS, i::ENUMERABLE_STRINGS)
- .ToHandle(&value);
+ i::KeyAccumulator accumulator(
+ isolate, static_cast<i::KeyCollectionMode>(mode),
+ static_cast<i::PropertyFilter>(property_filter));
+ accumulator.set_skip_indices(index_filter == IndexFilter::kSkipIndices);
+ has_pending_exception = accumulator.CollectKeys(self, self).IsNothing();
RETURN_ON_FAILED_EXECUTION(Array);
+ value = accumulator.GetKeys(i::GetKeysConversion::kKeepNumbers);
DCHECK(self->map()->EnumLength() == i::kInvalidEnumCacheSentinel ||
self->map()->EnumLength() == 0 ||
self->map()->instance_descriptors()->GetEnumCache() != *value);
@@ -3888,31 +3941,24 @@ Local<Array> v8::Object::GetPropertyNames() {
RETURN_TO_LOCAL_UNCHECKED(GetPropertyNames(context), Array);
}
-
MaybeLocal<Array> v8::Object::GetOwnPropertyNames(Local<Context> context) {
- PREPARE_FOR_EXECUTION(context, "v8::Object::GetOwnPropertyNames()", Array);
- auto self = Utils::OpenHandle(this);
- i::Handle<i::FixedArray> value;
- has_pending_exception =
- !i::JSReceiver::GetKeys(self, i::OWN_ONLY, i::ENUMERABLE_STRINGS)
- .ToHandle(&value);
- RETURN_ON_FAILED_EXECUTION(Array);
- DCHECK(self->map()->EnumLength() == i::kInvalidEnumCacheSentinel ||
- self->map()->EnumLength() == 0 ||
- self->map()->instance_descriptors()->GetEnumCache() != *value);
- auto result = isolate->factory()->NewJSArrayWithElements(value);
- RETURN_ESCAPED(Utils::ToLocal(result));
+ return GetOwnPropertyNames(
+ context, static_cast<v8::PropertyFilter>(ONLY_ENUMERABLE | SKIP_SYMBOLS));
}
-
Local<Array> v8::Object::GetOwnPropertyNames() {
auto context = ContextFromHeapObject(Utils::OpenHandle(this));
RETURN_TO_LOCAL_UNCHECKED(GetOwnPropertyNames(context), Array);
}
+MaybeLocal<Array> v8::Object::GetOwnPropertyNames(Local<Context> context,
+ PropertyFilter filter) {
+ return GetPropertyNames(context, KeyCollectionMode::kOwnOnly, filter,
+ v8::IndexFilter::kIncludeIndices);
+}
MaybeLocal<String> v8::Object::ObjectProtoToString(Local<Context> context) {
- PREPARE_FOR_EXECUTION(context, "v8::Object::ObjectProtoToString", String);
+ PREPARE_FOR_EXECUTION(context, Object, ObjectProtoToString, String);
auto obj = Utils::OpenHandle(this);
Local<String> result;
has_pending_exception =
@@ -3936,8 +3982,7 @@ Local<String> v8::Object::GetConstructorName() {
Maybe<bool> v8::Object::SetIntegrityLevel(Local<Context> context,
IntegrityLevel level) {
- PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::SetIntegrityLevel()",
- bool);
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, SetIntegrityLevel, bool);
auto self = Utils::OpenHandle(this);
i::JSReceiver::IntegrityLevel i_level =
level == IntegrityLevel::kFrozen ? i::FROZEN : i::SEALED;
@@ -3949,7 +3994,7 @@ Maybe<bool> v8::Object::SetIntegrityLevel(Local<Context> context,
}
Maybe<bool> v8::Object::Delete(Local<Context> context, Local<Value> key) {
- PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::Delete()", bool);
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, Delete, bool);
auto self = Utils::OpenHandle(this);
auto key_obj = Utils::OpenHandle(*key);
Maybe<bool> result =
@@ -3973,7 +4018,7 @@ Maybe<bool> v8::Object::DeletePrivate(Local<Context> context,
Maybe<bool> v8::Object::Has(Local<Context> context, Local<Value> key) {
- PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::Get()", bool);
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, Get, bool);
auto self = Utils::OpenHandle(this);
auto key_obj = Utils::OpenHandle(*key);
Maybe<bool> maybe = Nothing<bool>();
@@ -4006,8 +4051,7 @@ Maybe<bool> v8::Object::HasPrivate(Local<Context> context, Local<Private> key) {
Maybe<bool> v8::Object::Delete(Local<Context> context, uint32_t index) {
- PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::DeleteProperty()",
- bool);
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, DeleteProperty, bool);
auto self = Utils::OpenHandle(this);
Maybe<bool> result = i::JSReceiver::DeleteElement(self, index);
has_pending_exception = result.IsNothing();
@@ -4023,7 +4067,7 @@ bool v8::Object::Delete(uint32_t index) {
Maybe<bool> v8::Object::Has(Local<Context> context, uint32_t index) {
- PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::Get()", bool);
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, Get, bool);
auto self = Utils::OpenHandle(this);
auto maybe = i::JSReceiver::HasElement(self, index);
has_pending_exception = maybe.IsNothing();
@@ -4044,7 +4088,7 @@ static Maybe<bool> ObjectSetAccessor(Local<Context> context, Object* self,
Setter setter, Data data,
AccessControl settings,
PropertyAttribute attributes) {
- PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::SetAccessor()", bool);
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, SetAccessor, bool);
if (!Utils::OpenHandle(self)->IsJSObject()) return Just(false);
i::Handle<i::JSObject> obj =
i::Handle<i::JSObject>::cast(Utils::OpenHandle(self));
@@ -4057,7 +4101,7 @@ static Maybe<bool> ObjectSetAccessor(Local<Context> context, Object* self,
has_pending_exception =
!i::JSObject::SetAccessor(obj, info).ToHandle(&result);
RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
- if (result->IsUndefined()) return Nothing<bool>();
+ if (result->IsUndefined(obj->GetIsolate())) return Nothing<bool>();
if (fast) {
i::JSObject::MigrateSlowToFast(obj, 0, "APISetAccessor");
}
@@ -4116,8 +4160,7 @@ void Object::SetAccessorProperty(Local<Name> name, Local<Function> getter,
Maybe<bool> v8::Object::HasOwnProperty(Local<Context> context,
Local<Name> key) {
- PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::HasOwnProperty()",
- bool);
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, HasOwnProperty, bool);
auto self = Utils::OpenHandle(this);
auto key_val = Utils::OpenHandle(*key);
auto result = i::JSReceiver::HasOwnProperty(self, key_val);
@@ -4126,6 +4169,14 @@ Maybe<bool> v8::Object::HasOwnProperty(Local<Context> context,
return result;
}
+Maybe<bool> v8::Object::HasOwnProperty(Local<Context> context, uint32_t index) {
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, HasOwnProperty, bool);
+ auto self = Utils::OpenHandle(this);
+ auto result = i::JSReceiver::HasOwnProperty(self, index);
+ has_pending_exception = result.IsNothing();
+ RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
+ return result;
+}
bool v8::Object::HasOwnProperty(Local<String> key) {
auto context = ContextFromHeapObject(Utils::OpenHandle(this));
@@ -4135,8 +4186,7 @@ bool v8::Object::HasOwnProperty(Local<String> key) {
Maybe<bool> v8::Object::HasRealNamedProperty(Local<Context> context,
Local<Name> key) {
- PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::HasRealNamedProperty()",
- bool);
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, HasRealNamedProperty, bool);
auto self = Utils::OpenHandle(this);
if (!self->IsJSObject()) return Just(false);
auto key_val = Utils::OpenHandle(*key);
@@ -4156,8 +4206,8 @@ bool v8::Object::HasRealNamedProperty(Local<String> key) {
Maybe<bool> v8::Object::HasRealIndexedProperty(Local<Context> context,
uint32_t index) {
- PREPARE_FOR_EXECUTION_PRIMITIVE(context,
- "v8::Object::HasRealIndexedProperty()", bool);
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, HasRealIndexedProperty,
+ bool);
auto self = Utils::OpenHandle(this);
if (!self->IsJSObject()) return Just(false);
auto result = i::JSObject::HasRealElementProperty(
@@ -4176,8 +4226,8 @@ bool v8::Object::HasRealIndexedProperty(uint32_t index) {
Maybe<bool> v8::Object::HasRealNamedCallbackProperty(Local<Context> context,
Local<Name> key) {
- PREPARE_FOR_EXECUTION_PRIMITIVE(
- context, "v8::Object::HasRealNamedCallbackProperty()", bool);
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, HasRealNamedCallbackProperty,
+ bool);
auto self = Utils::OpenHandle(this);
if (!self->IsJSObject()) return Just(false);
auto key_val = Utils::OpenHandle(*key);
@@ -4211,8 +4261,8 @@ bool v8::Object::HasIndexedLookupInterceptor() {
MaybeLocal<Value> v8::Object::GetRealNamedPropertyInPrototypeChain(
Local<Context> context, Local<Name> key) {
- PREPARE_FOR_EXECUTION(
- context, "v8::Object::GetRealNamedPropertyInPrototypeChain()", Value);
+ PREPARE_FOR_EXECUTION(context, Object, GetRealNamedPropertyInPrototypeChain,
+ Value);
i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
if (!self->IsJSObject()) return MaybeLocal<Value>();
i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
@@ -4243,7 +4293,7 @@ Maybe<PropertyAttribute>
v8::Object::GetRealNamedPropertyAttributesInPrototypeChain(
Local<Context> context, Local<Name> key) {
PREPARE_FOR_EXECUTION_PRIMITIVE(
- context, "v8::Object::GetRealNamedPropertyAttributesInPrototypeChain()",
+ context, Object, GetRealNamedPropertyAttributesInPrototypeChain,
PropertyAttribute);
i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
if (!self->IsJSObject()) return Nothing<PropertyAttribute>();
@@ -4273,7 +4323,7 @@ v8::Object::GetRealNamedPropertyAttributesInPrototypeChain(Local<String> key) {
MaybeLocal<Value> v8::Object::GetRealNamedProperty(Local<Context> context,
Local<Name> key) {
- PREPARE_FOR_EXECUTION(context, "v8::Object::GetRealNamedProperty()", Value);
+ PREPARE_FOR_EXECUTION(context, Object, GetRealNamedProperty, Value);
auto self = Utils::OpenHandle(this);
auto key_obj = Utils::OpenHandle(*key);
i::LookupIterator it = i::LookupIterator::PropertyOrElement(
@@ -4296,8 +4346,7 @@ Local<Value> v8::Object::GetRealNamedProperty(Local<String> key) {
Maybe<PropertyAttribute> v8::Object::GetRealNamedPropertyAttributes(
Local<Context> context, Local<Name> key) {
PREPARE_FOR_EXECUTION_PRIMITIVE(
- context, "v8::Object::GetRealNamedPropertyAttributes()",
- PropertyAttribute);
+ context, Object, GetRealNamedPropertyAttributes, PropertyAttribute);
auto self = Utils::OpenHandle(this);
auto key_obj = Utils::OpenHandle(*key);
i::LookupIterator it = i::LookupIterator::PropertyOrElement(
@@ -4342,60 +4391,7 @@ int v8::Object::GetIdentityHash() {
auto isolate = Utils::OpenHandle(this)->GetIsolate();
i::HandleScope scope(isolate);
auto self = Utils::OpenHandle(this);
- return i::JSReceiver::GetOrCreateIdentityHash(self)->value();
-}
-
-
-bool v8::Object::SetHiddenValue(v8::Local<v8::String> key,
- v8::Local<v8::Value> value) {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ENTER_V8(isolate);
- i::HandleScope scope(isolate);
- i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
- if (!self->IsJSObject()) return false;
- i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
- i::Handle<i::String> key_string =
- isolate->factory()->InternalizeString(key_obj);
- if (value.IsEmpty()) {
- i::JSObject::DeleteHiddenProperty(i::Handle<i::JSObject>::cast(self),
- key_string);
- return true;
- }
- i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
- i::Handle<i::Object> result = i::JSObject::SetHiddenProperty(
- i::Handle<i::JSObject>::cast(self), key_string, value_obj);
- return *result == *self;
-}
-
-
-v8::Local<v8::Value> v8::Object::GetHiddenValue(v8::Local<v8::String> key) {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ENTER_V8(isolate);
- i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
- if (!self->IsJSObject()) return v8::Local<v8::Value>();
- i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
- i::Handle<i::String> key_string =
- isolate->factory()->InternalizeString(key_obj);
- i::Handle<i::Object> result(
- i::Handle<i::JSObject>::cast(self)->GetHiddenProperty(key_string),
- isolate);
- if (result->IsTheHole()) return v8::Local<v8::Value>();
- return Utils::ToLocal(result);
-}
-
-
-bool v8::Object::DeleteHiddenValue(v8::Local<v8::String> key) {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ENTER_V8(isolate);
- i::HandleScope scope(isolate);
- i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
- if (!self->IsJSObject()) return false;
- i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
- i::Handle<i::String> key_string =
- isolate->factory()->InternalizeString(key_obj);
- i::JSObject::DeleteHiddenProperty(i::Handle<i::JSObject>::cast(self),
- key_string);
- return true;
+ return i::JSReceiver::GetOrCreateIdentityHash(isolate, self)->value();
}
@@ -4404,14 +4400,17 @@ bool v8::Object::IsCallable() {
return self->IsCallable();
}
+bool v8::Object::IsConstructor() {
+ auto self = Utils::OpenHandle(this);
+ return self->IsConstructor();
+}
MaybeLocal<Value> Object::CallAsFunction(Local<Context> context,
Local<Value> recv, int argc,
Local<Value> argv[]) {
- PREPARE_FOR_EXECUTION_WITH_CALLBACK(context, "v8::Object::CallAsFunction()",
- Value);
+ PREPARE_FOR_EXECUTION_WITH_CALLBACK(context, Object, CallAsFunction, Value);
i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
- TRACE_EVENT0("v8", "V8.Execute");
+ TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
auto self = Utils::OpenHandle(this);
auto recv_obj = Utils::OpenHandle(*recv);
STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Object**));
@@ -4435,10 +4434,10 @@ Local<v8::Value> Object::CallAsFunction(v8::Local<v8::Value> recv, int argc,
MaybeLocal<Value> Object::CallAsConstructor(Local<Context> context, int argc,
Local<Value> argv[]) {
- PREPARE_FOR_EXECUTION_WITH_CALLBACK(context,
- "v8::Object::CallAsConstructor()", Value);
+ PREPARE_FOR_EXECUTION_WITH_CALLBACK(context, Object, CallAsConstructor,
+ Value);
i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
- TRACE_EVENT0("v8", "V8.Execute");
+ TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
auto self = Utils::OpenHandle(this);
STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Object**));
i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
@@ -4457,28 +4456,23 @@ Local<v8::Value> Object::CallAsConstructor(int argc,
RETURN_TO_LOCAL_UNCHECKED(CallAsConstructor(context, argc, argv_cast), Value);
}
-
-MaybeLocal<Function> Function::New(Local<Context> context,
- FunctionCallback callback, Local<Value> data,
- int length) {
- return New(context, callback, data, length, ConstructorBehavior::kAllow);
-}
-
MaybeLocal<Function> Function::New(Local<Context> context,
FunctionCallback callback, Local<Value> data,
int length, ConstructorBehavior behavior) {
i::Isolate* isolate = Utils::OpenHandle(*context)->GetIsolate();
- LOG_API(isolate, "Function::New");
+ LOG_API(isolate, Function, New);
ENTER_V8(isolate);
- auto tmpl = FunctionTemplateNew(isolate, callback, nullptr, data,
- Local<Signature>(), length, true);
- if (behavior == ConstructorBehavior::kThrow) tmpl->RemovePrototype();
- return tmpl->GetFunction(context);
+ auto templ = FunctionTemplateNew(isolate, callback, nullptr, data,
+ Local<Signature>(), length, true);
+ if (behavior == ConstructorBehavior::kThrow) templ->RemovePrototype();
+ return templ->GetFunction(context);
}
+
Local<Function> Function::New(Isolate* v8_isolate, FunctionCallback callback,
Local<Value> data, int length) {
- return Function::New(v8_isolate->GetCurrentContext(), callback, data, length)
+ return Function::New(v8_isolate->GetCurrentContext(), callback, data, length,
+ ConstructorBehavior::kAllow)
.FromMaybe(Local<Function>());
}
@@ -4491,10 +4485,9 @@ Local<v8::Object> Function::NewInstance() const {
MaybeLocal<Object> Function::NewInstance(Local<Context> context, int argc,
v8::Local<v8::Value> argv[]) const {
- PREPARE_FOR_EXECUTION_WITH_CALLBACK(context, "v8::Function::NewInstance()",
- Object);
+ PREPARE_FOR_EXECUTION_WITH_CALLBACK(context, Function, NewInstance, Object);
i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
- TRACE_EVENT0("v8", "V8.Execute");
+ TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
auto self = Utils::OpenHandle(this);
STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Object**));
i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
@@ -4516,9 +4509,9 @@ Local<v8::Object> Function::NewInstance(int argc,
MaybeLocal<v8::Value> Function::Call(Local<Context> context,
v8::Local<v8::Value> recv, int argc,
v8::Local<v8::Value> argv[]) {
- PREPARE_FOR_EXECUTION_WITH_CALLBACK(context, "v8::Function::Call()", Value);
+ PREPARE_FOR_EXECUTION_WITH_CALLBACK(context, Function, Call, Value);
i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
- TRACE_EVENT0("v8", "V8.Execute");
+ TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
auto self = Utils::OpenHandle(this);
i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Object**));
@@ -4548,16 +4541,20 @@ void Function::SetName(v8::Local<v8::String> name) {
Local<Value> Function::GetName() const {
auto self = Utils::OpenHandle(this);
+ i::Isolate* isolate = self->GetIsolate();
if (self->IsJSBoundFunction()) {
auto func = i::Handle<i::JSBoundFunction>::cast(self);
- return Utils::ToLocal(handle(func->name(), func->GetIsolate()));
+ i::Handle<i::Object> name;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, name,
+ i::JSBoundFunction::GetName(isolate, func),
+ Local<Value>());
+ return Utils::ToLocal(name);
}
if (self->IsJSFunction()) {
auto func = i::Handle<i::JSFunction>::cast(self);
- return Utils::ToLocal(handle(func->shared()->name(), func->GetIsolate()));
+ return Utils::ToLocal(handle(func->shared()->name(), isolate));
}
- return ToApiHandle<Primitive>(
- self->GetIsolate()->factory()->undefined_value());
+ return ToApiHandle<Primitive>(isolate->factory()->undefined_value());
}
@@ -5224,10 +5221,10 @@ int String::WriteUtf8(char* buffer,
int capacity,
int* nchars_ref,
int options) const {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- LOG_API(isolate, "String::WriteUtf8");
- ENTER_V8(isolate);
i::Handle<i::String> str = Utils::OpenHandle(this);
+ i::Isolate* isolate = str->GetIsolate();
+ LOG_API(isolate, String, WriteUtf8);
+ ENTER_V8(isolate);
if (options & HINT_MANY_WRITES_EXPECTED) {
str = i::String::Flatten(str); // Flatten the string for efficiency.
}
@@ -5243,7 +5240,7 @@ int String::WriteUtf8(char* buffer,
if (success) return writer.CompleteWrite(write_null, nchars_ref);
} else if (capacity >= string_length) {
// First check that the buffer is large enough.
- int utf8_bytes = v8::Utf8Length(*str, str->GetIsolate());
+ int utf8_bytes = v8::Utf8Length(*str, isolate);
if (utf8_bytes <= capacity) {
// one-byte fast path.
if (utf8_bytes == string_length) {
@@ -5278,7 +5275,7 @@ static inline int WriteHelper(const String* string,
int length,
int options) {
i::Isolate* isolate = Utils::OpenHandle(string)->GetIsolate();
- LOG_API(isolate, "String::Write");
+ LOG_API(isolate, String, Write);
ENTER_V8(isolate);
DCHECK(start >= 0 && length >= -1);
i::Handle<i::String> str = Utils::OpenHandle(string);
@@ -5399,7 +5396,7 @@ double Number::Value() const {
bool Boolean::Value() const {
i::Handle<i::Object> obj = Utils::OpenHandle(this);
- return obj->IsTrue();
+ return obj->IsTrue(i::HeapObject::cast(*obj)->GetIsolate());
}
@@ -5477,7 +5474,6 @@ void* v8::Object::SlowGetAlignedPointerFromInternalField(int index) {
i::Handle<i::JSObject>::cast(obj)->GetInternalField(index), location);
}
-
void v8::Object::SetAlignedPointerInInternalField(int index, void* value) {
i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
const char* location = "v8::Object::SetAlignedPointerInInternalField()";
@@ -5487,10 +5483,31 @@ void v8::Object::SetAlignedPointerInInternalField(int index, void* value) {
DCHECK_EQ(value, GetAlignedPointerFromInternalField(index));
}
+void v8::Object::SetAlignedPointerInInternalFields(int argc, int indices[],
+ void* values[]) {
+ i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
+ const char* location = "v8::Object::SetAlignedPointerInInternalFields()";
+ i::DisallowHeapAllocation no_gc;
+ i::JSObject* object = i::JSObject::cast(*obj);
+ int nof_internal_fields = object->GetInternalFieldCount();
+ for (int i = 0; i < argc; i++) {
+ int index = indices[i];
+ if (!Utils::ApiCheck(index < nof_internal_fields, location,
+ "Internal field out of bounds")) {
+ return;
+ }
+ void* value = values[i];
+ object->SetInternalField(index, EncodeAlignedAsSmi(value, location));
+ DCHECK_EQ(value, GetAlignedPointerFromInternalField(index));
+ }
+}
static void* ExternalValue(i::Object* obj) {
// Obscure semantics for undefined, but somehow checked in our unit tests...
- if (obj->IsUndefined()) return NULL;
+ if (!obj->IsSmi() &&
+ obj->IsUndefined(i::HeapObject::cast(obj)->GetIsolate())) {
+ return NULL;
+ }
i::Object* foreign = i::JSObject::cast(obj)->GetInternalField(0);
return i::Foreign::cast(foreign)->foreign_address();
}
@@ -5544,6 +5561,8 @@ HeapStatistics::HeapStatistics()
total_available_size_(0),
used_heap_size_(0),
heap_size_limit_(0),
+ malloced_memory_(0),
+ peak_malloced_memory_(0),
does_zap_garbage_(0) {}
HeapSpaceStatistics::HeapSpaceStatistics(): space_name_(0),
@@ -5559,11 +5578,17 @@ HeapObjectStatistics::HeapObjectStatistics()
object_count_(0),
object_size_(0) {}
+HeapCodeStatistics::HeapCodeStatistics()
+ : code_and_metadata_size_(0), bytecode_and_metadata_size_(0) {}
bool v8::V8::InitializeICU(const char* icu_data_file) {
return i::InitializeICU(icu_data_file);
}
+bool v8::V8::InitializeICUDefaultLocation(const char* exec_path,
+ const char* icu_data_file) {
+ return i::InitializeICUDefaultLocation(exec_path, icu_data_file);
+}
void v8::V8::InitializeExternalStartupData(const char* directory_path) {
i::InitializeExternalStartupData(directory_path);
@@ -5580,21 +5605,51 @@ const char* v8::V8::GetVersion() {
return i::Version::GetVersion();
}
+template <typename ObjectType>
+struct InvokeBootstrapper;
-static i::Handle<i::Context> CreateEnvironment(
+template <>
+struct InvokeBootstrapper<i::Context> {
+ i::Handle<i::Context> Invoke(
+ i::Isolate* isolate, i::MaybeHandle<i::JSGlobalProxy> maybe_global_proxy,
+ v8::Local<v8::ObjectTemplate> global_object_template,
+ v8::ExtensionConfiguration* extensions, size_t context_snapshot_index) {
+ return isolate->bootstrapper()->CreateEnvironment(
+ maybe_global_proxy, global_object_template, extensions,
+ context_snapshot_index);
+ }
+};
+
+template <>
+struct InvokeBootstrapper<i::JSGlobalProxy> {
+ i::Handle<i::JSGlobalProxy> Invoke(
+ i::Isolate* isolate, i::MaybeHandle<i::JSGlobalProxy> maybe_global_proxy,
+ v8::Local<v8::ObjectTemplate> global_object_template,
+ v8::ExtensionConfiguration* extensions, size_t context_snapshot_index) {
+ USE(extensions);
+ USE(context_snapshot_index);
+ return isolate->bootstrapper()->NewRemoteContext(maybe_global_proxy,
+ global_object_template);
+ }
+};
+
+template <typename ObjectType>
+static i::Handle<ObjectType> CreateEnvironment(
i::Isolate* isolate, v8::ExtensionConfiguration* extensions,
- v8::Local<ObjectTemplate> global_template,
- v8::Local<Value> maybe_global_proxy) {
- i::Handle<i::Context> env;
+ v8::MaybeLocal<ObjectTemplate> maybe_global_template,
+ v8::MaybeLocal<Value> maybe_global_proxy, size_t context_snapshot_index) {
+ i::Handle<ObjectType> result;
// Enter V8 via an ENTER_V8 scope.
{
ENTER_V8(isolate);
- v8::Local<ObjectTemplate> proxy_template = global_template;
+ v8::Local<ObjectTemplate> proxy_template;
i::Handle<i::FunctionTemplateInfo> proxy_constructor;
i::Handle<i::FunctionTemplateInfo> global_constructor;
- if (!global_template.IsEmpty()) {
+ if (!maybe_global_template.IsEmpty()) {
+ v8::Local<v8::ObjectTemplate> global_template =
+ maybe_global_template.ToLocalChecked();
// Make sure that the global_template has a constructor.
global_constructor = EnsureConstructor(isolate, *global_template);
@@ -5611,7 +5666,7 @@ static i::Handle<i::Context> CreateEnvironment(
// Migrate security handlers from global_template to
// proxy_template. Temporarily removing access check
// information from the global template.
- if (!global_constructor->access_check_info()->IsUndefined()) {
+ if (!global_constructor->access_check_info()->IsUndefined(isolate)) {
proxy_constructor->set_access_check_info(
global_constructor->access_check_info());
proxy_constructor->set_needs_access_check(
@@ -5622,17 +5677,18 @@ static i::Handle<i::Context> CreateEnvironment(
}
}
- i::Handle<i::Object> proxy = Utils::OpenHandle(*maybe_global_proxy, true);
i::MaybeHandle<i::JSGlobalProxy> maybe_proxy;
- if (!proxy.is_null()) {
- maybe_proxy = i::Handle<i::JSGlobalProxy>::cast(proxy);
+ if (!maybe_global_proxy.IsEmpty()) {
+ maybe_proxy = i::Handle<i::JSGlobalProxy>::cast(
+ Utils::OpenHandle(*maybe_global_proxy.ToLocalChecked()));
}
// Create the environment.
- env = isolate->bootstrapper()->CreateEnvironment(
- maybe_proxy, proxy_template, extensions);
+ InvokeBootstrapper<ObjectType> invoke;
+ result = invoke.Invoke(isolate, maybe_proxy, proxy_template, extensions,
+ context_snapshot_index);
// Restore the access check info on the global template.
- if (!global_template.IsEmpty()) {
+ if (!maybe_global_template.IsEmpty()) {
DCHECK(!global_constructor.is_null());
DCHECK(!proxy_constructor.is_null());
global_constructor->set_access_check_info(
@@ -5643,20 +5699,23 @@ static i::Handle<i::Context> CreateEnvironment(
}
// Leave V8.
- return env;
+ return result;
}
-Local<Context> v8::Context::New(v8::Isolate* external_isolate,
- v8::ExtensionConfiguration* extensions,
- v8::Local<ObjectTemplate> global_template,
- v8::Local<Value> global_object) {
+Local<Context> NewContext(v8::Isolate* external_isolate,
+ v8::ExtensionConfiguration* extensions,
+ v8::MaybeLocal<ObjectTemplate> global_template,
+ v8::MaybeLocal<Value> global_object,
+ size_t context_snapshot_index) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
- LOG_API(isolate, "Context::New");
+ LOG_API(isolate, Context, New);
+ TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.NewContext");
i::HandleScope scope(isolate);
ExtensionConfiguration no_extensions;
if (extensions == NULL) extensions = &no_extensions;
i::Handle<i::Context> env =
- CreateEnvironment(isolate, extensions, global_template, global_object);
+ CreateEnvironment<i::Context>(isolate, extensions, global_template,
+ global_object, context_snapshot_index);
if (env.is_null()) {
if (isolate->has_pending_exception()) {
isolate->OptionalRescheduleException(true);
@@ -5666,6 +5725,57 @@ Local<Context> v8::Context::New(v8::Isolate* external_isolate,
return Utils::ToLocal(scope.CloseAndEscape(env));
}
+Local<Context> v8::Context::New(v8::Isolate* external_isolate,
+ v8::ExtensionConfiguration* extensions,
+ v8::MaybeLocal<ObjectTemplate> global_template,
+ v8::MaybeLocal<Value> global_object) {
+ return NewContext(external_isolate, extensions, global_template,
+ global_object, 0);
+}
+
+MaybeLocal<Context> v8::Context::FromSnapshot(
+ v8::Isolate* external_isolate, size_t context_snapshot_index,
+ v8::ExtensionConfiguration* extensions,
+ v8::MaybeLocal<ObjectTemplate> global_template,
+ v8::MaybeLocal<Value> global_object) {
+ if (!i::Snapshot::HasContextSnapshot(
+ reinterpret_cast<i::Isolate*>(external_isolate),
+ context_snapshot_index)) {
+ return MaybeLocal<Context>();
+ }
+ return NewContext(external_isolate, extensions, global_template,
+ global_object, context_snapshot_index);
+}
+
+MaybeLocal<Object> v8::Context::NewRemoteContext(
+ v8::Isolate* external_isolate, v8::Local<ObjectTemplate> global_template,
+ v8::MaybeLocal<v8::Value> global_object) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
+ LOG_API(isolate, Context, NewRemoteContext);
+ i::HandleScope scope(isolate);
+ i::Handle<i::FunctionTemplateInfo> global_constructor =
+ EnsureConstructor(isolate, *global_template);
+ Utils::ApiCheck(global_constructor->needs_access_check(),
+ "v8::Context::NewRemoteContext",
+ "Global template needs to have access checks enabled.");
+ i::Handle<i::AccessCheckInfo> access_check_info = i::handle(
+ i::AccessCheckInfo::cast(global_constructor->access_check_info()),
+ isolate);
+ Utils::ApiCheck(access_check_info->named_interceptor() != nullptr,
+ "v8::Context::NewRemoteContext",
+ "Global template needs to have access check handlers.");
+ i::Handle<i::JSGlobalProxy> global_proxy =
+ CreateEnvironment<i::JSGlobalProxy>(isolate, nullptr, global_template,
+ global_object, 0);
+ if (global_proxy.is_null()) {
+ if (isolate->has_pending_exception()) {
+ isolate->OptionalRescheduleException(true);
+ }
+ return MaybeLocal<Object>();
+ }
+ return Utils::ToLocal(
+ scope.CloseAndEscape(i::Handle<i::JSObject>::cast(global_proxy)));
+}
void v8::Context::SetSecurityToken(Local<Value> token) {
i::Handle<i::Context> env = Utils::OpenHandle(this);
@@ -5736,7 +5846,8 @@ void Context::AllowCodeGenerationFromStrings(bool allow) {
bool Context::IsCodeGenerationFromStringsAllowed() {
i::Handle<i::Context> context = Utils::OpenHandle(this);
- return !context->allow_code_gen_from_strings()->IsFalse();
+ return !context->allow_code_gen_from_strings()->IsFalse(
+ context->GetIsolate());
}
@@ -5754,7 +5865,7 @@ size_t Context::EstimatedSize() {
MaybeLocal<v8::Object> ObjectTemplate::NewInstance(Local<Context> context) {
- PREPARE_FOR_EXECUTION(context, "v8::ObjectTemplate::NewInstance()", Object);
+ PREPARE_FOR_EXECUTION(context, ObjectTemplate, NewInstance, Object);
auto self = Utils::OpenHandle(this);
Local<Object> result;
has_pending_exception =
@@ -5771,8 +5882,7 @@ Local<v8::Object> ObjectTemplate::NewInstance() {
MaybeLocal<v8::Function> FunctionTemplate::GetFunction(Local<Context> context) {
- PREPARE_FOR_EXECUTION(context, "v8::FunctionTemplate::GetFunction()",
- Function);
+ PREPARE_FOR_EXECUTION(context, FunctionTemplate, GetFunction, Function);
auto self = Utils::OpenHandle(this);
Local<Function> result;
has_pending_exception =
@@ -5787,18 +5897,44 @@ Local<v8::Function> FunctionTemplate::GetFunction() {
RETURN_TO_LOCAL_UNCHECKED(GetFunction(context), Function);
}
+MaybeLocal<v8::Object> FunctionTemplate::NewRemoteInstance() {
+ auto self = Utils::OpenHandle(this);
+ i::Isolate* isolate = self->GetIsolate();
+ LOG_API(isolate, FunctionTemplate, NewRemoteInstance);
+ i::HandleScope scope(isolate);
+ i::Handle<i::FunctionTemplateInfo> constructor =
+ EnsureConstructor(isolate, *InstanceTemplate());
+ Utils::ApiCheck(constructor->needs_access_check(),
+ "v8::FunctionTemplate::NewRemoteInstance",
+ "InstanceTemplate needs to have access checks enabled.");
+ i::Handle<i::AccessCheckInfo> access_check_info = i::handle(
+ i::AccessCheckInfo::cast(constructor->access_check_info()), isolate);
+ Utils::ApiCheck(access_check_info->named_interceptor() != nullptr,
+ "v8::FunctionTemplate::NewRemoteInstance",
+ "InstanceTemplate needs to have access check handlers.");
+ i::Handle<i::JSObject> object;
+ if (!i::ApiNatives::InstantiateRemoteObject(
+ Utils::OpenHandle(*InstanceTemplate()))
+ .ToHandle(&object)) {
+ if (isolate->has_pending_exception()) {
+ isolate->OptionalRescheduleException(true);
+ }
+ return MaybeLocal<Object>();
+ }
+ return Utils::ToLocal(scope.CloseAndEscape(object));
+}
bool FunctionTemplate::HasInstance(v8::Local<v8::Value> value) {
auto self = Utils::OpenHandle(this);
auto obj = Utils::OpenHandle(*value);
- return self->IsTemplateFor(*obj);
+ return obj->IsJSObject() && self->IsTemplateFor(i::JSObject::cast(*obj));
}
Local<External> v8::External::New(Isolate* isolate, void* value) {
STATIC_ASSERT(sizeof(value) == sizeof(i::Address));
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
- LOG_API(i_isolate, "External::New");
+ LOG_API(i_isolate, External, New);
ENTER_V8(i_isolate);
i::Handle<i::JSObject> external = i_isolate->factory()->NewExternal(value);
return Utils::ExternalToLocal(external);
@@ -5866,42 +6002,42 @@ inline i::MaybeHandle<i::String> NewString(i::Factory* factory,
STATIC_ASSERT(v8::String::kMaxLength == i::String::kMaxLength);
-
-template <typename Char>
-inline MaybeLocal<String> NewString(Isolate* v8_isolate, const char* location,
- const char* env, const Char* data,
- v8::NewStringType type, int length) {
- i::Isolate* isolate = reinterpret_cast<internal::Isolate*>(v8_isolate);
- if (length == 0) return String::Empty(v8_isolate);
- // TODO(dcarney): throw a context free exception.
- if (length > i::String::kMaxLength) return MaybeLocal<String>();
- ENTER_V8(isolate);
- LOG_API(isolate, env);
- if (length < 0) length = StringLength(data);
- i::Handle<i::String> result =
- NewString(isolate->factory(), type, i::Vector<const Char>(data, length))
- .ToHandleChecked();
- return Utils::ToLocal(result);
-}
-
} // anonymous namespace
+// TODO(dcarney): throw a context free exception.
+#define NEW_STRING(isolate, class_name, function_name, Char, data, type, \
+ length) \
+ MaybeLocal<String> result; \
+ if (length == 0) { \
+ result = String::Empty(isolate); \
+ } else if (length > i::String::kMaxLength) { \
+ result = MaybeLocal<String>(); \
+ } else { \
+ i::Isolate* i_isolate = reinterpret_cast<internal::Isolate*>(isolate); \
+ ENTER_V8(i_isolate); \
+ LOG_API(i_isolate, class_name, function_name); \
+ if (length < 0) length = StringLength(data); \
+ i::Handle<i::String> handle_result = \
+ NewString(i_isolate->factory(), type, \
+ i::Vector<const Char>(data, length)) \
+ .ToHandleChecked(); \
+ result = Utils::ToLocal(handle_result); \
+ }
Local<String> String::NewFromUtf8(Isolate* isolate,
const char* data,
NewStringType type,
int length) {
- RETURN_TO_LOCAL_UNCHECKED(
- NewString(isolate, "v8::String::NewFromUtf8()", "String::NewFromUtf8",
- data, static_cast<v8::NewStringType>(type), length),
- String);
+ NEW_STRING(isolate, String, NewFromUtf8, char, data,
+ static_cast<v8::NewStringType>(type), length);
+ RETURN_TO_LOCAL_UNCHECKED(result, String);
}
MaybeLocal<String> String::NewFromUtf8(Isolate* isolate, const char* data,
v8::NewStringType type, int length) {
- return NewString(isolate, "v8::String::NewFromUtf8()", "String::NewFromUtf8",
- data, type, length);
+ NEW_STRING(isolate, String, NewFromUtf8, char, data, type, length);
+ return result;
}
@@ -5909,18 +6045,16 @@ Local<String> String::NewFromOneByte(Isolate* isolate,
const uint8_t* data,
NewStringType type,
int length) {
- RETURN_TO_LOCAL_UNCHECKED(
- NewString(isolate, "v8::String::NewFromOneByte()",
- "String::NewFromOneByte", data,
- static_cast<v8::NewStringType>(type), length),
- String);
+ NEW_STRING(isolate, String, NewFromOneByte, uint8_t, data,
+ static_cast<v8::NewStringType>(type), length);
+ RETURN_TO_LOCAL_UNCHECKED(result, String);
}
MaybeLocal<String> String::NewFromOneByte(Isolate* isolate, const uint8_t* data,
v8::NewStringType type, int length) {
- return NewString(isolate, "v8::String::NewFromOneByte()",
- "String::NewFromOneByte", data, type, length);
+ NEW_STRING(isolate, String, NewFromOneByte, uint8_t, data, type, length);
+ return result;
}
@@ -5928,19 +6062,17 @@ Local<String> String::NewFromTwoByte(Isolate* isolate,
const uint16_t* data,
NewStringType type,
int length) {
- RETURN_TO_LOCAL_UNCHECKED(
- NewString(isolate, "v8::String::NewFromTwoByte()",
- "String::NewFromTwoByte", data,
- static_cast<v8::NewStringType>(type), length),
- String);
+ NEW_STRING(isolate, String, NewFromTwoByte, uint16_t, data,
+ static_cast<v8::NewStringType>(type), length);
+ RETURN_TO_LOCAL_UNCHECKED(result, String);
}
MaybeLocal<String> String::NewFromTwoByte(Isolate* isolate,
const uint16_t* data,
v8::NewStringType type, int length) {
- return NewString(isolate, "v8::String::NewFromTwoByte()",
- "String::NewFromTwoByte", data, type, length);
+ NEW_STRING(isolate, String, NewFromTwoByte, uint16_t, data, type, length);
+ return result;
}
@@ -5948,7 +6080,7 @@ Local<String> v8::String::Concat(Local<String> left, Local<String> right) {
i::Handle<i::String> left_string = Utils::OpenHandle(*left);
i::Isolate* isolate = left_string->GetIsolate();
ENTER_V8(isolate);
- LOG_API(isolate, "v8::String::Concat");
+ LOG_API(isolate, String, Concat);
i::Handle<i::String> right_string = Utils::OpenHandle(*right);
// If we are steering towards a range error, do not wait for the error to be
// thrown, and return the null handle instead.
@@ -5970,7 +6102,7 @@ MaybeLocal<String> v8::String::NewExternalTwoByte(
}
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
ENTER_V8(i_isolate);
- LOG_API(i_isolate, "String::NewExternalTwoByte");
+ LOG_API(i_isolate, String, NewExternalTwoByte);
i::Handle<i::String> string = i_isolate->factory()
->NewExternalStringFromTwoByte(resource)
.ToHandleChecked();
@@ -5994,7 +6126,7 @@ MaybeLocal<String> v8::String::NewExternalOneByte(
}
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
ENTER_V8(i_isolate);
- LOG_API(i_isolate, "String::NewExternalOneByte");
+ LOG_API(i_isolate, String, NewExternalOneByte);
i::Handle<i::String> string = i_isolate->factory()
->NewExternalStringFromOneByte(resource)
.ToHandleChecked();
@@ -6058,14 +6190,11 @@ bool v8::String::MakeExternal(
bool v8::String::CanMakeExternal() {
i::Handle<i::String> obj = Utils::OpenHandle(this);
- i::Isolate* isolate = obj->GetIsolate();
+ if (obj->IsExternalString()) return false;
// Old space strings should be externalized.
- if (!isolate->heap()->new_space()->Contains(*obj)) return true;
- int size = obj->Size(); // Byte size of the original string.
- if (size <= i::ExternalString::kShortSize) return false;
- i::StringShape shape(*obj);
- return !shape.IsExternal();
+ i::Isolate* isolate = obj->GetIsolate();
+ return !isolate->heap()->new_space()->Contains(*obj);
}
@@ -6077,7 +6206,7 @@ Isolate* v8::Object::GetIsolate() {
Local<v8::Object> v8::Object::New(Isolate* isolate) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
- LOG_API(i_isolate, "Object::New");
+ LOG_API(i_isolate, Object, New);
ENTER_V8(i_isolate);
i::Handle<i::JSObject> obj =
i_isolate->factory()->NewJSObject(i_isolate->object_function());
@@ -6087,7 +6216,7 @@ Local<v8::Object> v8::Object::New(Isolate* isolate) {
Local<v8::Value> v8::NumberObject::New(Isolate* isolate, double value) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
- LOG_API(i_isolate, "NumberObject::New");
+ LOG_API(i_isolate, NumberObject, New);
ENTER_V8(i_isolate);
i::Handle<i::Object> number = i_isolate->factory()->NewNumber(value);
i::Handle<i::Object> obj =
@@ -6100,14 +6229,14 @@ double v8::NumberObject::ValueOf() const {
i::Handle<i::Object> obj = Utils::OpenHandle(this);
i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
i::Isolate* isolate = jsvalue->GetIsolate();
- LOG_API(isolate, "NumberObject::NumberValue");
+ LOG_API(isolate, NumberObject, NumberValue);
return jsvalue->value()->Number();
}
Local<v8::Value> v8::BooleanObject::New(Isolate* isolate, bool value) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
- LOG_API(i_isolate, "BooleanObject::New");
+ LOG_API(i_isolate, BooleanObject, New);
ENTER_V8(i_isolate);
i::Handle<i::Object> boolean(value ? i_isolate->heap()->true_value()
: i_isolate->heap()->false_value(),
@@ -6127,15 +6256,15 @@ bool v8::BooleanObject::ValueOf() const {
i::Handle<i::Object> obj = Utils::OpenHandle(this);
i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
i::Isolate* isolate = jsvalue->GetIsolate();
- LOG_API(isolate, "BooleanObject::BooleanValue");
- return jsvalue->value()->IsTrue();
+ LOG_API(isolate, BooleanObject, BooleanValue);
+ return jsvalue->value()->IsTrue(isolate);
}
Local<v8::Value> v8::StringObject::New(Local<String> value) {
i::Handle<i::String> string = Utils::OpenHandle(*value);
i::Isolate* isolate = string->GetIsolate();
- LOG_API(isolate, "StringObject::New");
+ LOG_API(isolate, StringObject, New);
ENTER_V8(isolate);
i::Handle<i::Object> obj =
i::Object::ToObject(isolate, string).ToHandleChecked();
@@ -6147,7 +6276,7 @@ Local<v8::String> v8::StringObject::ValueOf() const {
i::Handle<i::Object> obj = Utils::OpenHandle(this);
i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
i::Isolate* isolate = jsvalue->GetIsolate();
- LOG_API(isolate, "StringObject::StringValue");
+ LOG_API(isolate, StringObject, StringValue);
return Utils::ToLocal(
i::Handle<i::String>(i::String::cast(jsvalue->value())));
}
@@ -6155,7 +6284,7 @@ Local<v8::String> v8::StringObject::ValueOf() const {
Local<v8::Value> v8::SymbolObject::New(Isolate* isolate, Local<Symbol> value) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
- LOG_API(i_isolate, "SymbolObject::New");
+ LOG_API(i_isolate, SymbolObject, New);
ENTER_V8(i_isolate);
i::Handle<i::Object> obj = i::Object::ToObject(
i_isolate, Utils::OpenHandle(*value)).ToHandleChecked();
@@ -6167,7 +6296,7 @@ Local<v8::Symbol> v8::SymbolObject::ValueOf() const {
i::Handle<i::Object> obj = Utils::OpenHandle(this);
i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
i::Isolate* isolate = jsvalue->GetIsolate();
- LOG_API(isolate, "SymbolObject::SymbolValue");
+ LOG_API(isolate, SymbolObject, SymbolValue);
return Utils::ToLocal(
i::Handle<i::Symbol>(i::Symbol::cast(jsvalue->value())));
}
@@ -6178,7 +6307,7 @@ MaybeLocal<v8::Value> v8::Date::New(Local<Context> context, double time) {
// Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
time = std::numeric_limits<double>::quiet_NaN();
}
- PREPARE_FOR_EXECUTION(context, "Date::New", Value);
+ PREPARE_FOR_EXECUTION(context, Date, New, Value);
Local<Value> result;
has_pending_exception = !ToLocal<Value>(
i::JSDate::New(isolate->date_function(), isolate->date_function(), time),
@@ -6198,14 +6327,14 @@ double v8::Date::ValueOf() const {
i::Handle<i::Object> obj = Utils::OpenHandle(this);
i::Handle<i::JSDate> jsdate = i::Handle<i::JSDate>::cast(obj);
i::Isolate* isolate = jsdate->GetIsolate();
- LOG_API(isolate, "Date::NumberValue");
+ LOG_API(isolate, Date, NumberValue);
return jsdate->value()->Number();
}
void v8::Date::DateTimeConfigurationChangeNotification(Isolate* isolate) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
- LOG_API(i_isolate, "Date::DateTimeConfigurationChangeNotification");
+ LOG_API(i_isolate, Date, DateTimeConfigurationChangeNotification);
ENTER_V8(i_isolate);
i_isolate->date_cache()->ResetDateCache();
if (!i_isolate->eternal_handles()->Exists(
@@ -6225,7 +6354,7 @@ void v8::Date::DateTimeConfigurationChangeNotification(Isolate* isolate) {
MaybeLocal<v8::RegExp> v8::RegExp::New(Local<Context> context,
Local<String> pattern, Flags flags) {
- PREPARE_FOR_EXECUTION(context, "RegExp::New", RegExp);
+ PREPARE_FOR_EXECUTION(context, RegExp, New, RegExp);
Local<v8::RegExp> result;
has_pending_exception =
!ToLocal<RegExp>(i::JSRegExp::New(Utils::OpenHandle(*pattern),
@@ -6270,7 +6399,7 @@ v8::RegExp::Flags v8::RegExp::GetFlags() const {
Local<v8::Array> v8::Array::New(Isolate* isolate, int length) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
- LOG_API(i_isolate, "Array::New");
+ LOG_API(i_isolate, Array, New);
ENTER_V8(i_isolate);
int real_length = length > 0 ? length : 0;
i::Handle<i::JSArray> obj = i_isolate->factory()->NewJSArray(real_length);
@@ -6294,7 +6423,7 @@ uint32_t v8::Array::Length() const {
MaybeLocal<Object> Array::CloneElementAt(Local<Context> context,
uint32_t index) {
- PREPARE_FOR_EXECUTION(context, "v8::Array::CloneElementAt()", Object);
+ PREPARE_FOR_EXECUTION(context, Array, CloneElementAt, Object);
auto self = Utils::OpenHandle(this);
if (!self->HasFastObjectElements()) return Local<Object>();
i::FixedArray* elms = i::FixedArray::cast(self->elements());
@@ -6315,7 +6444,7 @@ Local<Object> Array::CloneElementAt(uint32_t index) { return Local<Object>(); }
Local<v8::Map> v8::Map::New(Isolate* isolate) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
- LOG_API(i_isolate, "Map::New");
+ LOG_API(i_isolate, Map, New);
ENTER_V8(i_isolate);
i::Handle<i::JSMap> obj = i_isolate->factory()->NewJSMap();
return Utils::ToLocal(obj);
@@ -6331,14 +6460,14 @@ size_t v8::Map::Size() const {
void Map::Clear() {
auto self = Utils::OpenHandle(this);
i::Isolate* isolate = self->GetIsolate();
- LOG_API(isolate, "Map::Clear");
+ LOG_API(isolate, Map, Clear);
ENTER_V8(isolate);
i::JSMap::Clear(self);
}
MaybeLocal<Value> Map::Get(Local<Context> context, Local<Value> key) {
- PREPARE_FOR_EXECUTION(context, "Map::Get", Value);
+ PREPARE_FOR_EXECUTION(context, Map, Get, Value);
auto self = Utils::OpenHandle(this);
Local<Value> result;
i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
@@ -6353,7 +6482,7 @@ MaybeLocal<Value> Map::Get(Local<Context> context, Local<Value> key) {
MaybeLocal<Map> Map::Set(Local<Context> context, Local<Value> key,
Local<Value> value) {
- PREPARE_FOR_EXECUTION(context, "Map::Set", Map);
+ PREPARE_FOR_EXECUTION(context, Map, Set, Map);
auto self = Utils::OpenHandle(this);
i::Handle<i::Object> result;
i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key),
@@ -6367,7 +6496,7 @@ MaybeLocal<Map> Map::Set(Local<Context> context, Local<Value> key,
Maybe<bool> Map::Has(Local<Context> context, Local<Value> key) {
- PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Map::Has", bool);
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, Map, Has, bool);
auto self = Utils::OpenHandle(this);
i::Handle<i::Object> result;
i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
@@ -6375,12 +6504,12 @@ Maybe<bool> Map::Has(Local<Context> context, Local<Value> key) {
arraysize(argv), argv)
.ToHandle(&result);
RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
- return Just(result->IsTrue());
+ return Just(result->IsTrue(isolate));
}
Maybe<bool> Map::Delete(Local<Context> context, Local<Value> key) {
- PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Map::Delete", bool);
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, Map, Delete, bool);
auto self = Utils::OpenHandle(this);
i::Handle<i::Object> result;
i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
@@ -6388,7 +6517,7 @@ Maybe<bool> Map::Delete(Local<Context> context, Local<Value> key) {
self, arraysize(argv), argv)
.ToHandle(&result);
RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
- return Just(result->IsTrue());
+ return Just(result->IsTrue(isolate));
}
@@ -6396,17 +6525,25 @@ Local<Array> Map::AsArray() const {
i::Handle<i::JSMap> obj = Utils::OpenHandle(this);
i::Isolate* isolate = obj->GetIsolate();
i::Factory* factory = isolate->factory();
- LOG_API(isolate, "Map::AsArray");
+ LOG_API(isolate, Map, AsArray);
ENTER_V8(isolate);
i::Handle<i::OrderedHashMap> table(i::OrderedHashMap::cast(obj->table()));
- int size = table->NumberOfElements();
- int length = size * 2;
+ int length = table->NumberOfElements() * 2;
i::Handle<i::FixedArray> result = factory->NewFixedArray(length);
- for (int i = 0; i < size; ++i) {
- if (table->KeyAt(i)->IsTheHole()) continue;
- result->set(i * 2, table->KeyAt(i));
- result->set(i * 2 + 1, table->ValueAt(i));
+ int result_index = 0;
+ {
+ i::DisallowHeapAllocation no_gc;
+ int capacity = table->UsedCapacity();
+ i::Oddball* the_hole = isolate->heap()->the_hole_value();
+ for (int i = 0; i < capacity; ++i) {
+ i::Object* key = table->KeyAt(i);
+ if (key == the_hole) continue;
+ result->set(result_index++, key);
+ result->set(result_index++, table->ValueAt(i));
+ }
}
+ DCHECK_EQ(result_index, result->length());
+ DCHECK_EQ(result_index, length);
i::Handle<i::JSArray> result_array =
factory->NewJSArrayWithElements(result, i::FAST_ELEMENTS, length);
return Utils::ToLocal(result_array);
@@ -6415,7 +6552,7 @@ Local<Array> Map::AsArray() const {
Local<v8::Set> v8::Set::New(Isolate* isolate) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
- LOG_API(i_isolate, "Set::New");
+ LOG_API(i_isolate, Set, New);
ENTER_V8(i_isolate);
i::Handle<i::JSSet> obj = i_isolate->factory()->NewJSSet();
return Utils::ToLocal(obj);
@@ -6431,14 +6568,14 @@ size_t v8::Set::Size() const {
void Set::Clear() {
auto self = Utils::OpenHandle(this);
i::Isolate* isolate = self->GetIsolate();
- LOG_API(isolate, "Set::Clear");
+ LOG_API(isolate, Set, Clear);
ENTER_V8(isolate);
i::JSSet::Clear(self);
}
MaybeLocal<Set> Set::Add(Local<Context> context, Local<Value> key) {
- PREPARE_FOR_EXECUTION(context, "Set::Add", Set);
+ PREPARE_FOR_EXECUTION(context, Set, Add, Set);
auto self = Utils::OpenHandle(this);
i::Handle<i::Object> result;
i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
@@ -6451,7 +6588,7 @@ MaybeLocal<Set> Set::Add(Local<Context> context, Local<Value> key) {
Maybe<bool> Set::Has(Local<Context> context, Local<Value> key) {
- PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Set::Has", bool);
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, Set, Has, bool);
auto self = Utils::OpenHandle(this);
i::Handle<i::Object> result;
i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
@@ -6459,12 +6596,12 @@ Maybe<bool> Set::Has(Local<Context> context, Local<Value> key) {
arraysize(argv), argv)
.ToHandle(&result);
RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
- return Just(result->IsTrue());
+ return Just(result->IsTrue(isolate));
}
Maybe<bool> Set::Delete(Local<Context> context, Local<Value> key) {
- PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Set::Delete", bool);
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, Set, Delete, bool);
auto self = Utils::OpenHandle(this);
i::Handle<i::Object> result;
i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
@@ -6472,7 +6609,7 @@ Maybe<bool> Set::Delete(Local<Context> context, Local<Value> key) {
self, arraysize(argv), argv)
.ToHandle(&result);
RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
- return Just(result->IsTrue());
+ return Just(result->IsTrue(isolate));
}
@@ -6480,17 +6617,24 @@ Local<Array> Set::AsArray() const {
i::Handle<i::JSSet> obj = Utils::OpenHandle(this);
i::Isolate* isolate = obj->GetIsolate();
i::Factory* factory = isolate->factory();
- LOG_API(isolate, "Set::AsArray");
+ LOG_API(isolate, Set, AsArray);
ENTER_V8(isolate);
i::Handle<i::OrderedHashSet> table(i::OrderedHashSet::cast(obj->table()));
int length = table->NumberOfElements();
i::Handle<i::FixedArray> result = factory->NewFixedArray(length);
- for (int i = 0; i < length; ++i) {
- i::Object* key = table->KeyAt(i);
- if (!key->IsTheHole()) {
- result->set(i, key);
+ int result_index = 0;
+ {
+ i::DisallowHeapAllocation no_gc;
+ int capacity = table->UsedCapacity();
+ i::Oddball* the_hole = isolate->heap()->the_hole_value();
+ for (int i = 0; i < capacity; ++i) {
+ i::Object* key = table->KeyAt(i);
+ if (key == the_hole) continue;
+ result->set(result_index++, key);
}
}
+ DCHECK_EQ(result_index, result->length());
+ DCHECK_EQ(result_index, length);
i::Handle<i::JSArray> result_array =
factory->NewJSArrayWithElements(result, i::FAST_ELEMENTS, length);
return Utils::ToLocal(result_array);
@@ -6498,7 +6642,7 @@ Local<Array> Set::AsArray() const {
MaybeLocal<Promise::Resolver> Promise::Resolver::New(Local<Context> context) {
- PREPARE_FOR_EXECUTION(context, "Promise::Resolver::New", Resolver);
+ PREPARE_FOR_EXECUTION(context, Promise_Resolver, New, Resolver);
i::Handle<i::Object> result;
has_pending_exception =
!i::Execution::Call(isolate, isolate->promise_create(),
@@ -6523,7 +6667,7 @@ Local<Promise> Promise::Resolver::GetPromise() {
Maybe<bool> Promise::Resolver::Resolve(Local<Context> context,
Local<Value> value) {
- PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Promise::Resolver::Resolve", bool);
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, Promise_Resolver, Resolve, bool);
auto self = Utils::OpenHandle(this);
i::Handle<i::Object> argv[] = {self, Utils::OpenHandle(*value)};
has_pending_exception =
@@ -6544,7 +6688,7 @@ void Promise::Resolver::Resolve(Local<Value> value) {
Maybe<bool> Promise::Resolver::Reject(Local<Context> context,
Local<Value> value) {
- PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Promise::Resolver::Resolve", bool);
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, Promise_Resolver, Resolve, bool);
auto self = Utils::OpenHandle(this);
i::Handle<i::Object> argv[] = {self, Utils::OpenHandle(*value)};
has_pending_exception =
@@ -6563,39 +6707,9 @@ void Promise::Resolver::Reject(Local<Value> value) {
}
-namespace {
-
-MaybeLocal<Promise> DoChain(Value* value, Local<Context> context,
- Local<Function> handler) {
- PREPARE_FOR_EXECUTION(context, "Promise::Chain", Promise);
- auto self = Utils::OpenHandle(value);
- i::Handle<i::Object> argv[] = {Utils::OpenHandle(*handler)};
- i::Handle<i::Object> result;
- has_pending_exception = !i::Execution::Call(isolate, isolate->promise_chain(),
- self, arraysize(argv), argv)
- .ToHandle(&result);
- RETURN_ON_FAILED_EXECUTION(Promise);
- RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
-}
-
-} // namespace
-
-
-MaybeLocal<Promise> Promise::Chain(Local<Context> context,
- Local<Function> handler) {
- return DoChain(this, context, handler);
-}
-
-
-Local<Promise> Promise::Chain(Local<Function> handler) {
- auto context = ContextFromHeapObject(Utils::OpenHandle(this));
- RETURN_TO_LOCAL_UNCHECKED(DoChain(this, context, handler), Promise);
-}
-
-
MaybeLocal<Promise> Promise::Catch(Local<Context> context,
Local<Function> handler) {
- PREPARE_FOR_EXECUTION(context, "Promise::Catch", Promise);
+ PREPARE_FOR_EXECUTION(context, Promise, Catch, Promise);
auto self = Utils::OpenHandle(this);
i::Handle<i::Object> argv[] = { Utils::OpenHandle(*handler) };
i::Handle<i::Object> result;
@@ -6615,7 +6729,7 @@ Local<Promise> Promise::Catch(Local<Function> handler) {
MaybeLocal<Promise> Promise::Then(Local<Context> context,
Local<Function> handler) {
- PREPARE_FOR_EXECUTION(context, "Promise::Then", Promise);
+ PREPARE_FOR_EXECUTION(context, Promise, Then, Promise);
auto self = Utils::OpenHandle(this);
i::Handle<i::Object> argv[] = { Utils::OpenHandle(*handler) };
i::Handle<i::Object> result;
@@ -6636,10 +6750,10 @@ Local<Promise> Promise::Then(Local<Function> handler) {
bool Promise::HasHandler() {
i::Handle<i::JSReceiver> promise = Utils::OpenHandle(this);
i::Isolate* isolate = promise->GetIsolate();
- LOG_API(isolate, "Promise::HasRejectHandler");
+ LOG_API(isolate, Promise, HasRejectHandler);
ENTER_V8(isolate);
i::Handle<i::Symbol> key = isolate->factory()->promise_has_handler_symbol();
- return i::JSReceiver::GetDataProperty(promise, key)->IsTrue();
+ return i::JSReceiver::GetDataProperty(promise, key)->IsTrue(isolate);
}
@@ -6671,7 +6785,7 @@ void Proxy::Revoke() {
MaybeLocal<Proxy> Proxy::New(Local<Context> context, Local<Object> local_target,
Local<Object> local_handler) {
- PREPARE_FOR_EXECUTION(context, "Proxy::New", Proxy);
+ PREPARE_FOR_EXECUTION(context, Proxy, New, Proxy);
i::Handle<i::JSReceiver> target = Utils::OpenHandle(*local_target);
i::Handle<i::JSReceiver> handler = Utils::OpenHandle(*local_handler);
Local<Proxy> result;
@@ -6681,6 +6795,40 @@ MaybeLocal<Proxy> Proxy::New(Local<Context> context, Local<Object> local_target,
RETURN_ESCAPED(result);
}
+WasmCompiledModule::SerializedModule WasmCompiledModule::Serialize() {
+ i::Handle<i::JSObject> obj =
+ i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
+ i::Handle<i::FixedArray> compiled_part =
+ i::handle(i::FixedArray::cast(obj->GetInternalField(0)));
+ std::unique_ptr<i::ScriptData> script_data =
+ i::WasmCompiledModuleSerializer::SerializeWasmModule(obj->GetIsolate(),
+ compiled_part);
+ script_data->ReleaseDataOwnership();
+ size_t size = static_cast<size_t>(script_data->length());
+ return {std::unique_ptr<const uint8_t[]>(script_data->data()), size};
+}
+
+MaybeLocal<WasmCompiledModule> WasmCompiledModule::Deserialize(
+ Isolate* isolate,
+ const WasmCompiledModule::SerializedModule& serialized_data) {
+ int size = static_cast<int>(serialized_data.second);
+ i::ScriptData sc(serialized_data.first.get(), size);
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ i::MaybeHandle<i::FixedArray> maybe_compiled_part =
+ i::WasmCompiledModuleSerializer::DeserializeWasmModule(i_isolate, &sc);
+ i::Handle<i::FixedArray> compiled_part;
+ if (!maybe_compiled_part.ToHandle(&compiled_part)) {
+ return MaybeLocal<WasmCompiledModule>();
+ }
+ return Local<WasmCompiledModule>::Cast(Utils::ToLocal(
+ i::wasm::CreateCompiledModuleObject(i_isolate, compiled_part)));
+}
+
+// static
+v8::ArrayBuffer::Allocator* v8::ArrayBuffer::Allocator::NewDefaultAllocator() {
+ return new ArrayBufferAllocator();
+}
+
bool v8::ArrayBuffer::IsExternal() const {
return Utils::OpenHandle(this)->is_external();
}
@@ -6694,7 +6842,7 @@ bool v8::ArrayBuffer::IsNeuterable() const {
v8::ArrayBuffer::Contents v8::ArrayBuffer::Externalize() {
i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
i::Isolate* isolate = self->GetIsolate();
- Utils::ApiCheck(!self->is_external(), "v8::ArrayBuffer::Externalize",
+ Utils::ApiCheck(!self->is_external(), "v8_ArrayBuffer_Externalize",
"ArrayBuffer already externalized");
self->set_is_external(true);
isolate->heap()->UnregisterArrayBuffer(*self);
@@ -6721,7 +6869,7 @@ void 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()");
+ LOG_API(isolate, ArrayBuffer, Neuter);
ENTER_V8(isolate);
obj->Neuter();
}
@@ -6735,7 +6883,7 @@ size_t v8::ArrayBuffer::ByteLength() const {
Local<ArrayBuffer> v8::ArrayBuffer::New(Isolate* isolate, size_t byte_length) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
- LOG_API(i_isolate, "v8::ArrayBuffer::New(size_t)");
+ LOG_API(i_isolate, ArrayBuffer, New);
ENTER_V8(i_isolate);
i::Handle<i::JSArrayBuffer> obj =
i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kNotShared);
@@ -6750,7 +6898,7 @@ Local<ArrayBuffer> v8::ArrayBuffer::New(Isolate* isolate, void* data,
// Embedders must guarantee that the external backing store is valid.
CHECK(byte_length == 0 || data != NULL);
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
- LOG_API(i_isolate, "v8::ArrayBuffer::New(void*, size_t)");
+ LOG_API(i_isolate, ArrayBuffer, New);
ENTER_V8(i_isolate);
i::Handle<i::JSArrayBuffer> obj =
i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kNotShared);
@@ -6778,10 +6926,9 @@ Local<ArrayBuffer> v8::ArrayBufferView::Buffer() {
size_t v8::ArrayBufferView::CopyContents(void* dest, size_t byte_length) {
i::Handle<i::JSArrayBufferView> self = Utils::OpenHandle(this);
- i::Isolate* isolate = self->GetIsolate();
- size_t byte_offset = i::NumberToSize(isolate, self->byte_offset());
+ size_t byte_offset = i::NumberToSize(self->byte_offset());
size_t bytes_to_copy =
- i::Min(byte_length, i::NumberToSize(isolate, self->byte_length()));
+ i::Min(byte_length, i::NumberToSize(self->byte_length()));
if (bytes_to_copy) {
i::DisallowHeapAllocation no_gc;
i::Handle<i::JSArrayBuffer> buffer(i::JSArrayBuffer::cast(self->buffer()));
@@ -6823,49 +6970,45 @@ size_t v8::TypedArray::Length() {
return static_cast<size_t>(obj->length_value());
}
-
-#define TYPED_ARRAY_NEW(Type, type, TYPE, ctype, size) \
- Local<Type##Array> Type##Array::New(Local<ArrayBuffer> array_buffer, \
- size_t byte_offset, size_t length) { \
- i::Isolate* isolate = Utils::OpenHandle(*array_buffer)->GetIsolate(); \
- LOG_API(isolate, \
- "v8::" #Type "Array::New(Local<ArrayBuffer>, size_t, size_t)"); \
- ENTER_V8(isolate); \
- if (!Utils::ApiCheck(length <= static_cast<size_t>(i::Smi::kMaxValue), \
- "v8::" #Type \
- "Array::New(Local<ArrayBuffer>, size_t, size_t)", \
- "length exceeds max allowed value")) { \
- return Local<Type##Array>(); \
- } \
- i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer); \
- i::Handle<i::JSTypedArray> obj = isolate->factory()->NewJSTypedArray( \
- i::kExternal##Type##Array, buffer, byte_offset, length); \
- return Utils::ToLocal##Type##Array(obj); \
- } \
- Local<Type##Array> Type##Array::New( \
- Local<SharedArrayBuffer> shared_array_buffer, size_t byte_offset, \
- size_t length) { \
- CHECK(i::FLAG_harmony_sharedarraybuffer); \
- i::Isolate* isolate = \
- Utils::OpenHandle(*shared_array_buffer)->GetIsolate(); \
- LOG_API(isolate, "v8::" #Type \
- "Array::New(Local<SharedArrayBuffer>, size_t, size_t)"); \
- ENTER_V8(isolate); \
- if (!Utils::ApiCheck( \
- length <= static_cast<size_t>(i::Smi::kMaxValue), \
- "v8::" #Type \
- "Array::New(Local<SharedArrayBuffer>, size_t, size_t)", \
- "length exceeds max allowed value")) { \
- return Local<Type##Array>(); \
- } \
- i::Handle<i::JSArrayBuffer> buffer = \
- Utils::OpenHandle(*shared_array_buffer); \
- i::Handle<i::JSTypedArray> obj = isolate->factory()->NewJSTypedArray( \
- i::kExternal##Type##Array, buffer, byte_offset, length); \
- return Utils::ToLocal##Type##Array(obj); \
+#define TYPED_ARRAY_NEW(Type, type, TYPE, ctype, size) \
+ Local<Type##Array> Type##Array::New(Local<ArrayBuffer> array_buffer, \
+ size_t byte_offset, size_t length) { \
+ i::Isolate* isolate = Utils::OpenHandle(*array_buffer)->GetIsolate(); \
+ LOG_API(isolate, Type##Array, New); \
+ ENTER_V8(isolate); \
+ if (!Utils::ApiCheck(length <= static_cast<size_t>(i::Smi::kMaxValue), \
+ "v8::" #Type \
+ "Array::New(Local<ArrayBuffer>, size_t, size_t)", \
+ "length exceeds max allowed value")) { \
+ return Local<Type##Array>(); \
+ } \
+ i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer); \
+ i::Handle<i::JSTypedArray> obj = isolate->factory()->NewJSTypedArray( \
+ i::kExternal##Type##Array, buffer, byte_offset, length); \
+ return Utils::ToLocal##Type##Array(obj); \
+ } \
+ Local<Type##Array> Type##Array::New( \
+ Local<SharedArrayBuffer> shared_array_buffer, size_t byte_offset, \
+ size_t length) { \
+ CHECK(i::FLAG_harmony_sharedarraybuffer); \
+ i::Isolate* isolate = \
+ Utils::OpenHandle(*shared_array_buffer)->GetIsolate(); \
+ LOG_API(isolate, Type##Array, New); \
+ ENTER_V8(isolate); \
+ if (!Utils::ApiCheck( \
+ length <= static_cast<size_t>(i::Smi::kMaxValue), \
+ "v8::" #Type \
+ "Array::New(Local<SharedArrayBuffer>, size_t, size_t)", \
+ "length exceeds max allowed value")) { \
+ return Local<Type##Array>(); \
+ } \
+ i::Handle<i::JSArrayBuffer> buffer = \
+ Utils::OpenHandle(*shared_array_buffer); \
+ i::Handle<i::JSTypedArray> obj = isolate->factory()->NewJSTypedArray( \
+ i::kExternal##Type##Array, buffer, byte_offset, length); \
+ return Utils::ToLocal##Type##Array(obj); \
}
-
TYPED_ARRAYS(TYPED_ARRAY_NEW)
#undef TYPED_ARRAY_NEW
@@ -6873,7 +7016,7 @@ Local<DataView> DataView::New(Local<ArrayBuffer> array_buffer,
size_t byte_offset, size_t byte_length) {
i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer);
i::Isolate* isolate = buffer->GetIsolate();
- LOG_API(isolate, "v8::DataView::New(Local<ArrayBuffer>, size_t, size_t)");
+ LOG_API(isolate, DataView, New);
ENTER_V8(isolate);
i::Handle<i::JSDataView> obj =
isolate->factory()->NewJSDataView(buffer, byte_offset, byte_length);
@@ -6886,8 +7029,7 @@ Local<DataView> DataView::New(Local<SharedArrayBuffer> shared_array_buffer,
CHECK(i::FLAG_harmony_sharedarraybuffer);
i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*shared_array_buffer);
i::Isolate* isolate = buffer->GetIsolate();
- LOG_API(isolate,
- "v8::DataView::New(Local<SharedArrayBuffer>, size_t, size_t)");
+ LOG_API(isolate, DataView, New);
ENTER_V8(isolate);
i::Handle<i::JSDataView> obj =
isolate->factory()->NewJSDataView(buffer, byte_offset, byte_length);
@@ -6903,7 +7045,7 @@ bool v8::SharedArrayBuffer::IsExternal() const {
v8::SharedArrayBuffer::Contents v8::SharedArrayBuffer::Externalize() {
i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
i::Isolate* isolate = self->GetIsolate();
- Utils::ApiCheck(!self->is_external(), "v8::SharedArrayBuffer::Externalize",
+ Utils::ApiCheck(!self->is_external(), "v8_SharedArrayBuffer_Externalize",
"SharedArrayBuffer already externalized");
self->set_is_external(true);
isolate->heap()->UnregisterArrayBuffer(*self);
@@ -6931,7 +7073,7 @@ Local<SharedArrayBuffer> v8::SharedArrayBuffer::New(Isolate* isolate,
size_t byte_length) {
CHECK(i::FLAG_harmony_sharedarraybuffer);
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
- LOG_API(i_isolate, "v8::SharedArrayBuffer::New(size_t)");
+ LOG_API(i_isolate, SharedArrayBuffer, New);
ENTER_V8(i_isolate);
i::Handle<i::JSArrayBuffer> obj =
i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kShared);
@@ -6948,7 +7090,7 @@ Local<SharedArrayBuffer> v8::SharedArrayBuffer::New(
// Embedders must guarantee that the external backing store is valid.
CHECK(byte_length == 0 || data != NULL);
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
- LOG_API(i_isolate, "v8::SharedArrayBuffer::New(void*, size_t)");
+ LOG_API(i_isolate, SharedArrayBuffer, New);
ENTER_V8(i_isolate);
i::Handle<i::JSArrayBuffer> obj =
i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kShared);
@@ -6961,7 +7103,7 @@ Local<SharedArrayBuffer> v8::SharedArrayBuffer::New(
Local<Symbol> v8::Symbol::New(Isolate* isolate, Local<String> name) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
- LOG_API(i_isolate, "Symbol::New()");
+ LOG_API(i_isolate, Symbol, New);
ENTER_V8(i_isolate);
i::Handle<i::Symbol> result = i_isolate->factory()->NewSymbol();
if (!name.IsEmpty()) result->set_name(*Utils::OpenHandle(*name));
@@ -6980,7 +7122,7 @@ static i::Handle<i::Symbol> SymbolFor(i::Isolate* isolate,
i::Handle<i::Object> symbol =
i::Object::GetPropertyOrElement(symbols, name).ToHandleChecked();
if (!symbol->IsSymbol()) {
- DCHECK(symbol->IsUndefined());
+ DCHECK(symbol->IsUndefined(isolate));
if (private_symbol)
symbol = isolate->factory()->NewPrivateSymbol();
else
@@ -7034,7 +7176,7 @@ Local<Symbol> v8::Symbol::GetIsConcatSpreadable(Isolate* isolate) {
Local<Private> v8::Private::New(Isolate* isolate, Local<String> name) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
- LOG_API(i_isolate, "Private::New()");
+ LOG_API(i_isolate, Private, New);
ENTER_V8(i_isolate);
i::Handle<i::Symbol> symbol = i_isolate->factory()->NewPrivateSymbol();
if (!name.IsEmpty()) symbol->set_name(*Utils::OpenHandle(*name));
@@ -7227,23 +7369,6 @@ void Isolate::SetEmbedderHeapTracer(EmbedderHeapTracer* tracer) {
isolate->heap()->SetEmbedderHeapTracer(tracer);
}
-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 Isolate::RemoveMemoryAllocationCallback(
- MemoryAllocationCallback callback) {
- i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
- isolate->memory_allocator()->RemoveMemoryAllocationCallback(
- callback);
-}
-
-
void Isolate::TerminateExecution() {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
isolate->stack_guard()->RequestTerminateExecution();
@@ -7326,18 +7451,12 @@ Isolate* Isolate::New(const Isolate::CreateParams& params) {
v8_isolate->SetAddHistogramSampleFunction(
params.add_histogram_sample_callback);
}
+
+ isolate->set_api_external_references(params.external_references);
SetResourceConstraints(isolate, params.constraints);
// 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)) {
- // If the isolate has a function entry hook, it needs to re-build all its
- // code stubs with entry hooks embedded, so don't deserialize a snapshot.
- if (i::Snapshot::EmbedsScript(isolate)) {
- // If the snapshot embeds a script, we cannot initialize the isolate
- // without the snapshot as a fallback. This is unlikely to happen though.
- V8_Fatal(__FILE__, __LINE__,
- "Initializing isolate from custom startup snapshot failed");
- }
isolate->Init(NULL);
}
return v8_isolate;
@@ -7445,6 +7564,10 @@ void Isolate::GetHeapStatistics(HeapStatistics* heap_statistics) {
heap_statistics->total_available_size_ = heap->Available();
heap_statistics->used_heap_size_ = heap->SizeOfObjects();
heap_statistics->heap_size_limit_ = heap->MaxReserved();
+ heap_statistics->malloced_memory_ =
+ isolate->allocator()->GetCurrentMemoryUsage();
+ heap_statistics->peak_malloced_memory_ =
+ isolate->allocator()->GetMaxMemoryUsage();
heap_statistics->does_zap_garbage_ = heap->ShouldZapGarbage();
}
@@ -7507,14 +7630,37 @@ bool Isolate::GetHeapObjectStatisticsAtLastGC(
return true;
}
+bool Isolate::GetHeapCodeAndMetadataStatistics(
+ HeapCodeStatistics* code_statistics) {
+ if (!code_statistics) return false;
+
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+ isolate->heap()->CollectCodeStatistics();
+
+ code_statistics->code_and_metadata_size_ = isolate->code_and_metadata_size();
+ code_statistics->bytecode_and_metadata_size_ =
+ isolate->bytecode_and_metadata_size();
+ return true;
+}
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);
+ RegisterState regs = state;
+ if (TickSample::GetStackSample(this, &regs, TickSample::kSkipCEntryFrame,
+ frames, frames_limit, sample_info)) {
+ return;
+ }
+ sample_info->frames_count = 0;
+ sample_info->vm_state = OTHER;
+ sample_info->external_callback_entry = nullptr;
}
+size_t Isolate::NumberOfPhantomHandleResetsSinceLastCall() {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+ size_t result = isolate->global_handles()->NumberOfPhantomHandleResets();
+ isolate->global_handles()->ResetNumberOfPhantomHandleResets();
+ return result;
+}
void Isolate::SetEventLogger(LogEventCallback that) {
// Do not overwrite the event logger if we want to log explicitly.
@@ -7700,13 +7846,13 @@ int Isolate::ContextDisposedNotification(bool dependant_context) {
void Isolate::IsolateInForegroundNotification() {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
- return isolate->heap()->SetOptimizeForLatency();
+ return isolate->IsolateInForegroundNotification();
}
void Isolate::IsolateInBackgroundNotification() {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
- return isolate->heap()->SetOptimizeForMemoryUsage();
+ return isolate->IsolateInBackgroundNotification();
}
void Isolate::MemoryPressureNotification(MemoryPressureLevel level) {
@@ -7715,6 +7861,11 @@ void Isolate::MemoryPressureNotification(MemoryPressureLevel level) {
Locker::IsLocked(this));
}
+void Isolate::SetRAILMode(RAILMode rail_mode) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+ return isolate->SetRAILMode(rail_mode);
+}
+
void Isolate::SetJitCodeEventHandler(JitCodeEventOptions options,
JitCodeEventHandler event_handler) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
@@ -7733,9 +7884,10 @@ void Isolate::SetStackLimit(uintptr_t 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();
+ if (isolate->heap()->memory_allocator()->code_range()->valid()) {
+ *start = isolate->heap()->memory_allocator()->code_range()->start();
+ *length_in_bytes =
+ isolate->heap()->memory_allocator()->code_range()->size();
} else {
*start = NULL;
*length_in_bytes = 0;
@@ -7748,6 +7900,10 @@ void Isolate::SetFatalErrorHandler(FatalErrorCallback that) {
isolate->set_exception_behavior(that);
}
+void Isolate::SetOOMErrorHandler(OOMErrorCallback that) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+ isolate->set_oom_behavior(that);
+}
void Isolate::SetAllowCodeGenerationFromStringsCallback(
AllowCodeGenerationFromStringsCallback callback) {
@@ -7766,12 +7922,15 @@ bool Isolate::AddMessageListener(MessageCallback that, Local<Value> data) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
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());
+ i::Handle<i::TemplateList> list = isolate->factory()->message_listeners();
+ i::Handle<i::FixedArray> listener = isolate->factory()->NewFixedArray(2);
+ i::Handle<i::Foreign> foreign =
+ isolate->factory()->NewForeign(FUNCTION_ADDR(that));
+ listener->set(0, *foreign);
+ listener->set(1, data.IsEmpty() ? isolate->heap()->undefined_value()
+ : *Utils::OpenHandle(*data));
+ list = i::TemplateList::Add(isolate, list, listener);
+ isolate->heap()->SetMessageListeners(*list);
return true;
}
@@ -7780,14 +7939,14 @@ void Isolate::RemoveMessageListeners(MessageCallback that) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
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)));
+ i::DisallowHeapAllocation no_gc;
+ i::TemplateList* listeners = isolate->heap()->message_listeners();
+ for (int i = 0; i < listeners->length(); i++) {
+ if (listeners->get(i)->IsUndefined(isolate)) continue; // skip deleted ones
+ i::FixedArray* listener = i::FixedArray::cast(listeners->get(i));
+ 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());
+ listeners->set(i, isolate->heap()->undefined_value());
}
}
}
@@ -7814,6 +7973,12 @@ void Isolate::VisitExternalResources(ExternalResourceVisitor* visitor) {
}
+bool Isolate::IsInUse() {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+ return isolate->IsInUse();
+}
+
+
class VisitorAdapter : public i::ObjectVisitor {
public:
explicit VisitorAdapter(PersistentHandleVisitor* visitor)
@@ -7821,6 +7986,7 @@ class VisitorAdapter : public i::ObjectVisitor {
void VisitPointers(i::Object** start, i::Object** end) override {
UNREACHABLE();
}
+ DISABLE_CFI_PERF
void VisitEmbedderReference(i::Object** p, uint16_t class_id) override {
Value* value = ToApi<Value>(i::Handle<i::Object>(p));
visitor_->VisitPersistentHandle(
@@ -7901,6 +8067,10 @@ int MicrotasksScope::GetCurrentDepth(Isolate* v8Isolate) {
return isolate->handle_scope_implementer()->GetMicrotasksScopeDepth();
}
+bool MicrotasksScope::IsRunningMicrotasks(Isolate* v8Isolate) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8Isolate);
+ return isolate->IsRunningMicrotasks();
+}
String::Utf8Value::Utf8Value(v8::Local<v8::Value> obj)
: str_(NULL), length_(0) {
@@ -7945,11 +8115,10 @@ String::Value::~Value() {
i::DeleteArray(str_);
}
-
#define DEFINE_ERROR(NAME, name) \
Local<Value> Exception::NAME(v8::Local<v8::String> raw_message) { \
i::Isolate* isolate = i::Isolate::Current(); \
- LOG_API(isolate, #NAME); \
+ LOG_API(isolate, NAME, New); \
ENTER_V8(isolate); \
i::Object* error; \
{ \
@@ -8016,12 +8185,6 @@ bool Debug::SetDebugEventListener(Isolate* isolate, EventCallback that,
}
-bool Debug::SetDebugEventListener(EventCallback that, Local<Value> data) {
- return SetDebugEventListener(
- reinterpret_cast<Isolate*>(i::Isolate::Current()), that, data);
-}
-
-
void Debug::DebugBreak(Isolate* isolate) {
reinterpret_cast<i::Isolate*>(isolate)->stack_guard()->RequestDebugBreak();
}
@@ -8047,11 +8210,6 @@ void Debug::SetMessageHandler(Isolate* isolate,
}
-void Debug::SetMessageHandler(v8::Debug::MessageHandler handler) {
- SetMessageHandler(reinterpret_cast<Isolate*>(i::Isolate::Current()), handler);
-}
-
-
void Debug::SendCommand(Isolate* isolate,
const uint16_t* command,
int length,
@@ -8065,7 +8223,7 @@ void Debug::SendCommand(Isolate* isolate,
MaybeLocal<Value> Debug::Call(Local<Context> context,
v8::Local<v8::Function> fun,
v8::Local<v8::Value> data) {
- PREPARE_FOR_EXECUTION(context, "v8::Debug::Call()", Value);
+ PREPARE_FOR_EXECUTION(context, Debug, Call, Value);
i::Handle<i::Object> data_obj;
if (data.IsEmpty()) {
data_obj = isolate->factory()->undefined_value();
@@ -8081,16 +8239,9 @@ MaybeLocal<Value> Debug::Call(Local<Context> context,
}
-Local<Value> Debug::Call(v8::Local<v8::Function> fun,
- v8::Local<v8::Value> data) {
- auto context = ContextFromHeapObject(Utils::OpenHandle(*fun));
- RETURN_TO_LOCAL_UNCHECKED(Call(context, fun, data), Value);
-}
-
-
MaybeLocal<Value> Debug::GetMirror(Local<Context> context,
v8::Local<v8::Value> obj) {
- PREPARE_FOR_EXECUTION(context, "v8::Debug::GetMirror()", Value);
+ PREPARE_FOR_EXECUTION(context, Debug, GetMirror, Value);
i::Debug* isolate_debug = isolate->debug();
has_pending_exception = !isolate_debug->Load();
RETURN_ON_FAILED_EXECUTION(Value);
@@ -8109,21 +8260,11 @@ MaybeLocal<Value> Debug::GetMirror(Local<Context> context,
}
-Local<Value> Debug::GetMirror(v8::Local<v8::Value> obj) {
- RETURN_TO_LOCAL_UNCHECKED(GetMirror(Local<Context>(), obj), Value);
-}
-
-
void Debug::ProcessDebugMessages(Isolate* isolate) {
reinterpret_cast<i::Isolate*>(isolate)->debug()->ProcessDebugMessages(true);
}
-void Debug::ProcessDebugMessages() {
- ProcessDebugMessages(reinterpret_cast<Isolate*>(i::Isolate::Current()));
-}
-
-
Local<Context> Debug::GetDebugContext(Isolate* isolate) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
ENTER_V8(i_isolate);
@@ -8131,11 +8272,15 @@ Local<Context> Debug::GetDebugContext(Isolate* isolate) {
}
-Local<Context> Debug::GetDebugContext() {
- return GetDebugContext(reinterpret_cast<Isolate*>(i::Isolate::Current()));
+MaybeLocal<Context> Debug::GetDebuggedContext(Isolate* isolate) {
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ ENTER_V8(i_isolate);
+ if (!i_isolate->debug()->in_debug_scope()) return MaybeLocal<Context>();
+ i::Handle<i::Object> calling = i_isolate->GetCallingNativeContext();
+ if (calling.is_null()) return MaybeLocal<Context>();
+ return Utils::ToLocal(i::Handle<i::Context>::cast(calling));
}
-
void Debug::SetLiveEditEnabled(Isolate* isolate, bool enable) {
i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
internal_isolate->debug()->set_live_edit_enabled(enable);
@@ -8261,9 +8406,8 @@ const std::vector<CpuProfileDeoptInfo>& CpuProfileNode::GetDeoptInfos() const {
void CpuProfile::Delete() {
i::CpuProfile* profile = reinterpret_cast<i::CpuProfile*>(this);
- i::Isolate* isolate = profile->top_down()->isolate();
- i::CpuProfiler* profiler = isolate->cpu_profiler();
- DCHECK(profiler != NULL);
+ i::CpuProfiler* profiler = profile->cpu_profiler();
+ DCHECK(profiler != nullptr);
profiler->DeleteProfile(profile);
}
@@ -8311,6 +8455,12 @@ int CpuProfile::GetSamplesCount() const {
return reinterpret_cast<const i::CpuProfile*>(this)->samples_count();
}
+CpuProfiler* CpuProfiler::New(Isolate* isolate) {
+ return reinterpret_cast<CpuProfiler*>(
+ new i::CpuProfiler(reinterpret_cast<i::Isolate*>(isolate)));
+}
+
+void CpuProfiler::Dispose() { delete reinterpret_cast<i::CpuProfiler*>(this); }
void CpuProfiler::SetSamplingInterval(int us) {
DCHECK_GE(us, 0);
@@ -8336,7 +8486,9 @@ CpuProfile* CpuProfiler::StopProfiling(Local<String> title) {
void CpuProfiler::SetIdle(bool is_idle) {
- i::Isolate* isolate = reinterpret_cast<i::CpuProfiler*>(this)->isolate();
+ i::CpuProfiler* profiler = reinterpret_cast<i::CpuProfiler*>(this);
+ i::Isolate* isolate = profiler->isolate();
+ if (!isolate->is_profiling()) return;
v8::StateTag state = isolate->current_vm_state();
DCHECK(state == v8::EXTERNAL || state == v8::IDLE);
if (isolate->js_entry_sp() != NULL) return;
@@ -8548,11 +8700,11 @@ SnapshotObjectId HeapProfiler::GetHeapStats(OutputStream* stream,
return heap_profiler->PushHeapObjectsStats(stream, timestamp_us);
}
-
bool HeapProfiler::StartSamplingHeapProfiler(uint64_t sample_interval,
- int stack_depth) {
- return reinterpret_cast<i::HeapProfiler*>(this)
- ->StartSamplingHeapProfiler(sample_interval, stack_depth);
+ int stack_depth,
+ SamplingFlags flags) {
+ return reinterpret_cast<i::HeapProfiler*>(this)->StartSamplingHeapProfiler(
+ sample_interval, stack_depth, flags);
}
@@ -8724,6 +8876,10 @@ void HandleScopeImplementer::IterateThis(ObjectVisitor* v) {
Object** start = reinterpret_cast<Object**>(&context_lists[i]->first());
v->VisitPointers(start, start + context_lists[i]->length());
}
+ if (microtask_context_) {
+ Object** start = reinterpret_cast<Object**>(&microtask_context_);
+ v->VisitPointers(start, start + 1);
+ }
}
@@ -8808,6 +8964,11 @@ void InvokeAccessorGetterCallback(
v8::AccessorNameGetterCallback getter) {
// Leaving JavaScript.
Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
+ RuntimeCallTimerScope timer(isolate,
+ &RuntimeCallStats::AccessorGetterCallback);
+ TRACE_EVENT_RUNTIME_CALL_STATS_TRACING_SCOPED(
+ isolate,
+ &internal::tracing::TraceEventStatsTable::AccessorGetterCallback);
Address getter_address = reinterpret_cast<Address>(reinterpret_cast<intptr_t>(
getter));
VMState<EXTERNAL> state(isolate);
@@ -8819,6 +8980,11 @@ void InvokeAccessorGetterCallback(
void InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>& info,
v8::FunctionCallback callback) {
Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
+ RuntimeCallTimerScope timer(isolate,
+ &RuntimeCallStats::InvokeFunctionCallback);
+ TRACE_EVENT_RUNTIME_CALL_STATS_TRACING_SCOPED(
+ isolate,
+ &internal::tracing::TraceEventStatsTable::InvokeFunctionCallback);
Address callback_address =
reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback));
VMState<EXTERNAL> state(isolate);