authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2021-07-23 22:31:45+02:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2021-07-24 19:49:25+02:00
log72149ae7e4a826d1657d82c367596e06ff771734
tree5bf870bd0249574b16c6f7970c04471349a634c7
parentcb41f0e58d4788806aac0bfece2e298c3c79b737
signaturelock-open Commit is signed but in an unrecognized format.

Allow negative values


1 files changed, 20 insertions(+), 7 deletions(-)

src/codegen/wasm.zig+20-7
...@@ -1281,15 +1281,15 @@ pub const Context = struct {...@@ -1281,15 +1281,15 @@ pub const Context = struct {
1281 var case_i: u32 = 0;1281 var case_i: u32 = 0;
12821282
1283 // a map that maps each value with its index and body1283 // 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 index: u32,1285 index: u32,
1286 body: []const Air.Inst.Index,1286 body: []const Air.Inst.Index,
1287 value: Value,1287 value: Value,
1288 }).init(self.gpa);1288 }).init(self.gpa);
1289 defer map.deinit();1289 defer map.deinit();
12901290
1291 var lowest: u32 = 0;1291 var lowest: i32 = 0;
1292 var highest: u32 = 0;1292 var highest: i32 = 0;
1293 while (case_i < switch_br.data.cases_len) : (case_i += 1) {1293 while (case_i < switch_br.data.cases_len) : (case_i += 1) {
1294 const case = self.air.extraData(Air.SwitchBr.Case, extra_index);1294 const case = self.air.extraData(Air.SwitchBr.Case, extra_index);
1295 const items = @bitCast([]const Air.Inst.Ref, self.air.extra[case.end..][0..case.data.items_len]);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,9 +1298,15 @@ pub const Context = struct {
12981298
1299 for (items) |ref| {1299 for (items) |ref| {
1300 const item_val = self.air.value(ref).?;1300 const item_val = self.air.value(ref).?;
1301 // safe to truncate the values as we only use them when1301 const int_val: i32 = blk: {
1302 // the target's bits is 32 or lower.1302 if (target_ty.intInfo(self.target).signedness == .signed) {
1303 const int_val = @truncate(u32, item_val.toUnsignedInt());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 if (int_val < lowest) {1310 if (int_val < lowest) {
1305 lowest = int_val;1311 lowest = int_val;
1306 }1312 }
...@@ -1333,9 +1339,16 @@ pub const Context = struct {...@@ -1333,9 +1339,16 @@ pub const Context = struct {
1333 // to jump to.1339 // to jump to.
1334 try self.startBlock(.block, blocktype, null);1340 try self.startBlock(.block, blocktype, null);
1335 try self.emitWValue(target);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 try self.code.append(wasm.opcode(.br_table));1349 try self.code.append(wasm.opcode(.br_table));
1337 const depth = highest - lowest + @boolToInt(has_else_body);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 while (lowest <= highest) : (lowest += 1) {1352 while (lowest <= highest) : (lowest += 1) {
1340 const idx = if (map.get(lowest)) |value| blk: {1353 const idx = if (map.get(lowest)) |value| blk: {
1341 break :blk value.index;1354 break :blk value.index;