Browse Source

wasi: job: read jsvalue

mattias 3 years ago
parent
commit
147d1cad54

+ 8 - 2
demo/wasienv/dom/WasiDomTest1.lpr

@@ -75,6 +75,7 @@ var
   u: UnicodeString;
   Freddy, Alice, aBird: TBird;
   i: Integer;
+  JSValue: TJOB_JSValue;
 begin
   obj:=TJSObject.CreateFromID(WasiObjIdBird);
   obj.WriteJSPropertyUnicodeString('Caption','Root');
@@ -84,15 +85,20 @@ begin
   //obj.InvokeJSNoResult('Proc',[]);
   //d:=obj.InvokeJSDoubleResult('GetDouble',[u,12345678901]);
   writeln('Create Freddy...');
-  Freddy:=obj.InvokeJSObjResult('CreateChick',['Freddy'],TBird) as TBird;
+  Freddy:=obj.InvokeJSObjectResult('CreateChick',['Freddy'],TBird) as TBird;
   writeln('AAA5 ',Freddy.Name);
+
   writeln('Create Alice...');
-  Alice:=obj.InvokeJSObjResult('CreateChick',['Alice'],TBird) as TBird;
+  Alice:=obj.InvokeJSObjectResult('CreateChick',['Alice'],TBird) as TBird;
   writeln('Freddy.Child:=Alice...');
   Freddy.Child:=Alice;
   aBird:=Freddy.Child;
   writeln('Freddy.Child=',aBird.Name);
 
+  //Freddy.Size:=123;
+  //writeln('Freddy.Size=',Freddy.Size);
+  JSValue:=Freddy.ReadJSPropertyValue('Child');
+  writeln('JSValue: ',JSValue.Kind,' ',JSValue.AsString);
 
   writeln('Freeing Freddy...');
   Freddy.Free;

+ 68 - 13
demo/wasienv/dom/job_browser.pp

@@ -23,23 +23,26 @@ Type
     FFreeLocalIds: TJSArray; // free positions in FLocalObjects
     FStringResult: string;
   Protected
-    function FindObject(ObjId: TJOBObjectID): TJSObject; virtual;
     function Invoke_JSResult(ObjId: TJOBObjectID; NameP, NameLen, Invoke, ArgsP: NativeInt; out JSResult: JSValue): TJOBResult; virtual;
+    function GetInvokeArguments(View: TJSDataView; ArgsP: NativeInt): TJSValueDynArray; virtual;
+    // exports
     function Invoke_NoResult(ObjId: TJOBObjectID; NameP, NameLen, Invoke, ArgsP: NativeInt): TJOBResult; virtual;
     function Invoke_BooleanResult(ObjId: TJOBObjectID; NameP, NameLen, Invoke, ArgsP, ResultP: NativeInt): TJOBResult; virtual;
     function Invoke_DoubleResult(ObjId: TJOBObjectID; NameP, NameLen, Invoke, ArgsP, ResultP: NativeInt): TJOBResult; virtual;
     function Invoke_StringResult(ObjId: TJOBObjectID; NameP, NameLen, Invoke, ArgsP, ResultP: NativeInt): TJOBResult; virtual;
     function Invoke_ObjectResult(ObjId: TJOBObjectID; NameP, NameLen, Invoke, ArgsP, ResultP: NativeInt): TJOBResult; virtual;
+    function Invoke_JSValueResult(ObjId: TJOBObjectID; NameP, NameLen, Invoke, 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 GetJOBResult(v: jsvalue): TJOBResult;
   Public
     Constructor Create(aEnv: TPas2JSWASIEnvironment); override;
     Procedure FillImportObject(aObject: TJSObject); override;
     Function ImportName: String; override;
+    function FindObject(ObjId: TJOBObjectID): TJSObject; virtual;
+    function RegisterLocalObject(Obj: TJSObject): TJOBObjectID; virtual;
     Function RegisterGlobalObject(Obj: TJSObject): TJOBObjectID; virtual;
+    Function GetJOBResult(v: jsvalue): TJOBResult;
   end;
 
 Implementation
@@ -81,6 +84,7 @@ begin
   aObject[JOBFn_ReleaseStringResult]:=@ReleaseStringResult;
   aObject[JOBFn_InvokeObjectResult]:=@Invoke_ObjectResult;
   aObject[JOBFn_ReleaseObject]:=@ReleaseObject;
+  aObject[JOBFn_InvokeJSValueResult]:=@Invoke_JSValueResult;
 end;
 
 function TJOBBridge.FindObject(ObjId: TJOBObjectID): TJSObject;
@@ -93,6 +97,22 @@ begin
     Result:=nil;
 end;
 
+function TJOBBridge.RegisterLocalObject(Obj: TJSObject): TJOBObjectID;
+var
+  NewId: JSValue;
+begin
+  NewId:=FFreeLocalIds.pop;
+  if isUndefined(NewId) then
+  begin
+    NewId:=FLocalObjects.push(Obj)-1;
+    Result:=TJOBObjectID(NewId);
+  end
+  else begin
+    Result:=TJOBObjectID(NewId);
+    FLocalObjects[Result]:=Obj;
+  end;
+end;
+
 function TJOBBridge.Invoke_JSResult(ObjId: TJOBObjectID; NameP, NameLen,
   Invoke, ArgsP: NativeInt; out JSResult: JSValue): TJOBResult;
 var
@@ -224,11 +244,11 @@ function TJOBBridge.Invoke_ObjectResult(ObjId: TJOBObjectID; NameP, NameLen,
   Invoke, ArgsP, ResultP: NativeInt): TJOBResult;
 var
   t: String;
-  JSResult, NewId: JSValue;
+  JSResult: JSValue;
+  NewId: TJOBObjectID;
 begin
   // invoke
   Result:=Invoke_JSResult(ObjId,NameP,NameLen,Invoke,ArgsP,JSResult);
-  writeln('BBB1 TJOBBridge.Invoke_ObjectResult ',Result,' JSResult=',JSResult);
   if Result<>JOBResult_Success then
     exit;
   // check result type
@@ -238,18 +258,53 @@ begin
   if JSResult=nil then
     exit(JOBResult_Null);
 
-  // create Id
-  NewId:=FFreeLocalIds.pop;
-  if isUndefined(NewId) then
-    NewId:=FLocalObjects.push(JSResult)-1
-  else
-    FLocalObjects[longword(NewId)]:=JSResult;
-
   // set result
+  NewId:=RegisterLocalObject(TJSObject(JSResult));
   getModuleMemoryDataView().setUint32(ResultP, longword(NewId), env.IsLittleEndian);
   Result:=JOBResult_Object;
 end;
 
+function TJOBBridge.Invoke_JSValueResult(ObjId: TJOBObjectID; NameP, NameLen,
+  Invoke, ArgsP, ResultP: NativeInt): TJOBResult;
+var
+  JSResult: JSValue;
+  b: byte;
+  NewId: TJOBObjectID;
+begin
+  writeln('TJOBBridge.Invoke_JSValueResult START');
+  // invoke
+  Result:=Invoke_JSResult(ObjId,NameP,NameLen,Invoke,ArgsP,JSResult);
+  writeln('TJOBBridge.Invoke_JSValueResult JSResult=',JSResult);
+  if Result<>JOBResult_Success then
+    exit;
+  Result:=GetJOBResult(JSResult);
+  writeln('TJOBBridge.Invoke_JSValueResult Type=',Result);
+  // set result
+  case Result of
+  JOBResult_Boolean:
+    begin
+      if JSResult then
+        b:=1
+      else
+        b:=0;
+      getModuleMemoryDataView().setUint8(ResultP, b);
+    end;
+  JOBResult_Double:
+    getModuleMemoryDataView().setFloat64(ResultP, double(JSResult), env.IsLittleEndian);
+  JOBResult_String:
+    begin
+      FStringResult:=String(JSResult);
+    getModuleMemoryDataView().setInt32(ResultP, length(FStringResult), env.IsLittleEndian);
+    end;
+  JOBResult_Function,
+  JOBResult_Object:
+    begin
+      NewId:=RegisterLocalObject(TJSObject(JSResult));
+      getModuleMemoryDataView().setUint32(ResultP, longword(NewId), env.IsLittleEndian);
+    end;
+  end;
+end;
+
 function TJOBBridge.ReleaseObject(ObjId: TJOBObjectID): TJOBResult;
 begin
   //writeln('TJOBBridge.ReleaseObject ',ObjId);
@@ -370,7 +425,7 @@ begin
   case jstypeof(v) of
   'undefined': Result:=JOBResult_Undefined;
   'boolean': Result:=JOBResult_Boolean;
-  'number': Result:=JOBResult_Number;
+  'number': Result:=JOBResult_Double;
   'string': Result:=JOBResult_String;
   'symbol': Result:=JOBResult_Symbol;
   'bigint': Result:=JOBResult_BigInt;

+ 8 - 9
demo/wasienv/dom/job_shared.pp

@@ -22,15 +22,14 @@ const
   JOBResult_Undefined = 5;
   JOBResult_Null = 6;
   JOBResult_Boolean = 7;
-  JOBResult_Number = 8;
-  JOBResult_Double = 9;
-  JOBResult_String = 10;
-  JOBResult_Function = 11;
-  JOBResult_Object = 12;
-  JOBResult_BigInt = 13;
-  JOBResult_Symbol = 14;
+  JOBResult_Double = 8;
+  JOBResult_String = 9;
+  JOBResult_Function = 10;
+  JOBResult_Object = 11;
+  JOBResult_BigInt = 12;
+  JOBResult_Symbol = 13;
 
-  JOBResultLast = 14;
+  JOBResultLast = 13;
 
   JOBResult_Names: array[0..JOBResultLast] of string = (
     'None',
@@ -41,7 +40,6 @@ const
     'Undefined',
     'Null',
     'Boolean',
-    'Number',
     'Double',
     'String',
     'Function',
@@ -59,6 +57,7 @@ const
   JOBFn_ReleaseStringResult = 'release_stringresult';
   JOBFn_InvokeObjectResult = 'invoke_objectresult';
   JOBFn_ReleaseObject = 'release_object';
+  JOBFn_InvokeJSValueResult = 'invoke_jsvalueresult';
 
   JOBArgNone = 0;
   JOBArgLongint = 1;

+ 230 - 17
demo/wasienv/dom/job_wasm.pas

@@ -28,6 +28,62 @@ Type
     FuncName: string;
   end;
 
+  TJOB_JSValueKind = (
+    jjvkUndefined,
+    jjvkBoolean,
+    jjvkDouble,
+    jjvkString,
+    jjvkObject
+    );
+  TJOB_JSValueKinds = set of TJOB_JSValueKind;
+
+const
+  JOB_JSValueKindNames: array[TJOB_JSValueKind] of string = (
+    'Undefined',
+    'Boolean',
+    'Double',
+    'String',
+    'Object'
+    );
+
+type
+
+  { TJOB_JSValue }
+
+  TJOB_JSValue = class
+  public
+    Kind: TJOB_JSValueKind;
+    constructor Create(aKind: TJOB_JSValueKind);
+    function AsString: string; virtual;
+  end;
+
+  { TJOB_JSValueBoolean }
+
+  TJOB_JSValueBoolean = class(TJOB_JSValue)
+  public
+    Value: Boolean;
+    constructor Create(aValue: Boolean);
+    function AsString: string; override;
+  end;
+
+  { TJOB_JSValueDouble }
+
+  TJOB_JSValueDouble = class(TJOB_JSValue)
+  public
+    Value: Double;
+    constructor Create(const aValue: Double);
+    function AsString: string; override;
+  end;
+
+  { TJOB_JSValueString }
+
+  TJOB_JSValueString = class(TJOB_JSValue)
+  public
+    Value: UnicodeString;
+    constructor Create(const aValue: UnicodeString);
+    function AsString: string; override;
+  end;
+
   PJOBObjectID = ^TJOBObjectID;
   TJOBInvokeOneResultFunc = function(
       ObjID: TJOBObjectID;
@@ -50,12 +106,31 @@ Type
   TJSObject = class;
   TJSObjectClass = class of TJSObject;
 
+  IJSObject = interface
+    function GetObjectID: TJOBObjectID;
+    function GetClassName: string;
+    property ObjectID: TJOBObjectID read GetObjectID;
+    property ClassName: string read GetClassName;
+  end;
+
+  { TJOB_JSValueObject }
+
+  TJOB_JSValueObject = class(TJOB_JSValue)
+  public
+    Value: IJSObject;
+    constructor Create(aValue: IJSObject);
+    function AsString: string; override;
+  end;
+
   { TJSObject }
 
-  TJSObject = class(TInterfacedObject)
+  TJSObject = class(TInterfacedObject,IJSObject)
   private
     FObjectID: TJOBObjectID;
   protected
+    function GetObjectID: TJOBObjectID;
+    function GetClassName: string;
+    function FetchString(Len: NativeInt): UnicodeString;
     function InvokeJSOneResult(const aName: string; Const Args: Array of const;
       const InvokeFunc: TJOBInvokeOneResultFunc; ResultP: PByte; Invoke: TJOBInvokeGetType): TJOBResult;
     procedure InvokeJS_Raise(const aName, Msg: string); virtual;
@@ -70,8 +145,8 @@ Type
     function InvokeJSBooleanResult(const aName: string; Const Args: Array of const; Invoke: TJOBInvokeGetType = jigCall): Boolean; virtual;
     function InvokeJSDoubleResult(const aName: string; Const Args: Array of const; Invoke: TJOBInvokeGetType = jigCall): Double; virtual;
     function InvokeJSUnicodeStringResult(const aName: string; Const Args: Array of const; Invoke: TJOBInvokeGetType = jigCall): UnicodeString; virtual;
-    function InvokeJSObjResult(const aName: string; Const Args: Array of const; aResultClass: TJSObjectClass; Invoke: TJOBInvokeGetType = jigCall): TJSObject; virtual;
-    // ToDo: InvokeJSValueResult
+    function InvokeJSObjectResult(const aName: string; Const Args: Array of const; aResultClass: TJSObjectClass; Invoke: TJOBInvokeGetType = jigCall): TJSObject; virtual;
+    function InvokeJSValueResult(const aName: string; Const Args: Array of const; Invoke: TJOBInvokeGetType = jigCall): TJOB_JSValue; virtual;
     function InvokeJSUtf8StringResult(const aName: string; Const args: Array of const; Invoke: TJOBInvokeGetType = jigCall): String; virtual;
     function InvokeJSLongIntResult(const aName: string; Const args: Array of const; Invoke: TJOBInvokeGetType = jigCall): LongInt; virtual;
     function ReadJSPropertyBoolean(const aName: string): boolean; virtual;
@@ -80,6 +155,7 @@ Type
     function ReadJSPropertyObject(const aName: string; aResultClass: TJSObjectClass): TJSObject; virtual;
     function ReadJSPropertyUtf8String(const aName: string): string; virtual;
     function ReadJSPropertyLongInt(const aName: string): LongInt; virtual;
+    function ReadJSPropertyValue(const aName: string): TJOB_JSValue; virtual;
     // ToDo: get JSValue property
     procedure WriteJSPropertyBoolean(const aName: string; Value: Boolean); virtual;
     procedure WriteJSPropertyDouble(const aName: string; Value: Double); virtual;
@@ -147,6 +223,15 @@ function __job_release_object(
   ObjID: TJOBObjectID
 ): TJOBResult; external JOBExportName name JOBFn_ReleaseObject;
 
+function __job_invoke_jsvalueresult(
+  ObjID: TJOBObjectID;
+  NameP: PChar;
+  NameLen: longint;
+  Invoke: longint;
+  ArgP: PByte;
+  ResultP: PByte
+): TJOBResult; external JOBExportName name JOBFn_InvokeJSValueResult;
+
 implementation
 
 const
@@ -190,8 +275,108 @@ begin
 end;
 {$ENDIF}
 
+{ TJOB_JSValue }
+
+constructor TJOB_JSValue.Create(aKind: TJOB_JSValueKind);
+begin
+  Kind:=aKind;
+end;
+
+function TJOB_JSValue.AsString: string;
+begin
+  case Kind of
+    jjvkUndefined: Result:='undefined';
+    jjvkBoolean: ;
+    jjvkDouble: ;
+    jjvkString: ;
+    jjvkObject: ;
+  end;
+end;
+
+{ TJOB_JSValueBoolean }
+
+constructor TJOB_JSValueBoolean.Create(aValue: Boolean);
+begin
+  Kind:=jjvkBoolean;
+  Value:=aValue;
+end;
+
+function TJOB_JSValueBoolean.AsString: string;
+begin
+  str(Value,Result);
+end;
+
+{ TJOB_JSValueDouble }
+
+constructor TJOB_JSValueDouble.Create(const aValue: Double);
+begin
+  Kind:=jjvkDouble;
+  Value:=aValue;
+end;
+
+function TJOB_JSValueDouble.AsString: string;
+begin
+  str(Value,Result);
+end;
+
+{ TJOB_JSValueString }
+
+constructor TJOB_JSValueString.Create(const aValue: UnicodeString);
+begin
+  Kind:=jjvkString;
+  Value:=aValue;
+end;
+
+function TJOB_JSValueString.AsString: string;
+begin
+  Result:=AnsiQuotedStr(String(Value),'"');
+end;
+
+{ TJOB_JSValueObject }
+
+constructor TJOB_JSValueObject.Create(aValue: IJSObject);
+begin
+  Kind:=jjvkObject;
+  Value:=aValue;
+end;
+
+function TJOB_JSValueObject.AsString: string;
+begin
+  if Value=nil then
+    Result:='nil'
+  else
+    Result:='['+IntToStr(Value.ObjectID)+']:'+Value.ClassName;
+end;
+
 { TJSObject }
 
+function TJSObject.GetObjectID: TJOBObjectID;
+begin
+  Result:=FObjectID;
+end;
+
+function TJSObject.GetClassName: string;
+begin
+  Result:=ClassName;
+end;
+
+function TJSObject.FetchString(Len: NativeInt): UnicodeString;
+var
+  ok: Boolean;
+begin
+  if Len=0 then exit('');
+  ok:=false;
+  try
+    // try to allocate the memory
+    SetLength(Result,Len);
+    ok:=true;
+  finally
+    if not ok then
+      __job_releasestringresult();
+  end;
+  __job_getstringresult(PByte(Result));
+end;
+
 function TJSObject.InvokeJSOneResult(const aName: string;
   const Args: array of const; const InvokeFunc: TJOBInvokeOneResultFunc;
   ResultP: PByte; Invoke: TJOBInvokeGetType): TJOBResult;
@@ -573,22 +758,11 @@ begin
   aError:=InvokeJSOneResult(aName,Args,@__job_invoke_stringresult,@ResultLen,Invoke);
   if aError<>JOBResult_String then
     InvokeJS_RaiseResultMismatch(aName,JOBResult_String,aError);
-  if ResultLen=0 then
-    exit('');
-  try
-    // try to allocate the memory
-    SetLength(Result,ResultLen);
-    //writeln('TJSObject.InvokeJSUnicodeStringResult ResultLen=',ResultLen);
-    aError:=JOBResult_Success;
-  finally
-    if aError<>JOBResult_Success then
-      __job_releasestringresult();
-  end;
-  __job_getstringresult(PByte(Result));
+  Result:=FetchString(ResultLen);
   //writeln('TJSObject.InvokeJSUnicodeStringResult Result="',Result,'"');
 end;
 
-function TJSObject.InvokeJSObjResult(const aName: string;
+function TJSObject.InvokeJSObjectResult(const aName: string;
   const Args: array of const; aResultClass: TJSObjectClass;
   Invoke: TJOBInvokeGetType): TJSObject;
 var
@@ -606,6 +780,40 @@ begin
   Result:=aResultClass.CreateFromID(NewObjId);
 end;
 
+function TJSObject.InvokeJSValueResult(const aName: string;
+  const Args: array of const; Invoke: TJOBInvokeGetType): TJOB_JSValue;
+var
+  Buf: array[0..7] of byte;
+  p: PByte;
+  aError: TJOBResult;
+  Obj: TJSObject;
+begin
+  Result:=nil;
+  FillByte(Buf[0],length(Buf),0);
+  p:=@Buf[0];
+  aError:=InvokeJSOneResult(aName,Args,@__job_invoke_jsvalueresult,p,Invoke);
+  case aError of
+  JOBResult_Undefined:
+    Result:=TJOB_JSValue.Create(jjvkUndefined);
+  JOBResult_Null:
+    Result:=TJOB_JSValueObject.Create(nil);
+  JOBResult_Boolean:
+    Result:=TJOB_JSValueBoolean.Create(p^<>0);
+  JOBResult_Double:
+    Result:=TJOB_JSValueDouble.Create(PDouble(p)^);
+  JOBResult_String:
+    Result:=TJOB_JSValueString.Create(FetchString(PNativeInt(p)^));
+  JOBResult_Function,
+  JOBResult_Object:
+    begin
+    Obj:=TJSObject.CreateFromID(PJOBObjectID(p)^);
+    Result:=TJOB_JSValueObject.Create(Obj);
+    end;
+  else
+    InvokeJS_RaiseResultMismatchStr(aName,'jsvalue',JOBResult_Names[aError]);
+  end;
+end;
+
 function TJSObject.InvokeJSUtf8StringResult(const aName: string;
   const args: array of const; Invoke: TJOBInvokeGetType): String;
 begin
@@ -643,7 +851,7 @@ end;
 function TJSObject.ReadJSPropertyObject(const aName: string;
   aResultClass: TJSObjectClass): TJSObject;
 begin
-  Result:=InvokeJSObjResult(aName,[],aResultClass,jigGetter);
+  Result:=InvokeJSObjectResult(aName,[],aResultClass,jigGetter);
 end;
 
 function TJSObject.ReadJSPropertyUtf8String(const aName: string): string;
@@ -656,6 +864,11 @@ begin
   Result:=InvokeJSLongIntResult(aName,[],jigGetter);
 end;
 
+function TJSObject.ReadJSPropertyValue(const aName: string): TJOB_JSValue;
+begin
+  Result:=InvokeJSValueResult(aName,[],jigGetter);
+end;
+
 procedure TJSObject.WriteJSPropertyBoolean(const aName: string; Value: Boolean);
 begin
   InvokeJSNoResult(aName,[Value],jisSetter);