Skip to content

Commit 4672b16

Browse files
committed
RemoteObject interface style implementation
1 parent c9c1ba1 commit 4672b16

File tree

3 files changed

+301
-9
lines changed

3 files changed

+301
-9
lines changed

src/binding.cpp

Lines changed: 130 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1569,6 +1569,13 @@ static inline std::string fromStringView(v8::Isolate* isolate, const v8_inspecto
15691569
return *result;
15701570
}
15711571

1572+
const char* toHeapCharPtr(const v8_inspector::String16& str) {
1573+
std::string utf8_str = str.utf8(); // Note that this may hold the string on the stack as an SSO
1574+
char* heap_str = new char[utf8_str.length() + 1];
1575+
strcpy(heap_str, utf8_str.c_str());
1576+
return heap_str;
1577+
}
1578+
15721579
// Inspector
15731580

15741581
v8_inspector::V8Inspector *v8_inspector__Inspector__Create(
@@ -1629,21 +1636,141 @@ void v8_inspector__Session__dispatchProtocolMessage(
16291636
session->dispatchProtocolMessage(str_view);
16301637
}
16311638

1632-
v8_inspector::protocol::Runtime::API::RemoteObject* v8_inspector__Session__wrapObject(
1639+
v8_inspector::protocol::Runtime::RemoteObject* v8_inspector__Session__wrapObject(
16331640
v8_inspector::V8InspectorSession *session, v8::Isolate *isolate,
16341641
const v8::Context* ctx, const v8::Value* val,
16351642
const char *grpname, int grpname_len, bool generatepreview) {
16361643
auto sv_grpname = toStringView(grpname, grpname_len);
16371644
auto remote_object = session->wrapObject(ptr_to_local(ctx), ptr_to_local(val), sv_grpname, generatepreview);
1638-
return remote_object.release();
1645+
assert(remote_object != nullptr);
1646+
auto* not_api = static_cast<v8_inspector::protocol::Runtime::RemoteObject*>(remote_object.release());
1647+
assert(not_api != nullptr);
1648+
return not_api;
16391649
}
16401650

16411651
// RemoteObject
16421652

1643-
void v8_inspector__RemoteObject__DELETE(v8_inspector::protocol::Runtime::API::RemoteObject* self) {
1653+
// To prevent extra allocations on every call a single default value value is reused everytime.
1654+
// It is expected that the precense of a value is checked before calling get* methods.
1655+
const v8_inspector::String16 DEFAULT_STRING = {"default"};
1656+
1657+
void v8_inspector__RemoteObject__DELETE(v8_inspector::protocol::Runtime::RemoteObject* self) {
16441658
delete self;
16451659
}
16461660

1661+
// RemoteObject - Type
1662+
const char* v8_inspector__RemoteObject__getType(v8_inspector::protocol::Runtime::RemoteObject* self) {
1663+
auto str = self->getType();
1664+
return toHeapCharPtr(str);
1665+
}
1666+
void v8_inspector__RemoteObject__setType(v8_inspector::protocol::Runtime::RemoteObject* self, const char* type, int type_len) {
1667+
self->setType(v8_inspector::String16::fromUTF8(type, type_len));
1668+
}
1669+
1670+
// RemoteObject - Subtype
1671+
bool v8_inspector__RemoteObject__hasSubtype(v8_inspector::protocol::Runtime::RemoteObject* self) {
1672+
return self->hasSubtype();
1673+
}
1674+
const char* v8_inspector__RemoteObject__getSubtype(v8_inspector::protocol::Runtime::RemoteObject* self) {
1675+
auto str = self->getSubtype(DEFAULT_STRING);
1676+
return toHeapCharPtr(str);
1677+
}
1678+
void v8_inspector__RemoteObject__setSubtype(v8_inspector::protocol::Runtime::RemoteObject* self, const char* subtype, int subtype_len) {
1679+
self->setSubtype(v8_inspector::String16::fromUTF8(subtype, subtype_len));
1680+
}
1681+
1682+
// RemoteObject - ClassName
1683+
bool v8_inspector__RemoteObject__hasClassName(v8_inspector::protocol::Runtime::RemoteObject* self) {
1684+
return self->hasClassName();
1685+
}
1686+
const char* v8_inspector__RemoteObject__getClassName(v8_inspector::protocol::Runtime::RemoteObject* self) {
1687+
auto str = self->getClassName(DEFAULT_STRING);
1688+
return toHeapCharPtr(str);
1689+
}
1690+
void v8_inspector__RemoteObject__setClassName(v8_inspector::protocol::Runtime::RemoteObject* self, const char* className, int className_len) {
1691+
self->setClassName(v8_inspector::String16::fromUTF8(className, className_len));
1692+
}
1693+
1694+
// RemoteObject - Value
1695+
bool v8_inspector__RemoteObject__hasValue(v8_inspector::protocol::Runtime::RemoteObject* self) {
1696+
return self->hasValue();
1697+
}
1698+
v8_inspector::protocol::Value* v8_inspector__RemoteObject__getValue(v8_inspector::protocol::Runtime::RemoteObject* self) {
1699+
return self->getValue(nullptr);
1700+
}
1701+
void v8_inspector__RemoteObject__setValue(v8_inspector::protocol::Runtime::RemoteObject* self, v8_inspector::protocol::Value* value) {
1702+
self->setValue(std::unique_ptr<v8_inspector::protocol::Value>(value));
1703+
}
1704+
1705+
//RemoteObject - UnserializableValue
1706+
bool v8_inspector__RemoteObject__hasUnserializableValue(v8_inspector::protocol::Runtime::RemoteObject* self) {
1707+
return self->hasUnserializableValue();
1708+
}
1709+
const char* v8_inspector__RemoteObject__getUnserializableValue(v8_inspector::protocol::Runtime::RemoteObject* self) {
1710+
auto str = self->getUnserializableValue(DEFAULT_STRING);
1711+
return toHeapCharPtr(str);
1712+
}
1713+
void v8_inspector__RemoteObject__setUnserializableValue(v8_inspector::protocol::Runtime::RemoteObject* self, const char* unserializableValue, int unserializableValue_len) {
1714+
self->setUnserializableValue(v8_inspector::String16::fromUTF8(unserializableValue, unserializableValue_len));
1715+
}
1716+
1717+
// RemoteObject - Description
1718+
bool v8_inspector__RemoteObject__hasDescription(v8_inspector::protocol::Runtime::RemoteObject* self) {
1719+
return self->hasDescription();
1720+
}
1721+
const char* v8_inspector__RemoteObject__getDescription(v8_inspector::protocol::Runtime::RemoteObject* self) {
1722+
auto str = self->getDescription(DEFAULT_STRING);
1723+
return toHeapCharPtr(str);
1724+
}
1725+
void v8_inspector__RemoteObject__setDescription(v8_inspector::protocol::Runtime::RemoteObject* self, const char* description, int description_len) {
1726+
self->setDescription(v8_inspector::String16::fromUTF8(description, description_len));
1727+
}
1728+
1729+
// RemoteObject - WebDriverValue
1730+
bool v8_inspector__RemoteObject__hasWebDriverValue(v8_inspector::protocol::Runtime::RemoteObject* self) {
1731+
return self->hasWebDriverValue();
1732+
}
1733+
v8_inspector::protocol::Runtime::WebDriverValue* v8_inspector__RemoteObject__getWebDriverValue(v8_inspector::protocol::Runtime::RemoteObject* self) {
1734+
return self->getWebDriverValue(nullptr);
1735+
}
1736+
void v8_inspector__RemoteObject__setWebDriverValue(v8_inspector::protocol::Runtime::RemoteObject* self, v8_inspector::protocol::Runtime::WebDriverValue* webDriverValue) {
1737+
self->setWebDriverValue(std::unique_ptr<v8_inspector::protocol::Runtime::WebDriverValue>(webDriverValue));
1738+
}
1739+
1740+
// RemoteObject - ObjectId
1741+
bool v8_inspector__RemoteObject__hasObjectId(v8_inspector::protocol::Runtime::RemoteObject* self) {
1742+
return self->hasObjectId();
1743+
}
1744+
const char* v8_inspector__RemoteObject__getObjectId(v8_inspector::protocol::Runtime::RemoteObject* self) {
1745+
auto str = self->getObjectId(DEFAULT_STRING);
1746+
return toHeapCharPtr(str);
1747+
}
1748+
void v8_inspector__RemoteObject__setObjectId(v8_inspector::protocol::Runtime::RemoteObject* self, const char* objectId, int objectId_len) {
1749+
self->setObjectId(v8_inspector::String16::fromUTF8(objectId, objectId_len));
1750+
}
1751+
1752+
// RemoteObject - Preview
1753+
bool v8_inspector__RemoteObject__hasPreview(v8_inspector::protocol::Runtime::RemoteObject* self) {
1754+
return self->hasPreview();
1755+
}
1756+
const v8_inspector::protocol::Runtime::ObjectPreview* v8_inspector__RemoteObject__getPreview(v8_inspector::protocol::Runtime::RemoteObject* self) {
1757+
return self->getPreview(nullptr);
1758+
}
1759+
void v8_inspector__RemoteObject__setPreview(v8_inspector::protocol::Runtime::RemoteObject* self, v8_inspector::protocol::Runtime::ObjectPreview* preview) {
1760+
self->setPreview(std::unique_ptr<v8_inspector::protocol::Runtime::ObjectPreview>(preview));
1761+
}
1762+
1763+
// RemoteObject - CustomPreview
1764+
bool v8_inspector__RemoteObject__hasCustomPreview(v8_inspector::protocol::Runtime::RemoteObject* self) {
1765+
return self->hasCustomPreview();
1766+
}
1767+
const v8_inspector::protocol::Runtime::CustomPreview* v8_inspector__RemoteObject__getCustomPreview(v8_inspector::protocol::Runtime::RemoteObject* self) {
1768+
return self->getCustomPreview(nullptr);
1769+
}
1770+
void v8_inspector__RemoteObject__setCustomPreview(v8_inspector::protocol::Runtime::RemoteObject* self, v8_inspector::protocol::Runtime::CustomPreview* customPreview) {
1771+
self->setCustomPreview(std::unique_ptr<v8_inspector::protocol::Runtime::CustomPreview>(customPreview));
1772+
}
1773+
16471774
// InspectorChannel
16481775

16491776
v8_inspector__Channel__IMPL * v8_inspector__Channel__IMPL__CREATE(v8::Isolate *isolate) {

src/binding.h

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -996,6 +996,9 @@ char* v8_inspector__Client__IMPL__descriptionForValueSubtype(
996996

997997
// RemoteObject
998998
typedef struct RemoteObject RemoteObject;
999+
typedef struct WebDriverValue WebDriverValue;
1000+
typedef struct ObjectPreview ObjectPreview;
1001+
typedef struct CustomPreview CustomPreview;
9991002

10001003
// InspectorSession
10011004

@@ -1005,7 +1008,7 @@ void v8_inspector__Session__dispatchProtocolMessage(InspectorSession *session, I
10051008
RemoteObject* v8_inspector__Session__wrapObject(
10061009
InspectorSession *session, Isolate *isolate,
10071010
const Context* ctx, const Value* val,
1008-
const char *grpname, int grpname_len, bool generatepreview);
1011+
const char *grpname, usize grpname_len, bool generatepreview);
10091012

10101013
// Inspector
10111014
typedef struct Inspector Inspector;
@@ -1022,3 +1025,56 @@ void v8_inspector__Inspector__ContextCreated(Inspector *self, const char *name,
10221025
const char *auxData, const usize auxData_len,
10231026
int contextGroupId,
10241027
const Context* context);
1028+
1029+
// RemoteObject
1030+
void v8_inspector__RemoteObject__DELETE(RemoteObject *self);
1031+
1032+
// RemoteObject - Type
1033+
const char* v8_inspector__RemoteObject__getType(RemoteObject* self);
1034+
void v8_inspector__RemoteObject__setType(RemoteObject* self, const char* type, int type_len);
1035+
1036+
// RemoteObject - Subtype
1037+
bool v8_inspector__RemoteObject__hasSubtype(RemoteObject* self);
1038+
const char* v8_inspector__RemoteObject__getSubtype(RemoteObject* self);
1039+
void v8_inspector__RemoteObject__setSubtype(RemoteObject* self, const char* subtype, int subtype_len);
1040+
1041+
// RemoteObject - ClassName
1042+
bool v8_inspector__RemoteObject__hasClassName(RemoteObject* self);
1043+
const char* v8_inspector__RemoteObject__getClassName(RemoteObject* self);
1044+
void v8_inspector__RemoteObject__setClassName(RemoteObject* self, const char* className, int className_len);
1045+
1046+
// RemoteObject - Value
1047+
bool v8_inspector__RemoteObject__hasValue(RemoteObject* self);
1048+
// Commented as these for now as the type should likely be the existing Value TBD
1049+
// v8_inspector::protocol::Value* v8_inspector__RemoteObject__getValue(Rem;eObject* self);
1050+
// void v8_inspector__RemoteObject__setValue(RemoteObject* self, v8_inspector::protocol::Value* value);
1051+
1052+
//RemoteObject - UnserializableValue
1053+
bool v8_inspector__RemoteObject__hasUnserializableValue(RemoteObject* self);
1054+
const char* v8_inspector__RemoteObject__getUnserializableValue(RemoteObject* self);
1055+
void v8_inspector__RemoteObject__setUnserializableValue(RemoteObject* self, const char* unserializableValue, int unserializableValue_len);
1056+
1057+
// RemoteObject - Description
1058+
bool v8_inspector__RemoteObject__hasDescription(RemoteObject* self);
1059+
const char* v8_inspector__RemoteObject__getDescription(RemoteObject* self);
1060+
void v8_inspector__RemoteObject__setDescription(RemoteObject* self, const char* description, int description_len);
1061+
1062+
// RemoteObject - WebDriverValue
1063+
bool v8_inspector__RemoteObject__hasWebDriverValue(RemoteObject* self);
1064+
WebDriverValue* v8_inspector__RemoteObject__getWebDriverValue(RemoteObject* self);
1065+
void v8_inspector__RemoteObject__setWebDriverValue(RemoteObject* self, WebDriverValue* webDriverValue);
1066+
1067+
// RemoteObject - ObjectId
1068+
bool v8_inspector__RemoteObject__hasObjectId(RemoteObject* self);
1069+
const char* v8_inspector__RemoteObject__getObjectId(RemoteObject* self);
1070+
void v8_inspector__RemoteObject__setObjectId(RemoteObject* self, const char* objectId, int objectId_len);
1071+
1072+
// RemoteObject - Preview
1073+
bool v8_inspector__RemoteObject__hasPreview(RemoteObject* self);
1074+
const ObjectPreview* v8_inspector__RemoteObject__getPreview(RemoteObject* self);
1075+
void v8_inspector__RemoteObject__setPreview(RemoteObject* self, ObjectPreview* preview);
1076+
1077+
// RemoteObject - CustomPreview
1078+
bool v8_inspector__RemoteObject__hasCustomPreview(RemoteObject* self);
1079+
const CustomPreview* v8_inspector__RemoteObject__getCustomPreview(RemoteObject* self);
1080+
void v8_inspector__RemoteObject__setCustomPreview(RemoteObject* self, CustomPreview* customPreview);

src/v8.zig

Lines changed: 114 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2678,17 +2678,126 @@ pub const InspectorSession = struct {
26782678
grpname.ptr,
26792679
grpname.len,
26802680
generatepreview,
2681-
);
2682-
if (remote_obj) {
2683-
return RemoteObject{ .handle = remote_obj };
2684-
} else return error.JsException;
2681+
).?;
2682+
return RemoteObject{ .handle = remote_obj };
26852683
}
26862684
};
26872685

2686+
/// RemoteObject is implemented as an interface to its members as opposed to a POD struct, since V8 is inconsistent with
2687+
/// returning owning and non-owning data. This is partly due to v8 using UTF16 strings.
2688+
/// NOTE: Some getters return owned memory (strings), while others return memory owned by V8 (objects).
2689+
/// The latter are not freed by the caller, but the former must be freed.
2690+
/// The getter methods short-circuit if the dafavalues is not available as converting the defaults to V8 causes unnecessary overhead.
26882691
pub const RemoteObject = struct {
26892692
handle: *c.RemoteObject,
26902693

2691-
pub fn deinit(self: *RemoteObject) void {
2694+
pub fn deinit(self: RemoteObject) void {
26922695
c.v8_inspector__RemoteObject__DELETE(self.handle);
26932696
}
2697+
2698+
// Type
2699+
pub fn getType(self: RemoteObject) []const u8 {
2700+
const type_ = c.v8_inspector__RemoteObject__getType(self.handle);
2701+
const idx = std.mem.indexOfSentinel(u8, 0, type_);
2702+
return type_[0..idx];
2703+
}
2704+
pub fn setType(self: RemoteObject, type_: []const u8) void {
2705+
c.v8_inspector__RemoteObject__setType(self.handle, type_.ptr, type_.len);
2706+
}
2707+
2708+
// Subtype
2709+
pub fn hasSubtype(self: RemoteObject) bool {
2710+
return c.v8_inspector__RemoteObject__hasSubtype(self.handle);
2711+
}
2712+
pub fn getSubtype(self: RemoteObject) ?[]const u8 {
2713+
if (!c.v8_inspector__RemoteObject__hasSubtype(self.handle)) {
2714+
return null;
2715+
}
2716+
2717+
const subtype = c.v8_inspector__RemoteObject__getSubtype(self.handle);
2718+
const idx = std.mem.indexOfSentinel(u8, 0, subtype);
2719+
return subtype[0..idx];
2720+
}
2721+
pub fn setSubtype(self: RemoteObject, subtype: []const u8) void {
2722+
c.v8_inspector__RemoteObject__setSubtype(self.handle, subtype.ptr, subtype.len);
2723+
}
2724+
2725+
// ClassName
2726+
pub fn hasClassName(self: RemoteObject) bool {
2727+
return c.v8_inspector__RemoteObject__hasClassName(self.handle);
2728+
}
2729+
pub fn getClassName(self: RemoteObject) ?[]const u8 {
2730+
if (!c.v8_inspector__RemoteObject__hasClassName(self.handle)) {
2731+
return null;
2732+
}
2733+
2734+
const class_name = c.v8_inspector__RemoteObject__getClassName(self.handle);
2735+
const idx = std.mem.indexOfSentinel(u8, 0, class_name);
2736+
return class_name[0..idx];
2737+
}
2738+
2739+
// Value
2740+
pub fn hasValue(self: RemoteObject) bool {
2741+
return c.v8_inspector__RemoteObject__hasValue(self.handle);
2742+
}
2743+
// TODO GET / SET
2744+
2745+
// UnserializableValue
2746+
pub fn hasUnserializableValue(self: RemoteObject) bool {
2747+
return c.v8_inspector__RemoteObject__hasUnserializableValue(self.handle);
2748+
}
2749+
// TODO GET / SET
2750+
2751+
// Description
2752+
pub fn hasDescription(self: RemoteObject) bool {
2753+
return c.v8_inspector__RemoteObject__hasDescription(self.handle);
2754+
}
2755+
pub fn getDescription(self: RemoteObject) ?[]const u8 {
2756+
if (!c.v8_inspector__RemoteObject__hasDescription(self.handle)) {
2757+
return null;
2758+
}
2759+
2760+
const description = c.v8_inspector__RemoteObject__getDescription(self.handle);
2761+
const idx = std.mem.indexOfSentinel(u8, 0, description);
2762+
return description[0..idx];
2763+
}
2764+
pub fn setDescription(self: RemoteObject, description: []const u8) void {
2765+
c.v8_inspector__RemoteObject__setDescription(self.handle, description.ptr, description.len);
2766+
}
2767+
2768+
// WebDriverValue
2769+
pub fn hasWebDriverValue(self: RemoteObject) bool {
2770+
return c.v8_inspector__RemoteObject__hasWebDriverValue(self.handle);
2771+
}
2772+
// TODO GET / SET
2773+
2774+
// ObjectId
2775+
pub fn hasObjectId(self: RemoteObject) bool {
2776+
return c.v8_inspector__RemoteObject__hasObjectId(self.handle);
2777+
}
2778+
pub fn getObjectId(self: RemoteObject) ?[]const u8 {
2779+
if (!c.v8_inspector__RemoteObject__hasObjectId(self.handle)) {
2780+
return null;
2781+
}
2782+
2783+
const object_id = c.v8_inspector__RemoteObject__getObjectId(self.handle);
2784+
const idx = std.mem.indexOfSentinel(u8, 0, object_id);
2785+
return object_id[0..idx];
2786+
}
2787+
2788+
pub fn setObjectId(self: RemoteObject, object_id: []const u8) void {
2789+
c.v8_inspector__RemoteObject__setObjectId(self.handle, object_id.ptr, object_id.len);
2790+
}
2791+
2792+
// Preview
2793+
pub fn hasPreview(self: RemoteObject) bool {
2794+
return c.v8_inspector__RemoteObject__hasPreview(self.handle);
2795+
}
2796+
// TODO GET / SET
2797+
2798+
// CustomPreview
2799+
pub fn hasCustomPreview(self: RemoteObject) bool {
2800+
return c.v8_inspector__RemoteObject__hasCustomPreview(self.handle);
2801+
}
2802+
// TODO GET / SET
26942803
};

0 commit comments

Comments
 (0)