job: renamed wasidom to job

This commit is contained in:
mattias 2022-05-24 19:15:29 +02:00
parent 1bd4ed47ad
commit 7093865f5b
8 changed files with 274 additions and 265 deletions

View File

@ -41,7 +41,7 @@
</CustomData>
</Unit>
<Unit>
<Filename Value="wadom_browser.pp"/>
<Filename Value="job_browser.pp"/>
<IsPartOfProject Value="True"/>
</Unit>
</Units>

View File

@ -4,7 +4,7 @@ program BrowserDomTest1;
uses
BrowserConsole, BrowserApp, JS, Classes, SysUtils, Web, WebAssembly, Types,
wasienv, wadom_browser, wadom_shared;
wasienv, job_browser, job_shared;
Type
@ -29,7 +29,7 @@ Type
FWasiEnv: TPas2JSWASIEnvironment;
FMemory : TJSWebAssemblyMemory; // Memory of webassembly
FTable : TJSWebAssemblyTable; // Table of exported functions
FWADomBridge : TWADomBridge;
FWADomBridge : TJOBBridge;
function CreateWebAssembly(Path: string; ImportObject: TJSObject
): TJSPromise;
procedure DoWrite(Sender: TObject; const aOutput: String);
@ -133,7 +133,7 @@ begin
FWasiEnv:=TPas2JSWASIEnvironment.Create;
FWasiEnv.OnStdErrorWrite:=@DoWrite;
FWasiEnv.OnStdOutputWrite:=@DoWrite;
FWADomBridge:=TWADomBridge.Create(FWasiEnv);
FWADomBridge:=TJOBBridge.Create(FWasiEnv);
if FWADomBridge.RegisterGlobalObject(TJSObject(TBird.Create('Root')))<>WasiObjIdBird then
raise Exception.Create('Root TBird wrong number');

View File

@ -29,7 +29,7 @@
<IsPartOfProject Value="True"/>
</Unit>
<Unit>
<Filename Value="wadom_wasm.pas"/>
<Filename Value="job_wasm.pas"/>
<IsPartOfProject Value="True"/>
</Unit>
</Units>

View File

@ -5,7 +5,7 @@ program WasiDomTest1;
{$codepage UTF8}
uses
SysUtils, wadom_wasm, wadom_shared;
SysUtils, JOB_WAsm, JOB_Shared;
type

View File

@ -1,40 +1,45 @@
unit wadom_browser;
{
JOB - JS Object Bridge for Webassembly
Browser side.
}
unit JOB_Browser;
{$mode objfpc}
interface
uses sysutils, types, js, web, wasienv, wadom_shared;
uses sysutils, types, js, web, wasienv, JOB_Shared;
Type
EWABridge = class(Exception);
EJOBBridge = class(Exception);
{ TWADomBridge }
{ TJOBBridge }
TWADomBridge = class(TImportExtension)
TJOBBridge = class(TImportExtension)
Private
FGlobalObjects: TJSArray;
FLocalObjects: TJSArray;
FFreeLocalIds: TJSArray; // free positions in FLocalObjects
FStringResult: string;
Protected
function FindObject(ObjId: TWasiDomObjectID): TJSObject; virtual;
function Invoke_JSResult(ObjId: TWasiDomObjectID; FuncNameP, FuncNameLen, ArgsP: NativeInt; out JSResult: JSValue): TWasiDomResult; virtual;
function Invoke_NoResult(ObjId: TWasiDomObjectID; FuncNameP, FuncNameLen, ArgsP, Dummy: NativeInt): TWasiDomResult; virtual;
function Invoke_BooleanResult(ObjId: TWasiDomObjectID; FuncNameP, FuncNameLen, ArgsP, ResultP: NativeInt): TWasiDomResult; virtual;
function Invoke_DoubleResult(ObjId: TWasiDomObjectID; FuncNameP, FuncNameLen, ArgsP, ResultP: NativeInt): TWasiDomResult; virtual;
function Invoke_StringResult(ObjId: TWasiDomObjectID; FuncNameP, FuncNameLen, ArgsP, ResultP: NativeInt): TWasiDomResult; virtual;
function Invoke_ObjectResult(ObjId: TWasiDomObjectID; FuncNameP, FuncNameLen, ArgsP, ResultP: NativeInt): TWasiDomResult; virtual;
function ReleaseObject(ObjId: TWasiDomObjectID): TWasiDomResult; virtual;
function GetStringResult(ResultP: NativeInt): TWasiDomResult; virtual;
function ReleaseStringResult: TWasiDomResult; virtual;
function FindObject(ObjId: TJOBObjectID): TJSObject; virtual;
function Invoke_JSResult(ObjId: TJOBObjectID; FuncNameP, FuncNameLen, ArgsP: NativeInt; out JSResult: JSValue): TJOBResult; virtual;
function Invoke_NoResult(ObjId: TJOBObjectID; FuncNameP, FuncNameLen, ArgsP, Dummy: NativeInt): TJOBResult; virtual;
function Invoke_BooleanResult(ObjId: TJOBObjectID; FuncNameP, FuncNameLen, ArgsP, ResultP: NativeInt): TJOBResult; virtual;
function Invoke_DoubleResult(ObjId: TJOBObjectID; FuncNameP, FuncNameLen, ArgsP, ResultP: NativeInt): TJOBResult; virtual;
function Invoke_StringResult(ObjId: TJOBObjectID; FuncNameP, FuncNameLen, ArgsP, ResultP: NativeInt): TJOBResult; virtual;
function Invoke_ObjectResult(ObjId: TJOBObjectID; FuncNameP, FuncNameLen, ArgsP, ResultP: NativeInt): TJOBResult; virtual;
function ReleaseObject(ObjId: TJOBObjectID): TJOBResult; virtual;
function GetStringResult(ResultP: NativeInt): TJOBResult; virtual;
function ReleaseStringResult: TJOBResult; virtual;
function GetInvokeArguments(View: TJSDataView; ArgsP: NativeInt): TJSValueDynArray; virtual;
function GetWasiDomResult(v: jsvalue): TWasiDomResult;
function GetJOBResult(v: jsvalue): TJOBResult;
Public
Constructor Create(aEnv: TPas2JSWASIEnvironment); override;
Procedure FillImportObject(aObject: TJSObject); override;
Function ImportName: String; override;
Function RegisterGlobalObject(Obj: TJSObject): TWasiDomObjectID; virtual;
Function RegisterGlobalObject(Obj: TJSObject): TJOBObjectID; virtual;
end;
Implementation
@ -44,41 +49,41 @@ asm
return String.fromCharCode.apply(null,a);
end;
constructor TWADomBridge.Create(aEnv: TPas2JSWASIEnvironment);
constructor TJOBBridge.Create(aEnv: TPas2JSWASIEnvironment);
begin
Inherited Create(aEnv);
FGlobalObjects:=TJSArray.new;
FGlobalObjects[-WasiObjIdDocument]:=document;
FGlobalObjects[-WasiObjIdWindow]:=window;
FGlobalObjects[-WasiObjIdConsole]:=console;
FGlobalObjects[-WasiObjIdCaches]:=caches;
FGlobalObjects[-JOBObjIdDocument]:=document;
FGlobalObjects[-JOBObjIdWindow]:=window;
FGlobalObjects[-JOBObjIdConsole]:=console;
FGlobalObjects[-JOBObjIdCaches]:=caches;
FLocalObjects:=TJSArray.new;
FFreeLocalIds:=TJSArray.new;
end;
function TWADomBridge.ImportName: String;
function TJOBBridge.ImportName: String;
begin
Result:=WasiDomExportName;
Result:=JOBExportName;
end;
function TWADomBridge.RegisterGlobalObject(Obj: TJSObject): TWasiDomObjectID;
function TJOBBridge.RegisterGlobalObject(Obj: TJSObject): TJOBObjectID;
begin
Result:=-(FGlobalObjects.push(Obj)-1);
end;
procedure TWADomBridge.FillImportObject(aObject: TJSObject);
procedure TJOBBridge.FillImportObject(aObject: TJSObject);
begin
aObject[WasiBridgeFn_InvokeNoResult]:=@Invoke_NoResult;
aObject[WasiBridgeFn_InvokeBooleanResult]:=@Invoke_BooleanResult;
aObject[WasiBridgeFn_InvokeDoubleResult]:=@Invoke_DoubleResult;
aObject[WasiBridgeFn_InvokeStringResult]:=@Invoke_StringResult;
aObject[WasiBridgeFn_GetStringResult]:=@GetStringResult;
aObject[WasiBridgeFn_ReleaseStringResult]:=@ReleaseStringResult;
aObject[WasiBridgeFn_InvokeObjectResult]:=@Invoke_ObjectResult;
aObject[WasiBridgeFn_ReleaseObject]:=@ReleaseObject;
aObject[JOBFn_InvokeNoResult]:=@Invoke_NoResult;
aObject[JOBFn_InvokeBooleanResult]:=@Invoke_BooleanResult;
aObject[JOBFn_InvokeDoubleResult]:=@Invoke_DoubleResult;
aObject[JOBFn_InvokeStringResult]:=@Invoke_StringResult;
aObject[JOBFn_GetStringResult]:=@GetStringResult;
aObject[JOBFn_ReleaseStringResult]:=@ReleaseStringResult;
aObject[JOBFn_InvokeObjectResult]:=@Invoke_ObjectResult;
aObject[JOBFn_ReleaseObject]:=@ReleaseObject;
end;
function TWADomBridge.FindObject(ObjId: TWasiDomObjectID): TJSObject;
function TJOBBridge.FindObject(ObjId: TJOBObjectID): TJSObject;
begin
if ObjId<0 then
Result:=TJSObject(FGlobalObjects[-ObjId])
@ -88,8 +93,8 @@ begin
Result:=nil;
end;
function TWADomBridge.Invoke_JSResult(ObjId: TWasiDomObjectID; FuncNameP,
FuncNameLen, ArgsP: NativeInt; out JSResult: JSValue): TWasiDomResult;
function TJOBBridge.Invoke_JSResult(ObjId: TJOBObjectID; FuncNameP,
FuncNameLen, ArgsP: NativeInt; out JSResult: JSValue): TJOBResult;
var
View: TJSDataView;
aBytes: TJSUint8Array;
@ -102,7 +107,7 @@ begin
Obj:=FindObject(ObjId);
if Obj=nil then
exit(WasiDomResult_UnknownObjId);
exit(JOBResult_UnknownObjId);
View:=getModuleMemoryDataView();
aBytes:=TJSUint8Array.New(View.buffer, FuncNameP, FuncNameLen);
@ -112,7 +117,7 @@ begin
fn:=Obj[FuncName];
if jstypeof(fn)<>'function' then
exit(WasiDomResult_NotAFunction);
exit(JOBResult_NotAFunction);
if ArgsP=0 then
JSResult:=TJSFunction(fn).call(Obj)
@ -121,11 +126,11 @@ begin
JSResult:=TJSFunction(fn).apply(Obj,Args);
end;
Result:=WasiDomResult_Success;
Result:=JOBResult_Success;
end;
function TWADomBridge.Invoke_NoResult(ObjId: TWasiDomObjectID; FuncNameP,
FuncNameLen, ArgsP, Dummy: NativeInt): TWasiDomResult;
function TJOBBridge.Invoke_NoResult(ObjId: TJOBObjectID; FuncNameP,
FuncNameLen, ArgsP, Dummy: NativeInt): TJOBResult;
var
JSResult: JSValue;
begin
@ -133,80 +138,80 @@ begin
Result:=Invoke_JSResult(ObjId,FuncNameP,FuncNameLen,ArgsP,JSResult);
end;
function TWADomBridge.Invoke_BooleanResult(ObjId: TWasiDomObjectID; FuncNameP,
FuncNameLen, ArgsP, ResultP: NativeInt): TWasiDomResult;
function TJOBBridge.Invoke_BooleanResult(ObjId: TJOBObjectID; FuncNameP,
FuncNameLen, ArgsP, ResultP: NativeInt): TJOBResult;
var
JSResult: JSValue;
b: byte;
begin
// invoke
Result:=Invoke_JSResult(ObjId,FuncNameP,FuncNameLen,ArgsP,JSResult);
if Result<>WasiDomResult_Success then
if Result<>JOBResult_Success then
exit;
// check result type
if jstypeof(JSResult)<>'boolean' then
exit(GetWasiDomResult(JSResult));
exit(GetJOBResult(JSResult));
if JSResult then
b:=1
else
b:=0;
// set result
getModuleMemoryDataView().setUint8(ResultP, b);
Result:=WasiDomResult_Boolean;
Result:=JOBResult_Boolean;
end;
function TWADomBridge.Invoke_DoubleResult(ObjId: TWasiDomObjectID; FuncNameP,
FuncNameLen, ArgsP, ResultP: NativeInt): TWasiDomResult;
function TJOBBridge.Invoke_DoubleResult(ObjId: TJOBObjectID; FuncNameP,
FuncNameLen, ArgsP, ResultP: NativeInt): TJOBResult;
var
JSResult: JSValue;
begin
// invoke
Result:=Invoke_JSResult(ObjId,FuncNameP,FuncNameLen,ArgsP,JSResult);
if Result<>WasiDomResult_Success then
if Result<>JOBResult_Success then
exit;
// check result type
if jstypeof(JSResult)<>'number' then
exit(GetWasiDomResult(JSResult));
exit(GetJOBResult(JSResult));
// set result
getModuleMemoryDataView().setFloat64(ResultP, double(JSResult), env.IsLittleEndian);
Result:=WasiDomResult_Double;
Result:=JOBResult_Double;
end;
function TWADomBridge.Invoke_StringResult(ObjId: TWasiDomObjectID; FuncNameP,
FuncNameLen, ArgsP, ResultP: NativeInt): TWasiDomResult;
function TJOBBridge.Invoke_StringResult(ObjId: TJOBObjectID; FuncNameP,
FuncNameLen, ArgsP, ResultP: NativeInt): TJOBResult;
var
JSResult: JSValue;
begin
// invoke
Result:=Invoke_JSResult(ObjId,FuncNameP,FuncNameLen,ArgsP,JSResult);
if Result<>WasiDomResult_Success then
if Result<>JOBResult_Success then
exit;
// check result type
if jstypeof(JSResult)<>'string' then
exit(GetWasiDomResult(JSResult));
Result:=WasiDomResult_String;
exit(GetJOBResult(JSResult));
Result:=JOBResult_String;
FStringResult:=String(JSResult);
// set result length
getModuleMemoryDataView().setInt32(ResultP, length(FStringResult), env.IsLittleEndian);
end;
function TWADomBridge.Invoke_ObjectResult(ObjId: TWasiDomObjectID; FuncNameP,
FuncNameLen, ArgsP, ResultP: NativeInt): TWasiDomResult;
function TJOBBridge.Invoke_ObjectResult(ObjId: TJOBObjectID; FuncNameP,
FuncNameLen, ArgsP, ResultP: NativeInt): TJOBResult;
var
t: String;
JSResult, NewId: JSValue;
begin
// invoke
Result:=Invoke_JSResult(ObjId,FuncNameP,FuncNameLen,ArgsP,JSResult);
if Result<>WasiDomResult_Success then
if Result<>JOBResult_Success then
exit;
// check result type
t:=jstypeof(JSResult);
if (t<>'object') and (t<>'function') then
exit(GetWasiDomResult(JSResult));
exit(GetJOBResult(JSResult));
if JSResult=nil then
exit(WasiDomResult_Null);
exit(JOBResult_Null);
// create Id
NewId:=FFreeLocalIds.pop;
@ -217,29 +222,29 @@ begin
// set result
getModuleMemoryDataView().setUint32(ResultP, longword(NewId), env.IsLittleEndian);
Result:=WasiDomResult_Object;
Result:=JOBResult_Object;
end;
function TWADomBridge.ReleaseObject(ObjId: TWasiDomObjectID): TWasiDomResult;
function TJOBBridge.ReleaseObject(ObjId: TJOBObjectID): TJOBResult;
begin
writeln('TWADomBridge.ReleaseObject ',ObjId);
if ObjId<0 then
raise EWABridge.Create('cannot release a global object');
raise EJOBBridge.Create('cannot release a global object');
if ObjId>=FLocalObjects.Length then
raise EWABridge.Create('cannot release unknown object');
raise EJOBBridge.Create('cannot release unknown object');
if FLocalObjects[ObjId]=nil then
raise EWABridge.Create('object already released');
raise EJOBBridge.Create('object already released');
FLocalObjects[ObjId]:=nil;
FFreeLocalIds.push(ObjId);
Result:=WasiDomResult_Success;
Result:=JOBResult_Success;
end;
function TWADomBridge.GetStringResult(ResultP: NativeInt): TWasiDomResult;
function TJOBBridge.GetStringResult(ResultP: NativeInt): TJOBResult;
var
View: TJSDataView;
l, i: SizeInt;
begin
Result:=WasiDomResult_Success;
Result:=JOBResult_Success;
l:=length(FStringResult);
if l=0 then exit;
View:=getModuleMemoryDataView();
@ -248,13 +253,13 @@ begin
FStringResult:='';
end;
function TWADomBridge.ReleaseStringResult: TWasiDomResult;
function TJOBBridge.ReleaseStringResult: TJOBResult;
begin
Result:=WasiDomResult_Success;
Result:=JOBResult_Success;
FStringResult:='';
end;
function TWADomBridge.GetInvokeArguments(View: TJSDataView; ArgsP: NativeInt
function TJOBBridge.GetInvokeArguments(View: TJSDataView; ArgsP: NativeInt
): TJSValueDynArray;
var
Cnt, aType: Byte;
@ -272,26 +277,26 @@ begin
aType:=View.getUInt8(p);
inc(p);
case aType of
WasiArgLongint:
JOBArgLongint:
begin
Result[i]:=View.getInt32(p,env.IsLittleEndian);
inc(p,4);
end;
WasiArgDouble:
JOBArgDouble:
begin
Result[i]:=View.getFloat64(p,env.IsLittleEndian);
inc(p,8);
end;
WasiArgTrue:
JOBArgTrue:
Result[i]:=true;
WasiArgFalse:
JOBArgFalse:
Result[i]:=false;
WasiArgChar:
JOBArgChar:
begin
Result[i]:=chr(View.getUint16(p,env.IsLittleEndian));
inc(p,2);
end;
WasiArgUTF8String:
JOBArgUTF8String:
begin
Len:=View.getUint32(p,env.IsLittleEndian);
inc(p,4);
@ -300,7 +305,7 @@ begin
aBytes:=TJSUint8Array.New(View.buffer, Ptr,Len);
Result[i]:=TypedArrayToString(aBytes);
end;
WasiArgUnicodeString:
JOBArgUnicodeString:
begin
Len:=View.getUint32(p,env.IsLittleEndian);
inc(p,4);
@ -309,7 +314,7 @@ begin
aWords:=TJSUint16Array.New(View.buffer, Ptr,Len);
Result[i]:=TypedArrayToString(aWords);
end;
WasiArgPointer:
JOBArgPointer:
begin
Result[i]:=View.getUint32(p,env.IsLittleEndian);
inc(p,4);
@ -321,18 +326,18 @@ begin
end;
end;
function TWADomBridge.GetWasiDomResult(v: jsvalue): TWasiDomResult;
function TJOBBridge.GetJOBResult(v: jsvalue): TJOBResult;
begin
case jstypeof(v) of
'undefined': Result:=WasiDomResult_Undefined;
'boolean': Result:=WasiDomResult_Boolean;
'number': Result:=WasiDomResult_Number;
'string': Result:=WasiDomResult_String;
'symbol': Result:=WasiDomResult_Symbol;
'bigint': Result:=WasiDomResult_BigInt;
'function': Result:=WasiDomResult_Function;
'object': if v=nil then Result:=WasiDomResult_Null else Result:=WasiDomResult_Object;
else Result:=WasiDomResult_None;
'undefined': Result:=JOBResult_Undefined;
'boolean': Result:=JOBResult_Boolean;
'number': Result:=JOBResult_Number;
'string': Result:=JOBResult_String;
'symbol': Result:=JOBResult_Symbol;
'bigint': Result:=JOBResult_BigInt;
'function': Result:=JOBResult_Function;
'object': if v=nil then Result:=JOBResult_Null else Result:=JOBResult_Object;
else Result:=JOBResult_None;
end;
end;

View File

@ -0,0 +1,80 @@
{
JOB - JS Object Bridge for Webassembly
These types and constants are shared between pas2js and webassembly.
}
unit JOB_Shared;
interface
type
TJOBObjectID = NativeInt;
// invoke results
type
TJOBResult = longint;
const
JOBResult_None = 0;
JOBResult_Success = 1;
JOBResult_UnknownObjId = 2;
JOBResult_NotAFunction = 3;
JOBResult_Undefined = 4;
JOBResult_Null = 5;
JOBResult_Boolean = 6;
JOBResult_Number = 7;
JOBResult_Double = 8;
JOBResult_String = 9;
JOBResult_Function = 10;
JOBResult_Object = 11;
JOBResult_BigInt = 12;
JOBResult_Symbol = 13;
JOBResultLast = 13;
JOBResult_Names: array[0..JOBResultLast] of string = (
'None',
'Success',
'UnknownObjId',
'NotAFunction',
'Undefined',
'Null',
'Boolean',
'Number',
'Double',
'String',
'Function',
'Object',
'BigInt',
'Symbol'
);
JOBExportName = 'job';
JOBFn_InvokeNoResult = 'invoke_noresult';
JOBFn_InvokeBooleanResult = 'invoke_boolresult';
JOBFn_InvokeDoubleResult = 'invoke_doubleresult';
JOBFn_InvokeStringResult = 'invoke_stringresult';
JOBFn_GetStringResult = 'get_stringresult';
JOBFn_ReleaseStringResult = 'release_stringresult';
JOBFn_InvokeObjectResult = 'invoke_objectresult';
JOBFn_ReleaseObject = 'release_object';
JOBArgNone = 0;
JOBArgLongint = 1;
JOBArgDouble = 2;
JOBArgTrue = 3;
JOBArgFalse = 4;
JOBArgChar = 5; // followed by a word
JOBArgUTF8String = 6; // followed by length and pointer
JOBArgUnicodeString = 7; // followed by length and pointer
JOBArgPointer = 8;
JOBObjIdDocument = -1;
JOBObjIdWindow = -2;
JOBObjIdConsole = -3;
JOBObjIdCaches = -4;
WasiObjIdBird = -5;
implementation
end.

View File

@ -1,18 +1,20 @@
{
JOB - JS Object Bridge for Webassembly
Webassembly unit giving access to the browser DOM.
see https://wiki.freepascal.org/WebAssembly/DOM
}
unit wadom_wasm;
unit JOB_WAsm;
{$mode ObjFPC}{$H+}
{$define VerboseWasiDom}
{$define VerboseJOB}
interface
uses
SysUtils, Types, Math, Classes, wadom_shared;
SysUtils, Types, Math, Classes, JOB_Shared;
const
MinSafeIntDouble = -$1fffffffffffff; // -9007199254740991 54 bits (52 plus signed bit plus implicit highest bit)
@ -22,18 +24,18 @@ Type
EJSObject = class(Exception);
EJSInvoke = class(EJSObject)
public
ObjectID: TWasiDomObjectID;
ObjectID: TJOBObjectID;
FuncName: string;
end;
PWasiDomObjectID = ^TWasiDomObjectID;
TWasiDomInvokeOneResultFunc = function(
ObjID: TWasiDomObjectID;
PJOBObjectID = ^TJOBObjectID;
TJOBInvokeOneResultFunc = function(
ObjID: TJOBObjectID;
FuncNameP: PChar;
FuncNameLen: longint;
ArgP: PByte;
ResultP: PByte
): TWasiDomResult;
): TJOBResult;
TJSObject = class;
TJSObjectClass = class of TJSObject;
@ -42,17 +44,17 @@ Type
TJSObject = class(TInterfacedObject)
private
FObjectID: TWasiDomObjectID;
FObjectID: TJOBObjectID;
protected
function InvokeJSOneResult(const aName: string; Const Args: Array of const;
const InvokeFunc: TWasiDomInvokeOneResultFunc; ResultP: PByte): TWasiDomResult;
procedure WasiInvokeRaise(const aName, Msg: string); virtual;
procedure WasiInvokeRaiseResultMismatch(const aName: string; Expected, Actual: TWasiDomResult); virtual;
const InvokeFunc: TJOBInvokeOneResultFunc; ResultP: PByte): TJOBResult;
procedure InvokeRaise(const aName, Msg: string); virtual;
procedure InvokeRaiseResultMismatch(const aName: string; Expected, Actual: TJOBResult); virtual;
function CreateInvokeJSArgs(const Args: array of const): PByte; virtual;
public
constructor CreateFromID(aID: TWasiDomObjectID); virtual;
constructor CreateFromID(aID: TJOBObjectID); virtual;
destructor Destroy; override;
property ObjectID: TWasiDomObjectID read FObjectID;
property ObjectID: TJOBObjectID read FObjectID;
procedure InvokeJSNoResult(const aName: string; Const Args: Array of const);
function InvokeJSBooleanResult(const aName: string; Const Args: Array of const): Boolean;
function InvokeJSDoubleResult(const aName: string; Const Args: Array of const): Double;
@ -65,60 +67,60 @@ Type
var
JSDocument: TJSObject; // ToDo
function __wasibridgefn_invoke_noresult(
ObjID: TWasiDomObjectID;
function __job_invoke_noresult(
ObjID: TJOBObjectID;
FuncNameP: PChar;
FuncNameLen: longint;
ArgP: PByte;
Dummy: PByte
): TWasiDomResult; external WasiDomExportName name WasiBridgeFn_InvokeNoResult;
): TJOBResult; external JOBExportName name JOBFn_InvokeNoResult;
function __wasibridgefn_invoke_boolresult(
ObjID: TWasiDomObjectID;
function __job_invoke_boolresult(
ObjID: TJOBObjectID;
FuncNameP: PChar;
FuncNameLen: longint;
ArgP: PByte;
ResultP: PByte // bytebool
): TWasiDomResult; external WasiDomExportName name WasiBridgeFn_InvokeBooleanResult;
): TJOBResult; external JOBExportName name JOBFn_InvokeBooleanResult;
function __wasibridgefn_invoke_doubleresult(
ObjID: TWasiDomObjectID;
function __job_invoke_doubleresult(
ObjID: TJOBObjectID;
FuncNameP: PChar;
FuncNameLen: longint;
ArgP: PByte;
ResultP: PByte // double
): TWasiDomResult; external WasiDomExportName name WasiBridgeFn_InvokeDoubleResult;
): TJOBResult; external JOBExportName name JOBFn_InvokeDoubleResult;
function __wasibridgefn_invoke_stringresult(
ObjID: TWasiDomObjectID;
function __job_invoke_stringresult(
ObjID: TJOBObjectID;
FuncNameP: PChar;
FuncNameLen: longint;
ArgP: PByte;
ResultLenP: PByte // length
): TWasiDomResult; external WasiDomExportName name WasiBridgeFn_InvokeStringResult;
): TJOBResult; external JOBExportName name JOBFn_InvokeStringResult;
function __wasibridgefn_getstringresult(
function __job_getstringresult(
ResultP: PByte
): TWasiDomResult; external WasiDomExportName name WasiBridgeFn_GetStringResult;
): TJOBResult; external JOBExportName name JOBFn_GetStringResult;
function __wasibridgefn_releasestringresult(
): TWasiDomResult; external WasiDomExportName name WasiBridgeFn_ReleaseStringResult;
function __job_releasestringresult(
): TJOBResult; external JOBExportName name JOBFn_ReleaseStringResult;
function __wasibridgefn_invoke_objectresult(
ObjID: TWasiDomObjectID;
function __job_invoke_objectresult(
ObjID: TJOBObjectID;
FuncNameP: PChar;
FuncNameLen: longint;
ArgP: PByte;
ResultP: PByte // nativeint
): TWasiDomResult; external WasiDomExportName name WasiBridgeFn_InvokeObjectResult;
): TJOBResult; external JOBExportName name JOBFn_InvokeObjectResult;
function __wasibridgefn_release_object(
ObjID: TWasiDomObjectID
): TWasiDomResult; external WasiDomExportName name WasiBridgeFn_ReleaseObject;
function __job_release_object(
ObjID: TJOBObjectID
): TJOBResult; external JOBExportName name JOBFn_ReleaseObject;
implementation
{$IFDEF VerboseWasiDom}
{$IFDEF VerboseJOB}
function GetVarRecName(vt: word): string;
begin
case vt of
@ -152,7 +154,7 @@ end;
{ TJSObject }
function TJSObject.InvokeJSOneResult(const aName: string; const Args: array of const;
const InvokeFunc: TWasiDomInvokeOneResultFunc; ResultP: PByte): TWasiDomResult;
const InvokeFunc: TJOBInvokeOneResultFunc; ResultP: PByte): TJOBResult;
var
InvokeArgs: PByte;
begin
@ -169,7 +171,7 @@ begin
end;
end;
procedure TJSObject.WasiInvokeRaise(const aName, Msg: string);
procedure TJSObject.InvokeRaise(const aName, Msg: string);
var
E: EJSInvoke;
begin
@ -179,14 +181,14 @@ begin
raise E;
end;
procedure TJSObject.WasiInvokeRaiseResultMismatch(const aName: string;
Expected, Actual: TWasiDomResult);
procedure TJSObject.InvokeRaiseResultMismatch(const aName: string;
Expected, Actual: TJOBResult);
begin
case Actual of
WasiDomResult_UnknownObjId: WasiInvokeRaise(aName,'unknown object id '+IntToStr(ObjectID));
WasiDomResult_NotAFunction: WasiInvokeRaise(aName,'object '+IntToStr(ObjectID)+' does not have a function "'+aName+'"');
JOBResult_UnknownObjId: InvokeRaise(aName,'unknown object id '+IntToStr(ObjectID));
JOBResult_NotAFunction: InvokeRaise(aName,'object '+IntToStr(ObjectID)+' does not have a function "'+aName+'"');
else
WasiInvokeRaise(aName,'expected '+WasiDomResult_Names[Expected]+', but got '+WasiDomResult_Names[Actual]+' from object '+IntToStr(ObjectID)+' function "'+aName+'"');
InvokeRaise(aName,'expected '+JOBResult_Names[Expected]+', but got '+JOBResult_Names[Actual]+' from object '+IntToStr(ObjectID)+' function "'+aName+'"');
end;
end;
@ -282,7 +284,7 @@ begin
case Args[i].VType of
vtInteger :
begin
p^:=WasiArgLongint;
p^:=JOBArgLongint;
inc(p);
PLongint(p)^:=Args[i].VInteger;
inc(p,4);
@ -290,15 +292,15 @@ begin
vtBoolean :
begin
if Args[i].VBoolean then
p^:=WasiArgTrue
p^:=JOBArgTrue
else
p^:=WasiArgFalse;
p^:=JOBArgFalse;
inc(p);
end;
{$ifndef FPUNONE}
vtExtended :
begin
p^:=WasiArgDouble;
p^:=JOBArgDouble;
inc(p);
PDouble(p)^:=double(Args[i].VExtended^);
inc(p,8);
@ -306,14 +308,14 @@ begin
{$endif}
vtChar:
begin
p^:=WasiArgChar;
p^:=JOBArgChar;
inc(p);
PWord(p)^:=ord(Args[i].VChar);
inc(p,2);
end;
vtWideChar :
begin
p^:=WasiArgChar;
p^:=JOBArgChar;
inc(p);
PWord(p)^:=ord(Args[i].VWideChar);
inc(p,2);
@ -321,7 +323,7 @@ begin
vtString :
begin
// shortstring
p^:=WasiArgUTF8String;
p^:=JOBArgUTF8String;
inc(p);
h:=PByte(Args[i].VString);
PNativeInt(p)^:=h^;
@ -332,14 +334,14 @@ begin
end;
vtPointer:
begin
p^:=WasiArgPointer;
p^:=JOBArgPointer;
inc(p);
PPointer(p)^:=Args[i].VPointer;
inc(p,sizeof(Pointer));
end;
vtPChar :
begin
p^:=WasiArgUTF8String;
p^:=JOBArgUTF8String;
inc(p);
h:=PByte(Args[i].VPChar);
PNativeInt(p)^:=strlen(PChar(h));
@ -352,7 +354,7 @@ begin
vtPWideChar : ;
vtAnsiString :
begin
p^:=WasiArgUTF8String;
p^:=JOBArgUTF8String;
inc(p);
h:=Args[i].VAnsiString;
s:=AnsiString(h);
@ -368,7 +370,7 @@ begin
vtInterface : ;
vtWideString :
begin
p^:=WasiArgUnicodeString;
p^:=JOBArgUnicodeString;
inc(p);
h:=Args[i].VWideString;
ws:=WideString(h);
@ -382,12 +384,12 @@ begin
i64:=Args[i].VInt64^;
if (i64>=low(longint)) and (i64<=high(longint)) then
begin
p^:=WasiArgLongint;
p^:=JOBArgLongint;
inc(p);
PLongint(p)^:=i64;
inc(p,4);
end else begin
p^:=WasiArgDouble;
p^:=JOBArgDouble;
inc(p);
PDouble(p)^:=i64;
inc(p,8);
@ -395,7 +397,7 @@ begin
end;
vtUnicodeString :
begin
p^:=WasiArgUnicodeString;
p^:=JOBArgUnicodeString;
inc(p);
h:=Args[i].VUnicodeString;
us:=UnicodeString(h);
@ -409,12 +411,12 @@ begin
qw:=Args[i].VQWord^;
if (qw<=high(longint)) then
begin
p^:=WasiArgLongint;
p^:=JOBArgLongint;
inc(p);
PLongint(p)^:=qw;
inc(p,4);
end else begin
p^:=WasiArgDouble;
p^:=JOBArgDouble;
inc(p);
PDouble(p)^:=qw;
inc(p,8);
@ -435,7 +437,7 @@ begin
{$ENDIF}
end;
constructor TJSObject.CreateFromID(aID: TWasiDomObjectID);
constructor TJSObject.CreateFromID(aID: TJOBObjectID);
begin
FObjectID:=aID;
end;
@ -443,97 +445,97 @@ end;
destructor TJSObject.Destroy;
begin
if ObjectID>=0 then
__wasibridgefn_release_object(ObjectID);
__job_release_object(ObjectID);
inherited Destroy;
end;
procedure TJSObject.InvokeJSNoResult(const aName: string;
const Args: array of const);
var
aError: TWasiDomResult;
aError: TJOBResult;
InvokeArgs: PByte;
begin
if length(Args)=0 then
aError:=__wasibridgefn_invoke_noresult(ObjectID,PChar(aName),length(aName),nil,nil)
aError:=__job_invoke_noresult(ObjectID,PChar(aName),length(aName),nil,nil)
else begin
InvokeArgs:=CreateInvokeJSArgs(Args);
try
aError:=__wasibridgefn_invoke_noresult(ObjectID,PChar(aName),length(aName),InvokeArgs,nil);
aError:=__job_invoke_noresult(ObjectID,PChar(aName),length(aName),InvokeArgs,nil);
finally
if InvokeArgs<>nil then
FreeMem(InvokeArgs);
end;
end;
if aError<>WasiDomResult_Success then
WasiInvokeRaiseResultMismatch(aName,WasiDomResult_Success,aError);
if aError<>JOBResult_Success then
InvokeRaiseResultMismatch(aName,JOBResult_Success,aError);
end;
function TJSObject.InvokeJSBooleanResult(const aName: string;
const Args: array of const): Boolean;
var
aError: TWasiDomResult;
aError: TJOBResult;
b: bytebool;
begin
b:=false;
aError:=InvokeJSOneResult(aName,Args,@__wasibridgefn_invoke_boolresult,@b);
if aError<>WasiDomResult_Boolean then
WasiInvokeRaiseResultMismatch(aName,WasiDomResult_Boolean,aError);
aError:=InvokeJSOneResult(aName,Args,@__job_invoke_boolresult,@b);
if aError<>JOBResult_Boolean then
InvokeRaiseResultMismatch(aName,JOBResult_Boolean,aError);
Result:=b;
end;
function TJSObject.InvokeJSDoubleResult(const aName: string;
const Args: array of const): Double;
var
aError: TWasiDomResult;
aError: TJOBResult;
begin
Result:=NaN;
aError:=InvokeJSOneResult(aName,Args,@__wasibridgefn_invoke_doubleresult,@Result);
if aError<>WasiDomResult_Double then
WasiInvokeRaiseResultMismatch(aName,WasiDomResult_Double,aError);
aError:=InvokeJSOneResult(aName,Args,@__job_invoke_doubleresult,@Result);
if aError<>JOBResult_Double then
InvokeRaiseResultMismatch(aName,JOBResult_Double,aError);
end;
function TJSObject.InvokeJSUnicodeStringResult(const aName: string;
const args: array of const): UnicodeString;
var
ResultLen: NativeInt;
aError: TWasiDomResult;
aError: TJOBResult;
begin
ResultLen:=0;
aError:=InvokeJSOneResult(aName,Args,@__wasibridgefn_invoke_stringresult,@ResultLen);
if aError<>WasiDomResult_String then
WasiInvokeRaiseResultMismatch(aName,WasiDomResult_String,aError);
aError:=InvokeJSOneResult(aName,Args,@__job_invoke_stringresult,@ResultLen);
if aError<>JOBResult_String then
InvokeRaiseResultMismatch(aName,JOBResult_String,aError);
if ResultLen=0 then
exit('');
try
// try to allocate the memory
SetLength(Result,ResultLen);
aError:=WasiDomResult_Success;
aError:=JOBResult_Success;
finally
if aError<>WasiDomResult_Success then
__wasibridgefn_releasestringresult();
if aError<>JOBResult_Success then
__job_releasestringresult();
end;
__wasibridgefn_getstringresult(PByte(Result));
__job_getstringresult(PByte(Result));
end;
function TJSObject.InvokeJSObjResult(const aName: string;
aResultClass: TJSObjectClass; const args: array of const): TJSObject;
var
aError: TWasiDomResult;
NewObjId: TWasiDomObjectID;
aError: TJOBResult;
NewObjId: TJOBObjectID;
begin
Result:=nil;
NewObjId:=-1;
aError:=InvokeJSOneResult(aName,Args,@__wasibridgefn_invoke_objectresult,@NewObjId);
if aError=WasiDomResult_Null then
aError:=InvokeJSOneResult(aName,Args,@__job_invoke_objectresult,@NewObjId);
if aError=JOBResult_Null then
exit;
if aError<>WasiDomResult_Object then
WasiInvokeRaiseResultMismatch(aName,WasiDomResult_Object,aError);
if aError<>JOBResult_Object then
InvokeRaiseResultMismatch(aName,JOBResult_Object,aError);
Result:=aResultClass.CreateFromID(NewObjId);
end;
initialization
JSDocument:=TJSObject.CreateFromID(WasiObjIdDocument);
JSDocument:=TJSObject.CreateFromID(JOBObjIdDocument);
end.

View File

@ -1,78 +0,0 @@
{
These types and constants are shared between pas2js and webassembly.
}
unit wadom_shared;
interface
type
TWasiDomObjectID = NativeInt;
// invoke results
type
TWasiDomResult = longint;
const
WasiDomResult_None = 0;
WasiDomResult_Success = 1;
WasiDomResult_UnknownObjId = 2;
WasiDomResult_NotAFunction = 3;
WasiDomResult_Undefined = 4;
WasiDomResult_Null = 5;
WasiDomResult_Boolean = 6;
WasiDomResult_Number = 7;
WasiDomResult_Double = 8;
WasiDomResult_String = 9;
WasiDomResult_Function = 10;
WasiDomResult_Object = 11;
WasiDomResult_BigInt = 12;
WasiDomResult_Symbol = 13;
WasiDomResultLast = 13;
WasiDomResult_Names: array[0..WasiDomResultLast] of string = (
'None',
'Success',
'UnknownObjId',
'NotAFunction',
'Undefined',
'Null',
'Boolean',
'Number',
'Double',
'String',
'Function',
'Object',
'BigInt',
'Symbol'
);
WasiDomExportName = 'wasi_dom';
WasiBridgeFn_InvokeNoResult = 'invoke_noresult';
WasiBridgeFn_InvokeBooleanResult = 'invoke_boolresult';
WasiBridgeFn_InvokeDoubleResult = 'invoke_doubleresult';
WasiBridgeFn_InvokeStringResult = 'invoke_stringresult';
WasiBridgeFn_GetStringResult = 'get_stringresult';
WasiBridgeFn_ReleaseStringResult = 'release_stringresult';
WasiBridgeFn_InvokeObjectResult = 'invoke_objectresult';
WasiBridgeFn_ReleaseObject = 'release_object';
WasiArgNone = 0;
WasiArgLongint = 1;
WasiArgDouble = 2;
WasiArgTrue = 3;
WasiArgFalse = 4;
WasiArgChar = 5; // followed by a word
WasiArgUTF8String = 6; // followed by length and pointer
WasiArgUnicodeString = 7; // followed by length and pointer
WasiArgPointer = 8;
WasiObjIdDocument = -1;
WasiObjIdWindow = -2;
WasiObjIdConsole = -3;
WasiObjIdCaches = -4;
WasiObjIdBird = -5;
implementation
end.