Initial commit
This commit is contained in:
commit
3361286352
29 files changed
+3386
No files matched your search
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,66 @@
|
||||
unit leb128;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
types;
|
||||
|
||||
function read_leb128_to_uint64(buf : puint8; buf_end : puint8; res : puint64) : uint8;
|
||||
function read_leb128_to_uint32(buf : puint8; buf_end : puint8; res : puint32) : uint8;
|
||||
|
||||
implementation
|
||||
|
||||
function read_leb128_to_uint64(buf: puint8; buf_end: puint8; res: puint64): uint8;
|
||||
var
|
||||
ptr : puint8;
|
||||
shift : uint32;
|
||||
localResult : uint64;
|
||||
currentByte : uint8;
|
||||
|
||||
begin
|
||||
ptr:= buf;
|
||||
shift:= 0;
|
||||
localResult:= 0;
|
||||
while (true) do begin
|
||||
if (ptr >= buf_end) then begin
|
||||
read_leb128_to_uint64:= 0;
|
||||
exit;
|
||||
end;
|
||||
currentByte:= ptr^;
|
||||
inc(ptr);
|
||||
localResult:= localResult or uint64(currentByte and $7F) SHL Shift;
|
||||
if ((currentByte AND $80) = 0) then break;
|
||||
Inc(Shift, 7);
|
||||
end;
|
||||
res^:= localResult;
|
||||
read_leb128_to_uint64:= uint8(ptr - buf);
|
||||
end;
|
||||
|
||||
function read_leb128_to_uint32(buf: puint8; buf_end: puint8; res: puint32): uint8;
|
||||
var
|
||||
ptr : puint8;
|
||||
shift : uint32;
|
||||
localResult : uint32;
|
||||
currentByte : uint8;
|
||||
|
||||
begin
|
||||
ptr:= buf;
|
||||
shift:= 0;
|
||||
localResult:= 0;
|
||||
while (true) do begin
|
||||
if (ptr >= buf_end) then begin
|
||||
read_leb128_to_uint32:= 0;
|
||||
exit;
|
||||
end;
|
||||
currentByte:= ptr^;
|
||||
inc(ptr);
|
||||
localResult:= localResult or uint64(currentByte and $7F) SHL Shift;
|
||||
if ((currentByte AND $80) = 0) then break;
|
||||
Inc(Shift, 7);
|
||||
end;
|
||||
res^:= localResult;
|
||||
read_leb128_to_uint32:= uint8(ptr - buf);
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
unit lmemorymanager;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
types;
|
||||
|
||||
function kalloc(size : uint32) : void;
|
||||
procedure kfree(area : void);
|
||||
|
||||
implementation
|
||||
|
||||
function kalloc(size: uint32): void;
|
||||
begin
|
||||
kalloc:= void(GetMem(size));
|
||||
end;
|
||||
|
||||
procedure kfree(area: void);
|
||||
begin
|
||||
FreeMem(pointer(area));
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
{ ************************************************
|
||||
* Asuro
|
||||
* Unit: system
|
||||
* Description: Standard System Types
|
||||
************************************************
|
||||
* Author: K Morris
|
||||
* Contributors:
|
||||
************************************************ }
|
||||
|
||||
unit types;
|
||||
|
||||
interface
|
||||
|
||||
const
|
||||
KERNEL_VIRTUAL_BASE = $C0000000;
|
||||
KERNEL_PAGE_NUMBER = KERNEL_VIRTUAL_BASE SHR 22;
|
||||
BSOD_ENABLE = true;
|
||||
TRACER_ENABLE = true;
|
||||
CONSOLE_SLOW_REDRAW = false; //Redraws the Window manager after every character, but slows performance.
|
||||
|
||||
type
|
||||
//internal types
|
||||
cardinal = 0..$FFFFFFFF;
|
||||
hresult = cardinal;
|
||||
dword = cardinal;
|
||||
integer = longint;
|
||||
|
||||
pchar = ^char;
|
||||
|
||||
//Standard Types
|
||||
uInt8 = BYTE;
|
||||
uInt16 = WORD;
|
||||
uInt32 = DWORD;
|
||||
uInt64 = QWORD;
|
||||
|
||||
sInt8 = shortint;
|
||||
sInt16 = smallint;
|
||||
sInt32 = integer;
|
||||
sInt64 = longint;
|
||||
|
||||
Float = Single;
|
||||
|
||||
//Pointer Types
|
||||
PuByte = ^Byte;
|
||||
PuInt8 = PuByte;
|
||||
PuInt16 = ^uInt16;
|
||||
PuInt32 = ^uInt32;
|
||||
PuInt64 = ^uInt64;
|
||||
|
||||
PsInt8 = ^sInt8;
|
||||
PsInt16 = ^sInt16;
|
||||
PsInt32 = ^sInt32;
|
||||
PsInt64 = ^sInt64;
|
||||
|
||||
PFloat = ^Float;
|
||||
PDouble = ^Double;
|
||||
|
||||
Void = ^uInt32;
|
||||
HWND = uint32;
|
||||
|
||||
//Alternate Types
|
||||
UBit1 = 0..(1 shl 01) - 1;
|
||||
UBit2 = 0..(1 shl 02) - 1;
|
||||
UBit3 = 0..(1 shl 03) - 1;
|
||||
UBit4 = 0..(1 shl 04) - 1;
|
||||
UBit5 = 0..(1 shl 05) - 1;
|
||||
UBit6 = 0..(1 shl 06) - 1;
|
||||
UBit7 = 0..(1 shl 07) - 1;
|
||||
UBit9 = 0..(1 shl 09) - 1;
|
||||
UBit10 = 0..(1 shl 10) - 1;
|
||||
UBit11 = 0..(1 shl 11) - 1;
|
||||
UBit12 = 0..(1 shl 12) - 1;
|
||||
UBit13 = 0..(1 shl 13) - 1;
|
||||
UBit14 = 0..(1 shl 14) - 1;
|
||||
UBit15 = 0..(1 shl 15) - 1;
|
||||
UBit16 = 0..(1 shl 16) - 1;
|
||||
UBit17 = 0..(1 shl 17) - 1;
|
||||
UBit18 = 0..(1 shl 18) - 1;
|
||||
UBit19 = 0..(1 shl 19) - 1;
|
||||
UBit20 = 0..(1 shl 20) - 1;
|
||||
UBit21 = 0..(1 shl 21) - 1;
|
||||
UBit22 = 0..(1 shl 22) - 1;
|
||||
UBit23 = 0..(1 shl 23) - 1;
|
||||
UBit24 = 0..(1 shl 24) - 1;
|
||||
UBit25 = 0..(1 shl 25) - 1;
|
||||
UBit26 = 0..(1 shl 26) - 1;
|
||||
UBit27 = 0..(1 shl 27) - 1;
|
||||
UBit28 = 0..(1 shl 28) - 1;
|
||||
UBit30 = 0..(1 shl 30) - 1;
|
||||
UBit31 = 0..(1 shl 31) - 1;
|
||||
|
||||
TBitMask = bitpacked record
|
||||
b0,b1,b2,b3,b4,b5,b6,b7 : Boolean;
|
||||
end;
|
||||
PBitMask = ^TBitMask;
|
||||
|
||||
TMask = bitpacked array[0..7] of Boolean;
|
||||
PMask = ^TMask;
|
||||
|
||||
TRGB565 = bitpacked record
|
||||
B : UBit5;
|
||||
G : UBit6;
|
||||
R : UBit5
|
||||
end;
|
||||
PRGB565 = ^TRGB565;
|
||||
|
||||
TRGB565Pair = bitpacked record
|
||||
Background : TRGB565;
|
||||
Foreground : TRGB565;
|
||||
end;
|
||||
PRGB565Pair = ^TRGB565Pair;
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,92 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CONFIG>
|
||||
<ProjectOptions>
|
||||
<Version Value="12"/>
|
||||
<PathDelim Value="\"/>
|
||||
<General>
|
||||
<Flags>
|
||||
<MainUnitHasCreateFormStatements Value="False"/>
|
||||
<MainUnitHasTitleStatement Value="False"/>
|
||||
<MainUnitHasScaledStatement Value="False"/>
|
||||
</Flags>
|
||||
<SessionStorage Value="InProjectDir"/>
|
||||
<Title Value="WASURO"/>
|
||||
<UseAppBundle Value="False"/>
|
||||
<ResourceType Value="res"/>
|
||||
</General>
|
||||
<BuildModes>
|
||||
<Item Name="Default" Default="True"/>
|
||||
</BuildModes>
|
||||
<PublishOptions>
|
||||
<Version Value="2"/>
|
||||
<UseFileFilters Value="True"/>
|
||||
</PublishOptions>
|
||||
<RunParams>
|
||||
<FormatVersion Value="2"/>
|
||||
</RunParams>
|
||||
<Units>
|
||||
<Unit>
|
||||
<Filename Value="WASURO.lpr"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="..\vm\vm.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="..\vm\vmtypes.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="..\vm\vmopcodes.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="..\vm\wasm.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="..\vm\wasm.parser.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="..\vm\wasm.test.binary.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="..\vm\wasm.leb128.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
<Version Value="11"/>
|
||||
<PathDelim Value="\"/>
|
||||
<Target>
|
||||
<Filename Value="..\..\bin\WASURO"/>
|
||||
</Target>
|
||||
<SearchPaths>
|
||||
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||
<OtherUnitFiles Value="..\emu;..\wasm;..\wasm\parser;..\wasm\parser\sections;..\wasm\test;..\wasm\types;..\wasm\vm"/>
|
||||
<UnitOutputDirectory Value="..\..\lib\$(TargetCPU)-$(TargetOS)"/>
|
||||
</SearchPaths>
|
||||
<Linking>
|
||||
<Debugging>
|
||||
<DebugInfoType Value="dsDwarf3"/>
|
||||
</Debugging>
|
||||
</Linking>
|
||||
</CompilerOptions>
|
||||
<Debugging>
|
||||
<Exceptions>
|
||||
<Item>
|
||||
<Name Value="EAbort"/>
|
||||
</Item>
|
||||
<Item>
|
||||
<Name Value="ECodetoolError"/>
|
||||
</Item>
|
||||
<Item>
|
||||
<Name Value="EFOpenError"/>
|
||||
</Item>
|
||||
</Exceptions>
|
||||
</Debugging>
|
||||
</CONFIG>
|
||||
@@ -0,0 +1,36 @@
|
||||
program WASURO;
|
||||
|
||||
uses
|
||||
sysutils,
|
||||
|
||||
console,
|
||||
|
||||
types,
|
||||
|
||||
wasm.types,
|
||||
wasm.parser,
|
||||
wasm.vm, wasm.test.binary,
|
||||
wasm.types.stack;
|
||||
|
||||
var
|
||||
Context : PWASMProcessContext;
|
||||
|
||||
begin
|
||||
writestringln('[main] Initializing VM');
|
||||
wasm.vm.init();
|
||||
|
||||
writestringln('[main] Parsing WASM Binary');
|
||||
Context:= wasm.parser.parse(@wasm.test.binary.TEST_BINARY_1[0], puint8(@wasm.test.binary.TEST_BINARY_1[0] + $26));
|
||||
|
||||
writestringln('[main] Running...');
|
||||
Context^.ExecutionState.Running:= true;
|
||||
while (wasm.vm.tick(Context)) do;
|
||||
writestringln('[main] Finished Execution');
|
||||
writestring('[main] Returns: ');
|
||||
while Context^.ExecutionState.Operand_Stack^.Top > 0 do begin
|
||||
write(wasm.types.stack.popi32(Context^.ExecutionState.Operand_Stack),', ');
|
||||
end;
|
||||
writeln();
|
||||
while true do sleep(1000);
|
||||
end.
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,19 @@
|
||||
unit wasm.parser.sections.customSection;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
types, lmemorymanager, console, leb128,
|
||||
wasm.types;
|
||||
|
||||
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext);
|
||||
|
||||
implementation
|
||||
|
||||
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext);
|
||||
begin
|
||||
writestring('[wasm.parser] Handle Section: Custom - Size: ');
|
||||
writeintlnWND(section_length, 0);
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,19 @@
|
||||
unit wasm.parser.sections.dataSection;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
types, lmemorymanager, console, leb128,
|
||||
wasm.types;
|
||||
|
||||
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext);
|
||||
|
||||
implementation
|
||||
|
||||
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext);
|
||||
begin
|
||||
writestring('[wasm.parser] Handle Section: Data - Size: ');
|
||||
writeintlnWND(section_length, 0);
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,19 @@
|
||||
unit wasm.parser.sections.elementSection;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
types, lmemorymanager, console, leb128,
|
||||
wasm.types;
|
||||
|
||||
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext);
|
||||
|
||||
implementation
|
||||
|
||||
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext);
|
||||
begin
|
||||
writestring('[wasm.parser] Handle Section: Element - Size: ');
|
||||
writeintlnWND(section_length, 0);
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,92 @@
|
||||
unit wasm.parser.sections.exportSection;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
types, lmemorymanager, console, leb128,
|
||||
wasm.types;
|
||||
|
||||
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext);
|
||||
|
||||
implementation
|
||||
|
||||
procedure walk(ctx : PWASMProcessContext);
|
||||
var
|
||||
currentEntry : PWASMExportEntry;
|
||||
i : uint32;
|
||||
|
||||
begin
|
||||
// Walk the export entries
|
||||
for i:=1 to ctx^.Sections.ExportSection^.ExportCount do begin
|
||||
currentEntry:= @ctx^.Sections.ExportSection^.Entries[i - 1];
|
||||
writestring('[wasm.parser] Export: ');
|
||||
writestring(currentEntry^.Name);
|
||||
writestring(' - Type: ');
|
||||
writestring(GetWasmExportTypeString(currentEntry^.ExportType));
|
||||
writestring(' - Index: ');
|
||||
writeintlnWND(currentEntry^.FunctionIndex, 0);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext);
|
||||
var
|
||||
pos, bend : puint8;
|
||||
bytesRead : uint8;
|
||||
currentEntry : PWASMExportEntry;
|
||||
i,j : uint32;
|
||||
|
||||
begin
|
||||
writestring('[wasm.parser] Handle Section: Export - Size: ');
|
||||
writeintlnWND(section_length, 0);
|
||||
|
||||
// Initialize the read/end pointers
|
||||
pos:= buffer;
|
||||
bend:= puint8(pos + section_length);
|
||||
|
||||
// Initialize the export section
|
||||
ctx^.Sections.ExportSection:= PWASMExportSection(kalloc(sizeof(TWASMExportSection)));
|
||||
|
||||
// Read the number of functions
|
||||
bytesRead:= read_leb128_to_uint32(pos, bend, @ctx^.Sections.ExportSection^.ExportCount);
|
||||
inc(pos, bytesRead);
|
||||
|
||||
// Read the export entries
|
||||
if(ctx^.Sections.ExportSection^.ExportCount > 0) then begin
|
||||
// Allocate the first export entry
|
||||
ctx^.Sections.ExportSection^.Entries:= PWASMExportEntry(kalloc(sizeof(TWASMExportEntry) * ctx^.Sections.ExportSection^.ExportCount));
|
||||
|
||||
// Read the export entries
|
||||
for i:=1 to ctx^.Sections.ExportSection^.ExportCount do begin
|
||||
|
||||
// set the current entry
|
||||
currentEntry:= @ctx^.Sections.ExportSection^.Entries[i - 1];
|
||||
|
||||
// Check if we are at the end of the buffer
|
||||
if pos >= bend then Exit;
|
||||
|
||||
// Read the name length
|
||||
bytesRead:= read_leb128_to_uint32(pos, bend, @currentEntry^.NameLength);
|
||||
inc(pos, bytesRead);
|
||||
|
||||
// Read the export name
|
||||
currentEntry^.Name:= pchar(kalloc(currentEntry^.NameLength + 1));
|
||||
for j:=0 to currentEntry^.NameLength - 1 do begin
|
||||
currentEntry^.Name[j]:= char(pos^);
|
||||
inc(pos);
|
||||
end;
|
||||
currentEntry^.Name[currentEntry^.NameLength]:= char($00);
|
||||
|
||||
// Read the export type
|
||||
currentEntry^.ExportType:= TWasmExportType(pos^);
|
||||
inc(pos);
|
||||
|
||||
// Read the export index
|
||||
bytesRead:= read_leb128_to_uint32(pos, bend, @currentEntry^.FunctionIndex);
|
||||
inc(pos, bytesRead);
|
||||
end;
|
||||
end;
|
||||
|
||||
walk(ctx);
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,71 @@
|
||||
unit wasm.parser.sections.functionSection;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
types, lmemorymanager, console, leb128,
|
||||
wasm.types;
|
||||
|
||||
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext);
|
||||
|
||||
implementation
|
||||
|
||||
procedure walk(ctx : PWASMProcessContext);
|
||||
var
|
||||
currentFunc : PWASMFunction;
|
||||
i : uint32;
|
||||
|
||||
begin
|
||||
// Walk the functions
|
||||
for i:=1 to ctx^.Sections.FunctionSection^.FunctionCount do begin
|
||||
currentFunc:= @ctx^.Sections.FunctionSection^.Functions[i - 1];
|
||||
writestring('[wasm.parser] Function: ');
|
||||
writeintlnWND(currentFunc^.Index, 0);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext);
|
||||
var
|
||||
pos, bend : puint8;
|
||||
bytesRead : uint8;
|
||||
currentFunc : PWASMFunction;
|
||||
i : uint32;
|
||||
|
||||
begin
|
||||
writestring('[wasm.parser] Handle Section: Function - Size: ');
|
||||
writeintlnWND(section_length, 0);
|
||||
|
||||
// Initialize the read/end pointers
|
||||
pos:= buffer;
|
||||
bend:= puint8(pos + section_length);
|
||||
|
||||
// Initialize the function section
|
||||
ctx^.Sections.FunctionSection:= PWASMFunctionSection(kalloc(sizeof(TWASMFunctionSection)));
|
||||
ctx^.Sections.FunctionSection^.FunctionCount:= 0;
|
||||
ctx^.Sections.FunctionSection^.Functions:= nil;
|
||||
|
||||
// Read the number of functions
|
||||
bytesRead:= read_leb128_to_uint32(pos, bend, @ctx^.Sections.FunctionSection^.FunctionCount);
|
||||
inc(pos, bytesRead);
|
||||
|
||||
// Read the functions
|
||||
if ctx^.Sections.FunctionSection^.FunctionCount > 0 then begin
|
||||
// Bounds check
|
||||
if pos >= bend then Exit;
|
||||
|
||||
// Allocate the first function
|
||||
ctx^.Sections.FunctionSection^.Functions:= PWASMFunction(kalloc(sizeof(TWASMFunction) * ctx^.Sections.FunctionSection^.FunctionCount));
|
||||
|
||||
// Read the functions
|
||||
for i:=1 to ctx^.Sections.FunctionSection^.FunctionCount do begin
|
||||
currentFunc:= @ctx^.Sections.FunctionSection^.Functions[i - 1];
|
||||
if pos >= bend then Exit;
|
||||
bytesRead:= read_leb128_to_uint32(pos, bend, @currentFunc^.Index);
|
||||
inc(pos, bytesRead);
|
||||
end;
|
||||
end;
|
||||
|
||||
walk(ctx);
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,19 @@
|
||||
unit wasm.parser.sections.globalSection;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
types, lmemorymanager, console, leb128,
|
||||
wasm.types;
|
||||
|
||||
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext);
|
||||
|
||||
implementation
|
||||
|
||||
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext);
|
||||
begin
|
||||
writestring('[wasm.parser] Handle Section: Global - Size: ');
|
||||
writeintlnWND(section_length, 0);
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,19 @@
|
||||
unit wasm.parser.sections.importSection;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
types, lmemorymanager, console, leb128,
|
||||
wasm.types;
|
||||
|
||||
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext);
|
||||
|
||||
implementation
|
||||
|
||||
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext);
|
||||
begin
|
||||
writestring('[wasm.parser] Handle Section: Import - Size: ');
|
||||
writeintlnWND(section_length, 0);
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,19 @@
|
||||
unit wasm.parser.sections.memorySection;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
types, lmemorymanager, console, leb128,
|
||||
wasm.types;
|
||||
|
||||
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext);
|
||||
|
||||
implementation
|
||||
|
||||
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext);
|
||||
begin
|
||||
writestring('[wasm.parser] Handle Section: Memory - Size: ');
|
||||
writeintlnWND(section_length, 0);
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,19 @@
|
||||
unit wasm.parser.sections.startSection;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
types, lmemorymanager, console, leb128,
|
||||
wasm.types;
|
||||
|
||||
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext);
|
||||
|
||||
implementation
|
||||
|
||||
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext);
|
||||
begin
|
||||
writestring('[wasm.parser] Handle Section: Start - Size: ');
|
||||
writeintlnWND(section_length, 0);
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,19 @@
|
||||
unit wasm.parser.sections.tableSection;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
types, lmemorymanager, console, leb128,
|
||||
wasm.types;
|
||||
|
||||
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext);
|
||||
|
||||
implementation
|
||||
|
||||
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext);
|
||||
begin
|
||||
writestring('[wasm.parser] Handle Section: Table - Size: ');
|
||||
writeintlnWND(section_length, 0);
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,124 @@
|
||||
unit wasm.parser.sections.typeSection;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
types, lmemorymanager, console, leb128,
|
||||
wasm.types;
|
||||
|
||||
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext);
|
||||
|
||||
implementation
|
||||
|
||||
procedure walk(ctx : PWASMProcessContext);
|
||||
var
|
||||
currentType : PWASMType;
|
||||
currentParam : PWASMParam;
|
||||
i,j : uint32;
|
||||
|
||||
begin
|
||||
// Walk the types
|
||||
for i:=1 to ctx^.Sections.TypeSection^.TypeCount do begin
|
||||
currentType:= @ctx^.Sections.TypeSection^.Types[i - 1];
|
||||
writestring('[wasm.parser] Index: ');
|
||||
writeintWND(i-1, 0);
|
||||
writestring(' - Function Type: ');
|
||||
writehexpair(currentType^._type);
|
||||
writestringln(' ');
|
||||
|
||||
writestring('[wasm.parser] Param Count: ');
|
||||
writeintlnWND(currentType^.ParamCount, 0);
|
||||
// Walk the parameters
|
||||
if(currentType^.ParamCount > 0) then begin
|
||||
for j:=1 to currentType^.ParamCount do begin
|
||||
currentParam:= @currentType^.ParamTypes[j - 1];
|
||||
writestring('[wasm.parser] Param Type: ');
|
||||
writestringln(GetWasmValueTypeString(currentParam^.ValueType));
|
||||
end;
|
||||
end;
|
||||
|
||||
// Walk the return values
|
||||
writestring('[wasm.parser] Return Count: ');
|
||||
writeintlnWND(currentType^.ReturnCount, 0);
|
||||
if(currentType^.ReturnCount > 0) then begin
|
||||
for j:=1 to currentType^.ReturnCount do begin
|
||||
currentParam:= @currentType^.ReturnTypes[j - 1];
|
||||
writestring('[wasm.parser] Return Type: ');
|
||||
writestringln(GetWasmValueTypeString(currentParam^.ValueType));
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure handle(buffer: puint8; section_length: uint32; ctx: PWASMProcessContext);
|
||||
var
|
||||
pos : puint8;
|
||||
bytesRead : uint8;
|
||||
currentType : PWASMType;
|
||||
currentParam : PWASMParam;
|
||||
i, parsedTypes : uint32;
|
||||
|
||||
begin
|
||||
writestring('[wasm.parser] Handle Section: Type - Size: ');
|
||||
writeintlnWND(section_length, 0);
|
||||
pos:= buffer;
|
||||
|
||||
// Initialize the type section
|
||||
ctx^.Sections.TypeSection:= PWASMTypeSection(kalloc(sizeof(TWASMTypeSection)));
|
||||
ctx^.Sections.TypeSection^.TypeCount:= 0;
|
||||
|
||||
// Read the number of function types
|
||||
bytesRead:= read_leb128_to_uint32(buffer, puint8(buffer + section_length), @ctx^.Sections.TypeSection^.TypeCount);
|
||||
inc(pos, bytesRead);
|
||||
|
||||
// Read the function types
|
||||
if(ctx^.Sections.TypeSection^.TypeCount > 0) then begin
|
||||
// Allocate the first type
|
||||
ctx^.Sections.TypeSection^.Types:= PWASMType(kalloc(sizeof(TWASMType) * ctx^.Sections.TypeSection^.TypeCount));
|
||||
|
||||
// Read the function types
|
||||
for parsedTypes:=1 to ctx^.Sections.TypeSection^.TypeCount do begin
|
||||
currentType:= @ctx^.Sections.TypeSection^.Types[parsedTypes - 1];
|
||||
|
||||
// Check if we are at the end of the buffer
|
||||
if pos >= puint8(buffer + section_length) then Exit;
|
||||
|
||||
// Read the function type
|
||||
currentType^._type:= pos^;
|
||||
inc(pos);
|
||||
|
||||
// Read the number of parameters
|
||||
bytesRead:= read_leb128_to_uint32(pos, puint8(buffer + section_length), @currentType^.ParamCount);
|
||||
inc(pos, bytesRead);
|
||||
|
||||
// Read the parameter types
|
||||
if(currentType^.ParamCount > 0) then begin
|
||||
currentType^.ParamTypes:= PWASMParam(kalloc(sizeof(TWASMParam) * currentType^.ParamCount));
|
||||
for i:=1 to currentType^.ParamCount do begin
|
||||
currentParam:= @currentType^.ParamTypes[i - 1];
|
||||
currentParam^.ValueType:= TWasmValueType(pos^);
|
||||
inc(pos);
|
||||
end;
|
||||
end;
|
||||
|
||||
// Read the number of return values
|
||||
bytesRead:= read_leb128_to_uint32(pos, puint8(buffer + section_length), @currentType^.ReturnCount);
|
||||
inc(pos, bytesRead);
|
||||
|
||||
// Read the return types
|
||||
if(currentType^.ReturnCount > 0) then begin
|
||||
currentType^.ReturnTypes:= PWASMParam(kalloc(sizeof(TWASMParam) * currentType^.ReturnCount));
|
||||
for i:=1 to currentType^.ReturnCount do begin
|
||||
currentParam:= @currentType^.ReturnTypes[i - 1];
|
||||
currentParam^.ValueType:= TWasmValueType(pos^);
|
||||
inc(pos);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
// Walk the types
|
||||
walk(ctx);
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,99 @@
|
||||
unit wasm.parser;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
types, lmemorymanager, console, leb128,
|
||||
wasm.types, wasm.types.heap, wasm.types.stack,
|
||||
wasm.parser.sections;
|
||||
|
||||
function parse(buffer: puint8; buffer_end: puint8) : PWASMProcessContext;
|
||||
|
||||
implementation
|
||||
|
||||
function newContext() : PWASMProcessContext;
|
||||
var
|
||||
ctx : PWASMProcessContext;
|
||||
|
||||
begin
|
||||
// Allocate the context
|
||||
ctx:= PWASMProcessContext(kalloc(SizeOf(TWASMProcessContext)));
|
||||
|
||||
// Initialize the context
|
||||
ctx^.ValidBinary:= false;
|
||||
ctx^.Version:= 0;
|
||||
|
||||
// Initialize the execution state
|
||||
ctx^.ExecutionState.Memory:= wasm.types.heap.new_heap();
|
||||
ctx^.ExecutionState.Control_Stack:= wasm.types.stack.newDefaultStack();
|
||||
ctx^.ExecutionState.Operand_Stack:= wasm.types.stack.newDefaultStack();
|
||||
|
||||
// Initialize the IP
|
||||
ctx^.ExecutionState.IP:= 0;
|
||||
|
||||
// Set not running initially
|
||||
ctx^.ExecutionState.Running:= false;
|
||||
|
||||
// Initialize the sections
|
||||
ctx^.Sections.TypeSection:= nil;
|
||||
ctx^.Sections.FunctionSection:= nil;
|
||||
ctx^.Sections.ExportSection:= nil;
|
||||
ctx^.Sections.CodeSection:= nil;
|
||||
|
||||
newContext:= ctx;
|
||||
end;
|
||||
|
||||
function parse(buffer: puint8; buffer_end: puint8): PWASMProcessContext;
|
||||
var
|
||||
ctx : PWASMProcessContext;
|
||||
pos : puint8;
|
||||
bytesRead : uint8;
|
||||
section_id : uint8;
|
||||
section_length : uint32;
|
||||
|
||||
begin
|
||||
// Allocate the context
|
||||
ctx:= newContext();
|
||||
pos:= buffer;
|
||||
|
||||
writestringln('[wasm.parser] Parsing WASM Binary');
|
||||
|
||||
// Check for the WASM Magic
|
||||
if(puint32(pos)^ = wasm.types.WASM_HDR_MAGIC) then begin
|
||||
writestringln('[wasm.parser] Binary is valid.');
|
||||
|
||||
// Set binary to valid
|
||||
ctx^.ValidBinary:= true;
|
||||
inc(pos, 4);
|
||||
|
||||
// Read the version
|
||||
ctx^.Version:= puint32(pos)^;
|
||||
inc(pos, 4);
|
||||
writestring('[wasm.parser] Version: ');
|
||||
writeintlnWND(ctx^.Version, 0);
|
||||
|
||||
// Read the sections
|
||||
while (pos < buffer_end) do begin
|
||||
// Read the section id
|
||||
section_id:= pos^;
|
||||
inc(pos);
|
||||
|
||||
// Read the section length
|
||||
bytesRead:= read_leb128_to_uint32(pos, buffer_end, @section_length);
|
||||
Inc(pos, bytesRead);
|
||||
|
||||
// Handle the section
|
||||
wasm.parser.sections.handle(section_id, pos, section_length, ctx);
|
||||
|
||||
// Move to the next section
|
||||
Inc(pos, section_length);
|
||||
end;
|
||||
end else begin
|
||||
writeln('[wasm.parser] Binary missing WASM Magic!');
|
||||
ctx^.ValidBinary:= false;
|
||||
end;
|
||||
parse:= ctx;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
Loaded 20 of 29 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user