Skip to content

Commit

Permalink
impl-wasm: Fix logger and initial implemtation of the heap
Browse files Browse the repository at this point in the history
  • Loading branch information
keyboard-slayer committed May 16, 2024
1 parent 97b1b75 commit dd8a239
Show file tree
Hide file tree
Showing 10 changed files with 162 additions and 113 deletions.
8 changes: 2 additions & 6 deletions meta/image/wasm/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@ const importObject = {
const out = new TextDecoder("utf-8").decode(buf);
console.error(out);
},
embedAlloc: (size) => {
new WebAssembly.Memory({initial: size});
}
}
};

Expand All @@ -33,7 +30,6 @@ const importObject = {

const wasmRaw = await fetch(bundle['ref'].replace('file:/', '')).then((response) => response.arrayBuffer());
wasmObj = await WebAssembly.instantiate(wasmRaw, importObject);
wasmObj.instance.exports.memory.grow(4096);
wasmObj.instance.exports.wasm_main();
})();

281474976710661
})();
2 changes: 1 addition & 1 deletion src/impls/impl-wasm/entry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@

void __panicHandler(Karm::PanicKind kind, char const *msg) {
embedConsoleError(kind == Karm::PanicKind::PANIC ? (u8 const *)"PANIC: " : (u8 const *)"DEBUG: ", 7);
embedConsoleError((const u8 *)msg, cstrLen(msg));
embedConsoleError((u8 const *)msg, cstrLen(msg));
}
9 changes: 5 additions & 4 deletions src/impls/impl-wasm/entry.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,19 @@
#include <karm-sys/chan.h>
#include <karm-sys/context.h>

#include "externs.h"
#include "abi.h"

#include "externs.h"

void __panicHandler(Karm::PanicKind kind, char const *msg);

extern "C" int wasm_export(wasm_main)(void) {
Abi::Wasm::init();
Karm::registerPanicHandler(__panicHandler);
auto &ctx = Sys::globalCtx();
Res<> code = entryPoint(ctx);

char const *self = "wasm-app";
char const *argv[] = {self, nullptr};
Sys::globalCtx().add<Sys::ArgsHook>(1, argv);
Res<> code = entryPoint(Sys::globalCtx());

if (not code) {
Karm::Sys::errln("{}", code);
Expand Down
6 changes: 6 additions & 0 deletions src/impls/impl-wasm/externs.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
#pragma once

#include <karm-base/size.h>
#include <karm-base/std.h>

static constexpr usize PAGE_SIZE = kib(64);

#define wasm_import(name) __attribute__((import_module("env"), import_name(#name))) name
#define wasm_export(name) __attribute__((visibility("default"), export_name(#name))) name

extern "C" ExternSym __heap_base;
extern "C" ExternSym __heap_end;

extern "C" u64 wasm_import(embedGetTimeStamp)();
extern "C" void wasm_import(embedConsoleLog)(u8 const *str, usize len);
extern "C" void wasm_import(embedConsoleError)(u8 const *str, usize len);
Expand Down
6 changes: 2 additions & 4 deletions src/impls/impl-wasm/init.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
#include <karm-base/std.h>

extern "C" void __wasm_call_ctors();

extern "C" void __wasm_call_ctors();

namespace Abi::Wasm {

__attribute__((export_name("_initialize")))
void init() {
__attribute__((export_name("_initialize"))) void init() {
__wasm_call_ctors();
}

Expand Down
64 changes: 35 additions & 29 deletions src/impls/impl-wasm/new-delete.cpp
Original file line number Diff line number Diff line change
@@ -1,57 +1,63 @@
#include <ce-heap/libheap.h>
#include <karm-base/bits.h>
#include <karm-base/lock.h>
#include <karm-logger/logger.h>

#include "externs.h"
#include "karm-base/align.h"

// MARK: WASM Implementation ---------------------------------------------------


static Lock _heapLock;
static Heap _heapImpl = {
.ctx = nullptr,
.alloc = [](void *, usize size) -> void * {
return embedAlloc(size);
},
.free = [](void *, void *, usize) {
// Yeet
},
.log = [](void *, enum HeapLogType type, char const *msg, va_list) {
if (type == HEAP_ERROR)
logError("heap: {}", msg);
},
.root = nullptr,
.best = nullptr,
};
static Heap *_ensureHeap() {
static Bits _heapBase = [] {
Bits bits(MutBytes{__heap_base, (usize)__heap_end - (usize)__heap_base});
bits.fill(false);
return bits;
}();
static Heap _heapImpl = {
.ctx = nullptr,
.alloc = [](void *, usize size) -> void * {
size = alignUp(size, PAGE_SIZE);
auto range = _heapBase.alloc(size / PAGE_SIZE, 0, false);
return (void *)(range.unwrap("out-of-memory").start * PAGE_SIZE);
},
.free = [](void *, void *ptr, usize size) {
size = alignUp(size, PAGE_SIZE);
_heapBase.set(BitsRange{(usize)ptr / PAGE_SIZE, size / PAGE_SIZE}, false);
},
.log = [](void *, enum HeapLogType type, char const *msg, va_list) {
if (type == HEAP_ERROR)
logError("heap: {}", msg);
},
.root = nullptr,
.best = nullptr,
};

return &_heapImpl;
}

// MARK: New/Delete Implementation ---------------------------------------------

void *operator new(usize size) {
LockScope scope(_heapLock);
return heap_calloc(&_heapImpl, size, 2);
return heap_calloc(_ensureHeap(), size, 2);
}

void *operator new[](usize size) {
LockScope scope(_heapLock);
return heap_calloc(&_heapImpl, size, 2);
return heap_calloc(_ensureHeap(), size, 2);
}

void operator delete(void *ptr) {
LockScope scope(_heapLock);
heap_free(&_heapImpl, ptr);
heap_free(_ensureHeap(), ptr);
}

void operator delete[](void *ptr) {
LockScope scope(_heapLock);
heap_free(&_heapImpl, ptr);
heap_free(_ensureHeap(), ptr);
}

void operator delete(void *ptr, usize) {
LockScope scope(_heapLock);
heap_free(&_heapImpl, ptr);
heap_free(_ensureHeap(), ptr);
}

void operator delete[](void *ptr, usize) {
LockScope scope(_heapLock);
heap_free(&_heapImpl, ptr);
heap_free(_ensureHeap(), ptr);
}
159 changes: 94 additions & 65 deletions src/impls/impl-wasm/sys.cpp
Original file line number Diff line number Diff line change
@@ -1,91 +1,120 @@
#include <karm-sys/_embed.h>
#include <karm-base/res.h>
#include <karm-base/func.h>
#include <karm-base/res.h>
#include <karm-base/time.h>

#include "externs.h"
#include <karm-sys/_embed.h>

#include "externs.h"

namespace Karm::Sys::_Embed {
struct JSConsole : public Sys::Fd {
enum Proto {
Log,
Error
} _proto;

JSConsole(Proto proto) : _proto(proto) {}

Sys::Handle handle() const override {
return Handle{(usize)0};
}
Res<usize> read(MutBytes) override {
notImplemented();
}

Res<usize> write(Bytes bytes) override {
switch (_proto) {
case Log:
embedConsoleLog(bytes._buf, bytes._len);
break;
case Error:
embedConsoleError(bytes._buf, bytes._len);
break;
}

return Ok(bytes._len);
}
struct JSConsole : public Sys::Fd {
enum Proto {
LOG,
ERROR
} _proto;

Res<usize> seek(Io::Seek) override {
notImplemented();
}

Res<usize> flush() override {
return Ok(0uz);
}
Io::BufferWriter _buf;
JSConsole(Proto proto) : _proto(proto) {}

Res<Strong<Fd>> dup() override {
notImplemented();
}
Sys::Handle handle() const override {
return Handle{(usize)_proto};
}
Res<usize> read(MutBytes) override {
notImplemented();
}

Res<_Accepted> accept() override {
notImplemented();
}
Res<usize> write(Bytes bytes) override {
return _buf.write(bytes);
}

Res<Stat> stat() override {
return Ok<Stat>();
}
Res<usize> seek(Io::Seek) override {
notImplemented();
}

Res<_Sent> send(Bytes, Slice<Handle>, SocketAddr) override {
notImplemented();
Res<usize> flush() override {
switch (_proto) {
case LOG:
embedConsoleLog(_buf.bytes().buf(), _buf.bytes().len());
break;
case ERROR:
embedConsoleError(_buf.bytes().buf(), _buf.bytes().len());
break;
}

Res<_Received> recv(MutBytes, MutSlice<Handle>) override {
notImplemented();
}
return _buf.flush();
}

Res<> pack(Io::PackEmit &) override {
notImplemented();
}
};
Res<Strong<Fd>> dup() override {
notImplemented();
}

TimeStamp now() {
auto span = embedGetTimeStamp();
return TimeStamp::epoch() + TimeSpan::fromMSecs(span);
Res<_Accepted> accept() override {
notImplemented();
}

Res<Strong<Sys::Fd>> createIn() {
return Ok(makeStrong<Sys::NullFd>());
Res<Stat> stat() override {
return Ok<Stat>();
}

Res<Strong<Sys::Fd>> createOut() {
return Ok(makeStrong<JSConsole>(JSConsole::Log));
Res<_Sent> send(Bytes, Slice<Handle>, SocketAddr) override {
notImplemented();
}

Res<Strong<Sys::Fd>> createErr() {
return Ok(makeStrong<JSConsole>(JSConsole::Error));
Res<_Received> recv(MutBytes, MutSlice<Handle>) override {
notImplemented();
}

Res<Strong<Sys::Fd>> unpackFd(Io::PackScan &) {
Res<> pack(Io::PackEmit &) override {
notImplemented();
}
};

TimeStamp now() {
auto span = embedGetTimeStamp();
return TimeStamp::epoch() + TimeSpan::fromMSecs(span);
}

Res<Strong<Sys::Fd>> createIn() {
return Ok(makeStrong<Sys::NullFd>());
}

Res<Strong<Sys::Fd>> createOut() {
return Ok(makeStrong<JSConsole>(JSConsole::LOG));
}

Res<Strong<Sys::Fd>> createErr() {
return Ok(makeStrong<JSConsole>(JSConsole::ERROR));
}

Res<Strong<Sys::Fd>> unpackFd(Io::PackScan &) {
notImplemented();
}

// MARK: System Informations ---------------------------------------------------

Res<> populate(Sys::SysInfo &) {
return Ok();
}

Res<> populate(Sys::MemInfo &mem) {
mem.physicalTotal = (usize)__heap_end - (usize)__heap_base;
mem.physicalUsed = -1;
mem.swapTotal = 0;
mem.swapUsed = 0;
mem.virtualTotal = 0;
mem.virtualUsed = 0;
return Ok();
}

Res<> populate(Vec<Sys::CpuInfo> &) {
return Ok();
}

Res<> populate(Sys::UserInfo &) {
return Ok();
}

Res<> populate(Vec<Sys::UserInfo> &) {
return Ok();
}
} // namespace Karm::Sys::_Embed
2 changes: 1 addition & 1 deletion src/kernel/hal-x86_64/cpuid.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ union Cpuid {
: "a"(leaf & 0x80000000)
: "rbx", "rcx", "rdx");

if (leaf > maxLeaf) [[unlikely]]
if (leaf > maxLeaf) [[unlikely]]
panic("cpuid leaf out of range");

Cpuid result{};
Expand Down
Loading

0 comments on commit dd8a239

Please sign in to comment.