| author | |
| committer | |
| log | 25fcf03a678c4fc357d1342322cfe7ca058d9c0f |
| tree | d5fde2e5e7720704c4d62a1d29cb784ae6ae01ed |
| parent | 2f7e082381e64bbcdd06cf8f06eb84a9c8ad67de |
6 files changed, 118 insertions(+), 73 deletions(-)
src/codegen/wasm/CodeGen.zig+35-8| ... | ... | @@ -1856,10 +1856,11 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 1856 | 1856 | .c_va_end => try cg.airVaEnd(inst), |
| 1857 | 1857 | .c_va_start => try cg.airVaStart(inst), |
| 1858 | 1858 | |
| 1859 | .is_named_enum_value => try cg.airIsNamedEnumValue(inst), | |
| 1860 | ||
| 1859 | 1861 | .err_return_trace, |
| 1860 | 1862 | .set_err_return_trace, |
| 1861 | 1863 | .save_err_return_trace_index, |
| 1862 | .is_named_enum_value, | |
| 1863 | 1864 | .addrspace_cast, |
| 1864 | 1865 | => |tag| return cg.fail("TODO: Implement wasm inst: {s}", .{@tagName(tag)}), |
| 1865 | 1866 | |
| ... | ... | @@ -7279,12 +7280,37 @@ fn airTagName(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7279 | 7280 | const operand = try cg.resolveInst(un_op); |
| 7280 | 7281 | const enum_ty = cg.typeOf(un_op); |
| 7281 | 7282 | |
| 7282 | const result_ptr = try cg.allocStack(cg.typeOfIndex(inst)); | |
| 7283 | try cg.lowerToStack(result_ptr); | |
| 7283 | try cg.addInst(.{ .tag = .enum_tag_name_table_ref, .data = .{ .ip_index = enum_ty.toIntern() } }); | |
| 7284 | try cg.lowerToStack(operand); | |
| 7285 | try cg.addInst(.{ .tag = .call_tag_index, .data = .{ .ip_index = enum_ty.toIntern() } }); | |
| 7286 | ||
| 7287 | switch (cg.ptr_size) { | |
| 7288 | .wasm32 => { | |
| 7289 | try cg.addImm32(@intCast(8)); | |
| 7290 | try cg.addTag(.i32_mul); | |
| 7291 | try cg.addTag(.i32_add); | |
| 7292 | }, | |
| 7293 | .wasm64 => { | |
| 7294 | try cg.addImm64(8); | |
| 7295 | try cg.addTag(.i64_mul); | |
| 7296 | try cg.addTag(.i64_add); | |
| 7297 | }, | |
| 7298 | } | |
| 7299 | ||
| 7300 | return cg.finishAir(inst, .stack, &.{un_op}); | |
| 7301 | } | |
| 7302 | ||
| 7303 | fn airIsNamedEnumValue(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { | |
| 7304 | const un_op = cg.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | |
| 7305 | const operand = try cg.resolveInst(un_op); | |
| 7306 | const enum_ty = cg.typeOf(un_op); | |
| 7307 | ||
| 7284 | 7308 | try cg.lowerToStack(operand); |
| 7285 | try cg.addInst(.{ .tag = .call_tag_name, .data = .{ .ip_index = enum_ty.toIntern() } }); | |
| 7309 | try cg.addInst(.{ .tag = .call_tag_index, .data = .{ .ip_index = enum_ty.toIntern() } }); | |
| 7310 | try cg.addImm32(~@as(u32, 0)); | |
| 7311 | try cg.addTag(.i32_ne); | |
| 7286 | 7312 | |
| 7287 | return cg.finishAir(inst, result_ptr, &.{un_op}); | |
| 7313 | return cg.finishAir(inst, .stack, &.{un_op}); | |
| 7288 | 7314 | } |
| 7289 | 7315 | |
| 7290 | 7316 | fn airErrorSetHasValue(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| ... | ... | @@ -7313,7 +7339,7 @@ fn airErrorSetHasValue(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7313 | 7339 | } |
| 7314 | 7340 | if (highest) |*h| { |
| 7315 | 7341 | if (err_int > h.*) { |
| 7316 | highest = err_int; | |
| 7342 | h.* = err_int; | |
| 7317 | 7343 | } |
| 7318 | 7344 | } else { |
| 7319 | 7345 | highest = err_int; |
| ... | ... | @@ -7336,10 +7362,10 @@ fn airErrorSetHasValue(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7336 | 7362 | |
| 7337 | 7363 | // Account for default branch so always add '1' |
| 7338 | 7364 | const depth = @as(u32, @intCast(highest.? - lowest.? + 1)); |
| 7339 | const jump_table: Mir.JumpTable = .{ .length = depth }; | |
| 7365 | const jump_table: Mir.JumpTable = .{ .length = depth + 1 }; | |
| 7340 | 7366 | const table_extra_index = try cg.addExtra(jump_table); |
| 7341 | 7367 | try cg.addInst(.{ .tag = .br_table, .data = .{ .payload = table_extra_index } }); |
| 7342 | try cg.mir_extra.ensureUnusedCapacity(cg.gpa, depth); | |
| 7368 | try cg.mir_extra.ensureUnusedCapacity(cg.gpa, depth + 1); | |
| 7343 | 7369 | |
| 7344 | 7370 | var value: u32 = lowest.?; |
| 7345 | 7371 | while (value <= highest.?) : (value += 1) { |
| ... | ... | @@ -7351,6 +7377,7 @@ fn airErrorSetHasValue(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7351 | 7377 | }; |
| 7352 | 7378 | cg.mir_extra.appendAssumeCapacity(idx); |
| 7353 | 7379 | } |
| 7380 | cg.mir_extra.appendAssumeCapacity(0); // outside lowest...highest | |
| 7354 | 7381 | try cg.endBlock(); |
| 7355 | 7382 | |
| 7356 | 7383 | // 'false' branch (i.e. error set does not have value |
src/codegen/wasm/Emit.zig+18-3| ... | ... | @@ -220,25 +220,40 @@ pub fn lowerToCode(emit: *Emit) Error!void { |
| 220 | 220 | continue :loop tags[inst]; |
| 221 | 221 | }, |
| 222 | 222 | |
| 223 | .call_tag_name => { | |
| 223 | .call_tag_index => { | |
| 224 | 224 | try code.ensureUnusedCapacity(gpa, 6); |
| 225 | 225 | code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.call)); |
| 226 | 226 | if (is_obj) { |
| 227 | 227 | try wasm.out_relocs.append(gpa, .{ |
| 228 | 228 | .offset = @intCast(code.items.len), |
| 229 | .pointee = .{ .symbol_index = try wasm.tagNameSymbolIndex(datas[inst].ip_index) }, | |
| 229 | .pointee = .{ .symbol_index = try wasm.tagTableIndexSymbolIndex(datas[inst].ip_index) }, | |
| 230 | 230 | .tag = .function_index_leb, |
| 231 | 231 | .addend = 0, |
| 232 | 232 | }); |
| 233 | 233 | code.appendNTimesAssumeCapacity(0, 5); |
| 234 | 234 | } else { |
| 235 | appendOutputFunctionIndex(code, .fromTagNameType(wasm, datas[inst].ip_index)); | |
| 235 | appendOutputFunctionIndex(code, .fromTagIndexType(wasm, datas[inst].ip_index)); | |
| 236 | 236 | } |
| 237 | 237 | |
| 238 | 238 | inst += 1; |
| 239 | 239 | continue :loop tags[inst]; |
| 240 | 240 | }, |
| 241 | 241 | |
| 242 | .enum_tag_name_table_ref => { | |
| 243 | try code.ensureUnusedCapacity(gpa, 11); | |
| 244 | const opcode: std.wasm.Opcode = if (is_wasm32) .i32_const else .i64_const; | |
| 245 | code.appendAssumeCapacity(@intFromEnum(opcode)); | |
| 246 | if (is_obj) { | |
| 247 | @panic("TODO"); | |
| 248 | } else { | |
| 249 | const addr: u32 = wasm.tagIndexTableAddr(datas[inst].ip_index); | |
| 250 | writeSleb128(code, addr); | |
| 251 | ||
| 252 | inst += 1; | |
| 253 | continue :loop tags[inst]; | |
| 254 | } | |
| 255 | }, | |
| 256 | ||
| 242 | 257 | .call_intrinsic => { |
| 243 | 258 | // Although this currently uses `wasm.internString`, note that it |
| 244 | 259 | // *could* be changed to directly index into a preloaded strings |
src/codegen/wasm/Mir.zig+7-2| ... | ... | @@ -164,9 +164,14 @@ pub const Inst = struct { |
| 164 | 164 | call_indirect, |
| 165 | 165 | /// Calls a function by its index. |
| 166 | 166 | /// |
| 167 | /// The function is the auto-generated tag name function for the type | |
| 167 | /// The function is the auto-generated tag index function for the type | |
| 168 | 168 | /// provided in `ip_index`. |
| 169 | call_tag_name, | |
| 169 | call_tag_index, | |
| 170 | /// Lowers to an i32_const (wasm32) or i64_const (wasm64) containing | |
| 171 | /// the base address of the table of enum tag names slices. | |
| 172 | /// | |
| 173 | /// Uses `ip_index`. | |
| 174 | enum_tag_name_table_ref, | |
| 170 | 175 | /// Lowers to a `call` instruction, using `intrinsic`. |
| 171 | 176 | call_intrinsic, |
| 172 | 177 | /// Pops a value from the stack, and discards it. |
src/link/Wasm.zig+14-6| ... | ... | @@ -348,7 +348,7 @@ pub const FunctionIndex = enum(u32) { |
| 348 | 348 | return fromResolution(wasm, .fromIpNav(wasm, nav_index)); |
| 349 | 349 | } |
| 350 | 350 | |
| 351 | pub fn fromTagNameType(wasm: *const Wasm, tag_type: InternPool.Index) ?FunctionIndex { | |
| 351 | pub fn fromTagIndexType(wasm: *const Wasm, tag_type: InternPool.Index) ?FunctionIndex { | |
| 352 | 352 | const zcu_func: ZcuFunc.Index = @enumFromInt(wasm.zcu_funcs.getIndex(tag_type) orelse return null); |
| 353 | 353 | return fromResolution(wasm, .pack(wasm, .{ .zcu_func = zcu_func })); |
| 354 | 354 | } |
| ... | ... | @@ -423,8 +423,8 @@ pub const OutputFunctionIndex = enum(u32) { |
| 423 | 423 | return fromIpIndex(wasm, nav.resolved.?.value); |
| 424 | 424 | } |
| 425 | 425 | |
| 426 | pub fn fromTagNameType(wasm: *const Wasm, tag_type: InternPool.Index) OutputFunctionIndex { | |
| 427 | return fromFunctionIndex(wasm, FunctionIndex.fromTagNameType(wasm, tag_type).?); | |
| 426 | pub fn fromTagIndexType(wasm: *const Wasm, tag_type: InternPool.Index) OutputFunctionIndex { | |
| 427 | return fromFunctionIndex(wasm, FunctionIndex.fromTagIndexType(wasm, tag_type).?); | |
| 428 | 428 | } |
| 429 | 429 | |
| 430 | 430 | pub fn fromSymbolName(wasm: *const Wasm, name: String) OutputFunctionIndex { |
| ... | ... | @@ -891,8 +891,6 @@ pub const ZcuFunc = union { |
| 891 | 891 | pub const TagName = extern struct { |
| 892 | 892 | symbol_name: String, |
| 893 | 893 | type_index: FunctionType.Index, |
| 894 | /// Index into `Wasm.tag_name_offs`. | |
| 895 | table_index: u32, | |
| 896 | 894 | }; |
| 897 | 895 | |
| 898 | 896 | /// Index into `Wasm.zcu_funcs`. |
| ... | ... | @@ -4015,7 +4013,7 @@ pub fn stackPointerSymbolIndex(wasm: *Wasm) Allocator.Error!SymbolTableIndex { |
| 4015 | 4013 | return @enumFromInt(gop.index); |
| 4016 | 4014 | } |
| 4017 | 4015 | |
| 4018 | pub fn tagNameSymbolIndex(wasm: *Wasm, ip_index: InternPool.Index) Allocator.Error!SymbolTableIndex { | |
| 4016 | pub fn tagTableIndexSymbolIndex(wasm: *Wasm, ip_index: InternPool.Index) Allocator.Error!SymbolTableIndex { | |
| 4019 | 4017 | const comp = wasm.base.comp; |
| 4020 | 4018 | assert(comp.config.output_mode == .Obj); |
| 4021 | 4019 | const gpa = comp.gpa; |
| ... | ... | @@ -4173,6 +4171,16 @@ pub fn errorNameTableAddr(wasm: *Wasm) u32 { |
| 4173 | 4171 | return wasm.flush_buffer.data_segments.get(.__zig_error_name_table).?; |
| 4174 | 4172 | } |
| 4175 | 4173 | |
| 4174 | pub fn tagIndexTableAddr(wasm: *Wasm, ip_index: InternPool.Index) u32 { | |
| 4175 | assert(wasm.flush_buffer.memory_layout_finished); | |
| 4176 | const comp = wasm.base.comp; | |
| 4177 | assert(comp.config.output_mode != .Obj); | |
| 4178 | const f = &wasm.flush_buffer; | |
| 4179 | const table_base_addr = f.data_segments.get(.__zig_tag_name_table).?; | |
| 4180 | const table_index = f.enum_tag_name_table.get(ip_index).?; | |
| 4181 | return table_base_addr + table_index * 8; | |
| 4182 | } | |
| 4183 | ||
| 4176 | 4184 | fn convertZcuFnType( |
| 4177 | 4185 | comp: *Compilation, |
| 4178 | 4186 | cc: std.lang.CallingConvention, |
src/link/Wasm/Flush.zig+43-53| ... | ... | @@ -41,6 +41,8 @@ indirect_function_table: std.array_hash_map.Auto(Wasm.OutputFunctionIndex, void) |
| 41 | 41 | /// A subset of the full interned function type list created only during flush. |
| 42 | 42 | func_types: std.array_hash_map.Auto(Wasm.FunctionType.Index, void) = .empty, |
| 43 | 43 | |
| 44 | enum_tag_name_table: std.array_hash_map.Auto(InternPool.Index, u32) = .empty, | |
| 45 | ||
| 44 | 46 | /// For debug purposes only. |
| 45 | 47 | memory_layout_finished: bool = false, |
| 46 | 48 | |
| ... | ... | @@ -90,6 +92,7 @@ pub fn clear(f: *Flush) void { |
| 90 | 92 | f.binary_bytes.clearRetainingCapacity(); |
| 91 | 93 | f.indirect_function_table.clearRetainingCapacity(); |
| 92 | 94 | f.func_types.clearRetainingCapacity(); |
| 95 | f.enum_tag_name_table.clearRetainingCapacity(); | |
| 93 | 96 | f.memory_layout_finished = false; |
| 94 | 97 | } |
| 95 | 98 | |
| ... | ... | @@ -103,6 +106,7 @@ pub fn deinit(f: *Flush, gpa: Allocator) void { |
| 103 | 106 | f.data_imports.deinit(gpa); |
| 104 | 107 | f.indirect_function_table.deinit(gpa); |
| 105 | 108 | f.func_types.deinit(gpa); |
| 109 | f.enum_tag_name_table.deinit(gpa); | |
| 106 | 110 | f.* = undefined; |
| 107 | 111 | } |
| 108 | 112 | |
| ... | ... | @@ -143,17 +147,24 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 143 | 147 | try wasm.markFunctionImport(symbol_name, i.value(wasm), i); |
| 144 | 148 | log.debug("markFunctionImport intrinsic {d}={t}", .{ i, data.intrinsic }); |
| 145 | 149 | }, |
| 146 | .call_tag_name => { | |
| 150 | .call_tag_index => { | |
| 147 | 151 | assert(ip.indexToKey(data.ip_index) == .enum_type); |
| 148 | 152 | const gop = try wasm.zcu_funcs.getOrPut(gpa, data.ip_index); |
| 149 | 153 | if (!gop.found_existing) { |
| 150 | wasm.tag_name_table_ref_count += 1; | |
| 151 | 154 | const int_tag_ty = Zcu.Type.fromInterned(data.ip_index).intTagType(zcu); |
| 152 | 155 | gop.value_ptr.* = .{ .tag_name = .{ |
| 153 | .symbol_name = try wasm.internStringFmt("__zig_tag_name_{d}", .{data.ip_index}), | |
| 154 | .type_index = try wasm.internFunctionType(.auto, &.{int_tag_ty.ip_index}, .slice_const_u8_sentinel_0, false, target), | |
| 155 | .table_index = @intCast(wasm.tag_name_offs.items.len), | |
| 156 | .symbol_name = try wasm.internStringFmt("__zig_tag_index_{d}", .{data.ip_index}), | |
| 157 | .type_index = try wasm.internFunctionType(.auto, &.{int_tag_ty.ip_index}, .u32, false, target), | |
| 156 | 158 | } }; |
| 159 | } | |
| 160 | try wasm.functions.put(gpa, .fromZcuFunc(wasm, @enumFromInt(gop.index)), {}); | |
| 161 | }, | |
| 162 | .enum_tag_name_table_ref => { | |
| 163 | assert(ip.indexToKey(data.ip_index) == .enum_type); | |
| 164 | const gop = try f.enum_tag_name_table.getOrPut(gpa, data.ip_index); | |
| 165 | if (!gop.found_existing) { | |
| 166 | wasm.tag_name_table_ref_count += 1; | |
| 167 | gop.value_ptr.* = @intCast(wasm.tag_name_offs.items.len); | |
| 157 | 168 | const tag_names = ip.loadEnumType(data.ip_index).field_names; |
| 158 | 169 | for (tag_names.get(ip)) |tag_name| { |
| 159 | 170 | const slice = tag_name.toSlice(ip); |
| ... | ... | @@ -161,7 +172,6 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 161 | 172 | try wasm.tag_name_bytes.appendSlice(gpa, slice[0 .. slice.len + 1]); |
| 162 | 173 | } |
| 163 | 174 | } |
| 164 | try wasm.functions.put(gpa, .fromZcuFunc(wasm, @enumFromInt(gop.index)), {}); | |
| 165 | 175 | }, |
| 166 | 176 | else => continue, |
| 167 | 177 | }; |
| ... | ... | @@ -874,7 +884,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 874 | 884 | const ip_index = i.key(wasm).*; |
| 875 | 885 | switch (ip.indexToKey(ip_index)) { |
| 876 | 886 | .enum_type => { |
| 877 | try emitTagNameFunction(wasm, binary_bytes, f.data_segments.get(.__zig_tag_name_table).?, i.value(wasm).tag_name.table_index, ip_index); | |
| 887 | try emitTagIndexFunction(wasm, binary_bytes, ip_index); | |
| 878 | 888 | }, |
| 879 | 889 | else => { |
| 880 | 890 | const func = i.value(wasm).function; |
| ... | ... | @@ -1856,11 +1866,9 @@ fn emitStartSection(gpa: Allocator, bytes: *ArrayList(u8), i: Wasm.OutputFunctio |
| 1856 | 1866 | replaceVecSectionHeader(bytes, header_offset, .start, @intFromEnum(i)); |
| 1857 | 1867 | } |
| 1858 | 1868 | |
| 1859 | fn emitTagNameFunction( | |
| 1869 | fn emitTagIndexFunction( | |
| 1860 | 1870 | wasm: *Wasm, |
| 1861 | 1871 | code: *ArrayList(u8), |
| 1862 | table_base_addr: u32, | |
| 1863 | table_index: u32, | |
| 1864 | 1872 | enum_type_ip: InternPool.Index, |
| 1865 | 1873 | ) !void { |
| 1866 | 1874 | const comp = wasm.base.comp; |
| ... | ... | @@ -1870,36 +1878,37 @@ fn emitTagNameFunction( |
| 1870 | 1878 | const enum_type = ip.loadEnumType(enum_type_ip); |
| 1871 | 1879 | const tag_values = enum_type.field_values.get(ip); |
| 1872 | 1880 | |
| 1873 | const slice_abi_size = 8; | |
| 1874 | const encoded_alignment = @ctz(@as(u32, 4)); | |
| 1875 | ||
| 1876 | 1881 | if (tag_values.len == 0) { |
| 1877 | // Auto-numbered, therefore a direct table lookup. | |
| 1882 | // Auto-numbered | |
| 1883 | ||
| 1884 | const len = enum_type.field_names.len; | |
| 1878 | 1885 | |
| 1879 | try code.ensureUnusedCapacity( | |
| 1880 | gpa, | |
| 1881 | 6 * @sizeOf(std.wasm.Opcode) + | |
| 1882 | 7 * 5 + // appendReservedUleb32 | |
| 1883 | 1 * 6, // appendReservedI32Const | |
| 1884 | ); | |
| 1886 | try code.ensureUnusedCapacity(gpa, 13 + 5 * 2); | |
| 1885 | 1887 | |
| 1886 | 1888 | appendReservedUleb32(code, 0); // no locals |
| 1887 | 1889 | |
| 1890 | code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.block)); | |
| 1891 | code.appendAssumeCapacity(@intFromEnum(std.wasm.BlockType.empty)); | |
| 1892 | ||
| 1888 | 1893 | code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.local_get)); |
| 1889 | 1894 | appendReservedUleb32(code, 0); |
| 1890 | 1895 | |
| 1891 | code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.local_get)); | |
| 1892 | appendReservedUleb32(code, 1); | |
| 1896 | appendReservedI32Const(code, len); | |
| 1897 | ||
| 1898 | // if < len -> break out of block | |
| 1899 | code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i32_lt_u)); | |
| 1893 | 1900 | |
| 1894 | appendReservedI32Const(code, slice_abi_size); | |
| 1895 | code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i32_mul)); | |
| 1901 | code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.br_if)); | |
| 1902 | appendReservedUleb32(code, 0); | |
| 1896 | 1903 | |
| 1897 | code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i64_load)); | |
| 1898 | appendReservedUleb32(code, encoded_alignment); | |
| 1899 | appendReservedUleb32(code, table_base_addr + table_index * 8); | |
| 1904 | // invalid -> return -1 | |
| 1905 | appendReservedI32Const(code, ~@as(u32, 0)); | |
| 1906 | code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.@"return")); | |
| 1900 | 1907 | |
| 1901 | code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i64_store)); | |
| 1902 | appendReservedUleb32(code, encoded_alignment); | |
| 1908 | code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.end)); | |
| 1909 | ||
| 1910 | // valid -> return input | |
| 1911 | code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.local_get)); | |
| 1903 | 1912 | appendReservedUleb32(code, 0); |
| 1904 | 1913 | |
| 1905 | 1914 | code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.end)); |
| ... | ... | @@ -1920,13 +1929,6 @@ fn emitTagNameFunction( |
| 1920 | 1929 | |
| 1921 | 1930 | appendReservedUleb32(code, 0); // no locals |
| 1922 | 1931 | |
| 1923 | code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.local_get)); | |
| 1924 | appendReservedUleb32(code, 0); | |
| 1925 | ||
| 1926 | // Outer block that computes table offset. | |
| 1927 | code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.block)); | |
| 1928 | code.appendAssumeCapacity(@intFromEnum(std.wasm.BlockType.i32)); | |
| 1929 | ||
| 1930 | 1932 | for (tag_values, 0..) |tag_value, tag_index| { |
| 1931 | 1933 | // block for this if case |
| 1932 | 1934 | code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.block)); |
| ... | ... | @@ -1946,7 +1948,7 @@ fn emitTagNameFunction( |
| 1946 | 1948 | |
| 1947 | 1949 | for (0..num_limbs) |limb_index| { |
| 1948 | 1950 | code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.local_get)); |
| 1949 | appendReservedUleb32(code, 1); | |
| 1951 | appendReservedUleb32(code, 0); | |
| 1950 | 1952 | |
| 1951 | 1953 | code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i64_load)); |
| 1952 | 1954 | appendReservedUleb32(code, @ctz(@as(u32, 8))); |
| ... | ... | @@ -1960,7 +1962,7 @@ fn emitTagNameFunction( |
| 1960 | 1962 | } |
| 1961 | 1963 | } else { |
| 1962 | 1964 | code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.local_get)); |
| 1963 | appendReservedUleb32(code, 1); | |
| 1965 | appendReservedUleb32(code, 0); | |
| 1964 | 1966 | |
| 1965 | 1967 | switch (int_info.bits) { |
| 1966 | 1968 | 0...32 => { |
| ... | ... | @@ -1986,26 +1988,14 @@ fn emitTagNameFunction( |
| 1986 | 1988 | appendReservedUleb32(code, 0); |
| 1987 | 1989 | } |
| 1988 | 1990 | |
| 1989 | // Put the table offset of the result on the stack. | |
| 1990 | appendReservedI32Const(code, @intCast(tag_index * slice_abi_size)); | |
| 1991 | ||
| 1992 | // break outside blocks | |
| 1993 | code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.br)); | |
| 1994 | appendReservedUleb32(code, 1); | |
| 1991 | appendReservedI32Const(code, @intCast(tag_index)); | |
| 1995 | 1992 | |
| 1993 | code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.@"return")); | |
| 1996 | 1994 | // end the block for this case |
| 1997 | 1995 | code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.end)); |
| 1998 | 1996 | } |
| 1999 | code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.@"unreachable")); | |
| 2000 | code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.end)); | |
| 2001 | ||
| 2002 | code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i64_load)); | |
| 2003 | appendReservedUleb32(code, encoded_alignment); | |
| 2004 | appendReservedUleb32(code, table_base_addr + table_index * 8); | |
| 2005 | 1997 | |
| 2006 | code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i64_store)); | |
| 2007 | appendReservedUleb32(code, encoded_alignment); | |
| 2008 | appendReservedUleb32(code, 0); | |
| 1998 | appendReservedI32Const(code, ~@as(u32, 0)); | |
| 2009 | 1999 | |
| 2010 | 2000 | code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.end)); |
| 2011 | 2001 | } |
src/target.zig+1-1| ... | ... | @@ -937,7 +937,7 @@ pub inline fn backendSupportsFeature(backend: std.lang.CompilerBackend, comptime |
| 937 | 937 | else => false, |
| 938 | 938 | }, |
| 939 | 939 | .is_named_enum_value => switch (backend) { |
| 940 | .stage2_llvm, .stage2_x86_64 => true, | |
| 940 | .stage2_llvm, .stage2_x86_64, .stage2_wasm => true, | |
| 941 | 941 | else => false, |
| 942 | 942 | }, |
| 943 | 943 | .error_set_has_value => switch (backend) { |