Compare commits

..
Author SHA1 Message Date
t3hn3rd ff65a0d5f0 refactor: build.bat flexible argument parsing, add run & help commands
- Replaced positional `%1` checks with a loop-based argument parser
  so flags (`test`, `clean`, `run`, `help`) work in any order/combination
- Added `run` flag: executes `bin\WASURO.exe` after a successful build
- Added `help` flag: prints usage info and exits
- Fixed `clean` early-exit to also check `DO_RUN` (not just `TESTFLAGS`),
  so `build.bat clean run` correctly continues to build+run
- Added section comment headers (Build, Run) for consistency
2026-02-24 14:57:30 +00:00
t3hn3rd 76d7d737c0 Merge branch 'feature/missing-opcodes' into develop 2026-02-24 14:47:01 +00:00
t3hn3rd d12ad11746 feature: implement control flow opcodes, extract constants & helpers
## Control Flow Opcodes
- Implemented all 10 remaining stub control flow opcodes:
  block, loop, if, else, end, br, br_if, br_table, call, call_indirect
- Rewrote return opcode to walk control stack and restore call frames
- Fixed tick() hang: now halts when IP >= Limit

## Refactoring
- Extracted WASM_HDR_MAGIC and CTRL_FRAME_* constants to wasm.types.constants.pas
- Extracted push_control_frame, scan_forward, do_branch helpers to wasm.vm.control.pas
- Updated wasm.parser.pas to reference constants via wasm.types.constants

## Tests
- Added 9 new test units (25 tests):
  block, loop, if, end, br, br_if, br_table, call, call_indirect
- Added E2E binary test: 115-byte handcrafted WASM binary exercising
  all control flow opcodes (2 functions, expected result=30)
- All 425/425 tests passing
2026-02-24 14:46:30 +00:00
t3hn3rd 679973c6e9 Merge branch 'feature/type-refactoring' into develop 2026-02-24 13:24:15 +00:00
t3hn3rd 68df3565cb feature: types refactored from one monolithic file to seperation of duties
- wasm.types.context.pas
- wasm.types.enums.pas
- wasm.types.sections.pas
- wasm.types.values.pas
2026-02-24 13:23:46 +00:00
t3hn3rd 862e3254df Merge branch 'hotfix/binary-test-builtins' into develop 2026-02-24 13:05:42 +00:00
t3hn3rd 6794c52a77 patch: binary-test patched to use builtin types 2026-02-24 13:05:33 +00:00
t3hn3rd 7cc4459dfd Merge branch 'feature/builtin-types' into develop 2026-02-24 13:04:25 +00:00
t3hn3rd ae344e7495 Merge branch 'feature/binary-tests' into develop 2026-02-24 13:04:20 +00:00
t3hn3rd 430ebcd203 feature: added built-in types as a OS/RTL->VM decoupling mechanism
- Added src/wasm/types/wasm.types.builtin.pas as a decoupling unit.
- Updated all units to only use these types.
- Added linter step (lint.ps1) to enforce usage of these types.
2026-02-24 13:03:27 +00:00
165 changed files with 2785 additions and 1196 deletions

No files matched your search

+38
View File
@@ -8,11 +8,43 @@ set LIB=%ROOT%lib
set FPC=C:\Lazarus\fpc\3.2.2\bin\x86_64-win64\fpc.exe set FPC=C:\Lazarus\fpc\3.2.2\bin\x86_64-win64\fpc.exe
set TESTFLAGS= set TESTFLAGS=
set DO_CLEAN=0
set DO_RUN=0
:parse_args
if "%1"=="" goto args_done
if "%1"=="test" set TESTFLAGS=-dRUN_TESTS if "%1"=="test" set TESTFLAGS=-dRUN_TESTS
if "%1"=="clean" set DO_CLEAN=1
if "%1"=="run" set DO_RUN=1
if "%1"=="help" (
echo Usage: build.bat [options]
echo Options:
echo test - Build with tests enabled
echo clean - Clean build outputs
echo run - Run the built executable after building
echo help - Show this help message
exit /b 0
)
shift
goto parse_args
:args_done
if %DO_CLEAN%==1 (
echo Cleaning build outputs...
if exist "%BIN%" rd /s /q "%BIN%"
if exist "%LIB%" rd /s /q "%LIB%"
echo Clean complete.
if "%TESTFLAGS%"=="" if %DO_RUN%==0 exit /b 0
)
if not exist "%BIN%" mkdir "%BIN%" if not exist "%BIN%" mkdir "%BIN%"
if not exist "%LIB%" mkdir "%LIB%" if not exist "%LIB%" mkdir "%LIB%"
REM ── Lint ────────────────────────────────────────────────────────────
powershell -NoProfile -ExecutionPolicy Bypass -File "%ROOT%lint.ps1" -SrcRoot "%SRC%"
if %ERRORLEVEL% NEQ 0 exit /b 1
REM ── Build ────────────────────────────────────────────────────────────
"%FPC%" ^ "%FPC%" ^
%TESTFLAGS% ^ %TESTFLAGS% ^
-FE"%BIN%" ^ -FE"%BIN%" ^
@@ -38,3 +70,9 @@ if %ERRORLEVEL% NEQ 0 (
) )
echo Build succeeded: %BIN%\WASURO.exe echo Build succeeded: %BIN%\WASURO.exe
REM ── Run ────────────────────────────────────────────────────────────
if %DO_RUN%==1 (
echo Running WASURO...
"%BIN%\WASURO.exe"
)
+48
View File
@@ -0,0 +1,48 @@
# lint.ps1 — Static lint rules for the WASURO project
# Called by build.bat before compilation. Exit 1 on any violation.
param(
[string]$SrcRoot = (Join-Path $PSScriptRoot 'src')
)
$fail = $false
# ── Rule: No native types in src\wasm ────────────────────────────────
# All code under src\wasm must use TWASM* aliases from wasm.types.builtin.
# Only wasm.types.builtin.pas itself may reference the raw types.
$forbiddenTypes = @(
'uint8','uint16','uint32','uint64',
'sint8','sint16',
'int32','int64',
'float','double',
'puint8','puint16','puint32','puint64',
'pfloat','pdouble','pchar',
'boolean','char','void','integer'
)
$pattern = '(?i)(?<![a-z0-9_])(' + ($forbiddenTypes -join '|') + ')(?![a-z0-9_])'
$files = Get-ChildItem (Join-Path $SrcRoot 'wasm') -Recurse -Filter '*.pas' |
Where-Object { $_.Name -ne 'wasm.types.builtin.pas' }
$ruleHits = 0
foreach ($file in $files) {
$content = [IO.File]::ReadAllText($file.FullName)
$matches = [regex]::Matches($content, $pattern)
if ($matches.Count -gt 0) {
$found = @{}
foreach ($m in $matches) { $found[$m.Value.ToLower()] = $true }
$list = ($found.Keys | Sort-Object) -join ', '
Write-Host " $($file.Name): $list"
$ruleHits++
}
}
if ($ruleHits -gt 0) {
Write-Host ''
Write-Host "Lint failed: $ruleHits file(s) use native types. Use TWASM* from wasm.types.builtin instead."
$fail = $true
}
# ── Add more rules here ─────────────────────────────────────────────
if ($fail) { exit 1 }
Write-Host 'Lint passed.'
+1 -1
View File
@@ -7,7 +7,7 @@ uses
types, types,
wasm.types, wasm.types.context,
wasm.parser, wasm.parser,
wasm.vm, wasm.test.binary.return42, wasm.vm, wasm.test.binary.return42,
wasm.types.stack wasm.types.stack
@@ -3,16 +3,16 @@ unit wasm.parser.sections.codeSection;
interface interface
uses uses
types, lmemorymanager, console, leb128, wasm.types.builtin, lmemorymanager, console, leb128,
wasm.types; wasm.types.enums, wasm.types.values, wasm.types.sections, wasm.types.context;
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext); procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext);
implementation implementation
procedure printCtxCode(ctx : PWASMProcessContext); procedure printCtxCode(ctx : PWASMProcessContext);
var var
i : uint32; i : TWASMUInt32;
begin begin
writestring('[wasm.parser] Flat Code: '); writestring('[wasm.parser] Flat Code: ');
@@ -25,15 +25,15 @@ end;
procedure walk(ctx : PWASMProcessContext); procedure walk(ctx : PWASMProcessContext);
var var
localpos, pos, bend : puint8; localpos, pos, bend : TWASMPUInt8;
bytesRead : uint8; bytesRead : TWASMUInt8;
currentEntry : PWASMCodeEntry; currentEntry : PWASMCodeEntry;
i,j,l : uint32; i,j,l : TWASMUInt32;
localCount,localTemp,localIndex : uint32; localCount,localTemp,localIndex : TWASMUInt32;
localType: TWasmValueType; localType: TWasmValueType;
codeLength: uint32; codeLength: TWASMUInt32;
codeOffset: uint32; codeOffset: TWASMUInt32;
totalSize: uint32; totalSize: TWASMUInt32;
begin begin
// Walk the code entries // Walk the code entries
for i:=1 to ctx^.Sections.CodeSection^.CodeCount do begin for i:=1 to ctx^.Sections.CodeSection^.CodeCount do begin
@@ -59,17 +59,17 @@ begin
end; end;
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext); procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext);
var var
localpos, pos, bend : puint8; localpos, pos, bend : TWASMPUInt8;
bytesRead : uint8; bytesRead : TWASMUInt8;
currentEntry : PWASMCodeEntry; currentEntry : PWASMCodeEntry;
i,j,l : uint32; i,j,l : TWASMUInt32;
localCount,localTemp,localIndex : uint32; localCount,localTemp,localIndex : TWASMUInt32;
localType: TWasmValueType; localType: TWasmValueType;
codeLength: uint32; codeLength: TWASMUInt32;
codeOffset: uint32; codeOffset: TWASMUInt32;
totalSize: uint32; totalSize: TWASMUInt32;
begin begin
writestring('[wasm.parser] Handle Section: Code - Size: '); writestring('[wasm.parser] Handle Section: Code - Size: ');
@@ -77,7 +77,7 @@ begin
// Initialize the read/end pointers // Initialize the read/end pointers
pos:= buffer; pos:= buffer;
bend:= puint8(pos + section_length); bend:= TWASMPUInt8(pos + section_length);
// Initialize the code section // Initialize the code section
ctx^.Sections.CodeSection:= PWASMCodeSection(kalloc(sizeof(TWASMCodeSection))); ctx^.Sections.CodeSection:= PWASMCodeSection(kalloc(sizeof(TWASMCodeSection)));
@@ -158,7 +158,7 @@ begin
end; end;
// Read the code // Read the code
currentEntry^.Code:= puint8(kalloc(currentEntry^.CodeLength)); currentEntry^.Code:= TWASMPUInt8(kalloc(currentEntry^.CodeLength));
for j:=1 to currentEntry^.CodeLength do begin for j:=1 to currentEntry^.CodeLength do begin
currentEntry^.Code[j - 1]:= pos^; currentEntry^.Code[j - 1]:= pos^;
inc(pos); inc(pos);
@@ -171,12 +171,12 @@ begin
totalSize:= totalSize + currentEntry^.CodeLength; totalSize:= totalSize + currentEntry^.CodeLength;
end; end;
ctx^.ExecutionState.Code:= puint8(kalloc(totalSize)); ctx^.ExecutionState.Code:= TWASMPUInt8(kalloc(totalSize));
ctx^.ExecutionState.Limit:= totalSize; ctx^.ExecutionState.Limit:= totalSize;
localpos:= ctx^.ExecutionState.Code; localpos:= ctx^.ExecutionState.Code;
for i:=1 to ctx^.Sections.CodeSection^.CodeCount do begin for i:=1 to ctx^.Sections.CodeSection^.CodeCount do begin
currentEntry:= @ctx^.Sections.CodeSection^.Entries[i - 1]; currentEntry:= @ctx^.Sections.CodeSection^.Entries[i - 1];
currentEntry^.CodeIndex:= uint32(localpos - ctx^.ExecutionState.Code); currentEntry^.CodeIndex:= TWASMUInt32(localpos - ctx^.ExecutionState.Code);
for j:=1 to currentEntry^.CodeLength do begin for j:=1 to currentEntry^.CodeLength do begin
localpos^:= currentEntry^.Code[j - 1]; localpos^:= currentEntry^.Code[j - 1];
inc(localpos); inc(localpos);
@@ -3,14 +3,14 @@ unit wasm.parser.sections.customSection;
interface interface
uses uses
types, lmemorymanager, console, leb128, wasm.types.builtin, lmemorymanager, console, leb128,
wasm.types; wasm.types.context;
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext); procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext);
implementation implementation
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext); procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext);
begin begin
writestring('[wasm.parser] Handle Section: Custom - Size: '); writestring('[wasm.parser] Handle Section: Custom - Size: ');
writeintlnWND(section_length, 0); writeintlnWND(section_length, 0);
@@ -3,31 +3,31 @@ unit wasm.parser.sections.dataSection;
interface interface
uses uses
types, lmemorymanager, console, leb128, wasm.types.builtin, lmemorymanager, console, leb128,
wasm.types, wasm.types.heap; wasm.types.context, wasm.types.heap;
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext); procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext);
implementation implementation
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext); procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext);
var var
pos, bend : puint8; pos, bend : TWASMPUInt8;
bytesRead : uint8; bytesRead : TWASMUInt8;
segCount : uint32; segCount : TWASMUInt32;
i, j : uint32; i, j : TWASMUInt32;
memIdx : uint32; memIdx : TWASMUInt32;
offset : uint32; offset : TWASMUInt32;
dataSize : uint32; dataSize : TWASMUInt32;
opcode : uint8; opcode : TWASMUInt8;
tmpU32 : uint32; tmpU32 : TWASMUInt32;
begin begin
writestring('[wasm.parser] Handle Section: Data - Size: '); writestring('[wasm.parser] Handle Section: Data - Size: ');
writeintlnWND(section_length, 0); writeintlnWND(section_length, 0);
pos := buffer; pos := buffer;
bend := puint8(buffer + section_length); bend := TWASMPUInt8(buffer + section_length);
{ Read segment count } { Read segment count }
bytesRead := read_leb128_to_uint32(pos, bend, @segCount); bytesRead := read_leb128_to_uint32(pos, bend, @segCount);
@@ -3,14 +3,14 @@ unit wasm.parser.sections.elementSection;
interface interface
uses uses
types, lmemorymanager, console, leb128, wasm.types.builtin, lmemorymanager, console, leb128,
wasm.types; wasm.types.context;
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext); procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext);
implementation implementation
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext); procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext);
begin begin
writestring('[wasm.parser] Handle Section: Element - Size: '); writestring('[wasm.parser] Handle Section: Element - Size: ');
writeintlnWND(section_length, 0); writeintlnWND(section_length, 0);
@@ -3,17 +3,17 @@ unit wasm.parser.sections.exportSection;
interface interface
uses uses
types, lmemorymanager, console, leb128, wasm.types.builtin, lmemorymanager, console, leb128,
wasm.types; wasm.types.enums, wasm.types.sections, wasm.types.context;
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext); procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext);
implementation implementation
procedure walk(ctx : PWASMProcessContext); procedure walk(ctx : PWASMProcessContext);
var var
currentEntry : PWASMExportEntry; currentEntry : PWASMExportEntry;
i : uint32; i : TWASMUInt32;
begin begin
// Walk the export entries // Walk the export entries
@@ -28,12 +28,12 @@ begin
end; end;
end; end;
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext); procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext);
var var
pos, bend : puint8; pos, bend : TWASMPUInt8;
bytesRead : uint8; bytesRead : TWASMUInt8;
currentEntry : PWASMExportEntry; currentEntry : PWASMExportEntry;
i,j : uint32; i,j : TWASMUInt32;
begin begin
writestring('[wasm.parser] Handle Section: Export - Size: '); writestring('[wasm.parser] Handle Section: Export - Size: ');
@@ -41,7 +41,7 @@ begin
// Initialize the read/end pointers // Initialize the read/end pointers
pos:= buffer; pos:= buffer;
bend:= puint8(pos + section_length); bend:= TWASMPUInt8(pos + section_length);
// Initialize the export section // Initialize the export section
ctx^.Sections.ExportSection:= PWASMExportSection(kalloc(sizeof(TWASMExportSection))); ctx^.Sections.ExportSection:= PWASMExportSection(kalloc(sizeof(TWASMExportSection)));
@@ -69,12 +69,12 @@ begin
inc(pos, bytesRead); inc(pos, bytesRead);
// Read the export name // Read the export name
currentEntry^.Name:= pchar(kalloc(currentEntry^.NameLength + 1)); currentEntry^.Name:= TWASMPChar(kalloc(currentEntry^.NameLength + 1));
for j:=0 to currentEntry^.NameLength - 1 do begin for j:=0 to currentEntry^.NameLength - 1 do begin
currentEntry^.Name[j]:= char(pos^); currentEntry^.Name[j]:= TWASMChar(pos^);
inc(pos); inc(pos);
end; end;
currentEntry^.Name[currentEntry^.NameLength]:= char($00); currentEntry^.Name[currentEntry^.NameLength]:= TWASMChar($00);
// Read the export type // Read the export type
currentEntry^.ExportType:= TWasmExportType(pos^); currentEntry^.ExportType:= TWasmExportType(pos^);
@@ -3,17 +3,17 @@ unit wasm.parser.sections.functionSection;
interface interface
uses uses
types, lmemorymanager, console, leb128, wasm.types.builtin, lmemorymanager, console, leb128,
wasm.types; wasm.types.sections, wasm.types.context;
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext); procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext);
implementation implementation
procedure walk(ctx : PWASMProcessContext); procedure walk(ctx : PWASMProcessContext);
var var
currentFunc : PWASMFunction; currentFunc : PWASMFunction;
i : uint32; i : TWASMUInt32;
begin begin
// Walk the functions // Walk the functions
@@ -24,12 +24,12 @@ begin
end; end;
end; end;
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext); procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext);
var var
pos, bend : puint8; pos, bend : TWASMPUInt8;
bytesRead : uint8; bytesRead : TWASMUInt8;
currentFunc : PWASMFunction; currentFunc : PWASMFunction;
i : uint32; i : TWASMUInt32;
begin begin
writestring('[wasm.parser] Handle Section: Function - Size: '); writestring('[wasm.parser] Handle Section: Function - Size: ');
@@ -37,7 +37,7 @@ begin
// Initialize the read/end pointers // Initialize the read/end pointers
pos:= buffer; pos:= buffer;
bend:= puint8(pos + section_length); bend:= TWASMPUInt8(pos + section_length);
// Initialize the function section // Initialize the function section
ctx^.Sections.FunctionSection:= PWASMFunctionSection(kalloc(sizeof(TWASMFunctionSection))); ctx^.Sections.FunctionSection:= PWASMFunctionSection(kalloc(sizeof(TWASMFunctionSection)));
@@ -3,16 +3,16 @@ unit wasm.parser.sections.globalSection;
interface interface
uses uses
types, lmemorymanager, console, leb128, wasm.types.builtin, lmemorymanager, console, leb128,
wasm.types; wasm.types.enums, wasm.types.sections, wasm.types.context;
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext); procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext);
implementation implementation
procedure walk(ctx : PWASMProcessContext); procedure walk(ctx : PWASMProcessContext);
var var
i : uint32; i : TWASMUInt32;
entry : PWASMGlobalEntry; entry : PWASMGlobalEntry;
begin begin
for i := 0 to ctx^.ExecutionState.Globals^.GlobalCount - 1 do begin for i := 0 to ctx^.ExecutionState.Globals^.GlobalCount - 1 do begin
@@ -35,25 +35,25 @@ begin
end; end;
end; end;
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext); procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext);
var var
pos, bend : puint8; pos, bend : TWASMPUInt8;
bytesRead : uint8; bytesRead : TWASMUInt8;
globalCount : uint32; globalCount : TWASMUInt32;
i : uint32; i : TWASMUInt32;
entry : PWASMGlobalEntry; entry : PWASMGlobalEntry;
valType : uint8; valType : TWASMUInt8;
mutFlag : uint8; mutFlag : TWASMUInt8;
opcode : uint8; opcode : TWASMUInt8;
tmpU32 : uint32; tmpU32 : TWASMUInt32;
tmpU64 : uint64; tmpU64 : TWASMUInt64;
begin begin
writestring('[wasm.parser] Handle Section: Global - Size: '); writestring('[wasm.parser] Handle Section: Global - Size: ');
writeintlnWND(section_length, 0); writeintlnWND(section_length, 0);
pos := buffer; pos := buffer;
bend := puint8(buffer + section_length); bend := TWASMPUInt8(buffer + section_length);
{ Read global count } { Read global count }
bytesRead := read_leb128_to_uint32(pos, bend, @globalCount); bytesRead := read_leb128_to_uint32(pos, bend, @globalCount);
@@ -88,19 +88,19 @@ begin
$41: begin { i32.const } $41: begin { i32.const }
bytesRead := read_leb128_to_uint32(pos, bend, @tmpU32); bytesRead := read_leb128_to_uint32(pos, bend, @tmpU32);
Inc(pos, bytesRead); Inc(pos, bytesRead);
entry^.Value.i32Value := int32(tmpU32); entry^.Value.i32Value := TWASMInt32(tmpU32);
end; end;
$42: begin { i64.const } $42: begin { i64.const }
bytesRead := read_leb128_to_uint64(pos, bend, @tmpU64); bytesRead := read_leb128_to_uint64(pos, bend, @tmpU64);
Inc(pos, bytesRead); Inc(pos, bytesRead);
entry^.Value.i64Value := int64(tmpU64); entry^.Value.i64Value := TWASMInt64(tmpU64);
end; end;
$43: begin { f32.const } $43: begin { f32.const }
entry^.Value.f32Value := pfloat(pos)^; entry^.Value.f32Value := TWASMPFloat(pos)^;
Inc(pos, 4); Inc(pos, 4);
end; end;
$44: begin { f64.const } $44: begin { f64.const }
entry^.Value.f64Value := pdouble(pos)^; entry^.Value.f64Value := TWASMPDouble(pos)^;
Inc(pos, 8); Inc(pos, 8);
end; end;
else else
@@ -3,14 +3,14 @@ unit wasm.parser.sections.importSection;
interface interface
uses uses
types, lmemorymanager, console, leb128, wasm.types.builtin, lmemorymanager, console, leb128,
wasm.types; wasm.types.context;
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext); procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext);
implementation implementation
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext); procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext);
begin begin
writestring('[wasm.parser] Handle Section: Import - Size: '); writestring('[wasm.parser] Handle Section: Import - Size: ');
writeintlnWND(section_length, 0); writeintlnWND(section_length, 0);
@@ -3,16 +3,16 @@ unit wasm.parser.sections.memorySection;
interface interface
uses uses
types, lmemorymanager, console, leb128, wasm.types.builtin, lmemorymanager, console, leb128,
wasm.types, wasm.types.heap; wasm.types.sections, wasm.types.context, wasm.types.heap;
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext); procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext);
implementation implementation
procedure walk(ctx : PWASMProcessContext); procedure walk(ctx : PWASMProcessContext);
var var
i : uint32; i : TWASMUInt32;
mem : PWASMMemoryLimits; mem : PWASMMemoryLimits;
begin begin
for i := 0 to ctx^.Sections.MemorySection^.MemoryCount - 1 do begin for i := 0 to ctx^.Sections.MemorySection^.MemoryCount - 1 do begin
@@ -29,21 +29,21 @@ begin
end; end;
end; end;
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext); procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext);
var var
pos, bend : puint8; pos, bend : TWASMPUInt8;
bytesRead : uint8; bytesRead : TWASMUInt8;
memCount : uint32; memCount : TWASMUInt32;
i : uint32; i : TWASMUInt32;
mem : PWASMMemoryLimits; mem : PWASMMemoryLimits;
flags : uint32; flags : TWASMUInt32;
begin begin
writestring('[wasm.parser] Handle Section: Memory - Size: '); writestring('[wasm.parser] Handle Section: Memory - Size: ');
writeintlnWND(section_length, 0); writeintlnWND(section_length, 0);
pos := buffer; pos := buffer;
bend := puint8(buffer + section_length); bend := TWASMPUInt8(buffer + section_length);
{ Read memory count } { Read memory count }
bytesRead := read_leb128_to_uint32(pos, bend, @memCount); bytesRead := read_leb128_to_uint32(pos, bend, @memCount);
@@ -3,25 +3,25 @@ unit wasm.parser.sections.startSection;
interface interface
uses uses
types, lmemorymanager, console, leb128, wasm.types.builtin, lmemorymanager, console, leb128,
wasm.types; wasm.types.context;
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext); procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext);
implementation implementation
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext); procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext);
var var
bytesRead : uint8; bytesRead : TWASMUInt8;
funcIdx : uint32; funcIdx : TWASMUInt32;
begin begin
writestring('[wasm.parser] Handle Section: Start - Size: '); writestring('[wasm.parser] Handle Section: Start - Size: ');
writeintlnWND(section_length, 0); writeintlnWND(section_length, 0);
{ Read the start function index } { Read the start function index }
bytesRead := read_leb128_to_uint32(buffer, puint8(buffer + section_length), @funcIdx); bytesRead := read_leb128_to_uint32(buffer, TWASMPUInt8(buffer + section_length), @funcIdx);
ctx^.Sections.StartIndex := int32(funcIdx); ctx^.Sections.StartIndex := TWASMInt32(funcIdx);
writestring('[wasm.parser] Start Function Index: '); writestring('[wasm.parser] Start Function Index: ');
writeintlnWND(funcIdx, 0); writeintlnWND(funcIdx, 0);
@@ -3,14 +3,14 @@ unit wasm.parser.sections.tableSection;
interface interface
uses uses
types, lmemorymanager, console, leb128, wasm.types.builtin, lmemorymanager, console, leb128,
wasm.types; wasm.types.context;
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext); procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext);
implementation implementation
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext); procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext);
begin begin
writestring('[wasm.parser] Handle Section: Table - Size: '); writestring('[wasm.parser] Handle Section: Table - Size: ');
writeintlnWND(section_length, 0); writeintlnWND(section_length, 0);
@@ -3,10 +3,10 @@ unit wasm.parser.sections.typeSection;
interface interface
uses uses
types, lmemorymanager, console, leb128, wasm.types.builtin, lmemorymanager, console, leb128,
wasm.types; wasm.types.enums, wasm.types.values, wasm.types.sections, wasm.types.context;
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext); procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext);
implementation implementation
@@ -14,10 +14,10 @@ procedure walk(ctx : PWASMProcessContext);
var var
currentType : PWASMType; currentType : PWASMType;
currentParam : PWASMParam; currentParam : PWASMParam;
i,j : uint32; i,j : TWASMUInt32;
begin begin
// Walk the types // Walk the wasm.types.builtin
for i:=1 to ctx^.Sections.TypeSection^.TypeCount do begin for i:=1 to ctx^.Sections.TypeSection^.TypeCount do begin
currentType:= @ctx^.Sections.TypeSection^.Types[i - 1]; currentType:= @ctx^.Sections.TypeSection^.Types[i - 1];
writestring('[wasm.parser] Index: '); writestring('[wasm.parser] Index: ');
@@ -50,13 +50,13 @@ begin
end; end;
end; end;
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext); procedure handle(buffer: TWASMPUInt8; section_length: TWASMUInt32; ctx: PWASMProcessContext);
var var
pos : puint8; pos : TWASMPUInt8;
bytesRead : uint8; bytesRead : TWASMUInt8;
currentType : PWASMType; currentType : PWASMType;
currentParam : PWASMParam; currentParam : PWASMParam;
i, parsedTypes : uint32; i, parsedTypes : TWASMUInt32;
begin begin
writestring('[wasm.parser] Handle Section: Type - Size: '); writestring('[wasm.parser] Handle Section: Type - Size: ');
@@ -67,31 +67,31 @@ begin
ctx^.Sections.TypeSection:= PWASMTypeSection(kalloc(sizeof(TWASMTypeSection))); ctx^.Sections.TypeSection:= PWASMTypeSection(kalloc(sizeof(TWASMTypeSection)));
ctx^.Sections.TypeSection^.TypeCount:= 0; ctx^.Sections.TypeSection^.TypeCount:= 0;
// Read the number of function types // Read the number of function wasm.types.builtin
bytesRead:= read_leb128_to_uint32(buffer, puint8(buffer + section_length), @ctx^.Sections.TypeSection^.TypeCount); bytesRead:= read_leb128_to_uint32(buffer, TWASMPUInt8(buffer + section_length), @ctx^.Sections.TypeSection^.TypeCount);
inc(pos, bytesRead); inc(pos, bytesRead);
// Read the function types // Read the function wasm.types.builtin
if(ctx^.Sections.TypeSection^.TypeCount > 0) then begin if(ctx^.Sections.TypeSection^.TypeCount > 0) then begin
// Allocate the first type // Allocate the first type
ctx^.Sections.TypeSection^.Types:= PWASMType(kalloc(sizeof(TWASMType) * ctx^.Sections.TypeSection^.TypeCount)); ctx^.Sections.TypeSection^.Types:= PWASMType(kalloc(sizeof(TWASMType) * ctx^.Sections.TypeSection^.TypeCount));
// Read the function types // Read the function wasm.types.builtin
for parsedTypes:=1 to ctx^.Sections.TypeSection^.TypeCount do begin for parsedTypes:=1 to ctx^.Sections.TypeSection^.TypeCount do begin
currentType:= @ctx^.Sections.TypeSection^.Types[parsedTypes - 1]; currentType:= @ctx^.Sections.TypeSection^.Types[parsedTypes - 1];
// Check if we are at the end of the buffer // Check if we are at the end of the buffer
if pos >= puint8(buffer + section_length) then Exit; if pos >= TWASMPUInt8(buffer + section_length) then Exit;
// Read the function type // Read the function type
currentType^._type:= pos^; currentType^._type:= pos^;
inc(pos); inc(pos);
// Read the number of parameters // Read the number of parameters
bytesRead:= read_leb128_to_uint32(pos, puint8(buffer + section_length), @currentType^.ParamCount); bytesRead:= read_leb128_to_uint32(pos, TWASMPUInt8(buffer + section_length), @currentType^.ParamCount);
inc(pos, bytesRead); inc(pos, bytesRead);
// Read the parameter types // Read the parameter wasm.types.builtin
if(currentType^.ParamCount > 0) then begin if(currentType^.ParamCount > 0) then begin
currentType^.ParamTypes:= PWASMParam(kalloc(sizeof(TWASMParam) * currentType^.ParamCount)); currentType^.ParamTypes:= PWASMParam(kalloc(sizeof(TWASMParam) * currentType^.ParamCount));
for i:=1 to currentType^.ParamCount do begin for i:=1 to currentType^.ParamCount do begin
@@ -102,10 +102,10 @@ begin
end; end;
// Read the number of return values // Read the number of return values
bytesRead:= read_leb128_to_uint32(pos, puint8(buffer + section_length), @currentType^.ReturnCount); bytesRead:= read_leb128_to_uint32(pos, TWASMPUInt8(buffer + section_length), @currentType^.ReturnCount);
inc(pos, bytesRead); inc(pos, bytesRead);
// Read the return types // Read the return wasm.types.builtin
if(currentType^.ReturnCount > 0) then begin if(currentType^.ReturnCount > 0) then begin
currentType^.ReturnTypes:= PWASMParam(kalloc(sizeof(TWASMParam) * currentType^.ReturnCount)); currentType^.ReturnTypes:= PWASMParam(kalloc(sizeof(TWASMParam) * currentType^.ReturnCount));
for i:=1 to currentType^.ReturnCount do begin for i:=1 to currentType^.ReturnCount do begin
@@ -117,7 +117,7 @@ begin
end; end;
end; end;
// Walk the types // Walk the wasm.types.builtin
walk(ctx); walk(ctx);
end; end;
+11 -11
View File
@@ -3,11 +3,11 @@ unit wasm.parser;
interface interface
uses uses
types, lmemorymanager, console, leb128, wasm.types.builtin, lmemorymanager, console, leb128,
wasm.types, 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.parser.sections, wasm.types.constants;
function parse(buffer: puint8; buffer_end: puint8) : PWASMProcessContext; function parse(buffer: TWASMPUInt8; buffer_end: TWASMPUInt8) : PWASMProcessContext;
implementation implementation
@@ -50,13 +50,13 @@ begin
newContext:= ctx; newContext:= ctx;
end; end;
function parse(buffer: puint8; buffer_end: puint8): PWASMProcessContext; function parse(buffer: TWASMPUInt8; buffer_end: TWASMPUInt8): PWASMProcessContext;
var var
ctx : PWASMProcessContext; ctx : PWASMProcessContext;
pos : puint8; pos : TWASMPUInt8;
bytesRead : uint8; bytesRead : TWASMUInt8;
section_id : uint8; section_id : TWASMUInt8;
section_length : uint32; section_length : TWASMUInt32;
begin begin
// Allocate the context // Allocate the context
@@ -66,7 +66,7 @@ begin
writestringln('[wasm.parser] Parsing WASM Binary'); writestringln('[wasm.parser] Parsing WASM Binary');
// Check for the WASM Magic // Check for the WASM Magic
if(puint32(pos)^ = wasm.types.WASM_HDR_MAGIC) then begin if(TWASMPUInt32(pos)^ = wasm.types.constants.WASM_HDR_MAGIC) then begin
writestringln('[wasm.parser] Binary is valid.'); writestringln('[wasm.parser] Binary is valid.');
// Set binary to valid // Set binary to valid
@@ -74,7 +74,7 @@ begin
inc(pos, 4); inc(pos, 4);
// Read the version // Read the version
ctx^.Version:= puint32(pos)^; ctx^.Version:= TWASMPUInt32(pos)^;
inc(pos, 4); inc(pos, 4);
writestring('[wasm.parser] Version: '); writestring('[wasm.parser] Version: ');
writeintlnWND(ctx^.Version, 0); writeintlnWND(ctx^.Version, 0);
+4 -4
View File
@@ -3,8 +3,8 @@ unit wasm.parser.sections;
interface interface
uses uses
types, wasm.types.builtin,
wasm.types, wasm.types.enums, wasm.types.context,
wasm.parser.sections.customSection, wasm.parser.sections.customSection,
wasm.parser.sections.typeSection, wasm.parser.sections.typeSection,
wasm.parser.sections.importSection, wasm.parser.sections.importSection,
@@ -18,11 +18,11 @@ uses
wasm.parser.sections.codeSection, wasm.parser.sections.codeSection,
wasm.parser.sections.dataSection; wasm.parser.sections.dataSection;
procedure handle(sectionId : uint8; buffer : puint8; section_length : uint32; ctx : PWASMProcessContext); procedure handle(sectionId : TWASMUInt8; buffer : TWASMPUInt8; section_length : TWASMUInt32; ctx : PWASMProcessContext);
implementation implementation
procedure handle(sectionId : uint8; buffer : puint8; section_length : uint32; ctx : PWASMProcessContext); procedure handle(sectionId : TWASMUInt8; buffer : TWASMPUInt8; section_length : TWASMUInt32; ctx : PWASMProcessContext);
begin begin
// Handle the section // Handle the section
case sectionId of case sectionId of
@@ -18,12 +18,12 @@ procedure run;
implementation implementation
uses uses
types, console, wasm.types, wasm.types.stack, wasm.types.builtin, console, wasm.types.context, wasm.types.stack,
wasm.parser, wasm.vm, wasm.test.framework; wasm.parser, wasm.vm, wasm.test.framework;
const const
BINARY_SIZE = 41; BINARY_SIZE = 41;
BINARY : Array[$00..$28] of uint8 = ( BINARY : Array[$00..$28] of TWASMUInt8 = (
$00, $61, $73, $6D, { magic } $00, $61, $73, $6D, { magic }
$01, $00, $00, $00, { version 1 } $01, $00, $00, $00, { version 1 }
$01, $05, $01, $60, { type section: 1 func type } $01, $05, $01, $60, { type section: 1 func type }
@@ -46,7 +46,7 @@ var
begin begin
test_begin('binary.addnums'); test_begin('binary.addnums');
ctx := wasm.parser.parse(@BINARY[0], puint8(@BINARY[0] + BINARY_SIZE)); ctx := wasm.parser.parse(@BINARY[0], TWASMPUInt8(@BINARY[0] + BINARY_SIZE));
assert_true('valid binary', ctx^.ValidBinary); assert_true('valid binary', ctx^.ValidBinary);
ctx^.ExecutionState.Running := true; ctx^.ExecutionState.Running := true;
@@ -20,12 +20,12 @@ procedure run;
implementation implementation
uses uses
types, console, wasm.types, wasm.types.stack, wasm.types.builtin, console, wasm.types.context, wasm.types.stack,
wasm.parser, wasm.vm, wasm.test.framework; wasm.parser, wasm.vm, wasm.test.framework;
const const
BINARY_SIZE = 44; BINARY_SIZE = 44;
BINARY : Array[$00..$2B] of uint8 = ( BINARY : Array[$00..$2B] of TWASMUInt8 = (
$00, $61, $73, $6D, { magic } $00, $61, $73, $6D, { magic }
$01, $00, $00, $00, { version 1 } $01, $00, $00, $00, { version 1 }
$01, $05, $01, $60, { type section: 1 func type } $01, $05, $01, $60, { type section: 1 func type }
@@ -50,7 +50,7 @@ var
begin begin
test_begin('binary.arithmetic'); test_begin('binary.arithmetic');
ctx := wasm.parser.parse(@BINARY[0], puint8(@BINARY[0] + BINARY_SIZE)); ctx := wasm.parser.parse(@BINARY[0], TWASMPUInt8(@BINARY[0] + BINARY_SIZE));
assert_true('valid binary', ctx^.ValidBinary); assert_true('valid binary', ctx^.ValidBinary);
ctx^.ExecutionState.Running := true; ctx^.ExecutionState.Running := true;
File diff suppressed because it is too large. Load diff
Loaded 20 of 165 files, more files were not shown because too many files have changed in this diff. Show more