5682 lines
221 KiB
ObjectPascal
5682 lines
221 KiB
ObjectPascal
/// 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) 2022 Arnaud Bouchez
|
|
Synopse Informatique - http://synopse.info
|
|
|
|
SyNode for mORMot Copyright (C) 2022 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) 2022
|
|
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,
|
|
{$IFNDEF SM52}
|
|
// We decommit memory lazily. If more than this number of megabytes is
|
|
// available to be decommitted, then JS_MaybeGC will trigger a shrinking GC
|
|
// to decommit it.
|
|
JSGC_DECOMMIT_THRESHOLD = 20,
|
|
{$ENDIF}
|
|
// 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
|
|
{$IFDEF SM52}
|
|
// If true, painting can trigger IGC slices.
|
|
,JSGC_REFRESH_FRAME_SLICES_ENABLED = 24
|
|
{$ENDIF}
|
|
);
|
|
|
|
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 = (
|
|
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,
|
|
/// Run-time version enumeration corresponding to default version
|
|
JSVERSION_DEFAULT = 0,
|
|
/// Run-time version enumeration corresponding to an identified version
|
|
JSVERSION_UNKNOWN = -1
|
|
);
|
|
|
|
/// 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.
|
|
{$IFDEF SM52}
|
|
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
|
|
);
|
|
{$ELSE}
|
|
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_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_LIMIT
|
|
);
|
|
{$ENDIF}
|
|
{$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,
|
|
{$IFDEF SM52}
|
|
JSVAL_TYPE_PRIVATE_GCTHING = $07,
|
|
JSVAL_TYPE_NULL = $08,
|
|
JSVAL_TYPE_OBJECT = $0C,
|
|
{$ELSE}
|
|
JSVAL_TYPE_NULL = $07,
|
|
JSVAL_TYPE_OBJECT = $08,
|
|
{$ENDIF}
|
|
// 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,
|
|
{$IFDEF SM52}
|
|
JSEXN_DEBUGGEEWOULDRUN,
|
|
JSEXN_WASMCOMPILEERROR,
|
|
JSEXN_WASMRUNTIMEERROR,
|
|
JSEXN_WARN,
|
|
{$ENDIF}
|
|
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
|
|
{$IFDEF SM52}
|
|
JSFreeOp = pointer;
|
|
PJSContextOptions = ^JSContextOptions;
|
|
{$ELSE}
|
|
PJSRuntime = ^JSRuntime;
|
|
PJSRuntimeOptions = ^JSRuntimeOptions;
|
|
{$ENDIF}
|
|
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;
|
|
/// internal Spidermonkey structure for storrage jsid
|
|
{$ifdef USERECORDWITHMETHODS}JSIdArray = record
|
|
{$else}JSIdArray = object{$endif}
|
|
private
|
|
_internal: _JSIdArray;
|
|
procedure init(cx: PJSContext); {$ifdef HASINLINE}inline;{$endif}
|
|
public
|
|
property Length: size_t read _internal.mLength;
|
|
property vector: PjsidVector read _internal.mBegin;
|
|
end;
|
|
|
|
// 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;
|
|
function getIsNull: Boolean;
|
|
|
|
function getIsInteger: Boolean;
|
|
function getAsInteger: Integer;
|
|
procedure setAsInteger(const Value: Integer);
|
|
|
|
function getAsInt64: Int64;
|
|
procedure setAsInt64(const Value: Int64);
|
|
|
|
function getIsDouble: Boolean;
|
|
function getAsDouble: Double;
|
|
procedure setAsDouble(const Value: Double);
|
|
|
|
function getIsNumber: Boolean;
|
|
|
|
function getIsBoolean: Boolean;
|
|
function getAsBoolean: Boolean;
|
|
procedure setAsBoolean(const Value: Boolean);
|
|
|
|
function getIsObject: Boolean;
|
|
function getAsObject: PJSObject;
|
|
procedure setAsObject(const Value: PJSObject);
|
|
|
|
function getIsString: Boolean;
|
|
function getJSString: PJSString;
|
|
procedure setJSString(const Value: PJSString);
|
|
|
|
function getIsSimpleVariant(cx: PJSContext): Boolean;
|
|
function getSimpleVariant(cx: PJSContext): Variant;
|
|
procedure setSimpleVariant(cx: PJSContext; const Value: Variant);
|
|
|
|
function getPrivate: Pointer;
|
|
procedure setPrivate(const Value: Pointer);
|
|
|
|
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;
|
|
function IsMagic: Boolean;
|
|
|
|
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;
|
|
|
|
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 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
|
|
{$IFDEF SM52}
|
|
JSWarningReporter = procedure(cx: PJSContext; report: PJSErrorReport); cdecl;
|
|
{$ELSE}
|
|
JSErrorReporter = procedure(cx: PJSContext; _message: PCChar; report: PJSErrorReport); cdecl;
|
|
{$ENDIF}
|
|
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;
|
|
{$IFDEF SM52}
|
|
JSFinalizeOp = procedure(var fop: JSFreeOp; obj: PJSObject); cdecl;
|
|
{$ELSE}
|
|
JSFinalizeOp = procedure(var rt: PJSRuntime; obj: PJSObject); cdecl;
|
|
{$ENDIF}
|
|
// 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;
|
|
|
|
{$IFNDEF SM52}
|
|
/// JavaScript execution runtime
|
|
// - this object does not store anything, but just provide some helper methods
|
|
JSRuntime = object
|
|
private
|
|
function GetPrivate: Pointer;
|
|
procedure SetPrivate(const Value: Pointer);
|
|
function GetOptions: PJSRuntimeOptions;
|
|
function GetGCParameter(key: JSGCParamKey): uint32;
|
|
procedure SetGCParameter(key: JSGCParamKey; const Value: uint32);
|
|
function GetErrorReporter: JSErrorReporter;
|
|
procedure SetErrorReporter(er: JSErrorReporter);
|
|
function GetInterruptCallback: JSInterruptCallback;
|
|
procedure SetInterruptCallback(callback: JSInterruptCallback);
|
|
function GetEmptyString: PJSString; {$ifdef HASINLINE}inline;{$endif}
|
|
function GetNowMs: int64; {$ifdef HASINLINE}inline;{$endif}
|
|
|
|
public
|
|
/// Initializes the JavaScript runtime.
|
|
class function New(maxbytes: uint32; maxNurseryBytes: uint32; parentRuntime: PJSRuntime): PJSRuntime;
|
|
/// Frees a JavaScript runtime.
|
|
procedure Destroy;
|
|
/// Wrote access a JSRuntime field for application-specific data.
|
|
// Memory management for this private data is the application's responsibility.
|
|
// The JavaScript engine itself never uses it.
|
|
procedure SetNativeStackQuota(systemCodeStackSize: size_t);
|
|
/// Performs garbage collection in the JS memory pool.
|
|
procedure GC;
|
|
/// Request a callback set using JS_SetInterruptCallback
|
|
procedure RequestInterruptCallback;
|
|
/// Create a new JSContext
|
|
function NewContext(stackChunkSize: size_t): PJSContext;
|
|
/// Read/write access a JSRuntime 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;
|
|
/// Get options of runtime
|
|
property Options: PJSRuntimeOptions read GetOptions;
|
|
/// 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);
|
|
/// Get/Set the error reporting mechanism for an application.
|
|
property ErrorReporter: JSErrorReporter read GetErrorReporter write SetErrorReporter;
|
|
/// Get/Set a callback function that is automatically called periodically while JavaScript code runs.
|
|
property InterruptCallback:JSInterruptCallback read GetInterruptCallback write SetInterruptCallback;
|
|
|
|
/// Microseconds since the epoch, midnight, January 1, 1970 UTC.
|
|
property NowMs: int64 read GetNowMs;
|
|
/// Returns the empty string as a JSString object.
|
|
property EmptyString: PJSString read GetEmptyString;
|
|
end;
|
|
|
|
/// Options of runtime
|
|
JSRuntimeOptions = 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 ThrowOnAsmJSValidationFailure: Boolean index 3 read getOptions write setOptions;
|
|
property NativeRegExp: Boolean index 4 read getOptions write setOptions;
|
|
property UnboxedArrays: Boolean index 5 read getOptions write setOptions;
|
|
property AsyncStack: Boolean index 6 read getOptions write setOptions;
|
|
property Werror: Boolean index 7 read getOptions write setOptions;
|
|
property StrictMode: Boolean index 8 read getOptions write setOptions;
|
|
property ExtraWarnings: Boolean index 9 read getOptions write setOptions;
|
|
end;
|
|
{$ENDIF}
|
|
{$IFDEF SM52}
|
|
/// 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;
|
|
{$ENDIF}
|
|
/// JavaScript execution context
|
|
// - this object does not store anything, but just provide some helper methods
|
|
JSContext = object
|
|
private
|
|
function GetPrivate: Pointer; {$ifdef HASINLINE}inline;{$endif}
|
|
procedure SetPrivate(const Value: Pointer);
|
|
{$IFDEF SM52}
|
|
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}
|
|
{$ELSE}
|
|
function GetRuntime: PJSRuntime; {$ifdef HASINLINE}inline;{$endif}
|
|
{$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
|
|
{$IFDEF SM52}
|
|
/// Initializes the JavaScript context.
|
|
class function CreateNew(maxbytes: uint32; maxNurseryBytes: uint32 = 16 * (1 SHL 20); parentContext: PJSContext = nil): PJSContext;
|
|
/// 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}
|
|
{$ELSE}
|
|
/// Runtime of this context
|
|
property rt: PJSRuntime read GetRuntime;
|
|
{$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;
|
|
/// Leave a the compartment, returning to the compartment active before the
|
|
// corresponding JS_EnterCompartment.
|
|
procedure LeaveCompartment(oldCompartment: PJSCompartment);
|
|
/// 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): 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;
|
|
/// Create a new object based on a specified class and root it
|
|
function NewObject(clasp: PJSClass): PJSObject;
|
|
/// 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;
|
|
|
|
/// 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);
|
|
|
|
/// 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);
|
|
|
|
/// 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);
|
|
|
|
/// create a new JavaScript string instance
|
|
function NewJSString(const Value: SynUnicode): PJSString; overload; {$ifdef HASINLINE}inline;{$endif}
|
|
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}
|
|
|
|
/// 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; //~~~ 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;
|
|
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): JSIdArray;
|
|
|
|
//array methods
|
|
function GetArrayLength(cx: PJSContext; var 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; var 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 = return ''
|
|
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;
|
|
{$IFDEF SM52}
|
|
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;
|
|
{$ENDIF}
|
|
JSClass = record
|
|
name: PCChar;
|
|
flags: uint32;
|
|
{$IFDEF SM52}
|
|
cOps: PJSClassOps;
|
|
reserved: array [0..2] of pointer;
|
|
{$ELSE}
|
|
addProperty: JSAddPropertyOp;
|
|
delProperty: JSDeletePropertyOp;
|
|
getProperty: JSGetterOp;
|
|
setProperty: JSSetterOp;
|
|
enumerate: JSEnumerateOp;
|
|
resolve: JSResolveOp;
|
|
mayResolve: JSMayResolveOp;
|
|
finalize: JSFinalizeOp;
|
|
call: JSNative;
|
|
hasInstance: JSHasInstanceOp;
|
|
construct: JSNative;
|
|
trace: JSTraceOp;
|
|
reserved: array [0..22] of pointer;
|
|
{$ENDIF}
|
|
end;
|
|
|
|
JSCompileOptions = record
|
|
reserved: array[0..1] of Pointer;
|
|
filename: PCChar;
|
|
reserved1: array[3..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
|
|
{$IFDEF SM52}
|
|
/// 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;
|
|
{$ELSE}
|
|
/// offending source line without final #13
|
|
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;
|
|
/// See the comment in ReadOnlyCompileOptions.
|
|
isMuted: Boolean;
|
|
/// error/warning, etc.
|
|
flags: uint32;
|
|
/// the error number, e.g. see js.msg
|
|
errorNumber: uint32;
|
|
/// the (default) error message
|
|
ucmessage: PCChar16;
|
|
/// arguments for the error message
|
|
messageArgs: PPCChar16;
|
|
/// One of the JSExnType constants
|
|
exnType: JSExnType;
|
|
{$ENDIF}
|
|
end;
|
|
|
|
/// used by JSErrorCallback() callback
|
|
JSErrorFormatString = record
|
|
{$IFDEF SM52}
|
|
/// The error message name in ASCII.
|
|
name: PCChar;
|
|
{$ENDIF}
|
|
/// 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));
|
|
// Bits 26 through 31 are reserved for the CACHED_PROTO_KEY mechanism, see
|
|
// below.
|
|
|
|
JSCLASS_GLOBAL_APPLICATION_SLOTS = 5;
|
|
|
|
// JSProto_LIMIT = 46;
|
|
{$IFDEF SM52}
|
|
JSCLASS_GLOBAL_SLOT_COUNT = (JSCLASS_GLOBAL_APPLICATION_SLOTS + ord(JSProto_LIMIT) * 2 + 39);
|
|
{$ELSE}
|
|
JSCLASS_GLOBAL_SLOT_COUNT = (JSCLASS_GLOBAL_APPLICATION_SLOTS + ord(JSProto_LIMIT) * 3 + 36);
|
|
{$ENDIF}
|
|
|
|
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
|
|
|
|
{$IFDEF SM52}
|
|
// unused
|
|
{$ELSE}
|
|
// Specify a generic native prototype methods, i.e., methods of a class
|
|
// prototype that are exposed as static methods taking an extra leading
|
|
// argument: the generic |this| parameter.
|
|
// If you set this flag in a JSFunctionSpec struct's flags initializer, then
|
|
// that struct must live at least as long as the native static method object
|
|
// created due to this flag by JS_DefineFunctions or JS_InitClass. Typically
|
|
// JSFunctionSpec structs are allocated in static arrays.
|
|
// JSFUN_GENERIC_NATIVE = $800;
|
|
|
|
JSFUN_GENERIC_NATIVE = $800;
|
|
{$ENDIF}
|
|
{$IFDEF SM52}
|
|
JSFUN_HAS_REST = $1000; // function has ...rest parameter.
|
|
{$ENDIF}
|
|
|
|
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
|
|
// ! vp.rval := JSVAL_VOID;
|
|
// ! JSError(cx, E);
|
|
// ! Result := False;
|
|
// ! end;
|
|
|
|
procedure JSError(cx: PJSContext; aException: Exception);
|
|
procedure JSErrorUC(cx: PJSContext; aMessage: WideString);
|
|
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
|
|
{$IFDEF SM52}
|
|
SpiderMonkeyLib = 'synmozjs52'{$IFDEF MSWINDOWS} + '.dll'{$ENDIF};
|
|
{$ELSE}
|
|
SpiderMonkeyLib = 'mozjs-45'{$IFDEF MSWINDOWS} + '.dll'{$ENDIF};
|
|
{$ENDIF}
|
|
|
|
/// 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.
|
|
function JS_Init: Boolean; cdecl; external SpiderMonkeyLib {$IFDEF SM52}name 'JS_Initialize'{$ENDIF};
|
|
/// 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.
|
|
procedure JS_ShutDown; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Microseconds since the epoch, midnight, January 1, 1970 UTC.
|
|
function JS_Now: int64; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Returns the empty string as a JSString object.
|
|
{$IFDEF SM52}
|
|
function JS_GetEmptyString(cx: PJSContext): PJSString; cdecl; external SpiderMonkeyLib;
|
|
{$ELSE}
|
|
function JS_GetEmptyString(rt: PJSRuntime): PJSString; cdecl; external SpiderMonkeyLib;
|
|
{$ENDIF}
|
|
|
|
/// Determines the JS data type of a JS value.
|
|
function JS_TypeOfValue(cx: PJSContext; var v: jsval): JSType; cdecl; external SpiderMonkeyLib;
|
|
|
|
{$IFNDEF SM52}
|
|
/// Initializes the JavaScript runtime.
|
|
function JS_NewRuntime(maxbytes: uint32; maxNurseryBytes: uint32; parentRuntime: PJSRuntime): PJSRuntime;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Frees a JavaScript runtime.
|
|
procedure JS_DestroyRuntime(runtime: PJSRuntime); cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Read access a JSRuntime field for application-specific data.
|
|
// Memory management for this private data is the application's responsibility.
|
|
// The JavaScript engine itself never uses it.
|
|
function JS_GetRuntimePrivate(rt: PJSRuntime): pointer; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Wrote access a JSRuntime field for application-specific data.
|
|
// Memory management for this private data is the application's responsibility.
|
|
// The JavaScript engine itself never uses it.
|
|
procedure JS_SetRuntimePrivate(rt: PJSRuntime; data: pointer); cdecl; external SpiderMonkeyLib;
|
|
{$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 JS_BeginRequest(cx: PJSContext); cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_EndRequest(cx: PJSContext); cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Create a new JSContext
|
|
{$IFDEF SM52}
|
|
function JS_NewContext(maxbytes: uint32; maxNurseryBytes: uint32 = 16 * (1 SHL 20); parentContext: PJSContext = nil): PJSContext;
|
|
cdecl; external SpiderMonkeyLib;
|
|
function InitSelfHostedCode(cx: PJSContext): boolean; cdecl; external SpiderMonkeyLib;
|
|
{$ELSE}
|
|
function JS_NewContext(rt: PJSRuntime; stackChunkSize: size_t): PJSContext;
|
|
cdecl; external SpiderMonkeyLib;
|
|
{$ENDIF}
|
|
/// Destroy a JSContext.
|
|
procedure JS_DestroyContext(cx: PJSContext); cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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.
|
|
function JS_GetContextPrivate(cx: PJSContext): Pointer; cdecl; external SpiderMonkeyLib;
|
|
/// 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.
|
|
procedure JS_SetContextPrivate(cx: PJSContext; data: Pointer); cdecl; external SpiderMonkeyLib;
|
|
|
|
{$IFNDEF SM52}
|
|
/// Retrieves a pointer to the JSRuntime with which a specified JSContext, cx, is associated
|
|
function JS_GetRuntime(cx: PJSContext): PJSRuntime; cdecl; external SpiderMonkeyLib;
|
|
{$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
|
|
function JS_WrapObject(cx: PJSContext; var obj: PJSObject): boolean; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_EnterCompartment(cx: PJSContext; target: PJSObject): PJSCompartment;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Leave a the compartment, returning to the compartment active before the
|
|
// corresponding JS_EnterCompartment.
|
|
procedure JS_LeaveCompartment(cx: PJSContext; oldCompartment: PJSCompartment);
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_InitStandardClasses(cx: PJSContext; var obj: PJSObject): boolean; cdecl; external SpiderMonkeyLib;
|
|
|
|
///Return the global object for the active function on the context.
|
|
function JS_CurrentGlobalOrNull(cx: PJSContext):PJSObject; cdecl; external SpiderMonkeyLib name 'CurrentGlobalOrNull';
|
|
|
|
/// Add 'Reflect.parse', a SpiderMonkey extension, to the Reflect object on the
|
|
// given global.
|
|
function JS_InitReflectParse(cx: PJSContext; var obj: PJSObject): boolean; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Initialize the 'ctypes' object on a global variable 'obj'. The 'ctypes'
|
|
// object will be sealed.
|
|
function JS_InitCTypesClass(cx: PJSContext; var obj: PJSObject): boolean; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Initialize the 'Debugger' object on a global variable 'obj'. The 'ctypes'
|
|
// object will be sealed.
|
|
function JS_DefineDebuggerObject(cx: PJSContext; var obj: PJSObject): boolean; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Performs garbage collection in the JS memory pool.
|
|
{$IFDEF SM52}
|
|
procedure JS_GC(cx: PJSContext); cdecl; external SpiderMonkeyLib;
|
|
{$ELSE}
|
|
procedure JS_GC(rt: PJSRuntime); cdecl; external SpiderMonkeyLib;
|
|
{$ENDIF}
|
|
|
|
/// Offer the JavaScript engine an opportunity to perform garbage collection if needed.
|
|
procedure JS_MaybeGC(cx: PJSContext); cdecl; external SpiderMonkeyLib;
|
|
|
|
///Set performance parameters related to garbage collection.
|
|
{$IFDEF SM52}
|
|
procedure JS_SetGCParameter(cx: PJSContext; key: JSGCParamKey; value: uint32);
|
|
cdecl; external SpiderMonkeyLib;
|
|
{$ELSE}
|
|
procedure JS_SetGCParameter(rt: PJSRuntime; key: JSGCParamKey; value: uint32);
|
|
cdecl; external SpiderMonkeyLib;
|
|
{$ENDIF}
|
|
|
|
///Get performance parameters related to garbage collection.
|
|
{$IFDEF SM52}
|
|
function JS_GetGCParameter(cx: PJSContext; key: JSGCParamKey): uint32;
|
|
cdecl; external SpiderMonkeyLib;
|
|
{$ELSE}
|
|
function JS_GetGCParameter(rt: PJSRuntime; key: JSGCParamKey): uint32;
|
|
cdecl; external SpiderMonkeyLib;
|
|
{$ENDIF}
|
|
|
|
///Adjust performance parameters related to garbage collection based on available memory(in megabytes).
|
|
{$IFDEF SM52}
|
|
procedure JS_SetGCParametersBasedOnAvailableMemory(cx: PJSContext; availMem: uint32);
|
|
cdecl; external SpiderMonkeyLib;
|
|
{$ELSE}
|
|
procedure JS_SetGCParametersBasedOnAvailableMemory(rt: PJSRuntime; availMem: uint32);
|
|
cdecl; external SpiderMonkeyLib;
|
|
{$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.
|
|
function JS_NewExternalString(cx: PJSContext; chars: PCChar16; length: size_t;
|
|
fin: PJSStringFinalizer): PJSString; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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.
|
|
{$IFDEF SM52}
|
|
procedure JS_SetNativeStackQuota(cx: PJSContext; systemCodeStackSize: size_t;
|
|
trustedScriptStackSize: size_t = 0; untrustedScriptStackSize: size_t = 0); cdecl; external SpiderMonkeyLib;
|
|
{$ELSE}
|
|
procedure JS_SetNativeStackQuota(runtime: PJSRuntime; systemCodeStackSize: size_t;
|
|
trustedScriptStackSize: size_t = 0; untrustedScriptStackSize: size_t = 0); cdecl; external SpiderMonkeyLib;
|
|
{$ENDIF}
|
|
|
|
/// Convert a JS::Value to type jsid.
|
|
function JS_ValueToId(cx: PJSContext; var v: jsval; out id: jsid): Boolean; cdecl; external SpiderMonkeyLib;
|
|
/// Convert a jsid to type JS::Value.
|
|
function JS_IdToValue(cx: PJSContext; id: jsid; out v: jsval): Boolean; cdecl; external SpiderMonkeyLib;
|
|
|
|
function JS_ValueToSource(cx: PJSContext; var v: jsval): PJSString; cdecl; external SpiderMonkeyLib;
|
|
|
|
|
|
/// Make a JSClass accessible to JavaScript code by creating its prototype,
|
|
// constructor, properties, and functions.
|
|
function JS_InitClass(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; external SpiderMonkeyLib ;
|
|
|
|
/// Retrieves the class associated with an object.
|
|
function JS_GetClass(obj: PJSObject): PJSClass; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// JSAPI method equivalent to the instanceof operator in JavaScript.
|
|
function JS_HasInstance(cx: PJSContext; var obj: PJSObject; var val: jsval; out res: Boolean): Boolean; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Access the private data field of an object.
|
|
function JS_GetPrivate(obj: PJSObject): Pointer; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Sets the private data field of an object.
|
|
procedure JS_SetPrivate(obj: PJSObject; data: Pointer); cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Retrieves the constructor for an object.
|
|
function JS_GetConstructor(cx: PJSContext; var proto: PJSObject): PJSObject; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Retrieve the private data associated with an object, if that object is an
|
|
// instance of a specified class.
|
|
function JS_GetInstancePrivate(cx: PJSContext; var obj: PJSObject; clasp: PJSClass; args: JSUnknown): Pointer;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Create a new JavaScript object for use as a global object.
|
|
function JS_NewGlobalObject(cx: PJSContext; clasp: PJSClass; principals: PJSPrincipals;
|
|
hookOption: OnNewGlobalHookOption; options: PJS_CompartmentOptions): PJSObject; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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.
|
|
procedure JS_GlobalObjectTraceHook(trc: Pointer{ JSTracer }; global: PJSObject); cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Create a new object based on a specified class
|
|
function JS_NewObject(cx: PJSContext; clasp: PJSClass): PJSObject; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_NewObjectWithGivenProto(cx: PJSContext; clasp: PJSClass; var proto: PJSObject): PJSObject; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Get the prototype of obj, storing it in result.
|
|
// - Implements: ES6 [[GetPrototypeOf]] internal method.
|
|
function JS_GetPrototype(cx: PJSContext; var obj: PJSObject; out result: PJSObject):Boolean; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_SetPrototype(cx: PJSContext; var obj: PJSObject; var proto: PJSObject):Boolean; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Create a new property on an object.
|
|
// Name indentifies by ID
|
|
function JS_DefinePropertyById(cx: PJSContext; var obj: PJSObject; var id: jsid;
|
|
var value: jsval; attrs: uint32; getter: JSNative; setter: JSNative): boolean;
|
|
cdecl; external SpiderMonkeyLib;
|
|
/// Create a new property on an object.
|
|
// Name indentifies by ansi string
|
|
function JS_DefineProperty(cx: PJSContext; var obj: PJSObject; const name: PCChar;
|
|
var value: jsval; attrs: uint32; getter: JSNative; setter: JSNative): boolean;
|
|
cdecl; external SpiderMonkeyLib;
|
|
/// Create a new property on an object.
|
|
// Name indentifies by unicode string
|
|
function JS_DefineUCProperty(cx: PJSContext; var obj: PJSObject; const name: PCChar16;
|
|
namelen: size_t; var value: jsval; attrs: uint32; getter: JSNative; setter: JSNative): Boolean;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Determine whether a JavaScript object has a specified property.
|
|
// Name indentifies by ansi string
|
|
function JS_HasProperty(cx: PJSContext; var obj: PJSObject;
|
|
const name: PCChar; var found: Boolean): Boolean;
|
|
cdecl; external SpiderMonkeyLib;
|
|
/// Determine whether a JavaScript object has a specified property.
|
|
// Name indentifies by unicode string
|
|
function JS_HasUCProperty(cx: PJSContext; var obj: PJSObject;
|
|
const name: PCChar16; namelen: size_t; var found: Boolean): Boolean;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Find a specified property and retrieve its value.
|
|
// Name indentifies by ID
|
|
function JS_GetPropertyById(cx: PJSContext; var obj: PJSObject; var id: jsid;
|
|
out vp: jsval): boolean; cdecl; external SpiderMonkeyLib;
|
|
/// Find a specified property and retrieve its value.
|
|
// Name indentifies by ansi string
|
|
function JS_GetProperty(cx: PJSContext; var obj: PJSObject; const name: PCChar;
|
|
out vp: jsval): boolean; cdecl; external SpiderMonkeyLib;
|
|
/// Find a specified property and retrieve its value.
|
|
// Name indentifies by unicode string
|
|
function JS_GetUCProperty(cx: PJSContext; var obj: PJSObject; const name: PCChar16; namelen: size_t;
|
|
out vp: jsval): boolean; cdecl; external SpiderMonkeyLib;
|
|
/// Find a specified numeric property of an object and return its current value.
|
|
function JS_GetElement(cx: PJSContext; var obj: PJSObject; index: uint32;
|
|
out vp: jsval): Boolean; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Assign a value to a property of an object.
|
|
// Name indentifies by ansi string
|
|
function JS_SetProperty(cx: PJSContext; var obj: PJSObject; const name: PCChar;
|
|
var vp: jsval): Boolean; cdecl; external SpiderMonkeyLib;
|
|
/// Assign a value to a property of an object.
|
|
// Name indentifies by unicode string
|
|
function JS_SetUCProperty(cx: PJSContext; var obj: PJSObject; const name: PCChar16; namelen: size_t;
|
|
var vp: jsval): boolean; cdecl; external SpiderMonkeyLib;
|
|
/// Assign a value to a numeric property of an object.
|
|
function JS_SetElement(cx: PJSContext; var obj: PJSObject; index: uint32;
|
|
var vp: jsval): Boolean; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Removes a specified property from an object.
|
|
// Name indentifies by ID
|
|
function JS_DeletePropertyById(cx: PJSContext; var obj: PJSObject; var id: jsid; out res: JS_ObjectOpResult): Boolean;
|
|
cdecl; external SpiderMonkeyLib;
|
|
/// Removes a specified element or numeric property from an object.
|
|
function JS_DeleteElement(cx: PJSContext; var obj: PJSObject; index: uint32; out res: JS_ObjectOpResult): Boolean;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 by JS_Enumerate must be rooted to protect its
|
|
// contents from garbage collection. Use JS::AutoIdArray.
|
|
function JS_Enumerate(cx: PJSContext; var obj: PJSObject; out props: JSIdArray): Boolean;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
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)`.
|
|
function JS_CallFunctionValue(cx: PJSContext; var obj: PJSObject; var val: jsval;
|
|
var args: JSHandleValueArray; out rval: jsval): Boolean; cdecl; external SpiderMonkeyLib;
|
|
/// Calls a specified JS function.
|
|
// Function identifies by PJSFunction
|
|
function JS_CallFunction(cx: PJSContext; var obj: PJSObject; var fun: PJSFunction;
|
|
var args: JSHandleValueArray; out rval: jsval): Boolean; cdecl; external SpiderMonkeyLib;
|
|
/// Calls a specified JS function.
|
|
// Function identifies by ansi string
|
|
// - Perform the method call `rval = obj[name](args)`.
|
|
function JS_CallFunctionName(cx: PJSContext; var obj: PJSObject; const name: PCChar;
|
|
var args: JSHandleValueArray; out rval: jsval): Boolean; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Invoke a constructor, like the JS expression `new ctor(...args)`. Returns
|
|
// the new object, or null on error.
|
|
function JS_New(cx: PJSContext; var ctor: PJSObject; var args: JSHandleValueArray): PJSObject; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Define multiple properties for a single object.
|
|
function JS_DefineProperties(cx: PJSContext; var obj: PJSObject; ps: PJSPropertySpec): boolean; cdecl; external SpiderMonkeyLib ;
|
|
|
|
/// Determine whether a property is already physically present on a JSObject.
|
|
// Name indentifies by unicode string
|
|
function JS_AlreadyHasOwnUCProperty(cx: PJSContext; var obj: PJSObject;
|
|
const name: PCChar16; namelen: size_t; var foundp: Boolean): Boolean;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Create a new Array object.
|
|
// Only length passed
|
|
function JS_NewArrayObject(cx: PJSContext; length: size_t): PJSObject; cdecl; external SpiderMonkeyLib;
|
|
/// Create a new Array object.
|
|
// Content passed
|
|
function JS_NewArrayObject2(cx: PJSContext; const contents: JSHandleValueArray): PJSObject; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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.
|
|
function JS_IsArrayObject(cx: PJSContext; var obj: PJSObject; out isArray: Boolean): boolean; cdecl; external SpiderMonkeyLib;
|
|
/// 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.
|
|
function JS_GetArrayLength(cx: PJSContext; var obj: PJSObject;
|
|
out length: uint32): Boolean; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Read access an object's reserved slots.
|
|
{$IFDEF SM52}
|
|
function JS_GetReservedSlot(obj: PJSObject; index: uint32): Int64; cdecl; external SpiderMonkeyLib name 'JS_GetReservedSlot1';
|
|
{$ELSE}
|
|
function JS_GetReservedSlot(obj: PJSObject; index: uint32): Int64; cdecl; external SpiderMonkeyLib;
|
|
{$ENDIF}
|
|
/// Write access an object's reserved slots
|
|
{$IFDEF SM52}
|
|
procedure JS_SetReservedSlot(obj: PJSObject; index: uint32; var v: jsval); cdecl; external SpiderMonkeyLib;
|
|
{$ELSE}
|
|
procedure JS_SetReservedSlot(obj: PJSObject; index: uint32; v: Int64); cdecl; external SpiderMonkeyLib;
|
|
{$ENDIF}
|
|
|
|
/// Create a new JavaScript function that is implemented as a JSNative.
|
|
function JS_NewFunction(cx: PJSContext; call: JSNative; nargs: uintN; flags: uintN; name: PCChar): PJSObject; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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.
|
|
function JS_GetFunctionId(fun: PJSFunction): PJSString; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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).
|
|
function JS_ObjectIsFunction(cx: PJSContext; obj: PJSObject): boolean; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Create zero or more functions and makes them properties (methods)
|
|
// of a specified object, obj, as if by calling JS_DefineFunction repeatedly
|
|
function JS_DefineFunctions(cx: PJSContext; var obj: PJSObject; fs: PJSFunctionSpec;
|
|
behavior: JSPropertyDefinitionBehavior): Boolean;
|
|
cdecl; external SpiderMonkeyLib;
|
|
/// Create a native function and assign it as a property to a specified JS object
|
|
function JS_DefineFunction(cx: PJSContext; var obj: PJSObject; name: PCChar;
|
|
call: JSNative; nargs: uintN; attrs: uintN): PJSFunction;
|
|
cdecl; external SpiderMonkeyLib;
|
|
/// Unicode version to create a native function
|
|
function JS_DefineUCFunction(cx: PJSContext; var obj: PJSObject; name: PCChar16;
|
|
namelen: size_t; call: JSNative; nargs: uintN; attrs: uintN): PJSFunction;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Compile a script, source, for execution.
|
|
// Ansi version
|
|
function JS_CompileScript(cx: PJSContext; bytes: PCChar;
|
|
length: size_t; options: PJSCompileOptions; out script: PJSScript): boolean;
|
|
cdecl; external SpiderMonkeyLib;
|
|
/// Compile a script, source, for execution.
|
|
// Unicode version
|
|
function JS_CompileUCScript(cx: PJSContext;
|
|
chars: PCChar16; length: size_t; options: PJSCompileOptions; out script: PJSScript): boolean;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Generate the complete source code of a function declaration from a compiled function
|
|
function JS_DecompileFunction(cx: PJSContext; var fun: PJSFunction; indent: uintN): PJSString;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Evaluate a script in the scope of the current global of cx.
|
|
function JS_ExecuteScript(cx: PJSContext; var script: PJSScript;
|
|
out rval: jsval): Boolean; cdecl; external SpiderMonkeyLib;
|
|
|
|
{$IFDEF SM52}
|
|
/// 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.
|
|
function JS_CheckForInterrupt(cx: PJSContext): Boolean; cdecl; external SpiderMonkeyLib;
|
|
function JS_AddInterruptCallback(cx: PJSContext; callback: JSInterruptCallback):
|
|
Boolean; cdecl; external SpiderMonkeyLib;
|
|
function JS_DisableInterruptCallback(cx: PJSContext):Boolean; cdecl; external SpiderMonkeyLib;
|
|
procedure JS_ResetInterruptCallback(cx: PJSContext; enable: Boolean); cdecl; external SpiderMonkeyLib;
|
|
/// Request a callback set using JS_SetInterruptCallback
|
|
procedure JS_RequestInterruptCallback(cx: PJSContext); cdecl; external SpiderMonkeyLib;
|
|
{$ELSE}
|
|
/// Set a callback function that is automatically called periodically while JavaScript code runs.
|
|
function JS_SetInterruptCallback(rt: PJSRuntime; callback: JSInterruptCallback):
|
|
JSInterruptCallback; cdecl; external SpiderMonkeyLib;
|
|
/// Return the currently installed interrupt callback, or NULL if none is currently installed
|
|
function JS_GetInterruptCallback(rt: PJSRuntime): JSInterruptCallback;
|
|
cdecl; external SpiderMonkeyLib;
|
|
/// Request a callback set using JS_SetInterruptCallback
|
|
procedure JS_RequestInterruptCallback(rt: PJSRuntime); cdecl; external SpiderMonkeyLib;
|
|
{$ENDIF}
|
|
/// Indicates whether or not a script or function is currently executing in a given context.
|
|
function JS_IsRunning(cx: PJSContext): Boolean; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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
|
|
function JS_NewStringCopyN(cx: PJSContext; s: PCChar; n: size_t): PJSString; cdecl; external SpiderMonkeyLib;
|
|
/// 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
|
|
function JS_NewUCStringCopyN(cx: PJSContext; s: PCChar16; n: size_t): PJSString; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Return the length of a JavaScript string.
|
|
function JS_GetStringLength(str: PJSString): size_t; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Return true if the string's characters are stored as Latin1.
|
|
function JS_StringHasLatin1Chars(str: PJSString): boolean; cdecl; external SpiderMonkeyLib;
|
|
/// Return a pointer to the string, and store the length to *length
|
|
// Use it when characters are stored as Latin1.
|
|
function JS_GetLatin1StringCharsAndLength(cx: PJSContext; nogc: PJSAutoCheckCannotGC; str: PJSString; plength: psize_t):PCChar; cdecl; external SpiderMonkeyLib;
|
|
/// Return a pointer to the string, and store the length to *length
|
|
// Use it when characters are stored as Unicode
|
|
function JS_GetTwoByteStringCharsAndLength(cx: PJSContext; nogc: PJSAutoCheckCannotGC; str: PJSString; plength: psize_t):PCChar16; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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
|
|
function JS_Stringify(cx: PJSContext; var vp: jsval; var replacer: PJSObject;
|
|
var space: jsval; callback: JSONWriteCallback; data: pointer): Boolean;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// parse a string using the JSON syntax described in ECMAScript 5 and
|
|
// return the corresponding value into vp
|
|
function JS_ParseJSON(cx: PJSContext; const chars: PCChar16;
|
|
len: uint32; out vp: jsval): Boolean; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_ReportError(cx: PJSContext; const format: PCChar);
|
|
cdecl; varargs; external SpiderMonkeyLib{$IFDEF SM52} name 'JS_ReportErrorASCII'{$ENDIF};
|
|
/// 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 JS_ReportErrorNumberUC(cx: PJSContext; errorCallback: JSErrorCallback;
|
|
userRef: pointer; const erroNubmer: uintN); cdecl; varargs; external SpiderMonkeyLib;
|
|
/// 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 JS_ReportOutOfMemory(cx: PJSContext); cdecl; external SpiderMonkeyLib;
|
|
|
|
{$IFDEF SM52}
|
|
/// Get the warning reporting mechanism for an application. It is not working for errors.
|
|
function JS_GetWarningReporter(cx: PJSContext): JSWarningReporter;
|
|
cdecl; external SpiderMonkeyLib name 'GetWarningReporter';
|
|
/// Specify the warning reporting mechanism for an application. It is not working for errors.
|
|
function JS_SetWarningReporter(cx: PJSContext; reporter: JSWarningReporter): JSWarningReporter;
|
|
cdecl; external SpiderMonkeyLib name 'SetWarningReporter';
|
|
{$ELSE}
|
|
/// Get the error reporting mechanism for an application.
|
|
function JS_GetErrorReporter(rt: PJSRuntime): JSErrorReporter; cdecl; external SpiderMonkeyLib;
|
|
/// Specify the error reporting mechanism for an application.
|
|
function JS_SetErrorReporter(rt: PJSRuntime; er: JSErrorReporter): JSErrorReporter;
|
|
cdecl; external SpiderMonkeyLib;
|
|
{$ENDIF}
|
|
|
|
/// Create a new JavaScript date object
|
|
function JS_NewDateObject(cx: PJSContext; year, mon, mday, hour, min, sec: int32): PJSObject;
|
|
cdecl; external SpiderMonkeyLib;
|
|
/// Create a new JavaScript date object from the Unix millisecond elapsed since EPOC
|
|
function JS_NewDateObjectMsec(cx: PJSContext; msec: double): PJSObject;
|
|
cdecl; external SpiderMonkeyLib;
|
|
// 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.
|
|
function JS_ObjectIsDate(cx: PJSContext; var obj: PJSObject; out isDate: boolean): boolean; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Determine whether an exception is pending in the JS engine.
|
|
function JS_IsExceptionPending(cx: PJSContext): Boolean; cdecl; external SpiderMonkeyLib;
|
|
/// Get the current pending exception for a given JSContext.
|
|
function JS_GetPendingException(cx: PJSContext; out vp: jsval): Boolean; cdecl; external SpiderMonkeyLib;
|
|
/// Sets the current exception being thrown within a context.
|
|
procedure JS_SetPendingException(cx: PJSContext; var vp: jsval); cdecl; external SpiderMonkeyLib;
|
|
/// Clear the currently pending exception in a context.
|
|
procedure JS_ClearPendingException(cx: PJSContext); cdecl; external SpiderMonkeyLib;
|
|
{$IFDEF SM52}
|
|
/// 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.
|
|
function JS_ErrorFromException(cx: PJSContext; var obj: PJSObject): PJSErrorReport;
|
|
cdecl; external SpiderMonkeyLib;
|
|
{$ELSE}
|
|
/// Forward the current pending exception in a given JSContext
|
|
// to the current JSErrorReporter callback.
|
|
function JS_ReportPendingException(cx: PJSContext): Boolean; cdecl; external SpiderMonkeyLib;
|
|
{$ENDIF}
|
|
|
|
{$IFDEF SM52}
|
|
/// Get options of context
|
|
function JS_GetContextOptions(cx: PJSContext): PJSContextOptions; cdecl; external SpiderMonkeyLib;
|
|
{$ELSE}
|
|
/// Get options of runtime
|
|
function JS_GetRuntimeOptions(runtime: PJSRuntime): PJSRuntimeOptions; cdecl; external SpiderMonkeyLib;
|
|
{$ENDIF}
|
|
|
|
//function JS_NewRootedValue(cx: PJSContext; val: jsval): PJSRootedValue; cdecl; external SpiderMonkeyLib;
|
|
function JS_NewRootedValue(cx: PJSContext; val: Int64): PJSRootedValue; cdecl; external SpiderMonkeyLib;
|
|
procedure JS_FreeRootedValue(val: PJSRootedValue); cdecl; external SpiderMonkeyLib name 'JS_FreeRooteValue';
|
|
|
|
function JS_NewRootedObject(cx: PJSContext; obj: PJSObject): PJSRootedObject; cdecl; external SpiderMonkeyLib;
|
|
procedure JS_FreeRootedObject(obj: PJSRootedObject); cdecl; external SpiderMonkeyLib;
|
|
|
|
function JS_NewRootedString(cx: PJSContext; obj: PJSString): PJSRootedString; cdecl; external SpiderMonkeyLib;
|
|
procedure JS_FreeRootedString(str: PJSRootedString); cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Create Compile Options
|
|
function JS_NewCompileOptions(cx: PJSContext): PJSCompileOptions; cdecl; external SpiderMonkeyLib;
|
|
/// Free Compile Options
|
|
procedure JS_FreeCompileOptions(opt: PJSCompileOptions); cdecl; external SpiderMonkeyLib;
|
|
///////////////////
|
|
|
|
function JS_EvaluateScript(cx: PJSContext;
|
|
options: PJSCompileOptions;
|
|
bytes: PCChar; length: size_t;
|
|
out rval: jsval): Boolean; cdecl; external SpiderMonkeyLib;
|
|
|
|
function JS_EvaluateUCScript(cx: PJSContext;
|
|
options: PJSCompileOptions;
|
|
chars: PCChar16; length: size_t;
|
|
out rval: jsval): Boolean; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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;
|
|
function JS_ComputeThis(cx: PJSContext; var vp: jsval): Int64; cdecl; external SpiderMonkeyLib;
|
|
|
|
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
|
|
function JS_NewInt8Array(cx: PJSContext; nelements: uint32): PJSObject;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Create a new unsigned 8 bit integer (byte) typed array with nelements elements
|
|
// - will fill the newly created array with zeros
|
|
function JS_NewUint8Array(cx: PJSContext; nelements: uint32): PJSObject;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Create a new 8 bit integer typed array with nelements elements
|
|
// - will fill the newly created array with zeros
|
|
function JS_NewUint8ClampedArray(cx: PJSContext; nelements: uint32): PJSObject;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Create a new signed 16 bit integer typed array with nelements elements
|
|
// - will fill the newly created array with zeros
|
|
function JS_NewInt16Array(cx: PJSContext; nelements: uint32): PJSObject;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Create a new unsigned 16 bit integer typed array with nelements elements
|
|
// - will fill the newly created array with zeros
|
|
function JS_NewUint16Array(cx: PJSContext; nelements: uint32): PJSObject;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Create a new signed 32 bit integer typed array with nelements elements
|
|
// - will fill the newly created array with zeros
|
|
function JS_NewInt32Array(cx: PJSContext; nelements: uint32): PJSObject;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Create a new unsigned 32 bit integer typed array with nelements elements
|
|
// - will fill the newly created array with zeros
|
|
function JS_NewUint32Array(cx: PJSContext; nelements: uint32): PJSObject;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Create a new signed 32 bit float (single) typed array with nelements elements
|
|
// - will fill the newly created array with zeros
|
|
function JS_NewFloat32Array(cx: PJSContext; nelements: uint32): PJSObject;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Create a new signed 64 bit float (double) typed array with nelements elements
|
|
// - will fill the newly created array with zeros
|
|
function JS_NewFloat64Array(cx: PJSContext; nelements: uint32): PJSObject;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_NewInt8ArrayFromArray(cx: PJSContext; var arr: PJSObject): PJSObject;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_NewUint8ArrayFromArray(cx: PJSContext; var arr: PJSObject): PJSObject;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_NewUint8ClampedArrayFromArray(cx: PJSContext; var arr: PJSObject): PJSObject;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_NewInt16ArrayFromArray(cx: PJSContext; var arr: PJSObject): PJSObject;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_NewUint16ArrayFromArray(cx: PJSContext; var arr: PJSObject): PJSObject;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_NewInt32ArrayFromArray(cx: PJSContext; var arr: PJSObject): PJSObject;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_NewUint32ArrayFromArray(cx: PJSContext; var arr: PJSObject): PJSObject;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_NewFloat32ArrayFromArray(cx: PJSContext; var arr: PJSObject): PJSObject;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_NewFloat64ArrayFromArray(cx: PJSContext; var arr: PJSObject): PJSObject;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_NewInt8ArrayWithBuffer(cx: PJSContext; var arrayBuffer: PJSObject;
|
|
byteOffset: uint32; length: int32): PJSObject; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_NewUint8ArrayWithBuffer(cx: PJSContext; var arrayBuffer: PJSObject;
|
|
byteOffset: uint32; length: int32): PJSObject; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_NewUint8ClampedArrayWithBuffer(cx: PJSContext; var arrayBuffer: PJSObject;
|
|
byteOffset: uint32; length: int32): PJSObject; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_NewInt16ArrayWithBuffer(cx: PJSContext; var arrayBuffer: PJSObject;
|
|
byteOffset: uint32; length: int32): PJSObject; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_NewUint16ArrayWithBuffer(cx: PJSContext; var arrayBuffer: PJSObject;
|
|
byteOffset: uint32; length: int32): PJSObject; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_NewInt32ArrayWithBuffer(cx: PJSContext; var arrayBuffer: PJSObject;
|
|
byteOffset: uint32; length: int32): PJSObject; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_NewUint32ArrayWithBuffer(cx: PJSContext; var arrayBuffer: PJSObject;
|
|
byteOffset: uint32; length: int32): PJSObject; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_NewFloat32ArrayWithBuffer(cx: PJSContext; var arrayBuffer: PJSObject;
|
|
byteOffset: uint32; length: int32): PJSObject; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_NewFloat64ArrayWithBuffer(cx: PJSContext; var arrayBuffer: PJSObject;
|
|
byteOffset: uint32; length: int32): PJSObject; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Create a new SharedArrayBuffer with the given byte length.
|
|
function JS_NewSharedArrayBuffer(cx: PJSContext; nbytes: uint32): PJSObject;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Create a new ArrayBuffer with the given byte length.
|
|
function JS_NewArrayBuffer(cx: PJSContext; nbytes: uint32): PJSObject;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_IsTypedArrayObject(obj: PJSObject): Boolean; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_IsArrayBufferViewObject(obj: PJSObject): Boolean; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Test for specific 8 bit signed integer typed array types (ArrayBufferView subtypes)
|
|
function JS_IsInt8Array(obj: PJSObject): Boolean; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Test for specific 8 bit unsigned integer typed array types (ArrayBufferView subtypes)
|
|
function JS_IsUint8Array(obj: PJSObject): Boolean; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Test for specific 8 bit unsigned integer typed array types (ArrayBufferView subtypes)
|
|
function JS_IsUint8ClampedArray(obj: PJSObject): Boolean; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Test for specific 16 bit signed integer typed array types (ArrayBufferView subtypes)
|
|
function JS_IsInt16Array(obj: PJSObject): Boolean; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Test for specific 16 bit unsigned integer typed array types (ArrayBufferView subtypes)
|
|
function JS_IsUint16Array(obj: PJSObject): Boolean; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Test for specific 32 bit signed integer typed array types (ArrayBufferView subtypes)
|
|
function JS_IsInt32Array(obj: PJSObject): Boolean; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Test for specific 32 bit unsigned integer typed array types (ArrayBufferView subtypes)
|
|
function JS_IsUint32Array(obj: PJSObject): Boolean; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Test for specific 32 bit float (single) typed array types (ArrayBufferView subtypes)
|
|
function JS_IsFloat32Array(obj: PJSObject): Boolean; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// Test for specific 64 bit float (double) typed array types (ArrayBufferView subtypes)
|
|
function JS_IsFloat64Array(obj: PJSObject): Boolean; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_GetTypedArraySharedness(obj: PJSObject): Boolean; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_GetObjectAsInt8Array(obj: PJSObject; out length: uint32; out isSharedMemory:Boolean; out Data: Pint8Vector): PJSObject;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_GetObjectAsUint8Array(obj: PJSObject; out length: uint32; out isSharedMemory:Boolean; out Data: Puint8Vector): PJSObject;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_GetObjectAsUint8ClampedArray(obj: PJSObject; out length: uint32; out isSharedMemory:Boolean; out Data: Puint8Vector): PJSObject;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_GetObjectAsInt16Array(obj: PJSObject; out length: uint32; out isSharedMemory:Boolean; out Data: Pint16Vector): PJSObject;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_GetObjectAsUint16Array(obj: PJSObject; out length: uint32; out isSharedMemory:Boolean; out Data: Puint16Vector): PJSObject;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_GetObjectAsInt32Array(obj: PJSObject; out length: uint32; out isSharedMemory:Boolean; out Data: Pint32Vector): PJSObject;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_GetObjectAsUint32Array(obj: PJSObject; out length: uint32; out isSharedMemory:Boolean; out Data: Puint32Vector): PJSObject;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_GetObjectAsFloat32Array(obj: PJSObject; out length: uint32; out isSharedMemory:Boolean; out Data: Pfloat32Vector): PJSObject;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_GetObjectAsFloat64Array(obj: PJSObject; out length: uint32; out isSharedMemory:Boolean; out Data: Pfloat64Vector): PJSObject;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_GetObjectAsArrayBufferView(obj: PJSObject; out length: uint32; out isSharedMemory:Boolean; out Data: Puint8Vector): PJSObject;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_GetObjectAsArrayBuffer(obj: PJSObject; out length: uint32; out Data: Puint8Vector): PJSObject;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
|
|
/// Get the type of elements in a typed array, or jsabTYPE_DATAVIEW if a DataView
|
|
function JS_GetArrayBufferViewType(obj: PJSObject): JSArrayBufferViewType;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
//function JS_GetSharedArrayBufferViewType(obj: PJSObject): JSArrayBufferViewType;
|
|
// cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_IsArrayBufferObject(obj: PJSObject): Boolean;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
function JS_IsSharedArrayBufferObject(obj: PJSObject): Boolean;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_GetArrayBufferByteLength(obj: PJSObject): uint32;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
function JS_GetSharedArrayBufferByteLength(obj: PJSObject): uint32;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_ArrayBufferHasData(obj: PJSObject): Boolean;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_GetArrayBufferData(obj: PJSObject; out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Puint8Vector; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_IsMappedArrayBufferObject(obj: PJSObject): Boolean;
|
|
cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_GetTypedArrayLength(obj: PJSObject): uint32; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_GetTypedArrayByteOffset(obj: PJSObject): uint32; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_GetTypedArrayByteLength(obj: PJSObject): uint32; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// More generic name for JS_GetTypedArrayByteLength to cover DataViews as well
|
|
function JS_GetArrayBufferViewByteLength(obj: PJSObject): uint32; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_GetInt8ArrayData(obj: PJSObject; out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Pint8Vector; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_GetUint8ArrayData(obj: PJSObject; out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Puint8Vector; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_GetUint8ClampedArrayData(obj: PJSObject; out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Puint8Vector; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_GetInt16ArrayData(obj: PJSObject; out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Pint16Vector; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_GetUint16ArrayData(obj: PJSObject; out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Puint16Vector; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_GetInt32ArrayData(obj: PJSObject; out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Pint32Vector; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_GetUint32ArrayData(obj: PJSObject; out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Puint32Vector; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_GetFloat32ArrayData(obj: PJSObject; out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Pfloat32Vector; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_GetFloat64ArrayData(obj: PJSObject; out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Pfloat64Vector; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_GetArrayBufferViewData(obj: PJSObject; out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Pointer; cdecl; external SpiderMonkeyLib;
|
|
|
|
/// 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 JS_GetArrayBufferViewBuffer(cx: PJSContext; var obj: PJSObject; out isSharedMemory: Boolean): PJSObject; cdecl; external SpiderMonkeyLib;
|
|
|
|
|
|
////modules
|
|
|
|
/// Initialize modeles classes next 2 functions cannot work without calling this function
|
|
function JS_InitModuleClasses(cx: PJSContext; var obj: PJSObject): boolean; cdecl; external SpiderMonkeyLib;
|
|
/// Compile script as module
|
|
function JS_CompileModule(cx: PJSContext;
|
|
var obj: PJSObject;
|
|
options: PJSCompileOptions;
|
|
chars: PCChar16; length: size_t): PJSObject; cdecl; external SpiderMonkeyLib;
|
|
/// Set handler for module resolving
|
|
procedure JS_SetModuleResolveHook(cx: PJSContext; var hook: PJSFunction); cdecl; external SpiderMonkeyLib;
|
|
|
|
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);
|
|
end;
|
|
end;
|
|
|
|
const
|
|
ErrorUCFormatString: JSErrorFormatString =
|
|
(
|
|
format: '{0}';
|
|
argCount: 1;
|
|
exnType: JSEXN_ERR;
|
|
);
|
|
RangeErrorUCFormatString: JSErrorFormatString =
|
|
(
|
|
format: '{0}';
|
|
argCount: 1;
|
|
exnType: JSEXN_RANGEERR;
|
|
);
|
|
TypeErrorUCFormatString: JSErrorFormatString =
|
|
(
|
|
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);
|
|
begin
|
|
if not JS_IsExceptionPending(cx) then
|
|
JS_ReportErrorNumberUC(cx, ReportErrorUC, nil, SMExceptionNumber ,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
|
|
Result := JS_Init;
|
|
end;
|
|
|
|
procedure ShutDownJS;
|
|
begin
|
|
JS_ShutDown;
|
|
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}
|
|
SetString(Result, str8, strL);
|
|
{$else}
|
|
Result := Latin1AnsiConvert.AnsiToUnicodeString(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; var 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;
|
|
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
|
|
result := '';
|
|
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 }
|
|
{$IFDEF SM52}
|
|
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;
|
|
|
|
{$ENDIF}
|
|
|
|
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;
|
|
procedure JS_FreeCompartmentOptions(opt: PJS_CompartmentOptions); cdecl; external SpiderMonkeyLib;
|
|
|
|
function JSContext.NewGlobalObject(clasp: PJSClass): PJSObject;
|
|
var
|
|
Opt: PJS_CompartmentOptions;
|
|
begin
|
|
Opt := JS_NewCompartmentOptions;
|
|
{$IFNDEF SM52}
|
|
Opt.version := JSVERSION_LATEST;
|
|
{$ENDIF}
|
|
Result := JS_NewGlobalObject(@Self, clasp, nil, DontFireOnNewGlobalHook, 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.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, 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;
|
|
|
|
{$IFNDEF SM52}
|
|
function JSContext.GetRuntime: PJSRuntime;
|
|
begin
|
|
result := JS_GetRuntime(@self);
|
|
end;
|
|
{$ENDIF}
|
|
|
|
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
|
|
result := NewJSString(pointer(Value),length(Value),CP_UTF8);
|
|
end;
|
|
|
|
{$IFDEF SM52}
|
|
function JSContextOptions.getOptions(const Index: Integer): Boolean;
|
|
{$ELSE}
|
|
function JSRuntimeOptions.getOptions(const Index: Integer): Boolean;
|
|
{$ENDIF}
|
|
{ JSRuntimeOptions }
|
|
begin
|
|
Result := (pword(@self)^ and (1 shl Index)) <> 0;
|
|
end;
|
|
|
|
{$IFDEF SM52}
|
|
procedure JSContextOptions.setOptions(const Index: Integer;
|
|
{$ELSE}
|
|
procedure JSRuntimeOptions.setOptions(const Index: Integer;
|
|
{$ENDIF}
|
|
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;
|
|
|
|
{$IFNDEF SM52}
|
|
{ JSRuntime }
|
|
procedure JSRuntime.Destroy;
|
|
begin
|
|
JS_DestroyRuntime(@self);
|
|
end;
|
|
{$ENDIF}
|
|
|
|
{$IFDEF SM52}
|
|
procedure JSContext.GC;
|
|
{$ELSE}
|
|
procedure JSRuntime.GC;
|
|
{$ENDIF}
|
|
begin
|
|
JS_GC(@self);
|
|
end;
|
|
|
|
{$IFDEF SM52}
|
|
function JSContext.GetEmptyString: PJSString;
|
|
{$ELSE}
|
|
function JSRuntime.GetEmptyString: PJSString;
|
|
{$ENDIF}
|
|
begin
|
|
Result := JS_GetEmptyString(@self);
|
|
end;
|
|
|
|
{$IFDEF SM52}
|
|
function JSContext.GetWarningReporter: JSWarningReporter;
|
|
begin
|
|
Result := JS_GetWarningReporter(@self);
|
|
end;
|
|
{$ELSE}
|
|
function JSRuntime.GetErrorReporter: JSErrorReporter;
|
|
begin
|
|
Result := JS_GetErrorReporter(@self);
|
|
end;
|
|
{$ENDIF}
|
|
|
|
{$IFDEF SM52}
|
|
function JSContext.GetGCParameter(key: JSGCParamKey): uint32;
|
|
{$ELSE}
|
|
function JSRuntime.GetGCParameter(key: JSGCParamKey): uint32;
|
|
{$ENDIF}
|
|
begin
|
|
Result := JS_GetGCParameter(@Self, key);
|
|
end;
|
|
|
|
{$IFDEF SM52}
|
|
{$ELSE}
|
|
function JSRuntime.GetInterruptCallback: JSInterruptCallback;
|
|
begin
|
|
Result := JS_GetInterruptCallback(@self);
|
|
end;
|
|
{$ENDIF}
|
|
|
|
{$IFDEF SM52}
|
|
function JSContext.GetNowMs: int64;
|
|
{$ELSE}
|
|
function JSRuntime.GetNowMs: int64;
|
|
{$ENDIF}
|
|
begin
|
|
Result := JS_Now;
|
|
end;
|
|
|
|
{$IFDEF SM52}
|
|
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;
|
|
{$ELSE}
|
|
|
|
function JSRuntime.GetPrivate: Pointer;
|
|
begin
|
|
Result := JS_GetRuntimePrivate(@self);
|
|
end;
|
|
|
|
class function JSRuntime.new(maxbytes: uint32; maxNurseryBytes: uint32; parentRuntime: PJSRuntime): PJSRuntime;
|
|
begin
|
|
Result := JS_NewRuntime(maxbytes, maxNurseryBytes, parentRuntime);
|
|
end;
|
|
|
|
function JSRuntime.NewContext(stackChunkSize: size_t): PJSContext;
|
|
begin
|
|
Result := JS_NewContext(@Self, stackChunkSize)
|
|
end;
|
|
{$ENDIF}
|
|
|
|
{$IFDEF SM52}
|
|
function JSContext.GetOptions: PJSContextOptions;
|
|
begin
|
|
Result := JS_GetContextOptions(@self);
|
|
end;
|
|
{$ELSE}
|
|
function JSRuntime.GetOptions: PJSRuntimeOptions;
|
|
begin
|
|
Result := JS_GetRuntimeOptions(@self);
|
|
end;
|
|
{$ENDIF}
|
|
|
|
|
|
{$IFDEF SM52}
|
|
procedure JSContext.RequestInterruptCallback;
|
|
{$ELSE}
|
|
procedure JSRuntime.RequestInterruptCallback;
|
|
{$ENDIF}
|
|
begin
|
|
JS_RequestInterruptCallback(@self);
|
|
end;
|
|
|
|
{$IFDEF SM52}
|
|
procedure JSContext.SetWarningReporter(reporter: JSWarningReporter);
|
|
begin
|
|
JS_SetWarningReporter(@self, reporter);
|
|
end;
|
|
{$ELSE}
|
|
procedure JSRuntime.SetErrorReporter(er: JSErrorReporter);
|
|
begin
|
|
JS_SetErrorReporter(@self, er);
|
|
end;
|
|
{$ENDIF}
|
|
|
|
{$IFDEF SM52}
|
|
procedure JSContext.SetGCParameter(key: JSGCParamKey; const Value: uint32);
|
|
{$ELSE}
|
|
procedure JSRuntime.SetGCParameter(key: JSGCParamKey; const Value: uint32);
|
|
{$ENDIF}
|
|
begin
|
|
JS_SetGCParameter(@Self, key, Value);
|
|
end;
|
|
|
|
{$IFDEF SM52}
|
|
procedure JSContext.SetGCParametersBasedOnAvailableMemory(availMem: uint32);
|
|
{$ELSE}
|
|
procedure JSRuntime.SetGCParametersBasedOnAvailableMemory(availMem: uint32);
|
|
{$ENDIF}
|
|
begin
|
|
JS_SetGCParametersBasedOnAvailableMemory(@Self, availMem);
|
|
end;
|
|
|
|
{$IFDEF SM52}
|
|
{$ELSE}
|
|
procedure JSRuntime.SetInterruptCallback(callback: JSInterruptCallback);
|
|
begin
|
|
JS_SetInterruptCallback(@Self, callback);
|
|
end;
|
|
{$ENDIF}
|
|
|
|
{$IFDEF SM52}
|
|
procedure JSContext.SetNativeStackQuota(systemCodeStackSize: size_t);
|
|
{$ELSE}
|
|
procedure JSRuntime.SetNativeStackQuota(systemCodeStackSize: size_t);
|
|
{$ENDIF}
|
|
begin
|
|
JS_SetNativeStackQuota(@Self, systemCodeStackSize);
|
|
end;
|
|
|
|
{$IFDEF SM52}
|
|
|
|
{$ELSE}
|
|
procedure JSRuntime.SetPrivate(const Value: Pointer);
|
|
begin
|
|
JS_SetRuntimePrivate(@Self, Value);
|
|
end;
|
|
{$ENDIF}
|
|
|
|
{ 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
|
|
{$IFDEF SM52}
|
|
result._l.asBits := JS_GetReservedSlot(@Self, index)
|
|
{$ELSE}
|
|
result._l.asBits := JS_GetReservedSlot(@Self, index)
|
|
{$ENDIF}
|
|
end;
|
|
|
|
function JSObject.GetSharedArrayBufferByteLength: uint32;
|
|
begin
|
|
result := JS_GetSharedArrayBufferByteLength(@self);
|
|
end;
|
|
|
|
//function JSObject.GetSharedArrayBufferViewType: JSArrayBufferViewType;
|
|
//begin
|
|
// result := JS_GetSharedArrayBufferViewType(@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): JSIdArray;
|
|
var obj: PJSObject;
|
|
begin
|
|
obj := @Self;
|
|
Result.init(cx);
|
|
{$ifdef WITHASSERT}
|
|
Assert(
|
|
{$ENDIF}
|
|
JS_Enumerate(cx, obj, Result)
|
|
{$ifdef WITHASSERT}
|
|
);
|
|
{$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; var 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
|
|
{$IFDEF SM52}
|
|
JS_SetReservedSlot(@Self, index, v);
|
|
{$ELSE}
|
|
JS_SetReservedSlot(@Self, index, v._l.asBits);
|
|
{$ENDIF}
|
|
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);
|
|
begin
|
|
Create(AMessage);
|
|
FJSErrorNum := AJSErrorNum;
|
|
if AFileName='' then
|
|
FFileName := '<>'
|
|
else
|
|
FFileName := AFileName;
|
|
FLineNum := ALineNum;
|
|
FJSStackTrace := AStackTrace;
|
|
end;
|
|
|
|
procedure ESMException.WriteFormatted(WR: TTextWriter);
|
|
{$IFNDEF SM_DEBUG}
|
|
var
|
|
P, Pb: PWord;
|
|
{$ENDIF}
|
|
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}
|
|
// any stack line what don't start with `@` is internal (core_modules) calls
|
|
// remove it to simplify domain logic debugging
|
|
if length(Stack) > 0 then begin
|
|
P := PWord(pointer(Stack));
|
|
while P^ <> 0 do begin
|
|
if (P^ = Ord('@')) then begin
|
|
Pb := P;
|
|
while (P^ <> 10) and (P^ <> 0) do Inc(P);
|
|
if (P^ = 10) then Inc(P);
|
|
WR.AddJSONEscapeW(Pb, (PtrUInt(P)-PtrUInt(Pb)) div 2);
|
|
end else
|
|
while (P^ <> 10) and (P^ <> 0) do
|
|
Inc(P);
|
|
if (P^ = 10) then Inc(P);
|
|
end;
|
|
end;
|
|
{$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;
|
|
|
|
{ JSIdArray }
|
|
|
|
procedure JSIdArray.init(cx: PJSContext);
|
|
begin
|
|
_internal.cx := cx;
|
|
_internal.mBegin := @_internal.mStorage;
|
|
_internal.mLength := 0;
|
|
_internal.mCapacity := 1;
|
|
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;
|
|
|
|
function SimpleVariantToJSval(cx: PJSContext; val: Variant): jsval;
|
|
begin
|
|
Result.asSimpleVariant[cx] := val;
|
|
end;
|
|
|
|
initialization
|
|
Latin1AnsiConvert := TSynAnsiConvert.Engine(CODEPAGE_LATIN1);
|
|
end.
|
|
|