snips.sh

   1/// SpiderMonkey 45/52 *.h header port to Delphi
   2// if defined SM52 condition then SpiderMonkey 52 is used
   3// - this unit is a part of the freeware Synopse framework,
   4// licensed under a MPL/GPL/LGPL tri-license; version 1.18
   5unit SpiderMonkey;
   6{
   7    This file is part of Synopse framework.
   8
   9    Synopse framework. Copyright (c) Arnaud Bouchez
  10      Synopse Informatique - http://synopse.info
  11
  12    SyNode for mORMot Copyright (c) Pavel Mashlyakovsky & Vadim Orel
  13      pavel.mash at gmail.com
  14
  15  *** BEGIN LICENSE BLOCK *****
  16  Version: MPL 1.1/GPL 2.0/LGPL 2.1
  17
  18  The contents of this file are subject to the Mozilla Public License Version
  19  1.1 (the "License"); you may not use this file except in compliance with
  20  the License. You may obtain a copy of the License at
  21  http://www.mozilla.org/MPL
  22
  23  Software distributed under the License is distributed on an "AS IS" basis,
  24  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  25  for the specific language governing rights and limitations under the License.
  26
  27  The Initial Developer of the Original Code is
  28  Pavel Mashlyakovsky & Vadim Orel.
  29  Portions created by the Initial Developer are Copyright (c)
  30  the Initial Developer. All Rights Reserved.
  31
  32  Contributor(s):
  33  - Arnaud Bouchez
  34  - Vadim Orel
  35  - Pavel Mashlyakovsky
  36  - win2014
  37
  38  Alternatively, the contents of this file may be used under the terms of
  39  either the GNU General Public License Version 2 or later (the "GPL"), or
  40  the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  41  in which case the provisions of the GPL or the LGPL are applicable instead
  42  of those above. If you wish to allow use of your version of this file only
  43  under the terms of either the GPL or the LGPL, and not to allow others to
  44  use your version of this file under the terms of the MPL, indicate your
  45  decision by deleting the provisions above and replace them with the notice
  46  and other provisions required by the GPL or the LGPL. If you do not delete
  47  the provisions above, a recipient may use your version of this file under
  48  the terms of any one of the MPL, the GPL or the LGPL.
  49
  50  ***** END LICENSE BLOCK *****
  51
  52  Version 1.18
  53  - initial release. Use SpiderMonkey 45
  54}
  55
  56{$I Synopse.inc} // define HASINLINE CPU32 CPU64 OWNNORMTOUPPER
  57{$I SyNode.inc}   //define WITHASSERT
  58
  59interface
  60uses
  61  {$ifdef MSWINDOWS}
  62  Windows,
  63  {$endif}
  64  SynCommons,
  65  SynTable,
  66  SynLog,
  67  SysUtils;
  68
  69type
  70  JSUnknown = Pointer; //Use this type for developping. In real case comment it and check than you use only known types
  71{$ifndef UNICODE}
  72  /// 8 bit signed integer type for C APIs
  73  int8 = ShortInt;
  74  /// 8 bit unsigned integer type for C APIs
  75  uint8 = Byte;
  76
  77  /// 16 bit signed integer type for C APIs
  78  int16 = Smallint;
  79  /// 16 bit unsigned integer type for C APIs
  80  uint16 = Word;
  81
  82  /// 32 bit signed integer type for C APIs
  83  int32 = Integer;
  84  /// 32 bit unsigned integer type for C APIs
  85  uint32 = Cardinal;
  86{$endif}
  87{$ifndef ISDELPHIXE2}
  88  uintptr = PtrUInt;
  89{$endif}
  90  uintN = PtrUInt;
  91
  92{.$ifndef FPC}
  93  /// variable type used to store a buffer size (in bytes) for SMAPI
  94  size_t = PtrUInt;
  95{.$endif}
  96  psize_t = ^size_t;
  97  CChar = AnsiChar;
  98  PCChar = PAnsiChar;
  99  CChar16 = WideChar;
 100  PCChar16 = PWideChar;
 101  PPCChar16 = ^PCChar16;
 102
 103{$Z4}
 104  JSType = (
 105    JSTYPE_VOID       = 0, // undefined
 106    JSTYPE_OBJECT     = 1, // object
 107    JSTYPE_FUNCTION   = 2, // function
 108    JSTYPE_STRING     = 3, // string
 109    JSTYPE_NUMBER     = 4, // number
 110    JSTYPE_BOOLEAN    = 5, // boolean
 111    JSTYPE_NULL       = 6, // null
 112    JSTYPE_SYMBOL     = 7, //symbol
 113    JSTYPE_LIMIT      = 8
 114  );
 115
 116  JSGCParamKey = (
 117    // Maximum nominal heap before last ditch GC.
 118    JSGC_MAX_BYTES = 0,
 119    // Number of JS_malloc bytes before last ditch GC.
 120    JSGC_MAX_MALLOC_BYTES = 1,
 121    // Amount of bytes allocated by the GC.
 122    JSGC_BYTES = 3,
 123    // Number of times GC has been invoked. Includes both major and minor GC.
 124    JSGC_NUMBER = 4,
 125    // Max size of the code cache in bytes.
 126    JSGC_MAX_CODE_CACHE_BYTES = 5,
 127    // Select GC mode.
 128    JSGC_MODE = 6,
 129    // Number of cached empty GC chunks.
 130    JSGC_UNUSED_CHUNKS = 7,
 131    // Total number of allocated GC chunks.
 132    JSGC_TOTAL_CHUNKS = 8,
 133    // Max milliseconds to spend in an incremental GC slice.
 134    JSGC_SLICE_TIME_BUDGET = 9,
 135    // Maximum size the GC mark stack can grow to.
 136    JSGC_MARK_STACK_LIMIT = 10,
 137    // GCs less than this far apart in time will be considered 'high-frequency GCs'.
 138    // See setGCLastBytes in jsgc.cpp.
 139    JSGC_HIGH_FREQUENCY_TIME_LIMIT = 11,
 140    // Start of dynamic heap growth.
 141    JSGC_HIGH_FREQUENCY_LOW_LIMIT = 12,
 142    // End of dynamic heap growth.
 143    JSGC_HIGH_FREQUENCY_HIGH_LIMIT = 13,
 144    // Upper bound of heap growth.
 145    JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX = 14,
 146    // Lower bound of heap growth.
 147    JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN = 15,
 148    // Heap growth for low frequency GCs.
 149    JSGC_LOW_FREQUENCY_HEAP_GROWTH = 16,
 150    // If false, the heap growth factor is fixed at 3. If true, it is determined
 151    // based on whether GCs are high- or low- frequency.
 152    JSGC_DYNAMIC_HEAP_GROWTH = 17,
 153    // If true, high-frequency GCs will use a longer mark slice.
 154    JSGC_DYNAMIC_MARK_SLICE = 18,
 155    // Lower limit after which we limit the heap growth.
 156    JSGC_ALLOCATION_THRESHOLD = 19,
 157    // We try to keep at least this many unused chunks in the free chunk pool at
 158    // all times, even after a shrinking GC.
 159    JSGC_MIN_EMPTY_CHUNK_COUNT = 21,
 160    // We never keep more than this many unused chunks in the free chunk pool.
 161    JSGC_MAX_EMPTY_CHUNK_COUNT = 22,
 162    // Whether compacting GC is enabled.
 163    JSGC_COMPACTING_ENABLED = 23
 164    // If true, painting can trigger IGC slices.
 165    ,JSGC_REFRESH_FRAME_SLICES_ENABLED = 24
 166  );
 167
 168  JSGCMode = (
 169    // Perform only global GCs.
 170    JSGC_MODE_GLOBAL = 0,
 171    // Perform per-compartment GCs until too much garbage has accumulated.
 172    JSGC_MODE_COMPARTMENT = 1,
 173    // Collect in short time slices rather than all at once. Implies
 174    // JSGC_MODE_COMPARTMENT.
 175    JSGC_MODE_INCREMENTAL = 2
 176  );
 177
 178  JSVersion = (
 179    /// Run-time version enumeration corresponding to an identified version
 180    JSVERSION_UNKNOWN = -1,
 181    /// Run-time version enumeration corresponding to default version
 182    JSVERSION_DEFAULT = 0,
 183
 184    JSVERSION_ECMA_3  = 148,
 185    /// Run-time version enumeration corresponding to 1.6
 186    JSVERSION_1_6     = 160,
 187    /// Run-time version enumeration corresponding to 1.7
 188    JSVERSION_1_7     = 170,
 189    /// Run-time version enumeration corresponding to 1.8
 190    JSVERSION_1_8     = 180,
 191    /// Run-time version enumeration corresponding to ECMA standard 5, i.e. 1.8.5
 192    JSVERSION_ECMA_5  = 185
 193  );
 194
 195///  This enum is used to select if properties with JSPROP_DEFINE_LATE flag
 196//  should be defined on the object.
 197//  Normal JSAPI consumers probably always want DefineAllProperties here.
 198  JSPropertyDefinitionBehavior = (
 199  DefineAllProperties,
 200  OnlyDefineLateProperties,
 201  DontDefineLateProperties
 202  );
 203/// During global creation, we fire notifications to callbacks registered
 204// via the Debugger API. These callbacks are arbitrary script, and can touch
 205// the global in arbitrary ways. When that happens, the global should not be
 206// in a half-baked state. But this creates a problem for consumers that need
 207// to set slots on the global to put it in a consistent state.
 208// - This API provides a way for consumers to set slots atomically (immediately
 209// after the global is created), before any debugger hooks are fired. It's
 210// unfortunately on the clunky side, but that's the way the cookie crumbles.
 211// - If callers have no additional state on the global to set up, they may pass
 212// |FireOnNewGlobalHook| to JS_NewGlobalObject, which causes that function to
 213// fire the hook as its final act before returning. Otherwise, callers should
 214// pass |DontFireOnNewGlobalHook|, which means that they are responsible for
 215// invoking JS_FireOnNewGlobalObject upon successfully creating the global. If
 216// an error occurs and the operation aborts, callers should skip firing the
 217// hook. But otherwise, callers must take care to fire the hook exactly once
 218// before compiling any script in the global's scope (we have assertions in
 219// place to enforce this). This lets us be sure that debugger clients never miss
 220// breakpoints.
 221  OnNewGlobalHookOption = (
 222    FireOnNewGlobalHook,
 223    DontFireOnNewGlobalHook
 224  );
 225/// Dense index into cached prototypes and class atoms for standard objects.
 226  JSProtoKey = (
 227  JSProto_Null = 0,
 228  JSProto_Object,
 229  JSProto_Function,
 230  JSProto_Array,
 231  JSProto_Boolean,
 232  JSProto_JSON,
 233  JSProto_Date,
 234  JSProto_Math,
 235  JSProto_Number,
 236  JSProto_String,
 237  JSProto_RegExp,
 238  JSProto_Error,
 239  JSProto_InternalError,
 240  JSProto_EvalError,
 241  JSProto_RangeError,
 242  JSProto_ReferenceError,
 243  JSProto_SyntaxError,
 244  JSProto_TypeError,
 245  JSProto_URIError,
 246  JSProto_DebuggeeWouldRun,
 247  JSProto_CompileError,
 248  JSProto_RuntimeError,
 249  JSProto_Iterator,
 250  JSProto_StopIteration,
 251  JSProto_ArrayBuffer,
 252  JSProto_Int8Array,
 253  JSProto_Uint8Array,
 254  JSProto_Int16Array,
 255  JSProto_Uint16Array,
 256  JSProto_Int32Array,
 257  JSProto_Uint32Array,
 258  JSProto_Float32Array,
 259  JSProto_Float64Array,
 260  JSProto_Uint8ClampedArray,
 261  JSProto_Proxy,
 262  JSProto_WeakMap,
 263  JSProto_Map,
 264  JSProto_Set,
 265  JSProto_DataView,
 266  JSProto_Symbol,
 267  JSProto_SharedArrayBuffer,
 268  JSProto_Intl,
 269  JSProto_TypedObject,
 270  JSProto_Reflect,
 271  JSProto_SIMD,
 272  JSProto_WeakSet,
 273  JSProto_TypedArray,
 274  JSProto_Atomics,
 275  JSProto_SavedFrame,
 276  JSProto_WebAssembly,
 277  JSProto_WasmModule,
 278  JSProto_WasmInstance,
 279  JSProto_WasmMemory,
 280  JSProto_WasmTable,
 281  JSProto_Promise,
 282  JSProto_LIMIT
 283  );
 284{$Z1}
 285/// Type of JSValue
 286  JSValueType = (
 287    JSVAL_TYPE_DOUBLE   = $00,
 288    JSVAL_TYPE_INT32    = $01,
 289    JSVAL_TYPE_UNDEFINED= $02,
 290    JSVAL_TYPE_BOOLEAN  = $03,
 291    JSVAL_TYPE_MAGIC    = $04,
 292    JSVAL_TYPE_STRING   = $05,
 293    JSVAL_TYPE_SYMBOL   = $06,
 294    JSVAL_TYPE_PRIVATE_GCTHING = $07,
 295    JSVAL_TYPE_NULL     = $08,
 296    JSVAL_TYPE_OBJECT   = $0C,
 297    // These never appear in a jsval; they are only provided as an out-of-band value.
 298    JSVAL_TYPE_UNKNOWN  = $20,
 299    JSVAL_TYPE_MISSING  = $21
 300  );
 301
 302{$ifndef CPU64}
 303/// first 4 bytes for JSValue
 304{$MINENUMSIZE 4}
 305{$WARN COMBINING_SIGNED_UNSIGNED OFF}
 306{$WARN BOUNDS_ERROR OFF}
 307  JSValueTag = (
 308  JSVAL_TAG_CLEAR      = Cardinal($FFFFFF80),
 309  JSVAL_TAG_INT32      = Cardinal(JSVAL_TAG_CLEAR or UInt8(JSVAL_TYPE_INT32)),
 310  JSVAL_TAG_UNDEFINED  = Cardinal(JSVAL_TAG_CLEAR or UInt8(JSVAL_TYPE_UNDEFINED)),
 311  JSVAL_TAG_STRING     = Cardinal(JSVAL_TAG_CLEAR or UInt8(JSVAL_TYPE_STRING)),
 312  JSVAL_TAG_SYMBOL     = Cardinal(JSVAL_TAG_CLEAR or UInt8(JSVAL_TYPE_SYMBOL)),
 313  JSVAL_TAG_BOOLEAN    = Cardinal(JSVAL_TAG_CLEAR or UInt8(JSVAL_TYPE_BOOLEAN)),
 314  JSVAL_TAG_MAGIC      = Cardinal(JSVAL_TAG_CLEAR or UInt8(JSVAL_TYPE_MAGIC)),
 315  JSVAL_TAG_NULL       = Cardinal(JSVAL_TAG_CLEAR or UInt8(JSVAL_TYPE_NULL)),
 316  JSVAL_TAG_OBJECT     = Cardinal(JSVAL_TAG_CLEAR or UInt8(JSVAL_TYPE_OBJECT))
 317  );
 318{$WARN BOUNDS_ERROR ON}
 319{$WARN COMBINING_SIGNED_UNSIGNED ON}
 320{$MINENUMSIZE 1}
 321{$endif}
 322
 323
 324{$Z2}
 325  /// Possible exception types
 326  // -These types are part of a JSErrorFormatString structure
 327  // - They define which error to throw in case of a runtime error
 328  // - JSEXN_NONE marks an unthrowable error
 329  JSExnType = (
 330    JSEXN_NONE = -1,
 331    JSEXN_ERR,
 332    JSEXN_INTERNALERR,
 333    JSEXN_EVALERR,
 334    JSEXN_RANGEERR,
 335    JSEXN_REFERENCEERR,
 336    JSEXN_SYNTAXERR,
 337    JSEXN_TYPEERR,
 338    JSEXN_URIERR,
 339    JSEXN_DEBUGGEEWOULDRUN,
 340    JSEXN_WASMCOMPILEERROR,
 341    JSEXN_WASMRUNTIMEERROR,
 342    JSEXN_WARN,
 343    JSEXN_LIMIT
 344  );
 345{$Z1}
 346
 347
 348  Tint8Vector = array[0..(MaxInt div sizeof(int8))-1] of int8;
 349  Pint8Vector = ^Tint8Vector;
 350  Tuint8Vector = array[0..(MaxInt div sizeof(uint8))-1] of uint8;
 351  Puint8Vector = ^Tuint8Vector;
 352  Tint16Vector = array[0..(MaxInt div sizeof(int16))-1] of int16;
 353  Pint16Vector = ^Tint16Vector;
 354  Tuint16Vector = array[0..(MaxInt div sizeof(uint16))-1] of uint16;
 355  Puint16Vector = ^Tuint16Vector;
 356  Tint32Vector = array[0..(MaxInt div sizeof(int32))-1] of int32;
 357  Pint32Vector = ^Tint32Vector;
 358  Tuint32Vector = array[0..(MaxInt div sizeof(uint32))-1] of uint32;
 359  Puint32Vector = ^Tuint32Vector;
 360  Tfloat32Vector = array[0..(MaxInt div sizeof(single))-1] of single;
 361  Pfloat32Vector = ^Tfloat32Vector;
 362  Tfloat64Vector = array[0..(MaxInt div sizeof(double))-1] of double;
 363  Pfloat64Vector = ^Tfloat64Vector;
 364
 365  /// the available types of elements in a typed array or data view
 366  // - obj must have passed a JS_IsArrayBufferView/JS_Is*Array test, or somehow
 367  // be known that it would pass such a test: it is an ArrayBufferView or a
 368  // wrapper of an ArrayBufferView, and the unwrapping will succeed.
 369  /// - jsabTYPE_UINT8_CLAMPED is a special type that is a uint8_t, but assignments
 370  // are clamped to [0,255]: treat the raw data type as a uint8_t.
 371  // - jsabTYPE_DATAVIEW is the type returned for a DataView. Note that
 372  // there is no single element type in this case
 373  JSArrayBufferViewType = (
 374    jsabTYPE_INT8 = 0,
 375    jsabTYPE_UINT8,
 376    jsabTYPE_INT16,
 377    jsabTYPE_UINT16,
 378    jsabTYPE_INT32,
 379    jsabTYPE_UINT32,
 380    jsabTYPE_FLOAT32,
 381    jsabTYPE_FLOAT64,
 382    jsabTYPE_UINT8_CLAMPED,
 383    jsabTYPE_MAXTYPEDARRAYVIEWTYPE,
 384    jsabTYPE_FLOAT32x4,
 385    jsabTYPE_INT32x4
 386
 387);
 388const
 389  nullPtr: pointer = nil;
 390  /// Run-time version enumeration corresponding to the latest available
 391  // - that is, ECMA standard 5, i.e. 1.8.5
 392  JSVERSION_LATEST  = JSVERSION_ECMA_5;
 393type
 394// pointers
 395  JSFreeOp = pointer;
 396  PJSContextOptions = ^JSContextOptions;
 397  PJSContext = ^JSContext;
 398  PJSCompartment = ^JSCompartment;
 399  PJS_CompartmentOptions = ^JS_CompartmentOptions;
 400  PJSObject = ^JSObject;
 401  PJSFunction = PJSObject;
 402  PJSString = ^JSString;
 403  PJSClass = ^JSClass;
 404  PJSCompileOptions = ^JSCompileOptions;
 405  PJSScript = JSUnknown;
 406  PJSRootedValue = ^JSRootedValue;
 407  PJSRootedObject = ^JSRootedObject;
 408  PJSRootedString = ^JSRootedString;
 409  PJSPropertySpec = ^JSPropertySpec;
 410  PJSFunctionSpec = ^JSFunctionSpec;
 411  PJSErrorReport = ^JSErrorReport;
 412  PJSErrorFormatString = ^JSErrorFormatString;
 413  PJSAtomState = JSUnknown;
 414  PJSPrincipals = JSUnknown;
 415  PJSAutoCheckCannotGC = JSUnknown;
 416  PJSStringFinalizer = ^JSStringFinalizer;
 417
 418// jsid
 419  JSIdType = (
 420    JSID_TYPE_STRING = $0,
 421    JSID_TYPE_INT    = $1,
 422    JSID_TYPE_VOID   = $2,
 423    JSID_TYPE_SYMBOL = $4
 424  );
 425  jsid = record
 426    asBits: size_t;
 427    function isString: Boolean;
 428    function asJSString: PJSString;
 429  end;
 430
 431  TjsidVector = array[0..(MaxInt div sizeof(jsid))-2] of jsid;
 432  PjsidVector = ^TjsidVector;
 433
 434  _JSIdArray = record
 435    cx: PJSContext;
 436    mBegin: PjsidVector;    //* actually, length jsid words */
 437    mLength: size_t;
 438    mCapacity: size_t;
 439    mStorage: Int64;
 440  end;
 441  _JSIdArrayPtr = ^_JSIdArray;
 442/// internal Spidermonkey structure for storrage jsid
 443
 444  { JSIdArray }
 445
 446  JSIdArray  = {$ifdef USERECORDWITHMETHODS}record{$else}object{$endif}
 447  end;
 448  PJSIdArray = ^JSIdArray;
 449
 450// jsvalue
 451  JSWhyMagic = Cardinal;
 452  jsval_payload = record
 453    case Byte of
 454      0: (i32: int32);
 455      1: (u32: uint32);
 456{$IFNDEF CPU64}
 457      2: (boo: uint32);   // Don't use |bool| -- it must be four bytes.
 458      3: (str: PJSString);
 459      4: (obj: PJSObject);
 460      5: (ptr: pointer);
 461{$ENDIF}
 462      6: (why: JSWhyMagic);
 463{$IFNDEF CPU64}
 464      7: (word: size_t);
 465      8: (uintptr: PtrUInt)
 466{$ENDIF}
 467  end;
 468{$ifdef IS_LITTLE_ENDIAN}
 469  jsval_val_layout = packed record
 470    payload: jsval_payload;
 471{$IFNDEF CPU64}
 472    tag: JSValueTag;
 473{$ENDIF}
 474  end;
 475{$else} //BIG_ENDIAN
 476  jsval_val_layout = record
 477    tag: JSValueTag;
 478    payload: jsval_payload;
 479  end;
 480{$endif}
 481
 482  /// low-level definition of the jsval internals
 483  // - do not use directly
 484  jsval_layout = record
 485    case Byte of
 486      0: (asBits: QWord);
 487{$IFNDEF CPU64}
 488      1: (s: jsval_val_layout);
 489{$ENDIF}
 490      2: (asDouble: double);
 491      3: (asPtr: Pointer);
 492  end;
 493
 494  /// used by JS_Stringify() method to incremently write the JSON content
 495  JSONWriteCallback = function(const buf: PCChar16; len: uint32; data: pointer): Boolean; cdecl;
 496
 497  /// high-level definition of the JSValue
 498  {$ifdef USERECORDWITHMETHODS}jsval = record
 499    {$else}jsval = object{$endif}
 500  private
 501    _l: jsval_layout;
 502
 503    function getIsVoid: Boolean; {$ifdef HASINLINE}inline;{$endif}
 504    function getIsNull: Boolean; {$ifdef HASINLINE}inline;{$endif}
 505
 506    function getIsInteger: Boolean; {$ifdef HASINLINE}inline;{$endif}
 507    function getAsInteger: Integer; {$ifdef HASINLINE}inline;{$endif}
 508    procedure setAsInteger(const Value: Integer); {$ifdef HASINLINE}inline;{$endif}
 509
 510    function getAsInt64: Int64; {$ifdef HASINLINE}inline;{$endif}
 511    procedure setAsInt64(const Value: Int64); {$ifdef HASINLINE}inline;{$endif}
 512
 513    function getIsDouble: Boolean;{$ifdef HASINLINE}inline;{$endif}
 514    function getAsDouble: Double;{$ifdef HASINLINE}inline;{$endif}
 515    procedure setAsDouble(const Value: Double);{$ifdef HASINLINE}inline;{$endif}
 516
 517    function getIsNumber: Boolean;{$ifdef HASINLINE}inline;{$endif}
 518
 519    function getIsBoolean: Boolean;{$ifdef HASINLINE}inline;{$endif}
 520    function getAsBoolean: Boolean;{$ifdef HASINLINE}inline;{$endif}
 521    procedure setAsBoolean(const Value: Boolean);{$ifdef HASINLINE}inline;{$endif}
 522
 523    function getIsObject: Boolean;{$ifdef HASINLINE}inline;{$endif}
 524    function getAsObject: PJSObject;{$ifdef HASINLINE}inline;{$endif}
 525    procedure setAsObject(const Value: PJSObject);{$ifdef HASINLINE}inline;{$endif}
 526
 527    function getIsString: Boolean; {$ifdef HASINLINE}inline;{$endif}
 528    function getJSString: PJSString; {$ifdef HASINLINE}inline;{$endif}
 529    procedure setJSString(const Value: PJSString);{$ifdef HASINLINE}inline;{$endif}
 530
 531    function getIsSimpleVariant(cx: PJSContext): Boolean;{$ifdef HASINLINE}inline;{$endif}
 532    function getSimpleVariant(cx: PJSContext): Variant;
 533    procedure setSimpleVariant(cx: PJSContext; const Value: Variant);
 534
 535    function getPrivate: Pointer;{$ifdef HASINLINE}inline;{$endif}
 536    procedure setPrivate(const Value: Pointer);{$ifdef HASINLINE}inline;{$endif}
 537
 538    function getAsDate(cx: PJSContext): TDateTime;
 539    procedure setAsDate(cx: PJSContext; const Value: TDateTime);
 540
 541    function getAsJson(cx: PJSContext): RawUTF8;
 542    procedure setAsJson(cx: PJSContext; const Value: RawUTF8);
 543
 544    function IsPrimitive: Boolean;{$ifdef HASINLINE}inline;{$endif}
 545    function IsMagic: Boolean;{$ifdef HASINLINE}inline;{$endif}
 546
 547  public
 548    /// Is vaule void
 549    property isVoid: Boolean read getIsVoid;
 550    /// Set vaule void
 551    procedure setVoid;
 552    /// Is vaule null
 553    property isNull: Boolean read getIsNull;
 554    /// Set vaule null
 555    procedure setNull;
 556    /// Is vaule 32bit integer
 557    property isInteger: Boolean read getIsInteger;
 558    /// Get/set vaule as 32bit integer
 559    property asInteger: Integer read getAsInteger write setAsInteger;
 560    /// Get/set vaule as 64bit integer (if more than 32 bits than as double)
 561    property asInt64: Int64 read getAsInt64 write setAsInt64;
 562    /// Is vaule double
 563    property isDouble: Boolean read getIsDouble;
 564    /// Get/set vaule as double
 565    property asDouble: Double read getAsDouble write setAsDouble;
 566    /// Is vaule Number (32bit integer or double)
 567    property isNumber: Boolean read getIsNumber;
 568    /// Is vaule boolean
 569    property isBoolean: Boolean read getIsBoolean;
 570    /// Get/set vaule as boolean
 571    property asBoolean: Boolean read getAsBoolean write setAsBoolean;
 572    /// Is vaule object(null is object too)
 573    property isObject: Boolean read getIsObject;
 574    /// Get/set vaule as object
 575    property asObject: PJSObject read getAsObject write setAsObject;
 576    /// Is vaule string
 577    property isString: Boolean read getIsString;
 578    /// Get/set vaule as JSString
 579    property asJSString: PJSString read getJSString write setJSString;
 580    /// Is vaule simple(void, null, boolean, number or string)
 581    property isSimpleVariant[cx: PJSContext]: Boolean read getIsSimpleVariant;
 582    /// Get/set vaule as simple
 583    property asSimpleVariant[cx: PJSContext]: Variant read getSimpleVariant write setSimpleVariant;
 584    /// Get/set vaule as Custom pointer
 585    property asPrivate: Pointer read getPrivate write setPrivate;
 586    /// Get/set vaule as DateTime(object Date used)
 587    property asDate[cx: PJSContext]: TDateTime read getAsDate write setAsDate;
 588    /// Add JSON representation of value to Writer
 589    procedure AddJSON(cx: PJSContext; W: TTextWriter);
 590    /// Get/set vaule as JSON representation
 591    property asJson[cx: PJSContext]: RawUTF8 read getAsJson write setAsJson;
 592    /// Get JSON representation of value and launch callback
 593    function Stringify(cx: PJSContext; var replacer: PJSObject; space: jsval;
 594      callback: JSONWriteCallback; data: pointer): Boolean;
 595    /// Get type of value
 596    function ValType(cx: PJSContext): JSType;
 597    /// Get source of value
 598    function toSource(cx: PJSContext): PJSString;
 599    /// jsval.*Value functions cunstruct new jsval as in JS::Value C++
 600    // classes - see https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_Reference/JS::Value
 601    class function NullValue: jsval; static; {$ifdef HASINLINE}inline;{$endif}
 602    class function Int32Value(v: integer): jsval; static; {$ifdef HASINLINE}inline;{$endif}
 603    class function BooleanValue(v: boolean): jsval; static; {$ifdef HASINLINE}inline;{$endif}
 604    class function TrueValue: jsval; static; {$ifdef HASINLINE}inline;{$endif}
 605    class function FalseValue: jsval; static; {$ifdef HASINLINE}inline;{$endif}
 606    class function DoubleValue(v: double): jsval; static; {$ifdef HASINLINE}inline;{$endif}
 607    class function StringValue(v: PJSString): jsval; static; {$ifdef HASINLINE}inline;{$endif}
 608    class function ObjectValue(v: PJSObject): jsval; static; {$ifdef HASINLINE}inline;{$endif}
 609    // SyNode extension (not present in original C++)
 610    class function Int64Value(v: Int64): jsval; static; {$ifdef HASINLINE}inline;{$endif}
 611  end;
 612
 613  /// an abstract array of jsval JavaScript values
 614  TjsvalVector = array[0..(MaxInt div sizeof(jsval))-3] of jsval;
 615  /// map an array of jsval JavaScript values
 616  PjsvalVector = ^TjsvalVector;
 617  TjsvalDynArray = array of jsval;
 618
 619  /// low-level definition of arguments of function
 620  // - do not use it dirrectly
 621  _JSArgRec = record
 622    case boolean of
 623      true: (
 624        calle: jsval;
 625        this: jsval;
 626        argv: jsval;
 627      );
 628      false: (rval: jsval);
 629  end;
 630
 631  /// hight-level definition of arguments of function
 632  {$ifdef USERECORDWITHMETHODS}JSArgRec = record
 633    {$else}JSArgRec = object{$endif}
 634  private
 635    rec: _JSArgRec;
 636    function GetIsConstructing: Boolean; {$ifdef HASINLINE}inline;{$endif}
 637    function getThis(cx: PJSContext): jsval; {$ifdef HASINLINE}inline;{$endif}
 638    function getThisObject(cx: PJSContext): PJSObject;
 639    function getArgv: PjsvalVector; {$ifdef HASINLINE}inline;{$endif}
 640    function getCalleObject: PJSObject; {$ifdef HASINLINE}inline;{$endif}
 641  public
 642  /// is function called as constructor
 643    property IsConstructing: Boolean read GetIsConstructing;
 644  /// function, that is called now
 645    property calle: jsval read rec.calle;
 646    property calleObject: PJSObject read getCalleObject;
 647  /// this value of function
 648    property this[cx: PJSContext]: jsval read getThis;
 649    property thisObject[cx: PJSContext]: PJSObject read getThisObject;
 650  /// arguments of function
 651    property argv: PjsvalVector read getArgv;
 652  /// return value of function
 653    property rval: jsval read rec.rval write rec.rval;
 654  end;
 655
 656//Todo - set correct codes for some sitautions
 657  JS_ObjectOpResult = object
 658    code: UIntPtr;
 659  end;
 660
 661// callback
 662  JSInterruptCallback = function(cx: PJSContext): Boolean; cdecl;
 663  /// callback prototype for returning an execution error
 664  JSErrorCallback = function(userRef: Pointer; const errorNumber: uintN): PJSErrorFormatString; cdecl;
 665  /// callback prototype for reporting error for a given runtime context
 666  JSWarningReporter = procedure(cx: PJSContext; report: PJSErrorReport); cdecl;
 667  JSStringFinalizerOp = procedure(fin: PJSStringFinalizer; chars: PCChar16);  cdecl;
 668
 669// Add or get a property named by id in obj.  Note the jsid id type -- id may
 670// be a string (Unicode property identifier) or an int (element index).  The
 671// *vp out parameter, on success, is the new property value after the action.
 672  JSAddPropertyOp = function(cx: PJSContext; var obj: PJSObject; var id: jsid;
 673    out vp: jsval): Boolean; cdecl;
 674// Delete a property named by id in obj.
 675// - If an error occurred, return false as per normal JSAPI error practice.
 676// - If no error occurred, but the deletion attempt wasn't allowed (perhaps
 677// because the property was non-configurable), set *succeeded to false and
 678// return true.  This will cause |delete obj[id]| to evaluate to false in
 679// non-strict mode code, and to throw a TypeError in strict mode code.
 680// - If no error occurred and the deletion wasn't disallowed (this is *not* the
 681// same as saying that a deletion actually occurred -- deleting a non-existent
 682// property, or an inherited property, is allowed -- it's just pointless),
 683// set *succeeded to true and return true.
 684  JSDeletePropertyOp = function(cx: PJSContext; var obj: PJSObject; var id: jsid;
 685    out res: JS_ObjectOpResult):Boolean; cdecl;
 686// Get a property named by id in obj.  Note the jsid id type -- id may
 687// be a string (Unicode property identifier) or an int (element index).  The
 688// *vp out parameter, on success, is the new property value after the action.
 689  JSGetterOp = function(cx: PJSContext; var obj: PJSObject; var id: jsid; out vp: jsval):Boolean; cdecl;
 690// Set a property named by id in obj, treating the assignment as strict
 691// mode code if strict is true. Note the jsid id type -- id may be a string
 692// (Unicode property identifier) or an int (element index). The *vp out
 693// parameter, on success, is the new property value after the
 694// set.
 695  JSSetterOp  = function(cx: PJSContext; var obj: PJSObject; var id: jsid;
 696    var vp: jsval; out res: JS_ObjectOpResult):Boolean; cdecl;
 697// The old-style JSClass.enumerate op should define all lazy properties not
 698// yet reflected in obj.
 699  JSEnumerateOp = function(cx: PJSContext; var obj: PJSObject): Boolean; cdecl;
 700// Resolve a lazy property named by id in obj by defining it directly in obj.
 701// Lazy properties are those reflected from some peer native property space
 702// (e.g., the DOM attributes for a given node reflected as obj) on demand.
 703// - JS looks for a property in an object, and if not found, tries to resolve
 704// the given id. *resolvedp should be set to true iff the property was
 705// was defined on |obj|.
 706  JSResolveOp = function(cx: PJSContext; var obj: PJSObject; var id: jsid; out resolved: Boolean): Boolean; cdecl;
 707// A class with a resolve hook can optionally have a mayResolve hook. This hook
 708// must have no side effects and must return true for a given id if the resolve
 709// hook may resolve this id. This is useful when we're doing a "pure" lookup: if
 710// mayResolve returns false, we know we don't have to call the effectful resolve
 711// hook.
 712//
 713// maybeObj, if non-null, is the object on which we're doing the lookup. This
 714// can be nullptr: during JIT compilation we sometimes know the Class but not
 715// the object.
 716  JSMayResolveOp = function(names: PJSAtomState; id: jsid; maybeObj: PJSObject): Boolean; cdecl;
 717  JSFinalizeOp = procedure(var fop: JSFreeOp; obj: PJSObject); cdecl;
 718// Check whether v is an instance of obj.  Return false on error or exception,
 719// true on success with true in *bp if v is an instance of obj, false in
 720// *bp otherwise.
 721  JSHasInstanceOp = function(cx: PJSContext; var obj: PJSObject; var vp: jsval; out b: Boolean): Boolean; cdecl;
 722// Typedef for native functions called by the JS VM.
 723  JSNative = function(cx: PJSContext; argc: uintN; var vp: JSArgRec): Boolean; cdecl;
 724// Function type for trace operation of the class called to enumerate all
 725// traceable things reachable from obj's private data structure. For each such
 726// thing, a trace implementation must call one of the JS_Call*Tracer variants
 727// on the thing.
 728//
 729// JSTraceOp implementation can assume that no other threads mutates object
 730// state. It must not change state of the object or corresponding native
 731// structures. The only exception for this rule is the case when the embedding
 732// needs a tight integration with GC. In that case the embedding can check if
 733// the traversal is a part of the marking phase through calling
 734// JS_IsGCMarkingTracer and apply a special code like emptying caches or
 735// marking its native structures.
 736  JSTraceOp = JSUnknown;
 737
 738/// Options of context
 739  JSContextOptions = object
 740  private
 741    function getOptions(const Index: Integer): Boolean;
 742    procedure setOptions(const Index: Integer; const Value: Boolean);
 743  public
 744    property Baseline: Boolean index 0 read getOptions write setOptions;
 745    property Ion: Boolean index 1 read getOptions write setOptions;
 746    property AsmJS: Boolean index 2 read getOptions write setOptions;
 747    property Wasm: Boolean index 3 read getOptions write setOptions;
 748    property WasmAlwaysBaseline: Boolean index 4 read getOptions write setOptions;
 749    property ThrowOnAsmJSValidationFailure: Boolean index 5 read getOptions write setOptions;
 750    property NativeRegExp: Boolean index 6 read getOptions write setOptions;
 751    property UnboxedArrays: Boolean index 7 read getOptions write setOptions;
 752    property AsyncStack: Boolean index 8 read getOptions write setOptions;
 753    property ThrowOnDebuggeeWouldRun: Boolean index 9 read getOptions write setOptions;
 754    property Werror: Boolean index 10 read getOptions write setOptions;
 755    property StrictMode: Boolean index 11 read getOptions write setOptions;
 756    property ExtraWarnings: Boolean index 12 read getOptions write setOptions;
 757  end;
 758  /// JavaScript execution context
 759  // - this object does not store anything, but just provide some helper methods
 760
 761  { JSContext }
 762
 763  JSContext = object
 764  private
 765    function GetPrivate: Pointer; {$ifdef HASINLINE}inline;{$endif}
 766    procedure SetPrivate(const Value: Pointer);{$ifdef HASINLINE}inline;{$endif}
 767    function GetEmptyString: PJSString; {$ifdef HASINLINE}inline;{$endif}
 768    function GetGCParameter(key: JSGCParamKey): uint32; {$ifdef HASINLINE}inline;{$endif}
 769    procedure SetGCParameter(key: JSGCParamKey; const Value: uint32); {$ifdef HASINLINE}inline;{$endif}
 770    function GetNowMs: int64; {$ifdef HASINLINE}inline;{$endif}
 771    function GetWarningReporter: JSWarningReporter; {$ifdef HASINLINE}inline;{$endif}
 772    procedure SetWarningReporter(reporter: JSWarningReporter); {$ifdef HASINLINE}inline;{$endif}
 773    function GetOptions: PJSContextOptions; {$ifdef HASINLINE}inline;{$endif}
 774    function GetIsRunning: boolean; {$ifdef HASINLINE}inline;{$endif}
 775  protected
 776    // Return the ArrayBuffer underlying an ArrayBufferView
 777    // - If the buffer has been neutered, this will still return the neutered buffer.
 778    // - obj must be an object that would return true for JS_IsArrayBufferViewObject()
 779    function GetArrayBufferViewBuffer(var obj: PJSObject; out isSharedMemory: Boolean): PJSObject; overload;{$ifdef HASINLINE}inline;{$endif}
 780    function GetArrayBufferViewBuffer(var obj: PJSObject): PJSObject; overload;{$ifdef HASINLINE}inline;{$endif}
 781  public
 782    /// Initializes the JavaScript context.
 783    class function CreateNew(maxbytes: uint32; maxNurseryBytes: uint32 = 16 * (1 SHL 20); parentContext: PJSContext = nil): PJSContext; static;
 784    /// Performs garbage collection in the JS memory pool.
 785    procedure GC; {$ifdef HASINLINE}inline;{$endif}
 786    /// Returns the empty string as a JSString object.
 787    property EmptyString: PJSString read GetEmptyString;
 788    /// Get/Set performance parameters related to garbage collection.
 789    property GCParameter[key: JSGCParamKey]: uint32 read GetGCParameter write SetGCParameter;
 790    /// Adjust performance parameters related to garbage collection based on available memory(in megabytes).
 791    procedure SetGCParametersBasedOnAvailableMemory(availMem: uint32);
 792    /// Microseconds since the epoch, midnight, January 1, 1970 UTC.
 793    property NowMs: int64 read GetNowMs;
 794    /// Request a callback set using JS_SetInterruptCallback
 795    procedure RequestInterruptCallback; {$ifdef HASINLINE}inline;{$endif}
 796    /// Set the size of the native stack that should not be exceed. To disable
 797    // stack size checking pass 0.
 798    // - SpiderMonkey allows for a distinction between system code (such as GCs, which
 799    // may incidentally be triggered by script but are not strictly performed on
 800    // behalf of such script), trusted script (as determined by JS_SetTrustedPrincipals),
 801    // and untrusted script. Each kind of code may have a different stack quota,
 802    // allowing embedders to keep higher-priority machinery running in the face of
 803    // scripted stack exhaustion by something else.
 804    // - The stack quotas for each kind of code should be monotonically descending,
 805    // and may be specified with this function. If 0 is passed for a given kind
 806    // of code, it defaults to the value of the next-highest-priority kind.
 807    // - This function may only be called immediately after the runtime is initialized
 808    // and before any code is executed and/or interrupts requested.
 809    procedure SetNativeStackQuota(systemCodeStackSize: size_t); {$ifdef HASINLINE}inline;{$endif}
 810    /// Get options of context
 811    property Options: PJSContextOptions read GetOptions;
 812    /// Get/Set the warning reporting mechanism for an application.
 813    property WarningReporter: JSWarningReporter read GetWarningReporter write SetWarningReporter;
 814    /// Add callback for interrupt
 815    procedure AddInterruptCallback(callback: JSInterruptCallback); {$ifdef HASINLINE}inline;{$endif}
 816    /// Disable interrupt callbacks call
 817    procedure DisableInterruptCallback; {$ifdef HASINLINE}inline;{$endif}
 818    /// Disable/enable interrupt callbacks call
 819    procedure ResetInterruptCallback(disable: boolean); {$ifdef HASINLINE}inline;{$endif}
 820    /// Call interrupt callback if it is requested
 821    function CheckForInterrupt: Boolean; {$ifdef HASINLINE}inline;{$endif}
 822    /// Read/Write access a JSContext field for application-specific data.
 823    // Memory management for this private data is the application's responsibility.
 824    // The JavaScript engine itself never uses it.
 825    property PrivateData: Pointer read GetPrivate write SetPrivate;
 826    /// Enter a different compartment on the given context, so that objects in that
 827    // compartment can be accessed.
 828    // - NB: This API is infallible; a NULL return value does not indicate error
 829    function EnterCompartment(target: PJSObject): PJSCompartment;{$ifdef HASINLINE}inline;{$endif}
 830    /// Leave a the compartment, returning to the compartment active before the
 831    // corresponding JS_EnterCompartment.
 832    procedure LeaveCompartment(oldCompartment: PJSCompartment);{$ifdef HASINLINE}inline;{$endif}
 833    /// indicates to the JS engine that the calling thread is entering a region
 834    // of code that may call into the JSAPI but does not block
 835    procedure BeginRequest; {$ifdef HASINLINE}inline;{$endif}
 836    /// indicates to the JS engine that the calling thread is leaving a region
 837    // of code that may call into the JSAPI but does not block
 838    procedure EndRequest; {$ifdef HASINLINE}inline;{$endif}
 839    /// Create Compile Options
 840    function NewCompileOptions: PJSCompileOptions;
 841    /// Free Compile Options
 842    procedure FreeCompileOptions(opt: PJSCompileOptions);
 843
 844    /// Create a new JavaScript object for use as a global object.
 845    function NewGlobalObject(clasp: PJSClass;
 846      hookOption: OnNewGlobalHookOption = DontFireOnNewGlobalHook): PJSObject;
 847    /// Initialize standard JS class constructors, prototypes, and any top-level
 848    // functions and constants associated with the standard classes (e.g. isNaN
 849    // for Number).
 850    // - NB: This sets cx's global object to obj if it was null.
 851    function InitStandardClasses(var obj: PJSObject): boolean;
 852    /// Add 'Reflect.parse', a SpiderMonkey extension, to the Reflect object on the
 853    // given global.
 854    function InitReflectParse(var obj: PJSObject): boolean;
 855    /// Initialize the 'ctypes' object on a global variable 'obj'. The 'ctypes'
 856    // object will be sealed.
 857    function InitCTypesClass(var obj: PJSObject): boolean;
 858    /// Initialize the 'Debugger' object on a global variable 'obj'. The 'ctypes'
 859    // object will be sealed.
 860    function DefineDebuggerObject(var obj: PJSObject): boolean;
 861    /// This function makes a cross-compartment wrapper for the given JS object.
 862    // Details see here http://stackoverflow.com/questions/18730477/what-does-js-wrapobject-do
 863    function WrapObject(var obj: PJSObject): boolean;
 864
 865    ///// modules support
 866
 867    /// Initialize modeles classes next 2 functions cannot work without calling this function
 868    function InitModuleClasses(var obj: PJSObject): boolean;
 869    /// Compile script as module
 870    function CompileModule(var obj: PJSObject; opts: PJSCompileOptions;
 871       chars: PCChar16; length: size_t): PJSObject;
 872    /// Set handler for module resolving
 873    procedure SetModuleResolveHook(var hook: PJSFunction);
 874
 875
 876    /// Invoke a constructor, like the JS expression `new ctor(...args)`. Returns
 877    // the new object, or null on error.
 878    function New(var ctor: PJSObject; argc: uintN; argv: PjsvalVector): PJSObject;{$ifdef HASINLINE}inline;{$endif}
 879    /// Create a new object based on a specified class and root it
 880    function NewObject(clasp: PJSClass): PJSObject;{$ifdef HASINLINE}inline;{$endif}
 881    /// Create a new object based on a specified class
 882    // - Unlike JS_NewObject, JS_NewObjectWithGivenProto does not compute a default
 883    // proto. If proto is nullptr, the JS object will have `null` as [[Prototype]].
 884    function NewObjectWithGivenProto(clasp: PJSClass; var proto: PJSObject): PJSObject;{$ifdef HASINLINE}inline;{$endif}
 885
 886    /// Create/Free rooted value(put value in rooting stack)
 887    // Garbage collection not performs to rooted values
 888    // - Warning!!! You must free rooted values in revers order for creating
 889    // that's why it's a bad idea store rooting values in any place except
 890    // local variables. Exception is root some values just after creating context
 891    // and unroot them (in reverse order) just before destroy context.
 892    // For other cases use reserved slots
 893    function NewRootedValue(val: jsval): PJSRootedValue; {$ifdef HASINLINE}inline;{$endif}
 894    procedure FreeRootedValue(str: PJSRootedValue);{$ifdef HASINLINE}inline;{$endif}
 895
 896    /// Create/Free rooted object(put object in rooting stack)
 897    // Garbage collection not performs to rooted objects
 898    // - Warning!!! You must free rooted objects in reverse order for creating
 899    // that's why it's a bad idea store rooting objects in any place except
 900    // local variables. Exception is root some objects just after creating context
 901    // and unroot them (in reverse order) just before destroy context.
 902    // For other cases use reserved slots
 903    function NewRootedObject(obj: PJSObject): PJSRootedObject; {$ifdef HASINLINE}inline;{$endif}
 904    procedure FreeRootedObject(obj: PJSRootedObject);{$ifdef HASINLINE}inline;{$endif}
 905
 906    /// Create/Free rooted string(put string in rooting stack)
 907    // Garbage collection not performs to rooted strings
 908    // - Warning!!! You must free rooted strings in reverse order for creating
 909    // that's why it's a bad idea store rooting strings in any place except
 910    // local variables. Exception is root some strings just after creating context
 911    // and unroot them (in reverse order) just before destroy context.
 912    // For other cases use reserved slots
 913    function NewRootedString(obj: PJSString): PJSRootedString; {$ifdef HASINLINE}inline;{$endif}
 914    procedure FreeRootedString(str: PJSRootedString);{$ifdef HASINLINE}inline;{$endif}
 915
 916    /// create a new JavaScript string instance
 917    function NewJSString(const Value: SynUnicode): PJSString; overload; {$ifdef HASINLINE}inline;{$endif}
 918    /// create a new JavaScript string from a RawUTF8
 919    // see https://gitlab.gnome.org/GNOME/gjs/commit/6fa31261e1131970f68aba63d977253118a5958a
 920    function NewJSString(const Value: RawUTF8): PJSString; overload; {$ifdef HASINLINE}inline;{$endif}
 921    function NewJSString(TextWide: PWideChar; TextLen: integer): PJSString; overload; {$ifdef HASINLINE}inline;{$endif}
 922    function NewJSString(TextAnsi: PAnsiChar; TextLen, CodePage: integer): PJSString; overload;
 923    function NewExternalString(const Value: SynUnicode): PJSString; {$ifdef HASINLINE}inline;{$endif}
 924    //function AtomizeAndPinString(const Value: SynUnicode): PJSString; {$ifdef HASINLINE}inline;{$endif}
 925
 926    /// create a new JavaScript Date object instance
 927    function NewDateObject(year, mon, mday, hour, min, sec: int32): PJSObject; {$ifdef HASINLINE}inline;{$endif}
 928    function NewDateObjectMsec(msec: double): PJSObject; {$ifdef HASINLINE}inline;{$endif}
 929
 930    /// create a new JavaScript Array object instance
 931    function NewArrayObject(length: size_t): PJSObject; overload; {$ifdef HASINLINE}inline;{$endif}
 932    function NewArrayObject(length: size_t; vector: PjsvalVector): PJSObject; overload; {$ifdef HASINLINE}inline;{$endif}
 933
 934    /// create a new JavaScript Function object instance
 935    function NewFunction(call: JSNative; nargs: uintN; flags: uintN; name: PCChar): PJSObject; {$ifdef HASINLINE}inline;{$endif}
 936
 937    /// Reports a memory allocation error
 938    // - Call JS_ReportOutOfMemory to report that an operation failed because the
 939    // system is out of memory
 940    // - When the JavaScript engine tries to allocate memory and allocation fails,
 941    // it reports an error as though by calling this function
 942    procedure ReportOutOfMemory;
 943    /// Create a new JavaScript Error object and set it to be the pending exception on cx.
 944    // The callback must then return JS_FALSE to cause the exception to be propagated
 945    // to the calling script.
 946    procedure ReportError(format: PCChar);
 947    /// Report an error with an application-defined error code.
 948    // - varargs is Additional arguments for the error message.
 949    //- These arguments must be of type jschar*
 950    // - The number of additional arguments required depends on the error
 951    // message, which is determined by the errorCallback
 952    procedure ReportErrorNumberUC(errorCallback: JSErrorCallback; userRef: pointer; const erroNubmer: uintN);
 953    /// Offer the JavaScript engine an opportunity to perform garbage collection if needed.
 954    procedure MaybeGC;
 955
 956    /// Get the current pending exception for a given JSContext.
 957    function GetPendingException(out rv: jsval): boolean; {$ifdef HASINLINE}inline;{$endif}
 958    /// Clear the currently pending exception in a context.
 959    procedure ClearPendingException; {$ifdef HASINLINE}inline;{$endif}
 960
 961    /// Convert a jsid to type JS::Value.
 962    function IdToValue(id: jsid; out v: jsval): Boolean; //~~~ write delphi realization
 963    /// Convert a JS::Value to type jsid.
 964    function ValueToId(var v: jsval; out id: jsid): Boolean; //~~~ write delphi realization
 965
 966    /// Determines the JS data type of a JS value.
 967    function TypeOfValue(v: jsval): JSType; {$ifdef HASINLINE}inline;{$endif} //~~~ write delphi realization
 968
 969    /// Compile and execute a script in the scope of the current global of cx.
 970    function EvaluateScript(opts: PJSCompileOptions;
 971       bytes: PCChar; length: size_t;
 972       out rval: jsval): Boolean; {$ifdef HASINLINE}inline;{$endif}
 973    function EvaluateUCScript(opts: PJSCompileOptions;
 974       chars: PCChar16; length: size_t;
 975       out rval: jsval): Boolean; {$ifdef HASINLINE}inline;{$endif}
 976
 977    /// Compile a script, source, for execution.
 978    function CompileScript(bytes: PCChar; length: size_t; opts: PJSCompileOptions;
 979      out script: PJSScript): boolean; {$ifdef HASINLINE}inline;{$endif}
 980    function CompileUCScript(chars: PCChar16; length: size_t; opts: PJSCompileOptions;
 981      out script: PJSScript): boolean; {$ifdef HASINLINE}inline;{$endif}
 982
 983    /// Evaluate a script in the scope of the current global of cx.
 984    function ExecuteScript(var script: PJSScript; out rval: jsval): Boolean; {$ifdef HASINLINE}inline;{$endif}
 985
 986    /// Return the global object for the active function on the context.
 987    // The global object is specific for a compartment
 988    function CurrentGlobalOrNull: PJSObject; {$ifdef HASINLINE}inline;{$endif}
 989
 990    //ArrayBuffer support
 991
 992    /// Create a new signed 8 bit integer typed array with nelements elements
 993    // - will fill the newly created array with zeros
 994    function NewInt8Array(nelements: uint32): PJSObject;{$ifdef HASINLINE}inline;{$endif}
 995
 996    /// Create a new unsigned 8 bit integer (byte) typed array with nelements elements
 997    // - will fill the newly created array with zeros
 998    function NewUint8Array(nelements: uint32): PJSObject;{$ifdef HASINLINE}inline;{$endif}
 999
1000    /// Create a new 8 bit integer typed array with nelements elements
1001    // - will fill the newly created array with zeros
1002    function NewUint8ClampedArray(nelements: uint32): PJSObject;{$ifdef HASINLINE}inline;{$endif}
1003
1004    /// Create a new signed 16 bit integer typed array with nelements elements
1005    // - will fill the newly created array with zeros
1006    function NewInt16Array(nelements: uint32): PJSObject;{$ifdef HASINLINE}inline;{$endif}
1007
1008    /// Create a new unsigned 16 bit integer typed array with nelements elements
1009    // - will fill the newly created array with zeros
1010    function NewUint16Array(nelements: uint32): PJSObject;{$ifdef HASINLINE}inline;{$endif}
1011
1012    /// Create a new signed 32 bit integer typed array with nelements elements
1013    // - will fill the newly created array with zeros
1014    function NewInt32Array(nelements: uint32): PJSObject;{$ifdef HASINLINE}inline;{$endif}
1015
1016    /// Create a new unsigned 32 bit integer typed array with nelements elements
1017    // - will fill the newly created array with zeros
1018    function NewUint32Array(nelements: uint32): PJSObject;{$ifdef HASINLINE}inline;{$endif}
1019
1020    /// Create a new signed 32 bit float (single) typed array with nelements elements
1021    // - will fill the newly created array with zeros
1022    function NewFloat32Array(nelements: uint32): PJSObject;{$ifdef HASINLINE}inline;{$endif}
1023
1024    /// Create a new signed 64 bit float (double) typed array with nelements elements
1025    // - will fill the newly created array with zeros
1026    function NewFloat64Array(nelements: uint32): PJSObject;{$ifdef HASINLINE}inline;{$endif}
1027
1028    /// Create a new 8 bit signed integer typed array and copy in values
1029    // from a given object
1030    // - The object is used as if it was an array; that is, the new array (if
1031    // successfully created) will have length given by array.length, and its
1032    // elements will be those specified by array[0], array[1], and so on, after
1033    // conversion to the typed array element type.
1034    function NewInt8ArrayFromArray(var arr: PJSObject): PJSObject;{$ifdef HASINLINE}inline;{$endif}
1035
1036    /// Create a new 8 bit unsigned integer typed array and copy in values
1037    // from a given object
1038    // - The object is used as if it was an array; that is, the new array (if
1039    // successfully created) will have length given by array.length, and its
1040    // elements will be those specified by array[0], array[1], and so on, after
1041    // conversion to the typed array element type.
1042    function NewUint8ArrayFromArray(var arr: PJSObject): PJSObject;{$ifdef HASINLINE}inline;{$endif}
1043
1044    /// Create a new 8 bit unsigned integer typed array and copy in values
1045    // from a given object
1046    // - The object is used as if it was an array; that is, the new array (if
1047    // successfully created) will have length given by array.length, and its
1048    // elements will be those specified by array[0], array[1], and so on, after
1049    // conversion to the typed array element type.
1050    function NewUint8ClampedArrayFromArray(var arr: PJSObject): PJSObject;{$ifdef HASINLINE}inline;{$endif}
1051
1052    /// Create a new 16 bit signed integer typed array and copy in values
1053    // from a given object
1054    // - The object is used as if it was an array; that is, the new array (if
1055    // successfully created) will have length given by array.length, and its
1056    // elements will be those specified by array[0], array[1], and so on, after
1057    // conversion to the typed array element type.
1058    function NewInt16ArrayFromArray(var arr: PJSObject): PJSObject;{$ifdef HASINLINE}inline;{$endif}
1059
1060    /// Create a new 16 bit unsigned integer typed array and copy in values
1061    // from a given object
1062    // - The object is used as if it was an array; that is, the new array (if
1063    // successfully created) will have length given by array.length, and its
1064    // elements will be those specified by array[0], array[1], and so on, after
1065    // conversion to the typed array element type.
1066    function NewUint16ArrayFromArray(var arr: PJSObject): PJSObject;{$ifdef HASINLINE}inline;{$endif}
1067
1068    /// Create a new 32 bit signed integer typed array and copy in values
1069    // from a given object
1070    // - The object is used as if it was an array; that is, the new array (if
1071    // successfully created) will have length given by array.length, and its
1072    // elements will be those specified by array[0], array[1], and so on, after
1073    // conversion to the typed array element type.
1074    function NewInt32ArrayFromArray(var arr: PJSObject): PJSObject;{$ifdef HASINLINE}inline;{$endif}
1075
1076    /// Create a new 32 bit unsigned integer typed array and copy in values
1077    // from a given object
1078    // - The object is used as if it was an array; that is, the new array (if
1079    // successfully created) will have length given by array.length, and its
1080    // elements will be those specified by array[0], array[1], and so on, after
1081    // conversion to the typed array element type.
1082    function NewUint32ArrayFromArray(var arr: PJSObject): PJSObject;{$ifdef HASINLINE}inline;{$endif}
1083
1084    /// Create a new 32 bit float (single) typed array and copy in values
1085    // from a given object
1086    // - The object is used as if it was an array; that is, the new array (if
1087    // successfully created) will have length given by array.length, and its
1088    // elements will be those specified by array[0], array[1], and so on, after
1089    // conversion to the typed array element type.
1090    function NewFloat32ArrayFromArray(var arr: PJSObject): PJSObject;{$ifdef HASINLINE}inline;{$endif}
1091
1092    /// Create a new 64 bit float (double) typed array and copy in values
1093    // from a given object
1094    // - The object is used as if it was an array; that is, the new array (if
1095    // successfully created) will have length given by array.length, and its
1096    // elements will be those specified by array[0], array[1], and so on, after
1097    // conversion to the typed array element type.
1098    function NewFloat64ArrayFromArray(var arr: PJSObject): PJSObject;{$ifdef HASINLINE}inline;{$endif}
1099
1100    /// Create a new 8 bit signed integer typed array using the given
1101    // ArrayBuffer for storage
1102    // - The length value is optional; if -1 is passed, enough elements to use up the
1103    // remainder of the byte array is used as the default value
1104    function NewInt8ArrayWithBuffer(var arrayBuffer: PJSObject;
1105      byteOffset: uint32; length: int32): PJSObject;{$ifdef HASINLINE}inline;{$endif}
1106
1107    /// Create a new 8 bit unsigned integer typed array using the given
1108    // ArrayBuffer for storage
1109    // - The length value is optional; if -1 is passed, enough elements to use up the
1110    // remainder of the byte array is used as the default value
1111    function NewUint8ArrayWithBuffer(var arrayBuffer: PJSObject;
1112      byteOffset: uint32; length: int32): PJSObject;{$ifdef HASINLINE}inline;{$endif}
1113
1114    /// Create a new 8 bit unsigned integer typed array using the given
1115    // ArrayBuffer for storage
1116    // - The length value is optional; if -1 is passed, enough elements to use up the
1117    // remainder of the byte array is used as the default value
1118    function NewUint8ClampedArrayWithBuffer(var arrayBuffer: PJSObject;
1119      byteOffset: uint32; length: int32): PJSObject;{$ifdef HASINLINE}inline;{$endif}
1120
1121    /// Create a new 16 bit signed integer typed array using the given
1122    // ArrayBuffer for storage
1123    // - The length value is optional; if -1 is passed, enough elements to use up the
1124    // remainder of the byte array is used as the default value
1125    function NewInt16ArrayWithBuffer(var arrayBuffer: PJSObject;
1126     byteOffset: uint32; length: int32): PJSObject;{$ifdef HASINLINE}inline;{$endif}
1127
1128    /// Create a new 16 bit unsigned integer typed array using the given
1129    // ArrayBuffer for storage
1130    // - The length value is optional; if -1 is passed, enough elements to use up the
1131    // remainder of the byte array is used as the default value
1132    function NewUint16ArrayWithBuffer(var arrayBuffer: PJSObject;
1133     byteOffset: uint32; length: int32): PJSObject;{$ifdef HASINLINE}inline;{$endif}
1134
1135    /// Create a new 32 bit signed integer typed array using the given
1136    // ArrayBuffer for storage
1137    // - The length value is optional; if -1 is passed, enough elements to use up the
1138    // remainder of the byte array is used as the default value
1139    function NewInt32ArrayWithBuffer(var arrayBuffer: PJSObject;
1140     byteOffset: uint32; length: int32): PJSObject;{$ifdef HASINLINE}inline;{$endif}
1141
1142    /// Create a new 32 bit unsigned integer typed array using the given
1143    // ArrayBuffer for storage
1144    // - The length value is optional; if -1 is passed, enough elements to use up the
1145    // remainder of the byte array is used as the default value
1146    function NewUint32ArrayWithBuffer(var arrayBuffer: PJSObject;
1147     byteOffset: uint32; length: int32): PJSObject;{$ifdef HASINLINE}inline;{$endif}
1148
1149    /// Create a new 32 bit float (single) typed array using the given
1150    // ArrayBuffer for storage
1151    // - The length value is optional; if -1 is passed, enough elements to use up the
1152    // remainder of the byte array is used as the default value
1153    function NewFloat32ArrayWithBuffer(var arrayBuffer: PJSObject;
1154     byteOffset: uint32; length: int32): PJSObject;{$ifdef HASINLINE}inline;{$endif}
1155
1156    /// Create a new 64 bit float (double) typed array using the given
1157    // ArrayBuffer for storage
1158    // - The length value is optional; if -1 is passed, enough elements to use up the
1159    // remainder of the byte array is used as the default value
1160    function NewFloat64ArrayWithBuffer(var arrayBuffer: PJSObject;
1161     byteOffset: uint32; length: int32): PJSObject; {$ifdef HASINLINE}inline;{$endif}
1162
1163    /// Create a new SharedArrayBuffer with the given byte length.
1164    function NewSharedArrayBuffer(nbytes: uint32): PJSObject;{$ifdef HASINLINE}inline;{$endif}
1165
1166    /// Create a new ArrayBuffer with the given byte length.
1167    function NewArrayBuffer(nbytes: uint32): PJSObject;{$ifdef HASINLINE}inline;{$endif}
1168
1169    /// Indicates whether or not a script or function is currently executing in a given context.
1170    property IsRunning: boolean read GetIsRunning;
1171    /// Destroy a JSContext.
1172    procedure Destroy;
1173  end;
1174
1175  /// JavaScript execution compartment
1176  // - this object does not store anything, but just provide some helper methods
1177  JSCompartment = object
1178  end;
1179  /// options of compartment
1180  JS_CompartmentOptions = record
1181    version: JSVersion;
1182    invisibleToDebugger: Boolean;
1183    mergeable: Boolean;
1184    discardSource: Boolean;
1185    disableLazyParsing_: Boolean;
1186    cloneSingletons: Boolean;
1187    extraWarningsOverride: JSUnknown;
1188    zone_: JSUnknown;
1189    traceGlobal: JSTraceOp;
1190    singletonsAsTemplates: Boolean;
1191    addonId: JSUnknown;
1192    preserveJitCode: Boolean;
1193  end;
1194
1195  /// JSObject is the type of JavaScript objects in the JSAPI
1196  // - this object does not store anything, but just provide some helper methods
1197  // to access a PJSObject value via low-level API functions
1198  {$ifdef USERECORDWITHMETHODS}JSObject = record
1199    {$else}JSObject = object{$endif}
1200  private
1201    function GetPrivate: Pointer; {$ifdef HASINLINE}inline;{$endif}
1202    procedure SetPrivate(data: Pointer); cdecl; {$ifdef HASINLINE}inline;{$endif}
1203    function GetReservedSlot(index: uint32): jsval; {$ifdef HASINLINE}inline;{$endif}
1204    procedure SetReservedSlot(index: uint32; v: jsval); {$ifdef HASINLINE}inline;{$endif}
1205    function GetClass: PJSClass; {$ifdef HASINLINE}inline;{$endif}
1206    function GetConstructor(cx: PJSContext): PJSObject; {$ifdef HASINLINE}inline;{$endif}
1207    // Return the available byte length of an array buffer
1208    // - obj must have passed a JS_IsArrayBufferObject test, or somehow be known
1209    // that it would pass such a test: it is an ArrayBuffer or a wrapper of an
1210    // ArrayBuffer, and the unwrapping will succeed
1211    function GetArrayBufferByteLength: uint32;{$ifdef HASINLINE}inline;{$endif}
1212    function GetSharedArrayBufferByteLength: uint32;{$ifdef HASINLINE}inline;{$endif}
1213    // Return a pointer to the start of the data referenced by any typed array
1214    // - The data is still owned by the typed array, and should not be modified on
1215    // another thread
1216    // - obj must have passed a JS_Is*Array test, or somehow be known that it would
1217    // pass such a test: it is a typed array or a wrapper of a typed array, and the
1218    // unwrapping will succeed
1219    // - Prefer the type-specific versions when possible
1220    function GetArrayBufferViewData(out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Pointer;{$ifdef HASINLINE}inline;{$endif}
1221  public
1222    /// get a jsval corresponding to this object
1223    function ToJSValue: jsval; {$ifdef HASINLINE}inline;{$endif}
1224
1225    /// Access the private data field of an object.
1226    property PrivateData: Pointer read GetPrivate write SetPrivate;
1227
1228    property Ctor[cx: PJSContext]: PJSObject read GetConstructor;
1229    /// Read access an object's reserved slots.
1230    property ReservedSlot[index: uint32]: jsval read GetReservedSlot write SetReservedSlot;
1231    /// Retrieves the class associated with an object.
1232    property Class_: PJSClass read GetClass;
1233
1234    /// JSAPI method equivalent to the instanceof operator in JavaScript.
1235    function HasInstance(cx: PJSContext; var val: jsval): Boolean;
1236
1237    /// is object is Date object
1238    function isDate(cx: PJSContext): Boolean; {$ifdef HASINLINE}inline;{$endif}
1239    /// is object is Function object
1240    function isFunction(cx: PJSContext): Boolean; {$ifdef HASINLINE}inline;{$endif}
1241    /// is object is Array object
1242    function isArray(cx: PJSContext): Boolean; {$ifdef HASINLINE}inline;{$endif}
1243
1244    /// Retrieve the private data associated with an object, if that object is an
1245    // instance of a specified class.
1246    function GetInstancePrivate(cx: PJSContext; clasp: PJSClass): Pointer; {$ifdef HASINLINE}inline;{$endif}
1247
1248    /// Create a new property on an object.
1249    function DefineProperty(cx: PJSContext; const name: PCChar;
1250        const value: jsval; attrs: uint32 = 0;
1251        getter: JSNative = nil; setter: JSNative = nil): boolean; {$ifdef HASINLINE}inline;{$endif}
1252    function DefineUCProperty(cx: PJSContext; const name: SynUnicode;
1253        const value: jsval; attrs: uint32 = 0;
1254        getter: JSNative = nil; setter: JSNative = nil): Boolean; overload; {$ifdef HASINLINE}inline;{$endif}
1255    function DefineUCProperty(cx: PJSContext; const name: PCChar16; namelen: size_t;
1256        const value: jsval; attrs: uint32 = 0;
1257        getter: JSNative = nil; setter: JSNative = nil): Boolean; overload; {$ifdef HASINLINE}inline;{$endif}
1258    function DefinePropertyById(cx: PJSContext; var id: jsid;
1259        const value: jsval; attrs: uint32 = 0;
1260        getter: JSNative = nil; setter: JSNative = nil): boolean; {$ifdef HASINLINE}inline;{$endif}
1261    /// Define multiple properties for a single object.
1262    // PJSPropertySpec must be null-terminated
1263    function DefineProperties(cx: PJSContext; ps: PJSPropertySpec): boolean; {$ifdef HASINLINE}inline;{$endif}
1264
1265    /// Find a specified property and retrieve its value.
1266    function GetPropValue(cx: PJSContext; const name: SynUnicode): jsval;{$ifdef HASINLINE}inline;{$endif}
1267    function GetProperty(cx: PJSContext; const name: PCChar; out vp: jsval): boolean; {$ifdef HASINLINE}inline;{$endif}
1268    function GetUCProperty(cx: PJSContext; const name: PCChar16; namelen: size_t; out vp: jsval): boolean; {$ifdef HASINLINE}inline;{$endif}
1269    function GetPropertyById(cx: PJSContext; const id: jsid; out vp: jsval): boolean; {$ifdef HASINLINE}inline;{$endif}
1270
1271    /// Assign a value to a property of an object.
1272    function SetProperty(cx: PJSContext; const name: PCChar; const vp: jsval): Boolean; {$ifdef HASINLINE}inline;{$endif}
1273    function SetUCProperty(cx: PJSContext; const name: PCChar16; namelen: size_t; const vp: jsval): boolean; {$ifdef HASINLINE}inline;{$endif}
1274
1275    /// Removes a specified property from an object.
1276    function DeletePropertyById(cx: PJSContext; const id: jsid;
1277      out res: JS_ObjectOpResult): Boolean; {$ifdef HASINLINE}inline;{$endif}
1278
1279    /// Determine whether a JavaScript object has a specified property.
1280    function HasProperty(cx: PJSContext; const name: PCChar): Boolean; {$ifdef HASINLINE}inline;{$endif}
1281    function HasUCProperty(cx: PJSContext; const name: PCChar16; namelen: size_t; out found: Boolean): Boolean; {$ifdef HASINLINE}inline;{$endif}
1282
1283    /// Determine whether a property is already physically present on a JSObject.
1284    function AlreadyHasOwnUCProperty(cx: PJSContext; const name: PCChar16; namelen: size_t): Boolean; {$ifdef HASINLINE}inline;{$endif}
1285
1286    /// Create a native function and assign it as a property to a specified JS object
1287    function DefineFunction(cx: PJSContext; name: PCChar;
1288        call: JSNative; nargs: uintN; attrs: uintN = 0): PJSFunction; {$ifdef HASINLINE}inline;{$endif}
1289    function DefineUCFunction(cx: PJSContext; name: PCChar16;
1290        namelen: size_t; call: JSNative; nargs: uintN; attrs: uintN = 0): PJSFunction; {$ifdef HASINLINE}inline;{$endif}
1291
1292    /// Create zero or more functions and makes them properties (methods)
1293    // of a specified object, obj, as if by calling JS_DefineFunction repeatedly
1294    function DefineFunctions(cx: PJSContext; fs: PJSFunctionSpec;
1295        behavior: JSPropertyDefinitionBehavior = DefineAllProperties): Boolean; {$ifdef HASINLINE}inline;{$endif}
1296
1297    /// Calls a specified JS function.
1298    // - Perform the method call `rval = obj[name](args)`.
1299    function RunMethod(cx: PJSContext; const name: PCChar;
1300      args: TjsvalDynArray; out rval: jsval): Boolean; overload; {$ifdef HASINLINE}inline;{$endif}
1301    function RunMethod(cx: PJSContext; const name: PCChar;
1302      arg: jsval; out rval: jsval): Boolean; overload; {$ifdef HASINLINE}inline;{$endif}
1303    function RunMethod(cx: PJSContext; const name: PCChar;
1304      out rval: jsval): Boolean; overload; {$ifdef HASINLINE}inline;{$endif}
1305    function CallFunction(cx: PJSContext; var fun: PJSFunction;
1306      argc: size_t; argv: PjsvalVector; out rval: jsval): Boolean; {$ifdef HASINLINE}inline;{$endif}
1307    function CallFunctionValue(cx: PJSContext; val: jsval;
1308      argc: size_t; argv: PjsvalVector; out rval: jsval): Boolean; {$ifdef HASINLINE}inline;{$endif}
1309    function CallFunctionName(cx: PJSContext; const name: PCChar;
1310      argc: size_t; argv: PjsvalVector; out rval: jsval): Boolean; {$ifdef HASINLINE}inline;{$endif}
1311
1312    /// Make a JSClass accessible to JavaScript code by creating its prototype,
1313    // constructor, properties, and functions.
1314    function InitClass(cx: PJSContext; var parent_proto: PJSObject;
1315      clasp: PJSClass; _constructor: JSNative; nargs: Cardinal;
1316      ps: PJSPropertySpec; fs: PJSFunctionSpec;
1317      static_ps: PJSPropertySpec; static_fs: PJSFunctionSpec): PJSObject; {$ifdef HASINLINE}inline;{$endif}
1318
1319    /// Get the prototype of obj, storing it in result.
1320    // - Implements: ES6 [[GetPrototypeOf]] internal method.
1321    function GetPrototype(cx: PJSContext; out protop: PJSObject): Boolean; {$ifdef HASINLINE}inline;{$endif}
1322    /// Change the prototype of obj.
1323    // - Implements: ES6 [[SetPrototypeOf]] internal method.
1324    // - In cases where ES6 [[SetPrototypeOf]] returns false without an exception,
1325    // JS_SetPrototype throws a TypeError and returns false.
1326    // - Performance warning: JS_SetPrototype is very bad for performance. It may
1327    // cause compiled jit-code to be invalidated. It also causes not only obj but
1328    // all other objects in the same "group" as obj to be permanently deoptimized.
1329    // It's better to create the object with the right prototype from the start.
1330    function SetPrototype(cx: PJSContext; var proto: PJSObject): Boolean; {$ifdef HASINLINE}inline;{$endif}
1331
1332    /// Get an array of the non-symbol enumerable properties of obj.
1333    // This function is roughly equivalent to:
1334    //
1335    //     var result = [];
1336    //     for (key in obj)
1337    //         result.push(key);
1338    //     return result;
1339    //
1340    // This is the closest thing we currently have to the ES6 [[Enumerate]]
1341    // internal method.
1342    function Enumerate(cx: PJSContext; out length: size_t;
1343      out data: PjsidVector): PJSIdArray;
1344
1345    //array methods
1346    function GetArrayLength(cx: PJSContext; out length: uint32): Boolean; {$ifdef HASINLINE}inline;{$endif}
1347    function GetElement(cx: PJSContext; index: uint32; out vp: jsval): Boolean; {$ifdef HASINLINE}inline;{$endif}
1348    function SetElement(cx: PJSContext; index: uint32; const vp: jsval): Boolean; {$ifdef HASINLINE}inline;{$endif}
1349    function DeleteElement(cx: PJSContext; index: uint32; out res: JS_ObjectOpResult): Boolean; {$ifdef HASINLINE}inline;{$endif}
1350
1351    //function methods
1352    function GetFunctionId: PJSString; {$ifdef HASINLINE}inline;{$endif}
1353    property FunctionId: PJSString read GetFunctionId;
1354    function DecompileFunction(cx: PJSContext; PrettyPrint: Boolean = true): PJSString;
1355
1356    //arrayBuffer methods
1357
1358    /// Check whether obj supports JS_GetTypedArray* APIs
1359    // - Note that this may return false if a security wrapper is encountered that
1360    // denies the unwrapping.
1361    // - if this test or one of the JS_Is*Array tests succeeds, then it is safe to call
1362    // the dedicated accessor JSAPI calls
1363    function IsTypedArrayObject: Boolean;{$ifdef HASINLINE}inline;{$endif}
1364
1365    /// Check whether obj supports JS_GetArrayBufferView* APIs
1366    // - Note that this may return false if a security wrapper is encountered that
1367    // denies the unwrapping.
1368    // - if this test or one of the JS_Is*Array tests succeeds, then it is safe to call
1369    // the dedicated ArrayBufferView accessor JSAPI calls
1370    function IsArrayBufferViewObject: Boolean;{$ifdef HASINLINE}inline;{$endif}
1371
1372    /// Test for specific 8 bit signed integer typed array types (ArrayBufferView subtypes)
1373    function IsInt8Array: Boolean;{$ifdef HASINLINE}inline;{$endif}
1374
1375    /// Test for specific 8 bit unsigned integer typed array types (ArrayBufferView subtypes)
1376    function IsUint8Array: Boolean;{$ifdef HASINLINE}inline;{$endif}
1377
1378    /// Test for specific 8 bit unsigned integer typed array types (ArrayBufferView subtypes)
1379    function IsUint8ClampedArray: Boolean;{$ifdef HASINLINE}inline;{$endif}
1380
1381    /// Test for specific 16 bit signed integer typed array types (ArrayBufferView subtypes)
1382    function IsInt16Array: Boolean;{$ifdef HASINLINE}inline;{$endif}
1383
1384    /// Test for specific 16 bit unsigned integer typed array types (ArrayBufferView subtypes)
1385    function IsUint16Array: Boolean;{$ifdef HASINLINE}inline;{$endif}
1386
1387    /// Test for specific 32 bit signed integer typed array types (ArrayBufferView subtypes)
1388    function IsInt32Array: Boolean;{$ifdef HASINLINE}inline;{$endif}
1389
1390    /// Test for specific 32 bit unsigned integer typed array types (ArrayBufferView subtypes)
1391    function IsUint32Array: Boolean;{$ifdef HASINLINE}inline;{$endif}
1392
1393    /// Test for specific 32 bit float (single) typed array types (ArrayBufferView subtypes)
1394    function IsFloat32Array: Boolean;{$ifdef HASINLINE}inline;{$endif}
1395
1396    /// Test for specific 64 bit float (double) typed array types (ArrayBufferView subtypes)
1397    function IsFloat64Array: Boolean;{$ifdef HASINLINE}inline;{$endif}
1398
1399    /// Return the isShared flag of a typed array, which denotes whether
1400    // the underlying buffer is a SharedArrayBuffer.
1401    //
1402    // |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow
1403    // be known that it would pass such a test: it is a typed array or a wrapper of
1404    // a typed array, and the unwrapping will succeed.
1405    function GetTypedArraySharedness: Boolean;{$ifdef HASINLINE}inline;{$endif}
1406
1407    /// Unwrap 8 bit signed integer typed array into direct memory buffer
1408    // - Return nil without throwing any exception if the object cannot be viewed as the
1409    // correct typed array, or the typed array object on success, filling both out parameters
1410    function GetObjectAsInt8Array(out length: uint32; out isSharedMemory:Boolean; out Data: Pint8Vector): PJSObject;{$ifdef HASINLINE}inline;{$endif}
1411
1412    /// Unwrap 8 bit unsigned integer typed array into direct memory buffer
1413    // - Return nil without throwing any exception if the object cannot be viewed as the
1414    // correct typed array, or the typed array object on success, filling both out parameters
1415    function GetObjectAsUint8Array(out length: uint32; out isSharedMemory:Boolean; out  Data: Puint8Vector): PJSObject;{$ifdef HASINLINE}inline;{$endif}
1416
1417    /// Unwrap 8 bit unsigned integer typed array into direct memory buffer
1418    // - Return nil without throwing any exception if the object cannot be viewed as the
1419    // correct typed array, or the typed array object on success, filling both out parameters
1420    function GetObjectAsUint8ClampedArray(out length: uint32; out isSharedMemory:Boolean; out  Data: Puint8Vector): PJSObject;{$ifdef HASINLINE}inline;{$endif}
1421
1422    /// Unwrap 16 bit signed integer typed array into direct memory buffer
1423    // - Return nil without throwing any exception if the object cannot be viewed as the
1424    // correct typed array, or the typed array object on success, filling both out parameters
1425    function GetObjectAsInt16Array(out length: uint32; out isSharedMemory:Boolean; out  Data: Pint16Vector): PJSObject;{$ifdef HASINLINE}inline;{$endif}
1426
1427    /// Unwrap 16 bit unsigned integer typed array into direct memory buffer
1428    // - Return nil without throwing any exception if the object cannot be viewed as the
1429    // correct typed array, or the typed array object on success, filling both out parameters
1430    function GetObjectAsUint16Array(out length: uint32; out isSharedMemory:Boolean; out  Data: Puint16Vector): PJSObject;{$ifdef HASINLINE}inline;{$endif}
1431
1432    /// Unwrap 32 bit signed integer typed array into direct memory buffer
1433    // - Return nil without throwing any exception if the object cannot be viewed as the
1434    // correct typed array, or the typed array object on success, filling both out parameters
1435    function GetObjectAsInt32Array(out length: uint32; out isSharedMemory:Boolean; out  Data: Pint32Vector): PJSObject;{$ifdef HASINLINE}inline;{$endif}
1436
1437    /// Unwrap 32 bit unsigned integer typed array into direct memory buffer
1438    // - Return nil without throwing any exception if the object cannot be viewed as the
1439    // correct typed array, or the typed array object on success, filling both out parameters
1440    function GetObjectAsUint32Array(out length: uint32; out isSharedMemory:Boolean; out  Data: Puint32Vector): PJSObject;{$ifdef HASINLINE}inline;{$endif}
1441
1442    /// Unwrap 32 bit float (single) typed array into direct memory buffer
1443    // - Return nil without throwing any exception if the object cannot be viewed as the
1444    // correct typed array, or the typed array object on success, filling both out parameters
1445    function GetObjectAsFloat32Array(out length: uint32; out isSharedMemory:Boolean; out  Data: Pfloat32Vector): PJSObject;{$ifdef HASINLINE}inline;{$endif}
1446
1447    /// Unwrap 64 bit float (double) typed array into direct memory buffer
1448    // - Return nil without throwing any exception if the object cannot be viewed as the
1449    // correct typed array, or the typed array object on success, filling both out parameters
1450    function GetObjectAsFloat64Array(out length: uint32; out isSharedMemory:Boolean; out  Data: Pfloat64Vector): PJSObject;{$ifdef HASINLINE}inline;{$endif}
1451
1452    /// Unwrap an object as its raw binary memory buffer
1453    // - Return nil without throwing any exception if the object cannot be viewed as the
1454    // correct typed array, or the typed array object on success, filling both out parameters
1455    function GetObjectAsArrayBufferView(out length: uint32; out isSharedMemory:Boolean; out  Data: Puint8Vector): PJSObject;{$ifdef HASINLINE}inline;{$endif}
1456
1457    /// Unwrap an object as its raw binary memory buffer
1458    // - Return nil without throwing any exception if the object cannot be viewed as the
1459    // correct typed array, or the typed array object on success, filling both out parameters
1460    function GetObjectAsArrayBuffer(out length: uint32; out Data: Puint8Vector): PJSObject;{$ifdef HASINLINE}inline;{$endif}
1461
1462    /// Get the type of elements in a typed array, or jsabTYPE_DATAVIEW if a DataView
1463    function GetArrayBufferViewType: JSArrayBufferViewType;{$ifdef HASINLINE}inline;{$endif}
1464
1465//    function GetSharedArrayBufferViewType: JSArrayBufferViewType;{$ifdef HASINLINE}inline;{$endif}
1466
1467    /// Check whether obj supports the JS_GetArrayBuffer* APIs
1468    // - Note that this may return false if a security wrapper is encountered that denies the
1469    // unwrapping
1470    // - If this test succeeds, then it is safe to call the various accessor JSAPI calls
1471    function IsArrayBufferObject: Boolean;{$ifdef HASINLINE}inline;{$endif}
1472
1473    function IsSharedArrayBufferObject: Boolean;
1474
1475    /// Return true if the arrayBuffer contains any data. This will return false for
1476    // ArrayBuffer.prototype and neutered ArrayBuffers.
1477    //
1478    // |obj| must have passed a JS_IsArrayBufferObject test, or somehow be known
1479    // that it would pass such a test: it is an ArrayBuffer or a wrapper of an
1480    // ArrayBuffer, and the unwrapping will succeed.
1481    function ArrayBufferHasData: Boolean;
1482
1483    /// Return a pointer to an array buffer's data
1484    // - The buffer is still owned by the array buffer object, and should not
1485    // be modified on another thread. The returned pointer is stable across GCs
1486    // - obj must have passed a JS_IsArrayBufferObject test, or somehow be known
1487    // that it would pass such a test: it is an ArrayBuffer or a wrapper of an
1488    // ArrayBuffer, and the unwrapping will succeed.
1489    function GetArrayBufferData(out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Puint8Vector; overload;{$ifdef HASINLINE}inline;{$endif}
1490    function GetArrayBufferData: Puint8Vector; overload;{$ifdef HASINLINE}inline;{$endif}
1491
1492    /// Check whether the obj is ArrayBufferObject and memory mapped. Note that this
1493    // may return false if a security wrapper is encountered that denies the
1494    // unwrapping.
1495    function IsMappedArrayBufferObject(obj: PJSObject): Boolean;{$ifdef HASINLINE}inline;{$endif}
1496
1497    /// Return the number of elements in a typed array
1498    // - obj must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow
1499    // be known that it would pass such a test: it is a typed array or a wrapper of
1500    // a typed array, and the unwrapping will succeed.
1501    function GetTypedArrayLength: uint32;{$ifdef HASINLINE}inline;{$endif}
1502
1503    /// Return the byte offset from the start of an array buffer to the start of a
1504    // typed array view
1505    // - obj must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow
1506    // be known that it would pass such a test: it is a typed array or a wrapper of
1507    // a typed array, and the unwrapping will succeed.
1508    function GetTypedArrayByteOffset: uint32;
1509
1510    /// Return the byte length of a typed array
1511    // - obj must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow
1512    // be known that it would pass such a test: it is a typed array or a wrapper of
1513    // a typed array, and the unwrapping will succeed
1514    function GetTypedArrayByteLength: uint32;{$ifdef HASINLINE}inline;{$endif}
1515
1516    /// More generic name for JS_GetTypedArrayByteLength to cover DataViews as well
1517    function GetArrayBufferViewByteLength: uint32;{$ifdef HASINLINE}inline;{$endif}
1518
1519    /// Return a pointer to the start of the data referenced by a typed 8 bit signed integer array
1520    // - The data is still owned by the typed array, and should not be modified on
1521    // another thread
1522    // - obj must have passed a JS_Is*Array test, or somehow be known that it would
1523    // pass such a test: it is a typed array or a wrapper of a typed array, and the
1524    // unwrapping will succeed
1525    function GetInt8ArrayData(out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Pint8Vector;{$ifdef HASINLINE}inline;{$endif}
1526
1527    /// Return a pointer to the start of the data referenced by a typed 8 bit unsigned integer array
1528    // - The data is still owned by the typed array, and should not be modified on
1529    // another thread
1530    // - obj must have passed a JS_Is*Array test, or somehow be known that it would
1531    // pass such a test: it is a typed array or a wrapper of a typed array, and the
1532    // unwrapping will succeed
1533    function GetUint8ArrayData(out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Puint8Vector; overload;{$ifdef HASINLINE}inline;{$endif}
1534    function GetUInt8ArrayData: Puint8Vector; overload;{$ifdef HASINLINE}inline;{$endif}
1535
1536    /// Return a pointer to the start of the data referenced by a typed 8 bit unsigned integer array
1537    // - The data is still owned by the typed array, and should not be modified on
1538    // another thread
1539    // - obj must have passed a JS_Is*Array test, or somehow be known that it would
1540    // pass such a test: it is a typed array or a wrapper of a typed array, and the
1541    // unwrapping will succeed
1542    function GetUint8ClampedArrayData(out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Puint8Vector;{$ifdef HASINLINE}inline;{$endif}
1543
1544    /// Return a pointer to the start of the data referenced by a typed 16 bit signed integer array
1545    // - The data is still owned by the typed array, and should not be modified on
1546    // another thread
1547    // - obj must have passed a JS_Is*Array test, or somehow be known that it would
1548    // pass such a test: it is a typed array or a wrapper of a typed array, and the
1549    // unwrapping will succeed
1550    function GetInt16ArrayData(out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Pint16Vector;{$ifdef HASINLINE}inline;{$endif}
1551
1552    /// Return a pointer to the start of the data referenced by a typed 16 bit unsigned integer array
1553    // - The data is still owned by the typed array, and should not be modified on
1554    // another thread
1555    // - obj must have passed a JS_Is*Array test, or somehow be known that it would
1556    // pass such a test: it is a typed array or a wrapper of a typed array, and the
1557    // unwrapping will succeed
1558    function GetUint16ArrayData(out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Puint16Vector;{$ifdef HASINLINE}inline;{$endif}
1559
1560    /// Return a pointer to the start of the data referenced by a typed 32 bit signed integer array
1561    // - The data is still owned by the typed array, and should not be modified on
1562    // another thread
1563    // - obj must have passed a JS_Is*Array test, or somehow be known that it would
1564    // pass such a test: it is a typed array or a wrapper of a typed array, and the
1565    // unwrapping will succeed
1566    function GetInt32ArrayData(out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Pint32Vector;{$ifdef HASINLINE}inline;{$endif}
1567
1568    /// Return a pointer to the start of the data referenced by a typed 32 bit unsigned integer array
1569    // - The data is still owned by the typed array, and should not be modified on
1570    // another thread
1571    // - obj must have passed a JS_Is*Array test, or somehow be known that it would
1572    // pass such a test: it is a typed array or a wrapper of a typed array, and the
1573    // unwrapping will succeed
1574    function GetUint32ArrayData(out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Puint32Vector;{$ifdef HASINLINE}inline;{$endif}
1575
1576    /// Return a pointer to the start of the data referenced by a typed 32 bit float (single) array
1577    // - The data is still owned by the typed array, and should not be modified on
1578    // another thread
1579    // - obj must have passed a JS_Is*Array test, or somehow be known that it would
1580    // pass such a test: it is a typed array or a wrapper of a typed array, and the
1581    // unwrapping will succeed
1582    function GetFloat32ArrayData(out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Pfloat32Vector;{$ifdef HASINLINE}inline;{$endif}
1583
1584    /// Return a pointer to the start of the data referenced by a typed 64 bit float (double) array
1585    // - The data is still owned by the typed array, and should not be modified on
1586    // another thread
1587    // - obj must have passed a JS_Is*Array test, or somehow be known that it would
1588    // pass such a test: it is a typed array or a wrapper of a typed array, and the
1589    // unwrapping will succeed
1590    function GetFloat64ArrayData(out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Pfloat64Vector;{$ifdef HASINLINE}inline;{$endif}
1591
1592    /// Return a pointer to the start of the data referenced by any typed array
1593    // and it's length. For ArrayBufferView return a pointer and length of slice.
1594    // - The data is still owned by the typed array, and should not be modified on
1595    // another thread
1596    // - If JSObject is not a typed array or arrayBufferView return false
1597    function GetBufferDataAndLength(out data: Puint8Vector; out len: uint32): boolean;{$ifdef HASINLINE}inline;{$endif}
1598  end;
1599
1600  JSString = object
1601    /// get the UTF-8 text corresponding to this string, for a given
1602    // runtime execution context
1603    function ToUTF8(cx: PJSContext): RawUTF8; overload;
1604    /// get the UTF-8 text corresponding to this string, for a given
1605    // runtime execution context
1606    // - slightly faster overloaded method (avoid string assignment)
1607    procedure ToUTF8(cx: PJSContext; out result: RawUTF8); overload;
1608    /// Add UTF-8 text corresponding to this string to writer,
1609    // without escaping
1610    procedure ToUTF8(cx: PJSContext; W: TTextWriter); overload;
1611
1612    /// get the Ansi text corresponding to this string
1613    // if source string containt non-ascii chars
1614    // convert it to Ansi using global CurrentAnsiConvert from SynCommons
1615    function ToAnsi(cx: PJSContext): AnsiString;
1616
1617    /// get the UTF-16 text corresponding to this string, for a given
1618    // runtime execution context
1619    function ToSynUnicode(cx: PJSContext): SynUnicode;
1620    function ToString(cx: PJSContext): string;
1621    procedure ToVariant(cx: PJSContext; var Value: Variant);
1622    procedure ToJSONString(cx: PJSContext; W: TTextWriter);
1623    /// get a jsval corresponding to this string
1624    function ToJSVal: jsval;
1625
1626    function HasLatin1Chars: Boolean;
1627    function Length: size_t;
1628
1629    function GetLatin1StringCharsAndLength(cx: PJSContext; out len: size_t):PCChar;
1630    function GetTwoByteStringCharsAndLength(cx: PJSContext; out len: size_t):PCChar16;
1631  end;
1632
1633  JSClassOps = record
1634    addProperty:        JSAddPropertyOp;
1635    delProperty:        JSDeletePropertyOp;
1636    getProperty:        JSGetterOp;
1637    setProperty:        JSSetterOp;
1638    enumerate:          JSEnumerateOp;
1639    resolve:            JSResolveOp;
1640    mayResolve:         JSMayResolveOp;
1641    finalize:           JSFinalizeOp;
1642    call:               JSNative;
1643    hasInstance:        JSHasInstanceOp;
1644    construct:          JSNative;
1645    trace:              JSTraceOp;
1646  end;
1647  PJSClassOps = ^JSClassOps;
1648
1649  JSClass =  record
1650    name:               PCChar;
1651    flags:              uint32;
1652    cOps:               PJSClassOps;
1653    reserved:           array [0..2] of pointer;
1654  end;
1655
1656  { JSCompileOptions }
1657  JSCompileOptions = object
1658    procedure SetFileLineAndUtf8(const fn: RawUTF8; l: cardinal; isUtf8: boolean);
1659  end;
1660
1661  // internal alignment of JSCompileOptions is a HACK and depends on C++ pragma
1662  // the only function we need is JSCompileOptions.SetFileLineAndUtf8
1663  //JSCompileOptions = record
1664  //  reserved: array[0..1] of Pointer;
1665  //  filename: PCChar;
1666  //
1667  //  introducerFilename_: PCChar;
1668  //  sourceMapURL_: PCChar16;
1669  //  version: JSVersion; //JSVersion version;
1670  //  versionSet: boolean; //bool versionSet;
1671  //  utf8: boolean; //bool utf8
1672  //  selfHostingMode: boolean; // bool selfHostingMode
1673  //  canLazilyParse: boolean; // bool canLazilyParse
1674  //  //strictOption: boolean;
1675  //  //extraWarningsOption: boolean;
1676  //  //werrorOption: boolean;
1677  //  //AsmJSOption asmJSOption;
1678  //  //bool throwOnAsmJSValidationFailureOption;
1679  //  //bool forceAsync;
1680  //  //bool installedFile;  // 'true' iff pre-compiling js file in packaged app
1681  //  //bool sourceIsLazy;
1682  //  reserved1: array[{$ifdef CPUX64}6{$else}7{$endif}..24] of Pointer;
1683  //end;
1684
1685  JSRootedValue = record
1686    Stack: JSUnknown;
1687    prev: JSUnknown;
1688    ptr: jsval;
1689  end;
1690  JSRootedObjectStack = record
1691    Last: PJSRootedObject;
1692  end;
1693  PJSRootedObjectStack = ^JSRootedObjectStack;
1694  JSRootedObject = record
1695    Stack: PJSRootedObjectStack;
1696    prev: PJSRootedObject;
1697    ptr: PJSObject;
1698  end;
1699
1700  JSRootedString = record
1701    Stack: JSUnknown;
1702    prev: JSUnknown;
1703    ptr: PJSString;
1704  end;
1705
1706  PJSJitInfo = JSUnknown;
1707  JSNativeWrapper = record
1708    op: JSNative;
1709    info: PJSJitInfo
1710  end;
1711  SelfHostedWrapper = record
1712    unused: Pointer;
1713    funname: PCChar;
1714  end;
1715  JSPropertySpecGetSetRec = record
1716    case Boolean of
1717    true: (native: JSNativeWrapper);
1718    false: (selfHosted: SelfHostedWrapper);
1719  end;
1720  JSPropertySpec = record
1721    name: PCChar;
1722    flags: uint8;
1723    getter: JSPropertySpecGetSetRec;
1724    setter: JSPropertySpecGetSetRec;
1725  end;
1726  TJSPropertySpecDynArray = array of JSPropertySpec;
1727
1728  JSFunctionSpec = record
1729    name: PCChar;
1730    call: JSNativeWrapper;
1731    nargs: uint16;
1732    flags: uint16;
1733    selfHostedName: PCChar;
1734  end;
1735  TJSFunctionSpecArray = array of JSFunctionSpec;
1736
1737  /// internal structure used to report JavaScript errors
1738  JSErrorReport = record
1739    /// The (default) error message.
1740    // If ownsMessage is true, the it is freed in destructor.
1741    message_: PUTF8Char;
1742    /// offending source line without final #13
1743    // If ownsLinebuf is true, the buffer is freed in destructor.
1744    linebuf: PCChar16;
1745    /// number of chars in linebuf_. Does not include trailing '\0'
1746    linebufLength: size_t;
1747    /// The 0-based offset of error token in linebuf_.
1748    tokenOffset: size_t;
1749    /// source file name, URL, etc., or null
1750    filename: PCChar;
1751    /// source line number
1752    lineno: uint32;
1753    /// zero-based column index in line
1754    column: uint32;
1755    /// error/warning, etc.
1756    flags: uint32;
1757    /// the error number, e.g. see js.msg
1758    errorNumber: uint32;
1759    /// One of the JSExnType constants
1760    exnType: JSExnType;
1761    /// See the comment in ReadOnlyCompileOptions.
1762    isMuted: Boolean;
1763    ownsLinebuf: Boolean;
1764    ownsMessage: Boolean;
1765  end;
1766
1767  /// used by JSErrorCallback() callback
1768  JSErrorFormatString = record
1769    /// The error message name in ASCII.
1770    name: PCChar;
1771    /// The error format string (UTF-8 if js_CStringsAreUTF8)
1772    format: PCChar;
1773    /// The number of arguments to expand in the formatted error message
1774    argCount: uint16;
1775    /// One of the JSExnType constants above
1776    exnType: JSExnType;
1777  end;
1778
1779/// * Finalizes external strings created by JS_NewExternalString.
1780  JSStringFinalizer = record
1781    finalize: JSStringFinalizerOp;
1782  end;
1783
1784const
1785  /// JSClass instance objects have private slot
1786  JSCLASS_HAS_PRIVATE             =   1 shl 0;
1787  /// JSClass instance class's initialization code will call
1788  // SetNewObjectMetadata itself
1789  JSCLASS_DELAY_METADATA_CALLBACK =   1 shl 1;
1790  /// JSClass instance private is (nsISupports*)
1791  JSCLASS_PRIVATE_IS_NSISUPPORTS =   1 shl 3;
1792  /// JSClass instance objects are DOM
1793  JSCLASS_IS_DOMJSCLASS          =   1 shl 4;
1794  /// JSClass instance objects of this class act like the value undefined,
1795  // in some contexts
1796  JSCLASS_EMULATES_UNDEFINED     =   1 shl 6;
1797  /// Reserved for embeddings.
1798  JSCLASS_USERBIT1               =   1 shl 7;
1799  /// JSClass instance room for 8 flags below
1800  JSCLASS_RESERVED_SLOTS_SHIFT   = 8;
1801  /// JSClass instance and 16 above this field
1802  JSCLASS_RESERVED_SLOTS_WIDTH   = 8;
1803
1804  JSCLASS_RESERVED_SLOTS_MASK    = (uint32(1) shl JSCLASS_RESERVED_SLOTS_WIDTH)-1;
1805  JSCLASS_HIGH_FLAGS_SHIFT       = (JSCLASS_RESERVED_SLOTS_SHIFT + JSCLASS_RESERVED_SLOTS_WIDTH);
1806
1807  JSCLASS_IS_ANONYMOUS           = (1 shl (JSCLASS_HIGH_FLAGS_SHIFT+0));
1808  JSCLASS_IS_GLOBAL              = (1 shl (JSCLASS_HIGH_FLAGS_SHIFT+1));
1809  JSCLASS_INTERNAL_FLAG2         = (1 shl (JSCLASS_HIGH_FLAGS_SHIFT+2));
1810  JSCLASS_INTERNAL_FLAG3         = (1 shl (JSCLASS_HIGH_FLAGS_SHIFT+3));
1811
1812  JSCLASS_IS_PROXY               = (1 shl (JSCLASS_HIGH_FLAGS_SHIFT+4));
1813
1814  JSCLASS_SKIP_NURSERY_FINALIZE  = (1 shl (JSCLASS_HIGH_FLAGS_SHIFT+5));
1815  // Reserved for embeddings.
1816  JSCLASS_USERBIT2               = (1 shl (JSCLASS_HIGH_FLAGS_SHIFT+6));
1817  JSCLASS_USERBIT3               = (1 shl (JSCLASS_HIGH_FLAGS_SHIFT+7));
1818
1819  JSCLASS_BACKGROUND_FINALIZE    = (1 shl (JSCLASS_HIGH_FLAGS_SHIFT+8));
1820  JSCLASS_FOREGROUND_FINALIZE    = (1 shl (JSCLASS_HIGH_FLAGS_SHIFT+9));
1821// Bits 26 through 31 are reserved for the CACHED_PROTO_KEY mechanism, see
1822// below.
1823
1824  JSCLASS_GLOBAL_APPLICATION_SLOTS = 5;
1825
1826//  JSProto_LIMIT = 46;
1827  JSCLASS_GLOBAL_SLOT_COUNT         = (JSCLASS_GLOBAL_APPLICATION_SLOTS + ord(JSProto_LIMIT) * 2 + 39);
1828
1829  JSCLASS_GLOBAL_FLAGS              = JSCLASS_IS_GLOBAL or
1830                                      (((JSCLASS_GLOBAL_SLOT_COUNT) and JSCLASS_RESERVED_SLOTS_MASK) shl JSCLASS_RESERVED_SLOTS_SHIFT);
1831
1832
1833/// Property attributes, set in JSPropertySpec and passed to API functions.
1834// NB: The data structure in which some of these values are stored only uses
1835//     a uint8_t to store the relevant information. Proceed with caution if
1836//     trying to reorder or change the the first byte worth of flags.
1837
1838  JSPROP_ENUMERATE        = $01; // property is visible to for/in loop
1839  JSPROP_READONLY         = $02; // not settable: assignment is no-op.
1840                                  //  This flag is only valid when neither
1841                                  //  JSPROP_GETTER nor JSPROP_SETTER is
1842                                  //  set.
1843  JSPROP_PERMANENT        = $04; // property cannot be deleted
1844  JSPROP_PROPOP_ACCESSORS = $08; // Passed to JS_Define(UC)Property* and
1845                                  //  JS_DefineElement if getters/setters
1846                                  //  are JSPropertyOp/JSStrictPropertyOp
1847  JSPROP_GETTER           = $10; // property holds getter function
1848  JSPROP_SETTER           = $20; // property holds setter function
1849  JSPROP_SHARED           = $40; // don't allocate a value slot for this
1850                                  // property; don't copy the property on
1851                                  // set of the same-named property in an
1852                                  // object that delegates to a prototype
1853                                  // containing this property
1854  JSPROP_INTERNAL_USE_BIT= $80; // name is actually (int) index
1855  JSPROP_DEFINE_LATE     = $100; // Don't define property when initially creating
1856                                  // the constructor. Some objects like Function/Object
1857                                  // have self-hosted functions that can only be defined
1858                                  // after the initialization is already finished.
1859  JSFUN_STUB_GSOPS       = $200; // use JS_PropertyStub getter/setter
1860                                  // instead of defaulting to class gsops
1861                                  // for property holding function
1862
1863  JSFUN_CONSTRUCTOR      = $400; // native that can be called as a ctor
1864  /// enumerable read-only property attributes
1865  JSPROPS_STATIC_RO      = JSPROP_ENUMERATE or JSPROP_READONLY or JSPROP_PERMANENT;
1866
1867  JSFUN_HAS_REST = $1000; // function has ...rest parameter.
1868
1869  JSPROP_REDEFINE_NONCONFIGURABLE = $1000; // If set, will allow redefining a
1870                                           // non-configurable property, but
1871                                           // only on a non-DOM global.  This
1872                                           // is a temporary hack that will
1873                                           // need to go away in bug
1874                                           // 1105518
1875
1876// Resolve hooks and enumerate hooks must pass this flag when calling
1877// JS_Define* APIs to reify lazily-defined properties.
1878// JSPROP_RESOLVING is used only with property-defining APIs. It tells the
1879// engine to skip the resolve hook when performing the lookup at the beginning
1880// of property definition. This keeps the resolve hook from accidentally
1881// triggering itself: unchecked recursion.
1882// For enumerate hooks, triggering the resolve hook would be merely silly, not
1883// fatal, except in some cases involving non-configurable properties.
1884  JSPROP_RESOLVING        = $2000;
1885
1886  JSPROP_IGNORE_ENUMERATE = $4000;  // ignore the value in JSPROP_ENUMERATE.
1887                                    // This flag only valid when defining over
1888                                    // an existing property.
1889  JSPROP_IGNORE_READONLY  = $8000;  // ignore the value in JSPROP_READONLY.
1890                                    // This flag only valid when defining over
1891                                    // an existing property.
1892  JSPROP_IGNORE_PERMANENT = $10000; // ignore the value in JSPROP_PERMANENT.
1893                                    // This flag only valid when defining over
1894                                    // an existing property.
1895  JSPROP_IGNORE_VALUE     = $20000; // ignore the Value in the descriptor. Nothing was
1896                                    // specified when passed to Object.defineProperty
1897                                    // from script.
1898
1899type
1900  /// available options for JS Objects Properties
1901  TJSPropertyAttr = (
1902    jspEnumerate, jspReadOnly, jspPermanent, jspPropAccessors, jspGetter,
1903    jspSetter, jspShared, jspInternal, jspDefineLate,
1904    jspFunStubGSOps, jspFunConstructor, jspFunGenericNative,
1905    jspRedefineNonConfigurable, jspResolving,
1906    jspIgnoreEnumerate, jspIgnoreReadOnly, jspIgnorePermanent, jspIgnoreValue);
1907  /// set of available options for JS Objects Properties
1908  TJSPropertyAttrs = set of TJSPropertyAttr;
1909
1910  ESMException = class(ESynException)
1911  private
1912    FJSErrorNum: integer;
1913    FFileName: RawUTF8;
1914    FLineNum: integer;
1915    FJSStackTrace: SynUnicode;
1916  public
1917    /// constructor which will create JavaScript exception with JS stack trace
1918    constructor CreateWithTrace(const AFileName: RawUTF8; AJSErrorNum, ALineNum: integer;
1919       AMessage: string; const AStackTrace: SynUnicode);
1920    /// Format a JS exception as text
1921    // If SM_DEBUG is defined will write full JS stack, including SyNode core_modules calls
1922    //  if not - core_modules is cutched from stack trace for simplicity
1923    procedure WriteFormatted(WR: TTextWriter);
1924
1925    {$ifndef NOEXCEPTIONINTERCEPT}
1926    /// Custmize SM exception log output
1927    function CustomLog(WR: TTextWriter; const Context: TSynLogExceptionContext): boolean; override;
1928    {$endif}
1929  published
1930    property ErrorNum: integer read FJSErrorNum;
1931    property Stack: SynUnicode read FJSStackTrace;
1932    property FileName: RawUTF8 read FFileName;
1933    property Line: integer read FLineNum;
1934  end;
1935
1936/// pass exception of this type to JSError for raising JS RangeError exception
1937  ESMRangeException = class(ESMException);
1938/// pass exception of this type to JSError for raising JS TypeError exception
1939  ESMTypeException = class(ESMException);
1940
1941/// to be used to catch Delphi exceptions inside JSNative function implementation
1942// - usage example:
1943// ! try
1944// !   doSomething()
1945// !   Result := True;
1946// ! except
1947// ! on E: Exception do begin
1948// !   JSError(cx, E);
1949// !   Result := False;
1950// ! end;
1951
1952procedure JSError(cx: PJSContext; aException: Exception);
1953procedure JSErrorUC(cx: PJSContext; aMessage: WideString; errorCode: integer = 0);
1954procedure JSRangeErrorUC(cx: PJSContext; aMessage: WideString);
1955procedure JSTypeErrorUC(cx: PJSContext; aMessage: WideString);
1956
1957// must be called ONCE per process before any interaction with JavaScript
1958function InitJS: Boolean;
1959// must be called ONCE per process after all engine managers are destroyed
1960procedure ShutDownJS;
1961
1962var
1963    nullObj: PJSObject = nil;
1964const
1965{$ifdef CPU64}
1966  JSVAL_TAG_SHIFT              = 47;
1967  JSVAL_PAYLOAD_MASK           = $00007FFFFFFFFFFF;
1968  JSVAL_TAG_MASK               = $FFFF800000000000;
1969
1970  JSVAL_TAG_MAX_DOUBLE                = UInt32($1FFF0);
1971  JSVAL_TAG_INT32                     = UInt32(JSVAL_TAG_MAX_DOUBLE or UInt8(JSVAL_TYPE_INT32));
1972  JSVAL_TAG_UNDEFINED                 = UInt32(JSVAL_TAG_MAX_DOUBLE or UInt8(JSVAL_TYPE_UNDEFINED));
1973  JSVAL_TAG_STRING                    = UInt32(JSVAL_TAG_MAX_DOUBLE or UInt8(JSVAL_TYPE_STRING));
1974  JSVAL_TAG_SYMBOL                    = UInt32(JSVAL_TAG_MAX_DOUBLE or UInt8(JSVAL_TYPE_SYMBOL));
1975  JSVAL_TAG_BOOLEAN                   = UInt32(JSVAL_TAG_MAX_DOUBLE or UInt8(JSVAL_TYPE_BOOLEAN));
1976  JSVAL_TAG_MAGIC                     = UInt32(JSVAL_TAG_MAX_DOUBLE or UInt8(JSVAL_TYPE_MAGIC));
1977  JSVAL_TAG_NULL                      = UInt32(JSVAL_TAG_MAX_DOUBLE or UInt8(JSVAL_TYPE_NULL));
1978  JSVAL_TAG_OBJECT                    = UInt32(JSVAL_TAG_MAX_DOUBLE or UInt8(JSVAL_TYPE_OBJECT));
1979
1980  JSVAL_SHIFTED_TAG_MAX_DOUBLE        = (uint64(JSVAL_TAG_MAX_DOUBLE) shl JSVAL_TAG_SHIFT) or $FFFFFFFF;
1981  JSVAL_SHIFTED_TAG_INT32             = uint64(JSVAL_TAG_INT32) shl JSVAL_TAG_SHIFT;
1982  JSVAL_SHIFTED_TAG_UNDEFINED         = uint64(JSVAL_TAG_UNDEFINED) shl JSVAL_TAG_SHIFT;
1983  JSVAL_SHIFTED_TAG_STRING            = uint64(JSVAL_TAG_STRING) shl JSVAL_TAG_SHIFT;
1984  JSVAL_SHIFTED_TAG_SYMBOL            = uint64(JSVAL_TAG_SYMBOL) shl JSVAL_TAG_SHIFT;
1985  JSVAL_SHIFTED_TAG_BOOLEAN           = uint64(JSVAL_TAG_BOOLEAN) shl JSVAL_TAG_SHIFT;
1986  JSVAL_SHIFTED_TAG_MAGIC             = uint64(JSVAL_TAG_MAGIC) shl JSVAL_TAG_SHIFT;
1987  JSVAL_SHIFTED_TAG_NULL              = uint64(JSVAL_TAG_NULL) shl JSVAL_TAG_SHIFT;
1988  JSVAL_SHIFTED_TAG_OBJECT            = uint64(JSVAL_TAG_OBJECT) shl JSVAL_TAG_SHIFT;
1989{$endif}
1990
1991{$ifdef CPU64}
1992  JSVAL_NULL_impl =  QWord(JSVAL_SHIFTED_TAG_NULL);
1993  JSVAL_VOID_impl =  QWord(JSVAL_SHIFTED_TAG_UNDEFINED);
1994{$ELSE}
1995  JSVAL_NULL_impl =  QWord(QWord(JSVAL_TAG_NULL     ) shl 32) or 0;
1996  JSVAL_VOID_impl =  QWord(QWord(JSVAL_TAG_UNDEFINED) shl 32) or 0;
1997{$endif}
1998
1999  JSVAL_NAN_impl  =  $7FF8000000000000;
2000
2001const
2002  JSVAL_NULL: jsval = (_l:(asBits: JSVAL_NULL_impl));
2003  JSVAL_VOID: jsval = (_l:(asBits: JSVAL_VOID_impl));
2004  JSVAL_NAN:  jsval = (_l:(asBits: JSVAL_NAN_impl));
2005
2006const
2007  JSREPORT_ERROR = 0;
2008  JSREPORT_WARNING = 1;
2009  JSREPORT_EXCEPTION = 2;
2010  JSREPORT_STRICT = 4;
2011  JSREPORT_STRICT_MODE_ERROR = 8;
2012
2013function SimpleVariantToJSval(cx: PJSContext; val: Variant): jsval;
2014
2015const
2016  SpiderMonkeyLib = 'synsm'{$IFDEF MSWINDOWS} + '.dll'{$ENDIF};
2017
2018type
2019  TModuleHandle = HINST;
2020const
2021  INVALID_MODULEHANDLE_VALUE = TModuleHandle(0);
2022var
2023  SM52Lib: TModuleHandle = INVALID_MODULEHANDLE_VALUE;
2024
2025 /// Initialize SpiderMonkey, returning true only if initialization succeeded.
2026 // Once this method has succeeded, it is safe to call JS_NewRuntime and other
2027 // JSAPI methods.
2028 // - This method must be called before any other JSAPI method is used on any
2029 // thread.  Once it has been used, it is safe to call any JSAPI method, and it
2030 // remains safe to do so until JS_ShutDown is correctly called.
2031 // - It is currently not possible to initialize SpiderMonkey multiple times (that
2032 // is, calling JS_Init/JSAPI methods/JS_ShutDown in that order, then doing so
2033 // again).  This restriction may eventually be lifted.
2034type TJS_Initialize = function : Boolean; cdecl;
2035var JS_Init: TJS_Initialize{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_Initialize'; {$ENDIF}
2036
2037procedure JS_DisableExtraThreads; cdecl;
2038  external SpiderMonkeyLib name 'SM_DisableExtraThreads';
2039
2040 /// Destroy free-standing resources allocated by SpiderMonkey, not associated
2041 // with any runtime, context, or other structure.
2042 // - This method should be called after all other JSAPI data has been properly
2043 // cleaned up: every new runtime must have been destroyed, every new context
2044 // must have been destroyed, and so on.  Calling this method before all other
2045 // resources have been destroyed has undefined behavior.
2046 // - Failure to call this method, at present, has no adverse effects other than
2047 // leaking memory.  This may not always be the case; it's recommended that all
2048 // embedders call this method when all other JSAPI operations have completed.
2049 // - It is currently not possible to initialize SpiderMonkey multiple times (that
2050 // is, calling JS_Init/JSAPI methods/JS_ShutDown in that order, then doing so
2051 // again).  This restriction may eventually be lifted.
2052type TJS_ShutDown = procedure; cdecl;
2053var JS_ShutDown: TJS_ShutDown{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_ShutDown'; {$ENDIF}
2054
2055/// Microseconds since the epoch, midnight, January 1, 1970 UTC.
2056type TJS_Now = function : int64; cdecl;
2057var JS_Now: TJS_Now{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_Now'; {$ENDIF}
2058
2059/// Returns the empty string as a JSString object.
2060type TJS_GetEmptyString = function (cx: PJSContext): PJSString; cdecl;
2061var JS_GetEmptyString: TJS_GetEmptyString{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetEmptyString'; {$ENDIF}
2062
2063/// Determines the JS data type of a JS value.
2064type TJS_TypeOfValue = function (cx: PJSContext; var v: jsval): JSType; cdecl;
2065var JS_TypeOfValue: TJS_TypeOfValue{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_TypeOfValue'; {$ENDIF}
2066
2067/// indicates to the JS engine that the calling thread is entering a region
2068// of code that may call into the JSAPI but does not block
2069type TJS_BeginRequest = procedure (cx: PJSContext); cdecl;
2070var JS_BeginRequest: TJS_BeginRequest{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_BeginRequest'; {$ENDIF}
2071
2072/// indicates to the JS engine that the calling thread is leaving a region
2073// of code that may call into the JSAPI but does not block
2074type TJS_EndRequest = procedure (cx: PJSContext); cdecl;
2075var JS_EndRequest: TJS_EndRequest{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_EndRequest'; {$ENDIF}
2076
2077/// Create a new JSContext
2078type TJS_NewContext = function (maxbytes: uint32;
2079  maxNurseryBytes: uint32 = 16 * (1 SHL 20);
2080  parentContext: PJSContext = nil): PJSContext; cdecl;
2081var JS_NewContext: TJS_NewContext{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewContext'; {$ENDIF}
2082
2083type TInitSelfHostedCode = function (cx: PJSContext): boolean; cdecl;
2084var InitSelfHostedCode: TInitSelfHostedCode{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_InitSelfHostedCode'; {$ENDIF}
2085
2086/// Destroy a JSContext.
2087type TJS_DestroyContext = procedure (cx: PJSContext); cdecl;
2088var JS_DestroyContext: TJS_DestroyContext{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_DestroyContext'; {$ENDIF}
2089
2090/// Read access a JSContext field for application-specific data.
2091// Memory management for this private data is the application's responsibility.
2092// The JavaScript engine itself never uses it.
2093type TJS_GetContextPrivate = function (cx: PJSContext): Pointer; cdecl;
2094var JS_GetContextPrivate: TJS_GetContextPrivate{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetContextPrivate'; {$ENDIF}
2095
2096/// Write access a JSContext field for application-specific data.
2097// Memory management for this private data is the application's responsibility.
2098// The JavaScript engine itself never uses it.
2099type TJS_SetContextPrivate = procedure (cx: PJSContext; data: Pointer); cdecl;
2100var JS_SetContextPrivate: TJS_SetContextPrivate{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_SetContextPrivate'; {$ENDIF}
2101
2102/// This function makes a cross-compartment wrapper for the given JS object.
2103// Details see here http://stackoverflow.com/questions/18730477/what-does-js-wrapobject-do
2104type TJS_WrapObject = function (cx: PJSContext; var obj: PJSObject): boolean; cdecl;
2105var JS_WrapObject: TJS_WrapObject{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_WrapObject'; {$ENDIF}
2106
2107/// Enter a different compartment on the given context, so that objects in that
2108// compartment can be accessed.
2109// - NB: This API is infallible; a NULL return value does not indicate error
2110type TJS_EnterCompartment = function (cx: PJSContext; target: PJSObject): PJSCompartment; cdecl;
2111var JS_EnterCompartment: TJS_EnterCompartment{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_EnterCompartment'; {$ENDIF}
2112
2113/// Leave a the compartment, returning to the compartment active before the
2114// corresponding JS_EnterCompartment.
2115type TJS_LeaveCompartment = procedure (cx: PJSContext; oldCompartment: PJSCompartment); cdecl;
2116var JS_LeaveCompartment: TJS_LeaveCompartment{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_LeaveCompartment'; {$ENDIF}
2117
2118/// Initialize standard JS class constructors, prototypes, and any top-level
2119// functions and constants associated with the standard classes (e.g. isNaN
2120// for Number).
2121// - NB: This sets cx's global object to obj if it was null.
2122type TJS_InitStandardClasses = function (cx: PJSContext; var obj: PJSObject): boolean; cdecl;
2123var JS_InitStandardClasses: TJS_InitStandardClasses{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_InitStandardClasses'; {$ENDIF}
2124
2125///Return the global object for the active function on the context.
2126type TJS_CurrentGlobalOrNull = function (cx: PJSContext):PJSObject; cdecl;
2127var JS_CurrentGlobalOrNull: TJS_CurrentGlobalOrNull{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_CurrentGlobalOrNull'; {$ENDIF}
2128
2129/// Add 'Reflect.parse', a SpiderMonkey extension, to the Reflect object on the
2130// given global.
2131type TJS_InitReflectParse = function (cx: PJSContext; var obj: PJSObject): boolean; cdecl;
2132var JS_InitReflectParse: TJS_InitReflectParse{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_InitReflectParse'; {$ENDIF}
2133
2134/// Initialize the 'ctypes' object on a global variable 'obj'. The 'ctypes'
2135// object will be sealed.
2136type TJS_InitCTypesClass = function (cx: PJSContext; var obj: PJSObject): boolean; cdecl;
2137var JS_InitCTypesClass: TJS_InitCTypesClass{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_InitCTypesClass'; {$ENDIF}
2138
2139/// Initialize the 'Debugger' object on a global variable 'obj'. The 'ctypes'
2140// object will be sealed.
2141type TJS_DefineDebuggerObject = function (cx: PJSContext; var obj: PJSObject): boolean; cdecl;
2142var JS_DefineDebuggerObject: TJS_DefineDebuggerObject{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_DefineDebuggerObject'; {$ENDIF}
2143
2144/// Performs garbage collection in the JS memory pool.
2145type TJS_GC = procedure (cx: PJSContext); cdecl;
2146var JS_GC: TJS_GC{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GC'; {$ENDIF}
2147
2148/// Offer the JavaScript engine an opportunity to perform garbage collection if needed.
2149type TJS_MaybeGC = procedure (cx: PJSContext); cdecl;
2150var JS_MaybeGC: TJS_MaybeGC{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_MaybeGC'; {$ENDIF}
2151
2152///Set performance parameters related to garbage collection.
2153type TJS_SetGCParameter = procedure (cx: PJSContext; key: JSGCParamKey; value: uint32); cdecl;
2154var JS_SetGCParameter: TJS_SetGCParameter{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_SetGCParameter'; {$ENDIF}
2155
2156///Get performance parameters related to garbage collection.
2157type TJS_GetGCParameter = function (cx: PJSContext; key: JSGCParamKey): uint32; cdecl;
2158var JS_GetGCParameter: TJS_GetGCParameter{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetGCParameter'; {$ENDIF}
2159
2160///Adjust performance parameters related to garbage collection based on available memory(in megabytes).
2161type TJS_SetGCParametersBasedOnAvailableMemory = procedure (cx: PJSContext; availMem: uint32); cdecl;
2162var JS_SetGCParametersBasedOnAvailableMemory: TJS_SetGCParametersBasedOnAvailableMemory{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_SetGCParametersBasedOnAvailableMemory'; {$ENDIF}
2163
2164/// Creates a new JSString whose characters are stored in external memory, i.e.,
2165//  memory allocated by the application, not the JavaScript engine
2166// - Since the program allocated the memory, it will need to free it;
2167//  this happens in an external string finalizer indicated by the type parameter.
2168// - chars is Pointer to the first element of an array of jschars.
2169//  This array is used as the character buffer of the JSString to be created.
2170//  The array must be populated with the desired character data before JS_NewExternalString
2171//  is called, and the array must remain in memory, with its contents unchanged,
2172//  for as long as the JavaScript engine needs to hold on to it.
2173// (Ultimately, the string will be garbage collected, and the JavaScript engine will
2174// call the string finalizer callback, allowing the application to free the array)
2175//  - The text buffer array does not need to be zero-terminated.
2176type TJS_NewExternalString = function (cx: PJSContext; chars: PCChar16; length: size_t;
2177  fin: PJSStringFinalizer): PJSString; cdecl;
2178var JS_NewExternalString: TJS_NewExternalString{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewExternalString'; {$ENDIF}
2179
2180/// Set the size of the native stack that should not be exceed. To disable
2181// stack size checking pass 0.
2182// - SpiderMonkey allows for a distinction between system code (such as GCs, which
2183// may incidentally be triggered by script but are not strictly performed on
2184// behalf of such script), trusted script (as determined by JS_SetTrustedPrincipals),
2185// and untrusted script. Each kind of code may have a different stack quota,
2186// allowing embedders to keep higher-priority machinery running in the face of
2187// scripted stack exhaustion by something else.
2188// - The stack quotas for each kind of code should be monotonically descending,
2189// and may be specified with this function. If 0 is passed for a given kind
2190// of code, it defaults to the value of the next-highest-priority kind.
2191// - This function may only be called immediately after the runtime is initialized
2192// and before any code is executed and/or interrupts requested.
2193type TJS_SetNativeStackQuota = procedure (cx: PJSContext; systemCodeStackSize: size_t;
2194  trustedScriptStackSize: size_t = 0; untrustedScriptStackSize: size_t = 0); cdecl;
2195var JS_SetNativeStackQuota: TJS_SetNativeStackQuota{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_SetNativeStackQuota'; {$ENDIF}
2196
2197/// Convert a JS::Value to type jsid.
2198type TJS_ValueToId = function (cx: PJSContext; var v: jsval; out id: jsid): Boolean; cdecl;
2199var JS_ValueToId: TJS_ValueToId{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_ValueToId'; {$ENDIF}
2200
2201/// Convert a jsid to type JS::Value.
2202type TJS_IdToValue = function (cx: PJSContext; id: jsid; out v: jsval): Boolean; cdecl;
2203var JS_IdToValue: TJS_IdToValue{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_IdToValue'; {$ENDIF}
2204
2205type TJS_ValueToSource = function (cx: PJSContext; var v: jsval): PJSString; cdecl;
2206var JS_ValueToSource: TJS_ValueToSource{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_ValueToSource'; {$ENDIF}
2207
2208/// Make a JSClass accessible to JavaScript code by creating its prototype,
2209// constructor, properties, and functions.
2210type TJS_InitClass = function (cx: PJSContext; var obj: PJSObject; var parent_proto: PJSObject;
2211  clasp: PJSClass; _constructor: JSNative; nargs: uintN;
2212  ps: PJSPropertySpec; fs: PJSFunctionSpec;
2213  static_ps: PJSPropertySpec; static_fs: PJSFunctionSpec): PJSObject; cdecl;
2214var JS_InitClass: TJS_InitClass{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_InitClass'; {$ENDIF}
2215
2216/// Retrieves the class associated with an object.
2217type TJS_GetClass = function (obj: PJSObject): PJSClass; cdecl;
2218var JS_GetClass: TJS_GetClass{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetClass'; {$ENDIF}
2219
2220/// JSAPI method equivalent to the instanceof operator in JavaScript.
2221type TJS_HasInstance = function (cx: PJSContext; var obj: PJSObject;
2222  var val: jsval; out res: Boolean): Boolean; cdecl;
2223var JS_HasInstance: TJS_HasInstance{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_HasInstance'; {$ENDIF}
2224
2225/// Access the private data field of an object.
2226type TJS_GetPrivate = function (obj: PJSObject): Pointer; cdecl;
2227var JS_GetPrivate: TJS_GetPrivate{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetPrivate'; {$ENDIF}
2228
2229/// Sets the private data field of an object.
2230type TJS_SetPrivate = procedure (obj: PJSObject; data: Pointer); cdecl;
2231var JS_SetPrivate: TJS_SetPrivate{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_SetPrivate'; {$ENDIF}
2232
2233/// Retrieves the constructor for an object.
2234type TJS_GetConstructor = function (cx: PJSContext; var proto: PJSObject): PJSObject; cdecl;
2235var JS_GetConstructor: TJS_GetConstructor{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetConstructor'; {$ENDIF}
2236
2237/// Retrieve the private data associated with an object, if that object is an
2238// instance of a specified class.
2239type TJS_GetInstancePrivate = function (cx: PJSContext; var obj: PJSObject;
2240  clasp: PJSClass; args: JSUnknown): Pointer; cdecl;
2241var JS_GetInstancePrivate: TJS_GetInstancePrivate{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetInstancePrivate'; {$ENDIF}
2242
2243/// Create a new JavaScript object for use as a global object.
2244type TJS_NewGlobalObject = function (cx: PJSContext; clasp: PJSClass; principals: PJSPrincipals;
2245  hookOption: OnNewGlobalHookOption; options: PJS_CompartmentOptions): PJSObject; cdecl;
2246var JS_NewGlobalObject: TJS_NewGlobalObject{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewGlobalObject'; {$ENDIF}
2247
2248/// Spidermonkey does not have a good way of keeping track of what compartments should be marked on
2249/// their own. We can mark the roots unconditionally, but marking GC things only relevant in live
2250/// compartments is hard. To mitigate this, we create a static trace hook, installed on each global
2251/// object, from which we can be sure the compartment is relevant, and mark it.
2252///
2253/// It is still possible to specify custom trace hooks for global object classes. They can be
2254/// provided via the CompartmentOptions passed to JS_NewGlobalObject.
2255type TJS_GlobalObjectTraceHook = procedure (trc: Pointer{ JSTracer }; global: PJSObject); cdecl;
2256var JS_GlobalObjectTraceHook: TJS_GlobalObjectTraceHook{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GlobalObjectTraceHook'; {$ENDIF}
2257
2258/// Create a new object based on a specified class
2259type TJS_NewObject = function (cx: PJSContext; clasp: PJSClass): PJSObject; cdecl;
2260var JS_NewObject: TJS_NewObject{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewObject'; {$ENDIF}
2261
2262/// Create a new object based on a specified class
2263// - Unlike JS_NewObject, JS_NewObjectWithGivenProto does not compute a default
2264// proto. If proto is nullptr, the JS object will have `null` as [[Prototype]].
2265type TJS_NewObjectWithGivenProto = function (cx: PJSContext; clasp: PJSClass;
2266  var proto: PJSObject): PJSObject; cdecl;
2267var JS_NewObjectWithGivenProto: TJS_NewObjectWithGivenProto{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewObjectWithGivenProto'; {$ENDIF}
2268
2269/// Get the prototype of obj, storing it in result.
2270// - Implements: ES6 [[GetPrototypeOf]] internal method.
2271type TJS_GetPrototype = function (cx: PJSContext; var obj: PJSObject;
2272  out result: PJSObject):Boolean; cdecl;
2273var JS_GetPrototype: TJS_GetPrototype{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetPrototype'; {$ENDIF}
2274
2275/// Change the prototype of obj.
2276// - Implements: ES6 [[SetPrototypeOf]] internal method.
2277// - In cases where ES6 [[SetPrototypeOf]] returns false without an exception,
2278// JS_SetPrototype throws a TypeError and returns false.
2279// - Performance warning: JS_SetPrototype is very bad for performance. It may
2280// cause compiled jit-code to be invalidated. It also causes not only obj but
2281// all other objects in the same "group" as obj to be permanently deoptimized.
2282// It's better to create the object with the right prototype from the start.
2283type TJS_SetPrototype = function (cx: PJSContext; var obj: PJSObject;
2284  var proto: PJSObject):Boolean; cdecl;
2285var JS_SetPrototype: TJS_SetPrototype{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_SetPrototype'; {$ENDIF}
2286
2287/// Create a new property on an object.
2288// Name indentifies by ID
2289type TJS_DefinePropertyById = function (cx: PJSContext; var obj: PJSObject;
2290  var id: jsid; var value: jsval; attrs: uint32; getter: JSNative;
2291  setter: JSNative): boolean; cdecl;
2292var JS_DefinePropertyById: TJS_DefinePropertyById{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_DefinePropertyById'; {$ENDIF}
2293
2294/// Create a new property on an object.
2295// Name indentifies by ansi string
2296type TJS_DefineProperty = function (cx: PJSContext; var obj: PJSObject;
2297  const name: PCChar; var value: jsval; attrs: uint32; getter: JSNative;
2298  setter: JSNative): boolean; cdecl;
2299var JS_DefineProperty: TJS_DefineProperty{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_DefineProperty'; {$ENDIF}
2300
2301/// Create a new property on an object.
2302// Name indentifies by unicode string
2303type TJS_DefineUCProperty = function (cx: PJSContext; var obj: PJSObject;
2304  const name: PCChar16; namelen: size_t; var value: jsval; attrs: uint32;
2305  getter: JSNative; setter: JSNative): Boolean; cdecl;
2306var JS_DefineUCProperty: TJS_DefineUCProperty{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_DefineUCProperty'; {$ENDIF}
2307
2308/// Determine whether a JavaScript object has a specified property.
2309// Name indentifies by ansi string
2310type TJS_HasProperty = function (cx: PJSContext; var obj: PJSObject;
2311  const name: PCChar; var found: Boolean): Boolean; cdecl;
2312var JS_HasProperty: TJS_HasProperty{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_HasProperty'; {$ENDIF}
2313
2314/// Determine whether a JavaScript object has a specified property.
2315// Name indentifies by unicode string
2316type TJS_HasUCProperty = function (cx: PJSContext; var obj: PJSObject;
2317  const name: PCChar16; namelen: size_t; var found: Boolean): Boolean; cdecl;
2318var JS_HasUCProperty: TJS_HasUCProperty{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_HasUCProperty'; {$ENDIF}
2319
2320/// Find a specified property and retrieve its value.
2321// Name indentifies by ID
2322type TJS_GetPropertyById = function (cx: PJSContext; var obj: PJSObject;
2323  var id: jsid; out vp: jsval): boolean; cdecl;
2324var JS_GetPropertyById: TJS_GetPropertyById{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetPropertyById'; {$ENDIF}
2325
2326/// Find a specified property and retrieve its value.
2327// Name indentifies by ansi string
2328type TJS_GetProperty = function (cx: PJSContext; var obj: PJSObject;
2329  const name: PCChar; out vp: jsval): boolean; cdecl;
2330var JS_GetProperty: TJS_GetProperty{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetProperty'; {$ENDIF}
2331
2332/// Find a specified property and retrieve its value.
2333// Name indentifies by unicode string
2334type TJS_GetUCProperty = function (cx: PJSContext; var obj: PJSObject;
2335  const name: PCChar16; namelen: size_t; out vp: jsval): boolean; cdecl;
2336var JS_GetUCProperty: TJS_GetUCProperty{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetUCProperty'; {$ENDIF}
2337
2338/// Find a specified numeric property of an object and return its current value.
2339type TJS_GetElement = function (cx: PJSContext; var obj: PJSObject; index: uint32;
2340  out vp: jsval): Boolean; cdecl;
2341var JS_GetElement: TJS_GetElement{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetElement'; {$ENDIF}
2342
2343/// Assign a value to a property of an object.
2344// Name indentifies by ansi string
2345type TJS_SetProperty = function (cx: PJSContext; var obj: PJSObject;
2346  const name: PCChar; var vp: jsval): Boolean; cdecl;
2347var JS_SetProperty: TJS_SetProperty{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_SetProperty'; {$ENDIF}
2348
2349/// Assign a value to a property of an object.
2350// Name indentifies by unicode string
2351type TJS_SetUCProperty = function (cx: PJSContext; var obj: PJSObject;
2352  const name: PCChar16; namelen: size_t; var vp: jsval): boolean; cdecl;
2353var JS_SetUCProperty: TJS_SetUCProperty{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_SetUCProperty'; {$ENDIF}
2354
2355/// Assign a value to a numeric property of an object.
2356type TJS_SetElement = function (cx: PJSContext; var obj: PJSObject; index: uint32;
2357  var vp: jsval): Boolean; cdecl;
2358var JS_SetElement: TJS_SetElement{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_SetElement'; {$ENDIF}
2359
2360/// Removes a specified property from an object.
2361// Name indentifies by ID
2362type TJS_DeletePropertyById = function (cx: PJSContext; var obj: PJSObject;
2363  var id: jsid; out res: JS_ObjectOpResult): Boolean; cdecl;
2364var JS_DeletePropertyById: tJS_DeletePropertyById{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_DeletePropertyById'; {$ENDIF}
2365
2366/// Removes a specified element or numeric property from an object.
2367type TJS_DeleteElement = function (cx: PJSContext; var obj: PJSObject;
2368  index: uint32; out res: JS_ObjectOpResult): Boolean; cdecl;
2369var JS_DeleteElement: TJS_DeleteElement{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_DeleteElement'; {$ENDIF}
2370
2371/// Get an array of the non-symbol enumerable properties of obj.
2372// This function is roughly equivalent to:
2373//
2374//     var result = [];
2375//     for (key in obj)
2376//         result.push(key);
2377//     return result;
2378//
2379// This is the closest thing we currently have to the ES6 [[Enumerate]]
2380// internal method.
2381//
2382// The JSIdArray returned is rooted to protect its
2383// contents from garbage collection.
2384function JS_EnumerateToAutoIdVector(cx: PJSContext; var obj: PJSObject;
2385  out length: size_t; out data: PjsidVector): PJSIdArray;
2386  cdecl; external SpiderMonkeyLib name 'SM_EnumerateToAutoIdVector';
2387
2388procedure JS_DestroyAutoIdVector(v: PJSIdArray);
2389  cdecl; external SpiderMonkeyLib name 'SM_DestroyAutoIdVector';
2390
2391type
2392  JSHandleValueArray = record
2393    length: size_t;
2394    elements_: PjsvalVector;
2395  end;
2396
2397/// Calls a specified JS function.
2398// Function identifies by jsvalue
2399// - equivalent of `rval = Reflect.apply(fun, obj, args)`.
2400type TJS_CallFunctionValue = function (cx: PJSContext; var obj: PJSObject;
2401  var val: jsval; var args: JSHandleValueArray; out rval: jsval): Boolean; cdecl;
2402var JS_CallFunctionValue: TJS_CallFunctionValue{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_CallFunctionValue'; {$ENDIF}
2403
2404/// Calls a specified JS function.
2405// Function identifies by PJSFunction
2406type TJS_CallFunction = function (cx: PJSContext; var obj: PJSObject;
2407  var fun: PJSFunction; var args: JSHandleValueArray; out rval: jsval): Boolean; cdecl;
2408var JS_CallFunction: TJS_CallFunction{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_CallFunction'; {$ENDIF}
2409
2410/// Calls a specified JS function.
2411// Function identifies by ansi string
2412// - Perform the method call `rval = obj[name](args)`.
2413type TJS_CallFunctionName = function (cx: PJSContext; var obj: PJSObject;
2414  const name: PCChar; var args: JSHandleValueArray; out rval: jsval): Boolean; cdecl;
2415var JS_CallFunctionName: TJS_CallFunctionName{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_CallFunctionName'; {$ENDIF}
2416
2417/// Invoke a constructor, like the JS expression `new ctor(...args)`. Returns
2418// the new object, or null on error.
2419type TJS_New = function (cx: PJSContext; var ctor: PJSObject;
2420  var args: JSHandleValueArray): PJSObject; cdecl;
2421var JS_New: TJS_New{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_New'; {$ENDIF}
2422
2423/// Define multiple properties for a single object.
2424type TJS_DefineProperties = function (cx: PJSContext; var obj: PJSObject;
2425  ps: PJSPropertySpec): boolean; cdecl;
2426var JS_DefineProperties: TJS_DefineProperties{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_DefineProperties'; {$ENDIF}
2427
2428/// Determine whether a property is already physically present on a JSObject.
2429// Name indentifies by unicode string
2430type TJS_AlreadyHasOwnUCProperty = function (cx: PJSContext; var obj: PJSObject;
2431    const name: PCChar16; namelen: size_t; var foundp: Boolean): Boolean; cdecl;
2432var JS_AlreadyHasOwnUCProperty: TJS_AlreadyHasOwnUCProperty{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_AlreadyHasOwnUCProperty'; {$ENDIF}
2433
2434/// Create a new Array object.
2435// Only length passed
2436type TJS_NewArrayObject = function (cx: PJSContext; length: size_t): PJSObject; cdecl;
2437var JS_NewArrayObject: TJS_NewArrayObject{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewArrayObject'; {$ENDIF}
2438
2439/// Create a new Array object.
2440// Content passed
2441type TJS_NewArrayObject2 = function (cx: PJSContext;
2442    const contents: JSHandleValueArray): PJSObject; cdecl;
2443var JS_NewArrayObject2: TJS_NewArrayObject2{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewArrayObject2'; {$ENDIF}
2444
2445/// Returns true and sets |*isArray| indicating whether |obj| is an Array object
2446// or a wrapper around one, otherwise returns false on failure.
2447// - This method returns true with |*isArray == false| when passed a proxy whose
2448// target is an Array, or when passed a revoked proxy.
2449type TJS_IsArrayObject = function (cx: PJSContext; var obj: PJSObject;
2450    out isArray: Boolean): boolean; cdecl;
2451var JS_IsArrayObject: TJS_IsArrayObject{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_IsArrayObject'; {$ENDIF}
2452
2453/// JS_GetArrayLength gets the .length property of obj as though by calling JS_GetProperty
2454// and converts it to a 32-bit unsigned integer. If obj is an array (see JS_IsArrayObject),
2455// this is guaranteed to succeed, because the .length property of an array is always a number
2456// and can't be deleted or redefined.
2457// - On success, JS_GetArrayLength stores the length in *lengthp and returns true.
2458// On failure, it reports an error and returns false, and the value left in *lengthp
2459// is undefined.
2460type TJS_GetArrayLength = function (cx: PJSContext; var obj: PJSObject;
2461  out length: uint32): Boolean; cdecl;
2462var JS_GetArrayLength: TJS_GetArrayLength{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetArrayLength'; {$ENDIF}
2463
2464/// Read access an object's reserved slots.
2465function JS_GetReservedSlot(obj: PJSObject; index: uint32): Int64; cdecl;
2466  external SpiderMonkeyLib name 'SM_GetReservedSlot';
2467
2468/// Write access an object's reserved slots
2469type TJS_SetReservedSlot = procedure (obj: PJSObject; index: uint32;
2470  var v: jsval); cdecl;
2471var JS_SetReservedSlot: TJS_SetReservedSlot{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_SetReservedSlot'; {$ENDIF}
2472
2473/// Create a new JavaScript function that is implemented as a JSNative.
2474type TJS_NewFunction = function (cx: PJSContext; call: JSNative; nargs: uintN;
2475  flags: uintN; name: PCChar): PJSObject; cdecl;
2476var JS_NewFunction: TJS_NewFunction{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewFunction'; {$ENDIF}
2477
2478/// Return the function's identifier as a JSString, or null if fun is unnamed.
2479// The returned string lives as long as fun, so you don't need to root a saved
2480// reference to it if fun is well-connected or rooted, and provided you bound
2481// the use of the saved reference by fun's lifetime.
2482type TJS_GetFunctionId = function (fun: PJSFunction): PJSString; cdecl;
2483var JS_GetFunctionId: TJS_GetFunctionId{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetFunctionId'; {$ENDIF}
2484
2485/// Infallible predicate to test whether obj is a function object (faster than
2486// comparing obj's class name to "Function", but equivalent unless someone has
2487// overwritten the "Function" identifier with a different constructor and then
2488// created instances using that constructor that might be passed in as obj).
2489type TJS_ObjectIsFunction = function (cx: PJSContext; obj: PJSObject): boolean; cdecl;
2490var JS_ObjectIsFunction: TJS_ObjectIsFunction{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_ObjectIsFunction'; {$ENDIF}
2491
2492/// Create zero or more functions and makes them properties (methods)
2493// of a specified object, obj, as if by calling JS_DefineFunction repeatedly
2494type TJS_DefineFunctions = function (cx: PJSContext; var obj: PJSObject;
2495  fs: PJSFunctionSpec; behavior: JSPropertyDefinitionBehavior): Boolean; cdecl;
2496var JS_DefineFunctions: TJS_DefineFunctions{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_DefineFunctions'; {$ENDIF}
2497
2498/// Create a native function and assign it as a property to a specified JS object
2499type TJS_DefineFunction = function (cx: PJSContext; var obj: PJSObject; name: PCChar;
2500    call: JSNative; nargs: uintN; attrs: uintN): PJSFunction; cdecl;
2501var JS_DefineFunction: TJS_DefineFunction{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_DefineFunction'; {$ENDIF}
2502
2503/// Unicode version to create a native function
2504type TJS_DefineUCFunction = function (cx: PJSContext; var obj: PJSObject;
2505    name: PCChar16; namelen: size_t; call: JSNative; nargs: uintN;
2506    attrs: uintN): PJSFunction; cdecl;
2507var JS_DefineUCFunction: TJS_DefineUCFunction{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_DefineUCFunction'; {$ENDIF}
2508
2509/// Compile a script, source, for execution.
2510// Ansi version
2511type TJS_CompileScript = function (cx: PJSContext; bytes: PCChar; length: size_t;
2512  options: PJSCompileOptions; out script: PJSScript): boolean; cdecl;
2513var JS_CompileScript: TJS_CompileScript{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_CompileScript'; {$ENDIF}
2514
2515/// Compile a script, source, for execution.
2516// Unicode version
2517type TJS_CompileUCScript = function (cx: PJSContext; chars: PCChar16;
2518  length: size_t; options: PJSCompileOptions; out script: PJSScript): boolean; cdecl;
2519var JS_CompileUCScript: TJS_CompileUCScript{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_CompileUCScript'; {$ENDIF}
2520
2521/// Generate the complete source code of a function declaration from a compiled function
2522type TJS_DecompileFunction = function (cx: PJSContext; var fun: PJSFunction;
2523  indent: uintN): PJSString; cdecl;
2524var JS_DecompileFunction: TJS_DecompileFunction{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_DecompileFunction'; {$ENDIF}
2525
2526/// Evaluate a script in the scope of the current global of cx.
2527type TJS_ExecuteScript = function (cx: PJSContext; var script: PJSScript;
2528  out rval: jsval): Boolean; cdecl;
2529var JS_ExecuteScript: TJS_ExecuteScript{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_ExecuteScript'; {$ENDIF}
2530
2531/// These functions allow setting an interrupt callback that will be called
2532// from the JS thread some time after any thread triggered the callback using
2533// JS_RequestInterruptCallback(cx).
2534// - To schedule the GC and for other activities the engine internally triggers
2535// interrupt callbacks. The embedding should thus not rely on callbacks being
2536//triggered through the external API only.
2537// - Important note: Additional callbacks can occur inside the callback handler
2538// if it re-enters the JS engine. The embedding must ensure that the callback
2539// is disconnected before attempting such re-entry.
2540type TJS_CheckForInterrupt = function (cx: PJSContext): Boolean; cdecl;
2541var JS_CheckForInterrupt: TJS_CheckForInterrupt{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_CheckForInterrupt'; {$ENDIF}
2542
2543type TJS_AddInterruptCallback = function (cx: PJSContext;
2544  callback: JSInterruptCallback): Boolean; cdecl;
2545var JS_AddInterruptCallback: TJS_AddInterruptCallback{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_AddInterruptCallback'; {$ENDIF}
2546
2547type TJS_DisableInterruptCallback = function (cx: PJSContext): Boolean; cdecl;
2548var JS_DisableInterruptCallback: TJS_DisableInterruptCallback{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_DisableInterruptCallback'; {$ENDIF}
2549
2550type TJS_ResetInterruptCallback = procedure (cx: PJSContext;
2551  enable: Boolean); cdecl;
2552var JS_ResetInterruptCallback: TJS_ResetInterruptCallback{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_ResetInterruptCallback'; {$ENDIF}
2553
2554/// Request a callback set using JS_SetInterruptCallback
2555type TJS_RequestInterruptCallback = procedure (cx: PJSContext); cdecl;
2556var JS_RequestInterruptCallback: TJS_RequestInterruptCallback{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_RequestInterruptCallback'; {$ENDIF}
2557
2558/// Indicates whether or not a script or function is currently executing in a given context.
2559type TJS_IsRunning = function (cx: PJSContext): Boolean; cdecl;
2560var JS_IsRunning: TJS_IsRunning{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_IsRunning'; {$ENDIF}
2561
2562/// Allocate space for a JavaScript string and its underlying storage,
2563// and copy n characters from a character array, s, into the new JSString
2564// Ansi version
2565type TJS_NewStringCopyN = function (cx: PJSContext; s: PCChar;
2566  n: size_t): PJSString; cdecl;
2567var JS_NewStringCopyN: TJS_NewStringCopyN{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewStringCopyN'; {$ENDIF}
2568
2569// TODO - recompile libsynsm with exported SM_AtomizeAndPinStringN
2570//type TJS_AtomizeAndPinStringN = function (cx: PJSContext; s: PCChar;
2571//  n: size_t): PJSString; cdecl;
2572//var JS_AtomizeAndPinStringN: TJS_AtomizeAndPinStringN external SpiderMonkeyLib name 'SM_AtomizeAndPinStringN';
2573
2574
2575/// Allocate space for a JavaScript string and its underlying storage,
2576// and copy characters from NULL TERMINATED! UTF8 character array
2577type TJS_NewStringCopyUTF8Z = function (cx: PJSContext;
2578  pNullTerminatedUTF8: PUTF8Char): PJSString; cdecl;
2579var JS_NewStringCopyUTF8Z: TJS_NewStringCopyUTF8Z{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewStringCopyUTF8Z'; {$ENDIF}
2580
2581
2582/// Returns the empty JSString as a JS value
2583type TJS_GetEmptyStringValue = function (cx: PJSContext): jsval; cdecl;
2584var JS_GetEmptyStringValue: TJS_GetEmptyStringValue{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetEmptyStringValue'; {$ENDIF}
2585
2586/// Allocate space for a JavaScript string and its underlying storage,
2587// and copy n characters from a character array, s, into the new JSString
2588// Unicode version
2589type TJS_NewUCStringCopyN = function (cx: PJSContext; s: PCChar16;
2590  n: size_t): PJSString; cdecl;
2591var JS_NewUCStringCopyN: TJS_NewUCStringCopyN{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewUCStringCopyN'; {$ENDIF}
2592
2593/// Return the length of a JavaScript string.
2594type TJS_GetStringLength = function (str: PJSString): size_t; cdecl;
2595var JS_GetStringLength: TJS_GetStringLength{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetStringLength'; {$ENDIF}
2596
2597/// Return true if the string's characters are stored as Latin1.
2598type TJS_StringHasLatin1Chars = function (str: PJSString): boolean; cdecl;
2599var JS_StringHasLatin1Chars: TJS_StringHasLatin1Chars{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_StringHasLatin1Chars'; {$ENDIF}
2600
2601/// Return a pointer to the string, and store the length to *length
2602// Use it when characters are stored as Latin1.
2603type TJS_GetLatin1StringCharsAndLength = function (cx: PJSContext;
2604  nogc: PJSAutoCheckCannotGC; str: PJSString; plength: psize_t):PCChar; cdecl;
2605var JS_GetLatin1StringCharsAndLength: TJS_GetLatin1StringCharsAndLength{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetLatin1StringCharsAndLength'; {$ENDIF}
2606
2607/// Return a pointer to the string, and store the length to *length
2608// Use it when characters are stored as Unicode
2609type TJS_GetTwoByteStringCharsAndLength = function (cx: PJSContext;
2610  nogc: PJSAutoCheckCannotGC; str: PJSString; plength: psize_t): PCChar16; cdecl;
2611var JS_GetTwoByteStringCharsAndLength: TJS_GetTwoByteStringCharsAndLength{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetTwoByteStringCharsAndLength'; {$ENDIF}
2612
2613/// converts a value to JSON, optionally replacing values if a replacer
2614// function is specified, or optionally including only the specified properties
2615// if a replacer array is specified
2616type TJS_Stringify = function (cx: PJSContext; var vp: jsval;
2617  var replacer: PJSObject; var space: jsval; callback: JSONWriteCallback;
2618  data: pointer): Boolean; cdecl;
2619var JS_Stringify: TJS_Stringify{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_Stringify'; {$ENDIF}
2620
2621/// parse a string using the JSON syntax described in ECMAScript 5 and
2622// return the corresponding value into vp
2623type TJS_ParseJSON = function (cx: PJSContext; const chars: PCChar16;
2624  len: uint32; out vp: jsval): Boolean; cdecl;
2625var JS_ParseJSON: TJS_ParseJSON{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_ParseJSON'; {$ENDIF}
2626
2627/// Create a new JavaScript Error object and set it to be the pending exception on cx.
2628// The callback must then return JS_FALSE to cause the exception to be propagated
2629// to the calling script.
2630// type TJS_ReportError = procedure (cx: PJSContext; const format: PCChar); cdecl; varargs;
2631// var JS_ReportError: TJS_ReportError{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_ReportErrorASCII'; {$ENDIF}
2632procedure JS_ReportError(cx: PJSContext; const format: PCChar);
2633  cdecl; varargs; external SpiderMonkeyLib name 'JS_ReportErrorASCII';
2634
2635/// Report an error with an application-defined error code.
2636// - varargs is Additional arguments for the error message.
2637//- These arguments must be of type jschar*
2638// - The number of additional arguments required depends on the error
2639// message, which is determined by the errorCallback
2640// type TJS_ReportErrorNumberUC = procedure (cx: PJSContext; errorCallback: JSErrorCallback;
2641//   userRef: pointer; const erroNubmer: uintN); cdecl; varargs;
2642// var JS_ReportErrorNumberUC: TJS_ReportErrorNumberUC{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_ReportErrorNumberUC'; {$ENDIF}
2643procedure JS_ReportErrorNumberUC(cx: PJSContext; errorCallback: JSErrorCallback;
2644  userRef: pointer; const erroNubmer: uintN); cdecl; varargs; external SpiderMonkeyLib name 'JS_ReportErrorNumberUC';
2645
2646// type TJS_ReportErrorNumberUTF8 = procedure (cx: PJSContext;
2647//   errorCallback: JSErrorCallback; userRef: pointer;
2648//   const erroNubmer: uintN); cdecl; varargs;
2649// var JS_ReportErrorNumberUTF8: TJS_ReportErrorNumberUTF8{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_ReportErrorNumberUTF8'; {$ENDIF}
2650procedure JS_ReportErrorNumberUTF8(cx: PJSContext; errorCallback: JSErrorCallback;
2651  userRef: pointer; const erroNubmer: uintN); cdecl; varargs; external SpiderMonkeyLib name 'JS_ReportErrorNumberUTF8';
2652
2653/// Reports a memory allocation error
2654// - Call JS_ReportOutOfMemory to report that an operation failed because the
2655// system is out of memory
2656// - When the JavaScript engine tries to allocate memory and allocation fails,
2657// it reports an error as though by calling this function
2658type TJS_ReportOutOfMemory = procedure (cx: PJSContext); cdecl;
2659var JS_ReportOutOfMemory: TJS_ReportOutOfMemory{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_ReportOutOfMemory'; {$ENDIF}
2660
2661/// Get the warning reporting mechanism for an application. It is not working for errors.
2662type TJS_GetWarningReporter = function (cx: PJSContext): JSWarningReporter; cdecl;
2663var JS_GetWarningReporter: TJS_GetWarningReporter{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetWarningReporter'; {$ENDIF}
2664
2665/// Specify the warning reporting mechanism for an application.  It is not working for errors.
2666type TJS_SetWarningReporter = function (cx: PJSContext;
2667  reporter: JSWarningReporter): JSWarningReporter; cdecl;
2668var JS_SetWarningReporter: TJS_SetWarningReporter{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_SetWarningReporter'; {$ENDIF}
2669
2670/// Create a new JavaScript date object
2671type TJS_NewDateObject = function (cx: PJSContext;
2672  year, mon, mday, hour, min, sec: int32): PJSObject; cdecl;
2673var JS_NewDateObject: TJS_NewDateObject{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewDateObject'; {$ENDIF}
2674
2675/// Create a new JavaScript date object from the Unix millisecond elapsed since EPOC
2676function JS_NewDateObjectMsec(cx: PJSContext; msec: double): PJSObject; cdecl;
2677  external SpiderMonkeyLib name 'SM_NewDateObjectMsec';
2678
2679// Returns true and sets |*isDate| indicating whether |obj| is a Date object or
2680// a wrapper around one, otherwise returns false on failure.
2681// - This method returns true with |*isDate == false| when passed a proxy whose
2682// target is a Date, or when passed a revoked proxy.
2683type TJS_ObjectIsDate = function (cx: PJSContext; var obj: PJSObject;
2684  out isDate: boolean): boolean; cdecl;
2685var JS_ObjectIsDate: TJS_ObjectIsDate{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_ObjectIsDate'; {$ENDIF}
2686
2687/// Determine whether an exception is pending in the JS engine.
2688type TJS_IsExceptionPending = function (cx: PJSContext): Boolean; cdecl;
2689var JS_IsExceptionPending: TJS_IsExceptionPending{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_IsExceptionPending'; {$ENDIF}
2690
2691/// Get the current pending exception for a given JSContext.
2692type TJS_GetPendingException = function (cx: PJSContext;
2693  out vp: jsval): Boolean; cdecl;
2694var JS_GetPendingException: TJS_GetPendingException{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetPendingException'; {$ENDIF}
2695
2696/// Sets the current exception being thrown within a context.
2697type TJS_SetPendingException = procedure (cx: PJSContext; var vp: jsval); cdecl;
2698var JS_SetPendingException: TJS_SetPendingException{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_SetPendingException'; {$ENDIF}
2699
2700/// Clear the currently pending exception in a context.
2701type TJS_ClearPendingException = procedure (cx: PJSContext); cdecl;
2702var JS_ClearPendingException: TJS_ClearPendingException{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_ClearPendingException'; {$ENDIF}
2703
2704/// If the given object is an exception object, the exception will have (or be
2705// able to lazily create) an error report struct, and this function will return
2706// the address of that struct.  Otherwise, it returns nullptr. The lifetime
2707// of the error report struct that might be returned is the same as the
2708// lifetime of the exception object.
2709type TJS_ErrorFromException = function (cx: PJSContext;
2710  var obj: PJSObject): PJSErrorReport; cdecl;
2711var JS_ErrorFromException: TJS_ErrorFromException{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_ErrorFromException'; {$ENDIF}
2712
2713/// Get options of context
2714function JS_GetContextOptions(cx: PJSContext): PJSContextOptions; cdecl;
2715  external SpiderMonkeyLib name 'SM_GetContextOptions';
2716
2717//function JS_NewRootedValue(cx: PJSContext; val: jsval): PJSRootedValue; cdecl; external SpiderMonkeyLib;
2718function JS_NewRootedValue(cx: PJSContext; val: Int64): PJSRootedValue; cdecl;
2719  external SpiderMonkeyLib name 'SM_NewRootedValue';
2720
2721procedure JS_FreeRootedValue(val: PJSRootedValue); cdecl;
2722  external SpiderMonkeyLib name 'SM_FreeRootedValue';
2723
2724function JS_NewRootedObject(cx: PJSContext; obj: PJSObject): PJSRootedObject; cdecl;
2725  external SpiderMonkeyLib name 'SM_NewRootedObject';
2726
2727procedure JS_FreeRootedObject(obj: PJSRootedObject); cdecl;
2728  external SpiderMonkeyLib name 'SM_FreeRootedObject';
2729
2730function JS_NewRootedString(cx: PJSContext; obj: PJSString): PJSRootedString; cdecl;
2731  external SpiderMonkeyLib name 'SM_NewRootedString';
2732
2733procedure JS_FreeRootedString(str: PJSRootedString); cdecl;
2734  external SpiderMonkeyLib name 'SM_FreeRootedString';
2735
2736/// Create Compile Options
2737function JS_NewCompileOptions(cx: PJSContext): PJSCompileOptions; cdecl;
2738  external SpiderMonkeyLib name 'SM_NewCompileOptions';
2739
2740/// expose to Pascal
2741// JS::CompileOptions.setFileAndLine + setUTF8
2742procedure JS_SetCompileOptionsFileLineAndUtf8(co: PJSCompileOptions;
2743  const f: PChar; l: cardinal; isUtf8: boolean); cdecl;
2744  external SpiderMonkeyLib name 'SM_SetCompileOptionsFileLineAndUtf8';
2745
2746/// Free Compile Options
2747procedure JS_FreeCompileOptions(opt: PJSCompileOptions); cdecl;
2748  external SpiderMonkeyLib name 'SM_FreeCompileOptions';
2749///////////////////
2750
2751type TJS_EvaluateScript = function (cx: PJSContext;
2752   options: PJSCompileOptions; bytes: PCChar; length: size_t;
2753   out rval: jsval): Boolean; cdecl;
2754var JS_EvaluateScript: TJS_EvaluateScript{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_EvaluateScript'; {$ENDIF}
2755
2756type TJS_EvaluateUCScript = function (cx: PJSContext;
2757   options: PJSCompileOptions; chars: PCChar16; length: size_t;
2758   out rval: jsval): Boolean; cdecl;
2759var JS_EvaluateUCScript: TJS_EvaluateUCScript{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_EvaluateUCScript'; {$ENDIF}
2760
2761/// Compute |this| for the |vp| inside a JSNative, either boxing primitives or
2762// replacing with the global object as necessary.
2763// - This method will go away at some point: instead use |args.thisv()|.  If the
2764// value is an object, no further work is required.  If that value is |null| or
2765// |undefined|, use |JS_GetGlobalForObject| to compute the global object.  If
2766// the value is some other primitive, use |JS_ValueToObject| to box it.
2767// - low-level API used by JS_THIS() macro.
2768//function JS_ComputeThis(cx: PJSContext; var vp: jsval): jsval; cdecl; external SpiderMonkeyLib;
2769type TJS_ComputeThis = function (cx: PJSContext; var vp: jsval): Int64; cdecl;
2770var JS_ComputeThis: TJS_ComputeThis{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_ComputeThis'; {$ENDIF}
2771
2772procedure strFinalizeOp(fin: PJSStringFinalizer; chars: PCChar16); cdecl;
2773const
2774  strFinalizer: JSStringFinalizer = (
2775    finalize: strFinalizeOp;
2776  );
2777
2778{ ArrayBuffer support from jsfriendapi.h}
2779
2780/// Create a new signed 8 bit integer typed array with nelements elements
2781// - will fill the newly created array with zeros
2782type TJS_NewInt8Array = function (cx: PJSContext;
2783  nelements: uint32): PJSObject; cdecl;
2784var JS_NewInt8Array: TJS_NewInt8Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewInt8Array'; {$ENDIF}
2785
2786/// Create a new unsigned 8 bit integer (byte) typed array with nelements elements
2787// - will fill the newly created array with zeros
2788type TJS_NewUint8Array = function (cx: PJSContext;
2789  nelements: uint32): PJSObject; cdecl;
2790var JS_NewUint8Array: TJS_NewUint8Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewUint8Array'; {$ENDIF}
2791
2792/// Create a new 8 bit integer typed array with nelements elements
2793// - will fill the newly created array with zeros
2794type TJS_NewUint8ClampedArray = function (cx: PJSContext;
2795  nelements: uint32): PJSObject; cdecl;
2796var JS_NewUint8ClampedArray: TJS_NewUint8ClampedArray{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewUint8ClampedArray'; {$ENDIF}
2797
2798/// Create a new signed 16 bit integer typed array with nelements elements
2799// - will fill the newly created array with zeros
2800type TJS_NewInt16Array = function (cx: PJSContext;
2801  nelements: uint32): PJSObject; cdecl;
2802var JS_NewInt16Array: TJS_NewInt16Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewInt16Array'; {$ENDIF}
2803
2804/// Create a new unsigned 16 bit integer typed array with nelements elements
2805// - will fill the newly created array with zeros
2806type TJS_NewUint16Array = function (cx: PJSContext;
2807  nelements: uint32): PJSObject; cdecl;
2808var JS_NewUint16Array: TJS_NewUint16Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewUint16Array'; {$ENDIF}
2809
2810/// Create a new signed 32 bit integer typed array with nelements elements
2811// - will fill the newly created array with zeros
2812type TJS_NewInt32Array = function (cx: PJSContext;
2813  nelements: uint32): PJSObject; cdecl;
2814var JS_NewInt32Array: TJS_NewInt32Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewInt32Array'; {$ENDIF}
2815
2816/// Create a new unsigned 32 bit integer typed array with nelements elements
2817// - will fill the newly created array with zeros
2818type TJS_NewUint32Array = function (cx: PJSContext;
2819  nelements: uint32): PJSObject; cdecl;
2820var JS_NewUint32Array: TJS_NewUint32Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewUint32Array'; {$ENDIF}
2821
2822/// Create a new signed 32 bit float (single) typed array with nelements elements
2823// - will fill the newly created array with zeros
2824type TJS_NewFloat32Array = function (cx: PJSContext;
2825  nelements: uint32): PJSObject; cdecl;
2826var JS_NewFloat32Array: TJS_NewFloat32Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewFloat32Array'; {$ENDIF}
2827
2828/// Create a new signed 64 bit float (double) typed array with nelements elements
2829// - will fill the newly created array with zeros
2830type TJS_NewFloat64Array = function (cx: PJSContext;
2831  nelements: uint32): PJSObject; cdecl;
2832var JS_NewFloat64Array: TJS_NewFloat64Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewFloat64Array'; {$ENDIF}
2833
2834/// Create a new 8 bit signed integer typed array and copy in values
2835// from a given object
2836// - The object is used as if it was an array; that is, the new array (if
2837// successfully created) will have length given by array.length, and its
2838// elements will be those specified by array[0], array[1], and so on, after
2839// conversion to the typed array element type.
2840type TJS_NewInt8ArrayFromArray = function (cx: PJSContext;
2841  var arr: PJSObject): PJSObject; cdecl;
2842var JS_NewInt8ArrayFromArray: TJS_NewInt8ArrayFromArray{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewInt8ArrayFromArray'; {$ENDIF}
2843
2844/// Create a new 8 bit unsigned integer typed array and copy in values
2845// from a given object
2846// - The object is used as if it was an array; that is, the new array (if
2847// successfully created) will have length given by array.length, and its
2848// elements will be those specified by array[0], array[1], and so on, after
2849// conversion to the typed array element type.
2850type TJS_NewUint8ArrayFromArray = function (cx: PJSContext;
2851  var arr: PJSObject): PJSObject; cdecl;
2852var JS_NewUint8ArrayFromArray: TJS_NewUint8ArrayFromArray{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewUint8ArrayFromArray'; {$ENDIF}
2853
2854/// Create a new 8 bit unsigned integer typed array and copy in values
2855// from a given object
2856// - The object is used as if it was an array; that is, the new array (if
2857// successfully created) will have length given by array.length, and its
2858// elements will be those specified by array[0], array[1], and so on, after
2859// conversion to the typed array element type.
2860type TJS_NewUint8ClampedArrayFromArray = function (cx: PJSContext;
2861  var arr: PJSObject): PJSObject; cdecl;
2862var JS_NewUint8ClampedArrayFromArray: TJS_NewUint8ClampedArrayFromArray{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewUint8ClampedArrayFromArray'; {$ENDIF}
2863
2864/// Create a new 16 bit signed integer typed array and copy in values
2865// from a given object
2866// - The object is used as if it was an array; that is, the new array (if
2867// successfully created) will have length given by array.length, and its
2868// elements will be those specified by array[0], array[1], and so on, after
2869// conversion to the typed array element type.
2870type TJS_NewInt16ArrayFromArray = function (cx: PJSContext;
2871  var arr: PJSObject): PJSObject; cdecl;
2872var JS_NewInt16ArrayFromArray: TJS_NewInt16ArrayFromArray{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewInt16ArrayFromArray'; {$ENDIF}
2873
2874/// Create a new 16 bit unsigned integer typed array and copy in values
2875// from a given object
2876// - The object is used as if it was an array; that is, the new array (if
2877// successfully created) will have length given by array.length, and its
2878// elements will be those specified by array[0], array[1], and so on, after
2879// conversion to the typed array element type.
2880type TJS_NewUint16ArrayFromArray = function (cx: PJSContext;
2881  var arr: PJSObject): PJSObject; cdecl;
2882var JS_NewUint16ArrayFromArray: TJS_NewUint16ArrayFromArray{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewUint16ArrayFromArray'; {$ENDIF}
2883
2884/// Create a new 32 bit signed integer typed array and copy in values
2885// from a given object
2886// - The object is used as if it was an array; that is, the new array (if
2887// successfully created) will have length given by array.length, and its
2888// elements will be those specified by array[0], array[1], and so on, after
2889// conversion to the typed array element type.
2890type TJS_NewInt32ArrayFromArray = function (cx: PJSContext;
2891  var arr: PJSObject): PJSObject; cdecl;
2892var JS_NewInt32ArrayFromArray: TJS_NewInt32ArrayFromArray{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewInt32ArrayFromArray'; {$ENDIF}
2893
2894/// Create a new 32 bit unsigned integer typed array and copy in values
2895// from a given object
2896// - The object is used as if it was an array; that is, the new array (if
2897// successfully created) will have length given by array.length, and its
2898// elements will be those specified by array[0], array[1], and so on, after
2899// conversion to the typed array element type.
2900type TJS_NewUint32ArrayFromArray = function (cx: PJSContext;
2901  var arr: PJSObject): PJSObject; cdecl;
2902var JS_NewUint32ArrayFromArray: TJS_NewUint32ArrayFromArray{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewUint32ArrayFromArray'; {$ENDIF}
2903
2904/// Create a new 32 bit float (single) typed array and copy in values
2905// from a given object
2906// - The object is used as if it was an array; that is, the new array (if
2907// successfully created) will have length given by array.length, and its
2908// elements will be those specified by array[0], array[1], and so on, after
2909// conversion to the typed array element type.
2910type TJS_NewFloat32ArrayFromArray = function (cx: PJSContext;
2911  var arr: PJSObject): PJSObject; cdecl;
2912var JS_NewFloat32ArrayFromArray: TJS_NewFloat32ArrayFromArray{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewFloat32ArrayFromArray'; {$ENDIF}
2913
2914/// Create a new 64 bit float (double) typed array and copy in values
2915// from a given object
2916// - The object is used as if it was an array; that is, the new array (if
2917// successfully created) will have length given by array.length, and its
2918// elements will be those specified by array[0], array[1], and so on, after
2919// conversion to the typed array element type.
2920type TJS_NewFloat64ArrayFromArray = function (cx: PJSContext;
2921  var arr: PJSObject): PJSObject; cdecl;
2922var JS_NewFloat64ArrayFromArray: TJS_NewFloat64ArrayFromArray{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewFloat64ArrayFromArray'; {$ENDIF}
2923
2924/// Create a new 8 bit signed integer typed array using the given
2925// ArrayBuffer for storage
2926// - The length value is optional; if -1 is passed, enough elements to use up the
2927// remainder of the byte array is used as the default value
2928type TJS_NewInt8ArrayWithBuffer = function (cx: PJSContext;
2929  var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject; cdecl;
2930var JS_NewInt8ArrayWithBuffer: TJS_NewInt8ArrayWithBuffer{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewInt8ArrayWithBuffer'; {$ENDIF}
2931
2932/// Create a new 8 bit unsigned integer typed array using the given
2933// ArrayBuffer for storage
2934// - The length value is optional; if -1 is passed, enough elements to use up the
2935// remainder of the byte array is used as the default value
2936type TJS_NewUint8ArrayWithBuffer = function (cx: PJSContext;
2937  var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject; cdecl;
2938var JS_NewUint8ArrayWithBuffer: TJS_NewUint8ArrayWithBuffer{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewUint8ArrayWithBuffer'; {$ENDIF}
2939
2940/// Create a new 8 bit unsigned integer typed array using the given
2941// ArrayBuffer for storage
2942// - The length value is optional; if -1 is passed, enough elements to use up the
2943// remainder of the byte array is used as the default value
2944type TJS_NewUint8ClampedArrayWithBuffer = function (cx: PJSContext;
2945  var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject; cdecl;
2946var JS_NewUint8ClampedArrayWithBuffer: TJS_NewUint8ClampedArrayWithBuffer{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewUint8ClampedArrayWithBuffer'; {$ENDIF}
2947
2948/// Create a new 16 bit signed integer typed array using the given
2949// ArrayBuffer for storage
2950// - The length value is optional; if -1 is passed, enough elements to use up the
2951// remainder of the byte array is used as the default value
2952type TJS_NewInt16ArrayWithBuffer = function (cx: PJSContext;
2953  var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject; cdecl;
2954var JS_NewInt16ArrayWithBuffer: TJS_NewInt16ArrayWithBuffer{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewInt16ArrayWithBuffer'; {$ENDIF}
2955
2956/// Create a new 16 bit unsigned integer typed array using the given
2957// ArrayBuffer for storage
2958// - The length value is optional; if -1 is passed, enough elements to use up the
2959// remainder of the byte array is used as the default value
2960type TJS_NewUint16ArrayWithBuffer = function (cx: PJSContext;
2961  var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject; cdecl;
2962var JS_NewUint16ArrayWithBuffer: TJS_NewUint16ArrayWithBuffer{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewUint16ArrayWithBuffer'; {$ENDIF}
2963
2964/// Create a new 32 bit signed integer typed array using the given
2965// ArrayBuffer for storage
2966// - The length value is optional; if -1 is passed, enough elements to use up the
2967// remainder of the byte array is used as the default value
2968type TJS_NewInt32ArrayWithBuffer = function (cx: PJSContext;
2969  var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject; cdecl;
2970var JS_NewInt32ArrayWithBuffer: TJS_NewInt32ArrayWithBuffer{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewInt32ArrayWithBuffer'; {$ENDIF}
2971
2972/// Create a new 32 bit unsigned integer typed array using the given
2973// ArrayBuffer for storage
2974// - The length value is optional; if -1 is passed, enough elements to use up the
2975// remainder of the byte array is used as the default value
2976type TJS_NewUint32ArrayWithBuffer = function (cx: PJSContext;
2977  var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject; cdecl;
2978var JS_NewUint32ArrayWithBuffer: TJS_NewUint32ArrayWithBuffer{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewUint32ArrayWithBuffer'; {$ENDIF}
2979
2980/// Create a new 32 bit float (single) typed array using the given
2981// ArrayBuffer for storage
2982// - The length value is optional; if -1 is passed, enough elements to use up the
2983// remainder of the byte array is used as the default value
2984type TJS_NewFloat32ArrayWithBuffer = function (cx: PJSContext;
2985  var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject; cdecl;
2986var JS_NewFloat32ArrayWithBuffer: TJS_NewFloat32ArrayWithBuffer{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewFloat32ArrayWithBuffer'; {$ENDIF}
2987
2988/// Create a new 64 bit float (double) typed array using the given
2989// ArrayBuffer for storage
2990// - The length value is optional; if -1 is passed, enough elements to use up the
2991// remainder of the byte array is used as the default value
2992type TJS_NewFloat64ArrayWithBuffer = function (cx: PJSContext;
2993  var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject; cdecl;
2994var JS_NewFloat64ArrayWithBuffer: TJS_NewFloat64ArrayWithBuffer{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewFloat64ArrayWithBuffer'; {$ENDIF}
2995
2996/// Create a new SharedArrayBuffer with the given byte length.
2997type TJS_NewSharedArrayBuffer = function (cx: PJSContext;
2998  nbytes: uint32): PJSObject; cdecl;
2999var JS_NewSharedArrayBuffer: TJS_NewSharedArrayBuffer{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewSharedArrayBuffer'; {$ENDIF}
3000
3001/// Create a new ArrayBuffer with the given byte length.
3002type TJS_NewArrayBuffer = function (cx: PJSContext;
3003  nbytes: uint32): PJSObject; cdecl;
3004var JS_NewArrayBuffer: TJS_NewArrayBuffer{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewArrayBuffer'; {$ENDIF}
3005
3006/// Check whether obj supports JS_GetTypedArray* APIs
3007// - Note that this may return false if a security wrapper is encountered that
3008// denies the unwrapping.
3009// - if this test or one of the JS_Is*Array tests succeeds, then it is safe to call
3010// the dedicated accessor JSAPI calls
3011type TJS_IsTypedArrayObject = function (obj: PJSObject): Boolean; cdecl;
3012var JS_IsTypedArrayObject: TJS_IsTypedArrayObject{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_IsTypedArrayObject'; {$ENDIF}
3013
3014/// Check whether obj supports JS_GetArrayBufferView* APIs
3015// - Note that this may return false if a security wrapper is encountered that
3016// denies the unwrapping.
3017// - if this test or one of the JS_Is*Array tests succeeds, then it is safe to call
3018// the dedicated ArrayBufferView accessor JSAPI calls
3019type TJS_IsArrayBufferViewObject = function (obj: PJSObject): Boolean; cdecl;
3020var JS_IsArrayBufferViewObject: TJS_IsArrayBufferViewObject{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_IsArrayBufferViewObject'; {$ENDIF}
3021
3022/// Test for specific 8 bit signed integer typed array types (ArrayBufferView subtypes)
3023type TJS_IsInt8Array = function (obj: PJSObject): Boolean; cdecl;
3024var JS_IsInt8Array: TJS_IsInt8Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_IsInt8Array'; {$ENDIF}
3025
3026/// Test for specific 8 bit unsigned integer typed array types (ArrayBufferView subtypes)
3027type TJS_IsUint8Array = function (obj: PJSObject): Boolean; cdecl;
3028var JS_IsUint8Array: TJS_IsUint8Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_IsUint8Array'; {$ENDIF}
3029
3030/// Test for specific 8 bit unsigned integer typed array types (ArrayBufferView subtypes)
3031type TJS_IsUint8ClampedArray = function (obj: PJSObject): Boolean; cdecl;
3032var JS_IsUint8ClampedArray: TJS_IsUint8ClampedArray{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_IsUint8ClampedArray'; {$ENDIF}
3033
3034/// Test for specific 16 bit signed integer typed array types (ArrayBufferView subtypes)
3035type TJS_IsInt16Array = function (obj: PJSObject): Boolean; cdecl;
3036var JS_IsInt16Array: TJS_IsInt16Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_IsInt16Array'; {$ENDIF}
3037
3038/// Test for specific 16 bit unsigned integer typed array types (ArrayBufferView subtypes)
3039type TJS_IsUint16Array = function (obj: PJSObject): Boolean; cdecl;
3040var JS_IsUint16Array: TJS_IsUint16Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_IsUint16Array'; {$ENDIF}
3041
3042/// Test for specific 32 bit signed integer typed array types (ArrayBufferView subtypes)
3043type TJS_IsInt32Array = function (obj: PJSObject): Boolean; cdecl;
3044var JS_IsInt32Array: TJS_IsInt32Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_IsInt32Array'; {$ENDIF}
3045
3046/// Test for specific 32 bit unsigned integer typed array types (ArrayBufferView subtypes)
3047type TJS_IsUint32Array = function (obj: PJSObject): Boolean; cdecl;
3048var JS_IsUint32Array: TJS_IsUint32Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_IsUint32Array'; {$ENDIF}
3049
3050/// Test for specific 32 bit float (single) typed array types (ArrayBufferView subtypes)
3051type TJS_IsFloat32Array = function (obj: PJSObject): Boolean; cdecl;
3052var JS_IsFloat32Array: TJS_IsFloat32Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_IsFloat32Array'; {$ENDIF}
3053
3054/// Test for specific 64 bit float (double) typed array types (ArrayBufferView subtypes)
3055type TJS_IsFloat64Array = function (obj: PJSObject): Boolean; cdecl;
3056var JS_IsFloat64Array: TJS_IsFloat64Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_IsFloat64Array'; {$ENDIF}
3057
3058/// Return the isShared flag of a typed array, which denotes whether
3059// the underlying buffer is a SharedArrayBuffer.
3060//
3061// |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow
3062// be known that it would pass such a test: it is a typed array or a wrapper of
3063// a typed array, and the unwrapping will succeed.
3064type TJS_GetTypedArraySharedness = function (obj: PJSObject): Boolean; cdecl;
3065var JS_GetTypedArraySharedness: TJS_GetTypedArraySharedness{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetTypedArraySharedness'; {$ENDIF}
3066
3067/// Unwrap 8 bit signed integer typed array into direct memory buffer
3068// - Return nil without throwing any exception if the object cannot be viewed as the
3069// correct typed array, or the typed array object on success, filling both out parameters
3070type TJS_GetObjectAsInt8Array = function (obj: PJSObject; out length: uint32;
3071  out isSharedMemory:Boolean; out Data: Pint8Vector): PJSObject; cdecl;
3072var JS_GetObjectAsInt8Array: TJS_GetObjectAsInt8Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetObjectAsInt8Array'; {$ENDIF}
3073
3074/// Unwrap 8 bit unsigned integer typed array into direct memory buffer
3075// - Return nil without throwing any exception if the object cannot be viewed as the
3076// correct typed array, or the typed array object on success, filling both out parameters
3077type TJS_GetObjectAsUint8Array = function (obj: PJSObject; out length: uint32;
3078  out isSharedMemory:Boolean; out  Data: Puint8Vector): PJSObject; cdecl;
3079var JS_GetObjectAsUint8Array: TJS_GetObjectAsUint8Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetObjectAsUint8Array'; {$ENDIF}
3080
3081/// Unwrap 8 bit unsigned integer typed array into direct memory buffer
3082// - Return nil without throwing any exception if the object cannot be viewed as the
3083// correct typed array, or the typed array object on success, filling both out parameters
3084type TJS_GetObjectAsUint8ClampedArray = function (obj: PJSObject;
3085  out length: uint32; out isSharedMemory:Boolean;
3086  out  Data: Puint8Vector): PJSObject; cdecl;
3087var JS_GetObjectAsUint8ClampedArray: TJS_GetObjectAsUint8ClampedArray{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetObjectAsUint8ClampedArray'; {$ENDIF}
3088
3089/// Unwrap 16 bit signed integer typed array into direct memory buffer
3090// - Return nil without throwing any exception if the object cannot be viewed as the
3091// correct typed array, or the typed array object on success, filling both out parameters
3092type TJS_GetObjectAsInt16Array = function (obj: PJSObject;
3093  out length: uint32; out isSharedMemory:Boolean;
3094  out  Data: Pint16Vector): PJSObject; cdecl;
3095var JS_GetObjectAsInt16Array: TJS_GetObjectAsInt16Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetObjectAsInt16Array'; {$ENDIF}
3096
3097/// Unwrap 16 bit unsigned integer typed array into direct memory buffer
3098// - Return nil without throwing any exception if the object cannot be viewed as the
3099// correct typed array, or the typed array object on success, filling both out parameters
3100type TJS_GetObjectAsUint16Array = function (obj: PJSObject; out length: uint32;
3101  out isSharedMemory:Boolean; out  Data: Puint16Vector): PJSObject; cdecl;
3102var JS_GetObjectAsUint16Array: TJS_GetObjectAsUint16Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetObjectAsUint16Array'; {$ENDIF}
3103
3104/// Unwrap 32 bit signed integer typed array into direct memory buffer
3105// - Return nil without throwing any exception if the object cannot be viewed as the
3106// correct typed array, or the typed array object on success, filling both out parameters
3107type TJS_GetObjectAsInt32Array = function (obj: PJSObject; out length: uint32;
3108  out isSharedMemory:Boolean; out  Data: Pint32Vector): PJSObject; cdecl;
3109var JS_GetObjectAsInt32Array: TJS_GetObjectAsInt32Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetObjectAsInt32Array'; {$ENDIF}
3110
3111/// Unwrap 32 bit unsigned integer typed array into direct memory buffer
3112// - Return nil without throwing any exception if the object cannot be viewed as the
3113// correct typed array, or the typed array object on success, filling both out parameters
3114type TJS_GetObjectAsUint32Array = function (obj: PJSObject; out length: uint32;
3115  out isSharedMemory:Boolean; out  Data: Puint32Vector): PJSObject; cdecl;
3116var JS_GetObjectAsUint32Array: TJS_GetObjectAsUint32Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetObjectAsUint32Array'; {$ENDIF}
3117
3118/// Unwrap 32 bit float (single) typed array into direct memory buffer
3119// - Return nil without throwing any exception if the object cannot be viewed as the
3120// correct typed array, or the typed array object on success, filling both out parameters
3121type TJS_GetObjectAsFloat32Array = function (obj: PJSObject; out length: uint32;
3122  out isSharedMemory:Boolean; out  Data: Pfloat32Vector): PJSObject; cdecl;
3123var JS_GetObjectAsFloat32Array: TJS_GetObjectAsFloat32Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetObjectAsFloat32Array'; {$ENDIF}
3124
3125/// Unwrap 64 bit float (double) typed array into direct memory buffer
3126// - Return nil without throwing any exception if the object cannot be viewed as the
3127// correct typed array, or the typed array object on success, filling both out parameters
3128type TJS_GetObjectAsFloat64Array = function (obj: PJSObject; out length: uint32;
3129  out isSharedMemory:Boolean; out  Data: Pfloat64Vector): PJSObject; cdecl;
3130var JS_GetObjectAsFloat64Array: TJS_GetObjectAsFloat64Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetObjectAsFloat64Array'; {$ENDIF}
3131
3132/// Unwrap an object as its raw binary memory buffer
3133// - Return nil without throwing any exception if the object cannot be viewed as the
3134// correct typed array, or the typed array object on success, filling both out parameters
3135type TJS_GetObjectAsArrayBufferView = function (obj: PJSObject;
3136  out length: uint32; out isSharedMemory:Boolean;
3137  out  Data: Puint8Vector): PJSObject; cdecl;
3138var JS_GetObjectAsArrayBufferView: TJS_GetObjectAsArrayBufferView{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetObjectAsArrayBufferView'; {$ENDIF}
3139
3140/// Unwrap an object as its raw binary memory buffer
3141// - Return nil without throwing any exception if the object cannot be viewed as the
3142// correct typed array, or the typed array object on success, filling both out parameters
3143type TJS_GetObjectAsArrayBuffer = function (obj: PJSObject; out length: uint32;
3144  out Data: Puint8Vector): PJSObject; cdecl;
3145var JS_GetObjectAsArrayBuffer: TJS_GetObjectAsArrayBuffer{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetObjectAsArrayBuffer'; {$ENDIF}
3146
3147  /// Get the type of elements in a typed array, or jsabTYPE_DATAVIEW if a DataView
3148type TJS_GetArrayBufferViewType = function (
3149  obj: PJSObject): JSArrayBufferViewType; cdecl;
3150var JS_GetArrayBufferViewType: TJS_GetArrayBufferViewType{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetArrayBufferViewType'; {$ENDIF}
3151
3152/// Check whether obj supports the JS_GetArrayBuffer* APIs
3153// - Note that this may return false if a security wrapper is encountered that denies the
3154// unwrapping
3155// - If this test succeeds, then it is safe to call the various accessor JSAPI calls
3156type TJS_IsArrayBufferObject = function (obj: PJSObject): Boolean; cdecl;
3157var JS_IsArrayBufferObject: TJS_IsArrayBufferObject{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_IsArrayBufferObject'; {$ENDIF}
3158
3159type TJS_IsSharedArrayBufferObject = function (obj: PJSObject): Boolean; cdecl;
3160var JS_IsSharedArrayBufferObject: TJS_IsSharedArrayBufferObject{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_IsSharedArrayBufferObject'; {$ENDIF}
3161
3162/// Return the available byte length of an array buffer
3163// - obj must have passed a JS_IsArrayBufferObject test, or somehow be known
3164// that it would pass such a test: it is an ArrayBuffer or a wrapper of an
3165// ArrayBuffer, and the unwrapping will succeed
3166type TJS_GetArrayBufferByteLength = function (obj: PJSObject): uint32; cdecl;
3167var JS_GetArrayBufferByteLength: TJS_GetArrayBufferByteLength{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetArrayBufferByteLength'; {$ENDIF}
3168
3169type TJS_GetSharedArrayBufferByteLength = function (
3170  obj: PJSObject): uint32; cdecl;
3171var JS_GetSharedArrayBufferByteLength: TJS_GetSharedArrayBufferByteLength{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetSharedArrayBufferByteLength'; {$ENDIF}
3172
3173/// Return true if the arrayBuffer contains any data. This will return false for
3174// ArrayBuffer.prototype and neutered ArrayBuffers.
3175//
3176// |obj| must have passed a JS_IsArrayBufferObject test, or somehow be known
3177// that it would pass such a test: it is an ArrayBuffer or a wrapper of an
3178// ArrayBuffer, and the unwrapping will succeed.
3179type TJS_ArrayBufferHasData = function (obj: PJSObject): Boolean; cdecl;
3180var JS_ArrayBufferHasData: TJS_ArrayBufferHasData{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_ArrayBufferHasData'; {$ENDIF}
3181
3182/// Return a pointer to an array buffer's data
3183// - The buffer is still owned by the array buffer object, and should not
3184// be modified on another thread. The returned pointer is stable across GCs
3185// - obj must have passed a JS_IsArrayBufferObject test, or somehow be known
3186// that it would pass such a test: it is an ArrayBuffer or a wrapper of an
3187// ArrayBuffer, and the unwrapping will succeed.
3188type TJS_GetArrayBufferData = function (obj: PJSObject;
3189  out isSharedMemory: Boolean;
3190  nogc: PJSAutoCheckCannotGC{Not used in SM code}): Puint8Vector; cdecl;
3191var JS_GetArrayBufferData: TJS_GetArrayBufferData{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetArrayBufferData'; {$ENDIF}
3192
3193/// Check whether the obj is ArrayBufferObject and memory mapped. Note that this
3194// may return false if a security wrapper is encountered that denies the
3195// unwrapping.
3196type TJS_IsMappedArrayBufferObject = function (obj: PJSObject): Boolean; cdecl;
3197var JS_IsMappedArrayBufferObject: TJS_IsMappedArrayBufferObject{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_IsMappedArrayBufferObject'; {$ENDIF}
3198
3199/// Return the number of elements in a typed array
3200// - obj must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow
3201// be known that it would pass such a test: it is a typed array or a wrapper of
3202// a typed array, and the unwrapping will succeed.
3203type TJS_GetTypedArrayLength = function (obj: PJSObject): uint32; cdecl;
3204var JS_GetTypedArrayLength: TJS_GetTypedArrayLength{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetTypedArrayLength'; {$ENDIF}
3205
3206/// Return the byte offset from the start of an array buffer to the start of a
3207// typed array view
3208// - obj must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow
3209// be known that it would pass such a test: it is a typed array or a wrapper of
3210// a typed array, and the unwrapping will succeed.
3211type TJS_GetTypedArrayByteOffset = function (obj: PJSObject): uint32; cdecl;
3212var JS_GetTypedArrayByteOffset: TJS_GetTypedArrayByteOffset{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetTypedArrayByteOffset'; {$ENDIF}
3213
3214/// Return the byte length of a typed array
3215// - obj must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow
3216// be known that it would pass such a test: it is a typed array or a wrapper of
3217// a typed array, and the unwrapping will succeed
3218type TJS_GetTypedArrayByteLength = function (obj: PJSObject): uint32; cdecl;
3219var JS_GetTypedArrayByteLength: TJS_GetTypedArrayByteLength{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetTypedArrayByteLength'; {$ENDIF}
3220
3221/// More generic name for JS_GetTypedArrayByteLength to cover DataViews as well
3222type TJS_GetArrayBufferViewByteLength = function (obj: PJSObject): uint32; cdecl;
3223var JS_GetArrayBufferViewByteLength: TJS_GetArrayBufferViewByteLength{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetArrayBufferViewByteLength'; {$ENDIF}
3224
3225/// Return a pointer to the start of the data referenced by a typed 8 bit signed integer array
3226// - The data is still owned by the typed array, and should not be modified on
3227// another thread
3228// - obj must have passed a JS_Is*Array test, or somehow be known that it would
3229// pass such a test: it is a typed array or a wrapper of a typed array, and the
3230// unwrapping will succeed
3231type TJS_GetInt8ArrayData = function (obj: PJSObject;
3232  out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Pint8Vector; cdecl;
3233var JS_GetInt8ArrayData: TJS_GetInt8ArrayData{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetInt8ArrayData'; {$ENDIF}
3234
3235/// Return a pointer to the start of the data referenced by a typed 8 bit unsigned integer array
3236// - The data is still owned by the typed array, and should not be modified on
3237// another thread
3238// - obj must have passed a JS_Is*Array test, or somehow be known that it would
3239// pass such a test: it is a typed array or a wrapper of a typed array, and the
3240// unwrapping will succeed
3241type TJS_GetUint8ArrayData = function (obj: PJSObject;
3242  out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Puint8Vector; cdecl;
3243var JS_GetUint8ArrayData: TJS_GetUint8ArrayData{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetUint8ArrayData'; {$ENDIF}
3244
3245/// Return a pointer to the start of the data referenced by a typed 8 bit unsigned integer array
3246// - The data is still owned by the typed array, and should not be modified on
3247// another thread
3248// - obj must have passed a JS_Is*Array test, or somehow be known that it would
3249// pass such a test: it is a typed array or a wrapper of a typed array, and the
3250// unwrapping will succeed
3251type TJS_GetUint8ClampedArrayData = function (obj: PJSObject;
3252  out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Puint8Vector; cdecl;
3253var JS_GetUint8ClampedArrayData: TJS_GetUint8ClampedArrayData{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetUint8ClampedArrayData'; {$ENDIF}
3254
3255/// Return a pointer to the start of the data referenced by a typed 16 bit signed integer array
3256// - The data is still owned by the typed array, and should not be modified on
3257// another thread
3258// - obj must have passed a JS_Is*Array test, or somehow be known that it would
3259// pass such a test: it is a typed array or a wrapper of a typed array, and the
3260// unwrapping will succeed
3261type TJS_GetInt16ArrayData = function (obj: PJSObject;
3262  out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Pint16Vector; cdecl;
3263var JS_GetInt16ArrayData: TJS_GetInt16ArrayData{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetInt16ArrayData'; {$ENDIF}
3264
3265/// Return a pointer to the start of the data referenced by a typed 16 bit unsigned integer array
3266// - The data is still owned by the typed array, and should not be modified on
3267// another thread
3268// - obj must have passed a JS_Is*Array test, or somehow be known that it would
3269// pass such a test: it is a typed array or a wrapper of a typed array, and the
3270// unwrapping will succeed
3271type TJS_GetUint16ArrayData = function (obj: PJSObject;
3272  out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Puint16Vector; cdecl;
3273var JS_GetUint16ArrayData: TJS_GetUint16ArrayData{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetUint16ArrayData'; {$ENDIF}
3274
3275/// Return a pointer to the start of the data referenced by a typed 32 bit signed integer array
3276// - The data is still owned by the typed array, and should not be modified on
3277// another thread
3278// - obj must have passed a JS_Is*Array test, or somehow be known that it would
3279// pass such a test: it is a typed array or a wrapper of a typed array, and the
3280// unwrapping will succeed
3281type TJS_GetInt32ArrayData = function (obj: PJSObject;
3282  out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Pint32Vector; cdecl;
3283var JS_GetInt32ArrayData: TJS_GetInt32ArrayData{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetInt32ArrayData'; {$ENDIF}
3284
3285/// Return a pointer to the start of the data referenced by a typed 32 bit unsigned integer array
3286// - The data is still owned by the typed array, and should not be modified on
3287// another thread
3288// - obj must have passed a JS_Is*Array test, or somehow be known that it would
3289// pass such a test: it is a typed array or a wrapper of a typed array, and the
3290// unwrapping will succeed
3291type TJS_GetUint32ArrayData = function (obj: PJSObject;
3292  out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Puint32Vector; cdecl;
3293var JS_GetUint32ArrayData: TJS_GetUint32ArrayData{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetUint32ArrayData'; {$ENDIF}
3294
3295/// Return a pointer to the start of the data referenced by a typed 32 bit float (single) array
3296// - The data is still owned by the typed array, and should not be modified on
3297// another thread
3298// - obj must have passed a JS_Is*Array test, or somehow be known that it would
3299// pass such a test: it is a typed array or a wrapper of a typed array, and the
3300// unwrapping will succeed
3301type TJS_GetFloat32ArrayData = function (obj: PJSObject;
3302  out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Pfloat32Vector; cdecl;
3303var JS_GetFloat32ArrayData: TJS_GetFloat32ArrayData{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetFloat32ArrayData'; {$ENDIF}
3304
3305/// Return a pointer to the start of the data referenced by a typed 64 bit float (double) array
3306// - The data is still owned by the typed array, and should not be modified on
3307// another thread
3308// - obj must have passed a JS_Is*Array test, or somehow be known that it would
3309// pass such a test: it is a typed array or a wrapper of a typed array, and the
3310// unwrapping will succeed
3311type TJS_GetFloat64ArrayData = function (obj: PJSObject;
3312  out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Pfloat64Vector; cdecl;
3313var JS_GetFloat64ArrayData: TJS_GetFloat64ArrayData{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetFloat64ArrayData'; {$ENDIF}
3314
3315/// Return a pointer to the start of the data referenced by any typed array
3316// - The data is still owned by the typed array, and should not be modified on
3317// another thread
3318// - obj must have passed a JS_Is*Array test, or somehow be known that it would
3319// pass such a test: it is a typed array or a wrapper of a typed array, and the
3320// unwrapping will succeed
3321// - Prefer the type-specific versions when possible
3322type TJS_GetArrayBufferViewData = function (obj: PJSObject;
3323  out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Pointer; cdecl;
3324var JS_GetArrayBufferViewData: TJS_GetArrayBufferViewData{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetArrayBufferViewData'; {$ENDIF}
3325
3326/// Return the ArrayBuffer underlying an ArrayBufferView
3327// - If the buffer has been neutered, this will still return the neutered buffer.
3328// - obj must be an object that would return true for JS_IsArrayBufferViewObject()
3329type TJS_GetArrayBufferViewBuffer = function (cx: PJSContext;
3330  var obj: PJSObject; out isSharedMemory: Boolean): PJSObject; cdecl;
3331var JS_GetArrayBufferViewBuffer: TJS_GetArrayBufferViewBuffer{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetArrayBufferViewBuffer'; {$ENDIF}
3332
3333////modules
3334
3335/// Initialize modeles classes next 2 functions cannot work without calling this function                !!! EMPTY !!!
3336function JS_InitModuleClasses(cx: PJSContext; var obj: PJSObject): boolean; cdecl; external SpiderMonkeyLib name 'SM_InitModuleClasses';
3337
3338/// Compile script as module
3339function JS_CompileModule(cx: PJSContext;
3340   var obj: PJSObject;
3341   options: PJSCompileOptions;
3342   chars: PCChar16; length: size_t): PJSObject; cdecl; external SpiderMonkeyLib name 'SM_CompileModule';
3343
3344/// Set handler for module resolving
3345type TJS_SetModuleResolveHook = procedure (cx: PJSContext; var hook: PJSFunction); cdecl;
3346var JS_SetModuleResolveHook: TJS_SetModuleResolveHook{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_SetModuleResolveHook'; {$ENDIF}
3347
3348type
3349  pjsval = ^jsval;
3350
3351var
3352  /// global TSynAnsiConvert instance to handle LATIN1(ISO/IEC 8859-1) encoding
3353  // - this instance is global and instantied during the whole program life time
3354  // - Spidermonkey internal encoding is LATIN1 or UTF-16
3355  Latin1AnsiConvert: TSynAnsiConvert;
3356
3357implementation
3358
3359uses
3360  Variants;
3361
3362const
3363  JSVAL_INT_MAX = int32($7fffffff);
3364
3365procedure JSError(cx: PJSContext; aException: Exception);
3366var
3367  ws: WideString;
3368begin
3369  if not JS_IsExceptionPending(cx) then
3370    // raise only if this is the first exception in chain
3371    if aException is EOutOfMemory then
3372      JS_ReportOutOfMemory(cx)
3373    else if aException is ESMRangeException then begin
3374      ws := StringToSynUnicode(aException.Message);
3375      JSRangeErrorUC(cx, ws);
3376    end else if aException is ESMTypeException then begin
3377      ws := StringToSynUnicode(aException.Message);
3378      JSTypeErrorUC(cx, ws);
3379    end else begin
3380      ws := StringToSynUnicode(aException.Message);
3381      JSErrorUC(cx, ws, aException.HelpContext);
3382    end;
3383end;
3384
3385const
3386 ErrorUCFormatString: JSErrorFormatString =
3387  (
3388    name: 'Error';
3389    format: '{0}';
3390    argCount: 1;
3391    exnType: JSEXN_ERR;
3392  );
3393 RangeErrorUCFormatString: JSErrorFormatString =
3394  (
3395    name: 'RangeError';
3396    format: '{0}';
3397    argCount: 1;
3398    exnType: JSEXN_RANGEERR;
3399  );
3400 TypeErrorUCFormatString: JSErrorFormatString =
3401  (
3402    name: 'TypeError';
3403    format: '{0}';
3404    argCount: 1;
3405    exnType: JSEXN_TYPEERR;
3406  );
3407  SMExceptionNumber = 500;//from 0 to JSErr_Limit(421 for SM 45 ) Error numbers are reserved
3408
3409function ReportErrorUC(userRef: Pointer; const errorNumber: uintN): PJSErrorFormatString; cdecl;
3410begin
3411  result := @ErrorUCFormatString;
3412end;
3413
3414function ReportRangeErrorUC(userRef: Pointer; const errorNumber: uintN): PJSErrorFormatString; cdecl;
3415begin
3416  result := @RangeErrorUCFormatString;
3417end;
3418
3419function TypeRangeErrorUC(userRef: Pointer; const errorNumber: uintN): PJSErrorFormatString; cdecl;
3420begin
3421  result := @TypeErrorUCFormatString;
3422end;
3423
3424procedure JSErrorUC(cx: PJSContext; aMessage: WideString; errorCode: integer);
3425begin
3426  if not JS_IsExceptionPending(cx) then
3427    JS_ReportErrorNumberUC(cx, ReportErrorUC, nil, SMExceptionNumber + errorCode, Pointer(aMessage));
3428end;
3429
3430procedure JSRangeErrorUC(cx: PJSContext; aMessage: WideString);
3431begin
3432  if not JS_IsExceptionPending(cx) then
3433    JS_ReportErrorNumberUC(cx, ReportRangeErrorUC, nil, SMExceptionNumber ,Pointer(aMessage));
3434end;
3435
3436procedure JSTypeErrorUC(cx: PJSContext; aMessage: WideString);
3437begin
3438  if not JS_IsExceptionPending(cx) then
3439    JS_ReportErrorNumberUC(cx, TypeRangeErrorUC, nil, SMExceptionNumber ,Pointer(aMessage));
3440end;
3441
3442function InitJS: Boolean;
3443begin
3444  // remove extra threads + allow GS to finalize native objects;
3445  // See for details the same issue in modgoDB:
3446  // https://jira.mongodb.org/browse/SERVER-21728
3447  JS_DisableExtraThreads();
3448  Result := JS_Init;
3449end;
3450
3451procedure ShutDownJS;
3452begin
3453  JS_ShutDown;
3454end;
3455
3456{ JSCompileOptions }
3457
3458procedure JSCompileOptions.SetFileLineAndUtf8(const fn: RawUTF8; l: cardinal;
3459  isUtf8: boolean);
3460begin
3461  JS_SetCompileOptionsFileLineAndUtf8(@Self, pointer(fn), l, isUtf8);
3462end;
3463
3464{ JSString }
3465
3466procedure JSString.ToJSONString(cx: PJSContext; W: TTextWriter);
3467var
3468  str8: PCChar;
3469  str16: PCChar16;
3470  strL: size_t;
3471begin
3472  W.Add('"');
3473  if JS_StringHasLatin1Chars(@self) then begin
3474    str8 := JS_GetLatin1StringCharsAndLength(cx, @nullPtr, @self, @strL);
3475    W.AddJSONEscape(pointer(str8),strL);
3476  end else begin
3477    str16 := JS_GetTwoByteStringCharsAndLength(cx, @nullPtr, @self, @strL);
3478    W.AddJSONEscapeW(pointer(str16),strL);
3479  end;
3480  W.Add('"');
3481end;
3482
3483function JSString.ToJSVal: jsval;
3484begin
3485  Result.asJSString := @self
3486end;
3487
3488function JSString.ToString(cx: PJSContext): string;
3489var
3490  str8: PCChar;
3491  str16: PCChar16;
3492  strL: size_t;
3493begin
3494  if JS_StringHasLatin1Chars(@self) then begin
3495    str8 := JS_GetLatin1StringCharsAndLength(cx, @nullPtr, @self, @strL);
3496    {$ifdef UNICODE}
3497      Result := Latin1AnsiConvert.AnsiToUnicodeString(str8, strL);
3498    {$else}
3499      SetString(Result, str8, strL);
3500    {$endif}
3501  end else begin
3502    str16 := JS_GetTwoByteStringCharsAndLength(cx, @nullPtr, @self, @strL);
3503    RawUnicodeToString(PWideChar(str16),strL,result)
3504  end;
3505end;
3506
3507function JSString.ToSynUnicode(cx: PJSContext): SynUnicode;
3508var
3509  str8: PCChar;
3510  str16: PCChar16;
3511  strL: size_t;
3512begin
3513  if JS_StringHasLatin1Chars(@self) then begin
3514    str8 := JS_GetLatin1StringCharsAndLength(cx, @nullPtr, @self, @strL);
3515    Result := Latin1AnsiConvert.AnsiToUnicodeString(str8, strL);
3516  end else begin
3517    str16 := JS_GetTwoByteStringCharsAndLength(cx, @nullPtr, @self, @strL);
3518    SetString(Result, str16, strL);
3519  end;
3520end;
3521
3522function JSString.ToUTF8(cx: PJSContext): RawUTF8;
3523begin
3524  ToUTF8(cx,result);
3525end;
3526
3527procedure JSString.ToUTF8(cx: PJSContext; out result: RawUTF8);
3528var
3529  str8: PCChar;
3530  str16: PCChar16;
3531  strL: size_t;
3532begin
3533  if JS_StringHasLatin1Chars(@self) then begin
3534    str8 := JS_GetLatin1StringCharsAndLength(cx, @nullPtr, @self, @strL);
3535    result := Latin1AnsiConvert.AnsiBufferToRawUTF8(str8, strL);
3536  end else begin
3537    str16 := JS_GetTwoByteStringCharsAndLength(cx, @nullPtr, @self, @strL);
3538    RawUnicodeToUTF8(str16,strL,result, [ccfNoTrailingZero, ccfReplacementCharacterForUnmatchedSurrogate]);
3539  end;
3540end;
3541
3542function JSString.ToAnsi(cx: PJSContext): AnsiString;
3543var
3544  str8: PCChar;
3545  str16: PCChar16;
3546  strL: size_t;
3547begin
3548  if JS_StringHasLatin1Chars(@self) then begin
3549    str8 := JS_GetLatin1StringCharsAndLength(cx, @nullPtr, @self, @strL);
3550    SetLength(Result, strL);
3551    MoveFast(Pointer(str8)^,Result[1],strL);
3552  end else begin
3553    str16 := JS_GetTwoByteStringCharsAndLength(cx, @nullPtr, @self, @strL);
3554    Result := CurrentAnsiConvert.UnicodeBufferToAnsi(str16,strL);
3555  end;
3556end;
3557
3558procedure JSString.ToVariant(cx: PJSContext; var Value: Variant);
3559var
3560  str8: PCChar;
3561  str16: PCChar16;
3562  strL: size_t;
3563begin
3564  VarClear(Value);
3565  with TVarData(Value) do begin
3566    VType := varSynUnicode;
3567    VAny := nil; // avoid GPF below
3568    if JS_StringHasLatin1Chars(@self) then begin
3569      str8 := JS_GetLatin1StringCharsAndLength(cx, @nullPtr, @self, @strL);
3570      SynUnicode(VAny) := Latin1AnsiConvert.AnsiToUnicodeString(str8, strL);
3571    end else begin
3572      str16 := JS_GetTwoByteStringCharsAndLength(cx, @nullPtr, @self, @strL);
3573      SetString(SynUnicode(VAny), str16, strL);
3574    end;
3575  end;
3576end;
3577
3578procedure JSString.ToUTF8(cx: PJSContext; W: TTextWriter);
3579var
3580  str8: PCChar;
3581  str16: PCChar16;
3582  strL: size_t;
3583  tmpU8: array[0..256*3] of AnsiChar;
3584  U8: PUTF8Char;
3585begin
3586  if JS_StringHasLatin1Chars(@self) then begin
3587    str8 := JS_GetLatin1StringCharsAndLength(cx, @nullPtr, @self, @strL);
3588
3589    if strL>=SizeOf(tmpU8)div 3 then
3590      Getmem(U8,strL*3+1) else
3591      U8 := @tmpU8;
3592    strL := Latin1AnsiConvert.AnsiBufferToUTF8(U8,pointer(str8),strL)-U8;
3593    W.AddNoJSONEscape(pointer(U8), strL);
3594    if U8<>@tmpU8 then
3595      FreeMem(U8);
3596  end else begin
3597    str16 := JS_GetTwoByteStringCharsAndLength(cx, @nullPtr, @self, @strL);
3598    W.AddNoJSONEscapeW(pointer(str16),strL);
3599  end;
3600end;
3601
3602function JSString.HasLatin1Chars: Boolean;
3603begin
3604  result := JS_StringHasLatin1Chars(@self);
3605end;
3606
3607function JSString.GetLatin1StringCharsAndLength(cx: PJSContext;
3608  out len: size_t): PCChar;
3609begin
3610  Result := JS_GetLatin1StringCharsAndLength(cx, @nullPtr, @Self, @len);
3611end;
3612
3613function JSString.Length: size_t;
3614begin
3615  Result := JS_GetStringLength(@self);
3616end;
3617
3618function JSString.GetTwoByteStringCharsAndLength(cx: PJSContext;
3619  out len: size_t): PCChar16;
3620begin
3621  Result := JS_GetTwoByteStringCharsAndLength(cx, @nullPtr, @Self, @len);
3622end;
3623
3624{ JSContext }
3625function JSContext.CheckForInterrupt: Boolean;
3626begin
3627  result := JS_CheckForInterrupt(@Self);
3628end;
3629
3630procedure JSContext.DisableInterruptCallback;
3631begin
3632  JS_DisableInterruptCallback(@self);
3633end;
3634
3635procedure JSContext.AddInterruptCallback(callback: JSInterruptCallback);
3636begin
3637  JS_AddInterruptCallback(@self, callback);
3638end;
3639
3640procedure JSContext.ResetInterruptCallback(disable: boolean);
3641begin
3642  JS_ResetInterruptCallback(@self, disable);
3643end;
3644
3645procedure JSContext.ClearPendingException;
3646begin
3647  JS_ClearPendingException(@self);
3648end;
3649
3650function JSContext.CurrentGlobalOrNull: PJSObject;
3651begin
3652  result := JS_CurrentGlobalOrNull(@self);
3653end;
3654
3655procedure JSContext.Destroy;
3656begin
3657  JS_DestroyContext(@self);
3658end;
3659
3660function JSContext.EnterCompartment(target: PJSObject): PJSCompartment;
3661begin
3662  Result := JS_EnterCompartment(@self, target);
3663end;
3664
3665function JSContext.GetPendingException(out rv: jsval): boolean;
3666begin
3667  Result := JS_GetPendingException(@self, rv);
3668end;
3669
3670function JSContext.GetPrivate: Pointer;
3671begin
3672  result := JS_GetContextPrivate(@self);
3673end;
3674
3675function JSContext.IdToValue(id: jsid; out v: jsval): Boolean;
3676begin
3677  Result := JS_IdToValue(@Self, id, v);
3678end;
3679
3680function JSContext.InitStandardClasses(var obj: PJSObject): boolean;
3681begin
3682  Result := JS_InitStandardClasses(@Self, obj);
3683end;
3684
3685procedure JSContext.SetModuleResolveHook(var hook: PJSFunction);
3686begin
3687  JS_SetModuleResolveHook(@Self, hook);
3688end;
3689
3690function JSContext.NewDateObjectMsec(msec: double): PJSObject;
3691begin
3692  Result := JS_NewDateObjectMsec(@Self, msec);
3693end;
3694
3695procedure JSContext.LeaveCompartment(oldCompartment: PJSCompartment);
3696begin
3697  JS_LeaveCompartment(@Self, oldCompartment);
3698end;
3699
3700procedure JSContext.MaybeGC;
3701begin
3702  JS_MaybeGC(@self);
3703end;
3704
3705function JSContext.NewDateObject(year, mon, mday, hour, min, sec: int32): PJSObject;
3706begin
3707  Result := JS_NewDateObject(@Self, year, mon, mday, hour, min, sec);
3708end;
3709
3710function JS_NewCompartmentOptions(): PJS_CompartmentOptions; cdecl;
3711  external SpiderMonkeyLib name 'SM_NewCompartmentOptions';
3712procedure JS_FreeCompartmentOptions(opt: PJS_CompartmentOptions); cdecl;
3713  external SpiderMonkeyLib name 'SM_FreeCompartmentOptions';
3714
3715function JSContext.NewGlobalObject(clasp: PJSClass; hookOption: OnNewGlobalHookOption): PJSObject;
3716var
3717  Opt: PJS_CompartmentOptions;
3718begin
3719  Opt := JS_NewCompartmentOptions;
3720  Result := JS_NewGlobalObject(@Self, clasp, nil, hookOption, Opt);
3721  JS_FreeCompartmentOptions(Opt);
3722end;
3723
3724function JSContext.NewInt16Array(nelements: uint32): PJSObject;
3725begin
3726  Result := JS_NewInt16Array(@Self, nelements);
3727end;
3728
3729function JSContext.NewInt16ArrayFromArray(var arr: PJSObject): PJSObject;
3730begin
3731  Result := JS_NewInt16ArrayFromArray(@Self, arr);
3732end;
3733
3734function JSContext.NewInt16ArrayWithBuffer(var arrayBuffer: PJSObject;
3735  byteOffset: uint32; length: int32): PJSObject;
3736begin
3737  Result := JS_NewInt16ArrayWithBuffer(@Self, arrayBuffer, byteOffset, length);
3738end;
3739
3740function JSContext.NewInt32Array(nelements: uint32): PJSObject;
3741begin
3742  Result := JS_NewInt32Array(@Self, nelements);
3743end;
3744
3745function JSContext.NewInt32ArrayFromArray(var arr: PJSObject): PJSObject;
3746begin
3747  Result := JS_NewInt32ArrayFromArray(@Self, arr);
3748end;
3749
3750function JSContext.NewInt32ArrayWithBuffer(var arrayBuffer: PJSObject;
3751  byteOffset: uint32; length: int32): PJSObject;
3752begin
3753  Result := JS_NewInt32ArrayWithBuffer(@Self, arrayBuffer, byteOffset, length);
3754end;
3755
3756function JSContext.NewInt8Array(nelements: uint32): PJSObject;
3757begin
3758  Result := JS_NewInt8Array(@Self, nelements);
3759end;
3760
3761function JSContext.NewInt8ArrayFromArray(var arr: PJSObject): PJSObject;
3762begin
3763  Result := JS_NewInt8ArrayFromArray(@Self, arr);
3764end;
3765
3766function JSContext.NewInt8ArrayWithBuffer(var arrayBuffer: PJSObject;
3767  byteOffset: uint32; length: int32): PJSObject;
3768begin
3769  Result := JS_NewInt8ArrayWithBuffer(@Self, arrayBuffer, byteOffset, length);
3770end;
3771
3772function JSContext.NewJSString(TextWide: PWideChar;
3773  TextLen: integer): PJSString;
3774begin
3775  result := JS_NewUCStringCopyN(@Self, pointer(TextWide), TextLen);
3776end;
3777
3778function JSContext.NewJSString(TextAnsi: PAnsiChar; TextLen,
3779  CodePage: integer): PJSString;
3780var short: array[byte] of CChar16; // to avoid temp allocation on heap
3781    buf: PCChar16;
3782begin
3783  if TextLen<(sizeof(short) div 3) then
3784    buf := @short else
3785    GetMem(buf,TextLen*3+2);
3786  result := JS_NewUCStringCopyN(@Self, buf,
3787    TSynAnsiConvert.Engine(CodePage).AnsiBufferToUnicode(PWideChar(buf),TextAnsi,TextLen)-buf);
3788  if buf<>@short then
3789    FreeMem(buf);
3790end;
3791
3792function JSContext.NewJSString(const Value: SynUnicode): PJSString;
3793begin
3794  result := JS_NewUCStringCopyN(@Self, pointer(Value), Length(Value));
3795end;
3796
3797function JSContext.NewObject(clasp: PJSClass): PJSObject;
3798begin
3799  Result := JS_NewObject(@Self, clasp);
3800end;
3801
3802function JSContext.NewObjectWithGivenProto(clasp: PJSClass; var proto: PJSObject): PJSObject;
3803begin
3804  Result := JS_NewObjectWithGivenProto(@Self, clasp, proto);
3805end;
3806
3807procedure JSContext.ReportError(format: PCChar);
3808begin
3809  JS_ReportError(@Self, format);
3810end;
3811
3812procedure JSContext.ReportErrorNumberUC(errorCallback: JSErrorCallback; userRef: pointer; const erroNubmer: uintN);
3813begin
3814  JS_ReportErrorNumberUC(@Self, errorCallback, userRef, erroNubmer);
3815end;
3816
3817procedure JSContext.ReportOutOfMemory;
3818begin
3819  JS_ReportOutOfMemory(@self);
3820end;
3821
3822procedure JSContext.SetPrivate(const Value: Pointer);
3823begin
3824  JS_SetContextPrivate(@self,Value);
3825end;
3826
3827function JSContext.TypeOfValue(v: jsval): JSType;
3828begin
3829  result := JS_TypeOfValue(@Self, v);
3830end;
3831
3832function JSContext.ValueToId(var v: jsval; out id: jsid): Boolean;
3833begin
3834  Result := JS_ValueToId(@Self, v, id);
3835end;
3836
3837function JSContext.WrapObject(var obj: PJSObject): boolean;
3838begin
3839  Result := JS_WrapObject(@Self, obj);
3840end;
3841
3842procedure JSContext.BeginRequest;
3843begin
3844  JS_BeginRequest(@self);
3845end;
3846
3847procedure JSContext.EndRequest;
3848begin
3849  JS_EndRequest(@self);
3850end;
3851
3852function JSContext.GetArrayBufferViewBuffer(var obj: PJSObject;
3853  out isSharedMemory: Boolean): PJSObject;
3854begin
3855  Result := JS_GetArrayBufferViewBuffer(@self, obj, isSharedMemory);
3856end;
3857
3858function JSContext.GetArrayBufferViewBuffer(var obj: PJSObject): PJSObject;
3859var
3860  isSharedMemory: Boolean;
3861begin
3862  Result := JS_GetArrayBufferViewBuffer(@self, obj, isSharedMemory);
3863end;
3864
3865function JSContext.GetIsRunning: boolean;
3866begin
3867  result := JS_IsRunning(@self);
3868end;
3869
3870procedure JSContext.FreeCompileOptions(opt: PJSCompileOptions);
3871begin
3872  JS_FreeCompileOptions(opt);
3873end;
3874
3875procedure JSContext.FreeRootedObject(obj: PJSRootedObject);
3876var
3877  curr: PJSRootedObject;
3878begin
3879  curr := obj.stack.Last;
3880  while curr.ptr = nil do curr := curr.prev;
3881  if curr <> obj then
3882    raise ESMException.Create('FreeRootedObject Stack error');
3883  JS_FreeRootedObject(obj);
3884end;
3885
3886procedure JSContext.FreeRootedString(str: PJSRootedString);
3887begin
3888  if ppointer(str.stack)^ <> str then
3889    raise ESMException.Create('FreeRootedString Stack error');
3890  JS_FreeRootedString(str);
3891end;
3892
3893procedure JSContext.FreeRootedValue(str: PJSRootedValue);
3894begin
3895  if ppointer(str.stack)^ <> str then
3896    raise ESMException.Create('FreeRootedValue Stack error');
3897  JS_FreeRootedValue(str);
3898end;
3899
3900function JSContext.NewRootedObject(obj: PJSObject): PJSRootedObject;
3901begin
3902  Result := JS_NewRootedObject(@Self, obj);
3903end;
3904
3905function JSContext.NewRootedString(obj: PJSString): PJSRootedString;
3906begin
3907  Result := JS_NewRootedString(@Self, obj)
3908end;
3909
3910function JSContext.NewRootedValue(val: jsval): PJSRootedValue;
3911begin
3912  Result := JS_NewRootedValue(@Self, val._l.asBits)
3913end;
3914
3915function JSContext.NewSharedArrayBuffer(nbytes: uint32): PJSObject;
3916begin
3917  Result := JS_NewSharedArrayBuffer(@Self, nbytes);
3918end;
3919
3920function JSContext.NewUint16Array(nelements: uint32): PJSObject;
3921begin
3922  Result := JS_NewUint16Array(@Self, nelements);
3923end;
3924
3925function JSContext.NewUint16ArrayFromArray(var arr: PJSObject): PJSObject;
3926begin
3927  Result := JS_NewUInt16ArrayFromArray(@Self, arr);
3928end;
3929
3930function JSContext.NewUint16ArrayWithBuffer(var arrayBuffer: PJSObject;
3931  byteOffset: uint32; length: int32): PJSObject;
3932begin
3933  Result := JS_NewUInt16ArrayWithBuffer(@Self, arrayBuffer, byteOffset, length);
3934end;
3935
3936function JSContext.NewUint32Array(nelements: uint32): PJSObject;
3937begin
3938  Result := JS_NewUInt32Array(@Self, nelements);
3939end;
3940
3941function JSContext.NewUint32ArrayFromArray(var arr: PJSObject): PJSObject;
3942begin
3943  Result := JS_NewUInt32ArrayFromArray(@Self, arr);
3944end;
3945
3946function JSContext.NewUint32ArrayWithBuffer(var arrayBuffer: PJSObject;
3947  byteOffset: uint32; length: int32): PJSObject;
3948begin
3949  Result := JS_NewUInt32ArrayWithBuffer(@Self, arrayBuffer, byteOffset, length);
3950end;
3951
3952function JSContext.NewUint8Array(nelements: uint32): PJSObject;
3953begin
3954  Result := JS_NewuInt8Array(@Self, nelements);
3955end;
3956
3957function JSContext.NewUint8ArrayFromArray(var arr: PJSObject): PJSObject;
3958begin
3959  Result := JS_NewUInt8ArrayFromArray(@Self, arr);
3960end;
3961
3962function JSContext.NewUint8ArrayWithBuffer(var arrayBuffer: PJSObject;
3963  byteOffset: uint32; length: int32): PJSObject;
3964begin
3965  Result := JS_NewUInt8ArrayWithBuffer(@Self, arrayBuffer, byteOffset, length);
3966end;
3967
3968function JSContext.NewUint8ClampedArray(nelements: uint32): PJSObject;
3969begin
3970  Result := JS_NewUint8ClampedArray(@Self, nelements);
3971end;
3972
3973function JSContext.NewUint8ClampedArrayFromArray(var arr: PJSObject): PJSObject;
3974begin
3975  Result := JS_NewUint8ClampedArrayFromArray(@Self, arr);
3976end;
3977
3978function JSContext.NewUint8ClampedArrayWithBuffer(var arrayBuffer: PJSObject;
3979  byteOffset: uint32; length: int32): PJSObject;
3980begin
3981  Result := JS_NewUint8ClampedArrayWithBuffer(@Self, arrayBuffer, byteOffset, length);
3982end;
3983
3984procedure strFinalizeOp(fin: PJSStringFinalizer; chars: PCChar16);  cdecl;
3985begin
3986
3987end;
3988
3989function JSContext.NewExternalString(const Value: SynUnicode): PJSString;
3990begin
3991  Result := JS_NewExternalString(@Self,  pointer(Value), length(Value), @strFinalizer);
3992end;
3993
3994//function JSContext.AtomizeAndPinString(const Value: SynUnicode): PJSString; {$ifdef HASINLINE}inline;{$endif}
3995//begin
3996//  Result := JS_AtomizeAndPinStringN(@Self,  pointer(Value), length(Value));
3997//end;
3998
3999function JSContext.NewFloat32Array(nelements: uint32): PJSObject;
4000begin
4001  Result := JS_NewFloat32Array(@Self, nelements);
4002end;
4003
4004function JSContext.NewFloat32ArrayFromArray(var arr: PJSObject): PJSObject;
4005begin
4006  Result := JS_NewFloat32ArrayFromArray(@Self, arr);
4007end;
4008
4009function JSContext.NewFloat32ArrayWithBuffer(var arrayBuffer: PJSObject;
4010  byteOffset: uint32; length: int32): PJSObject;
4011begin
4012  Result := JS_NewFloat32ArrayWithBuffer(@Self, arrayBuffer, byteOffset, length);
4013end;
4014
4015function JSContext.NewFloat64Array(nelements: uint32): PJSObject;
4016begin
4017  Result := JS_NewFloat64Array(@Self, nelements);
4018end;
4019
4020function JSContext.NewFloat64ArrayFromArray(var arr: PJSObject): PJSObject;
4021begin
4022  Result := JS_NewFloat64ArrayFromArray(@Self, arr);
4023end;
4024
4025function JSContext.NewFloat64ArrayWithBuffer(var arrayBuffer: PJSObject;
4026  byteOffset: uint32; length: int32): PJSObject;
4027begin
4028  Result := JS_NewFloat64ArrayWithBuffer(@Self, arrayBuffer, byteOffset, length);
4029end;
4030
4031function JSContext.NewFunction(call: JSNative; nargs: uintN; flags: uintN;
4032  name: PCChar): PJSObject;
4033begin
4034  Result := JS_NewFunction(@Self, call, nargs, flags, name);
4035end;
4036
4037function JSContext.DefineDebuggerObject(var obj: PJSObject): boolean;
4038begin
4039  Result := JS_DefineDebuggerObject(@Self, obj);
4040end;
4041
4042function JSContext.NewCompileOptions: PJSCompileOptions;
4043begin
4044  result := JS_NewCompileOptions(@self);
4045end;
4046
4047function JSContext.CompileModule(var obj: PJSObject; opts: PJSCompileOptions;
4048  chars: PCChar16; length: size_t): PJSObject;
4049begin
4050  Result := JS_CompileModule(@Self, obj, opts, chars, length);
4051end;
4052
4053function JSContext.CompileScript(bytes: PCChar;
4054  length: size_t; opts: PJSCompileOptions; out script: PJSScript): boolean;
4055begin
4056  Result := JS_CompileScript(@Self, bytes, length, opts, script);
4057end;
4058
4059function JSContext.CompileUCScript(chars: PCChar16; length: size_t;
4060  opts: PJSCompileOptions; out script: PJSScript): boolean;
4061begin
4062  Result := JS_CompileUCScript(@Self, chars, length, opts, script);
4063end;
4064
4065function JSContext.EvaluateScript(opts: PJSCompileOptions; bytes: PCChar; length: size_t;
4066  out rval: jsval): Boolean;
4067begin
4068  Result := JS_EvaluateScript(@Self, opts, bytes, length, rval);
4069end;
4070
4071function JSContext.EvaluateUCScript(opts: PJSCompileOptions; chars: PCChar16; length: size_t;
4072  out rval: jsval): Boolean;
4073begin
4074  Result := JS_EvaluateUCScript(@Self, opts, chars, length, rval);
4075end;
4076
4077function JSContext.ExecuteScript(var script: PJSScript; out rval: jsval): Boolean;
4078begin
4079  Result := JS_ExecuteScript(@Self, script, rval);
4080end;
4081
4082function JSContext.New(var ctor: PJSObject; argc: uintN; argv: PjsvalVector): PJSObject;
4083var
4084    args: JSHandleValueArray;
4085begin
4086  args.length := argc;
4087  args.elements_ := argv;
4088  Result := JS_New(@self, ctor, args);
4089end;
4090
4091function JSContext.NewArrayBuffer(nbytes: uint32): PJSObject;
4092begin
4093  Result := JS_NewArrayBuffer(@Self, nbytes);
4094end;
4095
4096function JSContext.NewArrayObject(length: size_t;
4097  vector: PjsvalVector): PJSObject;
4098var
4099    contents: JSHandleValueArray;
4100begin
4101  contents.length := length;
4102  contents.elements_ := vector;
4103  Result := JS_NewArrayObject2(@Self, contents);
4104end;
4105
4106function JSContext.NewArrayObject(length: size_t): PJSObject;
4107begin
4108  Result := JS_NewArrayObject(@Self, length);
4109end;
4110
4111function JSContext.InitCTypesClass(var obj: PJSObject): boolean;
4112begin
4113  Result := JS_InitCTypesClass(@Self, obj);
4114end;
4115
4116function JSContext.InitReflectParse(var obj: PJSObject): boolean;
4117begin
4118  Result := JS_InitReflectParse(@Self, obj);
4119end;
4120
4121function JSContext.InitModuleClasses(var obj: PJSObject): boolean;
4122begin
4123  Result := JS_InitModuleClasses(@Self, obj);
4124end;
4125
4126function JSContext.NewJSString(const Value: RawUTF8): PJSString;
4127begin
4128  if Value = '' then
4129    result := JS_GetEmptyString(@self) else
4130    result := JS_NewStringCopyUTF8Z(@self, pointer(Value));
4131end;
4132
4133function JSContextOptions.getOptions(const Index: Integer): Boolean;
4134begin
4135   Result := (pword(@self)^ and (1 shl Index)) <> 0;
4136end;
4137
4138procedure JSContextOptions.setOptions(const Index: Integer;
4139  const Value: Boolean);
4140var
4141  val: uint16;
4142begin
4143  val := 1 shl Index;
4144  if Value then
4145    pword(@self)^ := pword(@self)^ or val
4146  else
4147    pword(@self)^ := pword(@self)^ and (not val);
4148end;
4149
4150procedure JSContext.GC;
4151begin
4152  JS_GC(@self);
4153end;
4154
4155function JSContext.GetEmptyString: PJSString;
4156begin
4157  Result := JS_GetEmptyString(@self);
4158end;
4159
4160function JSContext.GetWarningReporter: JSWarningReporter;
4161begin
4162  Result := JS_GetWarningReporter(@self);
4163end;
4164
4165function JSContext.GetGCParameter(key: JSGCParamKey): uint32;
4166begin
4167  Result := JS_GetGCParameter(@Self, key);
4168end;
4169
4170function JSContext.GetNowMs: int64;
4171begin
4172  Result := JS_Now;
4173end;
4174
4175class function JSContext.CreateNew(maxbytes: uint32; maxNurseryBytes: uint32; parentContext: PJSContext): PJSContext;
4176begin
4177  with TSynFPUException.ForLibraryCode do begin
4178    Result := JS_NewContext(maxbytes, maxNurseryBytes, parentContext);
4179    InitSelfHostedCode(Result);
4180  end;
4181end;
4182
4183function JSContext.GetOptions: PJSContextOptions;
4184begin
4185  Result := JS_GetContextOptions(@self);
4186end;
4187
4188procedure JSContext.RequestInterruptCallback;
4189begin
4190  JS_RequestInterruptCallback(@self);
4191end;
4192
4193procedure JSContext.SetWarningReporter(reporter: JSWarningReporter);
4194begin
4195  JS_SetWarningReporter(@self, reporter);
4196end;
4197
4198procedure JSContext.SetGCParameter(key: JSGCParamKey; const Value: uint32);
4199begin
4200  JS_SetGCParameter(@Self, key, Value);
4201end;
4202
4203procedure JSContext.SetGCParametersBasedOnAvailableMemory(availMem: uint32);
4204begin
4205  JS_SetGCParametersBasedOnAvailableMemory(@Self, availMem);
4206end;
4207
4208procedure JSContext.SetNativeStackQuota(systemCodeStackSize: size_t);
4209begin
4210  JS_SetNativeStackQuota(@Self, systemCodeStackSize);
4211end;
4212
4213{ JSObject }
4214
4215function JSObject.isArray(cx: PJSContext): Boolean;
4216var
4217  _isArray: Boolean;
4218  obj: PJSObject;
4219begin
4220  obj := @Self;
4221  Result := JS_IsArrayObject(cx, obj, _isArray) and _isArray;
4222end;
4223
4224function JSObject.IsArrayBufferObject: Boolean;
4225begin
4226  result := JS_IsArrayBufferObject(@self)
4227end;
4228
4229function JSObject.IsArrayBufferViewObject: Boolean;
4230begin
4231  result := JS_IsArrayBufferViewObject(@self)
4232end;
4233
4234function JSObject.isDate(cx: PJSContext): Boolean;
4235var
4236  _isDate: Boolean;
4237  obj: PJSObject;
4238begin
4239  obj := @Self;
4240  Result := JS_ObjectIsDate(cx, obj, _isDate) and _isDate;
4241end;
4242
4243function JSObject.IsFloat32Array: Boolean;
4244begin
4245  result := JS_IsFloat32Array(@self);
4246end;
4247
4248function JSObject.IsFloat64Array: Boolean;
4249begin
4250  result := JS_IsFloat64Array(@self);
4251end;
4252
4253function JSObject.isFunction(cx: PJSContext): Boolean;
4254begin
4255  Result := JS_ObjectIsFunction(cx, @Self);
4256end;
4257
4258function JSObject.IsInt16Array: Boolean;
4259begin
4260  result := JS_IsInt16Array(@self)
4261end;
4262
4263function JSObject.IsInt32Array: Boolean;
4264begin
4265  result := JS_IsInt32Array(@self)
4266end;
4267
4268function JSObject.IsInt8Array: Boolean;
4269begin
4270  result := JS_IsInt8Array(@self)
4271end;
4272
4273function JSObject.IsMappedArrayBufferObject(obj: PJSObject): Boolean;
4274begin
4275  result := JS_IsMappedArrayBufferObject(@self);
4276end;
4277
4278function JSObject.IsSharedArrayBufferObject: Boolean;
4279begin
4280  result := JS_IsSharedArrayBufferObject(@self)
4281end;
4282
4283function JSObject.IsTypedArrayObject: Boolean;
4284begin
4285  result := JS_IsTypedArrayObject(@self)
4286end;
4287
4288function JSObject.IsUint16Array: Boolean;
4289begin
4290  result := JS_IsUInt16Array(@self)
4291end;
4292
4293function JSObject.IsUint32Array: Boolean;
4294begin
4295  result := JS_IsUInt32Array(@self);
4296end;
4297
4298function JSObject.IsUint8Array: Boolean;
4299begin
4300  result := JS_IsUint8Array(@self)
4301end;
4302
4303function JSObject.IsUint8ClampedArray: Boolean;
4304begin
4305  result := JS_IsUint8ClampedArray(@self)
4306end;
4307
4308function JSObject.GetArrayBufferViewData(out isSharedMemory: Boolean;
4309  nogc: PJSAutoCheckCannotGC): Pointer;
4310begin
4311  result := JS_GetArrayBufferViewData(@self, isSharedMemory, nogc);
4312end;
4313
4314function JSObject.RunMethod(cx: PJSContext; const name: PCChar;
4315  out rval: jsval): Boolean;
4316begin
4317  Result := CallFunctionName(cx, name, 0, nil, rval);
4318end;
4319
4320function JSObject.RunMethod(cx: PJSContext; const name: PCChar; arg: jsval;
4321  out rval: jsval): Boolean;
4322begin
4323  Result := CallFunctionName(cx, name, 1, @arg, rval);
4324end;
4325
4326function JSObject.RunMethod(cx: PJSContext; const name: PCChar;
4327  args: TjsvalDynArray; out rval: jsval): Boolean;
4328begin
4329  Result := CallFunctionName(cx, name, Length(args), @args[0], rval);
4330end;
4331
4332function JSObject.GetInstancePrivate(cx: PJSContext; clasp: PJSClass): Pointer;
4333var
4334  obj: PJSObject;
4335begin
4336  obj := @Self;
4337  result := JS_GetInstancePrivate(cx, obj, clasp, nil);
4338end;
4339
4340function JSObject.GetInt16ArrayData(out isSharedMemory: Boolean;
4341  nogc: PJSAutoCheckCannotGC): Pint16Vector;
4342begin
4343  result := JS_GetInt16ArrayData(@self, isSharedMemory, nogc);
4344end;
4345
4346function JSObject.GetInt32ArrayData(out isSharedMemory: Boolean;
4347  nogc: PJSAutoCheckCannotGC): Pint32Vector;
4348begin
4349  result := JS_GetInt32ArrayData(@self, isSharedMemory, nogc);
4350end;
4351
4352function JSObject.GetInt8ArrayData(out isSharedMemory: Boolean;
4353  nogc: PJSAutoCheckCannotGC): Pint8Vector;
4354begin
4355  result := JS_GetInt8ArrayData(@self, isSharedMemory, nogc);
4356end;
4357
4358function JSObject.GetObjectAsArrayBuffer(out length: uint32;
4359  out Data: Puint8Vector): PJSObject;
4360begin
4361  result := JS_GetObjectAsArrayBuffer(@self, length, data);
4362end;
4363
4364function JSObject.GetObjectAsArrayBufferView(out length: uint32;
4365  out isSharedMemory: Boolean; out Data: Puint8Vector): PJSObject;
4366begin
4367  result := JS_GetObjectAsArrayBufferView(@self, length, isSharedMemory, data);
4368end;
4369
4370function JSObject.GetObjectAsFloat32Array(out length: uint32;
4371  out isSharedMemory: Boolean; out Data: Pfloat32Vector): PJSObject;
4372begin
4373  result := JS_GetObjectAsFloat32Array(@self, length, isSharedMemory, data);
4374end;
4375
4376function JSObject.GetObjectAsFloat64Array(out length: uint32;
4377  out isSharedMemory: Boolean; out Data: Pfloat64Vector): PJSObject;
4378begin
4379  result := JS_GetObjectAsFloat64Array(@self, length, isSharedMemory, data);
4380end;
4381
4382function JSObject.GetObjectAsInt16Array(out length: uint32;
4383  out isSharedMemory: Boolean; out Data: Pint16Vector): PJSObject;
4384begin
4385  result := JS_GetObjectAsInt16Array(@self, length, isSharedMemory, data);
4386end;
4387
4388function JSObject.GetObjectAsInt32Array(out length: uint32;
4389  out isSharedMemory: Boolean; out Data: Pint32Vector): PJSObject;
4390begin
4391  result := JS_GetObjectAsInt32Array(@self, length, isSharedMemory, data);
4392end;
4393
4394function JSObject.GetObjectAsInt8Array(out length: uint32;
4395  out isSharedMemory: Boolean; out Data: Pint8Vector): PJSObject;
4396begin
4397  result := JS_GetObjectAsInt8Array(@self, length, isSharedMemory, data)
4398end;
4399
4400function JSObject.GetObjectAsUint16Array(out length: uint32;
4401  out isSharedMemory: Boolean; out Data: Puint16Vector): PJSObject;
4402begin
4403  result := JS_GetObjectAsUInt16Array(@self, length, isSharedMemory, data);
4404end;
4405
4406function JSObject.GetObjectAsUint32Array(out length: uint32;
4407  out isSharedMemory: Boolean; out Data: Puint32Vector): PJSObject;
4408begin
4409  result := JS_GetObjectAsUint32Array(@self, length, isSharedMemory, data);
4410end;
4411
4412function JSObject.GetObjectAsUint8Array(out length: uint32;
4413  out isSharedMemory: Boolean; out Data: Puint8Vector): PJSObject;
4414begin
4415  result := JS_GetObjectAsUInt8Array(@self, length, isSharedMemory, data)
4416end;
4417
4418function JSObject.GetObjectAsUint8ClampedArray(out length: uint32;
4419  out isSharedMemory: Boolean; out Data: Puint8Vector): PJSObject;
4420begin
4421  result := JS_GetObjectAsUint8ClampedArray(@self, length, isSharedMemory, data)
4422end;
4423
4424function JSObject.GetPrivate: Pointer;
4425begin
4426  Result := JS_GetPrivate(@self);
4427end;
4428
4429function JSObject.GetProperty(cx: PJSContext; const name: PCChar;
4430  out vp: jsval): boolean;
4431var
4432  obj: PJSObject;
4433begin
4434  obj := @Self;
4435  Result := JS_GetProperty(cx, obj, name, vp);
4436end;
4437
4438function JSObject.GetPropertyById(cx: PJSContext; const id: jsid;
4439  out vp: jsval): boolean;
4440var
4441  obj: PJSObject;
4442  _id: jsid;
4443begin
4444  obj := @Self;
4445  _id := id;
4446  Result := JS_GetPropertyById(cx, obj, _id, vp);
4447end;
4448
4449function JSObject.GetPropValue(cx: PJSContext; const name: SynUnicode): jsval;
4450begin
4451  {$ifdef WITHASSERT}
4452  Assert(
4453  {$ENDIF}
4454  GetUCProperty(cx, Pointer(name), Length(name), Result)
4455  {$ifdef WITHASSERT}
4456  );
4457  {$ENDIF}
4458end;
4459
4460function JSObject.GetPrototype(cx: PJSContext; out protop: PJSObject): Boolean;
4461var
4462  obj: PJSObject;
4463begin
4464  obj := @Self;
4465  Result := JS_GetPrototype(cx, obj, protop);
4466end;
4467
4468function JSObject.GetReservedSlot(index: uint32): jsval;
4469begin
4470  result._l.asBits := JS_GetReservedSlot(@Self, index)
4471end;
4472
4473function JSObject.GetSharedArrayBufferByteLength: uint32;
4474begin
4475  result := JS_GetSharedArrayBufferByteLength(@self);
4476end;
4477
4478function JSObject.GetTypedArrayByteLength: uint32;
4479begin
4480  result := JS_GetTypedArrayLength(@self);
4481end;
4482
4483function JSObject.GetTypedArrayByteOffset: uint32;
4484begin
4485  result := JS_GetTypedArrayByteOffset(@self);
4486end;
4487
4488function JSObject.GetTypedArrayLength: uint32;
4489begin
4490  result := JS_GetTypedArrayLength(@self);
4491end;
4492
4493function JSObject.GetTypedArraySharedness: Boolean;
4494begin
4495  result := JS_GetTypedArraySharedness(@self)
4496end;
4497
4498function JSObject.AlreadyHasOwnUCProperty(cx: PJSContext; const name: PCChar16;
4499  namelen: size_t): Boolean;
4500var
4501  obj: PJSObject;
4502  foundp: Boolean;
4503begin
4504  obj := @Self;
4505  Result := JS_AlreadyHasOwnUCProperty(cx, obj, name, namelen, foundp) and foundp;
4506end;
4507
4508function JSObject.ArrayBufferHasData: Boolean;
4509begin
4510  result := JS_ArrayBufferHasData(@self);
4511end;
4512
4513function JSObject.CallFunction(cx: PJSContext; var fun: PJSFunction;
4514  argc: uintN; argv: PjsvalVector; out rval: jsval): Boolean;
4515var obj: PJSObject;
4516    args: JSHandleValueArray;
4517begin
4518  obj := @Self;
4519  args.length := argc;
4520  args.elements_ := argv;
4521  Result := JS_CallFunction(cx, obj, fun, args, rval);
4522end;
4523
4524function JSObject.CallFunctionName(cx: PJSContext; const name: PCChar;
4525  argc: uintN; argv: PjsvalVector; out rval: jsval): Boolean;
4526var obj: PJSObject;
4527    args: JSHandleValueArray;
4528begin
4529  obj := @Self;
4530  args.length := argc;
4531  args.elements_ := argv;
4532  Result := JS_CallFunctionName(cx, obj, name, args, rval);
4533end;
4534
4535function JSObject.CallFunctionValue(cx: PJSContext; val: jsval; argc: uintN;
4536  argv: PjsvalVector; out rval: jsval): Boolean;
4537var obj: PJSObject;
4538    args: JSHandleValueArray;
4539begin
4540  obj := @Self;
4541  args.length := argc;
4542  args.elements_ := argv;
4543  Result := JS_CallFunctionValue(cx, obj, val, args, rval);
4544end;
4545
4546const
4547  /// API extension: OR this into indent to avoid pretty-printing the decompiled
4548  // source resulting from JS_DecompileFunction{,Body}.
4549  JS_DONT_PRETTY_PRINT = $8000;
4550  prettyPrintAr: array[boolean] of uintN = (JS_DONT_PRETTY_PRINT, 0);
4551function JSObject.DecompileFunction(cx: PJSContext;
4552  PrettyPrint: Boolean): PJSString;
4553var
4554  fun: PJSFunction;
4555begin
4556  fun := @self;
4557  Result := JS_DecompileFunction(cx, fun, prettyPrintAr[PrettyPrint]);
4558end;
4559
4560function JSObject.DefineFunction(cx: PJSContext; name: PCChar; call: JSNative;
4561  nargs, attrs: uintN): PJSFunction;
4562var obj: PJSObject;
4563begin
4564  obj := @Self;
4565  Result := JS_DefineFunction(cx, obj, name, call, nargs, attrs);
4566end;
4567
4568function JSObject.DefineFunctions(cx: PJSContext; fs: PJSFunctionSpec;
4569  behavior: JSPropertyDefinitionBehavior): Boolean;
4570var obj: PJSObject;
4571begin
4572  obj := @Self;
4573  Result := JS_DefineFunctions(cx, obj, fs, behavior);
4574end;
4575
4576function JSObject.DefineProperties(cx: PJSContext;
4577  ps: PJSPropertySpec): boolean;
4578var obj: PJSObject;
4579begin
4580  obj := @Self;
4581  result := JS_DefineProperties(cx, obj, ps)
4582end;
4583
4584function JSObject.DefineProperty(cx: PJSContext; const name: PCChar;
4585  const value: jsval; attrs: uint32; getter, setter: JSNative): boolean;
4586var obj: PJSObject;
4587begin
4588  obj := @Self;
4589  result := JS_DefineProperty(cx, obj, name, pjsval(@value)^, attrs, getter, setter)
4590end;
4591
4592function JSObject.DefinePropertyById(cx: PJSContext; var id: jsid;
4593  const value: jsval; attrs: uint32; getter, setter: JSNative): boolean;
4594var obj: PJSObject;
4595begin
4596  obj := @Self;
4597  result := JS_DefinePropertyById(cx, obj, id, pjsval(@value)^, attrs, getter, setter)
4598end;
4599
4600function JSObject.DefineUCFunction(cx: PJSContext; name: PCChar16;
4601  namelen: size_t; call: JSNative; nargs, attrs: uintN): PJSFunction;
4602var obj: PJSObject;
4603begin
4604  obj := @Self;
4605  Result := JS_DefineUCFunction(cx, obj, name, namelen, call, nargs, attrs);
4606end;
4607
4608function JSObject.DefineUCProperty(cx: PJSContext; const name: SynUnicode;
4609  const value: jsval; attrs: uint32; getter, setter: JSNative): Boolean;
4610var obj: PJSObject;
4611begin
4612  obj := @Self;
4613  result := JS_DefineUCProperty(cx, obj, Pointer(name), Length(name), pjsval(@value)^, attrs, getter, setter)
4614end;
4615
4616function JSObject.DefineUCProperty(cx: PJSContext; const name: PCChar16;
4617  namelen: size_t; const value: jsval; attrs: uint32; getter,
4618  setter: JSNative): Boolean;
4619var obj: PJSObject;
4620begin
4621  obj := @Self;
4622  result := JS_DefineUCProperty(cx, obj, name, namelen, pjsval(@value)^, attrs, getter, setter)
4623end;
4624
4625function JSObject.DeleteElement(cx: PJSContext; index: uint32;
4626  out res: JS_ObjectOpResult): Boolean;
4627var obj: PJSObject;
4628begin
4629  obj := @Self;
4630  result := JS_DeleteElement(cx, obj, index, res);
4631end;
4632
4633function JSObject.DeletePropertyById(cx: PJSContext; const id: jsid;
4634  out res: JS_ObjectOpResult): Boolean;
4635var obj: PJSObject;
4636    _id: jsid;
4637begin
4638  obj := @Self;
4639  _id := id;
4640  Result := JS_DeletePropertyById(cx, obj, _id, res);
4641end;
4642
4643function JSObject.Enumerate(cx: PJSContext; out length: size_t; out data: PjsidVector): PJSIdArray;
4644var obj: PJSObject;
4645begin
4646  obj := @Self;
4647  Result := JS_EnumerateToAutoIdVector(cx, obj, length, data);
4648  {$ifdef WITHASSERT}
4649  Assert(Assigned(Result));
4650  {$ENDIF}
4651end;
4652
4653function JSObject.GetUCProperty(cx: PJSContext; const name: PCChar16;
4654  namelen: size_t; out vp: jsval): boolean;
4655var obj: PJSObject;
4656begin
4657  obj := @Self;
4658  Result := JS_GetUCProperty(cx, obj, name, namelen, vp);
4659end;
4660
4661function JSObject.GetUint16ArrayData(out isSharedMemory: Boolean;
4662  nogc: PJSAutoCheckCannotGC): Puint16Vector;
4663begin
4664  result := JS_GetUInt16ArrayData(@self, isSharedMemory, nogc);
4665end;
4666
4667function JSObject.GetUint32ArrayData(out isSharedMemory: Boolean;
4668  nogc: PJSAutoCheckCannotGC): Puint32Vector;
4669begin
4670  result := JS_GetUint32ArrayData(@self, isSharedMemory, nogc);
4671end;
4672
4673function JSObject.GetUint8ArrayData(out isSharedMemory: Boolean;
4674  nogc: PJSAutoCheckCannotGC): Puint8Vector;
4675begin
4676  result := JS_GetUInt8ArrayData(@self, isSharedMemory, nogc);
4677end;
4678
4679function JSObject.GetUint8ArrayData: Puint8Vector;
4680var isShared: Boolean;
4681begin
4682  result := JS_GetUInt8ArrayData(@self, isShared, nil);
4683end;
4684
4685function JSObject.GetUint8ClampedArrayData(out isSharedMemory: Boolean;
4686  nogc: PJSAutoCheckCannotGC): Puint8Vector;
4687begin
4688  result := JS_GetUint8ClampedArrayData(@self, isSharedMemory, nogc);
4689end;
4690
4691function JSObject.HasInstance(cx: PJSContext; var val: jsval): Boolean;
4692var obj: PJSObject;
4693    res: Boolean;
4694begin
4695  obj := @Self;
4696  Result := JS_HasInstance(cx, obj, val, res) and res;
4697end;
4698
4699function JSObject.HasProperty(cx: PJSContext; const name: PCChar): Boolean;
4700var obj: PJSObject;
4701    found: Boolean;
4702begin
4703  obj := @Self;
4704  Result := JS_HasProperty(cx, obj, name, found) and found;
4705end;
4706
4707function JSObject.HasUCProperty(cx: PJSContext; const name: PCChar16;
4708  namelen: size_t; out found: Boolean): Boolean;
4709var obj: PJSObject;
4710begin
4711  obj := @Self;
4712  Result := JS_HasUCProperty(cx, obj, name, namelen, found);
4713end;
4714
4715function JSObject.InitClass(cx: PJSContext; var parent_proto: PJSObject;
4716  clasp: PJSClass; _constructor: JSNative; nargs: Cardinal; ps: PJSPropertySpec;
4717  fs: PJSFunctionSpec; static_ps: PJSPropertySpec;
4718  static_fs: PJSFunctionSpec): PJSObject;
4719var obj: PJSObject;
4720begin
4721  obj := @Self;
4722  Result := JS_InitClass(cx, obj, parent_proto, clasp, _constructor, nargs, ps, fs, static_ps, static_fs);
4723end;
4724
4725function JSObject.GetArrayBufferByteLength: uint32;
4726begin
4727  result := JS_GetArrayBufferByteLength(@self);
4728end;
4729
4730function JSObject.GetArrayBufferData: Puint8Vector;
4731var isShared: Boolean;
4732begin
4733  result := JS_GetArrayBufferData(@self, isShared, nil);
4734end;
4735
4736function JSObject.GetArrayBufferData(out isSharedMemory: Boolean;
4737  nogc: PJSAutoCheckCannotGC): Puint8Vector;
4738begin
4739  result := JS_GetArrayBufferData(@self, isSharedMemory, nogc);
4740end;
4741
4742function JSObject.GetArrayBufferViewByteLength: uint32;
4743begin
4744  result := JS_GetArrayBufferViewByteLength(@self);
4745end;
4746
4747function JSObject.GetArrayBufferViewType: JSArrayBufferViewType;
4748begin
4749  result := JS_GetArrayBufferViewType(@self);
4750end;
4751
4752function JSObject.GetArrayLength(cx: PJSContext; out length: uint32): Boolean;
4753var obj: PJSObject;
4754begin
4755  obj := @Self;
4756  result := JS_GetArrayLength(cx, obj, length);
4757end;
4758
4759function JSObject.GetClass: PJSClass;
4760begin
4761  result := JS_GetClass(@self);
4762end;
4763
4764function JSObject.GetConstructor(cx: PJSContext): PJSObject;
4765var obj: PJSObject;
4766begin
4767  obj := @Self;
4768  Result := JS_GetConstructor(cx, obj);
4769end;
4770
4771function JSObject.GetElement(cx: PJSContext; index: uint32;
4772  out vp: jsval): Boolean;
4773var obj: PJSObject;
4774begin
4775  obj := @Self;
4776  result := JS_GetElement(cx, obj, index, vp);
4777end;
4778
4779function JSObject.GetFloat32ArrayData(out isSharedMemory: Boolean;
4780  nogc: PJSAutoCheckCannotGC): Pfloat32Vector;
4781begin
4782  result := JS_GetFloat32ArrayData(@self, isSharedMemory, nogc);
4783end;
4784
4785function JSObject.GetFloat64ArrayData(out isSharedMemory: Boolean;
4786  nogc: PJSAutoCheckCannotGC): Pfloat64Vector;
4787begin
4788  result := JS_GetFloat64ArrayData(@self, isSharedMemory, nogc);
4789end;
4790
4791function JSObject.GetFunctionId: PJSString;
4792begin
4793  Result := JS_GetFunctionId(@self);
4794end;
4795
4796function JSObject.SetElement(cx: PJSContext; index: uint32;
4797  const vp: jsval): Boolean;
4798var obj: PJSObject;
4799begin
4800  obj := @Self;
4801  result := JS_SetElement(cx, obj, index, pjsval(@vp)^);
4802end;
4803
4804procedure JSObject.SetPrivate(data: Pointer);
4805begin
4806  JS_SetPrivate(@self, data);
4807end;
4808
4809function JSObject.SetProperty(cx: PJSContext; const name: PCChar;
4810  const vp: jsval): Boolean;
4811var obj: PJSObject;
4812begin
4813  obj := @Self;
4814  Result := JS_SetProperty(cx, obj, name, pjsval(@vp)^);
4815end;
4816
4817function JSObject.SetPrototype(cx: PJSContext; var proto: PJSObject): Boolean;
4818var
4819  obj: PJSObject;
4820begin
4821  obj := @Self;
4822  Result := JS_SetPrototype(cx, obj, proto);
4823end;
4824
4825procedure JSObject.SetReservedSlot(index: uint32; v: jsval);
4826begin
4827  JS_SetReservedSlot(@Self, index, v);
4828end;
4829
4830function JSObject.SetUCProperty(cx: PJSContext; const name: PCChar16;
4831  namelen: size_t; const vp: jsval): boolean;
4832var obj: PJSObject;
4833begin
4834  obj := @Self;
4835  Result := JS_SetUCProperty(cx, obj, name, namelen, pjsval(@vp)^);
4836end;
4837
4838function JSObject.ToJSValue: jsval;
4839begin
4840  Result.asObject := @self;
4841end;
4842
4843function JSObject.GetBufferDataAndLength(out data: Puint8Vector; out len: uint32): boolean;
4844var
4845  isShared: boolean;
4846begin
4847  if Self.IsArrayBufferViewObject then begin
4848    Result := Self.GetObjectAsArrayBufferView(len, isShared, data) <> nil;
4849  end else if Self.IsArrayBufferObject then begin
4850    data := Self.GetArrayBufferData;
4851    len := Self.GetArrayBufferByteLength;
4852    Result := True
4853  end else
4854    Result := False;
4855end;
4856
4857{ ESMException }
4858
4859constructor ESMException.CreateWithTrace(const AFileName: RawUTF8; AJSErrorNum, ALineNum: integer; AMessage: string; const AStackTrace: SynUnicode);
4860{$ifndef SM_DEBUG}
4861const
4862  MODULE_START: SynUnicode = #10'Module.';
4863var
4864  appStackEnd: LongInt;
4865{$endif}
4866begin
4867  Create(AMessage);
4868  FJSErrorNum := AJSErrorNum;
4869  if AFileName='' then
4870    FFileName := '<>'
4871  else
4872    FFileName := AFileName;
4873  FLineNum := ALineNum;
4874  {$ifdef SM_DEBUG}
4875  FJSStackTrace := AStackTrace;
4876  {$else}
4877  if length(AStackTrace) = 0 then
4878    FJSStackTrace := ''
4879  else begin
4880    appStackEnd := Pos(MODULE_START, AStackTrace);
4881    if appStackEnd = 0 then
4882      FJSStackTrace := AStackTrace
4883    else
4884      FJSStackTrace := Copy(AStackTrace, 0, appStackEnd - 1); // last \n
4885  end;
4886  {$endif}
4887end;
4888
4889procedure ESMException.WriteFormatted(WR: TTextWriter);
4890begin
4891  WR.AddJSONEscape(pointer(FileName), Length(fileName));
4892    WR.Add(':'); WR.Add(Line);
4893  WR.AddShort('\n\nError: ');
4894  WR.AddJSONEscapeString(Message); WR.AddShort('\n');
4895  {$ifdef SM_DEBUG}
4896    WR.AddJSONEscapeString(Stack);
4897  {$else}
4898   WR.AddJSONEscapeW(pointer(Stack), length(Stack));
4899  {$endif}
4900end;
4901
4902{$ifndef NOEXCEPTIONINTERCEPT}
4903function ESMException.CustomLog(
4904  WR: TTextWriter; const Context: TSynLogExceptionContext): boolean;
4905begin
4906  (Context.EInstance as ESMException).WriteFormatted(WR);
4907  result := true; // do not append a address
4908end;
4909{$endif}
4910
4911{ JSArgRec }
4912
4913function JSArgRec.getArgv: PjsvalVector;
4914begin
4915  Result := @rec.argv;
4916end;
4917
4918function JSArgRec.getCalleObject: PJSObject;
4919begin
4920  Result := rec.calle.asObject;
4921end;
4922
4923function JSArgRec.GetIsConstructing: Boolean;
4924begin
4925  Result := rec.this.IsMagic;
4926end;
4927
4928function JSArgRec.getThis(cx: PJSContext): jsval;
4929begin
4930  if rec.this.IsPrimitive then
4931    result._l.asBits := JS_ComputeThis(cx, rec.calle) else
4932    result := rec.this;
4933end;
4934
4935function JSArgRec.getThisObject(cx: PJSContext): PJSObject;
4936begin
4937  Result := this[cx].asObject;
4938end;
4939
4940{ jsid }
4941
4942const
4943  JSID_TYPE_MASK = $7;
4944
4945function jsid.isString: Boolean;
4946begin
4947  Result := JSIdType(asBits and JSID_TYPE_MASK) = JSID_TYPE_STRING;
4948end;
4949
4950function jsid.asJSString: PJSString;
4951begin
4952{$ifdef WITHASSERT}
4953  Assert(isString);
4954{$endif}
4955  Result := PJSString(asBits);
4956end;
4957
4958{ jsval }
4959
4960const
4961{$ifdef CPU64}
4962  JSVAL_LOWER_INCL_TAG_OF_OBJ_OR_NULL_SET         = JSVAL_TAG_NULL;
4963  JSVAL_UPPER_EXCL_TAG_OF_PRIMITIVE_SET           = JSVAL_TAG_OBJECT;
4964
4965  JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_NUMBER_SET      = JSVAL_SHIFTED_TAG_UNDEFINED;
4966  JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_PRIMITIVE_SET   = JSVAL_SHIFTED_TAG_OBJECT;
4967{$else}
4968  JSVAL_LOWER_INCL_TAG_OF_OBJ_OR_NULL_SET         = JSVAL_TAG_NULL;
4969  JSVAL_UPPER_EXCL_TAG_OF_PRIMITIVE_SET           = JSVAL_TAG_OBJECT;
4970  JSVAL_UPPER_INCL_TAG_OF_NUMBER_SET              = JSVAL_TAG_INT32;
4971  JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET             = JSVAL_TAG_STRING;
4972{$endif}
4973
4974function jsval.getAsBoolean: Boolean;
4975begin
4976  {$ifdef WITHASSERT}
4977  assert(isBoolean);
4978  {$endif}
4979  {$ifdef  CPU64}
4980  Result := Boolean(_l.asBits and JSVAL_PAYLOAD_MASK)
4981  {$else}
4982  Result := Boolean(_l.s.payload.boo);
4983  {$endif}
4984end;
4985
4986function jsval.getAsDate(cx: PJSContext): TDateTime;
4987var oDate: PJSObject;
4988{$ifdef CONSIDER_TIME_IN_Z} // as defined in SyNode.inc
4989    ms: double;
4990    ms64: Int64;
4991    fval: jsval;
4992{$else}
4993    d, m, Y, h, mn, s, ml: Integer;
4994    v, fval: jsval;
4995  function GetIntFuncPropVal(funcName: PWideChar): Integer;
4996  begin
4997    Result := 0;
4998    if oDate.GetUCProperty(cx, pointer(funcName), Length(funcName), fval) then
4999      if oDate.CallFunctionValue(cx, fval, 0, nil, v)   then
5000        Result := v.asInteger;
5001  end;
5002{$endif}
5003begin
5004  oDate := getAsObject;
5005  if not oDate.isDate(cx) then
5006    raise ESMException.create('not a DateTime object');
5007{$ifdef CONSIDER_TIME_IN_Z}
5008  ms := 0;
5009  if oDate.CallFunctionName(cx, PCChar('getTime'), 0, nil, fval) then
5010    ms := fval.asDouble;
5011  if ms = 0 then
5012    raise ESMException.Create('JSDateToDateTime: no getTime() in Date object');
5013  ms64 := Trunc(ms);
5014  // W/O millisec: Result := IncMilliSecond(UnixDateDelta, ms64);
5015  Result := UnixMSTimeToDateTime(ms64);
5016{$else}
5017  d := GetIntFuncPropVal('getDate');
5018  m := GetIntFuncPropVal('getMonth') + 1; //WTF months start from 0
5019  Y := GetIntFuncPropVal('getFullYear');
5020  h := GetIntFuncPropVal('getHours');
5021  mn := GetIntFuncPropVal('getMinutes');
5022  s := GetIntFuncPropVal('getSeconds');
5023  ml := GetIntFuncPropVal('getMilliseconds');
5024  Result := EncodeDateTime(Y, m, d, h, mn, s, ml);
5025{$endif}
5026end;
5027
5028function jsval.getAsDouble: Double;
5029begin
5030  {$ifdef WITHASSERT}
5031  assert(isDouble);
5032  {$endif}
5033  Result := _l.asDouble;
5034end;
5035
5036function jsval.getAsInteger: Integer;
5037begin
5038  {$ifdef WITHASSERT}
5039  assert(isInteger);
5040  {$endif}
5041  {$ifdef CPU64}
5042  Result := int32(_l.asBits);
5043  {$else}
5044  Result := _l.s.payload.i32;
5045  {$endif}
5046end;
5047
5048function writeCallback(const buf: PCChar16; len: uint32; data: pointer): Boolean; cdecl;
5049begin
5050  TTextWriter(data).AddNoJSONEscapeW(pointer(buf),len);
5051  result := true;
5052end;
5053
5054procedure jsval.AddJSON(cx: PJSContext; W: TTextWriter);
5055var
5056//  voidVal: jsval;
5057  T: JSType;
5058begin
5059  if @self=nil then
5060    W.AddShort('null')
5061  else begin
5062    T := cx.TypeOfValue(self);
5063    case T of
5064      JSTYPE_VOID,
5065      JSTYPE_NULL:
5066        W.AddShort('null');
5067      JSTYPE_STRING:
5068        asJSString.ToJSONString(cx,W);
5069      JSTYPE_NUMBER:
5070        if isInteger then
5071          W.Add(asInteger) else
5072          W.AddDouble(asDouble);
5073      JSTYPE_BOOLEAN:
5074        W.Add(asBoolean);
5075      JSTYPE_OBJECT,
5076      JSTYPE_FUNCTION: begin
5077        if not Stringify(cx, nullObj, JSVAL_VOID, writeCallback, pointer(W)) then
5078          ;
5079      end
5080      else
5081        raise ESMException.CreateFmt('Unhandled AddJSON(%d)',[ord(T)]);
5082    end;
5083  end;
5084end;
5085
5086function jsval.getAsJson(cx: PJSContext): RawUTF8;
5087var W: TJSONWriter;
5088begin
5089  W := TJSONWriter.CreateOwnedStream;
5090  try
5091    AddJSON(cx,W);
5092    W.SetText(result);
5093  finally
5094    W.Free;
5095  end;
5096end;
5097
5098function jsval.getAsInt64: Int64;
5099begin
5100  if isInteger then
5101    result := asInteger else
5102  {$ifdef WITHASSERT}
5103  if not isDouble then
5104    raise ESMException.Create('jsval.getAsInt64!') else
5105  {$endif}
5106    result := trunc(asDouble);
5107end;
5108
5109function jsval.getAsObject: PJSObject;
5110{$ifdef  CPU64}
5111var  ptrBits: UInt64 absolute Result;
5112{$endif}
5113begin
5114  {$ifdef WITHASSERT}
5115  assert(isObject);
5116  {$endif}
5117  {$ifdef CPU64}
5118  ptrBits := _l.asBits and JSVAL_PAYLOAD_MASK;
5119  {$ifdef WITHASSERT}
5120  assert(ptrBits and 7 = 0);
5121  {$endif}
5122  {$else}
5123  Result := _l.s.payload.obj;
5124  {$endif}
5125end;
5126
5127function jsval.getIsBoolean: Boolean;
5128begin
5129  {$ifdef CPU64}
5130  Result := _l.asBits shr JSVAL_TAG_SHIFT = JSVAL_TAG_BOOLEAN;
5131  {$else}
5132  Result := _l.s.tag = JSVAL_TAG_BOOLEAN;
5133  {$endif}
5134end;
5135
5136function jsval.getIsDouble: Boolean;
5137begin
5138  {$ifdef CPU64}
5139  Result := _l.asBits <= JSVAL_SHIFTED_TAG_MAX_DOUBLE
5140  {$else}
5141  Result := UInt32(_l.s.tag) <= UInt32(JSVAL_TAG_CLEAR)
5142  {$endif}
5143end;
5144
5145function jsval.getIsInteger: Boolean;
5146begin
5147  {$ifdef CPU64}
5148  Result := _l.asBits shr JSVAL_TAG_SHIFT = JSVAL_TAG_INT32;
5149  {$else}
5150  Result := _l.s.tag = JSVAL_TAG_INT32;
5151  {$endif}
5152end;
5153
5154function jsval.getIsNull: Boolean;
5155begin
5156  {$ifdef CPU64}
5157  Result := _l.asBits  = JSVAL_SHIFTED_TAG_NULL;
5158  {$else}
5159  Result := _l.s.tag = JSVAL_TAG_NULL;
5160  {$endif}
5161end;
5162
5163function jsval.getIsNumber: Boolean;
5164begin
5165  {$ifdef CPU64}
5166  Result := _l.asBits  < JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_NUMBER_SET;
5167  {$else}
5168  {$ifdef WITHASSERT}
5169  assert(_l.s.tag <> JSVAL_TAG_CLEAR);
5170  {$endif}
5171  Result := (UInt32(_l.s.tag) <= UInt32(JSVAL_UPPER_INCL_TAG_OF_NUMBER_SET));
5172  {$endif}
5173end;
5174
5175function jsval.getIsObject: Boolean;
5176begin
5177  {$ifdef CPU64}
5178  {$ifdef WITHASSERT}
5179  Assert(_l.asBits shr JSVAL_TAG_SHIFT <= JSVAL_TAG_OBJECT);
5180  {$endif}
5181  Result := _l.asBits >= JSVAL_SHIFTED_TAG_OBJECT;
5182  {$else}
5183  {$ifdef WITHASSERT}
5184  Assert(_l.s.tag <= JSVAL_TAG_OBJECT);
5185  {$endif}
5186  Result := (UInt32(_l.s.tag) >= UInt32(JSVAL_LOWER_INCL_TAG_OF_OBJ_OR_NULL_SET));
5187  {$endif}
5188end;
5189
5190function jsval.getIsSimpleVariant(cx: PJSContext): Boolean;
5191var
5192  t: JSType;
5193begin
5194  t := ValType(cx);
5195  Result := (t = JSTYPE_VOID) or (t = JSTYPE_NULL) or (t = JSTYPE_STRING)
5196      or (t = JSTYPE_NUMBER) or (t = JSTYPE_BOOLEAN);
5197end;
5198
5199function jsval.getIsString: Boolean;
5200begin
5201  {$ifdef CPU64}
5202  Result := _l.asBits shr JSVAL_TAG_SHIFT = JSVAL_TAG_STRING;
5203  {$else}
5204  Result := _l.s.tag = JSVAL_TAG_STRING;
5205  {$endif}
5206end;
5207
5208function jsval.getIsVoid: Boolean;
5209begin
5210  {$ifdef CPU64}
5211  Result := _l.asBits = JSVAL_SHIFTED_TAG_UNDEFINED;
5212  {$else}
5213  Result := _l.s.tag = JSVAL_TAG_UNDEFINED;
5214  {$endif}
5215end;
5216
5217function jsval.getJSString: PJSString;
5218begin
5219  {$ifdef CPU64}
5220  Result := PJSString(_l.asBits and JSVAL_PAYLOAD_MASK);
5221  {$else}
5222  {$ifdef WITHASSERT}
5223  Assert(isString);
5224  {$endif}
5225  Result := _l.s.payload.str;
5226  {$endif}
5227end;
5228
5229function jsval.getPrivate: Pointer;
5230begin
5231  {$ifdef CPU64}
5232  {$ifdef WITHASSERT}
5233  Assert(_l.asBits and $8000000000000000 = 0);
5234  {$endif}
5235  Result := Pointer(_l.asBits shl 1);
5236  {$else}
5237  {$ifdef WITHASSERT}
5238  Assert(isDouble);
5239  {$endif}
5240  Result := _l.s.payload.ptr;
5241  {$endif}
5242end;
5243
5244function jsval.getSimpleVariant(cx: PJSContext): Variant;
5245var
5246  t: JSType;
5247begin
5248  t := ValType(cx);
5249  case t of
5250    JSTYPE_VOID:
5251      VarClear(result);
5252    JSTYPE_NULL:
5253      SetVariantNull(result);
5254//    JSTYPE_OBJECT:
5255// todo
5256    JSTYPE_STRING:
5257       getJSString.ToVariant(cx,result);
5258    JSTYPE_NUMBER:
5259      if getIsInteger then
5260        result := getAsInteger else
5261        result := getAsDouble;
5262    JSTYPE_BOOLEAN:
5263      result := getAsBoolean;
5264//    JSTYPE_FUNCTION:
5265// todo
5266    else
5267      raise ESMException.CreateFmt('Unhandled ToVariant(%d)',[ord(t)]);
5268  end;
5269
5270end;
5271
5272function jsval.IsMagic: Boolean;
5273begin
5274  {$IFDEF CPU64}
5275  Result := _l.asBits shr JSVAL_TAG_SHIFT = JSVAL_TAG_MAGIC;
5276  {$ELSE}
5277  Result := _l.s.tag = JSVAL_TAG_MAGIC;
5278  {$ENDIF}
5279end;
5280
5281function jsval.IsPrimitive: Boolean;
5282begin
5283  {$IFDEF CPU64}
5284  Result := _l.asBits < JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_PRIMITIVE_SET;
5285  {$ELSE}
5286  Result := (UInt32(_l.s.tag) < UInt32(JSVAL_UPPER_EXCL_TAG_OF_PRIMITIVE_SET));
5287  {$ENDIF}
5288end;
5289
5290function doubleIsInt(Value: Double):boolean; {$ifdef HASINLINE}inline;{$endif}
5291var Value_int64:Int64 absolute Value;
5292    len: Int16;
5293begin
5294  len := (Value_int64 shr 52) and $7FF - $3FF;
5295  result := ((len >= 0) and (len < 31) and ((Value_int64 and (QWORD(1) shl (52 - len)-1)) = 0))
5296  or (Value_int64 = 0) or (Value_int64 = $C1E0000000000000);
5297end;
5298
5299function doubleToInt(Value: Double):Integer; {$ifdef HASINLINE}inline;{$endif}
5300var Value_int64:Int64 absolute Value;
5301    len: Smallint;
5302begin
5303  if Value_int64 = 0 then
5304    result := 0
5305  else begin
5306    len := (Value_int64 shr 52) and $7FF - $3FF;
5307    Result := (Value_int64 and $000FFFFFFFFFFFFF or $0010000000000000) shr (52-len);
5308    if (Value_int64 and $8000000000000000)<>0 then
5309      Result := -Result;
5310  end
5311end;
5312
5313procedure jsval.setAsBoolean(const Value: Boolean);
5314begin
5315  {$ifdef CPU64}
5316  _l.asBits := uint64(ord(Value)) or JSVAL_SHIFTED_TAG_BOOLEAN;
5317  {$else}
5318  _l.s.tag := JSVAL_TAG_BOOLEAN;
5319  _l.s.payload.boo := ord(Value);
5320  {$endif}
5321end;
5322
5323procedure jsval.setAsDate(cx: PJSContext; const Value: TDateTime);
5324var dmsec: double;
5325    unixTime: Int64;
5326  {$ifdef CONSIDER_TIME_IN_Z} // as defined in SyNode.inc
5327    oDate: PJSObject;
5328{$else}
5329    // this realisation is buggy - it ignores timezone rules change history
5330    // for server-side realisation the best solution is to use GMT time here
5331    ms: Word;
5332    STLocal, STUtc: TSystemTime;
5333    TZ: TTimeZoneInformation;
5334    AUTCDateTime: TDateTime;
5335{$endif}
5336begin
5337{$ifdef CONSIDER_TIME_IN_Z}
5338  unixTime := DateTimeToUnixMSTime(Value);
5339  dmsec := unixTime-(unixTime mod 1000);
5340  oDate := cx.NewDateObjectMsec(dmsec);
5341  if not oDate.IsDate(cx) then
5342    raise ESMException.CreateFmt('SetDateTime(%g): not a valid date',[Value]);
5343  setAsObject(oDate);
5344{$else}
5345  DateTimeToSystemTime(Value, STLocal);
5346  GetTimeZoneInformation(TZ);
5347  // use TzSpecificLocalTimeToSystemTime?
5348  TZ.Bias := -TZ.Bias;
5349  TZ.StandardBias := -TZ.StandardBias;
5350  TZ.DaylightBias := -TZ.DaylightBias;
5351  SystemTimeToTzSpecificLocalTime(@TZ, STLocal, STUtc);
5352  ms := STUtc.wMilliseconds;
5353  AUTCDateTime := SystemTimeToDateTime(STUtc);
5354  dmSec := DateTimeToUnixMSTime(AUTCDateTime) + ms;
5355  setAsObject(cx.NewDateObjectMsec(dmsec));
5356{$endif}
5357end;
5358
5359procedure jsval.setAsDouble(const Value: Double);
5360begin
5361  if doubleIsInt(Value) then
5362    asInteger := doubleToInt(Value)
5363  else begin
5364    _l.asDouble := Value;
5365    if ((_l.asBits and $7FF0000000000000) = $7FF0000000000000) and
5366       ((_l.asBits and $000FFFFFFFFFFFFF) <> $0000000000000000) then
5367      _l.asBits := JSVAL_NAN_impl; // canonize NaN
5368  end;
5369end;
5370
5371procedure jsval.setAsInteger(const Value: Integer);
5372
5373begin
5374  {$ifdef CPU64}
5375  _l.asBits := Value;
5376  _l.asBits := uint32(Value) or JSVAL_SHIFTED_TAG_INT32;
5377  {$else}
5378  _l.s.tag := JSVAL_TAG_INT32;
5379  _l.s.payload.i32 := Value;
5380  {$endif}
5381end;
5382
5383procedure jsval.setAsJson(cx: PJSContext; const Value: RawUTF8);
5384var tmp: RawUnicode;
5385    len: integer;
5386begin
5387  if Value='' then begin
5388    SetVoid;
5389  end else begin
5390    len := Utf8DecodeToRawUnicodeUI(Value,tmp);
5391    if not JS_ParseJSON(cx, pointer(tmp), len shr 1, self) then
5392    {$ifdef WITHASSERT}
5393      raise ESMException.Create('jsval.setAsJson!') else
5394    {$ELSE}
5395      SetVoid;
5396    {$endif}
5397  end;
5398end;
5399
5400procedure jsval.setAsInt64(const Value: Int64);
5401begin
5402  if (Value>=Low(integer)) and (Value<=High(integer)) then
5403    setAsInteger(Value) else
5404    setAsDouble(Value);
5405end;
5406
5407procedure jsval.setAsObject(const Value: PJSObject);
5408{$ifdef CPU64}
5409var objBits: UInt64 absolute Value;
5410{$endif}
5411begin
5412  {$ifdef CPU64}
5413  {$ifdef WITHASSERT}
5414  Assert(objBits shr JSVAL_TAG_SHIFT = 0);
5415  {$endif}
5416  _l.asBits := QWord(objBits or JSVAL_SHIFTED_TAG_OBJECT);
5417  {$else}
5418  if Value<>nil then begin
5419    _l.s.tag := JSVAL_TAG_OBJECT;
5420    _l.s.payload.obj := Value;
5421  end else
5422    _l.asBits := JSVAL_NULL_impl;
5423  {$endif}
5424end;
5425
5426procedure jsval.setJSString(const Value: PJSString);
5427{$ifdef CPU64}
5428var strBits: UInt64 absolute Value;
5429{$endif}
5430begin
5431  {$ifdef CPU64}
5432  {$ifdef WITHASSERT}
5433  Assert(strBits shr JSVAL_TAG_SHIFT = 0);
5434  {$endif}
5435  _l.asBits := strBits or JSVAL_SHIFTED_TAG_STRING;
5436  {$else}
5437  {$ifdef WITHASSERT}
5438  assert(str<>nil) ;
5439  {$endif}
5440  _l.s.tag := JSVAL_TAG_STRING;
5441  _l.s.payload.str := Value;
5442  {$endif}
5443end;
5444
5445procedure jsval.setNull;
5446begin
5447  _l.asBits := JSVAL_NULL_impl;
5448end;
5449
5450procedure jsval.setPrivate(const Value: Pointer);
5451{$ifdef CPU64}
5452var ptrBits: UInt64 absolute Value;
5453{$endif}
5454begin
5455  {$ifdef CPU64}
5456  {$ifdef WITHASSERT}
5457  Assert(ptrBits and 1 = 0);
5458  {$endif}
5459  _l.asBits := ptrBits shr 1;
5460  {$ifdef WITHASSERT}
5461  assert(isDouble);
5462  {$endif}
5463  {$else}
5464  {$ifdef WITHASSERT}
5465  assert((uint32(ptr) and 1) = 0);
5466  {$endif}
5467  _l.s.tag := JSValueTag(0);
5468  _l.s.payload.ptr := Value;
5469  {$ifdef WITHASSERT}
5470  assert(isDouble);
5471  {$endif}
5472  {$endif}
5473end;
5474
5475procedure jsval.setSimpleVariant(cx: PJSContext; const Value: Variant);
5476begin
5477  with TVarData(Value) do
5478  case VType of
5479    varNull: setNull;
5480    varEmpty: setVoid;
5481    varBoolean: setAsBoolean(VBoolean);
5482    varSmallint: setAsInteger(VSmallInt);
5483    {$ifndef DELPHI5OROLDER}
5484    varShortInt: setAsInteger(VShortInt);
5485    varWord: setAsInteger(VWord);
5486    varLongWord: setAsInt64(VLongWord);
5487    {$endif}
5488    varByte: setAsInteger(VByte);
5489    varInteger: setAsInteger(VInteger);
5490    {$ifdef FPC}varQword,{$endif}
5491    varInt64: setAsInt64(VInt64);
5492
5493    varSingle: setAsDouble(VSingle);
5494    varDouble: setAsDouble(VDouble);
5495    varCurrency: setAsDouble(VCurrency);
5496    varDate: setAsDate(cx, VDate);
5497    varOleStr: setJSString(cx.NewJSString(WideString(VAny)));
5498    varString: setJSString(cx.NewJSString(VAny,length(RawByteString(VAny)),
5499    {$ifndef UNICODE}   CP_UTF8));
5500    {$else}             StringCodePage(RawByteString(VAny))));
5501    varUString: setJSString(cx.NewJSString(UnicodeString(VAny)));
5502    {$endif}
5503  else
5504    if VType=varByRef or varVariant then
5505      setSimpleVariant(cx,PVariant(VPointer)^) else
5506    if VType=varByRef or varOleStr then
5507      setJSString(cx.NewJSString(PWideString(VAny)^)) else
5508    {$ifdef UNICODE}
5509    if VType=varByRef or varUString then
5510      setJSString(cx.NewJSString(PUnicodeString(VAny)^)) else
5511    {$endif}
5512      raise ESMException.CreateFmt('Unhandled variant type %d',[VType]);
5513  end;
5514end;
5515
5516procedure jsval.setVoid;
5517begin
5518  _l.asBits := JSVAL_VOID_impl;
5519end;
5520
5521function jsval.Stringify(cx: PJSContext; var replacer: PJSObject;
5522  space: jsval; callback: JSONWriteCallback; data: pointer): Boolean;
5523begin
5524  with TSynFPUException.ForLibraryCode do
5525    Result := JS_Stringify(cx, Self, replacer, space, callback, data);
5526end;
5527
5528function jsval.toSource(cx: PJSContext): PJSString;
5529begin
5530  Result := JS_ValueToSource(cx, self);
5531end;
5532
5533function jsval.ValType(cx: PJSContext): JSType;
5534begin
5535  Result := cx.TypeOfValue(self);
5536end;
5537
5538class function jsval.NullValue: jsval;
5539begin
5540  Result.setNull();
5541end;
5542
5543class function jsval.Int32Value(v: integer): jsval;
5544begin
5545  Result.asInteger := v;
5546end;
5547
5548class function jsval.BooleanValue(v: boolean): jsval;
5549begin
5550  Result.asBoolean := v;
5551end;
5552
5553class function jsval.TrueValue: jsval;
5554begin
5555  Result.asBoolean := True;
5556end;
5557
5558class function jsval.FalseValue: jsval;
5559begin
5560  Result.asBoolean := False;
5561end;
5562
5563class function jsval.DoubleValue(v: double): jsval;
5564begin
5565  Result.asDouble := v;
5566end;
5567
5568class function jsval.StringValue(v: PJSString): jsval;
5569begin
5570  Result.asJSString := v;
5571end;
5572
5573class function jsval.ObjectValue(v: PJSObject): jsval;
5574begin
5575  Result.asObject := v;
5576end;
5577
5578class function jsval.Int64Value(v: Int64): jsval;
5579begin
5580  Result.asInt64 := v;
5581end;
5582
5583function SimpleVariantToJSval(cx: PJSContext; val: Variant): jsval;
5584begin
5585  Result.asSimpleVariant[cx] := val;
5586end;
5587
5588function IsSM52Loaded: Boolean;
5589begin
5590  Result := SM52Lib <> INVALID_MODULEHANDLE_VALUE;
5591end;
5592
5593function LoadSM52: Boolean;
5594begin
5595  Result := SM52Lib <> INVALID_MODULEHANDLE_VALUE;
5596  if Result then
5597    Exit;
5598
5599  if SM52Lib = INVALID_MODULEHANDLE_VALUE then
5600    SM52Lib := SafeLoadLibrary(SpiderMonkeyLib);
5601  Result := SM52Lib <> INVALID_MODULEHANDLE_VALUE;
5602  if Result then
5603  begin
5604    JS_Init := TJS_Initialize(GetProcAddress(SM52Lib, 'SM_Initialize')^);
5605    JS_ShutDown := TJS_ShutDown(GetProcAddress(SM52Lib, 'SM_ShutDown')^);
5606    JS_Now := TJS_Now(GetProcAddress(SM52Lib, 'SM_Now')^);
5607    JS_GetEmptyString := TJS_GetEmptyString(GetProcAddress(SM52Lib, 'SM_GetEmptyString')^);
5608    JS_TypeOfValue := TJS_TypeOfValue(GetProcAddress(SM52Lib, 'SM_TypeOfValue')^);
5609    JS_BeginRequest := TJS_BeginRequest(GetProcAddress(SM52Lib, 'SM_BeginRequest')^);
5610    JS_EndRequest := TJS_EndRequest(GetProcAddress(SM52Lib, 'SM_EndRequest')^);
5611    JS_NewContext := TJS_NewContext(GetProcAddress(SM52Lib, 'SM_NewContext')^);
5612    InitSelfHostedCode := TInitSelfHostedCode(GetProcAddress(SM52Lib, 'SM_InitSelfHostedCode')^);
5613    JS_DestroyContext := TJS_DestroyContext(GetProcAddress(SM52Lib, 'SM_DestroyContext')^);
5614    JS_GetContextPrivate := TJS_GetContextPrivate(GetProcAddress(SM52Lib, 'SM_GetContextPrivate')^);
5615    JS_SetContextPrivate := TJS_SetContextPrivate(GetProcAddress(SM52Lib, 'SM_SetContextPrivate')^);
5616    JS_WrapObject := TJS_WrapObject(GetProcAddress(SM52Lib, 'SM_WrapObject')^);
5617    JS_EnterCompartment := TJS_EnterCompartment(GetProcAddress(SM52Lib, 'SM_EnterCompartment')^);
5618    JS_LeaveCompartment := TJS_LeaveCompartment(GetProcAddress(SM52Lib, 'SM_LeaveCompartment')^);
5619    JS_InitStandardClasses := TJS_InitStandardClasses(GetProcAddress(SM52Lib, 'SM_InitStandardClasses')^);
5620    JS_CurrentGlobalOrNull := TJS_CurrentGlobalOrNull(GetProcAddress(SM52Lib, 'SM_CurrentGlobalOrNull')^);
5621    JS_InitReflectParse := TJS_InitReflectParse(GetProcAddress(SM52Lib, 'SM_InitReflectParse')^);
5622    JS_InitCTypesClass := TJS_InitCTypesClass(GetProcAddress(SM52Lib, 'SM_InitCTypesClass')^);
5623    JS_DefineDebuggerObject := TJS_DefineDebuggerObject(GetProcAddress(SM52Lib, 'SM_DefineDebuggerObject')^);
5624    JS_GC := TJS_GC(GetProcAddress(SM52Lib, 'SM_GC')^);
5625    JS_MaybeGC := TJS_MaybeGC(GetProcAddress(SM52Lib, 'SM_MaybeGC')^);
5626    JS_SetGCParameter := TJS_SetGCParameter(GetProcAddress(SM52Lib, 'SM_SetGCParameter')^);
5627    JS_GetGCParameter := TJS_GetGCParameter(GetProcAddress(SM52Lib, 'SM_GetGCParameter')^);
5628    JS_SetGCParametersBasedOnAvailableMemory := TJS_SetGCParametersBasedOnAvailableMemory(GetProcAddress(SM52Lib, 'SM_SetGCParametersBasedOnAvailableMemory')^);
5629    JS_NewExternalString := TJS_NewExternalString(GetProcAddress(SM52Lib, 'SM_NewExternalString')^);
5630    JS_SetNativeStackQuota := TJS_SetNativeStackQuota(GetProcAddress(SM52Lib, 'SM_SetNativeStackQuota')^);
5631    JS_ValueToId := TJS_ValueToId(GetProcAddress(SM52Lib, 'SM_ValueToId')^);
5632    JS_IdToValue := TJS_IdToValue(GetProcAddress(SM52Lib, 'SM_IdToValue')^);
5633    JS_ValueToSource := TJS_ValueToSource(GetProcAddress(SM52Lib, 'SM_ValueToSource')^);
5634    JS_InitClass := TJS_InitClass(GetProcAddress(SM52Lib, 'SM_InitClass')^);
5635    JS_GetClass := TJS_GetClass(GetProcAddress(SM52Lib, 'SM_GetClass')^);
5636    JS_HasInstance := TJS_HasInstance(GetProcAddress(SM52Lib, 'SM_HasInstance')^);
5637    JS_GetPrivate := TJS_GetPrivate(GetProcAddress(SM52Lib, 'SM_GetPrivate')^);
5638    JS_SetPrivate := TJS_SetPrivate(GetProcAddress(SM52Lib, 'SM_SetPrivate')^);
5639    JS_GetConstructor := TJS_GetConstructor(GetProcAddress(SM52Lib, 'SM_GetConstructor')^);
5640    JS_GetInstancePrivate := TJS_GetInstancePrivate(GetProcAddress(SM52Lib, 'SM_GetInstancePrivate')^);
5641    JS_NewGlobalObject := TJS_NewGlobalObject(GetProcAddress(SM52Lib, 'SM_NewGlobalObject')^);
5642    JS_GlobalObjectTraceHook := TJS_GlobalObjectTraceHook(GetProcAddress(SM52Lib, 'SM_GlobalObjectTraceHook')^);
5643    JS_NewObject := TJS_NewObject(GetProcAddress(SM52Lib, 'SM_NewObject')^);
5644    JS_NewObjectWithGivenProto := TJS_NewObjectWithGivenProto(GetProcAddress(SM52Lib, 'SM_NewObjectWithGivenProto')^);
5645    JS_GetPrototype := TJS_GetPrototype(GetProcAddress(SM52Lib, 'SM_GetPrototype')^);
5646    JS_SetPrototype := TJS_SetPrototype(GetProcAddress(SM52Lib, 'SM_SetPrototype')^);
5647    JS_DefinePropertyById := TJS_DefinePropertyById(GetProcAddress(SM52Lib, 'SM_DefinePropertyById')^);
5648    JS_DefineProperty := TJS_DefineProperty(GetProcAddress(SM52Lib, 'SM_DefineProperty')^);
5649    JS_DefineUCProperty := TJS_DefineUCProperty(GetProcAddress(SM52Lib, 'SM_DefineUCProperty')^);
5650    JS_HasProperty := TJS_HasProperty(GetProcAddress(SM52Lib, 'SM_HasProperty')^);
5651    JS_HasUCProperty := TJS_HasUCProperty(GetProcAddress(SM52Lib, 'SM_HasUCProperty')^);
5652    JS_GetPropertyById := TJS_GetPropertyById(GetProcAddress(SM52Lib, 'SM_GetPropertyById')^);
5653    JS_GetProperty := TJS_GetProperty(GetProcAddress(SM52Lib, 'SM_GetProperty')^);
5654    JS_GetUCProperty := TJS_GetUCProperty(GetProcAddress(SM52Lib, 'SM_GetUCProperty')^);
5655    JS_GetElement := TJS_GetElement(GetProcAddress(SM52Lib, 'SM_GetElement')^);
5656    JS_SetProperty := TJS_SetProperty(GetProcAddress(SM52Lib, 'SM_SetProperty')^);
5657    JS_SetUCProperty := TJS_SetUCProperty(GetProcAddress(SM52Lib, 'SM_SetUCProperty')^);
5658    JS_SetElement := TJS_SetElement(GetProcAddress(SM52Lib, 'SM_SetElement')^);
5659    JS_DeletePropertyById := TJS_DeletePropertyById(GetProcAddress(SM52Lib, 'SM_DeletePropertyById')^);
5660    JS_DeleteElement := TJS_DeleteElement(GetProcAddress(SM52Lib, 'SM_DeleteElement')^);
5661    JS_CallFunctionValue := TJS_CallFunctionValue(GetProcAddress(SM52Lib, 'SM_CallFunctionValue')^);
5662    JS_CallFunction := TJS_CallFunction(GetProcAddress(SM52Lib, 'SM_CallFunction')^);
5663    JS_CallFunctionName := TJS_CallFunctionName(GetProcAddress(SM52Lib, 'SM_CallFunctionName')^);
5664    JS_New := TJS_New(GetProcAddress(SM52Lib, 'SM_New')^);
5665    JS_DefineProperties := TJS_DefineProperties(GetProcAddress(SM52Lib, 'SM_DefineProperties')^);
5666    JS_AlreadyHasOwnUCProperty := TJS_AlreadyHasOwnUCProperty(GetProcAddress(SM52Lib, 'SM_AlreadyHasOwnUCProperty')^);
5667    JS_NewArrayObject := TJS_NewArrayObject(GetProcAddress(SM52Lib, 'SM_NewArrayObject')^);
5668    JS_NewArrayObject2 := TJS_NewArrayObject2(GetProcAddress(SM52Lib, 'SM_NewArrayObject2')^);
5669    JS_IsArrayObject := TJS_IsArrayObject(GetProcAddress(SM52Lib, 'SM_IsArrayObject')^);
5670    JS_GetArrayLength := TJS_GetArrayLength(GetProcAddress(SM52Lib, 'SM_GetArrayLength')^);
5671    JS_SetReservedSlot := TJS_SetReservedSlot(GetProcAddress(SM52Lib, 'SM_SetReservedSlot')^);
5672    JS_NewFunction := TJS_NewFunction(GetProcAddress(SM52Lib, 'SM_NewFunction')^);
5673    JS_GetFunctionId := TJS_GetFunctionId(GetProcAddress(SM52Lib, 'SM_GetFunctionId')^);
5674    JS_ObjectIsFunction := TJS_ObjectIsFunction(GetProcAddress(SM52Lib, 'SM_ObjectIsFunction')^);
5675    JS_DefineFunctions := TJS_DefineFunctions(GetProcAddress(SM52Lib, 'SM_DefineFunctions')^);
5676    JS_DefineFunction := TJS_DefineFunction(GetProcAddress(SM52Lib, 'SM_DefineFunction')^);
5677    JS_DefineUCFunction := TJS_DefineUCFunction(GetProcAddress(SM52Lib, 'SM_DefineUCFunction')^);
5678    JS_CompileScript := TJS_CompileScript(GetProcAddress(SM52Lib, 'SM_CompileScript')^);
5679    JS_CompileUCScript := TJS_CompileUCScript(GetProcAddress(SM52Lib, 'SM_CompileUCScript')^);
5680    JS_DecompileFunction := TJS_DecompileFunction(GetProcAddress(SM52Lib, 'SM_DecompileFunction')^);
5681    JS_ExecuteScript := TJS_ExecuteScript(GetProcAddress(SM52Lib, 'SM_ExecuteScript')^);
5682    JS_CheckForInterrupt := TJS_CheckForInterrupt(GetProcAddress(SM52Lib, 'SM_CheckForInterrupt')^);
5683    JS_AddInterruptCallback := TJS_AddInterruptCallback(GetProcAddress(SM52Lib, 'SM_AddInterruptCallback')^);
5684    JS_DisableInterruptCallback := TJS_DisableInterruptCallback(GetProcAddress(SM52Lib, 'SM_DisableInterruptCallback')^);
5685    JS_ResetInterruptCallback := TJS_ResetInterruptCallback(GetProcAddress(SM52Lib, 'SM_ResetInterruptCallback')^);
5686    JS_RequestInterruptCallback := TJS_RequestInterruptCallback(GetProcAddress(SM52Lib, 'SM_RequestInterruptCallback')^);
5687    JS_IsRunning := TJS_IsRunning(GetProcAddress(SM52Lib, 'SM_IsRunning')^);
5688    JS_NewStringCopyN := TJS_NewStringCopyN(GetProcAddress(SM52Lib, 'SM_NewStringCopyN')^);
5689    JS_NewStringCopyUTF8Z := TJS_NewStringCopyUTF8Z(GetProcAddress(SM52Lib, 'SM_NewStringCopyUTF8Z')^);
5690    JS_GetEmptyStringValue := TJS_GetEmptyStringValue(GetProcAddress(SM52Lib, 'SM_GetEmptyStringValue')^);
5691    JS_NewUCStringCopyN := TJS_NewUCStringCopyN(GetProcAddress(SM52Lib, 'SM_NewUCStringCopyN')^);
5692    JS_GetStringLength := TJS_GetStringLength(GetProcAddress(SM52Lib, 'SM_GetStringLength')^);
5693    JS_StringHasLatin1Chars := TJS_StringHasLatin1Chars(GetProcAddress(SM52Lib, 'SM_StringHasLatin1Chars')^);
5694    JS_GetLatin1StringCharsAndLength := TJS_GetLatin1StringCharsAndLength(GetProcAddress(SM52Lib, 'SM_GetLatin1StringCharsAndLength')^);
5695    JS_GetTwoByteStringCharsAndLength := TJS_GetTwoByteStringCharsAndLength(GetProcAddress(SM52Lib, 'SM_GetTwoByteStringCharsAndLength')^);
5696    JS_Stringify := TJS_Stringify(GetProcAddress(SM52Lib, 'SM_Stringify')^);
5697    JS_ParseJSON := TJS_ParseJSON(GetProcAddress(SM52Lib, 'SM_ParseJSON')^);
5698    JS_ReportOutOfMemory := TJS_ReportOutOfMemory(GetProcAddress(SM52Lib, 'SM_ReportOutOfMemory')^);
5699    JS_GetWarningReporter := TJS_GetWarningReporter(GetProcAddress(SM52Lib, 'SM_GetWarningReporter')^);
5700    JS_SetWarningReporter := TJS_SetWarningReporter(GetProcAddress(SM52Lib, 'SM_SetWarningReporter')^);
5701    JS_NewDateObject := TJS_NewDateObject(GetProcAddress(SM52Lib, 'SM_NewDateObject')^);
5702    JS_ObjectIsDate := TJS_ObjectIsDate(GetProcAddress(SM52Lib, 'SM_ObjectIsDate')^);
5703    JS_IsExceptionPending := TJS_IsExceptionPending(GetProcAddress(SM52Lib, 'SM_IsExceptionPending')^);
5704    JS_GetPendingException := TJS_GetPendingException(GetProcAddress(SM52Lib, 'SM_GetPendingException')^);
5705    JS_SetPendingException := TJS_SetPendingException(GetProcAddress(SM52Lib, 'SM_SetPendingException')^);
5706    JS_ClearPendingException := TJS_ClearPendingException(GetProcAddress(SM52Lib, 'SM_ClearPendingException')^);
5707    JS_ErrorFromException := TJS_ErrorFromException(GetProcAddress(SM52Lib, 'SM_ErrorFromException')^);
5708    JS_EvaluateScript := TJS_EvaluateScript(GetProcAddress(SM52Lib, 'SM_EvaluateScript')^);
5709    JS_EvaluateUCScript := TJS_EvaluateUCScript(GetProcAddress(SM52Lib, 'SM_EvaluateUCScript')^);
5710    JS_ComputeThis := TJS_ComputeThis(GetProcAddress(SM52Lib, 'SM_ComputeThis')^);
5711    JS_NewInt8Array := TJS_NewInt8Array(GetProcAddress(SM52Lib, 'SM_NewInt8Array')^);
5712    JS_NewUint8Array := TJS_NewUint8Array(GetProcAddress(SM52Lib, 'SM_NewUint8Array')^);
5713    JS_NewUint8ClampedArray := TJS_NewUint8ClampedArray(GetProcAddress(SM52Lib, 'SM_NewUint8ClampedArray')^);
5714    JS_NewInt16Array := TJS_NewInt16Array(GetProcAddress(SM52Lib, 'SM_NewInt16Array')^);
5715    JS_NewUint16Array := TJS_NewUint16Array(GetProcAddress(SM52Lib, 'SM_NewUint16Array')^);
5716    JS_NewInt32Array := TJS_NewInt32Array(GetProcAddress(SM52Lib, 'SM_NewInt32Array')^);
5717    JS_NewUint32Array := TJS_NewUint32Array(GetProcAddress(SM52Lib, 'SM_NewUint32Array')^);
5718    JS_NewFloat32Array := TJS_NewFloat32Array(GetProcAddress(SM52Lib, 'SM_NewFloat32Array')^);
5719    JS_NewFloat64Array := TJS_NewFloat64Array(GetProcAddress(SM52Lib, 'SM_NewFloat64Array')^);
5720    JS_NewInt8ArrayFromArray := TJS_NewInt8ArrayFromArray(GetProcAddress(SM52Lib, 'SM_NewInt8ArrayFromArray')^);
5721    JS_NewUint8ArrayFromArray := TJS_NewUint8ArrayFromArray(GetProcAddress(SM52Lib, 'SM_NewUint8ArrayFromArray')^);
5722    JS_NewUint8ClampedArrayFromArray := TJS_NewUint8ClampedArrayFromArray(GetProcAddress(SM52Lib, 'SM_NewUint8ClampedArrayFromArray')^);
5723    JS_NewInt16ArrayFromArray := TJS_NewInt16ArrayFromArray(GetProcAddress(SM52Lib, 'SM_NewInt16ArrayFromArray')^);
5724    JS_NewUint16ArrayFromArray := TJS_NewUint16ArrayFromArray(GetProcAddress(SM52Lib, 'SM_NewUint16ArrayFromArray')^);
5725    JS_NewInt32ArrayFromArray := TJS_NewInt32ArrayFromArray(GetProcAddress(SM52Lib, 'SM_NewInt32ArrayFromArray')^);
5726    JS_NewUint32ArrayFromArray := TJS_NewUint32ArrayFromArray(GetProcAddress(SM52Lib, 'SM_NewUint32ArrayFromArray')^);
5727    JS_NewFloat32ArrayFromArray := TJS_NewFloat32ArrayFromArray(GetProcAddress(SM52Lib, 'SM_NewFloat32ArrayFromArray')^);
5728    JS_NewFloat64ArrayFromArray := TJS_NewFloat64ArrayFromArray(GetProcAddress(SM52Lib, 'SM_NewFloat64ArrayFromArray')^);
5729    JS_NewInt8ArrayWithBuffer := TJS_NewInt8ArrayWithBuffer(GetProcAddress(SM52Lib, 'SM_NewInt8ArrayWithBuffer')^);
5730    JS_NewUint8ArrayWithBuffer := TJS_NewUint8ArrayWithBuffer(GetProcAddress(SM52Lib, 'SM_NewUint8ArrayWithBuffer')^);
5731    JS_NewUint8ClampedArrayWithBuffer := TJS_NewUint8ClampedArrayWithBuffer(GetProcAddress(SM52Lib, 'SM_NewUint8ClampedArrayWithBuffer')^);
5732    JS_NewInt16ArrayWithBuffer := TJS_NewInt16ArrayWithBuffer(GetProcAddress(SM52Lib, 'SM_NewInt16ArrayWithBuffer')^);
5733    JS_NewUint16ArrayWithBuffer := TJS_NewUint16ArrayWithBuffer(GetProcAddress(SM52Lib, 'SM_NewUint16ArrayWithBuffer')^);
5734    JS_NewInt32ArrayWithBuffer := TJS_NewInt32ArrayWithBuffer(GetProcAddress(SM52Lib, 'SM_NewInt32ArrayWithBuffer')^);
5735    JS_NewUint32ArrayWithBuffer := TJS_NewUint32ArrayWithBuffer(GetProcAddress(SM52Lib, 'SM_NewUint32ArrayWithBuffer')^);
5736    JS_NewFloat32ArrayWithBuffer := TJS_NewFloat32ArrayWithBuffer(GetProcAddress(SM52Lib, 'SM_NewFloat32ArrayWithBuffer')^);
5737    JS_NewFloat64ArrayWithBuffer := TJS_NewFloat64ArrayWithBuffer(GetProcAddress(SM52Lib, 'SM_NewFloat64ArrayWithBuffer')^);
5738    JS_NewSharedArrayBuffer := TJS_NewSharedArrayBuffer(GetProcAddress(SM52Lib, 'SM_NewSharedArrayBuffer')^);
5739    JS_NewArrayBuffer := TJS_NewArrayBuffer(GetProcAddress(SM52Lib, 'SM_NewArrayBuffer')^);
5740    JS_IsTypedArrayObject := TJS_IsTypedArrayObject(GetProcAddress(SM52Lib, 'SM_IsTypedArrayObject')^);
5741    JS_IsArrayBufferViewObject := TJS_IsArrayBufferViewObject(GetProcAddress(SM52Lib, 'SM_IsArrayBufferViewObject')^);
5742    JS_IsInt8Array := TJS_IsInt8Array(GetProcAddress(SM52Lib, 'SM_IsInt8Array')^);
5743    JS_IsUint8Array := TJS_IsUint8Array(GetProcAddress(SM52Lib, 'SM_IsUint8Array')^);
5744    JS_IsUint8ClampedArray := TJS_IsUint8ClampedArray(GetProcAddress(SM52Lib, 'SM_IsUint8ClampedArray')^);
5745    JS_IsInt16Array := TJS_IsInt16Array(GetProcAddress(SM52Lib, 'SM_IsInt16Array')^);
5746    JS_IsUint16Array := TJS_IsUint16Array(GetProcAddress(SM52Lib, 'SM_IsUint16Array')^);
5747    JS_IsInt32Array := TJS_IsInt32Array(GetProcAddress(SM52Lib, 'SM_IsInt32Array')^);
5748    JS_IsUint32Array := TJS_IsUint32Array(GetProcAddress(SM52Lib, 'SM_IsUint32Array')^);
5749    JS_IsFloat32Array := TJS_IsFloat32Array(GetProcAddress(SM52Lib, 'SM_IsFloat32Array')^);
5750    JS_IsFloat64Array := TJS_IsFloat64Array(GetProcAddress(SM52Lib, 'SM_IsFloat64Array')^);
5751    JS_GetTypedArraySharedness := TJS_GetTypedArraySharedness(GetProcAddress(SM52Lib, 'SM_GetTypedArraySharedness')^);
5752    JS_GetObjectAsInt8Array := TJS_GetObjectAsInt8Array(GetProcAddress(SM52Lib, 'SM_GetObjectAsInt8Array')^);
5753    JS_GetObjectAsUint8Array := TJS_GetObjectAsUint8Array(GetProcAddress(SM52Lib, 'SM_GetObjectAsUint8Array')^);
5754    JS_GetObjectAsUint8ClampedArray := TJS_GetObjectAsUint8ClampedArray(GetProcAddress(SM52Lib, 'SM_GetObjectAsUint8ClampedArray')^);
5755    JS_GetObjectAsInt16Array := TJS_GetObjectAsInt16Array(GetProcAddress(SM52Lib, 'SM_GetObjectAsInt16Array')^);
5756    JS_GetObjectAsUint16Array := TJS_GetObjectAsUint16Array(GetProcAddress(SM52Lib, 'SM_GetObjectAsUint16Array')^);
5757    JS_GetObjectAsInt32Array := TJS_GetObjectAsInt32Array(GetProcAddress(SM52Lib, 'SM_GetObjectAsInt32Array')^);
5758    JS_GetObjectAsUint32Array := TJS_GetObjectAsUint32Array(GetProcAddress(SM52Lib, 'SM_GetObjectAsUint32Array')^);
5759    JS_GetObjectAsFloat32Array := TJS_GetObjectAsFloat32Array(GetProcAddress(SM52Lib, 'SM_GetObjectAsFloat32Array')^);
5760    JS_GetObjectAsFloat64Array := TJS_GetObjectAsFloat64Array(GetProcAddress(SM52Lib, 'SM_GetObjectAsFloat64Array')^);
5761    JS_GetObjectAsArrayBufferView := TJS_GetObjectAsArrayBufferView(GetProcAddress(SM52Lib, 'SM_GetObjectAsArrayBufferView')^);
5762    JS_GetObjectAsArrayBuffer := TJS_GetObjectAsArrayBuffer(GetProcAddress(SM52Lib, 'SM_GetObjectAsArrayBuffer')^);
5763    JS_GetArrayBufferViewType := TJS_GetArrayBufferViewType(GetProcAddress(SM52Lib, 'SM_GetArrayBufferViewType')^);
5764    JS_IsArrayBufferObject := TJS_IsArrayBufferObject(GetProcAddress(SM52Lib, 'SM_IsArrayBufferObject')^);
5765    JS_IsSharedArrayBufferObject := TJS_IsSharedArrayBufferObject(GetProcAddress(SM52Lib, 'SM_IsSharedArrayBufferObject')^);
5766    JS_GetArrayBufferByteLength := TJS_GetArrayBufferByteLength(GetProcAddress(SM52Lib, 'SM_GetArrayBufferByteLength')^);
5767    JS_GetSharedArrayBufferByteLength := TJS_GetSharedArrayBufferByteLength(GetProcAddress(SM52Lib, 'SM_GetSharedArrayBufferByteLength')^);
5768    JS_ArrayBufferHasData := TJS_ArrayBufferHasData(GetProcAddress(SM52Lib, 'SM_ArrayBufferHasData')^);
5769    JS_GetArrayBufferData := TJS_GetArrayBufferData(GetProcAddress(SM52Lib, 'SM_GetArrayBufferData')^);
5770    JS_IsMappedArrayBufferObject := TJS_IsMappedArrayBufferObject(GetProcAddress(SM52Lib, 'SM_IsMappedArrayBufferObject')^);
5771    JS_GetTypedArrayLength := TJS_GetTypedArrayLength(GetProcAddress(SM52Lib, 'SM_GetTypedArrayLength')^);
5772    JS_GetTypedArrayByteOffset := TJS_GetTypedArrayByteOffset(GetProcAddress(SM52Lib, 'SM_GetTypedArrayByteOffset')^);
5773    JS_GetTypedArrayByteLength := TJS_GetTypedArrayByteLength(GetProcAddress(SM52Lib, 'SM_GetTypedArrayByteLength')^);
5774    JS_GetArrayBufferViewByteLength := TJS_GetArrayBufferViewByteLength(GetProcAddress(SM52Lib, 'SM_GetArrayBufferViewByteLength')^);
5775    JS_GetInt8ArrayData := TJS_GetInt8ArrayData(GetProcAddress(SM52Lib, 'SM_GetInt8ArrayData')^);
5776    JS_GetUint8ArrayData := TJS_GetUint8ArrayData(GetProcAddress(SM52Lib, 'SM_GetUint8ArrayData')^);
5777    JS_GetUint8ClampedArrayData := TJS_GetUint8ClampedArrayData(GetProcAddress(SM52Lib, 'SM_GetUint8ClampedArrayData')^);
5778    JS_GetInt16ArrayData := TJS_GetInt16ArrayData(GetProcAddress(SM52Lib, 'SM_GetInt16ArrayData')^);
5779    JS_GetUint16ArrayData := TJS_GetUint16ArrayData(GetProcAddress(SM52Lib, 'SM_GetUint16ArrayData')^);
5780    JS_GetInt32ArrayData := TJS_GetInt32ArrayData(GetProcAddress(SM52Lib, 'SM_GetInt32ArrayData')^);
5781    JS_GetUint32ArrayData := TJS_GetUint32ArrayData(GetProcAddress(SM52Lib, 'SM_GetUint32ArrayData')^);
5782    JS_GetFloat32ArrayData := TJS_GetFloat32ArrayData(GetProcAddress(SM52Lib, 'SM_GetFloat32ArrayData')^);
5783    JS_GetFloat64ArrayData := TJS_GetFloat64ArrayData(GetProcAddress(SM52Lib, 'SM_GetFloat64ArrayData')^);
5784    JS_GetArrayBufferViewData := TJS_GetArrayBufferViewData(GetProcAddress(SM52Lib, 'SM_GetArrayBufferViewData')^);
5785    JS_GetArrayBufferViewBuffer := TJS_GetArrayBufferViewBuffer(GetProcAddress(SM52Lib, 'SM_GetArrayBufferViewBuffer')^);
5786    JS_SetModuleResolveHook := TJS_SetModuleResolveHook(GetProcAddress(SM52Lib, 'SM_SetModuleResolveHook')^);
5787  end;
5788end;
5789
5790procedure UnloadSM52;
5791begin
5792  if SM52Lib <> INVALID_MODULEHANDLE_VALUE then
5793    FreeLibrary(SM52Lib);
5794  SM52Lib := INVALID_MODULEHANDLE_VALUE;
5795end;
5796
5797initialization
5798
5799  Latin1AnsiConvert := TSynAnsiConvert.Engine(CODEPAGE_LATIN1);
5800
5801  LoadSM52;
5802
5803finalization
5804
5805  UnloadSM52;
5806
5807end.