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