diff --git a/build.rs b/build.rs index 9b8de2d..6270b2a 100644 --- a/build.rs +++ b/build.rs @@ -24,7 +24,7 @@ lazy_static::lazy_static! { static ref PROFILE: String = env::var("PROFILE").expect("PROFILE env var was not given"); - static ref V8_DEFAULT_VERSION: &'static str = "12.3.219.15"; + static ref V8_DEFAULT_VERSION: &'static str = "12.4.254.15"; static ref V8_VERSION: String = env::var("V8_VERSION").map(|v| if v == "default" {V8_DEFAULT_VERSION.to_string()} else {v}).unwrap_or(V8_DEFAULT_VERSION.to_string()); static ref V8_HEADERS_PATH: String = env::var("V8_HEADERS_PATH").unwrap_or("v8_c_api/libv8.include.zip".into()); static ref V8_HEADERS_URL: String = env::var("V8_HEADERS_URL").unwrap_or(format!("http://redismodules.s3.amazonaws.com/redisgears/dependencies/libv8.{}.include.zip", *V8_VERSION)); diff --git a/v8_c_api/src/v8include/v8-context.h b/v8_c_api/src/v8include/v8-context.h index c81dc80..4849c92 100644 --- a/v8_c_api/src/v8include/v8-context.h +++ b/v8_c_api/src/v8include/v8-context.h @@ -84,6 +84,29 @@ class V8_EXPORT Context : public Data { * created by a previous call to Context::New with the same global * template. The state of the global object will be completely reset * and only object identify will remain. + * + * \param internal_fields_deserializer An optional callback used + * to deserialize fields set by + * v8::Object::SetAlignedPointerInInternalField() in wrapper objects + * from the default context snapshot. It should match the + * SerializeInternalFieldsCallback() used by + * v8::SnapshotCreator::SetDefaultContext() when the default context + * snapshot is created. It does not need to be configured if the default + * context snapshot contains no wrapper objects with pointer internal + * fields, or if no custom startup snapshot is configured + * in the v8::CreateParams used to create the isolate. + * + * \param microtask_queue An optional microtask queue used to manage + * the microtasks created in this context. If not set the per-isolate + * default microtask queue would be used. + * + * \param context_data_deserializer An optional callback used + * to deserialize embedder data set by + * v8::Context::SetAlignedPointerInEmbedderData() in the default + * context from the default context snapshot. It does not need to be + * configured if the default context snapshot contains no pointer embedder + * data, or if no custom startup snapshot is configured in the + * v8::CreateParams used to create the isolate. */ static Local New( Isolate* isolate, ExtensionConfiguration* extensions = nullptr, @@ -91,7 +114,9 @@ class V8_EXPORT Context : public Data { MaybeLocal global_object = MaybeLocal(), DeserializeInternalFieldsCallback internal_fields_deserializer = DeserializeInternalFieldsCallback(), - MicrotaskQueue* microtask_queue = nullptr); + MicrotaskQueue* microtask_queue = nullptr, + DeserializeContextDataCallback context_data_deserializer = + DeserializeContextDataCallback()); /** * Create a new context from a (non-default) context snapshot. There @@ -103,21 +128,37 @@ class V8_EXPORT Context : public Data { * \param context_snapshot_index The index of the context snapshot to * deserialize from. Use v8::Context::New for the default snapshot. * - * \param embedder_fields_deserializer Optional callback to deserialize - * internal fields. It should match the SerializeInternalFieldCallback used - * to serialize. + * \param internal_fields_deserializer An optional callback used + * to deserialize fields set by + * v8::Object::SetAlignedPointerInInternalField() in wrapper objects + * from the default context snapshot. It does not need to be + * configured if there are no wrapper objects with no internal + * pointer fields in the default context snapshot or if no startup + * snapshot is configured when the isolate is created. * * \param extensions See v8::Context::New. * * \param global_object See v8::Context::New. + * + * \param internal_fields_deserializer Similar to + * internal_fields_deserializer in v8::Context::New but applies to + * the context specified by the context_snapshot_index. + * + * \param microtask_queue See v8::Context::New. + * + * \param context_data_deserializer Similar to + * context_data_deserializer in v8::Context::New but applies to + * the context specified by the context_snapshot_index. */ static MaybeLocal FromSnapshot( Isolate* isolate, size_t context_snapshot_index, - DeserializeInternalFieldsCallback embedder_fields_deserializer = + DeserializeInternalFieldsCallback internal_fields_deserializer = DeserializeInternalFieldsCallback(), ExtensionConfiguration* extensions = nullptr, MaybeLocal global_object = MaybeLocal(), - MicrotaskQueue* microtask_queue = nullptr); + MicrotaskQueue* microtask_queue = nullptr, + DeserializeContextDataCallback context_data_deserializer = + DeserializeContextDataCallback()); /** * Returns an global object that isn't backed by an actual context. @@ -181,27 +222,8 @@ class V8_EXPORT Context : public Data { * also be considered for freezing should be added to the children_out * parameter. Returns true if the operation completed successfully. */ - V8_DEPRECATED("Please use the version that takes a LocalVector&") - virtual bool FreezeEmbedderObjectAndGetChildren( - Local obj, std::vector>& children_out) { - // TODO(chromium:1454114): This method is temporarily defined in order to - // smoothen the transition to the version that follows. - return true; - } virtual bool FreezeEmbedderObjectAndGetChildren( - Local obj, LocalVector& children_out) { - // TODO(chromium:1454114): This method is temporarily defined and - // calls the previous version, soon to be deprecated, in order to - // smoothen the transition. When deprecation is completed, this - // will become an abstract method. - std::vector> children; - START_ALLOW_USE_DEPRECATED() - // Temporarily use the old callback. - bool result = FreezeEmbedderObjectAndGetChildren(obj, children); - END_ALLOW_USE_DEPRECATED() - children_out.insert(children_out.end(), children.begin(), children.end()); - return result; - } + Local obj, LocalVector& children_out) = 0; }; /** @@ -328,22 +350,6 @@ class V8_EXPORT Context : public Data { Local context); void SetAbortScriptExecution(AbortScriptExecutionCallback callback); - /** - * Returns the value that was set or restored by - * SetContinuationPreservedEmbedderData(), if any. - */ - V8_DEPRECATE_SOON( - "Use v8::Isolate::GetContinuationPreservedEmbedderData instead") - Local GetContinuationPreservedEmbedderData() const; - - /** - * Sets a value that will be stored on continuations and reset while the - * continuation runs. - */ - V8_DEPRECATE_SOON( - "Use v8::Isolate::SetContinuationPreservedEmbedderData instead") - void SetContinuationPreservedEmbedderData(Local context); - /** * Set or clear hooks to be invoked for promise lifecycle operations. * To clear a hook, set it to an empty v8::Function. Each function will diff --git a/v8_c_api/src/v8include/v8-function-callback.h b/v8_c_api/src/v8include/v8-function-callback.h index 22b5328..86a3ea7 100644 --- a/v8_c_api/src/v8include/v8-function-callback.h +++ b/v8_c_api/src/v8include/v8-function-callback.h @@ -82,8 +82,15 @@ class ReturnValue { friend class PropertyCallbackInfo; template friend class PersistentValueMapBase; - V8_INLINE void SetInternal(internal::Address value) { *value_ = value; } - V8_INLINE internal::Address GetDefaultValue(); + V8_INLINE void SetInternal(internal::Address value); + // Setting the hole value has different meanings depending on the usage: + // - for function template callbacks it means that the callback returns + // the undefined value, + // - for property getter callbacks is means that the callback returns + // the undefined value (for property setter callbacks the value returned + // is ignored), + // - for interceptor callbacks it means that the request was not handled. + V8_INLINE void SetTheHole(); V8_INLINE explicit ReturnValue(internal::Address* slot); // See FunctionCallbackInfo. @@ -286,14 +293,28 @@ using FunctionCallback = void (*)(const FunctionCallbackInfo& info); template ReturnValue::ReturnValue(internal::Address* slot) : value_(slot) {} +template +void ReturnValue::SetInternal(internal::Address value) { +#if V8_STATIC_ROOTS_BOOL + using I = internal::Internals; + // Ensure that the upper 32-bits are not modified. Compiler should be + // able to optimize this to a store of a lower 32-bits of the value. + // This is fine since the callback can return only JavaScript values which + // are either Smis or heap objects allocated in the main cage. + *value_ = I::DecompressTaggedField(*value_, I::CompressTagged(value)); +#else + *value_ = value; +#endif // V8_STATIC_ROOTS_BOOL +} + template template void ReturnValue::Set(const Global& handle) { static_assert(std::is_base_of::value, "type check"); if (V8_UNLIKELY(handle.IsEmpty())) { - *value_ = GetDefaultValue(); + SetTheHole(); } else { - *value_ = handle.ptr(); + SetInternal(handle.ptr()); } } @@ -304,7 +325,7 @@ void ReturnValue::SetNonEmpty(const Global& handle) { #ifdef V8_ENABLE_CHECKS internal::VerifyHandleIsNonEmpty(handle.IsEmpty()); #endif // V8_ENABLE_CHECKS - *value_ = handle.ptr(); + SetInternal(handle.ptr()); } template @@ -312,9 +333,9 @@ template void ReturnValue::Set(const BasicTracedReference& handle) { static_assert(std::is_base_of::value, "type check"); if (V8_UNLIKELY(handle.IsEmpty())) { - *value_ = GetDefaultValue(); + SetTheHole(); } else { - *value_ = handle.ptr(); + SetInternal(handle.ptr()); } } @@ -325,7 +346,7 @@ void ReturnValue::SetNonEmpty(const BasicTracedReference& handle) { #ifdef V8_ENABLE_CHECKS internal::VerifyHandleIsNonEmpty(handle.IsEmpty()); #endif // V8_ENABLE_CHECKS - *value_ = handle.ptr(); + SetInternal(handle.ptr()); } template @@ -334,9 +355,9 @@ void ReturnValue::Set(const Local handle) { static_assert(std::is_void::value || std::is_base_of::value, "type check"); if (V8_UNLIKELY(handle.IsEmpty())) { - *value_ = GetDefaultValue(); + SetTheHole(); } else { - *value_ = handle.ptr(); + SetInternal(handle.ptr()); } } @@ -348,13 +369,13 @@ void ReturnValue::SetNonEmpty(const Local handle) { #ifdef V8_ENABLE_CHECKS internal::VerifyHandleIsNonEmpty(handle.IsEmpty()); #endif // V8_ENABLE_CHECKS - *value_ = handle.ptr(); + SetInternal(handle.ptr()); } template void ReturnValue::Set(double i) { static_assert(std::is_base_of::value, "type check"); - Set(Number::New(GetIsolate(), i)); + SetNonEmpty(Number::New(GetIsolate(), i)); } template @@ -362,10 +383,10 @@ void ReturnValue::Set(int32_t i) { static_assert(std::is_base_of::value, "type check"); using I = internal::Internals; if (V8_LIKELY(I::IsValidSmi(i))) { - *value_ = I::IntToSmi(i); + SetInternal(I::IntToSmi(i)); return; } - Set(Integer::New(GetIsolate(), i)); + SetNonEmpty(Integer::New(GetIsolate(), i)); } template @@ -377,7 +398,7 @@ void ReturnValue::Set(uint32_t i) { Set(static_cast(i)); return; } - Set(Integer::NewFromUnsigned(GetIsolate(), i)); + SetNonEmpty(Integer::NewFromUnsigned(GetIsolate(), i)); } template @@ -386,7 +407,7 @@ void ReturnValue::Set(uint16_t i) { using I = internal::Internals; static_assert(I::IsValidSmi(std::numeric_limits::min())); static_assert(I::IsValidSmi(std::numeric_limits::max())); - *value_ = I::IntToSmi(i); + SetInternal(I::IntToSmi(i)); } template @@ -398,9 +419,8 @@ void ReturnValue::Set(bool value) { internal::PerformCastCheck( internal::ValueHelper::SlotAsValue(value_)); #endif // V8_ENABLE_CHECKS - *value_ = I::DecompressTaggedField( - *value_, value ? I::StaticReadOnlyRoot::kTrueValue - : I::StaticReadOnlyRoot::kFalseValue); + SetInternal(value ? I::StaticReadOnlyRoot::kTrueValue + : I::StaticReadOnlyRoot::kFalseValue); #else int root_index; if (value) { @@ -412,6 +432,16 @@ void ReturnValue::Set(bool value) { #endif // V8_STATIC_ROOTS_BOOL } +template +void ReturnValue::SetTheHole() { + using I = internal::Internals; +#if V8_STATIC_ROOTS_BOOL + SetInternal(I::StaticReadOnlyRoot::kTheHoleValue); +#else + *value_ = I::GetRoot(GetIsolate(), I::kTheHoleValueRootIndex); +#endif // V8_STATIC_ROOTS_BOOL +} + template void ReturnValue::SetNull() { static_assert(std::is_base_of::value, "type check"); @@ -421,8 +451,7 @@ void ReturnValue::SetNull() { internal::PerformCastCheck( internal::ValueHelper::SlotAsValue(value_)); #endif // V8_ENABLE_CHECKS - *value_ = - I::DecompressTaggedField(*value_, I::StaticReadOnlyRoot::kNullValue); + SetInternal(I::StaticReadOnlyRoot::kNullValue); #else *value_ = I::GetRoot(GetIsolate(), I::kNullValueRootIndex); #endif // V8_STATIC_ROOTS_BOOL @@ -437,8 +466,7 @@ void ReturnValue::SetUndefined() { internal::PerformCastCheck( internal::ValueHelper::SlotAsValue(value_)); #endif // V8_ENABLE_CHECKS - *value_ = - I::DecompressTaggedField(*value_, I::StaticReadOnlyRoot::kUndefinedValue); + SetInternal(I::StaticReadOnlyRoot::kUndefinedValue); #else *value_ = I::GetRoot(GetIsolate(), I::kUndefinedValueRootIndex); #endif // V8_STATIC_ROOTS_BOOL @@ -453,8 +481,7 @@ void ReturnValue::SetEmptyString() { internal::PerformCastCheck( internal::ValueHelper::SlotAsValue(value_)); #endif // V8_ENABLE_CHECKS - *value_ = - I::DecompressTaggedField(*value_, I::StaticReadOnlyRoot::kEmptyString); + SetInternal(I::StaticReadOnlyRoot::kEmptyString); #else *value_ = I::GetRoot(GetIsolate(), I::kEmptyStringRootIndex); #endif // V8_STATIC_ROOTS_BOOL @@ -485,12 +512,6 @@ void ReturnValue::Set(S* whatever) { static_assert(sizeof(S) < 0, "incompilable to prevent inadvertent misuse"); } -template -internal::Address ReturnValue::GetDefaultValue() { - using I = internal::Internals; - return I::GetRoot(GetIsolate(), I::kTheHoleValueRootIndex); -} - template FunctionCallbackInfo::FunctionCallbackInfo(internal::Address* implicit_args, internal::Address* values, diff --git a/v8_c_api/src/v8include/v8-internal.h b/v8_c_api/src/v8include/v8-internal.h index 48001c6..322b22d 100644 --- a/v8_c_api/src/v8include/v8-internal.h +++ b/v8_c_api/src/v8include/v8-internal.h @@ -425,7 +425,7 @@ constexpr uint64_t kAllExternalPointerTypeTags[] = { /* it is the Embedder's responsibility to ensure type safety (against */ \ /* substitution) and lifetime validity of these objects. */ \ V(kExternalObjectValueTag, TAG(13)) \ - V(kCallHandlerInfoCallbackTag, TAG(14)) \ + V(kFunctionTemplateInfoCallbackTag, TAG(14)) \ V(kAccessorInfoGetterTag, TAG(15)) \ V(kAccessorInfoSetterTag, TAG(16)) \ V(kWasmInternalFunctionCallTargetTag, TAG(17)) \ @@ -478,7 +478,7 @@ V8_INLINE static constexpr bool IsSharedExternalPointerType( V8_INLINE static constexpr bool IsMaybeReadOnlyExternalPointerType( ExternalPointerTag tag) { return tag == kAccessorInfoGetterTag || tag == kAccessorInfoSetterTag || - tag == kCallHandlerInfoCallbackTag; + tag == kFunctionTemplateInfoCallbackTag; } // Sanity checks. @@ -746,23 +746,28 @@ class Internals { #if V8_STATIC_ROOTS_BOOL -// These constants need to be initialized in api.cc. +// These constants are copied from static-roots.h and guarded by static asserts. #define EXPORTED_STATIC_ROOTS_PTR_LIST(V) \ - V(UndefinedValue) \ - V(NullValue) \ - V(TrueValue) \ - V(FalseValue) \ - V(EmptyString) \ - V(TheHoleValue) + V(UndefinedValue, 0x69) \ + V(NullValue, 0x85) \ + V(TrueValue, 0xc9) \ + V(FalseValue, 0xad) \ + V(EmptyString, 0xa1) \ + V(TheHoleValue, 0x719) using Tagged_t = uint32_t; struct StaticReadOnlyRoot { -#define DEF_ROOT(name) V8_EXPORT static const Tagged_t k##name; +#define DEF_ROOT(name, value) static constexpr Tagged_t k##name = value; EXPORTED_STATIC_ROOTS_PTR_LIST(DEF_ROOT) #undef DEF_ROOT - V8_EXPORT static const Tagged_t kFirstStringMap; - V8_EXPORT static const Tagged_t kLastStringMap; + static constexpr Tagged_t kFirstStringMap = 0xe5; + static constexpr Tagged_t kLastStringMap = 0x47d; + +#define PLUSONE(...) +1 + static constexpr size_t kNumberOfExportedStaticRoots = + 2 + EXPORTED_STATIC_ROOTS_PTR_LIST(PLUSONE); +#undef PLUSONE }; #endif // V8_STATIC_ROOTS_BOOL @@ -786,6 +791,11 @@ class Internals { static const int kJSObjectType = 0x421; static const int kFirstJSApiObjectType = 0x422; static const int kLastJSApiObjectType = 0x80A; + // Defines a range [kFirstEmbedderJSApiObjectType, kJSApiObjectTypesCount] + // of JSApiObject instance type values that an embedder can use. + static const int kFirstEmbedderJSApiObjectType = 0; + static const int kLastEmbedderJSApiObjectType = + kLastJSApiObjectType - kFirstJSApiObjectType; static const int kUndefinedOddballKind = 4; static const int kNullOddballKind = 3; @@ -939,15 +949,15 @@ class Internals { Address base = *reinterpret_cast( reinterpret_cast(isolate) + kIsolateCageBaseOffset); switch (index) { -#define DECOMPRESS_ROOT(name) \ - case k##name##RootIndex: \ +#define DECOMPRESS_ROOT(name, ...) \ + case k##name##RootIndex: \ return base + StaticReadOnlyRoot::k##name; EXPORTED_STATIC_ROOTS_PTR_LIST(DECOMPRESS_ROOT) #undef DECOMPRESS_ROOT +#undef EXPORTED_STATIC_ROOTS_PTR_LIST default: break; } -#undef EXPORTED_STATIC_ROOTS_PTR_LIST #endif // V8_STATIC_ROOTS_BOOL return *GetRootSlot(isolate, index); } @@ -1046,6 +1056,10 @@ class Internals { return addr & -static_cast(kPtrComprCageBaseAlignment); } + V8_INLINE static uint32_t CompressTagged(Address value) { + return static_cast(value); + } + V8_INLINE static Address DecompressTaggedField(Address heap_object_ptr, uint32_t value) { Address base = GetPtrComprCageBaseFromOnHeapAddress(heap_object_ptr); diff --git a/v8_c_api/src/v8include/v8-isolate.h b/v8_c_api/src/v8include/v8-isolate.h index a3ceec0..585b513 100644 --- a/v8_c_api/src/v8include/v8-isolate.h +++ b/v8_c_api/src/v8include/v8-isolate.h @@ -562,6 +562,7 @@ class V8_EXPORT Isolate { kWasmTypeReflection = 137, kWasmExnRef = 138, kWasmTypedFuncRef = 139, + kInvalidatedStringWrapperToPrimitiveProtector = 140, // If you add new values here, you'll also need to update Chromium's: // web_feature.mojom, use_counter_callback.cc, and enums.xml. V8 changes to diff --git a/v8_c_api/src/v8include/v8-platform.h b/v8_c_api/src/v8include/v8-platform.h index b61f27a..313c028 100644 --- a/v8_c_api/src/v8include/v8-platform.h +++ b/v8_c_api/src/v8include/v8-platform.h @@ -76,8 +76,12 @@ class TaskRunner { /** * Schedules a task to be invoked by this TaskRunner. The TaskRunner * implementation takes ownership of |task|. + * + * Embedders should override PostTaskImpl instead of this. */ - virtual void PostTask(std::unique_ptr task) = 0; + virtual void PostTask(std::unique_ptr task) { + PostTaskImpl(std::move(task), SourceLocation::Current()); + } /** * Schedules a task to be invoked by this TaskRunner. The TaskRunner @@ -93,16 +97,25 @@ class TaskRunner { * execution is not allowed to nest. * * Requires that |TaskRunner::NonNestableTasksEnabled()| is true. + * + * Embedders should override PostNonNestableTaskImpl instead of this. */ - virtual void PostNonNestableTask(std::unique_ptr task) {} + virtual void PostNonNestableTask(std::unique_ptr task) { + PostNonNestableTaskImpl(std::move(task), SourceLocation::Current()); + } /** * Schedules a task to be invoked by this TaskRunner. The task is scheduled * after the given number of seconds |delay_in_seconds|. The TaskRunner * implementation takes ownership of |task|. + * + * Embedders should override PostDelayedTaskImpl instead of this. */ virtual void PostDelayedTask(std::unique_ptr task, - double delay_in_seconds) = 0; + double delay_in_seconds) { + PostDelayedTaskImpl(std::move(task), delay_in_seconds, + SourceLocation::Current()); + } /** * Schedules a task to be invoked by this TaskRunner. The task is scheduled @@ -119,9 +132,14 @@ class TaskRunner { * execution is not allowed to nest. * * Requires that |TaskRunner::NonNestableDelayedTasksEnabled()| is true. + * + * Embedders should override PostNonNestableDelayedTaskImpl instead of this. */ virtual void PostNonNestableDelayedTask(std::unique_ptr task, - double delay_in_seconds) {} + double delay_in_seconds) { + PostNonNestableDelayedTaskImpl(std::move(task), delay_in_seconds, + SourceLocation::Current()); + } /** * Schedules an idle task to be invoked by this TaskRunner. The task is @@ -130,8 +148,12 @@ class TaskRunner { * relative to other task types and may be starved for an arbitrarily long * time if no idle time is available. The TaskRunner implementation takes * ownership of |task|. + * + * Embedders should override PostIdleTaskImpl instead of this. */ - virtual void PostIdleTask(std::unique_ptr task) = 0; + virtual void PostIdleTask(std::unique_ptr task) { + PostIdleTaskImpl(std::move(task), SourceLocation::Current()); + } /** * Returns true if idle tasks are enabled for this TaskRunner. @@ -153,6 +175,23 @@ class TaskRunner { TaskRunner(const TaskRunner&) = delete; TaskRunner& operator=(const TaskRunner&) = delete; + + protected: + /** + * Implementation of above methods with an additional `location` argument. + */ + virtual void PostTaskImpl(std::unique_ptr task, + const SourceLocation& location) {} + virtual void PostNonNestableTaskImpl(std::unique_ptr task, + const SourceLocation& location) {} + virtual void PostDelayedTaskImpl(std::unique_ptr task, + double delay_in_seconds, + const SourceLocation& location) {} + virtual void PostNonNestableDelayedTaskImpl(std::unique_ptr task, + double delay_in_seconds, + const SourceLocation& location) {} + virtual void PostIdleTaskImpl(std::unique_ptr task, + const SourceLocation& location) {} }; /** diff --git a/v8_c_api/src/v8include/v8-script.h b/v8_c_api/src/v8include/v8-script.h index db22de9..7558986 100644 --- a/v8_c_api/src/v8include/v8-script.h +++ b/v8_c_api/src/v8include/v8-script.h @@ -291,11 +291,6 @@ class V8_EXPORT Module : public Data { * module_name is used solely for logging/debugging and doesn't affect module * behavior. */ - V8_DEPRECATED("Please use the version that takes a MemorySpan") - static Local CreateSyntheticModule( - Isolate* isolate, Local module_name, - const std::vector>& export_names, - SyntheticModuleEvaluationSteps evaluation_steps); static Local CreateSyntheticModule( Isolate* isolate, Local module_name, const MemorySpan>& export_names, @@ -311,17 +306,6 @@ class V8_EXPORT Module : public Data { V8_WARN_UNUSED_RESULT Maybe SetSyntheticModuleExport( Isolate* isolate, Local export_name, Local export_value); - /** - * Search the modules requested directly or indirectly by the module for - * any top-level await that has not yet resolved. If there is any, the - * returned vector contains a tuple of the unresolved module and a message - * with the pending top-level await. - * An embedder may call this before exiting to improve error messages. - */ - V8_DEPRECATED("Please use GetStalledTopLevelAwaitMessages") - std::vector, Local>> - GetStalledTopLevelAwaitMessage(Isolate* isolate); - /** * Search the modules requested directly or indirectly by the module for * any top-level await that has not yet resolved. If there is any, the diff --git a/v8_c_api/src/v8include/v8-snapshot.h b/v8_c_api/src/v8include/v8-snapshot.h index a1dc0c3..9e5a53f 100644 --- a/v8_c_api/src/v8include/v8-snapshot.h +++ b/v8_c_api/src/v8include/v8-snapshot.h @@ -38,7 +38,7 @@ class V8_EXPORT StartupData { /** * Callback and supporting data used in SnapshotCreator to implement embedder - * logic to serialize internal fields. + * logic to serialize internal fields of v8::Objects. * Internal fields that directly reference V8 objects are serialized without * calling this callback. Internal fields that contain aligned pointers are * serialized by this callback if it returns non-zero result. Otherwise it is @@ -53,13 +53,24 @@ struct SerializeInternalFieldsCallback { CallbackFunction callback; void* data; }; -// Note that these fields are called "internal fields" in the API and called -// "embedder fields" within V8. -using SerializeEmbedderFieldsCallback = SerializeInternalFieldsCallback; + +/** + * Similar to SerializeInternalFieldsCallback, but works with the embedder data + * in a v8::Context. + */ +struct SerializeContextDataCallback { + using CallbackFunction = StartupData (*)(Local holder, int index, + void* data); + SerializeContextDataCallback(CallbackFunction function = nullptr, + void* data_arg = nullptr) + : callback(function), data(data_arg) {} + CallbackFunction callback; + void* data; +}; /** * Callback and supporting data used to implement embedder logic to deserialize - * internal fields. + * internal fields of v8::Objects. */ struct DeserializeInternalFieldsCallback { using CallbackFunction = void (*)(Local holder, int index, @@ -67,12 +78,24 @@ struct DeserializeInternalFieldsCallback { DeserializeInternalFieldsCallback(CallbackFunction function = nullptr, void* data_arg = nullptr) : callback(function), data(data_arg) {} - void (*callback)(Local holder, int index, StartupData payload, - void* data); + + CallbackFunction callback; void* data; }; -using DeserializeEmbedderFieldsCallback = DeserializeInternalFieldsCallback; +/** + * Similar to DeserializeInternalFieldsCallback, but works with the embedder + * data in a v8::Context. + */ +struct DeserializeContextDataCallback { + using CallbackFunction = void (*)(Local holder, int index, + StartupData payload, void* data); + DeserializeContextDataCallback(CallbackFunction function = nullptr, + void* data_arg = nullptr) + : callback(function), data(data_arg) {} + CallbackFunction callback; + void* data; +}; /** * Helper class to create a snapshot data blob. @@ -156,23 +179,37 @@ class V8_EXPORT SnapshotCreator { * The snapshot will not contain the global proxy, and we expect one or a * global object template to create one, to be provided upon deserialization. * - * \param callback optional callback to serialize internal fields. + * \param internal_fields_serializer An optional callback used to serialize + * internal pointer fields set by + * v8::Object::SetAlignedPointerInInternalField(). + * + * \param context_data_serializer An optional callback used to serialize + * context embedder data set by + * v8::Context::SetAlignedPointerInEmbedderData(). + * */ - void SetDefaultContext(Local context, - SerializeInternalFieldsCallback callback = - SerializeInternalFieldsCallback()); + void SetDefaultContext( + Local context, + SerializeInternalFieldsCallback internal_fields_serializer = + SerializeInternalFieldsCallback(), + SerializeContextDataCallback context_data_serializer = + SerializeContextDataCallback()); /** * Add additional context to be included in the snapshot blob. * The snapshot will include the global proxy. * - * \param callback optional callback to serialize internal fields. + * \param internal_fields_serializer Similar to internal_fields_serializer + * in SetDefaultContext() but only applies to the context being added. * - * \returns the index of the context in the snapshot blob. + * \param context_data_serializer Similar to context_data_serializer + * in SetDefaultContext() but only applies to the context being added. */ size_t AddContext(Local context, - SerializeInternalFieldsCallback callback = - SerializeInternalFieldsCallback()); + SerializeInternalFieldsCallback internal_fields_serializer = + SerializeInternalFieldsCallback(), + SerializeContextDataCallback context_data_serializer = + SerializeContextDataCallback()); /** * Attach arbitrary V8::Data to the context snapshot, which can be retrieved diff --git a/v8_c_api/src/v8include/v8-statistics.h b/v8_c_api/src/v8include/v8-statistics.h index aeca8cf..82b78f5 100644 --- a/v8_c_api/src/v8include/v8-statistics.h +++ b/v8_c_api/src/v8include/v8-statistics.h @@ -61,33 +61,8 @@ class V8_EXPORT MeasureMemoryDelegate { */ virtual bool ShouldMeasure(Local context) = 0; - /** - * This function is called when memory measurement finishes. - * - * \param context_sizes_in_bytes a vector of (context, size) pairs that - * includes each context for which ShouldMeasure returned true and that - * was not garbage collected while the memory measurement was in progress. - * - * \param unattributed_size_in_bytes total size of objects that were not - * attributed to any context (i.e. are likely shared objects). - */ - V8_DEPRECATED("Please use the version that takes a result struct") - virtual void MeasurementComplete( - const std::vector, size_t>>& - context_sizes_in_bytes, - size_t unattributed_size_in_bytes) {} - /** Holds the result of a memory measurement request. */ struct Result { - /** - * A vector of (context, size) pairs that includes each context for - * which ShouldMeasure returned true and that was not garbage collected - * while the memory measurement was in progress. - */ - V8_DEPRECATED("Please use contexts and sizes_in_bytes") - const std::vector, size_t>>& - context_sizes_in_bytes; - /** * Two spans of equal length: the first includes each context for which * ShouldMeasure returned true and that was not garbage collected while diff --git a/v8_c_api/src/v8include/v8-template.h b/v8_c_api/src/v8include/v8-template.h index 674d420..6a0c898 100644 --- a/v8_c_api/src/v8include/v8-template.h +++ b/v8_c_api/src/v8include/v8-template.h @@ -94,6 +94,7 @@ class V8_EXPORT Template : public Data { PropertyAttribute attribute, AccessControl settings, SideEffectType getter_side_effect_type = SideEffectType::kHasSideEffect, SideEffectType setter_side_effect_type = SideEffectType::kHasSideEffect); + V8_DEPRECATE_SOON("Use SetNativeDataProperty with Local instead") void SetNativeDataProperty( Local name, AccessorGetterCallback getter, AccessorSetterCallback setter = nullptr, @@ -131,27 +132,35 @@ class V8_EXPORT Template : public Data { friend class FunctionTemplate; }; -// TODO(dcarney): Replace GenericNamedPropertyFooCallback with just -// NamedPropertyFooCallback. +/** + * Interceptor callbacks use this value to indicate whether the request was + * intercepted or not. + */ +enum class Intercepted : uint8_t { kNo = 0, kYes = 1 }; /** * Interceptor for get requests on an object. * - * Use `info.GetReturnValue().Set()` to set the return value of the - * intercepted get request. If the property does not exist the callback should - * not set the result and must not produce side effects. + * If the interceptor handles the request (i.e. the property should not be + * looked up beyond the interceptor) it should + * - (optionally) use info.GetReturnValue().Set()` to set the return value + * (by default the result is set to v8::Undefined), + * - return `Intercepted::kYes`. + * If the interceptor does not handle the request it must return + * `Intercepted::kNo` and it must not produce side effects. * * \param property The name of the property for which the request was * intercepted. * \param info Information about the intercepted request, such as - * isolate, receiver, return value, or whether running in `'use strict`' mode. + * isolate, receiver, return value, or whether running in `'use strict'` mode. * See `PropertyCallbackInfo`. * * \code - * void GetterCallback( - * Local name, - * const v8::PropertyCallbackInfo& info) { - * info.GetReturnValue().Set(v8_num(42)); + * Intercepted GetterCallback( + * Local name, const v8::PropertyCallbackInfo& info) { + * if (!IsKnownProperty(info.GetIsolate(), name)) return Intercepted::kNo; + * info.GetReturnValue().Set(v8_num(42)); + * return Intercepted::kYes; * } * * v8::Local templ = @@ -171,18 +180,23 @@ class V8_EXPORT Template : public Data { * * See also `ObjectTemplate::SetHandler`. */ +using NamedPropertyGetterCallback = Intercepted (*)( + Local property, const PropertyCallbackInfo& info); +// This variant will be deprecated soon. +// +// Use `info.GetReturnValue().Set()` to set the return value of the +// intercepted get request. If the property does not exist the callback should +// not set the result and must not produce side effects. using GenericNamedPropertyGetterCallback = void (*)(Local property, const PropertyCallbackInfo& info); /** * Interceptor for set requests on an object. * - * Use `info.GetReturnValue()` to indicate whether the request was intercepted - * or not. If the setter successfully intercepts the request, i.e., if the - * request should not be further executed, call - * `info.GetReturnValue().Set(value)`. If the setter did not intercept the - * request, i.e., if the request should be handled as if no interceptor is - * present, do not not call `Set()` and do not produce side effects. + * If the interceptor handles the request (i.e. the property should not be + * looked up beyond the interceptor) it should return `Intercepted::kYes`. + * If the interceptor does not handle the request it must return + * `Intercepted::kNo` and it must not produce side effects. * * \param property The name of the property for which the request was * intercepted. @@ -192,9 +206,19 @@ using GenericNamedPropertyGetterCallback = * isolate, receiver, return value, or whether running in `'use strict'` mode. * See `PropertyCallbackInfo`. * - * See also - * `ObjectTemplate::SetHandler.` + * See also `ObjectTemplate::SetHandler.` */ +using NamedPropertySetterCallback = + Intercepted (*)(Local property, Local value, + const PropertyCallbackInfo& info); +// This variant will be deprecated soon. +// +// Use `info.GetReturnValue()` to indicate whether the request was intercepted +// or not. If the setter successfully intercepts the request, i.e., if the +// request should not be further executed, call +// `info.GetReturnValue().Set(value)`. If the setter did not intercept the +// request, i.e., if the request should be handled as if no interceptor is +// present, do not not call `Set()` and do not produce side effects. using GenericNamedPropertySetterCallback = void (*)(Local property, Local value, const PropertyCallbackInfo& info); @@ -204,10 +228,13 @@ using GenericNamedPropertySetterCallback = * property, e.g., getOwnPropertyDescriptor(), propertyIsEnumerable(), and * defineProperty(). * - * Use `info.GetReturnValue().Set(value)` to set the property attributes. The - * value is an integer encoding a `v8::PropertyAttribute`. If the property does - * not exist the callback should not set the result and must not produce side - * effects. + * If the interceptor handles the request (i.e. the property should not be + * looked up beyond the interceptor) it should + * - use `info.GetReturnValue().Set()` to set to an Integer value encoding + * a `v8::PropertyAttribute` bits, + * - return `Intercepted::kYes`. + * If the interceptor does not handle the request it must return + * `Intercepted::kNo` and it must not produce side effects. * * \param property The name of the property for which the request was * intercepted. @@ -219,21 +246,29 @@ using GenericNamedPropertySetterCallback = * they do not return the attributes. For example, `hasOwnProperty()` can * trigger this interceptor depending on the state of the object. * - * See also - * `ObjectTemplate::SetHandler.` + * See also `ObjectTemplate::SetHandler.` */ +using NamedPropertyQueryCallback = Intercepted (*)( + Local property, const PropertyCallbackInfo& info); +// This variant will be deprecated soon. +// +// Use `info.GetReturnValue().Set(value)` to set the property attributes. The +// value is an integer encoding a `v8::PropertyAttribute`. If the property does +// not exist the callback should not set the result and must not produce side +// effects. using GenericNamedPropertyQueryCallback = void (*)(Local property, const PropertyCallbackInfo& info); /** * Interceptor for delete requests on an object. * - * Use `info.GetReturnValue()` to indicate whether the request was intercepted - * or not. If the deleter successfully intercepts the request, i.e., if the - * request should not be further executed, call - * `info.GetReturnValue().Set(value)` with a boolean `value`. The `value` is - * used as the return value of `delete`. If the deleter does not intercept the - * request then it should not set the result and must not produce side effects. + * If the interceptor handles the request (i.e. the property should not be + * looked up beyond the interceptor) it should + * - use `info.GetReturnValue().Set()` to set to a Boolean value indicating + * whether the property deletion was successful or not, + * - return `Intercepted::kYes`. + * If the interceptor does not handle the request it must return + * `Intercepted::kNo` and it must not produce side effects. * * \param property The name of the property for which the request was * intercepted. @@ -247,6 +282,16 @@ using GenericNamedPropertyQueryCallback = * * See also `ObjectTemplate::SetHandler.` */ +using NamedPropertyDeleterCallback = Intercepted (*)( + Local property, const PropertyCallbackInfo& info); +// This variant will be deprecated soon. +// +// Use `info.GetReturnValue()` to indicate whether the request was intercepted +// or not. If the deleter successfully intercepts the request, i.e., if the +// request should not be further executed, call +// `info.GetReturnValue().Set(value)` with a boolean `value`. The `value` is +// used as the return value of `delete`. If the deleter does not intercept the +// request then it should not set the result and must not produce side effects. using GenericNamedPropertyDeleterCallback = void (*)(Local property, const PropertyCallbackInfo& info); @@ -256,18 +301,19 @@ using GenericNamedPropertyDeleterCallback = * * Note: The values in the array must be of type v8::Name. */ -using GenericNamedPropertyEnumeratorCallback = +using NamedPropertyEnumeratorCallback = void (*)(const PropertyCallbackInfo& info); +// This variant will be deprecated soon. +// This is just a renaming of the typedef. +using GenericNamedPropertyEnumeratorCallback = NamedPropertyEnumeratorCallback; /** * Interceptor for defineProperty requests on an object. * - * Use `info.GetReturnValue()` to indicate whether the request was intercepted - * or not. If the definer successfully intercepts the request, i.e., if the - * request should not be further executed, call - * `info.GetReturnValue().Set(value)`. If the definer did not intercept the - * request, i.e., if the request should be handled as if no interceptor is - * present, do not not call `Set()` and do not produce side effects. + * If the interceptor handles the request (i.e. the property should not be + * looked up beyond the interceptor) it should return `Intercepted::kYes`. + * If the interceptor does not handle the request it must return + * `Intercepted::kNo` and it must not produce side effects. * * \param property The name of the property for which the request was * intercepted. @@ -279,6 +325,17 @@ using GenericNamedPropertyEnumeratorCallback = * * See also `ObjectTemplate::SetHandler`. */ +using NamedPropertyDefinerCallback = + Intercepted (*)(Local property, const PropertyDescriptor& desc, + const PropertyCallbackInfo& info); +// This variant will be deprecated soon. +// +// Use `info.GetReturnValue()` to indicate whether the request was intercepted +// or not. If the definer successfully intercepts the request, i.e., if the +// request should not be further executed, call +// `info.GetReturnValue().Set(value)`. If the definer did not intercept the +// request, i.e., if the request should be handled as if no interceptor is +// present, do not not call `Set()` and do not produce side effects. using GenericNamedPropertyDefinerCallback = void (*)(Local property, const PropertyDescriptor& desc, const PropertyCallbackInfo& info); @@ -286,10 +343,14 @@ using GenericNamedPropertyDefinerCallback = /** * Interceptor for getOwnPropertyDescriptor requests on an object. * - * Use `info.GetReturnValue().Set()` to set the return value of the - * intercepted request. The return value must be an object that - * can be converted to a PropertyDescriptor, e.g., a `v8::value` returned from - * `v8::Object::getOwnPropertyDescriptor`. + * If the interceptor handles the request (i.e. the property should not be + * looked up beyond the interceptor) it should + * - use `info.GetReturnValue().Set()` to set the return value which must be + * object that can be converted to a PropertyDescriptor (for example, + * a value returned by `v8::Object::getOwnPropertyDescriptor`), + * - return `Intercepted::kYes`. + * If the interceptor does not handle the request it must return + * `Intercepted::kNo` and it must not produce side effects. * * \param property The name of the property for which the request was * intercepted. @@ -302,18 +363,36 @@ using GenericNamedPropertyDefinerCallback = * * See also `ObjectTemplate::SetHandler`. */ +using NamedPropertyDescriptorCallback = Intercepted (*)( + Local property, const PropertyCallbackInfo& info); +// This variant will be deprecated soon. +// +// Use `info.GetReturnValue().Set()` to set the return value of the +// intercepted request. The return value must be an object that +// can be converted to a PropertyDescriptor, e.g., a `v8::Value` returned from +// `v8::Object::getOwnPropertyDescriptor`. using GenericNamedPropertyDescriptorCallback = void (*)(Local property, const PropertyCallbackInfo& info); +// TODO(ishell): Rename IndexedPropertyXxxCallbackV2 back to +// IndexedPropertyXxxCallback once the old IndexedPropertyXxxCallback is +// removed. + /** * See `v8::GenericNamedPropertyGetterCallback`. */ +using IndexedPropertyGetterCallbackV2 = + Intercepted (*)(uint32_t index, const PropertyCallbackInfo& info); +// This variant will be deprecated soon. using IndexedPropertyGetterCallback = void (*)(uint32_t index, const PropertyCallbackInfo& info); /** * See `v8::GenericNamedPropertySetterCallback`. */ +using IndexedPropertySetterCallbackV2 = Intercepted (*)( + uint32_t index, Local value, const PropertyCallbackInfo& info); +// This variant will be deprecated soon. using IndexedPropertySetterCallback = void (*)(uint32_t index, Local value, const PropertyCallbackInfo& info); @@ -321,12 +400,18 @@ using IndexedPropertySetterCallback = /** * See `v8::GenericNamedPropertyQueryCallback`. */ +using IndexedPropertyQueryCallbackV2 = + Intercepted (*)(uint32_t index, const PropertyCallbackInfo& info); +// This variant will be deprecated soon. using IndexedPropertyQueryCallback = void (*)(uint32_t index, const PropertyCallbackInfo& info); /** * See `v8::GenericNamedPropertyDeleterCallback`. */ +using IndexedPropertyDeleterCallbackV2 = + Intercepted (*)(uint32_t index, const PropertyCallbackInfo& info); +// This variant will be deprecated soon. using IndexedPropertyDeleterCallback = void (*)(uint32_t index, const PropertyCallbackInfo& info); @@ -342,6 +427,10 @@ using IndexedPropertyEnumeratorCallback = /** * See `v8::GenericNamedPropertyDefinerCallback`. */ +using IndexedPropertyDefinerCallbackV2 = + Intercepted (*)(uint32_t index, const PropertyDescriptor& desc, + const PropertyCallbackInfo& info); +// This variant will be deprecated soon. using IndexedPropertyDefinerCallback = void (*)(uint32_t index, const PropertyDescriptor& desc, const PropertyCallbackInfo& info); @@ -349,6 +438,9 @@ using IndexedPropertyDefinerCallback = /** * See `v8::GenericNamedPropertyDescriptorCallback`. */ +using IndexedPropertyDescriptorCallbackV2 = + Intercepted (*)(uint32_t index, const PropertyCallbackInfo& info); +// This variant will be deprecated soon. using IndexedPropertyDescriptorCallback = void (*)(uint32_t index, const PropertyCallbackInfo& info); @@ -611,7 +703,8 @@ enum class PropertyHandlerFlags { */ kNone = 0, - /** Will not call into interceptor for properties on the receiver or prototype + /** + * Will not call into interceptor for properties on the receiver or prototype * chain, i.e., only call into interceptor for properties that do not exist. * Currently only valid for named interceptors. */ @@ -627,9 +720,49 @@ enum class PropertyHandlerFlags { * The getter, query, enumerator callbacks do not produce side effects. */ kHasNoSideEffect = 1 << 2, + + /** + * This flag is used to distinguish which callbacks were provided - + * GenericNamedPropertyXXXCallback (old signature) or + * NamedPropertyXXXCallback (new signature). + * DO NOT use this flag, it'll be removed once embedders migrate to new + * callbacks signatures. + */ + kInternalNewCallbacksSignatures = 1 << 10, }; struct NamedPropertyHandlerConfiguration { + private: + static constexpr PropertyHandlerFlags WithNewSignatureFlag( + PropertyHandlerFlags flags) { + return static_cast( + static_cast(flags) | + static_cast( + PropertyHandlerFlags::kInternalNewCallbacksSignatures)); + } + + public: + NamedPropertyHandlerConfiguration( + NamedPropertyGetterCallback getter, // + NamedPropertySetterCallback setter, // + NamedPropertyQueryCallback query, // + NamedPropertyDeleterCallback deleter, // + NamedPropertyEnumeratorCallback enumerator, // + NamedPropertyDefinerCallback definer, // + NamedPropertyDescriptorCallback descriptor, // + Local data = Local(), + PropertyHandlerFlags flags = PropertyHandlerFlags::kNone) + : getter(reinterpret_cast(getter)), + setter(reinterpret_cast(setter)), + query(reinterpret_cast(query)), + deleter(reinterpret_cast(deleter)), + enumerator(enumerator), + definer(reinterpret_cast(definer)), + descriptor(reinterpret_cast(descriptor)), + data(data), + flags(WithNewSignatureFlag(flags)) {} + + // This variant will be deprecated soon. NamedPropertyHandlerConfiguration( GenericNamedPropertyGetterCallback getter, GenericNamedPropertySetterCallback setter, @@ -640,35 +773,73 @@ struct NamedPropertyHandlerConfiguration { GenericNamedPropertyDescriptorCallback descriptor, Local data = Local(), PropertyHandlerFlags flags = PropertyHandlerFlags::kNone) - : getter(getter), - setter(setter), - query(query), - deleter(deleter), + : getter(reinterpret_cast(getter)), + setter(reinterpret_cast(setter)), + query(reinterpret_cast(query)), + deleter(reinterpret_cast(deleter)), enumerator(enumerator), - definer(definer), - descriptor(descriptor), + definer(reinterpret_cast(definer)), + descriptor(reinterpret_cast(descriptor)), data(data), flags(flags) {} - NamedPropertyHandlerConfiguration( - /** Note: getter is required */ - GenericNamedPropertyGetterCallback getter = nullptr, + explicit NamedPropertyHandlerConfiguration( + NamedPropertyGetterCallback getter, + NamedPropertySetterCallback setter = nullptr, + NamedPropertyQueryCallback query = nullptr, + NamedPropertyDeleterCallback deleter = nullptr, + NamedPropertyEnumeratorCallback enumerator = nullptr, + Local data = Local(), + PropertyHandlerFlags flags = PropertyHandlerFlags::kNone) + : getter(reinterpret_cast(getter)), + setter(reinterpret_cast(setter)), + query(reinterpret_cast(query)), + deleter(reinterpret_cast(deleter)), + enumerator(enumerator), + definer(nullptr), + descriptor(nullptr), + data(data), + flags(WithNewSignatureFlag(flags)) {} + + // This variant will be deprecated soon. + explicit NamedPropertyHandlerConfiguration( + GenericNamedPropertyGetterCallback getter, GenericNamedPropertySetterCallback setter = nullptr, GenericNamedPropertyQueryCallback query = nullptr, GenericNamedPropertyDeleterCallback deleter = nullptr, GenericNamedPropertyEnumeratorCallback enumerator = nullptr, Local data = Local(), PropertyHandlerFlags flags = PropertyHandlerFlags::kNone) - : getter(getter), - setter(setter), - query(query), - deleter(deleter), + : getter(reinterpret_cast(getter)), + setter(reinterpret_cast(setter)), + query(reinterpret_cast(query)), + deleter(reinterpret_cast(deleter)), enumerator(enumerator), definer(nullptr), descriptor(nullptr), data(data), flags(flags) {} + NamedPropertyHandlerConfiguration( + NamedPropertyGetterCallback getter, // + NamedPropertySetterCallback setter, // + NamedPropertyDescriptorCallback descriptor, // + NamedPropertyDeleterCallback deleter, // + NamedPropertyEnumeratorCallback enumerator, // + NamedPropertyDefinerCallback definer, // + Local data = Local(), + PropertyHandlerFlags flags = PropertyHandlerFlags::kNone) + : getter(reinterpret_cast(getter)), + setter(reinterpret_cast(setter)), + query(nullptr), + deleter(reinterpret_cast(deleter)), + enumerator(enumerator), + definer(reinterpret_cast(definer)), + descriptor(reinterpret_cast(descriptor)), + data(data), + flags(WithNewSignatureFlag(flags)) {} + + // This variant will be deprecated soon. NamedPropertyHandlerConfiguration( GenericNamedPropertyGetterCallback getter, GenericNamedPropertySetterCallback setter, @@ -678,66 +849,136 @@ struct NamedPropertyHandlerConfiguration { GenericNamedPropertyDefinerCallback definer, Local data = Local(), PropertyHandlerFlags flags = PropertyHandlerFlags::kNone) - : getter(getter), - setter(setter), + : getter(reinterpret_cast(getter)), + setter(reinterpret_cast(setter)), query(nullptr), - deleter(deleter), + deleter(reinterpret_cast(deleter)), enumerator(enumerator), - definer(definer), - descriptor(descriptor), + definer(reinterpret_cast(definer)), + descriptor(reinterpret_cast(descriptor)), data(data), flags(flags) {} - GenericNamedPropertyGetterCallback getter; - GenericNamedPropertySetterCallback setter; - GenericNamedPropertyQueryCallback query; - GenericNamedPropertyDeleterCallback deleter; - GenericNamedPropertyEnumeratorCallback enumerator; - GenericNamedPropertyDefinerCallback definer; - GenericNamedPropertyDescriptorCallback descriptor; + void* getter; // [Generic]NamedPropertyGetterCallback + void* setter; // [Generic]NamedPropertySetterCallback + void* query; // [Generic]NamedPropertyQueryCallback + void* deleter; // [Generic]NamedPropertyDeleterCallback + NamedPropertyEnumeratorCallback enumerator; + void* definer; // [Generic]NamedPropertyDefinerCallback + void* descriptor; // [Generic]NamedPropertyDescriptorCallback Local data; PropertyHandlerFlags flags; }; struct IndexedPropertyHandlerConfiguration { + private: + static constexpr PropertyHandlerFlags WithNewSignatureFlag( + PropertyHandlerFlags flags) { + return static_cast( + static_cast(flags) | + static_cast( + PropertyHandlerFlags::kInternalNewCallbacksSignatures)); + } + + public: IndexedPropertyHandlerConfiguration( - IndexedPropertyGetterCallback getter, - IndexedPropertySetterCallback setter, IndexedPropertyQueryCallback query, - IndexedPropertyDeleterCallback deleter, - IndexedPropertyEnumeratorCallback enumerator, - IndexedPropertyDefinerCallback definer, - IndexedPropertyDescriptorCallback descriptor, + IndexedPropertyGetterCallbackV2 getter, // + IndexedPropertySetterCallbackV2 setter, // + IndexedPropertyQueryCallbackV2 query, // + IndexedPropertyDeleterCallbackV2 deleter, // + IndexedPropertyEnumeratorCallback enumerator, // + IndexedPropertyDefinerCallbackV2 definer, // + IndexedPropertyDescriptorCallbackV2 descriptor, // Local data = Local(), PropertyHandlerFlags flags = PropertyHandlerFlags::kNone) - : getter(getter), - setter(setter), - query(query), - deleter(deleter), + : getter(reinterpret_cast(getter)), + setter(reinterpret_cast(setter)), + query(reinterpret_cast(query)), + deleter(reinterpret_cast(deleter)), enumerator(enumerator), - definer(definer), - descriptor(descriptor), + definer(reinterpret_cast(definer)), + descriptor(reinterpret_cast(descriptor)), data(data), - flags(flags) {} + flags(WithNewSignatureFlag(flags)) {} + // This variant will be deprecated soon. IndexedPropertyHandlerConfiguration( - /** Note: getter is required */ - IndexedPropertyGetterCallback getter = nullptr, + IndexedPropertyGetterCallback getter, // + IndexedPropertySetterCallback setter, // + IndexedPropertyQueryCallback query, // + IndexedPropertyDeleterCallback deleter, // + IndexedPropertyEnumeratorCallback enumerator, // + IndexedPropertyDefinerCallback definer, // + IndexedPropertyDescriptorCallback descriptor, // + Local data = Local(), + PropertyHandlerFlags flags = PropertyHandlerFlags::kNone) + : getter(reinterpret_cast(getter)), + setter(reinterpret_cast(setter)), + query(reinterpret_cast(query)), + deleter(reinterpret_cast(deleter)), + enumerator(enumerator), + definer(reinterpret_cast(definer)), + descriptor(reinterpret_cast(descriptor)), + data(data), + flags(flags) {} + + explicit IndexedPropertyHandlerConfiguration( + IndexedPropertyGetterCallbackV2 getter = nullptr, + IndexedPropertySetterCallbackV2 setter = nullptr, + IndexedPropertyQueryCallbackV2 query = nullptr, + IndexedPropertyDeleterCallbackV2 deleter = nullptr, + IndexedPropertyEnumeratorCallback enumerator = nullptr, + Local data = Local(), + PropertyHandlerFlags flags = PropertyHandlerFlags::kNone) + : getter(reinterpret_cast(getter)), + setter(reinterpret_cast(setter)), + query(reinterpret_cast(query)), + deleter(reinterpret_cast(deleter)), + enumerator(enumerator), + definer(nullptr), + descriptor(nullptr), + data(data), + flags(WithNewSignatureFlag(flags)) {} + + // This variant will be deprecated soon. + explicit IndexedPropertyHandlerConfiguration( + IndexedPropertyGetterCallback getter, IndexedPropertySetterCallback setter = nullptr, IndexedPropertyQueryCallback query = nullptr, IndexedPropertyDeleterCallback deleter = nullptr, IndexedPropertyEnumeratorCallback enumerator = nullptr, Local data = Local(), PropertyHandlerFlags flags = PropertyHandlerFlags::kNone) - : getter(getter), - setter(setter), - query(query), - deleter(deleter), + : getter(reinterpret_cast(getter)), + setter(reinterpret_cast(setter)), + query(reinterpret_cast(query)), + deleter(reinterpret_cast(deleter)), enumerator(enumerator), definer(nullptr), descriptor(nullptr), data(data), flags(flags) {} + IndexedPropertyHandlerConfiguration( + IndexedPropertyGetterCallbackV2 getter, + IndexedPropertySetterCallbackV2 setter, + IndexedPropertyDescriptorCallbackV2 descriptor, + IndexedPropertyDeleterCallbackV2 deleter, + IndexedPropertyEnumeratorCallback enumerator, + IndexedPropertyDefinerCallbackV2 definer, + Local data = Local(), + PropertyHandlerFlags flags = PropertyHandlerFlags::kNone) + : getter(reinterpret_cast(getter)), + setter(reinterpret_cast(setter)), + query(nullptr), + deleter(reinterpret_cast(deleter)), + enumerator(enumerator), + definer(reinterpret_cast(definer)), + descriptor(reinterpret_cast(descriptor)), + data(data), + flags(WithNewSignatureFlag(flags)) {} + + // This variant will be deprecated soon. IndexedPropertyHandlerConfiguration( IndexedPropertyGetterCallback getter, IndexedPropertySetterCallback setter, @@ -747,23 +988,23 @@ struct IndexedPropertyHandlerConfiguration { IndexedPropertyDefinerCallback definer, Local data = Local(), PropertyHandlerFlags flags = PropertyHandlerFlags::kNone) - : getter(getter), - setter(setter), + : getter(reinterpret_cast(getter)), + setter(reinterpret_cast(setter)), query(nullptr), - deleter(deleter), + deleter(reinterpret_cast(deleter)), enumerator(enumerator), - definer(definer), - descriptor(descriptor), + definer(reinterpret_cast(definer)), + descriptor(reinterpret_cast(descriptor)), data(data), flags(flags) {} - IndexedPropertyGetterCallback getter; - IndexedPropertySetterCallback setter; - IndexedPropertyQueryCallback query; - IndexedPropertyDeleterCallback deleter; + void* getter; // IndexedPropertyGetterCallback[V2] + void* setter; // IndexedPropertySetterCallback[V2] + void* query; // IndexedPropertyQueryCallback[V2] + void* deleter; // IndexedPropertyDeleterCallback[V2] IndexedPropertyEnumeratorCallback enumerator; - IndexedPropertyDefinerCallback definer; - IndexedPropertyDescriptorCallback descriptor; + void* definer; // IndexedPropertyDefinerCallback[V2] + void* descriptor; // IndexedPropertyDescriptorCallback[V2] Local data; PropertyHandlerFlags flags; }; @@ -804,6 +1045,7 @@ class V8_EXPORT ObjectTemplate : public Template { * \param attribute The attributes of the property for which an accessor * is added. */ + V8_DEPRECATE_SOON("Use SetAccessor with Local instead") void SetAccessor( Local name, AccessorGetterCallback getter, AccessorSetterCallback setter = nullptr, @@ -846,7 +1088,7 @@ class V8_EXPORT ObjectTemplate : public Template { * \param data A piece of data that will be passed to the callbacks * whenever they are invoked. */ - // TODO(dcarney): deprecate + V8_DEPRECATE_SOON("Use SetHandler instead") void SetIndexedPropertyHandler( IndexedPropertyGetterCallback getter, IndexedPropertySetterCallback setter = nullptr, @@ -951,8 +1193,7 @@ class V8_EXPORT ObjectTemplate : public Template { private: ObjectTemplate(); - static Local New(internal::Isolate* isolate, - Local constructor); + static void CheckCast(Data* that); friend class FunctionTemplate; }; diff --git a/v8_c_api/src/v8include/v8-typed-array.h b/v8_c_api/src/v8include/v8-typed-array.h index 9cb645f..66e21f4 100644 --- a/v8_c_api/src/v8include/v8-typed-array.h +++ b/v8_c_api/src/v8include/v8-typed-array.h @@ -249,6 +249,30 @@ class V8_EXPORT Int32Array : public TypedArray { static void CheckCast(Value* obj); }; +/** + * An instance of Float16Array constructor. + */ +class V8_EXPORT Float16Array : public TypedArray { + static constexpr size_t kMaxLength = + TypedArray::kMaxByteLength / sizeof(uint16_t); + + public: + static Local New(Local array_buffer, + size_t byte_offset, size_t length); + static Local New(Local shared_array_buffer, + size_t byte_offset, size_t length); + V8_INLINE static Float16Array* Cast(Value* value) { +#ifdef V8_ENABLE_CHECKS + CheckCast(value); +#endif + return static_cast(value); + } + + private: + Float16Array(); + static void CheckCast(Value* obj); +}; + /** * An instance of Float32Array constructor (ES6 draft 15.13.6). */ diff --git a/v8_c_api/src/v8include/v8-value.h b/v8_c_api/src/v8include/v8-value.h index 9356cd6..ac04525 100644 --- a/v8_c_api/src/v8include/v8-value.h +++ b/v8_c_api/src/v8include/v8-value.h @@ -301,6 +301,11 @@ class V8_EXPORT Value : public Data { */ bool IsInt32Array() const; + /** + * Returns true if this value is a Float16Array. + */ + bool IsFloat16Array() const; + /** * Returns true if this value is a Float32Array. */ diff --git a/v8_c_api/src/v8include/v8-version.h b/v8_c_api/src/v8include/v8-version.h index 66309d0..b11b78b 100644 --- a/v8_c_api/src/v8include/v8-version.h +++ b/v8_c_api/src/v8include/v8-version.h @@ -9,8 +9,8 @@ // 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 12 -#define V8_MINOR_VERSION 3 -#define V8_BUILD_NUMBER 219 +#define V8_MINOR_VERSION 4 +#define V8_BUILD_NUMBER 254 #define V8_PATCH_LEVEL 15 // Use 1 for candidates and 0 otherwise.