From 28225fde528022cb2b30d5d226aa09833860e512 Mon Sep 17 00:00:00 2001 From: sfja Date: Sun, 15 Dec 2024 03:07:33 +0100 Subject: [PATCH] fix last commit + fix status --- compiler/assembler.ts | 1 - compiler/compiler.ts | 2 +- runtime/actions.cpp | 36 ++++++++++++++++----------------- runtime/actions.hpp | 10 ++++----- runtime/main.cpp | 4 ++-- runtime/vm.cpp | 7 +++---- runtime/vm.hpp | 18 ++++++++++------- runtime/vm_provider.cpp | 10 ++++----- runtime/vm_provider.hpp | 12 +++++++++-- slige-build-run-all.sh | 5 +++++ web/main.ts | 2 +- web/public/src/data.ts | 10 +++++++++ web/public/src/index.ts | 45 ++++++++++++++++++++++++++++++++++++----- 13 files changed, 110 insertions(+), 52 deletions(-) diff --git a/compiler/assembler.ts b/compiler/assembler.ts index a5a3d88..5775715 100644 --- a/compiler/assembler.ts +++ b/compiler/assembler.ts @@ -46,7 +46,6 @@ export class Assembler { } public assemble(): { program: number[]; locs: Locs } { - console.log("Assembling..."); let ip = 0; const program: number[] = []; const locs: Locs = {}; diff --git a/compiler/compiler.ts b/compiler/compiler.ts index ec8666e..9309432 100644 --- a/compiler/compiler.ts +++ b/compiler/compiler.ts @@ -47,7 +47,7 @@ export class Compiler { const lowerer = new Lowerer(lexer.currentPos()); lowerer.lower(ast); - lowerer.printProgram(); + //lowerer.printProgram(); const { program, fnNames } = lowerer.finish(); return { program, fnNames }; diff --git a/runtime/actions.cpp b/runtime/actions.cpp index ff32273..7d5e965 100644 --- a/runtime/actions.cpp +++ b/runtime/actions.cpp @@ -7,18 +7,18 @@ using namespace sliger::rpc::action; -auto Status::perform_action(std::unique_ptr writer, - vm_provider::VmProvider& vm) -> void +auto Status::perform_action( + std::unique_ptr writer, VmProvider& vm) -> void { bool running = not vm.done(); - writer->write(std::format("{{ \"ok\": true, \"running\": {} }}", running)); + writer->write(std::format( + "{{ \"ok\": true, \"status\": {{ \"running\": {} }} }}", running)); writer->flush(); }; auto FlameGraph::perform_action( - std::unique_ptr writer, - vm_provider::VmProvider& vm) -> void + std::unique_ptr writer, VmProvider& vm) -> void { auto json = vm.flame_graph_json(); if (json) { @@ -31,8 +31,7 @@ auto FlameGraph::perform_action( }; auto CodeCoverage::perform_action( - std::unique_ptr writer, - vm_provider::VmProvider& vm) -> void + std::unique_ptr writer, VmProvider& vm) -> void { auto json = vm.code_coverage_json(); if (json) { @@ -45,11 +44,10 @@ auto CodeCoverage::perform_action( }; auto RunDebug::perform_action( - std::unique_ptr writer, - vm_provider::VmProvider& vm) -> void + std::unique_ptr writer, VmProvider& vm) -> void { auto program = this->instructions; - vm.load_and_run(program); + vm.load_and_start(program); writer->write("{ \"ok\": true }"); writer->flush(); }; @@ -60,27 +58,27 @@ auto sliger::rpc::action::action_from_json( auto& obj = value.as(); auto type = obj.fields.at("type")->as(); + if (type.value == "status") { + return std::make_unique(); + } + if (type.value == "flame-graph") { - auto action = FlameGraph(); - return std::make_unique(action); + return std::make_unique(); } if (type.value == "code-coverage") { - auto action = CodeCoverage(); - return std::make_unique(action); + return std::make_unique(); } if (type.value == "run-debug") { sliger::json::ArrayValues values = std::move( obj.fields.at("program")->as().values); auto instructions = std::vector(); - for (auto& v : values) { - std::unique_ptr moved = std::move(v); - auto value = moved->as().value; + for (auto&& v : values) { + auto value = v->as().value; instructions.push_back((uint32_t)value); } - auto action = RunDebug(instructions); - return std::make_unique(action); + return std::make_unique(instructions); } std::cout << "error: TODO " << __FILE__ << ":" << __LINE__ << "\n"; exit(1); diff --git a/runtime/actions.hpp b/runtime/actions.hpp index 9515f3d..2f01545 100644 --- a/runtime/actions.hpp +++ b/runtime/actions.hpp @@ -6,7 +6,7 @@ namespace sliger::rpc::action { struct Action { virtual auto perform_action(std::unique_ptr writer, - vm_provider::VmProvider& vm_provider) -> void = 0; + VmProvider& vm_provider) -> void = 0; virtual ~Action() = default; }; @@ -14,21 +14,21 @@ class Status : public Action { public: Status() { } auto perform_action(std::unique_ptr writer, - vm_provider::VmProvider& vm_provider) -> void; + VmProvider& vm_provider) -> void; }; class FlameGraph : public Action { public: FlameGraph() { } auto perform_action(std::unique_ptr writer, - vm_provider::VmProvider& vm_provider) -> void; + VmProvider& vm_provider) -> void; }; class CodeCoverage : public Action { public: CodeCoverage() { } auto perform_action(std::unique_ptr writer, - vm_provider::VmProvider& vm_provider) -> void; + VmProvider& vm_provider) -> void; }; class RunDebug : public Action { @@ -38,7 +38,7 @@ public: { } auto perform_action(std::unique_ptr writer, - vm_provider::VmProvider& vm_provider) -> void; + VmProvider& vm_provider) -> void; private: std::vector instructions; diff --git a/runtime/main.cpp b/runtime/main.cpp index b3a26cd..352edbf 100644 --- a/runtime/main.cpp +++ b/runtime/main.cpp @@ -67,7 +67,7 @@ int main(int argc, char** argv) return execute_file_and_exit(argv[2], print_debug); } - auto vm_provider = sliger::rpc::vm_provider::VmProvider(); + auto vm_provider = sliger::rpc::VmProvider(); auto rpc = sliger::rpc::RpcServer( [&](std::unique_ptr req, @@ -76,7 +76,7 @@ int main(int argc, char** argv) action->perform_action(std::move(writer), vm_provider); }); - std::cout << "binding on 127.0.0.1:13370\n"; + std::cout << "Runtime at 127.0.0.1:13370\n"; auto res = rpc.listen(); if (!res.is_ok()) { std::cout << res.err().msg << "\n"; diff --git a/runtime/vm.cpp b/runtime/vm.cpp index 97e2759..406bf30 100644 --- a/runtime/vm.cpp +++ b/runtime/vm.cpp @@ -13,7 +13,7 @@ using namespace sliger; void VM::run_until_done() { - while (!done()) { + while (not done()) { run_instruction(); } this->flame_graph.calculate_midway_result(this->instruction_counter); @@ -21,8 +21,7 @@ void VM::run_until_done() void VM::run_n_instructions(size_t amount) { - for (size_t i = 0; !done() and i < amount; ++i) { - + for (size_t i = 0; i < amount and not done(); ++i) { run_instruction(); } this->flame_graph.calculate_midway_result(this->instruction_counter); @@ -586,7 +585,7 @@ void VM::assert_stack_has(size_t count) void VM::assert_program_has(size_t count) { - if (this->pc + count > program_size) { + if (this->pc + count > program.size()) { std::cerr << std::format("malformed program, pc = {}", this->pc); std::exit(1); } diff --git a/runtime/vm.hpp b/runtime/vm.hpp index fec3772..45c1ff9 100644 --- a/runtime/vm.hpp +++ b/runtime/vm.hpp @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include #include @@ -90,7 +92,8 @@ private: int64_t diff = ic - this->nodes[this->current].ic_start; this->nodes[this->current].acc += diff; this->nodes[this->current].ic_start = ic; - if (node_index == 0) + // TODO this was a hack, idk if correct + if (node_index == this->nodes[this->current].parent) return; calculate_node_midway_result(ic, this->nodes[this->current].parent); } @@ -146,10 +149,9 @@ struct VMOpts { class VM { public: - VM(const std::vector& program, VMOpts opts) + VM(std::vector program, VMOpts opts) : opts(opts) - , program(program.data()) - , program_size(program.size()) + , program(std::move(program)) { } @@ -157,7 +159,10 @@ public: void run_n_instructions(size_t amount); void run_instruction(); - inline auto done() const -> bool { return this->pc >= this->program_size; } + inline auto done() const -> bool + { + return this->pc >= this->program.size(); + } inline auto flame_graph_json() const -> std::string { @@ -236,8 +241,7 @@ private: VMOpts opts; uint32_t pc = 0; uint32_t bp = 0; - const uint32_t* program; - size_t program_size; + std::vector program; std::vector stack; std::vector statics; heap::Heap heap; diff --git a/runtime/vm_provider.cpp b/runtime/vm_provider.cpp index ea5c6bf..8ddf4ff 100644 --- a/runtime/vm_provider.cpp +++ b/runtime/vm_provider.cpp @@ -3,14 +3,14 @@ #include #include -using namespace sliger::rpc::vm_provider; +using namespace sliger::rpc; -auto VmProvider::load_and_run(std::vector instructions) -> void +auto VmProvider::load_and_start(std::vector instructions) -> void { std::lock_guard lock(this->mutex); - this->vm = VM(instructions, - { + this->vm.emplace(instructions, + VMOpts { .flame_graph = true, .code_coverage = true, .print_debug = false, @@ -49,7 +49,7 @@ void VmProvider::run_timeslot() { std::lock_guard lock(this->mutex); - if (!this->vm.has_value()) + if (not this->vm) return; this->vm->run_n_instructions(100); diff --git a/runtime/vm_provider.hpp b/runtime/vm_provider.hpp index 7d8a72b..28f8e1b 100644 --- a/runtime/vm_provider.hpp +++ b/runtime/vm_provider.hpp @@ -1,15 +1,23 @@ #pragma once #include "vm.hpp" +#include #include #include +#include + +namespace sliger::rpc { -namespace sliger::rpc::vm_provider { class VmProvider { public: VmProvider() { } - auto load_and_run(std::vector instructions) -> void; + VmProvider(const VmProvider&) = delete; + VmProvider operator=(const VmProvider&) = delete; + VmProvider(VmProvider&&) = delete; + VmProvider operator=(VmProvider&&) = delete; + + auto load_and_start(std::vector instructions) -> void; auto flame_graph_json() -> std::optional; auto code_coverage_json() -> std::optional; diff --git a/slige-build-run-all.sh b/slige-build-run-all.sh index b1167ee..e3709b1 100755 --- a/slige-build-run-all.sh +++ b/slige-build-run-all.sh @@ -12,6 +12,11 @@ cd web/public deno task bundle cd ../.. +set +e +fuser -k 13370/tcp +set -e + + ./runtime/build/sliger & cd web diff --git a/web/main.ts b/web/main.ts index 8b78de3..5d241b2 100644 --- a/web/main.ts +++ b/web/main.ts @@ -53,7 +53,7 @@ router.get("/api/status", async (ctx) => { connection.send({ type: "status" }); const res = await connection.receive<{ ok: boolean; - status: "running" | "done"; + status: { running: boolean }; }>(); connection.close(); if (!res.ok) { diff --git a/web/public/src/data.ts b/web/public/src/data.ts index 2c79b21..b286b23 100644 --- a/web/public/src/data.ts +++ b/web/public/src/data.ts @@ -1,3 +1,13 @@ +export type Status = { + running: boolean; +}; + +export async function status(): Promise { + return await fetch("/api/status") + .then((v) => v.json()) + .then((v) => v.status); +} + export type FlameGraphNode = { fn: number; acc: number; diff --git a/web/public/src/index.ts b/web/public/src/index.ts index 4cb7607..22e1ac1 100644 --- a/web/public/src/index.ts +++ b/web/public/src/index.ts @@ -326,9 +326,6 @@ async function main() { } const codeData = await data.codeData(); - const codeCoverageData = await data.codeCoverageData(); - const flameGraphData = await data.flameGraphData(); - const flameGraphFnNames = await data.flameGraphFnNames(); const view = document.querySelector("#view")!; const renderFunctions: RenderFns = { @@ -348,7 +345,12 @@ async function main() { outerContainer.append(innerContainer); view.replaceChildren(outerContainer); }, - "code-coverage": () => { + "code-coverage": async () => { + if (await data.status().then((r) => r.running)) { + return; + } + const codeCoverageData = await data.codeCoverageData(); + const outerContainer = document.createElement("div"); outerContainer.classList.add("code-container"); @@ -372,7 +374,13 @@ async function main() { const view = document.querySelector("#view")!; view.replaceChildren(outerContainer, tooltip); }, - "flame-graph": () => { + "flame-graph": async () => { + if (await data.status().then((r) => r.running)) { + return; + } + const flameGraphData = await data.flameGraphData(); + const flameGraphFnNames = await data.flameGraphFnNames(); + const container = document.createElement("div"); container.classList.add("flame-graph"); container.id = "flame-graph"; @@ -396,6 +404,33 @@ async function main() { renderFunctions[value](); } } + + async function checkStatus(): Promise<"running" | "done"> { + const status = await data.status(); + + if (status.running) { + return "running"; + } + const statusHtml = document.querySelector( + "#status", + )!; + statusHtml.innerText = "Done"; + document.body.classList.remove("status-waiting"); + document.body.classList.add("status-done"); + return "done"; + } + + checkStatus().then((status) => { + if (status == "done") { + return; + } + const interval = setInterval(async () => { + const status = await checkStatus(); + if (status == "done") { + clearInterval(interval); + } + }, 500); + }); } main();