authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-08-04 18:22:09-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-08-07 00:48:32-07:00
logdb69641061ae300baabd6107aa22da60e78f0f38
treeb92197b59df8cefaee4c9dd545726314c2be9ef8
parente64a00950e7ec505fdcdb53da265828d1263bc22

fuzzing web ui: make entry point links clickable


2 files changed, 68 insertions(+), 9 deletions(-)

lib/fuzzer/main.js+47-3
...@@ -15,6 +15,8 @@...@@ -15,6 +15,8 @@
15 return response.arrayBuffer();15 return response.arrayBuffer();
16 });16 });
17 var wasm_exports = null;17 var wasm_exports = null;
18 var curNavSearch = null;
19 var curNavLocation = null;
1820
19 const text_decoder = new TextDecoder();21 const text_decoder = new TextDecoder();
20 const text_encoder = new TextEncoder();22 const text_encoder = new TextEncoder();
...@@ -47,11 +49,52 @@...@@ -47,11 +49,52 @@
47 wasm_array.set(js_array);49 wasm_array.set(js_array);
48 wasm_exports.unpack(ptr, js_array.length);50 wasm_exports.unpack(ptr, js_array.length);
4951
52 window.addEventListener('popstate', onPopState, false);
53 onHashChange(null);
54
50 domStatus.textContent = "Waiting for server to send source location metadata...";55 domStatus.textContent = "Waiting for server to send source location metadata...";
51 connectWebSocket();56 connectWebSocket();
52 });57 });
53 });58 });
5459
60 function onPopState(ev) {
61 onHashChange(ev.state);
62 }
63
64 function onHashChange(state) {
65 history.replaceState({}, "");
66 navigate(location.hash);
67 if (state == null) window.scrollTo({top: 0});
68 }
69
70 function navigate(location_hash) {
71 curNavLocation = null;
72 curNavSearch = null;
73
74 if (location_hash.length > 1 && location_hash[0] === '#') {
75 const query = location_hash.substring(1);
76 const qpos = query.indexOf("?");
77 let nonSearchPart;
78 if (qpos === -1) {
79 nonSearchPart = query;
80 } else {
81 nonSearchPart = query.substring(0, qpos);
82 curNavSearch = decodeURIComponent(query.substring(qpos + 1));
83 }
84
85 if (nonSearchPart.length > 0) {
86 curNavLocation = nonSearchPart;
87 }
88 }
89
90 render();
91
92 if (curNavLocation != null) {
93 // TODO
94 // scrollToSourceLocation(findSourceLocationIndex(curNavLocation));
95 }
96 }
97
55 function connectWebSocket() {98 function connectWebSocket() {
56 const host = window.document.location.host;99 const host = window.document.location.host;
57 const pathname = window.document.location.pathname;100 const pathname = window.document.location.pathname;
...@@ -104,8 +147,9 @@...@@ -104,8 +147,9 @@
104 domStatus.classList.add("hidden");147 domStatus.classList.add("hidden");
105 domSectSource.classList.add("hidden");148 domSectSource.classList.add("hidden");
106149
107 // TODO this is temporary debugging data150 if (curNavLocation != null) {
108 renderSource("/home/andy/dev/zig/lib/std/zig/tokenizer.zig");151 renderSource(curNavLocation.split(":")[0]);
152 }
109 }153 }
110154
111 function renderStats() {155 function renderStats() {
...@@ -122,7 +166,7 @@...@@ -122,7 +166,7 @@
122 resizeDomList(domEntryPointsList, entryPoints.length, "<li></li>");166 resizeDomList(domEntryPointsList, entryPoints.length, "<li></li>");
123 for (let i = 0; i < entryPoints.length; i += 1) {167 for (let i = 0; i < entryPoints.length; i += 1) {
124 const liDom = domEntryPointsList.children[i];168 const liDom = domEntryPointsList.children[i];
125 liDom.innerText = unwrapString(wasm_exports.sourceLocationLinkHtml(entryPoints[i]));169 liDom.innerHTML = unwrapString(wasm_exports.sourceLocationLinkHtml(entryPoints[i]));
126 }170 }
127171
128172
lib/fuzzer/wasm/main.zig+21-6
...@@ -4,6 +4,7 @@ const abi = std.Build.Fuzz.abi;...@@ -4,6 +4,7 @@ const abi = std.Build.Fuzz.abi;
4const gpa = std.heap.wasm_allocator;4const gpa = std.heap.wasm_allocator;
5const log = std.log;5const log = std.log;
6const Coverage = std.debug.Coverage;6const Coverage = std.debug.Coverage;
7const Allocator = std.mem.Allocator;
78
8const Walk = @import("Walk");9const Walk = @import("Walk");
9const Decl = Walk.Decl;10const Decl = Walk.Decl;
...@@ -263,12 +264,26 @@ fn updateCoverage(...@@ -263,12 +264,26 @@ fn updateCoverage(
263}264}
264265
265export fn sourceLocationLinkHtml(index: u32) String {266export fn sourceLocationLinkHtml(index: u32) String {
266 const sl = coverage_source_locations.items[index];
267 const file_name = coverage.stringAt(coverage.fileAt(sl.file).basename);
268
269 string_result.clearRetainingCapacity();267 string_result.clearRetainingCapacity();
270 string_result.writer(gpa).print("{s}:{d}:{d}", .{268 sourceLocationLinkHtmlFallible(index, &string_result) catch @panic("OOM");
271 file_name, sl.line, sl.column,
272 }) catch @panic("OOM");
273 return String.init(string_result.items);269 return String.init(string_result.items);
274}270}
271
272fn sourceLocationLinkHtmlFallible(index: u32, out: *std.ArrayListUnmanaged(u8)) Allocator.Error!void {
273 const sl = coverage_source_locations.items[index];
274 const file = coverage.fileAt(sl.file);
275 const file_name = coverage.stringAt(file.basename);
276 const dir_name = coverage.stringAt(coverage.directories.keys()[file.directory_index]);
277
278 out.clearRetainingCapacity();
279 try out.appendSlice(gpa, "<a href=\"#");
280 _ = html_render.missing_feature_url_escape;
281 try out.writer(gpa).print("{s}/{s}:{d}:{d}", .{
282 dir_name, file_name, sl.line, sl.column,
283 });
284 try out.appendSlice(gpa, "\">");
285 try html_render.appendEscaped(out, dir_name);
286 try out.appendSlice(gpa, "/");
287 try html_render.appendEscaped(out, file_name);
288 try out.writer(gpa).print(":{d}:{d}</a>", .{ sl.line, sl.column });
289}