| author | |
| committer | |
| log | f56d11350313d5e45be0679bd8fab2a96892c40c |
| tree | 5edaa66b6b03eb15e39f257f39c71233ca9f2283 |
| parent | dec7e45f7c7e61a3778767bbc7f8e1e9a33b01fa |
3 files changed, 43 insertions(+), 1 deletions(-)
lib/fuzzer/index.html+7| ... | @@ -125,6 +125,13 @@ | ... | @@ -125,6 +125,13 @@ |
| 125 | </head> | 125 | </head> |
| 126 | <body> | 126 | <body> |
| 127 | <p id="status">Loading JavaScript...</p> | 127 | <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> | ||
| 128 | <div id="sectSource" class="hidden"> | 135 | <div id="sectSource" class="hidden"> |
| 129 | <h2>Source Code</h2> | 136 | <h2>Source Code</h2> |
| 130 | <pre><code id="sourceText"></code></pre> | 137 | <pre><code id="sourceText"></code></pre> |
lib/fuzzer/main.js+19-1| ... | @@ -1,7 +1,11 @@ | ... | @@ -1,7 +1,11 @@ |
| 1 | (function() { | 1 | (function() { |
| 2 | const domStatus = document.getElementById("status"); | 2 | const domStatus = document.getElementById("status"); |
| 3 | const domSectSource = document.getElementById("sectSource"); | 3 | const domSectSource = document.getElementById("sectSource"); |
| 4 | const domSectStats = document.getElementById("sectStats"); | ||
| 4 | const domSourceText = document.getElementById("sourceText"); | 5 | const domSourceText = document.getElementById("sourceText"); |
| 6 | const domStatTotalRuns = document.getElementById("statTotalRuns"); | ||
| 7 | const domStatUniqueRuns = document.getElementById("statUniqueRuns"); | ||
| 8 | const domStatLowestStack = document.getElementById("statLowestStack"); | ||
| 5 | 9 | ||
| 6 | let wasm_promise = fetch("main.wasm"); | 10 | let wasm_promise = fetch("main.wasm"); |
| 7 | let sources_promise = fetch("sources.tar").then(function(response) { | 11 | let sources_promise = fetch("sources.tar").then(function(response) { |
| ... | @@ -94,7 +98,7 @@ | ... | @@ -94,7 +98,7 @@ |
| 94 | } | 98 | } |
| 95 | 99 | ||
| 96 | function onCoverageUpdate() { | 100 | function onCoverageUpdate() { |
| 97 | console.log("coverage update"); | 101 | renderStats(); |
| 98 | } | 102 | } |
| 99 | 103 | ||
| 100 | function render() { | 104 | function render() { |
| ... | @@ -105,6 +109,20 @@ | ... | @@ -105,6 +109,20 @@ |
| 105 | renderSource("/home/andy/dev/zig/lib/std/zig/tokenizer.zig"); | 109 | renderSource("/home/andy/dev/zig/lib/std/zig/tokenizer.zig"); |
| 106 | } | 110 | } |
| 107 | 111 | ||
| 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 | |||
| 108 | function renderSource(path) { | 126 | function renderSource(path) { |
| 109 | const decl_index = findFileRoot(path); | 127 | const decl_index = findFileRoot(path); |
| 110 | if (decl_index == null) throw new Error("file not found: " + path); | 128 | 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 { | ... | @@ -103,6 +103,23 @@ export fn decl_source_html(decl_index: Decl.Index) String { |
| 103 | return String.init(string_result.items); | 103 | return String.init(string_result.items); |
| 104 | } | 104 | } |
| 105 | 105 | ||
| 106 | export 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 | |||
| 113 | export fn totalRuns() u64 { | ||
| 114 | const header: *abi.CoverageUpdateHeader = @ptrCast(recent_coverage_update.items[0..@sizeOf(abi.CoverageUpdateHeader)]); | ||
| 115 | return header.n_runs; | ||
| 116 | } | ||
| 117 | |||
| 118 | export fn uniqueRuns() u64 { | ||
| 119 | const header: *abi.CoverageUpdateHeader = @ptrCast(recent_coverage_update.items[0..@sizeOf(abi.CoverageUpdateHeader)]); | ||
| 120 | return header.unique_runs; | ||
| 121 | } | ||
| 122 | |||
| 106 | const String = Slice(u8); | 123 | const String = Slice(u8); |
| 107 | 124 | ||
| 108 | fn Slice(T: type) type { | 125 | fn Slice(T: type) type { |