refactor: replace emu/console.pas with hookable wasm.vm.io abstraction #1

Merged
t3hn3rd merged 1 commits from feature/compatability into develop 2026-03-03 21:32:30 +00:00
81 changed files with 606 additions and 388 deletions
Showing only changes of commit 5bb7107997 - Show all commits

No files matched your search

-161
View File
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -36,7 +36,7 @@ type
sInt8 = shortint; sInt8 = shortint;
sInt16 = smallint; sInt16 = smallint;
sInt32 = integer; sInt32 = integer;
sInt64 = longint; sInt64 = int64;
Float = Single; Float = Single;
+15 -6
View File
@@ -2,7 +2,7 @@ program WASURO;
uses uses
sysutils, sysutils,
console, wasm.vm.io,
wasm.types.builtin, wasm.types.builtin,
wasm.types.context, wasm.types.context,
wasm, wasm,
@@ -16,6 +16,12 @@ uses
{$ENDIF} {$ENDIF}
; ;
{ Emu-layer writechar hook — forwards to RTL Write for host OS output }
procedure emu_writechar(ch : TWASMChar);
begin
Write(ch);
end;
var var
Context : PWASMProcessContext; Context : PWASMProcessContext;
ModuleSize : Int64; ModuleSize : Int64;
@@ -23,19 +29,22 @@ var
ModuleFile : File; ModuleFile : File;
begin begin
{ Wire up the IO subsystem before anything else }
wasm.vm.io.io_set_writechar(@emu_writechar);
{$IFDEF RUN_TESTS} {$IFDEF RUN_TESTS}
wasm.wasm_init; wasm.wasm_init;
wasm.test.run_all_tests; wasm.test.run_all_tests;
halt(wasm.test.framework.FailedTests); halt(wasm.test.framework.FailedTests);
{$ELSE} {$ELSE}
{$IFDEF DEBUG_OUTPUT} {$IFDEF DEBUG_OUTPUT}
console.writestringln('WASURO - WebAssembly Runtime in Object Pascal'); wasm.vm.io.writestringln('WASURO - WebAssembly Runtime in Object Pascal');
{$ENDIF} {$ENDIF}
wasm.wasm_init; wasm.wasm_init;
if ParamCount > 0 then begin if ParamCount > 0 then begin
if not FileExists(ParamStr(1)) then begin if not FileExists(ParamStr(1)) then begin
console.writestringln('File not found.'); wasm.vm.io.writestringln('File not found.');
halt(1); halt(1);
end; end;
Assign(ModuleFile, ParamStr(1)); Assign(ModuleFile, ParamStr(1));
@@ -53,7 +62,7 @@ begin
Context := wasm.wasm_load(ModuleBuffer, TWASMPUInt8(ModuleBuffer + ModuleSize)); Context := wasm.wasm_load(ModuleBuffer, TWASMPUInt8(ModuleBuffer + ModuleSize));
if not Context^.ValidBinary then begin if not Context^.ValidBinary then begin
console.writestringln('Error: Invalid WASM binary.'); wasm.vm.io.writestringln('Error: Invalid WASM binary.');
halt(1); halt(1);
end; end;
@@ -63,7 +72,7 @@ begin
{ Find _start and run to completion } { Find _start and run to completion }
if not wasm.wasm_start(Context) then begin if not wasm.wasm_start(Context) then begin
console.writestringln('No _start export found.'); wasm.vm.io.writestringln('No _start export found.');
halt(1); halt(1);
end; end;
@@ -74,7 +83,7 @@ begin
FreeMem(ModuleBuffer); FreeMem(ModuleBuffer);
halt(Context^.ExitCode); halt(Context^.ExitCode);
end else begin end else begin
console.writestringln('Usage: WASURO <module.wasm>'); wasm.vm.io.writestringln('Usage: WASURO <module.wasm>');
halt(1); halt(1);
end; end;
{$ENDIF} {$ENDIF}
@@ -3,7 +3,7 @@ unit wasm.parser.sections.codeSection;
interface interface
uses uses
wasm.types.builtin, lmemorymanager, console, wasm.types.leb128, wasm.types.builtin, lmemorymanager, wasm.vm.io, wasm.types.leb128,
wasm.types.enums, wasm.types.values, wasm.types.sections, wasm.types.context; wasm.types.enums, wasm.types.values, wasm.types.sections, wasm.types.context;
procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext); procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext);
@@ -73,8 +73,8 @@ var
begin begin
{$IFDEF DEBUG_OUTPUT} {$IFDEF DEBUG_OUTPUT}
console.writestring('[wasm.parser] Handle Section: Code - Size: '); wasm.vm.io.writestring('[wasm.parser] Handle Section: Code - Size: ');
console.writeintlnWND(section_length, 0); wasm.vm.io.writeintlnWND(section_length, 0);
{$ENDIF} {$ENDIF}
// Initialize the read/end pointers // Initialize the read/end pointers
@@ -3,7 +3,7 @@ unit wasm.parser.sections.customSection;
interface interface
uses uses
wasm.types.builtin, lmemorymanager, console, wasm.types.leb128, wasm.types.builtin, lmemorymanager, wasm.vm.io, wasm.types.leb128,
wasm.types.context; wasm.types.context;
procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext); procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext);
@@ -13,11 +13,11 @@ implementation
procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext); procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext);
begin begin
{$IFDEF DEBUG_OUTPUT} {$IFDEF DEBUG_OUTPUT}
console.writestring('[wasm.parser] Handle Section: Custom - Size: '); wasm.vm.io.writestring('[wasm.parser] Handle Section: Custom - Size: ');
console.writeintlnWND(section_length, 0); wasm.vm.io.writeintlnWND(section_length, 0);
{$ENDIF} {$ENDIF}
{ Custom sections are ignored in this implementation } { Custom sections are ignored in this implementation }
console.writestringln('[wasm.parser] TODO: Custom section skipped.'); wasm.vm.io.writestringln('[wasm.parser] TODO: Custom section skipped.');
end; end;
end. end.
@@ -9,7 +9,7 @@ procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMPro
implementation implementation
uses console, wasm.types.leb128, lmemorymanager, wasm.types.sections; uses wasm.vm.io, wasm.types.leb128, lmemorymanager, wasm.types.sections;
{ DataCount section (ID 12): contains a single u32 count of data segments. { DataCount section (ID 12): contains a single u32 count of data segments.
Pre-allocates the DataSegments array so that bulk memory opcodes Pre-allocates the DataSegments array so that bulk memory opcodes
@@ -21,8 +21,8 @@ var
dataCount : TWASMUInt32; dataCount : TWASMUInt32;
begin begin
{$IFDEF DEBUG_OUTPUT} {$IFDEF DEBUG_OUTPUT}
console.writestring('[wasm.parser] Handle Section: DataCount - Size: '); wasm.vm.io.writestring('[wasm.parser] Handle Section: DataCount - Size: ');
console.writeintlnWND(section_length, 0); wasm.vm.io.writeintlnWND(section_length, 0);
{$ENDIF} {$ENDIF}
pos := buffer; pos := buffer;
@@ -3,7 +3,7 @@ unit wasm.parser.sections.dataSection;
interface interface
uses uses
wasm.types.builtin, lmemorymanager, console, wasm.types.leb128, wasm.types.builtin, lmemorymanager, wasm.vm.io, wasm.types.leb128,
wasm.types.sections, wasm.types.context, wasm.types.heap; wasm.types.sections, wasm.types.context, wasm.types.heap;
procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext); procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext);
@@ -26,8 +26,8 @@ var
begin begin
{$IFDEF DEBUG_OUTPUT} {$IFDEF DEBUG_OUTPUT}
console.writestring('[wasm.parser] Handle Section: Data - Size: '); wasm.vm.io.writestring('[wasm.parser] Handle Section: Data - Size: ');
console.writeintlnWND(section_length, 0); wasm.vm.io.writeintlnWND(section_length, 0);
{$ENDIF} {$ENDIF}
pos := buffer; pos := buffer;
@@ -3,7 +3,7 @@ unit wasm.parser.sections.elementSection;
interface interface
uses uses
wasm.types.builtin, lmemorymanager, console, wasm.types.leb128, wasm.types.builtin, lmemorymanager, wasm.vm.io, wasm.types.leb128,
wasm.types.sections, wasm.types.context; wasm.types.sections, wasm.types.context;
procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext); procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext);
@@ -24,8 +24,8 @@ var
indices: TWASMPUInt32; indices: TWASMPUInt32;
begin begin
{$IFDEF DEBUG_OUTPUT} {$IFDEF DEBUG_OUTPUT}
console.writestring('[wasm.parser] Handle Section: Element - Size: '); wasm.vm.io.writestring('[wasm.parser] Handle Section: Element - Size: ');
console.writeintlnWND(section_length, 0); wasm.vm.io.writeintlnWND(section_length, 0);
{$ENDIF} {$ENDIF}
pos := buffer; pos := buffer;
@@ -3,7 +3,7 @@ unit wasm.parser.sections.exportSection;
interface interface
uses uses
wasm.types.builtin, lmemorymanager, console, wasm.types.leb128, wasm.types.builtin, lmemorymanager, wasm.vm.io, wasm.types.leb128,
wasm.types.enums, wasm.types.sections, wasm.types.context; wasm.types.enums, wasm.types.sections, wasm.types.context;
procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext); procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext);
@@ -37,8 +37,8 @@ var
begin begin
{$IFDEF DEBUG_OUTPUT} {$IFDEF DEBUG_OUTPUT}
console.writestring('[wasm.parser] Handle Section: Export - Size: '); wasm.vm.io.writestring('[wasm.parser] Handle Section: Export - Size: ');
console.writeintlnWND(section_length, 0); wasm.vm.io.writeintlnWND(section_length, 0);
{$ENDIF} {$ENDIF}
// Initialize the read/end pointers // Initialize the read/end pointers
@@ -3,7 +3,7 @@ unit wasm.parser.sections.functionSection;
interface interface
uses uses
wasm.types.builtin, lmemorymanager, console, wasm.types.leb128, wasm.types.builtin, lmemorymanager, wasm.vm.io, wasm.types.leb128,
wasm.types.sections, wasm.types.context; wasm.types.sections, wasm.types.context;
procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext); procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext);
@@ -33,8 +33,8 @@ var
begin begin
{$IFDEF DEBUG_OUTPUT} {$IFDEF DEBUG_OUTPUT}
console.writestring('[wasm.parser] Handle Section: Function - Size: '); wasm.vm.io.writestring('[wasm.parser] Handle Section: Function - Size: ');
console.writeintlnWND(section_length, 0); wasm.vm.io.writeintlnWND(section_length, 0);
{$ENDIF} {$ENDIF}
// Initialize the read/end pointers // Initialize the read/end pointers
@@ -3,7 +3,7 @@ unit wasm.parser.sections.globalSection;
interface interface
uses uses
wasm.types.builtin, lmemorymanager, console, wasm.types.leb128, wasm.types.builtin, lmemorymanager, wasm.vm.io, wasm.types.leb128,
wasm.types.enums, wasm.types.sections, wasm.types.context; wasm.types.enums, wasm.types.sections, wasm.types.context;
procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext); procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext);
@@ -50,8 +50,8 @@ var
begin begin
{$IFDEF DEBUG_OUTPUT} {$IFDEF DEBUG_OUTPUT}
console.writestring('[wasm.parser] Handle Section: Global - Size: '); wasm.vm.io.writestring('[wasm.parser] Handle Section: Global - Size: ');
console.writeintlnWND(section_length, 0); wasm.vm.io.writeintlnWND(section_length, 0);
{$ENDIF} {$ENDIF}
pos := buffer; pos := buffer;
@@ -3,7 +3,7 @@ unit wasm.parser.sections.importSection;
interface interface
uses uses
wasm.types.builtin, lmemorymanager, console, wasm.types.leb128, wasm.types.builtin, lmemorymanager, wasm.vm.io, wasm.types.leb128,
wasm.types.enums, wasm.types.sections, wasm.types.context; wasm.types.enums, wasm.types.sections, wasm.types.context;
procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext); procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext);
@@ -72,8 +72,8 @@ var
limitsFlag : TWASMUInt8; limitsFlag : TWASMUInt8;
begin begin
{$IFDEF DEBUG_OUTPUT} {$IFDEF DEBUG_OUTPUT}
console.writestring('[wasm.parser] Handle Section: Import - Size: '); wasm.vm.io.writestring('[wasm.parser] Handle Section: Import - Size: ');
console.writeintlnWND(section_length, 0); wasm.vm.io.writeintlnWND(section_length, 0);
{$ENDIF} {$ENDIF}
pos := buffer; pos := buffer;
@@ -3,7 +3,7 @@ unit wasm.parser.sections.memorySection;
interface interface
uses uses
wasm.types.builtin, lmemorymanager, console, wasm.types.leb128, wasm.types.builtin, lmemorymanager, wasm.vm.io, wasm.types.leb128,
wasm.types.sections, wasm.types.context, wasm.types.heap; wasm.types.sections, wasm.types.context, wasm.types.heap;
procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext); procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext);
@@ -40,8 +40,8 @@ var
begin begin
{$IFDEF DEBUG_OUTPUT} {$IFDEF DEBUG_OUTPUT}
console.writestring('[wasm.parser] Handle Section: Memory - Size: '); wasm.vm.io.writestring('[wasm.parser] Handle Section: Memory - Size: ');
console.writeintlnWND(section_length, 0); wasm.vm.io.writeintlnWND(section_length, 0);
{$ENDIF} {$ENDIF}
pos := buffer; pos := buffer;
@@ -3,7 +3,7 @@ unit wasm.parser.sections.startSection;
interface interface
uses uses
wasm.types.builtin, lmemorymanager, console, wasm.types.leb128, wasm.types.builtin, lmemorymanager, wasm.vm.io, wasm.types.leb128,
wasm.types.context; wasm.types.context;
procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext); procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext);
@@ -17,8 +17,8 @@ var
begin begin
{$IFDEF DEBUG_OUTPUT} {$IFDEF DEBUG_OUTPUT}
console.writestring('[wasm.parser] Handle Section: Start - Size: '); wasm.vm.io.writestring('[wasm.parser] Handle Section: Start - Size: ');
console.writeintlnWND(section_length, 0); wasm.vm.io.writeintlnWND(section_length, 0);
{$ENDIF} {$ENDIF}
{ Read the start function index } { Read the start function index }
@@ -26,8 +26,8 @@ begin
ctx^.Sections.StartIndex := TWASMInt32(funcIdx); ctx^.Sections.StartIndex := TWASMInt32(funcIdx);
{$IFDEF DEBUG_OUTPUT} {$IFDEF DEBUG_OUTPUT}
console.writestring('[wasm.parser] Start Function Index: '); wasm.vm.io.writestring('[wasm.parser] Start Function Index: ');
console.writeintlnWND(funcIdx, 0); wasm.vm.io.writeintlnWND(funcIdx, 0);
{$ENDIF} {$ENDIF}
end; end;
@@ -3,7 +3,7 @@ unit wasm.parser.sections.tableSection;
interface interface
uses uses
wasm.types.builtin, lmemorymanager, console, wasm.types.leb128, wasm.types.builtin, lmemorymanager, wasm.vm.io, wasm.types.leb128,
wasm.types.sections, wasm.types.context; wasm.types.sections, wasm.types.context;
procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext); procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext);
@@ -20,8 +20,8 @@ var
tables: PWASMTables; tables: PWASMTables;
begin begin
{$IFDEF DEBUG_OUTPUT} {$IFDEF DEBUG_OUTPUT}
console.writestring('[wasm.parser] Handle Section: Table - Size: '); wasm.vm.io.writestring('[wasm.parser] Handle Section: Table - Size: ');
console.writeintlnWND(section_length, 0); wasm.vm.io.writeintlnWND(section_length, 0);
{$ENDIF} {$ENDIF}
pos := buffer; pos := buffer;
@@ -60,17 +60,17 @@ begin
end; end;
{$IFDEF DEBUG_OUTPUT} {$IFDEF DEBUG_OUTPUT}
console.writestring('[wasm.parser] Table '); wasm.vm.io.writestring('[wasm.parser] Table ');
console.writeintWND(i, 0); wasm.vm.io.writeintWND(i, 0);
console.writestring(' - ElemType: $'); wasm.vm.io.writestring(' - ElemType: $');
console.writeintWND(elem_type, 0); wasm.vm.io.writeintWND(elem_type, 0);
console.writestring(' Initial: '); wasm.vm.io.writestring(' Initial: ');
console.writeintWND(min_size, 0); wasm.vm.io.writeintWND(min_size, 0);
if limits_flag = 1 then begin if limits_flag = 1 then begin
console.writestring(' Max: '); wasm.vm.io.writestring(' Max: ');
console.writeintWND(max_size, 0); wasm.vm.io.writeintWND(max_size, 0);
end; end;
console.writestringln(''); wasm.vm.io.writestringln('');
{$ENDIF} {$ENDIF}
tables^.Tables[i].ElementType := elem_type; tables^.Tables[i].ElementType := elem_type;
@@ -3,7 +3,7 @@ unit wasm.parser.sections.typeSection;
interface interface
uses uses
wasm.types.builtin, lmemorymanager, console, wasm.types.leb128, wasm.types.builtin, lmemorymanager, wasm.vm.io, wasm.types.leb128,
wasm.types.enums, wasm.types.values, wasm.types.sections, wasm.types.context; wasm.types.enums, wasm.types.values, wasm.types.sections, wasm.types.context;
procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext); procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext);
@@ -61,8 +61,8 @@ var
begin begin
{$IFDEF DEBUG_OUTPUT} {$IFDEF DEBUG_OUTPUT}
console.writestring('[wasm.parser] Handle Section: Type - Size: '); wasm.vm.io.writestring('[wasm.parser] Handle Section: Type - Size: ');
console.writeintlnWND(section_length, 0); wasm.vm.io.writeintlnWND(section_length, 0);
{$ENDIF} {$ENDIF}
pos:= buffer; pos:= buffer;
+5 -5
View File
@@ -3,7 +3,7 @@ unit wasm.parser;
interface interface
uses uses
wasm.types.builtin, lmemorymanager, console, wasm.types.leb128, wasm.types.builtin, lmemorymanager, wasm.vm.io, wasm.types.leb128,
wasm.types.enums, wasm.types.sections, wasm.types.context, wasm.types.heap, wasm.types.stack, wasm.types.enums, wasm.types.sections, wasm.types.context, wasm.types.heap, wasm.types.stack,
wasm.parser.sections, wasm.types.constants; wasm.parser.sections, wasm.types.constants;
@@ -104,13 +104,13 @@ begin
pos:= buffer; pos:= buffer;
{$IFDEF DEBUG_OUTPUT} {$IFDEF DEBUG_OUTPUT}
console.writestringln('[wasm.parser] Starting parse of WASM binary.'); wasm.vm.io.writestringln('[wasm.parser] Starting parse of WASM binary.');
{$ENDIF} {$ENDIF}
// Check for the WASM Magic // Check for the WASM Magic
if(TWASMPUInt32(pos)^ = wasm.types.constants.WASM_HDR_MAGIC) then begin if(TWASMPUInt32(pos)^ = wasm.types.constants.WASM_HDR_MAGIC) then begin
{$IFDEF DEBUG_OUTPUT} {$IFDEF DEBUG_OUTPUT}
console.writestringln('[wasm.parser] Binary is valid.'); wasm.vm.io.writestringln('[wasm.parser] Binary is valid.');
{$ENDIF} {$ENDIF}
// Set binary to valid // Set binary to valid
@@ -121,8 +121,8 @@ begin
ctx^.Version:= TWASMPUInt32(pos)^; ctx^.Version:= TWASMPUInt32(pos)^;
inc(pos, 4); inc(pos, 4);
{$IFDEF DEBUG_OUTPUT} {$IFDEF DEBUG_OUTPUT}
console.writestring('[wasm.parser] Version: '); wasm.vm.io.writestring('[wasm.parser] Version: ');
console.writeintlnWND(ctx^.Version, 0); wasm.vm.io.writeintlnWND(ctx^.Version, 0);
{$ENDIF} {$ENDIF}
// Read the sections // Read the sections
+1 -1
View File
@@ -11,7 +11,7 @@ function validate_module(ctx : PWASMProcessContext; var errorMsg : TWASMPChar) :
implementation implementation
uses console; uses wasm.vm.io;
function validate_module(ctx : PWASMProcessContext; var errorMsg : TWASMPChar) : TWASMBoolean; function validate_module(ctx : PWASMProcessContext; var errorMsg : TWASMPChar) : TWASMBoolean;
var i : TWASMUInt32; var i : TWASMUInt32;
@@ -18,7 +18,7 @@ procedure run;
implementation implementation
uses uses
wasm.types.builtin, console, wasm.types.context, wasm.types.stack, wasm.types.builtin, wasm.vm.io, wasm.types.context, wasm.types.stack,
wasm.parser, wasm.vm, wasm.test.framework; wasm.parser, wasm.vm, wasm.test.framework;
const const
@@ -20,7 +20,7 @@ procedure run;
implementation implementation
uses uses
wasm.types.builtin, console, wasm.types.context, wasm.types.stack, wasm.types.builtin, wasm.vm.io, wasm.types.context, wasm.types.stack,
wasm.parser, wasm.vm, wasm.test.framework; wasm.parser, wasm.vm, wasm.test.framework;
const const
Loaded 20 of 81 files, more files were not shown because too many files have changed in this diff. Show more