Browse Source

* Moved to FPC

Michael Van Canneyt 1 year ago
parent
commit
c38e2b65da
1 changed files with 0 additions and 3316 deletions
  1. 0 3316
      demo/wasienv/dom/job_js.pas

+ 0 - 3316
demo/wasienv/dom/job_js.pas

@@ -1,3316 +0,0 @@
-{
-  JOB - JS Object Bridge for Webassembly
-
-  Webassembly unit giving access to the browser DOM.
-
-  see https://wiki.freepascal.org/WebAssembly/DOM
-}
-unit JOB_JS;
-
-{$mode ObjFPC}{$H+}
-{$ModeSwitch advancedrecords}
-
-{$define VerboseJOB}
-
-interface
-uses
-  SysUtils, Types, Math, Classes, Variants, JOB_Shared;
-
-const
-  MinSafeIntDouble = -$1fffffffffffff; // -9007199254740991 54 bits (52 plus signed bit plus implicit highest bit)
-  MaxSafeIntDouble =  $1fffffffffffff; //  9007199254740991
-
-Type
-//  TDOMHighResTimeStamp = Int64;
-
-  PJOBObjectID = ^TJOBObjectID;
-
-  EJSObject = class(Exception);
-  EJSInvoke = class(EJSObject)
-  public
-    ObjectID: TJOBObjectID;
-    FuncName: string;
-  end;
-  EJSArgParse = class(EJSObject);
-
-  TJOB_JSValueKind = (
-    jjvkUndefined,
-    jjvkBoolean,
-    jjvkDouble,
-    jjvkString,
-    jjvkObject,
-    jjvkMethod,
-    jjvkDictionary,
-    jjvkArrayOfJSValue,
-    jjvkArrayOfDouble
-    );
-  TJOB_JSValueKinds = set of TJOB_JSValueKind;
-
-const
-  JOB_JSValueKindNames: array[TJOB_JSValueKind] of string = (
-    'Undefined',
-    'Boolean',
-    'Double',
-    'String',
-    'Object',
-    'Method',
-    'Dictionary',
-    'ArrayOfJSValue',
-    'ArrayOfDouble'
-    );
-
-  JOB_Undefined = Pointer(1);
-
-type
-  TUnicodeStringDynArray = array of UnicodeString;
-
-  { TJOB_JSValue }
-
-  TJOB_JSValue = class
-  public
-    Kind: TJOB_JSValueKind;
-    constructor Create(aKind: TJOB_JSValueKind);
-    function AsString: string; virtual;
-  end;
-  TJOB_JSValueClass = class of TJOB_JSValue;
-  TJOB_JSValueArray = array of TJOB_JSValue;
-
-  { TJOB_Boolean }
-
-  TJOB_Boolean = class(TJOB_JSValue)
-  public
-    Value: Boolean;
-    constructor Create(aValue: Boolean);
-    function AsString: string; override;
-  end;
-
-  { TJOB_Double }
-
-  TJOB_Double = class(TJOB_JSValue)
-  public
-    Value: Double;
-    constructor Create(const aValue: Double);
-    function AsString: string; override;
-  end;
-
-  { TJOB_String }
-
-  TJOB_String = class(TJOB_JSValue)
-  public
-    Value: UnicodeString;
-    constructor Create(const aValue: UnicodeString);
-    function AsString: string; override;
-  end;
-
-  IJSObject = interface;
-
-  { TJOB_Object }
-
-  TJOB_Object = class(TJOB_JSValue)
-  public
-    Value: IJSObject;
-    constructor Create(aValue: IJSObject);
-    function AsString: string; override;
-  end;
-
-  TJOBInvokeType = (
-    jiCall,  // call function
-    jiGet, // read property
-    jiGetTypeOf, // read property and do typeof
-    jiSet, // write property
-    jiNew // new operator
-    );
-  TJOBInvokeTypes = set of TJOBInvokeType;
-
-  TJSObject = class;
-  TJSArray = class;
-  TJSObjectClass = class of TJSObject;
-
-  { TJOBCallbackHelper - parse callback arguments and create result }
-
-  TJOBCallbackHelper = record
-    p: PByte;
-    Index: integer;
-    Count: integer;
-    procedure Init(Args: PByte);
-    function GetType: byte; // see JOBArg* constants, keeps p
-    procedure Skip;
-    function GetBoolean: boolean;
-    function GetDouble: double;
-    function GetString: UnicodeString;
-    function GetObject(aResultClass: TJSObjectClass): TJSObject;
-    function GetValue: TJOB_JSValue;
-    function GetVariant: Variant;
-    function GetLongInt: longint;
-    function GetMaxInt: int64;
-    function GetArray : TJSArray;
-
-    function AllocUndefined: PByte;
-    function AllocBool(b: boolean): PByte;
-    function AllocLongint(i: longint): PByte;
-    function AllocDouble(const d: double): PByte;
-    function AllocString(const s: UnicodeString): PByte;
-    function AllocNil: PByte;
-    function AllocIntf(const Intf: IJSObject): PByte;
-    function AllocObject(Obj: TJSObject): PByte;
-    function AllocObjId(ObjId: TJOBObjectID): PByte;
-    function AllocJSValue(const Value: TJOB_JSValue): PByte;
-    function AllocVariant(const Value: Variant): PByte;
-  end;
-
-  TJOBCallback = function(const aMethod: TMethod; var H: TJOBCallbackHelper): PByte;
-
-  { TJOB_Method }
-
-  TJOB_Method = class(TJOB_JSValue)
-  public
-    Value: TMethod;
-    Invoke: TJOBCallback;
-    constructor Create(const aMethod: TMethod; const AnInvoke: TJOBCallback);
-    function AsString: string; override;
-  end;
-
-  TJOB_Pair = record
-    Name: UnicodeString;
-    Value: TJOB_JSValue;
-  end;
-  TJOB_PairArray = array of TJOB_Pair;
-
-  { TJOB_Dictionary }
-
-  TJOB_Dictionary = class(TJOB_JSValue)
-  public
-    Values: TJOB_PairArray;
-    procedure Add(const aName: UnicodeString; const aValue: TJOB_JSValue);
-    constructor Create(const Pairs: array of const);
-    destructor Destroy; override;
-    procedure Clear;
-  end;
-
-  TJOB_ArrayBase = class(TJOB_JSValue)
-  end;
-
-  { TJOB_ArrayOfJSValue }
-
-  TJOB_ArrayOfJSValue = class(TJOB_ArrayBase)
-  public
-    Values: TJOB_JSValueArray;
-    procedure Add(const aValue: TJOB_JSValue);
-    constructor Create(const TheValues: array of const);
-    destructor Destroy; override;
-    procedure Clear;
-  end;
-
-  { TJOB_ArrayOfDouble }
-
-  TJOB_ArrayOfDouble = class(TJOB_ArrayBase)
-  public
-    Values: TDoubleDynArray;
-    constructor Create(const TheValues: TDoubleDynArray);
-  end;
-
-  IJSArray = interface;
-
-  { IJSObject }
-
-  IJSObject = interface
-    ['{BE5CDE03-D471-4AB3-8F27-A5EA637416F7}']
-    function GetJSObjectID: TJOBObjectID;
-    function GetJSObjectCastSrc: IJSObject;
-    function GetPascalClassName: string;
-    function GetProperties(const PropName: String): Variant; virtual;
-    procedure SetProperties(const PropName: String; const AValue: Variant); virtual;
-    // call a function
-    procedure InvokeJSNoResult(const aName: string; Const Args: Array of const; Invoke: TJOBInvokeType = jiCall); virtual;
-    function InvokeJSBooleanResult(const aName: string; Const Args: Array of const; Invoke: TJOBInvokeType = jiCall): Boolean; virtual;
-    function InvokeJSDoubleResult(const aName: string; Const Args: Array of const; Invoke: TJOBInvokeType = jiCall): Double; virtual;
-    function InvokeJSUnicodeStringResult(const aName: string; Const Args: Array of const; Invoke: TJOBInvokeType = jiCall): UnicodeString; virtual;
-    function InvokeJSObjectResult(const aName: string; Const Args: Array of const; aResultClass: TJSObjectClass; Invoke: TJOBInvokeType = jiCall): TJSObject; virtual;
-    function InvokeJSValueResult(const aName: string; Const Args: Array of const; Invoke: TJOBInvokeType = jiCall): TJOB_JSValue; virtual;
-    function InvokeJSVariantResult(const aName: string; Const Args: Array of const; Invoke: TJOBInvokeType = jiCall): Variant; virtual;
-    function InvokeJSUtf8StringResult(const aName: string; Const args: Array of const; Invoke: TJOBInvokeType = jiCall): String; virtual;
-    function InvokeJSLongIntResult(const aName: string; Const args: Array of const; Invoke: TJOBInvokeType = jiCall): LongInt; virtual;
-    function InvokeJSTypeOf(const aName: string; Const Args: Array of const): TJOBResult; virtual;
-    function InvokeJSUnicodeStringArrayResult(const aName: string; Const Args: Array of const; Invoke: TJOBInvokeType = jiCall): TUnicodeStringDynArray; virtual;
-    // read a property
-    function ReadJSPropertyBoolean(const aName: string): boolean; virtual;
-    function ReadJSPropertyDouble(const aName: string): double; virtual;
-    function ReadJSPropertyUnicodeString(const aName: string): UnicodeString; virtual;
-    function ReadJSPropertyObject(const aName: string; aResultClass: TJSObjectClass): TJSObject; virtual;
-    function ReadJSPropertyUtf8String(const aName: string): string; virtual;
-    function ReadJSPropertyLongInt(const aName: string): LongInt; virtual;
-    function ReadJSPropertyInt64(const aName: string): Int64; virtual;
-    function ReadJSPropertyValue(const aName: string): TJOB_JSValue; virtual;
-    function ReadJSPropertyVariant(const aName: string): Variant; virtual;
-    function ReadJSPropertyMethod(const aName: string): TMethod; virtual;
-    // write a property
-    procedure WriteJSPropertyBoolean(const aName: string; Value: Boolean); virtual;
-    procedure WriteJSPropertyDouble(const aName: string; Value: Double); virtual;
-    procedure WriteJSPropertyUnicodeString(const aName: string; const Value: UnicodeString); virtual;
-    procedure WriteJSPropertyUtf8String(const aName: string; const Value: String); virtual;
-    procedure WriteJSPropertyObject(const aName: string; Value: IJSObject); virtual;
-    procedure WriteJSPropertyLongInt(const aName: string; Value: LongInt); virtual;
-    procedure WriteJSPropertyInt64(const aName: string; Value: Int64); virtual;
-    procedure WriteJSPropertyValue(const aName: string; Value: TJOB_JSValue); virtual;
-    procedure WriteJSPropertyVariant(const aName: string; const Value: Variant); virtual;
-    procedure WriteJSPropertyMethod(const aName: string; const Value: TMethod); virtual;
-    // create a new object using the new-operator
-    function NewJSObject(Const Args: Array of const; aResultClass: TJSObjectClass): TJSObject; virtual;
-    // JS members
-    function getOwnPropertyNames(const Obj: IJSObject): TUnicodeStringDynArray;
-    function getPrototypeOf(const Obj: IJSObject): IJSObject;
-    function hasOwnProperty(const PropName: String): boolean; virtual;
-    function isPrototypeOf(const Obj: IJSObject): boolean; virtual;
-    function propertyIsEnumerable(const PropName: String): boolean; virtual;
-    function toLocaleString: UnicodeString; virtual; overload;
-    function toString: String; override; overload;
-    function toUString: UnicodeString; virtual; overload;
-    function valueOf: Variant; virtual; overload;
-    property Properties[const PropName: String]: Variant read GetProperties write SetProperties; default;
-  end;
-
-  { TJSObject }
-
-  TJSObject = class(TInterfacedObject,IJSObject)
-  private
-    FJOBObjectID: TJOBObjectID;
-    FJOBCastSrc: IJSObject;
-    FJOBObjectIDOwner: boolean;
-  protected
-    type
-      TJOBInvokeNoResultFunc = function(
-          ObjID: TJOBObjectID;
-          NameP: PChar;
-          NameLen: longint;
-          Invoke: longint;
-          ArgP: PByte
-        ): TJOBResult;
-      TJOBInvokeOneResultFunc = function(
-          ObjID: TJOBObjectID;
-          NameP: PChar;
-          NameLen: longint;
-          Invoke: longint;
-          ArgP: PByte;
-          ResultP: PByte
-        ): TJOBResult;
-    function GetJSObjectID: TJOBObjectID;
-    function GetJSObjectCastSrc: IJSObject;
-    function GetPascalClassName: string;
-    function GetProperties(const PropName: String): Variant; virtual;
-    procedure SetProperties(const PropName: String; const AValue: Variant); virtual;
-    function FetchString(Len: NativeInt): UnicodeString;
-    function InvokeJSNoResultFunc(const aName: string; Const Args: Array of const;
-      const InvokeFunc: TJOBInvokeNoResultFunc; Invoke: TJOBInvokeType): TJOBResult;
-    function InvokeJSOneResult(const aName: string; Const Args: Array of const;
-      const InvokeFunc: TJOBInvokeOneResultFunc; ResultP: PByte; Invoke: TJOBInvokeType): TJOBResult;
-    procedure InvokeJS_Raise(const aName, Msg: string); virtual;
-    procedure InvokeJS_RaiseResultMismatch(const aName: string; Expected, Actual: TJOBResult); virtual;
-    procedure InvokeJS_RaiseResultMismatchStr(const aName: string; const Expected, Actual: string); virtual;
-    function CreateInvokeJSArgs(const Args: array of const): PByte; virtual;
-  public
-    constructor JOBCast(const Intf: IJSObject); overload;
-    constructor JOBCreateFromID(aID: TJOBObjectID); virtual; // use this only for the owner (it will release it on free)
-    constructor JOBCreateGlobal(const aID: UnicodeString); virtual;
-    class function Cast(const Intf: IJSObject): IJSObject; overload;
-    destructor Destroy; override;
-    property JOBObjectID: TJOBObjectID read FJOBObjectID;
-    property JOBObjectIDOwner: boolean read FJOBObjectIDOwner write FJOBObjectIDOwner;
-    property JOBCastSrc: IJSObject read FJOBCastSrc; // nil means it is the original, otherwise it is a typecast
-    // call a function
-    procedure InvokeJSNoResult(const aName: string; Const Args: Array of const; Invoke: TJOBInvokeType = jiCall); virtual;
-    function InvokeJSBooleanResult(const aName: string; Const Args: Array of const; Invoke: TJOBInvokeType = jiCall): Boolean; virtual;
-    function InvokeJSDoubleResult(const aName: string; Const Args: Array of const; Invoke: TJOBInvokeType = jiCall): Double; virtual;
-    function InvokeJSUnicodeStringResult(const aName: string; Const Args: Array of const; Invoke: TJOBInvokeType = jiCall): UnicodeString; virtual;
-    function InvokeJSObjectResult(const aName: string; Const Args: Array of const; aResultClass: TJSObjectClass; Invoke: TJOBInvokeType = jiCall): TJSObject; virtual;
-    function InvokeJSValueResult(const aName: string; Const Args: Array of const; Invoke: TJOBInvokeType = jiCall): TJOB_JSValue; virtual;
-    function InvokeJSVariantResult(const aName: string; Const Args: Array of const; Invoke: TJOBInvokeType = jiCall): Variant; virtual;
-    function InvokeJSUtf8StringResult(const aName: string; Const args: Array of const; Invoke: TJOBInvokeType = jiCall): String; virtual;
-    function InvokeJSLongIntResult(const aName: string; Const args: Array of const; Invoke: TJOBInvokeType = jiCall): LongInt; virtual;
-    function InvokeJSMaxIntResult(const aName: string; Const args: Array of const; Invoke: TJOBInvokeType = jiCall): int64; virtual;
-    function InvokeJSTypeOf(const aName: string; Const Args: Array of const): TJOBResult; virtual;
-    function InvokeJSUnicodeStringArrayResult(const aName: string; Const Args: Array of const; Invoke: TJOBInvokeType = jiCall): TUnicodeStringDynArray; virtual;
-    // read a property
-    function ReadJSPropertyBoolean(const aName: string): boolean; virtual;
-    function ReadJSPropertyDouble(const aName: string): double; virtual;
-    function ReadJSPropertyUnicodeString(const aName: string): UnicodeString; virtual;
-    function ReadJSPropertyObject(const aName: string; aResultClass: TJSObjectClass): TJSObject; virtual;
-    function ReadJSPropertyUtf8String(const aName: string): string; virtual;
-    function ReadJSPropertyLongInt(const aName: string): LongInt; virtual;
-    function ReadJSPropertyInt64(const aName: string): Int64; virtual;
-    function ReadJSPropertyValue(const aName: string): TJOB_JSValue; virtual;
-    function ReadJSPropertyVariant(const aName: string): Variant; virtual;
-    function ReadJSPropertyMethod(const aName: string): TMethod; virtual;
-    // write a property
-    procedure WriteJSPropertyBoolean(const aName: string; Value: Boolean); virtual;
-    procedure WriteJSPropertyDouble(const aName: string; Value: Double); virtual;
-    procedure WriteJSPropertyUnicodeString(const aName: string; const Value: UnicodeString); virtual;
-    procedure WriteJSPropertyUtf8String(const aName: string; const Value: String); virtual;
-    procedure WriteJSPropertyObject(const aName: string; Value: IJSObject); virtual;
-    procedure WriteJSPropertyLongInt(const aName: string; Value: LongInt); virtual;
-    procedure WriteJSPropertyInt64(const aName: string; Value: Int64); virtual;
-    procedure WriteJSPropertyValue(const aName: string; Value: TJOB_JSValue); virtual;
-    procedure WriteJSPropertyVariant(const aName: string; const Value: Variant); virtual;
-    procedure WriteJSPropertyMethod(const aName: string; const Value: TMethod); virtual;
-    // create a new object using the new-operator
-    function NewJSObject(Const Args: Array of const; aResultClass: TJSObjectClass): TJSObject; virtual;
-    // JS members
-    function getOwnPropertyNames(const Obj: IJSObject): TUnicodeStringDynArray;
-    function getPrototypeOf(const Obj: IJSObject): IJSObject;
-    function hasOwnProperty(const PropName: String): boolean; virtual;
-    function isPrototypeOf(const Obj: IJSObject): boolean; virtual;
-    function propertyIsEnumerable(const PropName: String): boolean; virtual;
-    function toLocaleString: UnicodeString; virtual; overload;
-    function toString: String; override; overload;
-    function toUString: UnicodeString; virtual; overload;
-    function valueOf: Variant; virtual; overload;
-    property Properties[const PropName: String]: Variant read GetProperties write SetProperties; default;
-  end;
-
-  { IJSSet }
-
-  IJSSet = interface(IJSObject)
-    ['{1D276953-95E2-4B07-8D4E-BE70D1CEF356}']
-  end;
-
-  { TJSSet }
-
-  TJSSet = class(TJSObject,IJSSet)
-  public
-    class function Cast(const Intf: IJSObject): IJSSet; overload;
-  end;
-
-  { IJSMap }
-
-  IJSMap = interface(IJSObject)
-    ['{D31F19A1-388E-4612-BC71-9392ECA90DA3}']
-  end;
-
-  { TJSMap }
-
-  TJSMap = class(TJSObject,IJSMap)
-  public
-    class function Cast(const Intf: IJSObject): IJSMap; overload;
-  end;
-
-  { IJSFunction }
-
-  IJSFunction = interface(IJSObject)
-    ['{8BD36F12-F6F7-4F8B-91FB-43D8626A72FE}']
-    function _GetLength: NativeInt;
-    function _GetName: UnicodeString;
-    function _GetPrototyp: IJSFunction;
-    procedure _SetName(const AValue: UnicodeString);
-    property name: UnicodeString read _GetName write _SetName;
-    property prototyp: IJSFunction read _GetPrototyp;
-    property length: NativeInt read _GetLength;
-    //function apply(thisArg: TJSObject; const ArgArray: TJSValueDynArray): JSValue; varargs;
-    //function bind(thisArg: TJSObject): JSValue; varargs;
-    //function call(thisArg: TJSObject): JSValue; varargs;
-  end;
-
-  { TJSFunction }
-
-  TJSFunction = class(TJSObject,IJSFunction)
-  public
-    function _GetLength: NativeInt;
-    function _GetName: UnicodeString;
-    function _GetPrototyp: IJSFunction;
-    procedure _SetName(const AValue: UnicodeString);
-    property name: UnicodeString read _GetName write _SetName;
-    property prototyp: IJSFunction read _GetPrototyp;
-    property length: NativeInt read _GetLength;
-    class function Cast(const Intf: IJSObject): IJSFunction; overload;
-  end;
-
-  { IJSDate }
-
-  IJSDate = interface(IJSObject)
-    ['{F12818EA-542E-488C-A3C5-279E05639E9E}']
-    function Create(aYear: NativeInt; aMonth: NativeInt; aDayOfMonth: NativeInt = 1;
-      TheHours: NativeInt = 0; TheMinutes: NativeInt = 0; TheSeconds: NativeInt = 0;
-      TheMilliseconds: NativeInt = 0): IJSDate;
-    function toLocaleDateString: UnicodeString; overload; // date in locale timezone, no time
-  end;
-
-  { TJSDate }
-
-  TJSDate = class(TJSObject,IJSDate)
-  public
-    class function Cast(const Intf: IJSObject): IJSDate; overload;
-    function Create(aYear: NativeInt; aMonth: NativeInt; aDayOfMonth: NativeInt = 1;
-      TheHours: NativeInt = 0; TheMinutes: NativeInt = 0; TheSeconds: NativeInt = 0;
-      TheMilliseconds: NativeInt = 0): IJSDate;
-    function toLocaleDateString: UnicodeString; overload; // date in locale timezone, no time
-  end;
-
-  { IJSRegExp }
-
-  IJSRegExp = interface(IJSObject)
-    ['{3E9E4F54-10DA-45BF-ABED-7ED2C255617E}']
-    function exec(const aString: UnicodeString): IJSArray;
-    function _GetGlobal: Boolean;
-    function _GetIgnoreCase: Boolean;
-    function _GetLastIndex: NativeInt;
-    function _GetMultiLine: Boolean;
-    function _GetSource: UnicodeString;
-    function _GetUnicode: boolean;
-    procedure _SetGlobal(const AValue: Boolean);
-    procedure _SetIgnoreCase(const AValue: Boolean);
-    procedure _SetlastIndex(const AValue: NativeInt);
-    procedure _SetMultiline(const AValue: Boolean);
-    procedure _SetSource(const AValue: UnicodeString);
-    procedure _SetUnicode(const AValue: boolean);
-    function test(const aString: UnicodeString): boolean;
-    property lastIndex: NativeInt read _GetLastIndex write _SetlastIndex;
-    property global: Boolean read _GetGlobal write _SetGlobal;
-    property ignoreCase: Boolean read _GetIgnoreCase write _SetIgnoreCase;
-    property multiline: Boolean Read _GetMultiLine write _SetMultiline;
-    property source: UnicodeString Read _GetSource write _SetSource;
-    property unicode: boolean Read _GetUnicode write _SetUnicode;
-  end;
-
-  { TJSRegExp }
-
-  TJSRegExp = class(TJSObject,IJSRegExp)
-  public
-    function exec(const aString: UnicodeString): IJSArray;
-    function _GetGlobal: Boolean;
-    function _GetIgnoreCase: Boolean;
-    function _GetLastIndex: NativeInt;
-    function _GetMultiLine: Boolean;
-    function _GetSource: UnicodeString;
-    function _GetUnicode: boolean;
-    procedure _SetGlobal(const AValue: Boolean);
-    procedure _SetIgnoreCase(const AValue: Boolean);
-    procedure _SetlastIndex(const AValue: NativeInt);
-    procedure _SetMultiline(const AValue: Boolean);
-    procedure _SetSource(const AValue: UnicodeString);
-    procedure _SetUnicode(const AValue: boolean);
-    function test(const aString: UnicodeString): boolean;
-    property lastIndex: NativeInt read _GetLastIndex write _SetlastIndex;
-    property global: Boolean read _GetGlobal write _SetGlobal;
-    property ignoreCase: Boolean read _GetIgnoreCase write _SetIgnoreCase;
-    property multiline: Boolean Read _GetMultiLine write _SetMultiline;
-    property source: UnicodeString Read _GetSource write _SetSource;
-    property unicode: boolean Read _GetUnicode write _SetUnicode;
-    class function Cast(const Intf: IJSObject): IJSRegExp; overload;
-  end;
-
-  { IJSString }
-
-  IJSString = interface(IJSObject)
-    ['{4C3B1B1C-4C0D-42A2-81BE-36CC78DCF9AE}']
-  end;
-
-  { TJSString }
-
-  TJSString = class(TJSObject,IJSString)
-  public
-    class function Cast(const Intf: IJSObject): IJSString; overload;
-  end;
-  
-  IJSIterator = interface (IJSObject) ['{21E331BA-7B57-42DD-8DCE-B26FEA85C639}']
-  end;
-  
-  TJSIterator = class(TJSObject,IJSIterator)
-  end;
-
-  { IJSArray }
-
-  IJSArray = interface(IJSObject)
-    ['{21E331BA-7B57-42DD-8DCE-B26FEA85C693}']
-    function _GetElements(Index: NativeInt): TJOB_JSValue;
-    function _GetLength: NativeInt;
-    procedure _SetElements(Index: NativeInt; const AValue: TJOB_JSValue);
-    procedure _SetLength(const AValue: NativeInt);
-    function isArray(a: TJOB_JSValue): Boolean; overload;
-    function concat(el: TJOB_JSValue): IJSArray; overload; {varargs;}
-    //function copyWithin(aTarget: NativeInt): TJSArray;overload; // not in IE
-    //function copyWithin(aTarget, aStart: NativeInt): TJSArray;overload; // not in IE
-    //function copyWithin(aTarget, aStart, aEnd: NativeInt): TJSArray;overload; // not in IE
-    //function entries: TJSIterator;
-    //Function every(const aCallback: TJSArrayCallBack): boolean;overload;
-    //Function every(const aCallback: TJSArrayEvent; aThis: TObject): boolean;overload;
-    //Function filter(const aCallBack: TJSArrayCallBack): TJSArray; overload;
-    //Function filter(const aCallBack: TJSArrayEvent; aThis: TObject): TJSArray;overload;
-    Function fill(aValue: TJOB_JSValue): IJSArray; overload;
-    Function fill(aValue: TJOB_JSValue; aStartIndex: NativeInt): IJSArray; overload;
-    Function fill(aValue: TJOB_JSValue; aStartIndex,aEndIndex: NativeInt): IJSArray; overload;
-    //Function find(const aCallBack: TJSArrayCallBack): TJOB_JSValue; overload;
-    //Function find(const aCallBack: TJSArrayEvent; aThis: TObject): TJOB_JSValue; overload;
-    //Function findIndex(const aCallBack: TJSArrayCallBack): NativeInt; overload;
-    //Function findIndex(const aCallBack: TJSArrayEvent; aThis: TObject): NativeInt; overload;
-    //procedure forEach(const aCallBack: TJSArrayEventProc); overload;
-    //procedure forEach(const aCallBack: TJSArrayEvent); overload;
-    //procedure forEach(const aCallBack: TJSArrayEvent; aThis: TObject); overload;
-    function includes(aElement: TJOB_JSValue): Boolean; overload;
-    function includes(aElement: TJOB_JSValue; FromIndex: NativeInt): Boolean; overload;
-    function indexOf(aElement: TJOB_JSValue): NativeInt; overload;
-    function indexOf(aElement: TJOB_JSValue; FromIndex: NativeInt): NativeInt; overload;
-    function join: UnicodeString; overload;
-    function join (const aSeparator: UnicodeString): UnicodeString; overload;
-    //function keys: TJSIterator;
-    function lastIndexOf(aElement: TJOB_JSValue): NativeInt; overload;
-    function lastIndexOf(aElement: TJOB_JSValue; FromIndex: NativeInt): NativeInt; overload;
-    //Function map(const aCallBack: TJSArrayMapCallBack): TJSArray; overload;
-    //Function map(const aCallBack: TJSArrayMapEvent; aThis: TObject): TJSArray; overload;
-    function pop: TJOB_JSValue;
-    function push(aElement: TJOB_JSValue): NativeInt; overload; {varargs;}
-    //function reduce(const aCallBack: TJSArrayReduceCallBack): TJOB_JSValue; overload;
-    //function reduce(const aCallBack: TJSArrayReduceCallBack; initialValue: TJOB_JSValue): TJOB_JSValue; overload;
-    //function reduceRight(const aCallBack: TJSArrayReduceCallBack): TJOB_JSValue; overload;
-    //function reduceRight(const aCallBack: TJSArrayReduceCallBack; initialValue: TJOB_JSValue): TJOB_JSValue; overload;
-    Function reverse: IJSArray;
-    Function shift: TJOB_JSValue;
-    Function slice: IJSArray; overload;
-    function slice(aBegin: NativeInt): IJSArray; overload;
-    function slice(aBegin,aEnd: NativeInt): IJSArray; overload;
-    //Function some(const aCallback: TJSArrayCallBack): boolean; overload;
-    //Function some(const aCallback: TJSArrayEvent; aThis: TObject): boolean; overload;
-    //Function sort(const aCallback: TJSArrayCompareCallBack): IJSArray; overload;
-    Function sort(): IJSArray; overload;
-    function splice(aStart: NativeInt): IJSArray; overload;
-    function splice(aStart,aDeleteCount: NativeInt): IJSArray; {varargs;} overload;
-    function toLocaleString(const locales: UnicodeString): UnicodeString; overload;
-    //function toLocaleString(locales: string; const Options: TLocaleCompareOptions): String; overload;
-    function unshift: NativeInt; {varargs;}
-    //function values: TJSIterator;
-    Property Length: NativeInt Read _GetLength Write _SetLength;
-    property Elements[Index: NativeInt]: TJOB_JSValue read _GetElements write _SetElements; default;
-  end;
-
-  { TJSArray }
-
-  TJSArray = class(TJSObject,IJSArray)
-  private
-    function _GetElements(Index: NativeInt): TJOB_JSValue;
-    function _GetLength: NativeInt;
-    procedure _SetElements(Index: NativeInt; const AValue: TJOB_JSValue);
-    procedure _SetLength(const AValue: NativeInt);
-  public
-    function isArray(a: TJOB_JSValue): Boolean; overload;
-    function concat(el: TJOB_JSValue): IJSArray; overload; {varargs;}
-    //function copyWithin(aTarget: NativeInt): IJSArray;overload; // not in IE
-    //function copyWithin(aTarget, aStart: NativeInt): IJSArray;overload; // not in IE
-    //function copyWithin(aTarget, aStart, aEnd: NativeInt): IJSArray;overload; // not in IE
-    //function entries: TJSIterator;
-    //Function every(const aCallback: TJSArrayCallBack): boolean;overload;
-    //Function every(const aCallback: TJSArrayEvent; aThis: TObject): boolean;overload;
-    //Function filter(const aCallBack: TJSArrayCallBack): IJSArray; overload;
-    //Function filter(const aCallBack: TJSArrayEvent; aThis: TObject): IJSArray;overload;
-    Function fill(aValue: TJOB_JSValue): IJSArray; overload;
-    Function fill(aValue: TJOB_JSValue; aStartIndex: NativeInt): IJSArray; overload;
-    Function fill(aValue: TJOB_JSValue; aStartIndex,aEndIndex: NativeInt): IJSArray; overload;
-    //Function find(const aCallBack: TJSArrayCallBack): TJOB_JSValue; overload;
-    //Function find(const aCallBack: TJSArrayEvent; aThis: TObject): TJOB_JSValue; overload;
-    //Function findIndex(const aCallBack: TJSArrayCallBack): NativeInt; overload;
-    //Function findIndex(const aCallBack: TJSArrayEvent; aThis: TObject): NativeInt; overload;
-    //procedure forEach(const aCallBack: TJSArrayEventProc); overload;
-    //procedure forEach(const aCallBack: TJSArrayEvent); overload;
-    //procedure forEach(const aCallBack: TJSArrayEvent; aThis: TObject); overload;
-    function includes(aElement: TJOB_JSValue): Boolean; overload;
-    function includes(aElement: TJOB_JSValue; FromIndex: NativeInt): Boolean; overload;
-    function indexOf(aElement: TJOB_JSValue): NativeInt; overload;
-    function indexOf(aElement: TJOB_JSValue; FromIndex: NativeInt): NativeInt; overload;
-    function join: UnicodeString; overload;
-    function join (const aSeparator: UnicodeString): UnicodeString; overload;
-    //function keys: TJSIterator;
-    function lastIndexOf(aElement: TJOB_JSValue): NativeInt; overload;
-    function lastIndexOf(aElement: TJOB_JSValue; FromIndex: NativeInt): NativeInt; overload;
-    //Function map(const aCallBack: TJSArrayMapCallBack): IJSArray; overload;
-    //Function map(const aCallBack: TJSArrayMapEvent; aThis: TObject): IJSArray; overload;
-    function pop: TJOB_JSValue;
-    function push(aElement: TJOB_JSValue): NativeInt; overload; {varargs;}
-    //function reduce(const aCallBack: TJSArrayReduceCallBack): TJOB_JSValue; overload;
-    //function reduce(const aCallBack: TJSArrayReduceCallBack; initialValue: TJOB_JSValue): TJOB_JSValue; overload;
-    //function reduceRight(const aCallBack: TJSArrayReduceCallBack): TJOB_JSValue; overload;
-    //function reduceRight(const aCallBack: TJSArrayReduceCallBack; initialValue: TJOB_JSValue): TJOB_JSValue; overload;
-    Function reverse: IJSArray;
-    Function shift: TJOB_JSValue;
-    Function slice: IJSArray; overload;
-    function slice(aBegin: NativeInt): IJSArray; overload;
-    function slice(aBegin,aEnd: NativeInt): IJSArray; overload;
-    //Function some(const aCallback: TJSArrayCallBack): boolean; overload;
-    //Function some(const aCallback: TJSArrayEvent; aThis: TObject): boolean; overload;
-    //Function sort(const aCallback: TJSArrayCompareCallBack): IJSArray; overload;
-    Function sort(): IJSArray; overload;
-    function splice(aStart: NativeInt): IJSArray; overload;
-    function splice(aStart,aDeleteCount: NativeInt): IJSArray; {varargs;} overload;
-    function toLocaleString(const locales: UnicodeString): UnicodeString; overload;
-    //function toLocaleString(locales: string; const Options: TLocaleCompareOptions): String; overload;
-    function unshift: NativeInt; {varargs;}
-    //function values: TJSIterator;
-    Property Length: NativeInt Read _GetLength Write _SetLength;
-    property Elements[Index: NativeInt]: TJOB_JSValue read _GetElements write _SetElements; default;
-    class function Cast(const Intf: IJSObject): IJSArray; overload;
-  end;
-
-  { IJSArrayBuffer }
-
-  IJSArrayBuffer = interface(IJSObject)
-    ['{A1612EED-4F05-46C0-90BE-ACD511B15E89}']
-  end;
-
-
-  { TJSArrayBuffer }
-
-  TJSArrayBuffer = class(TJSObject,IJSArrayBuffer)
-  public
-    class function Cast(const Intf: IJSObject): IJSArrayBuffer; overload;
-  end;
-
-  { IJSArrayBufferView }
-  
-  IJSArrayBufferView = interface(IJSObject)
-    ['{A1612EED-4F05-46C0-90BE-ACD511B1598E}']
-  end;
-  
-  { TJSArrayBufferView }
-  
-  TJSArrayBufferView = class(TJSObject,IJSArrayBufferView)
-  public
-    class function Cast(const Intf: IJSObject): IJSArrayBufferView; overload;
-  end;
-
-
-  { IJSTypedArray }
-
-  IJSTypedArray = interface(IJSObject)
-    ['{6A76602B-9555-4136-A7B7-2E683265EA82}']
-  end;
-
-  { TJSTypedArray }
-
-  TJSTypedArray = class(TJSObject,IJSTypedArray)
-  public
-    class function Cast(const Intf: IJSObject): IJSTypedArray; overload;
-  end;
-
-  { IJSInt8Array }
-
-  IJSInt8Array = interface(IJSTypedArray)
-    ['{72D65C5E-E18E-4294-8709-D7A63BF12958}']
-  end;
-
-  { TJSInt8Array }
-
-  TJSInt8Array = class(TJSTypedArray,IJSInt8Array)
-  public
-    class function Cast(const Intf: IJSObject): IJSInt8Array; overload;
-  end;
-
-  { IJSUint8Array }
-
-  IJSUint8Array = interface(IJSTypedArray)
-    ['{99EC7B3A-30E5-425F-933C-C169B2F4193C}']
-  end;
-
-  { TJSUint8Array }
-
-  TJSUint8Array = class(TJSTypedArray,IJSUint8Array)
-  public
-    class function Cast(const Intf: IJSObject): IJSUint8Array; overload;
-  end;
-
-  { IJSUint8ClampedArray }
-
-  IJSUint8ClampedArray = interface(IJSTypedArray)
-    ['{A1508D6E-8629-4416-875E-9F669ECDC47F}']
-  end;
-
-  { TJSUint8ClampedArray }
-
-  TJSUint8ClampedArray = class(TJSTypedArray,IJSUint8ClampedArray)
-  public
-    class function Cast(const Intf: IJSObject): IJSUint8ClampedArray; overload;
-  end;
-
-  { IJSInt16Array }
-
-  IJSInt16Array = interface(IJSTypedArray)
-    ['{B5FA7A13-D8CA-44E4-ADAE-F10FFFAE46B4}']
-  end;
-
-  { TJSInt16Array }
-
-  TJSInt16Array = class(TJSTypedArray,IJSInt16Array)
-  public
-    class function Cast(const Intf: IJSObject): IJSInt16Array; overload;
-  end;
-
-  { IJSUint16Array }
-
-  IJSUint16Array = interface(IJSTypedArray)
-    ['{6023E2BC-C464-4288-A8DA-4A5D0B2B915E}']
-  end;
-
-  { TJSUint16Array }
-
-  TJSUint16Array = class(TJSTypedArray,IJSUint16Array)
-  public
-    class function Cast(const Intf: IJSObject): IJSUint16Array; overload;
-  end;
-
-  { IJSInt32Array }
-
-  IJSInt32Array = interface(IJSTypedArray)
-    ['{16F1A6FB-2F26-4A64-8A2B-D883DE2F58C4}']
-  end;
-
-  { TJSInt32Array }
-
-  TJSInt32Array = class(TJSTypedArray,IJSInt32Array)
-  public
-    class function Cast(const Intf: IJSObject): IJSInt32Array; overload;
-  end;
-
-  { IJSUint32Array }
-
-  IJSUint32Array = interface(IJSTypedArray)
-    ['{C637B2FA-CED6-4EC7-8D97-C56824EAF8B3}']
-  end;
-
-  { TJSUint32Array }
-
-  TJSUint32Array = class(TJSTypedArray,IJSUint32Array)
-  public
-    class function Cast(const Intf: IJSObject): IJSUint32Array; overload;
-  end;
-
-  { IJSFloat32Array }
-
-  IJSFloat32Array = interface(IJSTypedArray)
-    ['{B5CE57F6-CA7C-4168-AEA3-32EF13DA52D6}']
-  end;
-
-  { TJSFloat32Array }
-
-  TJSFloat32Array = class(TJSTypedArray,IJSFloat32Array)
-  public
-    class function Cast(const Intf: IJSObject): IJSFloat32Array; overload;
-  end;
-
-  { IJSFloat64Array }
-
-  IJSFloat64Array = interface(IJSTypedArray)
-    ['{A7876DC5-9549-4FDA-BE35-A641CE9D9F0B}']
-  end;
-
-  { TJSFloat64Array }
-
-  TJSFloat64Array = class(TJSTypedArray,IJSFloat64Array)
-  public
-    class function Cast(const Intf: IJSObject): IJSFloat64Array; overload;
-  end;
-
-  { IJSBufferSource }
-
-  IJSBufferSource = interface(IJSObject)
-    ['{7F2A68EE-2FA6-445C-BFC1-2C9E4D45FFBF}']
-  end;
-
-  { TJSBufferSource }
-
-  TJSBufferSource = class(TJSObject,IJSBufferSource)
-  public
-    class function Cast(const Intf: IJSObject): IJSBufferSource; overload;
-  end;
-
-  { IJSDataView }
-
-  IJSDataView = interface(IJSObject)
-    ['{42F14387-FAD2-46BA-8CB4-057445095CEE}']
-  end;
-
-  { TJSDataView }
-
-  TJSDataView = class(TJSObject,IJSDataView)
-  public
-    class function Cast(const Intf: IJSObject): IJSDataView; overload;
-  end;
-
-  { IJSJSON }
-
-  IJSJSON = interface(IJSObject)
-    ['{73535059-91DD-4A22-91A6-D8072008C5F3}']
-    function parse(const aJSON: UnicodeString): TJOB_JSValue; overload;
-    // Use this only when you are sure you will get an object, no checking is done.
-    function parseObject(const aJSON: UnicodeString): IJSObject; overload;
-    function stringify(aValue: TJOB_JSValue): UnicodeString; overload;
-    function stringify(aValue,aReplacer: TJOB_JSValue): UnicodeString; overload;
-    function stringify(aValue,aReplacer: TJOB_JSValue; space:  NativeInt): UnicodeString; overload;
-    function stringify(aValue,aReplacer: TJOB_JSValue; const space: UnicodeString): UnicodeString; overload;
-  end;
-
-  { TJSJSON }
-
-  TJSJSON = class(TJSObject,IJSJSON)
-  public
-    function parse(const aJSON: UnicodeString): TJOB_JSValue; overload;
-    // Use this only when you are sure you will get an object, no checking is done.
-    function parseObject(const aJSON: UnicodeString): IJSObject; overload;
-    function stringify(aValue: TJOB_JSValue): UnicodeString; overload;
-    function stringify(aValue,aReplacer: TJOB_JSValue): UnicodeString; overload;
-    function stringify(aValue,aReplacer: TJOB_JSValue; space:  NativeInt): UnicodeString; overload;
-    function stringify(aValue,aReplacer: TJOB_JSValue; const space: UnicodeString): UnicodeString; overload;
-    class function Cast(const Intf: IJSObject): IJSJSON; overload;
-  end;
-
-  { IJSError }
-
-  IJSError = interface(IJSObject)
-    ['{80532C4D-CAD2-4C70-A4EA-01B29BB8C2C8}']
-  end;
-
-  { TJSError }
-
-  TJSError = class(TJSObject,IJSError)
-  public
-    class function Cast(const Intf: IJSObject): IJSError; overload;
-  end;
-
-  TJSPromiseResolver = function(const aValue: Variant): Variant of object;
-  TJSPromiseExecutor = procedure(const OnResolve, OnReject: TJSPromiseResolver) of object;
-  TJSPromiseFinallyHandler = procedure of object;
-
-  { IJSPromise }
-
-  IJSPromise = interface(IJSObject)
-    ['{2BFE673B-B5D4-4F31-96CD-5E1A60EFBE26}']
-    function all(const arg: Variant): IJSPromise; overload;
-    function allSettled(const arg: Variant): IJSPromise; overload;
-    function race(const arg: Variant): IJSPromise; overload;
-    function reject(const reason: Variant): IJSPromise; overload;
-    function resolve(const value: Variant): IJSPromise; overload;
-    function resolve: IJSPromise; overload;
-    function _then(const OnAccepted: TJSPromiseResolver): IJSPromise; overload;
-    function _then(const OnAccepted, OnRejected: TJSPromiseResolver) : IJSPromise; overload;
-    function catch(const OnRejected: TJSPromiseResolver): IJSPromise; overload;
-    function _finally(const Handler: TJSPromiseFinallyHandler): IJSPromise; overload;
-  end;
-
-  { TJSPromise }
-
-  TJSPromise = class(TJSObject,IJSPromise)
-  public
-    //class function Create(const Executor: TJSPromiseExecutor): IJSPromise; overload;
-    function all(const arg: Variant): IJSPromise; overload;
-    function allSettled(const arg: Variant): IJSPromise; overload;
-    function race(const arg: Variant): IJSPromise; overload;
-    function reject(const reason: Variant): IJSPromise; overload;
-    function resolve(const value: Variant): IJSPromise; overload;
-    function resolve: IJSPromise; overload;
-    function _then(const OnAccepted: TJSPromiseResolver): IJSPromise; overload;
-    function _then(const OnAccepted, OnRejected: TJSPromiseResolver) : IJSPromise; overload;
-    function catch(const OnRejected: TJSPromiseResolver): IJSPromise; overload;
-    function _finally(const Handler: TJSPromiseFinallyHandler): IJSPromise; overload;
-    class function Cast(const Intf: IJSObject): IJSPromise; overload;
-  end;
-
-  { IJSTextDecoder }
-
-  IJSTextDecoder = interface(IJSObject)
-    ['{EB42F04D-B92D-42AC-96F8-58DEC2F7F8D0}']
-  end;
-
-  { TJSTextDecoder }
-
-  TJSTextDecoder = class(TJSObject,IJSTextDecoder)
-  public
-    class function Cast(const Intf: IJSObject): IJSTextDecoder; overload;
-  end;
-
-  { IJSTextEncoder }
-
-  IJSTextEncoder = interface(IJSObject)
-    ['{C2964DC1-E9AE-4321-99BD-EB788A7F2D9E}']
-  end;
-
-  { TJSTextEncoder }
-
-  TJSTextEncoder = class(TJSObject,IJSTextEncoder)
-  public
-    class function Cast(const Intf: IJSObject): IJSTextEncoder; overload;
-  end;
-
-var
-  JSObject: IJSObject; // singleton of JS 'Object'
-  JSDate: IJSDate; // singleton of JS 'Date'
-
-// imported functions from browser
-function __job_invoke_noresult(
-  ObjID: TJOBObjectID;
-  NameP: PChar;
-  NameLen: longint;
-  Invoke: longint;
-  ArgP: PByte
-): TJOBResult; external JOBExportName name JOBFn_InvokeNoResult;
-
-function __job_invoke_boolresult(
-  ObjID: TJOBObjectID;
-  NameP: PChar;
-  NameLen: longint;
-  Invoke: longint;
-  ArgP: PByte;
-  ResultByteBoolP: PByte
-): TJOBResult; external JOBExportName name JOBFn_InvokeBooleanResult;
-
-function __job_invoke_doubleresult(
-  ObjID: TJOBObjectID;
-  NameP: PChar;
-  NameLen: longint;
-  Invoke: longint;
-  ArgP: PByte;
-  ResultDoubleP: PByte
-): TJOBResult; external JOBExportName name JOBFn_InvokeDoubleResult;
-
-function __job_invoke_stringresult(
-  ObjID: TJOBObjectID;
-  NameP: PChar;
-  NameLen: longint;
-  Invoke: longint;
-  ArgP: PByte;
-  ResultLenP: PByte // nativeint
-): TJOBResult; external JOBExportName name JOBFn_InvokeStringResult;
-
-function __job_getstringresult(
-  ResultP: PByte
-): TJOBResult; external JOBExportName name JOBFn_GetStringResult;
-
-function __job_releasestringresult(
-): TJOBResult; external JOBExportName name JOBFn_ReleaseStringResult;
-
-function __job_invoke_objectresult(
-  ObjID: TJOBObjectID;
-  NameP: PChar;
-  NameLen: longint;
-  Invoke: longint;
-  ArgP: PByte;
-  ResultObjIDP: PByte // nativeint
-): TJOBResult; external JOBExportName name JOBFn_InvokeObjectResult;
-
-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  // various
-): TJOBResult; external JOBExportName name JOBFn_InvokeJSValueResult;
-
-function __job_invoke_arraystringresult(
-  ObjID: TJOBObjectID;
-  NameP: PChar;
-  NameLen: longint;
-  Invoke: longint;
-  ArgP: PByte;
-  ResultLenP: PByte // nativeint
-): TJOBResult; external JOBExportName name JOBFn_InvokeArrayStringResult;
-
-function __job_get_global(
-  NameP: PWideChar;
-  NameLen: longint
-  ): TJOBObjectID; external JOBExportName name JOBFn_GetGlobal;
-
-function JOBCallback(const Func: TJOBCallback; Data, Code: Pointer; Args: PByte): PByte;
-function VarRecToJSValue(const V: TVarRec): TJOB_JSValue;
-
-implementation
-
-const
-  InvokeGetToInt: array[TJOBInvokeType] of integer = (
-    JOBInvokeCall,
-    JOBInvokeGet,
-    JOBInvokeGetTypeOf,
-    JOBInvokeSet,
-    JOBInvokeNew
-    );
-
-{$IFDEF VerboseJOB}
-function GetVarRecName(vt: word): string;
-begin
-  case vt of
-    vtInteger: Result:='vtInteger';
-    vtBoolean: Result:='vtBoolean';
-    vtChar: Result:='vtChar';
-    {$ifndef FPUNONE}
-    vtExtended: Result:='vtExtended';
-    {$endif}
-    vtString: Result:='vtString';
-    vtPointer: Result:='vtPointer';
-    vtPChar: Result:='vtPChar';
-    vtObject: Result:='vtObject';
-    vtClass: Result:='vtClass';
-    vtWideChar: Result:='vtWideChar';
-    vtPWideChar: Result:='vtPWideChar';
-    vtAnsiString: Result:='vtAnsiString';
-    vtCurrency: Result:='vtCurrency';
-    vtVariant: Result:='vtVariant';
-    vtInterface: Result:='vtInterface';
-    vtWideString: Result:='vtWideString';
-    vtInt64: Result:='vtInt64';
-    vtQWord: Result:='vtQWord';
-    vtUnicodeString: Result:='vtUnicodeString';
-  else
-    Result:='vt?';
-  end;
-end;
-{$ENDIF}
-
-function __job_callback(w: NativeInt): boolean;
-begin
-  writeln('__job_callback w=',w);
-  Result:=true;
-end;
-
-function JOBCallback(const Func: TJOBCallback; Data, Code: Pointer; Args: PByte
-  ): PByte;
-var
-  m: TMethod;
-  h: TJOBCallbackHelper;
-begin
-  Result:=nil;
-  try
-    //writeln('JOBCallback');
-    m.Data:=Data;
-    m.Code:=Code;
-    h.Init(Args);
-    Result:=Func(m,h);
-  finally
-    if Args<>nil then
-      FreeMem(Args);
-  end;
-end;
-
-function VarRecToJSValue(const V: TVarRec): TJOB_JSValue;
-var
-  p: Pointer;
-  CurLen: SizeInt;
-  S: String;
-  Obj: TObject;
-  Intf: IJSObject;
-begin
-  case V.VType of
-  vtInteger:
-    Result:=TJOB_Double.Create(V.VInteger);
-  vtBoolean:
-    Result:=TJOB_Boolean.Create(V.VBoolean);
-  vtChar:
-    Result:=TJOB_String.Create(UnicodeString(V.VChar));
-  {$ifndef FPUNONE}
-  vtExtended:
-    Result:=TJOB_Double.Create(V.VExtended^);
-  {$endif}
-  vtString:
-    Result:=TJOB_String.Create(UTF8Decode(V.VString^));
-  vtPointer:
-    begin
-    p:=V.VPointer;
-    if p=nil then
-      Result:=TJOB_Object.Create(nil)
-    else if p=JOB_Undefined then
-      Result:=TJOB_JSValue.Create(jjvkUndefined)
-    else
-      raise EJSArgParse.Create('VarRecToJSValue pointer not supported');
-    end;
-  vtPChar:
-    begin
-    CurLen:=strlen(V.VPChar);
-    SetString(S,V.VPChar,CurLen);
-    Result:=TJOB_String.Create(UTF8Decode(S));
-    end;
-  vtObject:
-    begin
-    Obj:=V.VObject;
-    if Obj=nil then
-      Result:=TJOB_Object.Create(nil)
-    else if Obj is TJOB_JSValue then
-      Result:=TJOB_JSValue(Obj)
-    else if Obj is TJSObject then
-      Result:=TJOB_Object.Create(TJSObject(Obj) as IJSObject)
-    else
-      raise EJSArgParse.Create('VarRecToJSValue object '+Obj.ClassName+' not supported');
-    end;
-  vtClass:
-    raise EJSArgParse.Create('VarRecToJSValue class not supported');
-  vtWideChar:
-    Result:=TJOB_String.Create(V.VWideChar);
-  vtPWideChar:
-    raise EJSArgParse.Create('VarRecToJSValue vtPWideChar not supported');
-  vtAnsiString:
-    Result:=TJOB_String.Create(UTF8Decode(PAnsiString(V.VAnsiString)^));
-  vtCurrency:
-    Result:=TJOB_Double.Create(V.VCurrency^);
-  vtVariant:
-    raise EJSArgParse.Create('VarRecToJSValue vtVariant not supported');
-  vtInterface:
-    begin
-    Intf:=IJSObject(V.VInterface);
-    Result:=TJOB_Object.Create(Intf);
-    end;
-  vtWideString:
-    raise EJSArgParse.Create('VarRecToJSValue vtWideString not supported');
-  vtInt64:
-    Result:=TJOB_Double.Create(V.VInt64^);
-  vtQWord:
-    Result:=TJOB_Double.Create(V.VQWord^);
-  vtUnicodeString:
-    Result:=TJOB_String.Create(PUnicodeString(V.VUnicodeString)^);
-  else
-    raise EJSArgParse.Create('VarRecToJSValue unsupported VType '+IntToStr(V.VType));
-  end;
-end;
-
-function JOBCallTJSPromiseResolver(const aMethod: TMethod; var H: TJOBCallbackHelper): PByte;
-var
-  aValue: Variant;
-begin
-  aValue:=H.GetVariant;
-  Result:=H.AllocVariant(TJSPromiseResolver(aMethod)(aValue));
-end;
-
-function JOBCallTJSPromiseFinallyHandler(const aMethod: TMethod; var H: TJOBCallbackHelper): PByte;
-begin
-  Result:=H.AllocUndefined;
-  TJSPromiseFinallyHandler(aMethod)();
-end;
-
-{ TJSTextEncoder }
-
-class function TJSTextEncoder.Cast(const Intf: IJSObject): IJSTextEncoder;
-begin
-  Result:=TJSTextEncoder.Cast(Intf);
-end;
-
-{ TJSTextDecoder }
-
-class function TJSTextDecoder.Cast(const Intf: IJSObject): IJSTextDecoder;
-begin
-  Result:=TJSTextDecoder.Cast(Intf);
-end;
-
-{ TJSPromise }
-
-function TJSPromise.all(const arg: Variant): IJSPromise;
-begin
-  Result:=InvokeJSObjectResult('all',[arg],TJSPromise) as IJSPromise;
-end;
-
-function TJSPromise.allSettled(const arg: Variant): IJSPromise;
-begin
-  Result:=InvokeJSObjectResult('allSettled',[arg],TJSPromise) as IJSPromise;
-end;
-
-function TJSPromise.race(const arg: Variant): IJSPromise;
-begin
-  Result:=InvokeJSObjectResult('race',[arg],TJSPromise) as IJSPromise;
-end;
-
-function TJSPromise.reject(const reason: Variant): IJSPromise;
-begin
-  Result:=InvokeJSObjectResult('reject',[reason],TJSPromise) as IJSPromise;
-end;
-
-function TJSPromise.resolve(const value: Variant): IJSPromise;
-begin
-  Result:=InvokeJSObjectResult('resolve',[value],TJSPromise) as IJSPromise;
-end;
-
-function TJSPromise.resolve: IJSPromise;
-begin
-  Result:=InvokeJSObjectResult('resolve',[],TJSPromise) as IJSPromise;
-end;
-
-function TJSPromise._then(const OnAccepted: TJSPromiseResolver): IJSPromise;
-var
-  m: TJOB_Method;
-begin
-  m:=TJOB_Method.Create(TMethod(onAccepted),@JOBCallTJSPromiseResolver);
-  try
-    Result:=InvokeJSObjectResult('then',[m],TJSPromise) as IJSPromise;
-  finally
-    m.Free;
-  end;
-end;
-
-function TJSPromise._then(const OnAccepted, OnRejected: TJSPromiseResolver
-  ): IJSPromise;
-var
-  ma, mr: TJOB_Method;
-begin
-  ma:=TJOB_Method.Create(TMethod(OnAccepted),@JOBCallTJSPromiseResolver);
-  mr:=TJOB_Method.Create(TMethod(OnRejected),@JOBCallTJSPromiseResolver);
-  try
-    Result:=InvokeJSObjectResult('then',[ma,mr],TJSPromise) as IJSPromise;
-  finally
-    mr.Free;
-    ma.Free;
-  end;
-end;
-
-function TJSPromise.catch(const OnRejected: TJSPromiseResolver): IJSPromise;
-var
-  m: TJOB_Method;
-begin
-  m:=TJOB_Method.Create(TMethod(OnRejected),@JOBCallTJSPromiseResolver);
-  try
-    Result:=InvokeJSObjectResult('catch',[m],TJSPromise) as IJSPromise;
-  finally
-    m.Free;
-  end;
-end;
-
-function TJSPromise._finally(const Handler: TJSPromiseFinallyHandler
-  ): IJSPromise;
-var
-  m: TJOB_Method;
-begin
-  m:=TJOB_Method.Create(TMethod(Handler),@JOBCallTJSPromiseFinallyHandler);
-  try
-    Result:=InvokeJSObjectResult('finally',[m],TJSPromise) as IJSPromise;
-  finally
-    m.Free;
-  end;
-end;
-
-class function TJSPromise.Cast(const Intf: IJSObject): IJSPromise;
-begin
-  Result:=TJSPromise.Cast(Intf);
-end;
-
-{ TJSError }
-
-class function TJSError.Cast(const Intf: IJSObject): IJSError;
-begin
-  Result:=TJSError.Cast(Intf);
-end;
-
-{ TJSJSON }
-
-function TJSJSON.parse(const aJSON: UnicodeString): TJOB_JSValue;
-begin
-  Result:=InvokeJSValueResult('parse',[aJSON]);
-end;
-
-function TJSJSON.parseObject(const aJSON: UnicodeString): IJSObject;
-begin
-  Result:=InvokeJSObjectResult('parse',[aJSON],TJSObject) as IJSObject;
-end;
-
-function TJSJSON.stringify(aValue: TJOB_JSValue): UnicodeString;
-begin
-  Result:=InvokeJSUnicodeStringResult('stringify',[aValue]);
-end;
-
-function TJSJSON.stringify(aValue, aReplacer: TJOB_JSValue): UnicodeString;
-begin
-  Result:=InvokeJSUnicodeStringResult('stringify',[aValue,aReplacer]);
-end;
-
-function TJSJSON.stringify(aValue, aReplacer: TJOB_JSValue; space: NativeInt
-  ): UnicodeString;
-begin
-  Result:=InvokeJSUnicodeStringResult('stringify',[aValue,aReplacer,space]);
-end;
-
-function TJSJSON.stringify(aValue, aReplacer: TJOB_JSValue;
-  const space: UnicodeString): UnicodeString;
-begin
-  Result:=InvokeJSUnicodeStringResult('stringify',[aValue,aReplacer,space]);
-end;
-
-class function TJSJSON.Cast(const Intf: IJSObject): IJSJSON;
-begin
-  Result:=TJSJSON.Cast(Intf);
-end;
-
-{ TJSDataView }
-
-class function TJSDataView.Cast(const Intf: IJSObject): IJSDataView;
-begin
-  Result:=TJSDataView.Cast(Intf);
-end;
-
-{ TJSBufferSource }
-
-class function TJSBufferSource.Cast(const Intf: IJSObject): IJSBufferSource;
-begin
-  Result:=TJSBufferSource.Cast(Intf);
-end;
-
-{ TJSFloat64Array }
-
-class function TJSFloat64Array.Cast(const Intf: IJSObject): IJSFloat64Array;
-begin
-  Result:=TJSFloat64Array.Cast(Intf);
-end;
-
-{ TJSFloat32Array }
-
-class function TJSFloat32Array.Cast(const Intf: IJSObject): IJSFloat32Array;
-begin
-  Result:=TJSFloat32Array.Cast(Intf);
-end;
-
-{ TJSUint32Array }
-
-class function TJSUint32Array.Cast(const Intf: IJSObject): IJSUint32Array;
-begin
-  Result:=TJSUint32Array.Cast(Intf);
-end;
-
-{ TJSInt32Array }
-
-class function TJSInt32Array.Cast(const Intf: IJSObject): IJSInt32Array;
-begin
-  Result:=TJSInt32Array.Cast(Intf);
-end;
-
-{ TJSUint16Array }
-
-class function TJSUint16Array.Cast(const Intf: IJSObject): IJSUint16Array;
-begin
-  Result:=TJSUint16Array.Cast(Intf);
-end;
-
-{ TJSInt16Array }
-
-class function TJSInt16Array.Cast(const Intf: IJSObject): IJSInt16Array;
-begin
-  Result:=TJSInt16Array.Cast(Intf);
-end;
-
-{ TJSUint8ClampedArray }
-
-class function TJSUint8ClampedArray.Cast(const Intf: IJSObject
-  ): IJSUint8ClampedArray;
-begin
-  Result:=TJSUint8ClampedArray.Cast(Intf);
-end;
-
-{ TJSUInt8Array }
-
-class function TJSUint8Array.Cast(const Intf: IJSObject): IJSUint8Array;
-begin
-  Result:=TJSUInt8Array.Cast(Intf);
-end;
-
-{ TJSInt8Array }
-
-class function TJSInt8Array.Cast(const Intf: IJSObject): IJSInt8Array;
-begin
-  Result:=TJSInt8Array.Cast(Intf);
-end;
-
-{ TJSTypedArray }
-
-class function TJSTypedArray.Cast(const Intf: IJSObject): IJSTypedArray;
-begin
-  Result:=TJSTypedArray.Cast(Intf);
-end;
-
-{ TJSArrayBuffer }
-
-class function TJSArrayBuffer.Cast(const Intf: IJSObject): IJSArrayBuffer;
-begin
-  Result:=TJSArrayBuffer.Cast(Intf);
-end;
-
-{ TJSArrayBufferView }
-
-class function TJSArrayBufferView.Cast(const Intf: IJSObject): IJSArrayBufferView;
-begin
-  Result:=TJSArrayBufferView.JOBCast(Intf);
-end;
-
-
-
-
-{ TJSArray }
-
-function TJSArray._GetElements(Index: NativeInt): TJOB_JSValue;
-begin
-  Result:=InvokeJSValueResult(IntToStr(Index),[],jiGet);
-end;
-
-function TJSArray._GetLength: NativeInt;
-begin
-  Result:=ReadJSPropertyLongInt('length');
-end;
-
-procedure TJSArray._SetElements(Index: NativeInt; const AValue: TJOB_JSValue);
-begin
-  InvokeJSNoResult(IntToStr(Index),[AValue],jiSet);
-end;
-
-procedure TJSArray._SetLength(const AValue: NativeInt);
-begin
-  WriteJSPropertyLongInt('length',AValue);
-end;
-
-function TJSArray.isArray(a: TJOB_JSValue): Boolean;
-begin
-  Result:=InvokeJSBooleanResult('isArray',[a]);
-end;
-
-function TJSArray.concat(el: TJOB_JSValue): IJSArray;
-begin
-  Result:=InvokeJSObjectResult('isArray',[el],TJSArray) as IJSArray;
-end;
-
-function TJSArray.fill(aValue: TJOB_JSValue): IJSArray;
-begin
-  Result:=InvokeJSObjectResult('fill',[aValue],TJSArray) as IJSArray;
-end;
-
-function TJSArray.fill(aValue: TJOB_JSValue; aStartIndex: NativeInt): IJSArray;
-begin
-  Result:=InvokeJSObjectResult('fill',[aValue,aStartIndex],TJSArray) as IJSArray;
-end;
-
-function TJSArray.fill(aValue: TJOB_JSValue; aStartIndex, aEndIndex: NativeInt
-  ): IJSArray;
-begin
-  Result:=InvokeJSObjectResult('fill',[aValue,aStartIndex,aEndIndex],TJSArray) as IJSArray;
-end;
-
-function TJSArray.includes(aElement: TJOB_JSValue): Boolean;
-begin
-  Result:=InvokeJSBooleanResult('includes',[aElement]);
-end;
-
-function TJSArray.includes(aElement: TJOB_JSValue; FromIndex: NativeInt
-  ): Boolean;
-begin
-  Result:=InvokeJSBooleanResult('includes',[aElement,FromIndex]);
-end;
-
-function TJSArray.indexOf(aElement: TJOB_JSValue): NativeInt;
-begin
-  Result:=InvokeJSMaxIntResult('indexOf',[aElement]);
-end;
-
-function TJSArray.indexOf(aElement: TJOB_JSValue; FromIndex: NativeInt
-  ): NativeInt;
-begin
-  Result:=InvokeJSMaxIntResult('indexOf',[aElement,FromIndex]);
-end;
-
-function TJSArray.join: UnicodeString;
-begin
-  Result:=InvokeJSUnicodeStringResult('join',[]);
-end;
-
-function TJSArray.join(const aSeparator: UnicodeString): UnicodeString;
-begin
-  Result:=InvokeJSUnicodeStringResult('join',[aSeparator]);
-end;
-
-function TJSArray.lastIndexOf(aElement: TJOB_JSValue): NativeInt;
-begin
-  Result:=InvokeJSMaxIntResult('lastIndexOf',[aElement]);
-end;
-
-function TJSArray.lastIndexOf(aElement: TJOB_JSValue; FromIndex: NativeInt
-  ): NativeInt;
-begin
-  Result:=InvokeJSMaxIntResult('lastIndexOf',[aElement,FromIndex]);
-end;
-
-function TJSArray.pop: TJOB_JSValue;
-begin
-  Result:=InvokeJSValueResult('pop',[]);
-end;
-
-function TJSArray.push(aElement: TJOB_JSValue): NativeInt;
-begin
-  Result:=InvokeJSMaxIntResult('push',[aElement]);
-end;
-
-function TJSArray.reverse: IJSArray;
-begin
-  Result:=InvokeJSObjectResult('reverse',[],TJSArray) as IJSArray;
-end;
-
-function TJSArray.shift: TJOB_JSValue;
-begin
-  Result:=InvokeJSValueResult('shift',[]);
-end;
-
-function TJSArray.slice: IJSArray;
-begin
-  Result:=InvokeJSObjectResult('slice',[],TJSArray) as IJSArray;
-end;
-
-function TJSArray.slice(aBegin: NativeInt): IJSArray;
-begin
-  Result:=InvokeJSObjectResult('slice',[aBegin],TJSArray) as IJSArray;
-end;
-
-function TJSArray.slice(aBegin, aEnd: NativeInt): IJSArray;
-begin
-  Result:=InvokeJSObjectResult('slice',[aBegin,aEnd],TJSArray) as IJSArray;
-end;
-
-function TJSArray.sort(): IJSArray;
-begin
-  Result:=InvokeJSObjectResult('sort',[],TJSArray) as IJSArray;
-end;
-
-function TJSArray.splice(aStart: NativeInt): IJSArray;
-begin
-  Result:=InvokeJSObjectResult('splice',[aStart],TJSArray) as IJSArray;
-end;
-
-function TJSArray.splice(aStart, aDeleteCount: NativeInt): IJSArray;
-begin
-  Result:=InvokeJSObjectResult('splice',[aStart,aDeleteCount],TJSArray) as IJSArray;
-end;
-
-function TJSArray.toLocaleString(const locales: UnicodeString): UnicodeString;
-begin
-  Result:=InvokeJSUnicodeStringResult('toLocaleString',[locales]);
-end;
-
-function TJSArray.unshift: NativeInt;
-begin
-  Result:=InvokeJSMaxIntResult('unshift',[]);
-end;
-
-class function TJSArray.Cast(const Intf: IJSObject): IJSArray;
-begin
-  Result:=TJSArray.Cast(Intf);
-end;
-
-{ TJSString }
-
-class function TJSString.Cast(const Intf: IJSObject): IJSString;
-begin
-  Result:=TJSString.Cast(Intf);
-end;
-
-{ TJSRegExp }
-
-function TJSRegExp.exec(const aString: UnicodeString): IJSArray;
-begin
-  Result:=InvokeJSObjectResult('exec',[aString],TJSArray) as IJSArray;
-end;
-
-function TJSRegExp._GetGlobal: Boolean;
-begin
-  Result:=ReadJSPropertyBoolean('global');
-end;
-
-function TJSRegExp._GetIgnoreCase: Boolean;
-begin
-  Result:=ReadJSPropertyBoolean('ignoreCase');
-end;
-
-function TJSRegExp._GetLastIndex: NativeInt;
-begin
-  Result:=ReadJSPropertyLongInt('lastIndex');
-end;
-
-function TJSRegExp._GetMultiLine: Boolean;
-begin
-  Result:=ReadJSPropertyBoolean('multiline');
-end;
-
-function TJSRegExp._GetSource: UnicodeString;
-begin
-  Result:=ReadJSPropertyUnicodeString('source');
-end;
-
-function TJSRegExp._GetUnicode: boolean;
-begin
-  Result:=ReadJSPropertyBoolean('unicode');
-end;
-
-procedure TJSRegExp._SetGlobal(const AValue: Boolean);
-begin
-  WriteJSPropertyBoolean('global',AValue);
-end;
-
-procedure TJSRegExp._SetIgnoreCase(const AValue: Boolean);
-begin
-  WriteJSPropertyBoolean('ignoreCase',AValue);
-end;
-
-procedure TJSRegExp._SetlastIndex(const AValue: NativeInt);
-begin
-  WriteJSPropertyLongInt('lastIndex',AValue);
-end;
-
-procedure TJSRegExp._SetMultiline(const AValue: Boolean);
-begin
-  WriteJSPropertyBoolean('multiline',AValue);
-end;
-
-procedure TJSRegExp._SetSource(const AValue: UnicodeString);
-begin
-  WriteJSPropertyUnicodeString('source',AValue);
-end;
-
-procedure TJSRegExp._SetUnicode(const AValue: boolean);
-begin
-  WriteJSPropertyBoolean('unicode',AValue);
-end;
-
-function TJSRegExp.test(const aString: UnicodeString): boolean;
-begin
-  Result:=InvokeJSBooleanResult('test',[aString]);
-end;
-
-class function TJSRegExp.Cast(const Intf: IJSObject): IJSRegExp;
-begin
-  Result:=TJSRegExp.Cast(Intf);
-end;
-
-{ TJSFunction }
-
-function TJSFunction._GetLength: NativeInt;
-begin
-  Result:=ReadJSPropertyLongInt('length');
-end;
-
-function TJSFunction._GetName: UnicodeString;
-begin
-  Result:=ReadJSPropertyUnicodeString('name');
-end;
-
-function TJSFunction._GetPrototyp: IJSFunction;
-begin
-  Result:=ReadJSPropertyObject('prototyp',TJSFunction) as IJSFunction;
-end;
-
-procedure TJSFunction._SetName(const AValue: UnicodeString);
-begin
-  WriteJSPropertyUnicodeString('length',AValue);
-end;
-
-class function TJSFunction.Cast(const Intf: IJSObject): IJSFunction;
-begin
-  Result:=TJSFunction.Cast(Intf);
-end;
-
-{ TJSMap }
-
-class function TJSMap.Cast(const Intf: IJSObject): IJSMap;
-begin
-  Result:=TJSMap.Cast(Intf);
-end;
-
-{ TJSSet }
-
-class function TJSSet.Cast(const Intf: IJSObject): IJSSet;
-begin
-  Result:=TJSSet.Cast(Intf);
-end;
-
-{ TJOBCallbackHelper }
-
-procedure TJOBCallbackHelper.Init(Args: PByte);
-begin
-  p:=Args;
-  Index:=0;
-  if p<>nil then
-  begin
-    Count:=p^;
-    inc(p);
-  end else
-    Count:=0;
-end;
-
-function TJOBCallbackHelper.GetType: byte;
-begin
-  if Index=Count then
-    Result:=JOBArgUndefined
-  else
-    Result:=p^;
-end;
-
-procedure TJOBCallbackHelper.Skip;
-var
-  Len: LongWord;
-begin
-  if Index=Count then exit;
-  case p^ of
-  JOBArgUndefined,
-  JOBArgTrue,
-  JOBArgFalse,
-  JOBArgNil: inc(p);
-  JOBArgDouble: inc(p,9);
-  JOBArgUnicodeString:
-    begin
-      inc(p);
-      Len:=PLongWord(p)^;
-      inc(p,4+2*Len);
-    end
-  else
-    raise EJSArgParse.Create(JOBArgNames[p^]);
-  end;
-  inc(Index);
-end;
-
-function TJOBCallbackHelper.GetBoolean: boolean;
-begin
-  Result:=false;
-  if Index=Count then
-    exit;
-  case p^ of
-  JOBArgUndefined: ;
-  JOBArgTrue: Result:=true;
-  JOBArgFalse: ;
-  else
-    raise EJSArgParse.Create(JOBArgNames[p^]);
-  end;
-  inc(p);
-  inc(Index);
-end;
-
-function TJOBCallbackHelper.GetDouble: double;
-begin
-  Result:=NaN;
-  if Index=Count then
-    exit;
-  case p^ of
-  JOBArgUndefined:
-    inc(p);
-  JOBArgDouble:
-    begin
-      inc(p);
-      Result:=PDouble(p)^;
-      inc(p,8);
-    end
-  else
-    raise EJSArgParse.Create(JOBArgNames[p^]);
-  end;
-  inc(Index);
-end;
-
-function TJOBCallbackHelper.GetString: UnicodeString;
-var
-  Len: LongWord;
-begin
-  Result:='';
-  if Index=Count then
-    exit;
-  case p^ of
-  JOBArgUndefined:
-    inc(p);
-  JOBArgUnicodeString:
-    begin
-      inc(p);
-      Len:=PLongWord(p)^;
-      inc(p,4);
-      if Len>0 then
-      begin
-        SetLength(Result,Len);
-        Move(p^,Result[1],2*Len);
-        inc(p,2*Len);
-      end;
-    end
-  else
-    raise EJSArgParse.Create(JOBArgNames[p^]);
-  end;
-  inc(Index);
-end;
-
-function TJOBCallbackHelper.GetObject(aResultClass: TJSObjectClass): TJSObject;
-var
-  ObjId: LongWord;
-begin
-  //writeln('TJOBCallbackHelper.GetObject ',Index,' Count=',Count);
-  Result:=nil;
-  if Index=Count then
-    exit;
-  //writeln('TJOBCallbackHelper.GetObject type=',p^);
-  case p^ of
-  JOBArgUndefined,
-  JOBArgNil:
-    inc(p);
-  JOBArgObject:
-    begin
-      inc(p);
-      ObjId:=PLongWord(p)^;
-      inc(p,4);
-      Result:=aResultClass.JOBCreateFromID(ObjId);
-      Result.JOBObjectIDOwner:=false; // owned by caller (JS code in browser)
-    end
-  else
-    raise EJSArgParse.Create(JOBArgNames[p^]);
-  end;
-  inc(Index);
-end;
-
-function TJOBCallbackHelper.GetArray: TJSArray;
-var
-  ObjId: LongWord;
-begin
-  //writeln('TJOBCallbackHelper.GetObject ',Index,' Count=',Count);
-  Result:=nil;
-  if Index=Count then
-    exit;
-  //writeln('TJOBCallbackHelper.GetObject type=',p^);
-  case p^ of
-  JOBArgUndefined,
-  JOBArgNil:
-    inc(p);
-  JOBArgObject:
-    begin
-      inc(p);
-      ObjId:=PLongWord(p)^;
-      inc(p,4);
-      Result:=TJSArray.JOBCreateFromID(ObjId);
-      Result.JOBObjectIDOwner:=false; // owned by caller (JS code in browser)
-    end
-  else
-    raise EJSArgParse.Create(JOBArgNames[p^]);
-  end;
-  inc(Index);
-end;
-
-function TJOBCallbackHelper.GetValue: TJOB_JSValue;
-var
-  ObjId, Len: LongWord;
-  Obj: TJSObject;
-  S: UnicodeString;
-begin
-  Result:=nil;
-  if (Index=Count) or (p^=JOBArgUndefined) then
-  begin
-    Result:=TJOB_JSValue.Create(jjvkUndefined);
-    exit;
-  end;
-  case p^ of
-  JOBArgTrue:
-    begin
-      Result:=TJOB_Boolean.Create(true);
-      inc(p);
-    end;
-  JOBArgFalse:
-    begin
-      Result:=TJOB_Boolean.Create(false);
-      inc(p);
-    end;
-  JOBArgDouble:
-    begin
-      inc(p);
-      Result:=TJOB_Double.Create(PDouble(p)^);
-      inc(p,8);
-    end;
-  JOBArgUnicodeString:
-    begin
-      inc(p);
-      Len:=PLongWord(p)^;
-      inc(p,4);
-      S:='';
-      if Len>0 then
-      begin
-        SetLength(S,Len);
-        Move(p^,S[1],2*Len);
-        inc(p,2*Len);
-      end;
-      Result:=TJOB_String.Create(S);
-    end;
-  JOBArgNil:
-    begin
-      Result:=TJOB_Object.Create(nil);
-      inc(p);
-    end;
-  JOBArgObject:
-    begin
-      inc(p);
-      ObjId:=PLongWord(p)^;
-      inc(p,4);
-      Obj:=TJSObject.JOBCreateFromID(ObjId);
-      Result:=TJOB_Object.Create(Obj);
-    end;
-  else
-    raise EJSArgParse.Create(JOBArgNames[p^]);
-  end;
-  inc(Index);
-end;
-
-function TJOBCallbackHelper.GetVariant: Variant;
-var
-  ObjId, Len: LongWord;
-  Obj: TJSObject;
-  S: UnicodeString;
-begin
-  if Index=Count then
-  begin
-    Result:=Variants.Unassigned;
-    exit;
-  end;
-  case p^ of
-  JOBArgUndefined:
-    begin
-      Result:=Variants.Unassigned;
-      inc(p);
-    end;
-  JOBArgTrue:
-    begin
-      Result:=true;
-      inc(p);
-    end;
-  JOBArgFalse:
-    begin
-      Result:=false;
-      inc(p);
-    end;
-  JOBArgDouble:
-    begin
-      inc(p);
-      Result:=PDouble(p)^;
-      inc(p,8);
-    end;
-  JOBArgUnicodeString:
-    begin
-      inc(p);
-      Len:=PLongWord(p)^;
-      inc(p,4);
-      S:='';
-      if Len>0 then
-      begin
-        SetLength(S,Len);
-        Move(p^,S[1],2*Len);
-        inc(p,2*Len);
-      end;
-      Result:=S;
-    end;
-  JOBArgNil:
-    begin
-      Result:=Variants.Null;
-      inc(p);
-    end;
-  JOBArgObject:
-    begin
-      inc(p);
-      ObjId:=PLongWord(p)^;
-      inc(p,4);
-      Obj:=TJSObject.JOBCreateFromID(ObjId);
-      Obj.JOBObjectIDOwner:=false;
-      Result:=Obj as IJSObject;
-    end;
-  else
-    raise EJSArgParse.Create(JOBArgNames[p^]);
-  end;
-  inc(Index);
-end;
-
-function TJOBCallbackHelper.GetLongInt: longint;
-var
-  d: Double;
-begin
-  d:=GetDouble;
-  if (Frac(d)<>0) or (d<low(longint)) or (d>high(longint)) then
-    raise EJSArgParse.Create('expected longint, but got double')
-  else
-    Result:=Trunc(d);
-end;
-
-function TJOBCallbackHelper.GetMaxInt: int64;
-var
-  d: Double;
-begin
-  d:=GetDouble;
-  if (Frac(d)<>0) or (d<low(int64)) or (d>high(int64)) then
-    raise EJSArgParse.Create('expected int64, but got double')
-  else
-    Result:=Trunc(d);
-end;
-
-function TJOBCallbackHelper.AllocUndefined: PByte;
-begin
-  GetMem(Result,1);
-  Result^:=JOBArgUndefined;
-end;
-
-function TJOBCallbackHelper.AllocBool(b: boolean): PByte;
-begin
-  GetMem(Result,1);
-  if b then
-    Result^:=JOBArgTrue
-  else
-    Result^:=JOBArgFalse;
-end;
-
-function TJOBCallbackHelper.AllocLongint(i: longint): PByte;
-begin
-  GetMem(Result,5);
-  Result^:=JOBArgLongint;
-  PLongint(Result+1)^:=i;
-end;
-
-function TJOBCallbackHelper.AllocDouble(const d: double): PByte;
-begin
-  GetMem(Result,9);
-  Result^:=JOBArgDouble;
-  PDouble(Result+1)^:=d;
-end;
-
-function TJOBCallbackHelper.AllocString(const s: UnicodeString): PByte;
-var
-  l: SizeInt;
-begin
-  l:=length(s);
-  GetMem(Result,5+2*l);
-  Result^:=JOBArgUnicodeString;
-  PLongWord(Result+1)^:=l;
-  if l>0 then
-    Move(s[1],Result[5],2*l);
-end;
-
-function TJOBCallbackHelper.AllocNil: PByte;
-begin
-  GetMem(Result,1);
-  Result^:=JOBArgNil;
-end;
-
-function TJOBCallbackHelper.AllocIntf(const Intf: IJSObject): PByte;
-begin
-  if Intf=nil then
-    Result:=AllocNil
-  else
-    Result:=AllocObjId(Intf.GetJSObjectID);
-end;
-
-function TJOBCallbackHelper.AllocObject(Obj: TJSObject): PByte;
-begin
-  if Obj=nil then
-    Result:=AllocNil
-  else
-    Result:=AllocObjId(Obj.JOBObjectID);
-end;
-
-function TJOBCallbackHelper.AllocObjId(ObjId: TJOBObjectID): PByte;
-begin
-  //writeln('TJOBCallbackHelper.AllocObjId ObjID=',ObjId);
-  GetMem(Result,1+SizeOf(TJOBObjectID));
-  Result^:=JOBArgObject;
-  PJOBObjectID(Result+1)^:=ObjId;
-end;
-
-function TJOBCallbackHelper.AllocJSValue(const Value: TJOB_JSValue): PByte;
-begin
-  if Value=nil then
-    exit(AllocUndefined);
-  case Value.Kind of
-    jjvkUndefined: Result:=AllocUndefined;
-    jjvkBoolean: Result:=AllocBool(TJOB_Boolean(Value).Value);
-    jjvkDouble: Result:=AllocDouble(TJOB_Double(Value).Value);
-    jjvkString: Result:=AllocString(TJOB_String(Value).Value);
-    jjvkObject: Result:=AllocIntf(TJOB_Object(Value).Value);
-  else
-    raise EJSArgParse.Create('AllocJSValue unsupported: '+JOB_JSValueKindNames[Value.Kind]);
-  end;
-end;
-
-function TJOBCallbackHelper.AllocVariant(const Value: Variant): PByte;
-var
-  t: tvartype;
-  Intf: IJSObject;
-begin
-  t:=VarType(Value);
-  case t of
-  varEmpty:
-    Result:=AllocUndefined;
-  varNull:
-    Result:=AllocNil;
-  varSmallInt,varInteger,varByte,varWord,varShortInt:
-    Result:=AllocLongint(Value);
-  varLongWord,varCurrency,varInt64,varQWord,varSingle,varDouble,varDate:
-    Result:=AllocDouble(Value);
-  varOleStr,varString:
-    Result:=AllocString(Value);
-  varBoolean:
-    Result:=AllocBool(Value);
-  varUnknown:
-    begin
-    if tvardata(Value).vunknown=nil then
-      Result:=AllocNil
-    else if VarSupports(Value,IJSObject,Intf) then
-      Result:=AllocIntf(Intf)
-    else
-      raise EJSInvoke.Create('TJOBCallbackHelper.AllocVariant: [20220822103744] unsupported variant: '+IntToStr(t));
-    end
-  else
-    raise EJSInvoke.Create('TJOBCallbackHelper.AllocVariant: [20220822103751] unsupported variant: '+IntToStr(t));
-  end;
-end;
-
-{ TJOB_JSValue }
-
-constructor TJOB_JSValue.Create(aKind: TJOB_JSValueKind);
-begin
-  Kind:=aKind;
-end;
-
-function TJOB_JSValue.AsString: string;
-begin
-  if Kind=jjvkUndefined then
-    Result:='undefined'
-  else begin
-    Result:='';
-    str(Kind,Result);
-  end;
-end;
-
-{ TJOB_Boolean }
-
-constructor TJOB_Boolean.Create(aValue: Boolean);
-begin
-  Kind:=jjvkBoolean;
-  Value:=aValue;
-end;
-
-function TJOB_Boolean.AsString: string;
-begin
-  str(Value,Result);
-end;
-
-{ TJOB_Double }
-
-constructor TJOB_Double.Create(const aValue: Double);
-begin
-  Kind:=jjvkDouble;
-  Value:=aValue;
-end;
-
-function TJOB_Double.AsString: string;
-begin
-  str(Value,Result);
-end;
-
-{ TJOB_String }
-
-constructor TJOB_String.Create(const aValue: UnicodeString);
-begin
-  Kind:=jjvkString;
-  Value:=aValue;
-end;
-
-function TJOB_String.AsString: string;
-begin
-  Result:=AnsiQuotedStr(String(Value),'"');
-end;
-
-{ TJOB_Object }
-
-constructor TJOB_Object.Create(aValue: IJSObject);
-begin
-  Kind:=jjvkObject;
-  Value:=aValue;
-end;
-
-function TJOB_Object.AsString: string;
-begin
-  if Value=nil then
-    Result:='nil'
-  else
-    Result:='['+IntToStr(Value.GetJSObjectID)+']:'+Value.GetPascalClassName;
-end;
-
-{ TJOB_Method }
-
-constructor TJOB_Method.Create(const aMethod: TMethod;
-  const AnInvoke: TJOBCallback);
-begin
-  Kind:=jjvkMethod;
-  Value:=aMethod;
-  Invoke:=AnInvoke;
-end;
-
-function TJOB_Method.AsString: string;
-begin
-  Result:='Callback';
-end;
-
-{ TJOB_Dictionary }
-
-procedure TJOB_Dictionary.Add(const aName: UnicodeString;
-  const aValue: TJOB_JSValue);
-var
-  p: TJOB_Pair;
-begin
-  p.Name:=aName;
-  p.Value:=aValue;
-  Insert(p,Values,length(Values));
-end;
-
-constructor TJOB_Dictionary.Create(const Pairs: array of const);
-var
-  i: Integer;
-  l, CurLen: SizeInt;
-  CurName: UnicodeString;
-begin
-  inherited Create(jjvkDictionary);
-  l:=length(Pairs);
-  SetLength(Values,l div 2);
-  for i:=0 to length(Values)-1 do
-    Values[i].Value:=nil;
-  i:=0;
-  while i<l do
-  begin
-    case Pairs[i].VType of
-    vtChar:
-      CurName:=UnicodeString(Pairs[i].VChar);
-    vtString:
-      CurName:=UTF8Decode(Pairs[i].VString^);
-    vtPChar:
-      begin
-      CurLen:=strlen(Pairs[i].VPChar);
-      SetString(CurName,Pairs[i].VPChar,CurLen);
-      end;
-    vtWideChar:
-      CurName:=Pairs[i].VWideChar;
-    vtAnsiString:
-      CurName:=UTF8Decode(PAnsiString(Pairs[i].VAnsiString)^);
-    vtUnicodeString:
-      CurName:=PUnicodeString(Pairs[i].VUnicodeString)^;
-    else
-      raise EJSArgParse.Create('TJOB_Dictionary.Create expected name at index '+IntToStr(i)+', but found '+IntToStr(Pairs[i].VType));
-    end;
-    Values[i div 2].Name:=CurName;
-    inc(i);
-    if i=l then
-      raise EJSArgParse.Create('TJOB_Dictionary.Create name "'+String(CurName)+'" has no value');
-    Values[i div 2].Value:=VarRecToJSValue(Pairs[i]);
-    inc(i);
-  end;
-end;
-
-destructor TJOB_Dictionary.Destroy;
-begin
-  Clear;
-  inherited Destroy;
-end;
-
-procedure TJOB_Dictionary.Clear;
-var
-  i: Integer;
-begin
-  for i:=0 to length(Values)-1 do
-    FreeAndNil(Values[i].Value);
-  Values:=nil;
-end;
-
-{ TJOB_ArrayOfJSValue }
-
-procedure TJOB_ArrayOfJSValue.Add(const aValue: TJOB_JSValue);
-begin
-  Insert(aValue,Values,length(Values));
-end;
-
-constructor TJOB_ArrayOfJSValue.Create(const TheValues: array of const);
-var
-  l: SizeInt;
-  i: Integer;
-begin
-  inherited Create(jjvkArrayOfJSValue);
-  l:=length(TheValues);
-  SetLength(Values,l);
-  for i:=0 to l-1 do
-    Values[i]:=nil;
-  for i:=0 to l-1 do
-    Values[i]:=VarRecToJSValue(TheValues[i]);
-end;
-
-destructor TJOB_ArrayOfJSValue.Destroy;
-begin
-  Clear;
-  inherited Destroy;
-end;
-
-procedure TJOB_ArrayOfJSValue.Clear;
-var
-  i: Integer;
-begin
-  for i:=0 to length(Values)-1 do
-    FreeAndNil(Values[i]);
-  Values:=nil;
-end;
-
-{ TJOB_ArrayOfDouble }
-
-constructor TJOB_ArrayOfDouble.Create(const TheValues: TDoubleDynArray);
-begin
-  inherited Create(jjvkArrayOfDouble);
-  Values:=TheValues;
-end;
-
-{ TJSObject }
-
-function TJSObject.GetJSObjectID: TJOBObjectID;
-begin
-  Result:=FJOBObjectID;
-end;
-
-function TJSObject.GetJSObjectCastSrc: IJSObject;
-begin
-  Result:=FJOBCastSrc;
-end;
-
-function TJSObject.GetPascalClassName: string;
-begin
-  Result:=ClassName;
-end;
-
-function TJSObject.GetProperties(const PropName: String): Variant;
-begin
-  Result:=ReadJSPropertyVariant(PropName);
-end;
-
-procedure TJSObject.SetProperties(const PropName: String;
-  const AValue: Variant);
-begin
-  WriteJSPropertyVariant(PropName,AValue);
-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.InvokeJSNoResultFunc(const aName: string;
-  const Args: array of const; const InvokeFunc: TJOBInvokeNoResultFunc;
-  Invoke: TJOBInvokeType): TJOBResult;
-var
-  InvokeArgs: PByte;
-begin
-  if length(Args)=0 then
-    Result:=InvokeFunc(JOBObjectID,PChar(aName),length(aName),InvokeGetToInt[Invoke],nil)
-  else begin
-    InvokeArgs:=CreateInvokeJSArgs(Args);
-    try
-      Result:=InvokeFunc(JOBObjectID,PChar(aName),length(aName),InvokeGetToInt[Invoke],InvokeArgs);
-    finally
-      if InvokeArgs<>nil then
-        FreeMem(InvokeArgs);
-    end;
-  end;
-end;
-
-function TJSObject.InvokeJSOneResult(const aName: string;
-  const Args: array of const; const InvokeFunc: TJOBInvokeOneResultFunc;
-  ResultP: PByte; Invoke: TJOBInvokeType): TJOBResult;
-var
-  InvokeArgs: PByte;
-begin
-  if length(Args)=0 then
-    Result:=InvokeFunc(JOBObjectID,PChar(aName),length(aName),InvokeGetToInt[Invoke],nil,ResultP)
-  else begin
-    InvokeArgs:=CreateInvokeJSArgs(Args);
-    try
-      Result:=InvokeFunc(JOBObjectID,PChar(aName),length(aName),InvokeGetToInt[Invoke],InvokeArgs,ResultP);
-    finally
-      if InvokeArgs<>nil then
-        FreeMem(InvokeArgs);
-    end;
-  end;
-end;
-
-procedure TJSObject.InvokeJS_Raise(const aName, Msg: string);
-var
-  E: EJSInvoke;
-begin
-  E:=EJSInvoke.Create(Msg);
-  E.ObjectID:=JOBObjectID;
-  E.FuncName:=aName;
-  raise E;
-end;
-
-procedure TJSObject.InvokeJS_RaiseResultMismatch(const aName: string;
-  Expected, Actual: TJOBResult);
-begin
-  case Actual of
-  JOBResult_UnknownObjId: InvokeJS_Raise(aName,'unknown object id '+IntToStr(JOBObjectID));
-  JOBResult_NotAFunction: InvokeJS_Raise(aName,'object '+IntToStr(JOBObjectID)+' does not have a function "'+aName+'"');
-  else
-    InvokeJS_RaiseResultMismatchStr(aName,JOBResult_Names[Expected],JOBResult_Names[Actual]);
-  end;
-end;
-
-procedure TJSObject.InvokeJS_RaiseResultMismatchStr(const aName: string;
-  const Expected, Actual: string);
-begin
-  InvokeJS_Raise(aName,'expected '+Expected+', but got '+Actual+' from object '+IntToStr(JOBObjectID)+' function "'+aName+'"');
-end;
-
-function TJSObject.CreateInvokeJSArgs(const Args: array of const): PByte;
-
-  procedure RaiseNotSupported(const Msg: string);
-  begin
-    raise EJSInvoke.Create('Invoke js: type not supported '+Msg);
-  end;
-
-  procedure RaiseRange;
-  begin
-    raise ERangeError.Create('Invoke js: number out of bounds');
-  end;
-
-var
-  p: PByte;
-  Len: NativeInt;
-
-  function SizeOfTJOB_JSValue(JSValue: TJOB_JSValue): integer;
-  var
-    Dict: TJOB_PairArray;
-    i: Integer;
-    Arr: TJOB_JSValueArray;
-  begin
-    case JSValue.Kind of
-      jjvkUndefined: Result:=1;
-      jjvkBoolean: Result:=1;
-      jjvkDouble: Result:=9;
-      jjvkString: Result:=1+SizeOf(NativeInt)+SizeOf(PByte);
-      jjvkObject:
-        if TJOB_Object(JSValue).Value=nil then
-          Result:=1
-        else
-          Result:=1+SizeOf(TJOBObjectID);
-      jjvkMethod: Result:=1+3*SizeOf(PByte);
-      jjvkDictionary:
-        begin
-          Result:=1+SizeOf(NativeInt);
-          Dict:=TJOB_Dictionary(JSValue).Values;
-          for i:=0 to length(Dict)-1 do
-            begin
-            inc(Result,1+SizeOf(NativeInt)+SizeOf(PByte));
-            inc(Result,SizeOfTJOB_JSValue(Dict[i].Value));
-            end;
-        end;
-      jjvkArrayOfJSValue:
-        begin
-          Result:=1+SizeOf(NativeInt);
-          Arr:=TJOB_ArrayOfJSValue(JSValue).Values;
-          for i:=0 to length(Arr)-1 do
-            inc(Result,SizeOfTJOB_JSValue(Dict[i].Value));
-        end;
-      jjvkArrayOfDouble:
-        Result:=1+SizeOf(NativeInt)+SizeOf(PByte);
-      else
-        RaiseNotSupported('20220630135718'){%H-};
-    end;
-  end;
-
-  procedure Grow(Need: NativeInt);
-  begin
-    inc(Need,p-Result);
-    if Need<=Len then exit;
-    Len:=Len*2;
-    if Len<Need then
-      Len:=Need;
-    Need:=p-Result;
-    ReAllocMem(Result,Len);
-    p:=Result+Need;
-  end;
-
-  procedure Prep(Need: NativeInt; aType: Byte);
-  begin
-    Grow(Need);
-    p^:=aType;
-    inc(p);
-  end;
-
-  procedure AddBoolean(b: boolean);
-  begin
-    Grow(1);
-    if b then
-      p^:=JOBArgTrue
-    else
-      p^:=JOBArgFalse;
-    inc(p);
-  end;
-
-  procedure AddLongInt(const i: LongInt);
-  begin
-    Prep(5,JOBArgLongint);
-    PLongint(p)^:=i;
-    inc(p,4);
-  end;
-
-  procedure AddDouble(const d: double);
-  begin
-    Prep(9,JOBArgDouble);
-    PDouble(p)^:=d;
-    inc(p,8);
-  end;
-
-  procedure AddChar(c: word);
-  begin
-    Prep(3,JOBArgChar);
-    PWord(p)^:=c;
-    inc(p,2);
-  end;
-
-  procedure AddObjectID(const ObjId: TJOBObjectID);
-  begin
-    Prep(1+SizeOf(NativeInt),JOBArgObject);
-    PNativeInt(p)^:=ObjId;
-    inc(p,sizeof(NativeInt));
-  end;
-
-  procedure AddIJSObject(const Intf: IJSObject);
-  begin
-    if Intf=nil then
-      Prep(1,JOBArgNil)
-    else
-      AddObjectID(Intf.GetJSObjectID);
-  end;
-
-  procedure AddUnicodeString(s: PByte; Len: NativeInt); overload;
-  begin
-    Prep(1+SizeOf(NativeInt)+SizeOf(Pointer),JOBArgUnicodeString);
-    PNativeInt(p)^:=Len;
-    inc(p,sizeof(NativeInt));
-    PPointer(p)^:=s;
-    inc(p,sizeof(Pointer));
-  end;
-
-  procedure AddUnicodeString(const us: UnicodeString); overload;
-  begin
-    if us='' then
-      AddUnicodeString(nil,0)
-    else
-      AddUnicodeString(@us[1],length(us));
-  end;
-
-  procedure AddUTF8String(const s: String); overload;
-  var
-    us: UnicodeString;
-    l: SizeInt;
-  begin
-    //writeln('AddUTF8String s="',s,'"');
-    if s='' then
-    begin
-      AddUnicodeString(nil,0);
-      exit;
-    end;
-    us:=UTF8Decode(s);
-    l:=length(us);
-    if l=0 then
-    begin
-      AddUnicodeString(nil,0);
-      exit;
-    end;
-    Prep(1+SizeOf(NativeInt)+2*l,JOBArgString);
-    PNativeInt(p)^:=l;
-    inc(p,SizeOf(NativeInt));
-    Move(us[1],p^,2*l);
-    inc(p,2*l);
-  end;
-
-  procedure AddUTF8String(p: PByte; l: NativeInt);
-  var
-    s: string;
-  begin
-    if (p=nil) or (l=0) then
-    begin
-      AddUnicodeString(nil,0);
-      exit;
-    end;
-    SetString(s,PAnsiChar(p),l);
-    AddUTF8String(s);
-  end;
-
-  procedure Add_TJOB_JSValue(aValue: TJOB_JSValue);
-  var
-    us: UnicodeString;
-    h: PByte;
-    aMethod: TJOB_Method;
-    Dict: TJOB_PairArray;
-    i: Integer;
-    Arr: TJOB_JSValueArray;
-  begin
-    case aValue.Kind of
-      jjvkUndefined:
-        Prep(1,JOBArgUndefined);
-      jjvkBoolean:
-        AddBoolean(TJOB_Boolean(aValue).Value);
-      jjvkDouble:
-        AddDouble(TJOB_Double(aValue).Value);
-      jjvkString:
-        begin
-          us:=TJOB_String(aValue).Value;
-          h:=PByte(PWideChar(us));
-          AddUnicodeString(h,length(us));
-        end;
-      jjvkObject:
-        AddIJSObject(TJOB_Object(aValue).Value);
-      jjvkMethod:
-        begin
-          aMethod:=TJOB_Method(aValue);
-          Prep(1+3*SizeOf(Pointer),JOBArgMethod);
-          PPointer(p)^:=Pointer(aMethod.Invoke);
-          inc(p,sizeof(Pointer));
-          PPointer(p)^:=aMethod.Value.Data;
-          inc(p,sizeof(Pointer));
-          PPointer(p)^:=aMethod.Value.Code;
-          inc(p,sizeof(Pointer));
-        end;
-      jjvkDictionary:
-        begin
-          Dict:=TJOB_Dictionary(aValue).Values;
-          Prep(1+SizeOf(NativeInt),JOBArgDictionary);
-          PNativeInt(p)^:=length(Dict);
-          inc(p,SizeOf(NativeInt));
-          for i:=0 to length(Dict)-1 do
-          begin
-            AddUnicodeString(Dict[i].Name);
-            Add_TJOB_JSValue(Dict[i].Value);
-          end;
-        end;
-      jjvkArrayOfJSValue:
-        begin
-          Arr:=TJOB_ArrayOfJSValue(aValue).Values;
-          Prep(1+SizeOf(NativeInt),JOBArgArrayOfJSValue);
-          PNativeInt(p)^:=length(Arr);
-          inc(p,SizeOf(NativeInt));
-          for i:=0 to length(Arr)-1 do
-            Add_TJOB_JSValue(Arr[i]);
-        end;
-      jjvkArrayOfDouble:
-        begin
-          Prep(1+SizeOf(NativeInt)+SizeOf(Pointer),JOBArgArrayOfDouble);
-          i:=length(TJOB_ArrayOfDouble(aValue).Values);
-          PNativeInt(p)^:=i;
-          inc(p,SizeOf(NativeInt));
-          if i=0 then
-            PPointer(p)^:=nil
-          else
-            PPointer(p)^:=@TJOB_ArrayOfDouble(aValue).Values[0];
-          inc(p,sizeof(Pointer));
-        end;
-    end;
-  end;
-
-  procedure AddVariant(Index: integer);
-  var
-    v: Variant;
-    t: tvartype;
-    us: UnicodeString;
-    Intf: IJSObject;
-  begin
-    v:=Args[Index].VVariant^;
-    t:=VarType(v);
-    writeln('AddVariant Index=',Index,' VarType=',t);
-    case t of
-    varEmpty:
-      Prep(1,JOBArgUndefined);
-    varNull:
-      Prep(1,JOBArgNil);
-    varSmallInt,varInteger,varByte,varWord,varShortInt:
-      AddLongInt(v);
-    varLongWord,varCurrency,varInt64,varQWord,varSingle,varDouble,varDate:
-      AddDouble(v);
-    varOleStr:
-      begin
-        us:=v;
-        AddUnicodeString(us);
-      end;
-    varBoolean:
-      if v then
-        Prep(1,JOBArgTrue)
-      else
-        Prep(1,JOBArgFalse);
-    varString:
-      AddUTF8String(v);
-    varUnknown:
-      begin
-      if tvardata(v).vunknown=nil then
-        Prep(1,JOBArgNil)
-      else if VarSupports(v,IJSObject,Intf) then
-        AddObjectID(Intf.GetJSObjectID)
-      else
-        raise EJSInvoke.Create('Invoke js: [20220820210022] unsupported variant: '+IntToStr(t));
-      end
-    else
-      raise EJSInvoke.Create('Invoke js: [20220820185131] unsupported variant: '+IntToStr(t));
-    end;
-  end;
-
-var
-  i: Integer;
-  qw: QWord;
-  i64: Int64;
-  h: PByte;
-  s: String;
-  ws: WideString;
-  us: UnicodeString;
-  Obj: TObject;
-  JSValue: TJOB_JSValue;
-  ok: Boolean;
-begin
-  Result:=nil;
-  if length(Args)>255 then
-    raise EJSInvoke.Create('Invoke js: too many args');
-
-  Len:=1+length(Args);
-  Result:=GetMem(Len);
-  ok:=false;
-  try
-    p:=Result;
-
-    p^:=length(Args);
-    inc(p);
-    for i:=0 to high(Args) do
-    begin
-      case Args[i].VType of
-      vtInteger:
-        AddLongInt(Args[i].VInteger);
-      vtBoolean:
-        AddBoolean(Args[i].VBoolean);
-      vtExtended:
-        AddDouble(double(Args[i].VExtended^));
-      vtChar:
-        AddChar(ord(Args[i].VChar));
-      vtWideChar:
-        AddChar(ord(Args[i].VWideChar));
-      vtString:
-        begin
-          // shortstring
-          h:=PByte(Args[i].VString);
-          AddUTF8String(h+1,h^);
-        end;
-      vtPointer:
-        begin
-          h:=Args[i].VPointer;
-          if h=nil then
-            Prep(1,JOBArgNil)
-          else if h=JOB_Undefined then
-            Prep(1,JOBArgUndefined)
-          else begin
-            Prep(1+SizeOf(Pointer),JOBArgPointer);
-            PPointer(p)^:=h;
-            inc(p,sizeof(Pointer));
-          end;
-        end;
-      vtPChar:
-        begin
-          h:=PByte(Args[i].VPChar);
-          AddUTF8String(h,strlen(PChar(h)));
-        end;
-      vtObject:
-        begin
-          Obj:=Args[i].VObject;
-          if Obj=nil then
-            Prep(1,JOBArgNil)
-          else if Obj is TJSObject then
-            AddObjectID(TJSObject(Obj).JOBObjectID)
-          else if Obj is TJOB_JSValue then
-          begin
-            JSValue:=TJOB_JSValue(Obj);
-            Add_TJOB_JSValue(JSValue);
-          end else
-            RaiseNotSupported(Obj.ClassName);
-        end;
-      vtClass: ;
-      vtPWideChar:
-        begin
-          h:=PByte(Args[i].VPWideChar);
-          AddUnicodeString(h,strlen(PWideChar(h)));
-        end;
-      vtAnsiString:
-        begin
-          h:=Args[i].VAnsiString;
-          s:=AnsiString(h);
-          AddUTF8String(h,length(s));
-        end;
-      vtCurrency:
-        AddDouble(double(Args[i].VCurrency^));
-      vtVariant:
-        AddVariant(i);
-      vtInterface:
-        begin
-          h:=Args[i].VInterface;
-          AddIJSObject(IJSObject(h));
-        end;
-      vtWideString:
-        begin
-          h:=Args[i].VWideString;
-          ws:=WideString(h);
-          AddUnicodeString(h,length(ws));
-        end;
-      vtInt64:
-        begin
-          i64:=Args[i].VInt64^;
-          if (i64>=low(longint)) and (i64<=high(longint)) then
-            AddLongInt(i64)
-          else
-            AddDouble(i64);
-        end;
-      vtUnicodeString:
-        begin
-          h:=Args[i].VUnicodeString;
-          us:=UnicodeString(h);
-          AddUnicodeString(h,length(us));
-        end;
-      vtQWord:
-        begin
-          qw:=Args[i].VQWord^;
-          if (qw<=high(longint)) then
-            AddLongInt(qw)
-          else
-            AddDouble(qw);
-        end;
-      else
-        RaiseNotSupported(IntToStr(Args[i].VType));
-      end;
-    end;
-    Len:=p-Result;
-    ReAllocMem(Result,Len);
-    ok:=true;
-  finally
-    if not ok then
-      FreeMemAndNil(Result);
-  end;
-
-  {$IFDEF VerboseInvokeJSArgs}
-  s:='TJSObject.CreateInvokeJSArgs ArgCnt='+IntToStr(length(Args));
-  for i:=0 to high(Args) do
-    s:=s+' '+GetVarRecName(Args[i].VType);
-  s:=s+' Len='+IntToStr(Len);
-  s:=s+' Bytes=';
-  for i:=0 to Len-1 do
-    s:=s+HexStr(Result[i],2);
-  writeln(s);
-  {$ENDIF}
-end;
-
-constructor TJSObject.JOBCast(const Intf: IJSObject);
-begin
-  FJOBObjectID:=Intf.GetJSObjectID;
-  FJOBCastSrc:=Intf.GetJSObjectCastSrc;
-  if FJOBCastSrc=nil then
-    FJOBCastSrc:=Intf;
-end;
-
-constructor TJSObject.JOBCreateFromID(aID: TJOBObjectID);
-begin
-  FJOBObjectID:=aID;
-  FJOBObjectIDOwner:=true;
-end;
-
-constructor TJSObject.JOBCreateGlobal(const aID: UnicodeString);
-begin
-  FJOBObjectID:=__job_get_global(PWideChar(aID),length(aID));
-  if FJOBObjectID=0 then
-    raise EJSObject.Create('JS object "'+String(aID)+'" is not registered');
-  FJOBObjectIDOwner:=true;
-end;
-
-class function TJSObject.Cast(const Intf: IJSObject): IJSObject;
-begin
-  Result:=JOBCast(Intf);
-end;
-
-destructor TJSObject.Destroy;
-begin
-  if FJOBCastSrc<>nil then
-    FJOBCastSrc:=nil
-  else if (JOBObjectID>=0) and JOBObjectIDOwner then
-    __job_release_object(JOBObjectID);
-  FJOBObjectID:=0;
-  inherited Destroy;
-end;
-
-procedure TJSObject.InvokeJSNoResult(const aName: string;
-  const Args: array of const; Invoke: TJOBInvokeType);
-var
-  aError: TJOBResult;
-begin
-  aError:=InvokeJSNoResultFunc(aName,Args,@__job_invoke_noresult,Invoke);
-  if aError<>JOBResult_Success then
-    InvokeJS_RaiseResultMismatch(aName,JOBResult_Success,aError);
-end;
-
-function TJSObject.InvokeJSBooleanResult(const aName: string;
-  const Args: array of const; Invoke: TJOBInvokeType): Boolean;
-var
-  aError: TJOBResult;
-  b: bytebool;
-begin
-  b:=false;
-  aError:=InvokeJSOneResult(aName,Args,@__job_invoke_boolresult,@b,Invoke);
-  if aError=JOBResult_Boolean then
-  else if aError=JOBResult_Undefined then
-    b:=false
-  else
-    InvokeJS_RaiseResultMismatch(aName,JOBResult_Boolean,aError);
-  Result:=b;
-end;
-
-function TJSObject.InvokeJSDoubleResult(const aName: string;
-  const Args: array of const; Invoke: TJOBInvokeType): Double;
-var
-  aError: TJOBResult;
-begin
-  Result:=NaN;
-  aError:=InvokeJSOneResult(aName,Args,@__job_invoke_doubleresult,@Result,Invoke);
-  if aError=JOBResult_Double then
-  else if aError=JOBResult_Undefined then
-    Result:=NaN
-  else
-    InvokeJS_RaiseResultMismatch(aName,JOBResult_Double,aError);
-end;
-
-function TJSObject.InvokeJSUnicodeStringResult(const aName: string;
-  const Args: array of const; Invoke: TJOBInvokeType): UnicodeString;
-var
-  ResultLen: NativeInt;
-  aError: TJOBResult;
-begin
-  ResultLen:=0;
-  aError:=InvokeJSOneResult(aName,Args,@__job_invoke_stringresult,@ResultLen,Invoke);
-  if aError=JOBResult_String then
-    Result:=FetchString(ResultLen)
-  else begin
-    Result:='';
-    if aError<>JOBResult_Undefined then
-      InvokeJS_RaiseResultMismatch(aName,JOBResult_String,aError);
-  end;
-  //writeln('TJSObject.InvokeJSUnicodeStringResult Result="',Result,'"');
-end;
-
-function TJSObject.InvokeJSObjectResult(const aName: string;
-  const Args: array of const; aResultClass: TJSObjectClass;
-  Invoke: TJOBInvokeType): TJSObject;
-var
-  aError: TJOBResult;
-  NewObjId: TJOBObjectID;
-begin
-  Result:=nil;
-  NewObjId:=-1;
-  aError:=InvokeJSOneResult(aName,Args,@__job_invoke_objectresult,@NewObjId,Invoke);
-  if (aError=JOBResult_Null) or (aError=JOBResult_Undefined) then
-    exit;
-  if aError<>JOBResult_Object then
-    InvokeJS_RaiseResultMismatch(aName,JOBResult_Object,aError);
-
-  Result:=aResultClass.JOBCreateFromID(NewObjId);
-end;
-
-function TJSObject.InvokeJSValueResult(const aName: string;
-  const Args: array of const; Invoke: TJOBInvokeType): 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_Object.Create(nil);
-  JOBResult_Boolean:
-    Result:=TJOB_Boolean.Create(p^<>0);
-  JOBResult_Double:
-    Result:=TJOB_Double.Create(PDouble(p)^);
-  JOBResult_String:
-    Result:=TJOB_String.Create(FetchString(PNativeInt(p)^));
-  JOBResult_Function,
-  JOBResult_Object:
-    begin
-    Obj:=TJSObject.JOBCreateFromID(PJOBObjectID(p)^);
-    Result:=TJOB_Object.Create(Obj);
-    end;
-  else
-    InvokeJS_RaiseResultMismatchStr(aName,'jsvalue',JOBResult_Names[aError]);
-  end;
-end;
-
-function TJSObject.InvokeJSVariantResult(const aName: string;
-  const Args: array of const; Invoke: TJOBInvokeType): Variant;
-var
-  Buf: array[0..7] of byte;
-  p: PByte;
-  r: TJOBResult;
-  Obj: TJSObject;
-begin
-  FillByte(Buf[0],length(Buf),0);
-  p:=@Buf[0];
-  r:=InvokeJSOneResult(aName,Args,@__job_invoke_jsvalueresult,p,Invoke);
-  case r of
-  JOBResult_Undefined:
-    Result:=Variants.Unassigned;
-  JOBResult_Null:
-    Result:=Variants.Null;
-  JOBResult_Boolean:
-    Result:=p^<>0;
-  JOBResult_Double:
-    Result:=PDouble(p)^;
-  JOBResult_String:
-    Result:=FetchString(PNativeInt(p)^);
-  JOBResult_Function,
-  JOBResult_Object:
-    begin
-    Obj:=TJSObject.JOBCreateFromID(PJOBObjectID(p)^);
-    Result:=Obj as IJSObject;
-    end;
-  else
-    VarClear(Result);
-    InvokeJS_RaiseResultMismatchStr(aName,'jsvalue',JOBResult_Names[r]);
-  end;
-end;
-
-function TJSObject.InvokeJSUtf8StringResult(const aName: string;
-  const args: array of const; Invoke: TJOBInvokeType): String;
-begin
-  Result:=UTF8Encode(InvokeJSUnicodeStringResult(aName,Args,Invoke));
-end;
-
-function TJSObject.InvokeJSLongIntResult(const aName: string;
-  const args: array of const; Invoke: TJOBInvokeType): LongInt;
-var
-  d: Double;
-begin
-  d:=InvokeJSDoubleResult(aName,Args,Invoke);
-  if (Frac(d)<>0) or (d<low(longint)) or (d>high(longint)) then
-    InvokeJS_RaiseResultMismatchStr(aName,'longint','double')
-  else
-    Result:=Trunc(d);
-end;
-
-function TJSObject.InvokeJSMaxIntResult(const aName: string;
-  const args: array of const; Invoke: TJOBInvokeType): int64;
-var
-  d: Double;
-begin
-  d:=InvokeJSDoubleResult(aName,Args,Invoke);
-  if (Frac(d)<>0) or (d<low(int64)) or (d>high(int64)) then
-    InvokeJS_RaiseResultMismatchStr(aName,'int64','double')
-  else
-    Result:=Trunc(d);
-end;
-
-function TJSObject.InvokeJSTypeOf(const aName: string;
-  const Args: array of const): TJOBResult;
-begin
-  Result:=InvokeJSNoResultFunc(aName,Args,@__job_invoke_noresult,jiGetTypeOf);
-end;
-
-function TJSObject.InvokeJSUnicodeStringArrayResult(const aName: string;
-  const Args: array of const; Invoke: TJOBInvokeType): TUnicodeStringDynArray;
-var
-  ResultP: NativeInt;
-  aError: TJOBResult;
-begin
-  ResultP:=0;
-  aError:=InvokeJSOneResult(aName,Args,@__job_invoke_arraystringresult,@ResultP,Invoke);
-  if aError=JOBResult_ArrayOfString then
-    Result:=TUnicodeStringDynArray(ResultP)
-  else begin
-    Result:=[];
-    if aError<>JOBResult_Undefined then
-      InvokeJS_RaiseResultMismatch(aName,JOBResult_ArrayOfString,aError);
-  end;
-end;
-
-function TJSObject.ReadJSPropertyBoolean(const aName: string): boolean;
-begin
-  Result:=InvokeJSBooleanResult(aName,[],jiGet);
-end;
-
-function TJSObject.ReadJSPropertyDouble(const aName: string): double;
-begin
-  Result:=InvokeJSDoubleResult(aName,[],jiGet);
-end;
-
-function TJSObject.ReadJSPropertyUnicodeString(const aName: string
-  ): UnicodeString;
-begin
-  Result:=InvokeJSUnicodeStringResult(aName,[],jiGet);
-end;
-
-function TJSObject.ReadJSPropertyObject(const aName: string;
-  aResultClass: TJSObjectClass): TJSObject;
-begin
-  Result:=InvokeJSObjectResult(aName,[],aResultClass,jiGet);
-end;
-
-function TJSObject.ReadJSPropertyUtf8String(const aName: string): string;
-begin
-  Result:=InvokeJSUtf8StringResult(aName,[],jiGet);
-end;
-
-function TJSObject.ReadJSPropertyLongInt(const aName: string): LongInt;
-begin
-  Result:=InvokeJSLongIntResult(aName,[],jiGet);
-end;
-
-function TJSObject.ReadJSPropertyInt64(const aName: string): Int64;
-begin
-  Result:=Trunc(InvokeJSDoubleResult(aName,[],jiGet));
-end;
-
-function TJSObject.ReadJSPropertyValue(const aName: string): TJOB_JSValue;
-begin
-  Result:=InvokeJSValueResult(aName,[],jiGet);
-end;
-
-function TJSObject.ReadJSPropertyVariant(const aName: string): Variant;
-begin
-  Result:=InvokeJSVariantResult(aName,[],jiGet);
-end;
-
-function TJSObject.ReadJSPropertyMethod(const aName: string): TMethod;
-begin
-//  Result:=InvokeJSVariantResult(aName,[],jiGet);
-end;
-
-procedure TJSObject.WriteJSPropertyBoolean(const aName: string; Value: Boolean);
-begin
-  InvokeJSNoResult(aName,[Value],jiSet);
-end;
-
-procedure TJSObject.WriteJSPropertyDouble(const aName: string; Value: Double);
-begin
-  InvokeJSNoResult(aName,[Value],jiSet);
-end;
-
-procedure TJSObject.WriteJSPropertyUnicodeString(const aName: string;
-  const Value: UnicodeString);
-begin
-  InvokeJSNoResult(aName,[Value],jiSet);
-end;
-
-procedure TJSObject.WriteJSPropertyUtf8String(const aName: string;
-  const Value: String);
-begin
-  InvokeJSNoResult(aName,[Value],jiSet);
-end;
-
-procedure TJSObject.WriteJSPropertyObject(const aName: string; Value: IJSObject
-  );
-begin
-  InvokeJSNoResult(aName,[Value],jiSet);
-end;
-
-procedure TJSObject.WriteJSPropertyLongInt(const aName: string; Value: LongInt);
-begin
-  InvokeJSNoResult(aName,[Value],jiSet);
-end;
-
-procedure TJSObject.WriteJSPropertyInt64(const aName: string; Value: Int64);
-begin
-  InvokeJSNoResult(aName,[Value],jiSet);
-end;
-
-procedure TJSObject.WriteJSPropertyValue(const aName: string;
-  Value: TJOB_JSValue);
-begin
-  InvokeJSNoResult(aName,[Value],jiSet);
-end;
-
-procedure TJSObject.WriteJSPropertyVariant(const aName: string;
-  const Value: Variant);
-begin
-  InvokeJSNoResult(aName,[Value],jiSet);
-end;
-
-procedure TJSObject.WriteJSPropertyMethod(const aName: string;
-  const Value: TMethod);
-begin
-  // TODO InvokeJSNoResult(aName,[Value],jiSet);
-end;
-
-function TJSObject.NewJSObject(const Args: array of const;
-  aResultClass: TJSObjectClass): TJSObject;
-begin
-  Result:=InvokeJSObjectResult('',Args,aResultClass,jiNew);
-end;
-
-function TJSObject.getOwnPropertyNames(const Obj: IJSObject
-  ): TUnicodeStringDynArray;
-begin
-  Result:=JSObject.InvokeJSUnicodeStringArrayResult('getOwnPropertyNames',[Obj]);
-end;
-
-function TJSObject.getPrototypeOf(const Obj: IJSObject): IJSObject;
-begin
-  Result:=JSObject.InvokeJSObjectResult('getPrototypeOf',[Obj],TJSObject) as IJSObject;
-end;
-
-function TJSObject.hasOwnProperty(const PropName: String): boolean;
-begin
-  Result:=InvokeJSBooleanResult('hasOwnProperty',[PropName]);
-end;
-
-function TJSObject.isPrototypeOf(const Obj: IJSObject): boolean;
-begin
-  Result:=InvokeJSBooleanResult('isPrototypeOf',[Obj]);
-end;
-
-function TJSObject.propertyIsEnumerable(const PropName: String): boolean;
-begin
-  Result:=InvokeJSBooleanResult('propertyIsEnumerable',[PropName]);
-end;
-
-function TJSObject.toLocaleString: UnicodeString;
-begin
-  Result:=InvokeJSUnicodeStringResult('toLocaleString',[]);
-end;
-
-function TJSObject.toString: String;
-begin
-  Result:=InvokeJSUtf8StringResult('toString',[]);
-end;
-
-function TJSObject.toUString: UnicodeString;
-begin
-  Result:=InvokeJSUnicodeStringResult('toString',[]);
-end;
-
-function TJSObject.valueOf: Variant;
-begin
-  Result:=InvokeJSVariantResult('valueOf',[]);
-end;
-
-{ TJSDate }
-
-class function TJSDate.Cast(const Intf: IJSObject): IJSDate;
-begin
-  Result:=TJSDate.JOBCast(Intf);
-end;
-
-function TJSDate.Create(aYear: NativeInt; aMonth: NativeInt;
-  aDayOfMonth: NativeInt; TheHours: NativeInt; TheMinutes: NativeInt;
-  TheSeconds: NativeInt; TheMilliseconds: NativeInt): IJSDate;
-begin
-  Result:=JSDate.NewJSObject([aYear,aMonth,aDayOfMonth,TheHours,TheMinutes,TheSeconds,TheMilliseconds],TJSDate) as IJSDate;
-end;
-
-function TJSDate.toLocaleDateString: UnicodeString;
-begin
-  Result:=InvokeJSUnicodeStringResult('toLocaleDateString',[]);
-end;
-
-initialization
-  JSObject:=TJSObject.JOBCreateGlobal('Object') as IJSObject;
-  JSDate:=TJSDate.JOBCreateGlobal('Date') as IJSDate;
-
-end.
-