fix code coverage
This commit is contained in:
parent
1760913909
commit
f8b573c135
52
runtime/instruction_size.cpp
Normal file
52
runtime/instruction_size.cpp
Normal file
@ -0,0 +1,52 @@
|
||||
#include "arch.hpp"
|
||||
#include "vm.hpp"
|
||||
|
||||
using namespace sliger;
|
||||
|
||||
size_t VM::instruction_size(size_t i) const
|
||||
{
|
||||
switch (static_cast<Op>(this->program.at(i))) {
|
||||
case Op::Nop:
|
||||
case Op::PushNull:
|
||||
return 1;
|
||||
case Op::PushInt:
|
||||
case Op::PushBool:
|
||||
return 2;
|
||||
case Op::PushString: {
|
||||
auto string_length = this->program.at(i + 1);
|
||||
return 2 + string_length;
|
||||
}
|
||||
case Op::PushPtr:
|
||||
return 2;
|
||||
case Op::Pop:
|
||||
return 1;
|
||||
case Op::ReserveStatic:
|
||||
case Op::LoadStatic:
|
||||
case Op::StoreStatic:
|
||||
case Op::LoadLocal:
|
||||
case Op::StoreLocal:
|
||||
case Op::Call:
|
||||
return 2;
|
||||
case Op::Return:
|
||||
case Op::Jump:
|
||||
case Op::JumpIfTrue:
|
||||
return 1;
|
||||
case Op::Builtin:
|
||||
return 2;
|
||||
case Op::Add:
|
||||
case Op::Subtract:
|
||||
case Op::Multiply:
|
||||
case Op::Divide:
|
||||
case Op::Remainder:
|
||||
case Op::Equal:
|
||||
case Op::LessThan:
|
||||
case Op::And:
|
||||
case Op::Or:
|
||||
case Op::Xor:
|
||||
case Op::Not:
|
||||
return 1;
|
||||
case Op::SourceMap:
|
||||
return 4;
|
||||
}
|
||||
return 1;
|
||||
}
|
@ -451,7 +451,8 @@ void VM::run_file_builtin(Builtin builtin_id)
|
||||
auto filename = stack_pop().as_string().value;
|
||||
FILE* fp = std::fopen(filename.c_str(), mode.c_str());
|
||||
if (fp == nullptr) {
|
||||
std::cerr << std::format("error: could not open file '{}'\n", filename);
|
||||
std::cerr << std::format(
|
||||
"error: could not open file '{}'\n", filename);
|
||||
std::exit(1);
|
||||
}
|
||||
auto file_id = this->file_id_counter;
|
||||
@ -568,6 +569,14 @@ auto VM::stack_repr_string(size_t max_items) const -> std::string
|
||||
return result;
|
||||
};
|
||||
|
||||
void VM::assert_program_has(size_t count)
|
||||
{
|
||||
if (this->pc + count > program.size()) {
|
||||
std::cerr << std::format("malformed program, pc = {}", this->pc);
|
||||
std::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void VM::assert_fn_stack_has(size_t count)
|
||||
{
|
||||
if (this->stack.size() - this->bp < count) {
|
||||
@ -583,11 +592,3 @@ void VM::assert_stack_has(size_t count)
|
||||
std::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void VM::assert_program_has(size_t count)
|
||||
{
|
||||
if (this->pc + count > program.size()) {
|
||||
std::cerr << std::format("malformed program, pc = {}", this->pc);
|
||||
std::exit(1);
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace sliger {
|
||||
@ -108,6 +109,11 @@ struct CCPosEntry {
|
||||
|
||||
class CodeCoverageBuilder : public json::ToAndFromJson {
|
||||
public:
|
||||
inline void make_sure_entry_exists(SourcePos pos)
|
||||
{
|
||||
find_or_create_entry(pos);
|
||||
}
|
||||
|
||||
/// call when leaving a source location
|
||||
inline void report_cover(SourcePos pos)
|
||||
{
|
||||
@ -166,8 +172,19 @@ public:
|
||||
return json::to_json(this->flame_graph);
|
||||
}
|
||||
|
||||
inline auto code_coverage_json() const -> std::string
|
||||
inline auto code_coverage_json() -> std::string
|
||||
{
|
||||
for (size_t i = 0; i < this->program.size(); ++i) {
|
||||
if (this->program.at(i) == std::to_underlying(Op::SourceMap)
|
||||
&& this->program.size() - 1 - i >= 3) {
|
||||
auto index = static_cast<int32_t>(this->program.at(i + 1));
|
||||
auto line = static_cast<int32_t>(this->program.at(i + 2));
|
||||
auto col = static_cast<int32_t>(this->program.at(i + 3));
|
||||
this->code_coverage.make_sure_entry_exists(
|
||||
{ index, line, col });
|
||||
}
|
||||
i += instruction_size(i);
|
||||
}
|
||||
return json::to_json(this->code_coverage);
|
||||
}
|
||||
|
||||
@ -223,6 +240,7 @@ private:
|
||||
{
|
||||
return this->stack.at(this->bp + idx);
|
||||
}
|
||||
void assert_program_has(size_t count);
|
||||
void assert_fn_stack_has(size_t count);
|
||||
void assert_stack_has(size_t count);
|
||||
inline void stack_push(Value&& value) { this->stack.push_back(value); }
|
||||
@ -233,7 +251,7 @@ private:
|
||||
this->stack.pop_back();
|
||||
return value;
|
||||
}
|
||||
void assert_program_has(size_t count);
|
||||
size_t instruction_size(size_t i) const;
|
||||
|
||||
VMOpts opts;
|
||||
uint32_t pc = 0;
|
||||
|
@ -97,21 +97,6 @@ export function loadCodeCoverage(
|
||||
elements.push(span);
|
||||
col += 1;
|
||||
}
|
||||
function positionInBox(
|
||||
position: [number, number],
|
||||
boundingRect: {
|
||||
left: number;
|
||||
top: number;
|
||||
right: number;
|
||||
bottom: number;
|
||||
},
|
||||
) {
|
||||
const [x, y] = position;
|
||||
const outside = x < boundingRect.left ||
|
||||
x >= boundingRect.right || y < boundingRect.top ||
|
||||
y >= boundingRect.bottom;
|
||||
return !outside;
|
||||
}
|
||||
container.append(...elements);
|
||||
document.addEventListener("mousemove", (event) => {
|
||||
const [x, y] = [event.clientX, event.clientY];
|
||||
@ -146,3 +131,19 @@ export function loadCodeCoverage(
|
||||
});
|
||||
return container;
|
||||
}
|
||||
|
||||
function positionInBox(
|
||||
position: [number, number],
|
||||
boundingRect: {
|
||||
left: number;
|
||||
top: number;
|
||||
right: number;
|
||||
bottom: number;
|
||||
},
|
||||
) {
|
||||
const [x, y] = position;
|
||||
const outside = x < boundingRect.left ||
|
||||
x >= boundingRect.right || y < boundingRect.top ||
|
||||
y >= boundingRect.bottom;
|
||||
return !outside;
|
||||
}
|
||||
|
@ -57,15 +57,6 @@ function sourceCode(view: Element, codeData: string) {
|
||||
view.replaceChildren(outerContainer);
|
||||
}
|
||||
|
||||
async function codeCoverage(view: Element, codeData: string) {
|
||||
const codeCoverageData = await data.codeCoverageData();
|
||||
|
||||
const outerContainer = document.createElement("div");
|
||||
outerContainer.classList.add("code-container");
|
||||
|
||||
const innerContainer = document.createElement("div");
|
||||
innerContainer.classList.add("code-container-inner");
|
||||
|
||||
function createRadio(
|
||||
id: string,
|
||||
content: string,
|
||||
@ -85,6 +76,16 @@ async function codeCoverage(view: Element, codeData: string) {
|
||||
container.append(input, label);
|
||||
return [container, input];
|
||||
}
|
||||
|
||||
async function codeCoverage(view: Element, codeData: string) {
|
||||
const codeCoverageData = await data.codeCoverageData();
|
||||
|
||||
const outerContainer = document.createElement("div");
|
||||
outerContainer.classList.add("code-container");
|
||||
|
||||
const innerContainer = document.createElement("div");
|
||||
innerContainer.classList.add("code-container-inner");
|
||||
|
||||
const [perfGroup, perfInput] = createRadio(
|
||||
"performance-coverage",
|
||||
"Performance view",
|
||||
|
@ -159,6 +159,7 @@ main #cover {
|
||||
.coverage-radio {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.coverage-radio-group {
|
||||
@ -166,6 +167,7 @@ main #cover {
|
||||
justify-content: center;
|
||||
flex: 1;
|
||||
padding: 2rem;
|
||||
max-width: max-content;
|
||||
}
|
||||
|
||||
.coverage-radio-group label {
|
||||
@ -173,6 +175,8 @@ main #cover {
|
||||
border-radius: 0.25rem;
|
||||
cursor: pointer;
|
||||
border: 2px solid var(--code-status);
|
||||
width: 280px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.coverage-radio-group input:checked ~ label {
|
||||
|
Loading…
Reference in New Issue
Block a user