mirror of
https://git.sfja.dk/Mikkel/slige.git
synced 2025-01-18 07:46:32 +00:00
fix last commit + fix status
This commit is contained in:
parent
a3827243ff
commit
28225fde52
@ -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 = {};
|
||||
|
@ -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 };
|
||||
|
@ -7,18 +7,18 @@
|
||||
|
||||
using namespace sliger::rpc::action;
|
||||
|
||||
auto Status::perform_action(std::unique_ptr<sliger::rpc::BufferedWriter> writer,
|
||||
vm_provider::VmProvider& vm) -> void
|
||||
auto Status::perform_action(
|
||||
std::unique_ptr<sliger::rpc::BufferedWriter> 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<sliger::rpc::BufferedWriter> writer,
|
||||
vm_provider::VmProvider& vm) -> void
|
||||
std::unique_ptr<sliger::rpc::BufferedWriter> 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<sliger::rpc::BufferedWriter> writer,
|
||||
vm_provider::VmProvider& vm) -> void
|
||||
std::unique_ptr<sliger::rpc::BufferedWriter> 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<sliger::rpc::BufferedWriter> writer,
|
||||
vm_provider::VmProvider& vm) -> void
|
||||
std::unique_ptr<sliger::rpc::BufferedWriter> 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<sliger::json::Object>();
|
||||
auto type = obj.fields.at("type")->as<sliger::json::String>();
|
||||
|
||||
if (type.value == "status") {
|
||||
return std::make_unique<Status>();
|
||||
}
|
||||
|
||||
if (type.value == "flame-graph") {
|
||||
auto action = FlameGraph();
|
||||
return std::make_unique<FlameGraph>(action);
|
||||
return std::make_unique<FlameGraph>();
|
||||
}
|
||||
|
||||
if (type.value == "code-coverage") {
|
||||
auto action = CodeCoverage();
|
||||
return std::make_unique<CodeCoverage>(action);
|
||||
return std::make_unique<CodeCoverage>();
|
||||
}
|
||||
|
||||
if (type.value == "run-debug") {
|
||||
sliger::json::ArrayValues values = std::move(
|
||||
obj.fields.at("program")->as<sliger::json::Array>().values);
|
||||
auto instructions = std::vector<uint32_t>();
|
||||
for (auto& v : values) {
|
||||
std::unique_ptr<sliger::json::Value> moved = std::move(v);
|
||||
auto value = moved->as<sliger::json::Number>().value;
|
||||
for (auto&& v : values) {
|
||||
auto value = v->as<sliger::json::Number>().value;
|
||||
instructions.push_back((uint32_t)value);
|
||||
}
|
||||
auto action = RunDebug(instructions);
|
||||
return std::make_unique<RunDebug>(action);
|
||||
return std::make_unique<RunDebug>(instructions);
|
||||
}
|
||||
std::cout << "error: TODO " << __FILE__ << ":" << __LINE__ << "\n";
|
||||
exit(1);
|
||||
|
@ -6,7 +6,7 @@ namespace sliger::rpc::action {
|
||||
|
||||
struct Action {
|
||||
virtual auto perform_action(std::unique_ptr<BufferedWriter> 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<BufferedWriter> writer,
|
||||
vm_provider::VmProvider& vm_provider) -> void;
|
||||
VmProvider& vm_provider) -> void;
|
||||
};
|
||||
|
||||
class FlameGraph : public Action {
|
||||
public:
|
||||
FlameGraph() { }
|
||||
auto perform_action(std::unique_ptr<BufferedWriter> writer,
|
||||
vm_provider::VmProvider& vm_provider) -> void;
|
||||
VmProvider& vm_provider) -> void;
|
||||
};
|
||||
|
||||
class CodeCoverage : public Action {
|
||||
public:
|
||||
CodeCoverage() { }
|
||||
auto perform_action(std::unique_ptr<BufferedWriter> 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<BufferedWriter> writer,
|
||||
vm_provider::VmProvider& vm_provider) -> void;
|
||||
VmProvider& vm_provider) -> void;
|
||||
|
||||
private:
|
||||
std::vector<uint32_t> instructions;
|
||||
|
@ -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<sliger::json::Value> 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";
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -7,6 +7,8 @@
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@ -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<uint32_t>& program, VMOpts opts)
|
||||
VM(std::vector<uint32_t> 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<uint32_t> program;
|
||||
std::vector<Value> stack;
|
||||
std::vector<Value> statics;
|
||||
heap::Heap heap;
|
||||
|
@ -3,14 +3,14 @@
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
|
||||
using namespace sliger::rpc::vm_provider;
|
||||
using namespace sliger::rpc;
|
||||
|
||||
auto VmProvider::load_and_run(std::vector<uint32_t> instructions) -> void
|
||||
auto VmProvider::load_and_start(std::vector<uint32_t> 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);
|
||||
|
@ -1,15 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include "vm.hpp"
|
||||
#include <cstdint>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
namespace sliger::rpc {
|
||||
|
||||
namespace sliger::rpc::vm_provider {
|
||||
class VmProvider {
|
||||
public:
|
||||
VmProvider() { }
|
||||
|
||||
auto load_and_run(std::vector<uint32_t> instructions) -> void;
|
||||
VmProvider(const VmProvider&) = delete;
|
||||
VmProvider operator=(const VmProvider&) = delete;
|
||||
VmProvider(VmProvider&&) = delete;
|
||||
VmProvider operator=(VmProvider&&) = delete;
|
||||
|
||||
auto load_and_start(std::vector<uint32_t> instructions) -> void;
|
||||
auto flame_graph_json() -> std::optional<std::string>;
|
||||
auto code_coverage_json() -> std::optional<std::string>;
|
||||
|
||||
|
@ -12,6 +12,11 @@ cd web/public
|
||||
deno task bundle
|
||||
cd ../..
|
||||
|
||||
set +e
|
||||
fuser -k 13370/tcp
|
||||
set -e
|
||||
|
||||
|
||||
./runtime/build/sliger &
|
||||
|
||||
cd web
|
||||
|
@ -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) {
|
||||
|
@ -1,3 +1,13 @@
|
||||
export type Status = {
|
||||
running: boolean;
|
||||
};
|
||||
|
||||
export async function status(): Promise<Status> {
|
||||
return await fetch("/api/status")
|
||||
.then((v) => v.json())
|
||||
.then((v) => v.status);
|
||||
}
|
||||
|
||||
export type FlameGraphNode = {
|
||||
fn: number;
|
||||
acc: number;
|
||||
|
@ -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<HTMLSpanElement>(
|
||||
"#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();
|
||||
|
Loading…
Reference in New Issue
Block a user