| ... | ... | @@ -1281,15 +1281,15 @@ pub const Context = struct { |
| 1281 | 1281 | var case_i: u32 = 0; |
| 1282 | 1282 | |
| 1283 | 1283 | // a map that maps each value with its index and body |
| 1284 | | var map = std.AutoArrayHashMap(u32, struct { |
| 1284 | var map = std.AutoArrayHashMap(i32, struct { |
| 1285 | 1285 | index: u32, |
| 1286 | 1286 | body: []const Air.Inst.Index, |
| 1287 | 1287 | value: Value, |
| 1288 | 1288 | }).init(self.gpa); |
| 1289 | 1289 | defer map.deinit(); |
| 1290 | 1290 | |
| 1291 | | var lowest: u32 = 0; |
| 1292 | | var highest: u32 = 0; |
| 1291 | var lowest: i32 = 0; |
| 1292 | var highest: i32 = 0; |
| 1293 | 1293 | while (case_i < switch_br.data.cases_len) : (case_i += 1) { |
| 1294 | 1294 | const case = self.air.extraData(Air.SwitchBr.Case, extra_index); |
| 1295 | 1295 | const items = @bitCast([]const Air.Inst.Ref, self.air.extra[case.end..][0..case.data.items_len]); |
| ... | ... | @@ -1298,9 +1298,15 @@ pub const Context = struct { |
| 1298 | 1298 | |
| 1299 | 1299 | for (items) |ref| { |
| 1300 | 1300 | const item_val = self.air.value(ref).?; |
| 1301 | | // safe to truncate the values as we only use them when |
| 1302 | | // the target's bits is 32 or lower. |
| 1303 | | const int_val = @truncate(u32, item_val.toUnsignedInt()); |
| 1301 | const int_val: i32 = blk: { |
| 1302 | if (target_ty.intInfo(self.target).signedness == .signed) { |
| 1303 | // safe to truncate the values as we only use them when |
| 1304 | // the target's bits is 32 or lower. |
| 1305 | break :blk @truncate(i32, item_val.toSignedInt()); |
| 1306 | } |
| 1307 | |
| 1308 | break :blk @intCast(i32, @truncate(u31, item_val.toUnsignedInt()) - 1); |
| 1309 | }; |
| 1304 | 1310 | if (int_val < lowest) { |
| 1305 | 1311 | lowest = int_val; |
| 1306 | 1312 | } |
| ... | ... | @@ -1333,9 +1339,16 @@ pub const Context = struct { |
| 1333 | 1339 | // to jump to. |
| 1334 | 1340 | try self.startBlock(.block, blocktype, null); |
| 1335 | 1341 | try self.emitWValue(target); |
| 1342 | if (lowest < 0) { |
| 1343 | // since br_table works using indexes, starting from '0', we must ensure all values |
| 1344 | // we put inside, are atleast 0. |
| 1345 | try self.code.append(wasm.opcode(.i32_const)); |
| 1346 | try leb.writeILEB128(self.code.writer(), lowest * -1); |
| 1347 | try self.code.append(wasm.opcode(.i32_add)); |
| 1348 | } |
| 1336 | 1349 | try self.code.append(wasm.opcode(.br_table)); |
| 1337 | 1350 | const depth = highest - lowest + @boolToInt(has_else_body); |
| 1338 | | try leb.writeULEB128(self.code.writer(), depth); |
| 1351 | try leb.writeILEB128(self.code.writer(), depth); |
| 1339 | 1352 | while (lowest <= highest) : (lowest += 1) { |
| 1340 | 1353 | const idx = if (map.get(lowest)) |value| blk: { |
| 1341 | 1354 | break :blk value.index; |