Browse Source

demo: wasidom: started objectresult

mattias 3 years ago
parent
commit
54640f3e93

+ 1 - 0
demo/wasienv/dom/.gitignore

@@ -0,0 +1 @@
+lib

+ 49 - 6
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

+ 13 - 10
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';
 

+ 74 - 5
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.