Start reworking parser and moving away from Zig
This commit is contained in:
parent
54500c149f
commit
196b8c0588
509
build.zig
509
build.zig
@ -61,233 +61,6 @@ const CmakeBuildType = enum {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const LLVM = struct {
|
|
||||||
module: *std.Build.Module,
|
|
||||||
|
|
||||||
fn setup(b: *std.Build, path: []const u8) !LLVM {
|
|
||||||
var llvm_libs = std.ArrayList([]const u8).init(b.allocator);
|
|
||||||
var flags = std.ArrayList([]const u8).init(b.allocator);
|
|
||||||
const llvm_config_path = if (b.option([]const u8, "llvm_prefix", "LLVM prefix")) |llvm_prefix| blk: {
|
|
||||||
const full_path = try std.mem.concat(b.allocator, u8, &.{ llvm_prefix, "/bin/llvm-config" });
|
|
||||||
const f = std.fs.cwd().openFile(full_path, .{}) catch return error.llvm_not_found;
|
|
||||||
f.close();
|
|
||||||
break :blk full_path;
|
|
||||||
} else if (system_llvm) executable_find_in_path(b.allocator, "llvm-config", path) orelse return error.llvm_not_found else blk: {
|
|
||||||
const home_env = switch (@import("builtin").os.tag) {
|
|
||||||
.windows => "USERPROFILE",
|
|
||||||
else => "HOME",
|
|
||||||
};
|
|
||||||
const home_path = env.get(home_env) orelse unreachable;
|
|
||||||
const is_ci = std.mem.eql(u8, (env.get("BB_CI") orelse "0"), "1");
|
|
||||||
const download_dir = try std.mem.concat(b.allocator, u8, &.{ home_path, "/Downloads" });
|
|
||||||
std.fs.makeDirAbsolute(download_dir) catch {};
|
|
||||||
const cmake_build_type = if (is_ci) CmakeBuildType.from_zig_build_type(optimize) else CmakeBuildType.Release;
|
|
||||||
const llvm_base = try std.mem.concat(b.allocator, u8, &.{ "llvm-", @tagName(target.result.cpu.arch), "-", @tagName(target.result.os.tag), "-", @tagName(cmake_build_type) });
|
|
||||||
const base = try std.mem.concat(b.allocator, u8, &.{ download_dir, "/", llvm_base });
|
|
||||||
const full_path = try std.mem.concat(b.allocator, u8, &.{ base, "/bin/llvm-config" });
|
|
||||||
|
|
||||||
const f = std.fs.cwd().openFile(full_path, .{}) catch {
|
|
||||||
const url = try std.mem.concat(b.allocator, u8, &.{ "https://github.com/birth-software/llvm/releases/download/v19.1.7/", llvm_base, ".7z" });
|
|
||||||
var result = try std.process.Child.run(.{
|
|
||||||
.allocator = b.allocator,
|
|
||||||
.argv = &.{ "wget", "-P", download_dir, url },
|
|
||||||
.max_output_bytes = std.math.maxInt(usize),
|
|
||||||
});
|
|
||||||
var success = false;
|
|
||||||
switch (result.term) {
|
|
||||||
.Exited => |exit_code| {
|
|
||||||
success = exit_code == 0;
|
|
||||||
},
|
|
||||||
else => {},
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!success) {
|
|
||||||
std.debug.print("{s}\n{s}\n", .{ result.stdout, result.stderr });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (success) {
|
|
||||||
const file_7z = try std.mem.concat(b.allocator, u8, &.{ base, ".7z" });
|
|
||||||
result = try std.process.Child.run(.{
|
|
||||||
.allocator = b.allocator,
|
|
||||||
.argv = &.{ "7z", "x", try std.mem.concat(b.allocator, u8, &.{ "-o", download_dir }), file_7z },
|
|
||||||
.max_output_bytes = std.math.maxInt(usize),
|
|
||||||
});
|
|
||||||
success = false;
|
|
||||||
switch (result.term) {
|
|
||||||
.Exited => |exit_code| {
|
|
||||||
success = exit_code == 0;
|
|
||||||
},
|
|
||||||
else => {},
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!success) {
|
|
||||||
std.debug.print("{s}\n{s}\n", .{ result.stdout, result.stderr });
|
|
||||||
}
|
|
||||||
|
|
||||||
break :blk full_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
return error.llvm_not_found;
|
|
||||||
};
|
|
||||||
|
|
||||||
f.close();
|
|
||||||
break :blk full_path;
|
|
||||||
};
|
|
||||||
const llvm_components_result = try run_process_and_capture_stdout(b, &.{ llvm_config_path, "--components" });
|
|
||||||
var it = std.mem.splitScalar(u8, llvm_components_result, ' ');
|
|
||||||
var args = std.ArrayList([]const u8).init(b.allocator);
|
|
||||||
try args.append(llvm_config_path);
|
|
||||||
try args.append("--libs");
|
|
||||||
while (it.next()) |component| {
|
|
||||||
try args.append(std.mem.trimRight(u8, component, "\n"));
|
|
||||||
}
|
|
||||||
const llvm_libs_result = try run_process_and_capture_stdout(b, args.items);
|
|
||||||
it = std.mem.splitScalar(u8, llvm_libs_result, ' ');
|
|
||||||
|
|
||||||
while (it.next()) |lib| {
|
|
||||||
const llvm_lib = std.mem.trimLeft(u8, std.mem.trimRight(u8, lib, "\n"), "-l");
|
|
||||||
try llvm_libs.append(llvm_lib);
|
|
||||||
}
|
|
||||||
|
|
||||||
const llvm_cxx_flags_result = try run_process_and_capture_stdout(b, &.{ llvm_config_path, "--cxxflags" });
|
|
||||||
it = std.mem.splitScalar(u8, llvm_cxx_flags_result, ' ');
|
|
||||||
while (it.next()) |flag| {
|
|
||||||
const llvm_cxx_flag = std.mem.trimRight(u8, flag, "\n");
|
|
||||||
try flags.append(llvm_cxx_flag);
|
|
||||||
}
|
|
||||||
|
|
||||||
const llvm_lib_dir = std.mem.trimRight(u8, try run_process_and_capture_stdout(b, &.{ llvm_config_path, "--libdir" }), "\n");
|
|
||||||
|
|
||||||
if (optimize != .ReleaseSmall) {
|
|
||||||
try flags.append("-g");
|
|
||||||
}
|
|
||||||
|
|
||||||
try flags.append("-fno-rtti");
|
|
||||||
|
|
||||||
const llvm = b.createModule(.{
|
|
||||||
.target = target,
|
|
||||||
.optimize = optimize,
|
|
||||||
.sanitize_c = false,
|
|
||||||
});
|
|
||||||
|
|
||||||
llvm.addLibraryPath(.{ .cwd_relative = llvm_lib_dir });
|
|
||||||
|
|
||||||
const a = std.fs.cwd().openDir("/usr/lib/x86_64-linux-gnu/", .{});
|
|
||||||
if (a) |_| {
|
|
||||||
var dir = a catch unreachable;
|
|
||||||
dir.close();
|
|
||||||
llvm.addLibraryPath(.{ .cwd_relative = "/usr/lib/x86_64-linux-gnu/" });
|
|
||||||
} else |err| {
|
|
||||||
err catch {};
|
|
||||||
}
|
|
||||||
|
|
||||||
llvm.addCSourceFiles(.{
|
|
||||||
.files = &.{"src/llvm.cpp"},
|
|
||||||
.flags = flags.items,
|
|
||||||
});
|
|
||||||
|
|
||||||
var dir = try std.fs.cwd().openDir("/usr/include/c++", .{
|
|
||||||
.iterate = true,
|
|
||||||
});
|
|
||||||
var iterator = dir.iterate();
|
|
||||||
const gcc_version = while (try iterator.next()) |entry| {
|
|
||||||
if (entry.kind == .directory) {
|
|
||||||
break entry.name;
|
|
||||||
}
|
|
||||||
} else return error.include_cpp_dir_not_found;
|
|
||||||
dir.close();
|
|
||||||
const general_cpp_include_dir = try std.mem.concat(b.allocator, u8, &.{ "/usr/include/c++/", gcc_version });
|
|
||||||
llvm.addIncludePath(.{ .cwd_relative = general_cpp_include_dir });
|
|
||||||
|
|
||||||
{
|
|
||||||
const arch_cpp_include_dir = try std.mem.concat(b.allocator, u8, &.{ general_cpp_include_dir, "/x86_64-pc-linux-gnu" });
|
|
||||||
const d2 = std.fs.cwd().openDir(arch_cpp_include_dir, .{});
|
|
||||||
if (d2) |_| {
|
|
||||||
var d = d2 catch unreachable;
|
|
||||||
d.close();
|
|
||||||
llvm.addIncludePath(.{ .cwd_relative = arch_cpp_include_dir });
|
|
||||||
} else |err| err catch {};
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
const arch_cpp_include_dir = try std.mem.concat(b.allocator, u8, &.{ "/usr/include/x86_64-linux-gnu/c++/", gcc_version });
|
|
||||||
const d2 = std.fs.cwd().openDir(arch_cpp_include_dir, .{});
|
|
||||||
if (d2) |_| {
|
|
||||||
var d = d2 catch unreachable;
|
|
||||||
d.close();
|
|
||||||
llvm.addIncludePath(.{ .cwd_relative = arch_cpp_include_dir });
|
|
||||||
} else |err| err catch {};
|
|
||||||
}
|
|
||||||
|
|
||||||
var found_libcpp = false;
|
|
||||||
|
|
||||||
if (std.fs.cwd().openFile("/usr/lib/libstdc++.so.6", .{})) |file| {
|
|
||||||
file.close();
|
|
||||||
found_libcpp = true;
|
|
||||||
llvm.addObjectFile(.{ .cwd_relative = "/usr/lib/libstdc++.so.6" });
|
|
||||||
} else |err| {
|
|
||||||
err catch {};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (std.fs.cwd().openFile("/usr/lib/x86_64-linux-gnu/libstdc++.so.6", .{})) |file| {
|
|
||||||
file.close();
|
|
||||||
found_libcpp = true;
|
|
||||||
llvm.addObjectFile(.{ .cwd_relative = "/usr/lib/x86_64-linux-gnu/libstdc++.so.6" });
|
|
||||||
} else |err| {
|
|
||||||
err catch {};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found_libcpp) {
|
|
||||||
return error.libcpp_not_found;
|
|
||||||
}
|
|
||||||
|
|
||||||
const needed_libraries: []const []const u8 = &.{ "unwind", "z", "zstd" };
|
|
||||||
|
|
||||||
const lld_libs: []const []const u8 = &.{ "lldCommon", "lldCOFF", "lldELF", "lldMachO", "lldMinGW", "lldWasm" };
|
|
||||||
|
|
||||||
for (needed_libraries) |lib| {
|
|
||||||
llvm.linkSystemLibrary(lib, .{});
|
|
||||||
}
|
|
||||||
|
|
||||||
for (llvm_libs.items) |lib| {
|
|
||||||
llvm.linkSystemLibrary(lib, .{});
|
|
||||||
}
|
|
||||||
|
|
||||||
for (lld_libs) |lib| {
|
|
||||||
llvm.linkSystemLibrary(lib, .{});
|
|
||||||
}
|
|
||||||
|
|
||||||
return LLVM{
|
|
||||||
.module = llvm,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn link(llvm: LLVM, compile: *std.Build.Step.Compile) void {
|
|
||||||
if (compile.root_module != llvm.module) {
|
|
||||||
compile.root_module.addImport("llvm", llvm.module);
|
|
||||||
} else {
|
|
||||||
// TODO: should we allow this case?
|
|
||||||
unreachable;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
fn debug_binary(b: *std.Build, exe: *std.Build.Step.Compile) *std.Build.Step.Run {
|
|
||||||
const run_step = std.Build.Step.Run.create(b, b.fmt("debug {s}", .{exe.name}));
|
|
||||||
run_step.addArg("gdb");
|
|
||||||
run_step.addArg("-ex");
|
|
||||||
run_step.addArg("r");
|
|
||||||
if (b.args) |args| {
|
|
||||||
run_step.addArg("--args");
|
|
||||||
run_step.addArtifactArg(exe);
|
|
||||||
run_step.addArgs(args);
|
|
||||||
} else {
|
|
||||||
run_step.addArtifactArg(exe);
|
|
||||||
}
|
|
||||||
|
|
||||||
return run_step;
|
|
||||||
}
|
|
||||||
|
|
||||||
var system_llvm: bool = undefined;
|
var system_llvm: bool = undefined;
|
||||||
var target: std.Build.ResolvedTarget = undefined;
|
var target: std.Build.ResolvedTarget = undefined;
|
||||||
var optimize: std.builtin.OptimizeMode = undefined;
|
var optimize: std.builtin.OptimizeMode = undefined;
|
||||||
@ -309,18 +82,16 @@ pub fn build(b: *std.Build) !void {
|
|||||||
target = b.standardTargetOptions(.{});
|
target = b.standardTargetOptions(.{});
|
||||||
optimize = b.standardOptimizeOption(.{});
|
optimize = b.standardOptimizeOption(.{});
|
||||||
system_llvm = b.option(bool, "system_llvm", "Link against system LLVM libraries") orelse false;
|
system_llvm = b.option(bool, "system_llvm", "Link against system LLVM libraries") orelse false;
|
||||||
const path = env.get("PATH") orelse unreachable;
|
|
||||||
|
|
||||||
const c_abi_module = b.createModule(.{
|
|
||||||
.target = target,
|
|
||||||
.optimize = optimize,
|
|
||||||
.link_libc = true,
|
|
||||||
.sanitize_c = false,
|
|
||||||
});
|
|
||||||
const c_abi = b.addObject(.{
|
const c_abi = b.addObject(.{
|
||||||
.name = "c_abi",
|
.name = "c_abi",
|
||||||
.link_libc = true,
|
.link_libc = true,
|
||||||
.root_module = c_abi_module,
|
.root_module = b.createModule(.{
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
.link_libc = true,
|
||||||
|
.sanitize_c = false,
|
||||||
|
}),
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
});
|
});
|
||||||
c_abi.addCSourceFiles(.{
|
c_abi.addCSourceFiles(.{
|
||||||
@ -328,6 +99,18 @@ pub fn build(b: *std.Build) !void {
|
|||||||
.flags = &.{"-g"},
|
.flags = &.{"-g"},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const path = env.get("PATH") orelse unreachable;
|
||||||
|
|
||||||
|
const stack_trace_library = b.addObject(.{
|
||||||
|
.name = "stack_trace",
|
||||||
|
.root_module = b.createModule(.{
|
||||||
|
.target = target,
|
||||||
|
.optimize = .ReleaseFast,
|
||||||
|
.root_source_file = b.path("src/stack_trace.zig"),
|
||||||
|
.link_libc = true,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
const exe_mod = b.createModule(.{
|
const exe_mod = b.createModule(.{
|
||||||
.root_source_file = b.path("src/main.zig"),
|
.root_source_file = b.path("src/main.zig"),
|
||||||
.target = target,
|
.target = target,
|
||||||
@ -339,43 +122,241 @@ pub fn build(b: *std.Build) !void {
|
|||||||
configuration.addOptionPath("c_abi_object_path", c_abi.getEmittedBin());
|
configuration.addOptionPath("c_abi_object_path", c_abi.getEmittedBin());
|
||||||
exe_mod.addOptions("configuration", configuration);
|
exe_mod.addOptions("configuration", configuration);
|
||||||
|
|
||||||
const llvm = try LLVM.setup(b, path);
|
|
||||||
|
|
||||||
const exe = b.addExecutable(.{
|
const exe = b.addExecutable(.{
|
||||||
.name = "bloat-buster",
|
.name = "bloat-buster",
|
||||||
.root_module = exe_mod,
|
.root_module = exe_mod,
|
||||||
.link_libc = true,
|
.link_libc = true,
|
||||||
});
|
});
|
||||||
|
exe.addObject(stack_trace_library);
|
||||||
|
var llvm_libs = std.ArrayList([]const u8).init(b.allocator);
|
||||||
|
var flags = std.ArrayList([]const u8).init(b.allocator);
|
||||||
|
const llvm_config_path = if (b.option([]const u8, "llvm_prefix", "LLVM prefix")) |llvm_prefix| blk: {
|
||||||
|
const full_path = try std.mem.concat(b.allocator, u8, &.{ llvm_prefix, "/bin/llvm-config" });
|
||||||
|
const f = std.fs.cwd().openFile(full_path, .{}) catch return error.llvm_not_found;
|
||||||
|
f.close();
|
||||||
|
break :blk full_path;
|
||||||
|
} else if (system_llvm) executable_find_in_path(b.allocator, "llvm-config", path) orelse return error.llvm_not_found else blk: {
|
||||||
|
const home_env = switch (@import("builtin").os.tag) {
|
||||||
|
.windows => "USERPROFILE",
|
||||||
|
else => "HOME",
|
||||||
|
};
|
||||||
|
const home_path = env.get(home_env) orelse unreachable;
|
||||||
|
const is_ci = std.mem.eql(u8, (env.get("BB_CI") orelse "0"), "1");
|
||||||
|
const download_dir = try std.mem.concat(b.allocator, u8, &.{ home_path, "/Downloads" });
|
||||||
|
std.fs.makeDirAbsolute(download_dir) catch {};
|
||||||
|
const cmake_build_type = if (is_ci) CmakeBuildType.from_zig_build_type(optimize) else CmakeBuildType.Release;
|
||||||
|
const llvm_base = try std.mem.concat(b.allocator, u8, &.{ "llvm-", @tagName(target.result.cpu.arch), "-", @tagName(target.result.os.tag), "-", @tagName(cmake_build_type) });
|
||||||
|
const base = try std.mem.concat(b.allocator, u8, &.{ download_dir, "/", llvm_base });
|
||||||
|
const full_path = try std.mem.concat(b.allocator, u8, &.{ base, "/bin/llvm-config" });
|
||||||
|
|
||||||
llvm.link(exe);
|
const f = std.fs.cwd().openFile(full_path, .{}) catch {
|
||||||
|
const url = try std.mem.concat(b.allocator, u8, &.{ "https://github.com/birth-software/llvm/releases/download/v19.1.7/", llvm_base, ".7z" });
|
||||||
|
var result = try std.process.Child.run(.{
|
||||||
|
.allocator = b.allocator,
|
||||||
|
.argv = &.{ "wget", "-P", download_dir, url },
|
||||||
|
.max_output_bytes = std.math.maxInt(usize),
|
||||||
|
});
|
||||||
|
var success = false;
|
||||||
|
switch (result.term) {
|
||||||
|
.Exited => |exit_code| {
|
||||||
|
success = exit_code == 0;
|
||||||
|
},
|
||||||
|
else => {},
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
std.debug.print("{s}\n{s}\n", .{ result.stdout, result.stderr });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
const file_7z = try std.mem.concat(b.allocator, u8, &.{ base, ".7z" });
|
||||||
|
result = try std.process.Child.run(.{
|
||||||
|
.allocator = b.allocator,
|
||||||
|
.argv = &.{ "7z", "x", try std.mem.concat(b.allocator, u8, &.{ "-o", download_dir }), file_7z },
|
||||||
|
.max_output_bytes = std.math.maxInt(usize),
|
||||||
|
});
|
||||||
|
success = false;
|
||||||
|
switch (result.term) {
|
||||||
|
.Exited => |exit_code| {
|
||||||
|
success = exit_code == 0;
|
||||||
|
},
|
||||||
|
else => {},
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
std.debug.print("{s}\n{s}\n", .{ result.stdout, result.stderr });
|
||||||
|
}
|
||||||
|
|
||||||
|
break :blk full_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
return error.llvm_not_found;
|
||||||
|
};
|
||||||
|
|
||||||
|
f.close();
|
||||||
|
break :blk full_path;
|
||||||
|
};
|
||||||
|
const llvm_components_result = try run_process_and_capture_stdout(b, &.{ llvm_config_path, "--components" });
|
||||||
|
var it = std.mem.splitScalar(u8, llvm_components_result, ' ');
|
||||||
|
{
|
||||||
|
var args = std.ArrayList([]const u8).init(b.allocator);
|
||||||
|
try args.append(llvm_config_path);
|
||||||
|
try args.append("--libs");
|
||||||
|
while (it.next()) |component| {
|
||||||
|
try args.append(std.mem.trimRight(u8, component, "\n"));
|
||||||
|
}
|
||||||
|
const llvm_libs_result = try run_process_and_capture_stdout(b, args.items);
|
||||||
|
it = std.mem.splitScalar(u8, llvm_libs_result, ' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
while (it.next()) |lib| {
|
||||||
|
const llvm_lib = std.mem.trimLeft(u8, std.mem.trimRight(u8, lib, "\n"), "-l");
|
||||||
|
try llvm_libs.append(llvm_lib);
|
||||||
|
}
|
||||||
|
|
||||||
|
const llvm_cxx_flags_result = try run_process_and_capture_stdout(b, &.{ llvm_config_path, "--cxxflags" });
|
||||||
|
it = std.mem.splitScalar(u8, llvm_cxx_flags_result, ' ');
|
||||||
|
while (it.next()) |flag| {
|
||||||
|
const llvm_cxx_flag = std.mem.trimRight(u8, flag, "\n");
|
||||||
|
try flags.append(llvm_cxx_flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
const llvm_lib_dir = std.mem.trimRight(u8, try run_process_and_capture_stdout(b, &.{ llvm_config_path, "--libdir" }), "\n");
|
||||||
|
|
||||||
|
if (optimize != .ReleaseSmall) {
|
||||||
|
try flags.append("-g");
|
||||||
|
}
|
||||||
|
|
||||||
|
try flags.append("-fno-rtti");
|
||||||
|
|
||||||
|
exe.addLibraryPath(.{ .cwd_relative = llvm_lib_dir });
|
||||||
|
|
||||||
|
const a = std.fs.cwd().openDir("/usr/lib/x86_64-linux-gnu/", .{});
|
||||||
|
if (a) |_| {
|
||||||
|
var dir = a catch unreachable;
|
||||||
|
dir.close();
|
||||||
|
exe.addLibraryPath(.{ .cwd_relative = "/usr/lib/x86_64-linux-gnu/" });
|
||||||
|
} else |err| {
|
||||||
|
err catch {};
|
||||||
|
}
|
||||||
|
|
||||||
|
exe.addCSourceFiles(.{
|
||||||
|
.files = &.{"src/llvm.cpp"},
|
||||||
|
.flags = flags.items,
|
||||||
|
});
|
||||||
|
|
||||||
|
var dir = try std.fs.cwd().openDir("/usr/include/c++", .{
|
||||||
|
.iterate = true,
|
||||||
|
});
|
||||||
|
var iterator = dir.iterate();
|
||||||
|
const gcc_version = while (try iterator.next()) |entry| {
|
||||||
|
if (entry.kind == .directory) {
|
||||||
|
break entry.name;
|
||||||
|
}
|
||||||
|
} else return error.include_cpp_dir_not_found;
|
||||||
|
dir.close();
|
||||||
|
const general_cpp_include_dir = try std.mem.concat(b.allocator, u8, &.{ "/usr/include/c++/", gcc_version });
|
||||||
|
exe.addIncludePath(.{ .cwd_relative = general_cpp_include_dir });
|
||||||
|
|
||||||
|
{
|
||||||
|
const arch_cpp_include_dir = try std.mem.concat(b.allocator, u8, &.{ general_cpp_include_dir, "/x86_64-pc-linux-gnu" });
|
||||||
|
const d2 = std.fs.cwd().openDir(arch_cpp_include_dir, .{});
|
||||||
|
if (d2) |_| {
|
||||||
|
var d = d2 catch unreachable;
|
||||||
|
d.close();
|
||||||
|
exe.addIncludePath(.{ .cwd_relative = arch_cpp_include_dir });
|
||||||
|
} else |err| err catch {};
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const arch_cpp_include_dir = try std.mem.concat(b.allocator, u8, &.{ "/usr/include/x86_64-linux-gnu/c++/", gcc_version });
|
||||||
|
const d2 = std.fs.cwd().openDir(arch_cpp_include_dir, .{});
|
||||||
|
if (d2) |_| {
|
||||||
|
var d = d2 catch unreachable;
|
||||||
|
d.close();
|
||||||
|
exe.addIncludePath(.{ .cwd_relative = arch_cpp_include_dir });
|
||||||
|
} else |err| err catch {};
|
||||||
|
}
|
||||||
|
|
||||||
|
var found_libcpp = false;
|
||||||
|
|
||||||
|
if (std.fs.cwd().openFile("/usr/lib/libstdc++.so.6", .{})) |file| {
|
||||||
|
file.close();
|
||||||
|
found_libcpp = true;
|
||||||
|
exe.addObjectFile(.{ .cwd_relative = "/usr/lib/libstdc++.so.6" });
|
||||||
|
} else |err| {
|
||||||
|
err catch {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std.fs.cwd().openFile("/usr/lib/x86_64-linux-gnu/libstdc++.so.6", .{})) |file| {
|
||||||
|
file.close();
|
||||||
|
found_libcpp = true;
|
||||||
|
exe.addObjectFile(.{ .cwd_relative = "/usr/lib/x86_64-linux-gnu/libstdc++.so.6" });
|
||||||
|
} else |err| {
|
||||||
|
err catch {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found_libcpp) {
|
||||||
|
return error.libcpp_not_found;
|
||||||
|
}
|
||||||
|
|
||||||
|
const needed_libraries: []const []const u8 = &.{ "unwind", "z", "zstd" };
|
||||||
|
for (needed_libraries) |lib| {
|
||||||
|
exe.linkSystemLibrary(lib);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (llvm_libs.items) |lib| {
|
||||||
|
exe.linkSystemLibrary(lib);
|
||||||
|
}
|
||||||
|
|
||||||
|
const lld_libs: []const []const u8 = &.{ "lldCommon", "lldCOFF", "lldELF", "lldMachO", "lldMinGW", "lldWasm" };
|
||||||
|
for (lld_libs) |lib| {
|
||||||
|
exe.linkSystemLibrary(lib);
|
||||||
|
}
|
||||||
|
|
||||||
b.installArtifact(exe);
|
b.installArtifact(exe);
|
||||||
|
|
||||||
const run_cmd = b.addRunArtifact(exe);
|
for ([_]bool{ false, true }) |is_test| {
|
||||||
run_cmd.step.dependOn(b.getInstallStep());
|
const run_step_name = switch (is_test) {
|
||||||
if (b.args) |args| {
|
true => "test",
|
||||||
run_cmd.addArgs(args);
|
false => "run",
|
||||||
|
};
|
||||||
|
|
||||||
|
const debug_step_name = switch (is_test) {
|
||||||
|
true => "debug_test",
|
||||||
|
false => "debug",
|
||||||
|
};
|
||||||
|
|
||||||
|
const command = b.addRunArtifact(exe);
|
||||||
|
command.step.dependOn(b.getInstallStep());
|
||||||
|
|
||||||
|
if (is_test) {
|
||||||
|
command.addArg("test");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b.args) |args| {
|
||||||
|
command.addArgs(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
const run_step = b.step(run_step_name, "");
|
||||||
|
run_step.dependOn(&command.step);
|
||||||
|
|
||||||
|
const debug_command = std.Build.Step.Run.create(b, b.fmt("{s} {s}", .{ debug_step_name, exe.name }));
|
||||||
|
debug_command.addArg("gdb");
|
||||||
|
debug_command.addArg("-ex");
|
||||||
|
debug_command.addArg("r");
|
||||||
|
debug_command.addArg("--args");
|
||||||
|
debug_command.addArtifactArg(exe);
|
||||||
|
|
||||||
|
if (is_test) {
|
||||||
|
debug_command.addArg("test");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b.args) |args| {
|
||||||
|
debug_command.addArgs(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
const debug_step = b.step(debug_step_name, "");
|
||||||
|
debug_step.dependOn(&debug_command.step);
|
||||||
}
|
}
|
||||||
const run_step = b.step("run", "Run the app");
|
|
||||||
run_step.dependOn(&run_cmd.step);
|
|
||||||
|
|
||||||
const debug_cmd = debug_binary(b, exe);
|
|
||||||
const debug_step = b.step("debug", "Debug the app");
|
|
||||||
debug_step.dependOn(&debug_cmd.step);
|
|
||||||
|
|
||||||
const exe_unit_tests = b.addTest(.{
|
|
||||||
.root_module = exe_mod,
|
|
||||||
.link_libc = true,
|
|
||||||
});
|
|
||||||
|
|
||||||
llvm.link(exe);
|
|
||||||
|
|
||||||
const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests);
|
|
||||||
|
|
||||||
const test_step = b.step("test", "Run unit tests");
|
|
||||||
test_step.dependOn(&run_exe_unit_tests.step);
|
|
||||||
|
|
||||||
const debug_test_cmd = debug_binary(b, exe_unit_tests);
|
|
||||||
const debug_test_step = b.step("debug_test", "Debug the tests");
|
|
||||||
debug_test_step.dependOn(&debug_test_cmd.step);
|
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ c_string_length = fn (c_string: &u8) u64
|
|||||||
c_string_to_slice = fn (c_string: &u8) []u8
|
c_string_to_slice = fn (c_string: &u8) []u8
|
||||||
{
|
{
|
||||||
>length = c_string_length(c_string);
|
>length = c_string_length(c_string);
|
||||||
return #slice(c_string, length);
|
return c_string[0..length];
|
||||||
}
|
}
|
||||||
|
|
||||||
string_equal = fn(a: []u8, b: []u8) u1
|
string_equal = fn(a: []u8, b: []u8) u1
|
||||||
@ -251,10 +251,10 @@ global_state_initialize = fn () void
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (!string_equal(#slice(relative_file_path, extension_start), ".bbb"))
|
if (!string_equal(relative_file_path[extension_start..], ".bbb"))
|
||||||
//{
|
{
|
||||||
// return 1;
|
return 1;
|
||||||
//}
|
}
|
||||||
|
|
||||||
global_state_initialize();
|
global_state_initialize();
|
||||||
return 0;
|
return 0;
|
||||||
|
1519
src/converter.zig
1519
src/converter.zig
File diff suppressed because it is too large
Load Diff
252
src/lib.zig
252
src/lib.zig
@ -1,7 +1,12 @@
|
|||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
pub const is_test = builtin.is_test;
|
pub const is_test = builtin.is_test;
|
||||||
pub const optimization_mode = builtin.mode;
|
pub const optimization_mode = builtin.mode;
|
||||||
const VariableArguments = @import("std").builtin.VaList;
|
pub const VariableArguments = extern struct {
|
||||||
|
gp_offset: c_uint,
|
||||||
|
fp_offset: c_uint,
|
||||||
|
overflow_arg_area: *anyopaque,
|
||||||
|
reg_save_area: *anyopaque,
|
||||||
|
};
|
||||||
extern "c" fn IsDebuggerPresent() bool;
|
extern "c" fn IsDebuggerPresent() bool;
|
||||||
extern "c" fn __errno_location() *c_int;
|
extern "c" fn __errno_location() *c_int;
|
||||||
|
|
||||||
@ -14,6 +19,9 @@ const CSlice = extern struct {
|
|||||||
length: usize,
|
length: usize,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern fn dump_stack_trace(return_address: usize) void;
|
||||||
|
extern fn enable_signal_handlers() void;
|
||||||
|
|
||||||
pub const KB = 1024;
|
pub const KB = 1024;
|
||||||
pub const MB = 1024 * 1024;
|
pub const MB = 1024 * 1024;
|
||||||
pub const GB = 1024 * 1024 * 1024;
|
pub const GB = 1024 * 1024 * 1024;
|
||||||
@ -515,9 +523,7 @@ pub const os = struct {
|
|||||||
if (os.is_being_debugged()) {
|
if (os.is_being_debugged()) {
|
||||||
@trap();
|
@trap();
|
||||||
} else {
|
} else {
|
||||||
if (is_test) {
|
dump_stack_trace(@returnAddress());
|
||||||
@import("std").debug.dumpCurrentStackTrace(@returnAddress());
|
|
||||||
}
|
|
||||||
|
|
||||||
libc.exit(1);
|
libc.exit(1);
|
||||||
}
|
}
|
||||||
@ -566,6 +572,14 @@ pub const libc = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const string = struct {
|
pub const string = struct {
|
||||||
|
pub fn to_enum(comptime E: type, str: []const u8) ?E {
|
||||||
|
inline for (@typeInfo(E).@"enum".fields) |e| {
|
||||||
|
if (equal(e.name, str)) {
|
||||||
|
return @field(E, e.name);
|
||||||
|
}
|
||||||
|
} else return null;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn equal(a: []const u8, b: []const u8) bool {
|
pub fn equal(a: []const u8, b: []const u8) bool {
|
||||||
var result = a.len == b.len;
|
var result = a.len == b.len;
|
||||||
if (result) {
|
if (result) {
|
||||||
@ -2684,143 +2698,147 @@ pub fn print_string_stderr(str: []const u8) void {
|
|||||||
os.get_stderr().write(str);
|
os.get_stderr().write(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const panic_struct = switch (is_test) {
|
pub const panic_struct = struct {
|
||||||
true => @import("std").debug.FullPanic(@import("std").debug.defaultPanic),
|
const abort = os.abort;
|
||||||
false => struct {
|
pub fn call(_: []const u8, _: ?usize) noreturn {
|
||||||
const abort = os.abort;
|
@branchHint(.cold);
|
||||||
pub fn call(_: []const u8, _: ?usize) noreturn {
|
abort();
|
||||||
@branchHint(.cold);
|
}
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn sentinelMismatch(_: anytype, _: anytype) noreturn {
|
pub fn sentinelMismatch(_: anytype, _: anytype) noreturn {
|
||||||
@branchHint(.cold);
|
@branchHint(.cold);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unwrapError(_: anyerror) noreturn {
|
pub fn unwrapError(_: anyerror) noreturn {
|
||||||
@branchHint(.cold);
|
@branchHint(.cold);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn outOfBounds(_: usize, _: usize) noreturn {
|
pub fn outOfBounds(_: usize, _: usize) noreturn {
|
||||||
@branchHint(.cold);
|
@branchHint(.cold);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn startGreaterThanEnd(_: usize, _: usize) noreturn {
|
pub fn startGreaterThanEnd(_: usize, _: usize) noreturn {
|
||||||
@branchHint(.cold);
|
@branchHint(.cold);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn inactiveUnionField(_: anytype, _: anytype) noreturn {
|
pub fn inactiveUnionField(_: anytype, _: anytype) noreturn {
|
||||||
@branchHint(.cold);
|
@branchHint(.cold);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reachedUnreachable() noreturn {
|
pub fn reachedUnreachable() noreturn {
|
||||||
@branchHint(.cold);
|
@branchHint(.cold);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unwrapNull() noreturn {
|
pub fn unwrapNull() noreturn {
|
||||||
@branchHint(.cold);
|
@branchHint(.cold);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn castToNull() noreturn {
|
pub fn castToNull() noreturn {
|
||||||
@branchHint(.cold);
|
@branchHint(.cold);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn incorrectAlignment() noreturn {
|
pub fn incorrectAlignment() noreturn {
|
||||||
@branchHint(.cold);
|
@branchHint(.cold);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn invalidErrorCode() noreturn {
|
pub fn invalidErrorCode() noreturn {
|
||||||
@branchHint(.cold);
|
@branchHint(.cold);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn castTruncatedData() noreturn {
|
pub fn castTruncatedData() noreturn {
|
||||||
@branchHint(.cold);
|
@branchHint(.cold);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn negativeToUnsigned() noreturn {
|
pub fn negativeToUnsigned() noreturn {
|
||||||
@branchHint(.cold);
|
@branchHint(.cold);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn integerOverflow() noreturn {
|
pub fn integerOverflow() noreturn {
|
||||||
@branchHint(.cold);
|
@branchHint(.cold);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn shlOverflow() noreturn {
|
pub fn shlOverflow() noreturn {
|
||||||
@branchHint(.cold);
|
@branchHint(.cold);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn shrOverflow() noreturn {
|
pub fn shrOverflow() noreturn {
|
||||||
@branchHint(.cold);
|
@branchHint(.cold);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn divideByZero() noreturn {
|
pub fn divideByZero() noreturn {
|
||||||
@branchHint(.cold);
|
@branchHint(.cold);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn exactDivisionRemainder() noreturn {
|
pub fn exactDivisionRemainder() noreturn {
|
||||||
@branchHint(.cold);
|
@branchHint(.cold);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn integerPartOutOfBounds() noreturn {
|
pub fn integerPartOutOfBounds() noreturn {
|
||||||
@branchHint(.cold);
|
@branchHint(.cold);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn corruptSwitch() noreturn {
|
pub fn corruptSwitch() noreturn {
|
||||||
@branchHint(.cold);
|
@branchHint(.cold);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn shiftRhsTooBig() noreturn {
|
pub fn shiftRhsTooBig() noreturn {
|
||||||
@branchHint(.cold);
|
@branchHint(.cold);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn invalidEnumValue() noreturn {
|
pub fn invalidEnumValue() noreturn {
|
||||||
@branchHint(.cold);
|
@branchHint(.cold);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn forLenMismatch() noreturn {
|
pub fn forLenMismatch() noreturn {
|
||||||
@branchHint(.cold);
|
@branchHint(.cold);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn memcpyLenMismatch() noreturn {
|
pub fn memcpyLenMismatch() noreturn {
|
||||||
@branchHint(.cold);
|
@branchHint(.cold);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn memcpyAlias() noreturn {
|
pub fn memcpyAlias() noreturn {
|
||||||
@branchHint(.cold);
|
@branchHint(.cold);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn noreturnReturned() noreturn {
|
pub fn noreturnReturned() noreturn {
|
||||||
@branchHint(.cold);
|
@branchHint(.cold);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sliceCastLenRemainder(_: usize) noreturn {
|
pub fn sliceCastLenRemainder(_: usize) noreturn {
|
||||||
@branchHint(.cold);
|
@branchHint(.cold);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub export fn main(argc: c_int, argv: [*:null]const ?[*:0]const u8) callconv(.C) c_int {
|
||||||
|
enable_signal_handlers();
|
||||||
|
const arguments: []const [*:0]const u8 = @ptrCast(argv[0..@intCast(argc)]);
|
||||||
|
@import("root").entry_point(arguments);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
141
src/main.zig
141
src/main.zig
@ -2,18 +2,13 @@ const lib = @import("lib.zig");
|
|||||||
const configuration = @import("configuration");
|
const configuration = @import("configuration");
|
||||||
const os = lib.os;
|
const os = lib.os;
|
||||||
const llvm = @import("LLVM.zig");
|
const llvm = @import("LLVM.zig");
|
||||||
const converter = @import("converter.zig");
|
|
||||||
const Arena = lib.Arena;
|
const Arena = lib.Arena;
|
||||||
|
|
||||||
pub const panic = lib.panic_struct;
|
const converter = @import("converter.zig");
|
||||||
|
const BuildMode = converter.BuildMode;
|
||||||
|
|
||||||
comptime {
|
pub const panic = lib.panic_struct;
|
||||||
if (!lib.is_test) {
|
pub const std_options = lib.std_options;
|
||||||
@export(&main, .{
|
|
||||||
.name = "main",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
test {
|
test {
|
||||||
_ = lib;
|
_ = lib;
|
||||||
@ -21,46 +16,134 @@ test {
|
|||||||
_ = converter;
|
_ = converter;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main(argc: c_int, argv: [*:null]const ?[*:0]const u8) callconv(.C) c_int {
|
fn fail() noreturn {
|
||||||
if (argc != 2) {
|
lib.libc.exit(1);
|
||||||
lib.print_string("Failed to match argument count\n");
|
}
|
||||||
return 1;
|
|
||||||
}
|
pub const main = lib.main;
|
||||||
const relative_file_path_pointer = argv[1] orelse return 1;
|
|
||||||
const relative_file_path = lib.cstring.to_slice(relative_file_path_pointer);
|
const Command = enum {
|
||||||
|
@"test",
|
||||||
|
compile,
|
||||||
|
};
|
||||||
|
|
||||||
|
const Compile = struct {
|
||||||
|
relative_file_path: [:0]const u8,
|
||||||
|
build_mode: BuildMode,
|
||||||
|
has_debug_info: bool,
|
||||||
|
silent: bool,
|
||||||
|
};
|
||||||
|
|
||||||
|
fn compile_file(arena: *Arena, compile: Compile) converter.Options {
|
||||||
|
const checkpoint = arena.position;
|
||||||
|
defer arena.restore(checkpoint);
|
||||||
|
|
||||||
|
const relative_file_path = compile.relative_file_path;
|
||||||
if (relative_file_path.len < 5) {
|
if (relative_file_path.len < 5) {
|
||||||
return 1;
|
fail();
|
||||||
}
|
}
|
||||||
|
|
||||||
const extension_start = lib.string.last_character(relative_file_path, '.') orelse return 1;
|
const extension_start = lib.string.last_character(relative_file_path, '.') orelse fail();
|
||||||
if (!lib.string.equal(relative_file_path[extension_start..], ".bbb")) {
|
if (!lib.string.equal(relative_file_path[extension_start..], ".bbb")) {
|
||||||
return 1;
|
fail();
|
||||||
}
|
}
|
||||||
|
|
||||||
const separator_index = lib.string.last_character(relative_file_path, '/') orelse 0;
|
const separator_index = lib.string.last_character(relative_file_path, '/') orelse 0;
|
||||||
const base_start = separator_index + @intFromBool(separator_index != 0 or relative_file_path[separator_index] == '/');
|
const base_start = separator_index + @intFromBool(separator_index != 0 or relative_file_path[separator_index] == '/');
|
||||||
const base_name = relative_file_path[base_start..extension_start];
|
const base_name = relative_file_path[base_start..extension_start];
|
||||||
|
|
||||||
lib.GlobalState.initialize();
|
const is_compiler = lib.string.equal(relative_file_path, "src/compiler.bbb");
|
||||||
|
const output_path_dir = arena.join_string(&.{
|
||||||
|
base_cache_dir,
|
||||||
|
if (is_compiler) "/compiler/" else "/",
|
||||||
|
@tagName(compile.build_mode),
|
||||||
|
"_",
|
||||||
|
if (compile.has_debug_info) "di" else "nodi",
|
||||||
|
});
|
||||||
|
|
||||||
const arena = lib.global.arena;
|
os.make_directory(base_cache_dir);
|
||||||
|
if (is_compiler) {
|
||||||
|
os.make_directory(base_cache_dir ++ "/compiler");
|
||||||
|
}
|
||||||
|
|
||||||
|
os.make_directory(output_path_dir);
|
||||||
|
|
||||||
|
const output_path_base = arena.join_string(&.{
|
||||||
|
output_path_dir,
|
||||||
|
"/",
|
||||||
|
base_name,
|
||||||
|
});
|
||||||
|
|
||||||
const build_dir = "bb-cache";
|
|
||||||
const output_path_base = arena.join_string(&.{ build_dir, "/", base_name });
|
|
||||||
const output_object_path = arena.join_string(&.{ output_path_base, ".o" });
|
const output_object_path = arena.join_string(&.{ output_path_base, ".o" });
|
||||||
const output_executable_path = output_path_base;
|
const output_executable_path = output_path_base;
|
||||||
|
|
||||||
const c_abi_object_path = arena.duplicate_string(configuration.c_abi_object_path);
|
|
||||||
const file_content = lib.file.read(arena, relative_file_path);
|
const file_content = lib.file.read(arena, relative_file_path);
|
||||||
const file_path = os.absolute_path(arena, relative_file_path);
|
const file_path = os.absolute_path(arena, relative_file_path);
|
||||||
converter.convert(arena, .{
|
const c_abi_object_path = arena.duplicate_string(configuration.c_abi_object_path);
|
||||||
|
|
||||||
|
const convert_options = converter.Options{
|
||||||
.executable = output_executable_path,
|
.executable = output_executable_path,
|
||||||
.objects = if (lib.string.equal(base_name, "c_abi")) &.{ output_object_path, c_abi_object_path } else &.{output_object_path},
|
.objects = if (lib.string.equal(base_name, "c_abi")) &.{ output_object_path, c_abi_object_path } else &.{output_object_path},
|
||||||
.name = base_name,
|
.name = base_name,
|
||||||
.build_mode = .debug_none,
|
.build_mode = compile.build_mode,
|
||||||
.content = file_content,
|
.content = file_content,
|
||||||
.path = file_path,
|
.path = file_path,
|
||||||
.has_debug_info = true,
|
.has_debug_info = compile.has_debug_info,
|
||||||
.target = converter.Target.get_native(),
|
.target = converter.Target.get_native(),
|
||||||
});
|
.silent = compile.silent,
|
||||||
return 0;
|
};
|
||||||
|
|
||||||
|
converter.convert(arena, convert_options);
|
||||||
|
|
||||||
|
return convert_options;
|
||||||
|
}
|
||||||
|
|
||||||
|
const base_cache_dir = "bb-cache";
|
||||||
|
|
||||||
|
pub fn entry_point(arguments: []const [*:0]const u8) void {
|
||||||
|
lib.GlobalState.initialize();
|
||||||
|
const arena = lib.global.arena;
|
||||||
|
|
||||||
|
if (arguments.len < 2) {
|
||||||
|
lib.print_string("error: Not enough arguments\n");
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
|
||||||
|
const command = lib.string.to_enum(Command, lib.cstring.to_slice(arguments[1])) orelse fail();
|
||||||
|
|
||||||
|
switch (command) {
|
||||||
|
.compile => {
|
||||||
|
const relative_file_path = lib.cstring.to_slice(arguments[2]);
|
||||||
|
_ = compile_file(arena, .{
|
||||||
|
.relative_file_path = relative_file_path,
|
||||||
|
.build_mode = .debug_none,
|
||||||
|
.has_debug_info = true,
|
||||||
|
.silent = false,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
.@"test" => {
|
||||||
|
if (arguments.len != 2) {
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline for (@typeInfo(converter.BuildMode).@"enum".fields) |f| {
|
||||||
|
const build_mode = @field(converter.BuildMode, f.name);
|
||||||
|
inline for ([2]bool{ true, false }) |has_debug_info| {
|
||||||
|
const names = [_][]const u8{ "minimal", "constant_add", "minimal_stack" };
|
||||||
|
for (names) |name| {
|
||||||
|
const position = arena.position;
|
||||||
|
defer arena.restore(position);
|
||||||
|
|
||||||
|
const relative_file_path = arena.join_string(&.{ "tests/", name, ".bbb" });
|
||||||
|
_ = compile_file(arena, .{
|
||||||
|
.relative_file_path = relative_file_path,
|
||||||
|
.build_mode = build_mode,
|
||||||
|
.has_debug_info = has_debug_info,
|
||||||
|
.silent = true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
20
src/stack_trace.zig
Normal file
20
src/stack_trace.zig
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
export fn enable_signal_handlers() void {
|
||||||
|
std.debug.attachSegfaultHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
export fn dump_stack_trace(return_address: usize) void {
|
||||||
|
const stderr = std.io.getStdErr().writer();
|
||||||
|
if (@import("builtin").strip_debug_info) {
|
||||||
|
stderr.print("Unable to dump stack trace: debug info stripped\n", .{}) catch return;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const debug_info = std.debug.getSelfDebugInfo() catch |err| {
|
||||||
|
stderr.print("Unable to dump stack trace: Unable to open debug info: {s}\n", .{@errorName(err)}) catch return;
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
std.debug.writeCurrentStackTrace(stderr, debug_info, std.io.tty.detectConfig(std.io.getStdErr()), return_address) catch |err| {
|
||||||
|
stderr.print("Unable to dump stack trace: {s}\n", .{@errorName(err)}) catch return;
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
}
|
@ -17,6 +17,6 @@ slice_receiver = fn (slice: []u8) void
|
|||||||
[export] main = fn [cc(c)] () s32
|
[export] main = fn [cc(c)] () s32
|
||||||
{
|
{
|
||||||
>a: [_]u8 = [0, 1, 2];
|
>a: [_]u8 = [0, 1, 2];
|
||||||
slice_receiver(#slice(a));
|
slice_receiver(&a);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ c_string_length = fn (c_string: &u8) u64
|
|||||||
|
|
||||||
c_string_slice_build = fn (c_string: &u8, length: u64) []u8
|
c_string_slice_build = fn (c_string: &u8, length: u64) []u8
|
||||||
{
|
{
|
||||||
return #slice(c_string, length);
|
return c_string[0..length];
|
||||||
}
|
}
|
||||||
|
|
||||||
[export] main = fn [cc(c)] (argument_count: u32, argument_pointer: &&u8) s32
|
[export] main = fn [cc(c)] (argument_count: u32, argument_pointer: &&u8) s32
|
||||||
|
14
tests/comparison.bbb
Normal file
14
tests/comparison.bbb
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
trivial_comparison = fn (a: u32, b: u32) u1
|
||||||
|
{
|
||||||
|
return a + 1 == b + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
[export] main = fn [cc(c)] (argument_count: u32) s32
|
||||||
|
{
|
||||||
|
>result = trivial_comparison(argument_count, argument_count);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
#trap();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
@ -2,4 +2,3 @@
|
|||||||
{
|
{
|
||||||
return -1 + 1;
|
return -1 + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
34
tests/slice.bbb
Normal file
34
tests/slice.bbb
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
c_string_length = fn (c_string: &u8) u64
|
||||||
|
{
|
||||||
|
>it = c_string;
|
||||||
|
|
||||||
|
while (it.&)
|
||||||
|
{
|
||||||
|
it = it + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return #int_from_pointer(it) - #int_from_pointer(c_string);
|
||||||
|
}
|
||||||
|
|
||||||
|
[export] main = fn (argument_count: u32, argument_pointer: &&u8) s32
|
||||||
|
{
|
||||||
|
if (argument_count == 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
>arg_ptr = argument_pointer[0];
|
||||||
|
>a1 = arg_ptr[0..c_string_length(arg_ptr)];
|
||||||
|
>a2 = a1[1..];
|
||||||
|
|
||||||
|
if (a1.pointer != a2.pointer - 1)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a1.length != a2.length + 1)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user