Skip to content

Commit bc0915e

Browse files
committed
Propagate real filenames to JS_Eval for coverage
Add a filename field to the eval message payload. When a runtime loads a script via the :script option, the file path is passed through to JS_Eval so coverage reports show the actual source filename instead of <eval>. Inline eval/3 calls continue to use <eval> as the filename.
1 parent 4a356f7 commit bc0915e

6 files changed

Lines changed: 25 additions & 10 deletions

File tree

lib/quickbeam/context_worker.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ fn handle_ctx_eval(
294294
install_pump(pd, contexts, p.context_id, entry);
295295
qjs.JS_ResetContextReductionCount(entry.state.ctx);
296296
var result = worker.Result{};
297-
entry.state.do_eval(p.code, &result);
297+
entry.state.do_eval(p.code, "", &result);
298298
uninstall_pump(entry);
299299

300300
pd.deadline = null;

lib/quickbeam/native.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ defmodule QuickBEAM.Native do
154154
],
155155
resources: [:RuntimeResource, :PoolResource, :WasmModuleResource, :WasmInstanceResource],
156156
nifs: [
157-
eval: 3,
157+
eval: 4,
158158
compile: 2,
159159
call_function: 4,
160160
load_module: 3,

lib/quickbeam/quickbeam.zig

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ pub fn start_runtime(owner_pid: beam.pid, opts: beam.term) !RuntimeResource {
104104
return res;
105105
}
106106

107-
pub fn eval(resource: RuntimeResource, code: []const u8, timeout_ms: u64) beam.term {
107+
pub fn eval(resource: RuntimeResource, code: []const u8, timeout_ms: u64, filename: []const u8) beam.term {
108108
const data = resource.unpack();
109109
const env = beam.context.env orelse return beam.make(.{ .@"error", "no env" }, .{});
110110

@@ -113,13 +113,18 @@ pub fn eval(resource: RuntimeResource, code: []const u8, timeout_ms: u64) beam.t
113113
const ref_term = e.enif_make_ref(ref_env);
114114

115115
const code_copy = gpa.dupe(u8, code) catch return beam.make(.{ .@"error", "OOM" }, .{});
116+
const fname_copy = if (filename.len > 0) gpa.dupe(u8, filename) catch {
117+
gpa.free(code_copy);
118+
return beam.make(.{ .@"error", "OOM" }, .{});
119+
} else &[_]u8{};
116120

117121
enqueue(data, .{ .eval = .{
118122
.code = code_copy,
119123
.caller_pid = caller_pid,
120124
.ref_env = ref_env,
121125
.ref_term = ref_term,
122126
.timeout_ns = if (timeout_ms > 0) timeout_ms * 1_000_000 else 0,
127+
.filename = fname_copy,
123128
} });
124129

125130
return beam.term{ .v = e.enif_make_copy(env, ref_term) };

lib/quickbeam/runtime.ex

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ defmodule QuickBEAM.Runtime do
342342
defp eval_script_async(state, path) do
343343
case read_script(path) do
344344
{:ok, code} ->
345-
ref = QuickBEAM.Native.eval(state.resource, code, 0)
345+
ref = QuickBEAM.Native.eval(state.resource, code, 0, path)
346346
await_ref_with_callbacks(ref, state, path)
347347

348348
{:error, reason} when is_atom(reason) ->
@@ -405,7 +405,7 @@ defmodule QuickBEAM.Runtime do
405405
end
406406

407407
defp sync_eval(resource, code) do
408-
ref = QuickBEAM.Native.eval(resource, code, 0)
408+
ref = QuickBEAM.Native.eval(resource, code, 0, "")
409409
await_ref(ref)
410410
end
411411

@@ -458,7 +458,7 @@ defmodule QuickBEAM.Runtime do
458458
QuickBEAM.Native.define_global(state.resource, name, value)
459459
end)
460460

461-
ref = QuickBEAM.Native.eval(state.resource, code, timeout_ms)
461+
ref = QuickBEAM.Native.eval(state.resource, code, timeout_ms, "")
462462

463463
transform = fn result ->
464464
QuickBEAM.Native.delete_globals(state.resource, names)
@@ -539,7 +539,7 @@ defmodule QuickBEAM.Runtime do
539539

540540
# ── NIF dispatch callbacks ──
541541

542-
defp nif_eval(state, code, timeout), do: QuickBEAM.Native.eval(state.resource, code, timeout)
542+
defp nif_eval(state, code, timeout), do: QuickBEAM.Native.eval(state.resource, code, timeout, "")
543543

544544
defp nif_call(state, fn_name, args, timeout),
545545
do: QuickBEAM.Native.call_function(state.resource, fn_name, args, timeout)

lib/quickbeam/types.zig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ pub const AsyncRequestPayload = struct {
6666
ref_env: ?*e.ErlNifEnv,
6767
ref_term: e.ErlNifTerm,
6868
timeout_ns: u64 = 0,
69+
filename: []const u8 = "",
6970
};
7071

7172
pub const AsyncCallPayload = struct {

lib/quickbeam/worker.zig

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -382,19 +382,27 @@ pub const WorkerState = struct {
382382
self.drain_jobs();
383383
}
384384

385-
pub fn do_eval(self: *WorkerState, code: []const u8, result: *Result) void {
385+
pub fn do_eval(self: *WorkerState, code: []const u8, filename: []const u8, result: *Result) void {
386386
const code_z = gpa.dupeZ(u8, code) catch {
387387
result.ok = false;
388388
result.json = "Out of memory";
389389
return;
390390
};
391391
defer gpa.free(code_z);
392392

393+
const fname = if (filename.len > 0) filename else "<eval>";
394+
const fname_z = gpa.dupeZ(u8, fname) catch {
395+
result.ok = false;
396+
result.json = "Out of memory";
397+
return;
398+
};
399+
defer gpa.free(fname_z);
400+
393401
var flags: c_int = qjs.JS_EVAL_TYPE_GLOBAL;
394402
if (std.mem.indexOf(u8, code, "await") != null) {
395403
flags |= qjs.JS_EVAL_FLAG_ASYNC;
396404
}
397-
const val = qjs.JS_Eval(self.ctx, code_z.ptr, code.len, "<eval>", flags);
405+
const val = qjs.JS_Eval(self.ctx, code_z.ptr, code.len, fname_z.ptr, flags);
398406
defer qjs.JS_FreeValue(self.ctx, val);
399407
self.drain_jobs();
400408

@@ -949,9 +957,10 @@ pub fn worker_main(rd: *types.RuntimeData, owner_pid: beam.pid) void {
949957
.eval => |p| {
950958
var result = Result{};
951959
state.set_deadline(p.timeout_ns);
952-
state.do_eval(p.code, &result);
960+
state.do_eval(p.code, p.filename, &result);
953961
state.clear_deadline();
954962
gpa.free(p.code);
963+
if (p.filename.len > 0) gpa.free(p.filename);
955964
types.send_reply(p.caller_pid, p.ref_env, p.ref_term, result.ok, result.env, result.term, result.json);
956965
},
957966
.compile => |p| {

0 commit comments

Comments
 (0)