Enable native WASM execution with process-owned contexts and cleanup
This commit is contained in:
1 parent
e462165049
commit
a6a55153af
6 files changed
+161
-70
No files matched your search
+10
-10
@@ -22,12 +22,12 @@ type
|
||||
THeapPageHeader = memory.heap.THeapPageHeader;
|
||||
|
||||
procedure init;
|
||||
function kalloc(size : uint32) : void;
|
||||
function klalloc(size : uint32) : void;
|
||||
procedure klfree(address : uint32);
|
||||
function kpalloc(address : uint32) : void;
|
||||
function kalloc(size : SizeUInt) : void;
|
||||
function klalloc(size : SizeUInt) : void;
|
||||
procedure klfree(address : PtrUInt);
|
||||
function kpalloc(address : PtrUInt) : void;
|
||||
procedure kfree(area : void);
|
||||
function lmm_total_free : uint32;
|
||||
function lmm_total_free : SizeUInt;
|
||||
function lmm_page_count : uint32;
|
||||
|
||||
implementation
|
||||
@@ -37,22 +37,22 @@ begin
|
||||
memory.heap.init;
|
||||
end;
|
||||
|
||||
function kalloc(size : uint32) : void; inline;
|
||||
function kalloc(size : SizeUInt) : void; inline;
|
||||
begin
|
||||
kalloc := memory.heap.kalloc(size);
|
||||
end;
|
||||
|
||||
function klalloc(size : uint32) : void; inline;
|
||||
function klalloc(size : SizeUInt) : void; inline;
|
||||
begin
|
||||
klalloc := memory.heap.klalloc(size);
|
||||
end;
|
||||
|
||||
procedure klfree(address : uint32); inline;
|
||||
procedure klfree(address : PtrUInt); inline;
|
||||
begin
|
||||
memory.heap.klfree(address);
|
||||
end;
|
||||
|
||||
function kpalloc(address : uint32) : void; inline;
|
||||
function kpalloc(address : PtrUInt) : void; inline;
|
||||
begin
|
||||
kpalloc := memory.heap.kpalloc(address);
|
||||
end;
|
||||
@@ -62,7 +62,7 @@ begin
|
||||
memory.heap.kfree(area);
|
||||
end;
|
||||
|
||||
function lmm_total_free : uint32; inline;
|
||||
function lmm_total_free : SizeUInt; inline;
|
||||
begin
|
||||
lmm_total_free := memory.heap.lmm_total_free;
|
||||
end;
|
||||
|
||||
@@ -36,6 +36,7 @@ var
|
||||
begin
|
||||
if heap = nil then exit;
|
||||
if heap^.Memory <> nil then begin
|
||||
if heap^.PageCount <> 0 then
|
||||
for i := 0 to heap^.PageCount - 1 do begin
|
||||
if heap^.Memory[i] <> nil then
|
||||
kfree(void(heap^.Memory[i]));
|
||||
@@ -73,6 +74,7 @@ var
|
||||
begin
|
||||
if tables = nil then exit;
|
||||
if tables^.Tables <> nil then begin
|
||||
if tables^.TableCount <> 0 then
|
||||
for i := 0 to tables^.TableCount - 1 do begin
|
||||
if tables^.Tables[i].Elements <> nil then
|
||||
kfree(void(tables^.Tables[i].Elements));
|
||||
@@ -90,6 +92,7 @@ var
|
||||
begin
|
||||
if ds = nil then exit;
|
||||
if ds^.Segments <> nil then begin
|
||||
if ds^.SegmentCount <> 0 then
|
||||
for i := 0 to ds^.SegmentCount - 1 do begin
|
||||
if ds^.Segments[i].Data <> nil then
|
||||
kfree(void(ds^.Segments[i].Data));
|
||||
@@ -107,6 +110,7 @@ var
|
||||
begin
|
||||
if es = nil then exit;
|
||||
if es^.Segments <> nil then begin
|
||||
if es^.SegmentCount <> 0 then
|
||||
for i := 0 to es^.SegmentCount - 1 do begin
|
||||
if es^.Segments[i].FuncIndices <> nil then
|
||||
kfree(void(es^.Segments[i].FuncIndices));
|
||||
@@ -124,6 +128,7 @@ var
|
||||
begin
|
||||
if ts = nil then exit;
|
||||
if ts^.Types <> nil then begin
|
||||
if ts^.TypeCount <> 0 then
|
||||
for i := 0 to ts^.TypeCount - 1 do begin
|
||||
if ts^.Types[i].ParamTypes <> nil then
|
||||
kfree(void(ts^.Types[i].ParamTypes));
|
||||
@@ -143,6 +148,7 @@ var
|
||||
begin
|
||||
if is_ = nil then exit;
|
||||
if is_^.Entries <> nil then begin
|
||||
if is_^.ImportCount <> 0 then
|
||||
for i := 0 to is_^.ImportCount - 1 do begin
|
||||
if is_^.Entries[i].ModuleName <> nil then
|
||||
kfree(void(is_^.Entries[i].ModuleName));
|
||||
@@ -172,6 +178,7 @@ var
|
||||
begin
|
||||
if es = nil then exit;
|
||||
if es^.Entries <> nil then begin
|
||||
if es^.ExportCount <> 0 then
|
||||
for i := 0 to es^.ExportCount - 1 do begin
|
||||
if es^.Entries[i].Name <> nil then
|
||||
kfree(void(es^.Entries[i].Name));
|
||||
@@ -189,6 +196,7 @@ var
|
||||
begin
|
||||
if cs = nil then exit;
|
||||
if cs^.Entries <> nil then begin
|
||||
if cs^.CodeCount <> 0 then
|
||||
for i := 0 to cs^.CodeCount - 1 do begin
|
||||
if cs^.Entries[i].Code <> nil then
|
||||
kfree(void(cs^.Entries[i].Code));
|
||||
|
||||
@@ -4,9 +4,7 @@
|
||||
Provides concrete WASI callback functions that route fd 0/1/2
|
||||
to the owning Asuro process's StdIn/StdOut/StdErr buffers.
|
||||
|
||||
An ActiveShim module-level variable is set before each tick batch
|
||||
and cleared after. Hooks only fire synchronously within wasm_tick
|
||||
so this is safe under preemptive scheduling.
|
||||
Hooks resolve the shim from the currently scheduled process.
|
||||
|
||||
@author(Kieron Morris <[email protected]>)
|
||||
}
|
||||
@@ -20,9 +18,7 @@ uses
|
||||
wasm.types.context,
|
||||
wasm.types.values;
|
||||
|
||||
{ Set/clear the active shim — call before/after each tick batch }
|
||||
procedure setActiveShim(shim : PProcessWASMShim);
|
||||
procedure clearActiveShim;
|
||||
|
||||
|
||||
{ WASI hook implementations — register via wasm_set_fd_write etc. }
|
||||
function asuro_fd_write(fd : TWASMUInt32; buf : TWASMPUInt8; len : TWASMUInt32) : TWASMUInt32;
|
||||
@@ -46,19 +42,13 @@ implementation
|
||||
uses
|
||||
io.stdio, proc.types,
|
||||
wasm.types.wasi, wasm.types.stack, wasm.types.heap,
|
||||
arch.x86.bda, core.rand, core.util, arch.x86.util;
|
||||
proc.mgr, arch.platform.interrupts, arch.common.legacyirq, core.rand, core.util, arch.platform.cpu;
|
||||
|
||||
var
|
||||
ActiveShimPtr : PProcessWASMShim;
|
||||
|
||||
procedure setActiveShim(shim : PProcessWASMShim);
|
||||
begin
|
||||
ActiveShimPtr := shim;
|
||||
end;
|
||||
|
||||
procedure clearActiveShim;
|
||||
function ActiveShimPtr: PProcessWASMShim;
|
||||
begin
|
||||
ActiveShimPtr := nil;
|
||||
if proc.mgr.CurrentProcess <> nil then
|
||||
ActiveShimPtr := PProcessWASMShim(proc.mgr.CurrentProcess^.Local);
|
||||
end;
|
||||
|
||||
{ ---- fd_write: fd 1 = stdout, fd 2 = stderr ---- }
|
||||
@@ -81,7 +71,7 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
if outbuf = nil then exit;
|
||||
if (outbuf = nil) or (len = 0) then exit;
|
||||
|
||||
{ Write byte-by-byte into the POutBuf }
|
||||
for i := 0 to len - 1 do
|
||||
@@ -111,7 +101,7 @@ begin
|
||||
avail := inbuf^.len;
|
||||
if avail = 0 then exit;
|
||||
if len < avail then copyLen := len else copyLen := avail;
|
||||
memcpy(uint32(inbuf^.buf), uint32(buf), copyLen);
|
||||
memcpy(PtrUInt(inbuf^.buf), PtrUInt(buf), copyLen);
|
||||
asuro_fd_read := copyLen;
|
||||
end;
|
||||
|
||||
@@ -126,13 +116,16 @@ begin
|
||||
ActiveShimPtr^.ProcessCtx^.ExitCode := code;
|
||||
end;
|
||||
|
||||
{ ---- clock_time_get: use BIOS tick counter ---- }
|
||||
{ ---- Monotonic time from the platform timer ---- }
|
||||
|
||||
function asuro_clock_time_get(clock_id : TWASMUInt32; precision : TWASMUInt64;
|
||||
var time : TWASMUInt64) : TWASMUInt32;
|
||||
var
|
||||
ticks: uint64;
|
||||
begin
|
||||
{ Return time in nanoseconds based on BIOS 1024 Hz counter }
|
||||
time := TWASMUInt64(arch.x86.bda.Counters.c64) * 976562;
|
||||
ticks := arch.platform.interrupts.timerTicks;
|
||||
time := (ticks div PIT_INPUT_HZ) * PIT_DIVISOR * 1000000000 +
|
||||
((ticks mod PIT_INPUT_HZ) * PIT_DIVISOR * 1000000000) div PIT_INPUT_HZ;
|
||||
asuro_clock_time_get := WASI_ESUCCESS;
|
||||
end;
|
||||
|
||||
@@ -141,7 +134,7 @@ end;
|
||||
function asuro_clock_res_get(clock_id : TWASMUInt32;
|
||||
var resolution : TWASMUInt64) : TWASMUInt32;
|
||||
begin
|
||||
resolution := 976562; { ~0.977ms in nanoseconds (1/1024 s) }
|
||||
resolution := (uint64(PIT_DIVISOR) * 1000000000 + PIT_INPUT_HZ - 1) div PIT_INPUT_HZ;
|
||||
asuro_clock_res_get := WASI_ESUCCESS;
|
||||
end;
|
||||
|
||||
|
||||
@@ -2,8 +2,7 @@ unit app.wasm;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
boot.mgr;
|
||||
procedure init;
|
||||
|
||||
implementation
|
||||
|
||||
@@ -12,14 +11,15 @@ uses
|
||||
wasm.vm.io,
|
||||
wasm;
|
||||
|
||||
procedure init();
|
||||
var
|
||||
initialized: boolean = false;
|
||||
|
||||
procedure init;
|
||||
begin
|
||||
{ Let's test Wasuro! }
|
||||
if initialized then exit;
|
||||
wasm.vm.io.io_set_writechar(@io.syslog.logchar);
|
||||
wasm.wasm_init;
|
||||
initialized := true;
|
||||
end;
|
||||
|
||||
initialization
|
||||
boot.mgr.registerBoot('app.wasm', @init, 'Initialize WASM VM Backend', BOOT_MGR_BARRIER_FINAL)
|
||||
|
||||
end.
|
||||
File diff suppressed because it is too large.
Load diff
@@ -36,7 +36,7 @@ procedure init;
|
||||
implementation
|
||||
|
||||
uses
|
||||
core.strings, memory.heap, core.ds.lists, core.util, arch.x86.util;
|
||||
core.strings, memory.heap, core.ds.lists, core.util, arch.platform.cpu;
|
||||
|
||||
const
|
||||
MAX_RAM_FILES = 32;
|
||||
@@ -53,6 +53,7 @@ var
|
||||
Files : array[0..MAX_RAM_FILES-1] of TRAMFile;
|
||||
FileCount : uint32;
|
||||
RAMVolume : TStorage_Volume;
|
||||
RAMDevice : PStorage_Device;
|
||||
RAMFS : TFilesystem;
|
||||
|
||||
{ ---- Internal helpers ---- }
|
||||
@@ -75,7 +76,7 @@ end;
|
||||
function stripLeadingSlash(path : pchar) : pchar;
|
||||
begin
|
||||
if (path <> nil) and (path[0] = '/') then
|
||||
stripLeadingSlash := pchar(uint32(path) + 1)
|
||||
stripLeadingSlash := pchar(PtrUInt(path) + 1)
|
||||
else
|
||||
stripLeadingSlash := path;
|
||||
end;
|
||||
@@ -103,7 +104,7 @@ begin
|
||||
|
||||
avail := Files[idx].Size - offset;
|
||||
if byteCount < avail then copyLen := byteCount else copyLen := avail;
|
||||
memcpy(uint32(Files[idx].Data) + offset, uint32(buffer), copyLen);
|
||||
memcpy(PtrUInt(Files[idx].Data) + offset, PtrUInt(buffer), copyLen);
|
||||
rd_ReadOffset := copyLen;
|
||||
end;
|
||||
|
||||
@@ -193,8 +194,9 @@ begin
|
||||
if (data = nil) or (size = 0) then exit;
|
||||
buf := puint8(kalloc(size));
|
||||
if buf = nil then exit;
|
||||
memcpy(uint32(data), uint32(buf), size);
|
||||
memcpy(PtrUInt(data), PtrUInt(buf), size);
|
||||
storeFileCopy := storeFile(name, buf, size);
|
||||
if not storeFileCopy then kfree(void(buf));
|
||||
end;
|
||||
|
||||
procedure removeFile(name : pchar; freeBuf : boolean);
|
||||
@@ -255,7 +257,7 @@ begin
|
||||
FileCount := 0;
|
||||
|
||||
{ Set up a minimal filesystem descriptor with our callbacks }
|
||||
memset(uint32(@RAMFS), 0, sizeof(TFilesystem));
|
||||
memset(PtrUInt(@RAMFS), 0, sizeof(TFilesystem));
|
||||
RAMFS.sName := 'ramfs';
|
||||
RAMFS.readDirCallback := @rd_ReadDir;
|
||||
RAMFS.readOffsetCallback := @rd_ReadOffset;
|
||||
@@ -263,8 +265,14 @@ begin
|
||||
RAMFS.identifyCallback := @rd_Identify;
|
||||
|
||||
{ Set up a virtual volume backed by our filesystem }
|
||||
memset(uint32(@RAMVolume), 0, sizeof(TStorage_Volume));
|
||||
memset(PtrUInt(@RAMVolume), 0, sizeof(TStorage_Volume));
|
||||
RAMVolume.filesystem := @RAMFS;
|
||||
RAMDevice := PStorage_Device(kalloc(sizeof(TStorage_Device)));
|
||||
if RAMDevice = nil then exit;
|
||||
RAMDevice^.controller := ControllerRAM;
|
||||
RAMDevice^.sectorSize := 512;
|
||||
RAMVolume.device := RAMDevice;
|
||||
RAMVolume.sectorSize := 512;
|
||||
|
||||
{ Mount into VFS at /disk/ram }
|
||||
driver.storage.vfs.mountVolume('/disk/ram', @RAMVolume);
|
||||
|
||||
Reference in new issue
Block a user