mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-02-04 14:33:47 +00:00
port Platform and Inspector to use v8's C handles/functions directly
This commit is contained in:
@@ -119,8 +119,10 @@ pub fn deinit(self: *Env) void {
|
||||
self.allocator.free(self.templates);
|
||||
}
|
||||
|
||||
pub fn newInspector(self: *Env, arena: Allocator, ctx: anytype) !Inspector {
|
||||
return Inspector.init(arena, self.isolate, ctx);
|
||||
pub fn newInspector(self: *Env, arena: Allocator, ctx: anytype) !*Inspector {
|
||||
const inspector = try arena.create(Inspector);
|
||||
try Inspector.init(inspector, self.isolate.handle, ctx);
|
||||
return inspector;
|
||||
}
|
||||
|
||||
pub fn runMicrotasks(self: *const Env) void {
|
||||
@@ -128,11 +130,11 @@ pub fn runMicrotasks(self: *const Env) void {
|
||||
}
|
||||
|
||||
pub fn pumpMessageLoop(self: *const Env) bool {
|
||||
return self.platform.inner.pumpMessageLoop(self.isolate, false);
|
||||
return v8.c.v8__Platform__PumpMessageLoop(self.platform.handle, self.isolate.handle, false);
|
||||
}
|
||||
|
||||
pub fn runIdleTasks(self: *const Env) void {
|
||||
return self.platform.inner.runIdleTasks(self.isolate, 1);
|
||||
v8.c.v8__Platform__RunIdleTasks(self.platform.handle, self.isolate.handle, 1);
|
||||
}
|
||||
pub fn newExecutionWorld(self: *Env) !ExecutionWorld {
|
||||
return .{
|
||||
|
||||
@@ -37,16 +37,6 @@ pub fn id(self: *const Function) u32 {
|
||||
return @as(u32, @bitCast(v8.c.v8__Object__GetIdentityHash(@ptrCast(self.handle))));
|
||||
}
|
||||
|
||||
pub fn getName(self: *const Function, allocator: Allocator) ![]const u8 {
|
||||
const name = v8.c.v8__Function__GetName(self.handle).?;
|
||||
return self.context.valueToString(name, .{ .allocator = allocator });
|
||||
}
|
||||
|
||||
pub fn setName(self: *const Function, name: []const u8) void {
|
||||
const v8_name = v8.String.initUtf8(self.context.isolate, name);
|
||||
self.func.castToFunction().setName(v8_name);
|
||||
}
|
||||
|
||||
pub fn withThis(self: *const Function, value: anytype) !Function {
|
||||
const this_obj = if (@TypeOf(value) == js.Object)
|
||||
value.js_obj
|
||||
@@ -181,8 +171,7 @@ fn getThis(self: *const Function) v8.Object {
|
||||
}
|
||||
|
||||
pub fn src(self: *const Function) ![]const u8 {
|
||||
const value = self.func.castToFunction().toValue();
|
||||
return self.context.valueToString(value, .{});
|
||||
return self.context.valueToString(.{ .handle = @ptrCast(self.handle) }, .{});
|
||||
}
|
||||
|
||||
pub fn getPropertyValue(self: *const Function, name: []const u8) !?js.Value {
|
||||
|
||||
@@ -23,43 +23,76 @@ const v8 = js.v8;
|
||||
const Context = @import("Context.zig");
|
||||
|
||||
const Allocator = std.mem.Allocator;
|
||||
const RndGen = std.Random.DefaultPrng;
|
||||
|
||||
const CONTEST_GROUP_ID = 1;
|
||||
const CLIENT_TRUST_LEVEL = 1;
|
||||
|
||||
const Inspector = @This();
|
||||
|
||||
pub const RemoteObject = v8.RemoteObject;
|
||||
|
||||
isolate: v8.Isolate,
|
||||
inner: *v8.Inspector,
|
||||
session: v8.InspectorSession,
|
||||
handle: *v8.c.Inspector,
|
||||
isolate: *v8.c.Isolate,
|
||||
client: Client,
|
||||
channel: Channel,
|
||||
session: Session,
|
||||
rnd: RndGen = RndGen.init(0),
|
||||
ctx_handle: ?*const v8.c.Context = null,
|
||||
|
||||
// We expect allocator to be an arena
|
||||
pub fn init(allocator: Allocator, isolate: v8.Isolate, ctx: anytype) !Inspector {
|
||||
// Note: This initializes the pre-allocated inspector in-place
|
||||
pub fn init(self: *Inspector, isolate: *v8.c.Isolate, ctx: anytype) !void {
|
||||
const ContextT = @TypeOf(ctx);
|
||||
|
||||
const InspectorContainer = switch (@typeInfo(ContextT)) {
|
||||
const Container = switch (@typeInfo(ContextT)) {
|
||||
.@"struct" => ContextT,
|
||||
.pointer => |ptr| ptr.child,
|
||||
.void => NoopInspector,
|
||||
else => @compileError("invalid context type"),
|
||||
};
|
||||
|
||||
// If necessary, turn a void context into something we can safely ptrCast
|
||||
const safe_context: *anyopaque = if (ContextT == void) @ptrCast(@constCast(&{})) else ctx;
|
||||
|
||||
const channel = v8.InspectorChannel.init(
|
||||
// Initialize the fields that callbacks need first
|
||||
self.* = .{
|
||||
.handle = undefined,
|
||||
.isolate = isolate,
|
||||
.client = undefined,
|
||||
.channel = undefined,
|
||||
.rnd = RndGen.init(0),
|
||||
.ctx_handle = null,
|
||||
.session = undefined,
|
||||
};
|
||||
|
||||
// Create client and set inspector data BEFORE creating the inspector
|
||||
// because V8 will call generateUniqueId during inspector creation
|
||||
const client = Client.init();
|
||||
self.client = client;
|
||||
client.setInspector(self);
|
||||
|
||||
// Now create the inspector - generateUniqueId will work because data is set
|
||||
const handle = v8.c.v8_inspector__Inspector__Create(isolate, client.handle).?;
|
||||
self.handle = handle;
|
||||
|
||||
// Create the channel
|
||||
const channel = Channel.init(
|
||||
safe_context,
|
||||
InspectorContainer.onInspectorResponse,
|
||||
InspectorContainer.onInspectorEvent,
|
||||
InspectorContainer.onRunMessageLoopOnPause,
|
||||
InspectorContainer.onQuitMessageLoopOnPause,
|
||||
Container.onInspectorResponse,
|
||||
Container.onInspectorEvent,
|
||||
Container.onRunMessageLoopOnPause,
|
||||
Container.onQuitMessageLoopOnPause,
|
||||
isolate,
|
||||
);
|
||||
self.channel = channel;
|
||||
channel.setInspector(self);
|
||||
|
||||
const client = v8.InspectorClient.init();
|
||||
|
||||
const inner = try allocator.create(v8.Inspector);
|
||||
v8.Inspector.init(inner, client, channel, isolate);
|
||||
return .{ .inner = inner, .isolate = isolate, .session = inner.connect() };
|
||||
// Create the session
|
||||
const session_handle = v8.c.v8_inspector__Inspector__Connect(
|
||||
handle,
|
||||
CONTEST_GROUP_ID,
|
||||
channel.handle,
|
||||
CLIENT_TRUST_LEVEL,
|
||||
).?;
|
||||
self.session = .{ .handle = session_handle };
|
||||
}
|
||||
|
||||
pub fn deinit(self: *const Inspector) void {
|
||||
@@ -68,7 +101,9 @@ pub fn deinit(self: *const Inspector) void {
|
||||
defer temp_scope.deinit();
|
||||
|
||||
self.session.deinit();
|
||||
self.inner.deinit();
|
||||
self.client.deinit();
|
||||
self.channel.deinit();
|
||||
v8.c.v8_inspector__Inspector__DELETE(self.handle);
|
||||
}
|
||||
|
||||
pub fn send(self: *const Inspector, msg: []const u8) void {
|
||||
@@ -76,9 +111,9 @@ pub fn send(self: *const Inspector, msg: []const u8) void {
|
||||
// available when doing this. Pages (and thus the HandleScope)
|
||||
// comes and goes, but CDP can keep sending messages.
|
||||
const isolate = self.isolate;
|
||||
var temp_scope: v8.HandleScope = undefined;
|
||||
v8.HandleScope.init(&temp_scope, isolate);
|
||||
defer temp_scope.deinit();
|
||||
var temp_scope: v8.c.HandleScope = undefined;
|
||||
v8.c.v8__HandleScope__CONSTRUCT(&temp_scope, isolate);
|
||||
defer v8.c.v8__HandleScope__DESTRUCT(&temp_scope);
|
||||
|
||||
self.session.dispatchProtocolMessage(isolate, msg);
|
||||
}
|
||||
@@ -99,7 +134,27 @@ pub fn contextCreated(
|
||||
aux_data: ?[]const u8,
|
||||
is_default_context: bool,
|
||||
) void {
|
||||
self.inner.contextCreated(context.v8_context, name, origin, aux_data, is_default_context);
|
||||
_ = is_default_context; // TODO: Should this be passed to the C API?
|
||||
var auxData_ptr: [*c]const u8 = undefined;
|
||||
var auxData_len: usize = undefined;
|
||||
if (aux_data) |data| {
|
||||
auxData_ptr = data.ptr;
|
||||
auxData_len = data.len;
|
||||
} else {
|
||||
auxData_ptr = null;
|
||||
auxData_len = 0;
|
||||
}
|
||||
v8.c.v8_inspector__Inspector__ContextCreated(
|
||||
self.handle,
|
||||
name.ptr,
|
||||
name.len,
|
||||
origin.ptr,
|
||||
origin.len,
|
||||
auxData_ptr,
|
||||
auxData_len,
|
||||
CONTEST_GROUP_ID,
|
||||
context.v8_context.handle,
|
||||
);
|
||||
}
|
||||
|
||||
// Retrieves the RemoteObject for a given value.
|
||||
@@ -118,9 +173,9 @@ pub fn getRemoteObject(
|
||||
// We do not want to expose this as a parameter for now
|
||||
const generate_preview = false;
|
||||
return self.session.wrapObject(
|
||||
context.isolate,
|
||||
context.v8_context,
|
||||
js_value,
|
||||
context.isolate.handle,
|
||||
context.v8_context.handle,
|
||||
js_value.handle,
|
||||
group,
|
||||
generate_preview,
|
||||
);
|
||||
@@ -136,15 +191,210 @@ pub fn getNodePtr(self: *const Inspector, allocator: Allocator, object_id: []con
|
||||
const unwrapped = try self.session.unwrapObject(allocator, object_id);
|
||||
// The values context and groupId are not used here
|
||||
const js_val = unwrapped.value;
|
||||
if (js_val.isObject() == false) {
|
||||
if (!v8.c.v8__Value__IsObject(js_val)) {
|
||||
return error.ObjectIdIsNotANode;
|
||||
}
|
||||
const Node = @import("../webapi/Node.zig");
|
||||
return Context.typeTaggedAnyOpaque(*Node, js_val.castTo(v8.Object)) catch {
|
||||
// Wrap the C handle in a v8.Object for typeTaggedAnyOpaque
|
||||
const js_obj = v8.Object{ .handle = js_val };
|
||||
return Context.typeTaggedAnyOpaque(*Node, js_obj) catch {
|
||||
return error.ObjectIdIsNotANode;
|
||||
};
|
||||
}
|
||||
|
||||
pub const RemoteObject = struct {
|
||||
handle: *v8.c.RemoteObject,
|
||||
|
||||
pub fn deinit(self: RemoteObject) void {
|
||||
v8.c.v8_inspector__RemoteObject__DELETE(self.handle);
|
||||
}
|
||||
|
||||
pub fn getType(self: RemoteObject, allocator: Allocator) ![]const u8 {
|
||||
var ctype_: v8.c.CZigString = .{ .ptr = null, .len = 0 };
|
||||
if (!v8.c.v8_inspector__RemoteObject__getType(self.handle, &allocator, &ctype_)) return error.V8AllocFailed;
|
||||
return cZigStringToString(ctype_) orelse return error.InvalidType;
|
||||
}
|
||||
|
||||
pub fn getSubtype(self: RemoteObject, allocator: Allocator) !?[]const u8 {
|
||||
if (!v8.c.v8_inspector__RemoteObject__hasSubtype(self.handle)) return null;
|
||||
|
||||
var csubtype: v8.c.CZigString = .{ .ptr = null, .len = 0 };
|
||||
if (!v8.c.v8_inspector__RemoteObject__getSubtype(self.handle, &allocator, &csubtype)) return error.V8AllocFailed;
|
||||
return cZigStringToString(csubtype);
|
||||
}
|
||||
|
||||
pub fn getClassName(self: RemoteObject, allocator: Allocator) !?[]const u8 {
|
||||
if (!v8.c.v8_inspector__RemoteObject__hasClassName(self.handle)) return null;
|
||||
|
||||
var cclass_name: v8.c.CZigString = .{ .ptr = null, .len = 0 };
|
||||
if (!v8.c.v8_inspector__RemoteObject__getClassName(self.handle, &allocator, &cclass_name)) return error.V8AllocFailed;
|
||||
return cZigStringToString(cclass_name);
|
||||
}
|
||||
|
||||
pub fn getDescription(self: RemoteObject, allocator: Allocator) !?[]const u8 {
|
||||
if (!v8.c.v8_inspector__RemoteObject__hasDescription(self.handle)) return null;
|
||||
|
||||
var description: v8.c.CZigString = .{ .ptr = null, .len = 0 };
|
||||
if (!v8.c.v8_inspector__RemoteObject__getDescription(self.handle, &allocator, &description)) return error.V8AllocFailed;
|
||||
return cZigStringToString(description);
|
||||
}
|
||||
|
||||
pub fn getObjectId(self: RemoteObject, allocator: Allocator) !?[]const u8 {
|
||||
if (!v8.c.v8_inspector__RemoteObject__hasObjectId(self.handle)) return null;
|
||||
|
||||
var cobject_id: v8.c.CZigString = .{ .ptr = null, .len = 0 };
|
||||
if (!v8.c.v8_inspector__RemoteObject__getObjectId(self.handle, &allocator, &cobject_id)) return error.V8AllocFailed;
|
||||
return cZigStringToString(cobject_id);
|
||||
}
|
||||
};
|
||||
|
||||
const Session = struct {
|
||||
handle: *v8.c.InspectorSession,
|
||||
|
||||
fn deinit(self: Session) void {
|
||||
v8.c.v8_inspector__Session__DELETE(self.handle);
|
||||
}
|
||||
|
||||
fn dispatchProtocolMessage(self: Session, isolate: *v8.c.Isolate, msg: []const u8) void {
|
||||
v8.c.v8_inspector__Session__dispatchProtocolMessage(
|
||||
self.handle,
|
||||
isolate,
|
||||
msg.ptr,
|
||||
msg.len,
|
||||
);
|
||||
}
|
||||
|
||||
fn wrapObject(
|
||||
self: Session,
|
||||
isolate: *v8.c.Isolate,
|
||||
ctx: *const v8.c.Context,
|
||||
val: *const v8.c.Value,
|
||||
grpname: []const u8,
|
||||
generatepreview: bool,
|
||||
) !RemoteObject {
|
||||
const remote_object = v8.c.v8_inspector__Session__wrapObject(
|
||||
self.handle,
|
||||
isolate,
|
||||
ctx,
|
||||
val,
|
||||
grpname.ptr,
|
||||
grpname.len,
|
||||
generatepreview,
|
||||
).?;
|
||||
return .{ .handle = remote_object };
|
||||
}
|
||||
|
||||
fn unwrapObject(
|
||||
self: Session,
|
||||
allocator: Allocator,
|
||||
object_id: []const u8,
|
||||
) !UnwrappedObject {
|
||||
const in_object_id = v8.c.CZigString{
|
||||
.ptr = object_id.ptr,
|
||||
.len = object_id.len,
|
||||
};
|
||||
var out_error: v8.c.CZigString = .{ .ptr = null, .len = 0 };
|
||||
var out_value_handle: ?*v8.c.Value = null;
|
||||
var out_context_handle: ?*v8.c.Context = null;
|
||||
var out_object_group: v8.c.CZigString = .{ .ptr = null, .len = 0 };
|
||||
|
||||
const result = v8.c.v8_inspector__Session__unwrapObject(
|
||||
self.handle,
|
||||
&allocator,
|
||||
&out_error,
|
||||
in_object_id,
|
||||
&out_value_handle,
|
||||
&out_context_handle,
|
||||
&out_object_group,
|
||||
);
|
||||
|
||||
if (!result) {
|
||||
const error_str = cZigStringToString(out_error) orelse return error.UnwrapFailed;
|
||||
std.log.err("unwrapObject failed: {s}", .{error_str});
|
||||
return error.UnwrapFailed;
|
||||
}
|
||||
|
||||
return .{
|
||||
.value = out_value_handle.?,
|
||||
.context = out_context_handle.?,
|
||||
.object_group = cZigStringToString(out_object_group),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const UnwrappedObject = struct {
|
||||
value: *const v8.c.Value,
|
||||
context: *const v8.c.Context,
|
||||
object_group: ?[]const u8,
|
||||
};
|
||||
|
||||
const Channel = struct {
|
||||
handle: *v8.c.InspectorChannelImpl,
|
||||
|
||||
// callbacks
|
||||
ctx: *anyopaque,
|
||||
onNotif: onNotifFn = undefined,
|
||||
onResp: onRespFn = undefined,
|
||||
onRunMessageLoopOnPause: onRunMessageLoopOnPauseFn = undefined,
|
||||
onQuitMessageLoopOnPause: onQuitMessageLoopOnPauseFn = undefined,
|
||||
|
||||
pub const onNotifFn = *const fn (ctx: *anyopaque, msg: []const u8) void;
|
||||
pub const onRespFn = *const fn (ctx: *anyopaque, call_id: u32, msg: []const u8) void;
|
||||
pub const onRunMessageLoopOnPauseFn = *const fn (ctx: *anyopaque, context_group_id: u32) void;
|
||||
pub const onQuitMessageLoopOnPauseFn = *const fn (ctx: *anyopaque) void;
|
||||
|
||||
fn init(
|
||||
ctx: *anyopaque,
|
||||
onResp: onRespFn,
|
||||
onNotif: onNotifFn,
|
||||
onRunMessageLoopOnPause: onRunMessageLoopOnPauseFn,
|
||||
onQuitMessageLoopOnPause: onQuitMessageLoopOnPauseFn,
|
||||
isolate: *v8.c.Isolate,
|
||||
) Channel {
|
||||
const handle = v8.c.v8_inspector__Channel__IMPL__CREATE(isolate);
|
||||
return .{
|
||||
.handle = handle,
|
||||
.ctx = ctx,
|
||||
.onResp = onResp,
|
||||
.onNotif = onNotif,
|
||||
.onRunMessageLoopOnPause = onRunMessageLoopOnPause,
|
||||
.onQuitMessageLoopOnPause = onQuitMessageLoopOnPause,
|
||||
};
|
||||
}
|
||||
|
||||
fn deinit(self: Channel) void {
|
||||
v8.c.v8_inspector__Channel__IMPL__DELETE(self.handle);
|
||||
}
|
||||
|
||||
fn setInspector(self: Channel, inspector: *anyopaque) void {
|
||||
v8.c.v8_inspector__Channel__IMPL__SET_DATA(self.handle, inspector);
|
||||
}
|
||||
|
||||
fn resp(self: Channel, call_id: u32, msg: []const u8) void {
|
||||
self.onResp(self.ctx, call_id, msg);
|
||||
}
|
||||
|
||||
fn notif(self: Channel, msg: []const u8) void {
|
||||
self.onNotif(self.ctx, msg);
|
||||
}
|
||||
};
|
||||
|
||||
const Client = struct {
|
||||
handle: *v8.c.InspectorClientImpl,
|
||||
|
||||
fn init() Client {
|
||||
return .{ .handle = v8.c.v8_inspector__Client__IMPL__CREATE() };
|
||||
}
|
||||
|
||||
fn deinit(self: Client) void {
|
||||
v8.c.v8_inspector__Client__IMPL__DELETE(self.handle);
|
||||
}
|
||||
|
||||
fn setInspector(self: Client, inspector: *anyopaque) void {
|
||||
v8.c.v8_inspector__Client__IMPL__SET_DATA(self.handle, inspector);
|
||||
}
|
||||
};
|
||||
|
||||
const NoopInspector = struct {
|
||||
pub fn onInspectorResponse(_: *anyopaque, _: u32, _: []const u8) void {}
|
||||
pub fn onInspectorEvent(_: *anyopaque, _: []const u8) void {}
|
||||
@@ -152,15 +402,107 @@ const NoopInspector = struct {
|
||||
pub fn onQuitMessageLoopOnPause(_: *anyopaque) void {}
|
||||
};
|
||||
|
||||
pub fn getTaggedAnyOpaque(value: v8.Value) ?*js.TaggedAnyOpaque {
|
||||
if (value.isObject() == false) {
|
||||
fn fromData(data: *anyopaque) *Inspector {
|
||||
return @ptrCast(@alignCast(data));
|
||||
}
|
||||
|
||||
pub fn getTaggedAnyOpaque(value: *const v8.c.Value) ?*js.TaggedAnyOpaque {
|
||||
if (!v8.c.v8__Value__IsObject(value)) {
|
||||
return null;
|
||||
}
|
||||
const obj = value.castTo(v8.Object);
|
||||
if (obj.internalFieldCount() == 0) {
|
||||
const internal_field_count = v8.c.v8__Object__InternalFieldCount(value);
|
||||
if (internal_field_count == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const external_data = obj.getInternalField(0).castTo(v8.External).get().?;
|
||||
const external_value = v8.c.v8__Object__GetInternalField(value, 0).?;
|
||||
const external_data = v8.c.v8__External__Value(external_value).?;
|
||||
return @ptrCast(@alignCast(external_data));
|
||||
}
|
||||
|
||||
fn cZigStringToString(s: v8.c.CZigString) ?[]const u8 {
|
||||
if (s.ptr == null) return null;
|
||||
return s.ptr[0..s.len];
|
||||
}
|
||||
|
||||
// C export functions for Inspector callbacks
|
||||
pub export fn v8_inspector__Client__IMPL__generateUniqueId(
|
||||
_: *v8.c.InspectorClientImpl,
|
||||
data: *anyopaque,
|
||||
) callconv(.c) i64 {
|
||||
const inspector: *Inspector = @ptrCast(@alignCast(data));
|
||||
return inspector.rnd.random().int(i64);
|
||||
}
|
||||
|
||||
pub export fn v8_inspector__Client__IMPL__runMessageLoopOnPause(
|
||||
_: *v8.c.InspectorClientImpl,
|
||||
data: *anyopaque,
|
||||
ctx_group_id: c_int,
|
||||
) callconv(.c) void {
|
||||
const inspector: *Inspector = @ptrCast(@alignCast(data));
|
||||
inspector.channel.onRunMessageLoopOnPause(inspector.channel.ctx, @intCast(ctx_group_id));
|
||||
}
|
||||
|
||||
pub export fn v8_inspector__Client__IMPL__quitMessageLoopOnPause(
|
||||
_: *v8.c.InspectorClientImpl,
|
||||
data: *anyopaque,
|
||||
) callconv(.c) void {
|
||||
const inspector: *Inspector = @ptrCast(@alignCast(data));
|
||||
inspector.channel.onQuitMessageLoopOnPause(inspector.channel.ctx);
|
||||
}
|
||||
|
||||
pub export fn v8_inspector__Client__IMPL__runIfWaitingForDebugger(
|
||||
_: *v8.c.InspectorClientImpl,
|
||||
_: *anyopaque,
|
||||
_: c_int,
|
||||
) callconv(.c) void {
|
||||
// TODO
|
||||
}
|
||||
|
||||
pub export fn v8_inspector__Client__IMPL__consoleAPIMessage(
|
||||
_: *v8.c.InspectorClientImpl,
|
||||
_: *anyopaque,
|
||||
_: c_int,
|
||||
_: v8.c.MessageErrorLevel,
|
||||
_: *v8.c.StringView,
|
||||
_: *v8.c.StringView,
|
||||
_: c_uint,
|
||||
_: c_uint,
|
||||
_: *v8.c.StackTrace,
|
||||
) callconv(.c) void {}
|
||||
|
||||
pub export fn v8_inspector__Client__IMPL__ensureDefaultContextInGroup(
|
||||
_: *v8.c.InspectorClientImpl,
|
||||
data: *anyopaque,
|
||||
) callconv(.c) ?*const v8.c.Context {
|
||||
const inspector: *Inspector = @ptrCast(@alignCast(data));
|
||||
return inspector.ctx_handle;
|
||||
}
|
||||
|
||||
pub export fn v8_inspector__Channel__IMPL__sendResponse(
|
||||
_: *v8.c.InspectorChannelImpl,
|
||||
data: *anyopaque,
|
||||
call_id: c_int,
|
||||
msg: [*c]u8,
|
||||
length: usize,
|
||||
) callconv(.c) void {
|
||||
const inspector: *Inspector = @ptrCast(@alignCast(data));
|
||||
inspector.channel.resp(@as(u32, @intCast(call_id)), msg[0..length]);
|
||||
}
|
||||
|
||||
pub export fn v8_inspector__Channel__IMPL__sendNotification(
|
||||
_: *v8.c.InspectorChannelImpl,
|
||||
data: *anyopaque,
|
||||
msg: [*c]u8,
|
||||
length: usize,
|
||||
) callconv(.c) void {
|
||||
const inspector: *Inspector = @ptrCast(@alignCast(data));
|
||||
inspector.channel.notif(msg[0..length]);
|
||||
}
|
||||
|
||||
pub export fn v8_inspector__Channel__IMPL__flushProtocolNotifications(
|
||||
_: *v8.c.InspectorChannelImpl,
|
||||
_: *anyopaque,
|
||||
) callconv(.c) void {
|
||||
// TODO
|
||||
}
|
||||
|
||||
@@ -20,20 +20,22 @@ const js = @import("js.zig");
|
||||
const v8 = js.v8;
|
||||
|
||||
const Platform = @This();
|
||||
inner: v8.Platform,
|
||||
handle: *v8.c.Platform,
|
||||
|
||||
pub fn init() !Platform {
|
||||
if (v8.initV8ICU() == false) {
|
||||
if (v8.c.v8__V8__InitializeICU() == false) {
|
||||
return error.FailedToInitializeICU;
|
||||
}
|
||||
const platform = v8.Platform.initDefault(0, true);
|
||||
v8.initV8Platform(platform);
|
||||
v8.initV8();
|
||||
return .{ .inner = platform };
|
||||
// 0 - threadpool size, 0 == let v8 decide
|
||||
// 1 - idle_task_support, 1 == enabled
|
||||
const handle = v8.c.v8__Platform__NewDefaultPlatform(0, 1).?;
|
||||
v8.c.v8__V8__InitializePlatform(handle);
|
||||
v8.c.v8__V8__Initialize();
|
||||
return .{ .handle = handle };
|
||||
}
|
||||
|
||||
pub fn deinit(self: Platform) void {
|
||||
_ = v8.deinitV8();
|
||||
v8.deinitV8Platform();
|
||||
self.inner.deinit();
|
||||
_ = v8.c.v8__V8__Dispose();
|
||||
v8.c.v8__V8__DisposePlatform();
|
||||
v8.c.v8__Platform__DELETE(self.handle);
|
||||
}
|
||||
|
||||
@@ -481,7 +481,7 @@ pub export fn v8_inspector__Client__IMPL__valueSubtype(
|
||||
_: *v8.c.InspectorClientImpl,
|
||||
c_value: *const v8.C_Value,
|
||||
) callconv(.c) [*c]const u8 {
|
||||
const external_entry = Inspector.getTaggedAnyOpaque(.{ .handle = c_value }) orelse return null;
|
||||
const external_entry = Inspector.getTaggedAnyOpaque(c_value) orelse return null;
|
||||
return if (external_entry.subtype) |st| @tagName(st) else null;
|
||||
}
|
||||
|
||||
@@ -498,10 +498,17 @@ pub export fn v8_inspector__Client__IMPL__descriptionForValueSubtype(
|
||||
|
||||
// We _must_ include a non-null description in order for the subtype value
|
||||
// to be included. Besides that, I don't know if the value has any meaning
|
||||
const external_entry = Inspector.getTaggedAnyOpaque(.{ .handle = c_value }) orelse return null;
|
||||
const external_entry = Inspector.getTaggedAnyOpaque(c_value) orelse return null;
|
||||
return if (external_entry.subtype == null) null else "";
|
||||
}
|
||||
|
||||
/// Enables C to allocate using the given Zig allocator
|
||||
pub export fn zigAlloc(self: *anyopaque, bytes: usize) callconv(.c) ?[*]u8 {
|
||||
const allocator: *Allocator = @ptrCast(@alignCast(self));
|
||||
const allocated_bytes = allocator.alloc(u8, bytes) catch return null;
|
||||
return allocated_bytes.ptr;
|
||||
}
|
||||
|
||||
test "TaggedAnyOpaque" {
|
||||
// If we grow this, fine, but it should be a conscious decision
|
||||
try std.testing.expectEqual(24, @sizeOf(TaggedAnyOpaque));
|
||||
|
||||
@@ -331,7 +331,7 @@ pub fn BrowserContext(comptime CDP_T: type) type {
|
||||
node_registry: Node.Registry,
|
||||
node_search_list: Node.Search.List,
|
||||
|
||||
inspector: js.Inspector,
|
||||
inspector: *js.Inspector,
|
||||
isolated_worlds: std.ArrayListUnmanaged(IsolatedWorld),
|
||||
|
||||
http_proxy_changed: bool = false,
|
||||
|
||||
@@ -135,7 +135,7 @@ fn run(
|
||||
return err;
|
||||
};
|
||||
|
||||
return value.toString(arena);
|
||||
return value.toString(.{ .allocator = arena });
|
||||
}
|
||||
|
||||
const Writer = struct {
|
||||
|
||||
Reference in New Issue
Block a user