cjit: Fix some compilation errors
This commit is contained in:
@@ -87,8 +87,6 @@ pub fn deinit(self: *Self) void {
|
||||
}
|
||||
|
||||
pub fn compile(self: *Self, filename: []const u8, code: []const u8) !void {
|
||||
std.debug.assert(self.state == .init);
|
||||
|
||||
self.tokenizer.setSource(filename, code);
|
||||
while (try self.tokenizer.nextToken(self.arena.allocator())) |token| {
|
||||
_ = token;
|
||||
@@ -97,10 +95,11 @@ pub fn compile(self: *Self, filename: []const u8, code: []const u8) !void {
|
||||
}
|
||||
|
||||
pub fn setSymbol(self: *Self, comptime T: type, name: []const u8, ptr: *const T) !void {
|
||||
const symbol = self.symbols.getPtr(name) orelse return error.SymbolNotFound;
|
||||
const symbol = self.symbols_needed.getPtr(name) orelse return error.SymbolNotFound;
|
||||
if (!types.isCompatible(T, symbol.c_type)) return error.IncompatibleType;
|
||||
|
||||
symbol.ptr = @ptrCast(ptr);
|
||||
// TODO Figure out const-correctness
|
||||
symbol.ptr = @ptrCast(@constCast(ptr));
|
||||
}
|
||||
|
||||
pub fn link(self: *Self) !void {
|
||||
@@ -121,7 +120,7 @@ pub fn link(self: *Self) !void {
|
||||
.global_offset_table => {
|
||||
std.mem.writeInt(
|
||||
usize,
|
||||
self.sections.rodata.data[relocation.addr .. relocation.addr + @sizeOf(usize)],
|
||||
self.sections.rodata.data.items[relocation.addr..][0..@sizeOf(usize)],
|
||||
target_addr,
|
||||
builtin.cpu.arch.endian(),
|
||||
);
|
||||
@@ -129,10 +128,10 @@ pub fn link(self: *Self) !void {
|
||||
.rip_disp32 => {
|
||||
const rip = text_base + relocation.addr + 4;
|
||||
const disp64: isize = @bitCast(rip -% target_addr);
|
||||
const disp32 = std.math.cast(i32, disp64) orelse error.RelocationError;
|
||||
const disp32 = std.math.cast(i32, disp64) orelse return error.RelocationError;
|
||||
std.mem.writeInt(
|
||||
i32,
|
||||
self.sections.text.data[relocation.addr .. relocation.addr + 4],
|
||||
self.sections.text.data.items[relocation.addr..][0..4],
|
||||
disp32,
|
||||
builtin.cpu.arch.endian(),
|
||||
);
|
||||
@@ -146,7 +145,7 @@ pub fn link(self: *Self) !void {
|
||||
}
|
||||
|
||||
pub fn getSymbol(self: *const Self, comptime T: type, name: []const u8) ?*const T {
|
||||
const symbol = self.symbols.get(name) orelse return null;
|
||||
const symbol = self.symbols_located.get(name) orelse return null;
|
||||
return @ptrCast(@alignCast(symbol.ptr));
|
||||
}
|
||||
|
||||
|
||||
@@ -112,7 +112,7 @@ pub fn relocateSections(self: *Self, allocator: std.mem.Allocator) !void {
|
||||
|
||||
@memcpy(text_slice[0..self.text.data.items.len], self.text.data.items);
|
||||
@memcpy(data_slice[0..self.data.data.items.len], self.data.data.items);
|
||||
@memcpy(rodata_slice[0..self.rodata_slice.data.items.len], self.rodata.data.items);
|
||||
@memcpy(rodata_slice[0..self.rodata.data.items.len], self.rodata.data.items);
|
||||
|
||||
self.text.data.clearAndFree(allocator);
|
||||
self.data.data.clearAndFree(allocator);
|
||||
@@ -124,7 +124,7 @@ pub fn relocateSections(self: *Self, allocator: std.mem.Allocator) !void {
|
||||
}
|
||||
|
||||
pub fn protectSections(self: *Self) !void {
|
||||
const sections: []*Section = .{ &self.text, &self.data, &self.rodata };
|
||||
const sections = [_]*Section{ &self.text, &self.data, &self.rodata };
|
||||
|
||||
for (sections) |section| {
|
||||
switch (builtin.os.tag) {
|
||||
@@ -157,7 +157,7 @@ pub fn protectSections(self: *Self) !void {
|
||||
.linux => {
|
||||
const linux = std.os.linux;
|
||||
|
||||
const protection = switch (section.protection) {
|
||||
const protection: usize = switch (section.protection) {
|
||||
.executable => linux.PROT.EXEC,
|
||||
.read_only => linux.PROT.READ,
|
||||
.read_write => linux.PROT.READ | linux.PROT.WRITE,
|
||||
|
||||
@@ -57,14 +57,14 @@ pub const Punctuator = enum(u32) {
|
||||
pub const line_continuation_crlf = strToInt3("\\\r\n");
|
||||
};
|
||||
|
||||
fn strToInt1(str: *const u8[1]) u32 {
|
||||
fn strToInt1(str: *const [1]u8) u32 {
|
||||
return @as(u8, @bitCast(str.*));
|
||||
}
|
||||
|
||||
fn strToInt2(str: *const u8[2]) u32 {
|
||||
fn strToInt2(str: *const [2]u8) u32 {
|
||||
return @as(u16, @bitCast(str.*));
|
||||
}
|
||||
|
||||
fn strToInt3(str: *const u8[3]) u32 {
|
||||
fn strToInt3(str: *const [3]u8) u32 {
|
||||
return @as(u24, @bitCast(str.*));
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ wide_string: std.ArrayList(u32),
|
||||
|
||||
pub fn init(arena_allocator: std.mem.Allocator) !Self {
|
||||
const string_buffer = try arena_allocator.alloc(u8, max_string_length);
|
||||
const wide_string_buffer = try arena_allocator.alloc(u8, max_wide_string_length);
|
||||
const wide_string_buffer = try arena_allocator.alloc(u32, max_wide_string_length);
|
||||
|
||||
return .{
|
||||
.string = .initBuffer(string_buffer),
|
||||
@@ -34,7 +34,7 @@ pub fn setSource(self: *Self, filename: []const u8, code: []const u8) void {
|
||||
}
|
||||
|
||||
pub fn nextToken(self: *Self, arena_allocator: std.mem.Allocator) !?Token {
|
||||
self.skipWhitespace();
|
||||
try self.skipWhitespace();
|
||||
|
||||
// TODO Skip C and C++ style comments
|
||||
// TODO Preprocessor directives
|
||||
@@ -53,7 +53,7 @@ pub fn nextToken(self: *Self, arena_allocator: std.mem.Allocator) !?Token {
|
||||
const state = self.it.save();
|
||||
|
||||
self.it.advanceCodepoint(cp);
|
||||
const cp2 = self.peekCodepointSkipLineContinuation() orelse 0;
|
||||
const cp2 = try self.peekCodepointSkipLineContinuation() orelse 0;
|
||||
|
||||
switch (cp2) {
|
||||
// Wide string
|
||||
@@ -83,7 +83,7 @@ pub fn nextToken(self: *Self, arena_allocator: std.mem.Allocator) !?Token {
|
||||
next_cp = try self.peekCodepointSkipLineContinuation();
|
||||
}
|
||||
|
||||
const identifier = self.str[identifier_start..self.it.ptr];
|
||||
const identifier = self.it.str[identifier_start..self.it.ptr];
|
||||
|
||||
// TODO Preprocessor
|
||||
|
||||
@@ -92,7 +92,7 @@ pub fn nextToken(self: *Self, arena_allocator: std.mem.Allocator) !?Token {
|
||||
} else if (Builtin.isBuiltin(identifier)) |builtin| {
|
||||
return .{ .builtin = builtin };
|
||||
} else {
|
||||
return .{ .identifier = arena_allocator.dupe(u8, identifier) };
|
||||
return .{ .identifier = try arena_allocator.dupe(u8, identifier) };
|
||||
}
|
||||
},
|
||||
// String
|
||||
@@ -106,6 +106,7 @@ pub fn nextToken(self: *Self, arena_allocator: std.mem.Allocator) !?Token {
|
||||
self.it.advanceCodepoint(cp);
|
||||
// TODO Parse char
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
|
||||
// Higher code points should've been already handled. The code below may
|
||||
@@ -245,7 +246,7 @@ fn skipWhitespace(self: *Self) !void {
|
||||
0x000D,
|
||||
// Space (SP)
|
||||
0x0020,
|
||||
=> try self.it.advanceCodepoint(cp),
|
||||
=> self.it.advanceCodepoint(cp),
|
||||
else => return,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,10 +78,6 @@ pub fn peekThreeBytes(self: Self) ?u32 {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn advanceAsciiBytes(self: *Self, bytes: usize) void {
|
||||
std.debug.assert(self.str.ptr + bytes <= self.str.len);
|
||||
}
|
||||
|
||||
/// Call with value returned by `peekCodepoint`.
|
||||
pub fn advanceCodepoint(self: *Self, cp: u21) void {
|
||||
std.debug.assert(blk: {
|
||||
|
||||
@@ -36,7 +36,7 @@ pub const Gpr = enum(u4) {
|
||||
}
|
||||
|
||||
pub fn x(self: Gpr) bool {
|
||||
return @intFromEnum(self & 0b1000) != 0;
|
||||
return @intFromEnum(self) & 0b1000 != 0;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -63,17 +63,17 @@ pub const Xmm = enum(u4) {
|
||||
}
|
||||
|
||||
pub fn x(self: Xmm) bool {
|
||||
return @intFromEnum(self & 0b1000) != 0;
|
||||
return @intFromEnum(self) & 0b1000 != 0;
|
||||
}
|
||||
};
|
||||
|
||||
// --- EMIT HELPERS ------------------------------------------------------------
|
||||
|
||||
pub const Rex = packed struct(u8) {
|
||||
b: bool,
|
||||
x: bool,
|
||||
r: bool,
|
||||
w: bool,
|
||||
b: bool = false,
|
||||
x: bool = false,
|
||||
r: bool = false,
|
||||
w: bool = false,
|
||||
/// MUST always be the default value
|
||||
prefix: u4 = 0b0100,
|
||||
};
|
||||
@@ -127,19 +127,19 @@ pub fn imm8(rt: *Runtime, value: u8) !void {
|
||||
pub fn imm16(rt: *Runtime, value: u16) !void {
|
||||
var bytes: [2]u8 = undefined;
|
||||
std.mem.writeInt(u16, &bytes, value, .little);
|
||||
try rt.sections.text.writeBytes(value, rt.allocator);
|
||||
try rt.sections.text.writeBytes(&bytes, rt.allocator);
|
||||
}
|
||||
|
||||
pub fn imm32(rt: *Runtime, value: u32) !void {
|
||||
var bytes: [4]u8 = undefined;
|
||||
std.mem.writeInt(u32, &bytes, value, .little);
|
||||
try rt.sections.text.writeBytes(value, rt.allocator);
|
||||
try rt.sections.text.writeBytes(&bytes, rt.allocator);
|
||||
}
|
||||
|
||||
pub fn imm64(rt: *Runtime, value: u64) !void {
|
||||
var bytes: [8]u8 = undefined;
|
||||
std.mem.writeInt(u64, &bytes, value, .little);
|
||||
try rt.sections.text.writeBytes(value, rt.allocator);
|
||||
try rt.sections.text.writeBytes(&bytes, rt.allocator);
|
||||
}
|
||||
|
||||
pub fn disp8(rt: *Runtime, value: i8) !void {
|
||||
@@ -149,7 +149,7 @@ pub fn disp8(rt: *Runtime, value: i8) !void {
|
||||
pub fn disp32(rt: *Runtime, value: i32) !void {
|
||||
var bytes: [4]u8 = undefined;
|
||||
std.mem.writeInt(i32, &bytes, value, .little);
|
||||
try rt.sections.text.writeBytes(bytes, rt.allocator);
|
||||
try rt.sections.text.writeBytes(&bytes, rt.allocator);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -234,7 +234,8 @@ pub fn load(rt: *Runtime, dst_register: Register, src_value: *const StackValue)
|
||||
|
||||
switch (src_value.value) {
|
||||
.register => |src_register| {
|
||||
if (dst_register == src_register) return;
|
||||
if (std.meta.eql(dst_register, src_register)) return;
|
||||
// TODO
|
||||
},
|
||||
.constant => |constant| switch (dst_register) {
|
||||
.gpr => |dest_gpr| switch (size) {
|
||||
@@ -246,7 +247,7 @@ pub fn load(rt: *Runtime, dst_register: Register, src_value: *const StackValue)
|
||||
// otherwise ah, ch, dh and bh would be used.
|
||||
try rex(rt, .{ .r = dest_gpr.x() });
|
||||
}
|
||||
try op(rt, 0xB0 | dest_gpr.reg());
|
||||
try op(rt, 0xB0 | @as(u8, dest_gpr.reg()));
|
||||
try imm8(rt, @truncate(constant));
|
||||
},
|
||||
2 => {
|
||||
@@ -256,7 +257,7 @@ pub fn load(rt: *Runtime, dst_register: Register, src_value: *const StackValue)
|
||||
if (@intFromEnum(dest_gpr) >= 8) {
|
||||
try rex(rt, .{ .r = dest_gpr.x() });
|
||||
}
|
||||
try op(rt, 0xB8 | dest_gpr.reg());
|
||||
try op(rt, 0xB8 | @as(u8, dest_gpr.reg()));
|
||||
try imm16(rt, @truncate(constant));
|
||||
},
|
||||
4 => {
|
||||
@@ -265,14 +266,14 @@ pub fn load(rt: *Runtime, dst_register: Register, src_value: *const StackValue)
|
||||
if (@intFromEnum(dest_gpr) >= 8) {
|
||||
try rex(rt, .{ .r = dest_gpr.x() });
|
||||
}
|
||||
try op(rt, 0xB8 | dest_gpr.reg());
|
||||
try op(rt, 0xB8 | @as(u8, dest_gpr.reg()));
|
||||
try imm32(rt, @truncate(constant));
|
||||
},
|
||||
8 => {
|
||||
// MOV r64, imm64
|
||||
// REX.W + B8+ rd io
|
||||
try rex(rt, .{ .r = dest_gpr.x(), .w = true });
|
||||
try op(rt, 0xB8 | dest_gpr.reg());
|
||||
try op(rt, 0xB8 | @as(u8, dest_gpr.reg()));
|
||||
try imm64(rt, constant);
|
||||
},
|
||||
else => unreachable,
|
||||
@@ -295,7 +296,7 @@ pub fn load(rt: *Runtime, dst_register: Register, src_value: *const StackValue)
|
||||
try op2(rt, 0x0F, 0x6E);
|
||||
// [rip + disp32]
|
||||
try modrm(rt, .{ .mod = 0b00, .reg = dest_xmm.reg(), .rm = Gpr.rbp.reg() });
|
||||
try allocRodataDisp32(rt, &data);
|
||||
try allocRodataDisp32(rt, data);
|
||||
},
|
||||
},
|
||||
.symbol => |symbol| {},
|
||||
|
||||
@@ -9,7 +9,7 @@ test {
|
||||
var rt: cjit.Runtime = try .init(std.testing.allocator);
|
||||
defer rt.deinit();
|
||||
|
||||
try rt.compile(
|
||||
try rt.compile("test.c",
|
||||
\\int add(int a, int b);
|
||||
\\
|
||||
\\int add_one(int x)
|
||||
|
||||
Reference in New Issue
Block a user