Skip to content

Commit

Permalink
Merge pull request #216 from lightpanda-io/upgrade-zig
Browse files Browse the repository at this point in the history
Upgrade zig 0.12.1
  • Loading branch information
krichprollsch authored Jun 18, 2024
2 parents 27db56c + 9faf988 commit d491f04
Show file tree
Hide file tree
Showing 17 changed files with 244 additions and 152 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jobs:

runs-on: ubuntu-latest
container:
image: ghcr.io/lightpanda-io/zig-v8:0.12.0-dev.1773-8a8fd47d2
image: ghcr.io/lightpanda-io/zig-v8:0.12.1
credentials:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/zig-fmt.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:

runs-on: ubuntu-latest
container:
image: ghcr.io/lightpanda-io/zig:0.12.0-dev.1773-8a8fd47d2
image: ghcr.io/lightpanda-io/zig:0.12.1
credentials:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/zig-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jobs:

runs-on: ubuntu-latest
container:
image: ghcr.io/lightpanda-io/zig-v8:0.12.0-dev.1773-8a8fd47d2
image: ghcr.io/lightpanda-io/zig-v8:0.12.1
credentials:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
Expand Down Expand Up @@ -71,7 +71,7 @@ jobs:

runs-on: ubuntu-latest
container:
image: ghcr.io/lightpanda-io/zig-v8:0.12.0-dev.1773-8a8fd47d2
image: ghcr.io/lightpanda-io/zig-v8:0.12.1
credentials:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
Expand Down Expand Up @@ -102,7 +102,7 @@ jobs:

runs-on: ubuntu-latest
container:
image: ghcr.io/lightpanda-io/zig-v8:0.12.0-dev.1773-8a8fd47d2
image: ghcr.io/lightpanda-io/zig-v8:0.12.1
credentials:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,14 +146,14 @@ $ make shell
zig-js-runtime - Javascript Shell
exit with Ctrl+D or "exit"

>
>
```

## Build

### Prerequisites

zig-js-runtime is written with [Zig](https://ziglang.org/) `0.12`. You have to
zig-js-runtime is written with [Zig](https://ziglang.org/) `0.12.1`. You have to
install it with the right version in order to build the project.

To be able to build the v8 engine, you have to install some libs:
Expand Down
102 changes: 54 additions & 48 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const pkgs = packages("");

/// Do not rename this constant. It is scanned by some scripts to determine
/// which zig version to install.
pub const recommended_zig_version = "0.12.0-dev.1773+8a8fd47d2";
pub const recommended_zig_version = "0.12.1";

pub fn build(b: *std.Build) !void {
switch (comptime builtin.zig_version.order(std.SemanticVersion.parse(recommended_zig_version) catch unreachable)) {
Expand Down Expand Up @@ -48,17 +48,17 @@ pub fn build(b: *std.Build) !void {
// compile and install
const bench = b.addExecutable(.{
.name = "zig-js-runtime-bench",
.root_source_file = .{ .path = "src/main_bench.zig" },
.root_source_file = b.path("src/main_bench.zig"),
.single_threaded = true,
.target = target,
.optimize = mode,
});

try common(bench, mode, options);
try common(b, &bench.root_module, options);
if (mode == .ReleaseSafe) {
// remove debug info
// TODO: check if mandatory in release-safe
bench.strip = true;
bench.root_module.strip = true;
}
b.installArtifact(bench);

Expand All @@ -78,16 +78,16 @@ pub fn build(b: *std.Build) !void {
// compile and install
const shell = b.addExecutable(.{
.name = "zig-js-runtime-shell",
.root_source_file = .{ .path = "src/main_shell.zig" },
.root_source_file = b.path("src/main_shell.zig"),
.target = target,
.optimize = mode,
});
try common(shell, mode, options);
try common(b, &shell.root_module, options);
try pkgs.add_shell(shell);
if (mode == .ReleaseSafe) {
// remove debug info
// TODO: check if mandatory in release-safe
shell.strip = true;
shell.root_module.strip = true;
}
// do not install shell binary
// b.installArtifact(shell);
Expand All @@ -107,13 +107,13 @@ pub fn build(b: *std.Build) !void {

// compile
const tests = b.addTest(.{
.root_source_file = .{ .path = "src/run_tests.zig" },
.root_source_file = b.path("src/run_tests.zig"),
.target = target,
.optimize = mode,
});
try common(tests, mode, options);
tests.single_threaded = true;
tests.test_runner = "src/test_runner.zig";
try common(b, &tests.root_module, options);
tests.root_module.single_threaded = true;
tests.test_runner = b.path("src/test_runner.zig");
const run_tests = b.addRunArtifact(tests);

// step
Expand Down Expand Up @@ -149,15 +149,15 @@ pub fn buildOptions(b: *std.Build) !Options {
}

fn common(
step: *std.Build.Step.Compile,
mode: std.builtin.Mode,
b: *std.Build,
m: *std.Build.Module,
options: Options,
) !void {
step.addOptions("jsruntime_build_options", options.opts);
step.addModule("tigerbeetle-io", pkgs.tigerbeetle_io(step));
m.addOptions("jsruntime_build_options", options.opts);
m.addImport("tigerbeetle-io", pkgs.tigerbeetle_io(b));
if (options.engine == .v8) {
try pkgs.v8(step, mode);
step.addModule("v8", pkgs.zig_v8(step));
try pkgs.v8(m);
m.addImport("v8", pkgs.zig_v8(b));
}
}

Expand All @@ -167,33 +167,35 @@ pub fn packages(comptime vendor_path: []const u8) type {

const vendor = vendor_path ++ "vendor";

fn tigerbeetle_io(step: *std.Build.Step.Compile) *std.Build.Module {
return step.step.owner.createModule(.{
.source_file = .{ .path = vendor ++ "/tigerbeetle-io/io.zig" },
fn tigerbeetle_io(b: *std.Build) *std.Build.Module {
return b.createModule(.{
.root_source_file = b.path(vendor ++ "/tigerbeetle-io/io.zig"),
});
}

fn zig_v8(step: *std.Build.Step.Compile) *std.Build.Module {
step.addIncludePath(.{ .path = vendor ++ "/zig-v8/src" });

return step.step.owner.createModule(.{
.source_file = .{ .path = vendor ++ "/zig-v8/src/v8.zig" },
fn zig_v8(b: *std.Build) *std.Build.Module {
const mod = b.createModule(.{
.root_source_file = b.path(vendor ++ "/zig-v8/src/v8.zig"),
.link_libc = false,
.link_libcpp = false,
});
}

fn v8(step: *std.Build.Step.Compile, mode: std.builtin.Mode) !void {
const mode_str: []const u8 = if (mode == .Debug) "debug" else "release";
// step.linkLibC(); // TODO: do we need to link libc?
mod.addIncludePath(b.path(vendor ++ "/zig-v8/src"));

return mod;
}

fn v8(mod: *std.Build.Module) !void {
const mode_str: []const u8 = if (mod.optimize.? == .Debug) "debug" else "release";
// FIXME: we are tied to native v8 builds, currently:
// - aarch64-macos
// - x86_64-linux
const os = step.target.getOsTag();
const arch = step.target.getCpuArch();
const os = mod.resolved_target.?.result.os.tag;
const arch = mod.resolved_target.?.result.cpu.arch;
switch (os) {
.linux => blk: {
// TODO: why do we need it? It should be linked already when we built v8
step.linkLibCpp();
mod.link_libcpp = true;
break :blk;
},
.macos => blk: {
Expand All @@ -207,45 +209,49 @@ pub fn packages(comptime vendor_path: []const u8) type {
}

const lib_path = try std.fmt.allocPrint(
step.step.owner.allocator,
mod.owner.allocator,
"{s}vendor/v8/{s}-{s}/{s}/libc_v8.a",
.{ vendor_path, @tagName(arch), @tagName(os), mode_str },
);
step.addObjectFile(.{ .path = lib_path });
mod.addObjectFile(mod.owner.path(lib_path));
}

pub fn add_shell(step: *std.Build.Step.Compile) !void {
step.addIncludePath(.{ .path = vendor ++ "/linenoise-mob" });
step.addIncludePath(step.root_module.owner.path(vendor ++ "/linenoise-mob"));
const lib = step.step.owner.addStaticLibrary(.{
.name = "linenoise",
.target = step.target,
.optimize = step.optimize,
.target = step.root_module.resolved_target.?,
.optimize = step.root_module.optimize.?,
.link_libc = true,
});
// TODO: use mode to add debug/release flags
const cflags = &.{};
lib.addCSourceFile(.{
.file = .{ .path = vendor ++ "/linenoise-mob/linenoise.c" },
.file = step.root_module.owner.path(vendor ++ "/linenoise-mob/linenoise.c"),
.flags = cflags,
});
step.linkLibrary(lib);
}

pub fn add(
step: *std.build.Step.Compile,
pub fn module(
b: *std.Build,
options: Options,
) !void {
const jsruntime_mod = step.step.owner.createModule(.{
.source_file = .{ .path = vendor_path ++ "/src/api.zig" },
.dependencies = &[_]std.build.ModuleDependency{
mode: std.builtin.Mode,
target: std.Build.ResolvedTarget,
) !*std.Build.Module {
const mod = b.createModule(.{
.root_source_file = b.path(vendor_path ++ "/src/api.zig"),
.optimize = mode,
.target = target,
.imports = &[_]std.Build.Module.Import{
.{ .name = "jsruntime_build_options", .module = options.opts.createModule() },
.{ .name = "tigerbeetle-io", .module = Self.tigerbeetle_io(step) },
.{ .name = "v8", .module = Self.zig_v8(step) },
.{ .name = "tigerbeetle-io", .module = Self.tigerbeetle_io(b) },
.{ .name = "v8", .module = Self.zig_v8(b) },
},
});
try Self.v8(step, step.optimize);
try Self.v8(mod);

step.addModule("jsruntime", jsruntime_mod);
return mod;
}
};
}
13 changes: 7 additions & 6 deletions src/engines/v8/generate.zig
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ fn getNativeArg(

// JS object
const ptr = try getNativeObject(nat_ctx, T_refl, js_value.castTo(v8.Object));
if (arg_T.underPtr() != null) {
if (comptime arg_T.underPtr() != null) {
value = ptr;
} else {
value = ptr.*;
Expand Down Expand Up @@ -389,13 +389,14 @@ fn getArgs(

fn freeArgs(alloc: std.mem.Allocator, comptime func: refl.Func, obj: anytype) !void {
inline for (func.args) |arg_T| {
const underT = comptime arg_T.underT();

// free char slices
// the API functions will be responsible of copying the slice
// in their implementations if they want to keep it afterwards
if (arg_T.underT() == []u8 or arg_T.underT() == []const u8) {
if (underT == []u8 or underT == []const u8) {
const val = @field(obj, arg_T.name.?);
if (arg_T.underOpt() != null) {
if (comptime arg_T.underOpt() != null) {
// free only if val is non-null
if (val) |v| {
alloc.free(v);
Expand All @@ -406,7 +407,7 @@ fn freeArgs(alloc: std.mem.Allocator, comptime func: refl.Func, obj: anytype) !v
}

// free varidadic slices
if (try refl.Type.variadic(arg_T.underT(), null) != null) {
if (try refl.Type.variadic(underT, null) != null) {
const val = @field(obj, arg_T.name.?).?;
// NOTE: variadic are optional by design
alloc.free(@field(val, "slice"));
Expand Down Expand Up @@ -913,7 +914,7 @@ fn callFunc(

// call native func
const function = @field(T_refl.T, func.name);
const res_T = func.return_type.underErr() orelse func.return_type.T;
const res_T = comptime func.return_type.underErr() orelse func.return_type.T;
var res: res_T = undefined;
if (comptime @typeInfo(func.return_type.T) == .ErrorUnion) {
res = @call(.auto, function, args) catch |err| {
Expand All @@ -940,7 +941,7 @@ fn callFunc(
nat_ctx.alloc,
nat_ctx,
T_refl,
func.return_type.underT(),
comptime func.return_type.underT(),
res,
cbk_info.getThis(),
isolate,
Expand Down
17 changes: 11 additions & 6 deletions src/generate.zig
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,16 @@ const loadFn = @import("private_api.zig").loadFn;
// reflect the user-defined types to obtain type information (T_refl)
// This function must be called at comptime by the root file of the project
// and stored in a constant named `Types`
pub fn reflect(comptime types: anytype) []refl.Struct {
pub fn reflect(comptime types: anytype) []const refl.Struct {
std.debug.assert(@inComptime());

// call types reflection
return refl.do(types) catch unreachable;
const structs: []const refl.Struct = refl.do(types) catch |e| @compileError(@errorName(e));
return structs;
}

// Import user-defined types
pub const Types: []refl.Struct = @import("root").Types;
pub const Types: []const refl.Struct = @import("root").Types;

// retrieved the reflected type of a user-defined native type
pub fn getType(comptime T: type) refl.Struct {
Expand All @@ -61,7 +62,7 @@ pub fn getType(comptime T: type) refl.Struct {

// generate APIs from reflected types
// which can be later loaded in JS.
fn generate(comptime types: []refl.Struct) []API {
fn generate(comptime types: []const refl.Struct) []API {
std.debug.assert(@inComptime());

var apis: [types.len]API = undefined;
Expand Down Expand Up @@ -146,7 +147,11 @@ fn MergeTupleT(comptime value: anytype) type {
var i = 0;
while (i < fields_nb) {
fields[i] = .{
.name = itoa(i),
// StructField.name expect a null terminated string.
// concatenate the `[]const u8` string with an empty string
// literal (`name ++ ""`) to explicitly coerce it to `[:0]const
// u8`.
.name = itoa(i) ++ "",
.type = type,
.default_value = null,
.is_comptime = false,
Expand All @@ -156,7 +161,7 @@ fn MergeTupleT(comptime value: anytype) type {
}
const decls: [0]std.builtin.Type.Declaration = undefined;
const info = std.builtin.Type.Struct{
.layout = .Auto,
.layout = .auto,
.fields = &fields,
.decls = &decls,
.is_tuple = true,
Expand Down
Loading

0 comments on commit d491f04

Please sign in to comment.