diff --git a/CHANGELOG.md b/CHANGELOG.md index b583dddd..1d7c711d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Promise resolver and promise result +### Changed +- Upgrade to V8 8.9.255.20 + ### Fixed - Go GC attempting to free C memory (via finalizer) of values after an Isolate is disposed causes a panic diff --git a/README.md b/README.md index f66c581b..ea05c552 100644 --- a/README.md +++ b/README.md @@ -137,7 +137,7 @@ V8 requires 64-bit on Windows, therefore will not work on 32-bit systems. ## V8 dependency -V8 version: **8.8.278.14** (January 2021) +V8 version: **8.9.255.20** (March 2021) In order to make `v8go` usable as a standard Go package, prebuilt static libraries of V8 are included for Linux and macOS ie. you *should not* require to build V8 yourself. diff --git a/deps/darwin_x86_64/libv8.a b/deps/darwin_x86_64/libv8.a index ee7a564c..3e1a81cf 100644 Binary files a/deps/darwin_x86_64/libv8.a and b/deps/darwin_x86_64/libv8.a differ diff --git a/deps/depot_tools b/deps/depot_tools index 07bd2522..d071f2a8 160000 --- a/deps/depot_tools +++ b/deps/depot_tools @@ -1 +1 @@ -Subproject commit 07bd252238b7ba84f7039dc55ce03b37e475489c +Subproject commit d071f2a8a941d8f7e05eb43319c7b2ab81fc8fdd diff --git a/deps/include/DEPS b/deps/include/DEPS index 7d60081f..9f400205 100644 --- a/deps/include/DEPS +++ b/deps/include/DEPS @@ -2,5 +2,8 @@ include_rules = [ # v8-inspector-protocol.h depends on generated files under include/inspector. "+inspector", "+cppgc/common.h", + # Used by v8-cppgc.h to bridge to cppgc. + "+cppgc/custom-space.h", + "+cppgc/internal/write-barrier.h", "+cppgc/visitor.h", ] diff --git a/deps/include/cppgc/allocation.h b/deps/include/cppgc/allocation.h index 556f313a..1164f692 100644 --- a/deps/include/cppgc/allocation.h +++ b/deps/include/cppgc/allocation.h @@ -39,9 +39,8 @@ class V8_EXPORT MakeGarbageCollectedTraitInternal { const_cast(reinterpret_cast( reinterpret_cast(payload) - api_constants::kFullyConstructedBitFieldOffsetFromPayload))); - uint16_t value = atomic_mutable_bitfield->load(std::memory_order_relaxed); - value = value | api_constants::kFullyConstructedBitMask; - atomic_mutable_bitfield->store(value, std::memory_order_release); + atomic_mutable_bitfield->fetch_or(api_constants::kFullyConstructedBitMask, + std::memory_order_release); } static void* Allocate(cppgc::AllocationHandle& handle, size_t size, @@ -113,11 +112,29 @@ class MakeGarbageCollectedTraitBase }; /** - * struct used specify to MakeGarbageCollected how many bytes should be - * appended to the allocated object. + * Passed to MakeGarbageCollected to specify how many bytes should be appended + * to the allocated object. + * + * Example: + * \code + * class InlinedArray final : public GarbageCollected { + * public: + * explicit InlinedArray(size_t bytes) : size(bytes), byte_array(this + 1) {} + * void Trace(Visitor*) const {} + + * size_t size; + * char* byte_array; + * }; + * + * auto* inlined_array = MakeGarbageCollectedbyte_array[i]); + * } + * \endcode */ struct AdditionalBytes { - explicit AdditionalBytes(size_t bytes) : value(bytes) {} + constexpr explicit AdditionalBytes(size_t bytes) : value(bytes) {} const size_t value; }; diff --git a/deps/include/cppgc/common.h b/deps/include/cppgc/common.h index 228b9abb..1fff1a03 100644 --- a/deps/include/cppgc/common.h +++ b/deps/include/cppgc/common.h @@ -14,11 +14,11 @@ namespace cppgc { enum class EmbedderStackState { kMayContainHeapPointers, kNoHeapPointers, - kUnknown V8_ENUM_DEPRECATE_SOON("Use kMayContainHeapPointers") = + kUnknown V8_ENUM_DEPRECATED("Use kMayContainHeapPointers") = kMayContainHeapPointers, - kNonEmpty V8_ENUM_DEPRECATE_SOON("Use kMayContainHeapPointers") = + kNonEmpty V8_ENUM_DEPRECATED("Use kMayContainHeapPointers") = kMayContainHeapPointers, - kEmpty V8_ENUM_DEPRECATE_SOON("Use kNoHeapPointers") = kNoHeapPointers, + kEmpty V8_ENUM_DEPRECATED("Use kNoHeapPointers") = kNoHeapPointers, }; } // namespace cppgc diff --git a/deps/include/cppgc/default-platform.h b/deps/include/cppgc/default-platform.h index 28990da9..2ccdeddd 100644 --- a/deps/include/cppgc/default-platform.h +++ b/deps/include/cppgc/default-platform.h @@ -20,12 +20,24 @@ namespace cppgc { */ class V8_EXPORT DefaultPlatform : public Platform { public: + /** + * Use this method instead of 'cppgc::InitializeProcess' when using + * 'cppgc::DefaultPlatform'. 'cppgc::DefaultPlatform::InitializeProcess' + * will initialize cppgc and v8 if needed (for non-standalone builds). + * + * \param platform DefaultPlatform instance used to initialize cppgc/v8. + */ + static void InitializeProcess(DefaultPlatform* platform); + using IdleTaskSupport = v8::platform::IdleTaskSupport; explicit DefaultPlatform( int thread_pool_size = 0, - IdleTaskSupport idle_task_support = IdleTaskSupport::kDisabled) - : v8_platform_(v8::platform::NewDefaultPlatform(thread_pool_size, - idle_task_support)) {} + IdleTaskSupport idle_task_support = IdleTaskSupport::kDisabled, + std::unique_ptr tracing_controller = {}) + : v8_platform_(v8::platform::NewDefaultPlatform( + thread_pool_size, idle_task_support, + v8::platform::InProcessStackDumping::kDisabled, + std::move(tracing_controller))) {} cppgc::PageAllocator* GetPageAllocator() override { return v8_platform_->GetPageAllocator(); @@ -48,6 +60,10 @@ class V8_EXPORT DefaultPlatform : public Platform { return v8_platform_->PostJob(priority, std::move(job_task)); } + TracingController* GetTracingController() override { + return v8_platform_->GetTracingController(); + } + protected: static constexpr v8::Isolate* kNoIsolate = nullptr; diff --git a/deps/include/cppgc/heap-consistency.h b/deps/include/cppgc/heap-consistency.h new file mode 100644 index 00000000..4a4eb103 --- /dev/null +++ b/deps/include/cppgc/heap-consistency.h @@ -0,0 +1,137 @@ +// Copyright 2020 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. + +#ifndef INCLUDE_CPPGC_HEAP_CONSISTENCY_H_ +#define INCLUDE_CPPGC_HEAP_CONSISTENCY_H_ + +#include + +#include "cppgc/internal/write-barrier.h" +#include "cppgc/trace-trait.h" +#include "v8config.h" // NOLINT(build/include_directory) + +namespace cppgc { + +class HeapHandle; + +namespace subtle { + +/** + * **DO NOT USE: Use the appropriate managed types.** + * + * Consistency helpers that aid in maintaining a consistent internal state of + * the garbage collector. + */ +class HeapConsistency final { + public: + using WriteBarrierParams = internal::WriteBarrier::Params; + using WriteBarrierType = internal::WriteBarrier::Type; + + /** + * Gets the required write barrier type for a specific write. + * + * \param slot Slot containing the pointer to the object. The slot itself + * must reside in an object that has been allocated using + * `MakeGarbageCollected()`. + * \param value The pointer to the object. May be an interior pointer to an + * interface of the actual object. + * \param params Parameters that may be used for actual write barrier calls. + * Only filled if return value indicates that a write barrier is needed. The + * contents of the `params` are an implementation detail. + * \returns whether a write barrier is needed and which barrier to invoke. + */ + static V8_INLINE WriteBarrierType GetWriteBarrierType( + const void* slot, const void* value, WriteBarrierParams& params) { + return internal::WriteBarrier::GetWriteBarrierType(slot, value, params); + } + + /** + * Gets the required write barrier type for a specific write. + * + * \param slot Slot containing the pointer to some part of an object object + * that has been allocated using `MakeGarbageCollected()`. Does not consider + * the value of `slot`. + * \param params Parameters that may be used for actual write barrier calls. + * Only filled if return value indicates that a write barrier is needed. The + * contents of the `params` are an implementation detail. + * \returns whether a write barrier is needed and which barrier to invoke. + */ + static V8_INLINE WriteBarrierType + GetWriteBarrierType(const void* slot, WriteBarrierParams& params) { + return internal::WriteBarrier::GetWriteBarrierType(slot, params); + } + + /** + * Conservative Dijkstra-style write barrier that processes an object if it + * has not yet been processed. + * + * \param params The parameters retrieved from `GetWriteBarrierType()`. + * \param object The pointer to the object. May be an interior pointer to a + * an interface of the actual object. + */ + static V8_INLINE void DijkstraWriteBarrier(const WriteBarrierParams& params, + const void* object) { + internal::WriteBarrier::DijkstraMarkingBarrier(params, object); + } + + /** + * Conservative Dijkstra-style write barrier that processes a range of + * elements if they have not yet been processed. + * + * \param params The parameters retrieved from `GetWriteBarrierType()`. + * \param heap The corresponding heap. + * \param first_element Pointer to the first element that should be processed. + * The slot itself must reside in an object that has been allocated using + * `MakeGarbageCollected()`. + * \param element_size Size of the element in bytes. + * \param number_of_elements Number of elements that should be processed, + * starting with `first_element`. + * \param trace_callback The trace callback that should be invoked for each + * element if necessary. + */ + static V8_INLINE void DijkstraWriteBarrierRange( + const WriteBarrierParams& params, HeapHandle& heap, + const void* first_element, size_t element_size, size_t number_of_elements, + TraceCallback trace_callback) { + internal::WriteBarrier::DijkstraMarkingBarrierRange( + params, heap, first_element, element_size, number_of_elements, + trace_callback); + } + + /** + * Steele-style write barrier that re-processes an object if it has already + * been processed. + * + * \param params The parameters retrieved from `GetWriteBarrierType()`. + * \param object The pointer to the object which must point to an object that + * has been allocated using `MakeGarbageCollected()`. Interior pointers are + * not supported. + */ + static V8_INLINE void SteeleWriteBarrier(const WriteBarrierParams& params, + const void* object) { + internal::WriteBarrier::SteeleMarkingBarrier(params, object); + } + + /** + * Generational barrier for maintaining consistency when running with multiple + * generations. + * + * \param params The parameters retrieved from `GetWriteBarrierType()`. + * \param slot Slot containing the pointer to the object. The slot itself + * must reside in an object that has been allocated using + * `MakeGarbageCollected()`. + */ + static V8_INLINE void GenerationalBarrier(const WriteBarrierParams& params, + const void* slot) { + internal::WriteBarrier::GenerationalBarrier(params, slot); + } + + private: + HeapConsistency() = delete; +}; + +} // namespace subtle +} // namespace cppgc + +#endif // INCLUDE_CPPGC_HEAP_CONSISTENCY_H_ diff --git a/deps/include/cppgc/heap.h b/deps/include/cppgc/heap.h index 04a55598..fd0512f1 100644 --- a/deps/include/cppgc/heap.h +++ b/deps/include/cppgc/heap.h @@ -29,6 +29,11 @@ namespace internal { class Heap; } // namespace internal +/** + * Used for additional heap APIs. + */ +class HeapHandle; + class V8_EXPORT Heap { public: /** @@ -51,6 +56,41 @@ class V8_EXPORT Heap { kNoConservativeStackScan, }; + /** + * Specifies supported marking types + */ + enum class MarkingType : uint8_t { + /** + * Atomic stop-the-world marking. This option does not require any write + * barriers but is the most intrusive in terms of jank. + */ + kAtomic, + /** + * Incremental marking, i.e. interleave marking is the rest of the + * application on the same thread. + */ + kIncremental, + /** + * Incremental and concurrent marking. + */ + kIncrementalAndConcurrent + }; + + /** + * Specifies supported sweeping types + */ + enum class SweepingType : uint8_t { + /** + * Atomic stop-the-world sweeping. All of sweeping is performed at once. + */ + kAtomic, + /** + * Incremental and concurrent sweeping. Sweeping is split and interleaved + * with the rest of the application. + */ + kIncrementalAndConcurrent + }; + /** * Constraints for a Heap setup. */ @@ -93,6 +133,16 @@ class V8_EXPORT Heap { */ StackSupport stack_support = StackSupport::kSupportsConservativeStackScan; + /** + * Specifies which types of marking are supported by the heap. + */ + MarkingType marking_support = MarkingType::kIncrementalAndConcurrent; + + /** + * Specifies which types of sweeping are supported by the heap. + */ + SweepingType sweeping_support = SweepingType::kIncrementalAndConcurrent; + /** * Resource constraints specifying various properties that the internal * GC scheduler follows. @@ -132,6 +182,12 @@ class V8_EXPORT Heap { */ AllocationHandle& GetAllocationHandle(); + /** + * \returns the opaque heap handle which may be used to refer to this heap in + * other APIs. Valid as long as the underlying `Heap` is alive. + */ + HeapHandle& GetHeapHandle(); + private: Heap() = default; diff --git a/deps/include/cppgc/internal/api-constants.h b/deps/include/cppgc/internal/api-constants.h index 1303b8b8..a70f0071 100644 --- a/deps/include/cppgc/internal/api-constants.h +++ b/deps/include/cppgc/internal/api-constants.h @@ -28,7 +28,7 @@ constexpr size_t kGB = kMB * 1024; static constexpr size_t kFullyConstructedBitFieldOffsetFromPayload = 2 * sizeof(uint16_t); // Mask for in-construction bit. -static constexpr size_t kFullyConstructedBitMask = size_t{1}; +static constexpr uint16_t kFullyConstructedBitMask = uint16_t{1}; static constexpr size_t kPageSize = size_t{1} << 17; diff --git a/deps/include/cppgc/internal/pointer-policies.h b/deps/include/cppgc/internal/pointer-policies.h index 50c5d576..58f2515a 100644 --- a/deps/include/cppgc/internal/pointer-policies.h +++ b/deps/include/cppgc/internal/pointer-policies.h @@ -28,7 +28,17 @@ struct DijkstraWriteBarrierPolicy { // barrier doesn't break the tri-color invariant. } static void AssigningBarrier(const void* slot, const void* value) { - WriteBarrier::MarkingBarrier(slot, value); + WriteBarrier::Params params; + switch (WriteBarrier::GetWriteBarrierType(slot, value, params)) { + case WriteBarrier::Type::kGenerational: + WriteBarrier::GenerationalBarrier(params, slot); + break; + case WriteBarrier::Type::kMarking: + WriteBarrier::DijkstraMarkingBarrier(params, value); + break; + case WriteBarrier::Type::kNone: + break; + } } }; diff --git a/deps/include/cppgc/internal/write-barrier.h b/deps/include/cppgc/internal/write-barrier.h index 5bf550b0..e3cc4c98 100644 --- a/deps/include/cppgc/internal/write-barrier.h +++ b/deps/include/cppgc/internal/write-barrier.h @@ -7,6 +7,7 @@ #include "cppgc/internal/api-constants.h" #include "cppgc/internal/process-heap.h" +#include "cppgc/trace-trait.h" #include "v8config.h" // NOLINT(build/include_directory) #if defined(CPPGC_CAGED_HEAP) @@ -14,64 +15,235 @@ #endif namespace cppgc { + +class HeapHandle; + namespace internal { +class WriteBarrierTypeForCagedHeapPolicy; +class WriteBarrierTypeForNonCagedHeapPolicy; + class V8_EXPORT WriteBarrier final { public: - static V8_INLINE void MarkingBarrier(const void* slot, const void* value) { + enum class Type : uint8_t { + kNone, + kMarking, + kGenerational, + }; + + struct Params { +#if V8_ENABLE_CHECKS + Type type = Type::kNone; +#endif // !V8_ENABLE_CHECKS #if defined(CPPGC_CAGED_HEAP) - const uintptr_t start = - reinterpret_cast(value) & - ~(api_constants::kCagedHeapReservationAlignment - 1); - const uintptr_t slot_offset = reinterpret_cast(slot) - start; - if (slot_offset > api_constants::kCagedHeapReservationSize) { - // Check if slot is on stack or value is sentinel or nullptr. This relies - // on the fact that kSentinelPointer is encoded as 0x1. - return; - } + uintptr_t start; - CagedHeapLocalData* local_data = - reinterpret_cast(start); - if (V8_UNLIKELY(local_data->is_marking_in_progress)) { - MarkingBarrierSlow(value); - return; + CagedHeapLocalData& caged_heap() const { + return *reinterpret_cast(start); } + uintptr_t slot_offset; + uintptr_t value_offset; +#endif // CPPGC_CAGED_HEAP + }; + + enum class ValueMode { + kValuePresent, + kNoValuePresent, + }; + + // Returns the required write barrier for a given `slot` and `value`. + static V8_INLINE Type GetWriteBarrierType(const void* slot, const void* value, + Params& params); + // Returns the required write barrier for a given `slot`. + static V8_INLINE Type GetWriteBarrierType(const void* slot, Params& params); + + static V8_INLINE void DijkstraMarkingBarrier(const Params& params, + const void* object); + static V8_INLINE void DijkstraMarkingBarrierRange( + const Params& params, HeapHandle& heap, const void* first_element, + size_t element_size, size_t number_of_elements, + TraceCallback trace_callback); + static V8_INLINE void SteeleMarkingBarrier(const Params& params, + const void* object); #if defined(CPPGC_YOUNG_GENERATION) - GenerationalBarrier(local_data, slot, slot_offset, - reinterpret_cast(value) - start); -#endif -#else - if (V8_LIKELY(!ProcessHeap::IsAnyIncrementalOrConcurrentMarking())) return; + static V8_INLINE void GenerationalBarrier(const Params& params, + const void* slot); +#else // !CPPGC_YOUNG_GENERATION + static V8_INLINE void GenerationalBarrier(const Params& params, + const void* slot) {} +#endif // CPPGC_YOUNG_GENERATION - MarkingBarrierSlowWithSentinelCheck(value); -#endif // CPPGC_CAGED_HEAP - } +#if V8_ENABLE_CHECKS + static void CheckParams(Type expected_type, const Params& params); +#else // !V8_ENABLE_CHECKS + static void CheckParams(Type expected_type, const Params& params) {} +#endif // !V8_ENABLE_CHECKS private: WriteBarrier() = delete; - static void MarkingBarrierSlow(const void* value); - static void MarkingBarrierSlowWithSentinelCheck(const void* value); +#if defined(CPPGC_CAGED_HEAP) + using WriteBarrierTypePolicy = WriteBarrierTypeForCagedHeapPolicy; +#else // !CPPGC_CAGED_HEAP + using WriteBarrierTypePolicy = WriteBarrierTypeForNonCagedHeapPolicy; +#endif // !CPPGC_CAGED_HEAP + + static void DijkstraMarkingBarrierSlow(const void* value); + static void DijkstraMarkingBarrierSlowWithSentinelCheck(const void* value); + static void DijkstraMarkingBarrierRangeSlow(HeapHandle& heap_handle, + const void* first_element, + size_t element_size, + size_t number_of_elements, + TraceCallback trace_callback); + static void SteeleMarkingBarrierSlow(const void* value); + static void SteeleMarkingBarrierSlowWithSentinelCheck(const void* value); #if defined(CPPGC_YOUNG_GENERATION) - static V8_INLINE void GenerationalBarrier(CagedHeapLocalData* local_data, - const void* slot, - uintptr_t slot_offset, - uintptr_t value_offset) { - const AgeTable& age_table = local_data->age_table; + static void GenerationalBarrierSlow(const CagedHeapLocalData& local_data, + const AgeTable& ageTable, + const void* slot, uintptr_t value_offset); +#endif // CPPGC_YOUNG_GENERATION +}; - // Bail out if the slot is in young generation. - if (V8_LIKELY(age_table[slot_offset] == AgeTable::Age::kYoung)) return; +#if defined(CPPGC_CAGED_HEAP) +class WriteBarrierTypeForCagedHeapPolicy final { + public: + template + static V8_INLINE WriteBarrier::Type Get(const void* slot, const void* value, + WriteBarrier::Params& params) { + const bool have_caged_heap = + value_mode == WriteBarrier::ValueMode::kValuePresent + ? TryGetCagedHeap(slot, value, params) + : TryGetCagedHeap(slot, slot, params); + if (!have_caged_heap) { + return WriteBarrier::Type::kNone; + } + if (V8_UNLIKELY(params.caged_heap().is_marking_in_progress)) { +#if V8_ENABLE_CHECKS + params.type = WriteBarrier::Type::kMarking; +#endif // !V8_ENABLE_CHECKS + return WriteBarrier::Type::kMarking; + } +#if defined(CPPGC_YOUNG_GENERATION) + params.slot_offset = reinterpret_cast(slot) - params.start; + if (value_mode == WriteBarrier::ValueMode::kValuePresent) { + params.value_offset = reinterpret_cast(value) - params.start; + } else { + params.value_offset = 0; + } +#if V8_ENABLE_CHECKS + params.type = WriteBarrier::Type::kGenerational; +#endif // !V8_ENABLE_CHECKS + return WriteBarrier::Type::kGenerational; +#else // !CPPGC_YOUNG_GENERATION + return WriteBarrier::Type::kNone; +#endif // !CPPGC_YOUNG_GENERATION + } - GenerationalBarrierSlow(local_data, age_table, slot, value_offset); + private: + WriteBarrierTypeForCagedHeapPolicy() = delete; + + static V8_INLINE bool TryGetCagedHeap(const void* slot, const void* value, + WriteBarrier::Params& params) { + params.start = reinterpret_cast(value) & + ~(api_constants::kCagedHeapReservationAlignment - 1); + const uintptr_t slot_offset = + reinterpret_cast(slot) - params.start; + if (slot_offset > api_constants::kCagedHeapReservationSize) { + // Check if slot is on stack or value is sentinel or nullptr. This relies + // on the fact that kSentinelPointer is encoded as 0x1. + return false; + } + return true; + } +}; +#endif // CPPGC_CAGED_HEAP + +class WriteBarrierTypeForNonCagedHeapPolicy final { + public: + template + static V8_INLINE WriteBarrier::Type Get(const void* slot, const void* value, + WriteBarrier::Params& params) { + WriteBarrier::Type type = + V8_LIKELY(!ProcessHeap::IsAnyIncrementalOrConcurrentMarking()) + ? WriteBarrier::Type::kNone + : WriteBarrier::Type::kMarking; +#if V8_ENABLE_CHECKS + params.type = type; +#endif // !V8_ENABLE_CHECKS + return type; } - static void GenerationalBarrierSlow(CagedHeapLocalData* local_data, - const AgeTable& ageTable, - const void* slot, uintptr_t value_offset); -#endif + private: + WriteBarrierTypeForNonCagedHeapPolicy() = delete; }; +// static +WriteBarrier::Type WriteBarrier::GetWriteBarrierType( + const void* slot, const void* value, WriteBarrier::Params& params) { + return WriteBarrierTypePolicy::Get(slot, value, + params); +} + +// static +WriteBarrier::Type WriteBarrier::GetWriteBarrierType( + const void* slot, WriteBarrier::Params& params) { + return WriteBarrierTypePolicy::Get(slot, nullptr, + params); +} + +// static +void WriteBarrier::DijkstraMarkingBarrier(const Params& params, + const void* object) { + CheckParams(Type::kMarking, params); +#if defined(CPPGC_CAGED_HEAP) + // Caged heap already filters out sentinels. + DijkstraMarkingBarrierSlow(object); +#else // !CPPGC_CAGED_HEAP + DijkstraMarkingBarrierSlowWithSentinelCheck(object); +#endif // !CPPGC_CAGED_HEAP +} + +// static +void WriteBarrier::DijkstraMarkingBarrierRange(const Params& params, + HeapHandle& heap, + const void* first_element, + size_t element_size, + size_t number_of_elements, + TraceCallback trace_callback) { + CheckParams(Type::kMarking, params); + DijkstraMarkingBarrierRangeSlow(heap, first_element, element_size, + number_of_elements, trace_callback); +} + +// static +void WriteBarrier::SteeleMarkingBarrier(const Params& params, + const void* object) { + CheckParams(Type::kMarking, params); +#if defined(CPPGC_CAGED_HEAP) + // Caged heap already filters out sentinels. + SteeleMarkingBarrierSlow(object); +#else // !CPPGC_CAGED_HEAP + SteeleMarkingBarrierSlowWithSentinelCheck(object); +#endif // !CPPGC_CAGED_HEAP +} + +#if defined(CPPGC_YOUNG_GENERATION) +// static +void WriteBarrier::GenerationalBarrier(const Params& params, const void* slot) { + CheckParams(Type::kGenerational, params); + + const CagedHeapLocalData& local_data = params.caged_heap(); + const AgeTable& age_table = local_data.age_table; + + // Bail out if the slot is in young generation. + if (V8_LIKELY(age_table[params.slot_offset] == AgeTable::Age::kYoung)) return; + + GenerationalBarrierSlow(local_data, age_table, slot, params.value_offset); +} + +#endif // !CPPGC_YOUNG_GENERATION + } // namespace internal } // namespace cppgc diff --git a/deps/include/cppgc/platform.h b/deps/include/cppgc/platform.h index fb0b6b20..571aa80c 100644 --- a/deps/include/cppgc/platform.h +++ b/deps/include/cppgc/platform.h @@ -20,6 +20,7 @@ using PageAllocator = v8::PageAllocator; using Task = v8::Task; using TaskPriority = v8::TaskPriority; using TaskRunner = v8::TaskRunner; +using TracingController = v8::TracingController; /** * Platform interface used by Heap. Contains allocators and executors. @@ -113,6 +114,13 @@ class V8_EXPORT Platform { TaskPriority priority, std::unique_ptr job_task) { return nullptr; } + + /** + * Returns an instance of a `TracingController`. This must be non-nullptr. The + * default implementation returns an empty `TracingController` that consumes + * trace data without effect. + */ + virtual TracingController* GetTracingController(); }; /** diff --git a/deps/include/cppgc/prefinalizer.h b/deps/include/cppgc/prefinalizer.h index bde76429..9b7bc0e5 100644 --- a/deps/include/cppgc/prefinalizer.h +++ b/deps/include/cppgc/prefinalizer.h @@ -34,7 +34,7 @@ class PrefinalizerRegistration final { public: \ static bool InvokePreFinalizer(const cppgc::LivenessBroker& liveness_broker, \ void* object) { \ - static_assert(cppgc::internal::IsGarbageCollectedTypeV, \ + static_assert(cppgc::IsGarbageCollectedTypeV, \ "Only garbage collected objects can have prefinalizers"); \ Class* self = static_cast(object); \ if (liveness_broker.IsHeapObjectAlive(self)) return false; \ diff --git a/deps/include/cppgc/type-traits.h b/deps/include/cppgc/type-traits.h index 4d8ab809..c7d02db9 100644 --- a/deps/include/cppgc/type-traits.h +++ b/deps/include/cppgc/type-traits.h @@ -5,6 +5,8 @@ #ifndef INCLUDE_CPPGC_TYPE_TRAITS_H_ #define INCLUDE_CPPGC_TYPE_TRAITS_H_ +// This file should stay with minimal dependencies to allow embedder to check +// against Oilpan types without including any other parts. #include namespace cppgc { @@ -12,6 +14,14 @@ namespace cppgc { class Visitor; namespace internal { +template +class BasicMember; +struct DijkstraWriteBarrierPolicy; +struct NoWriteBarrierPolicy; +class StrongMemberTag; +class UntracedMemberTag; +class WeakMemberTag; // Pre-C++17 custom implementation of std::void_t. template @@ -25,18 +35,6 @@ using void_t = typename make_void::type; template struct IsWeak : std::false_type {}; -template class U> -struct IsSubclassOfTemplate { - private: - template - static std::true_type SubclassCheck(U*); - static std::false_type SubclassCheck(...); - - public: - static constexpr bool value = - decltype(SubclassCheck(std::declval()))::value; -}; - // IsTraceMethodConst is used to verify that all Trace methods are marked as // const. It is equivalent to IsTraceable but for a non-const object. template @@ -91,16 +89,56 @@ struct IsGarbageCollectedType< static_assert(sizeof(T), "T must be fully defined"); }; +template +struct IsSubclassOfBasicMemberTemplate { + private: + template + static std::true_type SubclassCheck( + BasicMember*); + static std::false_type SubclassCheck(...); + + public: + static constexpr bool value = + decltype(SubclassCheck(std::declval()))::value; +}; + +template ::value> +struct IsMemberType : std::false_type {}; + template -constexpr bool IsGarbageCollectedTypeV = - internal::IsGarbageCollectedType::value; +struct IsMemberType : std::true_type {}; + +template ::value> +struct IsWeakMemberType : std::false_type {}; template -constexpr bool IsGarbageCollectedMixinTypeV = - internal::IsGarbageCollectedMixinType::value; +struct IsWeakMemberType : std::true_type {}; + +template ::value> +struct IsUntracedMemberType : std::false_type {}; + +template +struct IsUntracedMemberType : std::true_type {}; } // namespace internal +template +constexpr bool IsGarbageCollectedMixinTypeV = + internal::IsGarbageCollectedMixinType::value; +template +constexpr bool IsGarbageCollectedTypeV = + internal::IsGarbageCollectedType::value; +template +constexpr bool IsMemberTypeV = internal::IsMemberType::value; +template +constexpr bool IsUntracedMemberTypeV = internal::IsUntracedMemberType::value; +template +constexpr bool IsWeakMemberTypeV = internal::IsWeakMemberType::value; template constexpr bool IsWeakV = internal::IsWeak::value; diff --git a/deps/include/cppgc/visitor.h b/deps/include/cppgc/visitor.h index 01f5f20e..74024c3d 100644 --- a/deps/include/cppgc/visitor.h +++ b/deps/include/cppgc/visitor.h @@ -190,7 +190,7 @@ class V8_EXPORT Visitor { static_assert(internal::IsAllocatedOnCompactableSpace::value, "Only references to objects allocated on compactable spaces " "should be registered as movable slots."); - static_assert(!internal::IsGarbageCollectedMixinTypeV, + static_assert(!IsGarbageCollectedMixinTypeV, "Mixin types do not support compaction."); HandleMovableReference(reinterpret_cast(slot)); } diff --git a/deps/include/js_protocol.pdl b/deps/include/js_protocol.pdl index 6971edd5..42470d88 100644 --- a/deps/include/js_protocol.pdl +++ b/deps/include/js_protocol.pdl @@ -211,21 +211,6 @@ domain Debugger # Exception details. optional Runtime.ExceptionDetails exceptionDetails - # Execute a Wasm Evaluator module on a given call frame. - experimental command executeWasmEvaluator - parameters - # WebAssembly call frame identifier to evaluate on. - CallFrameId callFrameId - # Code of the evaluator module. - binary evaluator - # Terminate execution after timing out (number of milliseconds). - experimental optional Runtime.TimeDelta timeout - returns - # Object wrapper for the evaluation result. - Runtime.RemoteObject result - # Exception details. - optional Runtime.ExceptionDetails exceptionDetails - # Returns possible locations for breakpoint. scriptId in start and end range locations should be # the same. command getPossibleBreakpoints @@ -508,6 +493,7 @@ domain Debugger enum reason ambiguous assert + CSPViolation debugCommand DOM EventListener @@ -1022,8 +1008,9 @@ domain Runtime boolean symbol bigint - wasm - # Object subtype hint. Specified for `object` or `wasm` type values only. + # Object subtype hint. Specified for `object` type values only. + # NOTE: If you change anything here, make sure to also update + # `subtype` in `ObjectPreview` and `PropertyPreview` below. optional enum subtype array null @@ -1042,12 +1029,7 @@ domain Runtime typedarray arraybuffer dataview - i32 - i64 - f32 - f64 - v128 - externref + webassemblymemory # Object class (constructor) name. Specified for `object` type values only. optional string className # Remote object value in case of primitive values or JSON values (if it was requested). @@ -1100,6 +1082,12 @@ domain Runtime iterator generator error + proxy + promise + typedarray + arraybuffer + dataview + webassemblymemory # String representation of the object. optional string description # True iff some of the properties or entries of the original object did not fit. @@ -1142,6 +1130,12 @@ domain Runtime iterator generator error + proxy + promise + typedarray + arraybuffer + dataview + webassemblymemory experimental type EntryPreview extends object properties @@ -1224,6 +1218,10 @@ domain Runtime string origin # Human readable name describing given context. string name + # A system-unique execution context identifier. Unlike the id, this is unique accross + # multiple processes, so can be reliably used to identify specific context while backend + # performs a cross-process navigation. + experimental string uniqueId # Embedder-specific auxiliary data. optional object auxData @@ -1387,6 +1385,9 @@ domain Runtime optional boolean silent # Specifies in which execution context to perform evaluation. If the parameter is omitted the # evaluation will be performed in the context of the inspected page. + # This is mutually exclusive with `uniqueContextId`, which offers an + # alternative way to identify the execution context that is more reliable + # in a multi-process environment. optional ExecutionContextId contextId # Whether the result is expected to be a JSON object that should be sent by value. optional boolean returnByValue @@ -1413,6 +1414,13 @@ domain Runtime # when called with non-callable arguments. This flag bypasses CSP for this # evaluation and allows unsafe-eval. Defaults to true. experimental optional boolean allowUnsafeEvalBlockedByCSP + # An alternative way to specify the execution context to evaluate in. + # Compared to contextId that may be reused accross processes, this is guaranteed to be + # system-unique, so it can be used to prevent accidental evaluation of the expression + # in context different than intended (e.g. as a result of navigation accross process + # boundaries). + # This is mutually exclusive with `contextId`. + experimental optional string uniqueContextId returns # Evaluation result. RemoteObject result diff --git a/deps/include/libplatform/libplatform.h b/deps/include/libplatform/libplatform.h index 1c874ba2..00de81df 100644 --- a/deps/include/libplatform/libplatform.h +++ b/deps/include/libplatform/libplatform.h @@ -43,6 +43,17 @@ V8_PLATFORM_EXPORT std::unique_ptr NewDefaultPlatform( InProcessStackDumping::kDisabled, std::unique_ptr tracing_controller = {}); +/** + * The same as NewDefaultPlatform but disables the worker thread pool. + * It must be used with the --single-threaded V8 flag. + */ +V8_PLATFORM_EXPORT std::unique_ptr +NewSingleThreadedDefaultPlatform( + IdleTaskSupport idle_task_support = IdleTaskSupport::kDisabled, + InProcessStackDumping in_process_stack_dumping = + InProcessStackDumping::kDisabled, + std::unique_ptr tracing_controller = {}); + /** * Returns a new instance of the default v8::JobHandle implementation. * diff --git a/deps/include/libplatform/v8-tracing.h b/deps/include/libplatform/v8-tracing.h index 45822d00..c7a5c4f9 100644 --- a/deps/include/libplatform/v8-tracing.h +++ b/deps/include/libplatform/v8-tracing.h @@ -125,6 +125,8 @@ class V8_PLATFORM_EXPORT TraceWriter { static TraceWriter* CreateJSONTraceWriter(std::ostream& stream, const std::string& tag); + static TraceWriter* CreateSystemInstrumentationTraceWriter(); + private: // Disallow copy and assign TraceWriter(const TraceWriter&) = delete; diff --git a/deps/include/v8-cppgc.h b/deps/include/v8-cppgc.h index 805eb015..8a0d9cb9 100644 --- a/deps/include/v8-cppgc.h +++ b/deps/include/v8-cppgc.h @@ -5,12 +5,55 @@ #ifndef INCLUDE_V8_CPPGC_H_ #define INCLUDE_V8_CPPGC_H_ +#include +#include + +#include "cppgc/custom-space.h" +#include "cppgc/internal/write-barrier.h" #include "cppgc/visitor.h" #include "v8-internal.h" // NOLINT(build/include_directory) -#include "v8.h" // NOLINT(build/include_directory) +#include "v8.h" // NOLINT(build/include_directory) + +namespace cppgc { +class AllocationHandle; +class HeapHandle; +} // namespace cppgc namespace v8 { +namespace internal { +class CppHeap; +} // namespace internal + +struct V8_EXPORT CppHeapCreateParams { + std::vector> custom_spaces; +}; + +/** + * A heap for allocating managed C++ objects. + */ +class V8_EXPORT CppHeap { + public: + virtual ~CppHeap() = default; + + /** + * \returns the opaque handle for allocating objects using + * `MakeGarbageCollected()`. + */ + cppgc::AllocationHandle& GetAllocationHandle(); + + /** + * \returns the opaque heap handle which may be used to refer to this heap in + * other APIs. Valid as long as the underlying `CppHeap` is alive. + */ + cppgc::HeapHandle& GetHeapHandle(); + + private: + CppHeap() = default; + + friend class internal::CppHeap; +}; + class JSVisitor : public cppgc::Visitor { public: explicit JSVisitor(cppgc::Visitor::Key key) : cppgc::Visitor(key) {} @@ -26,6 +69,64 @@ class JSVisitor : public cppgc::Visitor { virtual void Visit(const TracedReferenceBase& ref) {} }; +/** + * **DO NOT USE: Use the appropriate managed types.** + * + * Consistency helpers that aid in maintaining a consistent internal state of + * the garbage collector. + */ +class JSHeapConsistency final { + public: + using WriteBarrierParams = cppgc::internal::WriteBarrier::Params; + using WriteBarrierType = cppgc::internal::WriteBarrier::Type; + + /** + * Gets the required write barrier type for a specific write. + * + * \param ref The reference being written to. + * \param params Parameters that may be used for actual write barrier calls. + * Only filled if return value indicates that a write barrier is needed. The + * contents of the `params` are an implementation detail. + * \returns whether a write barrier is needed and which barrier to invoke. + */ + static V8_INLINE WriteBarrierType GetWriteBarrierType( + const TracedReferenceBase& ref, WriteBarrierParams& params) { + if (ref.IsEmpty()) return WriteBarrierType::kNone; + return cppgc::internal::WriteBarrier::GetWriteBarrierType(&ref, params); + } + + /** + * Conservative Dijkstra-style write barrier that processes an object if it + * has not yet been processed. + * + * \param params The parameters retrieved from `GetWriteBarrierType()`. + * \param ref The reference being written to. + */ + static V8_INLINE void DijkstraMarkingBarrier(const WriteBarrierParams& params, + cppgc::HeapHandle& heap_handle, + const TracedReferenceBase& ref) { + cppgc::internal::WriteBarrier::CheckParams(WriteBarrierType::kMarking, + params); + DijkstraMarkingBarrierSlow(heap_handle, ref); + } + + /** + * Generational barrier for maintaining consistency when running with multiple + * generations. + * + * \param params The parameters retrieved from `GetWriteBarrierType()`. + * \param ref The reference being written to. + */ + static V8_INLINE void GenerationalBarrier(const WriteBarrierParams& params, + const TracedReferenceBase& ref) {} + + private: + JSHeapConsistency() = delete; + + static void DijkstraMarkingBarrierSlow(cppgc::HeapHandle&, + const TracedReferenceBase& ref); +}; + } // namespace v8 namespace cppgc { diff --git a/deps/include/v8-inspector.h b/deps/include/v8-inspector.h index 86fcf518..a55518e4 100644 --- a/deps/include/v8-inspector.h +++ b/deps/include/v8-inspector.h @@ -106,6 +106,7 @@ class V8_EXPORT V8StackTrace { virtual int topLineNumber() const = 0; virtual int topColumnNumber() const = 0; virtual StringView topScriptId() const = 0; + virtual int topScriptIdAsInteger() const = 0; virtual StringView topFunctionName() const = 0; virtual ~V8StackTrace() = default; @@ -228,6 +229,10 @@ class V8_EXPORT V8InspectorClient { const StringView& resourceName) { return nullptr; } + + // The caller would defer to generating a random 64 bit integer if + // this method returns 0. + virtual int64_t generateUniqueId() { return 0; } }; // These stack trace ids are intended to be passed between debuggers and be diff --git a/deps/include/v8-internal.h b/deps/include/v8-internal.h index 06846d70..8abbcfb4 100644 --- a/deps/include/v8-internal.h +++ b/deps/include/v8-internal.h @@ -207,8 +207,10 @@ class Internals { kNumIsolateDataSlots * kApiSystemPointerSize; static const int kIsolateFastCCallCallerPcOffset = kIsolateFastCCallCallerFpOffset + kApiSystemPointerSize; - static const int kIsolateStackGuardOffset = + static const int kIsolateFastApiCallTargetOffset = kIsolateFastCCallCallerPcOffset + kApiSystemPointerSize; + static const int kIsolateStackGuardOffset = + kIsolateFastApiCallTargetOffset + kApiSystemPointerSize; static const int kIsolateRootsOffset = kIsolateStackGuardOffset + 7 * kApiSystemPointerSize; diff --git a/deps/include/v8-metrics.h b/deps/include/v8-metrics.h index 69784dcb..1e2bd50a 100644 --- a/deps/include/v8-metrics.h +++ b/deps/include/v8-metrics.h @@ -10,14 +10,12 @@ namespace v8 { namespace metrics { -// TODO(sartang@microsoft.com): Remove wall_clock_time_in_us. struct WasmModuleDecoded { bool async = false; bool streamed = false; bool success = false; size_t module_size_in_bytes = 0; size_t function_count = 0; - int64_t wall_clock_time_in_us = -1; int64_t wall_clock_duration_in_us = -1; }; @@ -30,7 +28,6 @@ struct WasmModuleCompiled { bool success = false; size_t code_size_in_bytes = 0; size_t liftoff_bailout_count = 0; - int64_t wall_clock_time_in_us = -1; int64_t wall_clock_duration_in_us = -1; }; @@ -38,14 +35,12 @@ struct WasmModuleInstantiated { bool async = false; bool success = false; size_t imported_function_count = 0; - int64_t wall_clock_time_in_us = -1; int64_t wall_clock_duration_in_us = -1; }; struct WasmModuleTieredUp { bool lazy = false; size_t code_size_in_bytes = 0; - int64_t wall_clock_time_in_us = -1; int64_t wall_clock_duration_in_us = -1; }; diff --git a/deps/include/v8-platform.h b/deps/include/v8-platform.h index 1f1497f6..e27d26cb 100644 --- a/deps/include/v8-platform.h +++ b/deps/include/v8-platform.h @@ -225,22 +225,24 @@ class JobHandle { virtual void CancelAndDetach() { Cancel(); } /** - * Returns true if there's currently no work pending and no worker running. - * TODO(etiennep): Deprecate IsCompleted in favor of IsActive once implemented - * by all embedders. + * Returns true if there's any work pending or any worker running. */ - virtual bool IsCompleted() = 0; - virtual bool IsActive() { return !IsCompleted(); } + virtual bool IsActive() = 0; + + // TODO(etiennep): Clean up once all overrides are removed. + V8_DEPRECATED("Use !IsActive() instead.") + virtual bool IsCompleted() { return !IsActive(); } /** * Returns true if associated with a Job and other methods may be called. * Returns false after Join() or Cancel() was called. This may return true * even if no workers are running and IsCompleted() returns true - * TODO(etiennep): Deprecate IsRunning in favor of IsValid once implemented by - * all embedders. */ - virtual bool IsRunning() = 0; - virtual bool IsValid() { return IsRunning(); } + virtual bool IsValid() = 0; + + // TODO(etiennep): Clean up once all overrides are removed. + V8_DEPRECATED("Use IsValid() instead.") + virtual bool IsRunning() { return IsValid(); } /** * Returns true if job priority can be changed. diff --git a/deps/include/v8-version.h b/deps/include/v8-version.h index 138614a8..32669970 100644 --- a/deps/include/v8-version.h +++ b/deps/include/v8-version.h @@ -9,9 +9,9 @@ // NOTE these macros are used by some of the tool scripts and the build // system so their names cannot be changed without changing the scripts. #define V8_MAJOR_VERSION 8 -#define V8_MINOR_VERSION 8 -#define V8_BUILD_NUMBER 278 -#define V8_PATCH_LEVEL 14 +#define V8_MINOR_VERSION 9 +#define V8_BUILD_NUMBER 255 +#define V8_PATCH_LEVEL 20 // Use 1 for candidates and 0 otherwise. // (Boolean macro values are not supported by all preprocessors.) diff --git a/deps/include/v8.h b/deps/include/v8.h index 83517820..e9235d17 100644 --- a/deps/include/v8.h +++ b/deps/include/v8.h @@ -48,6 +48,8 @@ class Boolean; class BooleanObject; class CFunction; class Context; +class CppHeap; +struct CppHeapCreateParams; class Data; class Date; class External; @@ -89,6 +91,7 @@ class Private; class Uint32; class Utils; class Value; +class WasmMemoryObject; class WasmModuleObject; template class Local; template @@ -433,7 +436,7 @@ static const int kEmbedderFieldsInWeakCallback = 2; template class WeakCallbackInfo { public: - typedef void (*Callback)(const WeakCallbackInfo& data); + using Callback = void (*)(const WeakCallbackInfo& data); WeakCallbackInfo(Isolate* isolate, T* parameter, void* embedder_fields[kEmbedderFieldsInWeakCallback], @@ -627,7 +630,7 @@ template class PersistentBase { template class NonCopyablePersistentTraits { public: - typedef Persistent > NonCopyablePersistent; + using NonCopyablePersistent = Persistent>; static const bool kResetInDestructor = false; template V8_INLINE static void Copy(const Persistent& source, @@ -644,7 +647,7 @@ class NonCopyablePersistentTraits { */ template struct CopyablePersistentTraits { - typedef Persistent > CopyablePersistent; + using CopyablePersistent = Persistent>; static const bool kResetInDestructor = true; template static V8_INLINE void Copy(const Persistent& source, @@ -806,7 +809,7 @@ class Global : public PersistentBase { /* * For compatibility with Chromium's base::Bind (base::Passed). */ - typedef void MoveOnlyTypeForCPP03; + using MoveOnlyTypeForCPP03 = void; Global(const Global&) = delete; void operator=(const Global&) = delete; @@ -1195,7 +1198,7 @@ class TracedReference : public BasicTracedReference { * handle and may deallocate it. The behavior of accessing a handle * for which the handle scope has been deleted is undefined. */ -class V8_EXPORT HandleScope { +class V8_EXPORT V8_NODISCARD HandleScope { public: explicit HandleScope(Isolate* isolate); @@ -1242,12 +1245,11 @@ class V8_EXPORT HandleScope { friend class Context; }; - /** * A HandleScope which first allocates a handle in the current scope * which will be later filled with the escape value. */ -class V8_EXPORT EscapableHandleScope : public HandleScope { +class V8_EXPORT V8_NODISCARD EscapableHandleScope : public HandleScope { public: explicit EscapableHandleScope(Isolate* isolate); V8_INLINE ~EscapableHandleScope() = default; @@ -1288,7 +1290,7 @@ class V8_EXPORT EscapableHandleScope : public HandleScope { * are allowed. It can be useful for debugging handle leaks. * Handles can be allocated within inner normal HandleScopes. */ -class V8_EXPORT SealHandleScope { +class V8_EXPORT V8_NODISCARD SealHandleScope { public: explicit SealHandleScope(Isolate* isolate); ~SealHandleScope(); @@ -1309,7 +1311,6 @@ class V8_EXPORT SealHandleScope { int prev_sealed_level_; }; - // --- Special objects --- /** @@ -1422,10 +1423,10 @@ class ScriptOriginOptions { */ class ScriptOrigin { public: - V8_INLINE ScriptOrigin( - Local resource_name, - Local resource_line_offset = Local(), - Local resource_column_offset = Local(), + V8_DEPRECATE_SOON("Use constructor with primitvie C++ types") + V8_INLINE explicit ScriptOrigin( + Local resource_name, Local resource_line_offset, + Local resource_column_offset, Local resource_is_shared_cross_origin = Local(), Local script_id = Local(), Local source_map_url = Local(), @@ -1433,21 +1434,36 @@ class ScriptOrigin { Local is_wasm = Local(), Local is_module = Local(), Local host_defined_options = Local()); + V8_INLINE explicit ScriptOrigin( + Local resource_name, int resource_line_offset = 0, + int resource_column_offset = 0, + bool resource_is_shared_cross_origin = false, int script_id = -1, + Local source_map_url = Local(), + bool resource_is_opaque = false, bool is_wasm = false, + bool is_module = false, + Local host_defined_options = Local()); V8_INLINE Local ResourceName() const; + V8_DEPRECATE_SOON("Use getter with primitvie C++ types.") V8_INLINE Local ResourceLineOffset() const; + V8_DEPRECATE_SOON("Use getter with primitvie C++ types.") V8_INLINE Local ResourceColumnOffset() const; + V8_DEPRECATE_SOON("Use getter with primitvie C++ types.") V8_INLINE Local ScriptID() const; + V8_INLINE int LineOffset() const; + V8_INLINE int ColumnOffset() const; + V8_INLINE int ScriptId() const; V8_INLINE Local SourceMapUrl() const; V8_INLINE Local HostDefinedOptions() const; V8_INLINE ScriptOriginOptions Options() const { return options_; } private: + Isolate* isolate_; Local resource_name_; - Local resource_line_offset_; - Local resource_column_offset_; + int resource_line_offset_; + int resource_column_offset_; ScriptOriginOptions options_; - Local script_id_; + int script_id_; Local source_map_url_; Local host_defined_options_; }; @@ -1506,6 +1522,43 @@ class V8_EXPORT Location { int column_number_; }; +/** + * A fixed-sized array with elements of type Data. + */ +class V8_EXPORT FixedArray : public Data { + public: + int Length() const; + Local Get(Local context, int i) const; +}; + +class V8_EXPORT ModuleRequest : public Data { + public: + /** + * Returns the module specifier for this ModuleRequest. + */ + Local GetSpecifier() const; + + /** + * Returns the source code offset of this module request. + * Use Module::SourceOffsetToLocation to convert this to line/column numbers. + */ + int GetSourceOffset() const; + + /** + * Contains the import assertions for this request in the form: + * [key1, value1, source_offset1, key2, value2, source_offset2, ...]. + * The keys and values are of type v8::String, and the source offsets are of + * type Int32. Use Module::SourceOffsetToLocation to convert the source + * offsets to Locations with line/column numbers. + */ + Local GetImportAssertions() const; + + V8_INLINE static ModuleRequest* Cast(Data* data); + + private: + static void CheckCast(Data* obj); +}; + /** * A compiled JavaScript module. */ @@ -1540,28 +1593,48 @@ class V8_EXPORT Module : public Data { /** * Returns the number of modules requested by this module. */ + V8_DEPRECATE_SOON("Use Module::GetModuleRequests() and FixedArray::Length().") int GetModuleRequestsLength() const; /** * Returns the ith module specifier in this module. * i must be < GetModuleRequestsLength() and >= 0. */ + V8_DEPRECATE_SOON( + "Use Module::GetModuleRequests() and ModuleRequest::GetSpecifier().") Local GetModuleRequest(int i) const; /** * Returns the source location (line number and column number) of the ith * module specifier's first occurrence in this module. */ + V8_DEPRECATE_SOON( + "Use Module::GetModuleRequests(), ModuleRequest::GetSourceOffset(), and " + "Module::SourceOffsetToLocation().") Location GetModuleRequestLocation(int i) const; + /** + * Returns the ModuleRequests for this module. + */ + Local GetModuleRequests() const; + + /** + * For the given source text offset in this module, returns the corresponding + * Location with line and column numbers. + */ + Location SourceOffsetToLocation(int offset) const; + /** * Returns the identity hash for this object. */ int GetIdentityHash() const; - typedef MaybeLocal (*ResolveCallback)(Local context, - Local specifier, - Local referrer); + using ResolveCallback V8_DEPRECATE_SOON("Use ResolveModuleCallback") = + MaybeLocal (*)(Local context, Local specifier, + Local referrer); + using ResolveModuleCallback = MaybeLocal (*)( + Local context, Local specifier, + Local import_assertions, Local referrer); /** * Instantiates the module and its dependencies. @@ -1570,8 +1643,13 @@ class V8_EXPORT Module : public Data { * instantiation. (In the case where the callback throws an exception, that * exception is propagated.) */ + V8_DEPRECATE_SOON( + "Use the version of InstantiateModule that takes a ResolveModuleCallback " + "parameter") V8_WARN_UNUSED_RESULT Maybe InstantiateModule(Local context, ResolveCallback callback); + V8_WARN_UNUSED_RESULT Maybe InstantiateModule( + Local context, ResolveModuleCallback callback); /** * Evaluates the module and its dependencies. @@ -1630,8 +1708,8 @@ class V8_EXPORT Module : public Data { * exception was thrown) and return an empy MaybeLocal to indicate falure * (where an exception was thrown). */ - typedef MaybeLocal (*SyntheticModuleEvaluationSteps)( - Local context, Local module); + using SyntheticModuleEvaluationSteps = + MaybeLocal (*)(Local context, Local module); /** * Creates a new SyntheticModule with the specified export names, where @@ -1654,7 +1732,7 @@ class V8_EXPORT Module : public Data { */ V8_WARN_UNUSED_RESULT Maybe SetSyntheticModuleExport( Isolate* isolate, Local export_name, Local export_value); - V8_DEPRECATE_SOON( + V8_DEPRECATED( "Use the preceding SetSyntheticModuleExport with an Isolate parameter, " "instead of the one that follows. The former will throw a runtime " "error if called for an export that doesn't exist (as per spec); " @@ -1694,6 +1772,7 @@ class V8_EXPORT Script { Local GetUnboundScript(); }; +enum class ScriptType { kClassic, kModule }; /** * For compiling scripts. @@ -1746,8 +1825,8 @@ class V8_EXPORT ScriptCompiler { // Source takes ownership of CachedData. V8_INLINE Source(Local source_string, const ScriptOrigin& origin, CachedData* cached_data = nullptr); - V8_INLINE Source(Local source_string, - CachedData* cached_data = nullptr); + V8_INLINE explicit Source(Local source_string, + CachedData* cached_data = nullptr); V8_INLINE ~Source(); // Ownership of the CachedData or its buffers is *not* transferred to the @@ -1768,8 +1847,8 @@ class V8_EXPORT ScriptCompiler { // Origin information Local resource_name; - Local resource_line_offset; - Local resource_column_offset; + int resource_line_offset; + int resource_column_offset; ScriptOriginOptions resource_options; Local source_map_url; Local host_defined_options; @@ -1839,7 +1918,7 @@ class V8_EXPORT ScriptCompiler { public: enum Encoding { ONE_BYTE, TWO_BYTE, UTF8 }; - V8_DEPRECATE_SOON( + V8_DEPRECATED( "This class takes ownership of source_stream, so use the constructor " "taking a unique_ptr to make these semantics clearer") StreamedSource(ExternalSourceStream* source_stream, Encoding encoding); @@ -1946,12 +2025,13 @@ class V8_EXPORT ScriptCompiler { * This API allows to start the streaming with as little data as possible, and * the remaining data (for example, the ScriptOrigin) is passed to Compile. */ - V8_DEPRECATE_SOON("Use ScriptCompiler::StartStreamingScript instead.") + V8_DEPRECATED("Use ScriptCompiler::StartStreaming instead.") static ScriptStreamingTask* StartStreamingScript( Isolate* isolate, StreamedSource* source, CompileOptions options = kNoCompileOptions); - static ScriptStreamingTask* StartStreaming(Isolate* isolate, - StreamedSource* source); + static ScriptStreamingTask* StartStreaming( + Isolate* isolate, StreamedSource* source, + ScriptType type = ScriptType::kClassic); /** * Compiles a streamed script (bound to current context). @@ -1996,6 +2076,17 @@ class V8_EXPORT ScriptCompiler { CompileOptions options = kNoCompileOptions, NoCacheReason no_cache_reason = kNoCacheNoReason); + /** + * Compiles a streamed module script. + * + * This can only be called after the streaming has finished + * (ScriptStreamingTask has been run). V8 doesn't construct the source string + * during streaming, so the embedder needs to pass the full source here. + */ + static V8_WARN_UNUSED_RESULT MaybeLocal CompileModule( + Local context, StreamedSource* v8_source, + Local full_source_string, const ScriptOrigin& origin); + /** * Compile a function for a given context. This is equivalent to running * @@ -2871,6 +2962,11 @@ class V8_EXPORT Value : public Data { */ bool IsProxy() const; + /** + * Returns true if this value is a WasmMemoryObject. + */ + bool IsWasmMemoryObject() const; + /** * Returns true if this value is a WasmModuleObject. */ @@ -2993,11 +3089,11 @@ class V8_EXPORT Primitive : public Value { }; class V8_EXPORT Boolean : public Primitive { public: bool Value() const; - V8_INLINE static Boolean* Cast(v8::Value* obj); + V8_INLINE static Boolean* Cast(v8::Data* data); V8_INLINE static Local New(Isolate* isolate, bool value); private: - static void CheckCast(v8::Value* obj); + static void CheckCast(v8::Data* that); }; @@ -3015,10 +3111,10 @@ class V8_EXPORT Name : public Primitive { */ int GetIdentityHash(); - V8_INLINE static Name* Cast(Value* obj); + V8_INLINE static Name* Cast(Data* data); private: - static void CheckCast(Value* obj); + static void CheckCast(Data* that); }; /** @@ -3131,14 +3227,6 @@ class V8_EXPORT String : public Name { */ V8_INLINE static Local Empty(Isolate* isolate); - /** - * Returns true if the string is external two-byte. - * - */ - V8_DEPRECATED( - "Use String::IsExternalTwoByte() or String::IsExternalOneByte()") - bool IsExternal() const; - /** * Returns true if the string is both external and two-byte. */ @@ -3274,7 +3362,7 @@ class V8_EXPORT String : public Name { */ const ExternalOneByteStringResource* GetExternalOneByteStringResource() const; - V8_INLINE static String* Cast(v8::Value* obj); + V8_INLINE static String* Cast(v8::Data* data); /** * Allocates a new string from a UTF-8 literal. This is equivalent to calling @@ -3431,7 +3519,7 @@ class V8_EXPORT String : public Name { const char* literal, NewStringType type, int length); - static void CheckCast(v8::Value* obj); + static void CheckCast(v8::Data* that); }; // Zero-length string specialization (templated string size includes @@ -3452,7 +3540,7 @@ class V8_EXPORT Symbol : public Name { */ Local Description() const; - V8_DEPRECATE_SOON("Use Symbol::Description()") + V8_DEPRECATED("Use Symbol::Description()") Local Name() const { return Description(); } /** @@ -3491,11 +3579,11 @@ class V8_EXPORT Symbol : public Name { static Local GetToStringTag(Isolate* isolate); static Local GetUnscopables(Isolate* isolate); - V8_INLINE static Symbol* Cast(Value* obj); + V8_INLINE static Symbol* Cast(Data* data); private: Symbol(); - static void CheckCast(Value* obj); + static void CheckCast(Data* that); }; @@ -3544,10 +3632,11 @@ class V8_EXPORT Number : public Primitive { public: double Value() const; static Local New(Isolate* isolate, double value); - V8_INLINE static Number* Cast(v8::Value* obj); + V8_INLINE static Number* Cast(v8::Data* data); + private: Number(); - static void CheckCast(v8::Value* obj); + static void CheckCast(v8::Data* that); }; @@ -3559,10 +3648,11 @@ class V8_EXPORT Integer : public Number { static Local New(Isolate* isolate, int32_t value); static Local NewFromUnsigned(Isolate* isolate, uint32_t value); int64_t Value() const; - V8_INLINE static Integer* Cast(v8::Value* obj); + V8_INLINE static Integer* Cast(v8::Data* data); + private: Integer(); - static void CheckCast(v8::Value* obj); + static void CheckCast(v8::Data* that); }; @@ -3572,11 +3662,11 @@ class V8_EXPORT Integer : public Number { class V8_EXPORT Int32 : public Integer { public: int32_t Value() const; - V8_INLINE static Int32* Cast(v8::Value* obj); + V8_INLINE static Int32* Cast(v8::Data* data); private: Int32(); - static void CheckCast(v8::Value* obj); + static void CheckCast(v8::Data* that); }; @@ -3586,11 +3676,11 @@ class V8_EXPORT Int32 : public Integer { class V8_EXPORT Uint32 : public Integer { public: uint32_t Value() const; - V8_INLINE static Uint32* Cast(v8::Value* obj); + V8_INLINE static Uint32* Cast(v8::Data* data); private: Uint32(); - static void CheckCast(v8::Value* obj); + static void CheckCast(v8::Data* that); }; /** @@ -3641,11 +3731,11 @@ class V8_EXPORT BigInt : public Primitive { */ void ToWordsArray(int* sign_bit, int* word_count, uint64_t* words) const; - V8_INLINE static BigInt* Cast(v8::Value* obj); + V8_INLINE static BigInt* Cast(v8::Data* data); private: BigInt(); - static void CheckCast(v8::Value* obj); + static void CheckCast(v8::Data* that); }; /** @@ -3667,23 +3757,17 @@ enum PropertyAttribute { * setting|getting a particular property. See Object and ObjectTemplate's * method SetAccessor. */ -typedef void (*AccessorGetterCallback)( - Local property, - const PropertyCallbackInfo& info); -typedef void (*AccessorNameGetterCallback)( - Local property, - const PropertyCallbackInfo& info); - - -typedef void (*AccessorSetterCallback)( - Local property, - Local value, - const PropertyCallbackInfo& info); -typedef void (*AccessorNameSetterCallback)( - Local property, - Local value, - const PropertyCallbackInfo& info); +using AccessorGetterCallback = + void (*)(Local property, const PropertyCallbackInfo& info); +using AccessorNameGetterCallback = + void (*)(Local property, const PropertyCallbackInfo& info); +using AccessorSetterCallback = void (*)(Local property, + Local value, + const PropertyCallbackInfo& info); +using AccessorNameSetterCallback = + void (*)(Local property, Local value, + const PropertyCallbackInfo& info); /** * Access control specifications. @@ -4535,8 +4619,7 @@ class PropertyCallbackInfo { internal::Address* args_; }; - -typedef void (*FunctionCallback)(const FunctionCallbackInfo& info); +using FunctionCallback = void (*)(const FunctionCallbackInfo& info); enum class ConstructorBehavior { kThrow, kAllow }; @@ -4897,6 +4980,22 @@ class V8_EXPORT CompiledWasmModule { const std::string source_url_; }; +// An instance of WebAssembly.Memory. +class V8_EXPORT WasmMemoryObject : public Object { + public: + WasmMemoryObject() = delete; + + /** + * Returns underlying ArrayBuffer. + */ + Local Buffer(); + + V8_INLINE static WasmMemoryObject* Cast(Value* obj); + + private: + static void CheckCast(Value* object); +}; + // An instance of WebAssembly.Module. class V8_EXPORT WasmModuleObject : public Object { public: @@ -6237,8 +6336,8 @@ class V8_EXPORT Template : public Data { * * See also `ObjectTemplate::SetHandler`. */ -typedef void (*GenericNamedPropertyGetterCallback)( - Local property, const PropertyCallbackInfo& info); +using GenericNamedPropertyGetterCallback = + void (*)(Local property, const PropertyCallbackInfo& info); /** * Interceptor for set requests on an object. @@ -6261,9 +6360,9 @@ typedef void (*GenericNamedPropertyGetterCallback)( * See also * `ObjectTemplate::SetHandler.` */ -typedef void (*GenericNamedPropertySetterCallback)( - Local property, Local value, - const PropertyCallbackInfo& info); +using GenericNamedPropertySetterCallback = + void (*)(Local property, Local value, + const PropertyCallbackInfo& info); /** * Intercepts all requests that query the attributes of the @@ -6286,8 +6385,8 @@ typedef void (*GenericNamedPropertySetterCallback)( * See also * `ObjectTemplate::SetHandler.` */ -typedef void (*GenericNamedPropertyQueryCallback)( - Local property, const PropertyCallbackInfo& info); +using GenericNamedPropertyQueryCallback = + void (*)(Local property, const PropertyCallbackInfo& info); /** * Interceptor for delete requests on an object. @@ -6310,8 +6409,8 @@ typedef void (*GenericNamedPropertyQueryCallback)( * * See also `ObjectTemplate::SetHandler.` */ -typedef void (*GenericNamedPropertyDeleterCallback)( - Local property, const PropertyCallbackInfo& info); +using GenericNamedPropertyDeleterCallback = + void (*)(Local property, const PropertyCallbackInfo& info); /** * Returns an array containing the names of the properties the named @@ -6319,8 +6418,8 @@ typedef void (*GenericNamedPropertyDeleterCallback)( * * Note: The values in the array must be of type v8::Name. */ -typedef void (*GenericNamedPropertyEnumeratorCallback)( - const PropertyCallbackInfo& info); +using GenericNamedPropertyEnumeratorCallback = + void (*)(const PropertyCallbackInfo& info); /** * Interceptor for defineProperty requests on an object. @@ -6342,9 +6441,9 @@ typedef void (*GenericNamedPropertyEnumeratorCallback)( * * See also `ObjectTemplate::SetHandler`. */ -typedef void (*GenericNamedPropertyDefinerCallback)( - Local property, const PropertyDescriptor& desc, - const PropertyCallbackInfo& info); +using GenericNamedPropertyDefinerCallback = + void (*)(Local property, const PropertyDescriptor& desc, + const PropertyCallbackInfo& info); /** * Interceptor for getOwnPropertyDescriptor requests on an object. @@ -6365,37 +6464,33 @@ typedef void (*GenericNamedPropertyDefinerCallback)( * * See also `ObjectTemplate::SetHandler`. */ -typedef void (*GenericNamedPropertyDescriptorCallback)( - Local property, const PropertyCallbackInfo& info); +using GenericNamedPropertyDescriptorCallback = + void (*)(Local property, const PropertyCallbackInfo& info); /** * See `v8::GenericNamedPropertyGetterCallback`. */ -typedef void (*IndexedPropertyGetterCallback)( - uint32_t index, - const PropertyCallbackInfo& info); +using IndexedPropertyGetterCallback = + void (*)(uint32_t index, const PropertyCallbackInfo& info); /** * See `v8::GenericNamedPropertySetterCallback`. */ -typedef void (*IndexedPropertySetterCallback)( - uint32_t index, - Local value, - const PropertyCallbackInfo& info); +using IndexedPropertySetterCallback = + void (*)(uint32_t index, Local value, + const PropertyCallbackInfo& info); /** * See `v8::GenericNamedPropertyQueryCallback`. */ -typedef void (*IndexedPropertyQueryCallback)( - uint32_t index, - const PropertyCallbackInfo& info); +using IndexedPropertyQueryCallback = + void (*)(uint32_t index, const PropertyCallbackInfo& info); /** * See `v8::GenericNamedPropertyDeleterCallback`. */ -typedef void (*IndexedPropertyDeleterCallback)( - uint32_t index, - const PropertyCallbackInfo& info); +using IndexedPropertyDeleterCallback = + void (*)(uint32_t index, const PropertyCallbackInfo& info); /** * Returns an array containing the indices of the properties the indexed @@ -6403,21 +6498,21 @@ typedef void (*IndexedPropertyDeleterCallback)( * * Note: The values in the array must be uint32_t. */ -typedef void (*IndexedPropertyEnumeratorCallback)( - const PropertyCallbackInfo& info); +using IndexedPropertyEnumeratorCallback = + void (*)(const PropertyCallbackInfo& info); /** * See `v8::GenericNamedPropertyDefinerCallback`. */ -typedef void (*IndexedPropertyDefinerCallback)( - uint32_t index, const PropertyDescriptor& desc, - const PropertyCallbackInfo& info); +using IndexedPropertyDefinerCallback = + void (*)(uint32_t index, const PropertyDescriptor& desc, + const PropertyCallbackInfo& info); /** * See `v8::GenericNamedPropertyDescriptorCallback`. */ -typedef void (*IndexedPropertyDescriptorCallback)( - uint32_t index, const PropertyCallbackInfo& info); +using IndexedPropertyDescriptorCallback = + void (*)(uint32_t index, const PropertyCallbackInfo& info); /** * Access type specification. @@ -6435,9 +6530,9 @@ enum AccessType { * Returns true if the given context should be allowed to access the given * object. */ -typedef bool (*AccessCheckCallback)(Local accessing_context, - Local accessed_object, - Local data); +using AccessCheckCallback = bool (*)(Local accessing_context, + Local accessed_object, + Local data); /** * A FunctionTemplate is used to create functions at runtime. There @@ -7228,36 +7323,11 @@ class V8_EXPORT ResourceConstraints { initial_young_generation_size_ = initial_size; } - /** - * Deprecated functions. Do not use in new code. - */ - V8_DEPRECATED("Use code_range_size_in_bytes.") - size_t code_range_size() const { return code_range_size_ / kMB; } - V8_DEPRECATED("Use set_code_range_size_in_bytes.") - void set_code_range_size(size_t limit_in_mb) { - code_range_size_ = limit_in_mb * kMB; - } - V8_DEPRECATED("Use max_young_generation_size_in_bytes.") - size_t max_semi_space_size_in_kb() const; - V8_DEPRECATED("Use set_max_young_generation_size_in_bytes.") - void set_max_semi_space_size_in_kb(size_t limit_in_kb); - V8_DEPRECATED("Use max_old_generation_size_in_bytes.") - size_t max_old_space_size() const { return max_old_generation_size_ / kMB; } - V8_DEPRECATED("Use set_max_old_generation_size_in_bytes.") - void set_max_old_space_size(size_t limit_in_mb) { - max_old_generation_size_ = limit_in_mb * kMB; - } - V8_DEPRECATED("Zone does not pool memory any more.") - size_t max_zone_pool_size() const { return max_zone_pool_size_; } - V8_DEPRECATED("Zone does not pool memory any more.") - void set_max_zone_pool_size(size_t bytes) { max_zone_pool_size_ = bytes; } - private: static constexpr size_t kMB = 1048576u; size_t code_range_size_ = 0; size_t max_old_generation_size_ = 0; size_t max_young_generation_size_ = 0; - size_t max_zone_pool_size_ = 0; size_t initial_old_generation_size_ = 0; size_t initial_young_generation_size_ = 0; uint32_t* stack_limit_ = nullptr; @@ -7266,19 +7336,18 @@ class V8_EXPORT ResourceConstraints { // --- Exceptions --- +using FatalErrorCallback = void (*)(const char* location, const char* message); -typedef void (*FatalErrorCallback)(const char* location, const char* message); +using OOMErrorCallback = void (*)(const char* location, bool is_heap_oom); -typedef void (*OOMErrorCallback)(const char* location, bool is_heap_oom); +using DcheckErrorCallback = void (*)(const char* file, int line, + const char* message); -typedef void (*DcheckErrorCallback)(const char* file, int line, - const char* message); - -typedef void (*MessageCallback)(Local message, Local data); +using MessageCallback = void (*)(Local message, Local data); // --- Tracing --- -typedef void (*LogEventCallback)(const char* name, int event); +using LogEventCallback = void (*)(const char* name, int event); /** * Create new error objects by calling the corresponding error object @@ -7312,14 +7381,12 @@ class V8_EXPORT Exception { // --- Counters Callbacks --- -typedef int* (*CounterLookupCallback)(const char* name); +using CounterLookupCallback = int* (*)(const char* name); -typedef void* (*CreateHistogramCallback)(const char* name, - int min, - int max, - size_t buckets); +using CreateHistogramCallback = void* (*)(const char* name, int min, int max, + size_t buckets); -typedef void (*AddHistogramSampleCallback)(void* histogram, int sample); +using AddHistogramSampleCallback = void (*)(void* histogram, int sample); // --- Crashkeys Callback --- enum class CrashKeyId { @@ -7330,11 +7397,11 @@ enum class CrashKeyId { kDumpType, }; -typedef void (*AddCrashKeyCallback)(CrashKeyId id, const std::string& value); +using AddCrashKeyCallback = void (*)(CrashKeyId id, const std::string& value); // --- Enter/Leave Script Callback --- -typedef void (*BeforeCallEnteredCallback)(Isolate*); -typedef void (*CallCompletedCallback)(Isolate*); +using BeforeCallEnteredCallback = void (*)(Isolate*); +using CallCompletedCallback = void (*)(Isolate*); /** * HostImportModuleDynamicallyCallback is called when we require the @@ -7356,7 +7423,7 @@ typedef void (*CallCompletedCallback)(Isolate*); * fails (e.g. due to stack overflow), the embedder must propagate * that exception by returning an empty MaybeLocal. */ -typedef MaybeLocal (*HostImportModuleDynamicallyCallback)( +using HostImportModuleDynamicallyCallback = MaybeLocal (*)( Local context, Local referrer, Local specifier); @@ -7370,9 +7437,9 @@ typedef MaybeLocal (*HostImportModuleDynamicallyCallback)( * The embedder should use v8::Object::CreateDataProperty to add properties on * the meta object. */ -typedef void (*HostInitializeImportMetaObjectCallback)(Local context, - Local module, - Local meta); +using HostInitializeImportMetaObjectCallback = void (*)(Local context, + Local module, + Local meta); /** * PrepareStackTraceCallback is called when the stack property of an error is @@ -7381,9 +7448,9 @@ typedef void (*HostInitializeImportMetaObjectCallback)(Local context, * |sites| is an array of call sites, specified in * https://v8.dev/docs/stack-trace-api */ -typedef MaybeLocal (*PrepareStackTraceCallback)(Local context, - Local error, - Local sites); +using PrepareStackTraceCallback = MaybeLocal (*)(Local context, + Local error, + Local sites); /** * PromiseHook with type kInit is called when a new promise is @@ -7403,8 +7470,8 @@ typedef MaybeLocal (*PrepareStackTraceCallback)(Local context, */ enum class PromiseHookType { kInit, kResolve, kBefore, kAfter }; -typedef void (*PromiseHook)(PromiseHookType type, Local promise, - Local parent); +using PromiseHook = void (*)(PromiseHookType type, Local promise, + Local parent); // --- Promise Reject Callback --- enum PromiseRejectEvent { @@ -7430,13 +7497,11 @@ class PromiseRejectMessage { Local value_; }; -typedef void (*PromiseRejectCallback)(PromiseRejectMessage message); +using PromiseRejectCallback = void (*)(PromiseRejectMessage message); // --- Microtasks Callbacks --- -V8_DEPRECATED("Use *WithData version.") -typedef void (*MicrotasksCompletedCallback)(Isolate*); -typedef void (*MicrotasksCompletedCallbackWithData)(Isolate*, void*); -typedef void (*MicrotaskCallback)(void* data); +using MicrotasksCompletedCallbackWithData = void (*)(Isolate*, void*); +using MicrotaskCallback = void (*)(void* data); /** * Policy for running microtasks: @@ -7540,7 +7605,7 @@ class V8_EXPORT MicrotaskQueue { * kDoNotRunMicrotasks should be used to annotate calls not intended to trigger * microtasks. */ -class V8_EXPORT MicrotasksScope { +class V8_EXPORT V8_NODISCARD MicrotasksScope { public: enum Type { kRunMicrotasks, kDoNotRunMicrotasks }; @@ -7573,11 +7638,9 @@ class V8_EXPORT MicrotasksScope { bool run_; }; - // --- Failed Access Check Callback --- -typedef void (*FailedAccessCheckCallback)(Local target, - AccessType type, - Local data); +using FailedAccessCheckCallback = void (*)(Local target, + AccessType type, Local data); // --- AllowCodeGenerationFromStrings callbacks --- @@ -7585,8 +7648,8 @@ typedef void (*FailedAccessCheckCallback)(Local target, * Callback to check if code generation from strings is allowed. See * Context::AllowCodeGenerationFromStrings. */ -typedef bool (*AllowCodeGenerationFromStringsCallback)(Local context, - Local source); +using AllowCodeGenerationFromStringsCallback = bool (*)(Local context, + Local source); struct ModifyCodeGenerationFromStringsResult { // If true, proceed with the codegen algorithm. Otherwise, block it. @@ -7601,36 +7664,36 @@ struct ModifyCodeGenerationFromStringsResult { * Callback to check if codegen is allowed from a source object, and convert * the source to string if necessary. See: ModifyCodeGenerationFromStrings. */ -typedef ModifyCodeGenerationFromStringsResult ( - *ModifyCodeGenerationFromStringsCallback)(Local context, +using ModifyCodeGenerationFromStringsCallback = + ModifyCodeGenerationFromStringsResult (*)(Local context, Local source); -typedef ModifyCodeGenerationFromStringsResult ( - *ModifyCodeGenerationFromStringsCallback2)(Local context, - Local source, - bool is_code_like); +using ModifyCodeGenerationFromStringsCallback2 = + ModifyCodeGenerationFromStringsResult (*)(Local context, + Local source, + bool is_code_like); // --- WebAssembly compilation callbacks --- -typedef bool (*ExtensionCallback)(const FunctionCallbackInfo&); +using ExtensionCallback = bool (*)(const FunctionCallbackInfo&); -typedef bool (*AllowWasmCodeGenerationCallback)(Local context, - Local source); +using AllowWasmCodeGenerationCallback = bool (*)(Local context, + Local source); // --- Callback for APIs defined on v8-supported objects, but implemented // by the embedder. Example: WebAssembly.{compile|instantiate}Streaming --- -typedef void (*ApiImplementationCallback)(const FunctionCallbackInfo&); +using ApiImplementationCallback = void (*)(const FunctionCallbackInfo&); // --- Callback for WebAssembly.compileStreaming --- -typedef void (*WasmStreamingCallback)(const FunctionCallbackInfo&); +using WasmStreamingCallback = void (*)(const FunctionCallbackInfo&); // --- Callback for checking if WebAssembly threads are enabled --- -typedef bool (*WasmThreadsEnabledCallback)(Local context); +using WasmThreadsEnabledCallback = bool (*)(Local context); // --- Callback for loading source map file for Wasm profiling support -typedef Local (*WasmLoadSourceMapCallback)(Isolate* isolate, - const char* name); +using WasmLoadSourceMapCallback = Local (*)(Isolate* isolate, + const char* name); // --- Callback for checking if WebAssembly Simd is enabled --- -typedef bool (*WasmSimdEnabledCallback)(Local context); +using WasmSimdEnabledCallback = bool (*)(Local context); // --- Garbage Collection Callbacks --- @@ -7674,9 +7737,9 @@ enum GCCallbackFlags { kGCCallbackScheduleIdleGarbageCollection = 1 << 6, }; -typedef void (*GCCallback)(GCType type, GCCallbackFlags flags); +using GCCallback = void (*)(GCType type, GCCallbackFlags flags); -typedef void (*InterruptCallback)(Isolate* isolate, void* data); +using InterruptCallback = void (*)(Isolate* isolate, void* data); /** * This callback is invoked when the heap size is close to the heap limit and @@ -7685,8 +7748,8 @@ typedef void (*InterruptCallback)(Isolate* isolate, void* data); * than the current_heap_limit. The initial heap limit is the limit that was * set after heap setup. */ -typedef size_t (*NearHeapLimitCallback)(void* data, size_t current_heap_limit, - size_t initial_heap_limit); +using NearHeapLimitCallback = size_t (*)(void* data, size_t current_heap_limit, + size_t initial_heap_limit); /** * Collection of shared per-process V8 memory information. @@ -7940,14 +8003,14 @@ enum JitCodeEventOptions { * * \param event code add, move or removal event. */ -typedef void (*JitCodeEventHandler)(const JitCodeEvent* event); +using JitCodeEventHandler = void (*)(const JitCodeEvent* event); /** * Callback function passed to SetUnhandledExceptionCallback. */ #if defined(V8_OS_WIN) -typedef int (*UnhandledExceptionCallback)( - _EXCEPTION_POINTERS* exception_pointers); +using UnhandledExceptionCallback = + int (*)(_EXCEPTION_POINTERS* exception_pointers); #endif /** @@ -8174,8 +8237,8 @@ class V8_EXPORT EmbedderHeapTracer { * serialized verbatim. */ struct SerializeInternalFieldsCallback { - typedef StartupData (*CallbackFunction)(Local holder, int index, - void* data); + using CallbackFunction = StartupData (*)(Local holder, int index, + void* data); SerializeInternalFieldsCallback(CallbackFunction function = nullptr, void* data_arg = nullptr) : callback(function), data(data_arg) {} @@ -8184,15 +8247,15 @@ struct SerializeInternalFieldsCallback { }; // Note that these fields are called "internal fields" in the API and called // "embedder fields" within V8. -typedef SerializeInternalFieldsCallback SerializeEmbedderFieldsCallback; +using SerializeEmbedderFieldsCallback = SerializeInternalFieldsCallback; /** * Callback and supporting data used to implement embedder logic to deserialize * internal fields. */ struct DeserializeInternalFieldsCallback { - typedef void (*CallbackFunction)(Local holder, int index, - StartupData payload, void* data); + using CallbackFunction = void (*)(Local holder, int index, + StartupData payload, void* data); DeserializeInternalFieldsCallback(CallbackFunction function = nullptr, void* data_arg = nullptr) : callback(function), data(data_arg) {} @@ -8200,7 +8263,7 @@ struct DeserializeInternalFieldsCallback { void* data); void* data; }; -typedef DeserializeInternalFieldsCallback DeserializeEmbedderFieldsCallback; +using DeserializeEmbedderFieldsCallback = DeserializeInternalFieldsCallback; /** * Controls how the default MeasureMemoryDelegate reports the result of @@ -8276,26 +8339,15 @@ class V8_EXPORT Isolate { /** * Initial configuration parameters for a new Isolate. */ - struct CreateParams { - CreateParams() - : code_event_handler(nullptr), - snapshot_blob(nullptr), - counter_lookup_callback(nullptr), - create_histogram_callback(nullptr), - add_histogram_sample_callback(nullptr), - array_buffer_allocator(nullptr), - array_buffer_allocator_shared(), - external_references(nullptr), - allow_atomics_wait(true), - only_terminate_in_safe_scope(false), - embedder_wrapper_type_index(-1), - embedder_wrapper_object_index(-1) {} + struct V8_EXPORT CreateParams { + CreateParams(); + ~CreateParams(); /** * Allows the host application to provide the address of a function that is * notified each time code is added, moved or removed. */ - JitCodeEventHandler code_event_handler; + JitCodeEventHandler code_event_handler = nullptr; /** * ResourceConstraints to use for the new Isolate. @@ -8305,14 +8357,13 @@ class V8_EXPORT Isolate { /** * Explicitly specify a startup snapshot blob. The embedder owns the blob. */ - StartupData* snapshot_blob; - + StartupData* snapshot_blob = nullptr; /** * Enables the host application to provide a mechanism for recording * statistics counters. */ - CounterLookupCallback counter_lookup_callback; + CounterLookupCallback counter_lookup_callback = nullptr; /** * Enables the host application to provide a mechanism for recording @@ -8320,8 +8371,8 @@ class V8_EXPORT Isolate { * histogram which will later be passed to the AddHistogramSample * function. */ - CreateHistogramCallback create_histogram_callback; - AddHistogramSampleCallback add_histogram_sample_callback; + CreateHistogramCallback create_histogram_callback = nullptr; + AddHistogramSampleCallback add_histogram_sample_callback = nullptr; /** * The ArrayBuffer::Allocator to use for allocating and freeing the backing @@ -8332,7 +8383,7 @@ class V8_EXPORT Isolate { * to the allocator, in order to facilitate lifetime * management for the allocator instance. */ - ArrayBuffer::Allocator* array_buffer_allocator; + ArrayBuffer::Allocator* array_buffer_allocator = nullptr; std::shared_ptr array_buffer_allocator_shared; /** @@ -8341,34 +8392,57 @@ class V8_EXPORT Isolate { * deserialization. This array and its content must stay valid for the * entire lifetime of the isolate. */ - const intptr_t* external_references; + const intptr_t* external_references = nullptr; /** * Whether calling Atomics.wait (a function that may block) is allowed in * this isolate. This can also be configured via SetAllowAtomicsWait. */ - bool allow_atomics_wait; + bool allow_atomics_wait = true; /** * Termination is postponed when there is no active SafeForTerminationScope. */ - bool only_terminate_in_safe_scope; + bool only_terminate_in_safe_scope = false; /** * The following parameters describe the offsets for addressing type info * for wrapped API objects and are used by the fast C API * (for details see v8-fast-api-calls.h). */ - int embedder_wrapper_type_index; - int embedder_wrapper_object_index; - }; + int embedder_wrapper_type_index = -1; + int embedder_wrapper_object_index = -1; + + /** + * If parameters are set, V8 creates a managed C++ heap as extension to its + * JavaScript heap. + * + * See v8::Isolate::GetCppHeap() for working with the heap. + * + * This is an experimental feature and may still change significantly. + */ + std::shared_ptr cpp_heap_params; + /** + * This list is provided by the embedder to indicate which import assertions + * they want to handle. Only import assertions whose keys are present in + * supported_import_assertions will be included in the import assertions + * lists of ModuleRequests that will be passed to the embedder. If + * supported_import_assertions is left empty, then the embedder will not + * receive any import assertions. + * + * This corresponds to the list returned by the HostGetSupportedAssertions + * host-defined abstract operation: + * https://tc39.es/proposal-import-assertions/#sec-hostgetsupportedimportassertions + */ + std::vector supported_import_assertions; + }; /** * Stack-allocated class which sets the isolate for all operations * executed within a local scope. */ - class V8_EXPORT Scope { + class V8_EXPORT V8_NODISCARD Scope { public: explicit Scope(Isolate* isolate) : isolate_(isolate) { isolate->Enter(); @@ -8384,11 +8458,10 @@ class V8_EXPORT Isolate { Isolate* const isolate_; }; - /** * Assert that no Javascript code is invoked. */ - class V8_EXPORT DisallowJavascriptExecutionScope { + class V8_EXPORT V8_NODISCARD DisallowJavascriptExecutionScope { public: enum OnFailure { CRASH_ON_FAILURE, THROW_ON_FAILURE, DUMP_ON_FAILURE }; @@ -8406,11 +8479,10 @@ class V8_EXPORT Isolate { void* internal_; }; - /** * Introduce exception to DisallowJavascriptExecutionScope. */ - class V8_EXPORT AllowJavascriptExecutionScope { + class V8_EXPORT V8_NODISCARD AllowJavascriptExecutionScope { public: explicit AllowJavascriptExecutionScope(Isolate* isolate); ~AllowJavascriptExecutionScope(); @@ -8431,7 +8503,7 @@ class V8_EXPORT Isolate { * Do not run microtasks while this scope is active, even if microtasks are * automatically executed otherwise. */ - class V8_EXPORT SuppressMicrotaskExecutionScope { + class V8_EXPORT V8_NODISCARD SuppressMicrotaskExecutionScope { public: explicit SuppressMicrotaskExecutionScope( Isolate* isolate, MicrotaskQueue* microtask_queue = nullptr); @@ -8455,7 +8527,7 @@ class V8_EXPORT Isolate { * This scope allows terminations inside direct V8 API calls and forbid them * inside any recursive API calls without explicit SafeForTerminationScope. */ - class V8_EXPORT SafeForTerminationScope { + class V8_EXPORT V8_NODISCARD SafeForTerminationScope { public: explicit SafeForTerminationScope(v8::Isolate* isolate); ~SafeForTerminationScope(); @@ -8612,8 +8684,8 @@ class V8_EXPORT Isolate { kMessageWarning, }; - typedef void (*UseCounterCallback)(Isolate* isolate, - UseCounterFeature feature); + using UseCounterCallback = void (*)(Isolate* isolate, + UseCounterFeature feature); /** * Allocates a new isolate but does not initialize it. Does not change the @@ -8679,7 +8751,7 @@ class V8_EXPORT Isolate { * - the custom callback set returns true. * Otherwise, the custom callback will not be called and V8 will not abort. */ - typedef bool (*AbortOnUncaughtExceptionCallback)(Isolate*); + using AbortOnUncaughtExceptionCallback = bool (*)(Isolate*); void SetAbortOnUncaughtExceptionCallback( AbortOnUncaughtExceptionCallback callback); @@ -8843,7 +8915,7 @@ class V8_EXPORT Isolate { std::unique_ptr delegate, MeasureMemoryExecution execution = MeasureMemoryExecution::kDefault); - V8_DEPRECATE_SOON("Use the version with a delegate") + V8_DEPRECATED("Use the version with a delegate") MaybeLocal MeasureMemory(Local context, MeasureMemoryMode mode); @@ -8906,10 +8978,6 @@ class V8_EXPORT Isolate { */ Local GetCurrentContext(); - /** Returns the last context entered through V8's C++ API. */ - V8_DEPRECATED("Use GetEnteredOrMicrotaskContext().") - Local GetEnteredContext(); - /** * Returns either the last context entered through V8's C++ API, or the * context of the currently running microtask while processing microtasks. @@ -8932,10 +9000,10 @@ class V8_EXPORT Isolate { */ Local ThrowException(Local exception); - typedef void (*GCCallback)(Isolate* isolate, GCType type, - GCCallbackFlags flags); - typedef void (*GCCallbackWithData)(Isolate* isolate, GCType type, - GCCallbackFlags flags, void* data); + using GCCallback = void (*)(Isolate* isolate, GCType type, + GCCallbackFlags flags); + using GCCallbackWithData = void (*)(Isolate* isolate, GCType type, + GCCallbackFlags flags, void* data); /** * Enables the host application to receive a notification before a @@ -8968,6 +9036,12 @@ class V8_EXPORT Isolate { */ EmbedderHeapTracer* GetEmbedderHeapTracer(); + /** + * \returns the C++ heap managed by V8. Only available if the Isolate was + * created with proper CreatePrams::cpp_heap_params option. + */ + CppHeap* GetCppHeap() const; + /** * Use for |AtomicsWaitCallback| to indicate the type of event it receives. */ @@ -9032,12 +9106,12 @@ class V8_EXPORT Isolate { * This callback may schedule exceptions, *unless* |event| is equal to * |kTerminatedExecution|. */ - typedef void (*AtomicsWaitCallback)(AtomicsWaitEvent event, - Local array_buffer, - size_t offset_in_bytes, int64_t value, - double timeout_in_ms, - AtomicsWaitWakeHandle* stop_handle, - void* data); + using AtomicsWaitCallback = void (*)(AtomicsWaitEvent event, + Local array_buffer, + size_t offset_in_bytes, int64_t value, + double timeout_in_ms, + AtomicsWaitWakeHandle* stop_handle, + void* data); /** * Set a new |AtomicsWaitCallback|. This overrides an earlier @@ -9069,7 +9143,7 @@ class V8_EXPORT Isolate { void* data = nullptr); void RemoveGCEpilogueCallback(GCCallback callback); - typedef size_t (*GetExternallyAllocatedMemoryInBytesCallback)(); + using GetExternallyAllocatedMemoryInBytesCallback = size_t (*)(); /** * Set the callback that tells V8 how much memory is currently allocated @@ -9188,12 +9262,6 @@ class V8_EXPORT Isolate { */ void SetPromiseRejectCallback(PromiseRejectCallback callback); - /** - * An alias for PerformMicrotaskCheckpoint. - */ - V8_DEPRECATED("Use PerformMicrotaskCheckpoint.") - void RunMicrotasks() { PerformMicrotaskCheckpoint(); } - /** * Runs the default MicrotaskQueue until it gets empty and perform other * microtask checkpoint steps, such as calling ClearKeptObjects. Asserts that @@ -9235,16 +9303,12 @@ class V8_EXPORT Isolate { * Executing scripts inside the callback will not re-trigger microtasks and * the callback. */ - V8_DEPRECATED("Use *WithData version.") - void AddMicrotasksCompletedCallback(MicrotasksCompletedCallback callback); void AddMicrotasksCompletedCallback( MicrotasksCompletedCallbackWithData callback, void* data = nullptr); /** * Removes callback that was installed by AddMicrotasksCompletedCallback. */ - V8_DEPRECATED("Use *WithData version.") - void RemoveMicrotasksCompletedCallback(MicrotasksCompletedCallback callback); void RemoveMicrotasksCompletedCallback( MicrotasksCompletedCallbackWithData callback, void* data = nullptr); @@ -9487,11 +9551,6 @@ class V8_EXPORT Isolate { * strings should be allowed. */ V8_DEPRECATED( - "Use Isolate::SetModifyCodeGenerationFromStringsCallback instead. " - "See http://crbug.com/v8/10096.") - void SetAllowCodeGenerationFromStringsCallback( - AllowCodeGenerationFromStringsCallback callback); - V8_DEPRECATE_SOON( "Use Isolate::SetModifyCodeGenerationFromStringsCallback with " "ModifyCodeGenerationFromStringsCallback2 instead. See " "http://crbug.com/1096017 and TC39 Dynamic Code Brand Checks proposal " @@ -9685,7 +9744,7 @@ class V8_EXPORT StartupData { * EntropySource is used as a callback function when v8 needs a source * of entropy. */ -typedef bool (*EntropySource)(unsigned char* buffer, size_t length); +using EntropySource = bool (*)(unsigned char* buffer, size_t length); /** * ReturnAddressLocationResolver is used as a callback function when v8 is @@ -9700,9 +9759,8 @@ typedef bool (*EntropySource)(unsigned char* buffer, size_t length); * * \note The resolver function must not cause garbage collection. */ -typedef uintptr_t (*ReturnAddressLocationResolver)( - uintptr_t return_addr_location); - +using ReturnAddressLocationResolver = + uintptr_t (*)(uintptr_t return_addr_location); /** * Container class for static utility functions. @@ -9856,7 +9914,7 @@ class V8_EXPORT V8 { * \param context The third argument passed to the Linux signal handler, which * points to a ucontext_t structure. */ - V8_DEPRECATE_SOON("Use TryHandleWebAssemblyTrapPosix") + V8_DEPRECATED("Use TryHandleWebAssemblyTrapPosix") static bool TryHandleSignal(int signal_number, void* info, void* context); #endif // V8_OS_POSIX @@ -10493,9 +10551,12 @@ class V8_EXPORT Context { */ void Exit(); - /** Returns an isolate associated with a current context. */ + /** Returns the isolate associated with a current context. */ Isolate* GetIsolate(); + /** Returns the microtask queue associated with a current context. */ + MicrotaskQueue* GetMicrotaskQueue(); + /** * The field at kDebugIdIndex used to be reserved for the inspector. * It now serves no purpose. @@ -10584,8 +10645,8 @@ class V8_EXPORT Context { * context, call the specified callback, and throw an exception. * To unset abort, pass nullptr as callback. */ - typedef void (*AbortScriptExecutionCallback)(Isolate* isolate, - Local context); + using AbortScriptExecutionCallback = void (*)(Isolate* isolate, + Local context); void SetAbortScriptExecution(AbortScriptExecutionCallback callback); /** @@ -10604,7 +10665,7 @@ class V8_EXPORT Context { * Stack-allocated class which sets the execution context for all * operations executed within a local scope. */ - class Scope { + class V8_NODISCARD Scope { public: explicit V8_INLINE Scope(Local context) : context_(context) { context_->Enter(); @@ -10620,7 +10681,7 @@ class V8_EXPORT Context { * stack. * https://html.spec.whatwg.org/multipage/webappapis.html#backup-incumbent-settings-object-stack */ - class V8_EXPORT BackupIncumbentScope final { + class V8_EXPORT V8_NODISCARD BackupIncumbentScope final { public: /** * |backup_incumbent_context| is pushed onto the backup incumbent settings @@ -10921,7 +10982,7 @@ void Persistent::Copy(const Persistent& that) { template bool PersistentBase::IsWeak() const { - typedef internal::Internals I; + using I = internal::Internals; if (this->IsEmpty()) return false; return I::GetNodeState(reinterpret_cast(this->val_)) == I::kNodeStateIsWeakValue; @@ -10962,7 +11023,7 @@ template V8_INLINE void PersistentBase::SetWeak( P* parameter, typename WeakCallbackInfo

::Callback callback, WeakCallbackType type) { - typedef typename WeakCallbackInfo::Callback Callback; + using Callback = WeakCallbackInfo::Callback; #if (__GNUC__ >= 8) && !defined(__clang__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-function-type" @@ -10994,7 +11055,7 @@ void PersistentBase::AnnotateStrongRetainer(const char* label) { template void PersistentBase::SetWrapperClassId(uint16_t class_id) { - typedef internal::Internals I; + using I = internal::Internals; if (this->IsEmpty()) return; internal::Address* obj = reinterpret_cast(this->val_); uint8_t* addr = reinterpret_cast(obj) + I::kNodeClassIdOffset; @@ -11004,7 +11065,7 @@ void PersistentBase::SetWrapperClassId(uint16_t class_id) { template uint16_t PersistentBase::WrapperClassId() const { - typedef internal::Internals I; + using I = internal::Internals; if (this->IsEmpty()) return 0; internal::Address* obj = reinterpret_cast(this->val_); uint8_t* addr = reinterpret_cast(obj) + I::kNodeClassIdOffset; @@ -11202,7 +11263,7 @@ TracedReference& TracedReference::operator=(const TracedReference& rhs) { } void TracedReferenceBase::SetWrapperClassId(uint16_t class_id) { - typedef internal::Internals I; + using I = internal::Internals; if (IsEmpty()) return; internal::Address* obj = reinterpret_cast(val_); uint8_t* addr = reinterpret_cast(obj) + I::kNodeClassIdOffset; @@ -11210,7 +11271,7 @@ void TracedReferenceBase::SetWrapperClassId(uint16_t class_id) { } uint16_t TracedReferenceBase::WrapperClassId() const { - typedef internal::Internals I; + using I = internal::Internals; if (IsEmpty()) return 0; internal::Address* obj = reinterpret_cast(val_); uint8_t* addr = reinterpret_cast(obj) + I::kNodeClassIdOffset; @@ -11270,7 +11331,7 @@ void ReturnValue::Set(double i) { template void ReturnValue::Set(int32_t i) { static_assert(std::is_base_of::value, "type check"); - typedef internal::Internals I; + using I = internal::Internals; if (V8_LIKELY(I::IsValidSmi(i))) { *value_ = I::IntToSmi(i); return; @@ -11293,7 +11354,7 @@ void ReturnValue::Set(uint32_t i) { template void ReturnValue::Set(bool value) { static_assert(std::is_base_of::value, "type check"); - typedef internal::Internals I; + using I = internal::Internals; int root_index; if (value) { root_index = I::kTrueValueRootIndex; @@ -11306,21 +11367,21 @@ void ReturnValue::Set(bool value) { template void ReturnValue::SetNull() { static_assert(std::is_base_of::value, "type check"); - typedef internal::Internals I; + using I = internal::Internals; *value_ = *I::GetRoot(GetIsolate(), I::kNullValueRootIndex); } template void ReturnValue::SetUndefined() { static_assert(std::is_base_of::value, "type check"); - typedef internal::Internals I; + using I = internal::Internals; *value_ = *I::GetRoot(GetIsolate(), I::kUndefinedValueRootIndex); } template void ReturnValue::SetEmptyString() { static_assert(std::is_base_of::value, "type check"); - typedef internal::Internals I; + using I = internal::Internals; *value_ = *I::GetRoot(GetIsolate(), I::kEmptyStringRootIndex); } @@ -11332,7 +11393,7 @@ Isolate* ReturnValue::GetIsolate() const { template Local ReturnValue::Get() const { - typedef internal::Internals I; + using I = internal::Internals; if (*value_ == *I::GetRoot(GetIsolate(), I::kTheHoleValueRootIndex)) return Local(*Undefined(GetIsolate())); return Local::New(GetIsolate(), reinterpret_cast(value_)); @@ -11412,23 +11473,33 @@ int FunctionCallbackInfo::Length() const { return length_; } -ScriptOrigin::ScriptOrigin(Local resource_name, - Local resource_line_offset, - Local resource_column_offset, - Local resource_is_shared_cross_origin, - Local script_id, - Local source_map_url, - Local resource_is_opaque, - Local is_wasm, Local is_module, +ScriptOrigin::ScriptOrigin( + Local resource_name, Local line_offset, + Local column_offset, Local is_shared_cross_origin, + Local script_id, Local source_map_url, + Local is_opaque, Local is_wasm, Local is_module, + Local host_defined_options) + : ScriptOrigin( + resource_name, + line_offset.IsEmpty() ? 0 : static_cast(line_offset->Value()), + column_offset.IsEmpty() ? 0 + : static_cast(column_offset->Value()), + !is_shared_cross_origin.IsEmpty() && is_shared_cross_origin->IsTrue(), + static_cast(script_id.IsEmpty() ? -1 : script_id->Value()), + source_map_url, !is_opaque.IsEmpty() && is_opaque->IsTrue(), + !is_wasm.IsEmpty() && is_wasm->IsTrue(), + !is_module.IsEmpty() && is_module->IsTrue(), host_defined_options) {} + +ScriptOrigin::ScriptOrigin(Local resource_name, int line_offset, + int column_offset, bool is_shared_cross_origin, + int script_id, Local source_map_url, + bool is_opaque, bool is_wasm, bool is_module, Local host_defined_options) - : resource_name_(resource_name), - resource_line_offset_(resource_line_offset), - resource_column_offset_(resource_column_offset), - options_(!resource_is_shared_cross_origin.IsEmpty() && - resource_is_shared_cross_origin->IsTrue(), - !resource_is_opaque.IsEmpty() && resource_is_opaque->IsTrue(), - !is_wasm.IsEmpty() && is_wasm->IsTrue(), - !is_module.IsEmpty() && is_module->IsTrue()), + : isolate_(Isolate::GetCurrent()), + resource_name_(resource_name), + resource_line_offset_(line_offset), + resource_column_offset_(column_offset), + options_(is_shared_cross_origin, is_opaque, is_wasm, is_module), script_id_(script_id), source_map_url_(source_map_url), host_defined_options_(host_defined_options) {} @@ -11440,17 +11511,22 @@ Local ScriptOrigin::HostDefinedOptions() const { } Local ScriptOrigin::ResourceLineOffset() const { - return resource_line_offset_; + return v8::Integer::New(isolate_, resource_line_offset_); } - Local ScriptOrigin::ResourceColumnOffset() const { - return resource_column_offset_; + return v8::Integer::New(isolate_, resource_column_offset_); +} + +Local ScriptOrigin::ScriptID() const { + return v8::Integer::New(isolate_, script_id_); } +int ScriptOrigin::LineOffset() const { return resource_line_offset_; } -Local ScriptOrigin::ScriptID() const { return script_id_; } +int ScriptOrigin::ColumnOffset() const { return resource_column_offset_; } +int ScriptOrigin::ScriptId() const { return script_id_; } Local ScriptOrigin::SourceMapUrl() const { return source_map_url_; } @@ -11458,8 +11534,8 @@ ScriptCompiler::Source::Source(Local string, const ScriptOrigin& origin, CachedData* data) : source_string(string), resource_name(origin.ResourceName()), - resource_line_offset(origin.ResourceLineOffset()), - resource_column_offset(origin.ResourceColumnOffset()), + resource_line_offset(origin.LineOffset()), + resource_column_offset(origin.ColumnOffset()), resource_options(origin.Options()), source_map_url(origin.SourceMapUrl()), host_defined_options(origin.HostDefinedOptions()), @@ -11524,8 +11600,8 @@ AccessorSignature* AccessorSignature::Cast(Data* data) { Local Object::GetInternalField(int index) { #ifndef V8_ENABLE_CHECKS - typedef internal::Address A; - typedef internal::Internals I; + using A = internal::Address; + using I = internal::Internals; A obj = *reinterpret_cast(this); // Fast path: If the object is a plain JSObject, which is the common case, we // know where to find the internal fields and can return the value directly. @@ -11552,8 +11628,8 @@ Local Object::GetInternalField(int index) { void* Object::GetAlignedPointerFromInternalField(int index) { #ifndef V8_ENABLE_CHECKS - typedef internal::Address A; - typedef internal::Internals I; + using A = internal::Address; + using I = internal::Internals; A obj = *reinterpret_cast(this); // Fast path: If the object is a plain JSObject, which is the common case, we // know where to find the internal fields and can return the value directly. @@ -11574,17 +11650,16 @@ void* Object::GetAlignedPointerFromInternalField(int index) { return SlowGetAlignedPointerFromInternalField(index); } -String* String::Cast(v8::Value* value) { +String* String::Cast(v8::Data* data) { #ifdef V8_ENABLE_CHECKS - CheckCast(value); + CheckCast(data); #endif - return static_cast(value); + return static_cast(data); } - Local String::Empty(Isolate* isolate) { - typedef internal::Address S; - typedef internal::Internals I; + using S = internal::Address; + using I = internal::Internals; I::CheckInitialized(isolate); S* slot = I::GetRoot(isolate, I::kEmptyStringRootIndex); return Local(reinterpret_cast(slot)); @@ -11592,8 +11667,8 @@ Local String::Empty(Isolate* isolate) { String::ExternalStringResource* String::GetExternalStringResource() const { - typedef internal::Address A; - typedef internal::Internals I; + using A = internal::Address; + using I = internal::Internals; A obj = *reinterpret_cast(this); ExternalStringResource* result; @@ -11615,8 +11690,8 @@ String::ExternalStringResource* String::GetExternalStringResource() const { String::ExternalStringResourceBase* String::GetExternalStringResourceBase( String::Encoding* encoding_out) const { - typedef internal::Address A; - typedef internal::Internals I; + using A = internal::Address; + using I = internal::Internals; A obj = *reinterpret_cast(this); int type = I::GetInstanceType(obj) & I::kFullStringRepresentationMask; *encoding_out = static_cast(type & I::kStringEncodingMask); @@ -11647,8 +11722,8 @@ bool Value::IsUndefined() const { } bool Value::QuickIsUndefined() const { - typedef internal::Address A; - typedef internal::Internals I; + using A = internal::Address; + using I = internal::Internals; A obj = *reinterpret_cast(this); if (!I::HasHeapObjectTag(obj)) return false; if (I::GetInstanceType(obj) != I::kOddballType) return false; @@ -11665,8 +11740,8 @@ bool Value::IsNull() const { } bool Value::QuickIsNull() const { - typedef internal::Address A; - typedef internal::Internals I; + using A = internal::Address; + using I = internal::Internals; A obj = *reinterpret_cast(this); if (!I::HasHeapObjectTag(obj)) return false; if (I::GetInstanceType(obj) != I::kOddballType) return false; @@ -11682,8 +11757,8 @@ bool Value::IsNullOrUndefined() const { } bool Value::QuickIsNullOrUndefined() const { - typedef internal::Address A; - typedef internal::Internals I; + using A = internal::Address; + using I = internal::Internals; A obj = *reinterpret_cast(this); if (!I::HasHeapObjectTag(obj)) return false; if (I::GetInstanceType(obj) != I::kOddballType) return false; @@ -11700,8 +11775,8 @@ bool Value::IsString() const { } bool Value::QuickIsString() const { - typedef internal::Address A; - typedef internal::Internals I; + using A = internal::Address; + using I = internal::Internals; A obj = *reinterpret_cast(this); if (!I::HasHeapObjectTag(obj)) return false; return (I::GetInstanceType(obj) < I::kFirstNonstringType); @@ -11720,30 +11795,27 @@ V8_INLINE Value* Value::Cast(Data* value) { return static_cast(value); } -Boolean* Boolean::Cast(v8::Value* value) { +Boolean* Boolean::Cast(v8::Data* data) { #ifdef V8_ENABLE_CHECKS - CheckCast(value); + CheckCast(data); #endif - return static_cast(value); + return static_cast(data); } - -Name* Name::Cast(v8::Value* value) { +Name* Name::Cast(v8::Data* data) { #ifdef V8_ENABLE_CHECKS - CheckCast(value); + CheckCast(data); #endif - return static_cast(value); + return static_cast(data); } - -Symbol* Symbol::Cast(v8::Value* value) { +Symbol* Symbol::Cast(v8::Data* data) { #ifdef V8_ENABLE_CHECKS - CheckCast(value); + CheckCast(data); #endif - return static_cast(value); + return static_cast(data); } - Private* Private::Cast(Data* data) { #ifdef V8_ENABLE_CHECKS CheckCast(data); @@ -11751,6 +11823,13 @@ Private* Private::Cast(Data* data) { return reinterpret_cast(data); } +ModuleRequest* ModuleRequest::Cast(Data* data) { +#ifdef V8_ENABLE_CHECKS + CheckCast(data); +#endif + return reinterpret_cast(data); +} + Module* Module::Cast(Data* data) { #ifdef V8_ENABLE_CHECKS CheckCast(data); @@ -11758,42 +11837,39 @@ Module* Module::Cast(Data* data) { return reinterpret_cast(data); } -Number* Number::Cast(v8::Value* value) { +Number* Number::Cast(v8::Data* data) { #ifdef V8_ENABLE_CHECKS - CheckCast(value); + CheckCast(data); #endif - return static_cast(value); + return static_cast(data); } - -Integer* Integer::Cast(v8::Value* value) { +Integer* Integer::Cast(v8::Data* data) { #ifdef V8_ENABLE_CHECKS - CheckCast(value); + CheckCast(data); #endif - return static_cast(value); + return static_cast(data); } - -Int32* Int32::Cast(v8::Value* value) { +Int32* Int32::Cast(v8::Data* data) { #ifdef V8_ENABLE_CHECKS - CheckCast(value); + CheckCast(data); #endif - return static_cast(value); + return static_cast(data); } - -Uint32* Uint32::Cast(v8::Value* value) { +Uint32* Uint32::Cast(v8::Data* data) { #ifdef V8_ENABLE_CHECKS - CheckCast(value); + CheckCast(data); #endif - return static_cast(value); + return static_cast(data); } -BigInt* BigInt::Cast(v8::Value* value) { +BigInt* BigInt::Cast(v8::Data* data) { #ifdef V8_ENABLE_CHECKS - CheckCast(value); + CheckCast(data); #endif - return static_cast(value); + return static_cast(data); } Date* Date::Cast(v8::Value* value) { @@ -11897,6 +11973,13 @@ Proxy* Proxy::Cast(v8::Value* value) { return static_cast(value); } +WasmMemoryObject* WasmMemoryObject::Cast(v8::Value* value) { +#ifdef V8_ENABLE_CHECKS + CheckCast(value); +#endif + return static_cast(value); +} + WasmModuleObject* WasmModuleObject::Cast(v8::Value* value) { #ifdef V8_ENABLE_CHECKS CheckCast(value); @@ -12084,7 +12167,7 @@ ReturnValue PropertyCallbackInfo::GetReturnValue() const { template bool PropertyCallbackInfo::ShouldThrowOnError() const { - typedef internal::Internals I; + using I = internal::Internals; if (args_[kShouldThrowOnErrorIndex] != I::IntToSmi(I::kInferShouldThrowMode)) { return args_[kShouldThrowOnErrorIndex] != I::IntToSmi(I::kDontThrow); @@ -12094,8 +12177,8 @@ bool PropertyCallbackInfo::ShouldThrowOnError() const { } Local Undefined(Isolate* isolate) { - typedef internal::Address S; - typedef internal::Internals I; + using S = internal::Address; + using I = internal::Internals; I::CheckInitialized(isolate); S* slot = I::GetRoot(isolate, I::kUndefinedValueRootIndex); return Local(reinterpret_cast(slot)); @@ -12103,8 +12186,8 @@ Local Undefined(Isolate* isolate) { Local Null(Isolate* isolate) { - typedef internal::Address S; - typedef internal::Internals I; + using S = internal::Address; + using I = internal::Internals; I::CheckInitialized(isolate); S* slot = I::GetRoot(isolate, I::kNullValueRootIndex); return Local(reinterpret_cast(slot)); @@ -12112,8 +12195,8 @@ Local Null(Isolate* isolate) { Local True(Isolate* isolate) { - typedef internal::Address S; - typedef internal::Internals I; + using S = internal::Address; + using I = internal::Internals; I::CheckInitialized(isolate); S* slot = I::GetRoot(isolate, I::kTrueValueRootIndex); return Local(reinterpret_cast(slot)); @@ -12121,8 +12204,8 @@ Local True(Isolate* isolate) { Local False(Isolate* isolate) { - typedef internal::Address S; - typedef internal::Internals I; + using S = internal::Address; + using I = internal::Internals; I::CheckInitialized(isolate); S* slot = I::GetRoot(isolate, I::kFalseValueRootIndex); return Local(reinterpret_cast(slot)); @@ -12130,19 +12213,19 @@ Local False(Isolate* isolate) { void Isolate::SetData(uint32_t slot, void* data) { - typedef internal::Internals I; + using I = internal::Internals; I::SetEmbedderData(this, slot, data); } void* Isolate::GetData(uint32_t slot) { - typedef internal::Internals I; + using I = internal::Internals; return I::GetEmbedderData(this, slot); } uint32_t Isolate::GetNumberOfDataSlots() { - typedef internal::Internals I; + using I = internal::Internals; return I::kNumIsolateDataSlots; } @@ -12155,8 +12238,8 @@ MaybeLocal Isolate::GetDataFromSnapshotOnce(size_t index) { Local Context::GetEmbedderData(int index) { #ifndef V8_ENABLE_CHECKS - typedef internal::Address A; - typedef internal::Internals I; + using A = internal::Address; + using I = internal::Internals; A ctx = *reinterpret_cast(this); A embedder_data = I::ReadTaggedPointerField(ctx, I::kNativeContextEmbedderDataOffset); @@ -12181,8 +12264,8 @@ Local Context::GetEmbedderData(int index) { void* Context::GetAlignedPointerFromEmbedderData(int index) { #ifndef V8_ENABLE_CHECKS - typedef internal::Address A; - typedef internal::Internals I; + using A = internal::Address; + using I = internal::Internals; A ctx = *reinterpret_cast(this); A embedder_data = I::ReadTaggedPointerField(ctx, I::kNativeContextEmbedderDataOffset); diff --git a/deps/include/v8config.h b/deps/include/v8config.h index ae89edb2..0886f691 100644 --- a/deps/include/v8config.h +++ b/deps/include/v8config.h @@ -239,6 +239,7 @@ // V8_HAS_ATTRIBUTE_VISIBILITY - __attribute__((visibility)) supported // V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT - __attribute__((warn_unused_result)) // supported +// V8_HAS_CPP_ATTRIBUTE_NODISCARD - [[nodiscard]] supported // V8_HAS_BUILTIN_BSWAP16 - __builtin_bswap16() supported // V8_HAS_BUILTIN_BSWAP32 - __builtin_bswap32() supported // V8_HAS_BUILTIN_BSWAP64 - __builtin_bswap64() supported @@ -262,6 +263,12 @@ // ... // #endif +#if defined(__has_cpp_attribute) +#define V8_HAS_CPP_ATTRIBUTE(FEATURE) __has_cpp_attribute(FEATURE) +#else +#define V8_HAS_CPP_ATTRIBUTE(FEATURE) 0 +#endif + #if defined(__clang__) #if defined(__GNUC__) // Clang in gcc mode. @@ -276,6 +283,8 @@ # define V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT \ (__has_attribute(warn_unused_result)) +# define V8_HAS_CPP_ATTRIBUTE_NODISCARD (V8_HAS_CPP_ATTRIBUTE(nodiscard)) + # define V8_HAS_BUILTIN_ASSUME_ALIGNED (__has_builtin(__builtin_assume_aligned)) # define V8_HAS_BUILTIN_BSWAP16 (__has_builtin(__builtin_bswap16)) # define V8_HAS_BUILTIN_BSWAP32 (__has_builtin(__builtin_bswap32)) @@ -319,6 +328,7 @@ # define V8_HAS_ATTRIBUTE_UNUSED 1 # define V8_HAS_ATTRIBUTE_VISIBILITY 1 # define V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT (!V8_CC_INTEL) +# define V8_HAS_CPP_ATTRIBUTE_NODISCARD (V8_HAS_CPP_ATTRIBUTE(nodiscard)) # define V8_HAS_BUILTIN_ASSUME_ALIGNED 1 # define V8_HAS_BUILTIN_CLZ 1 @@ -436,6 +446,20 @@ #define V8_WARN_UNUSED_RESULT /* NOT SUPPORTED */ #endif + +// Annotate a class or constructor indicating the caller must assign the +// constructed instances. +// Apply to the whole class like: +// class V8_NODISCARD Foo() { ... }; +// or apply to just one constructor like: +// V8_NODISCARD Foo() { ... }; +// [[nodiscard]] comes in C++17 but supported in clang with -std >= c++11. +#if V8_HAS_CPP_ATTRIBUTE_NODISCARD +#define V8_NODISCARD [[nodiscard]] +#else +#define V8_NODISCARD /* NOT SUPPORTED */ +#endif + // Helper macro to define no_sanitize attributes only with clang. #if defined(__clang__) && defined(__has_attribute) #if __has_attribute(no_sanitize) @@ -484,4 +508,6 @@ V8 shared library set USING_V8_SHARED. // clang-format on +#undef V8_HAS_CPP_ATTRIBUTE + #endif // V8CONFIG_H_ diff --git a/deps/linux_x86_64/libv8.a b/deps/linux_x86_64/libv8.a index bc11dea6..a1b88ba6 100644 Binary files a/deps/linux_x86_64/libv8.a and b/deps/linux_x86_64/libv8.a differ diff --git a/deps/v8 b/deps/v8 index e71858f7..6fbcc11c 160000 --- a/deps/v8 +++ b/deps/v8 @@ -1 +1 @@ -Subproject commit e71858f7a080b9bd813876c13be4ce30d993d1d9 +Subproject commit 6fbcc11c530bb348e805f6c5cfcd15c337640dc8