Skip to content

Commit

Permalink
fix(userdata): Userdata are now u64
Browse files Browse the repository at this point in the history
`ud` is sometimes use to wrap a u64 which can't be expressed with an `int`.
In such instance, zig won't let create a `*anyopaque` pointer with a value of `0`.
  • Loading branch information
giann committed Sep 8, 2023
1 parent 0ea3057 commit ade7f43
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 37 deletions.
24 changes: 9 additions & 15 deletions src/buzz_api.zig
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ const ObjFiber = _obj.ObjFiber;
const ObjForeignStruct = _obj.ObjForeignStruct;
const NativeFn = _obj.NativeFn;
const NativeCtx = _obj.NativeCtx;
const UserData = _obj.UserData;
const TypeRegistry = memory.TypeRegistry;
const Parser = _parser.Parser;
const CodeGen = _codegen.CodeGen;
Expand Down Expand Up @@ -351,7 +350,7 @@ export fn bz_valueDump(value: Value, vm: *VM) void {

// Obj manipulations

export fn bz_valueToUserData(value: Value) *UserData {
export fn bz_valueToUserData(value: Value) u64 {
return ObjUserData.cast(value.obj()).?.userdata;
}

Expand Down Expand Up @@ -579,7 +578,7 @@ export fn bz_mapConcat(vm: *VM, map: Value, other_map: Value) Value {
}) catch @panic("Could not concatenate maps")).toValue();
}

export fn bz_newUserData(vm: *VM, userdata: *UserData) ?*ObjUserData {
export fn bz_newUserData(vm: *VM, userdata: u64) ?*ObjUserData {
return vm.gc.allocateObject(
ObjUserData,
ObjUserData{ .userdata = userdata },
Expand All @@ -588,7 +587,7 @@ export fn bz_newUserData(vm: *VM, userdata: *UserData) ?*ObjUserData {
};
}

export fn bz_getUserDataPtr(userdata: *ObjUserData) *UserData {
export fn bz_getUserDataPtr(userdata: *ObjUserData) u64 {
return userdata.userdata;
}

Expand Down Expand Up @@ -1400,9 +1399,9 @@ export fn bz_readZigValueFromBuffer(
ObjUserData,
.{
.userdata = @as(
*UserData,
u64,
if (ztype.Int.signedness == .unsigned)
@ptrFromInt(
@intCast(
@as(
usize,
@intCast(
Expand All @@ -1414,7 +1413,7 @@ export fn bz_readZigValueFromBuffer(
),
)
else
@ptrFromInt(
@intCast(
@as(
usize,
@intCast(
Expand Down Expand Up @@ -1514,12 +1513,7 @@ export fn bz_readZigValueFromBuffer(
const userdata = vm.gc.allocateObject(
ObjUserData,
.{
.userdata = @as(
*UserData,
@ptrFromInt(
std.mem.bytesToValue(u64, bytes[0..8]),
),
),
.userdata = std.mem.bytesToValue(u64, bytes[0..8]),
},
) catch @panic("Out of memory");

Expand Down Expand Up @@ -1557,7 +1551,7 @@ export fn bz_writeZigValueToBuffer(
.Int => {
switch (ztype.Int.bits) {
64 => {
const unwrapped = @intFromPtr(ObjUserData.cast(value.obj()).?.userdata);
const unwrapped = ObjUserData.cast(value.obj()).?.userdata;
var bytes = std.mem.asBytes(&unwrapped);

buffer.replaceRange(at, bytes.len, bytes) catch @panic("Out of memory");
Expand Down Expand Up @@ -1601,7 +1595,7 @@ export fn bz_writeZigValueToBuffer(
.Fn,
.Opaque,
=> {
const unwrapped = @intFromPtr(ObjUserData.cast(value.obj()).?.userdata);
const unwrapped = ObjUserData.cast(value.obj()).?.userdata;
var bytes = std.mem.asBytes(&unwrapped);

buffer.replaceRange(at, bytes.len, bytes) catch @panic("Out of memory");
Expand Down
8 changes: 3 additions & 5 deletions src/lib/buzz_api.zig
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ pub const Value = packed struct {
pub extern fn bz_valueToString(value: Value, len: *usize) ?[*]const u8;
pub extern fn bz_valueToCString(value: Value) ?[*:0]const u8;
pub extern fn bz_valueToObjUserData(value: Value) *ObjUserData;
pub extern fn bz_valueToUserData(value: Value) *UserData;
pub extern fn bz_valueToUserData(value: Value) u64;
pub extern fn bz_valueToObjTypeDef(value: Value) *ObjTypeDef;
pub extern fn bz_valueToForeignStructPtr(value: Value) [*]u8;

Expand Down Expand Up @@ -322,12 +322,10 @@ pub const ObjMap = opaque {
pub extern fn bz_mapNext(vm: *VM, map_value: Value, index: *Value) Value;
};

pub const UserData = anyopaque;

pub const ObjUserData = opaque {
pub extern fn bz_newUserData(vm: *VM, userdata: *UserData) ?*ObjUserData;
pub extern fn bz_newUserData(vm: *VM, userdata: u64) ?*ObjUserData;
pub extern fn bz_userDataToValue(userdata: *ObjUserData) Value;
pub extern fn bz_getUserDataPtr(userdata: *ObjUserData) *UserData;
pub extern fn bz_getUserDataPtr(userdata: *ObjUserData) u64;
};

pub const ObjObjectInstance = opaque {};
Expand Down
12 changes: 6 additions & 6 deletions src/lib/buzz_buffer.zig
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export fn BufferNew(ctx: *api.NativeCtx) c_int {
@panic("Out of memory");
};

if (api.ObjUserData.bz_newUserData(ctx.vm, @as(*api.UserData, @ptrCast(buffer)))) |userdata| {
if (api.ObjUserData.bz_newUserData(ctx.vm, @intFromPtr(buffer))) |userdata| {
ctx.vm.bz_pushUserData(userdata);

return 1;
Expand Down Expand Up @@ -40,8 +40,8 @@ const Buffer = struct {
buffer: std.ArrayList(u8),
cursor: usize = 0,

pub fn fromUserData(userdata: *api.UserData) *Self {
return @ptrCast(@alignCast(userdata));
pub fn fromUserData(userdata: u64) *Self {
return @ptrCast(@alignCast(@as(*anyopaque, @ptrFromInt(userdata))));
}

pub fn init(allocator: std.mem.Allocator, capacity: usize) !Self {
Expand Down Expand Up @@ -150,7 +150,7 @@ const Buffer = struct {

self.cursor += @sizeOf(u64);

return api.ObjUserData.bz_newUserData(vm, @ptrFromInt(number));
return api.ObjUserData.bz_newUserData(vm, number);
}

pub fn writeUserData(self: *Self, userdata: *api.ObjUserData) !void {
Expand All @@ -163,7 +163,7 @@ const Buffer = struct {
// Flag so we know it an integer
try writer.writeIntNative(
u64,
@intFromPtr(userdata.bz_getUserDataPtr()),
userdata.bz_getUserDataPtr(),
);
}

Expand Down Expand Up @@ -441,7 +441,7 @@ export fn BufferPtr(ctx: *api.NativeCtx) c_int {
ctx.vm.bz_push(
api.ObjUserData.bz_newUserData(
ctx.vm,
@ptrCast(&buffer.buffer.items.ptr[@intCast(at * alignment)]),
@intFromPtr(&buffer.buffer.items.ptr[@intCast(at * alignment)]),
).?.bz_userDataToValue(),
);

Expand Down
12 changes: 6 additions & 6 deletions src/lib/buzz_http.zig
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export fn HttpClientNew(ctx: *api.NativeCtx) c_int {
.proxy = getProxy(),
};

if (api.ObjUserData.bz_newUserData(ctx.vm, @ptrCast(client))) |userdata| {
if (api.ObjUserData.bz_newUserData(ctx.vm, @intFromPtr(client))) |userdata| {
ctx.vm.bz_pushUserData(userdata);

return 1;
Expand All @@ -40,7 +40,7 @@ export fn HttpClientNew(ctx: *api.NativeCtx) c_int {

export fn HttpClientDeinit(ctx: *api.NativeCtx) c_int {
const userdata = ctx.vm.bz_peek(0).bz_valueToUserData();
const client = @as(*http.Client, @ptrCast(@alignCast(userdata)));
const client = @as(*http.Client, @ptrCast(@alignCast(@as(*anyopaque, @ptrFromInt(userdata)))));

client.deinit();

Expand All @@ -49,7 +49,7 @@ export fn HttpClientDeinit(ctx: *api.NativeCtx) c_int {

export fn HttpClientSend(ctx: *api.NativeCtx) c_int {
const userdata = ctx.vm.bz_peek(3).bz_valueToUserData();
const client = @as(*http.Client, @ptrCast(@alignCast(userdata)));
const client = @as(*http.Client, @ptrCast(@alignCast(@as(*anyopaque, @ptrFromInt(userdata)))));

const method: http.Method = @enumFromInt(api.ObjEnumInstance.bz_getEnumCaseValue(ctx.vm.bz_peek(2)).integer());

Expand Down Expand Up @@ -99,7 +99,7 @@ export fn HttpClientSend(ctx: *api.NativeCtx) c_int {
return -1;
};

if (api.ObjUserData.bz_newUserData(ctx.vm, @ptrCast(request))) |request_ud| {
if (api.ObjUserData.bz_newUserData(ctx.vm, @intFromPtr(request))) |request_ud| {
ctx.vm.bz_pushUserData(request_ud);

return 1;
Expand All @@ -111,7 +111,7 @@ export fn HttpClientSend(ctx: *api.NativeCtx) c_int {
export fn HttpRequestWait(ctx: *api.NativeCtx) c_int {
const userdata_value = ctx.vm.bz_peek(0);
const userdata = userdata_value.bz_valueToUserData();
const request = @as(*http.Client.Request, @ptrCast(@alignCast(userdata)));
const request = @as(*http.Client.Request, @ptrCast(@alignCast(@as(*anyopaque, @ptrFromInt(userdata)))));

request.wait() catch |err| {
handleWaitError(ctx, err);
Expand All @@ -127,7 +127,7 @@ export fn HttpRequestWait(ctx: *api.NativeCtx) c_int {
export fn HttpRequestRead(ctx: *api.NativeCtx) c_int {
const userdata_value = ctx.vm.bz_peek(0);
const userdata = userdata_value.bz_valueToUserData();
const request = @as(*http.Client.Request, @ptrCast(@alignCast(userdata)));
const request = @as(*http.Client.Request, @ptrCast(@alignCast(@as(*anyopaque, @ptrFromInt(userdata)))));

var body_raw = std.ArrayList(u8).init(api.VM.allocator);
defer body_raw.deinit();
Expand Down
2 changes: 1 addition & 1 deletion src/lib/buzz_std.zig
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export fn toUd(ctx: *api.NativeCtx) c_int {

const userdata = api.ObjUserData.bz_newUserData(
ctx.vm,
@ptrFromInt(ud),
ud,
).?.bz_userDataToValue();

ctx.vm.bz_push(userdata);
Expand Down
6 changes: 2 additions & 4 deletions src/obj.zig
Original file line number Diff line number Diff line change
Expand Up @@ -644,15 +644,13 @@ pub const ObjPattern = struct {
}
};

pub const UserData = anyopaque;

/// User data, type around an opaque pointer
pub const ObjUserData = struct {
const Self = @This();

obj: Obj = .{ .obj_type = .UserData },

userdata: *UserData,
userdata: u64,

pub fn mark(_: *Self, _: *GarbageCollector) void {}

Expand Down Expand Up @@ -3812,7 +3810,7 @@ pub fn objToString(writer: *const std.ArrayList(u8).Writer, obj: *Obj) (Allocato
.UserData => {
var userdata: *ObjUserData = ObjUserData.cast(obj).?;

try writer.print("userdata: 0x{x}", .{@intFromPtr(userdata)});
try writer.print("userdata: 0x{x}", .{userdata.userdata});
},
.ForeignStruct => {
const foreign = ObjForeignStruct.cast(obj).?;
Expand Down

0 comments on commit ade7f43

Please sign in to comment.