demo: wasidom: invoke string result

This commit is contained in:
mattias 2022-05-24 08:03:27 +02:00
parent c71dc54e5b
commit b359b4d41f
4 changed files with 175 additions and 27 deletions

View File

@ -7,19 +7,44 @@ program WasiDomTest1;
uses
SysUtils, wadom_wasm, wadom_shared;
type
{ TBird }
TBird = class(TJSObject)
public
function GetDouble: double;
end;
{ TBird }
function TBird.GetDouble: double;
begin
Result:=InvokeJSDoubleResult('GetDouble',[]);
end;
var
obj: TJSObject;
d: Double;
u: UnicodeString;
Freddy: TBird;
begin
obj:=TJSObject.CreateFromID(WasiObjIdBird);
writeln('AAA1 ');
obj.InvokeJSNoResult('Proc',[]);
writeln('AAA2 ');
u:='äbc';
u:=obj.InvokeJSUnicodeStringResult('GetString',[u]);
writeln('AAA2 u="',u,'"');
exit;
u:='äbc';
d:=obj.InvokeJSDoubleResult('GetDouble',[u,12345678901]);
writeln('AAA3 ',d);
//obj.InvokeJSNoResult('Proc',[]);
//d:=obj.InvokeJSDoubleResult('GetDouble',[u,12345678901]);
Freddy:=obj.InvokeJSObjResult('CreateChick',TBird,['Freddy']) as TBird;
writeln('AAA3 ');
d:=Freddy.GetDouble;
writeln('AAA4 ',d);
Freddy.Free;
writeln('AAA5 ');
end.

View File

@ -8,6 +8,7 @@ interface
uses sysutils, types, js, web, wasienv, wadom_shared;
Type
EWABridge = class(Exception);
{ TWADomBridge }
@ -16,13 +17,18 @@ Type
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 GetInvokeArguments(View: TJSDataView; ArgsP: NativeInt): TJSValueDynArray; virtual;
function GetWasiDomResult(const v: jsvalue): TWasiDomResult;
Public
@ -63,10 +69,14 @@ end;
procedure TWADomBridge.FillImportObject(aObject: TJSObject);
begin
aObject[WasiDomInvokeNoResult]:=@Invoke_NoResult;
aObject[WasiDomInvokeBooleanResult]:=@Invoke_BooleanResult;
aObject[WasiDomInvokeDoubleResult]:=@Invoke_DoubleResult;
aObject[WasiDomInvokeObjectResult]:=@Invoke_ObjectResult;
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;
end;
function TWADomBridge.FindObject(ObjId: TWasiDomObjectID): TJSObject;
@ -163,6 +173,25 @@ begin
Result:=WasiDomResult_Double;
end;
function TWADomBridge.Invoke_StringResult(ObjId: TWasiDomObjectID; FuncNameP,
FuncNameLen, ArgsP, ResultP: NativeInt): TWasiDomResult;
var
JSResult: JSValue;
begin
// invoke
Result:=Invoke_JSResult(ObjId,FuncNameP,FuncNameLen,ArgsP,JSResult);
if Result<>WasiDomResult_Success then
exit;
// check result type
if jstypeof(JSResult)<>'string' then
exit(GetWasiDomResult(JSResult));
Result:=WasiDomResult_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;
var
@ -192,6 +221,40 @@ begin
Result:=WasiDomResult_Object;
end;
function TWADomBridge.ReleaseObject(ObjId: TWasiDomObjectID): TWasiDomResult;
begin
writeln('TWADomBridge.ReleaseObject ',ObjId);
if ObjId<0 then
raise EWABridge.Create('cannot release a global object');
if ObjId>=FLocalObjects.Length then
raise EWABridge.Create('cannot release unknown object');
if FLocalObjects[ObjId]=nil then
raise EWABridge.Create('object already released');
FLocalObjects[ObjId]:=nil;
FFreeLocalIds.push(ObjId);
Result:=WasiDomResult_Success;
end;
function TWADomBridge.GetStringResult(ResultP: NativeInt): TWasiDomResult;
var
View: TJSDataView;
l, i: SizeInt;
begin
Result:=WasiDomResult_Success;
l:=length(FStringResult);
if l=0 then exit;
View:=getModuleMemoryDataView();
for i:=0 to l-1 do
View.setUint16(ResultP+2*i,ord(FStringResult[i]),env.IsLittleEndian);
FStringResult:='';
end;
function TWADomBridge.ReleaseStringResult: TWasiDomResult;
begin
Result:=WasiDomResult_Success;
FStringResult:='';
end;
function TWADomBridge.GetInvokeArguments(View: TJSDataView; ArgsP: NativeInt
): TJSValueDynArray;
var

View File

@ -47,10 +47,14 @@ const
);
WasiDomExportName = 'wasi_dom';
WasiDomInvokeNoResult = 'invoke_noresult';
WasiDomInvokeBooleanResult = 'invoke_boolresult';
WasiDomInvokeDoubleResult = 'invoke_doubleresult';
WasiDomInvokeObjectResult = 'invoke_objectresult';
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;

View File

@ -56,7 +56,7 @@ Type
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 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;
@ -65,37 +65,56 @@ Type
var
JSDocument: TJSObject; // ToDo
function __wasidom_invoke_noresult(
function __wasibridgefn_invoke_noresult(
ObjID: TWasiDomObjectID;
FuncNameP: PChar;
FuncNameLen: longint;
ArgP: PByte;
Dummy: PByte
): TWasiDomResult; external WasiDomExportName name WasiDomInvokeNoResult;
): TWasiDomResult; external WasiDomExportName name WasiBridgeFn_InvokeNoResult;
function __wasidom_invoke_boolresult(
function __wasibridgefn_invoke_boolresult(
ObjID: TWasiDomObjectID;
FuncNameP: PChar;
FuncNameLen: longint;
ArgP: PByte;
ResultP: PByte // bytebool
): TWasiDomResult; external WasiDomExportName name WasiDomInvokeBooleanResult;
): TWasiDomResult; external WasiDomExportName name WasiBridgeFn_InvokeBooleanResult;
function __wasidom_invoke_doubleresult(
function __wasibridgefn_invoke_doubleresult(
ObjID: TWasiDomObjectID;
FuncNameP: PChar;
FuncNameLen: longint;
ArgP: PByte;
ResultP: PByte // double
): TWasiDomResult; external WasiDomExportName name WasiDomInvokeDoubleResult;
): TWasiDomResult; external WasiDomExportName name WasiBridgeFn_InvokeDoubleResult;
function __wasidom_invoke_objectresult(
function __wasibridgefn_invoke_stringresult(
ObjID: TWasiDomObjectID;
FuncNameP: PChar;
FuncNameLen: longint;
ArgP: PByte;
ResultLenP: PNativeInt // length
): TWasiDomResult; external WasiDomExportName name WasiBridgeFn_InvokeStringResult;
function __wasibridgefn_getstringresult(
ResultP: PByte
): TWasiDomResult; external WasiDomExportName name WasiBridgeFn_GetStringResult;
function __wasibridgefn_releasestringresult(
): TWasiDomResult; external WasiDomExportName name WasiBridgeFn_ReleaseStringResult;
function __wasibridgefn_invoke_objectresult(
ObjID: TWasiDomObjectID;
FuncNameP: PChar;
FuncNameLen: longint;
ArgP: PByte;
ResultP: PByte // nativeint
): TWasiDomResult; external WasiDomExportName name WasiDomInvokeObjectResult;
): TWasiDomResult; external WasiDomExportName name WasiBridgeFn_InvokeObjectResult;
function __wasibridgefn_release_object(
ObjID: TWasiDomObjectID
): TWasiDomResult; external WasiDomExportName name WasiBridgeFn_ReleaseObject;
implementation
@ -423,6 +442,8 @@ end;
destructor TJSObject.Destroy;
begin
if ObjectID>=0 then
__wasibridgefn_release_object(ObjectID);
inherited Destroy;
end;
@ -433,11 +454,11 @@ var
InvokeArgs: PByte;
begin
if length(Args)=0 then
aError:=__wasidom_invoke_noresult(ObjectID,PChar(aName),length(aName),nil,nil)
aError:=__wasibridgefn_invoke_noresult(ObjectID,PChar(aName),length(aName),nil,nil)
else begin
InvokeArgs:=CreateInvokeJSArgs(Args);
try
aError:=__wasidom_invoke_noresult(ObjectID,PChar(aName),length(aName),InvokeArgs,nil);
aError:=__wasibridgefn_invoke_noresult(ObjectID,PChar(aName),length(aName),InvokeArgs,nil);
finally
if InvokeArgs<>nil then
FreeMem(InvokeArgs);
@ -454,7 +475,7 @@ var
b: bytebool;
begin
b:=false;
aError:=InvokeJSOneResult(aName,Args,@__wasidom_invoke_boolresult,@b);
aError:=InvokeJSOneResult(aName,Args,@__wasibridgefn_invoke_boolresult,@b);
if aError<>WasiDomResult_Boolean then
WasiInvokeRaiseResultMismatch(aName,WasiDomResult_Boolean,aError);
Result:=b;
@ -466,11 +487,46 @@ var
aError: TWasiDomResult;
begin
Result:=NaN;
aError:=InvokeJSOneResult(aName,Args,@__wasidom_invoke_doubleresult,@Result);
aError:=InvokeJSOneResult(aName,Args,@__wasibridgefn_invoke_doubleresult,@Result);
if aError<>WasiDomResult_Double then
WasiInvokeRaiseResultMismatch(aName,WasiDomResult_Double,aError);
end;
function TJSObject.InvokeJSUnicodeStringResult(const aName: string;
const args: array of const): UnicodeString;
var
ResultLen: NativeInt;
aError: TWasiDomResult;
InvokeArgs: PByte;
begin
ResultLen:=0;
if length(Args)=0 then
aError:=__wasibridgefn_invoke_stringresult(ObjectID,PChar(aName),length(aName),nil,@ResultLen)
else begin
InvokeArgs:=CreateInvokeJSArgs(Args);
try
aError:=__wasibridgefn_invoke_stringresult(ObjectID,PChar(aName),length(aName),InvokeArgs,@ResultLen);
finally
if InvokeArgs<>nil then
FreeMem(InvokeArgs);
end;
end;
if aError<>WasiDomResult_String then
WasiInvokeRaiseResultMismatch(aName,WasiDomResult_String,aError);
if ResultLen=0 then
exit('');
try
// try to allocate the memory
SetLength(Result,ResultLen);
aError:=WasiDomResult_Success;
finally
if aError<>WasiDomResult_Success then
__wasibridgefn_releasestringresult();
end;
__wasibridgefn_getstringresult(PByte(Result));
writeln('TJSObject.InvokeJSUnicodeStringResult Result="',Result,'"');
end;
function TJSObject.InvokeJSObjResult(const aName: string;
aResultClass: TJSObjectClass; const args: array of const): TJSObject;
var
@ -479,7 +535,7 @@ var
begin
Result:=nil;
NewObjId:=-1;
aError:=InvokeJSOneResult(aName,Args,@__wasidom_invoke_objectresult,@NewObjId);
aError:=InvokeJSOneResult(aName,Args,@__wasibridgefn_invoke_objectresult,@NewObjId);
if aError=WasiDomResult_Null then
exit;
if aError<>WasiDomResult_Object then