Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion V8_DEFAULT_VERSION.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
11.8.172.17
11.9.169.6
24 changes: 5 additions & 19 deletions v8_c_api/src/v8include/js_protocol.pdl
Original file line number Diff line number Diff line change
Expand Up @@ -1014,8 +1014,7 @@ domain Runtime
# Unique script identifier.
type ScriptId extends string

# Represents options for serialization. Overrides `generatePreview`, `returnByValue` and
# `generateWebDriverValue`.
# Represents options for serialization. Overrides `generatePreview` and `returnByValue`.
type SerializationOptions extends object
properties
enum serialization
Expand All @@ -1027,8 +1026,7 @@ domain Runtime
# `returnByValue: true`. Overrides `returnByValue`.
json
# Only remote object id is put in the result. Same bahaviour as if no
# `serializationOptions`, `generatePreview`, `returnByValue` nor `generateWebDriverValue`
# are provided.
# `serializationOptions`, `generatePreview` nor `returnByValue` are provided.
idOnly

# Deep serialization depth. Default is full depth. Respected only in `deep` serialization mode.
Expand Down Expand Up @@ -1066,6 +1064,7 @@ domain Runtime
arraybuffer
node
window
generator
optional any value
optional string objectId
# Set if value reference met more then once during serialization. In such
Expand Down Expand Up @@ -1125,8 +1124,6 @@ domain Runtime
optional UnserializableValue unserializableValue
# String representation of the object.
optional string description
# Deprecated. Use `deepSerializedValue` instead. WebDriver BiDi representation of the value.
deprecated optional DeepSerializedValue webDriverValue
# Deep serialized value.
experimental optional DeepSerializedValue deepSerializedValue
# Unique object identifier (for non-primitive values).
Expand Down Expand Up @@ -1442,13 +1439,8 @@ domain Runtime
# boundaries).
# This is mutually exclusive with `executionContextId`.
experimental optional string uniqueContextId
# Deprecated. Use `serializationOptions: {serialization:"deep"}` instead.
# Whether the result should contain `webDriverValue`, serialized according to
# https://w3c.github.io/webdriver-bidi. This is mutually exclusive with `returnByValue`, but
# resulting `objectId` is still provided.
deprecated optional boolean generateWebDriverValue
# Specifies the result serialization. If provided, overrides
# `generatePreview`, `returnByValue` and `generateWebDriverValue`.
# `generatePreview` and `returnByValue`.
experimental optional SerializationOptions serializationOptions

returns
Expand Down Expand Up @@ -1536,14 +1528,8 @@ domain Runtime
# boundaries).
# This is mutually exclusive with `contextId`.
experimental optional string uniqueContextId
# Deprecated. Use `serializationOptions: {serialization:"deep"}` instead.
# Whether the result should contain `webDriverValue`, serialized
# according to
# https://w3c.github.io/webdriver-bidi. This is mutually exclusive with `returnByValue`, but
# resulting `objectId` is still provided.
deprecated optional boolean generateWebDriverValue
# Specifies the result serialization. If provided, overrides
# `generatePreview`, `returnByValue` and `generateWebDriverValue`.
# `generatePreview` and `returnByValue`.
experimental optional SerializationOptions serializationOptions
returns
# Evaluation result.
Expand Down
36 changes: 36 additions & 0 deletions v8_c_api/src/v8include/v8-container.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,42 @@ class V8_EXPORT Array : public Object {
return static_cast<Array*>(value);
}

enum class CallbackResult {
kException,
kBreak,
kContinue,
};
using IterationCallback = CallbackResult (*)(uint32_t index,
Local<Value> element,
void* data);

/**
* Calls {callback} for every element of this array, passing {callback_data}
* as its {data} parameter.
* This function will typically be faster than calling {Get()} repeatedly.
* As a consequence of being optimized for low overhead, the provided
* callback must adhere to the following restrictions:
* - It must not allocate any V8 objects and continue iterating; it may
* allocate (e.g. an error message/object) and then immediately terminate
* the iteration.
* - It must not modify the array being iterated.
* - It must not call back into V8 (unless it can guarantee that such a
* call does not violate the above restrictions, which is difficult).
* - The {Local<Value> element} must not "escape", i.e. must not be assigned
* to any other {Local}. Creating a {Global} from it, or updating a
* v8::TypecheckWitness with it, is safe.
* These restrictions may be lifted in the future if use cases arise that
* justify a slower but more robust implementation.
*
* Returns {Nothing} on exception; use a {TryCatch} to catch and handle this
* exception.
* When the {callback} returns {kException}, iteration is terminated
* immediately, returning {Nothing}. By returning {kBreak}, the callback
* can request non-exceptional early termination of the iteration.
*/
Maybe<void> Iterate(Local<Context> context, IterationCallback callback,
void* callback_data);

private:
Array();
static void CheckCast(Value* obj);
Expand Down
23 changes: 15 additions & 8 deletions v8_c_api/src/v8include/v8-exception.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,21 @@ class ThreadLocalTop;
*/
class V8_EXPORT Exception {
public:
static Local<Value> RangeError(Local<String> message);
static Local<Value> ReferenceError(Local<String> message);
static Local<Value> SyntaxError(Local<String> message);
static Local<Value> TypeError(Local<String> message);
static Local<Value> WasmCompileError(Local<String> message);
static Local<Value> WasmLinkError(Local<String> message);
static Local<Value> WasmRuntimeError(Local<String> message);
static Local<Value> Error(Local<String> message);
static Local<Value> RangeError(Local<String> message,
Local<Value> options = {});
static Local<Value> ReferenceError(Local<String> message,
Local<Value> options = {});
static Local<Value> SyntaxError(Local<String> message,
Local<Value> options = {});
static Local<Value> TypeError(Local<String> message,
Local<Value> options = {});
static Local<Value> WasmCompileError(Local<String> message,
Local<Value> options = {});
static Local<Value> WasmLinkError(Local<String> message,
Local<Value> options = {});
static Local<Value> WasmRuntimeError(Local<String> message,
Local<Value> options = {});
static Local<Value> Error(Local<String> message, Local<Value> options = {});

/**
* Creates an error message for the given exception.
Expand Down
17 changes: 0 additions & 17 deletions v8_c_api/src/v8include/v8-inspector.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,17 +217,6 @@ class V8_EXPORT V8InspectorSession {
virtual void stop() = 0;
};

// Deprecated.
// TODO(crbug.com/1420968): remove.
class V8_EXPORT WebDriverValue {
public:
explicit WebDriverValue(std::unique_ptr<StringBuffer> type,
v8::MaybeLocal<v8::Value> value = {})
: type(std::move(type)), value(value) {}
std::unique_ptr<StringBuffer> type;
v8::MaybeLocal<v8::Value> value;
};

struct V8_EXPORT DeepSerializedValue {
explicit DeepSerializedValue(std::unique_ptr<StringBuffer> type,
v8::MaybeLocal<v8::Value> value = {})
Expand Down Expand Up @@ -266,12 +255,6 @@ class V8_EXPORT V8InspectorClient {
virtual void beginUserGesture() {}
virtual void endUserGesture() {}

// Deprecated. Use `deepSerialize` instead.
// TODO(crbug.com/1420968): remove.
virtual std::unique_ptr<WebDriverValue> serializeToWebDriverValue(
v8::Local<v8::Value> v8Value, int maxDepth) {
return nullptr;
}
virtual std::unique_ptr<DeepSerializationResult> deepSerialize(
v8::Local<v8::Value> v8Value, int maxDepth,
v8::Local<v8::Object> additionalParameters) {
Expand Down
84 changes: 53 additions & 31 deletions v8_c_api/src/v8include/v8-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -484,65 +484,74 @@ PER_ISOLATE_EXTERNAL_POINTER_TAGS(CHECK_NON_SHARED_EXTERNAL_POINTER_TAGS)
// Indirect Pointers.
//
// When the sandbox is enabled, indirect pointers are used to reference
// HeapObjects that live outside of the sandbox (but are still managed through
// the GC). When object A references an object B through an indirect pointer,
// object A will contain a IndirectPointerHandle, i.e. a shifted 32-bit index,
// which identifies an entry in a pointer table (such as the CodePointerTable).
// HeapObjects that live outside of the sandbox (but are still managed by V8's
// garbage collector). When object A references an object B through an indirect
// pointer, object A will contain a IndirectPointerHandle, i.e. a shifted
// 32-bit index, which identifies an entry in a pointer table (generally an
// indirect pointer table, or the code pointer table if it is a Code object).
// This table entry then contains the actual pointer to object B. Further,
// object B owns this pointer table entry, and it is responsible for updating
// the "self-pointer" in the entry when it is relocated in memory. This way, in
// contrast to "normal" pointers, indirect pointers never need to be tracked by
// the GC (i.e. there is no remembered set for them).
// Currently there is only one type of object referenced through indirect
// pointers (Code objects), but once there are different types of such objects,
// the pointer table entry would probably also contain the type of the target
// object (e.g. by XORing the instance type into the top bits of the pointer).

// An IndirectPointerHandle represents a 32-bit index into a pointer table.
using IndirectPointerHandle = uint32_t;

// The size of the virtual memory reservation for the indirect pointer table.
// As with the external pointer table, a maximum table size in combination with
// shifted indices allows omitting bounds checks.
constexpr size_t kIndirectPointerTableReservationSize = 8 * MB;

// The indirect pointer handles are stores shifted to the left by this amount
// to guarantee that they are smaller than the maximum table size.
constexpr uint32_t kIndirectPointerHandleShift = 6;
constexpr uint32_t kIndirectPointerHandleShift = 12;

// A null handle always references an entry that contains nullptr.
constexpr IndirectPointerHandle kNullIndirectPointerHandle = 0;

// Currently only Code objects can be referenced through indirect pointers and
// various places rely on that assumption. They will all static_assert against
// this constant to make them easy to find and fix once we reference other types
// of objects indirectly.
constexpr bool kAllIndirectPointerObjectsAreCode = true;
// The maximum number of entries in an indirect pointer table.
constexpr int kIndirectPointerTableEntrySize = 8;
constexpr int kIndirectPointerTableEntrySizeLog2 = 3;
constexpr size_t kMaxIndirectPointers =
kIndirectPointerTableReservationSize / kIndirectPointerTableEntrySize;
static_assert((1 << (32 - kIndirectPointerHandleShift)) == kMaxIndirectPointers,
"kIndirectPointerTableReservationSize and "
"kIndirectPointerHandleShift don't match");

//
// Code Pointers.
//
// When the sandbox is enabled, Code objects are referenced from inside the
// sandbox through indirect pointers that reference entries in the code pointer
// table (CPT). Each entry in the CPT contains both a pointer to a Code object
// as well as a pointer to the Code's entrypoint. This allows calling/jumping
// into Code with one fewer memory access (compared to the case where the
// entrypoint pointer needs to be loaded from the Code object).
// As such, a CodePointerHandle can be used both to obtain the referenced Code
// object and to directly load its entrypoint pointer.
// table (CPT) instead of the indirect pointer table (IPT). Each entry in the
// CPT contains both a pointer to a Code object as well as a pointer to the
// Code's entrypoint. This allows calling/jumping into Code with one fewer
// memory access (compared to the case where the entrypoint pointer needs to be
// loaded from the Code object). As such, a CodePointerHandle can be used both
// to obtain the referenced Code object and to directly load its entrypoint
// pointer.
using CodePointerHandle = IndirectPointerHandle;
constexpr uint32_t kCodePointerHandleShift = kIndirectPointerHandleShift;
constexpr CodePointerHandle kNullCodePointerHandle = 0;

// The size of the virtual memory reservation for code pointer table.
// This determines the maximum number of entries in a table. Using a maximum
// size allows omitting bounds checks on table accesses if the indices are
// guaranteed (e.g. through shifting) to be below the maximum index. This
// value must be a power of two.
// The size of the virtual memory reservation for the code pointer table.
// As with the other tables, a maximum table size in combination with shifted
// indices allows omitting bounds checks.
constexpr size_t kCodePointerTableReservationSize = 1 * GB;

// The maximum number of entries in an external pointer table.
// Code pointer handles are shifted by a different amount than indirect pointer
// handles as the tables have a different maximum size.
constexpr uint32_t kCodePointerHandleShift = 6;

// A null handle always references an entry that contains nullptr.
constexpr CodePointerHandle kNullCodePointerHandle = 0;

// The maximum number of entries in a code pointer table.
constexpr int kCodePointerTableEntrySize = 16;
constexpr int kCodePointerTableEntrySizeLog2 = 4;
constexpr size_t kMaxCodePointers =
kCodePointerTableReservationSize / kCodePointerTableEntrySize;
static_assert(
(1 << (32 - kIndirectPointerHandleShift)) == kMaxCodePointers,
(1 << (32 - kCodePointerHandleShift)) == kMaxCodePointers,
"kCodePointerTableReservationSize and kCodePointerHandleShift don't match");

constexpr int kCodePointerTableEntryEntrypointOffset = 0;
Expand Down Expand Up @@ -602,9 +611,11 @@ class Internals {
static const int kHandleScopeDataSize =
2 * kApiSystemPointerSize + 2 * kApiInt32Size;

// ExternalPointerTable layout guarantees.
// ExternalPointerTable and IndirectPointerTable layout guarantees.
static const int kExternalPointerTableBasePointerOffset = 0;
static const int kExternalPointerTableSize = 2 * kApiSystemPointerSize;
static const int kIndirectPointerTableSize = 2 * kApiSystemPointerSize;
static const int kIndirectPointerTableBasePointerOffset = 0;

// IsolateData layout guarantees.
static const int kIsolateCageBaseOffset = 0;
Expand Down Expand Up @@ -639,8 +650,10 @@ class Internals {
kIsolateEmbedderDataOffset + kNumIsolateDataSlots * kApiSystemPointerSize;
static const int kIsolateSharedExternalPointerTableAddressOffset =
kIsolateExternalPointerTableOffset + kExternalPointerTableSize;
static const int kIsolateApiCallbackThunkArgumentOffset =
static const int kIsolateIndirectPointerTableOffset =
kIsolateSharedExternalPointerTableAddressOffset + kApiSystemPointerSize;
static const int kIsolateApiCallbackThunkArgumentOffset =
kIsolateIndirectPointerTableOffset + kIndirectPointerTableSize;
#else
static const int kIsolateApiCallbackThunkArgumentOffset =
kIsolateEmbedderDataOffset + kNumIsolateDataSlots * kApiSystemPointerSize;
Expand Down Expand Up @@ -763,6 +776,15 @@ class Internals {
return ReadRawField<uint16_t>(map, kMapInstanceTypeOffset);
}

V8_INLINE static Address LoadMap(Address obj) {
if (!HasHeapObjectTag(obj)) return kNullAddress;
Address map = ReadTaggedPointerField(obj, kHeapObjectMapOffset);
#ifdef V8_MAP_PACKING
map = UnpackMapWord(map);
#endif
return map;
}

V8_INLINE static int GetOddballKind(Address obj) {
return SmiValue(ReadTaggedSignedField(obj, kOddballKindOffset));
}
Expand Down
Loading