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