summaryrefslogtreecommitdiff
path: root/deps/v8/src/api.cc
diff options
context:
space:
mode:
authorMichaël Zasso <targos@protonmail.com>2019-03-12 09:01:49 +0100
committerMichaël Zasso <targos@protonmail.com>2019-03-14 18:49:21 +0100
commit7b48713334469818661fe276cf571de9c7899f2d (patch)
tree4dbda49ac88db76ce09dc330a0cb587e68e139ba /deps/v8/src/api.cc
parent8549ac09b256666cf5275224ec58fab9939ff32e (diff)
downloadandroid-node-v8-7b48713334469818661fe276cf571de9c7899f2d.tar.gz
android-node-v8-7b48713334469818661fe276cf571de9c7899f2d.tar.bz2
android-node-v8-7b48713334469818661fe276cf571de9c7899f2d.zip
deps: update V8 to 7.3.492.25
PR-URL: https://github.com/nodejs/node/pull/25852 Reviewed-By: Ujjwal Sharma <usharma1998@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com>
Diffstat (limited to 'deps/v8/src/api.cc')
-rw-r--r--deps/v8/src/api.cc1726
1 files changed, 818 insertions, 908 deletions
diff --git a/deps/v8/src/api.cc b/deps/v8/src/api.cc
index 40e8b41e69..b1f9c99860 100644
--- a/deps/v8/src/api.cc
+++ b/deps/v8/src/api.cc
@@ -26,12 +26,13 @@
#include "src/bootstrapper.h"
#include "src/builtins/builtins-utils.h"
#include "src/char-predicates-inl.h"
-#include "src/code-stubs.h"
#include "src/compiler-dispatcher/compiler-dispatcher.h"
#include "src/compiler.h"
#include "src/contexts.h"
#include "src/conversions-inl.h"
#include "src/counters.h"
+#include "src/cpu-features.h"
+#include "src/date.h"
#include "src/debug/debug-coverage.h"
#include "src/debug/debug-evaluate.h"
#include "src/debug/debug-type-profile.h"
@@ -49,15 +50,23 @@
#include "src/json-parser.h"
#include "src/json-stringifier.h"
#include "src/messages.h"
+#include "src/microtask-queue.h"
#include "src/objects-inl.h"
#include "src/objects/api-callbacks.h"
+#include "src/objects/embedder-data-array-inl.h"
+#include "src/objects/embedder-data-slot-inl.h"
+#include "src/objects/hash-table-inl.h"
+#include "src/objects/heap-object.h"
#include "src/objects/js-array-inl.h"
#include "src/objects/js-collection-inl.h"
#include "src/objects/js-generator-inl.h"
#include "src/objects/js-promise-inl.h"
#include "src/objects/js-regexp-inl.h"
#include "src/objects/module-inl.h"
+#include "src/objects/oddball.h"
#include "src/objects/ordered-hash-table-inl.h"
+#include "src/objects/slots.h"
+#include "src/objects/smi.h"
#include "src/objects/stack-frame-info-inl.h"
#include "src/objects/templates.h"
#include "src/parsing/parse-info.h"
@@ -76,15 +85,16 @@
#include "src/runtime-profiler.h"
#include "src/runtime/runtime.h"
#include "src/simulator.h"
-#include "src/snapshot/builtin-serializer.h"
#include "src/snapshot/code-serializer.h"
#include "src/snapshot/natives.h"
+#include "src/snapshot/partial-serializer.h"
+#include "src/snapshot/read-only-serializer.h"
#include "src/snapshot/snapshot.h"
+#include "src/snapshot/startup-serializer.h"
#include "src/startup-data-util.h"
#include "src/string-hasher.h"
#include "src/tracing/trace-event.h"
#include "src/trap-handler/trap-handler.h"
-#include "src/unicode-cache-inl.h"
#include "src/unicode-inl.h"
#include "src/v8.h"
#include "src/v8threads.h"
@@ -97,6 +107,18 @@
#include "src/wasm/wasm-result.h"
#include "src/wasm/wasm-serialization.h"
+#if V8_OS_LINUX || V8_OS_MACOSX
+#include <signal.h>
+#include "include/v8-wasm-trap-handler-posix.h"
+#include "src/trap-handler/handler-inside-posix.h"
+#endif
+
+#if V8_OS_WIN
+#include <windows.h>
+#include "include/v8-wasm-trap-handler-win.h"
+#include "src/trap-handler/handler-inside-win.h"
+#endif
+
namespace v8 {
/*
@@ -217,7 +239,7 @@ namespace v8 {
namespace {
Local<Context> ContextFromNeverReadOnlySpaceObject(
- i::Handle<i::NeverReadOnlySpaceObject> obj) {
+ i::Handle<i::JSReceiver> obj) {
return reinterpret_cast<v8::Isolate*>(obj->GetIsolate())->GetCurrentContext();
}
@@ -231,10 +253,11 @@ class InternalEscapableScope : public v8::EscapableHandleScope {
#ifdef V8_CHECK_MICROTASKS_SCOPES_CONSISTENCY
void CheckMicrotasksScopesConsistency(i::Isolate* isolate) {
auto handle_scope_implementer = isolate->handle_scope_implementer();
+ auto* microtask_queue = isolate->default_microtask_queue();
if (handle_scope_implementer->microtasks_policy() ==
v8::MicrotasksPolicy::kScoped) {
- DCHECK(handle_scope_implementer->GetMicrotasksScopeDepth() ||
- !handle_scope_implementer->DebugMicrotasksScopeDepthIsZero());
+ DCHECK(microtask_queue->GetMicrotasksScopeDepth() ||
+ !microtask_queue->DebugMicrotasksScopeDepthIsZero());
}
}
#endif
@@ -253,14 +276,12 @@ class CallDepthScope {
? i::InterruptsScope::kRunInterrupts
: i::InterruptsScope::kPostponeInterrupts)
: i::InterruptsScope::kNoop) {
- // TODO(dcarney): remove this when blink stops crashing.
- DCHECK(!isolate_->external_caught_exception());
isolate_->handle_scope_implementer()->IncrementCallDepth();
isolate_->set_next_v8_call_is_safe_for_termination(false);
if (!context.IsEmpty()) {
i::Handle<i::Context> env = Utils::OpenHandle(*context);
i::HandleScopeImplementer* impl = isolate->handle_scope_implementer();
- if (isolate->context() != nullptr &&
+ if (!isolate->context().is_null() &&
isolate->context()->native_context() == env->native_context()) {
context_ = Local<Context>();
} else {
@@ -289,8 +310,10 @@ class CallDepthScope {
escaped_ = true;
auto handle_scope_implementer = isolate_->handle_scope_implementer();
handle_scope_implementer->DecrementCallDepth();
- bool call_depth_is_zero = handle_scope_implementer->CallDepthIsZero();
- isolate_->OptionalRescheduleException(call_depth_is_zero);
+ bool clear_exception =
+ handle_scope_implementer->CallDepthIsZero() &&
+ isolate_->thread_local_top()->try_catch_handler() == nullptr;
+ isolate_->OptionalRescheduleException(clear_exception);
}
private:
@@ -343,20 +366,19 @@ void i::V8::FatalProcessOutOfMemory(i::Isolate* isolate, const char* location,
i::HeapStats heap_stats;
if (isolate == nullptr) {
- isolate = Isolate::Current();
+ isolate = Isolate::TryGetCurrent();
}
if (isolate == nullptr) {
- // On a background thread -> we cannot retrieve memory information from the
- // Isolate. Write easy-to-recognize values on the stack.
+ // If the Isolate is not available for the current thread we cannot retrieve
+ // memory information from the Isolate. Write easy-to-recognize values on
+ // the stack.
memset(last_few_messages, 0x0BADC0DE, Heap::kTraceRingBufferSize + 1);
memset(js_stacktrace, 0x0BADC0DE, Heap::kStacktraceBufferSize + 1);
memset(&heap_stats, 0xBADC0DE, sizeof(heap_stats));
- // Note that the embedder's oom handler won't be called in this case. We
- // just crash.
- FATAL(
- "API fatal error handler returned after process out of memory on the "
- "background thread");
+ // Note that the embedder's oom handler is also not available and therefore
+ // won't be called in this case. We just crash.
+ FATAL("Fatal process out of memory: %s", location);
UNREACHABLE();
}
@@ -387,6 +409,8 @@ void i::V8::FatalProcessOutOfMemory(i::Isolate* isolate, const char* location,
heap_stats.map_space_capacity = &map_space_capacity;
size_t lo_space_size;
heap_stats.lo_space_size = &lo_space_size;
+ size_t code_lo_space_size;
+ heap_stats.code_lo_space_size = &code_lo_space_size;
size_t global_handle_count;
heap_stats.global_handle_count = &global_handle_count;
size_t weak_global_handle_count;
@@ -563,8 +587,8 @@ SnapshotCreator::SnapshotCreator(Isolate* isolate,
SnapshotCreator::SnapshotCreator(const intptr_t* external_references,
StartupData* existing_snapshot)
- : SnapshotCreator(reinterpret_cast<Isolate*>(new i::Isolate()),
- external_references, existing_snapshot) {}
+ : SnapshotCreator(Isolate::Allocate(), external_references,
+ existing_snapshot) {}
SnapshotCreator::~SnapshotCreator() {
SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
@@ -608,13 +632,13 @@ size_t SnapshotCreator::AddTemplate(Local<Template> template_obj) {
return AddData(template_obj);
}
-size_t SnapshotCreator::AddData(i::Object* object) {
- DCHECK_NOT_NULL(object);
+size_t SnapshotCreator::AddData(i::Address object) {
+ DCHECK_NE(object, i::kNullAddress);
SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
DCHECK(!data->created_);
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(data->isolate_);
i::HandleScope scope(isolate);
- i::Handle<i::Object> obj(object, isolate);
+ i::Handle<i::Object> obj(i::Object(object), isolate);
i::Handle<i::ArrayList> list;
if (!isolate->heap()->serialized_objects()->IsArrayList()) {
list = i::ArrayList::New(isolate, 1);
@@ -628,13 +652,13 @@ size_t SnapshotCreator::AddData(i::Object* object) {
return index;
}
-size_t SnapshotCreator::AddData(Local<Context> context, i::Object* object) {
- DCHECK_NOT_NULL(object);
+size_t SnapshotCreator::AddData(Local<Context> context, i::Address object) {
+ DCHECK_NE(object, i::kNullAddress);
DCHECK(!SnapshotCreatorData::cast(data_)->created_);
i::Handle<i::Context> ctx = Utils::OpenHandle(*context);
i::Isolate* isolate = ctx->GetIsolate();
i::HandleScope scope(isolate);
- i::Handle<i::Object> obj(object, isolate);
+ i::Handle<i::Object> obj(i::Object(object), isolate);
i::Handle<i::ArrayList> list;
if (!ctx->serialized_objects()->IsArrayList()) {
list = i::ArrayList::New(isolate, 1);
@@ -731,20 +755,32 @@ StartupData SnapshotCreator::CreateBlob(
// We have to iterate the heap and collect handles to each clearable SFI,
// before we disable allocation, since we have to allocate UncompiledDatas
// to be able to recompile them.
+ //
+ // Compiled irregexp code is also flushed by collecting and clearing any
+ // seen JSRegExp objects.
i::HandleScope scope(isolate);
std::vector<i::Handle<i::SharedFunctionInfo>> sfis_to_clear;
- i::HeapIterator heap_iterator(isolate->heap());
- while (i::HeapObject* current_obj = heap_iterator.next()) {
- if (current_obj->IsSharedFunctionInfo()) {
- i::SharedFunctionInfo* shared =
- i::SharedFunctionInfo::cast(current_obj);
- if (shared->CanDiscardCompiled()) {
- sfis_to_clear.emplace_back(shared, isolate);
+ { // Heap allocation is disallowed within this scope.
+ i::HeapIterator heap_iterator(isolate->heap());
+ for (i::HeapObject current_obj = heap_iterator.next();
+ !current_obj.is_null(); current_obj = heap_iterator.next()) {
+ if (current_obj->IsSharedFunctionInfo()) {
+ i::SharedFunctionInfo shared =
+ i::SharedFunctionInfo::cast(current_obj);
+ if (shared->CanDiscardCompiled()) {
+ sfis_to_clear.emplace_back(shared, isolate);
+ }
+ } else if (current_obj->IsJSRegExp()) {
+ i::JSRegExp regexp = i::JSRegExp::cast(current_obj);
+ if (regexp->HasCompiledCode()) {
+ regexp->DiscardCompiledCodeForSerialization();
+ }
}
}
}
- i::AllowHeapAllocation allocate_for_discard;
+
+ // Must happen after heap iteration since SFI::DiscardCompiled may allocate.
for (i::Handle<i::SharedFunctionInfo> shared : sfis_to_clear) {
i::SharedFunctionInfo::DiscardCompiled(isolate, shared);
}
@@ -753,7 +789,7 @@ StartupData SnapshotCreator::CreateBlob(
i::DisallowHeapAllocation no_gc_from_here_on;
int num_contexts = num_additional_contexts + 1;
- std::vector<i::Context*> contexts;
+ std::vector<i::Context> contexts;
contexts.reserve(num_contexts);
{
i::HandleScope scope(isolate);
@@ -773,16 +809,17 @@ StartupData SnapshotCreator::CreateBlob(
CHECK(handle_checker.CheckGlobalAndEternalHandles());
i::HeapIterator heap_iterator(isolate->heap());
- while (i::HeapObject* current_obj = heap_iterator.next()) {
+ for (i::HeapObject current_obj = heap_iterator.next(); !current_obj.is_null();
+ current_obj = heap_iterator.next()) {
if (current_obj->IsJSFunction()) {
- i::JSFunction* fun = i::JSFunction::cast(current_obj);
+ i::JSFunction fun = i::JSFunction::cast(current_obj);
// Complete in-object slack tracking for all functions.
fun->CompleteInobjectSlackTrackingIfActive();
// Also, clear out feedback vectors, or any optimized code.
- if (fun->has_feedback_vector()) {
- fun->feedback_cell()->set_value(
+ if (!fun->raw_feedback_cell()->value()->IsUndefined()) {
+ fun->raw_feedback_cell()->set_value(
i::ReadOnlyRoots(isolate).undefined_value());
fun->set_code(isolate->builtins()->builtin(i::Builtins::kCompileLazy));
}
@@ -790,12 +827,15 @@ StartupData SnapshotCreator::CreateBlob(
DCHECK(fun->shared()->HasWasmExportedFunctionData() ||
fun->shared()->HasBuiltinId() ||
fun->shared()->IsApiFunction() ||
- fun->shared()->HasUncompiledDataWithoutPreParsedScope());
+ fun->shared()->HasUncompiledDataWithoutPreparseData());
}
}
}
- i::StartupSerializer startup_serializer(isolate);
+ i::ReadOnlySerializer read_only_serializer(isolate);
+ read_only_serializer.SerializeReadOnlyRoots();
+
+ i::StartupSerializer startup_serializer(isolate, &read_only_serializer);
startup_serializer.SerializeStrongReferences();
// Serialize each context with a new partial serializer.
@@ -816,19 +856,17 @@ StartupData SnapshotCreator::CreateBlob(
context_snapshots.push_back(new i::SnapshotData(&partial_serializer));
}
- // Builtin serialization places additional objects into the partial snapshot
- // cache and thus needs to happen before SerializeWeakReferencesAndDeferred
- // is called below.
- i::BuiltinSerializer builtin_serializer(isolate, &startup_serializer);
- builtin_serializer.SerializeBuiltinsAndHandlers();
-
startup_serializer.SerializeWeakReferencesAndDeferred();
can_be_rehashed = can_be_rehashed && startup_serializer.can_be_rehashed();
+ read_only_serializer.FinalizeSerialization();
+ can_be_rehashed = can_be_rehashed && read_only_serializer.can_be_rehashed();
+
+ i::SnapshotData read_only_snapshot(&read_only_serializer);
i::SnapshotData startup_snapshot(&startup_serializer);
- i::BuiltinSnapshotData builtin_snapshot(&builtin_serializer);
- StartupData result = i::Snapshot::CreateSnapshotBlob(
- &startup_snapshot, &builtin_snapshot, context_snapshots, can_be_rehashed);
+ StartupData result =
+ i::Snapshot::CreateSnapshotBlob(&startup_snapshot, &read_only_snapshot,
+ context_snapshots, can_be_rehashed);
// Delete heap-allocated context snapshot instances.
for (const auto context_snapshot : context_snapshots) {
@@ -955,72 +993,52 @@ void SetResourceConstraints(i::Isolate* isolate,
}
}
-
-i::Object** V8::GlobalizeReference(i::Isolate* isolate, i::Object** obj) {
+i::Address* V8::GlobalizeReference(i::Isolate* isolate, i::Address* obj) {
LOG_API(isolate, Persistent, New);
i::Handle<i::Object> result = isolate->global_handles()->Create(*obj);
#ifdef VERIFY_HEAP
if (i::FLAG_verify_heap) {
- (*obj)->ObjectVerify(isolate);
+ i::Object(*obj)->ObjectVerify(isolate);
}
#endif // VERIFY_HEAP
return result.location();
}
-
-i::Object** V8::CopyPersistent(i::Object** obj) {
+i::Address* V8::CopyPersistent(i::Address* obj) {
i::Handle<i::Object> result = i::GlobalHandles::CopyGlobal(obj);
return result.location();
}
-void V8::RegisterExternallyReferencedObject(i::Object** object,
+void V8::RegisterExternallyReferencedObject(i::Address* location,
i::Isolate* isolate) {
- isolate->heap()->RegisterExternallyReferencedObject(object);
-}
-
-void V8::MakeWeak(i::Object** location, void* parameter,
- int embedder_field_index1, int embedder_field_index2,
- WeakCallbackInfo<void>::Callback weak_callback) {
- WeakCallbackType type = WeakCallbackType::kParameter;
- if (embedder_field_index1 == 0) {
- if (embedder_field_index2 == 1) {
- type = WeakCallbackType::kInternalFields;
- } else {
- DCHECK_EQ(embedder_field_index2, -1);
- type = WeakCallbackType::kInternalFields;
- }
- } else {
- DCHECK_EQ(embedder_field_index1, -1);
- DCHECK_EQ(embedder_field_index2, -1);
- }
- i::GlobalHandles::MakeWeak(location, parameter, weak_callback, type);
+ isolate->heap()->RegisterExternallyReferencedObject(location);
}
-void V8::MakeWeak(i::Object** location, void* parameter,
+void V8::MakeWeak(i::Address* location, void* parameter,
WeakCallbackInfo<void>::Callback weak_callback,
WeakCallbackType type) {
i::GlobalHandles::MakeWeak(location, parameter, weak_callback, type);
}
-void V8::MakeWeak(i::Object*** location_addr) {
+void V8::MakeWeak(i::Address** location_addr) {
i::GlobalHandles::MakeWeak(location_addr);
}
-void* V8::ClearWeak(i::Object** location) {
+void* V8::ClearWeak(i::Address* location) {
return i::GlobalHandles::ClearWeakness(location);
}
-void V8::AnnotateStrongRetainer(i::Object** location, const char* label) {
+void V8::AnnotateStrongRetainer(i::Address* location, const char* label) {
i::GlobalHandles::AnnotateStrongRetainer(location, label);
}
-void V8::DisposeGlobal(i::Object** location) {
+void V8::DisposeGlobal(i::Address* location) {
i::GlobalHandles::Destroy(location);
}
Value* V8::Eternalize(Isolate* v8_isolate, Value* value) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
- i::Object* object = *Utils::OpenHandle(value);
+ i::Object object = *Utils::OpenHandle(value);
int index = -1;
isolate->eternal_handles()->Create(isolate, object, &index);
return reinterpret_cast<Value*>(
@@ -1087,32 +1105,23 @@ int HandleScope::NumberOfHandles(Isolate* isolate) {
reinterpret_cast<i::Isolate*>(isolate));
}
-
-i::Object** HandleScope::CreateHandle(i::Isolate* isolate, i::Object* value) {
+i::Address* HandleScope::CreateHandle(i::Isolate* isolate, i::Address value) {
return i::HandleScope::CreateHandle(isolate, value);
}
-i::Object** HandleScope::CreateHandle(
- i::NeverReadOnlySpaceObject* writable_object, i::Object* value) {
- DCHECK(reinterpret_cast<i::HeapObject*>(writable_object)->IsHeapObject());
- return i::HandleScope::CreateHandle(writable_object->GetIsolate(), value);
-}
-
-
EscapableHandleScope::EscapableHandleScope(Isolate* v8_isolate) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
escape_slot_ =
- CreateHandle(isolate, i::ReadOnlyRoots(isolate).the_hole_value());
+ CreateHandle(isolate, i::ReadOnlyRoots(isolate).the_hole_value()->ptr());
Initialize(v8_isolate);
}
-
-i::Object** EscapableHandleScope::Escape(i::Object** escape_value) {
+i::Address* EscapableHandleScope::Escape(i::Address* escape_value) {
i::Heap* heap = reinterpret_cast<i::Isolate*>(GetIsolate())->heap();
- Utils::ApiCheck((*escape_slot_)->IsTheHole(heap->isolate()),
+ Utils::ApiCheck(i::Object(*escape_slot_)->IsTheHole(heap->isolate()),
"EscapableHandleScope::Escape", "Escape value set twice");
if (escape_value == nullptr) {
- *escape_slot_ = i::ReadOnlyRoots(heap).undefined_value();
+ *escape_slot_ = i::ReadOnlyRoots(heap).undefined_value()->ptr();
return nullptr;
}
*escape_slot_ = *escape_value;
@@ -1154,7 +1163,7 @@ void Context::Enter() {
i::Isolate* isolate = env->GetIsolate();
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
i::HandleScopeImplementer* impl = isolate->handle_scope_implementer();
- impl->EnterContext(env);
+ impl->EnterContext(*env);
impl->SaveContext(isolate->context());
isolate->set_context(*env);
}
@@ -1164,8 +1173,7 @@ void Context::Exit() {
i::Isolate* isolate = env->GetIsolate();
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
i::HandleScopeImplementer* impl = isolate->handle_scope_implementer();
- if (!Utils::ApiCheck(impl->LastEnteredContextWas(env),
- "v8::Context::Exit()",
+ if (!Utils::ApiCheck(impl->LastEnteredContextWas(*env), "v8::Context::Exit()",
"Cannot exit non-entered context")) {
return;
}
@@ -1180,6 +1188,10 @@ Context::BackupIncumbentScope::BackupIncumbentScope(
i::Handle<i::Context> env = Utils::OpenHandle(*backup_incumbent_context_);
i::Isolate* isolate = env->GetIsolate();
+
+ js_stack_comparable_address_ =
+ i::SimulatorStack::RegisterJSStackComparableAddress(isolate);
+
prev_ = isolate->top_backup_incumbent_scope();
isolate->set_top_backup_incumbent_scope(this);
}
@@ -1187,26 +1199,17 @@ Context::BackupIncumbentScope::BackupIncumbentScope(
Context::BackupIncumbentScope::~BackupIncumbentScope() {
i::Handle<i::Context> env = Utils::OpenHandle(*backup_incumbent_context_);
i::Isolate* isolate = env->GetIsolate();
- isolate->set_top_backup_incumbent_scope(prev_);
-}
-
-static void* DecodeSmiToAligned(i::Object* value, const char* location) {
- Utils::ApiCheck(value->IsSmi(), location, "Not a Smi");
- return reinterpret_cast<void*>(value);
-}
+ i::SimulatorStack::UnregisterJSStackComparableAddress(isolate);
-static i::Smi* EncodeAlignedAsSmi(void* value, const char* location) {
- i::Smi* smi = reinterpret_cast<i::Smi*>(value);
- Utils::ApiCheck(smi->IsSmi(), location, "Pointer is not aligned");
- return smi;
+ isolate->set_top_backup_incumbent_scope(prev_);
}
+STATIC_ASSERT(i::Internals::kEmbedderDataSlotSize == i::kEmbedderDataSlotSize);
-static i::Handle<i::FixedArray> EmbedderDataFor(Context* context,
- int index,
- bool can_grow,
- const char* location) {
+static i::Handle<i::EmbedderDataArray> EmbedderDataFor(Context* context,
+ int index, bool can_grow,
+ const char* location) {
i::Handle<i::Context> env = Utils::OpenHandle(context);
i::Isolate* isolate = env->GetIsolate();
bool ok =
@@ -1214,15 +1217,16 @@ static i::Handle<i::FixedArray> EmbedderDataFor(Context* context,
location,
"Not a native context") &&
Utils::ApiCheck(index >= 0, location, "Negative index");
- if (!ok) return i::Handle<i::FixedArray>();
- i::Handle<i::FixedArray> data(env->embedder_data(), isolate);
+ if (!ok) return i::Handle<i::EmbedderDataArray>();
+ // TODO(ishell): remove cast once embedder_data slot has a proper type.
+ i::Handle<i::EmbedderDataArray> data(
+ i::EmbedderDataArray::cast(env->embedder_data()), isolate);
if (index < data->length()) return data;
- if (!Utils::ApiCheck(can_grow, location, "Index too large")) {
- return i::Handle<i::FixedArray>();
+ if (!Utils::ApiCheck(can_grow && index < i::EmbedderDataArray::kMaxLength,
+ location, "Index too large")) {
+ return i::Handle<i::EmbedderDataArray>();
}
- int new_size = index + 1;
- int grow_by = new_size - data->length();
- data = isolate->factory()->CopyFixedArrayAndGrow(data, grow_by);
+ data = i::EmbedderDataArray::EnsureCapacity(isolate, data, index);
env->set_embedder_data(*data);
return data;
}
@@ -1230,26 +1234,30 @@ static i::Handle<i::FixedArray> EmbedderDataFor(Context* context,
uint32_t Context::GetNumberOfEmbedderDataFields() {
i::Handle<i::Context> context = Utils::OpenHandle(this);
CHECK(context->IsNativeContext());
- return static_cast<uint32_t>(context->embedder_data()->length());
+ // TODO(ishell): remove cast once embedder_data slot has a proper type.
+ return static_cast<uint32_t>(
+ i::EmbedderDataArray::cast(context->embedder_data())->length());
}
v8::Local<v8::Value> Context::SlowGetEmbedderData(int index) {
const char* location = "v8::Context::GetEmbedderData()";
- i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, false, location);
+ i::Handle<i::EmbedderDataArray> data =
+ EmbedderDataFor(this, index, false, location);
if (data.is_null()) return Local<Value>();
- i::Handle<i::Object> result(
- data->get(index),
- reinterpret_cast<i::Isolate*>(Utils::OpenHandle(this)->GetIsolate()));
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+ i::Handle<i::Object> result(i::EmbedderDataSlot(*data, index).load_tagged(),
+ isolate);
return Utils::ToLocal(result);
}
void Context::SetEmbedderData(int index, v8::Local<Value> value) {
const char* location = "v8::Context::SetEmbedderData()";
- i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, true, location);
+ i::Handle<i::EmbedderDataArray> data =
+ EmbedderDataFor(this, index, true, location);
if (data.is_null()) return;
i::Handle<i::Object> val = Utils::OpenHandle(*value);
- data->set(index, *val);
+ i::EmbedderDataSlot::store_tagged(*data, index, *val);
DCHECK_EQ(*Utils::OpenHandle(*value),
*Utils::OpenHandle(*GetEmbedderData(index)));
}
@@ -1257,16 +1265,22 @@ void Context::SetEmbedderData(int index, v8::Local<Value> value) {
void* Context::SlowGetAlignedPointerFromEmbedderData(int index) {
const char* location = "v8::Context::GetAlignedPointerFromEmbedderData()";
- i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, false, location);
+ i::Handle<i::EmbedderDataArray> data =
+ EmbedderDataFor(this, index, false, location);
if (data.is_null()) return nullptr;
- return DecodeSmiToAligned(data->get(index), location);
+ void* result;
+ Utils::ApiCheck(i::EmbedderDataSlot(*data, index).ToAlignedPointer(&result),
+ location, "Pointer is not aligned");
+ return result;
}
void Context::SetAlignedPointerInEmbedderData(int index, void* value) {
const char* location = "v8::Context::SetAlignedPointerInEmbedderData()";
- i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, true, location);
- data->set(index, EncodeAlignedAsSmi(value, location));
+ i::Handle<i::EmbedderDataArray> data =
+ EmbedderDataFor(this, index, true, location);
+ bool ok = i::EmbedderDataSlot(*data, index).store_aligned_pointer(value);
+ Utils::ApiCheck(ok, location, "Pointer is not aligned");
DCHECK_EQ(value, GetAlignedPointerFromEmbedderData(index));
}
@@ -1340,13 +1354,14 @@ static Local<ObjectTemplate> ObjectTemplateNew(
Local<ObjectTemplate> FunctionTemplate::PrototypeTemplate() {
i::Isolate* i_isolate = Utils::OpenHandle(this)->GetIsolate();
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
- i::Handle<i::Object> result(Utils::OpenHandle(this)->prototype_template(),
+ i::Handle<i::Object> result(Utils::OpenHandle(this)->GetPrototypeTemplate(),
i_isolate);
if (result->IsUndefined(i_isolate)) {
// Do not cache prototype objects.
result = Utils::OpenHandle(
*ObjectTemplateNew(i_isolate, Local<FunctionTemplate>(), true));
- Utils::OpenHandle(this)->set_prototype_template(*result);
+ i::FunctionTemplateInfo::SetPrototypeTemplate(
+ i_isolate, Utils::OpenHandle(this), result);
}
return ToApiHandle<ObjectTemplate>(result);
}
@@ -1357,9 +1372,10 @@ void FunctionTemplate::SetPrototypeProviderTemplate(
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
i::Handle<i::Object> result = Utils::OpenHandle(*prototype_provider);
auto info = Utils::OpenHandle(this);
- CHECK(info->prototype_template()->IsUndefined(i_isolate));
- CHECK(info->parent_template()->IsUndefined(i_isolate));
- info->set_prototype_provider_template(*result);
+ CHECK(info->GetPrototypeTemplate()->IsUndefined(i_isolate));
+ CHECK(info->GetParentTemplate()->IsUndefined(i_isolate));
+ i::FunctionTemplateInfo::SetPrototypeProviderTemplate(i_isolate, info,
+ result);
}
static void EnsureNotInstantiated(i::Handle<i::FunctionTemplateInfo> info,
@@ -1374,8 +1390,9 @@ void FunctionTemplate::Inherit(v8::Local<FunctionTemplate> value) {
EnsureNotInstantiated(info, "v8::FunctionTemplate::Inherit");
i::Isolate* i_isolate = info->GetIsolate();
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
- CHECK(info->prototype_provider_template()->IsUndefined(i_isolate));
- info->set_parent_template(*Utils::OpenHandle(*value));
+ CHECK(info->GetPrototypeProviderTemplate()->IsUndefined(i_isolate));
+ i::FunctionTemplateInfo::SetParentTemplate(i_isolate, info,
+ Utils::OpenHandle(*value));
}
static Local<FunctionTemplate> FunctionTemplateNew(
@@ -1429,10 +1446,10 @@ Local<FunctionTemplate> FunctionTemplate::New(
MaybeLocal<FunctionTemplate> FunctionTemplate::FromSnapshot(Isolate* isolate,
size_t index) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
- i::FixedArray* serialized_objects = i_isolate->heap()->serialized_objects();
+ i::FixedArray serialized_objects = i_isolate->heap()->serialized_objects();
int int_index = static_cast<int>(index);
if (int_index < serialized_objects->length()) {
- i::Object* info = serialized_objects->get(int_index);
+ i::Object info = serialized_objects->get(int_index);
if (info->IsFunctionTemplateInfo()) {
return Utils::ToLocal(i::Handle<i::FunctionTemplateInfo>(
i::FunctionTemplateInfo::cast(info), i_isolate));
@@ -1541,13 +1558,14 @@ Local<ObjectTemplate> FunctionTemplate::InstanceTemplate() {
}
i::Isolate* isolate = handle->GetIsolate();
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
- if (handle->instance_template()->IsUndefined(isolate)) {
+ if (handle->GetInstanceTemplate()->IsUndefined(isolate)) {
Local<ObjectTemplate> templ =
ObjectTemplate::New(isolate, ToApiHandle<FunctionTemplate>(handle));
- handle->set_instance_template(*Utils::OpenHandle(*templ));
+ i::FunctionTemplateInfo::SetInstanceTemplate(isolate, handle,
+ Utils::OpenHandle(*templ));
}
i::Handle<i::ObjectTemplateInfo> result(
- i::ObjectTemplateInfo::cast(handle->instance_template()), isolate);
+ i::ObjectTemplateInfo::cast(handle->GetInstanceTemplate()), isolate);
return Utils::ToLocal(result);
}
@@ -1644,10 +1662,10 @@ Local<ObjectTemplate> ObjectTemplate::New(
MaybeLocal<ObjectTemplate> ObjectTemplate::FromSnapshot(Isolate* isolate,
size_t index) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
- i::FixedArray* serialized_objects = i_isolate->heap()->serialized_objects();
+ i::FixedArray serialized_objects = i_isolate->heap()->serialized_objects();
int int_index = static_cast<int>(index);
if (int_index < serialized_objects->length()) {
- i::Object* info = serialized_objects->get(int_index);
+ i::Object info = serialized_objects->get(int_index);
if (info->IsObjectTemplateInfo()) {
return Utils::ToLocal(i::Handle<i::ObjectTemplateInfo>(
i::ObjectTemplateInfo::cast(info), i_isolate));
@@ -1661,15 +1679,16 @@ MaybeLocal<ObjectTemplate> ObjectTemplate::FromSnapshot(Isolate* isolate,
static i::Handle<i::FunctionTemplateInfo> EnsureConstructor(
i::Isolate* isolate,
ObjectTemplate* object_template) {
- i::Object* obj = Utils::OpenHandle(object_template)->constructor();
+ i::Object obj = Utils::OpenHandle(object_template)->constructor();
if (!obj->IsUndefined(isolate)) {
- i::FunctionTemplateInfo* info = i::FunctionTemplateInfo::cast(obj);
+ i::FunctionTemplateInfo info = i::FunctionTemplateInfo::cast(obj);
return i::Handle<i::FunctionTemplateInfo>(info, isolate);
}
Local<FunctionTemplate> templ =
FunctionTemplate::New(reinterpret_cast<Isolate*>(isolate));
i::Handle<i::FunctionTemplateInfo> constructor = Utils::OpenHandle(*templ);
- constructor->set_instance_template(*Utils::OpenHandle(object_template));
+ i::FunctionTemplateInfo::SetInstanceTemplate(
+ isolate, constructor, Utils::OpenHandle(object_template));
Utils::OpenHandle(object_template)->set_constructor(*constructor);
return constructor;
}
@@ -1843,7 +1862,7 @@ static void ObjectTemplateSetNamedPropertyHandler(
auto obj =
CreateNamedInterceptorInfo(isolate, getter, setter, query, descriptor,
remover, enumerator, definer, data, flags);
- cons->set_named_property_handler(*obj);
+ i::FunctionTemplateInfo::SetNamedPropertyHandler(isolate, cons, obj);
}
void ObjectTemplate::SetHandler(
@@ -1879,15 +1898,15 @@ void ObjectTemplate::SetAccessCheckCallback(AccessCheckCallback callback,
i::Handle<i::AccessCheckInfo>::cast(struct_info);
SET_FIELD_WRAPPED(isolate, info, set_callback, callback);
- info->set_named_interceptor(nullptr);
- info->set_indexed_interceptor(nullptr);
+ info->set_named_interceptor(i::Object());
+ info->set_indexed_interceptor(i::Object());
if (data.IsEmpty()) {
data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
}
info->set_data(*Utils::OpenHandle(*data));
- cons->set_access_check_info(*info);
+ i::FunctionTemplateInfo::SetAccessCheckInfo(isolate, cons, info);
cons->set_needs_access_check(true);
}
@@ -1926,7 +1945,7 @@ void ObjectTemplate::SetAccessCheckCallbackAndHandler(
}
info->set_data(*Utils::OpenHandle(*data));
- cons->set_access_check_info(*info);
+ i::FunctionTemplateInfo::SetAccessCheckInfo(isolate, cons, info);
cons->set_needs_access_check(true);
}
@@ -1941,7 +1960,7 @@ void ObjectTemplate::SetHandler(
isolate, config.getter, config.setter, config.query, config.descriptor,
config.deleter, config.enumerator, config.definer, config.data,
config.flags);
- cons->set_indexed_property_handler(*obj);
+ i::FunctionTemplateInfo::SetIndexedPropertyHandler(isolate, cons, obj);
}
void ObjectTemplate::SetCallAsFunctionHandler(FunctionCallback callback,
@@ -1958,7 +1977,7 @@ void ObjectTemplate::SetCallAsFunctionHandler(FunctionCallback callback,
data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
}
obj->set_data(*Utils::OpenHandle(*data));
- cons->set_instance_call_handler(*obj);
+ i::FunctionTemplateInfo::SetInstanceCallHandler(isolate, cons, obj);
}
int ObjectTemplate::InternalFieldCount() {
@@ -2064,7 +2083,7 @@ Local<Value> UnboundScript::GetScriptName() {
i::Isolate* isolate = obj->GetIsolate();
LOG_API(isolate, UnboundScript, GetName);
if (obj->script()->IsScript()) {
- i::Object* name = i::Script::cast(obj->script())->name();
+ i::Object name = i::Script::cast(obj->script())->name();
return Utils::ToLocal(i::Handle<i::Object>(name, isolate));
} else {
return Local<String>();
@@ -2078,7 +2097,7 @@ Local<Value> UnboundScript::GetSourceURL() {
i::Isolate* isolate = obj->GetIsolate();
LOG_API(isolate, UnboundScript, GetSourceURL);
if (obj->script()->IsScript()) {
- i::Object* url = i::Script::cast(obj->script())->source_url();
+ i::Object url = i::Script::cast(obj->script())->source_url();
return Utils::ToLocal(i::Handle<i::Object>(url, isolate));
} else {
return Local<String>();
@@ -2092,7 +2111,7 @@ Local<Value> UnboundScript::GetSourceMappingURL() {
i::Isolate* isolate = obj->GetIsolate();
LOG_API(isolate, UnboundScript, GetSourceMappingURL);
if (obj->script()->IsScript()) {
- i::Object* url = i::Script::cast(obj->script())->source_mapping_url();
+ i::Object url = i::Script::cast(obj->script())->source_mapping_url();
return Utils::ToLocal(i::Handle<i::Object>(url, isolate));
} else {
return Local<String>();
@@ -2138,7 +2157,7 @@ Local<PrimitiveArray> ScriptOrModule::GetHostDefinedOptions() {
Local<UnboundScript> Script::GetUnboundScript() {
i::Handle<i::Object> obj = Utils::OpenHandle(this);
- i::SharedFunctionInfo* sfi = i::JSFunction::cast(*obj)->shared();
+ i::SharedFunctionInfo sfi = i::JSFunction::cast(*obj)->shared();
i::Isolate* isolate = sfi->GetIsolate();
return ToApiHandle<UnboundScript>(i::handle(sfi, isolate));
}
@@ -2331,18 +2350,6 @@ MaybeLocal<UnboundScript> ScriptCompiler::CompileUnboundInternal(
ENTER_V8_NO_SCRIPT(isolate, v8_isolate->GetCurrentContext(), ScriptCompiler,
CompileUnbound, MaybeLocal<UnboundScript>(),
InternalEscapableScope);
- // ProduceParserCache, ProduceCodeCache, ProduceFullCodeCache and
- // ConsumeParserCache are not supported. They are present only for
- // backward compatability. All these options behave as kNoCompileOptions.
- if (options == kConsumeParserCache) {
- // We do not support parser caches anymore. Just set cached_data to
- // rejected to signal an error.
- options = kNoCompileOptions;
- source->cached_data->rejected = true;
- } else if (options == kProduceParserCache || options == kProduceCodeCache ||
- options == kProduceFullCodeCache) {
- options = kNoCompileOptions;
- }
i::ScriptData* script_data = nullptr;
if (options == kConsumeCodeCache) {
@@ -2417,44 +2424,28 @@ MaybeLocal<Module> ScriptCompiler::CompileModule(
return ToApiHandle<Module>(i_isolate->factory()->NewModule(shared));
}
-
-class IsIdentifierHelper {
- public:
- IsIdentifierHelper() : is_identifier_(false), first_char_(true) {}
-
- bool Check(i::String* string) {
- i::ConsString* cons_string = i::String::VisitFlat(this, string, 0);
- if (cons_string == nullptr) return is_identifier_;
- // We don't support cons strings here.
- return false;
- }
- void VisitOneByteString(const uint8_t* chars, int length) {
- for (int i = 0; i < length; ++i) {
- if (first_char_) {
- first_char_ = false;
- is_identifier_ = unicode_cache_.IsIdentifierStart(chars[0]);
- } else {
- is_identifier_ &= unicode_cache_.IsIdentifierPart(chars[i]);
- }
+namespace {
+bool IsIdentifier(i::Isolate* isolate, i::Handle<i::String> string) {
+ string = i::String::Flatten(isolate, string);
+ const int length = string->length();
+ if (length == 0) return false;
+ if (!i::IsIdentifierStart(string->Get(0))) return false;
+ i::DisallowHeapAllocation no_gc;
+ i::String::FlatContent flat = string->GetFlatContent(no_gc);
+ if (flat.IsOneByte()) {
+ auto vector = flat.ToOneByteVector();
+ for (int i = 1; i < length; i++) {
+ if (!i::IsIdentifierPart(vector[i])) return false;
}
- }
- void VisitTwoByteString(const uint16_t* chars, int length) {
- for (int i = 0; i < length; ++i) {
- if (first_char_) {
- first_char_ = false;
- is_identifier_ = unicode_cache_.IsIdentifierStart(chars[0]);
- } else {
- is_identifier_ &= unicode_cache_.IsIdentifierPart(chars[i]);
- }
+ } else {
+ auto vector = flat.ToUC16Vector();
+ for (int i = 1; i < length; i++) {
+ if (!i::IsIdentifierPart(vector[i])) return false;
}
}
-
- private:
- bool is_identifier_;
- bool first_char_;
- i::UnicodeCache unicode_cache_;
- DISALLOW_COPY_AND_ASSIGN(IsIdentifierHelper);
-};
+ return true;
+}
+} // anonymous namespace
MaybeLocal<Function> ScriptCompiler::CompileFunctionInContext(
Local<Context> v8_context, Source* source, size_t arguments_count,
@@ -2479,9 +2470,8 @@ MaybeLocal<Function> ScriptCompiler::CompileFunctionInContext(
i::Handle<i::FixedArray> arguments_list =
isolate->factory()->NewFixedArray(static_cast<int>(arguments_count));
for (int i = 0; i < static_cast<int>(arguments_count); i++) {
- IsIdentifierHelper helper;
i::Handle<i::String> argument = Utils::OpenHandle(*arguments[i]);
- if (!helper.Check(*argument)) return Local<Function>();
+ if (!IsIdentifier(isolate, argument)) return Local<Function>();
arguments_list->set(i, *argument);
}
@@ -2636,9 +2626,8 @@ v8::TryCatch::TryCatch(v8::Isolate* isolate)
has_terminated_(false) {
ResetInternal();
// Special handling for simulators which have a separate JS stack.
- js_stack_comparable_address_ =
- reinterpret_cast<void*>(i::SimulatorStack::RegisterCTryCatch(
- isolate_, i::GetCurrentStackPosition()));
+ js_stack_comparable_address_ = reinterpret_cast<void*>(
+ i::SimulatorStack::RegisterJSStackComparableAddress(isolate_));
isolate_->RegisterTryCatchHandler(this);
}
@@ -2657,7 +2646,7 @@ v8::TryCatch::~TryCatch() {
isolate_->RestorePendingMessageFromTryCatch(this);
}
isolate_->UnregisterTryCatchHandler(this);
- i::SimulatorStack::UnregisterCTryCatch(isolate_);
+ i::SimulatorStack::UnregisterJSStackComparableAddress(isolate_);
reinterpret_cast<Isolate*>(isolate_)->ThrowException(exc);
DCHECK(!isolate_->thread_local_top()->rethrowing_message_);
} else {
@@ -2668,7 +2657,7 @@ v8::TryCatch::~TryCatch() {
isolate_->CancelScheduledExceptionFromTryCatch(this);
}
isolate_->UnregisterTryCatchHandler(this);
- i::SimulatorStack::UnregisterCTryCatch(isolate_);
+ i::SimulatorStack::UnregisterJSStackComparableAddress(isolate_);
}
}
@@ -2678,7 +2667,8 @@ void v8::TryCatch::operator delete(void*, size_t) { base::OS::Abort(); }
void v8::TryCatch::operator delete[](void*, size_t) { base::OS::Abort(); }
bool v8::TryCatch::HasCaught() const {
- return !reinterpret_cast<i::Object*>(exception_)->IsTheHole(isolate_);
+ return !i::Object(reinterpret_cast<i::Address>(exception_))
+ ->IsTheHole(isolate_);
}
@@ -2702,7 +2692,7 @@ v8::Local<v8::Value> v8::TryCatch::ReThrow() {
v8::Local<Value> v8::TryCatch::Exception() const {
if (HasCaught()) {
// Check for out of memory exception.
- i::Object* exception = reinterpret_cast<i::Object*>(exception_);
+ i::Object exception(reinterpret_cast<i::Address>(exception_));
return v8::Utils::ToLocal(i::Handle<i::Object>(exception, isolate_));
} else {
return v8::Local<Value>();
@@ -2712,7 +2702,7 @@ v8::Local<Value> v8::TryCatch::Exception() const {
MaybeLocal<Value> v8::TryCatch::StackTrace(Local<Context> context) const {
if (!HasCaught()) return v8::Local<Value>();
- i::Object* raw_obj = reinterpret_cast<i::Object*>(exception_);
+ i::Object raw_obj(reinterpret_cast<i::Address>(exception_));
if (!raw_obj->IsJSObject()) return v8::Local<Value>();
PREPARE_FOR_EXECUTION(context, TryCatch, StackTrace, Value);
i::Handle<i::JSObject> obj(i::JSObject::cast(raw_obj), isolate_);
@@ -2730,7 +2720,7 @@ MaybeLocal<Value> v8::TryCatch::StackTrace(Local<Context> context) const {
v8::Local<v8::Message> v8::TryCatch::Message() const {
- i::Object* message = reinterpret_cast<i::Object*>(message_obj_);
+ i::Object message(reinterpret_cast<i::Address>(message_obj_));
DCHECK(message->IsJSMessageObject() || message->IsTheHole(isolate_));
if (HasCaught() && !message->IsTheHole(isolate_)) {
return v8::Utils::MessageToLocal(i::Handle<i::Object>(message, isolate_));
@@ -2752,9 +2742,9 @@ void v8::TryCatch::Reset() {
void v8::TryCatch::ResetInternal() {
- i::Object* the_hole = i::ReadOnlyRoots(isolate_).the_hole_value();
- exception_ = the_hole;
- message_obj_ = the_hole;
+ i::Object the_hole = i::ReadOnlyRoots(isolate_).the_hole_value();
+ exception_ = reinterpret_cast<void*>(the_hole->ptr());
+ message_obj_ = reinterpret_cast<void*>(the_hole->ptr());
}
@@ -2994,20 +2984,6 @@ bool StackFrame::IsWasm() const { return Utils::OpenHandle(this)->is_wasm(); }
// --- J S O N ---
-MaybeLocal<Value> JSON::Parse(Isolate* v8_isolate, Local<String> json_string) {
- PREPARE_FOR_EXECUTION(v8_isolate->GetCurrentContext(), JSON, Parse, Value);
- i::Handle<i::String> string = Utils::OpenHandle(*json_string);
- i::Handle<i::String> source = i::String::Flatten(isolate, 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);
-}
-
MaybeLocal<Value> JSON::Parse(Local<Context> context,
Local<String> json_string) {
PREPARE_FOR_EXECUTION(context, JSON, Parse, Value);
@@ -3064,7 +3040,7 @@ Maybe<uint32_t> ValueSerializer::Delegate::GetSharedArrayBufferId(
}
Maybe<uint32_t> ValueSerializer::Delegate::GetWasmModuleTransferId(
- Isolate* v8_isolate, Local<WasmCompiledModule> module) {
+ Isolate* v8_isolate, Local<WasmModuleObject> module) {
return Nothing<uint32_t>();
}
@@ -3113,10 +3089,6 @@ Maybe<bool> ValueSerializer::WriteValue(Local<Context> context,
return result;
}
-std::vector<uint8_t> ValueSerializer::ReleaseBuffer() {
- return private_->serializer.ReleaseBuffer();
-}
-
std::pair<uint8_t*, size_t> ValueSerializer::Release() {
return private_->serializer.Release();
}
@@ -3127,12 +3099,6 @@ void ValueSerializer::TransferArrayBuffer(uint32_t transfer_id,
Utils::OpenHandle(*array_buffer));
}
-void ValueSerializer::TransferSharedArrayBuffer(
- uint32_t transfer_id, Local<SharedArrayBuffer> shared_array_buffer) {
- private_->serializer.TransferArrayBuffer(
- transfer_id, Utils::OpenHandle(*shared_array_buffer));
-}
-
void ValueSerializer::WriteUint32(uint32_t value) {
private_->serializer.WriteUint32(value);
}
@@ -3158,13 +3124,13 @@ MaybeLocal<Object> ValueDeserializer::Delegate::ReadHostObject(
return MaybeLocal<Object>();
}
-MaybeLocal<WasmCompiledModule> ValueDeserializer::Delegate::GetWasmModuleFromId(
+MaybeLocal<WasmModuleObject> ValueDeserializer::Delegate::GetWasmModuleFromId(
Isolate* v8_isolate, uint32_t id) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
isolate->ScheduleThrow(*isolate->factory()->NewError(
isolate->error_function(),
i::MessageTemplate::kDataCloneDeserializationError));
- return MaybeLocal<WasmCompiledModule>();
+ return MaybeLocal<WasmModuleObject>();
}
MaybeLocal<SharedArrayBuffer>
@@ -3644,6 +3610,10 @@ MaybeLocal<Uint32> Value::ToUint32(Local<Context> context) const {
RETURN_ESCAPED(result);
}
+i::Isolate* i::IsolateFromNeverReadOnlySpaceObject(i::Address obj) {
+ return i::NeverReadOnlySpaceObject::GetIsolate(
+ i::HeapObject::cast(i::Object(obj)));
+}
void i::Internals::CheckInitializedImpl(v8::Isolate* external_isolate) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
@@ -3776,10 +3746,10 @@ void v8::Proxy::CheckCast(Value* that) {
"Could not convert to proxy");
}
-void v8::WasmCompiledModule::CheckCast(Value* that) {
+void v8::WasmModuleObject::CheckCast(Value* that) {
Utils::ApiCheck(that->IsWebAssemblyCompiledModule(),
- "v8::WasmCompiledModule::Cast",
- "Could not convert to wasm compiled module");
+ "v8::WasmModuleObject::Cast",
+ "Could not convert to wasm module object");
}
void v8::ArrayBuffer::CheckCast(Value* that) {
@@ -4411,7 +4381,7 @@ MaybeLocal<Array> v8::Object::GetPropertyNames(
accumulator.GetKeys(static_cast<i::GetKeysConversion>(key_conversion));
DCHECK(self->map()->EnumLength() == i::kInvalidEnumCacheSentinel ||
self->map()->EnumLength() == 0 ||
- self->map()->instance_descriptors()->GetEnumCache()->keys() != *value);
+ self->map()->instance_descriptors()->enum_cache()->keys() != *value);
auto result = isolate->factory()->NewJSArrayWithElements(value);
RETURN_ESCAPED(Utils::ToLocal(result));
}
@@ -4497,11 +4467,6 @@ Maybe<bool> v8::Object::Delete(Local<Context> context, Local<Value> key) {
}
}
-bool v8::Object::Delete(v8::Local<Value> key) {
- auto context = ContextFromNeverReadOnlySpaceObject(Utils::OpenHandle(this));
- return Delete(context, key).FromMaybe(false);
-}
-
Maybe<bool> v8::Object::DeletePrivate(Local<Context> context,
Local<Private> key) {
auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
@@ -4541,12 +4506,6 @@ Maybe<bool> v8::Object::Has(Local<Context> context, Local<Value> key) {
}
-bool v8::Object::Has(v8::Local<Value> key) {
- auto context = ContextFromNeverReadOnlySpaceObject(Utils::OpenHandle(this));
- return Has(context, key).FromMaybe(false);
-}
-
-
Maybe<bool> v8::Object::HasPrivate(Local<Context> context, Local<Private> key) {
return HasOwnProperty(context, Local<Name>(reinterpret_cast<Name*>(*key)));
}
@@ -4897,7 +4856,7 @@ MaybeLocal<Value> Object::CallAsFunction(Local<Context> context,
i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
auto self = Utils::OpenHandle(this);
auto recv_obj = Utils::OpenHandle(*recv);
- STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Object**));
+ STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Handle<i::Object>));
i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
Local<Value> result;
has_pending_exception = !ToLocal<Value>(
@@ -4915,7 +4874,7 @@ MaybeLocal<Value> Object::CallAsConstructor(Local<Context> context, int argc,
InternalEscapableScope);
i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
auto self = Utils::OpenHandle(this);
- STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Object**));
+ STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Handle<i::Object>));
i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
Local<Value> result;
has_pending_exception = !ToLocal<Value>(
@@ -4961,17 +4920,17 @@ MaybeLocal<Object> Function::NewInstanceWithSideEffectType(
InternalEscapableScope);
i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
auto self = Utils::OpenHandle(this);
- STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Object**));
+ STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Handle<i::Object>));
bool should_set_has_no_side_effect =
side_effect_type == SideEffectType::kHasNoSideEffect &&
isolate->debug_execution_mode() == i::DebugInfo::kSideEffects;
if (should_set_has_no_side_effect) {
CHECK(self->IsJSFunction() &&
i::JSFunction::cast(*self)->shared()->IsApiFunction());
- i::Object* obj =
+ i::Object obj =
i::JSFunction::cast(*self)->shared()->get_api_func_data()->call_code();
if (obj->IsCallHandlerInfo()) {
- i::CallHandlerInfo* handler_info = i::CallHandlerInfo::cast(obj);
+ i::CallHandlerInfo handler_info = i::CallHandlerInfo::cast(obj);
if (!handler_info->IsSideEffectFreeCallHandlerInfo()) {
handler_info->SetNextCallHasNoSideEffect();
}
@@ -4982,10 +4941,10 @@ MaybeLocal<Object> Function::NewInstanceWithSideEffectType(
has_pending_exception = !ToLocal<Object>(
i::Execution::New(isolate, self, self, argc, args), &result);
if (should_set_has_no_side_effect) {
- i::Object* obj =
+ i::Object obj =
i::JSFunction::cast(*self)->shared()->get_api_func_data()->call_code();
if (obj->IsCallHandlerInfo()) {
- i::CallHandlerInfo* handler_info = i::CallHandlerInfo::cast(obj);
+ i::CallHandlerInfo handler_info = i::CallHandlerInfo::cast(obj);
if (has_pending_exception) {
// Restore the map if an exception prevented restoration.
handler_info->NextCallHasNoSideEffect();
@@ -5012,7 +4971,7 @@ MaybeLocal<v8::Value> Function::Call(Local<Context> context,
Utils::ApiCheck(!self.is_null(), "v8::Function::Call",
"Function to be called is a null pointer");
i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
- STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Object**));
+ STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Handle<i::Object>));
i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
Local<Value> result;
has_pending_exception = !ToLocal<Value>(
@@ -5215,9 +5174,9 @@ static inline const uint16_t* Align(const uint16_t* chars) {
class ContainsOnlyOneByteHelper {
public:
ContainsOnlyOneByteHelper() : is_one_byte_(true) {}
- bool Check(i::String* string) {
- i::ConsString* cons_string = i::String::VisitFlat(this, string, 0);
- if (cons_string == nullptr) return is_one_byte_;
+ bool Check(i::String string) {
+ i::ConsString cons_string = i::String::VisitFlat(this, string, 0);
+ if (cons_string.is_null()) return is_one_byte_;
return CheckCons(cons_string);
}
void VisitOneByteString(const uint8_t* chars, int length) {
@@ -5256,20 +5215,18 @@ class ContainsOnlyOneByteHelper {
}
private:
- bool CheckCons(i::ConsString* cons_string) {
+ bool CheckCons(i::ConsString cons_string) {
while (true) {
// Check left side if flat.
- i::String* left = cons_string->first();
- i::ConsString* left_as_cons =
- i::String::VisitFlat(this, left, 0);
+ i::String left = cons_string->first();
+ i::ConsString left_as_cons = i::String::VisitFlat(this, left, 0);
if (!is_one_byte_) return false;
// Check right side if flat.
- i::String* right = cons_string->second();
- i::ConsString* right_as_cons =
- i::String::VisitFlat(this, right, 0);
+ i::String right = cons_string->second();
+ i::ConsString right_as_cons = i::String::VisitFlat(this, right, 0);
if (!is_one_byte_) return false;
// Standard recurse/iterate trick.
- if (left_as_cons != nullptr && right_as_cons != nullptr) {
+ if (!left_as_cons.is_null() && !right_as_cons.is_null()) {
if (left->length() < right->length()) {
CheckCons(left_as_cons);
cons_string = right_as_cons;
@@ -5282,12 +5239,12 @@ class ContainsOnlyOneByteHelper {
continue;
}
// Descend left in place.
- if (left_as_cons != nullptr) {
+ if (!left_as_cons.is_null()) {
cons_string = left_as_cons;
continue;
}
// Descend right in place.
- if (right_as_cons != nullptr) {
+ if (!right_as_cons.is_null()) {
cons_string = right_as_cons;
continue;
}
@@ -5314,7 +5271,7 @@ int String::Utf8Length(Isolate* isolate) const {
int length = str->length();
if (length == 0) return 0;
i::DisallowHeapAllocation no_gc;
- i::String::FlatContent flat = str->GetFlatContent();
+ i::String::FlatContent flat = str->GetFlatContent(no_gc);
DCHECK(flat.IsFlat());
int utf8_length = 0;
if (flat.IsOneByte()) {
@@ -5332,204 +5289,133 @@ int String::Utf8Length(Isolate* isolate) const {
return utf8_length;
}
-class Utf8WriterVisitor {
- public:
- Utf8WriterVisitor(
- char* buffer,
- int capacity,
- bool skip_capacity_check,
- bool replace_invalid_utf8)
- : early_termination_(false),
- last_character_(unibrow::Utf16::kNoPreviousCharacter),
- buffer_(buffer),
- start_(buffer),
- capacity_(capacity),
- skip_capacity_check_(capacity == -1 || skip_capacity_check),
- replace_invalid_utf8_(replace_invalid_utf8),
- utf16_chars_read_(0) {
- }
-
- static int WriteEndCharacter(uint16_t character,
- int last_character,
- int remaining,
- char* const buffer,
- bool replace_invalid_utf8) {
- DCHECK_GT(remaining, 0);
- // We can't use a local buffer here because Encode needs to modify
- // previous characters in the stream. We know, however, that
- // exactly one character will be advanced.
- if (unibrow::Utf16::IsSurrogatePair(last_character, character)) {
- int written = unibrow::Utf8::Encode(buffer, character, last_character,
- replace_invalid_utf8);
- DCHECK_EQ(written, 1);
- return written;
- }
- // Use a scratch buffer to check the required characters.
- char temp_buffer[unibrow::Utf8::kMaxEncodedSize];
- // Can't encode using last_character as gcc has array bounds issues.
- int written = unibrow::Utf8::Encode(temp_buffer, character,
- unibrow::Utf16::kNoPreviousCharacter,
- replace_invalid_utf8);
- // Won't fit.
- if (written > remaining) return 0;
- // Copy over the character from temp_buffer.
- for (int j = 0; j < written; j++) {
- buffer[j] = temp_buffer[j];
+namespace {
+// Writes the flat content of a string to a buffer. This is done in two phases.
+// The first phase calculates a pessimistic estimate (writable_length) on how
+// many code units can be safely written without exceeding the buffer capacity
+// and without leaving at a lone surrogate. The estimated number of code units
+// is then written out in one go, and the reported byte usage is used to
+// correct the estimate. This is repeated until the estimate becomes <= 0 or
+// all code units have been written out. The second phase writes out code
+// units until the buffer capacity is reached, would be exceeded by the next
+// unit, or all code units have been written out.
+template <typename Char>
+static int WriteUtf8Impl(i::Vector<const Char> string, char* write_start,
+ int write_capacity, int options,
+ int* utf16_chars_read_out) {
+ bool write_null = !(options & v8::String::NO_NULL_TERMINATION);
+ bool replace_invalid_utf8 = (options & v8::String::REPLACE_INVALID_UTF8);
+ char* current_write = write_start;
+ const Char* read_start = string.start();
+ int read_index = 0;
+ int read_length = string.length();
+ int prev_char = unibrow::Utf16::kNoPreviousCharacter;
+ // Do a fast loop where there is no exit capacity check.
+ // Need enough space to write everything but one character.
+ STATIC_ASSERT(unibrow::Utf16::kMaxExtraUtf8BytesForOneUtf16CodeUnit == 3);
+ static const int kMaxSizePerChar = sizeof(Char) == 1 ? 2 : 3;
+ while (read_index < read_length) {
+ int up_to = read_length;
+ if (write_capacity != -1) {
+ int remaining_capacity =
+ write_capacity - static_cast<int>(current_write - write_start);
+ int writable_length =
+ (remaining_capacity - kMaxSizePerChar) / kMaxSizePerChar;
+ // Need to drop into slow loop.
+ if (writable_length <= 0) break;
+ up_to = std::min(up_to, read_index + writable_length);
}
- return written;
- }
-
- // Visit writes out a group of code units (chars) of a v8::String to the
- // internal buffer_. This is done in two phases. The first phase calculates a
- // pesimistic estimate (writable_length) on how many code units can be safely
- // written without exceeding the buffer capacity and without writing the last
- // code unit (it could be a lead surrogate). The estimated number of code
- // units is then written out in one go, and the reported byte usage is used
- // to correct the estimate. This is repeated until the estimate becomes <= 0
- // or all code units have been written out. The second phase writes out code
- // units until the buffer capacity is reached, would be exceeded by the next
- // unit, or all units have been written out.
- template<typename Char>
- void Visit(const Char* chars, const int length) {
- DCHECK(!early_termination_);
- if (length == 0) return;
- // Copy state to stack.
- char* buffer = buffer_;
- int last_character = sizeof(Char) == 1
- ? unibrow::Utf16::kNoPreviousCharacter
- : last_character_;
- int i = 0;
- // Do a fast loop where there is no exit capacity check.
- while (true) {
- int fast_length;
- if (skip_capacity_check_) {
- fast_length = length;
+ // Write the characters to the stream.
+ if (sizeof(Char) == 1) {
+ // Simply memcpy if we only have ASCII characters.
+ uint8_t char_mask = 0;
+ for (int i = read_index; i < up_to; i++) char_mask |= read_start[i];
+ if ((char_mask & 0x80) == 0) {
+ int copy_length = up_to - read_index;
+ memcpy(current_write, read_start + read_index, copy_length);
+ current_write += copy_length;
+ read_index = up_to;
} else {
- int remaining_capacity = capacity_ - static_cast<int>(buffer - start_);
- // Need enough space to write everything but one character.
- STATIC_ASSERT(unibrow::Utf16::kMaxExtraUtf8BytesForOneUtf16CodeUnit ==
- 3);
- int max_size_per_char = sizeof(Char) == 1 ? 2 : 3;
- int writable_length =
- (remaining_capacity - max_size_per_char)/max_size_per_char;
- // Need to drop into slow loop.
- if (writable_length <= 0) break;
- fast_length = i + writable_length;
- if (fast_length > length) fast_length = length;
- }
- // Write the characters to the stream.
- if (sizeof(Char) == 1) {
- for (; i < fast_length; i++) {
- buffer += unibrow::Utf8::EncodeOneByte(
- buffer, static_cast<uint8_t>(*chars++));
- DCHECK(capacity_ == -1 || (buffer - start_) <= capacity_);
- }
- } else {
- for (; i < fast_length; i++) {
- uint16_t character = *chars++;
- buffer += unibrow::Utf8::Encode(buffer, character, last_character,
- replace_invalid_utf8_);
- last_character = character;
- DCHECK(capacity_ == -1 || (buffer - start_) <= capacity_);
+ for (; read_index < up_to; read_index++) {
+ current_write += unibrow::Utf8::EncodeOneByte(
+ current_write, static_cast<uint8_t>(read_start[read_index]));
+ DCHECK(write_capacity == -1 ||
+ (current_write - write_start) <= write_capacity);
}
}
- // Array is fully written. Exit.
- if (fast_length == length) {
- // Write state back out to object.
- last_character_ = last_character;
- buffer_ = buffer;
- utf16_chars_read_ += length;
- return;
+ } else {
+ for (; read_index < up_to; read_index++) {
+ uint16_t character = read_start[read_index];
+ current_write += unibrow::Utf8::Encode(current_write, character,
+ prev_char, replace_invalid_utf8);
+ prev_char = character;
+ DCHECK(write_capacity == -1 ||
+ (current_write - write_start) <= write_capacity);
}
}
- DCHECK(!skip_capacity_check_);
- // Slow loop. Must check capacity on each iteration.
- int remaining_capacity = capacity_ - static_cast<int>(buffer - start_);
+ }
+ if (read_index < read_length) {
+ DCHECK_NE(-1, write_capacity);
+ // Aborted due to limited capacity. Check capacity on each iteration.
+ int remaining_capacity =
+ write_capacity - static_cast<int>(current_write - write_start);
DCHECK_GE(remaining_capacity, 0);
- for (; i < length && remaining_capacity > 0; i++) {
- uint16_t character = *chars++;
- // remaining_capacity is <= 3 bytes at this point, so we do not write out
- // an umatched lead surrogate.
- if (replace_invalid_utf8_ && unibrow::Utf16::IsLeadSurrogate(character)) {
- early_termination_ = true;
- break;
- }
- int written = WriteEndCharacter(character,
- last_character,
- remaining_capacity,
- buffer,
- replace_invalid_utf8_);
- if (written == 0) {
- early_termination_ = true;
- break;
+ for (; read_index < read_length && remaining_capacity > 0; read_index++) {
+ uint32_t character = read_start[read_index];
+ int written = 0;
+ // We can't use a local buffer here because Encode needs to modify
+ // previous characters in the stream. We know, however, that
+ // exactly one character will be advanced.
+ if (unibrow::Utf16::IsSurrogatePair(prev_char, character)) {
+ written = unibrow::Utf8::Encode(current_write, character, prev_char,
+ replace_invalid_utf8);
+ DCHECK_EQ(written, 1);
+ } else {
+ // Use a scratch buffer to check the required characters.
+ char temp_buffer[unibrow::Utf8::kMaxEncodedSize];
+ // Encoding a surrogate pair to Utf8 always takes 4 bytes.
+ static const int kSurrogatePairEncodedSize =
+ static_cast<int>(unibrow::Utf8::kMaxEncodedSize);
+ // For REPLACE_INVALID_UTF8, catch the case where we cut off in the
+ // middle of a surrogate pair. Abort before encoding the pair instead.
+ if (replace_invalid_utf8 &&
+ remaining_capacity < kSurrogatePairEncodedSize &&
+ unibrow::Utf16::IsLeadSurrogate(character) &&
+ read_index + 1 < read_length &&
+ unibrow::Utf16::IsTrailSurrogate(read_start[read_index + 1])) {
+ write_null = false;
+ break;
+ }
+ // Can't encode using prev_char as gcc has array bounds issues.
+ written = unibrow::Utf8::Encode(temp_buffer, character,
+ unibrow::Utf16::kNoPreviousCharacter,
+ replace_invalid_utf8);
+ if (written > remaining_capacity) {
+ // Won't fit. Abort and do not null-terminate the result.
+ write_null = false;
+ break;
+ }
+ // Copy over the character from temp_buffer.
+ for (int i = 0; i < written; i++) current_write[i] = temp_buffer[i];
}
- buffer += written;
- remaining_capacity -= written;
- last_character = character;
- }
- // Write state back out to object.
- last_character_ = last_character;
- buffer_ = buffer;
- utf16_chars_read_ += i;
- }
-
- inline bool IsDone() {
- return early_termination_;
- }
- inline void VisitOneByteString(const uint8_t* chars, int length) {
- Visit(chars, length);
- }
-
- inline void VisitTwoByteString(const uint16_t* chars, int length) {
- Visit(chars, length);
- }
-
- int CompleteWrite(bool write_null, int* utf16_chars_read_out) {
- // Write out number of utf16 characters written to the stream.
- if (utf16_chars_read_out != nullptr) {
- *utf16_chars_read_out = utf16_chars_read_;
- }
- // Only null terminate if all of the string was written and there's space.
- if (write_null &&
- !early_termination_ &&
- (capacity_ == -1 || (buffer_ - start_) < capacity_)) {
- *buffer_++ = '\0';
+ current_write += written;
+ remaining_capacity -= written;
+ prev_char = character;
}
- return static_cast<int>(buffer_ - start_);
}
- private:
- bool early_termination_;
- int last_character_;
- char* buffer_;
- char* const start_;
- int capacity_;
- bool const skip_capacity_check_;
- bool const replace_invalid_utf8_;
- int utf16_chars_read_;
- DISALLOW_IMPLICIT_CONSTRUCTORS(Utf8WriterVisitor);
-};
-
+ // Write out number of utf16 characters written to the stream.
+ if (utf16_chars_read_out != nullptr) *utf16_chars_read_out = read_index;
-static bool RecursivelySerializeToUtf8(i::String* current,
- Utf8WriterVisitor* writer,
- int recursion_budget) {
- while (!writer->IsDone()) {
- i::ConsString* cons_string = i::String::VisitFlat(writer, current);
- if (cons_string == nullptr) return true; // Leaf node.
- if (recursion_budget <= 0) return false;
- // Must write the left branch first.
- i::String* first = cons_string->first();
- bool success = RecursivelySerializeToUtf8(first,
- writer,
- recursion_budget - 1);
- if (!success) return false;
- // Inline tail recurse for right branch.
- current = cons_string->second();
+ // Only null-terminate if there's space.
+ if (write_null && (write_capacity == -1 ||
+ (current_write - write_start) < write_capacity)) {
+ *current_write++ = '\0';
}
- return true;
+ return static_cast<int>(current_write - write_start);
}
+} // anonymous namespace
int String::WriteUtf8(Isolate* v8_isolate, char* buffer, int capacity,
int* nchars_ref, int options) const {
@@ -5537,43 +5423,16 @@ int String::WriteUtf8(Isolate* v8_isolate, char* buffer, int capacity,
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
LOG_API(isolate, String, WriteUtf8);
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
- str = i::String::Flatten(isolate, str); // Flatten the string for efficiency.
- const int string_length = str->length();
- bool write_null = !(options & NO_NULL_TERMINATION);
- bool replace_invalid_utf8 = (options & REPLACE_INVALID_UTF8);
- int max16BitCodeUnitSize = unibrow::Utf8::kMax16BitCodeUnitSize;
- // First check if we can just write the string without checking capacity.
- if (capacity == -1 || capacity / max16BitCodeUnitSize >= string_length) {
- Utf8WriterVisitor writer(buffer, capacity, true, replace_invalid_utf8);
- const int kMaxRecursion = 100;
- bool success = RecursivelySerializeToUtf8(*str, &writer, kMaxRecursion);
- 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 = Utf8Length(v8_isolate);
- if (utf8_bytes <= capacity) {
- // one-byte fast path.
- if (utf8_bytes == string_length) {
- WriteOneByte(v8_isolate, reinterpret_cast<uint8_t*>(buffer), 0,
- capacity, options);
- if (nchars_ref != nullptr) *nchars_ref = string_length;
- if (write_null && (utf8_bytes+1 <= capacity)) {
- return string_length + 1;
- }
- return string_length;
- }
- if (write_null && (utf8_bytes+1 > capacity)) {
- options |= NO_NULL_TERMINATION;
- }
- // Recurse once without a capacity limit.
- // This will get into the first branch above.
- // TODO(dcarney) Check max left rec. in Utf8Length and fall through.
- return WriteUtf8(v8_isolate, buffer, -1, nchars_ref, options);
- }
+ str = i::String::Flatten(isolate, str);
+ i::DisallowHeapAllocation no_gc;
+ i::String::FlatContent content = str->GetFlatContent(no_gc);
+ if (content.IsOneByte()) {
+ return WriteUtf8Impl<uint8_t>(content.ToOneByteVector(), buffer, capacity,
+ options, nchars_ref);
+ } else {
+ return WriteUtf8Impl<uint16_t>(content.ToUC16Vector(), buffer, capacity,
+ options, nchars_ref);
}
- Utf8WriterVisitor writer(buffer, capacity, false, replace_invalid_utf8);
- i::String::VisitFlat(&writer, *str);
- return writer.CompleteWrite(write_null, nchars_ref);
}
template <typename CharType>
@@ -5627,7 +5486,7 @@ bool v8::String::IsExternalOneByte() const {
void v8::String::VerifyExternalStringResource(
v8::String::ExternalStringResource* value) const {
i::DisallowHeapAllocation no_allocation;
- i::String* str = *Utils::OpenHandle(this);
+ i::String str = *Utils::OpenHandle(this);
const v8::String::ExternalStringResource* expected;
if (str->IsThinString()) {
@@ -5646,7 +5505,7 @@ void v8::String::VerifyExternalStringResource(
void v8::String::VerifyExternalStringResourceBase(
v8::String::ExternalStringResourceBase* value, Encoding encoding) const {
i::DisallowHeapAllocation no_allocation;
- i::String* str = *Utils::OpenHandle(this);
+ i::String str = *Utils::OpenHandle(this);
const v8::String::ExternalStringResourceBase* expected;
Encoding expectedEncoding;
@@ -5674,18 +5533,17 @@ void v8::String::VerifyExternalStringResourceBase(
String::ExternalStringResource* String::GetExternalStringResourceSlow() const {
i::DisallowHeapAllocation no_allocation;
typedef internal::Internals I;
- ExternalStringResource* result = nullptr;
- i::String* str = *Utils::OpenHandle(this);
+ i::String str = *Utils::OpenHandle(this);
if (str->IsThinString()) {
str = i::ThinString::cast(str)->actual();
}
if (i::StringShape(str).IsExternalTwoByte()) {
- void* value = I::ReadField<void*>(str, I::kStringResourceOffset);
- result = reinterpret_cast<String::ExternalStringResource*>(value);
+ void* value = I::ReadRawField<void*>(str.ptr(), I::kStringResourceOffset);
+ return reinterpret_cast<String::ExternalStringResource*>(value);
}
- return result;
+ return nullptr;
}
String::ExternalStringResourceBase* String::GetExternalStringResourceBaseSlow(
@@ -5693,48 +5551,36 @@ String::ExternalStringResourceBase* String::GetExternalStringResourceBaseSlow(
i::DisallowHeapAllocation no_allocation;
typedef internal::Internals I;
ExternalStringResourceBase* resource = nullptr;
- i::String* str = *Utils::OpenHandle(this);
+ i::String str = *Utils::OpenHandle(this);
if (str->IsThinString()) {
str = i::ThinString::cast(str)->actual();
}
- int type = I::GetInstanceType(str) & I::kFullStringRepresentationMask;
+ internal::Address string = str.ptr();
+ int type = I::GetInstanceType(string) & I::kFullStringRepresentationMask;
*encoding_out = static_cast<Encoding>(type & I::kStringEncodingMask);
if (i::StringShape(str).IsExternalOneByte() ||
i::StringShape(str).IsExternalTwoByte()) {
- void* value = I::ReadField<void*>(str, I::kStringResourceOffset);
+ void* value = I::ReadRawField<void*>(string, I::kStringResourceOffset);
resource = static_cast<ExternalStringResourceBase*>(value);
}
return resource;
}
-const String::ExternalOneByteStringResource*
-String::GetExternalOneByteStringResourceSlow() const {
- i::DisallowHeapAllocation no_allocation;
- i::String* str = *Utils::OpenHandle(this);
-
- if (str->IsThinString()) {
- str = i::ThinString::cast(str)->actual();
- }
-
- if (i::StringShape(str).IsExternalOneByte()) {
- const void* resource = i::ExternalOneByteString::cast(str)->resource();
- return reinterpret_cast<const ExternalOneByteStringResource*>(resource);
- }
- return nullptr;
-}
-
const v8::String::ExternalOneByteStringResource*
v8::String::GetExternalOneByteStringResource() const {
i::DisallowHeapAllocation no_allocation;
- i::String* str = *Utils::OpenHandle(this);
+ i::String str = *Utils::OpenHandle(this);
if (i::StringShape(str).IsExternalOneByte()) {
- const void* resource = i::ExternalOneByteString::cast(str)->resource();
- return reinterpret_cast<const ExternalOneByteStringResource*>(resource);
- } else {
- return GetExternalOneByteStringResourceSlow();
+ return i::ExternalOneByteString::cast(str)->resource();
+ } else if (str->IsThinString()) {
+ str = i::ThinString::cast(str)->actual();
+ if (i::StringShape(str).IsExternalOneByte()) {
+ return i::ExternalOneByteString::cast(str)->resource();
+ }
}
+ return nullptr;
}
@@ -5744,12 +5590,18 @@ Local<Value> Symbol::Name() const {
i::Isolate* isolate;
if (!i::Isolate::FromWritableHeapObject(*sym, &isolate)) {
// If the Symbol is in RO_SPACE, then its name must be too. Since RO_SPACE
- // objects are immovable we can use the Handle(T**) constructor with the
- // address of the name field in the Symbol object without needing an
+ // objects are immovable we can use the Handle(Address*) constructor with
+ // the address of the name field in the Symbol object without needing an
// isolate.
- i::Handle<i::HeapObject> ro_name(reinterpret_cast<i::HeapObject**>(
+#ifdef V8_COMPRESS_POINTERS
+ // Compressed fields can't serve as handle locations.
+ // TODO(ishell): get Isolate as a parameter.
+ isolate = i::Isolate::Current();
+#else
+ i::Handle<i::HeapObject> ro_name(reinterpret_cast<i::Address*>(
sym->GetFieldAddress(i::Symbol::kNameOffset)));
return Utils::ToLocal(ro_name);
+#endif
}
i::Handle<i::Object> name(sym->name(), isolate);
@@ -5822,9 +5674,8 @@ Local<Value> v8::Object::SlowGetInternalField(int index) {
i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
const char* location = "v8::Object::GetInternalField()";
if (!InternalFieldOK(obj, index, location)) return Local<Value>();
- i::Handle<i::Object> value(
- i::Handle<i::JSObject>::cast(obj)->GetEmbedderField(index),
- obj->GetIsolate());
+ i::Handle<i::Object> value(i::JSObject::cast(*obj)->GetEmbedderField(index),
+ obj->GetIsolate());
return Utils::ToLocal(value);
}
@@ -5840,16 +5691,20 @@ void* v8::Object::SlowGetAlignedPointerFromInternalField(int index) {
i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
const char* location = "v8::Object::GetAlignedPointerFromInternalField()";
if (!InternalFieldOK(obj, index, location)) return nullptr;
- return DecodeSmiToAligned(
- i::Handle<i::JSObject>::cast(obj)->GetEmbedderField(index), location);
+ void* result;
+ Utils::ApiCheck(i::EmbedderDataSlot(i::JSObject::cast(*obj), index)
+ .ToAlignedPointer(&result),
+ location, "Unaligned pointer");
+ return result;
}
void v8::Object::SetAlignedPointerInInternalField(int index, void* value) {
i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
const char* location = "v8::Object::SetAlignedPointerInInternalField()";
if (!InternalFieldOK(obj, index, location)) return;
- i::Handle<i::JSObject>::cast(obj)->SetEmbedderField(
- index, EncodeAlignedAsSmi(value, location));
+ Utils::ApiCheck(i::EmbedderDataSlot(i::JSObject::cast(*obj), index)
+ .store_aligned_pointer(value),
+ location, "Unaligned pointer");
DCHECK_EQ(value, GetAlignedPointerFromInternalField(index));
}
@@ -5858,8 +5713,8 @@ void v8::Object::SetAlignedPointerInInternalFields(int argc, int indices[],
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_embedder_fields = object->GetEmbedderFieldCount();
+ i::JSObject js_obj = i::JSObject::cast(*obj);
+ int nof_embedder_fields = js_obj->GetEmbedderFieldCount();
for (int i = 0; i < argc; i++) {
int index = indices[i];
if (!Utils::ApiCheck(index < nof_embedder_fields, location,
@@ -5867,21 +5722,22 @@ void v8::Object::SetAlignedPointerInInternalFields(int argc, int indices[],
return;
}
void* value = values[i];
- object->SetEmbedderField(index, EncodeAlignedAsSmi(value, location));
+ Utils::ApiCheck(
+ i::EmbedderDataSlot(js_obj, index).store_aligned_pointer(value),
+ location, "Unaligned pointer");
DCHECK_EQ(value, GetAlignedPointerFromInternalField(index));
}
}
-static void* ExternalValue(i::Object* obj) {
+static void* ExternalValue(i::Object obj) {
// Obscure semantics for undefined, but somehow checked in our unit tests...
if (obj->IsUndefined()) {
return nullptr;
}
- i::Object* foreign = i::JSObject::cast(obj)->GetEmbedderField(0);
+ i::Object foreign = i::JSObject::cast(obj)->GetEmbedderField(0);
return reinterpret_cast<void*>(i::Foreign::cast(foreign)->foreign_address());
}
-
// --- E n v i r o n m e n t ---
@@ -5903,15 +5759,29 @@ bool v8::V8::Initialize() {
return true;
}
-#if V8_OS_POSIX
-bool V8::TryHandleSignal(int signum, void* info, void* context) {
-#if V8_OS_LINUX && V8_TARGET_ARCH_X64 && !V8_OS_ANDROID
- return v8::internal::trap_handler::TryHandleSignal(
- signum, static_cast<siginfo_t*>(info), static_cast<ucontext_t*>(context));
-#else // V8_OS_LINUX && V8_TARGET_ARCH_X64 && !V8_OS_ANDROID
+#if V8_OS_LINUX || V8_OS_MACOSX
+bool TryHandleWebAssemblyTrapPosix(int sig_code, siginfo_t* info,
+ void* context) {
+#if V8_TARGET_ARCH_X64 && !V8_OS_ANDROID
+ return i::trap_handler::TryHandleSignal(sig_code, info, context);
+#else
return false;
#endif
}
+
+bool V8::TryHandleSignal(int signum, void* info, void* context) {
+ return TryHandleWebAssemblyTrapPosix(
+ signum, reinterpret_cast<siginfo_t*>(info), context);
+}
+#endif
+
+#if V8_OS_WIN
+bool TryHandleWebAssemblyTrapWindows(EXCEPTION_POINTERS* exception) {
+#if V8_TARGET_ARCH_X64
+ return i::trap_handler::TryHandleWasmTrap(exception);
+#endif
+ return false;
+}
#endif
bool V8::RegisterDefaultSignalHandler() {
@@ -5932,7 +5802,6 @@ void v8::V8::SetReturnAddressLocationResolver(
i::StackFrame::SetReturnAddressLocationResolver(return_address_resolver);
}
-
bool v8::V8::Dispose() {
i::V8::TearDown();
#ifdef V8_USE_EXTERNAL_STARTUP_DATA
@@ -6058,8 +5927,8 @@ static i::Handle<ObjectType> CreateEnvironment(
// Set the global template to be the prototype template of
// global proxy template.
- proxy_constructor->set_prototype_template(
- *Utils::OpenHandle(*global_template));
+ i::FunctionTemplateInfo::SetPrototypeTemplate(
+ isolate, proxy_constructor, Utils::OpenHandle(*global_template));
proxy_template->SetInternalFieldCount(
global_template->InternalFieldCount());
@@ -6067,32 +5936,37 @@ static i::Handle<ObjectType> 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(isolate)) {
- proxy_constructor->set_access_check_info(
- global_constructor->access_check_info());
+ if (!global_constructor->GetAccessCheckInfo()->IsUndefined(isolate)) {
+ i::FunctionTemplateInfo::SetAccessCheckInfo(
+ isolate, proxy_constructor,
+ i::handle(global_constructor->GetAccessCheckInfo(), isolate));
proxy_constructor->set_needs_access_check(
global_constructor->needs_access_check());
global_constructor->set_needs_access_check(false);
- global_constructor->set_access_check_info(
- i::ReadOnlyRoots(isolate).undefined_value());
+ i::FunctionTemplateInfo::SetAccessCheckInfo(
+ isolate, global_constructor,
+ i::ReadOnlyRoots(isolate).undefined_value_handle());
}
// Same for other interceptors. If the global constructor has
// interceptors, we need to replace them temporarily with noop
// interceptors, so the map is correctly marked as having interceptors,
// but we don't invoke any.
- if (!global_constructor->named_property_handler()->IsUndefined(isolate)) {
+ if (!global_constructor->GetNamedPropertyHandler()->IsUndefined(
+ isolate)) {
named_interceptor =
- handle(global_constructor->named_property_handler(), isolate);
- global_constructor->set_named_property_handler(
- i::ReadOnlyRoots(isolate).noop_interceptor_info());
+ handle(global_constructor->GetNamedPropertyHandler(), isolate);
+ i::FunctionTemplateInfo::SetNamedPropertyHandler(
+ isolate, global_constructor,
+ i::ReadOnlyRoots(isolate).noop_interceptor_info_handle());
}
- if (!global_constructor->indexed_property_handler()->IsUndefined(
+ if (!global_constructor->GetIndexedPropertyHandler()->IsUndefined(
isolate)) {
indexed_interceptor =
- handle(global_constructor->indexed_property_handler(), isolate);
- global_constructor->set_indexed_property_handler(
- i::ReadOnlyRoots(isolate).noop_interceptor_info());
+ handle(global_constructor->GetIndexedPropertyHandler(), isolate);
+ i::FunctionTemplateInfo::SetIndexedPropertyHandler(
+ isolate, global_constructor,
+ i::ReadOnlyRoots(isolate).noop_interceptor_info_handle());
}
}
@@ -6111,12 +5985,15 @@ static i::Handle<ObjectType> CreateEnvironment(
if (!maybe_global_template.IsEmpty()) {
DCHECK(!global_constructor.is_null());
DCHECK(!proxy_constructor.is_null());
- global_constructor->set_access_check_info(
- proxy_constructor->access_check_info());
+ i::FunctionTemplateInfo::SetAccessCheckInfo(
+ isolate, global_constructor,
+ i::handle(proxy_constructor->GetAccessCheckInfo(), isolate));
global_constructor->set_needs_access_check(
proxy_constructor->needs_access_check());
- global_constructor->set_named_property_handler(*named_interceptor);
- global_constructor->set_indexed_property_handler(*indexed_interceptor);
+ i::FunctionTemplateInfo::SetNamedPropertyHandler(
+ isolate, global_constructor, named_interceptor);
+ i::FunctionTemplateInfo::SetIndexedPropertyHandler(
+ isolate, global_constructor, indexed_interceptor);
}
}
// Leave V8.
@@ -6186,9 +6063,9 @@ MaybeLocal<Object> v8::Context::NewRemoteContext(
"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()),
+ i::AccessCheckInfo::cast(global_constructor->GetAccessCheckInfo()),
isolate);
- Utils::ApiCheck(access_check_info->named_interceptor() != nullptr,
+ Utils::ApiCheck(access_check_info->named_interceptor() != i::Object(),
"v8::Context::NewRemoteContext",
"Global template needs to have access check handlers.");
i::Handle<i::JSGlobalProxy> global_proxy =
@@ -6219,7 +6096,7 @@ void v8::Context::UseDefaultSecurityToken() {
Local<Value> v8::Context::GetSecurityToken() {
i::Handle<i::Context> env = Utils::OpenHandle(this);
i::Isolate* isolate = env->GetIsolate();
- i::Object* security_token = env->security_token();
+ i::Object security_token = env->security_token();
i::Handle<i::Object> token_handle(security_token, isolate);
return Utils::ToLocal(token_handle);
}
@@ -6284,11 +6161,11 @@ void Context::SetErrorMessageForCodeGenerationFromStrings(Local<String> error) {
}
namespace {
-i::Object** GetSerializedDataFromFixedArray(i::Isolate* isolate,
- i::FixedArray* list, size_t index) {
+i::Address* GetSerializedDataFromFixedArray(i::Isolate* isolate,
+ i::FixedArray list, size_t index) {
if (index < static_cast<size_t>(list->length())) {
int int_index = static_cast<int>(index);
- i::Object* object = list->get(int_index);
+ i::Object object = list->get(int_index);
if (!object->IsTheHole(isolate)) {
list->set_the_hole(isolate, int_index);
// Shrink the list so that the last element is not the hole (unless it's
@@ -6304,10 +6181,10 @@ i::Object** GetSerializedDataFromFixedArray(i::Isolate* isolate,
}
} // anonymous namespace
-i::Object** Context::GetDataFromSnapshotOnce(size_t index) {
+i::Address* Context::GetDataFromSnapshotOnce(size_t index) {
auto context = Utils::OpenHandle(this);
i::Isolate* i_isolate = context->GetIsolate();
- i::FixedArray* list = context->serialized_objects();
+ i::FixedArray list = context->serialized_objects();
return GetSerializedDataFromFixedArray(i_isolate, list, index);
}
@@ -6323,7 +6200,9 @@ MaybeLocal<v8::Object> ObjectTemplate::NewInstance(Local<Context> context) {
Local<v8::Object> ObjectTemplate::NewInstance() {
- auto context = ContextFromNeverReadOnlySpaceObject(Utils::OpenHandle(this));
+ Local<Context> context =
+ reinterpret_cast<v8::Isolate*>(Utils::OpenHandle(this)->GetIsolate())
+ ->GetCurrentContext();
RETURN_TO_LOCAL_UNCHECKED(NewInstance(context), Object);
}
@@ -6363,7 +6242,9 @@ MaybeLocal<v8::Function> FunctionTemplate::GetFunction(Local<Context> context) {
Local<v8::Function> FunctionTemplate::GetFunction() {
- auto context = ContextFromNeverReadOnlySpaceObject(Utils::OpenHandle(this));
+ Local<Context> context =
+ reinterpret_cast<v8::Isolate*>(Utils::OpenHandle(this)->GetIsolate())
+ ->GetCurrentContext();
RETURN_TO_LOCAL_UNCHECKED(GetFunction(context), Function);
}
@@ -6378,8 +6259,8 @@ MaybeLocal<v8::Object> FunctionTemplate::NewRemoteInstance() {
"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,
+ i::AccessCheckInfo::cast(constructor->GetAccessCheckInfo()), isolate);
+ Utils::ApiCheck(access_check_info->named_interceptor() != i::Object(),
"v8::FunctionTemplate::NewRemoteInstance",
"InstanceTemplate needs to have access check handlers.");
i::Handle<i::JSObject> object;
@@ -6617,7 +6498,7 @@ Local<String> v8::String::NewExternal(
bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) {
i::DisallowHeapAllocation no_allocation;
- i::String* obj = *Utils::OpenHandle(this);
+ i::String obj = *Utils::OpenHandle(this);
if (obj->IsThinString()) {
obj = i::ThinString::cast(obj)->actual();
@@ -6646,7 +6527,7 @@ bool v8::String::MakeExternal(
v8::String::ExternalOneByteStringResource* resource) {
i::DisallowHeapAllocation no_allocation;
- i::String* obj = *Utils::OpenHandle(this);
+ i::String obj = *Utils::OpenHandle(this);
if (obj->IsThinString()) {
obj = i::ThinString::cast(obj)->actual();
@@ -6673,7 +6554,7 @@ bool v8::String::MakeExternal(
bool v8::String::CanMakeExternal() {
i::DisallowHeapAllocation no_allocation;
- i::String* obj = *Utils::OpenHandle(this);
+ i::String obj = *Utils::OpenHandle(this);
if (obj->IsThinString()) {
obj = i::ThinString::cast(obj)->actual();
@@ -6708,6 +6589,64 @@ Local<v8::Object> v8::Object::New(Isolate* isolate) {
return Utils::ToLocal(obj);
}
+Local<v8::Object> v8::Object::New(Isolate* isolate,
+ Local<Value> prototype_or_null,
+ Local<Name>* names, Local<Value>* values,
+ size_t length) {
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ i::Handle<i::Object> proto = Utils::OpenHandle(*prototype_or_null);
+ if (!Utils::ApiCheck(proto->IsNull() || proto->IsJSReceiver(),
+ "v8::Object::New", "prototype must be null or object")) {
+ return Local<v8::Object>();
+ }
+ LOG_API(i_isolate, Object, New);
+ ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
+
+ // We assume that this API is mostly used to create objects with named
+ // properties, and so we default to creating a properties backing store
+ // large enough to hold all of them, while we start with no elements
+ // (see http://bit.ly/v8-fast-object-create-cpp for the motivation).
+ i::Handle<i::NameDictionary> properties =
+ i::NameDictionary::New(i_isolate, static_cast<int>(length));
+ i::Handle<i::FixedArrayBase> elements =
+ i_isolate->factory()->empty_fixed_array();
+ for (size_t i = 0; i < length; ++i) {
+ i::Handle<i::Name> name = Utils::OpenHandle(*names[i]);
+ i::Handle<i::Object> value = Utils::OpenHandle(*values[i]);
+
+ // See if the {name} is a valid array index, in which case we need to
+ // add the {name}/{value} pair to the {elements}, otherwise they end
+ // up in the {properties} backing store.
+ uint32_t index;
+ if (name->AsArrayIndex(&index)) {
+ // If this is the first element, allocate a proper
+ // dictionary elements backing store for {elements}.
+ if (!elements->IsNumberDictionary()) {
+ elements =
+ i::NumberDictionary::New(i_isolate, static_cast<int>(length));
+ }
+ elements = i::NumberDictionary::Set(
+ i_isolate, i::Handle<i::NumberDictionary>::cast(elements), index,
+ value);
+ } else {
+ // Internalize the {name} first.
+ name = i_isolate->factory()->InternalizeName(name);
+ int const entry = properties->FindEntry(i_isolate, name);
+ if (entry == i::NameDictionary::kNotFound) {
+ // Add the {name}/{value} pair as a new entry.
+ properties = i::NameDictionary::Add(i_isolate, properties, name, value,
+ i::PropertyDetails::Empty());
+ } else {
+ // Overwrite the {entry} with the {value}.
+ properties->ValueAtPut(entry, *value);
+ }
+ }
+ }
+ i::Handle<i::JSObject> obj =
+ i_isolate->factory()->NewSlowJSObjectWithPropertiesAndElements(
+ proto, properties, elements);
+ return Utils::ToLocal(obj);
+}
Local<v8::Value> v8::NumberObject::New(Isolate* isolate, double value) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
@@ -6827,12 +6766,6 @@ MaybeLocal<v8::Value> v8::Date::New(Local<Context> context, double time) {
}
-Local<v8::Value> v8::Date::New(Isolate* isolate, double time) {
- auto context = isolate->GetCurrentContext();
- RETURN_TO_LOCAL_UNCHECKED(New(context, time), Value);
-}
-
-
double v8::Date::ValueOf() const {
i::Handle<i::Object> obj = Utils::OpenHandle(this);
i::Handle<i::JSDate> jsdate = i::Handle<i::JSDate>::cast(obj);
@@ -6847,17 +6780,14 @@ void v8::Date::DateTimeConfigurationChangeNotification(Isolate* isolate) {
LOG_API(i_isolate, Date, DateTimeConfigurationChangeNotification);
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
i_isolate->date_cache()->ResetDateCache();
- if (!i_isolate->eternal_handles()->Exists(
- i::EternalHandles::DATE_CACHE_VERSION)) {
- return;
- }
- i::Handle<i::FixedArray> date_cache_version =
- i::Handle<i::FixedArray>::cast(i_isolate->eternal_handles()->GetSingleton(
- i::EternalHandles::DATE_CACHE_VERSION));
- DCHECK_EQ(1, date_cache_version->length());
- CHECK(date_cache_version->get(0)->IsSmi());
- date_cache_version->set(
- 0, i::Smi::FromInt(i::Smi::ToInt(date_cache_version->get(0)) + 1));
+#ifdef V8_INTL_SUPPORT
+ i_isolate->clear_cached_icu_object(
+ i::Isolate::ICUObjectCacheType::kDefaultSimpleDateFormat);
+ i_isolate->clear_cached_icu_object(
+ i::Isolate::ICUObjectCacheType::kDefaultSimpleDateFormatForTime);
+ i_isolate->clear_cached_icu_object(
+ i::Isolate::ICUObjectCacheType::kDefaultSimpleDateFormatForDate);
+#endif // V8_INTL_SUPPORT
}
@@ -6931,7 +6861,7 @@ Local<v8::Array> v8::Array::New(Isolate* isolate, Local<Value>* elements,
uint32_t v8::Array::Length() const {
i::Handle<i::JSArray> obj = Utils::OpenHandle(this);
- i::Object* length = obj->length();
+ i::Object length = obj->length();
if (length->IsSmi()) {
return i::Smi::ToInt(length);
} else {
@@ -7028,12 +6958,7 @@ enum class MapAsArrayKind {
kValues = i::JS_MAP_VALUE_ITERATOR_TYPE
};
-enum class SetAsArrayKind {
- kEntries = i::JS_SET_KEY_VALUE_ITERATOR_TYPE,
- kValues = i::JS_SET_VALUE_ITERATOR_TYPE
-};
-
-i::Handle<i::JSArray> MapAsArray(i::Isolate* isolate, i::Object* table_obj,
+i::Handle<i::JSArray> MapAsArray(i::Isolate* isolate, i::Object table_obj,
int offset, MapAsArrayKind kind) {
i::Factory* factory = isolate->factory();
i::Handle<i::OrderedHashMap> table(i::OrderedHashMap::cast(table_obj),
@@ -7049,9 +6974,9 @@ i::Handle<i::JSArray> MapAsArray(i::Isolate* isolate, i::Object* table_obj,
int result_index = 0;
{
i::DisallowHeapAllocation no_gc;
- i::Oddball* the_hole = i::ReadOnlyRoots(isolate).the_hole_value();
+ i::Oddball the_hole = i::ReadOnlyRoots(isolate).the_hole_value();
for (int i = offset; i < capacity; ++i) {
- i::Object* key = table->KeyAt(i);
+ i::Object key = table->KeyAt(i);
if (key == the_hole) continue;
if (collect_keys) result->set(result_index++, key);
if (collect_values) result->set(result_index++, table->ValueAt(i));
@@ -7141,26 +7066,24 @@ Maybe<bool> Set::Delete(Local<Context> context, Local<Value> key) {
}
namespace {
-i::Handle<i::JSArray> SetAsArray(i::Isolate* isolate, i::Object* table_obj,
- int offset, SetAsArrayKind kind) {
+i::Handle<i::JSArray> SetAsArray(i::Isolate* isolate, i::Object table_obj,
+ int offset) {
i::Factory* factory = isolate->factory();
i::Handle<i::OrderedHashSet> table(i::OrderedHashSet::cast(table_obj),
isolate);
// Elements skipped by |offset| may already be deleted.
int capacity = table->UsedCapacity();
- const bool collect_key_values = kind == SetAsArrayKind::kEntries;
- int max_length = (capacity - offset) * (collect_key_values ? 2 : 1);
+ int max_length = capacity - offset;
if (max_length == 0) return factory->NewJSArray(0);
i::Handle<i::FixedArray> result = factory->NewFixedArray(max_length);
int result_index = 0;
{
i::DisallowHeapAllocation no_gc;
- i::Oddball* the_hole = i::ReadOnlyRoots(isolate).the_hole_value();
+ i::Oddball the_hole = i::ReadOnlyRoots(isolate).the_hole_value();
for (int i = offset; i < capacity; ++i) {
- i::Object* key = table->KeyAt(i);
+ i::Object key = table->KeyAt(i);
if (key == the_hole) continue;
result->set(result_index++, key);
- if (collect_key_values) result->set(result_index++, key);
}
}
DCHECK_GE(max_length, result_index);
@@ -7176,8 +7099,7 @@ Local<Array> Set::AsArray() const {
i::Isolate* isolate = obj->GetIsolate();
LOG_API(isolate, Set, AsArray);
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
- return Utils::ToLocal(
- SetAsArray(isolate, obj->table(), 0, SetAsArrayKind::kValues));
+ return Utils::ToLocal(SetAsArray(isolate, obj->table(), 0));
}
@@ -7262,6 +7184,20 @@ MaybeLocal<Promise> Promise::Then(Local<Context> context,
RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
}
+MaybeLocal<Promise> Promise::Then(Local<Context> context,
+ Local<Function> on_fulfilled,
+ Local<Function> on_rejected) {
+ PREPARE_FOR_EXECUTION(context, Promise, Then, Promise);
+ auto self = Utils::OpenHandle(this);
+ i::Handle<i::Object> argv[] = {Utils::OpenHandle(*on_fulfilled),
+ Utils::OpenHandle(*on_rejected)};
+ i::Handle<i::Object> result;
+ has_pending_exception = !i::Execution::Call(isolate, isolate->promise_then(),
+ self, arraysize(argv), argv)
+ .ToHandle(&result);
+ RETURN_ON_FAILED_EXECUTION(Promise);
+ RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
+}
bool Promise::HasHandler() {
i::Handle<i::JSReceiver> promise = Utils::OpenHandle(this);
@@ -7294,6 +7230,11 @@ Promise::PromiseState Promise::State() {
return static_cast<PromiseState>(js_promise->status());
}
+void Promise::MarkAsHandled() {
+ i::Handle<i::JSPromise> js_promise = Utils::OpenHandle(this);
+ js_promise->set_has_handler(true);
+}
+
Local<Value> Proxy::GetTarget() {
i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
i::Handle<i::Object> target(self->target(), self->GetIsolate());
@@ -7332,39 +7273,64 @@ MaybeLocal<Proxy> Proxy::New(Local<Context> context, Local<Object> local_target,
RETURN_ESCAPED(result);
}
-WasmCompiledModule::BufferReference WasmCompiledModule::GetWasmWireBytesRef() {
- i::Handle<i::WasmModuleObject> obj =
- i::Handle<i::WasmModuleObject>::cast(Utils::OpenHandle(this));
- i::Vector<const uint8_t> bytes_vec = obj->native_module()->wire_bytes();
+CompiledWasmModule::CompiledWasmModule(
+ std::shared_ptr<internal::wasm::NativeModule> native_module)
+ : native_module_(std::move(native_module)) {
+ CHECK_NOT_NULL(native_module_);
+}
+
+OwnedBuffer CompiledWasmModule::Serialize() {
+ i::wasm::WasmSerializer wasm_serializer(native_module_.get());
+ size_t buffer_size = wasm_serializer.GetSerializedNativeModuleSize();
+ std::unique_ptr<uint8_t[]> buffer(new uint8_t[buffer_size]);
+ if (!wasm_serializer.SerializeNativeModule({buffer.get(), buffer_size}))
+ return {};
+ return {std::move(buffer), buffer_size};
+}
+
+MemorySpan<const uint8_t> CompiledWasmModule::GetWireBytesRef() {
+ i::Vector<const uint8_t> bytes_vec = native_module_->wire_bytes();
return {bytes_vec.start(), bytes_vec.size()};
}
-WasmCompiledModule::TransferrableModule
-WasmCompiledModule::GetTransferrableModule() {
+WasmModuleObject::BufferReference WasmModuleObject::GetWasmWireBytesRef() {
+ return GetCompiledModule().GetWireBytesRef();
+}
+
+WasmModuleObject::TransferrableModule
+WasmModuleObject::GetTransferrableModule() {
if (i::FLAG_wasm_shared_code) {
i::Handle<i::WasmModuleObject> obj =
i::Handle<i::WasmModuleObject>::cast(Utils::OpenHandle(this));
- return TransferrableModule(obj->managed_native_module()->get());
+ return TransferrableModule(obj->shared_native_module());
} else {
- WasmCompiledModule::SerializedModule serialized_module = Serialize();
- BufferReference wire_bytes_ref = GetWasmWireBytesRef();
- size_t wire_size = wire_bytes_ref.size;
+ CompiledWasmModule compiled_module = GetCompiledModule();
+ OwnedBuffer serialized_module = compiled_module.Serialize();
+ MemorySpan<const uint8_t> wire_bytes_ref =
+ compiled_module.GetWireBytesRef();
+ size_t wire_size = wire_bytes_ref.size();
std::unique_ptr<uint8_t[]> wire_bytes_copy(new uint8_t[wire_size]);
- memcpy(wire_bytes_copy.get(), wire_bytes_ref.start, wire_size);
+ memcpy(wire_bytes_copy.get(), wire_bytes_ref.data(), wire_size);
return TransferrableModule(std::move(serialized_module),
{std::move(wire_bytes_copy), wire_size});
}
}
-MaybeLocal<WasmCompiledModule> WasmCompiledModule::FromTransferrableModule(
+CompiledWasmModule WasmModuleObject::GetCompiledModule() {
+ i::Handle<i::WasmModuleObject> obj =
+ i::Handle<i::WasmModuleObject>::cast(Utils::OpenHandle(this));
+ return Utils::Convert(obj->shared_native_module());
+}
+
+MaybeLocal<WasmModuleObject> WasmModuleObject::FromTransferrableModule(
Isolate* isolate,
- const WasmCompiledModule::TransferrableModule& transferrable_module) {
+ const WasmModuleObject::TransferrableModule& transferrable_module) {
if (i::FLAG_wasm_shared_code) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
i::Handle<i::WasmModuleObject> module_object =
i_isolate->wasm_engine()->ImportNativeModule(
i_isolate, transferrable_module.shared_module_);
- return Local<WasmCompiledModule>::Cast(
+ return Local<WasmModuleObject>::Cast(
Utils::ToLocal(i::Handle<i::JSObject>::cast(module_object)));
} else {
return Deserialize(isolate, AsReference(transferrable_module.serialized_),
@@ -7372,60 +7338,54 @@ MaybeLocal<WasmCompiledModule> WasmCompiledModule::FromTransferrableModule(
}
}
-WasmCompiledModule::SerializedModule WasmCompiledModule::Serialize() {
- i::Handle<i::WasmModuleObject> obj =
- i::Handle<i::WasmModuleObject>::cast(Utils::OpenHandle(this));
- i::wasm::NativeModule* native_module = obj->native_module();
- i::wasm::WasmSerializer wasm_serializer(obj->GetIsolate(), native_module);
- size_t buffer_size = wasm_serializer.GetSerializedNativeModuleSize();
- std::unique_ptr<uint8_t[]> buffer(new uint8_t[buffer_size]);
- if (wasm_serializer.SerializeNativeModule({buffer.get(), buffer_size}))
- return {std::move(buffer), buffer_size};
- return {};
+WasmModuleObject::SerializedModule WasmModuleObject::Serialize() {
+ // TODO(clemensh): Deprecated; remove after M-73 branch.
+ OwnedBuffer serialized = GetCompiledModule().Serialize();
+ return {std::move(serialized.buffer), serialized.size};
}
-MaybeLocal<WasmCompiledModule> WasmCompiledModule::Deserialize(
- Isolate* isolate, WasmCompiledModule::BufferReference serialized_module,
- WasmCompiledModule::BufferReference wire_bytes) {
+MaybeLocal<WasmModuleObject> WasmModuleObject::Deserialize(
+ Isolate* isolate, MemorySpan<const uint8_t> serialized_module,
+ MemorySpan<const uint8_t> wire_bytes) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
i::MaybeHandle<i::WasmModuleObject> maybe_module_object =
i::wasm::DeserializeNativeModule(
- i_isolate, {serialized_module.start, serialized_module.size},
- {wire_bytes.start, wire_bytes.size});
+ i_isolate, {serialized_module.data(), serialized_module.size()},
+ {wire_bytes.data(), wire_bytes.size()});
i::Handle<i::WasmModuleObject> module_object;
if (!maybe_module_object.ToHandle(&module_object)) {
- return MaybeLocal<WasmCompiledModule>();
+ return MaybeLocal<WasmModuleObject>();
}
- return Local<WasmCompiledModule>::Cast(
+ return Local<WasmModuleObject>::Cast(
Utils::ToLocal(i::Handle<i::JSObject>::cast(module_object)));
}
-MaybeLocal<WasmCompiledModule> WasmCompiledModule::DeserializeOrCompile(
- Isolate* isolate, WasmCompiledModule::BufferReference serialized_module,
- WasmCompiledModule::BufferReference wire_bytes) {
- MaybeLocal<WasmCompiledModule> ret =
+MaybeLocal<WasmModuleObject> WasmModuleObject::DeserializeOrCompile(
+ Isolate* isolate, MemorySpan<const uint8_t> serialized_module,
+ MemorySpan<const uint8_t> wire_bytes) {
+ MaybeLocal<WasmModuleObject> ret =
Deserialize(isolate, serialized_module, wire_bytes);
if (!ret.IsEmpty()) {
return ret;
}
- return Compile(isolate, wire_bytes.start, wire_bytes.size);
+ return Compile(isolate, wire_bytes.data(), wire_bytes.size());
}
-MaybeLocal<WasmCompiledModule> WasmCompiledModule::Compile(Isolate* isolate,
- const uint8_t* start,
- size_t length) {
+MaybeLocal<WasmModuleObject> WasmModuleObject::Compile(Isolate* isolate,
+ const uint8_t* start,
+ size_t length) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
- i::wasm::ErrorThrower thrower(i_isolate, "WasmCompiledModule::Compile()");
+ i::wasm::ErrorThrower thrower(i_isolate, "WasmModuleObject::Compile()");
if (!i::wasm::IsWasmCodegenAllowed(i_isolate, i_isolate->native_context())) {
- return MaybeLocal<WasmCompiledModule>();
+ return MaybeLocal<WasmModuleObject>();
}
auto enabled_features = i::wasm::WasmFeaturesFromIsolate(i_isolate);
i::MaybeHandle<i::JSObject> maybe_compiled =
i_isolate->wasm_engine()->SyncCompile(
i_isolate, enabled_features, &thrower,
i::wasm::ModuleWireBytes(start, start + length));
- if (maybe_compiled.is_null()) return MaybeLocal<WasmCompiledModule>();
- return Local<WasmCompiledModule>::Cast(
+ if (maybe_compiled.is_null()) return MaybeLocal<WasmModuleObject>();
+ return Local<WasmModuleObject>::Cast(
Utils::ToLocal(maybe_compiled.ToHandleChecked()));
}
@@ -7440,7 +7400,7 @@ class AsyncCompilationResolver : public i::wasm::CompilationResultResolver {
*Utils::OpenHandle(*promise))) {}
~AsyncCompilationResolver() override {
- i::GlobalHandles::Destroy(i::Handle<i::Object>::cast(promise_).location());
+ i::GlobalHandles::Destroy(promise_.location());
}
void OnCompilationSucceeded(i::Handle<i::WasmModuleObject> result) override {
@@ -7487,12 +7447,10 @@ bool v8::ArrayBuffer::IsExternal() const {
return Utils::OpenHandle(this)->is_external();
}
-
-bool v8::ArrayBuffer::IsNeuterable() const {
- return Utils::OpenHandle(this)->is_neuterable();
+bool v8::ArrayBuffer::IsDetachable() const {
+ return Utils::OpenHandle(this)->is_detachable();
}
-
v8::ArrayBuffer::Contents v8::ArrayBuffer::Externalize() {
i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
i::Isolate* isolate = self->GetIsolate();
@@ -7549,21 +7507,18 @@ v8::ArrayBuffer::Contents v8::ArrayBuffer::GetContents() {
return contents;
}
-
-void v8::ArrayBuffer::Neuter() {
+void v8::ArrayBuffer::Detach() {
i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
i::Isolate* isolate = obj->GetIsolate();
- Utils::ApiCheck(obj->is_external(),
- "v8::ArrayBuffer::Neuter",
- "Only externalized ArrayBuffers can be neutered");
- Utils::ApiCheck(obj->is_neuterable(), "v8::ArrayBuffer::Neuter",
- "Only neuterable ArrayBuffers can be neutered");
- LOG_API(isolate, ArrayBuffer, Neuter);
+ Utils::ApiCheck(obj->is_external(), "v8::ArrayBuffer::Detach",
+ "Only externalized ArrayBuffers can be detached");
+ Utils::ApiCheck(obj->is_detachable(), "v8::ArrayBuffer::Detach",
+ "Only detachable ArrayBuffers can be detached");
+ LOG_API(isolate, ArrayBuffer, Detach);
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
- obj->Neuter();
+ obj->Detach();
}
-
size_t v8::ArrayBuffer::ByteLength() const {
i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
return obj->byte_length();
@@ -7654,19 +7609,19 @@ bool v8::ArrayBufferView::HasBuffer() const {
size_t v8::ArrayBufferView::ByteOffset() {
i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
- return obj->WasNeutered() ? 0 : obj->byte_offset();
+ return obj->WasDetached() ? 0 : obj->byte_offset();
}
size_t v8::ArrayBufferView::ByteLength() {
i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
- return obj->WasNeutered() ? 0 : obj->byte_length();
+ return obj->WasDetached() ? 0 : obj->byte_length();
}
size_t v8::TypedArray::Length() {
i::Handle<i::JSTypedArray> obj = Utils::OpenHandle(this);
- return obj->WasNeutered() ? 0 : obj->length_value();
+ return obj->WasDetached() ? 0 : obj->length_value();
}
static_assert(v8::TypedArray::kMaxLength == i::Smi::kMaxValue,
@@ -8007,23 +7962,18 @@ void Isolate::SetIdle(bool is_idle) {
isolate->SetIdle(is_idle);
}
-ArrayBuffer::Allocator* Isolate::GetArrayBufferAllocator() {
- i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
- return isolate->array_buffer_allocator();
-}
-
bool Isolate::InContext() {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
- return isolate->context() != nullptr;
+ return !isolate->context().is_null();
}
v8::Local<v8::Context> Isolate::GetCurrentContext() {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
- i::Context* context = isolate->context();
- if (context == nullptr) return Local<Context>();
- i::Context* native_context = context->native_context();
- if (native_context == nullptr) return Local<Context>();
+ i::Context context = isolate->context();
+ if (context.is_null()) return Local<Context>();
+ i::Context native_context = context->native_context();
+ if (native_context.is_null()) return Local<Context>();
return Utils::ToLocal(i::Handle<i::Context>(native_context, isolate));
}
@@ -8038,14 +7988,10 @@ v8::Local<v8::Context> Isolate::GetEnteredContext() {
v8::Local<v8::Context> Isolate::GetEnteredOrMicrotaskContext() {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
- i::Handle<i::Object> last;
- if (isolate->handle_scope_implementer()
- ->MicrotaskContextIsLastEnteredContext()) {
- last = isolate->handle_scope_implementer()->MicrotaskContext();
- } else {
- last = isolate->handle_scope_implementer()->LastEnteredContext();
- }
+ i::Handle<i::Object> last =
+ isolate->handle_scope_implementer()->LastEnteredOrMicrotaskContext();
if (last.is_null()) return Local<Context>();
+ DCHECK(last->IsNativeContext());
return Utils::ToLocal(i::Handle<i::Context>::cast(last));
}
@@ -8180,7 +8126,7 @@ Isolate* Isolate::GetCurrent() {
// static
Isolate* Isolate::Allocate() {
- return reinterpret_cast<Isolate*>(new i::Isolate());
+ return reinterpret_cast<Isolate*>(i::Isolate::New());
}
// static
@@ -8195,15 +8141,6 @@ void Isolate::Initialize(Isolate* isolate,
} else {
i_isolate->set_snapshot_blob(i::Snapshot::DefaultSnapshotBlob());
}
- if (params.entry_hook) {
-#ifdef V8_USE_SNAPSHOT
- // Setting a FunctionEntryHook is only supported in no-snapshot builds.
- Utils::ApiCheck(
- false, "v8::Isolate::New",
- "Setting a FunctionEntryHook is only supported in no-snapshot builds.");
-#endif
- i_isolate->set_function_entry_hook(params.entry_hook);
- }
auto code_event_handler = params.code_event_handler;
#ifdef ENABLE_GDB_JIT_INTERFACE
if (code_event_handler == nullptr && i::FLAG_gdbjit) {
@@ -8234,7 +8171,7 @@ void Isolate::Initialize(Isolate* isolate,
SetResourceConstraints(i_isolate, params.constraints);
// TODO(jochen): Once we got rid of Isolate::Current(), we can remove this.
Isolate::Scope isolate_scope(isolate);
- if (params.entry_hook || !i::Snapshot::Initialize(i_isolate)) {
+ if (!i::Snapshot::Initialize(i_isolate)) {
// If snapshot data was provided and we failed to deserialize it must
// have been corrupted.
if (i_isolate->snapshot_blob() != nullptr) {
@@ -8267,7 +8204,7 @@ void Isolate::Dispose() {
"Disposing the isolate that is entered by a thread.")) {
return;
}
- isolate->TearDown();
+ i::Isolate::Delete(isolate);
}
void Isolate::DumpAndResetStats() {
@@ -8321,22 +8258,41 @@ Isolate::DisallowJavascriptExecutionScope::DisallowJavascriptExecutionScope(
Isolate::DisallowJavascriptExecutionScope::OnFailure on_failure)
: on_failure_(on_failure) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
- if (on_failure_ == CRASH_ON_FAILURE) {
- internal_ = reinterpret_cast<void*>(
- new i::DisallowJavascriptExecution(i_isolate));
- } else {
- DCHECK_EQ(THROW_ON_FAILURE, on_failure);
- internal_ = reinterpret_cast<void*>(
- new i::ThrowOnJavascriptExecution(i_isolate));
+ switch (on_failure_) {
+ case CRASH_ON_FAILURE:
+ internal_ = reinterpret_cast<void*>(
+ new i::DisallowJavascriptExecution(i_isolate));
+ break;
+ case THROW_ON_FAILURE:
+ DCHECK_EQ(THROW_ON_FAILURE, on_failure);
+ internal_ =
+ reinterpret_cast<void*>(new i::ThrowOnJavascriptExecution(i_isolate));
+ break;
+ case DUMP_ON_FAILURE:
+ internal_ =
+ reinterpret_cast<void*>(new i::DumpOnJavascriptExecution(i_isolate));
+ break;
+ default:
+ UNREACHABLE();
+ break;
}
}
Isolate::DisallowJavascriptExecutionScope::~DisallowJavascriptExecutionScope() {
- if (on_failure_ == CRASH_ON_FAILURE) {
- delete reinterpret_cast<i::DisallowJavascriptExecution*>(internal_);
- } else {
- delete reinterpret_cast<i::ThrowOnJavascriptExecution*>(internal_);
+ switch (on_failure_) {
+ case CRASH_ON_FAILURE:
+ delete reinterpret_cast<i::DisallowJavascriptExecution*>(internal_);
+ break;
+ case THROW_ON_FAILURE:
+ delete reinterpret_cast<i::ThrowOnJavascriptExecution*>(internal_);
+ break;
+ case DUMP_ON_FAILURE:
+ delete reinterpret_cast<i::DumpOnJavascriptExecution*>(internal_);
+ break;
+ default:
+ UNREACHABLE();
+ break;
}
}
@@ -8348,12 +8304,15 @@ Isolate::AllowJavascriptExecutionScope::AllowJavascriptExecutionScope(
new i::AllowJavascriptExecution(i_isolate));
internal_throws_ = reinterpret_cast<void*>(
new i::NoThrowOnJavascriptExecution(i_isolate));
+ internal_dump_ =
+ reinterpret_cast<void*>(new i::NoDumpOnJavascriptExecution(i_isolate));
}
Isolate::AllowJavascriptExecutionScope::~AllowJavascriptExecutionScope() {
delete reinterpret_cast<i::AllowJavascriptExecution*>(internal_assert_);
delete reinterpret_cast<i::NoThrowOnJavascriptExecution*>(internal_throws_);
+ delete reinterpret_cast<i::NoDumpOnJavascriptExecution*>(internal_dump_);
}
@@ -8361,12 +8320,12 @@ Isolate::SuppressMicrotaskExecutionScope::SuppressMicrotaskExecutionScope(
Isolate* isolate)
: isolate_(reinterpret_cast<i::Isolate*>(isolate)) {
isolate_->handle_scope_implementer()->IncrementCallDepth();
- isolate_->handle_scope_implementer()->IncrementMicrotasksSuppressions();
+ isolate_->default_microtask_queue()->IncrementMicrotasksSuppressions();
}
Isolate::SuppressMicrotaskExecutionScope::~SuppressMicrotaskExecutionScope() {
- isolate_->handle_scope_implementer()->DecrementMicrotasksSuppressions();
+ isolate_->default_microtask_queue()->DecrementMicrotasksSuppressions();
isolate_->handle_scope_implementer()->DecrementCallDepth();
}
@@ -8380,9 +8339,9 @@ Isolate::SafeForTerminationScope::~SafeForTerminationScope() {
isolate_->set_next_v8_call_is_safe_for_termination(prev_value_);
}
-i::Object** Isolate::GetDataFromSnapshotOnce(size_t index) {
+i::Address* Isolate::GetDataFromSnapshotOnce(size_t index) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this);
- i::FixedArray* list = i_isolate->heap()->serialized_objects();
+ i::FixedArray list = i_isolate->heap()->serialized_objects();
return GetSerializedDataFromFixedArray(i_isolate, list, index);
}
@@ -8402,7 +8361,7 @@ void Isolate::GetHeapStatistics(HeapStatistics* heap_statistics) {
heap_statistics->malloced_memory_ =
isolate->allocator()->GetCurrentMemoryUsage() +
isolate->wasm_engine()->allocator()->GetCurrentMemoryUsage();
- heap_statistics->external_memory_ = isolate->heap()->external_memory();
+ heap_statistics->external_memory_ = isolate->heap()->backing_store_bytes();
heap_statistics->peak_malloced_memory_ =
isolate->allocator()->GetMaxMemoryUsage() +
isolate->wasm_engine()->allocator()->GetMaxMemoryUsage();
@@ -8500,9 +8459,7 @@ void Isolate::GetStackSample(const RegisterState& state, void** frames,
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;
+ return isolate->global_handles()->GetAndResetGlobalHandleResetCount();
}
void Isolate::SetEventLogger(LogEventCallback that) {
@@ -8562,14 +8519,15 @@ void Isolate::SetPromiseRejectCallback(PromiseRejectCallback callback) {
void Isolate::RunMicrotasks() {
DCHECK_NE(MicrotasksPolicy::kScoped, GetMicrotasksPolicy());
- reinterpret_cast<i::Isolate*>(this)->RunMicrotasks();
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+ isolate->default_microtask_queue()->RunMicrotasks(isolate);
}
void Isolate::EnqueueMicrotask(Local<Function> function) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
i::Handle<i::CallableTask> microtask = isolate->factory()->NewCallableTask(
Utils::OpenHandle(*function), isolate->native_context());
- isolate->EnqueueMicrotask(microtask);
+ isolate->default_microtask_queue()->EnqueueMicrotask(*microtask);
}
void Isolate::EnqueueMicrotask(MicrotaskCallback callback, void* data) {
@@ -8578,7 +8536,7 @@ void Isolate::EnqueueMicrotask(MicrotaskCallback callback, void* data) {
i::Handle<i::CallbackTask> microtask = isolate->factory()->NewCallbackTask(
isolate->factory()->NewForeign(reinterpret_cast<i::Address>(callback)),
isolate->factory()->NewForeign(reinterpret_cast<i::Address>(data)));
- isolate->EnqueueMicrotask(microtask);
+ isolate->default_microtask_queue()->EnqueueMicrotask(*microtask);
}
@@ -8599,14 +8557,15 @@ void Isolate::AddMicrotasksCompletedCallback(
MicrotasksCompletedCallback callback) {
DCHECK(callback);
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
- isolate->AddMicrotasksCompletedCallback(callback);
+ isolate->default_microtask_queue()->AddMicrotasksCompletedCallback(callback);
}
void Isolate::RemoveMicrotasksCompletedCallback(
MicrotasksCompletedCallback callback) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
- isolate->RemoveMicrotasksCompletedCallback(callback);
+ isolate->default_microtask_queue()->RemoveMicrotasksCompletedCallback(
+ callback);
}
@@ -8654,8 +8613,8 @@ void Isolate::LowMemoryNotification() {
}
{
i::HeapIterator iterator(isolate->heap());
- i::HeapObject* obj;
- while ((obj = iterator.next()) != nullptr) {
+ for (i::HeapObject obj = iterator.next(); !obj.is_null();
+ obj = iterator.next()) {
if (obj->IsAbstractCode()) {
i::AbstractCode::cast(obj)->DropStackFrameCache();
}
@@ -8695,8 +8654,6 @@ void Isolate::MemoryPressureNotification(MemoryPressureLevel level) {
: i::ThreadId::Current().Equals(isolate->thread_id());
isolate->heap()->MemoryPressureNotification(level, on_isolate_thread);
isolate->allocator()->MemoryPressureNotification(level);
- isolate->compiler_dispatcher()->MemoryPressureNotification(level,
- on_isolate_thread);
}
void Isolate::EnableMemorySavingsMode() {
@@ -8747,10 +8704,24 @@ void Isolate::GetCodeRange(void** start, size_t* length_in_bytes) {
*length_in_bytes = code_range.size();
}
-MemoryRange Isolate::GetEmbeddedCodeRange() {
+UnwindState Isolate::GetUnwindState() {
+ UnwindState unwind_state;
+ void* code_range_start;
+ GetCodeRange(&code_range_start, &unwind_state.code_range.length_in_bytes);
+ unwind_state.code_range.start = code_range_start;
+
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
- return {reinterpret_cast<const void*>(isolate->embedded_blob()),
- isolate->embedded_blob_size()};
+ unwind_state.embedded_code_range.start =
+ reinterpret_cast<const void*>(isolate->embedded_blob());
+ unwind_state.embedded_code_range.length_in_bytes =
+ isolate->embedded_blob_size();
+
+ i::Code js_entry = isolate->heap()->builtin(i::Builtins::kJSEntry);
+ unwind_state.js_entry_stub.code.start =
+ reinterpret_cast<const void*>(js_entry->InstructionStart());
+ unwind_state.js_entry_stub.code.length_in_bytes = js_entry->InstructionSize();
+
+ return unwind_state;
}
#define CALLBACK_SETTER(ExternalName, Type, InternalName) \
@@ -8790,6 +8761,13 @@ void Isolate::RemoveNearHeapLimitCallback(v8::NearHeapLimitCallback callback,
isolate->heap()->RemoveNearHeapLimitCallback(callback, heap_limit);
}
+void Isolate::AutomaticallyRestoreInitialHeapLimit(double threshold_percent) {
+ DCHECK_GT(threshold_percent, 0.0);
+ DCHECK_LT(threshold_percent, 1.0);
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+ isolate->heap()->AutomaticallyRestoreInitialHeapLimit(threshold_percent);
+}
+
bool Isolate::IsDead() {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
return isolate->IsDead();
@@ -8824,11 +8802,11 @@ void Isolate::RemoveMessageListeners(MessageCallback that) {
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
i::HandleScope scope(isolate);
i::DisallowHeapAllocation no_gc;
- i::TemplateList* listeners = isolate->heap()->message_listeners();
+ 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));
+ 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, i::ReadOnlyRoots(isolate).undefined_value());
}
@@ -8892,48 +8870,48 @@ void Isolate::SetAllowAtomicsWait(bool allow) {
MicrotasksScope::MicrotasksScope(Isolate* isolate, MicrotasksScope::Type type)
: isolate_(reinterpret_cast<i::Isolate*>(isolate)),
run_(type == MicrotasksScope::kRunMicrotasks) {
- auto handle_scope_implementer = isolate_->handle_scope_implementer();
- if (run_) handle_scope_implementer->IncrementMicrotasksScopeDepth();
+ auto* microtask_queue = isolate_->default_microtask_queue();
+ if (run_) microtask_queue->IncrementMicrotasksScopeDepth();
#ifdef DEBUG
- if (!run_) handle_scope_implementer->IncrementDebugMicrotasksScopeDepth();
+ if (!run_) microtask_queue->IncrementDebugMicrotasksScopeDepth();
#endif
}
MicrotasksScope::~MicrotasksScope() {
auto handle_scope_implementer = isolate_->handle_scope_implementer();
+ auto* microtask_queue = isolate_->default_microtask_queue();
if (run_) {
- handle_scope_implementer->DecrementMicrotasksScopeDepth();
+ microtask_queue->DecrementMicrotasksScopeDepth();
if (MicrotasksPolicy::kScoped ==
handle_scope_implementer->microtasks_policy()) {
PerformCheckpoint(reinterpret_cast<Isolate*>(isolate_));
}
}
#ifdef DEBUG
- if (!run_) handle_scope_implementer->DecrementDebugMicrotasksScopeDepth();
+ if (!run_) microtask_queue->DecrementDebugMicrotasksScopeDepth();
#endif
}
void MicrotasksScope::PerformCheckpoint(Isolate* v8Isolate) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8Isolate);
- if (IsExecutionTerminatingCheck(isolate)) return;
- auto handle_scope_implementer = isolate->handle_scope_implementer();
- if (!handle_scope_implementer->GetMicrotasksScopeDepth() &&
- !handle_scope_implementer->HasMicrotasksSuppressions()) {
- isolate->RunMicrotasks();
+ auto* microtask_queue = isolate->default_microtask_queue();
+ if (!microtask_queue->GetMicrotasksScopeDepth() &&
+ !microtask_queue->HasMicrotasksSuppressions()) {
+ microtask_queue->RunMicrotasks(isolate);
}
}
int MicrotasksScope::GetCurrentDepth(Isolate* v8Isolate) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8Isolate);
- return isolate->handle_scope_implementer()->GetMicrotasksScopeDepth();
+ return isolate->default_microtask_queue()->GetMicrotasksScopeDepth();
}
bool MicrotasksScope::IsRunningMicrotasks(Isolate* v8Isolate) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8Isolate);
- return isolate->IsRunningMicrotasks();
+ return isolate->default_microtask_queue()->IsRunningMicrotasks();
}
String::Utf8Value::Utf8Value(v8::Isolate* isolate, v8::Local<v8::Value> obj)
@@ -8979,7 +8957,7 @@ String::Value::~Value() {
i::Isolate* isolate = i::Isolate::Current(); \
LOG_API(isolate, NAME, New); \
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); \
- i::Object* error; \
+ i::Object error; \
{ \
i::HandleScope scope(isolate); \
i::Handle<i::String> message = Utils::OpenHandle(*raw_message); \
@@ -9027,7 +9005,7 @@ void debug::SetContextId(Local<Context> context, int id) {
}
int debug::GetContextId(Local<Context> context) {
- i::Object* value = Utils::OpenHandle(*context)->debug_context_id();
+ i::Object value = Utils::OpenHandle(*context)->debug_context_id();
return (value->IsSmi()) ? i::Smi::ToInt(value) : 0;
}
@@ -9148,7 +9126,7 @@ std::vector<int> debug::Script::LineEnds() const {
isolate);
std::vector<int> result(line_ends->length());
for (int i = 0; i < line_ends->length(); ++i) {
- i::Smi* line_end = i::Smi::cast(line_ends->get(i));
+ i::Smi line_end = i::Smi::cast(line_ends->get(i));
result[i] = line_end->value();
}
return result;
@@ -9188,7 +9166,7 @@ Maybe<int> debug::Script::ContextId() const {
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
i::HandleScope handle_scope(isolate);
i::Handle<i::Script> script = Utils::OpenHandle(this);
- i::Object* value = script->context_data();
+ i::Object value = script->context_data();
if (value->IsSmi()) return Just(i::Smi::ToInt(value));
return Nothing<int>();
}
@@ -9230,7 +9208,7 @@ bool debug::Script::GetPossibleBreakpoints(
i::Handle<i::Script> script = Utils::OpenHandle(this);
if (script->type() == i::Script::TYPE_WASM &&
this->SourceMappingURL().IsEmpty()) {
- i::WasmModuleObject* module_object =
+ i::WasmModuleObject module_object =
i::WasmModuleObject::cast(script->wasm_module_object());
return module_object->GetPossibleBreakpoints(start, end, locations);
}
@@ -9357,7 +9335,7 @@ int debug::WasmScript::NumFunctions() const {
i::DisallowHeapAllocation no_gc;
i::Handle<i::Script> script = Utils::OpenHandle(this);
DCHECK_EQ(i::Script::TYPE_WASM, script->type());
- i::WasmModuleObject* module_object =
+ i::WasmModuleObject module_object =
i::WasmModuleObject::cast(script->wasm_module_object());
const i::wasm::WasmModule* module = module_object->module();
DCHECK_GE(i::kMaxInt, module->functions.size());
@@ -9368,7 +9346,7 @@ int debug::WasmScript::NumImportedFunctions() const {
i::DisallowHeapAllocation no_gc;
i::Handle<i::Script> script = Utils::OpenHandle(this);
DCHECK_EQ(i::Script::TYPE_WASM, script->type());
- i::WasmModuleObject* module_object =
+ i::WasmModuleObject module_object =
i::WasmModuleObject::cast(script->wasm_module_object());
const i::wasm::WasmModule* module = module_object->module();
DCHECK_GE(i::kMaxInt, module->num_imported_functions);
@@ -9380,7 +9358,7 @@ std::pair<int, int> debug::WasmScript::GetFunctionRange(
i::DisallowHeapAllocation no_gc;
i::Handle<i::Script> script = Utils::OpenHandle(this);
DCHECK_EQ(i::Script::TYPE_WASM, script->type());
- i::WasmModuleObject* module_object =
+ i::WasmModuleObject module_object =
i::WasmModuleObject::cast(script->wasm_module_object());
const i::wasm::WasmModule* module = module_object->module();
DCHECK_LE(0, function_index);
@@ -9396,7 +9374,7 @@ uint32_t debug::WasmScript::GetFunctionHash(int function_index) {
i::DisallowHeapAllocation no_gc;
i::Handle<i::Script> script = Utils::OpenHandle(this);
DCHECK_EQ(i::Script::TYPE_WASM, script->type());
- i::WasmModuleObject* module_object =
+ i::WasmModuleObject module_object =
i::WasmModuleObject::cast(script->wasm_module_object());
const i::wasm::WasmModule* module = module_object->module();
DCHECK_LE(0, function_index);
@@ -9415,7 +9393,7 @@ debug::WasmDisassembly debug::WasmScript::DisassembleFunction(
i::DisallowHeapAllocation no_gc;
i::Handle<i::Script> script = Utils::OpenHandle(this);
DCHECK_EQ(i::Script::TYPE_WASM, script->type());
- i::WasmModuleObject* module_object =
+ i::WasmModuleObject module_object =
i::WasmModuleObject::cast(script->wasm_module_object());
return module_object->DisassembleFunction(function_index);
}
@@ -9449,8 +9427,8 @@ void debug::GetLoadedScripts(v8::Isolate* v8_isolate,
{
i::DisallowHeapAllocation no_gc;
i::Script::Iterator iterator(isolate);
- i::Script* script;
- while ((script = iterator.Next()) != nullptr) {
+ for (i::Script script = iterator.Next(); !script.is_null();
+ script = iterator.Next()) {
if (!script->IsUserJavaScript()) continue;
if (script->HasValidSource()) {
i::HandleScope handle_scope(isolate);
@@ -9501,7 +9479,8 @@ void debug::ResetBlackboxedStateCache(Isolate* v8_isolate,
i::DisallowHeapAllocation no_gc;
i::SharedFunctionInfo::ScriptIterator iter(isolate,
*Utils::OpenHandle(*script));
- while (i::SharedFunctionInfo* info = iter.Next()) {
+ for (i::SharedFunctionInfo info = iter.Next(); !info.is_null();
+ info = iter.Next()) {
if (info->HasDebugInfo()) {
info->GetDebugInfo()->set_computed_debug_is_blackboxed(false);
}
@@ -9512,7 +9491,7 @@ int debug::EstimatedValueSize(Isolate* v8_isolate, v8::Local<v8::Value> value) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
i::Handle<i::Object> object = Utils::OpenHandle(*value);
- if (object->IsSmi()) return i::kPointerSize;
+ if (object->IsSmi()) return i::kTaggedSize;
CHECK(object->IsHeapObject());
return i::Handle<i::HeapObject>::cast(object)->Size();
}
@@ -9537,22 +9516,21 @@ v8::MaybeLocal<v8::Array> v8::Object::PreviewEntries(bool* is_key_value) {
i::Handle<i::JSWeakCollection>::cast(object), 0));
}
if (object->IsJSMapIterator()) {
- i::Handle<i::JSMapIterator> it = i::Handle<i::JSMapIterator>::cast(object);
+ i::Handle<i::JSMapIterator> iterator =
+ i::Handle<i::JSMapIterator>::cast(object);
MapAsArrayKind const kind =
- static_cast<MapAsArrayKind>(it->map()->instance_type());
+ static_cast<MapAsArrayKind>(iterator->map()->instance_type());
*is_key_value = kind == MapAsArrayKind::kEntries;
- if (!it->HasMore()) return v8::Array::New(v8_isolate);
- return Utils::ToLocal(
- MapAsArray(isolate, it->table(), i::Smi::ToInt(it->index()), kind));
+ if (!iterator->HasMore()) return v8::Array::New(v8_isolate);
+ return Utils::ToLocal(MapAsArray(isolate, iterator->table(),
+ i::Smi::ToInt(iterator->index()), kind));
}
if (object->IsJSSetIterator()) {
i::Handle<i::JSSetIterator> it = i::Handle<i::JSSetIterator>::cast(object);
- SetAsArrayKind const kind =
- static_cast<SetAsArrayKind>(it->map()->instance_type());
- *is_key_value = kind == SetAsArrayKind::kEntries;
+ *is_key_value = false;
if (!it->HasMore()) return v8::Array::New(v8_isolate);
return Utils::ToLocal(
- SetAsArray(isolate, it->table(), i::Smi::ToInt(it->index()), kind));
+ SetAsArray(isolate, it->table(), i::Smi::ToInt(it->index())));
}
return v8::MaybeLocal<v8::Array>();
}
@@ -9563,20 +9541,8 @@ Local<Function> debug::GetBuiltin(Isolate* v8_isolate, Builtin builtin) {
i::HandleScope handle_scope(isolate);
i::Builtins::Name builtin_id;
switch (builtin) {
- case kObjectKeys:
- builtin_id = i::Builtins::kObjectKeys;
- break;
- case kObjectGetPrototypeOf:
- builtin_id = i::Builtins::kObjectGetPrototypeOf;
- break;
- case kObjectGetOwnPropertyDescriptor:
- builtin_id = i::Builtins::kObjectGetOwnPropertyDescriptor;
- break;
- case kObjectGetOwnPropertyNames:
- builtin_id = i::Builtins::kObjectGetOwnPropertyNames;
- break;
- case kObjectGetOwnPropertySymbols:
- builtin_id = i::Builtins::kObjectGetOwnPropertySymbols;
+ case kStringToLowerCase:
+ builtin_id = i::Builtins::kStringPrototypeToLocaleLowerCase;
break;
default:
UNREACHABLE();
@@ -9584,10 +9550,11 @@ Local<Function> debug::GetBuiltin(Isolate* v8_isolate, Builtin builtin) {
i::Handle<i::String> name = isolate->factory()->empty_string();
i::NewFunctionArgs args = i::NewFunctionArgs::ForBuiltinWithoutPrototype(
- name, builtin_id, i::LanguageMode::kSloppy);
+ name, builtin_id, i::LanguageMode::kStrict);
i::Handle<i::JSFunction> fun = isolate->factory()->NewFunction(args);
- fun->shared()->DontAdaptArguments();
+ fun->shared()->set_internal_formal_parameter_count(0);
+ fun->shared()->set_length(0);
return Utils::ToLocal(handle_scope.CloseAndEscape(fun));
}
@@ -9604,8 +9571,11 @@ debug::ConsoleCallArguments::ConsoleCallArguments(
debug::ConsoleCallArguments::ConsoleCallArguments(
internal::BuiltinArguments& args)
- : v8::FunctionCallbackInfo<v8::Value>(nullptr, &args[0] - 1,
- args.length() - 1) {}
+ : v8::FunctionCallbackInfo<v8::Value>(
+ nullptr,
+ // Drop the first argument (receiver, i.e. the "console" object).
+ args.address_of_arg_at(args.length() > 1 ? 1 : 0),
+ args.length() - 1) {}
int debug::GetStackFrameId(v8::Local<v8::StackFrame> frame) {
return Utils::OpenHandle(*frame)->id();
@@ -9625,7 +9595,7 @@ v8::Local<v8::StackTrace> debug::GetDetailedStackTrace(
MaybeLocal<debug::Script> debug::GeneratorObject::Script() {
i::Handle<i::JSGeneratorObject> obj = Utils::OpenHandle(this);
- i::Object* maybe_script = obj->function()->shared()->script();
+ i::Object maybe_script = obj->function()->shared()->script();
if (!maybe_script->IsScript()) return MaybeLocal<debug::Script>();
i::Handle<i::Script> script(i::Script::cast(maybe_script), obj->GetIsolate());
return ToApiHandle<debug::Script>(script);
@@ -9639,7 +9609,7 @@ Local<Function> debug::GeneratorObject::Function() {
debug::Location debug::GeneratorObject::SuspendedLocation() {
i::Handle<i::JSGeneratorObject> obj = Utils::OpenHandle(this);
CHECK(obj->is_suspended());
- i::Object* maybe_script = obj->function()->shared()->script();
+ i::Object maybe_script = obj->function()->shared()->script();
if (!maybe_script->IsScript()) return debug::Location();
i::Handle<i::Script> script(i::Script::cast(maybe_script), obj->GetIsolate());
i::Script::PositionInfo info;
@@ -9696,7 +9666,7 @@ void debug::GlobalLexicalScopeNames(
i::Handle<i::ScopeInfo> scope_info(context->scope_info(), isolate);
int local_count = scope_info->ContextLocalCount();
for (int j = 0; j < local_count; ++j) {
- i::String* name = scope_info->ContextLocalName(j);
+ i::String name = scope_info->ContextLocalName(j);
if (i::ScopeInfo::VariableIsSynthetic(name)) continue;
names->Append(Utils::ToLocal(handle(name, isolate)));
}
@@ -9709,41 +9679,6 @@ void debug::SetReturnValue(v8::Isolate* v8_isolate,
isolate->debug()->set_return_value(*Utils::OpenHandle(*value));
}
-int debug::GetNativeAccessorDescriptor(v8::Local<v8::Context> context,
- v8::Local<v8::Object> v8_object,
- v8::Local<v8::Name> v8_name) {
- i::Handle<i::JSReceiver> object = Utils::OpenHandle(*v8_object);
- i::Handle<i::Name> name = Utils::OpenHandle(*v8_name);
- uint32_t index;
- if (name->AsArrayIndex(&index)) {
- return static_cast<int>(debug::NativeAccessorType::None);
- }
- i::LookupIterator it = i::LookupIterator(object->GetIsolate(), object, name,
- i::LookupIterator::OWN);
- if (!it.IsFound()) return static_cast<int>(debug::NativeAccessorType::None);
- if (it.state() != i::LookupIterator::ACCESSOR) {
- return static_cast<int>(debug::NativeAccessorType::None);
- }
- i::Handle<i::Object> structure = it.GetAccessors();
- if (!structure->IsAccessorInfo()) {
- return static_cast<int>(debug::NativeAccessorType::None);
- }
- auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
- int result = 0;
-#define IS_BUILTIN_ACESSOR(_, name, ...) \
- if (*structure == *isolate->factory()->name##_accessor()) \
- result |= static_cast<int>(debug::NativeAccessorType::IsBuiltin);
- ACCESSOR_INFO_LIST_GENERATOR(IS_BUILTIN_ACESSOR, /* not used */)
-#undef IS_BUILTIN_ACESSOR
- i::Handle<i::AccessorInfo> accessor_info =
- i::Handle<i::AccessorInfo>::cast(structure);
- if (accessor_info->getter())
- result |= static_cast<int>(debug::NativeAccessorType::HasGetter);
- if (accessor_info->setter())
- result |= static_cast<int>(debug::NativeAccessorType::HasSetter);
- return result;
-}
-
int64_t debug::GetNextRandomInt64(v8::Isolate* v8_isolate) {
return reinterpret_cast<i::Isolate*>(v8_isolate)
->random_number_generator()
@@ -10418,7 +10353,6 @@ AllocationProfile* HeapProfiler::GetAllocationProfile() {
return reinterpret_cast<i::HeapProfiler*>(this)->GetAllocationProfile();
}
-
void HeapProfiler::DeleteAllHeapSnapshots() {
reinterpret_cast<i::HeapProfiler*>(this)->DeleteAllSnapshots();
}
@@ -10545,46 +10479,13 @@ void EmbedderHeapTracer::GarbageCollectionForTesting(
kGCCallbackFlagForced);
}
-bool EmbedderHeapTracer::AdvanceTracing(double deadline_in_ms) {
-#if __clang__
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated"
-#endif
- return !this->AdvanceTracing(
- deadline_in_ms, AdvanceTracingActions(std::isinf(deadline_in_ms)
- ? FORCE_COMPLETION
- : DO_NOT_FORCE_COMPLETION));
-#if __clang__
-#pragma clang diagnostic pop
-#endif
-}
-
-void EmbedderHeapTracer::EnterFinalPause(EmbedderStackState stack_state) {
-#if __clang__
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated"
-#endif
- this->EnterFinalPause();
-#if __clang__
-#pragma clang diagnostic pop
-#endif
-}
-
-bool EmbedderHeapTracer::IsTracingDone() {
-// TODO(mlippautz): Implement using "return true" after removing the deprecated
-// call.
-#if __clang__
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated"
-#endif
- return NumberOfWrappersToTrace() == 0;
-#if __clang__
-#pragma clang diagnostic pop
-#endif
-}
-
namespace internal {
+const size_t HandleScopeImplementer::kEnteredContextsOffset =
+ offsetof(HandleScopeImplementer, entered_contexts_);
+const size_t HandleScopeImplementer::kIsMicrotaskContextOffset =
+ offsetof(HandleScopeImplementer, is_microtask_context_);
+
void HandleScopeImplementer::FreeThreadResources() {
Free();
}
@@ -10619,19 +10520,23 @@ void HandleScopeImplementer::IterateThis(RootVisitor* v) {
#endif
// Iterate over all handles in the blocks except for the last.
for (int i = static_cast<int>(blocks()->size()) - 2; i >= 0; --i) {
- Object** block = blocks()->at(i);
+ Address* block = blocks()->at(i);
+ // Cast possibly-unrelated pointers to plain Address before comparing them
+ // to avoid undefined behavior.
if (last_handle_before_deferred_block_ != nullptr &&
- (last_handle_before_deferred_block_ <= &block[kHandleBlockSize]) &&
- (last_handle_before_deferred_block_ >= block)) {
- v->VisitRootPointers(Root::kHandleScope, nullptr, block,
- last_handle_before_deferred_block_);
+ (reinterpret_cast<Address>(last_handle_before_deferred_block_) <=
+ reinterpret_cast<Address>(&block[kHandleBlockSize])) &&
+ (reinterpret_cast<Address>(last_handle_before_deferred_block_) >=
+ reinterpret_cast<Address>(block))) {
+ v->VisitRootPointers(Root::kHandleScope, nullptr, FullObjectSlot(block),
+ FullObjectSlot(last_handle_before_deferred_block_));
DCHECK(!found_block_before_deferred);
#ifdef DEBUG
found_block_before_deferred = true;
#endif
} else {
- v->VisitRootPointers(Root::kHandleScope, nullptr, block,
- &block[kHandleBlockSize]);
+ v->VisitRootPointers(Root::kHandleScope, nullptr, FullObjectSlot(block),
+ FullObjectSlot(&block[kHandleBlockSize]));
}
}
@@ -10640,21 +10545,19 @@ void HandleScopeImplementer::IterateThis(RootVisitor* v) {
// Iterate over live handles in the last block (if any).
if (!blocks()->empty()) {
- v->VisitRootPointers(Root::kHandleScope, nullptr, blocks()->back(),
- handle_scope_data_.next);
+ v->VisitRootPointers(Root::kHandleScope, nullptr,
+ FullObjectSlot(blocks()->back()),
+ FullObjectSlot(handle_scope_data_.next));
}
- DetachableVector<Context*>* context_lists[2] = {&saved_contexts_,
- &entered_contexts_};
+ DetachableVector<Context>* context_lists[2] = {&saved_contexts_,
+ &entered_contexts_};
for (unsigned i = 0; i < arraysize(context_lists); i++) {
+ context_lists[i]->shrink_to_fit();
if (context_lists[i]->empty()) continue;
- Object** start = reinterpret_cast<Object**>(&context_lists[i]->front());
+ FullObjectSlot start(&context_lists[i]->front());
v->VisitRootPointers(Root::kHandleScope, nullptr, start,
- start + context_lists[i]->size());
- }
- if (microtask_context_) {
- v->VisitRootPointer(Root::kHandleScope, nullptr,
- reinterpret_cast<Object**>(&microtask_context_));
+ start + static_cast<int>(context_lists[i]->size()));
}
}
@@ -10671,14 +10574,13 @@ char* HandleScopeImplementer::Iterate(RootVisitor* v, char* storage) {
return storage + ArchiveSpacePerThread();
}
-
-DeferredHandles* HandleScopeImplementer::Detach(Object** prev_limit) {
+DeferredHandles* HandleScopeImplementer::Detach(Address* prev_limit) {
DeferredHandles* deferred =
new DeferredHandles(isolate()->handle_scope_data()->next, isolate());
while (!blocks_.empty()) {
- Object** block_start = blocks_.back();
- Object** block_limit = &block_start[kHandleBlockSize];
+ Address* block_start = blocks_.back();
+ Address* block_limit = &block_start[kHandleBlockSize];
// We should not need to check for SealHandleScope here. Assert this.
DCHECK(prev_limit == block_limit ||
!(block_start <= prev_limit && prev_limit <= block_limit));
@@ -10720,15 +10622,23 @@ DeferredHandles::~DeferredHandles() {
void DeferredHandles::Iterate(RootVisitor* v) {
DCHECK(!blocks_.empty());
- DCHECK((first_block_limit_ >= blocks_.front()) &&
- (first_block_limit_ <= &(blocks_.front())[kHandleBlockSize]));
+ // Comparing pointers that do not point into the same array is undefined
+ // behavior, which means if we didn't cast everything to plain Address
+ // before comparing, the compiler would be allowed to assume that all
+ // comparisons evaluate to true and drop the entire check.
+ DCHECK((reinterpret_cast<Address>(first_block_limit_) >=
+ reinterpret_cast<Address>(blocks_.front())) &&
+ (reinterpret_cast<Address>(first_block_limit_) <=
+ reinterpret_cast<Address>(&(blocks_.front())[kHandleBlockSize])));
- v->VisitRootPointers(Root::kHandleScope, nullptr, blocks_.front(),
- first_block_limit_);
+ v->VisitRootPointers(Root::kHandleScope, nullptr,
+ FullObjectSlot(blocks_.front()),
+ FullObjectSlot(first_block_limit_));
for (size_t i = 1; i < blocks_.size(); i++) {
- v->VisitRootPointers(Root::kHandleScope, nullptr, blocks_[i],
- &blocks_[i][kHandleBlockSize]);
+ v->VisitRootPointers(Root::kHandleScope, nullptr,
+ FullObjectSlot(blocks_[i]),
+ FullObjectSlot(&blocks_[i][kHandleBlockSize]));
}
}