authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-08-04 15:45:16-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-08-07 00:48:32-07:00
logf56d11350313d5e45be0679bd8fab2a96892c40c
tree5edaa66b6b03eb15e39f257f39c71233ca9f2283
parentdec7e45f7c7e61a3778767bbc7f8e1e9a33b01fa

fuzzer web ui: render stats


3 files changed, 43 insertions(+), 1 deletions(-)

lib/fuzzer/index.html+7
......@@ -125,6 +125,13 @@
125125 </head>
126126 <body>
127127 <p id="status">Loading JavaScript...</p>
128 <div id="sectStats" class="hidden">
129 <ul>
130 <li>Total Runs: <span id="statTotalRuns"></span></li>
131 <li>Unique Runs: <span id="statUniqueRuns"></span></li>
132 <li>Lowest Stack: <span id="statLowestStack"></span></li>
133 </ul>
134 </div>
128135 <div id="sectSource" class="hidden">
129136 <h2>Source Code</h2>
130137 <pre><code id="sourceText"></code></pre>
lib/fuzzer/main.js+19-1
......@@ -1,7 +1,11 @@
11(function() {
22 const domStatus = document.getElementById("status");
33 const domSectSource = document.getElementById("sectSource");
4 const domSectStats = document.getElementById("sectStats");
45 const domSourceText = document.getElementById("sourceText");
6 const domStatTotalRuns = document.getElementById("statTotalRuns");
7 const domStatUniqueRuns = document.getElementById("statUniqueRuns");
8 const domStatLowestStack = document.getElementById("statLowestStack");
59
610 let wasm_promise = fetch("main.wasm");
711 let sources_promise = fetch("sources.tar").then(function(response) {
......@@ -94,7 +98,7 @@
9498 }
9599
96100 function onCoverageUpdate() {
97 console.log("coverage update");
101 renderStats();
98102 }
99103
100104 function render() {
......@@ -105,6 +109,20 @@
105109 renderSource("/home/andy/dev/zig/lib/std/zig/tokenizer.zig");
106110 }
107111
112 function renderStats() {
113 const totalRuns = wasm_exports.totalRuns();
114 const uniqueRuns = wasm_exports.uniqueRuns();
115 domStatTotalRuns.innerText = totalRuns;
116 domStatUniqueRuns.innerText = uniqueRuns + " (" + percent(uniqueRuns, totalRuns) + "%)";
117 domStatLowestStack.innerText = unwrapString(wasm_exports.lowestStack());
118
119 domSectStats.classList.remove("hidden");
120 }
121
122 function percent(a, b) {
123 return ((Number(a) / Number(b)) * 100).toFixed(1);
124 }
125
108126 function renderSource(path) {
109127 const decl_index = findFileRoot(path);
110128 if (decl_index == null) throw new Error("file not found: " + path);
lib/fuzzer/wasm/main.zig+17
......@@ -103,6 +103,23 @@ export fn decl_source_html(decl_index: Decl.Index) String {
103103 return String.init(string_result.items);
104104}
105105
106export fn lowestStack() String {
107 const header: *abi.CoverageUpdateHeader = @ptrCast(recent_coverage_update.items[0..@sizeOf(abi.CoverageUpdateHeader)]);
108 string_result.clearRetainingCapacity();
109 string_result.writer(gpa).print("0x{d}", .{header.lowest_stack}) catch @panic("OOM");
110 return String.init(string_result.items);
111}
112
113export fn totalRuns() u64 {
114 const header: *abi.CoverageUpdateHeader = @ptrCast(recent_coverage_update.items[0..@sizeOf(abi.CoverageUpdateHeader)]);
115 return header.n_runs;
116}
117
118export fn uniqueRuns() u64 {
119 const header: *abi.CoverageUpdateHeader = @ptrCast(recent_coverage_update.items[0..@sizeOf(abi.CoverageUpdateHeader)]);
120 return header.unique_runs;
121}
122
106123const String = Slice(u8);
107124
108125fn Slice(T: type) type {