From 54640f3e934ec694fe0136b4c42fe6da2b6f5f3c Mon Sep 17 00:00:00 2001 From: mattias Date: Mon, 23 May 2022 20:16:41 +0200 Subject: [PATCH] demo: wasidom: started objectresult --- demo/wasienv/dom/.gitignore | 1 + demo/wasienv/dom/wadom_browser.pp | 55 ++++++++++++++++++--- demo/wasienv/dom/wadom_shared.pp | 23 +++++---- demo/wasienv/dom/wadom_wasm.pas | 79 +++++++++++++++++++++++++++++-- 4 files changed, 137 insertions(+), 21 deletions(-) create mode 100644 demo/wasienv/dom/.gitignore diff --git a/demo/wasienv/dom/.gitignore b/demo/wasienv/dom/.gitignore new file mode 100644 index 0000000..a65b417 --- /dev/null +++ b/demo/wasienv/dom/.gitignore @@ -0,0 +1 @@ +lib diff --git a/demo/wasienv/dom/wadom_browser.pp b/demo/wasienv/dom/wadom_browser.pp index 0985c97..c937e33 100644 --- a/demo/wasienv/dom/wadom_browser.pp +++ b/demo/wasienv/dom/wadom_browser.pp @@ -15,11 +15,14 @@ Type Private FGlobalObjects: TJSArray; FLocalObjects: TJSArray; + FFreeLocalIds: TJSArray; // free positions in FLocalObjects 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: 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_ObjectResult(ObjId: TWasiDomObjectID; FuncNameP, FuncNameLen, ArgsP, ResultP: NativeInt): TWasiDomResult; virtual; function GetInvokeArguments(View: TJSDataView; ArgsP: NativeInt): TJSValueDynArray; virtual; function GetWasiDomResult(const v: jsvalue): TWasiDomResult; Public @@ -44,17 +47,19 @@ begin FGlobalObjects[-WasiObjIdConsole]:=console; FGlobalObjects[-WasiObjIdCaches]:=caches; FLocalObjects:=TJSArray.new; + FFreeLocalIds:=TJSArray.new; end; function TWADomBridge.ImportName: String; begin - Result:=WasiDomExtName; + Result:=WasiDomExportName; end; procedure TWADomBridge.FillImportObject(aObject: TJSObject); begin - aObject[WasiDomInvokeBooleanResult]:=@invoke_booleanresult; - aObject[WasiDomInvokeDoubleResult]:=@invoke_doubleresult; + aObject[WasiDomInvokeNoResult]:=@Invoke_NoResult; + aObject[WasiDomInvokeBooleanResult]:=@Invoke_BooleanResult; + aObject[WasiDomInvokeDoubleResult]:=@Invoke_DoubleResult; end; function TWADomBridge.FindObject(ObjId: TWasiDomObjectID): TJSObject; @@ -100,7 +105,16 @@ begin JSResult:=TJSFunction(fn).apply(Obj,Args); end; - exit(WasiDomResult_Success); + Result:=WasiDomResult_Success; +end; + +function TWADomBridge.Invoke_NoResult(ObjId: TWasiDomObjectID; FuncNameP, + FuncNameLen, ArgsP: NativeInt): TWasiDomResult; +var + JSResult: JSValue; +begin + // invoke + Result:=Invoke_JSResult(ObjId,FuncNameP,FuncNameLen,ArgsP,JSResult); end; function TWADomBridge.Invoke_BooleanResult(ObjId: TWasiDomObjectID; FuncNameP, @@ -122,7 +136,7 @@ begin b:=0; // set result getModuleMemoryDataView().setUint8(ResultP, b); - Result:=WasiDomResult_Success; + Result:=WasiDomResult_Boolean; end; function TWADomBridge.Invoke_DoubleResult(ObjId: TWasiDomObjectID; FuncNameP, @@ -139,7 +153,36 @@ begin exit(GetWasiDomResult(JSResult)); // set result getModuleMemoryDataView().setFloat64(ResultP, double(JSResult), env.IsLittleEndian); - Result:=WasiDomResult_Success; + Result:=WasiDomResult_Double; +end; + +function TWADomBridge.Invoke_ObjectResult(ObjId: TWasiDomObjectID; FuncNameP, + FuncNameLen, ArgsP, ResultP: NativeInt): TWasiDomResult; +var + t: String; + JSResult, NewId: JSValue; +begin + // invoke + Result:=Invoke_JSResult(ObjId,FuncNameP,FuncNameLen,ArgsP,JSResult); + if Result<>WasiDomResult_Success then + exit; + // check result type + t:=jstypeof(JSResult); + if (t<>'object') and (t<>'function') then + exit(GetWasiDomResult(JSResult)); + if JSResult=nil then + exit(WasiDomResult_Null); + + // create Id + NewId:=FFreeLocalIds.pop; + if isUndefined(NewId) then + NewId:=FLocalObjects.push(JSResult)-1 + else + FLocalObjects[longword(NewId)]:=JSResult; + + // set result + getModuleMemoryDataView().setUint32(ResultP, longword(NewId), env.IsLittleEndian); + Result:=WasiDomResult_Object; end; function TWADomBridge.GetInvokeArguments(View: TJSDataView; ArgsP: NativeInt diff --git a/demo/wasienv/dom/wadom_shared.pp b/demo/wasienv/dom/wadom_shared.pp index 79455a0..0f5ce0b 100644 --- a/demo/wasienv/dom/wadom_shared.pp +++ b/demo/wasienv/dom/wadom_shared.pp @@ -17,16 +17,17 @@ const WasiDomResult_UnknownObjId = 2; WasiDomResult_NotAFunction = 3; WasiDomResult_Undefined = 4; - WasiDomResult_Boolean = 5; - WasiDomResult_Number = 6; - WasiDomResult_Double = 7; - WasiDomResult_String = 8; - WasiDomResult_Function = 9; - WasiDomResult_Object = 10; - WasiDomResult_BigInt = 11; - WasiDomResult_Symbol = 12; + 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 = 12; + WasiDomResultLast = 13; WasiDomResult_Names: array[0..WasiDomResultLast] of string = ( 'None', @@ -36,6 +37,7 @@ const 'Undefined', 'Null', 'Boolean', + 'Number', 'Double', 'String', 'Function', @@ -44,7 +46,8 @@ const 'Symbol' ); - WasiDomExtName = 'wasi_dom'; + WasiDomExportName = 'wasi_dom'; + WasiDomInvokeNoResult = 'invoke_noresult'; WasiDomInvokeBooleanResult = 'invoke_boolresult'; WasiDomInvokeDoubleResult = 'invoke_doubleresult'; diff --git a/demo/wasienv/dom/wadom_wasm.pas b/demo/wasienv/dom/wadom_wasm.pas index 952ff2b..a445ec8 100644 --- a/demo/wasienv/dom/wadom_wasm.pas +++ b/demo/wasienv/dom/wadom_wasm.pas @@ -26,8 +26,10 @@ Type FuncName: string; end; + PWasiDomObjectID = ^TWasiDomObjectID; + TJSObject = class; - //TJSObjectClass = class of TJSObject; + TJSObjectClass = class of TJSObject; { TJSObject } @@ -39,23 +41,32 @@ Type procedure WasiInvokeRaiseResultMismatch(const aName: string; Expected, Actual: TWasiDomResult); virtual; function CreateInvokeJSArgs(const Args: array of const): PByte; virtual; public - constructor CreateFromID(aID: TWasiDomObjectID); reintroduce; + constructor CreateFromID(aID: TWasiDomObjectID); virtual; destructor Destroy; override; property ObjectID: TWasiDomObjectID 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; //function InvokeJSUnicodeStringResult(const aName: string; Const args: Array of const): UnicodeString; + function InvokeJSObjResult(const aName: string; aResultClass: TJSObjectClass; Const args: Array of const): TJSObject; + // ToDo: InvokeJSVarRecResult //function InvokeJSUtf8StringResult(const aName: string; Const args: Array of const): String; - //function InvokeJSObjResult(const aName: string; aResultClass: TJSObjectClass; Const args: Array of const): TJSObject; end; +function __wasidom_invoke_noresult( + ObjID: TWasiDomObjectID; + FuncNameP: PChar; + FuncNameLen: longint; + ArgP: PByte +): TWasiDomResult; external WasiDomExportName name WasiDomInvokeBooleanResult; + function __wasidom_invoke_boolresult( ObjID: TWasiDomObjectID; FuncNameP: PChar; FuncNameLen: longint; ArgP: PByte; ResultP: PByteBool -): TWasiDomResult; external WasiDomExtName name WasiDomInvokeBooleanResult; +): TWasiDomResult; external WasiDomExportName name WasiDomInvokeBooleanResult; function __wasidom_invoke_doubleresult( ObjID: TWasiDomObjectID; @@ -63,7 +74,15 @@ function __wasidom_invoke_doubleresult( FuncNameLen: longint; ArgP: PByte; ResultP: PDouble -): TWasiDomResult; external WasiDomExtName name WasiDomInvokeDoubleResult; +): TWasiDomResult; external WasiDomExportName name WasiDomInvokeDoubleResult; + +function __wasidom_invoke_objectresult( + ObjID: TWasiDomObjectID; + FuncNameP: PChar; + FuncNameLen: longint; + ArgP: PByte; + ResultP: PWasiDomObjectID +): TWasiDomResult; external WasiDomExportName name WasiDomInvokeDoubleResult; implementation @@ -376,6 +395,27 @@ begin inherited Destroy; end; +procedure TJSObject.InvokeJSNoResult(const aName: string; + const args: array of const); +var + aError: TWasiDomResult; + InvokeArgs: PByte; +begin + if length(Args)=0 then + aError:=__wasidom_invoke_noresult(ObjectID,PChar(aName),length(aName),nil) + else begin + InvokeArgs:=CreateInvokeJSArgs(Args); + try + aError:=__wasidom_invoke_noresult(ObjectID,PChar(aName),length(aName),InvokeArgs); + finally + if InvokeArgs<>nil then + FreeMem(InvokeArgs); + end; + end; + if aError<>WasiDomResult_Success then + WasiInvokeRaiseResultMismatch(aName,WasiDomResult_Boolean,aError); +end; + function TJSObject.InvokeJSBooleanResult(const aName: string; const args: array of const): Boolean; var @@ -424,5 +464,34 @@ begin WasiInvokeRaiseResultMismatch(aName,WasiDomResult_Double,aError); end; +function TJSObject.InvokeJSObjResult(const aName: string; + aResultClass: TJSObjectClass; const args: array of const): TJSObject; +var + aError: TWasiDomResult; + InvokeArgs: PByte; + NewObjId: TWasiDomObjectID; +begin + Result:=nil; + NewObjId:=-1; + if length(Args)=0 then + aError:=__wasidom_invoke_objectresult(ObjectID,PChar(aName),length(aName),nil,@NewObjId) + else begin + InvokeArgs:=CreateInvokeJSArgs(Args); + try + aError:=__wasidom_invoke_objectresult(ObjectID,PChar(aName),length(aName), + InvokeArgs,@NewObjId); + finally + if InvokeArgs<>nil then + FreeMem(InvokeArgs); + end; + end; + if aError=WasiDomResult_Null then + exit; + if aError<>WasiDomResult_Object then + WasiInvokeRaiseResultMismatch(aName,WasiDomResult_Object,aError); + + Result:=aResultClass.CreateFromID(NewObjId); +end; + end.