Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/actions/install/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ inputs:
zig-v8:
description: 'zig v8 version to install'
required: false
default: 'v0.1.25'
default: 'v0.1.27'
v8:
description: 'v8 version to install'
required: false
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ ARG MINISIG=0.12
ARG ZIG=0.14.1
ARG ZIG_MINISIG=RWSGOq2NVecA2UPNdBUZykf1CCb147pkmdtYxgb3Ti+JO/wCYvhbAb/U
ARG V8=13.6.233.8
ARG ZIG_V8=v0.1.25
ARG ZIG_V8=v0.1.27
ARG TARGETPLATFORM

RUN apt-get update -yq && \
Expand Down
4 changes: 2 additions & 2 deletions build.zig.zon
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
.hash = "tigerbeetle_io-0.0.0-ViLgxpyRBAB5BMfIcj3KMXfbJzwARs9uSl8aRy2OXULd",
},
.v8 = .{
.url = "https://github.com/lightpanda-io/zig-v8-fork/archive/23718cdb99aaa45105d0a7e0ca22587bf77d3b5f.tar.gz",
.hash = "v8-0.0.0-xddH68m2AwDf42Qp2Udz4wTMVH8p71si7yLlUoZkPeEz",
.url = "https://github.com/lightpanda-io/zig-v8-fork/archive/46ddf8c0a2861a4e5717e6f8d0d81a17e42fa0c9.tar.gz",
.hash = "v8-0.0.0-xddH6865AwDiDnu-HjMsqm9wXvP9OZOh_4clh_67iQsq",
},
//.v8 = .{ .path = "../zig-v8-fork" },
//.tigerbeetle_io = .{ .path = "../tigerbeetle-io" },
Expand Down
6 changes: 5 additions & 1 deletion src/browser/page.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1001,7 +1001,11 @@ const Script = struct {
try_catch.init(page.main_context);
defer try_catch.deinit();

const src = self.src orelse page.url.raw;
const src: []const u8 = blk: {
const s = self.src orelse break :blk page.url.raw;
break :blk try URL.stitch(page.arena, s, page.url.raw, .{.alloc = .if_needed});
};

// if self.src is null, then this is an inline script, and it should
// not be cached.
const cacheable = self.src != null;
Expand Down
2 changes: 1 addition & 1 deletion src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -580,7 +580,7 @@ fn parseCommonArg(
var it = std.mem.splitScalar(u8, str, ',');
while (it.next()) |part| {
try arr.append(allocator, std.meta.stringToEnum(log.Scope, part) orelse {
log.fatal(.app, "invalid option choice", .{ .arg = "--log_scope_filter", .value = part });
log.fatal(.app, "invalid option choice", .{ .arg = "--log_filter_scopes", .value = part });
return false;
});
}
Expand Down
34 changes: 30 additions & 4 deletions src/runtime/js.zig
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,16 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
isolate.enter();
errdefer isolate.exit();

isolate.setHostInitializeImportMetaObjectCallback(struct {
fn callback(c_context: ?*v8.C_Context, c_module: ?*v8.C_Module, c_meta: ?*v8.C_Value) callconv(.C) void {
const v8_context = v8.Context{.handle = c_context.?};
const js_context: *JsContext = @ptrFromInt(v8_context.getEmbedderData(1).castTo(v8.BigInt).getUint64());
js_context.initializeImportMeta(v8.Module{.handle = c_module.?}, v8.Object{.handle = c_meta.?}) catch |err| {
log.err(.js, "import meta", .{ .err = err });
};
}
}.callback);

var temp_scope: v8.HandleScope = undefined;
v8.HandleScope.init(&temp_scope, isolate);
defer temp_scope.deinit();
Expand Down Expand Up @@ -726,13 +736,15 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {

fn moduleNoCache(self: *JsContext, src: []const u8, url: []const u8) !void {
const m = try compileModule(self.isolate, src, url);

const arena = self.context_arena;
const owned_url = try arena.dupe(u8, url);
try self.module_identifier.putNoClobber(arena, m.getIdentityHash(), owned_url);

const v8_context = self.v8_context;
if (try m.instantiate(v8_context, resolveModuleCallback) == false) {
return error.ModuleInstantiationError;
}
const arena = self.context_arena;
const owned_url = try arena.dupe(u8, url);
try self.module_identifier.putNoClobber(arena, m.getIdentityHash(), owned_url);
_ = try m.evaluate(v8_context);
}

Expand Down Expand Up @@ -1279,6 +1291,20 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
return self.createException(js_value);
}

fn initializeImportMeta(self: *JsContext, m: v8.Module, meta: v8.Object) !void {
const url = self.module_identifier.get(m.getIdentityHash()) orelse {
// Shouldn't be possible.
return error.UnknownModuleReferrer;
};

const js_key = v8.String.initUtf8(self.isolate, "url");
const js_value = try self.zigValueToJs(url);
const res = meta.defineOwnProperty(self.v8_context, js_key.toName(), js_value, 0) orelse false;
if (!res) {
return error.FailedToSet;
}
}

// Callback from V8, asking us to load a module. The "specifier" is
// the src of the module to load.
fn resolveModuleCallback(
Expand Down Expand Up @@ -1335,7 +1361,7 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
try_catch.init(self);
defer try_catch.deinit();

const m = compileModule(self.isolate, source, specifier) catch |err| {
const m = compileModule(self.isolate, source, normalized_specifier) catch |err| {
log.warn(.js, "compile resolved module", .{
.specifier = specifier,
.stack = try_catch.stack(self.call_arena) catch null,
Expand Down
19 changes: 18 additions & 1 deletion src/url.zig
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ pub const URL = struct {
return src;
}

var normalized_src = if (std.mem.startsWith(u8, src, "/")) src[1..] else src;
var normalized_src = src;
while (std.mem.startsWith(u8, normalized_src, "./")) {
normalized_src = normalized_src[2..];
}
Expand All @@ -131,6 +131,13 @@ pub const URL = struct {
}
};

if (normalized_src[0] == '/') {
if (std.mem.indexOfScalarPos(u8, base, protocol_end, '/')) |pos| {
return std.fmt.allocPrint(allocator, "{s}{s}", .{ base[0..pos], normalized_src });
}
// not sure what to do here...error? Just let it fallthrough for now.
}

if (std.mem.lastIndexOfScalar(u8, base[protocol_end..], '/')) |index| {
const last_slash_pos = index + protocol_end;
if (last_slash_pos == base.len - 1) {
Expand Down Expand Up @@ -257,6 +264,16 @@ test "URL: Stitching Base & Src URLs (No Ending Slash)" {
try testing.expectString("https://lightpanda.io/something.js", result);
}

test "URL: Stitching Base with absolute src" {
const allocator = testing.allocator;

const base = "https://lightpanda.io/hello";
const src = "/abc/something.js";
const result = try URL.stitch(allocator, src, base, .{});
defer allocator.free(result);
try testing.expectString("https://lightpanda.io/abc/something.js", result);
}

test "URL: Stiching Base & Src URLs (Both Local)" {
const allocator = testing.allocator;

Expand Down