diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2021-05-20 09:47:09 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2021-06-07 11:15:42 +0000 |
commit | 189d4fd8fad9e3c776873be51938cd31a42b6177 (patch) | |
tree | 6497caeff5e383937996768766ab3bb2081a40b2 /chromium/v8/src/api | |
parent | 8bc75099d364490b22f43a7ce366b366c08f4164 (diff) | |
download | qtwebengine-chromium-189d4fd8fad9e3c776873be51938cd31a42b6177.tar.gz |
BASELINE: Update Chromium to 90.0.4430.221
Change-Id: Iff4d9d18d2fcf1a576f3b1f453010f744a232920
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/v8/src/api')
-rw-r--r-- | chromium/v8/src/api/api-arguments-inl.h | 4 | ||||
-rw-r--r-- | chromium/v8/src/api/api-arguments.h | 12 | ||||
-rw-r--r-- | chromium/v8/src/api/api-inl.h | 111 | ||||
-rw-r--r-- | chromium/v8/src/api/api-macros-undef.h | 20 | ||||
-rw-r--r-- | chromium/v8/src/api/api-macros.h | 132 | ||||
-rw-r--r-- | chromium/v8/src/api/api-natives.cc | 73 | ||||
-rw-r--r-- | chromium/v8/src/api/api.cc | 2283 | ||||
-rw-r--r-- | chromium/v8/src/api/api.h | 22 |
8 files changed, 862 insertions, 1795 deletions
diff --git a/chromium/v8/src/api/api-arguments-inl.h b/chromium/v8/src/api/api-arguments-inl.h index 05bb35786a9..57b533c7c9f 100644 --- a/chromium/v8/src/api/api-arguments-inl.h +++ b/chromium/v8/src/api/api-arguments-inl.h @@ -57,8 +57,8 @@ inline Object PropertyCallbackArguments::receiver() { return *slot_at(T::kThisIndex); } -inline JSObject FunctionCallbackArguments::holder() { - return JSObject::cast(*slot_at(T::kHolderIndex)); +inline JSReceiver FunctionCallbackArguments::holder() { + return JSReceiver::cast(*slot_at(T::kHolderIndex)); } #define FOR_EACH_CALLBACK(F) \ diff --git a/chromium/v8/src/api/api-arguments.h b/chromium/v8/src/api/api-arguments.h index 18690b5db2b..464ebadf37b 100644 --- a/chromium/v8/src/api/api-arguments.h +++ b/chromium/v8/src/api/api-arguments.h @@ -74,6 +74,12 @@ class PropertyCallbackArguments PropertyCallbackArguments(Isolate* isolate, Object data, Object self, JSObject holder, Maybe<ShouldThrow> should_throw); + // Don't copy PropertyCallbackArguments, because they would both have the + // same prev_ pointer. + PropertyCallbackArguments(const PropertyCallbackArguments&) = delete; + PropertyCallbackArguments& operator=(const PropertyCallbackArguments&) = + delete; + // ------------------------------------------------------------------------- // Accessor Callbacks // Also used for AccessorSetterCallback. @@ -141,10 +147,6 @@ class PropertyCallbackArguments inline JSObject holder(); inline Object receiver(); - - // Don't copy PropertyCallbackArguments, because they would both have the - // same prev_ pointer. - DISALLOW_COPY_AND_ASSIGN(PropertyCallbackArguments); }; class FunctionCallbackArguments @@ -175,7 +177,7 @@ class FunctionCallbackArguments inline Handle<Object> Call(CallHandlerInfo handler); private: - inline JSObject holder(); + inline JSReceiver holder(); internal::Address* argv_; int argc_; diff --git a/chromium/v8/src/api/api-inl.h b/chromium/v8/src/api/api-inl.h index f686424286d..10c8fb064dd 100644 --- a/chromium/v8/src/api/api-inl.h +++ b/chromium/v8/src/api/api-inl.h @@ -6,6 +6,7 @@ #define V8_API_API_INL_H_ #include "src/api/api.h" +#include "src/execution/microtask-queue.h" #include "src/handles/handles-inl.h" #include "src/objects/foreign-inl.h" #include "src/objects/js-weak-refs.h" @@ -96,7 +97,7 @@ MAKE_TO_LOCAL(AccessorSignatureToLocal, FunctionTemplateInfo, AccessorSignature) MAKE_TO_LOCAL(MessageToLocal, Object, Message) MAKE_TO_LOCAL(PromiseToLocal, JSObject, Promise) MAKE_TO_LOCAL(StackTraceToLocal, FixedArray, StackTrace) -MAKE_TO_LOCAL(StackFrameToLocal, StackTraceFrame, StackFrame) +MAKE_TO_LOCAL(StackFrameToLocal, StackFrameInfo, StackFrame) MAKE_TO_LOCAL(NumberToLocal, Object, Number) MAKE_TO_LOCAL(IntegerToLocal, Object, Integer) MAKE_TO_LOCAL(Uint32ToLocal, Object, Uint32) @@ -104,7 +105,8 @@ MAKE_TO_LOCAL(ToLocal, BigInt, BigInt) MAKE_TO_LOCAL(ExternalToLocal, JSObject, External) MAKE_TO_LOCAL(CallableToLocal, JSReceiver, Function) MAKE_TO_LOCAL(ToLocalPrimitive, Object, Primitive) -MAKE_TO_LOCAL(ToLocal, FixedArray, PrimitiveArray) +MAKE_TO_LOCAL(FixedArrayToLocal, FixedArray, FixedArray) +MAKE_TO_LOCAL(PrimitiveArrayToLocal, FixedArray, PrimitiveArray) MAKE_TO_LOCAL(ScriptOrModuleToLocal, Script, ScriptOrModule) #undef MAKE_TO_LOCAL_TYPED_ARRAY @@ -130,6 +132,111 @@ OPEN_HANDLE_LIST(MAKE_OPEN_HANDLE) #undef MAKE_OPEN_HANDLE #undef OPEN_HANDLE_LIST +template <bool do_callback> +class V8_NODISCARD CallDepthScope { + public: + CallDepthScope(i::Isolate* isolate, Local<Context> context) + : isolate_(isolate), + context_(context), + escaped_(false), + safe_for_termination_(isolate->next_v8_call_is_safe_for_termination()), + interrupts_scope_(isolate_, i::StackGuard::TERMINATE_EXECUTION, + isolate_->only_terminate_in_safe_scope() + ? (safe_for_termination_ + ? i::InterruptsScope::kRunInterrupts + : i::InterruptsScope::kPostponeInterrupts) + : i::InterruptsScope::kNoop) { + isolate_->thread_local_top()->IncrementCallDepth(this); + 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().is_null() && + isolate->context().native_context() == env->native_context()) { + context_ = Local<Context>(); + } else { + impl->SaveContext(isolate->context()); + isolate->set_context(*env); + } + } + if (do_callback) isolate_->FireBeforeCallEnteredCallback(); + } + ~CallDepthScope() { + i::MicrotaskQueue* microtask_queue = isolate_->default_microtask_queue(); + if (!context_.IsEmpty()) { + i::HandleScopeImplementer* impl = isolate_->handle_scope_implementer(); + isolate_->set_context(impl->RestoreContext()); + + i::Handle<i::Context> env = Utils::OpenHandle(*context_); + microtask_queue = env->native_context().microtask_queue(); + } + if (!escaped_) isolate_->thread_local_top()->DecrementCallDepth(this); + if (do_callback) isolate_->FireCallCompletedCallback(microtask_queue); +// TODO(jochen): This should be #ifdef DEBUG +#ifdef V8_CHECK_MICROTASKS_SCOPES_CONSISTENCY + if (do_callback) { + if (microtask_queue && microtask_queue->microtasks_policy() == + v8::MicrotasksPolicy::kScoped) { + DCHECK(microtask_queue->GetMicrotasksScopeDepth() || + !microtask_queue->DebugMicrotasksScopeDepthIsZero()); + } + } +#endif + DCHECK(CheckKeptObjectsClearedAfterMicrotaskCheckpoint(microtask_queue)); + isolate_->set_next_v8_call_is_safe_for_termination(safe_for_termination_); + } + + CallDepthScope(const CallDepthScope&) = delete; + CallDepthScope& operator=(const CallDepthScope&) = delete; + + void Escape() { + DCHECK(!escaped_); + escaped_ = true; + auto thread_local_top = isolate_->thread_local_top(); + thread_local_top->DecrementCallDepth(this); + bool clear_exception = thread_local_top->CallDepthIsZero() && + thread_local_top->try_catch_handler_ == nullptr; + isolate_->OptionalRescheduleException(clear_exception); + } + + private: + bool CheckKeptObjectsClearedAfterMicrotaskCheckpoint( + i::MicrotaskQueue* microtask_queue) { + bool did_perform_microtask_checkpoint = + isolate_->thread_local_top()->CallDepthIsZero() && do_callback && + microtask_queue && + microtask_queue->microtasks_policy() == MicrotasksPolicy::kAuto; + return !did_perform_microtask_checkpoint || + isolate_->heap()->weak_refs_keep_during_job().IsUndefined(isolate_); + } + + i::Isolate* const isolate_; + Local<Context> context_; + bool escaped_; + bool do_callback_; + bool safe_for_termination_; + i::InterruptsScope interrupts_scope_; + i::Address previous_stack_height_; + + friend class i::ThreadLocalTop; + + DISALLOW_NEW_AND_DELETE() +}; + +class V8_NODISCARD InternalEscapableScope : public EscapableHandleScope { + public: + explicit inline InternalEscapableScope(i::Isolate* isolate) + : EscapableHandleScope(reinterpret_cast<v8::Isolate*>(isolate)) {} +}; + +inline bool IsExecutionTerminatingCheck(i::Isolate* isolate) { + if (isolate->has_scheduled_exception()) { + return isolate->scheduled_exception() == + i::ReadOnlyRoots(isolate).termination_exception(); + } + return false; +} + namespace internal { Handle<Context> HandleScopeImplementer::LastEnteredContext() { diff --git a/chromium/v8/src/api/api-macros-undef.h b/chromium/v8/src/api/api-macros-undef.h new file mode 100644 index 00000000000..d3eea83a5f0 --- /dev/null +++ b/chromium/v8/src/api/api-macros-undef.h @@ -0,0 +1,20 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// PRESUBMIT_INTENTIONALLY_MISSING_INCLUDE_GUARD + +#undef LOG_API +#undef ENTER_V8_DO_NOT_USE +#undef ENTER_V8_HELPER_DO_NOT_USE +#undef PREPARE_FOR_DEBUG_INTERFACE_EXECUTION_WITH_ISOLATE +#undef PREPARE_FOR_EXECUTION_WITH_CONTEXT +#undef PREPARE_FOR_EXECUTION +#undef ENTER_V8 +#undef ENTER_V8_NO_SCRIPT +#undef ENTER_V8_NO_SCRIPT_NO_EXCEPTION +#undef ENTER_V8_FOR_NEW_CONTEXT +#undef EXCEPTION_BAILOUT_CHECK_SCOPED_DO_NOT_USE +#undef RETURN_ON_FAILED_EXECUTION +#undef RETURN_ON_FAILED_EXECUTION_PRIMITIVE +#undef RETURN_ESCAPED diff --git a/chromium/v8/src/api/api-macros.h b/chromium/v8/src/api/api-macros.h new file mode 100644 index 00000000000..b126e1cd5a0 --- /dev/null +++ b/chromium/v8/src/api/api-macros.h @@ -0,0 +1,132 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Note 1: Any file that includes this one should include api-macros-undef.h +// at the bottom. + +// Note 2: This file is deliberately missing the include guards (the undeffing +// approach wouldn't work otherwise). +// +// PRESUBMIT_INTENTIONALLY_MISSING_INCLUDE_GUARD + +/* + * Most API methods should use one of the three macros: + * + * ENTER_V8, ENTER_V8_NO_SCRIPT, ENTER_V8_NO_SCRIPT_NO_EXCEPTION. + * + * The latter two assume that no script is executed, and no exceptions are + * scheduled in addition (respectively). Creating a pending exception and + * removing it before returning is ok. + * + * Exceptions should be handled either by invoking one of the + * RETURN_ON_FAILED_EXECUTION* macros. + * + * Don't use macros with DO_NOT_USE in their name. + * + * TODO(jochen): Document debugger specific macros. + * TODO(jochen): Document LOG_API and other RuntimeCallStats macros. + * TODO(jochen): All API methods should invoke one of the ENTER_V8* macros. + * TODO(jochen): Remove calls form API methods to DO_NOT_USE macros. + */ + +#define LOG_API(isolate, class_name, function_name) \ + i::RuntimeCallTimerScope _runtime_timer( \ + isolate, i::RuntimeCallCounterId::kAPI_##class_name##_##function_name); \ + LOG(isolate, ApiEntryCall("v8::" #class_name "::" #function_name)) + +#define ENTER_V8_DO_NOT_USE(isolate) i::VMState<v8::OTHER> __state__((isolate)) + +#define ENTER_V8_HELPER_DO_NOT_USE(isolate, context, class_name, \ + function_name, bailout_value, \ + HandleScopeClass, do_callback) \ + if (IsExecutionTerminatingCheck(isolate)) { \ + return bailout_value; \ + } \ + HandleScopeClass handle_scope(isolate); \ + CallDepthScope<do_callback> call_depth_scope(isolate, context); \ + LOG_API(isolate, class_name, function_name); \ + i::VMState<v8::OTHER> __state__((isolate)); \ + bool has_pending_exception = false + +#define PREPARE_FOR_DEBUG_INTERFACE_EXECUTION_WITH_ISOLATE(isolate, T) \ + if (IsExecutionTerminatingCheck(isolate)) { \ + return MaybeLocal<T>(); \ + } \ + InternalEscapableScope handle_scope(isolate); \ + CallDepthScope<false> call_depth_scope(isolate, v8::Local<v8::Context>()); \ + i::VMState<v8::OTHER> __state__((isolate)); \ + bool has_pending_exception = false + +#define PREPARE_FOR_EXECUTION_WITH_CONTEXT(context, class_name, function_name, \ + bailout_value, HandleScopeClass, \ + do_callback) \ + auto isolate = context.IsEmpty() \ + ? i::Isolate::Current() \ + : reinterpret_cast<i::Isolate*>(context->GetIsolate()); \ + ENTER_V8_HELPER_DO_NOT_USE(isolate, context, class_name, function_name, \ + bailout_value, HandleScopeClass, do_callback); + +#define PREPARE_FOR_EXECUTION(context, class_name, function_name, T) \ + PREPARE_FOR_EXECUTION_WITH_CONTEXT(context, class_name, function_name, \ + MaybeLocal<T>(), InternalEscapableScope, \ + false) + +#define ENTER_V8(isolate, context, class_name, function_name, bailout_value, \ + HandleScopeClass) \ + ENTER_V8_HELPER_DO_NOT_USE(isolate, context, class_name, function_name, \ + bailout_value, HandleScopeClass, true) + +#ifdef DEBUG +#define ENTER_V8_NO_SCRIPT(isolate, context, class_name, function_name, \ + bailout_value, HandleScopeClass) \ + ENTER_V8_HELPER_DO_NOT_USE(isolate, context, class_name, function_name, \ + bailout_value, HandleScopeClass, false); \ + i::DisallowJavascriptExecutionDebugOnly __no_script__((isolate)) + +// Lightweight version for APIs that don't require an active context. +#define ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate) \ + i::DisallowJavascriptExecutionDebugOnly __no_script__((isolate)); \ + i::DisallowExceptions __no_exceptions__((isolate)) + +#define ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate) \ + i::VMState<v8::OTHER> __state__((isolate)); \ + ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate) + +#define ENTER_V8_FOR_NEW_CONTEXT(isolate) \ + i::VMState<v8::OTHER> __state__((isolate)); \ + i::DisallowExceptions __no_exceptions__((isolate)) +#else +#define ENTER_V8_NO_SCRIPT(isolate, context, class_name, function_name, \ + bailout_value, HandleScopeClass) \ + ENTER_V8_HELPER_DO_NOT_USE(isolate, context, class_name, function_name, \ + bailout_value, HandleScopeClass, false) + +#define ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate) + +#define ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate) \ + i::VMState<v8::OTHER> __state__((isolate)); + +#define ENTER_V8_FOR_NEW_CONTEXT(isolate) \ + i::VMState<v8::OTHER> __state__((isolate)); +#endif // DEBUG + +#define EXCEPTION_BAILOUT_CHECK_SCOPED_DO_NOT_USE(isolate, value) \ + do { \ + if (has_pending_exception) { \ + call_depth_scope.Escape(); \ + return value; \ + } \ + } while (false) + +#define RETURN_ON_FAILED_EXECUTION(T) \ + EXCEPTION_BAILOUT_CHECK_SCOPED_DO_NOT_USE(isolate, MaybeLocal<T>()) + +#define RETURN_ON_FAILED_EXECUTION_PRIMITIVE(T) \ + EXCEPTION_BAILOUT_CHECK_SCOPED_DO_NOT_USE(isolate, Nothing<T>()) + +#define RETURN_ESCAPED(value) return handle_scope.Escape(value); + +// TODO(jochen): This should be #ifdef DEBUG +#ifdef V8_CHECK_MICROTASKS_SCOPES_CONSISTENCY +#endif diff --git a/chromium/v8/src/api/api-natives.cc b/chromium/v8/src/api/api-natives.cc index f8f660ea15c..584d326aaf5 100644 --- a/chromium/v8/src/api/api-natives.cc +++ b/chromium/v8/src/api/api-natives.cc @@ -18,7 +18,7 @@ namespace internal { namespace { -class InvokeScope { +class V8_NODISCARD InvokeScope { public: explicit InvokeScope(Isolate* isolate) : isolate_(isolate), save_context_(isolate) {} @@ -67,33 +67,31 @@ MaybeHandle<Object> Instantiate( } } -MaybeHandle<Object> DefineAccessorProperty( - Isolate* isolate, Handle<JSObject> object, Handle<Name> name, - Handle<Object> getter, Handle<Object> setter, PropertyAttributes attributes, - bool force_instantiate) { +MaybeHandle<Object> DefineAccessorProperty(Isolate* isolate, + Handle<JSObject> object, + Handle<Name> name, + Handle<Object> getter, + Handle<Object> setter, + PropertyAttributes attributes) { DCHECK(!getter->IsFunctionTemplateInfo() || !FunctionTemplateInfo::cast(*getter).do_not_cache()); DCHECK(!setter->IsFunctionTemplateInfo() || !FunctionTemplateInfo::cast(*setter).do_not_cache()); - if (getter->IsFunctionTemplateInfo()) { - if (force_instantiate || - FunctionTemplateInfo::cast(*getter).BreakAtEntry()) { - ASSIGN_RETURN_ON_EXCEPTION( - isolate, getter, - InstantiateFunction(isolate, - Handle<FunctionTemplateInfo>::cast(getter)), - Object); - } + if (getter->IsFunctionTemplateInfo() && + FunctionTemplateInfo::cast(*getter).BreakAtEntry()) { + ASSIGN_RETURN_ON_EXCEPTION( + isolate, getter, + InstantiateFunction(isolate, + Handle<FunctionTemplateInfo>::cast(getter)), + Object); } - if (setter->IsFunctionTemplateInfo()) { - if (force_instantiate || - FunctionTemplateInfo::cast(*setter).BreakAtEntry()) { - ASSIGN_RETURN_ON_EXCEPTION( - isolate, setter, - InstantiateFunction(isolate, - Handle<FunctionTemplateInfo>::cast(setter)), - Object); - } + if (setter->IsFunctionTemplateInfo() && + FunctionTemplateInfo::cast(*setter).BreakAtEntry()) { + ASSIGN_RETURN_ON_EXCEPTION( + isolate, setter, + InstantiateFunction(isolate, + Handle<FunctionTemplateInfo>::cast(setter)), + Object); } RETURN_ON_EXCEPTION( isolate, @@ -148,7 +146,7 @@ void EnableAccessChecks(Isolate* isolate, Handle<JSObject> object) { JSObject::MigrateToMap(isolate, object, new_map); } -class AccessCheckDisableScope { +class V8_NODISCARD AccessCheckDisableScope { public: AccessCheckDisableScope(Isolate* isolate, Handle<JSObject> obj) : isolate_(isolate), @@ -186,6 +184,8 @@ Object GetIntrinsic(Isolate* isolate, v8::Intrinsic intrinsic) { template <typename TemplateInfoT> MaybeHandle<JSObject> ConfigureInstance(Isolate* isolate, Handle<JSObject> obj, Handle<TemplateInfoT> data) { + RuntimeCallTimerScope timer(isolate, + RuntimeCallCounterId::kConfigureInstance); HandleScope scope(isolate); // Disable access checks while instantiating the object. AccessCheckDisableScope access_check_scope(isolate, obj); @@ -254,7 +254,7 @@ MaybeHandle<JSObject> ConfigureInstance(Isolate* isolate, Handle<JSObject> obj, auto setter = handle(properties->get(i++), isolate); RETURN_ON_EXCEPTION(isolate, DefineAccessorProperty(isolate, obj, name, getter, - setter, attributes, false), + setter, attributes), JSObject); } } else { @@ -293,7 +293,7 @@ MaybeHandle<JSObject> ProbeInstantiationsCache( FixedArray fast_cache = native_context->fast_template_instantiations_cache(); Handle<Object> object{fast_cache.get(serial_number - 1), isolate}; - if (object->IsUndefined(isolate)) return {}; + if (object->IsTheHole(isolate)) return {}; return Handle<JSObject>::cast(object); } if (caching_mode == CachingMode::kUnlimited || @@ -357,7 +357,7 @@ void UncacheTemplateInstantiation(Isolate* isolate, bool IsSimpleInstantiation(Isolate* isolate, ObjectTemplateInfo info, JSReceiver new_target) { - DisallowHeapAllocation no_gc; + DisallowGarbageCollection no_gc; if (!new_target.IsJSFunction()) return false; JSFunction fun = JSFunction::cast(new_target); @@ -371,6 +371,8 @@ MaybeHandle<JSObject> InstantiateObject(Isolate* isolate, Handle<ObjectTemplateInfo> info, Handle<JSReceiver> new_target, bool is_prototype) { + RuntimeCallTimerScope timer(isolate, + RuntimeCallCounterId::kInstantiateObject); Handle<JSFunction> constructor; int serial_number = info->serial_number(); if (!new_target.is_null()) { @@ -463,6 +465,8 @@ MaybeHandle<Object> GetInstancePrototype(Isolate* isolate, MaybeHandle<JSFunction> InstantiateFunction( Isolate* isolate, Handle<NativeContext> native_context, Handle<FunctionTemplateInfo> data, MaybeHandle<Name> maybe_name) { + RuntimeCallTimerScope timer(isolate, + RuntimeCallCounterId::kInstantiateFunction); int serial_number = data->serial_number(); if (serial_number) { Handle<JSObject> result; @@ -599,7 +603,7 @@ MaybeHandle<JSObject> ApiNatives::InstantiateRemoteObject( void ApiNatives::AddDataProperty(Isolate* isolate, Handle<TemplateInfo> info, Handle<Name> name, Handle<Object> value, PropertyAttributes attributes) { - PropertyDetails details(kData, attributes, PropertyCellType::kNoCell); + PropertyDetails details(kData, attributes, PropertyConstness::kMutable); auto details_handle = handle(details.AsSmi(), isolate); Handle<Object> data[] = {name, details_handle, value}; AddPropertyToPropertyList(isolate, info, arraysize(data), data); @@ -610,7 +614,7 @@ void ApiNatives::AddDataProperty(Isolate* isolate, Handle<TemplateInfo> info, PropertyAttributes attributes) { auto value = handle(Smi::FromInt(intrinsic), isolate); auto intrinsic_marker = isolate->factory()->true_value(); - PropertyDetails details(kData, attributes, PropertyCellType::kNoCell); + PropertyDetails details(kData, attributes, PropertyConstness::kMutable); auto details_handle = handle(details.AsSmi(), isolate); Handle<Object> data[] = {name, intrinsic_marker, details_handle, value}; AddPropertyToPropertyList(isolate, info, arraysize(data), data); @@ -622,7 +626,7 @@ void ApiNatives::AddAccessorProperty(Isolate* isolate, Handle<FunctionTemplateInfo> getter, Handle<FunctionTemplateInfo> setter, PropertyAttributes attributes) { - PropertyDetails details(kAccessor, attributes, PropertyCellType::kNoCell); + PropertyDetails details(kAccessor, attributes, PropertyConstness::kMutable); auto details_handle = handle(details.AsSmi(), isolate); Handle<Object> data[] = {name, details_handle, getter, setter}; AddPropertyToPropertyList(isolate, info, arraysize(data), data); @@ -646,6 +650,8 @@ Handle<JSFunction> ApiNatives::CreateApiFunction( Isolate* isolate, Handle<NativeContext> native_context, Handle<FunctionTemplateInfo> obj, Handle<Object> prototype, InstanceType type, MaybeHandle<Name> maybe_name) { + RuntimeCallTimerScope timer(isolate, + RuntimeCallCounterId::kCreateApiFunction); Handle<SharedFunctionInfo> shared = FunctionTemplateInfo::GetOrCreateSharedFunctionInfo(isolate, obj, maybe_name); @@ -653,8 +659,7 @@ Handle<JSFunction> ApiNatives::CreateApiFunction( DCHECK(shared->HasSharedName()); Handle<JSFunction> result = - isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, - native_context); + Factory::JSFunctionBuilder{isolate, shared, native_context}.Build(); if (obj->remove_prototype()) { DCHECK(prototype.is_null()); @@ -689,8 +694,8 @@ Handle<JSFunction> ApiNatives::CreateApiFunction( immutable_proto = GetInstanceTemplate->immutable_proto(); } - // JS_FUNCTION_TYPE requires information about the prototype slot. - DCHECK_NE(JS_FUNCTION_TYPE, type); + // JSFunction requires information about the prototype slot. + DCHECK(!InstanceTypeChecker::IsJSFunction(type)); int instance_size = JSObject::GetHeaderSize(type) + kEmbedderDataSlotSize * embedder_field_count; diff --git a/chromium/v8/src/api/api.cc b/chromium/v8/src/api/api.cc index a29747da62f..a56b7e1a7d7 100644 --- a/chromium/v8/src/api/api.cc +++ b/chromium/v8/src/api/api.cc @@ -11,6 +11,7 @@ #include <utility> // For move #include <vector> +#include "include/cppgc/custom-space.h" #include "include/v8-cppgc.h" #include "include/v8-fast-api-calls.h" #include "include/v8-profiler.h" @@ -33,10 +34,6 @@ #include "src/common/globals.h" #include "src/compiler-dispatcher/compiler-dispatcher.h" #include "src/date/date.h" -#include "src/debug/debug-coverage.h" -#include "src/debug/debug-evaluate.h" -#include "src/debug/debug-type-profile.h" -#include "src/debug/debug.h" #include "src/debug/liveedit.h" #include "src/deoptimizer/deoptimizer.h" #include "src/diagnostics/gdb-jit.h" @@ -67,12 +64,10 @@ #include "src/objects/contexts.h" #include "src/objects/embedder-data-array-inl.h" #include "src/objects/embedder-data-slot-inl.h" -#include "src/objects/frame-array-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/js-weak-refs-inl.h" @@ -84,6 +79,7 @@ #include "src/objects/property-details.h" #include "src/objects/property.h" #include "src/objects/prototype.h" +#include "src/objects/shared-function-info.h" #include "src/objects/slots.h" #include "src/objects/smi.h" #include "src/objects/stack-frame-info-inl.h" @@ -99,6 +95,7 @@ #include "src/profiler/heap-snapshot-generator-inl.h" #include "src/profiler/profile-generator-inl.h" #include "src/profiler/tick-sample.h" +#include "src/regexp/regexp-stack.h" #include "src/regexp/regexp-utils.h" #include "src/runtime/runtime.h" #include "src/snapshot/code-serializer.h" @@ -131,10 +128,14 @@ #include "include/v8-wasm-trap-handler-win.h" #include "src/trap-handler/handler-inside-win.h" #if defined(V8_OS_WIN64) +#include "src/base/platform/wrappers.h" #include "src/diagnostics/unwinding-info-win64.h" #endif // V8_OS_WIN64 #endif // V8_OS_WIN +// Has to be the last include (doesn't have include guards): +#include "src/api/api-macros.h" + #define TRACE_BS(...) \ do { \ if (i::FLAG_trace_backing_store) PrintF(__VA_ARGS__); \ @@ -142,240 +143,20 @@ namespace v8 { -/* - * Most API methods should use one of the three macros: - * - * ENTER_V8, ENTER_V8_NO_SCRIPT, ENTER_V8_NO_SCRIPT_NO_EXCEPTION. - * - * The latter two assume that no script is executed, and no exceptions are - * scheduled in addition (respectively). Creating a pending exception and - * removing it before returning is ok. - * - * Exceptions should be handled either by invoking one of the - * RETURN_ON_FAILED_EXECUTION* macros. - * - * Don't use macros with DO_NOT_USE in their name. - * - * TODO(jochen): Document debugger specific macros. - * TODO(jochen): Document LOG_API and other RuntimeCallStats macros. - * TODO(jochen): All API methods should invoke one of the ENTER_V8* macros. - * TODO(jochen): Remove calls form API methods to DO_NOT_USE macros. - */ - -#define LOG_API(isolate, class_name, function_name) \ - i::RuntimeCallTimerScope _runtime_timer( \ - isolate, i::RuntimeCallCounterId::kAPI_##class_name##_##function_name); \ - LOG(isolate, ApiEntryCall("v8::" #class_name "::" #function_name)) - -#define ENTER_V8_DO_NOT_USE(isolate) i::VMState<v8::OTHER> __state__((isolate)) - -#define ENTER_V8_HELPER_DO_NOT_USE(isolate, context, class_name, \ - function_name, bailout_value, \ - HandleScopeClass, do_callback) \ - if (IsExecutionTerminatingCheck(isolate)) { \ - return bailout_value; \ - } \ - HandleScopeClass handle_scope(isolate); \ - CallDepthScope<do_callback> call_depth_scope(isolate, context); \ - LOG_API(isolate, class_name, function_name); \ - i::VMState<v8::OTHER> __state__((isolate)); \ - bool has_pending_exception = false - -#define PREPARE_FOR_DEBUG_INTERFACE_EXECUTION_WITH_ISOLATE(isolate, T) \ - if (IsExecutionTerminatingCheck(isolate)) { \ - return MaybeLocal<T>(); \ - } \ - InternalEscapableScope handle_scope(isolate); \ - CallDepthScope<false> call_depth_scope(isolate, v8::Local<v8::Context>()); \ - i::VMState<v8::OTHER> __state__((isolate)); \ - bool has_pending_exception = false - -#define PREPARE_FOR_EXECUTION_WITH_CONTEXT(context, class_name, function_name, \ - bailout_value, HandleScopeClass, \ - do_callback) \ - auto isolate = context.IsEmpty() \ - ? i::Isolate::Current() \ - : reinterpret_cast<i::Isolate*>(context->GetIsolate()); \ - ENTER_V8_HELPER_DO_NOT_USE(isolate, context, class_name, function_name, \ - bailout_value, HandleScopeClass, do_callback); - -#define PREPARE_FOR_EXECUTION(context, class_name, function_name, T) \ - PREPARE_FOR_EXECUTION_WITH_CONTEXT(context, class_name, function_name, \ - MaybeLocal<T>(), InternalEscapableScope, \ - false) - -#define ENTER_V8(isolate, context, class_name, function_name, bailout_value, \ - HandleScopeClass) \ - ENTER_V8_HELPER_DO_NOT_USE(isolate, context, class_name, function_name, \ - bailout_value, HandleScopeClass, true) - -#ifdef DEBUG -#define ENTER_V8_NO_SCRIPT(isolate, context, class_name, function_name, \ - bailout_value, HandleScopeClass) \ - ENTER_V8_HELPER_DO_NOT_USE(isolate, context, class_name, function_name, \ - bailout_value, HandleScopeClass, false); \ - i::DisallowJavascriptExecutionDebugOnly __no_script__((isolate)) - -#define ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate) \ - i::VMState<v8::OTHER> __state__((isolate)); \ - i::DisallowJavascriptExecutionDebugOnly __no_script__((isolate)); \ - i::DisallowExceptions __no_exceptions__((isolate)) - -#define ENTER_V8_FOR_NEW_CONTEXT(isolate) \ - i::VMState<v8::OTHER> __state__((isolate)); \ - i::DisallowExceptions __no_exceptions__((isolate)) -#else -#define ENTER_V8_NO_SCRIPT(isolate, context, class_name, function_name, \ - bailout_value, HandleScopeClass) \ - ENTER_V8_HELPER_DO_NOT_USE(isolate, context, class_name, function_name, \ - bailout_value, HandleScopeClass, false) - -#define ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate) \ - i::VMState<v8::OTHER> __state__((isolate)); - -#define ENTER_V8_FOR_NEW_CONTEXT(isolate) \ - i::VMState<v8::OTHER> __state__((isolate)); -#endif // DEBUG - -#define EXCEPTION_BAILOUT_CHECK_SCOPED_DO_NOT_USE(isolate, value) \ - do { \ - if (has_pending_exception) { \ - call_depth_scope.Escape(); \ - return value; \ - } \ - } while (false) - -#define RETURN_ON_FAILED_EXECUTION(T) \ - EXCEPTION_BAILOUT_CHECK_SCOPED_DO_NOT_USE(isolate, MaybeLocal<T>()) - -#define RETURN_ON_FAILED_EXECUTION_PRIMITIVE(T) \ - EXCEPTION_BAILOUT_CHECK_SCOPED_DO_NOT_USE(isolate, Nothing<T>()) - -#define RETURN_ESCAPED(value) return handle_scope.Escape(value); - -namespace { - -class InternalEscapableScope : public v8::EscapableHandleScope { - public: - explicit inline InternalEscapableScope(i::Isolate* isolate) - : v8::EscapableHandleScope(reinterpret_cast<v8::Isolate*>(isolate)) {} -}; - -// TODO(jochen): This should be #ifdef DEBUG -#ifdef V8_CHECK_MICROTASKS_SCOPES_CONSISTENCY -void CheckMicrotasksScopesConsistency(i::MicrotaskQueue* microtask_queue) { - if (microtask_queue && - microtask_queue->microtasks_policy() == v8::MicrotasksPolicy::kScoped) { - DCHECK(microtask_queue->GetMicrotasksScopeDepth() || - !microtask_queue->DebugMicrotasksScopeDepthIsZero()); - } -} -#endif - -template <bool do_callback> -class CallDepthScope { - public: - CallDepthScope(i::Isolate* isolate, Local<Context> context) - : isolate_(isolate), - context_(context), - escaped_(false), - safe_for_termination_(isolate->next_v8_call_is_safe_for_termination()), - interrupts_scope_(isolate_, i::StackGuard::TERMINATE_EXECUTION, - isolate_->only_terminate_in_safe_scope() - ? (safe_for_termination_ - ? i::InterruptsScope::kRunInterrupts - : i::InterruptsScope::kPostponeInterrupts) - : i::InterruptsScope::kNoop) { - isolate_->thread_local_top()->IncrementCallDepth(this); - 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().is_null() && - isolate->context().native_context() == env->native_context()) { - context_ = Local<Context>(); - } else { - impl->SaveContext(isolate->context()); - isolate->set_context(*env); - } - } - if (do_callback) isolate_->FireBeforeCallEnteredCallback(); - } - ~CallDepthScope() { - i::MicrotaskQueue* microtask_queue = isolate_->default_microtask_queue(); - if (!context_.IsEmpty()) { - i::HandleScopeImplementer* impl = isolate_->handle_scope_implementer(); - isolate_->set_context(impl->RestoreContext()); - - i::Handle<i::Context> env = Utils::OpenHandle(*context_); - microtask_queue = env->native_context().microtask_queue(); - } - if (!escaped_) isolate_->thread_local_top()->DecrementCallDepth(this); - if (do_callback) isolate_->FireCallCompletedCallback(microtask_queue); -// TODO(jochen): This should be #ifdef DEBUG -#ifdef V8_CHECK_MICROTASKS_SCOPES_CONSISTENCY - if (do_callback) CheckMicrotasksScopesConsistency(microtask_queue); -#endif - DCHECK(CheckKeptObjectsClearedAfterMicrotaskCheckpoint(microtask_queue)); - isolate_->set_next_v8_call_is_safe_for_termination(safe_for_termination_); - } - - void Escape() { - DCHECK(!escaped_); - escaped_ = true; - auto thread_local_top = isolate_->thread_local_top(); - thread_local_top->DecrementCallDepth(this); - bool clear_exception = thread_local_top->CallDepthIsZero() && - thread_local_top->try_catch_handler_ == nullptr; - isolate_->OptionalRescheduleException(clear_exception); - } - - private: - bool CheckKeptObjectsClearedAfterMicrotaskCheckpoint( - i::MicrotaskQueue* microtask_queue) { - bool did_perform_microtask_checkpoint = - isolate_->thread_local_top()->CallDepthIsZero() && - do_callback && microtask_queue && - microtask_queue->microtasks_policy() == MicrotasksPolicy::kAuto; - return !did_perform_microtask_checkpoint || - isolate_->heap()->weak_refs_keep_during_job().IsUndefined(isolate_); - } - - i::Isolate* const isolate_; - Local<Context> context_; - bool escaped_; - bool do_callback_; - bool safe_for_termination_; - i::InterruptsScope interrupts_scope_; - i::Address previous_stack_height_; - - friend class i::ThreadLocalTop; - - DISALLOW_NEW_AND_DELETE() - DISALLOW_COPY_AND_ASSIGN(CallDepthScope); -}; - -} // namespace - static ScriptOrigin GetScriptOriginForScript(i::Isolate* isolate, i::Handle<i::Script> script) { i::Handle<i::Object> scriptName(script->GetNameOrSourceURL(), isolate); i::Handle<i::Object> source_map_url(script->source_mapping_url(), isolate); i::Handle<i::FixedArray> host_defined_options(script->host_defined_options(), isolate); - v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate); ScriptOriginOptions options(script->origin_options()); v8::ScriptOrigin origin( - Utils::ToLocal(scriptName), - v8::Integer::New(v8_isolate, script->line_offset()), - v8::Integer::New(v8_isolate, script->column_offset()), - v8::Boolean::New(v8_isolate, options.IsSharedCrossOrigin()), - v8::Integer::New(v8_isolate, script->id()), - Utils::ToLocal(source_map_url), - v8::Boolean::New(v8_isolate, options.IsOpaque()), - v8::Boolean::New(v8_isolate, script->type() == i::Script::TYPE_WASM), - v8::Boolean::New(v8_isolate, options.IsModule()), - Utils::ToLocal(host_defined_options)); + reinterpret_cast<v8::Isolate*>(isolate), Utils::ToLocal(scriptName), + script->line_offset(), script->column_offset(), + options.IsSharedCrossOrigin(), script->id(), + Utils::ToLocal(source_map_url), options.IsOpaque(), + script->type() == i::Script::TYPE_WASM, options.IsModule(), + Utils::PrimitiveArrayToLocal(host_defined_options)); return origin; } @@ -527,14 +308,6 @@ void Utils::ReportOOMFailure(i::Isolate* isolate, const char* location, isolate->SignalFatalError(); } -static inline bool IsExecutionTerminatingCheck(i::Isolate* isolate) { - if (isolate->has_scheduled_exception()) { - return isolate->scheduled_exception() == - i::ReadOnlyRoots(isolate).termination_exception(); - } - return false; -} - void V8::SetSnapshotDataBlob(StartupData* snapshot_blob) { i::V8::SetSnapshotBlob(snapshot_blob); } @@ -549,7 +322,7 @@ class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator { // See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79839 void* data = __linux_calloc(length, 1); #else - void* data = calloc(length, 1); + void* data = base::Calloc(length, 1); #endif return data; } @@ -560,12 +333,12 @@ class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator { // See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79839 void* data = __linux_malloc(length); #else - void* data = malloc(length); + void* data = base::Malloc(length); #endif return data; } - void Free(void* data, size_t) override { free(data); } + void Free(void* data, size_t) override { base::Free(data); } void* Reallocate(void* data, size_t old_length, size_t new_length) override { #if V8_OS_AIX && _LINUX_SOURCE_COMPAT @@ -573,7 +346,7 @@ class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator { // See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79839 void* new_data = __linux_realloc(data, new_length); #else - void* new_data = realloc(data, new_length); + void* new_data = base::Realloc(data, new_length); #endif if (new_length > old_length) { memset(reinterpret_cast<uint8_t*>(new_data) + old_length, 0, @@ -793,7 +566,7 @@ StartupData SnapshotCreator::CreateBlob( // Create a vector with all contexts and clear associated Persistent fields. // Note these contexts may be dead after calling Clear(), but will not be - // collected until serialization completes and the DisallowHeapAllocation + // collected until serialization completes and the DisallowGarbageCollection // scope above goes out of scope. std::vector<i::Context> contexts; contexts.reserve(num_contexts); @@ -954,17 +727,6 @@ void ResourceConstraints::ConfigureDefaults(uint64_t physical_memory, } } -size_t ResourceConstraints::max_semi_space_size_in_kb() const { - return i::Heap::SemiSpaceSizeFromYoungGenerationSize( - max_young_generation_size_) / - i::KB; -} - -void ResourceConstraints::set_max_semi_space_size_in_kb(size_t limit_in_kb) { - set_max_young_generation_size_in_bytes( - i::Heap::YoungGenerationSizeFromSemiSpaceSize(limit_in_kb * i::KB)); -} - 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); @@ -1162,7 +924,7 @@ void SealHandleScope::operator delete[](void*, size_t) { base::OS::Abort(); } bool Data::IsModule() const { return Utils::OpenHandle(this)->IsModule(); } bool Data::IsValue() const { - i::DisallowHeapAllocation no_gc; + i::DisallowGarbageCollection no_gc; i::Handle<i::Object> self = Utils::OpenHandle(this); if (self->IsSmi()) { return true; @@ -1187,6 +949,8 @@ bool Data::IsFunctionTemplate() const { return Utils::OpenHandle(this)->IsFunctionTemplateInfo(); } +bool Data::IsContext() const { return Utils::OpenHandle(this)->IsContext(); } + void Context::Enter() { i::Handle<i::Context> env = Utils::OpenHandle(this); i::Isolate* isolate = env->GetIsolate(); @@ -1241,6 +1005,7 @@ static i::Handle<i::EmbedderDataArray> EmbedderDataFor(Context* context, const char* location) { i::Handle<i::Context> env = Utils::OpenHandle(context); i::Isolate* isolate = env->GetIsolate(); + ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate); bool ok = Utils::ApiCheck(env->IsNativeContext(), location, "Not a native context") && Utils::ApiCheck(index >= 0, location, "Negative index"); @@ -1260,7 +1025,10 @@ static i::Handle<i::EmbedderDataArray> EmbedderDataFor(Context* context, uint32_t Context::GetNumberOfEmbedderDataFields() { i::Handle<i::Context> context = Utils::OpenHandle(this); - CHECK(context->IsNativeContext()); + ASSERT_NO_SCRIPT_NO_EXCEPTION(context->GetIsolate()); + Utils::ApiCheck(context->IsNativeContext(), + "Context::GetNumberOfEmbedderDataFields", + "Not a native context"); // TODO(ishell): remove cast once embedder_data slot has a proper type. return static_cast<uint32_t>( i::EmbedderDataArray::cast(context->embedder_data()).length()); @@ -1315,9 +1083,9 @@ void Context::SetAlignedPointerInEmbedderData(int index, void* value) { // --- T e m p l a t e --- -static void InitializeTemplate(i::Handle<i::TemplateInfo> that, int type) { - that->set_number_of_properties(0); - that->set_tag(type); +static void InitializeTemplate(i::TemplateInfo that, int type) { + that.set_number_of_properties(0); + that.set_tag(type); } void Template::Set(v8::Local<Name> name, v8::Local<Data> value, @@ -1365,10 +1133,9 @@ void Template::SetAccessorProperty(v8::Local<v8::Name> name, } // --- F u n c t i o n T e m p l a t e --- -static void InitializeFunctionTemplate( - i::Handle<i::FunctionTemplateInfo> info) { +static void InitializeFunctionTemplate(i::FunctionTemplateInfo info) { InitializeTemplate(info, Consts::FUNCTION_TEMPLATE); - info->set_flag(0); + info.set_flag(0); } static Local<ObjectTemplate> ObjectTemplateNew( @@ -1420,7 +1187,8 @@ void FunctionTemplate::Inherit(v8::Local<FunctionTemplate> value) { static Local<FunctionTemplate> FunctionTemplateNew( i::Isolate* isolate, FunctionCallback callback, v8::Local<Value> data, - v8::Local<Signature> signature, int length, bool do_not_cache, + v8::Local<Signature> signature, int length, ConstructorBehavior behavior, + bool do_not_cache, v8::Local<Private> cached_property_name = v8::Local<Private>(), SideEffectType side_effect_type = SideEffectType::kHasSideEffect, const CFunction* c_function = nullptr) { @@ -1430,30 +1198,32 @@ static Local<FunctionTemplate> FunctionTemplateNew( i::Handle<i::FunctionTemplateInfo>::cast(struct_obj); { // Disallow GC until all fields of obj have acceptable types. - i::DisallowHeapAllocation no_gc; - InitializeFunctionTemplate(obj); - obj->set_length(length); - obj->set_do_not_cache(do_not_cache); + i::DisallowGarbageCollection no_gc; + i::FunctionTemplateInfo raw = *obj; + InitializeFunctionTemplate(raw); + raw.set_length(length); + raw.set_do_not_cache(do_not_cache); int next_serial_number = i::FunctionTemplateInfo::kInvalidSerialNumber; if (!do_not_cache) { next_serial_number = isolate->heap()->GetNextTemplateSerialNumber(); } - obj->set_serial_number(next_serial_number); + raw.set_serial_number(next_serial_number); + raw.set_undetectable(false); + raw.set_needs_access_check(false); + raw.set_accept_any_receiver(true); + if (!signature.IsEmpty()) { + raw.set_signature(*Utils::OpenHandle(*signature)); + } + raw.set_cached_property_name( + cached_property_name.IsEmpty() + ? i::ReadOnlyRoots(isolate).the_hole_value() + : *Utils::OpenHandle(*cached_property_name)); + if (behavior == ConstructorBehavior::kThrow) raw.set_remove_prototype(true); } if (callback != nullptr) { Utils::ToLocal(obj)->SetCallHandler(callback, data, side_effect_type, c_function); } - obj->set_undetectable(false); - obj->set_needs_access_check(false); - obj->set_accept_any_receiver(true); - if (!signature.IsEmpty()) { - obj->set_signature(*Utils::OpenHandle(*signature)); - } - obj->set_cached_property_name( - cached_property_name.IsEmpty() - ? i::ReadOnlyRoots(isolate).the_hole_value() - : *Utils::OpenHandle(*cached_property_name)); return Utils::ToLocal(obj); } @@ -1466,10 +1236,9 @@ Local<FunctionTemplate> FunctionTemplate::New( // function templates when the isolate is created for serialization. LOG_API(i_isolate, FunctionTemplate, New); ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); - auto templ = - FunctionTemplateNew(i_isolate, callback, data, signature, length, false, - Local<Private>(), side_effect_type, c_function); - if (behavior == ConstructorBehavior::kThrow) templ->RemovePrototype(); + auto templ = FunctionTemplateNew(i_isolate, callback, data, signature, length, + behavior, false, Local<Private>(), + side_effect_type, c_function); return templ; } @@ -1481,7 +1250,8 @@ Local<FunctionTemplate> FunctionTemplate::NewWithCache( LOG_API(i_isolate, FunctionTemplate, NewWithCache); ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); return FunctionTemplateNew(i_isolate, callback, data, signature, length, - false, cache_property, side_effect_type); + ConstructorBehavior::kAllow, false, cache_property, + side_effect_type); } Local<Signature> Signature::New(Isolate* isolate, @@ -1651,17 +1421,19 @@ static Local<ObjectTemplate> ObjectTemplateNew( i::Handle<i::ObjectTemplateInfo>::cast(struct_obj); { // Disallow GC until all fields of obj have acceptable types. - i::DisallowHeapAllocation no_gc; - InitializeTemplate(obj, Consts::OBJECT_TEMPLATE); + i::DisallowGarbageCollection no_gc; + i::ObjectTemplateInfo raw = *obj; + InitializeTemplate(raw, Consts::OBJECT_TEMPLATE); + raw.set_data(0); int next_serial_number = 0; if (!do_not_cache) { next_serial_number = isolate->heap()->GetNextTemplateSerialNumber(); } - obj->set_serial_number(next_serial_number); - obj->set_data(0); + raw.set_serial_number(next_serial_number); + if (!constructor.IsEmpty()) { + raw.set_constructor(*Utils::OpenHandle(*constructor)); + } } - if (!constructor.IsEmpty()) - obj->set_constructor(*Utils::OpenHandle(*constructor)); return Utils::ToLocal(obj); } @@ -2052,9 +1824,11 @@ Local<Script> UnboundScript::BindToCurrentContext() { auto function_info = i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this)); i::Isolate* isolate = function_info->GetIsolate(); + ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); i::Handle<i::JSFunction> function = - isolate->factory()->NewFunctionFromSharedFunctionInfo( - function_info, isolate->native_context()); + i::Factory::JSFunctionBuilder{isolate, function_info, + isolate->native_context()} + .Build(); return ToApiHandle<Script>(function); } @@ -2073,6 +1847,7 @@ int UnboundScript::GetLineNumber(int code_pos) { i::Handle<i::SharedFunctionInfo> obj = i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this)); i::Isolate* isolate = obj->GetIsolate(); + ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); LOG_API(isolate, UnboundScript, GetLineNumber); if (obj->script().IsScript()) { i::Handle<i::Script> script(i::Script::cast(obj->script()), isolate); @@ -2086,6 +1861,7 @@ Local<Value> UnboundScript::GetScriptName() { i::Handle<i::SharedFunctionInfo> obj = i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this)); i::Isolate* isolate = obj->GetIsolate(); + ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); LOG_API(isolate, UnboundScript, GetName); if (obj->script().IsScript()) { i::Object name = i::Script::cast(obj->script()).name(); @@ -2099,6 +1875,7 @@ Local<Value> UnboundScript::GetSourceURL() { i::Handle<i::SharedFunctionInfo> obj = i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this)); i::Isolate* isolate = obj->GetIsolate(); + ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); LOG_API(isolate, UnboundScript, GetSourceURL); if (obj->script().IsScript()) { i::Object url = i::Script::cast(obj->script()).source_url(); @@ -2113,6 +1890,7 @@ Local<Value> UnboundScript::GetSourceMappingURL() { i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this)); i::Isolate* isolate = obj->GetIsolate(); LOG_API(isolate, UnboundScript, GetSourceMappingURL); + ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); if (obj->script().IsScript()) { i::Object url = i::Script::cast(obj->script()).source_mapping_url(); return Utils::ToLocal(i::Handle<i::Object>(url, isolate)); @@ -2203,6 +1981,35 @@ Local<Primitive> PrimitiveArray::Get(Isolate* v8_isolate, int index) { return ToApiHandle<Primitive>(i_item); } +int FixedArray::Length() const { + i::Handle<i::FixedArray> self = Utils::OpenHandle(this); + return self->length(); +} + +Local<Data> FixedArray::Get(Local<Context> context, int i) const { + i::Handle<i::FixedArray> self = Utils::OpenHandle(this); + auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate()); + CHECK_LT(i, self->length()); + i::Handle<i::Object> entry(self->get(i), isolate); + return ToApiHandle<Data>(entry); +} + +Local<String> ModuleRequest::GetSpecifier() const { + i::Handle<i::ModuleRequest> self = Utils::OpenHandle(this); + i::Isolate* isolate = self->GetIsolate(); + return ToApiHandle<String>(i::handle(self->specifier(), isolate)); +} + +int ModuleRequest::GetSourceOffset() const { + return Utils::OpenHandle(this)->position(); +} + +Local<FixedArray> ModuleRequest::GetImportAssertions() const { + i::Handle<i::ModuleRequest> self = Utils::OpenHandle(this); + i::Isolate* isolate = self->GetIsolate(); + return ToApiHandle<FixedArray>(i::handle(self->import_assertions(), isolate)); +} + Module::Status Module::GetStatus() const { i::Handle<i::Module> self = Utils::OpenHandle(this); switch (self->status()) { @@ -2228,12 +2035,14 @@ Local<Value> Module::GetException() const { "Module status must be kErrored"); i::Handle<i::Module> self = Utils::OpenHandle(this); i::Isolate* isolate = self->GetIsolate(); + ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); return ToApiHandle<Value>(i::handle(self->GetException(), isolate)); } int Module::GetModuleRequestsLength() const { i::Handle<i::Module> self = Utils::OpenHandle(this); if (self->IsSyntheticModule()) return 0; + ASSERT_NO_SCRIPT_NO_EXCEPTION(self->GetIsolate()); return i::Handle<i::SourceTextModule>::cast(self) ->info() .module_requests() @@ -2243,8 +2052,10 @@ int Module::GetModuleRequestsLength() const { Local<String> Module::GetModuleRequest(int i) const { CHECK_GE(i, 0); i::Handle<i::Module> self = Utils::OpenHandle(this); - CHECK(self->IsSourceTextModule()); + Utils::ApiCheck(self->IsSourceTextModule(), "Module::GetModuleRequest", + "Expected SourceTextModule"); i::Isolate* isolate = self->GetIsolate(); + ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate); i::Handle<i::FixedArray> module_requests( i::Handle<i::SourceTextModule>::cast(self)->info().module_requests(), isolate); @@ -2258,55 +2069,86 @@ Location Module::GetModuleRequestLocation(int i) const { CHECK_GE(i, 0); i::Handle<i::Module> self = Utils::OpenHandle(this); i::Isolate* isolate = self->GetIsolate(); + ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate); i::HandleScope scope(isolate); - CHECK(self->IsSourceTextModule()); - i::Handle<i::FixedArray> module_request_positions( - i::Handle<i::SourceTextModule>::cast(self) - ->info() - .module_request_positions(), + Utils::ApiCheck(self->IsSourceTextModule(), + "Module::GetModuleRequestLocation", + "Expected SourceTextModule"); + i::Handle<i::FixedArray> module_requests( + i::Handle<i::SourceTextModule>::cast(self)->info().module_requests(), isolate); - CHECK_LT(i, module_request_positions->length()); - int position = i::Smi::ToInt(module_request_positions->get(i)); + CHECK_LT(i, module_requests->length()); + i::Handle<i::ModuleRequest> module_request( + i::ModuleRequest::cast(module_requests->get(i)), isolate); + int position = module_request->position(); i::Handle<i::Script> script( - i::Handle<i::SourceTextModule>::cast(self)->script(), isolate); + i::Handle<i::SourceTextModule>::cast(self)->GetScript(), isolate); i::Script::PositionInfo info; i::Script::GetPositionInfo(script, position, &info, i::Script::WITH_OFFSET); return v8::Location(info.line, info.column); } +Local<FixedArray> Module::GetModuleRequests() const { + i::Handle<i::Module> self = Utils::OpenHandle(this); + if (self->IsSyntheticModule()) { + // Synthetic modules are leaf nodes in the module graph. They have no + // ModuleRequests. + return ToApiHandle<FixedArray>( + self->GetReadOnlyRoots().empty_fixed_array_handle()); + } else { + i::Isolate* isolate = self->GetIsolate(); + i::Handle<i::FixedArray> module_requests( + i::Handle<i::SourceTextModule>::cast(self)->info().module_requests(), + isolate); + return ToApiHandle<FixedArray>(module_requests); + } +} + +Location Module::SourceOffsetToLocation(int offset) const { + i::Handle<i::Module> self = Utils::OpenHandle(this); + i::Isolate* isolate = self->GetIsolate(); + ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); + i::HandleScope scope(isolate); + Utils::ApiCheck( + self->IsSourceTextModule(), "v8::Module::SourceOffsetToLocation", + "v8::Module::SourceOffsetToLocation must be used on an SourceTextModule"); + i::Handle<i::Script> script( + i::Handle<i::SourceTextModule>::cast(self)->GetScript(), isolate); + i::Script::PositionInfo info; + i::Script::GetPositionInfo(script, offset, &info, i::Script::WITH_OFFSET); + return v8::Location(info.line, info.column); +} + Local<Value> Module::GetModuleNamespace() { Utils::ApiCheck( GetStatus() >= kInstantiated, "v8::Module::GetModuleNamespace", "v8::Module::GetModuleNamespace must be used on an instantiated module"); i::Handle<i::Module> self = Utils::OpenHandle(this); + auto isolate = self->GetIsolate(); + ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate); i::Handle<i::JSModuleNamespace> module_namespace = - i::Module::GetModuleNamespace(self->GetIsolate(), self); + i::Module::GetModuleNamespace(isolate, self); return ToApiHandle<Value>(module_namespace); } Local<UnboundModuleScript> Module::GetUnboundModuleScript() { - Utils::ApiCheck( - GetStatus() < kEvaluating, "v8::Module::GetUnboundScript", - "v8::Module::GetUnboundScript must be used on an unevaluated module"); i::Handle<i::Module> self = Utils::OpenHandle(this); - CHECK(self->IsSourceTextModule()); - return ToApiHandle<UnboundModuleScript>(i::Handle<i::SharedFunctionInfo>( + Utils::ApiCheck( + self->IsSourceTextModule(), "v8::Module::GetUnboundModuleScript", + "v8::Module::GetUnboundModuleScript must be used on an SourceTextModule"); + auto isolate = self->GetIsolate(); + ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate); + return ToApiHandle<UnboundModuleScript>(i::handle( i::Handle<i::SourceTextModule>::cast(self)->GetSharedFunctionInfo(), - self->GetIsolate())); + isolate)); } int Module::ScriptId() { i::Handle<i::Module> self = Utils::OpenHandle(this); Utils::ApiCheck(self->IsSourceTextModule(), "v8::Module::ScriptId", "v8::Module::ScriptId must be used on an SourceTextModule"); - - // The SharedFunctionInfo is not available for errored modules. - Utils::ApiCheck(GetStatus() != kErrored, "v8::Module::ScriptId", - "v8::Module::ScriptId must not be used on an errored module"); - i::Handle<i::SharedFunctionInfo> sfi( - i::Handle<i::SourceTextModule>::cast(self)->GetSharedFunctionInfo(), - self->GetIsolate()); - return ToApiHandle<UnboundScript>(sfi)->GetId(); + ASSERT_NO_SCRIPT_NO_EXCEPTION(self->GetIsolate()); + return i::Handle<i::SourceTextModule>::cast(self)->GetScript().id(); } bool Module::IsGraphAsync() const { @@ -2314,7 +2156,8 @@ bool Module::IsGraphAsync() const { GetStatus() >= kInstantiated, "v8::Module::IsGraphAsync", "v8::Module::IsGraphAsync must be used on an instantiated module"); i::Handle<i::Module> self = Utils::OpenHandle(this); - auto isolate = reinterpret_cast<i::Isolate*>(self->GetIsolate()); + auto isolate = self->GetIsolate(); + ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate); return self->IsGraphAsync(isolate); } @@ -2333,8 +2176,21 @@ Maybe<bool> Module::InstantiateModule(Local<Context> context, auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate()); ENTER_V8(isolate, context, Module, InstantiateModule, Nothing<bool>(), i::HandleScope); + ResolveModuleCallback callback_with_import_assertions = nullptr; + has_pending_exception = + !i::Module::Instantiate(isolate, Utils::OpenHandle(this), context, + callback_with_import_assertions, callback); + RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); + return Just(true); +} + +Maybe<bool> Module::InstantiateModule(Local<Context> context, + Module::ResolveModuleCallback callback) { + auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate()); + ENTER_V8(isolate, context, Module, InstantiateModule, Nothing<bool>(), + i::HandleScope); has_pending_exception = !i::Module::Instantiate( - isolate, Utils::OpenHandle(this), context, callback); + isolate, Utils::OpenHandle(this), context, callback, nullptr); RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); return Just(true); } @@ -2363,6 +2219,7 @@ Local<Module> Module::CreateSyntheticModule( const std::vector<Local<v8::String>>& export_names, v8::Module::SyntheticModuleEvaluationSteps evaluation_steps) { auto i_isolate = reinterpret_cast<i::Isolate*>(isolate); + ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); i::Handle<i::String> i_module_name = Utils::OpenHandle(*module_name); i::Handle<i::FixedArray> i_export_names = i_isolate->factory()->NewFixedArray( static_cast<int>(export_names.size())); @@ -2403,6 +2260,7 @@ void Module::SetSyntheticModuleExport(Local<String> export_name, i::Handle<i::String> i_export_name = Utils::OpenHandle(*export_name); i::Handle<i::Object> i_export_value = Utils::OpenHandle(*export_value); i::Handle<i::Module> self = Utils::OpenHandle(this); + ASSERT_NO_SCRIPT_NO_EXCEPTION(self->GetIsolate()); Utils::ApiCheck(self->IsSyntheticModule(), "v8::Module::SetSyntheticModuleExport", "v8::Module::SetSyntheticModuleExport must only be called on " @@ -2415,26 +2273,19 @@ void Module::SetSyntheticModuleExport(Local<String> export_name, namespace { i::Compiler::ScriptDetails GetScriptDetails( - i::Isolate* isolate, Local<Value> resource_name, - Local<Integer> resource_line_offset, Local<Integer> resource_column_offset, - Local<Value> source_map_url, Local<PrimitiveArray> host_defined_options) { + i::Isolate* isolate, Local<Value> resource_name, int resource_line_offset, + int resource_column_offset, Local<Value> source_map_url, + Local<PrimitiveArray> host_defined_options) { i::Compiler::ScriptDetails script_details; if (!resource_name.IsEmpty()) { script_details.name_obj = Utils::OpenHandle(*(resource_name)); } - if (!resource_line_offset.IsEmpty()) { - script_details.line_offset = - static_cast<int>(resource_line_offset->Value()); - } - if (!resource_column_offset.IsEmpty()) { - script_details.column_offset = - static_cast<int>(resource_column_offset->Value()); - } - script_details.host_defined_options = isolate->factory()->empty_fixed_array(); - if (!host_defined_options.IsEmpty()) { - script_details.host_defined_options = - Utils::OpenHandle(*(host_defined_options)); - } + script_details.line_offset = resource_line_offset; + script_details.column_offset = resource_column_offset; + script_details.host_defined_options = + host_defined_options.IsEmpty() + ? isolate->factory()->empty_fixed_array() + : Utils::OpenHandle(*(host_defined_options)); if (!source_map_url.IsEmpty()) { script_details.source_map_url = Utils::OpenHandle(*(source_map_url)); } @@ -2511,8 +2362,6 @@ MaybeLocal<Module> ScriptCompiler::CompileModule( NoCacheReason no_cache_reason) { CHECK(options == kNoCompileOptions || options == kConsumeCodeCache); - i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); - Utils::ApiCheck(source->GetResourceOptions().IsModule(), "v8::ScriptCompiler::CompileModule", "Invalid ScriptOrigin: is_module must be true"); @@ -2522,6 +2371,7 @@ MaybeLocal<Module> ScriptCompiler::CompileModule( if (!maybe.ToLocal(&unbound)) return MaybeLocal<Module>(); i::Handle<i::SharedFunctionInfo> shared = Utils::OpenHandle(*unbound); + i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); return ToApiHandle<Module>(i_isolate->factory()->NewSourceTextModule(shared)); } @@ -2531,7 +2381,7 @@ bool IsIdentifier(i::Isolate* isolate, i::Handle<i::String> string) { const int length = string->length(); if (length == 0) return false; if (!i::IsIdentifierStart(string->Get(0))) return false; - i::DisallowHeapAllocation no_gc; + i::DisallowGarbageCollection no_gc; i::String::FlatContent flat = string->GetFlatContent(no_gc); if (flat.IsOneByte()) { auto vector = flat.ToOneByteVector(); @@ -2642,16 +2492,33 @@ ScriptCompiler::ScriptStreamingTask* ScriptCompiler::StartStreamingScript( } ScriptCompiler::ScriptStreamingTask* ScriptCompiler::StartStreaming( - Isolate* v8_isolate, StreamedSource* source) { + Isolate* v8_isolate, StreamedSource* source, v8::ScriptType type) { if (!i::FLAG_script_streaming) return nullptr; i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); + ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate); i::ScriptStreamingData* data = source->impl(); std::unique_ptr<i::BackgroundCompileTask> task = - std::make_unique<i::BackgroundCompileTask>(data, isolate); + std::make_unique<i::BackgroundCompileTask>(data, isolate, type); data->task = std::move(task); return new ScriptCompiler::ScriptStreamingTask(data); } +namespace { +i::MaybeHandle<i::SharedFunctionInfo> CompileStreamedSource( + i::Isolate* isolate, ScriptCompiler::StreamedSource* v8_source, + Local<String> full_source_string, const ScriptOrigin& origin) { + i::Handle<i::String> str = Utils::OpenHandle(*(full_source_string)); + i::Compiler::ScriptDetails script_details = + GetScriptDetails(isolate, origin.ResourceName(), origin.LineOffset(), + origin.ColumnOffset(), origin.SourceMapUrl(), + origin.HostDefinedOptions()); + i::ScriptStreamingData* data = v8_source->impl(); + return i::Compiler::GetSharedFunctionInfoForStreamedScript( + isolate, str, script_details, origin.Options(), data); +} + +} // namespace + MaybeLocal<Script> ScriptCompiler::Compile(Local<Context> context, StreamedSource* v8_source, Local<String> full_source_string, @@ -2660,31 +2527,37 @@ MaybeLocal<Script> ScriptCompiler::Compile(Local<Context> context, TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.ScriptCompiler"); TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.CompileStreamedScript"); - - i::Handle<i::String> str = Utils::OpenHandle(*(full_source_string)); - i::Compiler::ScriptDetails script_details = GetScriptDetails( - isolate, origin.ResourceName(), origin.ResourceLineOffset(), - origin.ResourceColumnOffset(), origin.SourceMapUrl(), - origin.HostDefinedOptions()); - i::ScriptStreamingData* data = v8_source->impl(); - - i::MaybeHandle<i::SharedFunctionInfo> maybe_function_info = - i::Compiler::GetSharedFunctionInfoForStreamedScript( - isolate, str, script_details, origin.Options(), data); - - i::Handle<i::SharedFunctionInfo> result; - has_pending_exception = !maybe_function_info.ToHandle(&result); + i::Handle<i::SharedFunctionInfo> sfi; + i::MaybeHandle<i::SharedFunctionInfo> maybe_sfi = + CompileStreamedSource(isolate, v8_source, full_source_string, origin); + has_pending_exception = !maybe_sfi.ToHandle(&sfi); if (has_pending_exception) isolate->ReportPendingMessages(); - RETURN_ON_FAILED_EXECUTION(Script); - - Local<UnboundScript> generic = ToApiHandle<UnboundScript>(result); + Local<UnboundScript> generic = ToApiHandle<UnboundScript>(sfi); if (generic.IsEmpty()) return Local<Script>(); Local<Script> bound = generic->BindToCurrentContext(); if (bound.IsEmpty()) return Local<Script>(); RETURN_ESCAPED(bound); } +MaybeLocal<Module> ScriptCompiler::CompileModule( + Local<Context> context, StreamedSource* v8_source, + Local<String> full_source_string, const ScriptOrigin& origin) { + PREPARE_FOR_EXECUTION(context, ScriptCompiler, Compile, Module); + TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.ScriptCompiler"); + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), + "V8.CompileStreamedModule"); + i::Handle<i::SharedFunctionInfo> sfi; + i::MaybeHandle<i::SharedFunctionInfo> maybe_sfi = + CompileStreamedSource(isolate, v8_source, full_source_string, origin); + has_pending_exception = !maybe_sfi.ToHandle(&sfi); + if (has_pending_exception) isolate->ReportPendingMessages(); + RETURN_ON_FAILED_EXECUTION(Module); + i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); + RETURN_ESCAPED( + ToApiHandle<Module>(i_isolate->factory()->NewSourceTextModule(sfi))); +} + uint32_t ScriptCompiler::CachedDataVersionTag() { return static_cast<uint32_t>(base::hash_combine( internal::Version::Hash(), internal::FlagList::Hash(), @@ -2696,6 +2569,7 @@ ScriptCompiler::CachedData* ScriptCompiler::CreateCodeCache( i::Handle<i::SharedFunctionInfo> shared = i::Handle<i::SharedFunctionInfo>::cast( Utils::OpenHandle(*unbound_script)); + ASSERT_NO_SCRIPT_NO_EXCEPTION(shared->GetIsolate()); DCHECK(shared->is_toplevel()); return i::CodeSerializer::Serialize(shared); } @@ -2706,6 +2580,7 @@ ScriptCompiler::CachedData* ScriptCompiler::CreateCodeCache( i::Handle<i::SharedFunctionInfo> shared = i::Handle<i::SharedFunctionInfo>::cast( Utils::OpenHandle(*unbound_module_script)); + ASSERT_NO_SCRIPT_NO_EXCEPTION(shared->GetIsolate()); DCHECK(shared->is_toplevel()); return i::CodeSerializer::Serialize(shared); } @@ -2716,6 +2591,7 @@ ScriptCompiler::CachedData* ScriptCompiler::CreateCodeCacheForFunction( i::Handle<i::JSFunction>::cast(Utils::OpenHandle(*function)); i::Handle<i::SharedFunctionInfo> shared(js_function->shared(), js_function->GetIsolate()); + ASSERT_NO_SCRIPT_NO_EXCEPTION(shared->GetIsolate()); CHECK(shared->is_wrapped()); return i::CodeSerializer::Serialize(shared); } @@ -2888,6 +2764,7 @@ ScriptOrigin Message::GetScriptOrigin() const { } v8::Local<Value> Message::GetScriptResourceName() const { + ASSERT_NO_SCRIPT_NO_EXCEPTION(Utils::OpenHandle(this)->GetIsolate()); return GetScriptOrigin().ResourceName(); } @@ -2931,6 +2808,7 @@ int Message::GetEndPosition() const { int Message::ErrorLevel() const { auto self = Utils::OpenHandle(this); + ASSERT_NO_SCRIPT_NO_EXCEPTION(self->GetIsolate()); return self->error_level(); } @@ -3018,11 +2896,9 @@ void Message::PrintCurrentStackTrace(Isolate* isolate, FILE* out) { Local<StackFrame> StackTrace::GetFrame(Isolate* v8_isolate, uint32_t index) const { i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); - ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); - EscapableHandleScope scope(v8_isolate); - auto obj = handle(Utils::OpenHandle(this)->get(index), isolate); - auto frame = i::Handle<i::StackTraceFrame>::cast(obj); - return scope.Escape(Utils::StackFrameToLocal(frame)); + i::Handle<i::StackFrameInfo> frame( + i::StackFrameInfo::cast(Utils::OpenHandle(this)->get(index)), isolate); + return Utils::StackFrameToLocal(frame); } int StackTrace::GetFrameCount() const { @@ -3042,62 +2918,50 @@ Local<StackTrace> StackTrace::CurrentStackTrace(Isolate* isolate, // --- S t a c k F r a m e --- int StackFrame::GetLineNumber() const { - return i::StackTraceFrame::GetOneBasedLineNumber(Utils::OpenHandle(this)); + return i::StackFrameInfo::GetLineNumber(Utils::OpenHandle(this)); } int StackFrame::GetColumn() const { - return i::StackTraceFrame::GetOneBasedColumnNumber(Utils::OpenHandle(this)); + return i::StackFrameInfo::GetColumnNumber(Utils::OpenHandle(this)); } int StackFrame::GetScriptId() const { - return i::StackTraceFrame::GetScriptId(Utils::OpenHandle(this)); + return Utils::OpenHandle(this)->GetScriptId(); } Local<String> StackFrame::GetScriptName() const { auto self = Utils::OpenHandle(this); - i::Isolate* isolate = self->GetIsolate(); - EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate)); - i::Handle<i::Object> name = i::StackTraceFrame::GetFileName(self); - return name->IsString() - ? scope.Escape(Local<String>::Cast(Utils::ToLocal(name))) - : Local<String>(); + auto isolate = self->GetIsolate(); + i::Handle<i::Object> name(self->GetScriptName(), isolate); + if (!name->IsString()) return {}; + return Local<String>::Cast(Utils::ToLocal(name)); } Local<String> StackFrame::GetScriptNameOrSourceURL() const { auto self = Utils::OpenHandle(this); - i::Isolate* isolate = self->GetIsolate(); - EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate)); - i::Handle<i::Object> name = - i::StackTraceFrame::GetScriptNameOrSourceUrl(self); - return name->IsString() - ? scope.Escape(Local<String>::Cast(Utils::ToLocal(name))) - : Local<String>(); + auto isolate = self->GetIsolate(); + i::Handle<i::Object> name_or_url(self->GetScriptNameOrSourceURL(), isolate); + if (!name_or_url->IsString()) return {}; + return Local<String>::Cast(Utils::ToLocal(name_or_url)); } Local<String> StackFrame::GetFunctionName() const { auto self = Utils::OpenHandle(this); - i::Isolate* isolate = self->GetIsolate(); - EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate)); - i::Handle<i::Object> name = i::StackTraceFrame::GetFunctionName(self); - return name->IsString() - ? scope.Escape(Local<String>::Cast(Utils::ToLocal(name))) - : Local<String>(); + auto name = i::StackFrameInfo::GetFunctionName(self); + if (!name->IsString()) return {}; + return Local<String>::Cast(Utils::ToLocal(name)); } -bool StackFrame::IsEval() const { - return i::StackTraceFrame::IsEval(Utils::OpenHandle(this)); -} +bool StackFrame::IsEval() const { return Utils::OpenHandle(this)->IsEval(); } bool StackFrame::IsConstructor() const { - return i::StackTraceFrame::IsConstructor(Utils::OpenHandle(this)); + return Utils::OpenHandle(this)->IsConstructor(); } -bool StackFrame::IsWasm() const { - return i::StackTraceFrame::IsWasm(Utils::OpenHandle(this)); -} +bool StackFrame::IsWasm() const { return Utils::OpenHandle(this)->IsWasm(); } bool StackFrame::IsUserJavaScript() const { - return i::StackTraceFrame::IsUserJavaScript(Utils::OpenHandle(this)); + return Utils::OpenHandle(this)->IsUserJavaScript(); } // --- J S O N --- @@ -3166,11 +3030,11 @@ void* ValueSerializer::Delegate::ReallocateBufferMemory(void* old_buffer, size_t size, size_t* actual_size) { *actual_size = size; - return realloc(old_buffer, size); + return base::Realloc(old_buffer, size); } void ValueSerializer::Delegate::FreeBufferMemory(void* buffer) { - return free(buffer); + return base::Free(buffer); } struct ValueSerializer::PrivateData { @@ -3476,6 +3340,7 @@ VALUE_IS_SPECIFIC_TYPE(SymbolObject, SymbolWrapper) VALUE_IS_SPECIFIC_TYPE(Date, JSDate) VALUE_IS_SPECIFIC_TYPE(Map, JSMap) VALUE_IS_SPECIFIC_TYPE(Set, JSSet) +VALUE_IS_SPECIFIC_TYPE(WasmMemoryObject, WasmMemoryObject) VALUE_IS_SPECIFIC_TYPE(WasmModuleObject, WasmModuleObject) VALUE_IS_SPECIFIC_TYPE(WeakMap, JSWeakMap) VALUE_IS_SPECIFIC_TYPE(WeakSet, JSWeakSet) @@ -3493,6 +3358,7 @@ bool Value::IsExternal() const { // and GetIsolate will work. if (heap_obj->map().instance_type() != i::JS_OBJECT_TYPE) return false; i::Isolate* isolate = i::JSObject::cast(*heap_obj).GetIsolate(); + ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate); return heap_obj->IsExternal(isolate); } @@ -3536,6 +3402,7 @@ bool Value::IsGeneratorFunction() const { i::Handle<i::Object> obj = Utils::OpenHandle(this); if (!obj->IsJSFunction()) return false; i::Handle<i::JSFunction> func = i::Handle<i::JSFunction>::cast(obj); + ASSERT_NO_SCRIPT_NO_EXCEPTION(func->GetIsolate()); return i::IsGeneratorFunction(func->shared().kind()); } @@ -3607,6 +3474,7 @@ bool Value::BooleanValue(Isolate* v8_isolate) const { Local<Boolean> Value::ToBoolean(Isolate* v8_isolate) const { auto isolate = reinterpret_cast<i::Isolate*>(v8_isolate); + ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate); return ToApiHandle<Boolean>( isolate->factory()->ToBoolean(BooleanValue(v8_isolate))); } @@ -3698,23 +3566,23 @@ void v8::Function::CheckCast(Value* that) { "Value is not a Function"); } -void v8::Boolean::CheckCast(v8::Value* that) { +void v8::Boolean::CheckCast(v8::Data* that) { i::Handle<i::Object> obj = Utils::OpenHandle(that); Utils::ApiCheck(obj->IsBoolean(), "v8::Boolean::Cast", "Value is not a Boolean"); } -void v8::Name::CheckCast(v8::Value* that) { +void v8::Name::CheckCast(v8::Data* that) { i::Handle<i::Object> obj = Utils::OpenHandle(that); Utils::ApiCheck(obj->IsName(), "v8::Name::Cast", "Value is not a Name"); } -void v8::String::CheckCast(v8::Value* that) { +void v8::String::CheckCast(v8::Data* that) { i::Handle<i::Object> obj = Utils::OpenHandle(that); Utils::ApiCheck(obj->IsString(), "v8::String::Cast", "Value is not a String"); } -void v8::Symbol::CheckCast(v8::Value* that) { +void v8::Symbol::CheckCast(v8::Data* that) { i::Handle<i::Object> obj = Utils::OpenHandle(that); Utils::ApiCheck(obj->IsSymbol(), "v8::Symbol::Cast", "Value is not a Symbol"); } @@ -3726,38 +3594,50 @@ void v8::Private::CheckCast(v8::Data* that) { "v8::Private::Cast", "Value is not a Private"); } +void v8::ModuleRequest::CheckCast(v8::Data* that) { + i::Handle<i::Object> obj = Utils::OpenHandle(that); + Utils::ApiCheck(obj->IsModuleRequest(), "v8::ModuleRequest::Cast", + "Value is not a ModuleRequest"); +} + void v8::Module::CheckCast(v8::Data* that) { i::Handle<i::Object> obj = Utils::OpenHandle(that); Utils::ApiCheck(obj->IsModule(), "v8::Module::Cast", "Value is not a Module"); } -void v8::Number::CheckCast(v8::Value* that) { +void v8::Number::CheckCast(v8::Data* that) { i::Handle<i::Object> obj = Utils::OpenHandle(that); Utils::ApiCheck(obj->IsNumber(), "v8::Number::Cast()", "Value is not a Number"); } -void v8::Integer::CheckCast(v8::Value* that) { +void v8::Integer::CheckCast(v8::Data* that) { i::Handle<i::Object> obj = Utils::OpenHandle(that); Utils::ApiCheck(obj->IsNumber(), "v8::Integer::Cast", "Value is not an Integer"); } -void v8::Int32::CheckCast(v8::Value* that) { - Utils::ApiCheck(that->IsInt32(), "v8::Int32::Cast", +void v8::Int32::CheckCast(v8::Data* that) { + Utils::ApiCheck(Value::Cast(that)->IsInt32(), "v8::Int32::Cast", "Value is not a 32-bit signed integer"); } -void v8::Uint32::CheckCast(v8::Value* that) { - Utils::ApiCheck(that->IsUint32(), "v8::Uint32::Cast", +void v8::Uint32::CheckCast(v8::Data* that) { + Utils::ApiCheck(Value::Cast(that)->IsUint32(), "v8::Uint32::Cast", "Value is not a 32-bit unsigned integer"); } -void v8::BigInt::CheckCast(v8::Value* that) { - Utils::ApiCheck(that->IsBigInt(), "v8::BigInt::Cast", +void v8::BigInt::CheckCast(v8::Data* that) { + Utils::ApiCheck(Value::Cast(that)->IsBigInt(), "v8::BigInt::Cast", "Value is not a BigInt"); } +void v8::Context::CheckCast(v8::Data* that) { + i::Handle<i::Object> obj = Utils::OpenHandle(that); + Utils::ApiCheck(obj->IsContext(), "v8::Context::Cast", + "Value is not a Context"); +} + void v8::Array::CheckCast(Value* that) { i::Handle<i::Object> obj = Utils::OpenHandle(that); Utils::ApiCheck(obj->IsJSArray(), "v8::Array::Cast", "Value is not an Array"); @@ -3787,23 +3667,16 @@ void v8::Proxy::CheckCast(Value* that) { Utils::ApiCheck(that->IsProxy(), "v8::Proxy::Cast", "Value is not a Proxy"); } +void v8::WasmMemoryObject::CheckCast(Value* that) { + Utils::ApiCheck(that->IsWasmMemoryObject(), "v8::WasmMemoryObject::Cast", + "Value is not a WasmMemoryObject"); +} + void v8::WasmModuleObject::CheckCast(Value* that) { Utils::ApiCheck(that->IsWasmModuleObject(), "v8::WasmModuleObject::Cast", "Value is not a WasmModuleObject"); } -void v8::debug::AccessorPair::CheckCast(Value* that) { - i::Handle<i::Object> obj = Utils::OpenHandle(that); - Utils::ApiCheck(obj->IsAccessorPair(), "v8::AccessorPair::Cast", - "Value is not a debug::AccessorPair"); -} - -void v8::debug::WasmValue::CheckCast(Value* that) { - i::Handle<i::Object> obj = Utils::OpenHandle(that); - Utils::ApiCheck(obj->IsWasmValue(), "v8::WasmValue::Cast", - "Value is not a debug::WasmValue"); -} - v8::BackingStore::~BackingStore() { auto i_this = reinterpret_cast<const i::BackingStore*>(this); i_this->~BackingStore(); // manually call internal destructor @@ -4033,9 +3906,13 @@ MaybeLocal<Uint32> Value::ToArrayIndex(Local<Context> context) const { Maybe<bool> Value::Equals(Local<Context> context, Local<Value> that) const { i::Isolate* isolate = Utils::OpenHandle(*context)->GetIsolate(); + ENTER_V8(isolate, context, Value, Equals, Nothing<bool>(), i::HandleScope); auto self = Utils::OpenHandle(this); auto other = Utils::OpenHandle(*that); - return i::Object::Equals(isolate, self, other); + Maybe<bool> result = i::Object::Equals(isolate, self, other); + has_pending_exception = result.IsNothing(); + RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); + return result; } bool Value::StrictEquals(Local<Value> that) const { @@ -4833,16 +4710,43 @@ Local<v8::Object> v8::Object::Clone() { return Utils::ToLocal(result); } +namespace { +Local<v8::Context> CreationContextImpl(i::Handle<i::JSReceiver> self) { + i::Handle<i::Context> context; + if (self->GetCreationContext().ToHandle(&context)) { + return Utils::ToLocal(context); + } + + return Local<v8::Context>(); +} +} // namespace + Local<v8::Context> v8::Object::CreationContext() { auto self = Utils::OpenHandle(this); - i::Handle<i::Context> context = self->GetCreationContext(); - return Utils::ToLocal(context); + return CreationContextImpl(self); +} + +Local<v8::Context> v8::Object::CreationContext( + const PersistentBase<Object>& object) { + auto self = Utils::OpenHandle(object.val_); + return CreationContextImpl(self); +} + +MaybeLocal<v8::Context> v8::Object::GetCreationContext() { + auto self = Utils::OpenHandle(this); + i::Handle<i::Context> context; + if (self->GetCreationContext().ToHandle(&context)) { + return Utils::ToLocal(context); + } + + return MaybeLocal<v8::Context>(); } int v8::Object::GetIdentityHash() { - i::DisallowHeapAllocation no_gc; + i::DisallowGarbageCollection no_gc; auto self = Utils::OpenHandle(this); auto isolate = self->GetIsolate(); + ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate); i::HandleScope scope(isolate); return self->GetOrCreateIdentityHash(isolate).value(); } @@ -4912,8 +4816,7 @@ MaybeLocal<Function> Function::New(Local<Context> context, ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); auto templ = FunctionTemplateNew(isolate, callback, data, Local<Signature>(), length, - true, Local<Private>(), side_effect_type); - if (behavior == ConstructorBehavior::kThrow) templ->RemovePrototype(); + behavior, true, Local<Private>(), side_effect_type); return templ->GetFunction(context); } @@ -4997,6 +4900,7 @@ void Function::SetName(v8::Local<v8::String> name) { auto self = Utils::OpenHandle(this); if (!self->IsJSFunction()) return; auto func = i::Handle<i::JSFunction>::cast(self); + ASSERT_NO_SCRIPT_NO_EXCEPTION(func->GetIsolate()); func->shared().SetName(*Utils::OpenHandle(*name)); } @@ -5049,7 +4953,7 @@ Local<Value> Function::GetDisplayName() const { } auto func = i::Handle<i::JSFunction>::cast(self); i::Handle<i::String> property_name = - isolate->factory()->display_name_string(); + isolate->factory()->InternalizeString(i::StaticCharVector("displayName")); i::Handle<i::Object> value = i::JSReceiver::GetDataProperty(func, property_name); if (value->IsString()) { @@ -5061,16 +4965,15 @@ Local<Value> Function::GetDisplayName() const { ScriptOrigin Function::GetScriptOrigin() const { auto self = Utils::OpenHandle(this); - if (!self->IsJSFunction()) { - return v8::ScriptOrigin(Local<Value>()); - } + auto isolate = reinterpret_cast<v8::Isolate*>(self->GetIsolate()); + if (!self->IsJSFunction()) return v8::ScriptOrigin(isolate, Local<Value>()); auto func = i::Handle<i::JSFunction>::cast(self); if (func->shared().script().IsScript()) { i::Handle<i::Script> script(i::Script::cast(func->shared().script()), func->GetIsolate()); return GetScriptOriginForScript(func->GetIsolate(), script); } - return v8::ScriptOrigin(Local<Value>()); + return v8::ScriptOrigin(isolate, Local<Value>()); } const int Function::kLineOffsetNotFound = -1; @@ -5142,7 +5045,7 @@ MaybeLocal<String> v8::Function::FunctionProtoToString(Local<Context> context) { int Name::GetIdentityHash() { auto self = Utils::OpenHandle(this); - return static_cast<int>(self->Hash()); + return static_cast<int>(self->EnsureHash()); } int String::Length() const { @@ -5180,6 +5083,9 @@ static inline const uint16_t* Align(const uint16_t* chars) { class ContainsOnlyOneByteHelper { public: ContainsOnlyOneByteHelper() : is_one_byte_(true) {} + ContainsOnlyOneByteHelper(const ContainsOnlyOneByteHelper&) = delete; + ContainsOnlyOneByteHelper& operator=(const ContainsOnlyOneByteHelper&) = + delete; bool Check(i::String string) { i::ConsString cons_string = i::String::VisitFlat(this, string, 0); if (cons_string.is_null()) return is_one_byte_; @@ -5260,7 +5166,6 @@ class ContainsOnlyOneByteHelper { return is_one_byte_; } bool is_one_byte_; - DISALLOW_COPY_AND_ASSIGN(ContainsOnlyOneByteHelper); }; bool String::ContainsOnlyOneByte() const { @@ -5275,7 +5180,7 @@ int String::Utf8Length(Isolate* isolate) const { str = i::String::Flatten(reinterpret_cast<i::Isolate*>(isolate), str); int length = str->length(); if (length == 0) return 0; - i::DisallowHeapAllocation no_gc; + i::DisallowGarbageCollection no_gc; i::String::FlatContent flat = str->GetFlatContent(no_gc); DCHECK(flat.IsFlat()); int utf8_length = 0; @@ -5337,7 +5242,7 @@ static int WriteUtf8Impl(i::Vector<const Char> string, char* write_start, 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); + base::Memcpy(current_write, read_start + read_index, copy_length); current_write += copy_length; read_index = up_to; } else { @@ -5429,7 +5334,7 @@ int String::WriteUtf8(Isolate* v8_isolate, char* buffer, int capacity, LOG_API(isolate, String, WriteUtf8); ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); str = i::String::Flatten(isolate, str); - i::DisallowHeapAllocation no_gc; + i::DisallowGarbageCollection no_gc; i::String::FlatContent content = str->GetFlatContent(no_gc); if (content.IsOneByte()) { return WriteUtf8Impl<uint8_t>(content.ToOneByteVector(), buffer, capacity, @@ -5472,10 +5377,6 @@ int String::Write(Isolate* isolate, uint16_t* buffer, int start, int length, start, length, options); } -bool v8::String::IsExternal() const { - return IsExternalTwoByte(); -} - bool v8::String::IsExternalTwoByte() const { i::Handle<i::String> str = Utils::OpenHandle(this); return i::StringShape(*str).IsExternalTwoByte(); @@ -5488,7 +5389,7 @@ bool v8::String::IsExternalOneByte() const { void v8::String::VerifyExternalStringResource( v8::String::ExternalStringResource* value) const { - i::DisallowHeapAllocation no_allocation; + i::DisallowGarbageCollection no_gc; i::String str = *Utils::OpenHandle(this); const v8::String::ExternalStringResource* expected; @@ -5507,7 +5408,7 @@ void v8::String::VerifyExternalStringResource( void v8::String::VerifyExternalStringResourceBase( v8::String::ExternalStringResourceBase* value, Encoding encoding) const { - i::DisallowHeapAllocation no_allocation; + i::DisallowGarbageCollection no_gc; i::String str = *Utils::OpenHandle(this); const v8::String::ExternalStringResourceBase* expected; Encoding expectedEncoding; @@ -5534,7 +5435,7 @@ void v8::String::VerifyExternalStringResourceBase( } String::ExternalStringResource* String::GetExternalStringResourceSlow() const { - i::DisallowHeapAllocation no_allocation; + i::DisallowGarbageCollection no_gc; using I = internal::Internals; i::String str = *Utils::OpenHandle(this); @@ -5552,9 +5453,27 @@ String::ExternalStringResource* String::GetExternalStringResourceSlow() const { return nullptr; } +void String::ExternalStringResource::UpdateDataCache() { + DCHECK(IsCacheable()); + cached_data_ = data(); +} + +void String::ExternalStringResource::CheckCachedDataInvariants() const { + DCHECK(IsCacheable() && cached_data_ != nullptr); +} + +void String::ExternalOneByteStringResource::UpdateDataCache() { + DCHECK(IsCacheable()); + cached_data_ = data(); +} + +void String::ExternalOneByteStringResource::CheckCachedDataInvariants() const { + DCHECK(IsCacheable() && cached_data_ != nullptr); +} + String::ExternalStringResourceBase* String::GetExternalStringResourceBaseSlow( String::Encoding* encoding_out) const { - i::DisallowHeapAllocation no_allocation; + i::DisallowGarbageCollection no_gc; using I = internal::Internals; ExternalStringResourceBase* resource = nullptr; i::String str = *Utils::OpenHandle(this); @@ -5579,7 +5498,7 @@ String::ExternalStringResourceBase* String::GetExternalStringResourceBaseSlow( const v8::String::ExternalOneByteStringResource* v8::String::GetExternalOneByteStringResource() const { - i::DisallowHeapAllocation no_allocation; + i::DisallowGarbageCollection no_gc; i::String str = *Utils::OpenHandle(this); if (i::StringShape(str).IsExternalOneByte()) { return i::ExternalOneByteString::cast(str).resource(); @@ -5709,7 +5628,7 @@ void v8::Object::SetAlignedPointerInInternalFields(int argc, int indices[], void* values[]) { i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this); const char* location = "v8::Object::SetAlignedPointerInInternalFields()"; - i::DisallowHeapAllocation no_gc; + i::DisallowGarbageCollection no_gc; i::JSObject js_obj = i::JSObject::cast(*obj); int nof_embedder_fields = js_obj.GetEmbedderFieldCount(); for (int i = 0; i < argc; i++) { @@ -5778,7 +5697,13 @@ bool v8::V8::Initialize(const int build_config) { #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 + // When the target code runs on the V8 arm simulator, the trap handler does + // not behave as expected: the instruction pointer points inside the simulator + // code rather than the wasm code, so the trap handler cannot find the landing + // pad and lets the process crash. Therefore, only enable trap handlers if + // the host and target arch are the same. +#if (V8_TARGET_ARCH_X64 && !V8_OS_ANDROID) || \ + (V8_HOST_ARCH_ARM64 && V8_TARGET_ARCH_ARM64 && V8_OS_MACOSX) return i::trap_handler::TryHandleSignal(sig_code, info, context); #else return false; @@ -5893,6 +5818,7 @@ void V8::GetSharedMemoryStatistics(SharedMemoryStatistics* statistics) { void V8::SetIsCrossOriginIsolated() { i::FLAG_harmony_sharedarraybuffer = true; + i::FLAG_experimental_wasm_threads = true; } template <typename ObjectType> @@ -6137,6 +6063,12 @@ v8::Isolate* Context::GetIsolate() { return reinterpret_cast<Isolate*>(env->GetIsolate()); } +v8::MicrotaskQueue* Context::GetMicrotaskQueue() { + i::Handle<i::Context> env = Utils::OpenHandle(this); + CHECK(env->IsNativeContext()); + return i::Handle<i::NativeContext>::cast(env)->microtask_queue(); +} + v8::Local<v8::Object> Context::Global() { i::Handle<i::Context> context = Utils::OpenHandle(this); i::Isolate* isolate = context->GetIsolate(); @@ -6529,7 +6461,7 @@ MaybeLocal<String> v8::String::NewExternalOneByte( } bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) { - i::DisallowHeapAllocation no_allocation; + i::DisallowGarbageCollection no_gc; i::String obj = *Utils::OpenHandle(this); @@ -6556,7 +6488,7 @@ bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) { bool v8::String::MakeExternal( v8::String::ExternalOneByteStringResource* resource) { - i::DisallowHeapAllocation no_allocation; + i::DisallowGarbageCollection no_gc; i::String obj = *Utils::OpenHandle(this); @@ -6581,7 +6513,7 @@ bool v8::String::MakeExternal( } bool v8::String::CanMakeExternal() { - i::DisallowHeapAllocation no_allocation; + i::DisallowGarbageCollection no_gc; i::String obj = *Utils::OpenHandle(this); if (obj.IsThinString()) { @@ -6616,27 +6548,27 @@ 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); +namespace { - // 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(); +// TODO(v8:7569): This is a workaround for the Handle vs MaybeHandle difference +// in the return types of the different Add functions: +// OrderedNameDictionary::Add returns MaybeHandle, NameDictionary::Add returns +// Handle. +template <typename T> +i::Handle<T> ToHandle(i::Handle<T> h) { + return h; +} +template <typename T> +i::Handle<T> ToHandle(i::MaybeHandle<T> h) { + return h.ToHandleChecked(); +} + +template <typename Dictionary> +void AddPropertiesAndElementsToObject(i::Isolate* i_isolate, + i::Handle<Dictionary>& properties, + i::Handle<i::FixedArrayBase>& elements, + Local<Name>* names, Local<Value>* values, + size_t length) { 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]); @@ -6661,18 +6593,58 @@ Local<v8::Object> v8::Object::New(Isolate* isolate, i::InternalIndex const entry = properties->FindEntry(i_isolate, name); if (entry.is_not_found()) { // Add the {name}/{value} pair as a new entry. - properties = i::NameDictionary::Add(i_isolate, properties, name, value, - i::PropertyDetails::Empty()); + properties = ToHandle(Dictionary::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( - i::Handle<i::HeapObject>::cast(proto), properties, elements); - return Utils::ToLocal(obj); +} + +} // namespace + +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); + + i::Handle<i::FixedArrayBase> elements = + i_isolate->factory()->empty_fixed_array(); + + // 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). + if (V8_DICT_MODE_PROTOTYPES_BOOL) { + i::Handle<i::OrderedNameDictionary> properties = + i::OrderedNameDictionary::Allocate(i_isolate, static_cast<int>(length)) + .ToHandleChecked(); + AddPropertiesAndElementsToObject(i_isolate, properties, elements, names, + values, length); + i::Handle<i::JSObject> obj = + i_isolate->factory()->NewSlowJSObjectWithPropertiesAndElements( + i::Handle<i::HeapObject>::cast(proto), properties, elements); + return Utils::ToLocal(obj); + } else { + i::Handle<i::NameDictionary> properties = + i::NameDictionary::New(i_isolate, static_cast<int>(length)); + AddPropertiesAndElementsToObject(i_isolate, properties, elements, names, + values, length); + i::Handle<i::JSObject> obj = + i_isolate->factory()->NewSlowJSObjectWithPropertiesAndElements( + i::Handle<i::HeapObject>::cast(proto), properties, elements); + return Utils::ToLocal(obj); + } } Local<v8::Value> v8::NumberObject::New(Isolate* isolate, double value) { @@ -6852,6 +6824,7 @@ REGEXP_FLAG_ASSERT_EQ(kIgnoreCase); REGEXP_FLAG_ASSERT_EQ(kMultiline); REGEXP_FLAG_ASSERT_EQ(kSticky); REGEXP_FLAG_ASSERT_EQ(kUnicode); +REGEXP_FLAG_ASSERT_EQ(kHasIndices); REGEXP_FLAG_ASSERT_EQ(kLinear); #undef REGEXP_FLAG_ASSERT_EQ @@ -7026,7 +6999,7 @@ i::Handle<i::JSArray> MapAsArray(i::Isolate* isolate, i::Object table_obj, i::Handle<i::FixedArray> result = factory->NewFixedArray(max_length); int result_index = 0; { - i::DisallowHeapAllocation no_gc; + i::DisallowGarbageCollection no_gc; i::Oddball the_hole = i::ReadOnlyRoots(isolate).the_hole_value(); for (int i = offset; i < capacity; ++i) { i::InternalIndex entry(i); @@ -7130,7 +7103,7 @@ i::Handle<i::JSArray> SetAsArray(i::Isolate* isolate, i::Object table_obj, i::Handle<i::FixedArray> result = factory->NewFixedArray(max_length); int result_index = 0; { - i::DisallowHeapAllocation no_gc; + i::DisallowGarbageCollection no_gc; i::Oddball the_hole = i::ReadOnlyRoots(isolate).the_hole_value(); for (int i = offset; i < capacity; ++i) { i::InternalIndex entry(i); @@ -7211,10 +7184,14 @@ MaybeLocal<Promise> Promise::Catch(Local<Context> context, Local<Function> handler) { PREPARE_FOR_EXECUTION(context, Promise, Catch, Promise); auto self = Utils::OpenHandle(this); - i::Handle<i::Object> argv[] = {Utils::OpenHandle(*handler)}; + i::Handle<i::Object> argv[] = {isolate->factory()->undefined_value(), + Utils::OpenHandle(*handler)}; i::Handle<i::Object> result; + // Do not call the built-in Promise.prototype.catch! + // v8::Promise should not call out to a monkeypatched Promise.prototype.then + // as the implementation of Promise.prototype.catch does. has_pending_exception = - !i::Execution::CallBuiltin(isolate, isolate->promise_catch(), self, + !i::Execution::CallBuiltin(isolate, isolate->promise_then(), self, arraysize(argv), argv) .ToHandle(&result); RETURN_ON_FAILED_EXECUTION(Promise); @@ -7344,6 +7321,12 @@ MemorySpan<const uint8_t> CompiledWasmModule::GetWireBytesRef() { return {bytes_vec.begin(), bytes_vec.size()}; } +Local<ArrayBuffer> v8::WasmMemoryObject::Buffer() { + i::Handle<i::WasmMemoryObject> obj = Utils::OpenHandle(this); + i::Handle<i::JSArrayBuffer> buffer(obj->array_buffer(), obj->GetIsolate()); + return Utils::ToLocal(buffer); +} + CompiledWasmModule WasmModuleObject::GetCompiledModule() { i::Handle<i::WasmModuleObject> obj = i::Handle<i::WasmModuleObject>::cast(Utils::OpenHandle(this)); @@ -7388,7 +7371,7 @@ void* v8::ArrayBuffer::Allocator::Reallocate(void* data, size_t old_length, reinterpret_cast<uint8_t*>(AllocateUninitialized(new_length)); if (new_data == nullptr) return nullptr; size_t bytes_to_copy = std::min(old_length, new_length); - memcpy(new_data, data, bytes_to_copy); + base::Memcpy(new_data, data, bytes_to_copy); if (new_length > bytes_to_copy) { memset(new_data + bytes_to_copy, 0, new_length - bytes_to_copy); } @@ -7684,7 +7667,7 @@ size_t v8::ArrayBufferView::CopyContents(void* dest, size_t byte_length) { size_t byte_offset = self->byte_offset(); size_t bytes_to_copy = std::min(byte_length, self->byte_length()); if (bytes_to_copy) { - i::DisallowHeapAllocation no_gc; + i::DisallowGarbageCollection no_gc; i::Isolate* isolate = self->GetIsolate(); i::Handle<i::JSArrayBuffer> buffer(i::JSArrayBuffer::cast(self->buffer()), isolate); @@ -7695,7 +7678,7 @@ size_t v8::ArrayBufferView::CopyContents(void* dest, size_t byte_length) { isolate); source = reinterpret_cast<char*>(typed_array->DataPtr()); } - memcpy(dest, source + byte_offset, bytes_to_copy); + base::Memcpy(dest, source + byte_offset, bytes_to_copy); } return bytes_to_copy; } @@ -8179,14 +8162,6 @@ v8::Local<v8::Context> Isolate::GetCurrentContext() { return Utils::ToLocal(i::Handle<i::Context>(native_context, isolate)); } -v8::Local<v8::Context> Isolate::GetEnteredContext() { - i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); - i::Handle<i::Object> last = - isolate->handle_scope_implementer()->LastEnteredContext(); - if (last.is_null()) return Local<Context>(); - return Utils::ToLocal(i::Handle<i::Context>::cast(last)); -} - v8::Local<v8::Context> Isolate::GetEnteredOrMicrotaskContext() { i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); i::Handle<i::Object> last = @@ -8274,6 +8249,21 @@ EmbedderHeapTracer* Isolate::GetEmbedderHeapTracer() { return isolate->heap()->GetEmbedderHeapTracer(); } +void Isolate::AttachCppHeap(CppHeap* cpp_heap) { + i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); + isolate->heap()->AttachCppHeap(cpp_heap); +} + +void Isolate::DetachCppHeap() { + i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); + isolate->heap()->DetachCppHeap(); +} + +CppHeap* Isolate::GetCppHeap() const { + const i::Isolate* isolate = reinterpret_cast<const i::Isolate*>(this); + return isolate->heap()->cpp_heap(); +} + void Isolate::SetGetExternallyAllocatedMemoryInBytesCallback( GetExternallyAllocatedMemoryInBytesCallback callback) { i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); @@ -8330,6 +8320,10 @@ Isolate* Isolate::Allocate() { return reinterpret_cast<Isolate*>(i::Isolate::New()); } +Isolate::CreateParams::CreateParams() = default; + +Isolate::CreateParams::~CreateParams() = default; + // static // This is separate so that tests can provide a different |isolate|. void Isolate::Initialize(Isolate* isolate, @@ -8458,7 +8452,13 @@ void Isolate::SetAbortOnUncaughtExceptionCallback( } void Isolate::SetHostImportModuleDynamicallyCallback( - HostImportModuleDynamicallyCallback callback) { + i::Isolate::DeprecatedHostImportModuleDynamicallyCallback callback) { + i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); + isolate->SetHostImportModuleDynamicallyCallback(callback); +} + +void Isolate::SetHostImportModuleDynamicallyCallback( + HostImportModuleDynamicallyWithImportAssertionsCallback callback) { i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); isolate->SetHostImportModuleDynamicallyCallback(callback); } @@ -8477,21 +8477,20 @@ void Isolate::SetPrepareStackTraceCallback(PrepareStackTraceCallback callback) { Isolate::DisallowJavascriptExecutionScope::DisallowJavascriptExecutionScope( Isolate* isolate, Isolate::DisallowJavascriptExecutionScope::OnFailure on_failure) - : on_failure_(on_failure) { + : on_failure_(on_failure), isolate_(isolate) { i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); switch (on_failure_) { case CRASH_ON_FAILURE: - internal_ = reinterpret_cast<void*>( - new i::DisallowJavascriptExecution(i_isolate)); + i::DisallowJavascriptExecution::Open(i_isolate, + &was_execution_allowed_assert_); break; case THROW_ON_FAILURE: - DCHECK_EQ(THROW_ON_FAILURE, on_failure); - internal_ = - reinterpret_cast<void*>(new i::ThrowOnJavascriptExecution(i_isolate)); + i::ThrowOnJavascriptExecution::Open(i_isolate, + &was_execution_allowed_throws_); break; case DUMP_ON_FAILURE: - internal_ = - reinterpret_cast<void*>(new i::DumpOnJavascriptExecution(i_isolate)); + i::DumpOnJavascriptExecution::Open(i_isolate, + &was_execution_allowed_dump_); break; default: UNREACHABLE(); @@ -8499,15 +8498,19 @@ Isolate::DisallowJavascriptExecutionScope::DisallowJavascriptExecutionScope( } Isolate::DisallowJavascriptExecutionScope::~DisallowJavascriptExecutionScope() { + i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate_); switch (on_failure_) { case CRASH_ON_FAILURE: - delete reinterpret_cast<i::DisallowJavascriptExecution*>(internal_); + i::DisallowJavascriptExecution::Close(i_isolate, + was_execution_allowed_assert_); break; case THROW_ON_FAILURE: - delete reinterpret_cast<i::ThrowOnJavascriptExecution*>(internal_); + i::ThrowOnJavascriptExecution::Close(i_isolate, + was_execution_allowed_throws_); break; case DUMP_ON_FAILURE: - delete reinterpret_cast<i::DumpOnJavascriptExecution*>(internal_); + i::DumpOnJavascriptExecution::Close(i_isolate, + was_execution_allowed_dump_); break; default: UNREACHABLE(); @@ -8515,20 +8518,21 @@ Isolate::DisallowJavascriptExecutionScope::~DisallowJavascriptExecutionScope() { } Isolate::AllowJavascriptExecutionScope::AllowJavascriptExecutionScope( - Isolate* isolate) { + Isolate* isolate) + : isolate_(isolate) { i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); - internal_assert_ = - reinterpret_cast<void*>(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)); + i::AllowJavascriptExecution::Open(i_isolate, &was_execution_allowed_assert_); + i::NoThrowOnJavascriptExecution::Open(i_isolate, + &was_execution_allowed_throws_); + i::NoDumpOnJavascriptExecution::Open(i_isolate, &was_execution_allowed_dump_); } Isolate::AllowJavascriptExecutionScope::~AllowJavascriptExecutionScope() { - delete reinterpret_cast<i::AllowJavascriptExecution*>(internal_assert_); - delete reinterpret_cast<i::NoThrowOnJavascriptExecution*>(internal_throws_); - delete reinterpret_cast<i::NoDumpOnJavascriptExecution*>(internal_dump_); + i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate_); + i::AllowJavascriptExecution::Close(i_isolate, was_execution_allowed_assert_); + i::NoThrowOnJavascriptExecution::Close(i_isolate, + was_execution_allowed_throws_); + i::NoDumpOnJavascriptExecution::Close(i_isolate, was_execution_allowed_dump_); } Isolate::SuppressMicrotaskExecutionScope::SuppressMicrotaskExecutionScope( @@ -8746,6 +8750,14 @@ size_t Isolate::NumberOfPhantomHandleResetsSinceLastCall() { int64_t Isolate::AdjustAmountOfExternalAllocatedMemory( int64_t change_in_bytes) { + // Try to check for unreasonably large or small values from the embedder. + const int64_t kMaxReasonableBytes = int64_t(1) << 60; + const int64_t kMinReasonableBytes = -kMaxReasonableBytes; + STATIC_ASSERT(kMaxReasonableBytes >= i::JSArrayBuffer::kMaxByteLength); + + CHECK(kMinReasonableBytes <= change_in_bytes && + change_in_bytes < kMaxReasonableBytes); + i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this); int64_t amount = i_isolate->heap()->update_external_memory(change_in_bytes); @@ -8840,23 +8852,6 @@ MicrotasksPolicy Isolate::GetMicrotasksPolicy() const { return isolate->default_microtask_queue()->microtasks_policy(); } -namespace { - -void MicrotasksCompletedCallbackAdapter(v8::Isolate* isolate, void* data) { - auto callback = reinterpret_cast<void (*)(v8::Isolate*)>(data); - callback(isolate); -} - -} // namespace - -void Isolate::AddMicrotasksCompletedCallback( - MicrotasksCompletedCallback callback) { - DCHECK(callback); - i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); - isolate->default_microtask_queue()->AddMicrotasksCompletedCallback( - &MicrotasksCompletedCallbackAdapter, reinterpret_cast<void*>(callback)); -} - void Isolate::AddMicrotasksCompletedCallback( MicrotasksCompletedCallbackWithData callback, void* data) { DCHECK(callback); @@ -8866,13 +8861,6 @@ void Isolate::AddMicrotasksCompletedCallback( } void Isolate::RemoveMicrotasksCompletedCallback( - MicrotasksCompletedCallback callback) { - i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); - isolate->default_microtask_queue()->RemoveMicrotasksCompletedCallback( - &MicrotasksCompletedCallbackAdapter, reinterpret_cast<void*>(callback)); -} - -void Isolate::RemoveMicrotasksCompletedCallback( MicrotasksCompletedCallbackWithData callback, void* data) { i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); isolate->default_microtask_queue()->RemoveMicrotasksCompletedCallback( @@ -9070,11 +9058,6 @@ size_t Isolate::CopyCodePages(size_t capacity, MemoryRange* code_pages_out) { CALLBACK_SETTER(FatalErrorHandler, FatalErrorCallback, exception_behavior) CALLBACK_SETTER(OOMErrorHandler, OOMErrorCallback, oom_behavior) -CALLBACK_SETTER(AllowCodeGenerationFromStringsCallback, - AllowCodeGenerationFromStringsCallback, allow_code_gen_callback) -CALLBACK_SETTER(ModifyCodeGenerationFromStringsCallback, - ModifyCodeGenerationFromStringsCallback, - modify_code_gen_callback) CALLBACK_SETTER(ModifyCodeGenerationFromStringsCallback, ModifyCodeGenerationFromStringsCallback2, modify_code_gen_callback2) @@ -9087,15 +9070,15 @@ CALLBACK_SETTER(WasmInstanceCallback, ExtensionCallback, wasm_instance_callback) CALLBACK_SETTER(WasmStreamingCallback, WasmStreamingCallback, wasm_streaming_callback) -CALLBACK_SETTER(WasmThreadsEnabledCallback, WasmThreadsEnabledCallback, - wasm_threads_enabled_callback) - CALLBACK_SETTER(WasmLoadSourceMapCallback, WasmLoadSourceMapCallback, wasm_load_source_map_callback) CALLBACK_SETTER(WasmSimdEnabledCallback, WasmSimdEnabledCallback, wasm_simd_enabled_callback) +CALLBACK_SETTER(WasmExceptionsEnabledCallback, WasmExceptionsEnabledCallback, + wasm_exceptions_enabled_callback) + void Isolate::AddNearHeapLimitCallback(v8::NearHeapLimitCallback callback, void* data) { i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); @@ -9147,7 +9130,7 @@ void Isolate::RemoveMessageListeners(MessageCallback that) { i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); i::HandleScope scope(isolate); - i::DisallowHeapAllocation no_gc; + i::DisallowGarbageCollection no_gc; i::TemplateList listeners = isolate->heap()->message_listeners(); for (int i = 0; i < listeners.length(); i++) { if (listeners.get(i).IsUndefined(isolate)) continue; // skip deleted ones @@ -9184,13 +9167,13 @@ bool Isolate::IsInUse() { void Isolate::VisitHandlesWithClassIds(PersistentHandleVisitor* visitor) { i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); - i::DisallowHeapAllocation no_allocation; + i::DisallowGarbageCollection no_gc; isolate->global_handles()->IterateAllRootsWithClassIds(visitor); } void Isolate::VisitWeakHandles(PersistentHandleVisitor* visitor) { i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); - i::DisallowHeapAllocation no_allocation; + i::DisallowGarbageCollection no_gc; isolate->global_handles()->IterateYoungWeakRootsWithClassIds(visitor); } @@ -9376,726 +9359,6 @@ Local<StackTrace> Exception::GetStackTrace(Local<Value> exception) { return Utils::StackTraceToLocal(isolate->GetDetailedStackTrace(js_obj)); } -// --- D e b u g S u p p o r t --- - -void debug::SetContextId(Local<Context> context, int id) { - Utils::OpenHandle(*context)->set_debug_context_id(i::Smi::FromInt(id)); -} - -int debug::GetContextId(Local<Context> context) { - i::Object value = Utils::OpenHandle(*context)->debug_context_id(); - return (value.IsSmi()) ? i::Smi::ToInt(value) : 0; -} - -void debug::SetInspector(Isolate* isolate, - v8_inspector::V8Inspector* inspector) { - i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); - i_isolate->set_inspector(inspector); -} - -v8_inspector::V8Inspector* debug::GetInspector(Isolate* isolate) { - return reinterpret_cast<i::Isolate*>(isolate)->inspector(); -} - -void debug::SetBreakOnNextFunctionCall(Isolate* isolate) { - reinterpret_cast<i::Isolate*>(isolate)->debug()->SetBreakOnNextFunctionCall(); -} - -void debug::ClearBreakOnNextFunctionCall(Isolate* isolate) { - reinterpret_cast<i::Isolate*>(isolate) - ->debug() - ->ClearBreakOnNextFunctionCall(); -} - -MaybeLocal<Array> debug::GetInternalProperties(Isolate* v8_isolate, - Local<Value> value) { - i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); - ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); - i::Handle<i::Object> val = Utils::OpenHandle(*value); - i::Handle<i::JSArray> result; - if (!i::Runtime::GetInternalProperties(isolate, val).ToHandle(&result)) - return MaybeLocal<Array>(); - return Utils::ToLocal(result); -} - -namespace { -void CollectPrivateMethodsAndAccessorsFromContext( - i::Isolate* isolate, i::Handle<i::Context> context, - i::IsStaticFlag is_static_flag, std::vector<Local<Value>>* names_out, - std::vector<Local<Value>>* values_out) { - 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::VariableMode mode = scope_info->ContextLocalMode(j); - i::IsStaticFlag flag = scope_info->ContextLocalIsStaticFlag(j); - if (!i::IsPrivateMethodOrAccessorVariableMode(mode) || - flag != is_static_flag) { - continue; - } - - i::Handle<i::String> name(scope_info->ContextLocalName(j), isolate); - int context_index = scope_info->ContextHeaderLength() + j; - i::Handle<i::Object> slot_value(context->get(context_index), isolate); - DCHECK_IMPLIES(mode == i::VariableMode::kPrivateMethod, - slot_value->IsJSFunction()); - DCHECK_IMPLIES(mode != i::VariableMode::kPrivateMethod, - slot_value->IsAccessorPair()); - names_out->push_back(Utils::ToLocal(name)); - values_out->push_back(Utils::ToLocal(slot_value)); - } -} -} // anonymous namespace - -bool debug::GetPrivateMembers(Local<Context> context, Local<Object> value, - std::vector<Local<Value>>* names_out, - std::vector<Local<Value>>* values_out) { - i::Isolate* isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate()); - LOG_API(isolate, debug, GetPrivateMembers); - ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); - i::Handle<i::JSReceiver> receiver = Utils::OpenHandle(*value); - i::Handle<i::JSArray> names; - i::Handle<i::FixedArray> values; - - i::PropertyFilter key_filter = - static_cast<i::PropertyFilter>(i::PropertyFilter::PRIVATE_NAMES_ONLY); - i::Handle<i::FixedArray> keys; - ASSIGN_RETURN_ON_EXCEPTION_VALUE( - isolate, keys, - i::KeyAccumulator::GetKeys(receiver, i::KeyCollectionMode::kOwnOnly, - key_filter, - i::GetKeysConversion::kConvertToString), - false); - - // Estimate number of private fields and private instance methods/accessors. - int private_entries_count = 0; - for (int i = 0; i < keys->length(); ++i) { - // Exclude the private brand symbols. - i::Handle<i::Symbol> key(i::Symbol::cast(keys->get(i)), isolate); - if (key->is_private_brand()) { - i::Handle<i::Object> value; - ASSIGN_RETURN_ON_EXCEPTION_VALUE( - isolate, value, i::Object::GetProperty(isolate, receiver, key), - false); - - i::Handle<i::Context> context(i::Context::cast(*value), isolate); - i::Handle<i::ScopeInfo> scope_info(context->scope_info(), isolate); - // At least one slot contains the brand symbol so it does not count. - private_entries_count += (scope_info->ContextLocalCount() - 1); - } else { - private_entries_count++; - } - } - - // Estimate number of static private methods/accessors for classes. - bool has_static_private_methods_or_accessors = false; - if (receiver->IsJSFunction()) { - i::Handle<i::JSFunction> func(i::JSFunction::cast(*receiver), isolate); - i::Handle<i::SharedFunctionInfo> shared(func->shared(), isolate); - if (shared->is_class_constructor() && - shared->has_static_private_methods_or_accessors()) { - has_static_private_methods_or_accessors = true; - i::Handle<i::Context> context(func->context(), isolate); - 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::VariableMode mode = scope_info->ContextLocalMode(j); - i::IsStaticFlag is_static_flag = - scope_info->ContextLocalIsStaticFlag(j); - if (i::IsPrivateMethodOrAccessorVariableMode(mode) && - is_static_flag == i::IsStaticFlag::kStatic) { - private_entries_count += local_count; - break; - } - } - } - } - - DCHECK(names_out->empty()); - names_out->reserve(private_entries_count); - DCHECK(values_out->empty()); - values_out->reserve(private_entries_count); - - if (has_static_private_methods_or_accessors) { - i::Handle<i::Context> context(i::JSFunction::cast(*receiver).context(), - isolate); - CollectPrivateMethodsAndAccessorsFromContext( - isolate, context, i::IsStaticFlag::kStatic, names_out, values_out); - } - - for (int i = 0; i < keys->length(); ++i) { - i::Handle<i::Object> obj_key(keys->get(i), isolate); - i::Handle<i::Symbol> key(i::Symbol::cast(*obj_key), isolate); - CHECK(key->is_private_name()); - i::Handle<i::Object> value; - ASSIGN_RETURN_ON_EXCEPTION_VALUE( - isolate, value, i::Object::GetProperty(isolate, receiver, key), false); - - if (key->is_private_brand()) { - DCHECK(value->IsContext()); - i::Handle<i::Context> context(i::Context::cast(*value), isolate); - CollectPrivateMethodsAndAccessorsFromContext( - isolate, context, i::IsStaticFlag::kNotStatic, names_out, values_out); - } else { // Private fields - i::Handle<i::String> name( - i::String::cast(i::Symbol::cast(*key).description()), isolate); - names_out->push_back(Utils::ToLocal(name)); - values_out->push_back(Utils::ToLocal(value)); - } - } - - DCHECK_EQ(names_out->size(), values_out->size()); - DCHECK_LE(names_out->size(), private_entries_count); - return true; -} - -Local<Context> debug::GetCreationContext(Local<Object> value) { - i::Handle<i::Object> val = Utils::OpenHandle(*value); - if (val->IsJSGlobalProxy()) { - return Local<Context>(); - } - return value->CreationContext(); -} - -void debug::ChangeBreakOnException(Isolate* isolate, ExceptionBreakState type) { - i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate); - internal_isolate->debug()->ChangeBreakOnException( - i::BreakException, type == BreakOnAnyException); - internal_isolate->debug()->ChangeBreakOnException(i::BreakUncaughtException, - type != NoBreakOnException); -} - -void debug::SetBreakPointsActive(Isolate* v8_isolate, bool is_active) { - i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); - ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); - isolate->debug()->set_break_points_active(is_active); -} - -void debug::PrepareStep(Isolate* v8_isolate, StepAction action) { - i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); - ENTER_V8_DO_NOT_USE(isolate); - CHECK(isolate->debug()->CheckExecutionState()); - // Clear all current stepping setup. - isolate->debug()->ClearStepping(); - // Prepare step. - isolate->debug()->PrepareStep(static_cast<i::StepAction>(action)); -} - -void debug::ClearStepping(Isolate* v8_isolate) { - i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); - ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); - // Clear all current stepping setup. - isolate->debug()->ClearStepping(); -} - -void debug::BreakRightNow(Isolate* v8_isolate) { - i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); - ENTER_V8_DO_NOT_USE(isolate); - isolate->debug()->HandleDebugBreak(i::kIgnoreIfAllFramesBlackboxed); -} - -void debug::SetTerminateOnResume(Isolate* v8_isolate) { - i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); - ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); - isolate->debug()->SetTerminateOnResume(); -} - -bool debug::AllFramesOnStackAreBlackboxed(Isolate* v8_isolate) { - i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); - ENTER_V8_DO_NOT_USE(isolate); - return isolate->debug()->AllFramesOnStackAreBlackboxed(); -} - -v8::Isolate* debug::Script::GetIsolate() const { - return reinterpret_cast<v8::Isolate*>(Utils::OpenHandle(this)->GetIsolate()); -} - -ScriptOriginOptions debug::Script::OriginOptions() const { - return Utils::OpenHandle(this)->origin_options(); -} - -bool debug::Script::WasCompiled() const { - return Utils::OpenHandle(this)->compilation_state() == - i::Script::COMPILATION_STATE_COMPILED; -} - -bool debug::Script::IsEmbedded() const { - i::Handle<i::Script> script = Utils::OpenHandle(this); - return script->context_data() == - script->GetReadOnlyRoots().uninitialized_symbol(); -} - -int debug::Script::Id() const { return Utils::OpenHandle(this)->id(); } - -int debug::Script::LineOffset() const { - return Utils::OpenHandle(this)->line_offset(); -} - -int debug::Script::ColumnOffset() const { - return Utils::OpenHandle(this)->column_offset(); -} - -std::vector<int> debug::Script::LineEnds() const { - i::Handle<i::Script> script = Utils::OpenHandle(this); - if (script->type() == i::Script::TYPE_WASM) return std::vector<int>(); - - i::Isolate* isolate = script->GetIsolate(); - i::HandleScope scope(isolate); - i::Script::InitLineEnds(isolate, script); - CHECK(script->line_ends().IsFixedArray()); - i::Handle<i::FixedArray> line_ends(i::FixedArray::cast(script->line_ends()), - 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)); - result[i] = line_end.value(); - } - return result; -} - -MaybeLocal<String> debug::Script::Name() const { - i::Handle<i::Script> script = Utils::OpenHandle(this); - i::Isolate* isolate = script->GetIsolate(); - i::HandleScope handle_scope(isolate); - i::Handle<i::Object> value(script->name(), isolate); - if (!value->IsString()) return MaybeLocal<String>(); - return Utils::ToLocal( - handle_scope.CloseAndEscape(i::Handle<i::String>::cast(value))); -} - -MaybeLocal<String> debug::Script::SourceURL() const { - i::Handle<i::Script> script = Utils::OpenHandle(this); - i::Isolate* isolate = script->GetIsolate(); - i::HandleScope handle_scope(isolate); - i::Handle<i::Object> value(script->source_url(), isolate); - if (!value->IsString()) return MaybeLocal<String>(); - return Utils::ToLocal( - handle_scope.CloseAndEscape(i::Handle<i::String>::cast(value))); -} - -MaybeLocal<String> debug::Script::SourceMappingURL() const { - i::Handle<i::Script> script = Utils::OpenHandle(this); - i::Isolate* isolate = script->GetIsolate(); - i::HandleScope handle_scope(isolate); - i::Handle<i::Object> value(script->source_mapping_url(), isolate); - if (!value->IsString()) return MaybeLocal<String>(); - return Utils::ToLocal( - handle_scope.CloseAndEscape(i::Handle<i::String>::cast(value))); -} - -Maybe<int> debug::Script::ContextId() const { - i::Handle<i::Script> script = Utils::OpenHandle(this); - i::Isolate* isolate = script->GetIsolate(); - i::HandleScope handle_scope(isolate); - i::Object value = script->context_data(); - if (value.IsSmi()) return Just(i::Smi::ToInt(value)); - return Nothing<int>(); -} - -MaybeLocal<String> debug::Script::Source() const { - i::Handle<i::Script> script = Utils::OpenHandle(this); - i::Isolate* isolate = script->GetIsolate(); - i::HandleScope handle_scope(isolate); - i::Handle<i::Object> value(script->source(), isolate); - if (!value->IsString()) return MaybeLocal<String>(); - return Utils::ToLocal( - handle_scope.CloseAndEscape(i::Handle<i::String>::cast(value))); -} - -bool debug::Script::IsWasm() const { - return Utils::OpenHandle(this)->type() == i::Script::TYPE_WASM; -} - -bool debug::Script::IsModule() const { - return Utils::OpenHandle(this)->origin_options().IsModule(); -} - -namespace { -int GetSmiValue(i::Handle<i::FixedArray> array, int index) { - return i::Smi::ToInt(array->get(index)); -} - -bool CompareBreakLocation(const i::BreakLocation& loc1, - const i::BreakLocation& loc2) { - return loc1.position() < loc2.position(); -} -} // namespace - -bool debug::Script::GetPossibleBreakpoints( - const debug::Location& start, const debug::Location& end, - bool restrict_to_function, - std::vector<debug::BreakLocation>* locations) const { - CHECK(!start.IsEmpty()); - i::Handle<i::Script> script = Utils::OpenHandle(this); - if (script->type() == i::Script::TYPE_WASM) { - i::wasm::NativeModule* native_module = script->wasm_native_module(); - return i::WasmScript::GetPossibleBreakpoints(native_module, start, end, - locations); - } - - i::Isolate* isolate = script->GetIsolate(); - i::Script::InitLineEnds(isolate, script); - CHECK(script->line_ends().IsFixedArray()); - i::Handle<i::FixedArray> line_ends = - i::Handle<i::FixedArray>::cast(i::handle(script->line_ends(), isolate)); - CHECK(line_ends->length()); - - int start_offset = GetSourceOffset(start); - int end_offset = end.IsEmpty() - ? GetSmiValue(line_ends, line_ends->length() - 1) + 1 - : GetSourceOffset(end); - if (start_offset >= end_offset) return true; - - std::vector<i::BreakLocation> v8_locations; - if (!isolate->debug()->GetPossibleBreakpoints( - script, start_offset, end_offset, restrict_to_function, - &v8_locations)) { - return false; - } - - std::sort(v8_locations.begin(), v8_locations.end(), CompareBreakLocation); - int current_line_end_index = 0; - for (const auto& v8_location : v8_locations) { - int offset = v8_location.position(); - while (offset > GetSmiValue(line_ends, current_line_end_index)) { - ++current_line_end_index; - CHECK(current_line_end_index < line_ends->length()); - } - int line_offset = 0; - - if (current_line_end_index > 0) { - line_offset = GetSmiValue(line_ends, current_line_end_index - 1) + 1; - } - locations->emplace_back( - current_line_end_index + script->line_offset(), - offset - line_offset + - (current_line_end_index == 0 ? script->column_offset() : 0), - v8_location.type()); - } - return true; -} - -int debug::Script::GetSourceOffset(const debug::Location& location) const { - i::Handle<i::Script> script = Utils::OpenHandle(this); - if (script->type() == i::Script::TYPE_WASM) { - DCHECK_EQ(0, location.GetLineNumber()); - return location.GetColumnNumber(); - } - - int line = std::max(location.GetLineNumber() - script->line_offset(), 0); - int column = location.GetColumnNumber(); - if (line == 0) { - column = std::max(0, column - script->column_offset()); - } - - i::Script::InitLineEnds(script->GetIsolate(), script); - CHECK(script->line_ends().IsFixedArray()); - i::Handle<i::FixedArray> line_ends = i::Handle<i::FixedArray>::cast( - i::handle(script->line_ends(), script->GetIsolate())); - CHECK(line_ends->length()); - if (line >= line_ends->length()) - return GetSmiValue(line_ends, line_ends->length() - 1); - int line_offset = GetSmiValue(line_ends, line); - if (line == 0) return std::min(column, line_offset); - int prev_line_offset = GetSmiValue(line_ends, line - 1); - return std::min(prev_line_offset + column + 1, line_offset); -} - -v8::debug::Location debug::Script::GetSourceLocation(int offset) const { - i::Handle<i::Script> script = Utils::OpenHandle(this); - i::Script::PositionInfo info; - i::Script::GetPositionInfo(script, offset, &info, i::Script::WITH_OFFSET); - return debug::Location(info.line, info.column); -} - -bool debug::Script::SetScriptSource(v8::Local<v8::String> newSource, - bool preview, - debug::LiveEditResult* result) const { - i::Handle<i::Script> script = Utils::OpenHandle(this); - i::Isolate* isolate = script->GetIsolate(); - return isolate->debug()->SetScriptSource( - script, Utils::OpenHandle(*newSource), preview, result); -} - -bool debug::Script::SetBreakpoint(v8::Local<v8::String> condition, - debug::Location* location, - debug::BreakpointId* id) const { - i::Handle<i::Script> script = Utils::OpenHandle(this); - i::Isolate* isolate = script->GetIsolate(); - int offset = GetSourceOffset(*location); - if (!isolate->debug()->SetBreakPointForScript( - script, Utils::OpenHandle(*condition), &offset, id)) { - return false; - } - *location = GetSourceLocation(offset); - return true; -} - -bool debug::Script::SetBreakpointOnScriptEntry(BreakpointId* id) const { - i::Handle<i::Script> script = Utils::OpenHandle(this); - i::Isolate* isolate = script->GetIsolate(); - i::SharedFunctionInfo::ScriptIterator it(isolate, *script); - for (i::SharedFunctionInfo sfi = it.Next(); !sfi.is_null(); sfi = it.Next()) { - if (sfi.is_toplevel()) { - return isolate->debug()->SetBreakpointForFunction( - handle(sfi, isolate), isolate->factory()->empty_string(), id); - } - } - return false; -} - -void debug::Script::RemoveWasmBreakpoint(debug::BreakpointId id) { - i::Handle<i::Script> script = Utils::OpenHandle(this); - i::Isolate* isolate = script->GetIsolate(); - isolate->debug()->RemoveBreakpointForWasmScript(script, id); -} - -void debug::RemoveBreakpoint(Isolate* v8_isolate, BreakpointId id) { - i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); - i::HandleScope handle_scope(isolate); - isolate->debug()->RemoveBreakpoint(id); -} - -v8::Platform* debug::GetCurrentPlatform() { - return i::V8::GetCurrentPlatform(); -} - -void debug::ForceGarbageCollection( - v8::Isolate* isolate, - v8::EmbedderHeapTracer::EmbedderStackState embedder_stack_state) { - i::Heap* heap = reinterpret_cast<i::Isolate*>(isolate)->heap(); - heap->SetEmbedderStackStateForNextFinalization(embedder_stack_state); - isolate->LowMemoryNotification(); -} - -debug::WasmScript* debug::WasmScript::Cast(debug::Script* script) { - CHECK(script->IsWasm()); - return static_cast<WasmScript*>(script); -} - -debug::WasmScript::DebugSymbolsType debug::WasmScript::GetDebugSymbolType() - const { - i::Handle<i::Script> script = Utils::OpenHandle(this); - DCHECK_EQ(i::Script::TYPE_WASM, script->type()); - switch (script->wasm_native_module()->module()->debug_symbols.type) { - case i::wasm::WasmDebugSymbols::Type::None: - return debug::WasmScript::DebugSymbolsType::None; - case i::wasm::WasmDebugSymbols::Type::EmbeddedDWARF: - return debug::WasmScript::DebugSymbolsType::EmbeddedDWARF; - case i::wasm::WasmDebugSymbols::Type::ExternalDWARF: - return debug::WasmScript::DebugSymbolsType::ExternalDWARF; - case i::wasm::WasmDebugSymbols::Type::SourceMap: - return debug::WasmScript::DebugSymbolsType::SourceMap; - } -} - -MemorySpan<const char> debug::WasmScript::ExternalSymbolsURL() const { - i::Handle<i::Script> script = Utils::OpenHandle(this); - DCHECK_EQ(i::Script::TYPE_WASM, script->type()); - - const i::wasm::WasmDebugSymbols& symbols = - script->wasm_native_module()->module()->debug_symbols; - if (symbols.external_url.is_empty()) return {}; - - internal::wasm::ModuleWireBytes wire_bytes( - script->wasm_native_module()->wire_bytes()); - i::wasm::WasmName external_url = - wire_bytes.GetNameOrNull(symbols.external_url); - return {external_url.data(), external_url.size()}; -} - -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::wasm::NativeModule* native_module = script->wasm_native_module(); - const i::wasm::WasmModule* module = native_module->module(); - DCHECK_GE(i::kMaxInt, module->functions.size()); - return static_cast<int>(module->functions.size()); -} - -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::wasm::NativeModule* native_module = script->wasm_native_module(); - const i::wasm::WasmModule* module = native_module->module(); - DCHECK_GE(i::kMaxInt, module->num_imported_functions); - return static_cast<int>(module->num_imported_functions); -} - -MemorySpan<const uint8_t> debug::WasmScript::Bytecode() const { - i::Handle<i::Script> script = Utils::OpenHandle(this); - i::Vector<const uint8_t> wire_bytes = - script->wasm_native_module()->wire_bytes(); - return {wire_bytes.begin(), wire_bytes.size()}; -} - -std::pair<int, int> debug::WasmScript::GetFunctionRange( - int function_index) const { - i::DisallowHeapAllocation no_gc; - i::Handle<i::Script> script = Utils::OpenHandle(this); - DCHECK_EQ(i::Script::TYPE_WASM, script->type()); - i::wasm::NativeModule* native_module = script->wasm_native_module(); - const i::wasm::WasmModule* module = native_module->module(); - DCHECK_LE(0, function_index); - DCHECK_GT(module->functions.size(), function_index); - const i::wasm::WasmFunction& func = module->functions[function_index]; - DCHECK_GE(i::kMaxInt, func.code.offset()); - DCHECK_GE(i::kMaxInt, func.code.end_offset()); - return std::make_pair(static_cast<int>(func.code.offset()), - static_cast<int>(func.code.end_offset())); -} - -int debug::WasmScript::GetContainingFunction(int byte_offset) const { - i::DisallowHeapAllocation no_gc; - i::Handle<i::Script> script = Utils::OpenHandle(this); - DCHECK_EQ(i::Script::TYPE_WASM, script->type()); - i::wasm::NativeModule* native_module = script->wasm_native_module(); - const i::wasm::WasmModule* module = native_module->module(); - DCHECK_LE(0, byte_offset); - - return i::wasm::GetContainingWasmFunction(module, byte_offset); -} - -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::wasm::NativeModule* native_module = script->wasm_native_module(); - const i::wasm::WasmModule* module = native_module->module(); - DCHECK_LE(0, function_index); - DCHECK_GT(module->functions.size(), function_index); - const i::wasm::WasmFunction& func = module->functions[function_index]; - i::wasm::ModuleWireBytes wire_bytes(native_module->wire_bytes()); - i::Vector<const i::byte> function_bytes = wire_bytes.GetFunctionBytes(&func); - // TODO(herhut): Maybe also take module, name and signature into account. - return i::StringHasher::HashSequentialString(function_bytes.begin(), - function_bytes.length(), 0); -} - -int debug::WasmScript::CodeOffset() const { - i::Handle<i::Script> script = Utils::OpenHandle(this); - DCHECK_EQ(i::Script::TYPE_WASM, script->type()); - i::wasm::NativeModule* native_module = script->wasm_native_module(); - const i::wasm::WasmModule* module = native_module->module(); - - // If the module contains at least one function, the code offset must have - // been initialized, and it cannot be zero. - DCHECK_IMPLIES(module->num_declared_functions > 0, - module->code.offset() != 0); - return module->code.offset(); -} - -debug::Location::Location(int line_number, int column_number) - : line_number_(line_number), - column_number_(column_number), - is_empty_(false) {} - -debug::Location::Location() - : line_number_(v8::Function::kLineOffsetNotFound), - column_number_(v8::Function::kLineOffsetNotFound), - is_empty_(true) {} - -int debug::Location::GetLineNumber() const { - DCHECK(!IsEmpty()); - return line_number_; -} - -int debug::Location::GetColumnNumber() const { - DCHECK(!IsEmpty()); - return column_number_; -} - -bool debug::Location::IsEmpty() const { return is_empty_; } - -void debug::GetLoadedScripts(v8::Isolate* v8_isolate, - PersistentValueVector<debug::Script>& scripts) { - i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); - ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); - { - i::DisallowHeapAllocation no_gc; - i::Script::Iterator iterator(isolate); - for (i::Script script = iterator.Next(); !script.is_null(); - script = iterator.Next()) { - if (script.type() == i::Script::TYPE_NORMAL || - script.type() == i::Script::TYPE_WASM) { - if (script.HasValidSource()) { - i::HandleScope handle_scope(isolate); - i::Handle<i::Script> script_handle(script, isolate); - scripts.Append(ToApiHandle<Script>(script_handle)); - } - } - } - } -} - -MaybeLocal<UnboundScript> debug::CompileInspectorScript(Isolate* v8_isolate, - Local<String> source) { - i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); - PREPARE_FOR_DEBUG_INTERFACE_EXECUTION_WITH_ISOLATE(isolate, UnboundScript); - i::Handle<i::String> str = Utils::OpenHandle(*source); - i::Handle<i::SharedFunctionInfo> result; - { - ScriptOriginOptions origin_options; - i::ScriptData* script_data = nullptr; - i::MaybeHandle<i::SharedFunctionInfo> maybe_function_info = - i::Compiler::GetSharedFunctionInfoForScript( - isolate, str, i::Compiler::ScriptDetails(), origin_options, nullptr, - script_data, ScriptCompiler::kNoCompileOptions, - ScriptCompiler::kNoCacheBecauseInspector, - i::FLAG_expose_inspector_scripts ? i::NOT_NATIVES_CODE - : i::INSPECTOR_CODE); - has_pending_exception = !maybe_function_info.ToHandle(&result); - RETURN_ON_FAILED_EXECUTION(UnboundScript); - } - RETURN_ESCAPED(ToApiHandle<UnboundScript>(result)); -} - -void debug::TierDownAllModulesPerIsolate(Isolate* v8_isolate) { - i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); - isolate->wasm_engine()->TierDownAllModulesPerIsolate(isolate); -} - -void debug::TierUpAllModulesPerIsolate(Isolate* v8_isolate) { - i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); - isolate->wasm_engine()->TierUpAllModulesPerIsolate(isolate); -} - -void debug::SetDebugDelegate(Isolate* v8_isolate, - debug::DebugDelegate* delegate) { - i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); - isolate->debug()->SetDebugDelegate(delegate); -} - -void debug::SetAsyncEventDelegate(Isolate* v8_isolate, - debug::AsyncEventDelegate* delegate) { - reinterpret_cast<i::Isolate*>(v8_isolate)->set_async_event_delegate(delegate); -} - -void debug::ResetBlackboxedStateCache(Isolate* v8_isolate, - v8::Local<debug::Script> script) { - i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); - ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); - i::DisallowHeapAllocation no_gc; - i::SharedFunctionInfo::ScriptIterator iter(isolate, - *Utils::OpenHandle(*script)); - for (i::SharedFunctionInfo info = iter.Next(); !info.is_null(); - info = iter.Next()) { - if (info.HasDebugInfo()) { - info.GetDebugInfo().set_computed_debug_is_blackboxed(false); - } - } -} - -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::kTaggedSize; - CHECK(object->IsHeapObject()); - return i::Handle<i::HeapObject>::cast(object)->Size(); -} - v8::MaybeLocal<v8::Array> v8::Object::PreviewEntries(bool* is_key_value) { if (IsMap()) { *is_key_value = true; @@ -10136,205 +9399,6 @@ v8::MaybeLocal<v8::Array> v8::Object::PreviewEntries(bool* is_key_value) { return v8::MaybeLocal<v8::Array>(); } -Local<Function> debug::GetBuiltin(Isolate* v8_isolate, Builtin builtin) { - i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); - ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); - i::HandleScope handle_scope(isolate); - i::Builtins::Name builtin_id; - switch (builtin) { - case kStringToLowerCase: - builtin_id = i::Builtins::kStringPrototypeToLocaleLowerCase; - break; - default: - UNREACHABLE(); - } - - i::Handle<i::String> name = isolate->factory()->empty_string(); - i::NewFunctionArgs args = i::NewFunctionArgs::ForBuiltinWithoutPrototype( - name, builtin_id, i::LanguageMode::kStrict); - i::Handle<i::JSFunction> fun = isolate->factory()->NewFunction(args); - - fun->shared().set_internal_formal_parameter_count(0); - fun->shared().set_length(0); - return Utils::ToLocal(handle_scope.CloseAndEscape(fun)); -} - -void debug::SetConsoleDelegate(Isolate* v8_isolate, ConsoleDelegate* delegate) { - i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); - ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); - isolate->set_console_delegate(delegate); -} - -debug::ConsoleCallArguments::ConsoleCallArguments( - const v8::FunctionCallbackInfo<v8::Value>& info) - : v8::FunctionCallbackInfo<v8::Value>(nullptr, info.values_, info.length_) { -} - -debug::ConsoleCallArguments::ConsoleCallArguments( - const internal::BuiltinArguments& args) - : v8::FunctionCallbackInfo<v8::Value>( - nullptr, - // Drop the first argument (receiver, i.e. the "console" object). - args.length() > 1 ? args.address_of_first_argument() : nullptr, - args.length() - 1) {} - -// Marked V8_DEPRECATED. -int debug::GetStackFrameId(v8::Local<v8::StackFrame> frame) { return 0; } - -v8::Local<v8::StackTrace> debug::GetDetailedStackTrace( - Isolate* v8_isolate, v8::Local<v8::Object> v8_error) { - i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); - i::Handle<i::JSReceiver> error = Utils::OpenHandle(*v8_error); - if (!error->IsJSObject()) { - return v8::Local<v8::StackTrace>(); - } - i::Handle<i::FixedArray> stack_trace = - isolate->GetDetailedStackTrace(i::Handle<i::JSObject>::cast(error)); - return Utils::StackTraceToLocal(stack_trace); -} - -MaybeLocal<debug::Script> debug::GeneratorObject::Script() { - i::Handle<i::JSGeneratorObject> obj = Utils::OpenHandle(this); - 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); -} - -Local<Function> debug::GeneratorObject::Function() { - i::Handle<i::JSGeneratorObject> obj = Utils::OpenHandle(this); - return Utils::ToLocal(handle(obj->function(), obj->GetIsolate())); -} - -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(); - if (!maybe_script.IsScript()) return debug::Location(); - i::Isolate* isolate = obj->GetIsolate(); - i::Handle<i::Script> script(i::Script::cast(maybe_script), isolate); - i::Script::PositionInfo info; - i::SharedFunctionInfo::EnsureSourcePositionsAvailable( - isolate, i::handle(obj->function().shared(), isolate)); - i::Script::GetPositionInfo(script, obj->source_position(), &info, - i::Script::WITH_OFFSET); - return debug::Location(info.line, info.column); -} - -bool debug::GeneratorObject::IsSuspended() { - return Utils::OpenHandle(this)->is_suspended(); -} - -v8::Local<debug::GeneratorObject> debug::GeneratorObject::Cast( - v8::Local<v8::Value> value) { - CHECK(value->IsGeneratorObject()); - return ToApiHandle<debug::GeneratorObject>(Utils::OpenHandle(*value)); -} - -MaybeLocal<v8::Value> debug::EvaluateGlobal(v8::Isolate* isolate, - v8::Local<v8::String> source, - EvaluateGlobalMode mode, - bool repl) { - i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate); - PREPARE_FOR_DEBUG_INTERFACE_EXECUTION_WITH_ISOLATE(internal_isolate, Value); - i::REPLMode repl_mode = repl ? i::REPLMode::kYes : i::REPLMode::kNo; - Local<Value> result; - has_pending_exception = !ToLocal<Value>( - i::DebugEvaluate::Global(internal_isolate, Utils::OpenHandle(*source), - mode, repl_mode), - &result); - RETURN_ON_FAILED_EXECUTION(Value); - RETURN_ESCAPED(result); -} - -void debug::QueryObjects(v8::Local<v8::Context> v8_context, - QueryObjectPredicate* predicate, - PersistentValueVector<v8::Object>* objects) { - i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_context->GetIsolate()); - ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); - isolate->heap_profiler()->QueryObjects(Utils::OpenHandle(*v8_context), - predicate, objects); -} - -void debug::GlobalLexicalScopeNames( - v8::Local<v8::Context> v8_context, - v8::PersistentValueVector<v8::String>* names) { - i::Handle<i::Context> context = Utils::OpenHandle(*v8_context); - i::Isolate* isolate = context->GetIsolate(); - i::Handle<i::ScriptContextTable> table( - context->global_object().native_context().script_context_table(), - isolate); - for (int i = 0; i < table->synchronized_used(); i++) { - i::Handle<i::Context> context = - i::ScriptContextTable::GetContext(isolate, table, i); - DCHECK(context->IsScriptContext()); - 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); - if (i::ScopeInfo::VariableIsSynthetic(name)) continue; - names->Append(Utils::ToLocal(handle(name, isolate))); - } - } -} - -void debug::SetReturnValue(v8::Isolate* v8_isolate, - v8::Local<v8::Value> value) { - i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); - isolate->debug()->set_return_value(*Utils::OpenHandle(*value)); -} - -int64_t debug::GetNextRandomInt64(v8::Isolate* v8_isolate) { - return reinterpret_cast<i::Isolate*>(v8_isolate) - ->random_number_generator() - ->NextInt64(); -} - -void debug::EnumerateRuntimeCallCounters(v8::Isolate* v8_isolate, - RuntimeCallCounterCallback callback) { - i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); - if (isolate->counters()) { - isolate->counters()->runtime_call_stats()->EnumerateCounters(callback); - } -} - -int debug::GetDebuggingId(v8::Local<v8::Function> function) { - i::Handle<i::JSReceiver> callable = v8::Utils::OpenHandle(*function); - if (!callable->IsJSFunction()) return i::DebugInfo::kNoDebuggingId; - i::Handle<i::JSFunction> func = i::Handle<i::JSFunction>::cast(callable); - int id = func->GetIsolate()->debug()->GetFunctionDebuggingId(func); - DCHECK_NE(i::DebugInfo::kNoDebuggingId, id); - return id; -} - -bool debug::SetFunctionBreakpoint(v8::Local<v8::Function> function, - v8::Local<v8::String> condition, - BreakpointId* id) { - i::Handle<i::JSReceiver> callable = Utils::OpenHandle(*function); - if (!callable->IsJSFunction()) return false; - i::Handle<i::JSFunction> jsfunction = - i::Handle<i::JSFunction>::cast(callable); - i::Isolate* isolate = jsfunction->GetIsolate(); - i::Handle<i::String> condition_string = - condition.IsEmpty() ? isolate->factory()->empty_string() - : Utils::OpenHandle(*condition); - return isolate->debug()->SetBreakpointForFunction( - handle(jsfunction->shared(), isolate), condition_string, id); -} - -debug::PostponeInterruptsScope::PostponeInterruptsScope(v8::Isolate* isolate) - : scope_( - new i::PostponeInterruptsScope(reinterpret_cast<i::Isolate*>(isolate), - i::StackGuard::API_INTERRUPT)) {} - -debug::PostponeInterruptsScope::~PostponeInterruptsScope() = default; - -debug::DisableBreakScope::DisableBreakScope(v8::Isolate* isolate) - : scope_(std::make_unique<i::DisableBreak>( - reinterpret_cast<i::Isolate*>(isolate)->debug())) {} - -debug::DisableBreakScope::~DisableBreakScope() = default; - Local<String> CpuProfileNode::GetFunctionName() const { const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this); i::Isolate* isolate = node->isolate(); @@ -10344,239 +9408,6 @@ Local<String> CpuProfileNode::GetFunctionName() const { return ToApiHandle<String>(name); } -int debug::Coverage::BlockData::StartOffset() const { return block_->start; } -int debug::Coverage::BlockData::EndOffset() const { return block_->end; } -uint32_t debug::Coverage::BlockData::Count() const { return block_->count; } - -int debug::Coverage::FunctionData::StartOffset() const { - return function_->start; -} -int debug::Coverage::FunctionData::EndOffset() const { return function_->end; } -uint32_t debug::Coverage::FunctionData::Count() const { - return function_->count; -} - -MaybeLocal<String> debug::Coverage::FunctionData::Name() const { - return ToApiHandle<String>(function_->name); -} - -size_t debug::Coverage::FunctionData::BlockCount() const { - return function_->blocks.size(); -} - -bool debug::Coverage::FunctionData::HasBlockCoverage() const { - return function_->has_block_coverage; -} - -debug::Coverage::BlockData debug::Coverage::FunctionData::GetBlockData( - size_t i) const { - return BlockData(&function_->blocks.at(i), coverage_); -} - -Local<debug::Script> debug::Coverage::ScriptData::GetScript() const { - return ToApiHandle<debug::Script>(script_->script); -} - -size_t debug::Coverage::ScriptData::FunctionCount() const { - return script_->functions.size(); -} - -debug::Coverage::FunctionData debug::Coverage::ScriptData::GetFunctionData( - size_t i) const { - return FunctionData(&script_->functions.at(i), coverage_); -} - -debug::Coverage::ScriptData::ScriptData(size_t index, - std::shared_ptr<i::Coverage> coverage) - : script_(&coverage->at(index)), coverage_(std::move(coverage)) {} - -size_t debug::Coverage::ScriptCount() const { return coverage_->size(); } - -debug::Coverage::ScriptData debug::Coverage::GetScriptData(size_t i) const { - return ScriptData(i, coverage_); -} - -debug::Coverage debug::Coverage::CollectPrecise(Isolate* isolate) { - return Coverage( - i::Coverage::CollectPrecise(reinterpret_cast<i::Isolate*>(isolate))); -} - -debug::Coverage debug::Coverage::CollectBestEffort(Isolate* isolate) { - return Coverage( - i::Coverage::CollectBestEffort(reinterpret_cast<i::Isolate*>(isolate))); -} - -void debug::Coverage::SelectMode(Isolate* isolate, debug::CoverageMode mode) { - i::Coverage::SelectMode(reinterpret_cast<i::Isolate*>(isolate), mode); -} - -int debug::TypeProfile::Entry::SourcePosition() const { - return entry_->position; -} - -std::vector<MaybeLocal<String>> debug::TypeProfile::Entry::Types() const { - std::vector<MaybeLocal<String>> result; - for (const internal::Handle<internal::String>& type : entry_->types) { - result.emplace_back(ToApiHandle<String>(type)); - } - return result; -} - -debug::TypeProfile::ScriptData::ScriptData( - size_t index, std::shared_ptr<i::TypeProfile> type_profile) - : script_(&type_profile->at(index)), - type_profile_(std::move(type_profile)) {} - -Local<debug::Script> debug::TypeProfile::ScriptData::GetScript() const { - return ToApiHandle<debug::Script>(script_->script); -} - -std::vector<debug::TypeProfile::Entry> debug::TypeProfile::ScriptData::Entries() - const { - std::vector<debug::TypeProfile::Entry> result; - for (const internal::TypeProfileEntry& entry : script_->entries) { - result.push_back(debug::TypeProfile::Entry(&entry, type_profile_)); - } - return result; -} - -debug::TypeProfile debug::TypeProfile::Collect(Isolate* isolate) { - return TypeProfile( - i::TypeProfile::Collect(reinterpret_cast<i::Isolate*>(isolate))); -} - -void debug::TypeProfile::SelectMode(Isolate* isolate, - debug::TypeProfileMode mode) { - i::TypeProfile::SelectMode(reinterpret_cast<i::Isolate*>(isolate), mode); -} - -size_t debug::TypeProfile::ScriptCount() const { return type_profile_->size(); } - -debug::TypeProfile::ScriptData debug::TypeProfile::GetScriptData( - size_t i) const { - return ScriptData(i, type_profile_); -} - -v8::MaybeLocal<v8::Value> debug::WeakMap::Get(v8::Local<v8::Context> context, - v8::Local<v8::Value> key) { - PREPARE_FOR_EXECUTION(context, WeakMap, Get, Value); - auto self = Utils::OpenHandle(this); - Local<Value> result; - i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)}; - has_pending_exception = - !ToLocal<Value>(i::Execution::CallBuiltin(isolate, isolate->weakmap_get(), - self, arraysize(argv), argv), - &result); - RETURN_ON_FAILED_EXECUTION(Value); - RETURN_ESCAPED(result); -} - -v8::MaybeLocal<debug::WeakMap> debug::WeakMap::Set( - v8::Local<v8::Context> context, v8::Local<v8::Value> key, - v8::Local<v8::Value> value) { - PREPARE_FOR_EXECUTION(context, WeakMap, Set, WeakMap); - auto self = Utils::OpenHandle(this); - i::Handle<i::Object> result; - i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key), - Utils::OpenHandle(*value)}; - has_pending_exception = - !i::Execution::CallBuiltin(isolate, isolate->weakmap_set(), self, - arraysize(argv), argv) - .ToHandle(&result); - RETURN_ON_FAILED_EXECUTION(WeakMap); - RETURN_ESCAPED(Local<WeakMap>::Cast(Utils::ToLocal(result))); -} - -Local<debug::WeakMap> debug::WeakMap::New(v8::Isolate* isolate) { - i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); - LOG_API(i_isolate, WeakMap, New); - ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); - i::Handle<i::JSWeakMap> obj = i_isolate->factory()->NewJSWeakMap(); - return ToApiHandle<debug::WeakMap>(obj); -} - -debug::WeakMap* debug::WeakMap::Cast(v8::Value* value) { - return static_cast<debug::WeakMap*>(value); -} - -Local<Value> debug::AccessorPair::getter() { - i::Handle<i::AccessorPair> accessors = Utils::OpenHandle(this); - i::Isolate* isolate = accessors->GetIsolate(); - i::Handle<i::Object> getter(accessors->getter(), isolate); - return Utils::ToLocal(getter); -} - -Local<Value> debug::AccessorPair::setter() { - i::Handle<i::AccessorPair> accessors = Utils::OpenHandle(this); - i::Isolate* isolate = accessors->GetIsolate(); - i::Handle<i::Object> setter(accessors->setter(), isolate); - return Utils::ToLocal(setter); -} - -bool debug::AccessorPair::IsAccessorPair(Local<Value> that) { - i::Handle<i::Object> obj = Utils::OpenHandle(*that); - return obj->IsAccessorPair(); -} - -int debug::WasmValue::value_type() { - i::Handle<i::WasmValue> obj = Utils::OpenHandle(this); - return obj->value_type(); -} - -v8::Local<v8::Array> debug::WasmValue::bytes() { - i::Handle<i::WasmValue> obj = Utils::OpenHandle(this); - DCHECK(i::wasm::ValueType::Kind::kI32 == obj->value_type() || - i::wasm::ValueType::Kind::kI64 == obj->value_type() || - i::wasm::ValueType::Kind::kF32 == obj->value_type() || - i::wasm::ValueType::Kind::kF64 == obj->value_type() || - i::wasm::ValueType::Kind::kS128 == obj->value_type()); - - i::Isolate* isolate = obj->GetIsolate(); - i::Handle<i::Object> bytes_or_ref(obj->bytes_or_ref(), isolate); - i::Handle<i::ByteArray> bytes(i::Handle<i::ByteArray>::cast(bytes_or_ref)); - - int length = bytes->length(); - - i::Handle<i::FixedArray> fa = isolate->factory()->NewFixedArray(length); - i::Handle<i::JSArray> arr = obj->GetIsolate()->factory()->NewJSArray( - i::PACKED_SMI_ELEMENTS, length, length); - i::JSArray::SetContent(arr, fa); - - for (int i = 0; i < length; i++) { - fa->set(i, i::Smi::FromInt(bytes->get(i))); - } - - return Utils::ToLocal(arr); -} - -v8::Local<v8::Value> debug::WasmValue::ref() { - i::Handle<i::WasmValue> obj = Utils::OpenHandle(this); - DCHECK_EQ(i::wasm::HeapType::kExtern, obj->value_type()); - - i::Isolate* isolate = obj->GetIsolate(); - i::Handle<i::Object> bytes_or_ref(obj->bytes_or_ref(), isolate); - - return Utils::ToLocal(bytes_or_ref); -} - -bool debug::WasmValue::IsWasmValue(Local<Value> that) { - i::Handle<i::Object> obj = Utils::OpenHandle(*that); - return obj->IsWasmValue(); -} - -MaybeLocal<Message> debug::GetMessageFromPromise(Local<Promise> p) { - i::Handle<i::JSPromise> promise = Utils::OpenHandle(*p); - i::Isolate* isolate = promise->GetIsolate(); - - i::Handle<i::Symbol> key = isolate->factory()->promise_debug_message_symbol(); - i::Handle<i::Object> maybeMessage = - i::JSReceiver::GetDataProperty(promise, key); - - if (!maybeMessage->IsJSMessageObject(isolate)) return MaybeLocal<Message>(); - return ToApiHandle<Message>( - i::Handle<i::JSMessageObject>::cast(maybeMessage)); -} - const char* CpuProfileNode::GetFunctionNameStr() const { const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this); return node->entry()->name(); @@ -10689,6 +9520,9 @@ const CpuProfileNode* CpuProfile::GetSample(int index) const { return reinterpret_cast<const CpuProfileNode*>(profile->sample(index).node); } +const int CpuProfileNode::kNoLineNumberInfo; +const int CpuProfileNode::kNoColumnNumberInfo; + int64_t CpuProfile::GetSampleTimestamp(int index) const { const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this); return profile->sample(index).timestamp.since_origin().InMicroseconds(); @@ -10741,10 +9575,11 @@ void CpuProfiler::SetUsePreciseSampling(bool use_precise_sampling) { use_precise_sampling); } -CpuProfilingStatus CpuProfiler::StartProfiling(Local<String> title, - CpuProfilingOptions options) { +CpuProfilingStatus CpuProfiler::StartProfiling( + Local<String> title, CpuProfilingOptions options, + std::unique_ptr<DiscardedSamplesDelegate> delegate) { return reinterpret_cast<i::CpuProfiler*>(this)->StartProfiling( - *Utils::OpenHandle(*title), options); + *Utils::OpenHandle(*title), options, std::move(delegate)); } CpuProfilingStatus CpuProfiler::StartProfiling(Local<String> title, @@ -11127,7 +9962,7 @@ void EmbedderHeapTracer::RegisterEmbedderReference( void EmbedderHeapTracer::IterateTracedGlobalHandles( TracedGlobalHandleVisitor* visitor) { i::Isolate* isolate = reinterpret_cast<i::Isolate*>(isolate_); - i::DisallowHeapAllocation no_allocation; + i::DisallowGarbageCollection no_gc; isolate->global_handles()->IterateTracedNodes(visitor); } @@ -11146,44 +9981,19 @@ void EmbedderHeapTracer::ResetHandleInNonTracingGC( UNREACHABLE(); } -const void* CTypeInfo::GetWrapperInfo() const { - DCHECK(payload_ & kWrapperTypeInfoMask); - return reinterpret_cast<const void*>(payload_ & kWrapperTypeInfoMask); -} - CFunction::CFunction(const void* address, const CFunctionInfo* type_info) : address_(address), type_info_(type_info) { CHECK_NOT_NULL(address_); CHECK_NOT_NULL(type_info_); - for (unsigned int i = 0; i < type_info_->ArgumentCount(); ++i) { - if (type_info_->ArgumentInfo(i).IsArray()) { - // Array args require an integer passed for their length - // as the next argument. - DCHECK_LT(i + 1, type_info_->ArgumentCount()); - switch (type_info_->ArgumentInfo(i + 1).GetType()) { - case CTypeInfo::Type::kInt32: - case CTypeInfo::Type::kUint32: - case CTypeInfo::Type::kInt64: - case CTypeInfo::Type::kUint64: - break; - default: - UNREACHABLE(); - break; - } - } - } } RegisterState::RegisterState() : pc(nullptr), sp(nullptr), fp(nullptr), lr(nullptr) {} RegisterState::~RegisterState() = default; -RegisterState::RegisterState(const RegisterState& other) V8_NOEXCEPT { - *this = other; -} +RegisterState::RegisterState(const RegisterState& other) { *this = other; } -RegisterState& RegisterState::operator=(const RegisterState& other) - V8_NOEXCEPT { +RegisterState& RegisterState::operator=(const RegisterState& other) { if (&other != this) { pc = other.pc; sp = other.sp; @@ -11382,20 +10192,6 @@ void InvokeFinalizationRegistryCleanupFromTask( } // Undefine macros for jumbo build. -#undef LOG_API -#undef ENTER_V8_DO_NOT_USE -#undef ENTER_V8_HELPER_DO_NOT_USE -#undef PREPARE_FOR_DEBUG_INTERFACE_EXECUTION_WITH_ISOLATE -#undef PREPARE_FOR_EXECUTION_WITH_CONTEXT -#undef PREPARE_FOR_EXECUTION -#undef ENTER_V8 -#undef ENTER_V8_NO_SCRIPT -#undef ENTER_V8_NO_SCRIPT_NO_EXCEPTION -#undef ENTER_V8_FOR_NEW_CONTEXT -#undef EXCEPTION_BAILOUT_CHECK_SCOPED_DO_NOT_USE -#undef RETURN_ON_FAILED_EXECUTION -#undef RETURN_ON_FAILED_EXECUTION_PRIMITIVE -#undef RETURN_ESCAPED #undef SET_FIELD_WRAPPED #undef NEW_STRING #undef CALLBACK_SETTER @@ -11404,3 +10200,4 @@ void InvokeFinalizationRegistryCleanupFromTask( } // namespace v8 #undef TRACE_BS +#include "src/api/api-macros-undef.h" diff --git a/chromium/v8/src/api/api.h b/chromium/v8/src/api/api.h index 6c0ea8faea2..b323f71bd8c 100644 --- a/chromium/v8/src/api/api.h +++ b/chromium/v8/src/api/api.h @@ -33,7 +33,6 @@ namespace debug { class AccessorPair; class GeneratorObject; class Script; -class WasmValue; class WeakMap; } // namespace debug @@ -123,18 +122,20 @@ class RegisteredExtension { V(Context, Context) \ V(External, Object) \ V(StackTrace, FixedArray) \ - V(StackFrame, StackTraceFrame) \ + V(StackFrame, StackFrameInfo) \ V(Proxy, JSProxy) \ V(debug::GeneratorObject, JSGeneratorObject) \ V(debug::Script, Script) \ V(debug::WeakMap, JSWeakMap) \ V(debug::AccessorPair, AccessorPair) \ - V(debug::WasmValue, WasmValue) \ V(Promise, JSPromise) \ V(Primitive, Object) \ V(PrimitiveArray, FixedArray) \ V(BigInt, BigInt) \ - V(ScriptOrModule, Script) + V(ScriptOrModule, Script) \ + V(FixedArray, FixedArray) \ + V(ModuleRequest, ModuleRequest) \ + V(WasmMemoryObject, WasmMemoryObject) class Utils { public: @@ -217,7 +218,7 @@ class Utils { static inline Local<StackTrace> StackTraceToLocal( v8::internal::Handle<v8::internal::FixedArray> obj); static inline Local<StackFrame> StackFrameToLocal( - v8::internal::Handle<v8::internal::StackTraceFrame> obj); + v8::internal::Handle<v8::internal::StackFrameInfo> obj); static inline Local<Number> NumberToLocal( v8::internal::Handle<v8::internal::Object> obj); static inline Local<Integer> IntegerToLocal( @@ -240,7 +241,9 @@ class Utils { v8::internal::Handle<v8::internal::JSReceiver> obj); static inline Local<Primitive> ToLocalPrimitive( v8::internal::Handle<v8::internal::Object> obj); - static inline Local<PrimitiveArray> ToLocal( + static inline Local<FixedArray> FixedArrayToLocal( + v8::internal::Handle<v8::internal::FixedArray> obj); + static inline Local<PrimitiveArray> PrimitiveArrayToLocal( v8::internal::Handle<v8::internal::FixedArray> obj); static inline Local<ScriptOrModule> ScriptOrModuleToLocal( v8::internal::Handle<v8::internal::Script> obj); @@ -315,7 +318,7 @@ class PersistentHandles; // data. class HandleScopeImplementer { public: - class EnteredContextRewindScope { + class V8_NODISCARD EnteredContextRewindScope { public: explicit EnteredContextRewindScope(HandleScopeImplementer* hsi) : hsi_(hsi), saved_entered_context_count_(hsi->EnteredContextCount()) {} @@ -338,6 +341,9 @@ class HandleScopeImplementer { ~HandleScopeImplementer() { DeleteArray(spare_); } + HandleScopeImplementer(const HandleScopeImplementer&) = delete; + HandleScopeImplementer& operator=(const HandleScopeImplementer&) = delete; + // Threading support for handle data. static int ArchiveSpacePerThread(); char* RestoreThread(char* from); @@ -434,8 +440,6 @@ class HandleScopeImplementer { friend class HandleScopeImplementerOffsets; friend class PersistentHandlesScope; - - DISALLOW_COPY_AND_ASSIGN(HandleScopeImplementer); }; const int kHandleBlockSize = v8::internal::KB - 2; // fit in one page |