cjit: Fix some compilation errors

This commit is contained in:
2026-01-27 14:56:39 +01:00
parent 0a3d82a562
commit f2b7817cac
7 changed files with 38 additions and 41 deletions

View File

@@ -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));
}

View File

@@ -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,

View File

@@ -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.*));
}

View File

@@ -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,
}
}

View File

@@ -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: {

View File

@@ -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| {},

View File

@@ -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)