authorgravatar for kcbanner@gmail.comCasey Banner <kcbanner@gmail.com> 2023-07-08 00:20:37-04:00
committergravatar for kcbanner@gmail.comCasey Banner <kcbanner@gmail.com> 2023-07-20 22:58:15-04:00
log021f5378630f8acb5525974305a52314e227c276
tree91b27a0ed71b98dcab3d7ec78f5bd7bd03da34c3
parent54ca62fef4a621e0d64b6461706c8b5fe5a80348

dwarf: fixup default endianness in ExpressionOptions, add control flow tests


1 files changed, 75 insertions(+), 9 deletions(-)

lib/std/dwarf/expressions.zig+75-9
......@@ -33,7 +33,7 @@ pub const ExpressionOptions = struct {
3333 addr_size: u8 = @sizeOf(usize),
3434
3535 /// Endianess of the target architecture
36 endian: std.builtin.Endian = .Little,
36 endian: std.builtin.Endian = builtin.target.cpu.arch.endian(),
3737
3838 /// Restrict the stack machine to a subset of opcodes used in call frame instructions
3939 call_frame_context: bool = false,
......@@ -272,7 +272,7 @@ pub fn StackMachine(comptime options: ExpressionOptions) type {
272272 return self.stack.items[self.stack.items.len - 1];
273273 }
274274
275 /// Reads an opcode and its operands from the stream and executes it
275 /// Reads an opcode and its operands from `stream`, then executes it
276276 pub fn step(
277277 self: *Self,
278278 stream: *std.io.FixedBufferStream([]const u8),
......@@ -607,7 +607,7 @@ pub fn StackMachine(comptime options: ExpressionOptions) type {
607607 const a_int: isize = @bitCast(a.asIntegral() catch unreachable);
608608 const b_int: isize = @bitCast(b.asIntegral() catch unreachable);
609609 const result = @intFromBool(switch (opcode) {
610 OP.le => b_int < a_int,
610 OP.le => b_int <= a_int,
611611 OP.ge => b_int >= a_int,
612612 OP.eq => b_int == a_int,
613613 OP.lt => b_int < a_int,
......@@ -635,7 +635,7 @@ pub fn StackMachine(comptime options: ExpressionOptions) type {
635635 try std.math.add(isize, @as(isize, @intCast(stream.pos)), branch_offset),
636636 ) orelse return error.InvalidExpression;
637637
638 if (new_pos < 0 or new_pos >= stream.buffer.len) return error.InvalidExpression;
638 if (new_pos < 0 or new_pos > stream.buffer.len) return error.InvalidExpression;
639639 stream.pos = new_pos;
640640 }
641641 },
......@@ -657,12 +657,16 @@ pub fn StackMachine(comptime options: ExpressionOptions) type {
657657 OP.convert => {
658658 if (self.stack.items.len == 0) return error.InvalidExpression;
659659 const type_offset = (try readOperand(stream, opcode)).?.generic;
660 _ = type_offset;
661660
662 // TODO: Load the DW_TAG_base_type entry in context.compile_unit, find a conversion operator
663 // from the old type to the new type, run it.
664
665 return error.UnimplementedTypeConversion;
661 // TODO: Load the DW_TAG_base_type entries in context.compile_unit and verify both types are the same size
662 const value = self.stack.items[self.stack.items.len - 1];
663 if (type_offset == 0) {
664 self.stack.items[self.stack.items.len - 1] = .{ .generic = try value.asIntegral() };
665 } else {
666 // TODO: Load the DW_TAG_base_type entry in context.compile_unit, find a conversion operator
667 // from the old type to the new type, run it.
668 return error.UnimplementedTypeConversion;
669 }
666670 },
667671 OP.reinterpret => {
668672 if (self.stack.items.len == 0) return error.InvalidExpression;
......@@ -1373,4 +1377,66 @@ test "DWARF expressions" {
13731377 _ = try stack_machine.run(program.items, allocator, context, null);
13741378 try testing.expectEqual(@as(usize, 0x0ff0), stack_machine.stack.popOrNull().?.generic);
13751379 }
1380
1381
1382 // Control Flow Operations
1383 {
1384 var context = ExpressionContext{};
1385 const expected = .{
1386 .{ OP.le, 1, 1, 0 },
1387 .{ OP.ge, 1, 0, 1 },
1388 .{ OP.eq, 1, 0, 0 },
1389 .{ OP.lt, 0, 1, 0 },
1390 .{ OP.gt, 0, 0, 1 },
1391 .{ OP.ne, 0, 1, 1 },
1392 };
1393
1394 inline for (expected) |e| {
1395 stack_machine.reset();
1396 program.clearRetainingCapacity();
1397
1398 try b.writeConst(writer, u16, 0);
1399 try b.writeConst(writer, u16, 0);
1400 try b.writeOpcode(writer, e[0]);
1401 try b.writeConst(writer, u16, 0);
1402 try b.writeConst(writer, u16, 1);
1403 try b.writeOpcode(writer, e[0]);
1404 try b.writeConst(writer, u16, 1);
1405 try b.writeConst(writer, u16, 0);
1406 try b.writeOpcode(writer, e[0]);
1407 _ = try stack_machine.run(program.items, allocator, context, null);
1408 try testing.expectEqual(@as(usize, e[3]), stack_machine.stack.popOrNull().?.generic);
1409 try testing.expectEqual(@as(usize, e[2]), stack_machine.stack.popOrNull().?.generic);
1410 try testing.expectEqual(@as(usize, e[1]), stack_machine.stack.popOrNull().?.generic);
1411 }
1412
1413 stack_machine.reset();
1414 program.clearRetainingCapacity();
1415 try b.writeLiteral(writer, 2);
1416 try b.writeSkip(writer, 1);
1417 try b.writeLiteral(writer, 3);
1418 _ = try stack_machine.run(program.items, allocator, context, null);
1419 try testing.expectEqual(@as(usize, 2), stack_machine.stack.popOrNull().?.generic);
1420
1421
1422 stack_machine.reset();
1423 program.clearRetainingCapacity();
1424 try b.writeLiteral(writer, 2);
1425 try b.writeBra(writer, 1);
1426 try b.writeLiteral(writer, 3);
1427 try b.writeLiteral(writer, 0);
1428 try b.writeBra(writer, 1);
1429 try b.writeLiteral(writer, 4);
1430 try b.writeLiteral(writer, 5);
1431 _ = try stack_machine.run(program.items, allocator, context, null);
1432 try testing.expectEqual(@as(usize, 5), stack_machine.stack.popOrNull().?.generic);
1433 try testing.expectEqual(@as(usize, 4), stack_machine.stack.popOrNull().?.generic);
1434 try testing.expect(stack_machine.stack.popOrNull() == null);
1435
1436 // TODO: Test call2, call4, call_ref once implemented
1437
1438 }
1439
1440
13761441}
1442