mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-10-29 07:03:29 +00:00
Merge pull request #253 from lightpanda-io/refacto_exec
Adapt to js_exec changes in zig-js-runtime
This commit is contained in:
@@ -198,21 +198,21 @@ pub const Page = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn wait(self: *Page) !void {
|
pub fn wait(self: *Page) !void {
|
||||||
const alloc = self.arena.allocator();
|
|
||||||
var res = try self.session.env.waitTryCatch(alloc);
|
|
||||||
defer res.deinit(alloc);
|
|
||||||
|
|
||||||
if (res.success) {
|
// try catch
|
||||||
log.debug("wait: {s}", .{res.result});
|
var try_catch: jsruntime.TryCatch = undefined;
|
||||||
} else {
|
try_catch.init(self.session.env);
|
||||||
if (builtin.mode == .Debug and res.stack != null) {
|
defer try_catch.deinit();
|
||||||
log.info("wait: {s}", .{res.stack.?});
|
|
||||||
} else {
|
self.session.env.wait() catch {
|
||||||
log.info("wait: {s}", .{res.result});
|
const alloc = self.arena.allocator();
|
||||||
|
if (try try_catch.err(alloc, self.session.env)) |msg| {
|
||||||
|
defer alloc.free(msg);
|
||||||
|
log.info("wait error: {s}", .{msg});
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
log.debug("wait: OK", .{});
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// spec reference: https://html.spec.whatwg.org/#document-lifecycle
|
// spec reference: https://html.spec.whatwg.org/#document-lifecycle
|
||||||
@@ -322,7 +322,7 @@ pub const Page = struct {
|
|||||||
// start JS env
|
// start JS env
|
||||||
// TODO load the js env concurrently with the HTML parsing.
|
// TODO load the js env concurrently with the HTML parsing.
|
||||||
log.debug("start js env", .{});
|
log.debug("start js env", .{});
|
||||||
try self.session.env.start(alloc);
|
try self.session.env.start();
|
||||||
|
|
||||||
// replace the user context document with the new one.
|
// replace the user context document with the new one.
|
||||||
try self.session.env.setUserContext(.{
|
try self.session.env.setUserContext(.{
|
||||||
@@ -473,22 +473,26 @@ pub const Page = struct {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var try_catch: jsruntime.TryCatch = undefined;
|
||||||
|
try_catch.init(self.session.env);
|
||||||
|
defer try_catch.deinit();
|
||||||
|
|
||||||
const opt_text = try parser.nodeTextContent(parser.elementToNode(e));
|
const opt_text = try parser.nodeTextContent(parser.elementToNode(e));
|
||||||
if (opt_text) |text| {
|
if (opt_text) |text| {
|
||||||
// TODO handle charset attribute
|
// TODO handle charset attribute
|
||||||
var res = try self.session.env.execTryCatch(alloc, text, "");
|
const res = self.session.env.exec(text, "") catch {
|
||||||
defer res.deinit(alloc);
|
if (try try_catch.err(alloc, self.session.env)) |msg| {
|
||||||
|
defer alloc.free(msg);
|
||||||
if (res.success) {
|
log.info("eval inline {s}: {s}", .{ text, msg });
|
||||||
log.debug("eval inline: {s}", .{res.result});
|
|
||||||
} else {
|
|
||||||
if (builtin.mode == .Debug and res.stack != null) {
|
|
||||||
log.info("eval inline: {s}", .{res.stack.?});
|
|
||||||
} else {
|
|
||||||
log.info("eval inline: {s}", .{res.result});
|
|
||||||
}
|
}
|
||||||
}
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (builtin.mode == .Debug) {
|
||||||
|
const msg = try res.toString(alloc, self.session.env);
|
||||||
|
defer alloc.free(msg);
|
||||||
|
log.debug("eval inline {s}", .{msg});
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -530,18 +534,22 @@ pub const Page = struct {
|
|||||||
// check no body
|
// check no body
|
||||||
if (body.len == 0) return FetchError.NoBody;
|
if (body.len == 0) return FetchError.NoBody;
|
||||||
|
|
||||||
var res = try self.session.env.execTryCatch(alloc, body, src);
|
var try_catch: jsruntime.TryCatch = undefined;
|
||||||
defer res.deinit(alloc);
|
try_catch.init(self.session.env);
|
||||||
|
defer try_catch.deinit();
|
||||||
|
|
||||||
if (res.success) {
|
const res = self.session.env.exec(body, src) catch {
|
||||||
log.debug("eval remote {s}: {s}", .{ src, res.result });
|
if (try try_catch.err(alloc, self.session.env)) |msg| {
|
||||||
} else {
|
defer alloc.free(msg);
|
||||||
if (builtin.mode == .Debug and res.stack != null) {
|
log.info("eval remote {s}: {s}", .{ src, msg });
|
||||||
log.info("eval remote {s}: {s}", .{ src, res.stack.? });
|
|
||||||
} else {
|
|
||||||
log.info("eval remote {s}: {s}", .{ src, res.result });
|
|
||||||
}
|
}
|
||||||
return FetchError.JsErr;
|
return FetchError.JsErr;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (builtin.mode == .Debug) {
|
||||||
|
const msg = try res.toString(alloc, self.session.env);
|
||||||
|
defer alloc.free(msg);
|
||||||
|
log.debug("eval remote {s}: {s}", .{ src, msg });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
18
src/main.zig
18
src/main.zig
@@ -37,7 +37,7 @@ fn execJS(
|
|||||||
js_env: *jsruntime.Env,
|
js_env: *jsruntime.Env,
|
||||||
) anyerror!void {
|
) anyerror!void {
|
||||||
// start JS env
|
// start JS env
|
||||||
try js_env.start(alloc);
|
try js_env.start();
|
||||||
defer js_env.stop();
|
defer js_env.stop();
|
||||||
|
|
||||||
// alias global as self and window
|
// alias global as self and window
|
||||||
@@ -45,6 +45,11 @@ fn execJS(
|
|||||||
window.replaceDocument(doc);
|
window.replaceDocument(doc);
|
||||||
try js_env.bindGlobal(window);
|
try js_env.bindGlobal(window);
|
||||||
|
|
||||||
|
// try catch
|
||||||
|
var try_catch: jsruntime.TryCatch = undefined;
|
||||||
|
try_catch.init(js_env.*);
|
||||||
|
defer try_catch.deinit();
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
|
||||||
// read cmd
|
// read cmd
|
||||||
@@ -57,11 +62,12 @@ fn execJS(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const res = try js_env.execTryCatch(alloc, cmd, "cdp");
|
const res = try js_env.exec(cmd, "cdp");
|
||||||
if (res.success) {
|
const res_str = try res.toString(alloc, js_env.*);
|
||||||
std.debug.print("-> {s}\n", .{res.result});
|
defer alloc.free(res_str);
|
||||||
}
|
std.debug.print("-> {s}\n", .{res_str});
|
||||||
_ = try conn.stream.write(res.result);
|
|
||||||
|
_ = try conn.stream.write(res_str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ fn execJS(
|
|||||||
js_env: *jsruntime.Env,
|
js_env: *jsruntime.Env,
|
||||||
) anyerror!void {
|
) anyerror!void {
|
||||||
// start JS env
|
// start JS env
|
||||||
try js_env.start(alloc);
|
try js_env.start();
|
||||||
defer js_env.stop();
|
defer js_env.stop();
|
||||||
|
|
||||||
var cli = Client{ .allocator = alloc, .loop = js_env.nat_ctx.loop };
|
var cli = Client{ .allocator = alloc, .loop = js_env.nat_ctx.loop };
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ pub fn main() !void {
|
|||||||
defer arena.deinit();
|
defer arena.deinit();
|
||||||
|
|
||||||
const res = wpt.run(&arena, wpt_dir, tc, &loader) catch |err| {
|
const res = wpt.run(&arena, wpt_dir, tc, &loader) catch |err| {
|
||||||
const suite = try Suite.init(alloc, tc, false, @errorName(err), null);
|
const suite = try Suite.init(alloc, tc, false, @errorName(err));
|
||||||
try results.append(suite);
|
try results.append(suite);
|
||||||
|
|
||||||
if (out == .text) {
|
if (out == .text) {
|
||||||
@@ -151,9 +151,9 @@ pub fn main() !void {
|
|||||||
failures += 1;
|
failures += 1;
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
// no need to call res.deinit() thanks to the arena allocator.
|
defer res.deinit(arena.allocator());
|
||||||
|
|
||||||
const suite = try Suite.init(alloc, tc, res.success, res.result, res.stack);
|
const suite = try Suite.init(alloc, tc, res.ok, res.msg orelse "");
|
||||||
try results.append(suite);
|
try results.append(suite);
|
||||||
|
|
||||||
if (out == .json) {
|
if (out == .json) {
|
||||||
@@ -196,7 +196,7 @@ pub fn main() !void {
|
|||||||
try cases.append(Case{
|
try cases.append(Case{
|
||||||
.pass = suite.pass,
|
.pass = suite.pass,
|
||||||
.name = suite.name,
|
.name = suite.name,
|
||||||
.message = suite.stack orelse suite.message,
|
.message = suite.message,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ fn testExecFn(
|
|||||||
defer parser.deinit();
|
defer parser.deinit();
|
||||||
|
|
||||||
// start JS env
|
// start JS env
|
||||||
try js_env.start(alloc);
|
try js_env.start();
|
||||||
defer js_env.stop();
|
defer js_env.stop();
|
||||||
|
|
||||||
var storageShelf = storage.Shelf.init(alloc);
|
var storageShelf = storage.Shelf.init(alloc);
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ const Client = @import("../async/Client.zig");
|
|||||||
// runWPT parses the given HTML file, starts a js env and run the first script
|
// runWPT parses the given HTML file, starts a js env and run the first script
|
||||||
// tags containing javascript sources.
|
// tags containing javascript sources.
|
||||||
// It loads first the js libs files.
|
// It loads first the js libs files.
|
||||||
pub fn run(arena: *std.heap.ArenaAllocator, comptime dir: []const u8, f: []const u8, loader: *FileLoader) !jsruntime.JSResult {
|
pub fn run(arena: *std.heap.ArenaAllocator, comptime dir: []const u8, f: []const u8, loader: *FileLoader) !Res {
|
||||||
const alloc = arena.allocator();
|
const alloc = arena.allocator();
|
||||||
try parser.init();
|
try parser.init();
|
||||||
defer parser.deinit();
|
defer parser.deinit();
|
||||||
@@ -70,15 +70,16 @@ pub fn run(arena: *std.heap.ArenaAllocator, comptime dir: []const u8, f: []const
|
|||||||
try js_env.load(&js_types);
|
try js_env.load(&js_types);
|
||||||
|
|
||||||
// start JS env
|
// start JS env
|
||||||
try js_env.start(alloc);
|
try js_env.start();
|
||||||
defer js_env.stop();
|
defer js_env.stop();
|
||||||
|
|
||||||
// display console logs
|
// display console logs
|
||||||
defer {
|
defer {
|
||||||
var res = evalJS(js_env, alloc, "console.join('\\n');", "console") catch unreachable;
|
const res = evalJS(js_env, alloc, "console.join('\\n');", "console") catch unreachable;
|
||||||
defer res.deinit(alloc);
|
defer res.deinit(alloc);
|
||||||
if (res.result.len > 0) {
|
|
||||||
std.debug.print("-- CONSOLE LOG\n{s}\n--\n", .{res.result});
|
if (res.msg != null and res.msg.?.len > 0) {
|
||||||
|
std.debug.print("-- CONSOLE LOG\n{s}\n--\n", .{res.msg.?});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,9 +89,6 @@ pub fn run(arena: *std.heap.ArenaAllocator, comptime dir: []const u8, f: []const
|
|||||||
window.setStorageShelf(&storageShelf);
|
window.setStorageShelf(&storageShelf);
|
||||||
try js_env.bindGlobal(&window);
|
try js_env.bindGlobal(&window);
|
||||||
|
|
||||||
// thanks to the arena, we don't need to deinit res.
|
|
||||||
var res: jsruntime.JSResult = undefined;
|
|
||||||
|
|
||||||
const init =
|
const init =
|
||||||
\\console = [];
|
\\console = [];
|
||||||
\\console.log = function () {
|
\\console.log = function () {
|
||||||
@@ -100,10 +98,8 @@ pub fn run(arena: *std.heap.ArenaAllocator, comptime dir: []const u8, f: []const
|
|||||||
\\ console.push("debug", ...arguments);
|
\\ console.push("debug", ...arguments);
|
||||||
\\};
|
\\};
|
||||||
;
|
;
|
||||||
res = try evalJS(js_env, alloc, init, "init");
|
var res = try evalJS(js_env, alloc, init, "init");
|
||||||
if (!res.success) {
|
if (!res.ok) return res;
|
||||||
return res;
|
|
||||||
}
|
|
||||||
res.deinit(alloc);
|
res.deinit(alloc);
|
||||||
|
|
||||||
// loop hover the scripts.
|
// loop hover the scripts.
|
||||||
@@ -122,20 +118,14 @@ pub fn run(arena: *std.heap.ArenaAllocator, comptime dir: []const u8, f: []const
|
|||||||
}
|
}
|
||||||
|
|
||||||
res = try evalJS(js_env, alloc, try loader.get(path), src);
|
res = try evalJS(js_env, alloc, try loader.get(path), src);
|
||||||
if (!res.success) {
|
if (!res.ok) return res;
|
||||||
return res;
|
|
||||||
}
|
|
||||||
res.deinit(alloc);
|
res.deinit(alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the script as a source text, execute it.
|
// If the script as a source text, execute it.
|
||||||
const src = try parser.nodeTextContent(s) orelse continue;
|
const src = try parser.nodeTextContent(s) orelse continue;
|
||||||
res = try evalJS(js_env, alloc, src, "");
|
res = try evalJS(js_env, alloc, src, "");
|
||||||
|
if (!res.ok) return res;
|
||||||
// return the first failure.
|
|
||||||
if (!res.success) {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
res.deinit(alloc);
|
res.deinit(alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,25 +140,52 @@ pub fn run(arena: *std.heap.ArenaAllocator, comptime dir: []const u8, f: []const
|
|||||||
);
|
);
|
||||||
|
|
||||||
// wait for all async executions
|
// wait for all async executions
|
||||||
res = try js_env.waitTryCatch(alloc);
|
var try_catch: jsruntime.TryCatch = undefined;
|
||||||
if (!res.success) {
|
try_catch.init(js_env);
|
||||||
return res;
|
defer try_catch.deinit();
|
||||||
}
|
js_env.wait() catch {
|
||||||
res.deinit(alloc);
|
return .{
|
||||||
|
.ok = false,
|
||||||
|
.msg = try try_catch.err(alloc, js_env),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
// Check the final test status.
|
// Check the final test status.
|
||||||
res = try evalJS(js_env, alloc, "report.status;", "teststatus");
|
res = try evalJS(js_env, alloc, "report.status;", "teststatus");
|
||||||
if (!res.success) {
|
if (!res.ok) return res;
|
||||||
return res;
|
|
||||||
}
|
|
||||||
res.deinit(alloc);
|
res.deinit(alloc);
|
||||||
|
|
||||||
// return the detailed result.
|
// return the detailed result.
|
||||||
return try evalJS(js_env, alloc, "report.log", "teststatus");
|
return try evalJS(js_env, alloc, "report.log", "teststatus");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn evalJS(env: jsruntime.Env, alloc: std.mem.Allocator, script: []const u8, name: ?[]const u8) !jsruntime.JSResult {
|
pub const Res = struct {
|
||||||
return try env.execTryCatch(alloc, script, name);
|
ok: bool,
|
||||||
|
msg: ?[]const u8,
|
||||||
|
|
||||||
|
pub fn deinit(res: Res, alloc: std.mem.Allocator) void {
|
||||||
|
if (res.msg) |msg| {
|
||||||
|
alloc.free(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fn evalJS(env: jsruntime.Env, alloc: std.mem.Allocator, script: []const u8, name: ?[]const u8) !Res {
|
||||||
|
var try_catch: jsruntime.TryCatch = undefined;
|
||||||
|
try_catch.init(env);
|
||||||
|
defer try_catch.deinit();
|
||||||
|
|
||||||
|
const v = env.exec(script, name) catch {
|
||||||
|
return .{
|
||||||
|
.ok = false,
|
||||||
|
.msg = try try_catch.err(alloc, env),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
return .{
|
||||||
|
.ok = true,
|
||||||
|
.msg = try v.toString(alloc, env),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// browse the path to find the tests list.
|
// browse the path to find the tests list.
|
||||||
|
|||||||
@@ -67,28 +67,22 @@ pub const Suite = struct {
|
|||||||
pass: bool,
|
pass: bool,
|
||||||
name: []const u8,
|
name: []const u8,
|
||||||
message: ?[]const u8,
|
message: ?[]const u8,
|
||||||
stack: ?[]const u8,
|
|
||||||
cases: ?[]Case,
|
cases: ?[]Case,
|
||||||
|
|
||||||
// caller owns the wpt.Suite.
|
// caller owns the wpt.Suite.
|
||||||
// owner must call deinit().
|
// owner must call deinit().
|
||||||
pub fn init(alloc: std.mem.Allocator, name: []const u8, pass: bool, res: []const u8, stack: ?[]const u8) !Suite {
|
pub fn init(alloc: std.mem.Allocator, name: []const u8, pass: bool, res: []const u8) !Suite {
|
||||||
var suite = Suite{
|
var suite = Suite{
|
||||||
.alloc = alloc,
|
.alloc = alloc,
|
||||||
.pass = false,
|
.pass = false,
|
||||||
.name = try alloc.dupe(u8, name),
|
.name = try alloc.dupe(u8, name),
|
||||||
.message = null,
|
.message = null,
|
||||||
.stack = null,
|
|
||||||
.cases = null,
|
.cases = null,
|
||||||
};
|
};
|
||||||
|
|
||||||
// handle JS error.
|
// handle JS error.
|
||||||
if (!pass) {
|
if (!pass) {
|
||||||
suite.message = try alloc.dupe(u8, res);
|
suite.message = try alloc.dupe(u8, res);
|
||||||
if (stack) |st| {
|
|
||||||
suite.stack = try alloc.dupe(u8, st);
|
|
||||||
}
|
|
||||||
|
|
||||||
return suite;
|
return suite;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,10 +149,6 @@ pub const Suite = struct {
|
|||||||
pub fn deinit(self: Suite) void {
|
pub fn deinit(self: Suite) void {
|
||||||
self.alloc.free(self.name);
|
self.alloc.free(self.name);
|
||||||
|
|
||||||
if (self.stack) |stack| {
|
|
||||||
self.alloc.free(stack);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self.message) |res| {
|
if (self.message) |res| {
|
||||||
self.alloc.free(res);
|
self.alloc.free(res);
|
||||||
}
|
}
|
||||||
@@ -175,9 +165,6 @@ pub const Suite = struct {
|
|||||||
if (self.message) |v| {
|
if (self.message) |v| {
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
if (self.stack) |v| {
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -199,7 +186,7 @@ test "success test case" {
|
|||||||
,
|
,
|
||||||
};
|
};
|
||||||
|
|
||||||
const suite = Suite.init(alloc, "foo", res.pass, res.result, null) catch unreachable; // TODO
|
const suite = Suite.init(alloc, "foo", res.pass, res.result) catch unreachable; // TODO
|
||||||
defer suite.deinit();
|
defer suite.deinit();
|
||||||
|
|
||||||
try testing.expect(suite.pass == true);
|
try testing.expect(suite.pass == true);
|
||||||
@@ -226,7 +213,7 @@ test "failed test case" {
|
|||||||
,
|
,
|
||||||
};
|
};
|
||||||
|
|
||||||
const suite = Suite.init(alloc, "foo", res.pass, res.result, null) catch unreachable; // TODO
|
const suite = Suite.init(alloc, "foo", res.pass, res.result) catch unreachable; // TODO
|
||||||
defer suite.deinit();
|
defer suite.deinit();
|
||||||
|
|
||||||
try testing.expect(suite.pass == false);
|
try testing.expect(suite.pass == false);
|
||||||
@@ -251,7 +238,7 @@ test "invalid result" {
|
|||||||
,
|
,
|
||||||
};
|
};
|
||||||
|
|
||||||
const suite = Suite.init(alloc, "foo", res.pass, res.result, null) catch unreachable; // TODO
|
const suite = Suite.init(alloc, "foo", res.pass, res.result) catch unreachable; // TODO
|
||||||
defer suite.deinit();
|
defer suite.deinit();
|
||||||
|
|
||||||
try testing.expect(suite.pass == false);
|
try testing.expect(suite.pass == false);
|
||||||
@@ -266,7 +253,7 @@ test "invalid result" {
|
|||||||
,
|
,
|
||||||
};
|
};
|
||||||
|
|
||||||
const suite2 = Suite.init(alloc, "foo", res2.pass, res2.result, null) catch unreachable; // TODO
|
const suite2 = Suite.init(alloc, "foo", res2.pass, res2.result) catch unreachable; // TODO
|
||||||
defer suite2.deinit();
|
defer suite2.deinit();
|
||||||
|
|
||||||
try testing.expect(suite2.pass == false);
|
try testing.expect(suite2.pass == false);
|
||||||
|
|||||||
2
vendor/zig-js-runtime
vendored
2
vendor/zig-js-runtime
vendored
Submodule vendor/zig-js-runtime updated: a820cf4387...e7fd4b1e04
Reference in New Issue
Block a user