| author | |
| committer | |
| log | f0400ad93eac984332c938b39e9c1627062d6b6a |
| tree | 408041de12ad2ba66bb139e2ca10d08297195469 |
| parent | e139c41fd8955f873615b2c2434d162585c0e44c |
| parent | 9c6d416bec10b9edd88545287133921274af1d2f |
| signature | Signed by PGP key 4AEE18F83AFDEB23 |
stage2: Wasm - implement field_ptr7 files changed, 117 insertions(+), 32 deletions(-)
src/arch/wasm/CodeGen.zig+70-25| ... | @@ -1106,6 +1106,20 @@ pub const DeclGen = struct { | ... | @@ -1106,6 +1106,20 @@ pub const DeclGen = struct { |
| 1106 | } | 1106 | } |
| 1107 | return Result{ .appended = {} }; | 1107 | return Result{ .appended = {} }; |
| 1108 | }, | 1108 | }, |
| 1109 | .Float => { | ||
| 1110 | const float_bits = ty.floatBits(self.target()); | ||
| 1111 | if (float_bits > 64) { | ||
| 1112 | return self.fail("Wasm TODO: Implement f80 and f128", .{}); | ||
| 1113 | } | ||
| 1114 | |||
| 1115 | switch (float_bits) { | ||
| 1116 | 16, 32 => try writer.writeIntLittle(u32, @bitCast(u32, val.toFloat(f32))), | ||
| 1117 | 64 => try writer.writeIntLittle(u64, @bitCast(u64, val.toFloat(f64))), | ||
| 1118 | else => unreachable, | ||
| 1119 | } | ||
| 1120 | |||
| 1121 | return Result{ .appended = {} }; | ||
| 1122 | }, | ||
| 1109 | .Enum => { | 1123 | .Enum => { |
| 1110 | var int_buffer: Value.Payload.U64 = undefined; | 1124 | var int_buffer: Value.Payload.U64 = undefined; |
| 1111 | const int_val = val.enumToInt(ty, &int_buffer); | 1125 | const int_val = val.enumToInt(ty, &int_buffer); |
| ... | @@ -1334,10 +1348,12 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) InnerError!CallWValu | ... | @@ -1334,10 +1348,12 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) InnerError!CallWValu |
| 1334 | defer self.gpa.free(param_types); | 1348 | defer self.gpa.free(param_types); |
| 1335 | fn_ty.fnParamTypes(param_types); | 1349 | fn_ty.fnParamTypes(param_types); |
| 1336 | var result: CallWValues = .{ | 1350 | var result: CallWValues = .{ |
| 1337 | .args = try self.gpa.alloc(WValue, param_types.len), | 1351 | .args = &.{}, |
| 1338 | .return_value = .none, | 1352 | .return_value = .none, |
| 1339 | }; | 1353 | }; |
| 1340 | errdefer self.gpa.free(result.args); | 1354 | var args = std.ArrayList(WValue).init(self.gpa); |
| 1355 | defer args.deinit(); | ||
| 1356 | |||
| 1341 | const ret_ty = fn_ty.fnReturnType(); | 1357 | const ret_ty = fn_ty.fnReturnType(); |
| 1342 | // Check if we store the result as a pointer to the stack rather than | 1358 | // Check if we store the result as a pointer to the stack rather than |
| 1343 | // by value | 1359 | // by value |
| ... | @@ -1350,18 +1366,18 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) InnerError!CallWValu | ... | @@ -1350,18 +1366,18 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) InnerError!CallWValu |
| 1350 | switch (cc) { | 1366 | switch (cc) { |
| 1351 | .Naked => return result, | 1367 | .Naked => return result, |
| 1352 | .Unspecified, .C => { | 1368 | .Unspecified, .C => { |
| 1353 | for (param_types) |ty, ty_index| { | 1369 | for (param_types) |ty| { |
| 1354 | if (!ty.hasRuntimeBits()) { | 1370 | if (!ty.hasRuntimeBits()) { |
| 1355 | result.args[ty_index] = .{ .none = {} }; | ||
| 1356 | continue; | 1371 | continue; |
| 1357 | } | 1372 | } |
| 1358 | 1373 | ||
| 1359 | result.args[ty_index] = .{ .local = self.local_index }; | 1374 | try args.append(.{ .local = self.local_index }); |
| 1360 | self.local_index += 1; | 1375 | self.local_index += 1; |
| 1361 | } | 1376 | } |
| 1362 | }, | 1377 | }, |
| 1363 | else => return self.fail("TODO implement function parameters for cc '{}' on wasm", .{cc}), | 1378 | else => return self.fail("TODO implement function parameters for cc '{}' on wasm", .{cc}), |
| 1364 | } | 1379 | } |
| 1380 | result.args = args.toOwnedSlice(); | ||
| 1365 | return result; | 1381 | return result; |
| 1366 | } | 1382 | } |
| 1367 | 1383 | ||
| ... | @@ -2060,6 +2076,26 @@ fn airWrapBinOp(self: *Self, inst: Air.Inst.Index, op: Op) InnerError!WValue { | ... | @@ -2060,6 +2076,26 @@ fn airWrapBinOp(self: *Self, inst: Air.Inst.Index, op: Op) InnerError!WValue { |
| 2060 | 2076 | ||
| 2061 | fn lowerConstant(self: *Self, val: Value, ty: Type) InnerError!WValue { | 2077 | fn lowerConstant(self: *Self, val: Value, ty: Type) InnerError!WValue { |
| 2062 | if (val.isUndefDeep()) return self.emitUndefined(ty); | 2078 | if (val.isUndefDeep()) return self.emitUndefined(ty); |
| 2079 | if (val.castTag(.decl_ref)) |decl_ref| { | ||
| 2080 | const decl = decl_ref.data; | ||
| 2081 | decl.markAlive(); | ||
| 2082 | const target_sym_index = decl.link.wasm.sym_index; | ||
| 2083 | if (ty.isSlice()) { | ||
| 2084 | var slice_len: Value.Payload.U64 = .{ | ||
| 2085 | .base = .{ .tag = .int_u64 }, | ||
| 2086 | .data = val.sliceLen(), | ||
| 2087 | }; | ||
| 2088 | var slice_val: Value.Payload.Slice = .{ | ||
| 2089 | .base = .{ .tag = .slice }, | ||
| 2090 | .data = .{ .ptr = val.slicePtr(), .len = Value.initPayload(&slice_len.base) }, | ||
| 2091 | }; | ||
| 2092 | return self.lowerConstant(Value.initPayload(&slice_val.base), ty); | ||
| 2093 | } else if (decl.ty.zigTypeTag() == .Fn) { | ||
| 2094 | try self.bin_file.addTableFunction(target_sym_index); | ||
| 2095 | return WValue{ .function_index = target_sym_index }; | ||
| 2096 | } else return WValue{ .memory = target_sym_index }; | ||
| 2097 | } | ||
| 2098 | |||
| 2063 | switch (ty.zigTypeTag()) { | 2099 | switch (ty.zigTypeTag()) { |
| 2064 | .Int => { | 2100 | .Int => { |
| 2065 | const int_info = ty.intInfo(self.target); | 2101 | const int_info = ty.intInfo(self.target); |
| ... | @@ -2084,25 +2120,6 @@ fn lowerConstant(self: *Self, val: Value, ty: Type) InnerError!WValue { | ... | @@ -2084,25 +2120,6 @@ fn lowerConstant(self: *Self, val: Value, ty: Type) InnerError!WValue { |
| 2084 | else => unreachable, | 2120 | else => unreachable, |
| 2085 | }, | 2121 | }, |
| 2086 | .Pointer => switch (val.tag()) { | 2122 | .Pointer => switch (val.tag()) { |
| 2087 | .decl_ref => { | ||
| 2088 | const decl = val.castTag(.decl_ref).?.data; | ||
| 2089 | decl.markAlive(); | ||
| 2090 | const target_sym_index = decl.link.wasm.sym_index; | ||
| 2091 | if (ty.isSlice()) { | ||
| 2092 | var slice_len: Value.Payload.U64 = .{ | ||
| 2093 | .base = .{ .tag = .int_u64 }, | ||
| 2094 | .data = val.sliceLen(), | ||
| 2095 | }; | ||
| 2096 | var slice_val: Value.Payload.Slice = .{ | ||
| 2097 | .base = .{ .tag = .slice }, | ||
| 2098 | .data = .{ .ptr = val.slicePtr(), .len = Value.initPayload(&slice_len.base) }, | ||
| 2099 | }; | ||
| 2100 | return self.lowerConstant(Value.initPayload(&slice_val.base), ty); | ||
| 2101 | } else if (decl.ty.zigTypeTag() == .Fn) { | ||
| 2102 | try self.bin_file.addTableFunction(target_sym_index); | ||
| 2103 | return WValue{ .function_index = target_sym_index }; | ||
| 2104 | } else return WValue{ .memory = target_sym_index }; | ||
| 2105 | }, | ||
| 2106 | .elem_ptr => { | 2123 | .elem_ptr => { |
| 2107 | const elem_ptr = val.castTag(.elem_ptr).?.data; | 2124 | const elem_ptr = val.castTag(.elem_ptr).?.data; |
| 2108 | const index = elem_ptr.index; | 2125 | const index = elem_ptr.index; |
| ... | @@ -2114,6 +2131,27 @@ fn lowerConstant(self: *Self, val: Value, ty: Type) InnerError!WValue { | ... | @@ -2114,6 +2131,27 @@ fn lowerConstant(self: *Self, val: Value, ty: Type) InnerError!WValue { |
| 2114 | .offset = @intCast(u32, offset), | 2131 | .offset = @intCast(u32, offset), |
| 2115 | } }; | 2132 | } }; |
| 2116 | }, | 2133 | }, |
| 2134 | .field_ptr => { | ||
| 2135 | const field_ptr = val.castTag(.field_ptr).?.data; | ||
| 2136 | const container = field_ptr.container_ptr; | ||
| 2137 | const parent_ptr = try self.lowerConstant(container, ty); | ||
| 2138 | |||
| 2139 | const offset = switch (container.tag()) { | ||
| 2140 | .decl_ref => blk: { | ||
| 2141 | const decl_ref = container.castTag(.decl_ref).?.data; | ||
| 2142 | if (decl_ref.ty.castTag(.@"struct")) |_| { | ||
| 2143 | const offset = decl_ref.ty.structFieldOffset(field_ptr.field_index, self.target); | ||
| 2144 | break :blk offset; | ||
| 2145 | } | ||
| 2146 | return self.fail("Wasm TODO: field_ptr decl_ref for type '{}'", .{decl_ref.ty}); | ||
| 2147 | }, | ||
| 2148 | else => |tag| return self.fail("Wasm TODO: Implement field_ptr for value tag: '{s}'", .{tag}), | ||
| 2149 | }; | ||
| 2150 | return WValue{ .memory_offset = .{ | ||
| 2151 | .pointer = parent_ptr.memory, | ||
| 2152 | .offset = @intCast(u32, offset), | ||
| 2153 | } }; | ||
| 2154 | }, | ||
| 2117 | .int_u64, .one => return WValue{ .imm32 = @intCast(u32, val.toUnsignedInt()) }, | 2155 | .int_u64, .one => return WValue{ .imm32 = @intCast(u32, val.toUnsignedInt()) }, |
| 2118 | .zero, .null_value => return WValue{ .imm32 = 0 }, | 2156 | .zero, .null_value => return WValue{ .imm32 = 0 }, |
| 2119 | else => return self.fail("Wasm TODO: lowerConstant for other const pointer tag {s}", .{val.tag()}), | 2157 | else => return self.fail("Wasm TODO: lowerConstant for other const pointer tag {s}", .{val.tag()}), |
| ... | @@ -2160,7 +2198,14 @@ fn lowerConstant(self: *Self, val: Value, ty: Type) InnerError!WValue { | ... | @@ -2160,7 +2198,14 @@ fn lowerConstant(self: *Self, val: Value, ty: Type) InnerError!WValue { |
| 2160 | }, | 2198 | }, |
| 2161 | .Optional => if (ty.isPtrLikeOptional()) { | 2199 | .Optional => if (ty.isPtrLikeOptional()) { |
| 2162 | var buf: Type.Payload.ElemType = undefined; | 2200 | var buf: Type.Payload.ElemType = undefined; |
| 2163 | return self.lowerConstant(val, ty.optionalChild(&buf)); | 2201 | const pl_ty = ty.optionalChild(&buf); |
| 2202 | if (val.castTag(.opt_payload)) |payload| { | ||
| 2203 | return self.lowerConstant(payload.data, pl_ty); | ||
| 2204 | } else if (val.isNull()) { | ||
| 2205 | return WValue{ .imm32 = 0 }; | ||
| 2206 | } else { | ||
| 2207 | return self.lowerConstant(val, pl_ty); | ||
| 2208 | } | ||
| 2164 | } else { | 2209 | } else { |
| 2165 | const is_pl = val.tag() == .opt_payload; | 2210 | const is_pl = val.tag() == .opt_payload; |
| 2166 | return WValue{ .imm32 = if (is_pl) @as(u32, 1) else 0 }; | 2211 | return WValue{ .imm32 = if (is_pl) @as(u32, 1) else 0 }; |
src/link/Wasm.zig+3-3| ... | @@ -428,7 +428,7 @@ pub fn addTableFunction(self: *Wasm, symbol_index: u32) !void { | ... | @@ -428,7 +428,7 @@ pub fn addTableFunction(self: *Wasm, symbol_index: u32) !void { |
| 428 | 428 | ||
| 429 | fn mapFunctionTable(self: *Wasm) void { | 429 | fn mapFunctionTable(self: *Wasm) void { |
| 430 | var it = self.function_table.valueIterator(); | 430 | var it = self.function_table.valueIterator(); |
| 431 | var index: u32 = 0; | 431 | var index: u32 = 1; |
| 432 | while (it.next()) |value_ptr| : (index += 1) { | 432 | while (it.next()) |value_ptr| : (index += 1) { |
| 433 | value_ptr.* = index; | 433 | value_ptr.* = index; |
| 434 | } | 434 | } |
| ... | @@ -821,7 +821,7 @@ pub fn flushModule(self: *Wasm, comp: *Compilation) !void { | ... | @@ -821,7 +821,7 @@ pub fn flushModule(self: *Wasm, comp: *Compilation) !void { |
| 821 | 821 | ||
| 822 | try leb.writeULEB128(writer, wasm.reftype(.funcref)); | 822 | try leb.writeULEB128(writer, wasm.reftype(.funcref)); |
| 823 | try emitLimits(writer, .{ | 823 | try emitLimits(writer, .{ |
| 824 | .min = @intCast(u32, self.function_table.count()), | 824 | .min = @intCast(u32, self.function_table.count()) + 1, |
| 825 | .max = null, | 825 | .max = null, |
| 826 | }); | 826 | }); |
| 827 | 827 | ||
| ... | @@ -931,7 +931,7 @@ pub fn flushModule(self: *Wasm, comp: *Compilation) !void { | ... | @@ -931,7 +931,7 @@ pub fn flushModule(self: *Wasm, comp: *Compilation) !void { |
| 931 | var flags: u32 = 0x2; // Yes we have a table | 931 | var flags: u32 = 0x2; // Yes we have a table |
| 932 | try leb.writeULEB128(writer, flags); | 932 | try leb.writeULEB128(writer, flags); |
| 933 | try leb.writeULEB128(writer, @as(u32, 0)); // index of that table. TODO: Store synthetic symbols | 933 | try leb.writeULEB128(writer, @as(u32, 0)); // index of that table. TODO: Store synthetic symbols |
| 934 | try emitInit(writer, .{ .i32_const = 0 }); | 934 | try emitInit(writer, .{ .i32_const = 1 }); // We start at index 1, so unresolved function pointers are invalid |
| 935 | try leb.writeULEB128(writer, @as(u8, 0)); | 935 | try leb.writeULEB128(writer, @as(u8, 0)); |
| 936 | try leb.writeULEB128(writer, @intCast(u32, self.function_table.count())); | 936 | try leb.writeULEB128(writer, @intCast(u32, self.function_table.count())); |
| 937 | var symbol_it = self.function_table.keyIterator(); | 937 | var symbol_it = self.function_table.keyIterator(); |
test/behavior.zig+4-4| ... | @@ -23,6 +23,8 @@ test { | ... | @@ -23,6 +23,8 @@ test { |
| 23 | _ = @import("behavior/bugs/1914.zig"); | 23 | _ = @import("behavior/bugs/1914.zig"); |
| 24 | _ = @import("behavior/bugs/2006.zig"); | 24 | _ = @import("behavior/bugs/2006.zig"); |
| 25 | _ = @import("behavior/bugs/2346.zig"); | 25 | _ = @import("behavior/bugs/2346.zig"); |
| 26 | _ = @import("behavior/bugs/2578.zig"); | ||
| 27 | _ = @import("behavior/bugs/3007.zig"); | ||
| 26 | _ = @import("behavior/bugs/3112.zig"); | 28 | _ = @import("behavior/bugs/3112.zig"); |
| 27 | _ = @import("behavior/bugs/3367.zig"); | 29 | _ = @import("behavior/bugs/3367.zig"); |
| 28 | _ = @import("behavior/bugs/6850.zig"); | 30 | _ = @import("behavior/bugs/6850.zig"); |
| ... | @@ -58,9 +60,11 @@ test { | ... | @@ -58,9 +60,11 @@ test { |
| 58 | _ = @import("behavior/bugs/4954.zig"); | 60 | _ = @import("behavior/bugs/4954.zig"); |
| 59 | _ = @import("behavior/byval_arg_var.zig"); | 61 | _ = @import("behavior/byval_arg_var.zig"); |
| 60 | _ = @import("behavior/call.zig"); | 62 | _ = @import("behavior/call.zig"); |
| 63 | _ = @import("behavior/cast_llvm.zig"); | ||
| 61 | _ = @import("behavior/defer.zig"); | 64 | _ = @import("behavior/defer.zig"); |
| 62 | _ = @import("behavior/enum.zig"); | 65 | _ = @import("behavior/enum.zig"); |
| 63 | _ = @import("behavior/error.zig"); | 66 | _ = @import("behavior/error.zig"); |
| 67 | _ = @import("behavior/fn.zig"); | ||
| 64 | _ = @import("behavior/for.zig"); | 68 | _ = @import("behavior/for.zig"); |
| 65 | _ = @import("behavior/generics.zig"); | 69 | _ = @import("behavior/generics.zig"); |
| 66 | _ = @import("behavior/if.zig"); | 70 | _ = @import("behavior/if.zig"); |
| ... | @@ -93,14 +97,10 @@ test { | ... | @@ -93,14 +97,10 @@ test { |
| 93 | if (builtin.zig_backend != .stage2_c) { | 97 | if (builtin.zig_backend != .stage2_c) { |
| 94 | // Tests that pass for stage1 and the llvm backend. | 98 | // Tests that pass for stage1 and the llvm backend. |
| 95 | _ = @import("behavior/atomics.zig"); | 99 | _ = @import("behavior/atomics.zig"); |
| 96 | _ = @import("behavior/bugs/2578.zig"); | ||
| 97 | _ = @import("behavior/bugs/3007.zig"); | ||
| 98 | _ = @import("behavior/bugs/9584.zig"); | 100 | _ = @import("behavior/bugs/9584.zig"); |
| 99 | _ = @import("behavior/cast_llvm.zig"); | ||
| 100 | _ = @import("behavior/error_llvm.zig"); | 101 | _ = @import("behavior/error_llvm.zig"); |
| 101 | _ = @import("behavior/eval.zig"); | 102 | _ = @import("behavior/eval.zig"); |
| 102 | _ = @import("behavior/floatop.zig"); | 103 | _ = @import("behavior/floatop.zig"); |
| 103 | _ = @import("behavior/fn.zig"); | ||
| 104 | _ = @import("behavior/math.zig"); | 104 | _ = @import("behavior/math.zig"); |
| 105 | _ = @import("behavior/maximum_minimum.zig"); | 105 | _ = @import("behavior/maximum_minimum.zig"); |
| 106 | _ = @import("behavior/merge_error_sets.zig"); | 106 | _ = @import("behavior/merge_error_sets.zig"); |
test/behavior/bugs/2578.zig+6| ... | @@ -1,3 +1,5 @@ | ... | @@ -1,3 +1,5 @@ |
| 1 | const builtin = @import("builtin"); | ||
| 2 | |||
| 1 | const Foo = struct { | 3 | const Foo = struct { |
| 2 | y: u8, | 4 | y: u8, |
| 3 | }; | 5 | }; |
| ... | @@ -10,5 +12,9 @@ fn bar(pointer: ?*anyopaque) void { | ... | @@ -10,5 +12,9 @@ fn bar(pointer: ?*anyopaque) void { |
| 10 | } | 12 | } |
| 11 | 13 | ||
| 12 | test "fixed" { | 14 | test "fixed" { |
| 15 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 16 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 17 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 18 | |||
| 13 | bar(t); | 19 | bar(t); |
| 14 | } | 20 | } |
test/behavior/bugs/3007.zig+5| ... | @@ -1,4 +1,5 @@ | ... | @@ -1,4 +1,5 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const builtin = @import("builtin"); | ||
| 2 | 3 | ||
| 3 | const Foo = struct { | 4 | const Foo = struct { |
| 4 | free: bool, | 5 | free: bool, |
| ... | @@ -18,6 +19,10 @@ fn get_foo() Foo.FooError!*Foo { | ... | @@ -18,6 +19,10 @@ fn get_foo() Foo.FooError!*Foo { |
| 18 | } | 19 | } |
| 19 | 20 | ||
| 20 | test "fixed" { | 21 | test "fixed" { |
| 22 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 23 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 24 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 25 | |||
| 21 | default_foo = get_foo() catch null; // This Line | 26 | default_foo = get_foo() catch null; // This Line |
| 22 | try std.testing.expect(!default_foo.?.free); | 27 | try std.testing.expect(!default_foo.?.free); |
| 23 | } | 28 | } |
test/behavior/cast_llvm.zig+24| ... | @@ -6,6 +6,8 @@ const maxInt = std.math.maxInt; | ... | @@ -6,6 +6,8 @@ const maxInt = std.math.maxInt; |
| 6 | const native_endian = builtin.target.cpu.arch.endian(); | 6 | const native_endian = builtin.target.cpu.arch.endian(); |
| 7 | 7 | ||
| 8 | test "pointer reinterpret const float to int" { | 8 | test "pointer reinterpret const float to int" { |
| 9 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 10 | |||
| 9 | // The hex representation is 0x3fe3333333333303. | 11 | // The hex representation is 0x3fe3333333333303. |
| 10 | const float: f64 = 5.99999999999994648725e-01; | 12 | const float: f64 = 5.99999999999994648725e-01; |
| 11 | const float_ptr = &float; | 13 | const float_ptr = &float; |
| ... | @@ -18,6 +20,8 @@ test "pointer reinterpret const float to int" { | ... | @@ -18,6 +20,8 @@ test "pointer reinterpret const float to int" { |
| 18 | } | 20 | } |
| 19 | 21 | ||
| 20 | test "@floatToInt" { | 22 | test "@floatToInt" { |
| 23 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 24 | |||
| 21 | try testFloatToInts(); | 25 | try testFloatToInts(); |
| 22 | comptime try testFloatToInts(); | 26 | comptime try testFloatToInts(); |
| 23 | } | 27 | } |
| ... | @@ -33,6 +37,8 @@ fn expectFloatToInt(comptime F: type, f: F, comptime I: type, i: I) !void { | ... | @@ -33,6 +37,8 @@ fn expectFloatToInt(comptime F: type, f: F, comptime I: type, i: I) !void { |
| 33 | } | 37 | } |
| 34 | 38 | ||
| 35 | test "implicit cast from [*]T to ?*anyopaque" { | 39 | test "implicit cast from [*]T to ?*anyopaque" { |
| 40 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 41 | |||
| 36 | var a = [_]u8{ 3, 2, 1 }; | 42 | var a = [_]u8{ 3, 2, 1 }; |
| 37 | var runtime_zero: usize = 0; | 43 | var runtime_zero: usize = 0; |
| 38 | incrementVoidPtrArray(a[runtime_zero..].ptr, 3); | 44 | incrementVoidPtrArray(a[runtime_zero..].ptr, 3); |
| ... | @@ -49,6 +55,7 @@ fn incrementVoidPtrArray(array: ?*anyopaque, len: usize) void { | ... | @@ -49,6 +55,7 @@ fn incrementVoidPtrArray(array: ?*anyopaque, len: usize) void { |
| 49 | test "compile time int to ptr of function" { | 55 | test "compile time int to ptr of function" { |
| 50 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; | 56 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; |
| 51 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .aarch64) return error.SkipZigTest; // TODO | 57 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .aarch64) return error.SkipZigTest; // TODO |
| 58 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 52 | 59 | ||
| 53 | try foobar(FUNCTION_CONSTANT); | 60 | try foobar(FUNCTION_CONSTANT); |
| 54 | } | 61 | } |
| ... | @@ -61,6 +68,8 @@ fn foobar(func: PFN_void) !void { | ... | @@ -61,6 +68,8 @@ fn foobar(func: PFN_void) !void { |
| 61 | } | 68 | } |
| 62 | 69 | ||
| 63 | test "implicit ptr to *anyopaque" { | 70 | test "implicit ptr to *anyopaque" { |
| 71 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 72 | |||
| 64 | var a: u32 = 1; | 73 | var a: u32 = 1; |
| 65 | var ptr: *align(@alignOf(u32)) anyopaque = &a; | 74 | var ptr: *align(@alignOf(u32)) anyopaque = &a; |
| 66 | var b: *u32 = @ptrCast(*u32, ptr); | 75 | var b: *u32 = @ptrCast(*u32, ptr); |
| ... | @@ -87,6 +96,7 @@ fn returnNullLitFromOptionalTypeErrorRef() anyerror!?*A { | ... | @@ -87,6 +96,7 @@ fn returnNullLitFromOptionalTypeErrorRef() anyerror!?*A { |
| 87 | } | 96 | } |
| 88 | 97 | ||
| 89 | test "peer type resolution: [0]u8 and []const u8" { | 98 | test "peer type resolution: [0]u8 and []const u8" { |
| 99 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 90 | try expect(peerTypeEmptyArrayAndSlice(true, "hi").len == 0); | 100 | try expect(peerTypeEmptyArrayAndSlice(true, "hi").len == 0); |
| 91 | try expect(peerTypeEmptyArrayAndSlice(false, "hi").len == 1); | 101 | try expect(peerTypeEmptyArrayAndSlice(false, "hi").len == 1); |
| 92 | comptime { | 102 | comptime { |
| ... | @@ -103,6 +113,7 @@ fn peerTypeEmptyArrayAndSlice(a: bool, slice: []const u8) []const u8 { | ... | @@ -103,6 +113,7 @@ fn peerTypeEmptyArrayAndSlice(a: bool, slice: []const u8) []const u8 { |
| 103 | } | 113 | } |
| 104 | 114 | ||
| 105 | test "implicitly cast from [N]T to ?[]const T" { | 115 | test "implicitly cast from [N]T to ?[]const T" { |
| 116 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 106 | try expect(mem.eql(u8, castToOptionalSlice().?, "hi")); | 117 | try expect(mem.eql(u8, castToOptionalSlice().?, "hi")); |
| 107 | comptime try expect(mem.eql(u8, castToOptionalSlice().?, "hi")); | 118 | comptime try expect(mem.eql(u8, castToOptionalSlice().?, "hi")); |
| 108 | } | 119 | } |
| ... | @@ -112,6 +123,7 @@ fn castToOptionalSlice() ?[]const u8 { | ... | @@ -112,6 +123,7 @@ fn castToOptionalSlice() ?[]const u8 { |
| 112 | } | 123 | } |
| 113 | 124 | ||
| 114 | test "cast u128 to f128 and back" { | 125 | test "cast u128 to f128 and back" { |
| 126 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 115 | comptime try testCast128(); | 127 | comptime try testCast128(); |
| 116 | try testCast128(); | 128 | try testCast128(); |
| 117 | } | 129 | } |
| ... | @@ -129,6 +141,7 @@ fn cast128Float(x: u128) f128 { | ... | @@ -129,6 +141,7 @@ fn cast128Float(x: u128) f128 { |
| 129 | } | 141 | } |
| 130 | 142 | ||
| 131 | test "implicit cast from *[N]T to ?[*]T" { | 143 | test "implicit cast from *[N]T to ?[*]T" { |
| 144 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 132 | var x: ?[*]u16 = null; | 145 | var x: ?[*]u16 = null; |
| 133 | var y: [4]u16 = [4]u16{ 0, 1, 2, 3 }; | 146 | var y: [4]u16 = [4]u16{ 0, 1, 2, 3 }; |
| 134 | 147 | ||
| ... | @@ -140,6 +153,7 @@ test "implicit cast from *[N]T to ?[*]T" { | ... | @@ -140,6 +153,7 @@ test "implicit cast from *[N]T to ?[*]T" { |
| 140 | } | 153 | } |
| 141 | 154 | ||
| 142 | test "implicit cast from *T to ?*anyopaque" { | 155 | test "implicit cast from *T to ?*anyopaque" { |
| 156 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 143 | var a: u8 = 1; | 157 | var a: u8 = 1; |
| 144 | incrementVoidPtrValue(&a); | 158 | incrementVoidPtrValue(&a); |
| 145 | try std.testing.expect(a == 2); | 159 | try std.testing.expect(a == 2); |
| ... | @@ -150,6 +164,7 @@ fn incrementVoidPtrValue(value: ?*anyopaque) void { | ... | @@ -150,6 +164,7 @@ fn incrementVoidPtrValue(value: ?*anyopaque) void { |
| 150 | } | 164 | } |
| 151 | 165 | ||
| 152 | test "implicit cast *[0]T to E![]const u8" { | 166 | test "implicit cast *[0]T to E![]const u8" { |
| 167 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 153 | var x = @as(anyerror![]const u8, &[0]u8{}); | 168 | var x = @as(anyerror![]const u8, &[0]u8{}); |
| 154 | try expect((x catch unreachable).len == 0); | 169 | try expect((x catch unreachable).len == 0); |
| 155 | } | 170 | } |
| ... | @@ -160,11 +175,13 @@ test "cast from array reference to fn: comptime fn ptr" { | ... | @@ -160,11 +175,13 @@ test "cast from array reference to fn: comptime fn ptr" { |
| 160 | try expect(@ptrToInt(f) == @ptrToInt(&global_array)); | 175 | try expect(@ptrToInt(f) == @ptrToInt(&global_array)); |
| 161 | } | 176 | } |
| 162 | test "cast from array reference to fn: runtime fn ptr" { | 177 | test "cast from array reference to fn: runtime fn ptr" { |
| 178 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 163 | var f = @ptrCast(*const fn () callconv(.C) void, &global_array); | 179 | var f = @ptrCast(*const fn () callconv(.C) void, &global_array); |
| 164 | try expect(@ptrToInt(f) == @ptrToInt(&global_array)); | 180 | try expect(@ptrToInt(f) == @ptrToInt(&global_array)); |
| 165 | } | 181 | } |
| 166 | 182 | ||
| 167 | test "*const [N]null u8 to ?[]const u8" { | 183 | test "*const [N]null u8 to ?[]const u8" { |
| 184 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 168 | const S = struct { | 185 | const S = struct { |
| 169 | fn doTheTest() !void { | 186 | fn doTheTest() !void { |
| 170 | var a = "Hello"; | 187 | var a = "Hello"; |
| ... | @@ -196,6 +213,7 @@ test "cast between [*c]T and ?[*:0]T on fn parameter" { | ... | @@ -196,6 +213,7 @@ test "cast between [*c]T and ?[*:0]T on fn parameter" { |
| 196 | 213 | ||
| 197 | var global_struct: struct { f0: usize } = undefined; | 214 | var global_struct: struct { f0: usize } = undefined; |
| 198 | test "assignment to optional pointer result loc" { | 215 | test "assignment to optional pointer result loc" { |
| 216 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 199 | var foo: struct { ptr: ?*anyopaque } = .{ .ptr = &global_struct }; | 217 | var foo: struct { ptr: ?*anyopaque } = .{ .ptr = &global_struct }; |
| 200 | try expect(foo.ptr.? == @ptrCast(*anyopaque, &global_struct)); | 218 | try expect(foo.ptr.? == @ptrCast(*anyopaque, &global_struct)); |
| 201 | } | 219 | } |
| ... | @@ -217,6 +235,8 @@ fn boolToStr(b: bool) []const u8 { | ... | @@ -217,6 +235,8 @@ fn boolToStr(b: bool) []const u8 { |
| 217 | } | 235 | } |
| 218 | 236 | ||
| 219 | test "cast f16 to wider types" { | 237 | test "cast f16 to wider types" { |
| 238 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 239 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | ||
| 220 | const S = struct { | 240 | const S = struct { |
| 221 | fn doTheTest() !void { | 241 | fn doTheTest() !void { |
| 222 | var x: f16 = 1234.0; | 242 | var x: f16 = 1234.0; |
| ... | @@ -230,6 +250,9 @@ test "cast f16 to wider types" { | ... | @@ -230,6 +250,9 @@ test "cast f16 to wider types" { |
| 230 | } | 250 | } |
| 231 | 251 | ||
| 232 | test "cast f128 to narrower types" { | 252 | test "cast f128 to narrower types" { |
| 253 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 254 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | ||
| 255 | |||
| 233 | const S = struct { | 256 | const S = struct { |
| 234 | fn doTheTest() !void { | 257 | fn doTheTest() !void { |
| 235 | var x: f128 = 1234.0; | 258 | var x: f128 = 1234.0; |
| ... | @@ -243,6 +266,7 @@ test "cast f128 to narrower types" { | ... | @@ -243,6 +266,7 @@ test "cast f128 to narrower types" { |
| 243 | } | 266 | } |
| 244 | 267 | ||
| 245 | test "peer type resolution: unreachable, null, slice" { | 268 | test "peer type resolution: unreachable, null, slice" { |
| 269 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 246 | const S = struct { | 270 | const S = struct { |
| 247 | fn doTheTest(num: usize, word: []const u8) !void { | 271 | fn doTheTest(num: usize, word: []const u8) !void { |
| 248 | const result = switch (num) { | 272 | const result = switch (num) { |
test/behavior/fn.zig+5| ... | @@ -75,6 +75,7 @@ test "return inner function which references comptime variable of outer function | ... | @@ -75,6 +75,7 @@ test "return inner function which references comptime variable of outer function |
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | test "discard the result of a function that returns a struct" { | 77 | test "discard the result of a function that returns a struct" { |
| 78 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 78 | const S = struct { | 79 | const S = struct { |
| 79 | fn entry() void { | 80 | fn entry() void { |
| 80 | _ = func(); | 81 | _ = func(); |
| ... | @@ -94,6 +95,7 @@ test "discard the result of a function that returns a struct" { | ... | @@ -94,6 +95,7 @@ test "discard the result of a function that returns a struct" { |
| 94 | } | 95 | } |
| 95 | 96 | ||
| 96 | test "inline function call that calls optional function pointer, return pointer at callsite interacts correctly with callsite return type" { | 97 | test "inline function call that calls optional function pointer, return pointer at callsite interacts correctly with callsite return type" { |
| 98 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 97 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; | 99 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; |
| 98 | 100 | ||
| 99 | const S = struct { | 101 | const S = struct { |
| ... | @@ -139,6 +141,7 @@ fn fnWithUnreachable() noreturn { | ... | @@ -139,6 +141,7 @@ fn fnWithUnreachable() noreturn { |
| 139 | } | 141 | } |
| 140 | 142 | ||
| 141 | test "extern struct with stdcallcc fn pointer" { | 143 | test "extern struct with stdcallcc fn pointer" { |
| 144 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 142 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; | 145 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; |
| 143 | 146 | ||
| 144 | const S = extern struct { | 147 | const S = extern struct { |
| ... | @@ -252,6 +255,7 @@ test "implicit cast fn call result to optional in field result" { | ... | @@ -252,6 +255,7 @@ test "implicit cast fn call result to optional in field result" { |
| 252 | } | 255 | } |
| 253 | 256 | ||
| 254 | test "void parameters" { | 257 | test "void parameters" { |
| 258 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 255 | try voidFun(1, void{}, 2, {}); | 259 | try voidFun(1, void{}, 2, {}); |
| 256 | } | 260 | } |
| 257 | fn voidFun(a: i32, b: void, c: i32, d: void) !void { | 261 | fn voidFun(a: i32, b: void, c: i32, d: void) !void { |
| ... | @@ -306,6 +310,7 @@ fn numberLiteralArg(a: anytype) !void { | ... | @@ -306,6 +310,7 @@ fn numberLiteralArg(a: anytype) !void { |
| 306 | } | 310 | } |
| 307 | 311 | ||
| 308 | test "function call with anon list literal" { | 312 | test "function call with anon list literal" { |
| 313 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 309 | const S = struct { | 314 | const S = struct { |
| 310 | fn doTheTest() !void { | 315 | fn doTheTest() !void { |
| 311 | try consumeVec(.{ 9, 8, 7 }); | 316 | try consumeVec(.{ 9, 8, 7 }); |