/// SpiderMonkey 45/52 *.h header port to Delphi // if defined SM52 condition then SpiderMonkey 52 is used // - this unit is a part of the freeware Synopse framework, // licensed under a MPL/GPL/LGPL tri-license; version 1.18 unit SpiderMonkey; { This file is part of Synopse framework. Synopse framework. Copyright (c) Arnaud Bouchez Synopse Informatique - http://synopse.info SyNode for mORMot Copyright (c) Pavel Mashlyakovsky & Vadim Orel pavel.mash at gmail.com *** BEGIN LICENSE BLOCK ***** Version: MPL 1.1/GPL 2.0/LGPL 2.1 The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. The Initial Developer of the Original Code is Pavel Mashlyakovsky & Vadim Orel. Portions created by the Initial Developer are Copyright (c) the Initial Developer. All Rights Reserved. Contributor(s): - Arnaud Bouchez - Vadim Orel - Pavel Mashlyakovsky - win2014 Alternatively, the contents of this file may be used under the terms of either the GNU General Public License Version 2 or later (the "GPL"), or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), in which case the provisions of the GPL or the LGPL are applicable instead of those above. If you wish to allow use of your version of this file only under the terms of either the GPL or the LGPL, and not to allow others to use your version of this file under the terms of the MPL, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the GPL or the LGPL. If you do not delete the provisions above, a recipient may use your version of this file under the terms of any one of the MPL, the GPL or the LGPL. ***** END LICENSE BLOCK ***** Version 1.18 - initial release. Use SpiderMonkey 45 } {$I Synopse.inc} // define HASINLINE CPU32 CPU64 OWNNORMTOUPPER {$I SyNode.inc} //define WITHASSERT interface uses {$ifdef MSWINDOWS} Windows, {$endif} SynCommons, SynTable, SynLog, SysUtils; type JSUnknown = Pointer; //Use this type for developping. In real case comment it and check than you use only known types {$ifndef UNICODE} /// 8 bit signed integer type for C APIs int8 = ShortInt; /// 8 bit unsigned integer type for C APIs uint8 = Byte; /// 16 bit signed integer type for C APIs int16 = Smallint; /// 16 bit unsigned integer type for C APIs uint16 = Word; /// 32 bit signed integer type for C APIs int32 = Integer; /// 32 bit unsigned integer type for C APIs uint32 = Cardinal; {$endif} {$ifndef ISDELPHIXE2} uintptr = PtrUInt; {$endif} uintN = PtrUInt; {.$ifndef FPC} /// variable type used to store a buffer size (in bytes) for SMAPI size_t = PtrUInt; {.$endif} psize_t = ^size_t; CChar = AnsiChar; PCChar = PAnsiChar; CChar16 = WideChar; PCChar16 = PWideChar; PPCChar16 = ^PCChar16; {$Z4} JSType = ( JSTYPE_VOID = 0, // undefined JSTYPE_OBJECT = 1, // object JSTYPE_FUNCTION = 2, // function JSTYPE_STRING = 3, // string JSTYPE_NUMBER = 4, // number JSTYPE_BOOLEAN = 5, // boolean JSTYPE_NULL = 6, // null JSTYPE_SYMBOL = 7, //symbol JSTYPE_LIMIT = 8 ); JSGCParamKey = ( // Maximum nominal heap before last ditch GC. JSGC_MAX_BYTES = 0, // Number of JS_malloc bytes before last ditch GC. JSGC_MAX_MALLOC_BYTES = 1, // Amount of bytes allocated by the GC. JSGC_BYTES = 3, // Number of times GC has been invoked. Includes both major and minor GC. JSGC_NUMBER = 4, // Max size of the code cache in bytes. JSGC_MAX_CODE_CACHE_BYTES = 5, // Select GC mode. JSGC_MODE = 6, // Number of cached empty GC chunks. JSGC_UNUSED_CHUNKS = 7, // Total number of allocated GC chunks. JSGC_TOTAL_CHUNKS = 8, // Max milliseconds to spend in an incremental GC slice. JSGC_SLICE_TIME_BUDGET = 9, // Maximum size the GC mark stack can grow to. JSGC_MARK_STACK_LIMIT = 10, // GCs less than this far apart in time will be considered 'high-frequency GCs'. // See setGCLastBytes in jsgc.cpp. JSGC_HIGH_FREQUENCY_TIME_LIMIT = 11, // Start of dynamic heap growth. JSGC_HIGH_FREQUENCY_LOW_LIMIT = 12, // End of dynamic heap growth. JSGC_HIGH_FREQUENCY_HIGH_LIMIT = 13, // Upper bound of heap growth. JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX = 14, // Lower bound of heap growth. JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN = 15, // Heap growth for low frequency GCs. JSGC_LOW_FREQUENCY_HEAP_GROWTH = 16, // If false, the heap growth factor is fixed at 3. If true, it is determined // based on whether GCs are high- or low- frequency. JSGC_DYNAMIC_HEAP_GROWTH = 17, // If true, high-frequency GCs will use a longer mark slice. JSGC_DYNAMIC_MARK_SLICE = 18, // Lower limit after which we limit the heap growth. JSGC_ALLOCATION_THRESHOLD = 19, // We try to keep at least this many unused chunks in the free chunk pool at // all times, even after a shrinking GC. JSGC_MIN_EMPTY_CHUNK_COUNT = 21, // We never keep more than this many unused chunks in the free chunk pool. JSGC_MAX_EMPTY_CHUNK_COUNT = 22, // Whether compacting GC is enabled. JSGC_COMPACTING_ENABLED = 23 // If true, painting can trigger IGC slices. ,JSGC_REFRESH_FRAME_SLICES_ENABLED = 24 ); JSGCMode = ( // Perform only global GCs. JSGC_MODE_GLOBAL = 0, // Perform per-compartment GCs until too much garbage has accumulated. JSGC_MODE_COMPARTMENT = 1, // Collect in short time slices rather than all at once. Implies // JSGC_MODE_COMPARTMENT. JSGC_MODE_INCREMENTAL = 2 ); JSVersion = ( /// Run-time version enumeration corresponding to an identified version JSVERSION_UNKNOWN = -1, /// Run-time version enumeration corresponding to default version JSVERSION_DEFAULT = 0, JSVERSION_ECMA_3 = 148, /// Run-time version enumeration corresponding to 1.6 JSVERSION_1_6 = 160, /// Run-time version enumeration corresponding to 1.7 JSVERSION_1_7 = 170, /// Run-time version enumeration corresponding to 1.8 JSVERSION_1_8 = 180, /// Run-time version enumeration corresponding to ECMA standard 5, i.e. 1.8.5 JSVERSION_ECMA_5 = 185 ); /// This enum is used to select if properties with JSPROP_DEFINE_LATE flag // should be defined on the object. // Normal JSAPI consumers probably always want DefineAllProperties here. JSPropertyDefinitionBehavior = ( DefineAllProperties, OnlyDefineLateProperties, DontDefineLateProperties ); /// During global creation, we fire notifications to callbacks registered // via the Debugger API. These callbacks are arbitrary script, and can touch // the global in arbitrary ways. When that happens, the global should not be // in a half-baked state. But this creates a problem for consumers that need // to set slots on the global to put it in a consistent state. // - This API provides a way for consumers to set slots atomically (immediately // after the global is created), before any debugger hooks are fired. It's // unfortunately on the clunky side, but that's the way the cookie crumbles. // - If callers have no additional state on the global to set up, they may pass // |FireOnNewGlobalHook| to JS_NewGlobalObject, which causes that function to // fire the hook as its final act before returning. Otherwise, callers should // pass |DontFireOnNewGlobalHook|, which means that they are responsible for // invoking JS_FireOnNewGlobalObject upon successfully creating the global. If // an error occurs and the operation aborts, callers should skip firing the // hook. But otherwise, callers must take care to fire the hook exactly once // before compiling any script in the global's scope (we have assertions in // place to enforce this). This lets us be sure that debugger clients never miss // breakpoints. OnNewGlobalHookOption = ( FireOnNewGlobalHook, DontFireOnNewGlobalHook ); /// Dense index into cached prototypes and class atoms for standard objects. JSProtoKey = ( JSProto_Null = 0, JSProto_Object, JSProto_Function, JSProto_Array, JSProto_Boolean, JSProto_JSON, JSProto_Date, JSProto_Math, JSProto_Number, JSProto_String, JSProto_RegExp, JSProto_Error, JSProto_InternalError, JSProto_EvalError, JSProto_RangeError, JSProto_ReferenceError, JSProto_SyntaxError, JSProto_TypeError, JSProto_URIError, JSProto_DebuggeeWouldRun, JSProto_CompileError, JSProto_RuntimeError, JSProto_Iterator, JSProto_StopIteration, JSProto_ArrayBuffer, JSProto_Int8Array, JSProto_Uint8Array, JSProto_Int16Array, JSProto_Uint16Array, JSProto_Int32Array, JSProto_Uint32Array, JSProto_Float32Array, JSProto_Float64Array, JSProto_Uint8ClampedArray, JSProto_Proxy, JSProto_WeakMap, JSProto_Map, JSProto_Set, JSProto_DataView, JSProto_Symbol, JSProto_SharedArrayBuffer, JSProto_Intl, JSProto_TypedObject, JSProto_Reflect, JSProto_SIMD, JSProto_WeakSet, JSProto_TypedArray, JSProto_Atomics, JSProto_SavedFrame, JSProto_WebAssembly, JSProto_WasmModule, JSProto_WasmInstance, JSProto_WasmMemory, JSProto_WasmTable, JSProto_Promise, JSProto_LIMIT ); {$Z1} /// Type of JSValue JSValueType = ( JSVAL_TYPE_DOUBLE = $00, JSVAL_TYPE_INT32 = $01, JSVAL_TYPE_UNDEFINED= $02, JSVAL_TYPE_BOOLEAN = $03, JSVAL_TYPE_MAGIC = $04, JSVAL_TYPE_STRING = $05, JSVAL_TYPE_SYMBOL = $06, JSVAL_TYPE_PRIVATE_GCTHING = $07, JSVAL_TYPE_NULL = $08, JSVAL_TYPE_OBJECT = $0C, // These never appear in a jsval; they are only provided as an out-of-band value. JSVAL_TYPE_UNKNOWN = $20, JSVAL_TYPE_MISSING = $21 ); {$ifndef CPU64} /// first 4 bytes for JSValue {$MINENUMSIZE 4} {$WARN COMBINING_SIGNED_UNSIGNED OFF} {$WARN BOUNDS_ERROR OFF} JSValueTag = ( JSVAL_TAG_CLEAR = Cardinal($FFFFFF80), JSVAL_TAG_INT32 = Cardinal(JSVAL_TAG_CLEAR or UInt8(JSVAL_TYPE_INT32)), JSVAL_TAG_UNDEFINED = Cardinal(JSVAL_TAG_CLEAR or UInt8(JSVAL_TYPE_UNDEFINED)), JSVAL_TAG_STRING = Cardinal(JSVAL_TAG_CLEAR or UInt8(JSVAL_TYPE_STRING)), JSVAL_TAG_SYMBOL = Cardinal(JSVAL_TAG_CLEAR or UInt8(JSVAL_TYPE_SYMBOL)), JSVAL_TAG_BOOLEAN = Cardinal(JSVAL_TAG_CLEAR or UInt8(JSVAL_TYPE_BOOLEAN)), JSVAL_TAG_MAGIC = Cardinal(JSVAL_TAG_CLEAR or UInt8(JSVAL_TYPE_MAGIC)), JSVAL_TAG_NULL = Cardinal(JSVAL_TAG_CLEAR or UInt8(JSVAL_TYPE_NULL)), JSVAL_TAG_OBJECT = Cardinal(JSVAL_TAG_CLEAR or UInt8(JSVAL_TYPE_OBJECT)) ); {$WARN BOUNDS_ERROR ON} {$WARN COMBINING_SIGNED_UNSIGNED ON} {$MINENUMSIZE 1} {$endif} {$Z2} /// Possible exception types // -These types are part of a JSErrorFormatString structure // - They define which error to throw in case of a runtime error // - JSEXN_NONE marks an unthrowable error JSExnType = ( JSEXN_NONE = -1, JSEXN_ERR, JSEXN_INTERNALERR, JSEXN_EVALERR, JSEXN_RANGEERR, JSEXN_REFERENCEERR, JSEXN_SYNTAXERR, JSEXN_TYPEERR, JSEXN_URIERR, JSEXN_DEBUGGEEWOULDRUN, JSEXN_WASMCOMPILEERROR, JSEXN_WASMRUNTIMEERROR, JSEXN_WARN, JSEXN_LIMIT ); {$Z1} Tint8Vector = array[0..(MaxInt div sizeof(int8))-1] of int8; Pint8Vector = ^Tint8Vector; Tuint8Vector = array[0..(MaxInt div sizeof(uint8))-1] of uint8; Puint8Vector = ^Tuint8Vector; Tint16Vector = array[0..(MaxInt div sizeof(int16))-1] of int16; Pint16Vector = ^Tint16Vector; Tuint16Vector = array[0..(MaxInt div sizeof(uint16))-1] of uint16; Puint16Vector = ^Tuint16Vector; Tint32Vector = array[0..(MaxInt div sizeof(int32))-1] of int32; Pint32Vector = ^Tint32Vector; Tuint32Vector = array[0..(MaxInt div sizeof(uint32))-1] of uint32; Puint32Vector = ^Tuint32Vector; Tfloat32Vector = array[0..(MaxInt div sizeof(single))-1] of single; Pfloat32Vector = ^Tfloat32Vector; Tfloat64Vector = array[0..(MaxInt div sizeof(double))-1] of double; Pfloat64Vector = ^Tfloat64Vector; /// the available types of elements in a typed array or data view // - obj must have passed a JS_IsArrayBufferView/JS_Is*Array test, or somehow // be known that it would pass such a test: it is an ArrayBufferView or a // wrapper of an ArrayBufferView, and the unwrapping will succeed. /// - jsabTYPE_UINT8_CLAMPED is a special type that is a uint8_t, but assignments // are clamped to [0,255]: treat the raw data type as a uint8_t. // - jsabTYPE_DATAVIEW is the type returned for a DataView. Note that // there is no single element type in this case JSArrayBufferViewType = ( jsabTYPE_INT8 = 0, jsabTYPE_UINT8, jsabTYPE_INT16, jsabTYPE_UINT16, jsabTYPE_INT32, jsabTYPE_UINT32, jsabTYPE_FLOAT32, jsabTYPE_FLOAT64, jsabTYPE_UINT8_CLAMPED, jsabTYPE_MAXTYPEDARRAYVIEWTYPE, jsabTYPE_FLOAT32x4, jsabTYPE_INT32x4 ); const nullPtr: pointer = nil; /// Run-time version enumeration corresponding to the latest available // - that is, ECMA standard 5, i.e. 1.8.5 JSVERSION_LATEST = JSVERSION_ECMA_5; type // pointers JSFreeOp = pointer; PJSContextOptions = ^JSContextOptions; PJSContext = ^JSContext; PJSCompartment = ^JSCompartment; PJS_CompartmentOptions = ^JS_CompartmentOptions; PJSObject = ^JSObject; PJSFunction = PJSObject; PJSString = ^JSString; PJSClass = ^JSClass; PJSCompileOptions = ^JSCompileOptions; PJSScript = JSUnknown; PJSRootedValue = ^JSRootedValue; PJSRootedObject = ^JSRootedObject; PJSRootedString = ^JSRootedString; PJSPropertySpec = ^JSPropertySpec; PJSFunctionSpec = ^JSFunctionSpec; PJSErrorReport = ^JSErrorReport; PJSErrorFormatString = ^JSErrorFormatString; PJSAtomState = JSUnknown; PJSPrincipals = JSUnknown; PJSAutoCheckCannotGC = JSUnknown; PJSStringFinalizer = ^JSStringFinalizer; // jsid JSIdType = ( JSID_TYPE_STRING = $0, JSID_TYPE_INT = $1, JSID_TYPE_VOID = $2, JSID_TYPE_SYMBOL = $4 ); jsid = record asBits: size_t; function isString: Boolean; function asJSString: PJSString; end; TjsidVector = array[0..(MaxInt div sizeof(jsid))-2] of jsid; PjsidVector = ^TjsidVector; _JSIdArray = record cx: PJSContext; mBegin: PjsidVector; //* actually, length jsid words */ mLength: size_t; mCapacity: size_t; mStorage: Int64; end; _JSIdArrayPtr = ^_JSIdArray; /// internal Spidermonkey structure for storrage jsid { JSIdArray } JSIdArray = {$ifdef USERECORDWITHMETHODS}record{$else}object{$endif} end; PJSIdArray = ^JSIdArray; // jsvalue JSWhyMagic = Cardinal; jsval_payload = record case Byte of 0: (i32: int32); 1: (u32: uint32); {$IFNDEF CPU64} 2: (boo: uint32); // Don't use |bool| -- it must be four bytes. 3: (str: PJSString); 4: (obj: PJSObject); 5: (ptr: pointer); {$ENDIF} 6: (why: JSWhyMagic); {$IFNDEF CPU64} 7: (word: size_t); 8: (uintptr: PtrUInt) {$ENDIF} end; {$ifdef IS_LITTLE_ENDIAN} jsval_val_layout = packed record payload: jsval_payload; {$IFNDEF CPU64} tag: JSValueTag; {$ENDIF} end; {$else} //BIG_ENDIAN jsval_val_layout = record tag: JSValueTag; payload: jsval_payload; end; {$endif} /// low-level definition of the jsval internals // - do not use directly jsval_layout = record case Byte of 0: (asBits: QWord); {$IFNDEF CPU64} 1: (s: jsval_val_layout); {$ENDIF} 2: (asDouble: double); 3: (asPtr: Pointer); end; /// used by JS_Stringify() method to incremently write the JSON content JSONWriteCallback = function(const buf: PCChar16; len: uint32; data: pointer): Boolean; cdecl; /// high-level definition of the JSValue {$ifdef USERECORDWITHMETHODS}jsval = record {$else}jsval = object{$endif} private _l: jsval_layout; function getIsVoid: Boolean; {$ifdef HASINLINE}inline;{$endif} function getIsNull: Boolean; {$ifdef HASINLINE}inline;{$endif} function getIsInteger: Boolean; {$ifdef HASINLINE}inline;{$endif} function getAsInteger: Integer; {$ifdef HASINLINE}inline;{$endif} procedure setAsInteger(const Value: Integer); {$ifdef HASINLINE}inline;{$endif} function getAsInt64: Int64; {$ifdef HASINLINE}inline;{$endif} procedure setAsInt64(const Value: Int64); {$ifdef HASINLINE}inline;{$endif} function getIsDouble: Boolean;{$ifdef HASINLINE}inline;{$endif} function getAsDouble: Double;{$ifdef HASINLINE}inline;{$endif} procedure setAsDouble(const Value: Double);{$ifdef HASINLINE}inline;{$endif} function getIsNumber: Boolean;{$ifdef HASINLINE}inline;{$endif} function getIsBoolean: Boolean;{$ifdef HASINLINE}inline;{$endif} function getAsBoolean: Boolean;{$ifdef HASINLINE}inline;{$endif} procedure setAsBoolean(const Value: Boolean);{$ifdef HASINLINE}inline;{$endif} function getIsObject: Boolean;{$ifdef HASINLINE}inline;{$endif} function getAsObject: PJSObject;{$ifdef HASINLINE}inline;{$endif} procedure setAsObject(const Value: PJSObject);{$ifdef HASINLINE}inline;{$endif} function getIsString: Boolean; {$ifdef HASINLINE}inline;{$endif} function getJSString: PJSString; {$ifdef HASINLINE}inline;{$endif} procedure setJSString(const Value: PJSString);{$ifdef HASINLINE}inline;{$endif} function getIsSimpleVariant(cx: PJSContext): Boolean;{$ifdef HASINLINE}inline;{$endif} function getSimpleVariant(cx: PJSContext): Variant; procedure setSimpleVariant(cx: PJSContext; const Value: Variant); function getPrivate: Pointer;{$ifdef HASINLINE}inline;{$endif} procedure setPrivate(const Value: Pointer);{$ifdef HASINLINE}inline;{$endif} function getAsDate(cx: PJSContext): TDateTime; procedure setAsDate(cx: PJSContext; const Value: TDateTime); function getAsJson(cx: PJSContext): RawUTF8; procedure setAsJson(cx: PJSContext; const Value: RawUTF8); function IsPrimitive: Boolean;{$ifdef HASINLINE}inline;{$endif} function IsMagic: Boolean;{$ifdef HASINLINE}inline;{$endif} public /// Is vaule void property isVoid: Boolean read getIsVoid; /// Set vaule void procedure setVoid; /// Is vaule null property isNull: Boolean read getIsNull; /// Set vaule null procedure setNull; /// Is vaule 32bit integer property isInteger: Boolean read getIsInteger; /// Get/set vaule as 32bit integer property asInteger: Integer read getAsInteger write setAsInteger; /// Get/set vaule as 64bit integer (if more than 32 bits than as double) property asInt64: Int64 read getAsInt64 write setAsInt64; /// Is vaule double property isDouble: Boolean read getIsDouble; /// Get/set vaule as double property asDouble: Double read getAsDouble write setAsDouble; /// Is vaule Number (32bit integer or double) property isNumber: Boolean read getIsNumber; /// Is vaule boolean property isBoolean: Boolean read getIsBoolean; /// Get/set vaule as boolean property asBoolean: Boolean read getAsBoolean write setAsBoolean; /// Is vaule object(null is object too) property isObject: Boolean read getIsObject; /// Get/set vaule as object property asObject: PJSObject read getAsObject write setAsObject; /// Is vaule string property isString: Boolean read getIsString; /// Get/set vaule as JSString property asJSString: PJSString read getJSString write setJSString; /// Is vaule simple(void, null, boolean, number or string) property isSimpleVariant[cx: PJSContext]: Boolean read getIsSimpleVariant; /// Get/set vaule as simple property asSimpleVariant[cx: PJSContext]: Variant read getSimpleVariant write setSimpleVariant; /// Get/set vaule as Custom pointer property asPrivate: Pointer read getPrivate write setPrivate; /// Get/set vaule as DateTime(object Date used) property asDate[cx: PJSContext]: TDateTime read getAsDate write setAsDate; /// Add JSON representation of value to Writer procedure AddJSON(cx: PJSContext; W: TTextWriter); /// Get/set vaule as JSON representation property asJson[cx: PJSContext]: RawUTF8 read getAsJson write setAsJson; /// Get JSON representation of value and launch callback function Stringify(cx: PJSContext; var replacer: PJSObject; space: jsval; callback: JSONWriteCallback; data: pointer): Boolean; /// Get type of value function ValType(cx: PJSContext): JSType; /// Get source of value function toSource(cx: PJSContext): PJSString; /// jsval.*Value functions cunstruct new jsval as in JS::Value C++ // classes - see https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_Reference/JS::Value class function NullValue: jsval; static; {$ifdef HASINLINE}inline;{$endif} class function Int32Value(v: integer): jsval; static; {$ifdef HASINLINE}inline;{$endif} class function BooleanValue(v: boolean): jsval; static; {$ifdef HASINLINE}inline;{$endif} class function TrueValue: jsval; static; {$ifdef HASINLINE}inline;{$endif} class function FalseValue: jsval; static; {$ifdef HASINLINE}inline;{$endif} class function DoubleValue(v: double): jsval; static; {$ifdef HASINLINE}inline;{$endif} class function StringValue(v: PJSString): jsval; static; {$ifdef HASINLINE}inline;{$endif} class function ObjectValue(v: PJSObject): jsval; static; {$ifdef HASINLINE}inline;{$endif} // SyNode extension (not present in original C++) class function Int64Value(v: Int64): jsval; static; {$ifdef HASINLINE}inline;{$endif} end; /// an abstract array of jsval JavaScript values TjsvalVector = array[0..(MaxInt div sizeof(jsval))-3] of jsval; /// map an array of jsval JavaScript values PjsvalVector = ^TjsvalVector; TjsvalDynArray = array of jsval; /// low-level definition of arguments of function // - do not use it dirrectly _JSArgRec = record case boolean of true: ( calle: jsval; this: jsval; argv: jsval; ); false: (rval: jsval); end; /// hight-level definition of arguments of function {$ifdef USERECORDWITHMETHODS}JSArgRec = record {$else}JSArgRec = object{$endif} private rec: _JSArgRec; function GetIsConstructing: Boolean; {$ifdef HASINLINE}inline;{$endif} function getThis(cx: PJSContext): jsval; {$ifdef HASINLINE}inline;{$endif} function getThisObject(cx: PJSContext): PJSObject; function getArgv: PjsvalVector; {$ifdef HASINLINE}inline;{$endif} function getCalleObject: PJSObject; {$ifdef HASINLINE}inline;{$endif} public /// is function called as constructor property IsConstructing: Boolean read GetIsConstructing; /// function, that is called now property calle: jsval read rec.calle; property calleObject: PJSObject read getCalleObject; /// this value of function property this[cx: PJSContext]: jsval read getThis; property thisObject[cx: PJSContext]: PJSObject read getThisObject; /// arguments of function property argv: PjsvalVector read getArgv; /// return value of function property rval: jsval read rec.rval write rec.rval; end; //Todo - set correct codes for some sitautions JS_ObjectOpResult = object code: UIntPtr; end; // callback JSInterruptCallback = function(cx: PJSContext): Boolean; cdecl; /// callback prototype for returning an execution error JSErrorCallback = function(userRef: Pointer; const errorNumber: uintN): PJSErrorFormatString; cdecl; /// callback prototype for reporting error for a given runtime context JSWarningReporter = procedure(cx: PJSContext; report: PJSErrorReport); cdecl; JSStringFinalizerOp = procedure(fin: PJSStringFinalizer; chars: PCChar16); cdecl; // Add or get a property named by id in obj. Note the jsid id type -- id may // be a string (Unicode property identifier) or an int (element index). The // *vp out parameter, on success, is the new property value after the action. JSAddPropertyOp = function(cx: PJSContext; var obj: PJSObject; var id: jsid; out vp: jsval): Boolean; cdecl; // Delete a property named by id in obj. // - If an error occurred, return false as per normal JSAPI error practice. // - If no error occurred, but the deletion attempt wasn't allowed (perhaps // because the property was non-configurable), set *succeeded to false and // return true. This will cause |delete obj[id]| to evaluate to false in // non-strict mode code, and to throw a TypeError in strict mode code. // - If no error occurred and the deletion wasn't disallowed (this is *not* the // same as saying that a deletion actually occurred -- deleting a non-existent // property, or an inherited property, is allowed -- it's just pointless), // set *succeeded to true and return true. JSDeletePropertyOp = function(cx: PJSContext; var obj: PJSObject; var id: jsid; out res: JS_ObjectOpResult):Boolean; cdecl; // Get a property named by id in obj. Note the jsid id type -- id may // be a string (Unicode property identifier) or an int (element index). The // *vp out parameter, on success, is the new property value after the action. JSGetterOp = function(cx: PJSContext; var obj: PJSObject; var id: jsid; out vp: jsval):Boolean; cdecl; // Set a property named by id in obj, treating the assignment as strict // mode code if strict is true. Note the jsid id type -- id may be a string // (Unicode property identifier) or an int (element index). The *vp out // parameter, on success, is the new property value after the // set. JSSetterOp = function(cx: PJSContext; var obj: PJSObject; var id: jsid; var vp: jsval; out res: JS_ObjectOpResult):Boolean; cdecl; // The old-style JSClass.enumerate op should define all lazy properties not // yet reflected in obj. JSEnumerateOp = function(cx: PJSContext; var obj: PJSObject): Boolean; cdecl; // Resolve a lazy property named by id in obj by defining it directly in obj. // Lazy properties are those reflected from some peer native property space // (e.g., the DOM attributes for a given node reflected as obj) on demand. // - JS looks for a property in an object, and if not found, tries to resolve // the given id. *resolvedp should be set to true iff the property was // was defined on |obj|. JSResolveOp = function(cx: PJSContext; var obj: PJSObject; var id: jsid; out resolved: Boolean): Boolean; cdecl; // A class with a resolve hook can optionally have a mayResolve hook. This hook // must have no side effects and must return true for a given id if the resolve // hook may resolve this id. This is useful when we're doing a "pure" lookup: if // mayResolve returns false, we know we don't have to call the effectful resolve // hook. // // maybeObj, if non-null, is the object on which we're doing the lookup. This // can be nullptr: during JIT compilation we sometimes know the Class but not // the object. JSMayResolveOp = function(names: PJSAtomState; id: jsid; maybeObj: PJSObject): Boolean; cdecl; JSFinalizeOp = procedure(var fop: JSFreeOp; obj: PJSObject); cdecl; // Check whether v is an instance of obj. Return false on error or exception, // true on success with true in *bp if v is an instance of obj, false in // *bp otherwise. JSHasInstanceOp = function(cx: PJSContext; var obj: PJSObject; var vp: jsval; out b: Boolean): Boolean; cdecl; // Typedef for native functions called by the JS VM. JSNative = function(cx: PJSContext; argc: uintN; var vp: JSArgRec): Boolean; cdecl; // Function type for trace operation of the class called to enumerate all // traceable things reachable from obj's private data structure. For each such // thing, a trace implementation must call one of the JS_Call*Tracer variants // on the thing. // // JSTraceOp implementation can assume that no other threads mutates object // state. It must not change state of the object or corresponding native // structures. The only exception for this rule is the case when the embedding // needs a tight integration with GC. In that case the embedding can check if // the traversal is a part of the marking phase through calling // JS_IsGCMarkingTracer and apply a special code like emptying caches or // marking its native structures. JSTraceOp = JSUnknown; /// Options of context JSContextOptions = object private function getOptions(const Index: Integer): Boolean; procedure setOptions(const Index: Integer; const Value: Boolean); public property Baseline: Boolean index 0 read getOptions write setOptions; property Ion: Boolean index 1 read getOptions write setOptions; property AsmJS: Boolean index 2 read getOptions write setOptions; property Wasm: Boolean index 3 read getOptions write setOptions; property WasmAlwaysBaseline: Boolean index 4 read getOptions write setOptions; property ThrowOnAsmJSValidationFailure: Boolean index 5 read getOptions write setOptions; property NativeRegExp: Boolean index 6 read getOptions write setOptions; property UnboxedArrays: Boolean index 7 read getOptions write setOptions; property AsyncStack: Boolean index 8 read getOptions write setOptions; property ThrowOnDebuggeeWouldRun: Boolean index 9 read getOptions write setOptions; property Werror: Boolean index 10 read getOptions write setOptions; property StrictMode: Boolean index 11 read getOptions write setOptions; property ExtraWarnings: Boolean index 12 read getOptions write setOptions; end; /// JavaScript execution context // - this object does not store anything, but just provide some helper methods { JSContext } JSContext = object private function GetPrivate: Pointer; {$ifdef HASINLINE}inline;{$endif} procedure SetPrivate(const Value: Pointer);{$ifdef HASINLINE}inline;{$endif} function GetEmptyString: PJSString; {$ifdef HASINLINE}inline;{$endif} function GetGCParameter(key: JSGCParamKey): uint32; {$ifdef HASINLINE}inline;{$endif} procedure SetGCParameter(key: JSGCParamKey; const Value: uint32); {$ifdef HASINLINE}inline;{$endif} function GetNowMs: int64; {$ifdef HASINLINE}inline;{$endif} function GetWarningReporter: JSWarningReporter; {$ifdef HASINLINE}inline;{$endif} procedure SetWarningReporter(reporter: JSWarningReporter); {$ifdef HASINLINE}inline;{$endif} function GetOptions: PJSContextOptions; {$ifdef HASINLINE}inline;{$endif} function GetIsRunning: boolean; {$ifdef HASINLINE}inline;{$endif} protected // Return the ArrayBuffer underlying an ArrayBufferView // - If the buffer has been neutered, this will still return the neutered buffer. // - obj must be an object that would return true for JS_IsArrayBufferViewObject() function GetArrayBufferViewBuffer(var obj: PJSObject; out isSharedMemory: Boolean): PJSObject; overload;{$ifdef HASINLINE}inline;{$endif} function GetArrayBufferViewBuffer(var obj: PJSObject): PJSObject; overload;{$ifdef HASINLINE}inline;{$endif} public /// Initializes the JavaScript context. class function CreateNew(maxbytes: uint32; maxNurseryBytes: uint32 = 16 * (1 SHL 20); parentContext: PJSContext = nil): PJSContext; static; /// Performs garbage collection in the JS memory pool. procedure GC; {$ifdef HASINLINE}inline;{$endif} /// Returns the empty string as a JSString object. property EmptyString: PJSString read GetEmptyString; /// Get/Set performance parameters related to garbage collection. property GCParameter[key: JSGCParamKey]: uint32 read GetGCParameter write SetGCParameter; /// Adjust performance parameters related to garbage collection based on available memory(in megabytes). procedure SetGCParametersBasedOnAvailableMemory(availMem: uint32); /// Microseconds since the epoch, midnight, January 1, 1970 UTC. property NowMs: int64 read GetNowMs; /// Request a callback set using JS_SetInterruptCallback procedure RequestInterruptCallback; {$ifdef HASINLINE}inline;{$endif} /// Set the size of the native stack that should not be exceed. To disable // stack size checking pass 0. // - SpiderMonkey allows for a distinction between system code (such as GCs, which // may incidentally be triggered by script but are not strictly performed on // behalf of such script), trusted script (as determined by JS_SetTrustedPrincipals), // and untrusted script. Each kind of code may have a different stack quota, // allowing embedders to keep higher-priority machinery running in the face of // scripted stack exhaustion by something else. // - The stack quotas for each kind of code should be monotonically descending, // and may be specified with this function. If 0 is passed for a given kind // of code, it defaults to the value of the next-highest-priority kind. // - This function may only be called immediately after the runtime is initialized // and before any code is executed and/or interrupts requested. procedure SetNativeStackQuota(systemCodeStackSize: size_t); {$ifdef HASINLINE}inline;{$endif} /// Get options of context property Options: PJSContextOptions read GetOptions; /// Get/Set the warning reporting mechanism for an application. property WarningReporter: JSWarningReporter read GetWarningReporter write SetWarningReporter; /// Add callback for interrupt procedure AddInterruptCallback(callback: JSInterruptCallback); {$ifdef HASINLINE}inline;{$endif} /// Disable interrupt callbacks call procedure DisableInterruptCallback; {$ifdef HASINLINE}inline;{$endif} /// Disable/enable interrupt callbacks call procedure ResetInterruptCallback(disable: boolean); {$ifdef HASINLINE}inline;{$endif} /// Call interrupt callback if it is requested function CheckForInterrupt: Boolean; {$ifdef HASINLINE}inline;{$endif} /// Read/Write access a JSContext field for application-specific data. // Memory management for this private data is the application's responsibility. // The JavaScript engine itself never uses it. property PrivateData: Pointer read GetPrivate write SetPrivate; /// Enter a different compartment on the given context, so that objects in that // compartment can be accessed. // - NB: This API is infallible; a NULL return value does not indicate error function EnterCompartment(target: PJSObject): PJSCompartment;{$ifdef HASINLINE}inline;{$endif} /// Leave a the compartment, returning to the compartment active before the // corresponding JS_EnterCompartment. procedure LeaveCompartment(oldCompartment: PJSCompartment);{$ifdef HASINLINE}inline;{$endif} /// indicates to the JS engine that the calling thread is entering a region // of code that may call into the JSAPI but does not block procedure BeginRequest; {$ifdef HASINLINE}inline;{$endif} /// indicates to the JS engine that the calling thread is leaving a region // of code that may call into the JSAPI but does not block procedure EndRequest; {$ifdef HASINLINE}inline;{$endif} /// Create Compile Options function NewCompileOptions: PJSCompileOptions; /// Free Compile Options procedure FreeCompileOptions(opt: PJSCompileOptions); /// Create a new JavaScript object for use as a global object. function NewGlobalObject(clasp: PJSClass; hookOption: OnNewGlobalHookOption = DontFireOnNewGlobalHook): PJSObject; /// Initialize standard JS class constructors, prototypes, and any top-level // functions and constants associated with the standard classes (e.g. isNaN // for Number). // - NB: This sets cx's global object to obj if it was null. function InitStandardClasses(var obj: PJSObject): boolean; /// Add 'Reflect.parse', a SpiderMonkey extension, to the Reflect object on the // given global. function InitReflectParse(var obj: PJSObject): boolean; /// Initialize the 'ctypes' object on a global variable 'obj'. The 'ctypes' // object will be sealed. function InitCTypesClass(var obj: PJSObject): boolean; /// Initialize the 'Debugger' object on a global variable 'obj'. The 'ctypes' // object will be sealed. function DefineDebuggerObject(var obj: PJSObject): boolean; /// This function makes a cross-compartment wrapper for the given JS object. // Details see here http://stackoverflow.com/questions/18730477/what-does-js-wrapobject-do function WrapObject(var obj: PJSObject): boolean; ///// modules support /// Initialize modeles classes next 2 functions cannot work without calling this function function InitModuleClasses(var obj: PJSObject): boolean; /// Compile script as module function CompileModule(var obj: PJSObject; opts: PJSCompileOptions; chars: PCChar16; length: size_t): PJSObject; /// Set handler for module resolving procedure SetModuleResolveHook(var hook: PJSFunction); /// Invoke a constructor, like the JS expression `new ctor(...args)`. Returns // the new object, or null on error. function New(var ctor: PJSObject; argc: uintN; argv: PjsvalVector): PJSObject;{$ifdef HASINLINE}inline;{$endif} /// Create a new object based on a specified class and root it function NewObject(clasp: PJSClass): PJSObject;{$ifdef HASINLINE}inline;{$endif} /// Create a new object based on a specified class // - Unlike JS_NewObject, JS_NewObjectWithGivenProto does not compute a default // proto. If proto is nullptr, the JS object will have `null` as [[Prototype]]. function NewObjectWithGivenProto(clasp: PJSClass; var proto: PJSObject): PJSObject;{$ifdef HASINLINE}inline;{$endif} /// Create/Free rooted value(put value in rooting stack) // Garbage collection not performs to rooted values // - Warning!!! You must free rooted values in revers order for creating // that's why it's a bad idea store rooting values in any place except // local variables. Exception is root some values just after creating context // and unroot them (in reverse order) just before destroy context. // For other cases use reserved slots function NewRootedValue(val: jsval): PJSRootedValue; {$ifdef HASINLINE}inline;{$endif} procedure FreeRootedValue(str: PJSRootedValue);{$ifdef HASINLINE}inline;{$endif} /// Create/Free rooted object(put object in rooting stack) // Garbage collection not performs to rooted objects // - Warning!!! You must free rooted objects in reverse order for creating // that's why it's a bad idea store rooting objects in any place except // local variables. Exception is root some objects just after creating context // and unroot them (in reverse order) just before destroy context. // For other cases use reserved slots function NewRootedObject(obj: PJSObject): PJSRootedObject; {$ifdef HASINLINE}inline;{$endif} procedure FreeRootedObject(obj: PJSRootedObject);{$ifdef HASINLINE}inline;{$endif} /// Create/Free rooted string(put string in rooting stack) // Garbage collection not performs to rooted strings // - Warning!!! You must free rooted strings in reverse order for creating // that's why it's a bad idea store rooting strings in any place except // local variables. Exception is root some strings just after creating context // and unroot them (in reverse order) just before destroy context. // For other cases use reserved slots function NewRootedString(obj: PJSString): PJSRootedString; {$ifdef HASINLINE}inline;{$endif} procedure FreeRootedString(str: PJSRootedString);{$ifdef HASINLINE}inline;{$endif} /// create a new JavaScript string instance function NewJSString(const Value: SynUnicode): PJSString; overload; {$ifdef HASINLINE}inline;{$endif} /// create a new JavaScript string from a RawUTF8 // see https://gitlab.gnome.org/GNOME/gjs/commit/6fa31261e1131970f68aba63d977253118a5958a function NewJSString(const Value: RawUTF8): PJSString; overload; {$ifdef HASINLINE}inline;{$endif} function NewJSString(TextWide: PWideChar; TextLen: integer): PJSString; overload; {$ifdef HASINLINE}inline;{$endif} function NewJSString(TextAnsi: PAnsiChar; TextLen, CodePage: integer): PJSString; overload; function NewExternalString(const Value: SynUnicode): PJSString; {$ifdef HASINLINE}inline;{$endif} //function AtomizeAndPinString(const Value: SynUnicode): PJSString; {$ifdef HASINLINE}inline;{$endif} /// create a new JavaScript Date object instance function NewDateObject(year, mon, mday, hour, min, sec: int32): PJSObject; {$ifdef HASINLINE}inline;{$endif} function NewDateObjectMsec(msec: double): PJSObject; {$ifdef HASINLINE}inline;{$endif} /// create a new JavaScript Array object instance function NewArrayObject(length: size_t): PJSObject; overload; {$ifdef HASINLINE}inline;{$endif} function NewArrayObject(length: size_t; vector: PjsvalVector): PJSObject; overload; {$ifdef HASINLINE}inline;{$endif} /// create a new JavaScript Function object instance function NewFunction(call: JSNative; nargs: uintN; flags: uintN; name: PCChar): PJSObject; {$ifdef HASINLINE}inline;{$endif} /// Reports a memory allocation error // - Call JS_ReportOutOfMemory to report that an operation failed because the // system is out of memory // - When the JavaScript engine tries to allocate memory and allocation fails, // it reports an error as though by calling this function procedure ReportOutOfMemory; /// Create a new JavaScript Error object and set it to be the pending exception on cx. // The callback must then return JS_FALSE to cause the exception to be propagated // to the calling script. procedure ReportError(format: PCChar); /// Report an error with an application-defined error code. // - varargs is Additional arguments for the error message. //- These arguments must be of type jschar* // - The number of additional arguments required depends on the error // message, which is determined by the errorCallback procedure ReportErrorNumberUC(errorCallback: JSErrorCallback; userRef: pointer; const erroNubmer: uintN); /// Offer the JavaScript engine an opportunity to perform garbage collection if needed. procedure MaybeGC; /// Get the current pending exception for a given JSContext. function GetPendingException(out rv: jsval): boolean; {$ifdef HASINLINE}inline;{$endif} /// Clear the currently pending exception in a context. procedure ClearPendingException; {$ifdef HASINLINE}inline;{$endif} /// Convert a jsid to type JS::Value. function IdToValue(id: jsid; out v: jsval): Boolean; //~~~ write delphi realization /// Convert a JS::Value to type jsid. function ValueToId(var v: jsval; out id: jsid): Boolean; //~~~ write delphi realization /// Determines the JS data type of a JS value. function TypeOfValue(v: jsval): JSType; {$ifdef HASINLINE}inline;{$endif} //~~~ write delphi realization /// Compile and execute a script in the scope of the current global of cx. function EvaluateScript(opts: PJSCompileOptions; bytes: PCChar; length: size_t; out rval: jsval): Boolean; {$ifdef HASINLINE}inline;{$endif} function EvaluateUCScript(opts: PJSCompileOptions; chars: PCChar16; length: size_t; out rval: jsval): Boolean; {$ifdef HASINLINE}inline;{$endif} /// Compile a script, source, for execution. function CompileScript(bytes: PCChar; length: size_t; opts: PJSCompileOptions; out script: PJSScript): boolean; {$ifdef HASINLINE}inline;{$endif} function CompileUCScript(chars: PCChar16; length: size_t; opts: PJSCompileOptions; out script: PJSScript): boolean; {$ifdef HASINLINE}inline;{$endif} /// Evaluate a script in the scope of the current global of cx. function ExecuteScript(var script: PJSScript; out rval: jsval): Boolean; {$ifdef HASINLINE}inline;{$endif} /// Return the global object for the active function on the context. // The global object is specific for a compartment function CurrentGlobalOrNull: PJSObject; {$ifdef HASINLINE}inline;{$endif} //ArrayBuffer support /// Create a new signed 8 bit integer typed array with nelements elements // - will fill the newly created array with zeros function NewInt8Array(nelements: uint32): PJSObject;{$ifdef HASINLINE}inline;{$endif} /// Create a new unsigned 8 bit integer (byte) typed array with nelements elements // - will fill the newly created array with zeros function NewUint8Array(nelements: uint32): PJSObject;{$ifdef HASINLINE}inline;{$endif} /// Create a new 8 bit integer typed array with nelements elements // - will fill the newly created array with zeros function NewUint8ClampedArray(nelements: uint32): PJSObject;{$ifdef HASINLINE}inline;{$endif} /// Create a new signed 16 bit integer typed array with nelements elements // - will fill the newly created array with zeros function NewInt16Array(nelements: uint32): PJSObject;{$ifdef HASINLINE}inline;{$endif} /// Create a new unsigned 16 bit integer typed array with nelements elements // - will fill the newly created array with zeros function NewUint16Array(nelements: uint32): PJSObject;{$ifdef HASINLINE}inline;{$endif} /// Create a new signed 32 bit integer typed array with nelements elements // - will fill the newly created array with zeros function NewInt32Array(nelements: uint32): PJSObject;{$ifdef HASINLINE}inline;{$endif} /// Create a new unsigned 32 bit integer typed array with nelements elements // - will fill the newly created array with zeros function NewUint32Array(nelements: uint32): PJSObject;{$ifdef HASINLINE}inline;{$endif} /// Create a new signed 32 bit float (single) typed array with nelements elements // - will fill the newly created array with zeros function NewFloat32Array(nelements: uint32): PJSObject;{$ifdef HASINLINE}inline;{$endif} /// Create a new signed 64 bit float (double) typed array with nelements elements // - will fill the newly created array with zeros function NewFloat64Array(nelements: uint32): PJSObject;{$ifdef HASINLINE}inline;{$endif} /// Create a new 8 bit signed integer typed array and copy in values // from a given object // - The object is used as if it was an array; that is, the new array (if // successfully created) will have length given by array.length, and its // elements will be those specified by array[0], array[1], and so on, after // conversion to the typed array element type. function NewInt8ArrayFromArray(var arr: PJSObject): PJSObject;{$ifdef HASINLINE}inline;{$endif} /// Create a new 8 bit unsigned integer typed array and copy in values // from a given object // - The object is used as if it was an array; that is, the new array (if // successfully created) will have length given by array.length, and its // elements will be those specified by array[0], array[1], and so on, after // conversion to the typed array element type. function NewUint8ArrayFromArray(var arr: PJSObject): PJSObject;{$ifdef HASINLINE}inline;{$endif} /// Create a new 8 bit unsigned integer typed array and copy in values // from a given object // - The object is used as if it was an array; that is, the new array (if // successfully created) will have length given by array.length, and its // elements will be those specified by array[0], array[1], and so on, after // conversion to the typed array element type. function NewUint8ClampedArrayFromArray(var arr: PJSObject): PJSObject;{$ifdef HASINLINE}inline;{$endif} /// Create a new 16 bit signed integer typed array and copy in values // from a given object // - The object is used as if it was an array; that is, the new array (if // successfully created) will have length given by array.length, and its // elements will be those specified by array[0], array[1], and so on, after // conversion to the typed array element type. function NewInt16ArrayFromArray(var arr: PJSObject): PJSObject;{$ifdef HASINLINE}inline;{$endif} /// Create a new 16 bit unsigned integer typed array and copy in values // from a given object // - The object is used as if it was an array; that is, the new array (if // successfully created) will have length given by array.length, and its // elements will be those specified by array[0], array[1], and so on, after // conversion to the typed array element type. function NewUint16ArrayFromArray(var arr: PJSObject): PJSObject;{$ifdef HASINLINE}inline;{$endif} /// Create a new 32 bit signed integer typed array and copy in values // from a given object // - The object is used as if it was an array; that is, the new array (if // successfully created) will have length given by array.length, and its // elements will be those specified by array[0], array[1], and so on, after // conversion to the typed array element type. function NewInt32ArrayFromArray(var arr: PJSObject): PJSObject;{$ifdef HASINLINE}inline;{$endif} /// Create a new 32 bit unsigned integer typed array and copy in values // from a given object // - The object is used as if it was an array; that is, the new array (if // successfully created) will have length given by array.length, and its // elements will be those specified by array[0], array[1], and so on, after // conversion to the typed array element type. function NewUint32ArrayFromArray(var arr: PJSObject): PJSObject;{$ifdef HASINLINE}inline;{$endif} /// Create a new 32 bit float (single) typed array and copy in values // from a given object // - The object is used as if it was an array; that is, the new array (if // successfully created) will have length given by array.length, and its // elements will be those specified by array[0], array[1], and so on, after // conversion to the typed array element type. function NewFloat32ArrayFromArray(var arr: PJSObject): PJSObject;{$ifdef HASINLINE}inline;{$endif} /// Create a new 64 bit float (double) typed array and copy in values // from a given object // - The object is used as if it was an array; that is, the new array (if // successfully created) will have length given by array.length, and its // elements will be those specified by array[0], array[1], and so on, after // conversion to the typed array element type. function NewFloat64ArrayFromArray(var arr: PJSObject): PJSObject;{$ifdef HASINLINE}inline;{$endif} /// Create a new 8 bit signed integer typed array using the given // ArrayBuffer for storage // - The length value is optional; if -1 is passed, enough elements to use up the // remainder of the byte array is used as the default value function NewInt8ArrayWithBuffer(var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject;{$ifdef HASINLINE}inline;{$endif} /// Create a new 8 bit unsigned integer typed array using the given // ArrayBuffer for storage // - The length value is optional; if -1 is passed, enough elements to use up the // remainder of the byte array is used as the default value function NewUint8ArrayWithBuffer(var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject;{$ifdef HASINLINE}inline;{$endif} /// Create a new 8 bit unsigned integer typed array using the given // ArrayBuffer for storage // - The length value is optional; if -1 is passed, enough elements to use up the // remainder of the byte array is used as the default value function NewUint8ClampedArrayWithBuffer(var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject;{$ifdef HASINLINE}inline;{$endif} /// Create a new 16 bit signed integer typed array using the given // ArrayBuffer for storage // - The length value is optional; if -1 is passed, enough elements to use up the // remainder of the byte array is used as the default value function NewInt16ArrayWithBuffer(var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject;{$ifdef HASINLINE}inline;{$endif} /// Create a new 16 bit unsigned integer typed array using the given // ArrayBuffer for storage // - The length value is optional; if -1 is passed, enough elements to use up the // remainder of the byte array is used as the default value function NewUint16ArrayWithBuffer(var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject;{$ifdef HASINLINE}inline;{$endif} /// Create a new 32 bit signed integer typed array using the given // ArrayBuffer for storage // - The length value is optional; if -1 is passed, enough elements to use up the // remainder of the byte array is used as the default value function NewInt32ArrayWithBuffer(var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject;{$ifdef HASINLINE}inline;{$endif} /// Create a new 32 bit unsigned integer typed array using the given // ArrayBuffer for storage // - The length value is optional; if -1 is passed, enough elements to use up the // remainder of the byte array is used as the default value function NewUint32ArrayWithBuffer(var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject;{$ifdef HASINLINE}inline;{$endif} /// Create a new 32 bit float (single) typed array using the given // ArrayBuffer for storage // - The length value is optional; if -1 is passed, enough elements to use up the // remainder of the byte array is used as the default value function NewFloat32ArrayWithBuffer(var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject;{$ifdef HASINLINE}inline;{$endif} /// Create a new 64 bit float (double) typed array using the given // ArrayBuffer for storage // - The length value is optional; if -1 is passed, enough elements to use up the // remainder of the byte array is used as the default value function NewFloat64ArrayWithBuffer(var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject; {$ifdef HASINLINE}inline;{$endif} /// Create a new SharedArrayBuffer with the given byte length. function NewSharedArrayBuffer(nbytes: uint32): PJSObject;{$ifdef HASINLINE}inline;{$endif} /// Create a new ArrayBuffer with the given byte length. function NewArrayBuffer(nbytes: uint32): PJSObject;{$ifdef HASINLINE}inline;{$endif} /// Indicates whether or not a script or function is currently executing in a given context. property IsRunning: boolean read GetIsRunning; /// Destroy a JSContext. procedure Destroy; end; /// JavaScript execution compartment // - this object does not store anything, but just provide some helper methods JSCompartment = object end; /// options of compartment JS_CompartmentOptions = record version: JSVersion; invisibleToDebugger: Boolean; mergeable: Boolean; discardSource: Boolean; disableLazyParsing_: Boolean; cloneSingletons: Boolean; extraWarningsOverride: JSUnknown; zone_: JSUnknown; traceGlobal: JSTraceOp; singletonsAsTemplates: Boolean; addonId: JSUnknown; preserveJitCode: Boolean; end; /// JSObject is the type of JavaScript objects in the JSAPI // - this object does not store anything, but just provide some helper methods // to access a PJSObject value via low-level API functions {$ifdef USERECORDWITHMETHODS}JSObject = record {$else}JSObject = object{$endif} private function GetPrivate: Pointer; {$ifdef HASINLINE}inline;{$endif} procedure SetPrivate(data: Pointer); cdecl; {$ifdef HASINLINE}inline;{$endif} function GetReservedSlot(index: uint32): jsval; {$ifdef HASINLINE}inline;{$endif} procedure SetReservedSlot(index: uint32; v: jsval); {$ifdef HASINLINE}inline;{$endif} function GetClass: PJSClass; {$ifdef HASINLINE}inline;{$endif} function GetConstructor(cx: PJSContext): PJSObject; {$ifdef HASINLINE}inline;{$endif} // Return the available byte length of an array buffer // - obj must have passed a JS_IsArrayBufferObject test, or somehow be known // that it would pass such a test: it is an ArrayBuffer or a wrapper of an // ArrayBuffer, and the unwrapping will succeed function GetArrayBufferByteLength: uint32;{$ifdef HASINLINE}inline;{$endif} function GetSharedArrayBufferByteLength: uint32;{$ifdef HASINLINE}inline;{$endif} // Return a pointer to the start of the data referenced by any typed array // - The data is still owned by the typed array, and should not be modified on // another thread // - obj must have passed a JS_Is*Array test, or somehow be known that it would // pass such a test: it is a typed array or a wrapper of a typed array, and the // unwrapping will succeed // - Prefer the type-specific versions when possible function GetArrayBufferViewData(out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Pointer;{$ifdef HASINLINE}inline;{$endif} public /// get a jsval corresponding to this object function ToJSValue: jsval; {$ifdef HASINLINE}inline;{$endif} /// Access the private data field of an object. property PrivateData: Pointer read GetPrivate write SetPrivate; property Ctor[cx: PJSContext]: PJSObject read GetConstructor; /// Read access an object's reserved slots. property ReservedSlot[index: uint32]: jsval read GetReservedSlot write SetReservedSlot; /// Retrieves the class associated with an object. property Class_: PJSClass read GetClass; /// JSAPI method equivalent to the instanceof operator in JavaScript. function HasInstance(cx: PJSContext; var val: jsval): Boolean; /// is object is Date object function isDate(cx: PJSContext): Boolean; {$ifdef HASINLINE}inline;{$endif} /// is object is Function object function isFunction(cx: PJSContext): Boolean; {$ifdef HASINLINE}inline;{$endif} /// is object is Array object function isArray(cx: PJSContext): Boolean; {$ifdef HASINLINE}inline;{$endif} /// Retrieve the private data associated with an object, if that object is an // instance of a specified class. function GetInstancePrivate(cx: PJSContext; clasp: PJSClass): Pointer; {$ifdef HASINLINE}inline;{$endif} /// Create a new property on an object. function DefineProperty(cx: PJSContext; const name: PCChar; const value: jsval; attrs: uint32 = 0; getter: JSNative = nil; setter: JSNative = nil): boolean; {$ifdef HASINLINE}inline;{$endif} function DefineUCProperty(cx: PJSContext; const name: SynUnicode; const value: jsval; attrs: uint32 = 0; getter: JSNative = nil; setter: JSNative = nil): Boolean; overload; {$ifdef HASINLINE}inline;{$endif} function DefineUCProperty(cx: PJSContext; const name: PCChar16; namelen: size_t; const value: jsval; attrs: uint32 = 0; getter: JSNative = nil; setter: JSNative = nil): Boolean; overload; {$ifdef HASINLINE}inline;{$endif} function DefinePropertyById(cx: PJSContext; var id: jsid; const value: jsval; attrs: uint32 = 0; getter: JSNative = nil; setter: JSNative = nil): boolean; {$ifdef HASINLINE}inline;{$endif} /// Define multiple properties for a single object. // PJSPropertySpec must be null-terminated function DefineProperties(cx: PJSContext; ps: PJSPropertySpec): boolean; {$ifdef HASINLINE}inline;{$endif} /// Find a specified property and retrieve its value. function GetPropValue(cx: PJSContext; const name: SynUnicode): jsval;{$ifdef HASINLINE}inline;{$endif} function GetProperty(cx: PJSContext; const name: PCChar; out vp: jsval): boolean; {$ifdef HASINLINE}inline;{$endif} function GetUCProperty(cx: PJSContext; const name: PCChar16; namelen: size_t; out vp: jsval): boolean; {$ifdef HASINLINE}inline;{$endif} function GetPropertyById(cx: PJSContext; const id: jsid; out vp: jsval): boolean; {$ifdef HASINLINE}inline;{$endif} /// Assign a value to a property of an object. function SetProperty(cx: PJSContext; const name: PCChar; const vp: jsval): Boolean; {$ifdef HASINLINE}inline;{$endif} function SetUCProperty(cx: PJSContext; const name: PCChar16; namelen: size_t; const vp: jsval): boolean; {$ifdef HASINLINE}inline;{$endif} /// Removes a specified property from an object. function DeletePropertyById(cx: PJSContext; const id: jsid; out res: JS_ObjectOpResult): Boolean; {$ifdef HASINLINE}inline;{$endif} /// Determine whether a JavaScript object has a specified property. function HasProperty(cx: PJSContext; const name: PCChar): Boolean; {$ifdef HASINLINE}inline;{$endif} function HasUCProperty(cx: PJSContext; const name: PCChar16; namelen: size_t; out found: Boolean): Boolean; {$ifdef HASINLINE}inline;{$endif} /// Determine whether a property is already physically present on a JSObject. function AlreadyHasOwnUCProperty(cx: PJSContext; const name: PCChar16; namelen: size_t): Boolean; {$ifdef HASINLINE}inline;{$endif} /// Create a native function and assign it as a property to a specified JS object function DefineFunction(cx: PJSContext; name: PCChar; call: JSNative; nargs: uintN; attrs: uintN = 0): PJSFunction; {$ifdef HASINLINE}inline;{$endif} function DefineUCFunction(cx: PJSContext; name: PCChar16; namelen: size_t; call: JSNative; nargs: uintN; attrs: uintN = 0): PJSFunction; {$ifdef HASINLINE}inline;{$endif} /// Create zero or more functions and makes them properties (methods) // of a specified object, obj, as if by calling JS_DefineFunction repeatedly function DefineFunctions(cx: PJSContext; fs: PJSFunctionSpec; behavior: JSPropertyDefinitionBehavior = DefineAllProperties): Boolean; {$ifdef HASINLINE}inline;{$endif} /// Calls a specified JS function. // - Perform the method call `rval = obj[name](args)`. function RunMethod(cx: PJSContext; const name: PCChar; args: TjsvalDynArray; out rval: jsval): Boolean; overload; {$ifdef HASINLINE}inline;{$endif} function RunMethod(cx: PJSContext; const name: PCChar; arg: jsval; out rval: jsval): Boolean; overload; {$ifdef HASINLINE}inline;{$endif} function RunMethod(cx: PJSContext; const name: PCChar; out rval: jsval): Boolean; overload; {$ifdef HASINLINE}inline;{$endif} function CallFunction(cx: PJSContext; var fun: PJSFunction; argc: size_t; argv: PjsvalVector; out rval: jsval): Boolean; {$ifdef HASINLINE}inline;{$endif} function CallFunctionValue(cx: PJSContext; val: jsval; argc: size_t; argv: PjsvalVector; out rval: jsval): Boolean; {$ifdef HASINLINE}inline;{$endif} function CallFunctionName(cx: PJSContext; const name: PCChar; argc: size_t; argv: PjsvalVector; out rval: jsval): Boolean; {$ifdef HASINLINE}inline;{$endif} /// Make a JSClass accessible to JavaScript code by creating its prototype, // constructor, properties, and functions. function InitClass(cx: PJSContext; var parent_proto: PJSObject; clasp: PJSClass; _constructor: JSNative; nargs: Cardinal; ps: PJSPropertySpec; fs: PJSFunctionSpec; static_ps: PJSPropertySpec; static_fs: PJSFunctionSpec): PJSObject; {$ifdef HASINLINE}inline;{$endif} /// Get the prototype of obj, storing it in result. // - Implements: ES6 [[GetPrototypeOf]] internal method. function GetPrototype(cx: PJSContext; out protop: PJSObject): Boolean; {$ifdef HASINLINE}inline;{$endif} /// Change the prototype of obj. // - Implements: ES6 [[SetPrototypeOf]] internal method. // - In cases where ES6 [[SetPrototypeOf]] returns false without an exception, // JS_SetPrototype throws a TypeError and returns false. // - Performance warning: JS_SetPrototype is very bad for performance. It may // cause compiled jit-code to be invalidated. It also causes not only obj but // all other objects in the same "group" as obj to be permanently deoptimized. // It's better to create the object with the right prototype from the start. function SetPrototype(cx: PJSContext; var proto: PJSObject): Boolean; {$ifdef HASINLINE}inline;{$endif} /// Get an array of the non-symbol enumerable properties of obj. // This function is roughly equivalent to: // // var result = []; // for (key in obj) // result.push(key); // return result; // // This is the closest thing we currently have to the ES6 [[Enumerate]] // internal method. function Enumerate(cx: PJSContext; out length: size_t; out data: PjsidVector): PJSIdArray; //array methods function GetArrayLength(cx: PJSContext; out length: uint32): Boolean; {$ifdef HASINLINE}inline;{$endif} function GetElement(cx: PJSContext; index: uint32; out vp: jsval): Boolean; {$ifdef HASINLINE}inline;{$endif} function SetElement(cx: PJSContext; index: uint32; const vp: jsval): Boolean; {$ifdef HASINLINE}inline;{$endif} function DeleteElement(cx: PJSContext; index: uint32; out res: JS_ObjectOpResult): Boolean; {$ifdef HASINLINE}inline;{$endif} //function methods function GetFunctionId: PJSString; {$ifdef HASINLINE}inline;{$endif} property FunctionId: PJSString read GetFunctionId; function DecompileFunction(cx: PJSContext; PrettyPrint: Boolean = true): PJSString; //arrayBuffer methods /// Check whether obj supports JS_GetTypedArray* APIs // - Note that this may return false if a security wrapper is encountered that // denies the unwrapping. // - if this test or one of the JS_Is*Array tests succeeds, then it is safe to call // the dedicated accessor JSAPI calls function IsTypedArrayObject: Boolean;{$ifdef HASINLINE}inline;{$endif} /// Check whether obj supports JS_GetArrayBufferView* APIs // - Note that this may return false if a security wrapper is encountered that // denies the unwrapping. // - if this test or one of the JS_Is*Array tests succeeds, then it is safe to call // the dedicated ArrayBufferView accessor JSAPI calls function IsArrayBufferViewObject: Boolean;{$ifdef HASINLINE}inline;{$endif} /// Test for specific 8 bit signed integer typed array types (ArrayBufferView subtypes) function IsInt8Array: Boolean;{$ifdef HASINLINE}inline;{$endif} /// Test for specific 8 bit unsigned integer typed array types (ArrayBufferView subtypes) function IsUint8Array: Boolean;{$ifdef HASINLINE}inline;{$endif} /// Test for specific 8 bit unsigned integer typed array types (ArrayBufferView subtypes) function IsUint8ClampedArray: Boolean;{$ifdef HASINLINE}inline;{$endif} /// Test for specific 16 bit signed integer typed array types (ArrayBufferView subtypes) function IsInt16Array: Boolean;{$ifdef HASINLINE}inline;{$endif} /// Test for specific 16 bit unsigned integer typed array types (ArrayBufferView subtypes) function IsUint16Array: Boolean;{$ifdef HASINLINE}inline;{$endif} /// Test for specific 32 bit signed integer typed array types (ArrayBufferView subtypes) function IsInt32Array: Boolean;{$ifdef HASINLINE}inline;{$endif} /// Test for specific 32 bit unsigned integer typed array types (ArrayBufferView subtypes) function IsUint32Array: Boolean;{$ifdef HASINLINE}inline;{$endif} /// Test for specific 32 bit float (single) typed array types (ArrayBufferView subtypes) function IsFloat32Array: Boolean;{$ifdef HASINLINE}inline;{$endif} /// Test for specific 64 bit float (double) typed array types (ArrayBufferView subtypes) function IsFloat64Array: Boolean;{$ifdef HASINLINE}inline;{$endif} /// Return the isShared flag of a typed array, which denotes whether // the underlying buffer is a SharedArrayBuffer. // // |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow // be known that it would pass such a test: it is a typed array or a wrapper of // a typed array, and the unwrapping will succeed. function GetTypedArraySharedness: Boolean;{$ifdef HASINLINE}inline;{$endif} /// Unwrap 8 bit signed integer typed array into direct memory buffer // - Return nil without throwing any exception if the object cannot be viewed as the // correct typed array, or the typed array object on success, filling both out parameters function GetObjectAsInt8Array(out length: uint32; out isSharedMemory:Boolean; out Data: Pint8Vector): PJSObject;{$ifdef HASINLINE}inline;{$endif} /// Unwrap 8 bit unsigned integer typed array into direct memory buffer // - Return nil without throwing any exception if the object cannot be viewed as the // correct typed array, or the typed array object on success, filling both out parameters function GetObjectAsUint8Array(out length: uint32; out isSharedMemory:Boolean; out Data: Puint8Vector): PJSObject;{$ifdef HASINLINE}inline;{$endif} /// Unwrap 8 bit unsigned integer typed array into direct memory buffer // - Return nil without throwing any exception if the object cannot be viewed as the // correct typed array, or the typed array object on success, filling both out parameters function GetObjectAsUint8ClampedArray(out length: uint32; out isSharedMemory:Boolean; out Data: Puint8Vector): PJSObject;{$ifdef HASINLINE}inline;{$endif} /// Unwrap 16 bit signed integer typed array into direct memory buffer // - Return nil without throwing any exception if the object cannot be viewed as the // correct typed array, or the typed array object on success, filling both out parameters function GetObjectAsInt16Array(out length: uint32; out isSharedMemory:Boolean; out Data: Pint16Vector): PJSObject;{$ifdef HASINLINE}inline;{$endif} /// Unwrap 16 bit unsigned integer typed array into direct memory buffer // - Return nil without throwing any exception if the object cannot be viewed as the // correct typed array, or the typed array object on success, filling both out parameters function GetObjectAsUint16Array(out length: uint32; out isSharedMemory:Boolean; out Data: Puint16Vector): PJSObject;{$ifdef HASINLINE}inline;{$endif} /// Unwrap 32 bit signed integer typed array into direct memory buffer // - Return nil without throwing any exception if the object cannot be viewed as the // correct typed array, or the typed array object on success, filling both out parameters function GetObjectAsInt32Array(out length: uint32; out isSharedMemory:Boolean; out Data: Pint32Vector): PJSObject;{$ifdef HASINLINE}inline;{$endif} /// Unwrap 32 bit unsigned integer typed array into direct memory buffer // - Return nil without throwing any exception if the object cannot be viewed as the // correct typed array, or the typed array object on success, filling both out parameters function GetObjectAsUint32Array(out length: uint32; out isSharedMemory:Boolean; out Data: Puint32Vector): PJSObject;{$ifdef HASINLINE}inline;{$endif} /// Unwrap 32 bit float (single) typed array into direct memory buffer // - Return nil without throwing any exception if the object cannot be viewed as the // correct typed array, or the typed array object on success, filling both out parameters function GetObjectAsFloat32Array(out length: uint32; out isSharedMemory:Boolean; out Data: Pfloat32Vector): PJSObject;{$ifdef HASINLINE}inline;{$endif} /// Unwrap 64 bit float (double) typed array into direct memory buffer // - Return nil without throwing any exception if the object cannot be viewed as the // correct typed array, or the typed array object on success, filling both out parameters function GetObjectAsFloat64Array(out length: uint32; out isSharedMemory:Boolean; out Data: Pfloat64Vector): PJSObject;{$ifdef HASINLINE}inline;{$endif} /// Unwrap an object as its raw binary memory buffer // - Return nil without throwing any exception if the object cannot be viewed as the // correct typed array, or the typed array object on success, filling both out parameters function GetObjectAsArrayBufferView(out length: uint32; out isSharedMemory:Boolean; out Data: Puint8Vector): PJSObject;{$ifdef HASINLINE}inline;{$endif} /// Unwrap an object as its raw binary memory buffer // - Return nil without throwing any exception if the object cannot be viewed as the // correct typed array, or the typed array object on success, filling both out parameters function GetObjectAsArrayBuffer(out length: uint32; out Data: Puint8Vector): PJSObject;{$ifdef HASINLINE}inline;{$endif} /// Get the type of elements in a typed array, or jsabTYPE_DATAVIEW if a DataView function GetArrayBufferViewType: JSArrayBufferViewType;{$ifdef HASINLINE}inline;{$endif} // function GetSharedArrayBufferViewType: JSArrayBufferViewType;{$ifdef HASINLINE}inline;{$endif} /// Check whether obj supports the JS_GetArrayBuffer* APIs // - Note that this may return false if a security wrapper is encountered that denies the // unwrapping // - If this test succeeds, then it is safe to call the various accessor JSAPI calls function IsArrayBufferObject: Boolean;{$ifdef HASINLINE}inline;{$endif} function IsSharedArrayBufferObject: Boolean; /// Return true if the arrayBuffer contains any data. This will return false for // ArrayBuffer.prototype and neutered ArrayBuffers. // // |obj| must have passed a JS_IsArrayBufferObject test, or somehow be known // that it would pass such a test: it is an ArrayBuffer or a wrapper of an // ArrayBuffer, and the unwrapping will succeed. function ArrayBufferHasData: Boolean; /// Return a pointer to an array buffer's data // - The buffer is still owned by the array buffer object, and should not // be modified on another thread. The returned pointer is stable across GCs // - obj must have passed a JS_IsArrayBufferObject test, or somehow be known // that it would pass such a test: it is an ArrayBuffer or a wrapper of an // ArrayBuffer, and the unwrapping will succeed. function GetArrayBufferData(out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Puint8Vector; overload;{$ifdef HASINLINE}inline;{$endif} function GetArrayBufferData: Puint8Vector; overload;{$ifdef HASINLINE}inline;{$endif} /// Check whether the obj is ArrayBufferObject and memory mapped. Note that this // may return false if a security wrapper is encountered that denies the // unwrapping. function IsMappedArrayBufferObject(obj: PJSObject): Boolean;{$ifdef HASINLINE}inline;{$endif} /// Return the number of elements in a typed array // - obj must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow // be known that it would pass such a test: it is a typed array or a wrapper of // a typed array, and the unwrapping will succeed. function GetTypedArrayLength: uint32;{$ifdef HASINLINE}inline;{$endif} /// Return the byte offset from the start of an array buffer to the start of a // typed array view // - obj must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow // be known that it would pass such a test: it is a typed array or a wrapper of // a typed array, and the unwrapping will succeed. function GetTypedArrayByteOffset: uint32; /// Return the byte length of a typed array // - obj must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow // be known that it would pass such a test: it is a typed array or a wrapper of // a typed array, and the unwrapping will succeed function GetTypedArrayByteLength: uint32;{$ifdef HASINLINE}inline;{$endif} /// More generic name for JS_GetTypedArrayByteLength to cover DataViews as well function GetArrayBufferViewByteLength: uint32;{$ifdef HASINLINE}inline;{$endif} /// Return a pointer to the start of the data referenced by a typed 8 bit signed integer array // - The data is still owned by the typed array, and should not be modified on // another thread // - obj must have passed a JS_Is*Array test, or somehow be known that it would // pass such a test: it is a typed array or a wrapper of a typed array, and the // unwrapping will succeed function GetInt8ArrayData(out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Pint8Vector;{$ifdef HASINLINE}inline;{$endif} /// Return a pointer to the start of the data referenced by a typed 8 bit unsigned integer array // - The data is still owned by the typed array, and should not be modified on // another thread // - obj must have passed a JS_Is*Array test, or somehow be known that it would // pass such a test: it is a typed array or a wrapper of a typed array, and the // unwrapping will succeed function GetUint8ArrayData(out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Puint8Vector; overload;{$ifdef HASINLINE}inline;{$endif} function GetUInt8ArrayData: Puint8Vector; overload;{$ifdef HASINLINE}inline;{$endif} /// Return a pointer to the start of the data referenced by a typed 8 bit unsigned integer array // - The data is still owned by the typed array, and should not be modified on // another thread // - obj must have passed a JS_Is*Array test, or somehow be known that it would // pass such a test: it is a typed array or a wrapper of a typed array, and the // unwrapping will succeed function GetUint8ClampedArrayData(out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Puint8Vector;{$ifdef HASINLINE}inline;{$endif} /// Return a pointer to the start of the data referenced by a typed 16 bit signed integer array // - The data is still owned by the typed array, and should not be modified on // another thread // - obj must have passed a JS_Is*Array test, or somehow be known that it would // pass such a test: it is a typed array or a wrapper of a typed array, and the // unwrapping will succeed function GetInt16ArrayData(out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Pint16Vector;{$ifdef HASINLINE}inline;{$endif} /// Return a pointer to the start of the data referenced by a typed 16 bit unsigned integer array // - The data is still owned by the typed array, and should not be modified on // another thread // - obj must have passed a JS_Is*Array test, or somehow be known that it would // pass such a test: it is a typed array or a wrapper of a typed array, and the // unwrapping will succeed function GetUint16ArrayData(out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Puint16Vector;{$ifdef HASINLINE}inline;{$endif} /// Return a pointer to the start of the data referenced by a typed 32 bit signed integer array // - The data is still owned by the typed array, and should not be modified on // another thread // - obj must have passed a JS_Is*Array test, or somehow be known that it would // pass such a test: it is a typed array or a wrapper of a typed array, and the // unwrapping will succeed function GetInt32ArrayData(out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Pint32Vector;{$ifdef HASINLINE}inline;{$endif} /// Return a pointer to the start of the data referenced by a typed 32 bit unsigned integer array // - The data is still owned by the typed array, and should not be modified on // another thread // - obj must have passed a JS_Is*Array test, or somehow be known that it would // pass such a test: it is a typed array or a wrapper of a typed array, and the // unwrapping will succeed function GetUint32ArrayData(out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Puint32Vector;{$ifdef HASINLINE}inline;{$endif} /// Return a pointer to the start of the data referenced by a typed 32 bit float (single) array // - The data is still owned by the typed array, and should not be modified on // another thread // - obj must have passed a JS_Is*Array test, or somehow be known that it would // pass such a test: it is a typed array or a wrapper of a typed array, and the // unwrapping will succeed function GetFloat32ArrayData(out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Pfloat32Vector;{$ifdef HASINLINE}inline;{$endif} /// Return a pointer to the start of the data referenced by a typed 64 bit float (double) array // - The data is still owned by the typed array, and should not be modified on // another thread // - obj must have passed a JS_Is*Array test, or somehow be known that it would // pass such a test: it is a typed array or a wrapper of a typed array, and the // unwrapping will succeed function GetFloat64ArrayData(out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Pfloat64Vector;{$ifdef HASINLINE}inline;{$endif} /// Return a pointer to the start of the data referenced by any typed array // and it's length. For ArrayBufferView return a pointer and length of slice. // - The data is still owned by the typed array, and should not be modified on // another thread // - If JSObject is not a typed array or arrayBufferView return false function GetBufferDataAndLength(out data: Puint8Vector; out len: uint32): boolean;{$ifdef HASINLINE}inline;{$endif} end; JSString = object /// get the UTF-8 text corresponding to this string, for a given // runtime execution context function ToUTF8(cx: PJSContext): RawUTF8; overload; /// get the UTF-8 text corresponding to this string, for a given // runtime execution context // - slightly faster overloaded method (avoid string assignment) procedure ToUTF8(cx: PJSContext; out result: RawUTF8); overload; /// Add UTF-8 text corresponding to this string to writer, // without escaping procedure ToUTF8(cx: PJSContext; W: TTextWriter); overload; /// get the Ansi text corresponding to this string // if source string containt non-ascii chars // convert it to Ansi using global CurrentAnsiConvert from SynCommons function ToAnsi(cx: PJSContext): AnsiString; /// get the UTF-16 text corresponding to this string, for a given // runtime execution context function ToSynUnicode(cx: PJSContext): SynUnicode; function ToString(cx: PJSContext): string; procedure ToVariant(cx: PJSContext; var Value: Variant); procedure ToJSONString(cx: PJSContext; W: TTextWriter); /// get a jsval corresponding to this string function ToJSVal: jsval; function HasLatin1Chars: Boolean; function Length: size_t; function GetLatin1StringCharsAndLength(cx: PJSContext; out len: size_t):PCChar; function GetTwoByteStringCharsAndLength(cx: PJSContext; out len: size_t):PCChar16; end; JSClassOps = record addProperty: JSAddPropertyOp; delProperty: JSDeletePropertyOp; getProperty: JSGetterOp; setProperty: JSSetterOp; enumerate: JSEnumerateOp; resolve: JSResolveOp; mayResolve: JSMayResolveOp; finalize: JSFinalizeOp; call: JSNative; hasInstance: JSHasInstanceOp; construct: JSNative; trace: JSTraceOp; end; PJSClassOps = ^JSClassOps; JSClass = record name: PCChar; flags: uint32; cOps: PJSClassOps; reserved: array [0..2] of pointer; end; { JSCompileOptions } JSCompileOptions = object procedure SetFileLineAndUtf8(const fn: RawUTF8; l: cardinal; isUtf8: boolean); end; // internal alignment of JSCompileOptions is a HACK and depends on C++ pragma // the only function we need is JSCompileOptions.SetFileLineAndUtf8 //JSCompileOptions = record // reserved: array[0..1] of Pointer; // filename: PCChar; // // introducerFilename_: PCChar; // sourceMapURL_: PCChar16; // version: JSVersion; //JSVersion version; // versionSet: boolean; //bool versionSet; // utf8: boolean; //bool utf8 // selfHostingMode: boolean; // bool selfHostingMode // canLazilyParse: boolean; // bool canLazilyParse // //strictOption: boolean; // //extraWarningsOption: boolean; // //werrorOption: boolean; // //AsmJSOption asmJSOption; // //bool throwOnAsmJSValidationFailureOption; // //bool forceAsync; // //bool installedFile; // 'true' iff pre-compiling js file in packaged app // //bool sourceIsLazy; // reserved1: array[{$ifdef CPUX64}6{$else}7{$endif}..24] of Pointer; //end; JSRootedValue = record Stack: JSUnknown; prev: JSUnknown; ptr: jsval; end; JSRootedObjectStack = record Last: PJSRootedObject; end; PJSRootedObjectStack = ^JSRootedObjectStack; JSRootedObject = record Stack: PJSRootedObjectStack; prev: PJSRootedObject; ptr: PJSObject; end; JSRootedString = record Stack: JSUnknown; prev: JSUnknown; ptr: PJSString; end; PJSJitInfo = JSUnknown; JSNativeWrapper = record op: JSNative; info: PJSJitInfo end; SelfHostedWrapper = record unused: Pointer; funname: PCChar; end; JSPropertySpecGetSetRec = record case Boolean of true: (native: JSNativeWrapper); false: (selfHosted: SelfHostedWrapper); end; JSPropertySpec = record name: PCChar; flags: uint8; getter: JSPropertySpecGetSetRec; setter: JSPropertySpecGetSetRec; end; TJSPropertySpecDynArray = array of JSPropertySpec; JSFunctionSpec = record name: PCChar; call: JSNativeWrapper; nargs: uint16; flags: uint16; selfHostedName: PCChar; end; TJSFunctionSpecArray = array of JSFunctionSpec; /// internal structure used to report JavaScript errors JSErrorReport = record /// The (default) error message. // If ownsMessage is true, the it is freed in destructor. message_: PUTF8Char; /// offending source line without final #13 // If ownsLinebuf is true, the buffer is freed in destructor. linebuf: PCChar16; /// number of chars in linebuf_. Does not include trailing '\0' linebufLength: size_t; /// The 0-based offset of error token in linebuf_. tokenOffset: size_t; /// source file name, URL, etc., or null filename: PCChar; /// source line number lineno: uint32; /// zero-based column index in line column: uint32; /// error/warning, etc. flags: uint32; /// the error number, e.g. see js.msg errorNumber: uint32; /// One of the JSExnType constants exnType: JSExnType; /// See the comment in ReadOnlyCompileOptions. isMuted: Boolean; ownsLinebuf: Boolean; ownsMessage: Boolean; end; /// used by JSErrorCallback() callback JSErrorFormatString = record /// The error message name in ASCII. name: PCChar; /// The error format string (UTF-8 if js_CStringsAreUTF8) format: PCChar; /// The number of arguments to expand in the formatted error message argCount: uint16; /// One of the JSExnType constants above exnType: JSExnType; end; /// * Finalizes external strings created by JS_NewExternalString. JSStringFinalizer = record finalize: JSStringFinalizerOp; end; const /// JSClass instance objects have private slot JSCLASS_HAS_PRIVATE = 1 shl 0; /// JSClass instance class's initialization code will call // SetNewObjectMetadata itself JSCLASS_DELAY_METADATA_CALLBACK = 1 shl 1; /// JSClass instance private is (nsISupports*) JSCLASS_PRIVATE_IS_NSISUPPORTS = 1 shl 3; /// JSClass instance objects are DOM JSCLASS_IS_DOMJSCLASS = 1 shl 4; /// JSClass instance objects of this class act like the value undefined, // in some contexts JSCLASS_EMULATES_UNDEFINED = 1 shl 6; /// Reserved for embeddings. JSCLASS_USERBIT1 = 1 shl 7; /// JSClass instance room for 8 flags below JSCLASS_RESERVED_SLOTS_SHIFT = 8; /// JSClass instance and 16 above this field JSCLASS_RESERVED_SLOTS_WIDTH = 8; JSCLASS_RESERVED_SLOTS_MASK = (uint32(1) shl JSCLASS_RESERVED_SLOTS_WIDTH)-1; JSCLASS_HIGH_FLAGS_SHIFT = (JSCLASS_RESERVED_SLOTS_SHIFT + JSCLASS_RESERVED_SLOTS_WIDTH); JSCLASS_IS_ANONYMOUS = (1 shl (JSCLASS_HIGH_FLAGS_SHIFT+0)); JSCLASS_IS_GLOBAL = (1 shl (JSCLASS_HIGH_FLAGS_SHIFT+1)); JSCLASS_INTERNAL_FLAG2 = (1 shl (JSCLASS_HIGH_FLAGS_SHIFT+2)); JSCLASS_INTERNAL_FLAG3 = (1 shl (JSCLASS_HIGH_FLAGS_SHIFT+3)); JSCLASS_IS_PROXY = (1 shl (JSCLASS_HIGH_FLAGS_SHIFT+4)); JSCLASS_SKIP_NURSERY_FINALIZE = (1 shl (JSCLASS_HIGH_FLAGS_SHIFT+5)); // Reserved for embeddings. JSCLASS_USERBIT2 = (1 shl (JSCLASS_HIGH_FLAGS_SHIFT+6)); JSCLASS_USERBIT3 = (1 shl (JSCLASS_HIGH_FLAGS_SHIFT+7)); JSCLASS_BACKGROUND_FINALIZE = (1 shl (JSCLASS_HIGH_FLAGS_SHIFT+8)); JSCLASS_FOREGROUND_FINALIZE = (1 shl (JSCLASS_HIGH_FLAGS_SHIFT+9)); // Bits 26 through 31 are reserved for the CACHED_PROTO_KEY mechanism, see // below. JSCLASS_GLOBAL_APPLICATION_SLOTS = 5; // JSProto_LIMIT = 46; JSCLASS_GLOBAL_SLOT_COUNT = (JSCLASS_GLOBAL_APPLICATION_SLOTS + ord(JSProto_LIMIT) * 2 + 39); JSCLASS_GLOBAL_FLAGS = JSCLASS_IS_GLOBAL or (((JSCLASS_GLOBAL_SLOT_COUNT) and JSCLASS_RESERVED_SLOTS_MASK) shl JSCLASS_RESERVED_SLOTS_SHIFT); /// Property attributes, set in JSPropertySpec and passed to API functions. // NB: The data structure in which some of these values are stored only uses // a uint8_t to store the relevant information. Proceed with caution if // trying to reorder or change the the first byte worth of flags. JSPROP_ENUMERATE = $01; // property is visible to for/in loop JSPROP_READONLY = $02; // not settable: assignment is no-op. // This flag is only valid when neither // JSPROP_GETTER nor JSPROP_SETTER is // set. JSPROP_PERMANENT = $04; // property cannot be deleted JSPROP_PROPOP_ACCESSORS = $08; // Passed to JS_Define(UC)Property* and // JS_DefineElement if getters/setters // are JSPropertyOp/JSStrictPropertyOp JSPROP_GETTER = $10; // property holds getter function JSPROP_SETTER = $20; // property holds setter function JSPROP_SHARED = $40; // don't allocate a value slot for this // property; don't copy the property on // set of the same-named property in an // object that delegates to a prototype // containing this property JSPROP_INTERNAL_USE_BIT= $80; // name is actually (int) index JSPROP_DEFINE_LATE = $100; // Don't define property when initially creating // the constructor. Some objects like Function/Object // have self-hosted functions that can only be defined // after the initialization is already finished. JSFUN_STUB_GSOPS = $200; // use JS_PropertyStub getter/setter // instead of defaulting to class gsops // for property holding function JSFUN_CONSTRUCTOR = $400; // native that can be called as a ctor /// enumerable read-only property attributes JSPROPS_STATIC_RO = JSPROP_ENUMERATE or JSPROP_READONLY or JSPROP_PERMANENT; JSFUN_HAS_REST = $1000; // function has ...rest parameter. JSPROP_REDEFINE_NONCONFIGURABLE = $1000; // If set, will allow redefining a // non-configurable property, but // only on a non-DOM global. This // is a temporary hack that will // need to go away in bug // 1105518 // Resolve hooks and enumerate hooks must pass this flag when calling // JS_Define* APIs to reify lazily-defined properties. // JSPROP_RESOLVING is used only with property-defining APIs. It tells the // engine to skip the resolve hook when performing the lookup at the beginning // of property definition. This keeps the resolve hook from accidentally // triggering itself: unchecked recursion. // For enumerate hooks, triggering the resolve hook would be merely silly, not // fatal, except in some cases involving non-configurable properties. JSPROP_RESOLVING = $2000; JSPROP_IGNORE_ENUMERATE = $4000; // ignore the value in JSPROP_ENUMERATE. // This flag only valid when defining over // an existing property. JSPROP_IGNORE_READONLY = $8000; // ignore the value in JSPROP_READONLY. // This flag only valid when defining over // an existing property. JSPROP_IGNORE_PERMANENT = $10000; // ignore the value in JSPROP_PERMANENT. // This flag only valid when defining over // an existing property. JSPROP_IGNORE_VALUE = $20000; // ignore the Value in the descriptor. Nothing was // specified when passed to Object.defineProperty // from script. type /// available options for JS Objects Properties TJSPropertyAttr = ( jspEnumerate, jspReadOnly, jspPermanent, jspPropAccessors, jspGetter, jspSetter, jspShared, jspInternal, jspDefineLate, jspFunStubGSOps, jspFunConstructor, jspFunGenericNative, jspRedefineNonConfigurable, jspResolving, jspIgnoreEnumerate, jspIgnoreReadOnly, jspIgnorePermanent, jspIgnoreValue); /// set of available options for JS Objects Properties TJSPropertyAttrs = set of TJSPropertyAttr; ESMException = class(ESynException) private FJSErrorNum: integer; FFileName: RawUTF8; FLineNum: integer; FJSStackTrace: SynUnicode; public /// constructor which will create JavaScript exception with JS stack trace constructor CreateWithTrace(const AFileName: RawUTF8; AJSErrorNum, ALineNum: integer; AMessage: string; const AStackTrace: SynUnicode); /// Format a JS exception as text // If SM_DEBUG is defined will write full JS stack, including SyNode core_modules calls // if not - core_modules is cutched from stack trace for simplicity procedure WriteFormatted(WR: TTextWriter); {$ifndef NOEXCEPTIONINTERCEPT} /// Custmize SM exception log output function CustomLog(WR: TTextWriter; const Context: TSynLogExceptionContext): boolean; override; {$endif} published property ErrorNum: integer read FJSErrorNum; property Stack: SynUnicode read FJSStackTrace; property FileName: RawUTF8 read FFileName; property Line: integer read FLineNum; end; /// pass exception of this type to JSError for raising JS RangeError exception ESMRangeException = class(ESMException); /// pass exception of this type to JSError for raising JS TypeError exception ESMTypeException = class(ESMException); /// to be used to catch Delphi exceptions inside JSNative function implementation // - usage example: // ! try // ! doSomething() // ! Result := True; // ! except // ! on E: Exception do begin // ! JSError(cx, E); // ! Result := False; // ! end; procedure JSError(cx: PJSContext; aException: Exception); procedure JSErrorUC(cx: PJSContext; aMessage: WideString; errorCode: integer = 0); procedure JSRangeErrorUC(cx: PJSContext; aMessage: WideString); procedure JSTypeErrorUC(cx: PJSContext; aMessage: WideString); // must be called ONCE per process before any interaction with JavaScript function InitJS: Boolean; // must be called ONCE per process after all engine managers are destroyed procedure ShutDownJS; var nullObj: PJSObject = nil; const {$ifdef CPU64} JSVAL_TAG_SHIFT = 47; JSVAL_PAYLOAD_MASK = $00007FFFFFFFFFFF; JSVAL_TAG_MASK = $FFFF800000000000; JSVAL_TAG_MAX_DOUBLE = UInt32($1FFF0); JSVAL_TAG_INT32 = UInt32(JSVAL_TAG_MAX_DOUBLE or UInt8(JSVAL_TYPE_INT32)); JSVAL_TAG_UNDEFINED = UInt32(JSVAL_TAG_MAX_DOUBLE or UInt8(JSVAL_TYPE_UNDEFINED)); JSVAL_TAG_STRING = UInt32(JSVAL_TAG_MAX_DOUBLE or UInt8(JSVAL_TYPE_STRING)); JSVAL_TAG_SYMBOL = UInt32(JSVAL_TAG_MAX_DOUBLE or UInt8(JSVAL_TYPE_SYMBOL)); JSVAL_TAG_BOOLEAN = UInt32(JSVAL_TAG_MAX_DOUBLE or UInt8(JSVAL_TYPE_BOOLEAN)); JSVAL_TAG_MAGIC = UInt32(JSVAL_TAG_MAX_DOUBLE or UInt8(JSVAL_TYPE_MAGIC)); JSVAL_TAG_NULL = UInt32(JSVAL_TAG_MAX_DOUBLE or UInt8(JSVAL_TYPE_NULL)); JSVAL_TAG_OBJECT = UInt32(JSVAL_TAG_MAX_DOUBLE or UInt8(JSVAL_TYPE_OBJECT)); JSVAL_SHIFTED_TAG_MAX_DOUBLE = (uint64(JSVAL_TAG_MAX_DOUBLE) shl JSVAL_TAG_SHIFT) or $FFFFFFFF; JSVAL_SHIFTED_TAG_INT32 = uint64(JSVAL_TAG_INT32) shl JSVAL_TAG_SHIFT; JSVAL_SHIFTED_TAG_UNDEFINED = uint64(JSVAL_TAG_UNDEFINED) shl JSVAL_TAG_SHIFT; JSVAL_SHIFTED_TAG_STRING = uint64(JSVAL_TAG_STRING) shl JSVAL_TAG_SHIFT; JSVAL_SHIFTED_TAG_SYMBOL = uint64(JSVAL_TAG_SYMBOL) shl JSVAL_TAG_SHIFT; JSVAL_SHIFTED_TAG_BOOLEAN = uint64(JSVAL_TAG_BOOLEAN) shl JSVAL_TAG_SHIFT; JSVAL_SHIFTED_TAG_MAGIC = uint64(JSVAL_TAG_MAGIC) shl JSVAL_TAG_SHIFT; JSVAL_SHIFTED_TAG_NULL = uint64(JSVAL_TAG_NULL) shl JSVAL_TAG_SHIFT; JSVAL_SHIFTED_TAG_OBJECT = uint64(JSVAL_TAG_OBJECT) shl JSVAL_TAG_SHIFT; {$endif} {$ifdef CPU64} JSVAL_NULL_impl = QWord(JSVAL_SHIFTED_TAG_NULL); JSVAL_VOID_impl = QWord(JSVAL_SHIFTED_TAG_UNDEFINED); {$ELSE} JSVAL_NULL_impl = QWord(QWord(JSVAL_TAG_NULL ) shl 32) or 0; JSVAL_VOID_impl = QWord(QWord(JSVAL_TAG_UNDEFINED) shl 32) or 0; {$endif} JSVAL_NAN_impl = $7FF8000000000000; const JSVAL_NULL: jsval = (_l:(asBits: JSVAL_NULL_impl)); JSVAL_VOID: jsval = (_l:(asBits: JSVAL_VOID_impl)); JSVAL_NAN: jsval = (_l:(asBits: JSVAL_NAN_impl)); const JSREPORT_ERROR = 0; JSREPORT_WARNING = 1; JSREPORT_EXCEPTION = 2; JSREPORT_STRICT = 4; JSREPORT_STRICT_MODE_ERROR = 8; function SimpleVariantToJSval(cx: PJSContext; val: Variant): jsval; const SpiderMonkeyLib = 'synsm'{$IFDEF MSWINDOWS} + '.dll'{$ENDIF}; type TModuleHandle = HINST; const INVALID_MODULEHANDLE_VALUE = TModuleHandle(0); var SM52Lib: TModuleHandle = INVALID_MODULEHANDLE_VALUE; /// Initialize SpiderMonkey, returning true only if initialization succeeded. // Once this method has succeeded, it is safe to call JS_NewRuntime and other // JSAPI methods. // - This method must be called before any other JSAPI method is used on any // thread. Once it has been used, it is safe to call any JSAPI method, and it // remains safe to do so until JS_ShutDown is correctly called. // - It is currently not possible to initialize SpiderMonkey multiple times (that // is, calling JS_Init/JSAPI methods/JS_ShutDown in that order, then doing so // again). This restriction may eventually be lifted. type TJS_Initialize = function : Boolean; cdecl; var JS_Init: TJS_Initialize{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_Initialize'; {$ENDIF} procedure JS_DisableExtraThreads; cdecl; external SpiderMonkeyLib name 'SM_DisableExtraThreads'; /// Destroy free-standing resources allocated by SpiderMonkey, not associated // with any runtime, context, or other structure. // - This method should be called after all other JSAPI data has been properly // cleaned up: every new runtime must have been destroyed, every new context // must have been destroyed, and so on. Calling this method before all other // resources have been destroyed has undefined behavior. // - Failure to call this method, at present, has no adverse effects other than // leaking memory. This may not always be the case; it's recommended that all // embedders call this method when all other JSAPI operations have completed. // - It is currently not possible to initialize SpiderMonkey multiple times (that // is, calling JS_Init/JSAPI methods/JS_ShutDown in that order, then doing so // again). This restriction may eventually be lifted. type TJS_ShutDown = procedure; cdecl; var JS_ShutDown: TJS_ShutDown{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_ShutDown'; {$ENDIF} /// Microseconds since the epoch, midnight, January 1, 1970 UTC. type TJS_Now = function : int64; cdecl; var JS_Now: TJS_Now{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_Now'; {$ENDIF} /// Returns the empty string as a JSString object. type TJS_GetEmptyString = function (cx: PJSContext): PJSString; cdecl; var JS_GetEmptyString: TJS_GetEmptyString{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetEmptyString'; {$ENDIF} /// Determines the JS data type of a JS value. type TJS_TypeOfValue = function (cx: PJSContext; var v: jsval): JSType; cdecl; var JS_TypeOfValue: TJS_TypeOfValue{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_TypeOfValue'; {$ENDIF} /// indicates to the JS engine that the calling thread is entering a region // of code that may call into the JSAPI but does not block type TJS_BeginRequest = procedure (cx: PJSContext); cdecl; var JS_BeginRequest: TJS_BeginRequest{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_BeginRequest'; {$ENDIF} /// indicates to the JS engine that the calling thread is leaving a region // of code that may call into the JSAPI but does not block type TJS_EndRequest = procedure (cx: PJSContext); cdecl; var JS_EndRequest: TJS_EndRequest{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_EndRequest'; {$ENDIF} /// Create a new JSContext type TJS_NewContext = function (maxbytes: uint32; maxNurseryBytes: uint32 = 16 * (1 SHL 20); parentContext: PJSContext = nil): PJSContext; cdecl; var JS_NewContext: TJS_NewContext{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewContext'; {$ENDIF} type TInitSelfHostedCode = function (cx: PJSContext): boolean; cdecl; var InitSelfHostedCode: TInitSelfHostedCode{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_InitSelfHostedCode'; {$ENDIF} /// Destroy a JSContext. type TJS_DestroyContext = procedure (cx: PJSContext); cdecl; var JS_DestroyContext: TJS_DestroyContext{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_DestroyContext'; {$ENDIF} /// Read access a JSContext field for application-specific data. // Memory management for this private data is the application's responsibility. // The JavaScript engine itself never uses it. type TJS_GetContextPrivate = function (cx: PJSContext): Pointer; cdecl; var JS_GetContextPrivate: TJS_GetContextPrivate{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetContextPrivate'; {$ENDIF} /// Write access a JSContext field for application-specific data. // Memory management for this private data is the application's responsibility. // The JavaScript engine itself never uses it. type TJS_SetContextPrivate = procedure (cx: PJSContext; data: Pointer); cdecl; var JS_SetContextPrivate: TJS_SetContextPrivate{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_SetContextPrivate'; {$ENDIF} /// This function makes a cross-compartment wrapper for the given JS object. // Details see here http://stackoverflow.com/questions/18730477/what-does-js-wrapobject-do type TJS_WrapObject = function (cx: PJSContext; var obj: PJSObject): boolean; cdecl; var JS_WrapObject: TJS_WrapObject{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_WrapObject'; {$ENDIF} /// Enter a different compartment on the given context, so that objects in that // compartment can be accessed. // - NB: This API is infallible; a NULL return value does not indicate error type TJS_EnterCompartment = function (cx: PJSContext; target: PJSObject): PJSCompartment; cdecl; var JS_EnterCompartment: TJS_EnterCompartment{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_EnterCompartment'; {$ENDIF} /// Leave a the compartment, returning to the compartment active before the // corresponding JS_EnterCompartment. type TJS_LeaveCompartment = procedure (cx: PJSContext; oldCompartment: PJSCompartment); cdecl; var JS_LeaveCompartment: TJS_LeaveCompartment{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_LeaveCompartment'; {$ENDIF} /// Initialize standard JS class constructors, prototypes, and any top-level // functions and constants associated with the standard classes (e.g. isNaN // for Number). // - NB: This sets cx's global object to obj if it was null. type TJS_InitStandardClasses = function (cx: PJSContext; var obj: PJSObject): boolean; cdecl; var JS_InitStandardClasses: TJS_InitStandardClasses{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_InitStandardClasses'; {$ENDIF} ///Return the global object for the active function on the context. type TJS_CurrentGlobalOrNull = function (cx: PJSContext):PJSObject; cdecl; var JS_CurrentGlobalOrNull: TJS_CurrentGlobalOrNull{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_CurrentGlobalOrNull'; {$ENDIF} /// Add 'Reflect.parse', a SpiderMonkey extension, to the Reflect object on the // given global. type TJS_InitReflectParse = function (cx: PJSContext; var obj: PJSObject): boolean; cdecl; var JS_InitReflectParse: TJS_InitReflectParse{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_InitReflectParse'; {$ENDIF} /// Initialize the 'ctypes' object on a global variable 'obj'. The 'ctypes' // object will be sealed. type TJS_InitCTypesClass = function (cx: PJSContext; var obj: PJSObject): boolean; cdecl; var JS_InitCTypesClass: TJS_InitCTypesClass{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_InitCTypesClass'; {$ENDIF} /// Initialize the 'Debugger' object on a global variable 'obj'. The 'ctypes' // object will be sealed. type TJS_DefineDebuggerObject = function (cx: PJSContext; var obj: PJSObject): boolean; cdecl; var JS_DefineDebuggerObject: TJS_DefineDebuggerObject{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_DefineDebuggerObject'; {$ENDIF} /// Performs garbage collection in the JS memory pool. type TJS_GC = procedure (cx: PJSContext); cdecl; var JS_GC: TJS_GC{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GC'; {$ENDIF} /// Offer the JavaScript engine an opportunity to perform garbage collection if needed. type TJS_MaybeGC = procedure (cx: PJSContext); cdecl; var JS_MaybeGC: TJS_MaybeGC{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_MaybeGC'; {$ENDIF} ///Set performance parameters related to garbage collection. type TJS_SetGCParameter = procedure (cx: PJSContext; key: JSGCParamKey; value: uint32); cdecl; var JS_SetGCParameter: TJS_SetGCParameter{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_SetGCParameter'; {$ENDIF} ///Get performance parameters related to garbage collection. type TJS_GetGCParameter = function (cx: PJSContext; key: JSGCParamKey): uint32; cdecl; var JS_GetGCParameter: TJS_GetGCParameter{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetGCParameter'; {$ENDIF} ///Adjust performance parameters related to garbage collection based on available memory(in megabytes). type TJS_SetGCParametersBasedOnAvailableMemory = procedure (cx: PJSContext; availMem: uint32); cdecl; var JS_SetGCParametersBasedOnAvailableMemory: TJS_SetGCParametersBasedOnAvailableMemory{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_SetGCParametersBasedOnAvailableMemory'; {$ENDIF} /// Creates a new JSString whose characters are stored in external memory, i.e., // memory allocated by the application, not the JavaScript engine // - Since the program allocated the memory, it will need to free it; // this happens in an external string finalizer indicated by the type parameter. // - chars is Pointer to the first element of an array of jschars. // This array is used as the character buffer of the JSString to be created. // The array must be populated with the desired character data before JS_NewExternalString // is called, and the array must remain in memory, with its contents unchanged, // for as long as the JavaScript engine needs to hold on to it. // (Ultimately, the string will be garbage collected, and the JavaScript engine will // call the string finalizer callback, allowing the application to free the array) // - The text buffer array does not need to be zero-terminated. type TJS_NewExternalString = function (cx: PJSContext; chars: PCChar16; length: size_t; fin: PJSStringFinalizer): PJSString; cdecl; var JS_NewExternalString: TJS_NewExternalString{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewExternalString'; {$ENDIF} /// Set the size of the native stack that should not be exceed. To disable // stack size checking pass 0. // - SpiderMonkey allows for a distinction between system code (such as GCs, which // may incidentally be triggered by script but are not strictly performed on // behalf of such script), trusted script (as determined by JS_SetTrustedPrincipals), // and untrusted script. Each kind of code may have a different stack quota, // allowing embedders to keep higher-priority machinery running in the face of // scripted stack exhaustion by something else. // - The stack quotas for each kind of code should be monotonically descending, // and may be specified with this function. If 0 is passed for a given kind // of code, it defaults to the value of the next-highest-priority kind. // - This function may only be called immediately after the runtime is initialized // and before any code is executed and/or interrupts requested. type TJS_SetNativeStackQuota = procedure (cx: PJSContext; systemCodeStackSize: size_t; trustedScriptStackSize: size_t = 0; untrustedScriptStackSize: size_t = 0); cdecl; var JS_SetNativeStackQuota: TJS_SetNativeStackQuota{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_SetNativeStackQuota'; {$ENDIF} /// Convert a JS::Value to type jsid. type TJS_ValueToId = function (cx: PJSContext; var v: jsval; out id: jsid): Boolean; cdecl; var JS_ValueToId: TJS_ValueToId{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_ValueToId'; {$ENDIF} /// Convert a jsid to type JS::Value. type TJS_IdToValue = function (cx: PJSContext; id: jsid; out v: jsval): Boolean; cdecl; var JS_IdToValue: TJS_IdToValue{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_IdToValue'; {$ENDIF} type TJS_ValueToSource = function (cx: PJSContext; var v: jsval): PJSString; cdecl; var JS_ValueToSource: TJS_ValueToSource{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_ValueToSource'; {$ENDIF} /// Make a JSClass accessible to JavaScript code by creating its prototype, // constructor, properties, and functions. type TJS_InitClass = function (cx: PJSContext; var obj: PJSObject; var parent_proto: PJSObject; clasp: PJSClass; _constructor: JSNative; nargs: uintN; ps: PJSPropertySpec; fs: PJSFunctionSpec; static_ps: PJSPropertySpec; static_fs: PJSFunctionSpec): PJSObject; cdecl; var JS_InitClass: TJS_InitClass{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_InitClass'; {$ENDIF} /// Retrieves the class associated with an object. type TJS_GetClass = function (obj: PJSObject): PJSClass; cdecl; var JS_GetClass: TJS_GetClass{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetClass'; {$ENDIF} /// JSAPI method equivalent to the instanceof operator in JavaScript. type TJS_HasInstance = function (cx: PJSContext; var obj: PJSObject; var val: jsval; out res: Boolean): Boolean; cdecl; var JS_HasInstance: TJS_HasInstance{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_HasInstance'; {$ENDIF} /// Access the private data field of an object. type TJS_GetPrivate = function (obj: PJSObject): Pointer; cdecl; var JS_GetPrivate: TJS_GetPrivate{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetPrivate'; {$ENDIF} /// Sets the private data field of an object. type TJS_SetPrivate = procedure (obj: PJSObject; data: Pointer); cdecl; var JS_SetPrivate: TJS_SetPrivate{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_SetPrivate'; {$ENDIF} /// Retrieves the constructor for an object. type TJS_GetConstructor = function (cx: PJSContext; var proto: PJSObject): PJSObject; cdecl; var JS_GetConstructor: TJS_GetConstructor{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetConstructor'; {$ENDIF} /// Retrieve the private data associated with an object, if that object is an // instance of a specified class. type TJS_GetInstancePrivate = function (cx: PJSContext; var obj: PJSObject; clasp: PJSClass; args: JSUnknown): Pointer; cdecl; var JS_GetInstancePrivate: TJS_GetInstancePrivate{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetInstancePrivate'; {$ENDIF} /// Create a new JavaScript object for use as a global object. type TJS_NewGlobalObject = function (cx: PJSContext; clasp: PJSClass; principals: PJSPrincipals; hookOption: OnNewGlobalHookOption; options: PJS_CompartmentOptions): PJSObject; cdecl; var JS_NewGlobalObject: TJS_NewGlobalObject{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewGlobalObject'; {$ENDIF} /// Spidermonkey does not have a good way of keeping track of what compartments should be marked on /// their own. We can mark the roots unconditionally, but marking GC things only relevant in live /// compartments is hard. To mitigate this, we create a static trace hook, installed on each global /// object, from which we can be sure the compartment is relevant, and mark it. /// /// It is still possible to specify custom trace hooks for global object classes. They can be /// provided via the CompartmentOptions passed to JS_NewGlobalObject. type TJS_GlobalObjectTraceHook = procedure (trc: Pointer{ JSTracer }; global: PJSObject); cdecl; var JS_GlobalObjectTraceHook: TJS_GlobalObjectTraceHook{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GlobalObjectTraceHook'; {$ENDIF} /// Create a new object based on a specified class type TJS_NewObject = function (cx: PJSContext; clasp: PJSClass): PJSObject; cdecl; var JS_NewObject: TJS_NewObject{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewObject'; {$ENDIF} /// Create a new object based on a specified class // - Unlike JS_NewObject, JS_NewObjectWithGivenProto does not compute a default // proto. If proto is nullptr, the JS object will have `null` as [[Prototype]]. type TJS_NewObjectWithGivenProto = function (cx: PJSContext; clasp: PJSClass; var proto: PJSObject): PJSObject; cdecl; var JS_NewObjectWithGivenProto: TJS_NewObjectWithGivenProto{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewObjectWithGivenProto'; {$ENDIF} /// Get the prototype of obj, storing it in result. // - Implements: ES6 [[GetPrototypeOf]] internal method. type TJS_GetPrototype = function (cx: PJSContext; var obj: PJSObject; out result: PJSObject):Boolean; cdecl; var JS_GetPrototype: TJS_GetPrototype{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetPrototype'; {$ENDIF} /// Change the prototype of obj. // - Implements: ES6 [[SetPrototypeOf]] internal method. // - In cases where ES6 [[SetPrototypeOf]] returns false without an exception, // JS_SetPrototype throws a TypeError and returns false. // - Performance warning: JS_SetPrototype is very bad for performance. It may // cause compiled jit-code to be invalidated. It also causes not only obj but // all other objects in the same "group" as obj to be permanently deoptimized. // It's better to create the object with the right prototype from the start. type TJS_SetPrototype = function (cx: PJSContext; var obj: PJSObject; var proto: PJSObject):Boolean; cdecl; var JS_SetPrototype: TJS_SetPrototype{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_SetPrototype'; {$ENDIF} /// Create a new property on an object. // Name indentifies by ID type TJS_DefinePropertyById = function (cx: PJSContext; var obj: PJSObject; var id: jsid; var value: jsval; attrs: uint32; getter: JSNative; setter: JSNative): boolean; cdecl; var JS_DefinePropertyById: TJS_DefinePropertyById{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_DefinePropertyById'; {$ENDIF} /// Create a new property on an object. // Name indentifies by ansi string type TJS_DefineProperty = function (cx: PJSContext; var obj: PJSObject; const name: PCChar; var value: jsval; attrs: uint32; getter: JSNative; setter: JSNative): boolean; cdecl; var JS_DefineProperty: TJS_DefineProperty{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_DefineProperty'; {$ENDIF} /// Create a new property on an object. // Name indentifies by unicode string type TJS_DefineUCProperty = function (cx: PJSContext; var obj: PJSObject; const name: PCChar16; namelen: size_t; var value: jsval; attrs: uint32; getter: JSNative; setter: JSNative): Boolean; cdecl; var JS_DefineUCProperty: TJS_DefineUCProperty{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_DefineUCProperty'; {$ENDIF} /// Determine whether a JavaScript object has a specified property. // Name indentifies by ansi string type TJS_HasProperty = function (cx: PJSContext; var obj: PJSObject; const name: PCChar; var found: Boolean): Boolean; cdecl; var JS_HasProperty: TJS_HasProperty{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_HasProperty'; {$ENDIF} /// Determine whether a JavaScript object has a specified property. // Name indentifies by unicode string type TJS_HasUCProperty = function (cx: PJSContext; var obj: PJSObject; const name: PCChar16; namelen: size_t; var found: Boolean): Boolean; cdecl; var JS_HasUCProperty: TJS_HasUCProperty{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_HasUCProperty'; {$ENDIF} /// Find a specified property and retrieve its value. // Name indentifies by ID type TJS_GetPropertyById = function (cx: PJSContext; var obj: PJSObject; var id: jsid; out vp: jsval): boolean; cdecl; var JS_GetPropertyById: TJS_GetPropertyById{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetPropertyById'; {$ENDIF} /// Find a specified property and retrieve its value. // Name indentifies by ansi string type TJS_GetProperty = function (cx: PJSContext; var obj: PJSObject; const name: PCChar; out vp: jsval): boolean; cdecl; var JS_GetProperty: TJS_GetProperty{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetProperty'; {$ENDIF} /// Find a specified property and retrieve its value. // Name indentifies by unicode string type TJS_GetUCProperty = function (cx: PJSContext; var obj: PJSObject; const name: PCChar16; namelen: size_t; out vp: jsval): boolean; cdecl; var JS_GetUCProperty: TJS_GetUCProperty{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetUCProperty'; {$ENDIF} /// Find a specified numeric property of an object and return its current value. type TJS_GetElement = function (cx: PJSContext; var obj: PJSObject; index: uint32; out vp: jsval): Boolean; cdecl; var JS_GetElement: TJS_GetElement{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetElement'; {$ENDIF} /// Assign a value to a property of an object. // Name indentifies by ansi string type TJS_SetProperty = function (cx: PJSContext; var obj: PJSObject; const name: PCChar; var vp: jsval): Boolean; cdecl; var JS_SetProperty: TJS_SetProperty{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_SetProperty'; {$ENDIF} /// Assign a value to a property of an object. // Name indentifies by unicode string type TJS_SetUCProperty = function (cx: PJSContext; var obj: PJSObject; const name: PCChar16; namelen: size_t; var vp: jsval): boolean; cdecl; var JS_SetUCProperty: TJS_SetUCProperty{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_SetUCProperty'; {$ENDIF} /// Assign a value to a numeric property of an object. type TJS_SetElement = function (cx: PJSContext; var obj: PJSObject; index: uint32; var vp: jsval): Boolean; cdecl; var JS_SetElement: TJS_SetElement{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_SetElement'; {$ENDIF} /// Removes a specified property from an object. // Name indentifies by ID type TJS_DeletePropertyById = function (cx: PJSContext; var obj: PJSObject; var id: jsid; out res: JS_ObjectOpResult): Boolean; cdecl; var JS_DeletePropertyById: tJS_DeletePropertyById{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_DeletePropertyById'; {$ENDIF} /// Removes a specified element or numeric property from an object. type TJS_DeleteElement = function (cx: PJSContext; var obj: PJSObject; index: uint32; out res: JS_ObjectOpResult): Boolean; cdecl; var JS_DeleteElement: TJS_DeleteElement{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_DeleteElement'; {$ENDIF} /// Get an array of the non-symbol enumerable properties of obj. // This function is roughly equivalent to: // // var result = []; // for (key in obj) // result.push(key); // return result; // // This is the closest thing we currently have to the ES6 [[Enumerate]] // internal method. // // The JSIdArray returned is rooted to protect its // contents from garbage collection. function JS_EnumerateToAutoIdVector(cx: PJSContext; var obj: PJSObject; out length: size_t; out data: PjsidVector): PJSIdArray; cdecl; external SpiderMonkeyLib name 'SM_EnumerateToAutoIdVector'; procedure JS_DestroyAutoIdVector(v: PJSIdArray); cdecl; external SpiderMonkeyLib name 'SM_DestroyAutoIdVector'; type JSHandleValueArray = record length: size_t; elements_: PjsvalVector; end; /// Calls a specified JS function. // Function identifies by jsvalue // - equivalent of `rval = Reflect.apply(fun, obj, args)`. type TJS_CallFunctionValue = function (cx: PJSContext; var obj: PJSObject; var val: jsval; var args: JSHandleValueArray; out rval: jsval): Boolean; cdecl; var JS_CallFunctionValue: TJS_CallFunctionValue{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_CallFunctionValue'; {$ENDIF} /// Calls a specified JS function. // Function identifies by PJSFunction type TJS_CallFunction = function (cx: PJSContext; var obj: PJSObject; var fun: PJSFunction; var args: JSHandleValueArray; out rval: jsval): Boolean; cdecl; var JS_CallFunction: TJS_CallFunction{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_CallFunction'; {$ENDIF} /// Calls a specified JS function. // Function identifies by ansi string // - Perform the method call `rval = obj[name](args)`. type TJS_CallFunctionName = function (cx: PJSContext; var obj: PJSObject; const name: PCChar; var args: JSHandleValueArray; out rval: jsval): Boolean; cdecl; var JS_CallFunctionName: TJS_CallFunctionName{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_CallFunctionName'; {$ENDIF} /// Invoke a constructor, like the JS expression `new ctor(...args)`. Returns // the new object, or null on error. type TJS_New = function (cx: PJSContext; var ctor: PJSObject; var args: JSHandleValueArray): PJSObject; cdecl; var JS_New: TJS_New{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_New'; {$ENDIF} /// Define multiple properties for a single object. type TJS_DefineProperties = function (cx: PJSContext; var obj: PJSObject; ps: PJSPropertySpec): boolean; cdecl; var JS_DefineProperties: TJS_DefineProperties{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_DefineProperties'; {$ENDIF} /// Determine whether a property is already physically present on a JSObject. // Name indentifies by unicode string type TJS_AlreadyHasOwnUCProperty = function (cx: PJSContext; var obj: PJSObject; const name: PCChar16; namelen: size_t; var foundp: Boolean): Boolean; cdecl; var JS_AlreadyHasOwnUCProperty: TJS_AlreadyHasOwnUCProperty{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_AlreadyHasOwnUCProperty'; {$ENDIF} /// Create a new Array object. // Only length passed type TJS_NewArrayObject = function (cx: PJSContext; length: size_t): PJSObject; cdecl; var JS_NewArrayObject: TJS_NewArrayObject{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewArrayObject'; {$ENDIF} /// Create a new Array object. // Content passed type TJS_NewArrayObject2 = function (cx: PJSContext; const contents: JSHandleValueArray): PJSObject; cdecl; var JS_NewArrayObject2: TJS_NewArrayObject2{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewArrayObject2'; {$ENDIF} /// Returns true and sets |*isArray| indicating whether |obj| is an Array object // or a wrapper around one, otherwise returns false on failure. // - This method returns true with |*isArray == false| when passed a proxy whose // target is an Array, or when passed a revoked proxy. type TJS_IsArrayObject = function (cx: PJSContext; var obj: PJSObject; out isArray: Boolean): boolean; cdecl; var JS_IsArrayObject: TJS_IsArrayObject{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_IsArrayObject'; {$ENDIF} /// JS_GetArrayLength gets the .length property of obj as though by calling JS_GetProperty // and converts it to a 32-bit unsigned integer. If obj is an array (see JS_IsArrayObject), // this is guaranteed to succeed, because the .length property of an array is always a number // and can't be deleted or redefined. // - On success, JS_GetArrayLength stores the length in *lengthp and returns true. // On failure, it reports an error and returns false, and the value left in *lengthp // is undefined. type TJS_GetArrayLength = function (cx: PJSContext; var obj: PJSObject; out length: uint32): Boolean; cdecl; var JS_GetArrayLength: TJS_GetArrayLength{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetArrayLength'; {$ENDIF} /// Read access an object's reserved slots. function JS_GetReservedSlot(obj: PJSObject; index: uint32): Int64; cdecl; external SpiderMonkeyLib name 'SM_GetReservedSlot'; /// Write access an object's reserved slots type TJS_SetReservedSlot = procedure (obj: PJSObject; index: uint32; var v: jsval); cdecl; var JS_SetReservedSlot: TJS_SetReservedSlot{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_SetReservedSlot'; {$ENDIF} /// Create a new JavaScript function that is implemented as a JSNative. type TJS_NewFunction = function (cx: PJSContext; call: JSNative; nargs: uintN; flags: uintN; name: PCChar): PJSObject; cdecl; var JS_NewFunction: TJS_NewFunction{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewFunction'; {$ENDIF} /// Return the function's identifier as a JSString, or null if fun is unnamed. // The returned string lives as long as fun, so you don't need to root a saved // reference to it if fun is well-connected or rooted, and provided you bound // the use of the saved reference by fun's lifetime. type TJS_GetFunctionId = function (fun: PJSFunction): PJSString; cdecl; var JS_GetFunctionId: TJS_GetFunctionId{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetFunctionId'; {$ENDIF} /// Infallible predicate to test whether obj is a function object (faster than // comparing obj's class name to "Function", but equivalent unless someone has // overwritten the "Function" identifier with a different constructor and then // created instances using that constructor that might be passed in as obj). type TJS_ObjectIsFunction = function (cx: PJSContext; obj: PJSObject): boolean; cdecl; var JS_ObjectIsFunction: TJS_ObjectIsFunction{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_ObjectIsFunction'; {$ENDIF} /// Create zero or more functions and makes them properties (methods) // of a specified object, obj, as if by calling JS_DefineFunction repeatedly type TJS_DefineFunctions = function (cx: PJSContext; var obj: PJSObject; fs: PJSFunctionSpec; behavior: JSPropertyDefinitionBehavior): Boolean; cdecl; var JS_DefineFunctions: TJS_DefineFunctions{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_DefineFunctions'; {$ENDIF} /// Create a native function and assign it as a property to a specified JS object type TJS_DefineFunction = function (cx: PJSContext; var obj: PJSObject; name: PCChar; call: JSNative; nargs: uintN; attrs: uintN): PJSFunction; cdecl; var JS_DefineFunction: TJS_DefineFunction{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_DefineFunction'; {$ENDIF} /// Unicode version to create a native function type TJS_DefineUCFunction = function (cx: PJSContext; var obj: PJSObject; name: PCChar16; namelen: size_t; call: JSNative; nargs: uintN; attrs: uintN): PJSFunction; cdecl; var JS_DefineUCFunction: TJS_DefineUCFunction{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_DefineUCFunction'; {$ENDIF} /// Compile a script, source, for execution. // Ansi version type TJS_CompileScript = function (cx: PJSContext; bytes: PCChar; length: size_t; options: PJSCompileOptions; out script: PJSScript): boolean; cdecl; var JS_CompileScript: TJS_CompileScript{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_CompileScript'; {$ENDIF} /// Compile a script, source, for execution. // Unicode version type TJS_CompileUCScript = function (cx: PJSContext; chars: PCChar16; length: size_t; options: PJSCompileOptions; out script: PJSScript): boolean; cdecl; var JS_CompileUCScript: TJS_CompileUCScript{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_CompileUCScript'; {$ENDIF} /// Generate the complete source code of a function declaration from a compiled function type TJS_DecompileFunction = function (cx: PJSContext; var fun: PJSFunction; indent: uintN): PJSString; cdecl; var JS_DecompileFunction: TJS_DecompileFunction{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_DecompileFunction'; {$ENDIF} /// Evaluate a script in the scope of the current global of cx. type TJS_ExecuteScript = function (cx: PJSContext; var script: PJSScript; out rval: jsval): Boolean; cdecl; var JS_ExecuteScript: TJS_ExecuteScript{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_ExecuteScript'; {$ENDIF} /// These functions allow setting an interrupt callback that will be called // from the JS thread some time after any thread triggered the callback using // JS_RequestInterruptCallback(cx). // - To schedule the GC and for other activities the engine internally triggers // interrupt callbacks. The embedding should thus not rely on callbacks being //triggered through the external API only. // - Important note: Additional callbacks can occur inside the callback handler // if it re-enters the JS engine. The embedding must ensure that the callback // is disconnected before attempting such re-entry. type TJS_CheckForInterrupt = function (cx: PJSContext): Boolean; cdecl; var JS_CheckForInterrupt: TJS_CheckForInterrupt{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_CheckForInterrupt'; {$ENDIF} type TJS_AddInterruptCallback = function (cx: PJSContext; callback: JSInterruptCallback): Boolean; cdecl; var JS_AddInterruptCallback: TJS_AddInterruptCallback{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_AddInterruptCallback'; {$ENDIF} type TJS_DisableInterruptCallback = function (cx: PJSContext): Boolean; cdecl; var JS_DisableInterruptCallback: TJS_DisableInterruptCallback{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_DisableInterruptCallback'; {$ENDIF} type TJS_ResetInterruptCallback = procedure (cx: PJSContext; enable: Boolean); cdecl; var JS_ResetInterruptCallback: TJS_ResetInterruptCallback{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_ResetInterruptCallback'; {$ENDIF} /// Request a callback set using JS_SetInterruptCallback type TJS_RequestInterruptCallback = procedure (cx: PJSContext); cdecl; var JS_RequestInterruptCallback: TJS_RequestInterruptCallback{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_RequestInterruptCallback'; {$ENDIF} /// Indicates whether or not a script or function is currently executing in a given context. type TJS_IsRunning = function (cx: PJSContext): Boolean; cdecl; var JS_IsRunning: TJS_IsRunning{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_IsRunning'; {$ENDIF} /// Allocate space for a JavaScript string and its underlying storage, // and copy n characters from a character array, s, into the new JSString // Ansi version type TJS_NewStringCopyN = function (cx: PJSContext; s: PCChar; n: size_t): PJSString; cdecl; var JS_NewStringCopyN: TJS_NewStringCopyN{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewStringCopyN'; {$ENDIF} // TODO - recompile libsynsm with exported SM_AtomizeAndPinStringN //type TJS_AtomizeAndPinStringN = function (cx: PJSContext; s: PCChar; // n: size_t): PJSString; cdecl; //var JS_AtomizeAndPinStringN: TJS_AtomizeAndPinStringN external SpiderMonkeyLib name 'SM_AtomizeAndPinStringN'; /// Allocate space for a JavaScript string and its underlying storage, // and copy characters from NULL TERMINATED! UTF8 character array type TJS_NewStringCopyUTF8Z = function (cx: PJSContext; pNullTerminatedUTF8: PUTF8Char): PJSString; cdecl; var JS_NewStringCopyUTF8Z: TJS_NewStringCopyUTF8Z{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewStringCopyUTF8Z'; {$ENDIF} /// Returns the empty JSString as a JS value type TJS_GetEmptyStringValue = function (cx: PJSContext): jsval; cdecl; var JS_GetEmptyStringValue: TJS_GetEmptyStringValue{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetEmptyStringValue'; {$ENDIF} /// Allocate space for a JavaScript string and its underlying storage, // and copy n characters from a character array, s, into the new JSString // Unicode version type TJS_NewUCStringCopyN = function (cx: PJSContext; s: PCChar16; n: size_t): PJSString; cdecl; var JS_NewUCStringCopyN: TJS_NewUCStringCopyN{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewUCStringCopyN'; {$ENDIF} /// Return the length of a JavaScript string. type TJS_GetStringLength = function (str: PJSString): size_t; cdecl; var JS_GetStringLength: TJS_GetStringLength{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetStringLength'; {$ENDIF} /// Return true if the string's characters are stored as Latin1. type TJS_StringHasLatin1Chars = function (str: PJSString): boolean; cdecl; var JS_StringHasLatin1Chars: TJS_StringHasLatin1Chars{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_StringHasLatin1Chars'; {$ENDIF} /// Return a pointer to the string, and store the length to *length // Use it when characters are stored as Latin1. type TJS_GetLatin1StringCharsAndLength = function (cx: PJSContext; nogc: PJSAutoCheckCannotGC; str: PJSString; plength: psize_t):PCChar; cdecl; var JS_GetLatin1StringCharsAndLength: TJS_GetLatin1StringCharsAndLength{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetLatin1StringCharsAndLength'; {$ENDIF} /// Return a pointer to the string, and store the length to *length // Use it when characters are stored as Unicode type TJS_GetTwoByteStringCharsAndLength = function (cx: PJSContext; nogc: PJSAutoCheckCannotGC; str: PJSString; plength: psize_t): PCChar16; cdecl; var JS_GetTwoByteStringCharsAndLength: TJS_GetTwoByteStringCharsAndLength{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetTwoByteStringCharsAndLength'; {$ENDIF} /// converts a value to JSON, optionally replacing values if a replacer // function is specified, or optionally including only the specified properties // if a replacer array is specified type TJS_Stringify = function (cx: PJSContext; var vp: jsval; var replacer: PJSObject; var space: jsval; callback: JSONWriteCallback; data: pointer): Boolean; cdecl; var JS_Stringify: TJS_Stringify{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_Stringify'; {$ENDIF} /// parse a string using the JSON syntax described in ECMAScript 5 and // return the corresponding value into vp type TJS_ParseJSON = function (cx: PJSContext; const chars: PCChar16; len: uint32; out vp: jsval): Boolean; cdecl; var JS_ParseJSON: TJS_ParseJSON{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_ParseJSON'; {$ENDIF} /// Create a new JavaScript Error object and set it to be the pending exception on cx. // The callback must then return JS_FALSE to cause the exception to be propagated // to the calling script. // type TJS_ReportError = procedure (cx: PJSContext; const format: PCChar); cdecl; varargs; // var JS_ReportError: TJS_ReportError{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_ReportErrorASCII'; {$ENDIF} procedure JS_ReportError(cx: PJSContext; const format: PCChar); cdecl; varargs; external SpiderMonkeyLib name 'JS_ReportErrorASCII'; /// Report an error with an application-defined error code. // - varargs is Additional arguments for the error message. //- These arguments must be of type jschar* // - The number of additional arguments required depends on the error // message, which is determined by the errorCallback // type TJS_ReportErrorNumberUC = procedure (cx: PJSContext; errorCallback: JSErrorCallback; // userRef: pointer; const erroNubmer: uintN); cdecl; varargs; // var JS_ReportErrorNumberUC: TJS_ReportErrorNumberUC{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_ReportErrorNumberUC'; {$ENDIF} procedure JS_ReportErrorNumberUC(cx: PJSContext; errorCallback: JSErrorCallback; userRef: pointer; const erroNubmer: uintN); cdecl; varargs; external SpiderMonkeyLib name 'JS_ReportErrorNumberUC'; // type TJS_ReportErrorNumberUTF8 = procedure (cx: PJSContext; // errorCallback: JSErrorCallback; userRef: pointer; // const erroNubmer: uintN); cdecl; varargs; // var JS_ReportErrorNumberUTF8: TJS_ReportErrorNumberUTF8{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_ReportErrorNumberUTF8'; {$ENDIF} procedure JS_ReportErrorNumberUTF8(cx: PJSContext; errorCallback: JSErrorCallback; userRef: pointer; const erroNubmer: uintN); cdecl; varargs; external SpiderMonkeyLib name 'JS_ReportErrorNumberUTF8'; /// Reports a memory allocation error // - Call JS_ReportOutOfMemory to report that an operation failed because the // system is out of memory // - When the JavaScript engine tries to allocate memory and allocation fails, // it reports an error as though by calling this function type TJS_ReportOutOfMemory = procedure (cx: PJSContext); cdecl; var JS_ReportOutOfMemory: TJS_ReportOutOfMemory{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_ReportOutOfMemory'; {$ENDIF} /// Get the warning reporting mechanism for an application. It is not working for errors. type TJS_GetWarningReporter = function (cx: PJSContext): JSWarningReporter; cdecl; var JS_GetWarningReporter: TJS_GetWarningReporter{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetWarningReporter'; {$ENDIF} /// Specify the warning reporting mechanism for an application. It is not working for errors. type TJS_SetWarningReporter = function (cx: PJSContext; reporter: JSWarningReporter): JSWarningReporter; cdecl; var JS_SetWarningReporter: TJS_SetWarningReporter{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_SetWarningReporter'; {$ENDIF} /// Create a new JavaScript date object type TJS_NewDateObject = function (cx: PJSContext; year, mon, mday, hour, min, sec: int32): PJSObject; cdecl; var JS_NewDateObject: TJS_NewDateObject{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewDateObject'; {$ENDIF} /// Create a new JavaScript date object from the Unix millisecond elapsed since EPOC function JS_NewDateObjectMsec(cx: PJSContext; msec: double): PJSObject; cdecl; external SpiderMonkeyLib name 'SM_NewDateObjectMsec'; // Returns true and sets |*isDate| indicating whether |obj| is a Date object or // a wrapper around one, otherwise returns false on failure. // - This method returns true with |*isDate == false| when passed a proxy whose // target is a Date, or when passed a revoked proxy. type TJS_ObjectIsDate = function (cx: PJSContext; var obj: PJSObject; out isDate: boolean): boolean; cdecl; var JS_ObjectIsDate: TJS_ObjectIsDate{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_ObjectIsDate'; {$ENDIF} /// Determine whether an exception is pending in the JS engine. type TJS_IsExceptionPending = function (cx: PJSContext): Boolean; cdecl; var JS_IsExceptionPending: TJS_IsExceptionPending{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_IsExceptionPending'; {$ENDIF} /// Get the current pending exception for a given JSContext. type TJS_GetPendingException = function (cx: PJSContext; out vp: jsval): Boolean; cdecl; var JS_GetPendingException: TJS_GetPendingException{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetPendingException'; {$ENDIF} /// Sets the current exception being thrown within a context. type TJS_SetPendingException = procedure (cx: PJSContext; var vp: jsval); cdecl; var JS_SetPendingException: TJS_SetPendingException{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_SetPendingException'; {$ENDIF} /// Clear the currently pending exception in a context. type TJS_ClearPendingException = procedure (cx: PJSContext); cdecl; var JS_ClearPendingException: TJS_ClearPendingException{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_ClearPendingException'; {$ENDIF} /// If the given object is an exception object, the exception will have (or be // able to lazily create) an error report struct, and this function will return // the address of that struct. Otherwise, it returns nullptr. The lifetime // of the error report struct that might be returned is the same as the // lifetime of the exception object. type TJS_ErrorFromException = function (cx: PJSContext; var obj: PJSObject): PJSErrorReport; cdecl; var JS_ErrorFromException: TJS_ErrorFromException{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_ErrorFromException'; {$ENDIF} /// Get options of context function JS_GetContextOptions(cx: PJSContext): PJSContextOptions; cdecl; external SpiderMonkeyLib name 'SM_GetContextOptions'; //function JS_NewRootedValue(cx: PJSContext; val: jsval): PJSRootedValue; cdecl; external SpiderMonkeyLib; function JS_NewRootedValue(cx: PJSContext; val: Int64): PJSRootedValue; cdecl; external SpiderMonkeyLib name 'SM_NewRootedValue'; procedure JS_FreeRootedValue(val: PJSRootedValue); cdecl; external SpiderMonkeyLib name 'SM_FreeRootedValue'; function JS_NewRootedObject(cx: PJSContext; obj: PJSObject): PJSRootedObject; cdecl; external SpiderMonkeyLib name 'SM_NewRootedObject'; procedure JS_FreeRootedObject(obj: PJSRootedObject); cdecl; external SpiderMonkeyLib name 'SM_FreeRootedObject'; function JS_NewRootedString(cx: PJSContext; obj: PJSString): PJSRootedString; cdecl; external SpiderMonkeyLib name 'SM_NewRootedString'; procedure JS_FreeRootedString(str: PJSRootedString); cdecl; external SpiderMonkeyLib name 'SM_FreeRootedString'; /// Create Compile Options function JS_NewCompileOptions(cx: PJSContext): PJSCompileOptions; cdecl; external SpiderMonkeyLib name 'SM_NewCompileOptions'; /// expose to Pascal // JS::CompileOptions.setFileAndLine + setUTF8 procedure JS_SetCompileOptionsFileLineAndUtf8(co: PJSCompileOptions; const f: PChar; l: cardinal; isUtf8: boolean); cdecl; external SpiderMonkeyLib name 'SM_SetCompileOptionsFileLineAndUtf8'; /// Free Compile Options procedure JS_FreeCompileOptions(opt: PJSCompileOptions); cdecl; external SpiderMonkeyLib name 'SM_FreeCompileOptions'; /////////////////// type TJS_EvaluateScript = function (cx: PJSContext; options: PJSCompileOptions; bytes: PCChar; length: size_t; out rval: jsval): Boolean; cdecl; var JS_EvaluateScript: TJS_EvaluateScript{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_EvaluateScript'; {$ENDIF} type TJS_EvaluateUCScript = function (cx: PJSContext; options: PJSCompileOptions; chars: PCChar16; length: size_t; out rval: jsval): Boolean; cdecl; var JS_EvaluateUCScript: TJS_EvaluateUCScript{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_EvaluateUCScript'; {$ENDIF} /// Compute |this| for the |vp| inside a JSNative, either boxing primitives or // replacing with the global object as necessary. // - This method will go away at some point: instead use |args.thisv()|. If the // value is an object, no further work is required. If that value is |null| or // |undefined|, use |JS_GetGlobalForObject| to compute the global object. If // the value is some other primitive, use |JS_ValueToObject| to box it. // - low-level API used by JS_THIS() macro. //function JS_ComputeThis(cx: PJSContext; var vp: jsval): jsval; cdecl; external SpiderMonkeyLib; type TJS_ComputeThis = function (cx: PJSContext; var vp: jsval): Int64; cdecl; var JS_ComputeThis: TJS_ComputeThis{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_ComputeThis'; {$ENDIF} procedure strFinalizeOp(fin: PJSStringFinalizer; chars: PCChar16); cdecl; const strFinalizer: JSStringFinalizer = ( finalize: strFinalizeOp; ); { ArrayBuffer support from jsfriendapi.h} /// Create a new signed 8 bit integer typed array with nelements elements // - will fill the newly created array with zeros type TJS_NewInt8Array = function (cx: PJSContext; nelements: uint32): PJSObject; cdecl; var JS_NewInt8Array: TJS_NewInt8Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewInt8Array'; {$ENDIF} /// Create a new unsigned 8 bit integer (byte) typed array with nelements elements // - will fill the newly created array with zeros type TJS_NewUint8Array = function (cx: PJSContext; nelements: uint32): PJSObject; cdecl; var JS_NewUint8Array: TJS_NewUint8Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewUint8Array'; {$ENDIF} /// Create a new 8 bit integer typed array with nelements elements // - will fill the newly created array with zeros type TJS_NewUint8ClampedArray = function (cx: PJSContext; nelements: uint32): PJSObject; cdecl; var JS_NewUint8ClampedArray: TJS_NewUint8ClampedArray{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewUint8ClampedArray'; {$ENDIF} /// Create a new signed 16 bit integer typed array with nelements elements // - will fill the newly created array with zeros type TJS_NewInt16Array = function (cx: PJSContext; nelements: uint32): PJSObject; cdecl; var JS_NewInt16Array: TJS_NewInt16Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewInt16Array'; {$ENDIF} /// Create a new unsigned 16 bit integer typed array with nelements elements // - will fill the newly created array with zeros type TJS_NewUint16Array = function (cx: PJSContext; nelements: uint32): PJSObject; cdecl; var JS_NewUint16Array: TJS_NewUint16Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewUint16Array'; {$ENDIF} /// Create a new signed 32 bit integer typed array with nelements elements // - will fill the newly created array with zeros type TJS_NewInt32Array = function (cx: PJSContext; nelements: uint32): PJSObject; cdecl; var JS_NewInt32Array: TJS_NewInt32Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewInt32Array'; {$ENDIF} /// Create a new unsigned 32 bit integer typed array with nelements elements // - will fill the newly created array with zeros type TJS_NewUint32Array = function (cx: PJSContext; nelements: uint32): PJSObject; cdecl; var JS_NewUint32Array: TJS_NewUint32Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewUint32Array'; {$ENDIF} /// Create a new signed 32 bit float (single) typed array with nelements elements // - will fill the newly created array with zeros type TJS_NewFloat32Array = function (cx: PJSContext; nelements: uint32): PJSObject; cdecl; var JS_NewFloat32Array: TJS_NewFloat32Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewFloat32Array'; {$ENDIF} /// Create a new signed 64 bit float (double) typed array with nelements elements // - will fill the newly created array with zeros type TJS_NewFloat64Array = function (cx: PJSContext; nelements: uint32): PJSObject; cdecl; var JS_NewFloat64Array: TJS_NewFloat64Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewFloat64Array'; {$ENDIF} /// Create a new 8 bit signed integer typed array and copy in values // from a given object // - The object is used as if it was an array; that is, the new array (if // successfully created) will have length given by array.length, and its // elements will be those specified by array[0], array[1], and so on, after // conversion to the typed array element type. type TJS_NewInt8ArrayFromArray = function (cx: PJSContext; var arr: PJSObject): PJSObject; cdecl; var JS_NewInt8ArrayFromArray: TJS_NewInt8ArrayFromArray{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewInt8ArrayFromArray'; {$ENDIF} /// Create a new 8 bit unsigned integer typed array and copy in values // from a given object // - The object is used as if it was an array; that is, the new array (if // successfully created) will have length given by array.length, and its // elements will be those specified by array[0], array[1], and so on, after // conversion to the typed array element type. type TJS_NewUint8ArrayFromArray = function (cx: PJSContext; var arr: PJSObject): PJSObject; cdecl; var JS_NewUint8ArrayFromArray: TJS_NewUint8ArrayFromArray{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewUint8ArrayFromArray'; {$ENDIF} /// Create a new 8 bit unsigned integer typed array and copy in values // from a given object // - The object is used as if it was an array; that is, the new array (if // successfully created) will have length given by array.length, and its // elements will be those specified by array[0], array[1], and so on, after // conversion to the typed array element type. type TJS_NewUint8ClampedArrayFromArray = function (cx: PJSContext; var arr: PJSObject): PJSObject; cdecl; var JS_NewUint8ClampedArrayFromArray: TJS_NewUint8ClampedArrayFromArray{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewUint8ClampedArrayFromArray'; {$ENDIF} /// Create a new 16 bit signed integer typed array and copy in values // from a given object // - The object is used as if it was an array; that is, the new array (if // successfully created) will have length given by array.length, and its // elements will be those specified by array[0], array[1], and so on, after // conversion to the typed array element type. type TJS_NewInt16ArrayFromArray = function (cx: PJSContext; var arr: PJSObject): PJSObject; cdecl; var JS_NewInt16ArrayFromArray: TJS_NewInt16ArrayFromArray{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewInt16ArrayFromArray'; {$ENDIF} /// Create a new 16 bit unsigned integer typed array and copy in values // from a given object // - The object is used as if it was an array; that is, the new array (if // successfully created) will have length given by array.length, and its // elements will be those specified by array[0], array[1], and so on, after // conversion to the typed array element type. type TJS_NewUint16ArrayFromArray = function (cx: PJSContext; var arr: PJSObject): PJSObject; cdecl; var JS_NewUint16ArrayFromArray: TJS_NewUint16ArrayFromArray{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewUint16ArrayFromArray'; {$ENDIF} /// Create a new 32 bit signed integer typed array and copy in values // from a given object // - The object is used as if it was an array; that is, the new array (if // successfully created) will have length given by array.length, and its // elements will be those specified by array[0], array[1], and so on, after // conversion to the typed array element type. type TJS_NewInt32ArrayFromArray = function (cx: PJSContext; var arr: PJSObject): PJSObject; cdecl; var JS_NewInt32ArrayFromArray: TJS_NewInt32ArrayFromArray{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewInt32ArrayFromArray'; {$ENDIF} /// Create a new 32 bit unsigned integer typed array and copy in values // from a given object // - The object is used as if it was an array; that is, the new array (if // successfully created) will have length given by array.length, and its // elements will be those specified by array[0], array[1], and so on, after // conversion to the typed array element type. type TJS_NewUint32ArrayFromArray = function (cx: PJSContext; var arr: PJSObject): PJSObject; cdecl; var JS_NewUint32ArrayFromArray: TJS_NewUint32ArrayFromArray{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewUint32ArrayFromArray'; {$ENDIF} /// Create a new 32 bit float (single) typed array and copy in values // from a given object // - The object is used as if it was an array; that is, the new array (if // successfully created) will have length given by array.length, and its // elements will be those specified by array[0], array[1], and so on, after // conversion to the typed array element type. type TJS_NewFloat32ArrayFromArray = function (cx: PJSContext; var arr: PJSObject): PJSObject; cdecl; var JS_NewFloat32ArrayFromArray: TJS_NewFloat32ArrayFromArray{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewFloat32ArrayFromArray'; {$ENDIF} /// Create a new 64 bit float (double) typed array and copy in values // from a given object // - The object is used as if it was an array; that is, the new array (if // successfully created) will have length given by array.length, and its // elements will be those specified by array[0], array[1], and so on, after // conversion to the typed array element type. type TJS_NewFloat64ArrayFromArray = function (cx: PJSContext; var arr: PJSObject): PJSObject; cdecl; var JS_NewFloat64ArrayFromArray: TJS_NewFloat64ArrayFromArray{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewFloat64ArrayFromArray'; {$ENDIF} /// Create a new 8 bit signed integer typed array using the given // ArrayBuffer for storage // - The length value is optional; if -1 is passed, enough elements to use up the // remainder of the byte array is used as the default value type TJS_NewInt8ArrayWithBuffer = function (cx: PJSContext; var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject; cdecl; var JS_NewInt8ArrayWithBuffer: TJS_NewInt8ArrayWithBuffer{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewInt8ArrayWithBuffer'; {$ENDIF} /// Create a new 8 bit unsigned integer typed array using the given // ArrayBuffer for storage // - The length value is optional; if -1 is passed, enough elements to use up the // remainder of the byte array is used as the default value type TJS_NewUint8ArrayWithBuffer = function (cx: PJSContext; var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject; cdecl; var JS_NewUint8ArrayWithBuffer: TJS_NewUint8ArrayWithBuffer{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewUint8ArrayWithBuffer'; {$ENDIF} /// Create a new 8 bit unsigned integer typed array using the given // ArrayBuffer for storage // - The length value is optional; if -1 is passed, enough elements to use up the // remainder of the byte array is used as the default value type TJS_NewUint8ClampedArrayWithBuffer = function (cx: PJSContext; var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject; cdecl; var JS_NewUint8ClampedArrayWithBuffer: TJS_NewUint8ClampedArrayWithBuffer{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewUint8ClampedArrayWithBuffer'; {$ENDIF} /// Create a new 16 bit signed integer typed array using the given // ArrayBuffer for storage // - The length value is optional; if -1 is passed, enough elements to use up the // remainder of the byte array is used as the default value type TJS_NewInt16ArrayWithBuffer = function (cx: PJSContext; var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject; cdecl; var JS_NewInt16ArrayWithBuffer: TJS_NewInt16ArrayWithBuffer{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewInt16ArrayWithBuffer'; {$ENDIF} /// Create a new 16 bit unsigned integer typed array using the given // ArrayBuffer for storage // - The length value is optional; if -1 is passed, enough elements to use up the // remainder of the byte array is used as the default value type TJS_NewUint16ArrayWithBuffer = function (cx: PJSContext; var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject; cdecl; var JS_NewUint16ArrayWithBuffer: TJS_NewUint16ArrayWithBuffer{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewUint16ArrayWithBuffer'; {$ENDIF} /// Create a new 32 bit signed integer typed array using the given // ArrayBuffer for storage // - The length value is optional; if -1 is passed, enough elements to use up the // remainder of the byte array is used as the default value type TJS_NewInt32ArrayWithBuffer = function (cx: PJSContext; var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject; cdecl; var JS_NewInt32ArrayWithBuffer: TJS_NewInt32ArrayWithBuffer{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewInt32ArrayWithBuffer'; {$ENDIF} /// Create a new 32 bit unsigned integer typed array using the given // ArrayBuffer for storage // - The length value is optional; if -1 is passed, enough elements to use up the // remainder of the byte array is used as the default value type TJS_NewUint32ArrayWithBuffer = function (cx: PJSContext; var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject; cdecl; var JS_NewUint32ArrayWithBuffer: TJS_NewUint32ArrayWithBuffer{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewUint32ArrayWithBuffer'; {$ENDIF} /// Create a new 32 bit float (single) typed array using the given // ArrayBuffer for storage // - The length value is optional; if -1 is passed, enough elements to use up the // remainder of the byte array is used as the default value type TJS_NewFloat32ArrayWithBuffer = function (cx: PJSContext; var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject; cdecl; var JS_NewFloat32ArrayWithBuffer: TJS_NewFloat32ArrayWithBuffer{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewFloat32ArrayWithBuffer'; {$ENDIF} /// Create a new 64 bit float (double) typed array using the given // ArrayBuffer for storage // - The length value is optional; if -1 is passed, enough elements to use up the // remainder of the byte array is used as the default value type TJS_NewFloat64ArrayWithBuffer = function (cx: PJSContext; var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject; cdecl; var JS_NewFloat64ArrayWithBuffer: TJS_NewFloat64ArrayWithBuffer{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewFloat64ArrayWithBuffer'; {$ENDIF} /// Create a new SharedArrayBuffer with the given byte length. type TJS_NewSharedArrayBuffer = function (cx: PJSContext; nbytes: uint32): PJSObject; cdecl; var JS_NewSharedArrayBuffer: TJS_NewSharedArrayBuffer{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewSharedArrayBuffer'; {$ENDIF} /// Create a new ArrayBuffer with the given byte length. type TJS_NewArrayBuffer = function (cx: PJSContext; nbytes: uint32): PJSObject; cdecl; var JS_NewArrayBuffer: TJS_NewArrayBuffer{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_NewArrayBuffer'; {$ENDIF} /// Check whether obj supports JS_GetTypedArray* APIs // - Note that this may return false if a security wrapper is encountered that // denies the unwrapping. // - if this test or one of the JS_Is*Array tests succeeds, then it is safe to call // the dedicated accessor JSAPI calls type TJS_IsTypedArrayObject = function (obj: PJSObject): Boolean; cdecl; var JS_IsTypedArrayObject: TJS_IsTypedArrayObject{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_IsTypedArrayObject'; {$ENDIF} /// Check whether obj supports JS_GetArrayBufferView* APIs // - Note that this may return false if a security wrapper is encountered that // denies the unwrapping. // - if this test or one of the JS_Is*Array tests succeeds, then it is safe to call // the dedicated ArrayBufferView accessor JSAPI calls type TJS_IsArrayBufferViewObject = function (obj: PJSObject): Boolean; cdecl; var JS_IsArrayBufferViewObject: TJS_IsArrayBufferViewObject{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_IsArrayBufferViewObject'; {$ENDIF} /// Test for specific 8 bit signed integer typed array types (ArrayBufferView subtypes) type TJS_IsInt8Array = function (obj: PJSObject): Boolean; cdecl; var JS_IsInt8Array: TJS_IsInt8Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_IsInt8Array'; {$ENDIF} /// Test for specific 8 bit unsigned integer typed array types (ArrayBufferView subtypes) type TJS_IsUint8Array = function (obj: PJSObject): Boolean; cdecl; var JS_IsUint8Array: TJS_IsUint8Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_IsUint8Array'; {$ENDIF} /// Test for specific 8 bit unsigned integer typed array types (ArrayBufferView subtypes) type TJS_IsUint8ClampedArray = function (obj: PJSObject): Boolean; cdecl; var JS_IsUint8ClampedArray: TJS_IsUint8ClampedArray{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_IsUint8ClampedArray'; {$ENDIF} /// Test for specific 16 bit signed integer typed array types (ArrayBufferView subtypes) type TJS_IsInt16Array = function (obj: PJSObject): Boolean; cdecl; var JS_IsInt16Array: TJS_IsInt16Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_IsInt16Array'; {$ENDIF} /// Test for specific 16 bit unsigned integer typed array types (ArrayBufferView subtypes) type TJS_IsUint16Array = function (obj: PJSObject): Boolean; cdecl; var JS_IsUint16Array: TJS_IsUint16Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_IsUint16Array'; {$ENDIF} /// Test for specific 32 bit signed integer typed array types (ArrayBufferView subtypes) type TJS_IsInt32Array = function (obj: PJSObject): Boolean; cdecl; var JS_IsInt32Array: TJS_IsInt32Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_IsInt32Array'; {$ENDIF} /// Test for specific 32 bit unsigned integer typed array types (ArrayBufferView subtypes) type TJS_IsUint32Array = function (obj: PJSObject): Boolean; cdecl; var JS_IsUint32Array: TJS_IsUint32Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_IsUint32Array'; {$ENDIF} /// Test for specific 32 bit float (single) typed array types (ArrayBufferView subtypes) type TJS_IsFloat32Array = function (obj: PJSObject): Boolean; cdecl; var JS_IsFloat32Array: TJS_IsFloat32Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_IsFloat32Array'; {$ENDIF} /// Test for specific 64 bit float (double) typed array types (ArrayBufferView subtypes) type TJS_IsFloat64Array = function (obj: PJSObject): Boolean; cdecl; var JS_IsFloat64Array: TJS_IsFloat64Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_IsFloat64Array'; {$ENDIF} /// Return the isShared flag of a typed array, which denotes whether // the underlying buffer is a SharedArrayBuffer. // // |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow // be known that it would pass such a test: it is a typed array or a wrapper of // a typed array, and the unwrapping will succeed. type TJS_GetTypedArraySharedness = function (obj: PJSObject): Boolean; cdecl; var JS_GetTypedArraySharedness: TJS_GetTypedArraySharedness{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetTypedArraySharedness'; {$ENDIF} /// Unwrap 8 bit signed integer typed array into direct memory buffer // - Return nil without throwing any exception if the object cannot be viewed as the // correct typed array, or the typed array object on success, filling both out parameters type TJS_GetObjectAsInt8Array = function (obj: PJSObject; out length: uint32; out isSharedMemory:Boolean; out Data: Pint8Vector): PJSObject; cdecl; var JS_GetObjectAsInt8Array: TJS_GetObjectAsInt8Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetObjectAsInt8Array'; {$ENDIF} /// Unwrap 8 bit unsigned integer typed array into direct memory buffer // - Return nil without throwing any exception if the object cannot be viewed as the // correct typed array, or the typed array object on success, filling both out parameters type TJS_GetObjectAsUint8Array = function (obj: PJSObject; out length: uint32; out isSharedMemory:Boolean; out Data: Puint8Vector): PJSObject; cdecl; var JS_GetObjectAsUint8Array: TJS_GetObjectAsUint8Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetObjectAsUint8Array'; {$ENDIF} /// Unwrap 8 bit unsigned integer typed array into direct memory buffer // - Return nil without throwing any exception if the object cannot be viewed as the // correct typed array, or the typed array object on success, filling both out parameters type TJS_GetObjectAsUint8ClampedArray = function (obj: PJSObject; out length: uint32; out isSharedMemory:Boolean; out Data: Puint8Vector): PJSObject; cdecl; var JS_GetObjectAsUint8ClampedArray: TJS_GetObjectAsUint8ClampedArray{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetObjectAsUint8ClampedArray'; {$ENDIF} /// Unwrap 16 bit signed integer typed array into direct memory buffer // - Return nil without throwing any exception if the object cannot be viewed as the // correct typed array, or the typed array object on success, filling both out parameters type TJS_GetObjectAsInt16Array = function (obj: PJSObject; out length: uint32; out isSharedMemory:Boolean; out Data: Pint16Vector): PJSObject; cdecl; var JS_GetObjectAsInt16Array: TJS_GetObjectAsInt16Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetObjectAsInt16Array'; {$ENDIF} /// Unwrap 16 bit unsigned integer typed array into direct memory buffer // - Return nil without throwing any exception if the object cannot be viewed as the // correct typed array, or the typed array object on success, filling both out parameters type TJS_GetObjectAsUint16Array = function (obj: PJSObject; out length: uint32; out isSharedMemory:Boolean; out Data: Puint16Vector): PJSObject; cdecl; var JS_GetObjectAsUint16Array: TJS_GetObjectAsUint16Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetObjectAsUint16Array'; {$ENDIF} /// Unwrap 32 bit signed integer typed array into direct memory buffer // - Return nil without throwing any exception if the object cannot be viewed as the // correct typed array, or the typed array object on success, filling both out parameters type TJS_GetObjectAsInt32Array = function (obj: PJSObject; out length: uint32; out isSharedMemory:Boolean; out Data: Pint32Vector): PJSObject; cdecl; var JS_GetObjectAsInt32Array: TJS_GetObjectAsInt32Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetObjectAsInt32Array'; {$ENDIF} /// Unwrap 32 bit unsigned integer typed array into direct memory buffer // - Return nil without throwing any exception if the object cannot be viewed as the // correct typed array, or the typed array object on success, filling both out parameters type TJS_GetObjectAsUint32Array = function (obj: PJSObject; out length: uint32; out isSharedMemory:Boolean; out Data: Puint32Vector): PJSObject; cdecl; var JS_GetObjectAsUint32Array: TJS_GetObjectAsUint32Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetObjectAsUint32Array'; {$ENDIF} /// Unwrap 32 bit float (single) typed array into direct memory buffer // - Return nil without throwing any exception if the object cannot be viewed as the // correct typed array, or the typed array object on success, filling both out parameters type TJS_GetObjectAsFloat32Array = function (obj: PJSObject; out length: uint32; out isSharedMemory:Boolean; out Data: Pfloat32Vector): PJSObject; cdecl; var JS_GetObjectAsFloat32Array: TJS_GetObjectAsFloat32Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetObjectAsFloat32Array'; {$ENDIF} /// Unwrap 64 bit float (double) typed array into direct memory buffer // - Return nil without throwing any exception if the object cannot be viewed as the // correct typed array, or the typed array object on success, filling both out parameters type TJS_GetObjectAsFloat64Array = function (obj: PJSObject; out length: uint32; out isSharedMemory:Boolean; out Data: Pfloat64Vector): PJSObject; cdecl; var JS_GetObjectAsFloat64Array: TJS_GetObjectAsFloat64Array{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetObjectAsFloat64Array'; {$ENDIF} /// Unwrap an object as its raw binary memory buffer // - Return nil without throwing any exception if the object cannot be viewed as the // correct typed array, or the typed array object on success, filling both out parameters type TJS_GetObjectAsArrayBufferView = function (obj: PJSObject; out length: uint32; out isSharedMemory:Boolean; out Data: Puint8Vector): PJSObject; cdecl; var JS_GetObjectAsArrayBufferView: TJS_GetObjectAsArrayBufferView{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetObjectAsArrayBufferView'; {$ENDIF} /// Unwrap an object as its raw binary memory buffer // - Return nil without throwing any exception if the object cannot be viewed as the // correct typed array, or the typed array object on success, filling both out parameters type TJS_GetObjectAsArrayBuffer = function (obj: PJSObject; out length: uint32; out Data: Puint8Vector): PJSObject; cdecl; var JS_GetObjectAsArrayBuffer: TJS_GetObjectAsArrayBuffer{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetObjectAsArrayBuffer'; {$ENDIF} /// Get the type of elements in a typed array, or jsabTYPE_DATAVIEW if a DataView type TJS_GetArrayBufferViewType = function ( obj: PJSObject): JSArrayBufferViewType; cdecl; var JS_GetArrayBufferViewType: TJS_GetArrayBufferViewType{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetArrayBufferViewType'; {$ENDIF} /// Check whether obj supports the JS_GetArrayBuffer* APIs // - Note that this may return false if a security wrapper is encountered that denies the // unwrapping // - If this test succeeds, then it is safe to call the various accessor JSAPI calls type TJS_IsArrayBufferObject = function (obj: PJSObject): Boolean; cdecl; var JS_IsArrayBufferObject: TJS_IsArrayBufferObject{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_IsArrayBufferObject'; {$ENDIF} type TJS_IsSharedArrayBufferObject = function (obj: PJSObject): Boolean; cdecl; var JS_IsSharedArrayBufferObject: TJS_IsSharedArrayBufferObject{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_IsSharedArrayBufferObject'; {$ENDIF} /// Return the available byte length of an array buffer // - obj must have passed a JS_IsArrayBufferObject test, or somehow be known // that it would pass such a test: it is an ArrayBuffer or a wrapper of an // ArrayBuffer, and the unwrapping will succeed type TJS_GetArrayBufferByteLength = function (obj: PJSObject): uint32; cdecl; var JS_GetArrayBufferByteLength: TJS_GetArrayBufferByteLength{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetArrayBufferByteLength'; {$ENDIF} type TJS_GetSharedArrayBufferByteLength = function ( obj: PJSObject): uint32; cdecl; var JS_GetSharedArrayBufferByteLength: TJS_GetSharedArrayBufferByteLength{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetSharedArrayBufferByteLength'; {$ENDIF} /// Return true if the arrayBuffer contains any data. This will return false for // ArrayBuffer.prototype and neutered ArrayBuffers. // // |obj| must have passed a JS_IsArrayBufferObject test, or somehow be known // that it would pass such a test: it is an ArrayBuffer or a wrapper of an // ArrayBuffer, and the unwrapping will succeed. type TJS_ArrayBufferHasData = function (obj: PJSObject): Boolean; cdecl; var JS_ArrayBufferHasData: TJS_ArrayBufferHasData{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_ArrayBufferHasData'; {$ENDIF} /// Return a pointer to an array buffer's data // - The buffer is still owned by the array buffer object, and should not // be modified on another thread. The returned pointer is stable across GCs // - obj must have passed a JS_IsArrayBufferObject test, or somehow be known // that it would pass such a test: it is an ArrayBuffer or a wrapper of an // ArrayBuffer, and the unwrapping will succeed. type TJS_GetArrayBufferData = function (obj: PJSObject; out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC{Not used in SM code}): Puint8Vector; cdecl; var JS_GetArrayBufferData: TJS_GetArrayBufferData{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetArrayBufferData'; {$ENDIF} /// Check whether the obj is ArrayBufferObject and memory mapped. Note that this // may return false if a security wrapper is encountered that denies the // unwrapping. type TJS_IsMappedArrayBufferObject = function (obj: PJSObject): Boolean; cdecl; var JS_IsMappedArrayBufferObject: TJS_IsMappedArrayBufferObject{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_IsMappedArrayBufferObject'; {$ENDIF} /// Return the number of elements in a typed array // - obj must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow // be known that it would pass such a test: it is a typed array or a wrapper of // a typed array, and the unwrapping will succeed. type TJS_GetTypedArrayLength = function (obj: PJSObject): uint32; cdecl; var JS_GetTypedArrayLength: TJS_GetTypedArrayLength{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetTypedArrayLength'; {$ENDIF} /// Return the byte offset from the start of an array buffer to the start of a // typed array view // - obj must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow // be known that it would pass such a test: it is a typed array or a wrapper of // a typed array, and the unwrapping will succeed. type TJS_GetTypedArrayByteOffset = function (obj: PJSObject): uint32; cdecl; var JS_GetTypedArrayByteOffset: TJS_GetTypedArrayByteOffset{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetTypedArrayByteOffset'; {$ENDIF} /// Return the byte length of a typed array // - obj must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow // be known that it would pass such a test: it is a typed array or a wrapper of // a typed array, and the unwrapping will succeed type TJS_GetTypedArrayByteLength = function (obj: PJSObject): uint32; cdecl; var JS_GetTypedArrayByteLength: TJS_GetTypedArrayByteLength{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetTypedArrayByteLength'; {$ENDIF} /// More generic name for JS_GetTypedArrayByteLength to cover DataViews as well type TJS_GetArrayBufferViewByteLength = function (obj: PJSObject): uint32; cdecl; var JS_GetArrayBufferViewByteLength: TJS_GetArrayBufferViewByteLength{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetArrayBufferViewByteLength'; {$ENDIF} /// Return a pointer to the start of the data referenced by a typed 8 bit signed integer array // - The data is still owned by the typed array, and should not be modified on // another thread // - obj must have passed a JS_Is*Array test, or somehow be known that it would // pass such a test: it is a typed array or a wrapper of a typed array, and the // unwrapping will succeed type TJS_GetInt8ArrayData = function (obj: PJSObject; out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Pint8Vector; cdecl; var JS_GetInt8ArrayData: TJS_GetInt8ArrayData{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetInt8ArrayData'; {$ENDIF} /// Return a pointer to the start of the data referenced by a typed 8 bit unsigned integer array // - The data is still owned by the typed array, and should not be modified on // another thread // - obj must have passed a JS_Is*Array test, or somehow be known that it would // pass such a test: it is a typed array or a wrapper of a typed array, and the // unwrapping will succeed type TJS_GetUint8ArrayData = function (obj: PJSObject; out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Puint8Vector; cdecl; var JS_GetUint8ArrayData: TJS_GetUint8ArrayData{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetUint8ArrayData'; {$ENDIF} /// Return a pointer to the start of the data referenced by a typed 8 bit unsigned integer array // - The data is still owned by the typed array, and should not be modified on // another thread // - obj must have passed a JS_Is*Array test, or somehow be known that it would // pass such a test: it is a typed array or a wrapper of a typed array, and the // unwrapping will succeed type TJS_GetUint8ClampedArrayData = function (obj: PJSObject; out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Puint8Vector; cdecl; var JS_GetUint8ClampedArrayData: TJS_GetUint8ClampedArrayData{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetUint8ClampedArrayData'; {$ENDIF} /// Return a pointer to the start of the data referenced by a typed 16 bit signed integer array // - The data is still owned by the typed array, and should not be modified on // another thread // - obj must have passed a JS_Is*Array test, or somehow be known that it would // pass such a test: it is a typed array or a wrapper of a typed array, and the // unwrapping will succeed type TJS_GetInt16ArrayData = function (obj: PJSObject; out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Pint16Vector; cdecl; var JS_GetInt16ArrayData: TJS_GetInt16ArrayData{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetInt16ArrayData'; {$ENDIF} /// Return a pointer to the start of the data referenced by a typed 16 bit unsigned integer array // - The data is still owned by the typed array, and should not be modified on // another thread // - obj must have passed a JS_Is*Array test, or somehow be known that it would // pass such a test: it is a typed array or a wrapper of a typed array, and the // unwrapping will succeed type TJS_GetUint16ArrayData = function (obj: PJSObject; out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Puint16Vector; cdecl; var JS_GetUint16ArrayData: TJS_GetUint16ArrayData{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetUint16ArrayData'; {$ENDIF} /// Return a pointer to the start of the data referenced by a typed 32 bit signed integer array // - The data is still owned by the typed array, and should not be modified on // another thread // - obj must have passed a JS_Is*Array test, or somehow be known that it would // pass such a test: it is a typed array or a wrapper of a typed array, and the // unwrapping will succeed type TJS_GetInt32ArrayData = function (obj: PJSObject; out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Pint32Vector; cdecl; var JS_GetInt32ArrayData: TJS_GetInt32ArrayData{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetInt32ArrayData'; {$ENDIF} /// Return a pointer to the start of the data referenced by a typed 32 bit unsigned integer array // - The data is still owned by the typed array, and should not be modified on // another thread // - obj must have passed a JS_Is*Array test, or somehow be known that it would // pass such a test: it is a typed array or a wrapper of a typed array, and the // unwrapping will succeed type TJS_GetUint32ArrayData = function (obj: PJSObject; out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Puint32Vector; cdecl; var JS_GetUint32ArrayData: TJS_GetUint32ArrayData{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetUint32ArrayData'; {$ENDIF} /// Return a pointer to the start of the data referenced by a typed 32 bit float (single) array // - The data is still owned by the typed array, and should not be modified on // another thread // - obj must have passed a JS_Is*Array test, or somehow be known that it would // pass such a test: it is a typed array or a wrapper of a typed array, and the // unwrapping will succeed type TJS_GetFloat32ArrayData = function (obj: PJSObject; out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Pfloat32Vector; cdecl; var JS_GetFloat32ArrayData: TJS_GetFloat32ArrayData{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetFloat32ArrayData'; {$ENDIF} /// Return a pointer to the start of the data referenced by a typed 64 bit float (double) array // - The data is still owned by the typed array, and should not be modified on // another thread // - obj must have passed a JS_Is*Array test, or somehow be known that it would // pass such a test: it is a typed array or a wrapper of a typed array, and the // unwrapping will succeed type TJS_GetFloat64ArrayData = function (obj: PJSObject; out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Pfloat64Vector; cdecl; var JS_GetFloat64ArrayData: TJS_GetFloat64ArrayData{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetFloat64ArrayData'; {$ENDIF} /// Return a pointer to the start of the data referenced by any typed array // - The data is still owned by the typed array, and should not be modified on // another thread // - obj must have passed a JS_Is*Array test, or somehow be known that it would // pass such a test: it is a typed array or a wrapper of a typed array, and the // unwrapping will succeed // - Prefer the type-specific versions when possible type TJS_GetArrayBufferViewData = function (obj: PJSObject; out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Pointer; cdecl; var JS_GetArrayBufferViewData: TJS_GetArrayBufferViewData{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetArrayBufferViewData'; {$ENDIF} /// Return the ArrayBuffer underlying an ArrayBufferView // - If the buffer has been neutered, this will still return the neutered buffer. // - obj must be an object that would return true for JS_IsArrayBufferViewObject() type TJS_GetArrayBufferViewBuffer = function (cx: PJSContext; var obj: PJSObject; out isSharedMemory: Boolean): PJSObject; cdecl; var JS_GetArrayBufferViewBuffer: TJS_GetArrayBufferViewBuffer{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_GetArrayBufferViewBuffer'; {$ENDIF} ////modules /// Initialize modeles classes next 2 functions cannot work without calling this function !!! EMPTY !!! function JS_InitModuleClasses(cx: PJSContext; var obj: PJSObject): boolean; cdecl; external SpiderMonkeyLib name 'SM_InitModuleClasses'; /// Compile script as module function JS_CompileModule(cx: PJSContext; var obj: PJSObject; options: PJSCompileOptions; chars: PCChar16; length: size_t): PJSObject; cdecl; external SpiderMonkeyLib name 'SM_CompileModule'; /// Set handler for module resolving type TJS_SetModuleResolveHook = procedure (cx: PJSContext; var hook: PJSFunction); cdecl; var JS_SetModuleResolveHook: TJS_SetModuleResolveHook{$IFNDEF FPC}; {$ELSE} external SpiderMonkeyLib name 'SM_SetModuleResolveHook'; {$ENDIF} type pjsval = ^jsval; var /// global TSynAnsiConvert instance to handle LATIN1(ISO/IEC 8859-1) encoding // - this instance is global and instantied during the whole program life time // - Spidermonkey internal encoding is LATIN1 or UTF-16 Latin1AnsiConvert: TSynAnsiConvert; implementation uses Variants; const JSVAL_INT_MAX = int32($7fffffff); procedure JSError(cx: PJSContext; aException: Exception); var ws: WideString; begin if not JS_IsExceptionPending(cx) then // raise only if this is the first exception in chain if aException is EOutOfMemory then JS_ReportOutOfMemory(cx) else if aException is ESMRangeException then begin ws := StringToSynUnicode(aException.Message); JSRangeErrorUC(cx, ws); end else if aException is ESMTypeException then begin ws := StringToSynUnicode(aException.Message); JSTypeErrorUC(cx, ws); end else begin ws := StringToSynUnicode(aException.Message); JSErrorUC(cx, ws, aException.HelpContext); end; end; const ErrorUCFormatString: JSErrorFormatString = ( name: 'Error'; format: '{0}'; argCount: 1; exnType: JSEXN_ERR; ); RangeErrorUCFormatString: JSErrorFormatString = ( name: 'RangeError'; format: '{0}'; argCount: 1; exnType: JSEXN_RANGEERR; ); TypeErrorUCFormatString: JSErrorFormatString = ( name: 'TypeError'; format: '{0}'; argCount: 1; exnType: JSEXN_TYPEERR; ); SMExceptionNumber = 500;//from 0 to JSErr_Limit(421 for SM 45 ) Error numbers are reserved function ReportErrorUC(userRef: Pointer; const errorNumber: uintN): PJSErrorFormatString; cdecl; begin result := @ErrorUCFormatString; end; function ReportRangeErrorUC(userRef: Pointer; const errorNumber: uintN): PJSErrorFormatString; cdecl; begin result := @RangeErrorUCFormatString; end; function TypeRangeErrorUC(userRef: Pointer; const errorNumber: uintN): PJSErrorFormatString; cdecl; begin result := @TypeErrorUCFormatString; end; procedure JSErrorUC(cx: PJSContext; aMessage: WideString; errorCode: integer); begin if not JS_IsExceptionPending(cx) then JS_ReportErrorNumberUC(cx, ReportErrorUC, nil, SMExceptionNumber + errorCode, Pointer(aMessage)); end; procedure JSRangeErrorUC(cx: PJSContext; aMessage: WideString); begin if not JS_IsExceptionPending(cx) then JS_ReportErrorNumberUC(cx, ReportRangeErrorUC, nil, SMExceptionNumber ,Pointer(aMessage)); end; procedure JSTypeErrorUC(cx: PJSContext; aMessage: WideString); begin if not JS_IsExceptionPending(cx) then JS_ReportErrorNumberUC(cx, TypeRangeErrorUC, nil, SMExceptionNumber ,Pointer(aMessage)); end; function InitJS: Boolean; begin // remove extra threads + allow GS to finalize native objects; // See for details the same issue in modgoDB: // https://jira.mongodb.org/browse/SERVER-21728 JS_DisableExtraThreads(); Result := JS_Init; end; procedure ShutDownJS; begin JS_ShutDown; end; { JSCompileOptions } procedure JSCompileOptions.SetFileLineAndUtf8(const fn: RawUTF8; l: cardinal; isUtf8: boolean); begin JS_SetCompileOptionsFileLineAndUtf8(@Self, pointer(fn), l, isUtf8); end; { JSString } procedure JSString.ToJSONString(cx: PJSContext; W: TTextWriter); var str8: PCChar; str16: PCChar16; strL: size_t; begin W.Add('"'); if JS_StringHasLatin1Chars(@self) then begin str8 := JS_GetLatin1StringCharsAndLength(cx, @nullPtr, @self, @strL); W.AddJSONEscape(pointer(str8),strL); end else begin str16 := JS_GetTwoByteStringCharsAndLength(cx, @nullPtr, @self, @strL); W.AddJSONEscapeW(pointer(str16),strL); end; W.Add('"'); end; function JSString.ToJSVal: jsval; begin Result.asJSString := @self end; function JSString.ToString(cx: PJSContext): string; var str8: PCChar; str16: PCChar16; strL: size_t; begin if JS_StringHasLatin1Chars(@self) then begin str8 := JS_GetLatin1StringCharsAndLength(cx, @nullPtr, @self, @strL); {$ifdef UNICODE} Result := Latin1AnsiConvert.AnsiToUnicodeString(str8, strL); {$else} SetString(Result, str8, strL); {$endif} end else begin str16 := JS_GetTwoByteStringCharsAndLength(cx, @nullPtr, @self, @strL); RawUnicodeToString(PWideChar(str16),strL,result) end; end; function JSString.ToSynUnicode(cx: PJSContext): SynUnicode; var str8: PCChar; str16: PCChar16; strL: size_t; begin if JS_StringHasLatin1Chars(@self) then begin str8 := JS_GetLatin1StringCharsAndLength(cx, @nullPtr, @self, @strL); Result := Latin1AnsiConvert.AnsiToUnicodeString(str8, strL); end else begin str16 := JS_GetTwoByteStringCharsAndLength(cx, @nullPtr, @self, @strL); SetString(Result, str16, strL); end; end; function JSString.ToUTF8(cx: PJSContext): RawUTF8; begin ToUTF8(cx,result); end; procedure JSString.ToUTF8(cx: PJSContext; out result: RawUTF8); var str8: PCChar; str16: PCChar16; strL: size_t; begin if JS_StringHasLatin1Chars(@self) then begin str8 := JS_GetLatin1StringCharsAndLength(cx, @nullPtr, @self, @strL); result := Latin1AnsiConvert.AnsiBufferToRawUTF8(str8, strL); end else begin str16 := JS_GetTwoByteStringCharsAndLength(cx, @nullPtr, @self, @strL); RawUnicodeToUTF8(str16,strL,result, [ccfNoTrailingZero, ccfReplacementCharacterForUnmatchedSurrogate]); end; end; function JSString.ToAnsi(cx: PJSContext): AnsiString; var str8: PCChar; str16: PCChar16; strL: size_t; begin if JS_StringHasLatin1Chars(@self) then begin str8 := JS_GetLatin1StringCharsAndLength(cx, @nullPtr, @self, @strL); SetLength(Result, strL); MoveFast(Pointer(str8)^,Result[1],strL); end else begin str16 := JS_GetTwoByteStringCharsAndLength(cx, @nullPtr, @self, @strL); Result := CurrentAnsiConvert.UnicodeBufferToAnsi(str16,strL); end; end; procedure JSString.ToVariant(cx: PJSContext; var Value: Variant); var str8: PCChar; str16: PCChar16; strL: size_t; begin VarClear(Value); with TVarData(Value) do begin VType := varSynUnicode; VAny := nil; // avoid GPF below if JS_StringHasLatin1Chars(@self) then begin str8 := JS_GetLatin1StringCharsAndLength(cx, @nullPtr, @self, @strL); SynUnicode(VAny) := Latin1AnsiConvert.AnsiToUnicodeString(str8, strL); end else begin str16 := JS_GetTwoByteStringCharsAndLength(cx, @nullPtr, @self, @strL); SetString(SynUnicode(VAny), str16, strL); end; end; end; procedure JSString.ToUTF8(cx: PJSContext; W: TTextWriter); var str8: PCChar; str16: PCChar16; strL: size_t; tmpU8: array[0..256*3] of AnsiChar; U8: PUTF8Char; begin if JS_StringHasLatin1Chars(@self) then begin str8 := JS_GetLatin1StringCharsAndLength(cx, @nullPtr, @self, @strL); if strL>=SizeOf(tmpU8)div 3 then Getmem(U8,strL*3+1) else U8 := @tmpU8; strL := Latin1AnsiConvert.AnsiBufferToUTF8(U8,pointer(str8),strL)-U8; W.AddNoJSONEscape(pointer(U8), strL); if U8<>@tmpU8 then FreeMem(U8); end else begin str16 := JS_GetTwoByteStringCharsAndLength(cx, @nullPtr, @self, @strL); W.AddNoJSONEscapeW(pointer(str16),strL); end; end; function JSString.HasLatin1Chars: Boolean; begin result := JS_StringHasLatin1Chars(@self); end; function JSString.GetLatin1StringCharsAndLength(cx: PJSContext; out len: size_t): PCChar; begin Result := JS_GetLatin1StringCharsAndLength(cx, @nullPtr, @Self, @len); end; function JSString.Length: size_t; begin Result := JS_GetStringLength(@self); end; function JSString.GetTwoByteStringCharsAndLength(cx: PJSContext; out len: size_t): PCChar16; begin Result := JS_GetTwoByteStringCharsAndLength(cx, @nullPtr, @Self, @len); end; { JSContext } function JSContext.CheckForInterrupt: Boolean; begin result := JS_CheckForInterrupt(@Self); end; procedure JSContext.DisableInterruptCallback; begin JS_DisableInterruptCallback(@self); end; procedure JSContext.AddInterruptCallback(callback: JSInterruptCallback); begin JS_AddInterruptCallback(@self, callback); end; procedure JSContext.ResetInterruptCallback(disable: boolean); begin JS_ResetInterruptCallback(@self, disable); end; procedure JSContext.ClearPendingException; begin JS_ClearPendingException(@self); end; function JSContext.CurrentGlobalOrNull: PJSObject; begin result := JS_CurrentGlobalOrNull(@self); end; procedure JSContext.Destroy; begin JS_DestroyContext(@self); end; function JSContext.EnterCompartment(target: PJSObject): PJSCompartment; begin Result := JS_EnterCompartment(@self, target); end; function JSContext.GetPendingException(out rv: jsval): boolean; begin Result := JS_GetPendingException(@self, rv); end; function JSContext.GetPrivate: Pointer; begin result := JS_GetContextPrivate(@self); end; function JSContext.IdToValue(id: jsid; out v: jsval): Boolean; begin Result := JS_IdToValue(@Self, id, v); end; function JSContext.InitStandardClasses(var obj: PJSObject): boolean; begin Result := JS_InitStandardClasses(@Self, obj); end; procedure JSContext.SetModuleResolveHook(var hook: PJSFunction); begin JS_SetModuleResolveHook(@Self, hook); end; function JSContext.NewDateObjectMsec(msec: double): PJSObject; begin Result := JS_NewDateObjectMsec(@Self, msec); end; procedure JSContext.LeaveCompartment(oldCompartment: PJSCompartment); begin JS_LeaveCompartment(@Self, oldCompartment); end; procedure JSContext.MaybeGC; begin JS_MaybeGC(@self); end; function JSContext.NewDateObject(year, mon, mday, hour, min, sec: int32): PJSObject; begin Result := JS_NewDateObject(@Self, year, mon, mday, hour, min, sec); end; function JS_NewCompartmentOptions(): PJS_CompartmentOptions; cdecl; external SpiderMonkeyLib name 'SM_NewCompartmentOptions'; procedure JS_FreeCompartmentOptions(opt: PJS_CompartmentOptions); cdecl; external SpiderMonkeyLib name 'SM_FreeCompartmentOptions'; function JSContext.NewGlobalObject(clasp: PJSClass; hookOption: OnNewGlobalHookOption): PJSObject; var Opt: PJS_CompartmentOptions; begin Opt := JS_NewCompartmentOptions; Result := JS_NewGlobalObject(@Self, clasp, nil, hookOption, Opt); JS_FreeCompartmentOptions(Opt); end; function JSContext.NewInt16Array(nelements: uint32): PJSObject; begin Result := JS_NewInt16Array(@Self, nelements); end; function JSContext.NewInt16ArrayFromArray(var arr: PJSObject): PJSObject; begin Result := JS_NewInt16ArrayFromArray(@Self, arr); end; function JSContext.NewInt16ArrayWithBuffer(var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject; begin Result := JS_NewInt16ArrayWithBuffer(@Self, arrayBuffer, byteOffset, length); end; function JSContext.NewInt32Array(nelements: uint32): PJSObject; begin Result := JS_NewInt32Array(@Self, nelements); end; function JSContext.NewInt32ArrayFromArray(var arr: PJSObject): PJSObject; begin Result := JS_NewInt32ArrayFromArray(@Self, arr); end; function JSContext.NewInt32ArrayWithBuffer(var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject; begin Result := JS_NewInt32ArrayWithBuffer(@Self, arrayBuffer, byteOffset, length); end; function JSContext.NewInt8Array(nelements: uint32): PJSObject; begin Result := JS_NewInt8Array(@Self, nelements); end; function JSContext.NewInt8ArrayFromArray(var arr: PJSObject): PJSObject; begin Result := JS_NewInt8ArrayFromArray(@Self, arr); end; function JSContext.NewInt8ArrayWithBuffer(var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject; begin Result := JS_NewInt8ArrayWithBuffer(@Self, arrayBuffer, byteOffset, length); end; function JSContext.NewJSString(TextWide: PWideChar; TextLen: integer): PJSString; begin result := JS_NewUCStringCopyN(@Self, pointer(TextWide), TextLen); end; function JSContext.NewJSString(TextAnsi: PAnsiChar; TextLen, CodePage: integer): PJSString; var short: array[byte] of CChar16; // to avoid temp allocation on heap buf: PCChar16; begin if TextLen<(sizeof(short) div 3) then buf := @short else GetMem(buf,TextLen*3+2); result := JS_NewUCStringCopyN(@Self, buf, TSynAnsiConvert.Engine(CodePage).AnsiBufferToUnicode(PWideChar(buf),TextAnsi,TextLen)-buf); if buf<>@short then FreeMem(buf); end; function JSContext.NewJSString(const Value: SynUnicode): PJSString; begin result := JS_NewUCStringCopyN(@Self, pointer(Value), Length(Value)); end; function JSContext.NewObject(clasp: PJSClass): PJSObject; begin Result := JS_NewObject(@Self, clasp); end; function JSContext.NewObjectWithGivenProto(clasp: PJSClass; var proto: PJSObject): PJSObject; begin Result := JS_NewObjectWithGivenProto(@Self, clasp, proto); end; procedure JSContext.ReportError(format: PCChar); begin JS_ReportError(@Self, format); end; procedure JSContext.ReportErrorNumberUC(errorCallback: JSErrorCallback; userRef: pointer; const erroNubmer: uintN); begin JS_ReportErrorNumberUC(@Self, errorCallback, userRef, erroNubmer); end; procedure JSContext.ReportOutOfMemory; begin JS_ReportOutOfMemory(@self); end; procedure JSContext.SetPrivate(const Value: Pointer); begin JS_SetContextPrivate(@self,Value); end; function JSContext.TypeOfValue(v: jsval): JSType; begin result := JS_TypeOfValue(@Self, v); end; function JSContext.ValueToId(var v: jsval; out id: jsid): Boolean; begin Result := JS_ValueToId(@Self, v, id); end; function JSContext.WrapObject(var obj: PJSObject): boolean; begin Result := JS_WrapObject(@Self, obj); end; procedure JSContext.BeginRequest; begin JS_BeginRequest(@self); end; procedure JSContext.EndRequest; begin JS_EndRequest(@self); end; function JSContext.GetArrayBufferViewBuffer(var obj: PJSObject; out isSharedMemory: Boolean): PJSObject; begin Result := JS_GetArrayBufferViewBuffer(@self, obj, isSharedMemory); end; function JSContext.GetArrayBufferViewBuffer(var obj: PJSObject): PJSObject; var isSharedMemory: Boolean; begin Result := JS_GetArrayBufferViewBuffer(@self, obj, isSharedMemory); end; function JSContext.GetIsRunning: boolean; begin result := JS_IsRunning(@self); end; procedure JSContext.FreeCompileOptions(opt: PJSCompileOptions); begin JS_FreeCompileOptions(opt); end; procedure JSContext.FreeRootedObject(obj: PJSRootedObject); var curr: PJSRootedObject; begin curr := obj.stack.Last; while curr.ptr = nil do curr := curr.prev; if curr <> obj then raise ESMException.Create('FreeRootedObject Stack error'); JS_FreeRootedObject(obj); end; procedure JSContext.FreeRootedString(str: PJSRootedString); begin if ppointer(str.stack)^ <> str then raise ESMException.Create('FreeRootedString Stack error'); JS_FreeRootedString(str); end; procedure JSContext.FreeRootedValue(str: PJSRootedValue); begin if ppointer(str.stack)^ <> str then raise ESMException.Create('FreeRootedValue Stack error'); JS_FreeRootedValue(str); end; function JSContext.NewRootedObject(obj: PJSObject): PJSRootedObject; begin Result := JS_NewRootedObject(@Self, obj); end; function JSContext.NewRootedString(obj: PJSString): PJSRootedString; begin Result := JS_NewRootedString(@Self, obj) end; function JSContext.NewRootedValue(val: jsval): PJSRootedValue; begin Result := JS_NewRootedValue(@Self, val._l.asBits) end; function JSContext.NewSharedArrayBuffer(nbytes: uint32): PJSObject; begin Result := JS_NewSharedArrayBuffer(@Self, nbytes); end; function JSContext.NewUint16Array(nelements: uint32): PJSObject; begin Result := JS_NewUint16Array(@Self, nelements); end; function JSContext.NewUint16ArrayFromArray(var arr: PJSObject): PJSObject; begin Result := JS_NewUInt16ArrayFromArray(@Self, arr); end; function JSContext.NewUint16ArrayWithBuffer(var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject; begin Result := JS_NewUInt16ArrayWithBuffer(@Self, arrayBuffer, byteOffset, length); end; function JSContext.NewUint32Array(nelements: uint32): PJSObject; begin Result := JS_NewUInt32Array(@Self, nelements); end; function JSContext.NewUint32ArrayFromArray(var arr: PJSObject): PJSObject; begin Result := JS_NewUInt32ArrayFromArray(@Self, arr); end; function JSContext.NewUint32ArrayWithBuffer(var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject; begin Result := JS_NewUInt32ArrayWithBuffer(@Self, arrayBuffer, byteOffset, length); end; function JSContext.NewUint8Array(nelements: uint32): PJSObject; begin Result := JS_NewuInt8Array(@Self, nelements); end; function JSContext.NewUint8ArrayFromArray(var arr: PJSObject): PJSObject; begin Result := JS_NewUInt8ArrayFromArray(@Self, arr); end; function JSContext.NewUint8ArrayWithBuffer(var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject; begin Result := JS_NewUInt8ArrayWithBuffer(@Self, arrayBuffer, byteOffset, length); end; function JSContext.NewUint8ClampedArray(nelements: uint32): PJSObject; begin Result := JS_NewUint8ClampedArray(@Self, nelements); end; function JSContext.NewUint8ClampedArrayFromArray(var arr: PJSObject): PJSObject; begin Result := JS_NewUint8ClampedArrayFromArray(@Self, arr); end; function JSContext.NewUint8ClampedArrayWithBuffer(var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject; begin Result := JS_NewUint8ClampedArrayWithBuffer(@Self, arrayBuffer, byteOffset, length); end; procedure strFinalizeOp(fin: PJSStringFinalizer; chars: PCChar16); cdecl; begin end; function JSContext.NewExternalString(const Value: SynUnicode): PJSString; begin Result := JS_NewExternalString(@Self, pointer(Value), length(Value), @strFinalizer); end; //function JSContext.AtomizeAndPinString(const Value: SynUnicode): PJSString; {$ifdef HASINLINE}inline;{$endif} //begin // Result := JS_AtomizeAndPinStringN(@Self, pointer(Value), length(Value)); //end; function JSContext.NewFloat32Array(nelements: uint32): PJSObject; begin Result := JS_NewFloat32Array(@Self, nelements); end; function JSContext.NewFloat32ArrayFromArray(var arr: PJSObject): PJSObject; begin Result := JS_NewFloat32ArrayFromArray(@Self, arr); end; function JSContext.NewFloat32ArrayWithBuffer(var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject; begin Result := JS_NewFloat32ArrayWithBuffer(@Self, arrayBuffer, byteOffset, length); end; function JSContext.NewFloat64Array(nelements: uint32): PJSObject; begin Result := JS_NewFloat64Array(@Self, nelements); end; function JSContext.NewFloat64ArrayFromArray(var arr: PJSObject): PJSObject; begin Result := JS_NewFloat64ArrayFromArray(@Self, arr); end; function JSContext.NewFloat64ArrayWithBuffer(var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject; begin Result := JS_NewFloat64ArrayWithBuffer(@Self, arrayBuffer, byteOffset, length); end; function JSContext.NewFunction(call: JSNative; nargs: uintN; flags: uintN; name: PCChar): PJSObject; begin Result := JS_NewFunction(@Self, call, nargs, flags, name); end; function JSContext.DefineDebuggerObject(var obj: PJSObject): boolean; begin Result := JS_DefineDebuggerObject(@Self, obj); end; function JSContext.NewCompileOptions: PJSCompileOptions; begin result := JS_NewCompileOptions(@self); end; function JSContext.CompileModule(var obj: PJSObject; opts: PJSCompileOptions; chars: PCChar16; length: size_t): PJSObject; begin Result := JS_CompileModule(@Self, obj, opts, chars, length); end; function JSContext.CompileScript(bytes: PCChar; length: size_t; opts: PJSCompileOptions; out script: PJSScript): boolean; begin Result := JS_CompileScript(@Self, bytes, length, opts, script); end; function JSContext.CompileUCScript(chars: PCChar16; length: size_t; opts: PJSCompileOptions; out script: PJSScript): boolean; begin Result := JS_CompileUCScript(@Self, chars, length, opts, script); end; function JSContext.EvaluateScript(opts: PJSCompileOptions; bytes: PCChar; length: size_t; out rval: jsval): Boolean; begin Result := JS_EvaluateScript(@Self, opts, bytes, length, rval); end; function JSContext.EvaluateUCScript(opts: PJSCompileOptions; chars: PCChar16; length: size_t; out rval: jsval): Boolean; begin Result := JS_EvaluateUCScript(@Self, opts, chars, length, rval); end; function JSContext.ExecuteScript(var script: PJSScript; out rval: jsval): Boolean; begin Result := JS_ExecuteScript(@Self, script, rval); end; function JSContext.New(var ctor: PJSObject; argc: uintN; argv: PjsvalVector): PJSObject; var args: JSHandleValueArray; begin args.length := argc; args.elements_ := argv; Result := JS_New(@self, ctor, args); end; function JSContext.NewArrayBuffer(nbytes: uint32): PJSObject; begin Result := JS_NewArrayBuffer(@Self, nbytes); end; function JSContext.NewArrayObject(length: size_t; vector: PjsvalVector): PJSObject; var contents: JSHandleValueArray; begin contents.length := length; contents.elements_ := vector; Result := JS_NewArrayObject2(@Self, contents); end; function JSContext.NewArrayObject(length: size_t): PJSObject; begin Result := JS_NewArrayObject(@Self, length); end; function JSContext.InitCTypesClass(var obj: PJSObject): boolean; begin Result := JS_InitCTypesClass(@Self, obj); end; function JSContext.InitReflectParse(var obj: PJSObject): boolean; begin Result := JS_InitReflectParse(@Self, obj); end; function JSContext.InitModuleClasses(var obj: PJSObject): boolean; begin Result := JS_InitModuleClasses(@Self, obj); end; function JSContext.NewJSString(const Value: RawUTF8): PJSString; begin if Value = '' then result := JS_GetEmptyString(@self) else result := JS_NewStringCopyUTF8Z(@self, pointer(Value)); end; function JSContextOptions.getOptions(const Index: Integer): Boolean; begin Result := (pword(@self)^ and (1 shl Index)) <> 0; end; procedure JSContextOptions.setOptions(const Index: Integer; const Value: Boolean); var val: uint16; begin val := 1 shl Index; if Value then pword(@self)^ := pword(@self)^ or val else pword(@self)^ := pword(@self)^ and (not val); end; procedure JSContext.GC; begin JS_GC(@self); end; function JSContext.GetEmptyString: PJSString; begin Result := JS_GetEmptyString(@self); end; function JSContext.GetWarningReporter: JSWarningReporter; begin Result := JS_GetWarningReporter(@self); end; function JSContext.GetGCParameter(key: JSGCParamKey): uint32; begin Result := JS_GetGCParameter(@Self, key); end; function JSContext.GetNowMs: int64; begin Result := JS_Now; end; class function JSContext.CreateNew(maxbytes: uint32; maxNurseryBytes: uint32; parentContext: PJSContext): PJSContext; begin with TSynFPUException.ForLibraryCode do begin Result := JS_NewContext(maxbytes, maxNurseryBytes, parentContext); InitSelfHostedCode(Result); end; end; function JSContext.GetOptions: PJSContextOptions; begin Result := JS_GetContextOptions(@self); end; procedure JSContext.RequestInterruptCallback; begin JS_RequestInterruptCallback(@self); end; procedure JSContext.SetWarningReporter(reporter: JSWarningReporter); begin JS_SetWarningReporter(@self, reporter); end; procedure JSContext.SetGCParameter(key: JSGCParamKey; const Value: uint32); begin JS_SetGCParameter(@Self, key, Value); end; procedure JSContext.SetGCParametersBasedOnAvailableMemory(availMem: uint32); begin JS_SetGCParametersBasedOnAvailableMemory(@Self, availMem); end; procedure JSContext.SetNativeStackQuota(systemCodeStackSize: size_t); begin JS_SetNativeStackQuota(@Self, systemCodeStackSize); end; { JSObject } function JSObject.isArray(cx: PJSContext): Boolean; var _isArray: Boolean; obj: PJSObject; begin obj := @Self; Result := JS_IsArrayObject(cx, obj, _isArray) and _isArray; end; function JSObject.IsArrayBufferObject: Boolean; begin result := JS_IsArrayBufferObject(@self) end; function JSObject.IsArrayBufferViewObject: Boolean; begin result := JS_IsArrayBufferViewObject(@self) end; function JSObject.isDate(cx: PJSContext): Boolean; var _isDate: Boolean; obj: PJSObject; begin obj := @Self; Result := JS_ObjectIsDate(cx, obj, _isDate) and _isDate; end; function JSObject.IsFloat32Array: Boolean; begin result := JS_IsFloat32Array(@self); end; function JSObject.IsFloat64Array: Boolean; begin result := JS_IsFloat64Array(@self); end; function JSObject.isFunction(cx: PJSContext): Boolean; begin Result := JS_ObjectIsFunction(cx, @Self); end; function JSObject.IsInt16Array: Boolean; begin result := JS_IsInt16Array(@self) end; function JSObject.IsInt32Array: Boolean; begin result := JS_IsInt32Array(@self) end; function JSObject.IsInt8Array: Boolean; begin result := JS_IsInt8Array(@self) end; function JSObject.IsMappedArrayBufferObject(obj: PJSObject): Boolean; begin result := JS_IsMappedArrayBufferObject(@self); end; function JSObject.IsSharedArrayBufferObject: Boolean; begin result := JS_IsSharedArrayBufferObject(@self) end; function JSObject.IsTypedArrayObject: Boolean; begin result := JS_IsTypedArrayObject(@self) end; function JSObject.IsUint16Array: Boolean; begin result := JS_IsUInt16Array(@self) end; function JSObject.IsUint32Array: Boolean; begin result := JS_IsUInt32Array(@self); end; function JSObject.IsUint8Array: Boolean; begin result := JS_IsUint8Array(@self) end; function JSObject.IsUint8ClampedArray: Boolean; begin result := JS_IsUint8ClampedArray(@self) end; function JSObject.GetArrayBufferViewData(out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Pointer; begin result := JS_GetArrayBufferViewData(@self, isSharedMemory, nogc); end; function JSObject.RunMethod(cx: PJSContext; const name: PCChar; out rval: jsval): Boolean; begin Result := CallFunctionName(cx, name, 0, nil, rval); end; function JSObject.RunMethod(cx: PJSContext; const name: PCChar; arg: jsval; out rval: jsval): Boolean; begin Result := CallFunctionName(cx, name, 1, @arg, rval); end; function JSObject.RunMethod(cx: PJSContext; const name: PCChar; args: TjsvalDynArray; out rval: jsval): Boolean; begin Result := CallFunctionName(cx, name, Length(args), @args[0], rval); end; function JSObject.GetInstancePrivate(cx: PJSContext; clasp: PJSClass): Pointer; var obj: PJSObject; begin obj := @Self; result := JS_GetInstancePrivate(cx, obj, clasp, nil); end; function JSObject.GetInt16ArrayData(out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Pint16Vector; begin result := JS_GetInt16ArrayData(@self, isSharedMemory, nogc); end; function JSObject.GetInt32ArrayData(out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Pint32Vector; begin result := JS_GetInt32ArrayData(@self, isSharedMemory, nogc); end; function JSObject.GetInt8ArrayData(out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Pint8Vector; begin result := JS_GetInt8ArrayData(@self, isSharedMemory, nogc); end; function JSObject.GetObjectAsArrayBuffer(out length: uint32; out Data: Puint8Vector): PJSObject; begin result := JS_GetObjectAsArrayBuffer(@self, length, data); end; function JSObject.GetObjectAsArrayBufferView(out length: uint32; out isSharedMemory: Boolean; out Data: Puint8Vector): PJSObject; begin result := JS_GetObjectAsArrayBufferView(@self, length, isSharedMemory, data); end; function JSObject.GetObjectAsFloat32Array(out length: uint32; out isSharedMemory: Boolean; out Data: Pfloat32Vector): PJSObject; begin result := JS_GetObjectAsFloat32Array(@self, length, isSharedMemory, data); end; function JSObject.GetObjectAsFloat64Array(out length: uint32; out isSharedMemory: Boolean; out Data: Pfloat64Vector): PJSObject; begin result := JS_GetObjectAsFloat64Array(@self, length, isSharedMemory, data); end; function JSObject.GetObjectAsInt16Array(out length: uint32; out isSharedMemory: Boolean; out Data: Pint16Vector): PJSObject; begin result := JS_GetObjectAsInt16Array(@self, length, isSharedMemory, data); end; function JSObject.GetObjectAsInt32Array(out length: uint32; out isSharedMemory: Boolean; out Data: Pint32Vector): PJSObject; begin result := JS_GetObjectAsInt32Array(@self, length, isSharedMemory, data); end; function JSObject.GetObjectAsInt8Array(out length: uint32; out isSharedMemory: Boolean; out Data: Pint8Vector): PJSObject; begin result := JS_GetObjectAsInt8Array(@self, length, isSharedMemory, data) end; function JSObject.GetObjectAsUint16Array(out length: uint32; out isSharedMemory: Boolean; out Data: Puint16Vector): PJSObject; begin result := JS_GetObjectAsUInt16Array(@self, length, isSharedMemory, data); end; function JSObject.GetObjectAsUint32Array(out length: uint32; out isSharedMemory: Boolean; out Data: Puint32Vector): PJSObject; begin result := JS_GetObjectAsUint32Array(@self, length, isSharedMemory, data); end; function JSObject.GetObjectAsUint8Array(out length: uint32; out isSharedMemory: Boolean; out Data: Puint8Vector): PJSObject; begin result := JS_GetObjectAsUInt8Array(@self, length, isSharedMemory, data) end; function JSObject.GetObjectAsUint8ClampedArray(out length: uint32; out isSharedMemory: Boolean; out Data: Puint8Vector): PJSObject; begin result := JS_GetObjectAsUint8ClampedArray(@self, length, isSharedMemory, data) end; function JSObject.GetPrivate: Pointer; begin Result := JS_GetPrivate(@self); end; function JSObject.GetProperty(cx: PJSContext; const name: PCChar; out vp: jsval): boolean; var obj: PJSObject; begin obj := @Self; Result := JS_GetProperty(cx, obj, name, vp); end; function JSObject.GetPropertyById(cx: PJSContext; const id: jsid; out vp: jsval): boolean; var obj: PJSObject; _id: jsid; begin obj := @Self; _id := id; Result := JS_GetPropertyById(cx, obj, _id, vp); end; function JSObject.GetPropValue(cx: PJSContext; const name: SynUnicode): jsval; begin {$ifdef WITHASSERT} Assert( {$ENDIF} GetUCProperty(cx, Pointer(name), Length(name), Result) {$ifdef WITHASSERT} ); {$ENDIF} end; function JSObject.GetPrototype(cx: PJSContext; out protop: PJSObject): Boolean; var obj: PJSObject; begin obj := @Self; Result := JS_GetPrototype(cx, obj, protop); end; function JSObject.GetReservedSlot(index: uint32): jsval; begin result._l.asBits := JS_GetReservedSlot(@Self, index) end; function JSObject.GetSharedArrayBufferByteLength: uint32; begin result := JS_GetSharedArrayBufferByteLength(@self); end; function JSObject.GetTypedArrayByteLength: uint32; begin result := JS_GetTypedArrayLength(@self); end; function JSObject.GetTypedArrayByteOffset: uint32; begin result := JS_GetTypedArrayByteOffset(@self); end; function JSObject.GetTypedArrayLength: uint32; begin result := JS_GetTypedArrayLength(@self); end; function JSObject.GetTypedArraySharedness: Boolean; begin result := JS_GetTypedArraySharedness(@self) end; function JSObject.AlreadyHasOwnUCProperty(cx: PJSContext; const name: PCChar16; namelen: size_t): Boolean; var obj: PJSObject; foundp: Boolean; begin obj := @Self; Result := JS_AlreadyHasOwnUCProperty(cx, obj, name, namelen, foundp) and foundp; end; function JSObject.ArrayBufferHasData: Boolean; begin result := JS_ArrayBufferHasData(@self); end; function JSObject.CallFunction(cx: PJSContext; var fun: PJSFunction; argc: uintN; argv: PjsvalVector; out rval: jsval): Boolean; var obj: PJSObject; args: JSHandleValueArray; begin obj := @Self; args.length := argc; args.elements_ := argv; Result := JS_CallFunction(cx, obj, fun, args, rval); end; function JSObject.CallFunctionName(cx: PJSContext; const name: PCChar; argc: uintN; argv: PjsvalVector; out rval: jsval): Boolean; var obj: PJSObject; args: JSHandleValueArray; begin obj := @Self; args.length := argc; args.elements_ := argv; Result := JS_CallFunctionName(cx, obj, name, args, rval); end; function JSObject.CallFunctionValue(cx: PJSContext; val: jsval; argc: uintN; argv: PjsvalVector; out rval: jsval): Boolean; var obj: PJSObject; args: JSHandleValueArray; begin obj := @Self; args.length := argc; args.elements_ := argv; Result := JS_CallFunctionValue(cx, obj, val, args, rval); end; const /// API extension: OR this into indent to avoid pretty-printing the decompiled // source resulting from JS_DecompileFunction{,Body}. JS_DONT_PRETTY_PRINT = $8000; prettyPrintAr: array[boolean] of uintN = (JS_DONT_PRETTY_PRINT, 0); function JSObject.DecompileFunction(cx: PJSContext; PrettyPrint: Boolean): PJSString; var fun: PJSFunction; begin fun := @self; Result := JS_DecompileFunction(cx, fun, prettyPrintAr[PrettyPrint]); end; function JSObject.DefineFunction(cx: PJSContext; name: PCChar; call: JSNative; nargs, attrs: uintN): PJSFunction; var obj: PJSObject; begin obj := @Self; Result := JS_DefineFunction(cx, obj, name, call, nargs, attrs); end; function JSObject.DefineFunctions(cx: PJSContext; fs: PJSFunctionSpec; behavior: JSPropertyDefinitionBehavior): Boolean; var obj: PJSObject; begin obj := @Self; Result := JS_DefineFunctions(cx, obj, fs, behavior); end; function JSObject.DefineProperties(cx: PJSContext; ps: PJSPropertySpec): boolean; var obj: PJSObject; begin obj := @Self; result := JS_DefineProperties(cx, obj, ps) end; function JSObject.DefineProperty(cx: PJSContext; const name: PCChar; const value: jsval; attrs: uint32; getter, setter: JSNative): boolean; var obj: PJSObject; begin obj := @Self; result := JS_DefineProperty(cx, obj, name, pjsval(@value)^, attrs, getter, setter) end; function JSObject.DefinePropertyById(cx: PJSContext; var id: jsid; const value: jsval; attrs: uint32; getter, setter: JSNative): boolean; var obj: PJSObject; begin obj := @Self; result := JS_DefinePropertyById(cx, obj, id, pjsval(@value)^, attrs, getter, setter) end; function JSObject.DefineUCFunction(cx: PJSContext; name: PCChar16; namelen: size_t; call: JSNative; nargs, attrs: uintN): PJSFunction; var obj: PJSObject; begin obj := @Self; Result := JS_DefineUCFunction(cx, obj, name, namelen, call, nargs, attrs); end; function JSObject.DefineUCProperty(cx: PJSContext; const name: SynUnicode; const value: jsval; attrs: uint32; getter, setter: JSNative): Boolean; var obj: PJSObject; begin obj := @Self; result := JS_DefineUCProperty(cx, obj, Pointer(name), Length(name), pjsval(@value)^, attrs, getter, setter) end; function JSObject.DefineUCProperty(cx: PJSContext; const name: PCChar16; namelen: size_t; const value: jsval; attrs: uint32; getter, setter: JSNative): Boolean; var obj: PJSObject; begin obj := @Self; result := JS_DefineUCProperty(cx, obj, name, namelen, pjsval(@value)^, attrs, getter, setter) end; function JSObject.DeleteElement(cx: PJSContext; index: uint32; out res: JS_ObjectOpResult): Boolean; var obj: PJSObject; begin obj := @Self; result := JS_DeleteElement(cx, obj, index, res); end; function JSObject.DeletePropertyById(cx: PJSContext; const id: jsid; out res: JS_ObjectOpResult): Boolean; var obj: PJSObject; _id: jsid; begin obj := @Self; _id := id; Result := JS_DeletePropertyById(cx, obj, _id, res); end; function JSObject.Enumerate(cx: PJSContext; out length: size_t; out data: PjsidVector): PJSIdArray; var obj: PJSObject; begin obj := @Self; Result := JS_EnumerateToAutoIdVector(cx, obj, length, data); {$ifdef WITHASSERT} Assert(Assigned(Result)); {$ENDIF} end; function JSObject.GetUCProperty(cx: PJSContext; const name: PCChar16; namelen: size_t; out vp: jsval): boolean; var obj: PJSObject; begin obj := @Self; Result := JS_GetUCProperty(cx, obj, name, namelen, vp); end; function JSObject.GetUint16ArrayData(out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Puint16Vector; begin result := JS_GetUInt16ArrayData(@self, isSharedMemory, nogc); end; function JSObject.GetUint32ArrayData(out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Puint32Vector; begin result := JS_GetUint32ArrayData(@self, isSharedMemory, nogc); end; function JSObject.GetUint8ArrayData(out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Puint8Vector; begin result := JS_GetUInt8ArrayData(@self, isSharedMemory, nogc); end; function JSObject.GetUint8ArrayData: Puint8Vector; var isShared: Boolean; begin result := JS_GetUInt8ArrayData(@self, isShared, nil); end; function JSObject.GetUint8ClampedArrayData(out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Puint8Vector; begin result := JS_GetUint8ClampedArrayData(@self, isSharedMemory, nogc); end; function JSObject.HasInstance(cx: PJSContext; var val: jsval): Boolean; var obj: PJSObject; res: Boolean; begin obj := @Self; Result := JS_HasInstance(cx, obj, val, res) and res; end; function JSObject.HasProperty(cx: PJSContext; const name: PCChar): Boolean; var obj: PJSObject; found: Boolean; begin obj := @Self; Result := JS_HasProperty(cx, obj, name, found) and found; end; function JSObject.HasUCProperty(cx: PJSContext; const name: PCChar16; namelen: size_t; out found: Boolean): Boolean; var obj: PJSObject; begin obj := @Self; Result := JS_HasUCProperty(cx, obj, name, namelen, found); end; function JSObject.InitClass(cx: PJSContext; var parent_proto: PJSObject; clasp: PJSClass; _constructor: JSNative; nargs: Cardinal; ps: PJSPropertySpec; fs: PJSFunctionSpec; static_ps: PJSPropertySpec; static_fs: PJSFunctionSpec): PJSObject; var obj: PJSObject; begin obj := @Self; Result := JS_InitClass(cx, obj, parent_proto, clasp, _constructor, nargs, ps, fs, static_ps, static_fs); end; function JSObject.GetArrayBufferByteLength: uint32; begin result := JS_GetArrayBufferByteLength(@self); end; function JSObject.GetArrayBufferData: Puint8Vector; var isShared: Boolean; begin result := JS_GetArrayBufferData(@self, isShared, nil); end; function JSObject.GetArrayBufferData(out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Puint8Vector; begin result := JS_GetArrayBufferData(@self, isSharedMemory, nogc); end; function JSObject.GetArrayBufferViewByteLength: uint32; begin result := JS_GetArrayBufferViewByteLength(@self); end; function JSObject.GetArrayBufferViewType: JSArrayBufferViewType; begin result := JS_GetArrayBufferViewType(@self); end; function JSObject.GetArrayLength(cx: PJSContext; out length: uint32): Boolean; var obj: PJSObject; begin obj := @Self; result := JS_GetArrayLength(cx, obj, length); end; function JSObject.GetClass: PJSClass; begin result := JS_GetClass(@self); end; function JSObject.GetConstructor(cx: PJSContext): PJSObject; var obj: PJSObject; begin obj := @Self; Result := JS_GetConstructor(cx, obj); end; function JSObject.GetElement(cx: PJSContext; index: uint32; out vp: jsval): Boolean; var obj: PJSObject; begin obj := @Self; result := JS_GetElement(cx, obj, index, vp); end; function JSObject.GetFloat32ArrayData(out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Pfloat32Vector; begin result := JS_GetFloat32ArrayData(@self, isSharedMemory, nogc); end; function JSObject.GetFloat64ArrayData(out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Pfloat64Vector; begin result := JS_GetFloat64ArrayData(@self, isSharedMemory, nogc); end; function JSObject.GetFunctionId: PJSString; begin Result := JS_GetFunctionId(@self); end; function JSObject.SetElement(cx: PJSContext; index: uint32; const vp: jsval): Boolean; var obj: PJSObject; begin obj := @Self; result := JS_SetElement(cx, obj, index, pjsval(@vp)^); end; procedure JSObject.SetPrivate(data: Pointer); begin JS_SetPrivate(@self, data); end; function JSObject.SetProperty(cx: PJSContext; const name: PCChar; const vp: jsval): Boolean; var obj: PJSObject; begin obj := @Self; Result := JS_SetProperty(cx, obj, name, pjsval(@vp)^); end; function JSObject.SetPrototype(cx: PJSContext; var proto: PJSObject): Boolean; var obj: PJSObject; begin obj := @Self; Result := JS_SetPrototype(cx, obj, proto); end; procedure JSObject.SetReservedSlot(index: uint32; v: jsval); begin JS_SetReservedSlot(@Self, index, v); end; function JSObject.SetUCProperty(cx: PJSContext; const name: PCChar16; namelen: size_t; const vp: jsval): boolean; var obj: PJSObject; begin obj := @Self; Result := JS_SetUCProperty(cx, obj, name, namelen, pjsval(@vp)^); end; function JSObject.ToJSValue: jsval; begin Result.asObject := @self; end; function JSObject.GetBufferDataAndLength(out data: Puint8Vector; out len: uint32): boolean; var isShared: boolean; begin if Self.IsArrayBufferViewObject then begin Result := Self.GetObjectAsArrayBufferView(len, isShared, data) <> nil; end else if Self.IsArrayBufferObject then begin data := Self.GetArrayBufferData; len := Self.GetArrayBufferByteLength; Result := True end else Result := False; end; { ESMException } constructor ESMException.CreateWithTrace(const AFileName: RawUTF8; AJSErrorNum, ALineNum: integer; AMessage: string; const AStackTrace: SynUnicode); {$ifndef SM_DEBUG} const MODULE_START: SynUnicode = #10'Module.'; var appStackEnd: LongInt; {$endif} begin Create(AMessage); FJSErrorNum := AJSErrorNum; if AFileName='' then FFileName := '<>' else FFileName := AFileName; FLineNum := ALineNum; {$ifdef SM_DEBUG} FJSStackTrace := AStackTrace; {$else} if length(AStackTrace) = 0 then FJSStackTrace := '' else begin appStackEnd := Pos(MODULE_START, AStackTrace); if appStackEnd = 0 then FJSStackTrace := AStackTrace else FJSStackTrace := Copy(AStackTrace, 0, appStackEnd - 1); // last \n end; {$endif} end; procedure ESMException.WriteFormatted(WR: TTextWriter); begin WR.AddJSONEscape(pointer(FileName), Length(fileName)); WR.Add(':'); WR.Add(Line); WR.AddShort('\n\nError: '); WR.AddJSONEscapeString(Message); WR.AddShort('\n'); {$ifdef SM_DEBUG} WR.AddJSONEscapeString(Stack); {$else} WR.AddJSONEscapeW(pointer(Stack), length(Stack)); {$endif} end; {$ifndef NOEXCEPTIONINTERCEPT} function ESMException.CustomLog( WR: TTextWriter; const Context: TSynLogExceptionContext): boolean; begin (Context.EInstance as ESMException).WriteFormatted(WR); result := true; // do not append a address end; {$endif} { JSArgRec } function JSArgRec.getArgv: PjsvalVector; begin Result := @rec.argv; end; function JSArgRec.getCalleObject: PJSObject; begin Result := rec.calle.asObject; end; function JSArgRec.GetIsConstructing: Boolean; begin Result := rec.this.IsMagic; end; function JSArgRec.getThis(cx: PJSContext): jsval; begin if rec.this.IsPrimitive then result._l.asBits := JS_ComputeThis(cx, rec.calle) else result := rec.this; end; function JSArgRec.getThisObject(cx: PJSContext): PJSObject; begin Result := this[cx].asObject; end; { jsid } const JSID_TYPE_MASK = $7; function jsid.isString: Boolean; begin Result := JSIdType(asBits and JSID_TYPE_MASK) = JSID_TYPE_STRING; end; function jsid.asJSString: PJSString; begin {$ifdef WITHASSERT} Assert(isString); {$endif} Result := PJSString(asBits); end; { jsval } const {$ifdef CPU64} JSVAL_LOWER_INCL_TAG_OF_OBJ_OR_NULL_SET = JSVAL_TAG_NULL; JSVAL_UPPER_EXCL_TAG_OF_PRIMITIVE_SET = JSVAL_TAG_OBJECT; JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_NUMBER_SET = JSVAL_SHIFTED_TAG_UNDEFINED; JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_PRIMITIVE_SET = JSVAL_SHIFTED_TAG_OBJECT; {$else} JSVAL_LOWER_INCL_TAG_OF_OBJ_OR_NULL_SET = JSVAL_TAG_NULL; JSVAL_UPPER_EXCL_TAG_OF_PRIMITIVE_SET = JSVAL_TAG_OBJECT; JSVAL_UPPER_INCL_TAG_OF_NUMBER_SET = JSVAL_TAG_INT32; JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET = JSVAL_TAG_STRING; {$endif} function jsval.getAsBoolean: Boolean; begin {$ifdef WITHASSERT} assert(isBoolean); {$endif} {$ifdef CPU64} Result := Boolean(_l.asBits and JSVAL_PAYLOAD_MASK) {$else} Result := Boolean(_l.s.payload.boo); {$endif} end; function jsval.getAsDate(cx: PJSContext): TDateTime; var oDate: PJSObject; {$ifdef CONSIDER_TIME_IN_Z} // as defined in SyNode.inc ms: double; ms64: Int64; fval: jsval; {$else} d, m, Y, h, mn, s, ml: Integer; v, fval: jsval; function GetIntFuncPropVal(funcName: PWideChar): Integer; begin Result := 0; if oDate.GetUCProperty(cx, pointer(funcName), Length(funcName), fval) then if oDate.CallFunctionValue(cx, fval, 0, nil, v) then Result := v.asInteger; end; {$endif} begin oDate := getAsObject; if not oDate.isDate(cx) then raise ESMException.create('not a DateTime object'); {$ifdef CONSIDER_TIME_IN_Z} ms := 0; if oDate.CallFunctionName(cx, PCChar('getTime'), 0, nil, fval) then ms := fval.asDouble; if ms = 0 then raise ESMException.Create('JSDateToDateTime: no getTime() in Date object'); ms64 := Trunc(ms); // W/O millisec: Result := IncMilliSecond(UnixDateDelta, ms64); Result := UnixMSTimeToDateTime(ms64); {$else} d := GetIntFuncPropVal('getDate'); m := GetIntFuncPropVal('getMonth') + 1; //WTF months start from 0 Y := GetIntFuncPropVal('getFullYear'); h := GetIntFuncPropVal('getHours'); mn := GetIntFuncPropVal('getMinutes'); s := GetIntFuncPropVal('getSeconds'); ml := GetIntFuncPropVal('getMilliseconds'); Result := EncodeDateTime(Y, m, d, h, mn, s, ml); {$endif} end; function jsval.getAsDouble: Double; begin {$ifdef WITHASSERT} assert(isDouble); {$endif} Result := _l.asDouble; end; function jsval.getAsInteger: Integer; begin {$ifdef WITHASSERT} assert(isInteger); {$endif} {$ifdef CPU64} Result := int32(_l.asBits); {$else} Result := _l.s.payload.i32; {$endif} end; function writeCallback(const buf: PCChar16; len: uint32; data: pointer): Boolean; cdecl; begin TTextWriter(data).AddNoJSONEscapeW(pointer(buf),len); result := true; end; procedure jsval.AddJSON(cx: PJSContext; W: TTextWriter); var // voidVal: jsval; T: JSType; begin if @self=nil then W.AddShort('null') else begin T := cx.TypeOfValue(self); case T of JSTYPE_VOID, JSTYPE_NULL: W.AddShort('null'); JSTYPE_STRING: asJSString.ToJSONString(cx,W); JSTYPE_NUMBER: if isInteger then W.Add(asInteger) else W.AddDouble(asDouble); JSTYPE_BOOLEAN: W.Add(asBoolean); JSTYPE_OBJECT, JSTYPE_FUNCTION: begin if not Stringify(cx, nullObj, JSVAL_VOID, writeCallback, pointer(W)) then ; end else raise ESMException.CreateFmt('Unhandled AddJSON(%d)',[ord(T)]); end; end; end; function jsval.getAsJson(cx: PJSContext): RawUTF8; var W: TJSONWriter; begin W := TJSONWriter.CreateOwnedStream; try AddJSON(cx,W); W.SetText(result); finally W.Free; end; end; function jsval.getAsInt64: Int64; begin if isInteger then result := asInteger else {$ifdef WITHASSERT} if not isDouble then raise ESMException.Create('jsval.getAsInt64!') else {$endif} result := trunc(asDouble); end; function jsval.getAsObject: PJSObject; {$ifdef CPU64} var ptrBits: UInt64 absolute Result; {$endif} begin {$ifdef WITHASSERT} assert(isObject); {$endif} {$ifdef CPU64} ptrBits := _l.asBits and JSVAL_PAYLOAD_MASK; {$ifdef WITHASSERT} assert(ptrBits and 7 = 0); {$endif} {$else} Result := _l.s.payload.obj; {$endif} end; function jsval.getIsBoolean: Boolean; begin {$ifdef CPU64} Result := _l.asBits shr JSVAL_TAG_SHIFT = JSVAL_TAG_BOOLEAN; {$else} Result := _l.s.tag = JSVAL_TAG_BOOLEAN; {$endif} end; function jsval.getIsDouble: Boolean; begin {$ifdef CPU64} Result := _l.asBits <= JSVAL_SHIFTED_TAG_MAX_DOUBLE {$else} Result := UInt32(_l.s.tag) <= UInt32(JSVAL_TAG_CLEAR) {$endif} end; function jsval.getIsInteger: Boolean; begin {$ifdef CPU64} Result := _l.asBits shr JSVAL_TAG_SHIFT = JSVAL_TAG_INT32; {$else} Result := _l.s.tag = JSVAL_TAG_INT32; {$endif} end; function jsval.getIsNull: Boolean; begin {$ifdef CPU64} Result := _l.asBits = JSVAL_SHIFTED_TAG_NULL; {$else} Result := _l.s.tag = JSVAL_TAG_NULL; {$endif} end; function jsval.getIsNumber: Boolean; begin {$ifdef CPU64} Result := _l.asBits < JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_NUMBER_SET; {$else} {$ifdef WITHASSERT} assert(_l.s.tag <> JSVAL_TAG_CLEAR); {$endif} Result := (UInt32(_l.s.tag) <= UInt32(JSVAL_UPPER_INCL_TAG_OF_NUMBER_SET)); {$endif} end; function jsval.getIsObject: Boolean; begin {$ifdef CPU64} {$ifdef WITHASSERT} Assert(_l.asBits shr JSVAL_TAG_SHIFT <= JSVAL_TAG_OBJECT); {$endif} Result := _l.asBits >= JSVAL_SHIFTED_TAG_OBJECT; {$else} {$ifdef WITHASSERT} Assert(_l.s.tag <= JSVAL_TAG_OBJECT); {$endif} Result := (UInt32(_l.s.tag) >= UInt32(JSVAL_LOWER_INCL_TAG_OF_OBJ_OR_NULL_SET)); {$endif} end; function jsval.getIsSimpleVariant(cx: PJSContext): Boolean; var t: JSType; begin t := ValType(cx); Result := (t = JSTYPE_VOID) or (t = JSTYPE_NULL) or (t = JSTYPE_STRING) or (t = JSTYPE_NUMBER) or (t = JSTYPE_BOOLEAN); end; function jsval.getIsString: Boolean; begin {$ifdef CPU64} Result := _l.asBits shr JSVAL_TAG_SHIFT = JSVAL_TAG_STRING; {$else} Result := _l.s.tag = JSVAL_TAG_STRING; {$endif} end; function jsval.getIsVoid: Boolean; begin {$ifdef CPU64} Result := _l.asBits = JSVAL_SHIFTED_TAG_UNDEFINED; {$else} Result := _l.s.tag = JSVAL_TAG_UNDEFINED; {$endif} end; function jsval.getJSString: PJSString; begin {$ifdef CPU64} Result := PJSString(_l.asBits and JSVAL_PAYLOAD_MASK); {$else} {$ifdef WITHASSERT} Assert(isString); {$endif} Result := _l.s.payload.str; {$endif} end; function jsval.getPrivate: Pointer; begin {$ifdef CPU64} {$ifdef WITHASSERT} Assert(_l.asBits and $8000000000000000 = 0); {$endif} Result := Pointer(_l.asBits shl 1); {$else} {$ifdef WITHASSERT} Assert(isDouble); {$endif} Result := _l.s.payload.ptr; {$endif} end; function jsval.getSimpleVariant(cx: PJSContext): Variant; var t: JSType; begin t := ValType(cx); case t of JSTYPE_VOID: VarClear(result); JSTYPE_NULL: SetVariantNull(result); // JSTYPE_OBJECT: // todo JSTYPE_STRING: getJSString.ToVariant(cx,result); JSTYPE_NUMBER: if getIsInteger then result := getAsInteger else result := getAsDouble; JSTYPE_BOOLEAN: result := getAsBoolean; // JSTYPE_FUNCTION: // todo else raise ESMException.CreateFmt('Unhandled ToVariant(%d)',[ord(t)]); end; end; function jsval.IsMagic: Boolean; begin {$IFDEF CPU64} Result := _l.asBits shr JSVAL_TAG_SHIFT = JSVAL_TAG_MAGIC; {$ELSE} Result := _l.s.tag = JSVAL_TAG_MAGIC; {$ENDIF} end; function jsval.IsPrimitive: Boolean; begin {$IFDEF CPU64} Result := _l.asBits < JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_PRIMITIVE_SET; {$ELSE} Result := (UInt32(_l.s.tag) < UInt32(JSVAL_UPPER_EXCL_TAG_OF_PRIMITIVE_SET)); {$ENDIF} end; function doubleIsInt(Value: Double):boolean; {$ifdef HASINLINE}inline;{$endif} var Value_int64:Int64 absolute Value; len: Int16; begin len := (Value_int64 shr 52) and $7FF - $3FF; result := ((len >= 0) and (len < 31) and ((Value_int64 and (QWORD(1) shl (52 - len)-1)) = 0)) or (Value_int64 = 0) or (Value_int64 = $C1E0000000000000); end; function doubleToInt(Value: Double):Integer; {$ifdef HASINLINE}inline;{$endif} var Value_int64:Int64 absolute Value; len: Smallint; begin if Value_int64 = 0 then result := 0 else begin len := (Value_int64 shr 52) and $7FF - $3FF; Result := (Value_int64 and $000FFFFFFFFFFFFF or $0010000000000000) shr (52-len); if (Value_int64 and $8000000000000000)<>0 then Result := -Result; end end; procedure jsval.setAsBoolean(const Value: Boolean); begin {$ifdef CPU64} _l.asBits := uint64(ord(Value)) or JSVAL_SHIFTED_TAG_BOOLEAN; {$else} _l.s.tag := JSVAL_TAG_BOOLEAN; _l.s.payload.boo := ord(Value); {$endif} end; procedure jsval.setAsDate(cx: PJSContext; const Value: TDateTime); var dmsec: double; unixTime: Int64; {$ifdef CONSIDER_TIME_IN_Z} // as defined in SyNode.inc oDate: PJSObject; {$else} // this realisation is buggy - it ignores timezone rules change history // for server-side realisation the best solution is to use GMT time here ms: Word; STLocal, STUtc: TSystemTime; TZ: TTimeZoneInformation; AUTCDateTime: TDateTime; {$endif} begin {$ifdef CONSIDER_TIME_IN_Z} unixTime := DateTimeToUnixMSTime(Value); dmsec := unixTime-(unixTime mod 1000); oDate := cx.NewDateObjectMsec(dmsec); if not oDate.IsDate(cx) then raise ESMException.CreateFmt('SetDateTime(%g): not a valid date',[Value]); setAsObject(oDate); {$else} DateTimeToSystemTime(Value, STLocal); GetTimeZoneInformation(TZ); // use TzSpecificLocalTimeToSystemTime? TZ.Bias := -TZ.Bias; TZ.StandardBias := -TZ.StandardBias; TZ.DaylightBias := -TZ.DaylightBias; SystemTimeToTzSpecificLocalTime(@TZ, STLocal, STUtc); ms := STUtc.wMilliseconds; AUTCDateTime := SystemTimeToDateTime(STUtc); dmSec := DateTimeToUnixMSTime(AUTCDateTime) + ms; setAsObject(cx.NewDateObjectMsec(dmsec)); {$endif} end; procedure jsval.setAsDouble(const Value: Double); begin if doubleIsInt(Value) then asInteger := doubleToInt(Value) else begin _l.asDouble := Value; if ((_l.asBits and $7FF0000000000000) = $7FF0000000000000) and ((_l.asBits and $000FFFFFFFFFFFFF) <> $0000000000000000) then _l.asBits := JSVAL_NAN_impl; // canonize NaN end; end; procedure jsval.setAsInteger(const Value: Integer); begin {$ifdef CPU64} _l.asBits := Value; _l.asBits := uint32(Value) or JSVAL_SHIFTED_TAG_INT32; {$else} _l.s.tag := JSVAL_TAG_INT32; _l.s.payload.i32 := Value; {$endif} end; procedure jsval.setAsJson(cx: PJSContext; const Value: RawUTF8); var tmp: RawUnicode; len: integer; begin if Value='' then begin SetVoid; end else begin len := Utf8DecodeToRawUnicodeUI(Value,tmp); if not JS_ParseJSON(cx, pointer(tmp), len shr 1, self) then {$ifdef WITHASSERT} raise ESMException.Create('jsval.setAsJson!') else {$ELSE} SetVoid; {$endif} end; end; procedure jsval.setAsInt64(const Value: Int64); begin if (Value>=Low(integer)) and (Value<=High(integer)) then setAsInteger(Value) else setAsDouble(Value); end; procedure jsval.setAsObject(const Value: PJSObject); {$ifdef CPU64} var objBits: UInt64 absolute Value; {$endif} begin {$ifdef CPU64} {$ifdef WITHASSERT} Assert(objBits shr JSVAL_TAG_SHIFT = 0); {$endif} _l.asBits := QWord(objBits or JSVAL_SHIFTED_TAG_OBJECT); {$else} if Value<>nil then begin _l.s.tag := JSVAL_TAG_OBJECT; _l.s.payload.obj := Value; end else _l.asBits := JSVAL_NULL_impl; {$endif} end; procedure jsval.setJSString(const Value: PJSString); {$ifdef CPU64} var strBits: UInt64 absolute Value; {$endif} begin {$ifdef CPU64} {$ifdef WITHASSERT} Assert(strBits shr JSVAL_TAG_SHIFT = 0); {$endif} _l.asBits := strBits or JSVAL_SHIFTED_TAG_STRING; {$else} {$ifdef WITHASSERT} assert(str<>nil) ; {$endif} _l.s.tag := JSVAL_TAG_STRING; _l.s.payload.str := Value; {$endif} end; procedure jsval.setNull; begin _l.asBits := JSVAL_NULL_impl; end; procedure jsval.setPrivate(const Value: Pointer); {$ifdef CPU64} var ptrBits: UInt64 absolute Value; {$endif} begin {$ifdef CPU64} {$ifdef WITHASSERT} Assert(ptrBits and 1 = 0); {$endif} _l.asBits := ptrBits shr 1; {$ifdef WITHASSERT} assert(isDouble); {$endif} {$else} {$ifdef WITHASSERT} assert((uint32(ptr) and 1) = 0); {$endif} _l.s.tag := JSValueTag(0); _l.s.payload.ptr := Value; {$ifdef WITHASSERT} assert(isDouble); {$endif} {$endif} end; procedure jsval.setSimpleVariant(cx: PJSContext; const Value: Variant); begin with TVarData(Value) do case VType of varNull: setNull; varEmpty: setVoid; varBoolean: setAsBoolean(VBoolean); varSmallint: setAsInteger(VSmallInt); {$ifndef DELPHI5OROLDER} varShortInt: setAsInteger(VShortInt); varWord: setAsInteger(VWord); varLongWord: setAsInt64(VLongWord); {$endif} varByte: setAsInteger(VByte); varInteger: setAsInteger(VInteger); {$ifdef FPC}varQword,{$endif} varInt64: setAsInt64(VInt64); varSingle: setAsDouble(VSingle); varDouble: setAsDouble(VDouble); varCurrency: setAsDouble(VCurrency); varDate: setAsDate(cx, VDate); varOleStr: setJSString(cx.NewJSString(WideString(VAny))); varString: setJSString(cx.NewJSString(VAny,length(RawByteString(VAny)), {$ifndef UNICODE} CP_UTF8)); {$else} StringCodePage(RawByteString(VAny)))); varUString: setJSString(cx.NewJSString(UnicodeString(VAny))); {$endif} else if VType=varByRef or varVariant then setSimpleVariant(cx,PVariant(VPointer)^) else if VType=varByRef or varOleStr then setJSString(cx.NewJSString(PWideString(VAny)^)) else {$ifdef UNICODE} if VType=varByRef or varUString then setJSString(cx.NewJSString(PUnicodeString(VAny)^)) else {$endif} raise ESMException.CreateFmt('Unhandled variant type %d',[VType]); end; end; procedure jsval.setVoid; begin _l.asBits := JSVAL_VOID_impl; end; function jsval.Stringify(cx: PJSContext; var replacer: PJSObject; space: jsval; callback: JSONWriteCallback; data: pointer): Boolean; begin with TSynFPUException.ForLibraryCode do Result := JS_Stringify(cx, Self, replacer, space, callback, data); end; function jsval.toSource(cx: PJSContext): PJSString; begin Result := JS_ValueToSource(cx, self); end; function jsval.ValType(cx: PJSContext): JSType; begin Result := cx.TypeOfValue(self); end; class function jsval.NullValue: jsval; begin Result.setNull(); end; class function jsval.Int32Value(v: integer): jsval; begin Result.asInteger := v; end; class function jsval.BooleanValue(v: boolean): jsval; begin Result.asBoolean := v; end; class function jsval.TrueValue: jsval; begin Result.asBoolean := True; end; class function jsval.FalseValue: jsval; begin Result.asBoolean := False; end; class function jsval.DoubleValue(v: double): jsval; begin Result.asDouble := v; end; class function jsval.StringValue(v: PJSString): jsval; begin Result.asJSString := v; end; class function jsval.ObjectValue(v: PJSObject): jsval; begin Result.asObject := v; end; class function jsval.Int64Value(v: Int64): jsval; begin Result.asInt64 := v; end; function SimpleVariantToJSval(cx: PJSContext; val: Variant): jsval; begin Result.asSimpleVariant[cx] := val; end; function IsSM52Loaded: Boolean; begin Result := SM52Lib <> INVALID_MODULEHANDLE_VALUE; end; function LoadSM52: Boolean; begin Result := SM52Lib <> INVALID_MODULEHANDLE_VALUE; if Result then Exit; if SM52Lib = INVALID_MODULEHANDLE_VALUE then SM52Lib := SafeLoadLibrary(SpiderMonkeyLib); Result := SM52Lib <> INVALID_MODULEHANDLE_VALUE; if Result then begin JS_Init := TJS_Initialize(GetProcAddress(SM52Lib, 'SM_Initialize')^); JS_ShutDown := TJS_ShutDown(GetProcAddress(SM52Lib, 'SM_ShutDown')^); JS_Now := TJS_Now(GetProcAddress(SM52Lib, 'SM_Now')^); JS_GetEmptyString := TJS_GetEmptyString(GetProcAddress(SM52Lib, 'SM_GetEmptyString')^); JS_TypeOfValue := TJS_TypeOfValue(GetProcAddress(SM52Lib, 'SM_TypeOfValue')^); JS_BeginRequest := TJS_BeginRequest(GetProcAddress(SM52Lib, 'SM_BeginRequest')^); JS_EndRequest := TJS_EndRequest(GetProcAddress(SM52Lib, 'SM_EndRequest')^); JS_NewContext := TJS_NewContext(GetProcAddress(SM52Lib, 'SM_NewContext')^); InitSelfHostedCode := TInitSelfHostedCode(GetProcAddress(SM52Lib, 'SM_InitSelfHostedCode')^); JS_DestroyContext := TJS_DestroyContext(GetProcAddress(SM52Lib, 'SM_DestroyContext')^); JS_GetContextPrivate := TJS_GetContextPrivate(GetProcAddress(SM52Lib, 'SM_GetContextPrivate')^); JS_SetContextPrivate := TJS_SetContextPrivate(GetProcAddress(SM52Lib, 'SM_SetContextPrivate')^); JS_WrapObject := TJS_WrapObject(GetProcAddress(SM52Lib, 'SM_WrapObject')^); JS_EnterCompartment := TJS_EnterCompartment(GetProcAddress(SM52Lib, 'SM_EnterCompartment')^); JS_LeaveCompartment := TJS_LeaveCompartment(GetProcAddress(SM52Lib, 'SM_LeaveCompartment')^); JS_InitStandardClasses := TJS_InitStandardClasses(GetProcAddress(SM52Lib, 'SM_InitStandardClasses')^); JS_CurrentGlobalOrNull := TJS_CurrentGlobalOrNull(GetProcAddress(SM52Lib, 'SM_CurrentGlobalOrNull')^); JS_InitReflectParse := TJS_InitReflectParse(GetProcAddress(SM52Lib, 'SM_InitReflectParse')^); JS_InitCTypesClass := TJS_InitCTypesClass(GetProcAddress(SM52Lib, 'SM_InitCTypesClass')^); JS_DefineDebuggerObject := TJS_DefineDebuggerObject(GetProcAddress(SM52Lib, 'SM_DefineDebuggerObject')^); JS_GC := TJS_GC(GetProcAddress(SM52Lib, 'SM_GC')^); JS_MaybeGC := TJS_MaybeGC(GetProcAddress(SM52Lib, 'SM_MaybeGC')^); JS_SetGCParameter := TJS_SetGCParameter(GetProcAddress(SM52Lib, 'SM_SetGCParameter')^); JS_GetGCParameter := TJS_GetGCParameter(GetProcAddress(SM52Lib, 'SM_GetGCParameter')^); JS_SetGCParametersBasedOnAvailableMemory := TJS_SetGCParametersBasedOnAvailableMemory(GetProcAddress(SM52Lib, 'SM_SetGCParametersBasedOnAvailableMemory')^); JS_NewExternalString := TJS_NewExternalString(GetProcAddress(SM52Lib, 'SM_NewExternalString')^); JS_SetNativeStackQuota := TJS_SetNativeStackQuota(GetProcAddress(SM52Lib, 'SM_SetNativeStackQuota')^); JS_ValueToId := TJS_ValueToId(GetProcAddress(SM52Lib, 'SM_ValueToId')^); JS_IdToValue := TJS_IdToValue(GetProcAddress(SM52Lib, 'SM_IdToValue')^); JS_ValueToSource := TJS_ValueToSource(GetProcAddress(SM52Lib, 'SM_ValueToSource')^); JS_InitClass := TJS_InitClass(GetProcAddress(SM52Lib, 'SM_InitClass')^); JS_GetClass := TJS_GetClass(GetProcAddress(SM52Lib, 'SM_GetClass')^); JS_HasInstance := TJS_HasInstance(GetProcAddress(SM52Lib, 'SM_HasInstance')^); JS_GetPrivate := TJS_GetPrivate(GetProcAddress(SM52Lib, 'SM_GetPrivate')^); JS_SetPrivate := TJS_SetPrivate(GetProcAddress(SM52Lib, 'SM_SetPrivate')^); JS_GetConstructor := TJS_GetConstructor(GetProcAddress(SM52Lib, 'SM_GetConstructor')^); JS_GetInstancePrivate := TJS_GetInstancePrivate(GetProcAddress(SM52Lib, 'SM_GetInstancePrivate')^); JS_NewGlobalObject := TJS_NewGlobalObject(GetProcAddress(SM52Lib, 'SM_NewGlobalObject')^); JS_GlobalObjectTraceHook := TJS_GlobalObjectTraceHook(GetProcAddress(SM52Lib, 'SM_GlobalObjectTraceHook')^); JS_NewObject := TJS_NewObject(GetProcAddress(SM52Lib, 'SM_NewObject')^); JS_NewObjectWithGivenProto := TJS_NewObjectWithGivenProto(GetProcAddress(SM52Lib, 'SM_NewObjectWithGivenProto')^); JS_GetPrototype := TJS_GetPrototype(GetProcAddress(SM52Lib, 'SM_GetPrototype')^); JS_SetPrototype := TJS_SetPrototype(GetProcAddress(SM52Lib, 'SM_SetPrototype')^); JS_DefinePropertyById := TJS_DefinePropertyById(GetProcAddress(SM52Lib, 'SM_DefinePropertyById')^); JS_DefineProperty := TJS_DefineProperty(GetProcAddress(SM52Lib, 'SM_DefineProperty')^); JS_DefineUCProperty := TJS_DefineUCProperty(GetProcAddress(SM52Lib, 'SM_DefineUCProperty')^); JS_HasProperty := TJS_HasProperty(GetProcAddress(SM52Lib, 'SM_HasProperty')^); JS_HasUCProperty := TJS_HasUCProperty(GetProcAddress(SM52Lib, 'SM_HasUCProperty')^); JS_GetPropertyById := TJS_GetPropertyById(GetProcAddress(SM52Lib, 'SM_GetPropertyById')^); JS_GetProperty := TJS_GetProperty(GetProcAddress(SM52Lib, 'SM_GetProperty')^); JS_GetUCProperty := TJS_GetUCProperty(GetProcAddress(SM52Lib, 'SM_GetUCProperty')^); JS_GetElement := TJS_GetElement(GetProcAddress(SM52Lib, 'SM_GetElement')^); JS_SetProperty := TJS_SetProperty(GetProcAddress(SM52Lib, 'SM_SetProperty')^); JS_SetUCProperty := TJS_SetUCProperty(GetProcAddress(SM52Lib, 'SM_SetUCProperty')^); JS_SetElement := TJS_SetElement(GetProcAddress(SM52Lib, 'SM_SetElement')^); JS_DeletePropertyById := TJS_DeletePropertyById(GetProcAddress(SM52Lib, 'SM_DeletePropertyById')^); JS_DeleteElement := TJS_DeleteElement(GetProcAddress(SM52Lib, 'SM_DeleteElement')^); JS_CallFunctionValue := TJS_CallFunctionValue(GetProcAddress(SM52Lib, 'SM_CallFunctionValue')^); JS_CallFunction := TJS_CallFunction(GetProcAddress(SM52Lib, 'SM_CallFunction')^); JS_CallFunctionName := TJS_CallFunctionName(GetProcAddress(SM52Lib, 'SM_CallFunctionName')^); JS_New := TJS_New(GetProcAddress(SM52Lib, 'SM_New')^); JS_DefineProperties := TJS_DefineProperties(GetProcAddress(SM52Lib, 'SM_DefineProperties')^); JS_AlreadyHasOwnUCProperty := TJS_AlreadyHasOwnUCProperty(GetProcAddress(SM52Lib, 'SM_AlreadyHasOwnUCProperty')^); JS_NewArrayObject := TJS_NewArrayObject(GetProcAddress(SM52Lib, 'SM_NewArrayObject')^); JS_NewArrayObject2 := TJS_NewArrayObject2(GetProcAddress(SM52Lib, 'SM_NewArrayObject2')^); JS_IsArrayObject := TJS_IsArrayObject(GetProcAddress(SM52Lib, 'SM_IsArrayObject')^); JS_GetArrayLength := TJS_GetArrayLength(GetProcAddress(SM52Lib, 'SM_GetArrayLength')^); JS_SetReservedSlot := TJS_SetReservedSlot(GetProcAddress(SM52Lib, 'SM_SetReservedSlot')^); JS_NewFunction := TJS_NewFunction(GetProcAddress(SM52Lib, 'SM_NewFunction')^); JS_GetFunctionId := TJS_GetFunctionId(GetProcAddress(SM52Lib, 'SM_GetFunctionId')^); JS_ObjectIsFunction := TJS_ObjectIsFunction(GetProcAddress(SM52Lib, 'SM_ObjectIsFunction')^); JS_DefineFunctions := TJS_DefineFunctions(GetProcAddress(SM52Lib, 'SM_DefineFunctions')^); JS_DefineFunction := TJS_DefineFunction(GetProcAddress(SM52Lib, 'SM_DefineFunction')^); JS_DefineUCFunction := TJS_DefineUCFunction(GetProcAddress(SM52Lib, 'SM_DefineUCFunction')^); JS_CompileScript := TJS_CompileScript(GetProcAddress(SM52Lib, 'SM_CompileScript')^); JS_CompileUCScript := TJS_CompileUCScript(GetProcAddress(SM52Lib, 'SM_CompileUCScript')^); JS_DecompileFunction := TJS_DecompileFunction(GetProcAddress(SM52Lib, 'SM_DecompileFunction')^); JS_ExecuteScript := TJS_ExecuteScript(GetProcAddress(SM52Lib, 'SM_ExecuteScript')^); JS_CheckForInterrupt := TJS_CheckForInterrupt(GetProcAddress(SM52Lib, 'SM_CheckForInterrupt')^); JS_AddInterruptCallback := TJS_AddInterruptCallback(GetProcAddress(SM52Lib, 'SM_AddInterruptCallback')^); JS_DisableInterruptCallback := TJS_DisableInterruptCallback(GetProcAddress(SM52Lib, 'SM_DisableInterruptCallback')^); JS_ResetInterruptCallback := TJS_ResetInterruptCallback(GetProcAddress(SM52Lib, 'SM_ResetInterruptCallback')^); JS_RequestInterruptCallback := TJS_RequestInterruptCallback(GetProcAddress(SM52Lib, 'SM_RequestInterruptCallback')^); JS_IsRunning := TJS_IsRunning(GetProcAddress(SM52Lib, 'SM_IsRunning')^); JS_NewStringCopyN := TJS_NewStringCopyN(GetProcAddress(SM52Lib, 'SM_NewStringCopyN')^); JS_NewStringCopyUTF8Z := TJS_NewStringCopyUTF8Z(GetProcAddress(SM52Lib, 'SM_NewStringCopyUTF8Z')^); JS_GetEmptyStringValue := TJS_GetEmptyStringValue(GetProcAddress(SM52Lib, 'SM_GetEmptyStringValue')^); JS_NewUCStringCopyN := TJS_NewUCStringCopyN(GetProcAddress(SM52Lib, 'SM_NewUCStringCopyN')^); JS_GetStringLength := TJS_GetStringLength(GetProcAddress(SM52Lib, 'SM_GetStringLength')^); JS_StringHasLatin1Chars := TJS_StringHasLatin1Chars(GetProcAddress(SM52Lib, 'SM_StringHasLatin1Chars')^); JS_GetLatin1StringCharsAndLength := TJS_GetLatin1StringCharsAndLength(GetProcAddress(SM52Lib, 'SM_GetLatin1StringCharsAndLength')^); JS_GetTwoByteStringCharsAndLength := TJS_GetTwoByteStringCharsAndLength(GetProcAddress(SM52Lib, 'SM_GetTwoByteStringCharsAndLength')^); JS_Stringify := TJS_Stringify(GetProcAddress(SM52Lib, 'SM_Stringify')^); JS_ParseJSON := TJS_ParseJSON(GetProcAddress(SM52Lib, 'SM_ParseJSON')^); JS_ReportOutOfMemory := TJS_ReportOutOfMemory(GetProcAddress(SM52Lib, 'SM_ReportOutOfMemory')^); JS_GetWarningReporter := TJS_GetWarningReporter(GetProcAddress(SM52Lib, 'SM_GetWarningReporter')^); JS_SetWarningReporter := TJS_SetWarningReporter(GetProcAddress(SM52Lib, 'SM_SetWarningReporter')^); JS_NewDateObject := TJS_NewDateObject(GetProcAddress(SM52Lib, 'SM_NewDateObject')^); JS_ObjectIsDate := TJS_ObjectIsDate(GetProcAddress(SM52Lib, 'SM_ObjectIsDate')^); JS_IsExceptionPending := TJS_IsExceptionPending(GetProcAddress(SM52Lib, 'SM_IsExceptionPending')^); JS_GetPendingException := TJS_GetPendingException(GetProcAddress(SM52Lib, 'SM_GetPendingException')^); JS_SetPendingException := TJS_SetPendingException(GetProcAddress(SM52Lib, 'SM_SetPendingException')^); JS_ClearPendingException := TJS_ClearPendingException(GetProcAddress(SM52Lib, 'SM_ClearPendingException')^); JS_ErrorFromException := TJS_ErrorFromException(GetProcAddress(SM52Lib, 'SM_ErrorFromException')^); JS_EvaluateScript := TJS_EvaluateScript(GetProcAddress(SM52Lib, 'SM_EvaluateScript')^); JS_EvaluateUCScript := TJS_EvaluateUCScript(GetProcAddress(SM52Lib, 'SM_EvaluateUCScript')^); JS_ComputeThis := TJS_ComputeThis(GetProcAddress(SM52Lib, 'SM_ComputeThis')^); JS_NewInt8Array := TJS_NewInt8Array(GetProcAddress(SM52Lib, 'SM_NewInt8Array')^); JS_NewUint8Array := TJS_NewUint8Array(GetProcAddress(SM52Lib, 'SM_NewUint8Array')^); JS_NewUint8ClampedArray := TJS_NewUint8ClampedArray(GetProcAddress(SM52Lib, 'SM_NewUint8ClampedArray')^); JS_NewInt16Array := TJS_NewInt16Array(GetProcAddress(SM52Lib, 'SM_NewInt16Array')^); JS_NewUint16Array := TJS_NewUint16Array(GetProcAddress(SM52Lib, 'SM_NewUint16Array')^); JS_NewInt32Array := TJS_NewInt32Array(GetProcAddress(SM52Lib, 'SM_NewInt32Array')^); JS_NewUint32Array := TJS_NewUint32Array(GetProcAddress(SM52Lib, 'SM_NewUint32Array')^); JS_NewFloat32Array := TJS_NewFloat32Array(GetProcAddress(SM52Lib, 'SM_NewFloat32Array')^); JS_NewFloat64Array := TJS_NewFloat64Array(GetProcAddress(SM52Lib, 'SM_NewFloat64Array')^); JS_NewInt8ArrayFromArray := TJS_NewInt8ArrayFromArray(GetProcAddress(SM52Lib, 'SM_NewInt8ArrayFromArray')^); JS_NewUint8ArrayFromArray := TJS_NewUint8ArrayFromArray(GetProcAddress(SM52Lib, 'SM_NewUint8ArrayFromArray')^); JS_NewUint8ClampedArrayFromArray := TJS_NewUint8ClampedArrayFromArray(GetProcAddress(SM52Lib, 'SM_NewUint8ClampedArrayFromArray')^); JS_NewInt16ArrayFromArray := TJS_NewInt16ArrayFromArray(GetProcAddress(SM52Lib, 'SM_NewInt16ArrayFromArray')^); JS_NewUint16ArrayFromArray := TJS_NewUint16ArrayFromArray(GetProcAddress(SM52Lib, 'SM_NewUint16ArrayFromArray')^); JS_NewInt32ArrayFromArray := TJS_NewInt32ArrayFromArray(GetProcAddress(SM52Lib, 'SM_NewInt32ArrayFromArray')^); JS_NewUint32ArrayFromArray := TJS_NewUint32ArrayFromArray(GetProcAddress(SM52Lib, 'SM_NewUint32ArrayFromArray')^); JS_NewFloat32ArrayFromArray := TJS_NewFloat32ArrayFromArray(GetProcAddress(SM52Lib, 'SM_NewFloat32ArrayFromArray')^); JS_NewFloat64ArrayFromArray := TJS_NewFloat64ArrayFromArray(GetProcAddress(SM52Lib, 'SM_NewFloat64ArrayFromArray')^); JS_NewInt8ArrayWithBuffer := TJS_NewInt8ArrayWithBuffer(GetProcAddress(SM52Lib, 'SM_NewInt8ArrayWithBuffer')^); JS_NewUint8ArrayWithBuffer := TJS_NewUint8ArrayWithBuffer(GetProcAddress(SM52Lib, 'SM_NewUint8ArrayWithBuffer')^); JS_NewUint8ClampedArrayWithBuffer := TJS_NewUint8ClampedArrayWithBuffer(GetProcAddress(SM52Lib, 'SM_NewUint8ClampedArrayWithBuffer')^); JS_NewInt16ArrayWithBuffer := TJS_NewInt16ArrayWithBuffer(GetProcAddress(SM52Lib, 'SM_NewInt16ArrayWithBuffer')^); JS_NewUint16ArrayWithBuffer := TJS_NewUint16ArrayWithBuffer(GetProcAddress(SM52Lib, 'SM_NewUint16ArrayWithBuffer')^); JS_NewInt32ArrayWithBuffer := TJS_NewInt32ArrayWithBuffer(GetProcAddress(SM52Lib, 'SM_NewInt32ArrayWithBuffer')^); JS_NewUint32ArrayWithBuffer := TJS_NewUint32ArrayWithBuffer(GetProcAddress(SM52Lib, 'SM_NewUint32ArrayWithBuffer')^); JS_NewFloat32ArrayWithBuffer := TJS_NewFloat32ArrayWithBuffer(GetProcAddress(SM52Lib, 'SM_NewFloat32ArrayWithBuffer')^); JS_NewFloat64ArrayWithBuffer := TJS_NewFloat64ArrayWithBuffer(GetProcAddress(SM52Lib, 'SM_NewFloat64ArrayWithBuffer')^); JS_NewSharedArrayBuffer := TJS_NewSharedArrayBuffer(GetProcAddress(SM52Lib, 'SM_NewSharedArrayBuffer')^); JS_NewArrayBuffer := TJS_NewArrayBuffer(GetProcAddress(SM52Lib, 'SM_NewArrayBuffer')^); JS_IsTypedArrayObject := TJS_IsTypedArrayObject(GetProcAddress(SM52Lib, 'SM_IsTypedArrayObject')^); JS_IsArrayBufferViewObject := TJS_IsArrayBufferViewObject(GetProcAddress(SM52Lib, 'SM_IsArrayBufferViewObject')^); JS_IsInt8Array := TJS_IsInt8Array(GetProcAddress(SM52Lib, 'SM_IsInt8Array')^); JS_IsUint8Array := TJS_IsUint8Array(GetProcAddress(SM52Lib, 'SM_IsUint8Array')^); JS_IsUint8ClampedArray := TJS_IsUint8ClampedArray(GetProcAddress(SM52Lib, 'SM_IsUint8ClampedArray')^); JS_IsInt16Array := TJS_IsInt16Array(GetProcAddress(SM52Lib, 'SM_IsInt16Array')^); JS_IsUint16Array := TJS_IsUint16Array(GetProcAddress(SM52Lib, 'SM_IsUint16Array')^); JS_IsInt32Array := TJS_IsInt32Array(GetProcAddress(SM52Lib, 'SM_IsInt32Array')^); JS_IsUint32Array := TJS_IsUint32Array(GetProcAddress(SM52Lib, 'SM_IsUint32Array')^); JS_IsFloat32Array := TJS_IsFloat32Array(GetProcAddress(SM52Lib, 'SM_IsFloat32Array')^); JS_IsFloat64Array := TJS_IsFloat64Array(GetProcAddress(SM52Lib, 'SM_IsFloat64Array')^); JS_GetTypedArraySharedness := TJS_GetTypedArraySharedness(GetProcAddress(SM52Lib, 'SM_GetTypedArraySharedness')^); JS_GetObjectAsInt8Array := TJS_GetObjectAsInt8Array(GetProcAddress(SM52Lib, 'SM_GetObjectAsInt8Array')^); JS_GetObjectAsUint8Array := TJS_GetObjectAsUint8Array(GetProcAddress(SM52Lib, 'SM_GetObjectAsUint8Array')^); JS_GetObjectAsUint8ClampedArray := TJS_GetObjectAsUint8ClampedArray(GetProcAddress(SM52Lib, 'SM_GetObjectAsUint8ClampedArray')^); JS_GetObjectAsInt16Array := TJS_GetObjectAsInt16Array(GetProcAddress(SM52Lib, 'SM_GetObjectAsInt16Array')^); JS_GetObjectAsUint16Array := TJS_GetObjectAsUint16Array(GetProcAddress(SM52Lib, 'SM_GetObjectAsUint16Array')^); JS_GetObjectAsInt32Array := TJS_GetObjectAsInt32Array(GetProcAddress(SM52Lib, 'SM_GetObjectAsInt32Array')^); JS_GetObjectAsUint32Array := TJS_GetObjectAsUint32Array(GetProcAddress(SM52Lib, 'SM_GetObjectAsUint32Array')^); JS_GetObjectAsFloat32Array := TJS_GetObjectAsFloat32Array(GetProcAddress(SM52Lib, 'SM_GetObjectAsFloat32Array')^); JS_GetObjectAsFloat64Array := TJS_GetObjectAsFloat64Array(GetProcAddress(SM52Lib, 'SM_GetObjectAsFloat64Array')^); JS_GetObjectAsArrayBufferView := TJS_GetObjectAsArrayBufferView(GetProcAddress(SM52Lib, 'SM_GetObjectAsArrayBufferView')^); JS_GetObjectAsArrayBuffer := TJS_GetObjectAsArrayBuffer(GetProcAddress(SM52Lib, 'SM_GetObjectAsArrayBuffer')^); JS_GetArrayBufferViewType := TJS_GetArrayBufferViewType(GetProcAddress(SM52Lib, 'SM_GetArrayBufferViewType')^); JS_IsArrayBufferObject := TJS_IsArrayBufferObject(GetProcAddress(SM52Lib, 'SM_IsArrayBufferObject')^); JS_IsSharedArrayBufferObject := TJS_IsSharedArrayBufferObject(GetProcAddress(SM52Lib, 'SM_IsSharedArrayBufferObject')^); JS_GetArrayBufferByteLength := TJS_GetArrayBufferByteLength(GetProcAddress(SM52Lib, 'SM_GetArrayBufferByteLength')^); JS_GetSharedArrayBufferByteLength := TJS_GetSharedArrayBufferByteLength(GetProcAddress(SM52Lib, 'SM_GetSharedArrayBufferByteLength')^); JS_ArrayBufferHasData := TJS_ArrayBufferHasData(GetProcAddress(SM52Lib, 'SM_ArrayBufferHasData')^); JS_GetArrayBufferData := TJS_GetArrayBufferData(GetProcAddress(SM52Lib, 'SM_GetArrayBufferData')^); JS_IsMappedArrayBufferObject := TJS_IsMappedArrayBufferObject(GetProcAddress(SM52Lib, 'SM_IsMappedArrayBufferObject')^); JS_GetTypedArrayLength := TJS_GetTypedArrayLength(GetProcAddress(SM52Lib, 'SM_GetTypedArrayLength')^); JS_GetTypedArrayByteOffset := TJS_GetTypedArrayByteOffset(GetProcAddress(SM52Lib, 'SM_GetTypedArrayByteOffset')^); JS_GetTypedArrayByteLength := TJS_GetTypedArrayByteLength(GetProcAddress(SM52Lib, 'SM_GetTypedArrayByteLength')^); JS_GetArrayBufferViewByteLength := TJS_GetArrayBufferViewByteLength(GetProcAddress(SM52Lib, 'SM_GetArrayBufferViewByteLength')^); JS_GetInt8ArrayData := TJS_GetInt8ArrayData(GetProcAddress(SM52Lib, 'SM_GetInt8ArrayData')^); JS_GetUint8ArrayData := TJS_GetUint8ArrayData(GetProcAddress(SM52Lib, 'SM_GetUint8ArrayData')^); JS_GetUint8ClampedArrayData := TJS_GetUint8ClampedArrayData(GetProcAddress(SM52Lib, 'SM_GetUint8ClampedArrayData')^); JS_GetInt16ArrayData := TJS_GetInt16ArrayData(GetProcAddress(SM52Lib, 'SM_GetInt16ArrayData')^); JS_GetUint16ArrayData := TJS_GetUint16ArrayData(GetProcAddress(SM52Lib, 'SM_GetUint16ArrayData')^); JS_GetInt32ArrayData := TJS_GetInt32ArrayData(GetProcAddress(SM52Lib, 'SM_GetInt32ArrayData')^); JS_GetUint32ArrayData := TJS_GetUint32ArrayData(GetProcAddress(SM52Lib, 'SM_GetUint32ArrayData')^); JS_GetFloat32ArrayData := TJS_GetFloat32ArrayData(GetProcAddress(SM52Lib, 'SM_GetFloat32ArrayData')^); JS_GetFloat64ArrayData := TJS_GetFloat64ArrayData(GetProcAddress(SM52Lib, 'SM_GetFloat64ArrayData')^); JS_GetArrayBufferViewData := TJS_GetArrayBufferViewData(GetProcAddress(SM52Lib, 'SM_GetArrayBufferViewData')^); JS_GetArrayBufferViewBuffer := TJS_GetArrayBufferViewBuffer(GetProcAddress(SM52Lib, 'SM_GetArrayBufferViewBuffer')^); JS_SetModuleResolveHook := TJS_SetModuleResolveHook(GetProcAddress(SM52Lib, 'SM_SetModuleResolveHook')^); end; end; procedure UnloadSM52; begin if SM52Lib <> INVALID_MODULEHANDLE_VALUE then FreeLibrary(SM52Lib); SM52Lib := INVALID_MODULEHANDLE_VALUE; end; initialization Latin1AnsiConvert := TSynAnsiConvert.Engine(CODEPAGE_LATIN1); LoadSM52; finalization UnloadSM52; end.