From 3933a4bac5179c30cb6a08d6f1e42f9b44ce9599 Mon Sep 17 00:00:00 2001 From: Luuk de Gram Date: Wed, 30 Nov 2022 17:52:37 +0100 Subject: codegen: support generating packed structs --- src/codegen.zig | 44 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 8 deletions(-) (limited to 'src/codegen.zig') diff --git a/src/codegen.zig b/src/codegen.zig index 53a4f9a402..6f262a8179 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -556,14 +556,42 @@ pub fn generateSymbol( }, .Struct => { if (typed_value.ty.containerLayout() == .Packed) { - return Result{ - .fail = try ErrorMsg.create( - bin_file.allocator, - src_loc, - "TODO implement generateSymbol for packed struct", - .{}, - ), - }; + const struct_obj = typed_value.ty.castTag(.@"struct").?.data; + const fields = struct_obj.fields.values(); + const field_vals = typed_value.val.castTag(.aggregate).?.data; + const abi_size = math.cast(usize, typed_value.ty.abiSize(target)) orelse return error.Overflow; + const current_pos = code.items.len; + const mod = bin_file.options.module.?; + try code.resize(current_pos + abi_size); + var bits: u16 = 0; + + for (field_vals) |field_val, index| { + const field_ty = fields[index].ty; + // pointer may point to a decl which must be marked used + // but can also result in a relocation. Therefore we handle those seperately. + if (field_ty.zigTypeTag() == .Pointer) { + std.debug.print("Hit!\n", .{}); + var tmp_list = try std.ArrayList(u8).initCapacity(code.allocator, field_ty.abiSize(target)); + defer tmp_list.deinit(); + switch (try generateSymbol(bin_file, src_loc, .{ + .ty = field_ty, + .val = field_val, + }, &tmp_list, debug_output, reloc_info)) { + .appended => { + mem.copy(u8, code.items[current_pos..], tmp_list.items); + }, + .externally_managed => |external_slice| { + mem.copy(u8, code.items[current_pos..], external_slice); + }, + .fail => |em| return Result{ .fail = em }, + } + } else { + field_val.writeToPackedMemory(field_ty, mod, code.items[current_pos..], bits); + } + bits += @intCast(u16, field_ty.bitSize(target)); + } + + return Result{ .appended = {} }; } const struct_begin = code.items.len; -- cgit v1.2.3 From 090deae41dbb79bcbe6a06d0bea0413f21576881 Mon Sep 17 00:00:00 2001 From: Luuk de Gram Date: Wed, 30 Nov 2022 17:55:33 +0100 Subject: wasm: enable behavior tests for packed structs --- src/codegen.zig | 4 ++-- src/link/Wasm.zig | 2 +- test/behavior/bitcast.zig | 6 ------ test/behavior/bugs/12776.zig | 1 - test/behavior/bugs/9584.zig | 1 - test/behavior/enum.zig | 2 -- test/behavior/packed-struct.zig | 9 --------- test/behavior/struct.zig | 12 ------------ 8 files changed, 3 insertions(+), 34 deletions(-) (limited to 'src/codegen.zig') diff --git a/src/codegen.zig b/src/codegen.zig index 6f262a8179..5a28ce1860 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -570,8 +570,8 @@ pub fn generateSymbol( // pointer may point to a decl which must be marked used // but can also result in a relocation. Therefore we handle those seperately. if (field_ty.zigTypeTag() == .Pointer) { - std.debug.print("Hit!\n", .{}); - var tmp_list = try std.ArrayList(u8).initCapacity(code.allocator, field_ty.abiSize(target)); + const field_size = math.cast(usize, field_ty.abiSize(target)) orelse return error.Overflow; + var tmp_list = try std.ArrayList(u8).initCapacity(code.allocator, field_size); defer tmp_list.deinit(); switch (try generateSymbol(bin_file, src_loc, .{ .ty = field_ty, diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index 4e573c9954..04b3e42db5 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -1841,7 +1841,7 @@ fn setupStart(wasm: *Wasm) !void { /// Sets up the memory section of the wasm module, as well as the stack. fn setupMemory(wasm: *Wasm) !void { log.debug("Setting up memory layout", .{}); - const page_size = std.wasm.page_size; // 65kb + const page_size = std.wasm.page_size; // 64kb // Use the user-provided stack size or else we use 1MB by default const stack_size = wasm.base.options.stack_size_override orelse page_size * 16; const stack_alignment = 16; // wasm's stack alignment as specified by tool-convention diff --git a/test/behavior/bitcast.zig b/test/behavior/bitcast.zig index 0071996056..8b180f6d0b 100644 --- a/test/behavior/bitcast.zig +++ b/test/behavior/bitcast.zig @@ -18,7 +18,6 @@ test "@bitCast iX -> uX (32, 64)" { } test "@bitCast iX -> uX (8, 16, 128)" { - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; @@ -160,7 +159,6 @@ test "@bitCast packed structs at runtime and comptime" { // stage1 gets the wrong answer for a lot of targets return error.SkipZigTest; } - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; @@ -187,7 +185,6 @@ test "@bitCast packed structs at runtime and comptime" { } test "@bitCast extern structs at runtime and comptime" { - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const Full = extern struct { @@ -218,7 +215,6 @@ test "@bitCast extern structs at runtime and comptime" { } test "bitcast packed struct to integer and back" { - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; @@ -257,8 +253,6 @@ test "implicit cast to error union by returning" { } test "bitcast packed struct literal to byte" { - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; - const Foo = packed struct { value: u8, }; diff --git a/test/behavior/bugs/12776.zig b/test/behavior/bugs/12776.zig index 3c89163f27..5ae9efc05f 100644 --- a/test/behavior/bugs/12776.zig +++ b/test/behavior/bugs/12776.zig @@ -31,7 +31,6 @@ const CPU = packed struct { test { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; var ram = try RAM.new(); diff --git a/test/behavior/bugs/9584.zig b/test/behavior/bugs/9584.zig index 48475cd96b..f80ff05228 100644 --- a/test/behavior/bugs/9584.zig +++ b/test/behavior/bugs/9584.zig @@ -44,7 +44,6 @@ pub fn b(x: *X) !void { } test { - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO diff --git a/test/behavior/enum.zig b/test/behavior/enum.zig index a6e417f2ae..4bca08859a 100644 --- a/test/behavior/enum.zig +++ b/test/behavior/enum.zig @@ -1146,8 +1146,6 @@ test "size of enum with only one tag which has explicit integer tag type" { } test "switch on an extern enum with negative value" { - if (@import("builtin").zig_backend == .stage2_wasm) return error.SkipZigTest; - const Foo = enum(c_int) { Bar = -1, }; diff --git a/test/behavior/packed-struct.zig b/test/behavior/packed-struct.zig index 76ce4e9acd..cbf66005d1 100644 --- a/test/behavior/packed-struct.zig +++ b/test/behavior/packed-struct.zig @@ -150,7 +150,6 @@ test "consistent size of packed structs" { test "correct sizeOf and offsets in packed structs" { if (builtin.zig_backend == .stage1) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -220,7 +219,6 @@ test "correct sizeOf and offsets in packed structs" { test "nested packed structs" { if (builtin.zig_backend == .stage1) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -267,7 +265,6 @@ test "nested packed structs" { } test "regular in irregular packed struct" { - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; @@ -289,7 +286,6 @@ test "regular in irregular packed struct" { test "byte-aligned field pointer offsets" { if (builtin.zig_backend == .stage1) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; @@ -395,7 +391,6 @@ test "load pointer from packed struct" { if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; const A = struct { index: u16, @@ -413,7 +408,6 @@ test "load pointer from packed struct" { } test "@ptrToInt on a packed struct field" { - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; @@ -437,7 +431,6 @@ test "optional pointer in packed struct" { if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; const T = packed struct { ptr: ?*const u8 }; var n: u8 = 0; @@ -566,7 +559,6 @@ test "nested packed struct field access test" { test "runtime init of unnamed packed struct type" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; var z: u8 = 123; @@ -582,7 +574,6 @@ test "packed struct passed to callconv(.C) function" { if (builtin.zig_backend == .stage1) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; const S = struct { diff --git a/test/behavior/struct.zig b/test/behavior/struct.zig index b598dca026..a74b9fdd53 100644 --- a/test/behavior/struct.zig +++ b/test/behavior/struct.zig @@ -386,7 +386,6 @@ const APackedStruct = packed struct { test "packed struct" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -460,7 +459,6 @@ test "packed struct 24bits" { test "runtime struct initialization of bitfield" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -504,7 +502,6 @@ test "packed struct fields are ordered from LSB to MSB" { return error.SkipZigTest; } if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -525,7 +522,6 @@ test "packed struct fields are ordered from LSB to MSB" { test "implicit cast packed struct field to const ptr" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -546,7 +542,6 @@ test "implicit cast packed struct field to const ptr" { } test "zero-bit field in packed struct" { - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -591,7 +586,6 @@ const bit_field_1 = BitField1{ test "bit field access" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -647,7 +641,6 @@ test "default struct initialization fields" { test "packed array 24bits" { if (builtin.zig_backend == .stage1) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; @@ -735,7 +728,6 @@ const FooArrayOfAligned = packed struct { }; test "pointer to packed struct member in a stack variable" { - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO @@ -754,7 +746,6 @@ test "pointer to packed struct member in a stack variable" { } test "packed struct with u0 field access" { - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -864,7 +855,6 @@ test "non-packed struct with u128 entry in union" { } test "packed struct field passed to generic function" { - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO @@ -1298,7 +1288,6 @@ test "packed struct aggregate init" { // stage1 fails this test on mips return error.SkipZigTest; } - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -1319,7 +1308,6 @@ test "packed struct aggregate init" { } test "packed struct field access via pointer" { - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO -- cgit v1.2.3