Skip to content

Commit 4c9ef05

Browse files
Restore Zig glue argument wrapper names
1 parent 441c72f commit 4c9ef05

6 files changed

Lines changed: 87 additions & 5 deletions

File tree

src/cli/test/parallel_cli_runner.zig

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2551,9 +2551,11 @@ fn customGlueZigCompiles(io: std.Io, allocator: Allocator, env: *const CaseEnv,
25512551
\\ var host: abi.RocHost = undefined;
25522552
\\ var box: abi.RocBox = null;
25532553
\\ var str: abi.RocStr = undefined;
2554+
\\ var builder_args: abi.BuilderPrint_valueArgs = undefined;
25542555
\\ _ = &host;
25552556
\\ _ = &box;
25562557
\\ _ = &str;
2558+
\\ _ = &builder_args;
25572559
\\}}
25582560
, .{"roc_platform_abi.zig"}) catch |err|
25592561
return customInfraFailure(allocator, timer, "failed to render test Zig source: {}", .{err});
@@ -2612,6 +2614,7 @@ fn customGlueZig(io: std.Io, allocator: Allocator, env: *const CaseEnv, timer: *
26122614
"pub fn decrefBox",
26132615
"pub fn decrefBoxWith",
26142616
"pub extern fn roc_alloc(length: usize, alignment: usize) callconv(.c) ?*anyopaque;",
2617+
"pub const BuilderPrint_valueArgs = extern struct",
26152618
"pub extern fn roc_stdout_line(arg0: RocStr) callconv(.c) void;",
26162619
"pub extern fn roc_main() callconv(.c) void;",
26172620
}) |needle| {
@@ -2811,7 +2814,12 @@ fn customGlueZigBangRecordFields(io: std.Io, allocator: Allocator, env: *const C
28112814
const generated = std.Io.Dir.cwd().readFileAlloc(io, generated_path, allocator, .limited(1024 * 1024)) catch |err|
28122815
return customFailure(allocator, timer, "failed to read generated Zig file: {}", .{err});
28132816

2814-
for ([_][]const u8{ "@\"init!\": *anyopaque", "@\"render!\": *anyopaque" }) |needle| {
2817+
for ([_][]const u8{
2818+
"@\"init!\": *anyopaque",
2819+
"@\"render!\": *anyopaque",
2820+
"pub const HostSet_mouseArgs = extern struct",
2821+
"pub extern fn roc_host_set_mouse(arg0: HostSet_mouseArgs) callconv(.c) void;",
2822+
}) |needle| {
28152823
if (std.mem.find(u8, generated, needle) == null) {
28162824
return customFailure(allocator, timer, "generated Zig file missing {s}", .{needle});
28172825
}

src/glue/glue.zig

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -882,7 +882,7 @@ const CollectedTypeRepr = union(enum) {
882882
unit,
883883
list: u64,
884884
function: struct { arg_ids: []const u64, ret_id: u64 },
885-
record: struct { name: []const u8, fields: []const CollectedRecordField, size: u64, alignment: u64 },
885+
record: struct { name: []const u8, anonymous: bool, fields: []const CollectedRecordField, size: u64, alignment: u64 },
886886
tag_union: struct { name: []const u8, tags: []const CollectedTagInfo, size: u64, alignment: u64 },
887887
unknown: []const u8,
888888
};
@@ -1007,6 +1007,7 @@ const TypeTable = struct {
10071007
if (rec.name.len == 0) {
10081008
self.entries.items[@intCast(idx)] = .{ .record = .{
10091009
.name = try std.fmt.allocPrint(self.gpa, "__AnonStruct{d}", .{idx}),
1010+
.anonymous = true,
10101011
.fields = rec.fields,
10111012
.size = rec.size,
10121013
.alignment = rec.alignment,
@@ -1124,6 +1125,7 @@ const TypeTable = struct {
11241125
return switch (backing_repr) {
11251126
.record => |rec| .{ .record = .{
11261127
.name = try self.gpa.dupe(u8, display_name),
1128+
.anonymous = false,
11271129
.fields = rec.fields,
11281130
.size = rec.size,
11291131
.alignment = rec.alignment,
@@ -1221,6 +1223,7 @@ const TypeTable = struct {
12211223

12221224
return .{ .record = .{
12231225
.name = "",
1226+
.anonymous = true,
12241227
.fields = collected_fields,
12251228
.size = record_size,
12261229
.alignment = max_alignment,
@@ -1307,6 +1310,7 @@ const TypeTable = struct {
13071310

13081311
return .{ .record = .{
13091312
.name = "",
1313+
.anonymous = true,
13101314
.fields = collected_fields,
13111315
.size = record_size,
13121316
.alignment = max_alignment,
@@ -1814,6 +1818,7 @@ fn writeTypeRepr(
18141818
writer.zeroValue(value_base, payload_layout);
18151819
const fields_slot = writer.recordField(value_base, payload_layout, "RecordRepr", "fields");
18161820
writer.writeField(value_base, payload_layout, "RecordRepr", "alignment", u64, rec.alignment);
1821+
writer.writeField(value_base, payload_layout, "RecordRepr", "anonymous", bool, rec.anonymous);
18171822
writer.writeField(value_base, payload_layout, "RecordRepr", "fields", RocList, buildRecordFieldTypeReprList(writer, rec.fields, fields_slot.layout_idx));
18181823
writer.writeField(value_base, payload_layout, "RecordRepr", "name", RocStr, createBigRocStr(rec.name, writer.roc_ops));
18191824
writer.writeField(value_base, payload_layout, "RecordRepr", "size", u64, rec.size);

src/glue/platform/RecordRepr.roc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
import RecordField exposing [RecordField]
22

3-
RecordRepr := { alignment : U64, fields : List(RecordField), name : Str, size : U64 }
3+
RecordRepr := { alignment : U64, anonymous : Bool, fields : List(RecordField), name : Str, size : U64 }

src/glue/src/ZigGlue.roc

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -839,6 +839,7 @@ generate_zig_file = |hosted_functions, type_table, provides_list| {
839839
.concat(generate_element_type_structs(type_table))
840840
.concat(generate_tag_union_structs(type_table))
841841
.concat(generate_all_record_structs(hosted_functions, type_table))
842+
.concat(generate_all_args_structs(hosted_functions, type_table))
842843
.concat("\n")
843844
.concat(generate_runtime_symbol_externs)
844845
.concat("\n")
@@ -1262,6 +1263,34 @@ is_unit_type_id = |type_table, type_id| {
12621263
}
12631264
}
12641265

1266+
## Check whether a type is an explicitly anonymous record shape.
1267+
is_anonymous_record_type_id = |type_table, type_id| {
1268+
match List.get(type_table, type_id) {
1269+
Ok(type_repr) => is_anonymous_record_repr(type_table, type_repr)
1270+
Err(_) => Bool.False
1271+
}
1272+
}
1273+
1274+
is_anonymous_record_repr = |type_table, type_repr| {
1275+
match type_repr {
1276+
RocRecord(rec) => rec.anonymous
1277+
RocTagUnion(tu) =>
1278+
if List.len(tu.tags) == 1 {
1279+
match List.first(tu.tags) {
1280+
Ok(tag) =>
1281+
match List.first(tag.payload) {
1282+
Ok(payload_id) => is_anonymous_record_type_id(type_table, payload_id)
1283+
_ => Bool.False
1284+
}
1285+
_ => Bool.False
1286+
}
1287+
} else {
1288+
Bool.False
1289+
}
1290+
_ => Bool.False
1291+
}
1292+
}
1293+
12651294
## Build a natural C ABI parameter list from Roc function argument type IDs.
12661295
direct_param_list = |type_table, arg_type_ids| {
12671296
var $params = ""
@@ -1283,6 +1312,42 @@ direct_param_list = |type_table, arg_type_ids| {
12831312
$params
12841313
}
12851314

1315+
## Build a hosted symbol parameter list, using the generated Args wrapper for
1316+
## anonymous single-record arguments so direct-symbol glue stays readable.
1317+
direct_hosted_param_list = |type_table, func| {
1318+
use_args_wrapper =
1319+
if List.len(func.arg_type_ids) == 1 {
1320+
match List.first(func.arg_type_ids) {
1321+
Ok(arg_id) => is_anonymous_record_type_id(type_table, arg_id)
1322+
Err(_) => Bool.False
1323+
}
1324+
} else {
1325+
Bool.False
1326+
}
1327+
1328+
var $params = ""
1329+
var $idx = 0
1330+
1331+
for arg_type_id in func.arg_type_ids {
1332+
if !is_unit_type_id(type_table, arg_type_id) {
1333+
arg_zig = if use_args_wrapper {
1334+
"${name_to_struct_name(func.name)}Args"
1335+
} else {
1336+
type_id_to_zig(type_table, arg_type_id)
1337+
}
1338+
sep = if $params == "" {
1339+
""
1340+
} else {
1341+
", "
1342+
}
1343+
$params = "${$params}${sep}arg${U64.to_str($idx)}: ${arg_zig}"
1344+
$idx = $idx + 1
1345+
}
1346+
}
1347+
1348+
$params
1349+
}
1350+
12861351
## Generate direct extern declarations for the fixed runtime symbols every host defines.
12871352
generate_runtime_symbol_externs : Str
12881353
generate_runtime_symbol_externs =
@@ -1309,7 +1374,7 @@ generate_hosted_symbol_externs = |hosted_functions, type_table| {
13091374
var $result = "// =============================================================================\n// Hosted Symbols\n//\n// The platform host must export these symbols with the exact direct C ABI signatures.\n// Refcounted arguments are owned by the hosted function.\n// =============================================================================\n\n"
13101375

13111376
for func in hosted_functions {
1312-
params = direct_param_list(type_table, func.arg_type_ids)
1377+
params = direct_hosted_param_list(type_table, func)
13131378
ret_zig = type_id_to_zig(type_table, func.ret_type_id)
13141379

13151380
$result = Str.concat(

test/postcheck/platform_required_init/platform/Host.roc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ Host := {
66
},
77
}.{
88
read_env! : Host, Str => Try(Str, [NotFound, ..])
9+
set_mouse! : { x : F32, y : F32 } => {}
910
}

test/postcheck/platform_required_init/platform/main.roc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ platform ""
1111
"roc_init_for_host": init_for_host!,
1212
"roc_render_for_host": render_for_host!,
1313
}
14-
hosted { "roc_host_read_env": Host.read_env! }
14+
hosted {
15+
"roc_host_read_env": Host.read_env!,
16+
"roc_host_set_mouse": Host.set_mouse!,
17+
}
1518
targets: {
1619
inputs: "targets/",
1720
x64mac: { inputs: [app], output: Archive },

0 commit comments

Comments
 (0)