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
2018 /// Initialize SpiderMonkey, returning true only if initialization succeeded.
2019 // Once this method has succeeded, it is safe to call JS_NewRuntime and other
2020 // JSAPI methods.
2021 // - This method must be called before any other JSAPI method is used on any
2022 // thread. Once it has been used, it is safe to call any JSAPI method, and it
2023 // remains safe to do so until JS_ShutDown is correctly called.
2024 // - It is currently not possible to initialize SpiderMonkey multiple times (that
2025 // is, calling JS_Init/JSAPI methods/JS_ShutDown in that order, then doing so
2026 // again). This restriction may eventually be lifted.
2027type TJS_Initialize = function : Boolean; cdecl;
2028var JS_Init: TJS_Initialize external SpiderMonkeyLib name 'SM_Initialize';
2029
2030procedure JS_DisableExtraThreads; cdecl;
2031 external SpiderMonkeyLib name 'SM_DisableExtraThreads';
2032
2033 /// Destroy free-standing resources allocated by SpiderMonkey, not associated
2034 // with any runtime, context, or other structure.
2035 // - This method should be called after all other JSAPI data has been properly
2036 // cleaned up: every new runtime must have been destroyed, every new context
2037 // must have been destroyed, and so on. Calling this method before all other
2038 // resources have been destroyed has undefined behavior.
2039 // - Failure to call this method, at present, has no adverse effects other than
2040 // leaking memory. This may not always be the case; it's recommended that all
2041 // embedders call this method when all other JSAPI operations have completed.
2042 // - It is currently not possible to initialize SpiderMonkey multiple times (that
2043 // is, calling JS_Init/JSAPI methods/JS_ShutDown in that order, then doing so
2044 // again). This restriction may eventually be lifted.
2045type TJS_ShutDown = procedure; cdecl;
2046var JS_ShutDown: TJS_ShutDown external SpiderMonkeyLib name 'SM_ShutDown';
2047
2048/// Microseconds since the epoch, midnight, January 1, 1970 UTC.
2049type TJS_Now = function : int64; cdecl;
2050var JS_Now: TJS_Now external SpiderMonkeyLib name 'SM_Now';
2051
2052/// Returns the empty string as a JSString object.
2053type TJS_GetEmptyString = function (cx: PJSContext): PJSString; cdecl;
2054var JS_GetEmptyString: TJS_GetEmptyString external SpiderMonkeyLib name 'SM_GetEmptyString';
2055
2056/// Determines the JS data type of a JS value.
2057type TJS_TypeOfValue = function (cx: PJSContext; var v: jsval): JSType; cdecl;
2058var JS_TypeOfValue: TJS_TypeOfValue external SpiderMonkeyLib name 'SM_TypeOfValue';
2059
2060/// indicates to the JS engine that the calling thread is entering a region
2061// of code that may call into the JSAPI but does not block
2062type TJS_BeginRequest = procedure (cx: PJSContext); cdecl;
2063var JS_BeginRequest: TJS_BeginRequest external SpiderMonkeyLib name 'SM_BeginRequest';
2064
2065/// indicates to the JS engine that the calling thread is leaving a region
2066// of code that may call into the JSAPI but does not block
2067type TJS_EndRequest = procedure (cx: PJSContext); cdecl;
2068var JS_EndRequest: TJS_EndRequest external SpiderMonkeyLib name 'SM_EndRequest';
2069
2070/// Create a new JSContext
2071type TJS_NewContext = function (maxbytes: uint32;
2072 maxNurseryBytes: uint32 = 16 * (1 SHL 20);
2073 parentContext: PJSContext = nil): PJSContext; cdecl;
2074var JS_NewContext: TJS_NewContext external SpiderMonkeyLib name 'SM_NewContext';
2075
2076type TInitSelfHostedCode = function (cx: PJSContext): boolean; cdecl;
2077var InitSelfHostedCode: TInitSelfHostedCode external SpiderMonkeyLib name 'SM_InitSelfHostedCode';
2078
2079/// Destroy a JSContext.
2080type TJS_DestroyContext = procedure (cx: PJSContext); cdecl;
2081var JS_DestroyContext: TJS_DestroyContext external SpiderMonkeyLib name 'SM_DestroyContext';
2082
2083/// Read access a JSContext field for application-specific data.
2084// Memory management for this private data is the application's responsibility.
2085// The JavaScript engine itself never uses it.
2086type TJS_GetContextPrivate = function (cx: PJSContext): Pointer; cdecl;
2087var JS_GetContextPrivate: TJS_GetContextPrivate external SpiderMonkeyLib name 'SM_GetContextPrivate';
2088
2089/// Write access a JSContext field for application-specific data.
2090// Memory management for this private data is the application's responsibility.
2091// The JavaScript engine itself never uses it.
2092type TJS_SetContextPrivate = procedure (cx: PJSContext; data: Pointer); cdecl;
2093var JS_SetContextPrivate: TJS_SetContextPrivate external SpiderMonkeyLib name 'SM_SetContextPrivate';
2094
2095/// This function makes a cross-compartment wrapper for the given JS object.
2096// Details see here http://stackoverflow.com/questions/18730477/what-does-js-wrapobject-do
2097type TJS_WrapObject = function (cx: PJSContext; var obj: PJSObject): boolean; cdecl;
2098var JS_WrapObject: TJS_WrapObject external SpiderMonkeyLib name 'SM_WrapObject';
2099
2100/// Enter a different compartment on the given context, so that objects in that
2101// compartment can be accessed.
2102// - NB: This API is infallible; a NULL return value does not indicate error
2103type TJS_EnterCompartment = function (cx: PJSContext; target: PJSObject): PJSCompartment; cdecl;
2104var JS_EnterCompartment: TJS_EnterCompartment external SpiderMonkeyLib name 'SM_EnterCompartment';
2105
2106/// Leave a the compartment, returning to the compartment active before the
2107// corresponding JS_EnterCompartment.
2108type TJS_LeaveCompartment = procedure (cx: PJSContext; oldCompartment: PJSCompartment); cdecl;
2109var JS_LeaveCompartment: TJS_LeaveCompartment external SpiderMonkeyLib name 'SM_LeaveCompartment';
2110
2111/// Initialize standard JS class constructors, prototypes, and any top-level
2112// functions and constants associated with the standard classes (e.g. isNaN
2113// for Number).
2114// - NB: This sets cx's global object to obj if it was null.
2115type TJS_InitStandardClasses = function (cx: PJSContext; var obj: PJSObject): boolean; cdecl;
2116var JS_InitStandardClasses: TJS_InitStandardClasses external SpiderMonkeyLib name 'SM_InitStandardClasses';
2117
2118///Return the global object for the active function on the context.
2119type TJS_CurrentGlobalOrNull = function (cx: PJSContext):PJSObject; cdecl;
2120var JS_CurrentGlobalOrNull: TJS_CurrentGlobalOrNull external SpiderMonkeyLib name 'SM_CurrentGlobalOrNull';
2121
2122/// Add 'Reflect.parse', a SpiderMonkey extension, to the Reflect object on the
2123// given global.
2124type TJS_InitReflectParse = function (cx: PJSContext; var obj: PJSObject): boolean; cdecl;
2125var JS_InitReflectParse: TJS_InitReflectParse external SpiderMonkeyLib name 'SM_InitReflectParse';
2126
2127/// Initialize the 'ctypes' object on a global variable 'obj'. The 'ctypes'
2128// object will be sealed.
2129type TJS_InitCTypesClass = function (cx: PJSContext; var obj: PJSObject): boolean; cdecl;
2130var JS_InitCTypesClass: TJS_InitCTypesClass external SpiderMonkeyLib name 'SM_InitCTypesClass';
2131
2132/// Initialize the 'Debugger' object on a global variable 'obj'. The 'ctypes'
2133// object will be sealed.
2134type TJS_DefineDebuggerObject = function (cx: PJSContext; var obj: PJSObject): boolean; cdecl;
2135var JS_DefineDebuggerObject: TJS_DefineDebuggerObject external SpiderMonkeyLib name 'SM_DefineDebuggerObject';
2136
2137/// Performs garbage collection in the JS memory pool.
2138type TJS_GC = procedure (cx: PJSContext); cdecl;
2139var JS_GC: TJS_GC external SpiderMonkeyLib name 'SM_GC';
2140
2141/// Offer the JavaScript engine an opportunity to perform garbage collection if needed.
2142type TJS_MaybeGC = procedure (cx: PJSContext); cdecl;
2143var JS_MaybeGC: TJS_MaybeGC external SpiderMonkeyLib name 'SM_MaybeGC';
2144
2145///Set performance parameters related to garbage collection.
2146type TJS_SetGCParameter = procedure (cx: PJSContext; key: JSGCParamKey; value: uint32); cdecl;
2147var JS_SetGCParameter: TJS_SetGCParameter external SpiderMonkeyLib name 'SM_SetGCParameter';
2148
2149///Get performance parameters related to garbage collection.
2150type TJS_GetGCParameter = function (cx: PJSContext; key: JSGCParamKey): uint32; cdecl;
2151var JS_GetGCParameter: TJS_GetGCParameter external SpiderMonkeyLib name 'SM_GetGCParameter';
2152
2153///Adjust performance parameters related to garbage collection based on available memory(in megabytes).
2154type TJS_SetGCParametersBasedOnAvailableMemory = procedure (cx: PJSContext; availMem: uint32); cdecl;
2155var JS_SetGCParametersBasedOnAvailableMemory: TJS_SetGCParametersBasedOnAvailableMemory external SpiderMonkeyLib name 'SM_SetGCParametersBasedOnAvailableMemory';
2156
2157/// Creates a new JSString whose characters are stored in external memory, i.e.,
2158// memory allocated by the application, not the JavaScript engine
2159// - Since the program allocated the memory, it will need to free it;
2160// this happens in an external string finalizer indicated by the type parameter.
2161// - chars is Pointer to the first element of an array of jschars.
2162// This array is used as the character buffer of the JSString to be created.
2163// The array must be populated with the desired character data before JS_NewExternalString
2164// is called, and the array must remain in memory, with its contents unchanged,
2165// for as long as the JavaScript engine needs to hold on to it.
2166// (Ultimately, the string will be garbage collected, and the JavaScript engine will
2167// call the string finalizer callback, allowing the application to free the array)
2168// - The text buffer array does not need to be zero-terminated.
2169type TJS_NewExternalString = function (cx: PJSContext; chars: PCChar16; length: size_t;
2170 fin: PJSStringFinalizer): PJSString; cdecl;
2171var JS_NewExternalString: TJS_NewExternalString external SpiderMonkeyLib name 'SM_NewExternalString';
2172
2173/// Set the size of the native stack that should not be exceed. To disable
2174// stack size checking pass 0.
2175// - SpiderMonkey allows for a distinction between system code (such as GCs, which
2176// may incidentally be triggered by script but are not strictly performed on
2177// behalf of such script), trusted script (as determined by JS_SetTrustedPrincipals),
2178// and untrusted script. Each kind of code may have a different stack quota,
2179// allowing embedders to keep higher-priority machinery running in the face of
2180// scripted stack exhaustion by something else.
2181// - The stack quotas for each kind of code should be monotonically descending,
2182// and may be specified with this function. If 0 is passed for a given kind
2183// of code, it defaults to the value of the next-highest-priority kind.
2184// - This function may only be called immediately after the runtime is initialized
2185// and before any code is executed and/or interrupts requested.
2186type TJS_SetNativeStackQuota = procedure (cx: PJSContext; systemCodeStackSize: size_t;
2187 trustedScriptStackSize: size_t = 0; untrustedScriptStackSize: size_t = 0); cdecl;
2188var JS_SetNativeStackQuota: TJS_SetNativeStackQuota external SpiderMonkeyLib name 'SM_SetNativeStackQuota';
2189
2190/// Convert a JS::Value to type jsid.
2191type TJS_ValueToId = function (cx: PJSContext; var v: jsval; out id: jsid): Boolean; cdecl;
2192var JS_ValueToId: TJS_ValueToId external SpiderMonkeyLib name 'SM_ValueToId';
2193
2194/// Convert a jsid to type JS::Value.
2195type TJS_IdToValue = function (cx: PJSContext; id: jsid; out v: jsval): Boolean; cdecl;
2196var JS_IdToValue: TJS_IdToValue external SpiderMonkeyLib name 'SM_IdToValue';
2197
2198type TJS_ValueToSource = function (cx: PJSContext; var v: jsval): PJSString; cdecl;
2199var JS_ValueToSource: TJS_ValueToSource external SpiderMonkeyLib name 'SM_ValueToSource';
2200
2201/// Make a JSClass accessible to JavaScript code by creating its prototype,
2202// constructor, properties, and functions.
2203type TJS_InitClass = function (cx: PJSContext; var obj: PJSObject; var parent_proto: PJSObject;
2204 clasp: PJSClass; _constructor: JSNative; nargs: uintN;
2205 ps: PJSPropertySpec; fs: PJSFunctionSpec;
2206 static_ps: PJSPropertySpec; static_fs: PJSFunctionSpec): PJSObject; cdecl;
2207var JS_InitClass: TJS_InitClass external SpiderMonkeyLib name 'SM_InitClass';
2208
2209/// Retrieves the class associated with an object.
2210type TJS_GetClass = function (obj: PJSObject): PJSClass; cdecl;
2211var JS_GetClass: TJS_GetClass external SpiderMonkeyLib name 'SM_GetClass';
2212
2213/// JSAPI method equivalent to the instanceof operator in JavaScript.
2214type TJS_HasInstance = function (cx: PJSContext; var obj: PJSObject;
2215 var val: jsval; out res: Boolean): Boolean; cdecl;
2216var JS_HasInstance: TJS_HasInstance external SpiderMonkeyLib name 'SM_HasInstance';
2217
2218/// Access the private data field of an object.
2219type TJS_GetPrivate = function (obj: PJSObject): Pointer; cdecl;
2220var JS_GetPrivate: TJS_GetPrivate external SpiderMonkeyLib name 'SM_GetPrivate';
2221
2222/// Sets the private data field of an object.
2223type TJS_SetPrivate = procedure (obj: PJSObject; data: Pointer); cdecl;
2224var JS_SetPrivate: TJS_SetPrivate external SpiderMonkeyLib name 'SM_SetPrivate';
2225
2226/// Retrieves the constructor for an object.
2227type TJS_GetConstructor = function (cx: PJSContext; var proto: PJSObject): PJSObject; cdecl;
2228var JS_GetConstructor: TJS_GetConstructor external SpiderMonkeyLib name 'SM_GetConstructor';
2229
2230/// Retrieve the private data associated with an object, if that object is an
2231// instance of a specified class.
2232type TJS_GetInstancePrivate = function (cx: PJSContext; var obj: PJSObject;
2233 clasp: PJSClass; args: JSUnknown): Pointer; cdecl;
2234var JS_GetInstancePrivate: TJS_GetInstancePrivate external SpiderMonkeyLib name 'SM_GetInstancePrivate';
2235
2236/// Create a new JavaScript object for use as a global object.
2237type TJS_NewGlobalObject = function (cx: PJSContext; clasp: PJSClass; principals: PJSPrincipals;
2238 hookOption: OnNewGlobalHookOption; options: PJS_CompartmentOptions): PJSObject; cdecl;
2239var JS_NewGlobalObject: TJS_NewGlobalObject external SpiderMonkeyLib name 'SM_NewGlobalObject';
2240
2241/// Spidermonkey does not have a good way of keeping track of what compartments should be marked on
2242/// their own. We can mark the roots unconditionally, but marking GC things only relevant in live
2243/// compartments is hard. To mitigate this, we create a static trace hook, installed on each global
2244/// object, from which we can be sure the compartment is relevant, and mark it.
2245///
2246/// It is still possible to specify custom trace hooks for global object classes. They can be
2247/// provided via the CompartmentOptions passed to JS_NewGlobalObject.
2248type TJS_GlobalObjectTraceHook = procedure (trc: Pointer{ JSTracer }; global: PJSObject); cdecl;
2249var JS_GlobalObjectTraceHook: TJS_GlobalObjectTraceHook
2250 external SpiderMonkeyLib name 'SM_GlobalObjectTraceHook';
2251
2252/// Create a new object based on a specified class
2253type TJS_NewObject = function (cx: PJSContext; clasp: PJSClass): PJSObject; cdecl;
2254var JS_NewObject: TJS_NewObject external SpiderMonkeyLib name 'SM_NewObject';
2255
2256/// Create a new object based on a specified class
2257// - Unlike JS_NewObject, JS_NewObjectWithGivenProto does not compute a default
2258// proto. If proto is nullptr, the JS object will have `null` as [[Prototype]].
2259type TJS_NewObjectWithGivenProto = function (cx: PJSContext; clasp: PJSClass;
2260 var proto: PJSObject): PJSObject; cdecl;
2261var JS_NewObjectWithGivenProto: TJS_NewObjectWithGivenProto external SpiderMonkeyLib name 'SM_NewObjectWithGivenProto';
2262
2263/// Get the prototype of obj, storing it in result.
2264// - Implements: ES6 [[GetPrototypeOf]] internal method.
2265type TJS_GetPrototype = function (cx: PJSContext; var obj: PJSObject;
2266 out result: PJSObject):Boolean; cdecl;
2267var JS_GetPrototype: TJS_GetPrototype external SpiderMonkeyLib name 'SM_GetPrototype';
2268
2269/// Change the prototype of obj.
2270// - Implements: ES6 [[SetPrototypeOf]] internal method.
2271// - In cases where ES6 [[SetPrototypeOf]] returns false without an exception,
2272// JS_SetPrototype throws a TypeError and returns false.
2273// - Performance warning: JS_SetPrototype is very bad for performance. It may
2274// cause compiled jit-code to be invalidated. It also causes not only obj but
2275// all other objects in the same "group" as obj to be permanently deoptimized.
2276// It's better to create the object with the right prototype from the start.
2277type TJS_SetPrototype = function (cx: PJSContext; var obj: PJSObject;
2278 var proto: PJSObject):Boolean; cdecl;
2279var JS_SetPrototype: TJS_SetPrototype external SpiderMonkeyLib name 'SM_SetPrototype';
2280
2281/// Create a new property on an object.
2282// Name indentifies by ID
2283type TJS_DefinePropertyById = function (cx: PJSContext; var obj: PJSObject;
2284 var id: jsid; var value: jsval; attrs: uint32; getter: JSNative;
2285 setter: JSNative): boolean; cdecl;
2286var JS_DefinePropertyById: TJS_DefinePropertyById external SpiderMonkeyLib name 'SM_DefinePropertyById';
2287
2288/// Create a new property on an object.
2289// Name indentifies by ansi string
2290type TJS_DefineProperty = function (cx: PJSContext; var obj: PJSObject;
2291 const name: PCChar; var value: jsval; attrs: uint32; getter: JSNative;
2292 setter: JSNative): boolean; cdecl;
2293var JS_DefineProperty: TJS_DefineProperty external SpiderMonkeyLib name 'SM_DefineProperty';
2294
2295/// Create a new property on an object.
2296// Name indentifies by unicode string
2297type TJS_DefineUCProperty = function (cx: PJSContext; var obj: PJSObject;
2298 const name: PCChar16; namelen: size_t; var value: jsval; attrs: uint32;
2299 getter: JSNative; setter: JSNative): Boolean; cdecl;
2300var JS_DefineUCProperty: TJS_DefineUCProperty external SpiderMonkeyLib name 'SM_DefineUCProperty';
2301
2302/// Determine whether a JavaScript object has a specified property.
2303// Name indentifies by ansi string
2304type TJS_HasProperty = function (cx: PJSContext; var obj: PJSObject;
2305 const name: PCChar; var found: Boolean): Boolean; cdecl;
2306var JS_HasProperty: TJS_HasProperty external SpiderMonkeyLib name 'SM_HasProperty';
2307
2308/// Determine whether a JavaScript object has a specified property.
2309// Name indentifies by unicode string
2310type TJS_HasUCProperty = function (cx: PJSContext; var obj: PJSObject;
2311 const name: PCChar16; namelen: size_t; var found: Boolean): Boolean; cdecl;
2312var JS_HasUCProperty: TJS_HasUCProperty external SpiderMonkeyLib name 'SM_HasUCProperty';
2313
2314/// Find a specified property and retrieve its value.
2315// Name indentifies by ID
2316type TJS_GetPropertyById = function (cx: PJSContext; var obj: PJSObject;
2317 var id: jsid; out vp: jsval): boolean; cdecl;
2318var JS_GetPropertyById: TJS_GetPropertyById external SpiderMonkeyLib name 'SM_GetPropertyById';
2319
2320/// Find a specified property and retrieve its value.
2321// Name indentifies by ansi string
2322type TJS_GetProperty = function (cx: PJSContext; var obj: PJSObject;
2323 const name: PCChar; out vp: jsval): boolean; cdecl;
2324var JS_GetProperty: TJS_GetProperty external SpiderMonkeyLib name 'SM_GetProperty';
2325
2326/// Find a specified property and retrieve its value.
2327// Name indentifies by unicode string
2328type TJS_GetUCProperty = function (cx: PJSContext; var obj: PJSObject;
2329 const name: PCChar16; namelen: size_t; out vp: jsval): boolean; cdecl;
2330var JS_GetUCProperty: TJS_GetUCProperty external SpiderMonkeyLib name 'SM_GetUCProperty';
2331
2332/// Find a specified numeric property of an object and return its current value.
2333type TJS_GetElement = function (cx: PJSContext; var obj: PJSObject; index: uint32;
2334 out vp: jsval): Boolean; cdecl;
2335var JS_GetElement: TJS_GetElement external SpiderMonkeyLib name 'SM_GetElement';
2336
2337/// Assign a value to a property of an object.
2338// Name indentifies by ansi string
2339type TJS_SetProperty = function (cx: PJSContext; var obj: PJSObject;
2340 const name: PCChar; var vp: jsval): Boolean; cdecl;
2341var JS_SetProperty: TJS_SetProperty external SpiderMonkeyLib name 'SM_SetProperty';
2342
2343/// Assign a value to a property of an object.
2344// Name indentifies by unicode string
2345type TJS_SetUCProperty = function (cx: PJSContext; var obj: PJSObject;
2346 const name: PCChar16; namelen: size_t; var vp: jsval): boolean; cdecl;
2347var JS_SetUCProperty: TJS_SetUCProperty external SpiderMonkeyLib name 'SM_SetUCProperty';
2348
2349/// Assign a value to a numeric property of an object.
2350type TJS_SetElement = function (cx: PJSContext; var obj: PJSObject; index: uint32;
2351 var vp: jsval): Boolean; cdecl;
2352var JS_SetElement: TJS_SetElement external SpiderMonkeyLib name 'SM_SetElement';
2353
2354/// Removes a specified property from an object.
2355// Name indentifies by ID
2356type TJS_DeletePropertyById = function (cx: PJSContext; var obj: PJSObject;
2357 var id: jsid; out res: JS_ObjectOpResult): Boolean; cdecl;
2358var JS_DeletePropertyById: tJS_DeletePropertyById external SpiderMonkeyLib name 'SM_DeletePropertyById';
2359
2360/// Removes a specified element or numeric property from an object.
2361type TJS_DeleteElement = function (cx: PJSContext; var obj: PJSObject;
2362 index: uint32; out res: JS_ObjectOpResult): Boolean; cdecl;
2363var JS_DeleteElement: TJS_DeleteElement external SpiderMonkeyLib name 'SM_DeleteElement';
2364
2365/// Get an array of the non-symbol enumerable properties of obj.
2366// This function is roughly equivalent to:
2367//
2368// var result = [];
2369// for (key in obj)
2370// result.push(key);
2371// return result;
2372//
2373// This is the closest thing we currently have to the ES6 [[Enumerate]]
2374// internal method.
2375//
2376// The JSIdArray returned is rooted to protect its
2377// contents from garbage collection.
2378function JS_EnumerateToAutoIdVector(cx: PJSContext; var obj: PJSObject;
2379 out length: size_t; out data: PjsidVector): PJSIdArray;
2380 cdecl; external SpiderMonkeyLib name 'SM_EnumerateToAutoIdVector';
2381
2382procedure JS_DestroyAutoIdVector(v: PJSIdArray);
2383 cdecl; external SpiderMonkeyLib name 'SM_DestroyAutoIdVector';
2384
2385type
2386 JSHandleValueArray = record
2387 length: size_t;
2388 elements_: PjsvalVector;
2389 end;
2390
2391/// Calls a specified JS function.
2392// Function identifies by jsvalue
2393// - equivalent of `rval = Reflect.apply(fun, obj, args)`.
2394type TJS_CallFunctionValue = function (cx: PJSContext; var obj: PJSObject;
2395 var val: jsval; var args: JSHandleValueArray; out rval: jsval): Boolean; cdecl;
2396var JS_CallFunctionValue: TJS_CallFunctionValue external SpiderMonkeyLib name 'SM_CallFunctionValue';
2397
2398/// Calls a specified JS function.
2399// Function identifies by PJSFunction
2400type TJS_CallFunction = function (cx: PJSContext; var obj: PJSObject;
2401 var fun: PJSFunction; var args: JSHandleValueArray; out rval: jsval): Boolean; cdecl;
2402var JS_CallFunction: TJS_CallFunction external SpiderMonkeyLib name 'SM_CallFunction';
2403
2404/// Calls a specified JS function.
2405// Function identifies by ansi string
2406// - Perform the method call `rval = obj[name](args)`.
2407type TJS_CallFunctionName = function (cx: PJSContext; var obj: PJSObject;
2408 const name: PCChar; var args: JSHandleValueArray; out rval: jsval): Boolean; cdecl;
2409var JS_CallFunctionName: TJS_CallFunctionName external SpiderMonkeyLib name 'SM_CallFunctionName';
2410
2411/// Invoke a constructor, like the JS expression `new ctor(...args)`. Returns
2412// the new object, or null on error.
2413type TJS_New = function (cx: PJSContext; var ctor: PJSObject;
2414 var args: JSHandleValueArray): PJSObject; cdecl;
2415var JS_New: TJS_New external SpiderMonkeyLib name 'SM_New';
2416
2417/// Define multiple properties for a single object.
2418type TJS_DefineProperties = function (cx: PJSContext; var obj: PJSObject;
2419 ps: PJSPropertySpec): boolean; cdecl;
2420var JS_DefineProperties: TJS_DefineProperties external SpiderMonkeyLib name 'SM_DefineProperties';
2421
2422/// Determine whether a property is already physically present on a JSObject.
2423// Name indentifies by unicode string
2424type TJS_AlreadyHasOwnUCProperty = function (cx: PJSContext; var obj: PJSObject;
2425 const name: PCChar16; namelen: size_t; var foundp: Boolean): Boolean; cdecl;
2426var JS_AlreadyHasOwnUCProperty: TJS_AlreadyHasOwnUCProperty external SpiderMonkeyLib name 'SM_AlreadyHasOwnUCProperty';
2427
2428/// Create a new Array object.
2429// Only length passed
2430type TJS_NewArrayObject = function (cx: PJSContext; length: size_t): PJSObject; cdecl;
2431var JS_NewArrayObject: TJS_NewArrayObject external SpiderMonkeyLib name 'SM_NewArrayObject';
2432
2433/// Create a new Array object.
2434// Content passed
2435type TJS_NewArrayObject2 = function (cx: PJSContext;
2436 const contents: JSHandleValueArray): PJSObject; cdecl;
2437var JS_NewArrayObject2: TJS_NewArrayObject2 external SpiderMonkeyLib name 'SM_NewArrayObject2';
2438
2439/// Returns true and sets |*isArray| indicating whether |obj| is an Array object
2440// or a wrapper around one, otherwise returns false on failure.
2441// - This method returns true with |*isArray == false| when passed a proxy whose
2442// target is an Array, or when passed a revoked proxy.
2443type TJS_IsArrayObject = function (cx: PJSContext; var obj: PJSObject;
2444 out isArray: Boolean): boolean; cdecl;
2445var JS_IsArrayObject: TJS_IsArrayObject external SpiderMonkeyLib name 'SM_IsArrayObject';
2446
2447/// JS_GetArrayLength gets the .length property of obj as though by calling JS_GetProperty
2448// and converts it to a 32-bit unsigned integer. If obj is an array (see JS_IsArrayObject),
2449// this is guaranteed to succeed, because the .length property of an array is always a number
2450// and can't be deleted or redefined.
2451// - On success, JS_GetArrayLength stores the length in *lengthp and returns true.
2452// On failure, it reports an error and returns false, and the value left in *lengthp
2453// is undefined.
2454type TJS_GetArrayLength = function (cx: PJSContext; var obj: PJSObject;
2455 out length: uint32): Boolean; cdecl;
2456var JS_GetArrayLength: TJS_GetArrayLength external SpiderMonkeyLib name 'SM_GetArrayLength';
2457
2458/// Read access an object's reserved slots.
2459function JS_GetReservedSlot(obj: PJSObject; index: uint32): Int64; cdecl;
2460 external SpiderMonkeyLib name 'SM_GetReservedSlot';
2461
2462/// Write access an object's reserved slots
2463type TJS_SetReservedSlot = procedure (obj: PJSObject; index: uint32;
2464 var v: jsval); cdecl;
2465var JS_SetReservedSlot: TJS_SetReservedSlot external SpiderMonkeyLib name 'SM_SetReservedSlot';
2466
2467/// Create a new JavaScript function that is implemented as a JSNative.
2468type TJS_NewFunction = function (cx: PJSContext; call: JSNative; nargs: uintN;
2469 flags: uintN; name: PCChar): PJSObject; cdecl;
2470var JS_NewFunction: TJS_NewFunction external SpiderMonkeyLib name 'SM_NewFunction';
2471
2472/// Return the function's identifier as a JSString, or null if fun is unnamed.
2473// The returned string lives as long as fun, so you don't need to root a saved
2474// reference to it if fun is well-connected or rooted, and provided you bound
2475// the use of the saved reference by fun's lifetime.
2476type TJS_GetFunctionId = function (fun: PJSFunction): PJSString; cdecl;
2477var JS_GetFunctionId: TJS_GetFunctionId external SpiderMonkeyLib name 'SM_GetFunctionId';
2478
2479/// Infallible predicate to test whether obj is a function object (faster than
2480// comparing obj's class name to "Function", but equivalent unless someone has
2481// overwritten the "Function" identifier with a different constructor and then
2482// created instances using that constructor that might be passed in as obj).
2483type TJS_ObjectIsFunction = function (cx: PJSContext; obj: PJSObject): boolean; cdecl;
2484var JS_ObjectIsFunction: TJS_ObjectIsFunction external SpiderMonkeyLib name 'SM_ObjectIsFunction';
2485
2486/// Create zero or more functions and makes them properties (methods)
2487// of a specified object, obj, as if by calling JS_DefineFunction repeatedly
2488type TJS_DefineFunctions = function (cx: PJSContext; var obj: PJSObject;
2489 fs: PJSFunctionSpec; behavior: JSPropertyDefinitionBehavior): Boolean; cdecl;
2490var JS_DefineFunctions: TJS_DefineFunctions external SpiderMonkeyLib name 'SM_DefineFunctions';
2491
2492/// Create a native function and assign it as a property to a specified JS object
2493type TJS_DefineFunction = function (cx: PJSContext; var obj: PJSObject; name: PCChar;
2494 call: JSNative; nargs: uintN; attrs: uintN): PJSFunction; cdecl;
2495var JS_DefineFunction: TJS_DefineFunction external SpiderMonkeyLib name 'SM_DefineFunction';
2496
2497/// Unicode version to create a native function
2498type TJS_DefineUCFunction = function (cx: PJSContext; var obj: PJSObject;
2499 name: PCChar16; namelen: size_t; call: JSNative; nargs: uintN;
2500 attrs: uintN): PJSFunction; cdecl;
2501var JS_DefineUCFunction: TJS_DefineUCFunction external SpiderMonkeyLib name 'SM_DefineUCFunction';
2502
2503/// Compile a script, source, for execution.
2504// Ansi version
2505type TJS_CompileScript = function (cx: PJSContext; bytes: PCChar; length: size_t;
2506 options: PJSCompileOptions; out script: PJSScript): boolean; cdecl;
2507var JS_CompileScript: TJS_CompileScript external SpiderMonkeyLib name 'SM_CompileScript';
2508
2509/// Compile a script, source, for execution.
2510// Unicode version
2511type TJS_CompileUCScript = function (cx: PJSContext; chars: PCChar16;
2512 length: size_t; options: PJSCompileOptions; out script: PJSScript): boolean; cdecl;
2513var JS_CompileUCScript: TJS_CompileUCScript external SpiderMonkeyLib name 'SM_CompileUCScript';
2514
2515/// Generate the complete source code of a function declaration from a compiled function
2516type TJS_DecompileFunction = function (cx: PJSContext; var fun: PJSFunction;
2517 indent: uintN): PJSString; cdecl;
2518var JS_DecompileFunction: TJS_DecompileFunction external SpiderMonkeyLib name 'SM_DecompileFunction';
2519
2520/// Evaluate a script in the scope of the current global of cx.
2521type TJS_ExecuteScript = function (cx: PJSContext; var script: PJSScript;
2522 out rval: jsval): Boolean; cdecl;
2523var JS_ExecuteScript: TJS_ExecuteScript external SpiderMonkeyLib name 'SM_ExecuteScript';
2524
2525/// These functions allow setting an interrupt callback that will be called
2526// from the JS thread some time after any thread triggered the callback using
2527// JS_RequestInterruptCallback(cx).
2528// - To schedule the GC and for other activities the engine internally triggers
2529// interrupt callbacks. The embedding should thus not rely on callbacks being
2530//triggered through the external API only.
2531// - Important note: Additional callbacks can occur inside the callback handler
2532// if it re-enters the JS engine. The embedding must ensure that the callback
2533// is disconnected before attempting such re-entry.
2534type TJS_CheckForInterrupt = function (cx: PJSContext): Boolean; cdecl;
2535var JS_CheckForInterrupt: TJS_CheckForInterrupt external SpiderMonkeyLib name 'SM_CheckForInterrupt';
2536
2537type TJS_AddInterruptCallback = function (cx: PJSContext;
2538 callback: JSInterruptCallback): Boolean; cdecl;
2539var JS_AddInterruptCallback: TJS_AddInterruptCallback external SpiderMonkeyLib name 'SM_AddInterruptCallback';
2540
2541type TJS_DisableInterruptCallback = function (cx: PJSContext): Boolean; cdecl;
2542var JS_DisableInterruptCallback: TJS_DisableInterruptCallback external SpiderMonkeyLib name 'SM_DisableInterruptCallback';
2543
2544type TJS_ResetInterruptCallback = procedure (cx: PJSContext;
2545 enable: Boolean); cdecl;
2546var JS_ResetInterruptCallback: TJS_ResetInterruptCallback external SpiderMonkeyLib name 'SM_ResetInterruptCallback';
2547
2548/// Request a callback set using JS_SetInterruptCallback
2549type TJS_RequestInterruptCallback = procedure (cx: PJSContext); cdecl;
2550var JS_RequestInterruptCallback: TJS_RequestInterruptCallback external SpiderMonkeyLib name 'SM_RequestInterruptCallback';
2551
2552/// Indicates whether or not a script or function is currently executing in a given context.
2553type TJS_IsRunning = function (cx: PJSContext): Boolean; cdecl;
2554var JS_IsRunning: TJS_IsRunning external SpiderMonkeyLib name 'SM_IsRunning';
2555
2556/// Allocate space for a JavaScript string and its underlying storage,
2557// and copy n characters from a character array, s, into the new JSString
2558// Ansi version
2559type TJS_NewStringCopyN = function (cx: PJSContext; s: PCChar;
2560 n: size_t): PJSString; cdecl;
2561var JS_NewStringCopyN: TJS_NewStringCopyN external SpiderMonkeyLib name 'SM_NewStringCopyN';
2562
2563// TODO - recompile libsynsm with exported SM_AtomizeAndPinStringN
2564//type TJS_AtomizeAndPinStringN = function (cx: PJSContext; s: PCChar;
2565// n: size_t): PJSString; cdecl;
2566//var JS_AtomizeAndPinStringN: TJS_AtomizeAndPinStringN external SpiderMonkeyLib name 'SM_AtomizeAndPinStringN';
2567
2568
2569/// Allocate space for a JavaScript string and its underlying storage,
2570// and copy characters from NULL TERMINATED! UTF8 character array
2571type TJS_NewStringCopyUTF8Z = function (cx: PJSContext;
2572 pNullTerminatedUTF8: PUTF8Char): PJSString; cdecl;
2573var JS_NewStringCopyUTF8Z: TJS_NewStringCopyUTF8Z external SpiderMonkeyLib name 'SM_NewStringCopyUTF8Z';
2574
2575
2576/// Returns the empty JSString as a JS value
2577type TJS_GetEmptyStringValue = function (cx: PJSContext): jsval; cdecl;
2578var JS_GetEmptyStringValue: TJS_GetEmptyStringValue external SpiderMonkeyLib name 'SM_GetEmptyStringValue';
2579
2580/// Allocate space for a JavaScript string and its underlying storage,
2581// and copy n characters from a character array, s, into the new JSString
2582// Unicode version
2583type TJS_NewUCStringCopyN = function (cx: PJSContext; s: PCChar16;
2584 n: size_t): PJSString; cdecl;
2585var JS_NewUCStringCopyN: TJS_NewUCStringCopyN external SpiderMonkeyLib name 'SM_NewUCStringCopyN';
2586
2587/// Return the length of a JavaScript string.
2588type TJS_GetStringLength = function (str: PJSString): size_t; cdecl;
2589var JS_GetStringLength: TJS_GetStringLength external SpiderMonkeyLib name 'SM_GetStringLength';
2590
2591/// Return true if the string's characters are stored as Latin1.
2592type TJS_StringHasLatin1Chars = function (str: PJSString): boolean; cdecl;
2593var JS_StringHasLatin1Chars: TJS_StringHasLatin1Chars external SpiderMonkeyLib name 'SM_StringHasLatin1Chars';
2594
2595/// Return a pointer to the string, and store the length to *length
2596// Use it when characters are stored as Latin1.
2597type TJS_GetLatin1StringCharsAndLength = function (cx: PJSContext;
2598 nogc: PJSAutoCheckCannotGC; str: PJSString; plength: psize_t):PCChar; cdecl;
2599var JS_GetLatin1StringCharsAndLength: TJS_GetLatin1StringCharsAndLength external SpiderMonkeyLib name 'SM_GetLatin1StringCharsAndLength';
2600
2601/// Return a pointer to the string, and store the length to *length
2602// Use it when characters are stored as Unicode
2603type TJS_GetTwoByteStringCharsAndLength = function (cx: PJSContext;
2604 nogc: PJSAutoCheckCannotGC; str: PJSString; plength: psize_t): PCChar16; cdecl;
2605var JS_GetTwoByteStringCharsAndLength: TJS_GetTwoByteStringCharsAndLength external SpiderMonkeyLib name 'SM_GetTwoByteStringCharsAndLength';
2606
2607/// converts a value to JSON, optionally replacing values if a replacer
2608// function is specified, or optionally including only the specified properties
2609// if a replacer array is specified
2610type TJS_Stringify = function (cx: PJSContext; var vp: jsval;
2611 var replacer: PJSObject; var space: jsval; callback: JSONWriteCallback;
2612 data: pointer): Boolean; cdecl;
2613var JS_Stringify: TJS_Stringify external SpiderMonkeyLib name 'SM_Stringify';
2614
2615/// parse a string using the JSON syntax described in ECMAScript 5 and
2616// return the corresponding value into vp
2617type TJS_ParseJSON = function (cx: PJSContext; const chars: PCChar16;
2618 len: uint32; out vp: jsval): Boolean; cdecl;
2619var JS_ParseJSON: TJS_ParseJSON external SpiderMonkeyLib name 'SM_ParseJSON';
2620
2621/// Create a new JavaScript Error object and set it to be the pending exception on cx.
2622// The callback must then return JS_FALSE to cause the exception to be propagated
2623// to the calling script.
2624type TJS_ReportError = procedure (cx: PJSContext; const format: PCChar); cdecl; varargs;
2625var JS_ReportError: TJS_ReportError external SpiderMonkeyLib name 'SM_ReportErrorASCII';
2626
2627/// Report an error with an application-defined error code.
2628// - varargs is Additional arguments for the error message.
2629//- These arguments must be of type jschar*
2630// - The number of additional arguments required depends on the error
2631// message, which is determined by the errorCallback
2632type TJS_ReportErrorNumberUC = procedure (cx: PJSContext; errorCallback: JSErrorCallback;
2633 userRef: pointer; const erroNubmer: uintN); cdecl; varargs;
2634var JS_ReportErrorNumberUC: TJS_ReportErrorNumberUC external SpiderMonkeyLib name 'SM_ReportErrorNumberUC';
2635
2636type TJS_ReportErrorNumberUTF8 = procedure (cx: PJSContext;
2637 errorCallback: JSErrorCallback; userRef: pointer;
2638 const erroNubmer: uintN); cdecl; varargs;
2639var JS_ReportErrorNumberUTF8: TJS_ReportErrorNumberUTF8 external SpiderMonkeyLib name 'SM_ReportErrorNumberUTF8';
2640
2641/// Reports a memory allocation error
2642// - Call JS_ReportOutOfMemory to report that an operation failed because the
2643// system is out of memory
2644// - When the JavaScript engine tries to allocate memory and allocation fails,
2645// it reports an error as though by calling this function
2646type TJS_ReportOutOfMemory = procedure (cx: PJSContext); cdecl;
2647var JS_ReportOutOfMemory: TJS_ReportOutOfMemory external SpiderMonkeyLib name 'SM_ReportOutOfMemory';
2648
2649/// Get the warning reporting mechanism for an application. It is not working for errors.
2650type TJS_GetWarningReporter = function (cx: PJSContext): JSWarningReporter; cdecl;
2651var JS_GetWarningReporter: TJS_GetWarningReporter external SpiderMonkeyLib name 'SM_GetWarningReporter';
2652
2653/// Specify the warning reporting mechanism for an application. It is not working for errors.
2654type TJS_SetWarningReporter = function (cx: PJSContext;
2655 reporter: JSWarningReporter): JSWarningReporter; cdecl;
2656var JS_SetWarningReporter: TJS_SetWarningReporter external SpiderMonkeyLib name 'SM_SetWarningReporter';
2657
2658/// Create a new JavaScript date object
2659type TJS_NewDateObject = function (cx: PJSContext;
2660 year, mon, mday, hour, min, sec: int32): PJSObject; cdecl;
2661var JS_NewDateObject: TJS_NewDateObject external SpiderMonkeyLib name 'SM_NewDateObject';
2662
2663/// Create a new JavaScript date object from the Unix millisecond elapsed since EPOC
2664function JS_NewDateObjectMsec(cx: PJSContext; msec: double): PJSObject; cdecl;
2665 external SpiderMonkeyLib name 'SM_NewDateObjectMsec';
2666
2667// Returns true and sets |*isDate| indicating whether |obj| is a Date object or
2668// a wrapper around one, otherwise returns false on failure.
2669// - This method returns true with |*isDate == false| when passed a proxy whose
2670// target is a Date, or when passed a revoked proxy.
2671type TJS_ObjectIsDate = function (cx: PJSContext; var obj: PJSObject;
2672 out isDate: boolean): boolean; cdecl;
2673var JS_ObjectIsDate: TJS_ObjectIsDate external SpiderMonkeyLib name 'SM_ObjectIsDate';
2674
2675/// Determine whether an exception is pending in the JS engine.
2676type TJS_IsExceptionPending = function (cx: PJSContext): Boolean; cdecl;
2677var JS_IsExceptionPending: TJS_IsExceptionPending external SpiderMonkeyLib name 'SM_IsExceptionPending';
2678
2679/// Get the current pending exception for a given JSContext.
2680type TJS_GetPendingException = function (cx: PJSContext;
2681 out vp: jsval): Boolean; cdecl;
2682var JS_GetPendingException: TJS_GetPendingException external SpiderMonkeyLib name 'SM_GetPendingException';
2683
2684/// Sets the current exception being thrown within a context.
2685type TJS_SetPendingException = procedure (cx: PJSContext; var vp: jsval); cdecl;
2686var JS_SetPendingException: TJS_SetPendingException external SpiderMonkeyLib name 'SM_SetPendingException';
2687
2688/// Clear the currently pending exception in a context.
2689type TJS_ClearPendingException = procedure (cx: PJSContext); cdecl;
2690var JS_ClearPendingException: TJS_ClearPendingException external SpiderMonkeyLib name 'SM_ClearPendingException';
2691
2692/// If the given object is an exception object, the exception will have (or be
2693// able to lazily create) an error report struct, and this function will return
2694// the address of that struct. Otherwise, it returns nullptr. The lifetime
2695// of the error report struct that might be returned is the same as the
2696// lifetime of the exception object.
2697type TJS_ErrorFromException = function (cx: PJSContext;
2698 var obj: PJSObject): PJSErrorReport; cdecl;
2699var JS_ErrorFromException: TJS_ErrorFromException external SpiderMonkeyLib name 'SM_ErrorFromException';
2700
2701/// Get options of context
2702function JS_GetContextOptions(cx: PJSContext): PJSContextOptions; cdecl;
2703 external SpiderMonkeyLib name 'SM_GetContextOptions';
2704
2705//function JS_NewRootedValue(cx: PJSContext; val: jsval): PJSRootedValue; cdecl; external SpiderMonkeyLib;
2706function JS_NewRootedValue(cx: PJSContext; val: Int64): PJSRootedValue; cdecl;
2707 external SpiderMonkeyLib name 'SM_NewRootedValue';
2708
2709procedure JS_FreeRootedValue(val: PJSRootedValue); cdecl;
2710 external SpiderMonkeyLib name 'SM_FreeRootedValue';
2711
2712function JS_NewRootedObject(cx: PJSContext; obj: PJSObject): PJSRootedObject; cdecl;
2713 external SpiderMonkeyLib name 'SM_NewRootedObject';
2714
2715procedure JS_FreeRootedObject(obj: PJSRootedObject); cdecl;
2716 external SpiderMonkeyLib name 'SM_FreeRootedObject';
2717
2718function JS_NewRootedString(cx: PJSContext; obj: PJSString): PJSRootedString; cdecl;
2719 external SpiderMonkeyLib name 'SM_NewRootedString';
2720
2721procedure JS_FreeRootedString(str: PJSRootedString); cdecl;
2722 external SpiderMonkeyLib name 'SM_FreeRootedString';
2723
2724/// Create Compile Options
2725function JS_NewCompileOptions(cx: PJSContext): PJSCompileOptions; cdecl;
2726 external SpiderMonkeyLib name 'SM_NewCompileOptions';
2727
2728/// expose to Pascal
2729// JS::CompileOptions.setFileAndLine + setUTF8
2730procedure JS_SetCompileOptionsFileLineAndUtf8(co: PJSCompileOptions;
2731 const f: PChar; l: cardinal; isUtf8: boolean); cdecl;
2732 external SpiderMonkeyLib name 'SM_SetCompileOptionsFileLineAndUtf8';
2733
2734/// Free Compile Options
2735procedure JS_FreeCompileOptions(opt: PJSCompileOptions); cdecl;
2736 external SpiderMonkeyLib name 'SM_FreeCompileOptions';
2737///////////////////
2738
2739type TJS_EvaluateScript = function (cx: PJSContext;
2740 options: PJSCompileOptions; bytes: PCChar; length: size_t;
2741 out rval: jsval): Boolean; cdecl;
2742var JS_EvaluateScript: TJS_EvaluateScript external SpiderMonkeyLib name 'SM_EvaluateScript';
2743
2744type TJS_EvaluateUCScript = function (cx: PJSContext;
2745 options: PJSCompileOptions; chars: PCChar16; length: size_t;
2746 out rval: jsval): Boolean; cdecl;
2747var JS_EvaluateUCScript: TJS_EvaluateUCScript external SpiderMonkeyLib name 'SM_EvaluateUCScript';
2748
2749/// Compute |this| for the |vp| inside a JSNative, either boxing primitives or
2750// replacing with the global object as necessary.
2751// - This method will go away at some point: instead use |args.thisv()|. If the
2752// value is an object, no further work is required. If that value is |null| or
2753// |undefined|, use |JS_GetGlobalForObject| to compute the global object. If
2754// the value is some other primitive, use |JS_ValueToObject| to box it.
2755// - low-level API used by JS_THIS() macro.
2756//function JS_ComputeThis(cx: PJSContext; var vp: jsval): jsval; cdecl; external SpiderMonkeyLib;
2757type TJS_ComputeThis = function (cx: PJSContext; var vp: jsval): Int64; cdecl;
2758var JS_ComputeThis: TJS_ComputeThis external SpiderMonkeyLib name 'SM_ComputeThis';
2759
2760procedure strFinalizeOp(fin: PJSStringFinalizer; chars: PCChar16); cdecl;
2761const
2762 strFinalizer: JSStringFinalizer = (
2763 finalize: strFinalizeOp;
2764 );
2765
2766{ ArrayBuffer support from jsfriendapi.h}
2767
2768/// Create a new signed 8 bit integer typed array with nelements elements
2769// - will fill the newly created array with zeros
2770type TJS_NewInt8Array = function (cx: PJSContext;
2771 nelements: uint32): PJSObject; cdecl;
2772var JS_NewInt8Array: TJS_NewInt8Array external SpiderMonkeyLib name 'SM_NewInt8Array';
2773
2774/// Create a new unsigned 8 bit integer (byte) typed array with nelements elements
2775// - will fill the newly created array with zeros
2776type TJS_NewUint8Array = function (cx: PJSContext;
2777 nelements: uint32): PJSObject; cdecl;
2778var JS_NewUint8Array: TJS_NewUint8Array external SpiderMonkeyLib name 'SM_NewUint8Array';
2779
2780/// Create a new 8 bit integer typed array with nelements elements
2781// - will fill the newly created array with zeros
2782type TJS_NewUint8ClampedArray = function (cx: PJSContext;
2783 nelements: uint32): PJSObject; cdecl;
2784var JS_NewUint8ClampedArray: TJS_NewUint8ClampedArray external SpiderMonkeyLib name 'SM_NewUint8ClampedArray';
2785
2786/// Create a new signed 16 bit integer typed array with nelements elements
2787// - will fill the newly created array with zeros
2788type TJS_NewInt16Array = function (cx: PJSContext;
2789 nelements: uint32): PJSObject; cdecl;
2790var JS_NewInt16Array: TJS_NewInt16Array external SpiderMonkeyLib name 'SM_NewInt16Array';
2791
2792/// Create a new unsigned 16 bit integer typed array with nelements elements
2793// - will fill the newly created array with zeros
2794type TJS_NewUint16Array = function (cx: PJSContext;
2795 nelements: uint32): PJSObject; cdecl;
2796var JS_NewUint16Array: TJS_NewUint16Array external SpiderMonkeyLib name 'SM_NewUint16Array';
2797
2798/// Create a new signed 32 bit integer typed array with nelements elements
2799// - will fill the newly created array with zeros
2800type TJS_NewInt32Array = function (cx: PJSContext;
2801 nelements: uint32): PJSObject; cdecl;
2802var JS_NewInt32Array: TJS_NewInt32Array external SpiderMonkeyLib name 'SM_NewInt32Array';
2803
2804/// Create a new unsigned 32 bit integer typed array with nelements elements
2805// - will fill the newly created array with zeros
2806type TJS_NewUint32Array = function (cx: PJSContext;
2807 nelements: uint32): PJSObject; cdecl;
2808var JS_NewUint32Array: TJS_NewUint32Array external SpiderMonkeyLib name 'SM_NewUint32Array';
2809
2810/// Create a new signed 32 bit float (single) typed array with nelements elements
2811// - will fill the newly created array with zeros
2812type TJS_NewFloat32Array = function (cx: PJSContext;
2813 nelements: uint32): PJSObject; cdecl;
2814var JS_NewFloat32Array: TJS_NewFloat32Array external SpiderMonkeyLib name 'SM_NewFloat32Array';
2815
2816/// Create a new signed 64 bit float (double) typed array with nelements elements
2817// - will fill the newly created array with zeros
2818type TJS_NewFloat64Array = function (cx: PJSContext;
2819 nelements: uint32): PJSObject; cdecl;
2820var JS_NewFloat64Array: TJS_NewFloat64Array external SpiderMonkeyLib name 'SM_NewFloat64Array';
2821
2822/// Create a new 8 bit signed integer typed array and copy in values
2823// from a given object
2824// - The object is used as if it was an array; that is, the new array (if
2825// successfully created) will have length given by array.length, and its
2826// elements will be those specified by array[0], array[1], and so on, after
2827// conversion to the typed array element type.
2828type TJS_NewInt8ArrayFromArray = function (cx: PJSContext;
2829 var arr: PJSObject): PJSObject; cdecl;
2830var JS_NewInt8ArrayFromArray: TJS_NewInt8ArrayFromArray external SpiderMonkeyLib name 'SM_NewInt8ArrayFromArray';
2831
2832/// Create a new 8 bit unsigned integer typed array and copy in values
2833// from a given object
2834// - The object is used as if it was an array; that is, the new array (if
2835// successfully created) will have length given by array.length, and its
2836// elements will be those specified by array[0], array[1], and so on, after
2837// conversion to the typed array element type.
2838type TJS_NewUint8ArrayFromArray = function (cx: PJSContext;
2839 var arr: PJSObject): PJSObject; cdecl;
2840var JS_NewUint8ArrayFromArray: TJS_NewUint8ArrayFromArray external SpiderMonkeyLib name 'SM_NewUint8ArrayFromArray';
2841
2842/// Create a new 8 bit unsigned integer typed array and copy in values
2843// from a given object
2844// - The object is used as if it was an array; that is, the new array (if
2845// successfully created) will have length given by array.length, and its
2846// elements will be those specified by array[0], array[1], and so on, after
2847// conversion to the typed array element type.
2848type TJS_NewUint8ClampedArrayFromArray = function (cx: PJSContext;
2849 var arr: PJSObject): PJSObject; cdecl;
2850var JS_NewUint8ClampedArrayFromArray: TJS_NewUint8ClampedArrayFromArray external SpiderMonkeyLib name 'SM_NewUint8ClampedArrayFromArray';
2851
2852/// Create a new 16 bit signed integer typed array and copy in values
2853// from a given object
2854// - The object is used as if it was an array; that is, the new array (if
2855// successfully created) will have length given by array.length, and its
2856// elements will be those specified by array[0], array[1], and so on, after
2857// conversion to the typed array element type.
2858type TJS_NewInt16ArrayFromArray = function (cx: PJSContext;
2859 var arr: PJSObject): PJSObject; cdecl;
2860var JS_NewInt16ArrayFromArray: TJS_NewInt16ArrayFromArray external SpiderMonkeyLib name 'SM_NewInt16ArrayFromArray';
2861
2862/// Create a new 16 bit unsigned integer typed array and copy in values
2863// from a given object
2864// - The object is used as if it was an array; that is, the new array (if
2865// successfully created) will have length given by array.length, and its
2866// elements will be those specified by array[0], array[1], and so on, after
2867// conversion to the typed array element type.
2868type TJS_NewUint16ArrayFromArray = function (cx: PJSContext;
2869 var arr: PJSObject): PJSObject; cdecl;
2870var JS_NewUint16ArrayFromArray: TJS_NewUint16ArrayFromArray external SpiderMonkeyLib name 'SM_NewUint16ArrayFromArray';
2871
2872/// Create a new 32 bit signed integer typed array and copy in values
2873// from a given object
2874// - The object is used as if it was an array; that is, the new array (if
2875// successfully created) will have length given by array.length, and its
2876// elements will be those specified by array[0], array[1], and so on, after
2877// conversion to the typed array element type.
2878type TJS_NewInt32ArrayFromArray = function (cx: PJSContext;
2879 var arr: PJSObject): PJSObject; cdecl;
2880var JS_NewInt32ArrayFromArray: TJS_NewInt32ArrayFromArray external SpiderMonkeyLib name 'SM_NewInt32ArrayFromArray';
2881
2882/// Create a new 32 bit unsigned integer typed array and copy in values
2883// from a given object
2884// - The object is used as if it was an array; that is, the new array (if
2885// successfully created) will have length given by array.length, and its
2886// elements will be those specified by array[0], array[1], and so on, after
2887// conversion to the typed array element type.
2888type TJS_NewUint32ArrayFromArray = function (cx: PJSContext;
2889 var arr: PJSObject): PJSObject; cdecl;
2890var JS_NewUint32ArrayFromArray: TJS_NewUint32ArrayFromArray external SpiderMonkeyLib name 'SM_NewUint32ArrayFromArray';
2891
2892/// Create a new 32 bit float (single) typed array and copy in values
2893// from a given object
2894// - The object is used as if it was an array; that is, the new array (if
2895// successfully created) will have length given by array.length, and its
2896// elements will be those specified by array[0], array[1], and so on, after
2897// conversion to the typed array element type.
2898type TJS_NewFloat32ArrayFromArray = function (cx: PJSContext;
2899 var arr: PJSObject): PJSObject; cdecl;
2900var JS_NewFloat32ArrayFromArray: TJS_NewFloat32ArrayFromArray external SpiderMonkeyLib name 'SM_NewFloat32ArrayFromArray';
2901
2902/// Create a new 64 bit float (double) typed array and copy in values
2903// from a given object
2904// - The object is used as if it was an array; that is, the new array (if
2905// successfully created) will have length given by array.length, and its
2906// elements will be those specified by array[0], array[1], and so on, after
2907// conversion to the typed array element type.
2908type TJS_NewFloat64ArrayFromArray = function (cx: PJSContext;
2909 var arr: PJSObject): PJSObject; cdecl;
2910var JS_NewFloat64ArrayFromArray: TJS_NewFloat64ArrayFromArray external SpiderMonkeyLib name 'SM_NewFloat64ArrayFromArray';
2911
2912/// Create a new 8 bit signed integer typed array using the given
2913// ArrayBuffer for storage
2914// - The length value is optional; if -1 is passed, enough elements to use up the
2915// remainder of the byte array is used as the default value
2916type TJS_NewInt8ArrayWithBuffer = function (cx: PJSContext;
2917 var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject; cdecl;
2918var JS_NewInt8ArrayWithBuffer: TJS_NewInt8ArrayWithBuffer external SpiderMonkeyLib name 'SM_NewInt8ArrayWithBuffer';
2919
2920/// Create a new 8 bit unsigned integer typed array using the given
2921// ArrayBuffer for storage
2922// - The length value is optional; if -1 is passed, enough elements to use up the
2923// remainder of the byte array is used as the default value
2924type TJS_NewUint8ArrayWithBuffer = function (cx: PJSContext;
2925 var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject; cdecl;
2926var JS_NewUint8ArrayWithBuffer: TJS_NewUint8ArrayWithBuffer external SpiderMonkeyLib name 'SM_NewUint8ArrayWithBuffer';
2927
2928/// Create a new 8 bit unsigned integer typed array using the given
2929// ArrayBuffer for storage
2930// - The length value is optional; if -1 is passed, enough elements to use up the
2931// remainder of the byte array is used as the default value
2932type TJS_NewUint8ClampedArrayWithBuffer = function (cx: PJSContext;
2933 var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject; cdecl;
2934var JS_NewUint8ClampedArrayWithBuffer: TJS_NewUint8ClampedArrayWithBuffer external SpiderMonkeyLib name 'SM_NewUint8ClampedArrayWithBuffer';
2935
2936/// Create a new 16 bit signed integer typed array using the given
2937// ArrayBuffer for storage
2938// - The length value is optional; if -1 is passed, enough elements to use up the
2939// remainder of the byte array is used as the default value
2940type TJS_NewInt16ArrayWithBuffer = function (cx: PJSContext;
2941 var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject; cdecl;
2942var JS_NewInt16ArrayWithBuffer: TJS_NewInt16ArrayWithBuffer external SpiderMonkeyLib name 'SM_NewInt16ArrayWithBuffer';
2943
2944/// Create a new 16 bit unsigned integer typed array using the given
2945// ArrayBuffer for storage
2946// - The length value is optional; if -1 is passed, enough elements to use up the
2947// remainder of the byte array is used as the default value
2948type TJS_NewUint16ArrayWithBuffer = function (cx: PJSContext;
2949 var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject; cdecl;
2950var JS_NewUint16ArrayWithBuffer: TJS_NewUint16ArrayWithBuffer external SpiderMonkeyLib name 'SM_NewUint16ArrayWithBuffer';
2951
2952/// Create a new 32 bit signed integer typed array using the given
2953// ArrayBuffer for storage
2954// - The length value is optional; if -1 is passed, enough elements to use up the
2955// remainder of the byte array is used as the default value
2956type TJS_NewInt32ArrayWithBuffer = function (cx: PJSContext;
2957 var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject; cdecl;
2958var JS_NewInt32ArrayWithBuffer: TJS_NewInt32ArrayWithBuffer external SpiderMonkeyLib name 'SM_NewInt32ArrayWithBuffer';
2959
2960/// Create a new 32 bit unsigned integer typed array using the given
2961// ArrayBuffer for storage
2962// - The length value is optional; if -1 is passed, enough elements to use up the
2963// remainder of the byte array is used as the default value
2964type TJS_NewUint32ArrayWithBuffer = function (cx: PJSContext;
2965 var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject; cdecl;
2966var JS_NewUint32ArrayWithBuffer: TJS_NewUint32ArrayWithBuffer external SpiderMonkeyLib name 'SM_NewUint32ArrayWithBuffer';
2967
2968/// Create a new 32 bit float (single) typed array using the given
2969// ArrayBuffer for storage
2970// - The length value is optional; if -1 is passed, enough elements to use up the
2971// remainder of the byte array is used as the default value
2972type TJS_NewFloat32ArrayWithBuffer = function (cx: PJSContext;
2973 var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject; cdecl;
2974var JS_NewFloat32ArrayWithBuffer: TJS_NewFloat32ArrayWithBuffer external SpiderMonkeyLib name 'SM_NewFloat32ArrayWithBuffer';
2975
2976/// Create a new 64 bit float (double) typed array using the given
2977// ArrayBuffer for storage
2978// - The length value is optional; if -1 is passed, enough elements to use up the
2979// remainder of the byte array is used as the default value
2980type TJS_NewFloat64ArrayWithBuffer = function (cx: PJSContext;
2981 var arrayBuffer: PJSObject; byteOffset: uint32; length: int32): PJSObject; cdecl;
2982var JS_NewFloat64ArrayWithBuffer: TJS_NewFloat64ArrayWithBuffer external SpiderMonkeyLib name 'SM_NewFloat64ArrayWithBuffer';
2983
2984/// Create a new SharedArrayBuffer with the given byte length.
2985type TJS_NewSharedArrayBuffer = function (cx: PJSContext;
2986 nbytes: uint32): PJSObject; cdecl;
2987var JS_NewSharedArrayBuffer: TJS_NewSharedArrayBuffer external SpiderMonkeyLib name 'SM_NewSharedArrayBuffer';
2988
2989/// Create a new ArrayBuffer with the given byte length.
2990type TJS_NewArrayBuffer = function (cx: PJSContext;
2991 nbytes: uint32): PJSObject; cdecl;
2992var JS_NewArrayBuffer: TJS_NewArrayBuffer external SpiderMonkeyLib name 'SM_NewArrayBuffer';
2993
2994/// Check whether obj supports JS_GetTypedArray* APIs
2995// - Note that this may return false if a security wrapper is encountered that
2996// denies the unwrapping.
2997// - if this test or one of the JS_Is*Array tests succeeds, then it is safe to call
2998// the dedicated accessor JSAPI calls
2999type TJS_IsTypedArrayObject = function (obj: PJSObject): Boolean; cdecl;
3000var JS_IsTypedArrayObject: TJS_IsTypedArrayObject external SpiderMonkeyLib name 'SM_IsTypedArrayObject';
3001
3002/// Check whether obj supports JS_GetArrayBufferView* APIs
3003// - Note that this may return false if a security wrapper is encountered that
3004// denies the unwrapping.
3005// - if this test or one of the JS_Is*Array tests succeeds, then it is safe to call
3006// the dedicated ArrayBufferView accessor JSAPI calls
3007type TJS_IsArrayBufferViewObject = function (obj: PJSObject): Boolean; cdecl;
3008var JS_IsArrayBufferViewObject: TJS_IsArrayBufferViewObject external SpiderMonkeyLib name 'SM_IsArrayBufferViewObject';
3009
3010/// Test for specific 8 bit signed integer typed array types (ArrayBufferView subtypes)
3011type TJS_IsInt8Array = function (obj: PJSObject): Boolean; cdecl;
3012var JS_IsInt8Array: TJS_IsInt8Array external SpiderMonkeyLib name 'SM_IsInt8Array';
3013
3014/// Test for specific 8 bit unsigned integer typed array types (ArrayBufferView subtypes)
3015type TJS_IsUint8Array = function (obj: PJSObject): Boolean; cdecl;
3016var JS_IsUint8Array: TJS_IsUint8Array external SpiderMonkeyLib name 'SM_IsUint8Array';
3017
3018/// Test for specific 8 bit unsigned integer typed array types (ArrayBufferView subtypes)
3019type TJS_IsUint8ClampedArray = function (obj: PJSObject): Boolean; cdecl;
3020var JS_IsUint8ClampedArray: TJS_IsUint8ClampedArray external SpiderMonkeyLib name 'SM_IsUint8ClampedArray';
3021
3022/// Test for specific 16 bit signed integer typed array types (ArrayBufferView subtypes)
3023type TJS_IsInt16Array = function (obj: PJSObject): Boolean; cdecl;
3024var JS_IsInt16Array: TJS_IsInt16Array external SpiderMonkeyLib name 'SM_IsInt16Array';
3025
3026/// Test for specific 16 bit unsigned integer typed array types (ArrayBufferView subtypes)
3027type TJS_IsUint16Array = function (obj: PJSObject): Boolean; cdecl;
3028var JS_IsUint16Array: TJS_IsUint16Array external SpiderMonkeyLib name 'SM_IsUint16Array';
3029
3030/// Test for specific 32 bit signed integer typed array types (ArrayBufferView subtypes)
3031type TJS_IsInt32Array = function (obj: PJSObject): Boolean; cdecl;
3032var JS_IsInt32Array: TJS_IsInt32Array external SpiderMonkeyLib name 'SM_IsInt32Array';
3033
3034/// Test for specific 32 bit unsigned integer typed array types (ArrayBufferView subtypes)
3035type TJS_IsUint32Array = function (obj: PJSObject): Boolean; cdecl;
3036var JS_IsUint32Array: TJS_IsUint32Array external SpiderMonkeyLib name 'SM_IsUint32Array';
3037
3038/// Test for specific 32 bit float (single) typed array types (ArrayBufferView subtypes)
3039type TJS_IsFloat32Array = function (obj: PJSObject): Boolean; cdecl;
3040var JS_IsFloat32Array: TJS_IsFloat32Array external SpiderMonkeyLib name 'SM_IsFloat32Array';
3041
3042/// Test for specific 64 bit float (double) typed array types (ArrayBufferView subtypes)
3043type TJS_IsFloat64Array = function (obj: PJSObject): Boolean; cdecl;
3044var JS_IsFloat64Array: TJS_IsFloat64Array external SpiderMonkeyLib name 'SM_IsFloat64Array';
3045
3046/// Return the isShared flag of a typed array, which denotes whether
3047// the underlying buffer is a SharedArrayBuffer.
3048//
3049// |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow
3050// be known that it would pass such a test: it is a typed array or a wrapper of
3051// a typed array, and the unwrapping will succeed.
3052type TJS_GetTypedArraySharedness = function (obj: PJSObject): Boolean; cdecl;
3053var JS_GetTypedArraySharedness: TJS_GetTypedArraySharedness external SpiderMonkeyLib name 'SM_GetTypedArraySharedness';
3054
3055/// Unwrap 8 bit signed integer typed array into direct memory buffer
3056// - Return nil without throwing any exception if the object cannot be viewed as the
3057// correct typed array, or the typed array object on success, filling both out parameters
3058type TJS_GetObjectAsInt8Array = function (obj: PJSObject; out length: uint32;
3059 out isSharedMemory:Boolean; out Data: Pint8Vector): PJSObject; cdecl;
3060var JS_GetObjectAsInt8Array: TJS_GetObjectAsInt8Array external SpiderMonkeyLib name 'SM_GetObjectAsInt8Array';
3061
3062/// Unwrap 8 bit unsigned integer typed array into direct memory buffer
3063// - Return nil without throwing any exception if the object cannot be viewed as the
3064// correct typed array, or the typed array object on success, filling both out parameters
3065type TJS_GetObjectAsUint8Array = function (obj: PJSObject; out length: uint32;
3066 out isSharedMemory:Boolean; out Data: Puint8Vector): PJSObject; cdecl;
3067var JS_GetObjectAsUint8Array: TJS_GetObjectAsUint8Array external SpiderMonkeyLib name 'SM_GetObjectAsUint8Array';
3068
3069/// Unwrap 8 bit unsigned integer typed array into direct memory buffer
3070// - Return nil without throwing any exception if the object cannot be viewed as the
3071// correct typed array, or the typed array object on success, filling both out parameters
3072type TJS_GetObjectAsUint8ClampedArray = function (obj: PJSObject;
3073 out length: uint32; out isSharedMemory:Boolean;
3074 out Data: Puint8Vector): PJSObject; cdecl;
3075var JS_GetObjectAsUint8ClampedArray: TJS_GetObjectAsUint8ClampedArray external SpiderMonkeyLib name 'SM_GetObjectAsUint8ClampedArray';
3076
3077/// Unwrap 16 bit signed integer typed array into direct memory buffer
3078// - Return nil without throwing any exception if the object cannot be viewed as the
3079// correct typed array, or the typed array object on success, filling both out parameters
3080type TJS_GetObjectAsInt16Array = function (obj: PJSObject;
3081 out length: uint32; out isSharedMemory:Boolean;
3082 out Data: Pint16Vector): PJSObject; cdecl;
3083var JS_GetObjectAsInt16Array: TJS_GetObjectAsInt16Array external SpiderMonkeyLib name 'SM_GetObjectAsInt16Array';
3084
3085/// Unwrap 16 bit unsigned integer typed array into direct memory buffer
3086// - Return nil without throwing any exception if the object cannot be viewed as the
3087// correct typed array, or the typed array object on success, filling both out parameters
3088type TJS_GetObjectAsUint16Array = function (obj: PJSObject; out length: uint32;
3089 out isSharedMemory:Boolean; out Data: Puint16Vector): PJSObject; cdecl;
3090var JS_GetObjectAsUint16Array: TJS_GetObjectAsUint16Array external SpiderMonkeyLib name 'SM_GetObjectAsUint16Array';
3091
3092/// Unwrap 32 bit signed integer typed array into direct memory buffer
3093// - Return nil without throwing any exception if the object cannot be viewed as the
3094// correct typed array, or the typed array object on success, filling both out parameters
3095type TJS_GetObjectAsInt32Array = function (obj: PJSObject; out length: uint32;
3096 out isSharedMemory:Boolean; out Data: Pint32Vector): PJSObject; cdecl;
3097var JS_GetObjectAsInt32Array: TJS_GetObjectAsInt32Array external SpiderMonkeyLib name 'SM_GetObjectAsInt32Array';
3098
3099/// Unwrap 32 bit unsigned integer typed array into direct memory buffer
3100// - Return nil without throwing any exception if the object cannot be viewed as the
3101// correct typed array, or the typed array object on success, filling both out parameters
3102type TJS_GetObjectAsUint32Array = function (obj: PJSObject; out length: uint32;
3103 out isSharedMemory:Boolean; out Data: Puint32Vector): PJSObject; cdecl;
3104var JS_GetObjectAsUint32Array: TJS_GetObjectAsUint32Array external SpiderMonkeyLib name 'SM_GetObjectAsUint32Array';
3105
3106/// Unwrap 32 bit float (single) typed array into direct memory buffer
3107// - Return nil without throwing any exception if the object cannot be viewed as the
3108// correct typed array, or the typed array object on success, filling both out parameters
3109type TJS_GetObjectAsFloat32Array = function (obj: PJSObject; out length: uint32;
3110 out isSharedMemory:Boolean; out Data: Pfloat32Vector): PJSObject; cdecl;
3111var JS_GetObjectAsFloat32Array: TJS_GetObjectAsFloat32Array external SpiderMonkeyLib name 'SM_GetObjectAsFloat32Array';
3112
3113/// Unwrap 64 bit float (double) typed array into direct memory buffer
3114// - Return nil without throwing any exception if the object cannot be viewed as the
3115// correct typed array, or the typed array object on success, filling both out parameters
3116type TJS_GetObjectAsFloat64Array = function (obj: PJSObject; out length: uint32;
3117 out isSharedMemory:Boolean; out Data: Pfloat64Vector): PJSObject; cdecl;
3118var JS_GetObjectAsFloat64Array: TJS_GetObjectAsFloat64Array external SpiderMonkeyLib name 'SM_GetObjectAsFloat64Array';
3119
3120/// Unwrap an object as its raw binary memory buffer
3121// - Return nil without throwing any exception if the object cannot be viewed as the
3122// correct typed array, or the typed array object on success, filling both out parameters
3123type TJS_GetObjectAsArrayBufferView = function (obj: PJSObject;
3124 out length: uint32; out isSharedMemory:Boolean;
3125 out Data: Puint8Vector): PJSObject; cdecl;
3126var JS_GetObjectAsArrayBufferView: TJS_GetObjectAsArrayBufferView external SpiderMonkeyLib name 'SM_GetObjectAsArrayBufferView';
3127
3128/// Unwrap an object as its raw binary memory buffer
3129// - Return nil without throwing any exception if the object cannot be viewed as the
3130// correct typed array, or the typed array object on success, filling both out parameters
3131type TJS_GetObjectAsArrayBuffer = function (obj: PJSObject; out length: uint32;
3132 out Data: Puint8Vector): PJSObject; cdecl;
3133var JS_GetObjectAsArrayBuffer: TJS_GetObjectAsArrayBuffer external SpiderMonkeyLib name 'SM_GetObjectAsArrayBuffer';
3134
3135 /// Get the type of elements in a typed array, or jsabTYPE_DATAVIEW if a DataView
3136type TJS_GetArrayBufferViewType = function (
3137 obj: PJSObject): JSArrayBufferViewType; cdecl;
3138var JS_GetArrayBufferViewType: TJS_GetArrayBufferViewType external SpiderMonkeyLib name 'SM_GetArrayBufferViewType';
3139
3140/// Check whether obj supports the JS_GetArrayBuffer* APIs
3141// - Note that this may return false if a security wrapper is encountered that denies the
3142// unwrapping
3143// - If this test succeeds, then it is safe to call the various accessor JSAPI calls
3144type TJS_IsArrayBufferObject = function (obj: PJSObject): Boolean; cdecl;
3145var JS_IsArrayBufferObject: TJS_IsArrayBufferObject external SpiderMonkeyLib name 'SM_IsArrayBufferObject';
3146
3147type TJS_IsSharedArrayBufferObject = function (obj: PJSObject): Boolean; cdecl;
3148var JS_IsSharedArrayBufferObject: TJS_IsSharedArrayBufferObject external SpiderMonkeyLib name 'SM_IsSharedArrayBufferObject';
3149
3150/// Return the available byte length of an array buffer
3151// - obj must have passed a JS_IsArrayBufferObject test, or somehow be known
3152// that it would pass such a test: it is an ArrayBuffer or a wrapper of an
3153// ArrayBuffer, and the unwrapping will succeed
3154type TJS_GetArrayBufferByteLength = function (obj: PJSObject): uint32; cdecl;
3155var JS_GetArrayBufferByteLength: TJS_GetArrayBufferByteLength external SpiderMonkeyLib name 'SM_GetArrayBufferByteLength';
3156
3157type TJS_GetSharedArrayBufferByteLength = function (
3158 obj: PJSObject): uint32; cdecl;
3159var JS_GetSharedArrayBufferByteLength: TJS_GetSharedArrayBufferByteLength external SpiderMonkeyLib name 'SM_GetSharedArrayBufferByteLength';
3160
3161/// Return true if the arrayBuffer contains any data. This will return false for
3162// ArrayBuffer.prototype and neutered ArrayBuffers.
3163//
3164// |obj| must have passed a JS_IsArrayBufferObject test, or somehow be known
3165// that it would pass such a test: it is an ArrayBuffer or a wrapper of an
3166// ArrayBuffer, and the unwrapping will succeed.
3167type TJS_ArrayBufferHasData = function (obj: PJSObject): Boolean; cdecl;
3168var JS_ArrayBufferHasData: TJS_ArrayBufferHasData external SpiderMonkeyLib name 'SM_ArrayBufferHasData';
3169
3170/// Return a pointer to an array buffer's data
3171// - The buffer is still owned by the array buffer object, and should not
3172// be modified on another thread. The returned pointer is stable across GCs
3173// - obj must have passed a JS_IsArrayBufferObject test, or somehow be known
3174// that it would pass such a test: it is an ArrayBuffer or a wrapper of an
3175// ArrayBuffer, and the unwrapping will succeed.
3176type TJS_GetArrayBufferData = function (obj: PJSObject;
3177 out isSharedMemory: Boolean;
3178 nogc: PJSAutoCheckCannotGC{Not used in SM code}): Puint8Vector; cdecl;
3179var JS_GetArrayBufferData: TJS_GetArrayBufferData external SpiderMonkeyLib name 'SM_GetArrayBufferData';
3180
3181/// Check whether the obj is ArrayBufferObject and memory mapped. Note that this
3182// may return false if a security wrapper is encountered that denies the
3183// unwrapping.
3184type TJS_IsMappedArrayBufferObject = function (obj: PJSObject): Boolean; cdecl;
3185var JS_IsMappedArrayBufferObject: TJS_IsMappedArrayBufferObject external SpiderMonkeyLib name 'SM_IsMappedArrayBufferObject';
3186
3187/// Return the number of elements in a typed array
3188// - obj must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow
3189// be known that it would pass such a test: it is a typed array or a wrapper of
3190// a typed array, and the unwrapping will succeed.
3191type TJS_GetTypedArrayLength = function (obj: PJSObject): uint32; cdecl;
3192var JS_GetTypedArrayLength: TJS_GetTypedArrayLength external SpiderMonkeyLib name 'SM_GetTypedArrayLength';
3193
3194/// Return the byte offset from the start of an array buffer to the start of a
3195// typed array view
3196// - obj must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow
3197// be known that it would pass such a test: it is a typed array or a wrapper of
3198// a typed array, and the unwrapping will succeed.
3199type TJS_GetTypedArrayByteOffset = function (obj: PJSObject): uint32; cdecl;
3200var JS_GetTypedArrayByteOffset: TJS_GetTypedArrayByteOffset external SpiderMonkeyLib name 'SM_GetTypedArrayByteOffset';
3201
3202/// Return the byte length of a typed array
3203// - obj must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow
3204// be known that it would pass such a test: it is a typed array or a wrapper of
3205// a typed array, and the unwrapping will succeed
3206type TJS_GetTypedArrayByteLength = function (obj: PJSObject): uint32; cdecl;
3207var JS_GetTypedArrayByteLength: TJS_GetTypedArrayByteLength external SpiderMonkeyLib name 'SM_GetTypedArrayByteLength';
3208
3209/// More generic name for JS_GetTypedArrayByteLength to cover DataViews as well
3210type TJS_GetArrayBufferViewByteLength = function (obj: PJSObject): uint32; cdecl;
3211var JS_GetArrayBufferViewByteLength: TJS_GetArrayBufferViewByteLength external SpiderMonkeyLib name 'SM_GetArrayBufferViewByteLength';
3212
3213/// Return a pointer to the start of the data referenced by a typed 8 bit signed integer array
3214// - The data is still owned by the typed array, and should not be modified on
3215// another thread
3216// - obj must have passed a JS_Is*Array test, or somehow be known that it would
3217// pass such a test: it is a typed array or a wrapper of a typed array, and the
3218// unwrapping will succeed
3219type TJS_GetInt8ArrayData = function (obj: PJSObject;
3220 out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Pint8Vector; cdecl;
3221var JS_GetInt8ArrayData: TJS_GetInt8ArrayData external SpiderMonkeyLib name 'SM_GetInt8ArrayData';
3222
3223/// Return a pointer to the start of the data referenced by a typed 8 bit unsigned integer array
3224// - The data is still owned by the typed array, and should not be modified on
3225// another thread
3226// - obj must have passed a JS_Is*Array test, or somehow be known that it would
3227// pass such a test: it is a typed array or a wrapper of a typed array, and the
3228// unwrapping will succeed
3229type TJS_GetUint8ArrayData = function (obj: PJSObject;
3230 out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Puint8Vector; cdecl;
3231var JS_GetUint8ArrayData: TJS_GetUint8ArrayData external SpiderMonkeyLib name 'SM_GetUint8ArrayData';
3232
3233/// Return a pointer to the start of the data referenced by a typed 8 bit unsigned integer array
3234// - The data is still owned by the typed array, and should not be modified on
3235// another thread
3236// - obj must have passed a JS_Is*Array test, or somehow be known that it would
3237// pass such a test: it is a typed array or a wrapper of a typed array, and the
3238// unwrapping will succeed
3239type TJS_GetUint8ClampedArrayData = function (obj: PJSObject;
3240 out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Puint8Vector; cdecl;
3241var JS_GetUint8ClampedArrayData: TJS_GetUint8ClampedArrayData external SpiderMonkeyLib name 'SM_GetUint8ClampedArrayData';
3242
3243/// Return a pointer to the start of the data referenced by a typed 16 bit signed integer array
3244// - The data is still owned by the typed array, and should not be modified on
3245// another thread
3246// - obj must have passed a JS_Is*Array test, or somehow be known that it would
3247// pass such a test: it is a typed array or a wrapper of a typed array, and the
3248// unwrapping will succeed
3249type TJS_GetInt16ArrayData = function (obj: PJSObject;
3250 out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Pint16Vector; cdecl;
3251var JS_GetInt16ArrayData: TJS_GetInt16ArrayData external SpiderMonkeyLib name 'SM_GetInt16ArrayData';
3252
3253/// Return a pointer to the start of the data referenced by a typed 16 bit unsigned integer array
3254// - The data is still owned by the typed array, and should not be modified on
3255// another thread
3256// - obj must have passed a JS_Is*Array test, or somehow be known that it would
3257// pass such a test: it is a typed array or a wrapper of a typed array, and the
3258// unwrapping will succeed
3259type TJS_GetUint16ArrayData = function (obj: PJSObject;
3260 out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Puint16Vector; cdecl;
3261var JS_GetUint16ArrayData: TJS_GetUint16ArrayData external SpiderMonkeyLib name 'SM_GetUint16ArrayData';
3262
3263/// Return a pointer to the start of the data referenced by a typed 32 bit signed integer array
3264// - The data is still owned by the typed array, and should not be modified on
3265// another thread
3266// - obj must have passed a JS_Is*Array test, or somehow be known that it would
3267// pass such a test: it is a typed array or a wrapper of a typed array, and the
3268// unwrapping will succeed
3269type TJS_GetInt32ArrayData = function (obj: PJSObject;
3270 out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Pint32Vector; cdecl;
3271var JS_GetInt32ArrayData: TJS_GetInt32ArrayData external SpiderMonkeyLib name 'SM_GetInt32ArrayData';
3272
3273/// Return a pointer to the start of the data referenced by a typed 32 bit unsigned integer array
3274// - The data is still owned by the typed array, and should not be modified on
3275// another thread
3276// - obj must have passed a JS_Is*Array test, or somehow be known that it would
3277// pass such a test: it is a typed array or a wrapper of a typed array, and the
3278// unwrapping will succeed
3279type TJS_GetUint32ArrayData = function (obj: PJSObject;
3280 out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Puint32Vector; cdecl;
3281var JS_GetUint32ArrayData: TJS_GetUint32ArrayData external SpiderMonkeyLib name 'SM_GetUint32ArrayData';
3282
3283/// Return a pointer to the start of the data referenced by a typed 32 bit float (single) array
3284// - The data is still owned by the typed array, and should not be modified on
3285// another thread
3286// - obj must have passed a JS_Is*Array test, or somehow be known that it would
3287// pass such a test: it is a typed array or a wrapper of a typed array, and the
3288// unwrapping will succeed
3289type TJS_GetFloat32ArrayData = function (obj: PJSObject;
3290 out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Pfloat32Vector; cdecl;
3291var JS_GetFloat32ArrayData: TJS_GetFloat32ArrayData external SpiderMonkeyLib name 'SM_GetFloat32ArrayData';
3292
3293/// Return a pointer to the start of the data referenced by a typed 64 bit float (double) array
3294// - The data is still owned by the typed array, and should not be modified on
3295// another thread
3296// - obj must have passed a JS_Is*Array test, or somehow be known that it would
3297// pass such a test: it is a typed array or a wrapper of a typed array, and the
3298// unwrapping will succeed
3299type TJS_GetFloat64ArrayData = function (obj: PJSObject;
3300 out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Pfloat64Vector; cdecl;
3301var JS_GetFloat64ArrayData: TJS_GetFloat64ArrayData external SpiderMonkeyLib name 'SM_GetFloat64ArrayData';
3302
3303/// Return a pointer to the start of the data referenced by any typed array
3304// - The data is still owned by the typed array, and should not be modified on
3305// another thread
3306// - obj must have passed a JS_Is*Array test, or somehow be known that it would
3307// pass such a test: it is a typed array or a wrapper of a typed array, and the
3308// unwrapping will succeed
3309// - Prefer the type-specific versions when possible
3310type TJS_GetArrayBufferViewData = function (obj: PJSObject;
3311 out isSharedMemory: Boolean; nogc: PJSAutoCheckCannotGC): Pointer; cdecl;
3312var JS_GetArrayBufferViewData: TJS_GetArrayBufferViewData external SpiderMonkeyLib name 'SM_GetArrayBufferViewData';
3313
3314/// Return the ArrayBuffer underlying an ArrayBufferView
3315// - If the buffer has been neutered, this will still return the neutered buffer.
3316// - obj must be an object that would return true for JS_IsArrayBufferViewObject()
3317type TJS_GetArrayBufferViewBuffer = function (cx: PJSContext;
3318 var obj: PJSObject; out isSharedMemory: Boolean): PJSObject; cdecl;
3319var JS_GetArrayBufferViewBuffer: TJS_GetArrayBufferViewBuffer external SpiderMonkeyLib name 'SM_GetArrayBufferViewBuffer';
3320
3321////modules
3322
3323/// Initialize modeles classes next 2 functions cannot work without calling this function !!! EMPTY !!!
3324function JS_InitModuleClasses(cx: PJSContext; var obj: PJSObject): boolean; cdecl; external SpiderMonkeyLib name 'SM_InitModuleClasses';
3325
3326/// Compile script as module
3327function JS_CompileModule(cx: PJSContext;
3328 var obj: PJSObject;
3329 options: PJSCompileOptions;
3330 chars: PCChar16; length: size_t): PJSObject; cdecl; external SpiderMonkeyLib name 'SM_CompileModule';
3331
3332/// Set handler for module resolving
3333type TJS_SetModuleResolveHook = procedure (cx: PJSContext; var hook: PJSFunction); cdecl;
3334var JS_SetModuleResolveHook: TJS_SetModuleResolveHook external SpiderMonkeyLib name 'SM_SetModuleResolveHook';
3335
3336type
3337 pjsval = ^jsval;
3338
3339var
3340 /// global TSynAnsiConvert instance to handle LATIN1(ISO/IEC 8859-1) encoding
3341 // - this instance is global and instantied during the whole program life time
3342 // - Spidermonkey internal encoding is LATIN1 or UTF-16
3343 Latin1AnsiConvert: TSynAnsiConvert;
3344
3345implementation
3346
3347uses
3348 Variants;
3349
3350const
3351 JSVAL_INT_MAX = int32($7fffffff);
3352
3353procedure JSError(cx: PJSContext; aException: Exception);
3354var
3355 ws: WideString;
3356begin
3357 if not JS_IsExceptionPending(cx) then
3358 // raise only if this is the first exception in chain
3359 if aException is EOutOfMemory then
3360 JS_ReportOutOfMemory(cx)
3361 else if aException is ESMRangeException then begin
3362 ws := StringToSynUnicode(aException.Message);
3363 JSRangeErrorUC(cx, ws);
3364 end else if aException is ESMTypeException then begin
3365 ws := StringToSynUnicode(aException.Message);
3366 JSTypeErrorUC(cx, ws);
3367 end else begin
3368 ws := StringToSynUnicode(aException.Message);
3369 JSErrorUC(cx, ws, aException.HelpContext);
3370 end;
3371end;
3372
3373const
3374 ErrorUCFormatString: JSErrorFormatString =
3375 (
3376 name: 'Error';
3377 format: '{0}';
3378 argCount: 1;
3379 exnType: JSEXN_ERR;
3380 );
3381 RangeErrorUCFormatString: JSErrorFormatString =
3382 (
3383 name: 'RangeError';
3384 format: '{0}';
3385 argCount: 1;
3386 exnType: JSEXN_RANGEERR;
3387 );
3388 TypeErrorUCFormatString: JSErrorFormatString =
3389 (
3390 name: 'TypeError';
3391 format: '{0}';
3392 argCount: 1;
3393 exnType: JSEXN_TYPEERR;
3394 );
3395 SMExceptionNumber = 500;//from 0 to JSErr_Limit(421 for SM 45 ) Error numbers are reserved
3396
3397function ReportErrorUC(userRef: Pointer; const errorNumber: uintN): PJSErrorFormatString; cdecl;
3398begin
3399 result := @ErrorUCFormatString;
3400end;
3401
3402function ReportRangeErrorUC(userRef: Pointer; const errorNumber: uintN): PJSErrorFormatString; cdecl;
3403begin
3404 result := @RangeErrorUCFormatString;
3405end;
3406
3407function TypeRangeErrorUC(userRef: Pointer; const errorNumber: uintN): PJSErrorFormatString; cdecl;
3408begin
3409 result := @TypeErrorUCFormatString;
3410end;
3411
3412procedure JSErrorUC(cx: PJSContext; aMessage: WideString; errorCode: integer);
3413begin
3414 if not JS_IsExceptionPending(cx) then
3415 JS_ReportErrorNumberUC(cx, ReportErrorUC, nil, SMExceptionNumber + errorCode, Pointer(aMessage));
3416end;
3417
3418procedure JSRangeErrorUC(cx: PJSContext; aMessage: WideString);
3419begin
3420 if not JS_IsExceptionPending(cx) then
3421 JS_ReportErrorNumberUC(cx, ReportRangeErrorUC, nil, SMExceptionNumber ,Pointer(aMessage));
3422end;
3423
3424procedure JSTypeErrorUC(cx: PJSContext; aMessage: WideString);
3425begin
3426 if not JS_IsExceptionPending(cx) then
3427 JS_ReportErrorNumberUC(cx, TypeRangeErrorUC, nil, SMExceptionNumber ,Pointer(aMessage));
3428end;
3429
3430function InitJS: Boolean;
3431begin
3432 // remove extra threads + allow GS to finalize native objects;
3433 // See for details the same issue in modgoDB:
3434 // https://jira.mongodb.org/browse/SERVER-21728
3435 JS_DisableExtraThreads();
3436 Result := JS_Init;
3437end;
3438
3439procedure ShutDownJS;
3440begin
3441 JS_ShutDown;
3442end;
3443
3444{ JSCompileOptions }
3445
3446procedure JSCompileOptions.SetFileLineAndUtf8(const fn: RawUTF8; l: cardinal;
3447 isUtf8: boolean);
3448begin
3449 JS_SetCompileOptionsFileLineAndUtf8(@Self, pointer(fn), l, isUtf8);
3450end;
3451
3452{ JSString }
3453
3454procedure JSString.ToJSONString(cx: PJSContext; W: TTextWriter);
3455var
3456 str8: PCChar;
3457 str16: PCChar16;
3458 strL: size_t;
3459begin
3460 W.Add('"');
3461 if JS_StringHasLatin1Chars(@self) then begin
3462 str8 := JS_GetLatin1StringCharsAndLength(cx, @nullPtr, @self, @strL);
3463 W.AddJSONEscape(pointer(str8),strL);
3464 end else begin
3465 str16 := JS_GetTwoByteStringCharsAndLength(cx, @nullPtr, @self, @strL);
3466 W.AddJSONEscapeW(pointer(str16),strL);
3467 end;
3468 W.Add('"');
3469end;
3470
3471function JSString.ToJSVal: jsval;
3472begin
3473 Result.asJSString := @self
3474end;
3475
3476function JSString.ToString(cx: PJSContext): string;
3477var
3478 str8: PCChar;
3479 str16: PCChar16;
3480 strL: size_t;
3481begin
3482 if JS_StringHasLatin1Chars(@self) then begin
3483 str8 := JS_GetLatin1StringCharsAndLength(cx, @nullPtr, @self, @strL);
3484 {$ifdef UNICODE}
3485 Result := Latin1AnsiConvert.AnsiToUnicodeString(str8, strL);
3486 {$else}
3487 SetString(Result, str8, strL);
3488 {$endif}
3489 end else begin
3490 str16 := JS_GetTwoByteStringCharsAndLength(cx, @nullPtr, @self, @strL);
3491 RawUnicodeToString(PWideChar(str16),strL,result)
3492 end;
3493end;
3494
3495function JSString.ToSynUnicode(cx: PJSContext): SynUnicode;
3496var
3497 str8: PCChar;
3498 str16: PCChar16;
3499 strL: size_t;
3500begin
3501 if JS_StringHasLatin1Chars(@self) then begin
3502 str8 := JS_GetLatin1StringCharsAndLength(cx, @nullPtr, @self, @strL);
3503 Result := Latin1AnsiConvert.AnsiToUnicodeString(str8, strL);
3504 end else begin
3505 str16 := JS_GetTwoByteStringCharsAndLength(cx, @nullPtr, @self, @strL);
3506 SetString(Result, str16, strL);
3507 end;
3508end;
3509
3510function JSString.ToUTF8(cx: PJSContext): RawUTF8;
3511begin
3512 ToUTF8(cx,result);
3513end;
3514
3515procedure JSString.ToUTF8(cx: PJSContext; out result: RawUTF8);
3516var
3517 str8: PCChar;
3518 str16: PCChar16;
3519 strL: size_t;
3520begin
3521 if JS_StringHasLatin1Chars(@self) then begin
3522 str8 := JS_GetLatin1StringCharsAndLength(cx, @nullPtr, @self, @strL);
3523 result := Latin1AnsiConvert.AnsiBufferToRawUTF8(str8, strL);
3524 end else begin
3525 str16 := JS_GetTwoByteStringCharsAndLength(cx, @nullPtr, @self, @strL);
3526 RawUnicodeToUTF8(str16,strL,result, [ccfNoTrailingZero, ccfReplacementCharacterForUnmatchedSurrogate]);
3527 end;
3528end;
3529
3530function JSString.ToAnsi(cx: PJSContext): AnsiString;
3531var
3532 str8: PCChar;
3533 str16: PCChar16;
3534 strL: size_t;
3535begin
3536 if JS_StringHasLatin1Chars(@self) then begin
3537 str8 := JS_GetLatin1StringCharsAndLength(cx, @nullPtr, @self, @strL);
3538 SetLength(Result, strL);
3539 MoveFast(Pointer(str8)^,Result[1],strL);
3540 end else begin
3541 str16 := JS_GetTwoByteStringCharsAndLength(cx, @nullPtr, @self, @strL);
3542 Result := CurrentAnsiConvert.UnicodeBufferToAnsi(str16,strL);
3543 end;
3544end;
3545
3546procedure JSString.ToVariant(cx: PJSContext; var Value: Variant);
3547var
3548 str8: PCChar;
3549 str16: PCChar16;
3550 strL: size_t;
3551begin
3552 VarClear(Value);
3553 with TVarData(Value) do begin
3554 VType := varSynUnicode;
3555 VAny := nil; // avoid GPF below
3556 if JS_StringHasLatin1Chars(@self) then begin
3557 str8 := JS_GetLatin1StringCharsAndLength(cx, @nullPtr, @self, @strL);
3558 SynUnicode(VAny) := Latin1AnsiConvert.AnsiToUnicodeString(str8, strL);
3559 end else begin
3560 str16 := JS_GetTwoByteStringCharsAndLength(cx, @nullPtr, @self, @strL);
3561 SetString(SynUnicode(VAny), str16, strL);
3562 end;
3563 end;
3564end;
3565
3566procedure JSString.ToUTF8(cx: PJSContext; W: TTextWriter);
3567var
3568 str8: PCChar;
3569 str16: PCChar16;
3570 strL: size_t;
3571 tmpU8: array[0..256*3] of AnsiChar;
3572 U8: PUTF8Char;
3573begin
3574 if JS_StringHasLatin1Chars(@self) then begin
3575 str8 := JS_GetLatin1StringCharsAndLength(cx, @nullPtr, @self, @strL);
3576
3577 if strL>=SizeOf(tmpU8)div 3 then
3578 Getmem(U8,strL*3+1) else
3579 U8 := @tmpU8;
3580 strL := Latin1AnsiConvert.AnsiBufferToUTF8(U8,pointer(str8),strL)-U8;
3581 W.AddNoJSONEscape(pointer(U8), strL);
3582 if U8<>@tmpU8 then
3583 FreeMem(U8);
3584 end else begin
3585 str16 := JS_GetTwoByteStringCharsAndLength(cx, @nullPtr, @self, @strL);
3586 W.AddNoJSONEscapeW(pointer(str16),strL);
3587 end;
3588end;
3589
3590function JSString.HasLatin1Chars: Boolean;
3591begin
3592 result := JS_StringHasLatin1Chars(@self);
3593end;
3594
3595function JSString.GetLatin1StringCharsAndLength(cx: PJSContext;
3596 out len: size_t): PCChar;
3597begin
3598 Result := JS_GetLatin1StringCharsAndLength(cx, @nullPtr, @Self, @len);
3599end;
3600
3601function JSString.Length: size_t;
3602begin
3603 Result := JS_GetStringLength(@self);
3604end;
3605
3606function JSString.GetTwoByteStringCharsAndLength(cx: PJSContext;
3607 out len: size_t): PCChar16;
3608begin
3609 Result := JS_GetTwoByteStringCharsAndLength(cx, @nullPtr, @Self, @len);
3610end;
3611
3612{ JSContext }
3613function JSContext.CheckForInterrupt: Boolean;
3614begin
3615 result := JS_CheckForInterrupt(@Self);
3616end;
3617
3618procedure JSContext.DisableInterruptCallback;
3619begin
3620 JS_DisableInterruptCallback(@self);
3621end;
3622
3623procedure JSContext.AddInterruptCallback(callback: JSInterruptCallback);
3624begin
3625 JS_AddInterruptCallback(@self, callback);
3626end;
3627
3628procedure JSContext.ResetInterruptCallback(disable: boolean);
3629begin
3630 JS_ResetInterruptCallback(@self, disable);
3631end;
3632
3633procedure JSContext.ClearPendingException;
3634begin
3635 JS_ClearPendingException(@self);
3636end;
3637
3638function JSContext.CurrentGlobalOrNull: PJSObject;
3639begin
3640 result := JS_CurrentGlobalOrNull(@self);
3641end;
3642
3643procedure JSContext.Destroy;
3644begin
3645 JS_DestroyContext(@self);
3646end;
3647
3648function JSContext.EnterCompartment(target: PJSObject): PJSCompartment;
3649begin
3650 Result := JS_EnterCompartment(@self, target);
3651end;
3652
3653function JSContext.GetPendingException(out rv: jsval): boolean;
3654begin
3655 Result := JS_GetPendingException(@self, rv);
3656end;
3657
3658function JSContext.GetPrivate: Pointer;
3659begin
3660 result := JS_GetContextPrivate(@self);
3661end;
3662
3663function JSContext.IdToValue(id: jsid; out v: jsval): Boolean;
3664begin
3665 Result := JS_IdToValue(@Self, id, v);
3666end;
3667
3668function JSContext.InitStandardClasses(var obj: PJSObject): boolean;
3669begin
3670 Result := JS_InitStandardClasses(@Self, obj);
3671end;
3672
3673procedure JSContext.SetModuleResolveHook(var hook: PJSFunction);
3674begin
3675 JS_SetModuleResolveHook(@Self, hook);
3676end;
3677
3678function JSContext.NewDateObjectMsec(msec: double): PJSObject;
3679begin
3680 Result := JS_NewDateObjectMsec(@Self, msec);
3681end;
3682
3683procedure JSContext.LeaveCompartment(oldCompartment: PJSCompartment);
3684begin
3685 JS_LeaveCompartment(@Self, oldCompartment);
3686end;
3687
3688procedure JSContext.MaybeGC;
3689begin
3690 JS_MaybeGC(@self);
3691end;
3692
3693function JSContext.NewDateObject(year, mon, mday, hour, min, sec: int32): PJSObject;
3694begin
3695 Result := JS_NewDateObject(@Self, year, mon, mday, hour, min, sec);
3696end;
3697
3698function JS_NewCompartmentOptions(): PJS_CompartmentOptions; cdecl;
3699 external SpiderMonkeyLib name 'SM_NewCompartmentOptions';
3700procedure JS_FreeCompartmentOptions(opt: PJS_CompartmentOptions); cdecl;
3701 external SpiderMonkeyLib name 'SM_FreeCompartmentOptions';
3702
3703function JSContext.NewGlobalObject(clasp: PJSClass; hookOption: OnNewGlobalHookOption): PJSObject;
3704var
3705 Opt: PJS_CompartmentOptions;
3706begin
3707 Opt := JS_NewCompartmentOptions;
3708 Result := JS_NewGlobalObject(@Self, clasp, nil, hookOption, Opt);
3709 JS_FreeCompartmentOptions(Opt);
3710end;
3711
3712function JSContext.NewInt16Array(nelements: uint32): PJSObject;
3713begin
3714 Result := JS_NewInt16Array(@Self, nelements);
3715end;
3716
3717function JSContext.NewInt16ArrayFromArray(var arr: PJSObject): PJSObject;
3718begin
3719 Result := JS_NewInt16ArrayFromArray(@Self, arr);
3720end;
3721
3722function JSContext.NewInt16ArrayWithBuffer(var arrayBuffer: PJSObject;
3723 byteOffset: uint32; length: int32): PJSObject;
3724begin
3725 Result := JS_NewInt16ArrayWithBuffer(@Self, arrayBuffer, byteOffset, length);
3726end;
3727
3728function JSContext.NewInt32Array(nelements: uint32): PJSObject;
3729begin
3730 Result := JS_NewInt32Array(@Self, nelements);
3731end;
3732
3733function JSContext.NewInt32ArrayFromArray(var arr: PJSObject): PJSObject;
3734begin
3735 Result := JS_NewInt32ArrayFromArray(@Self, arr);
3736end;
3737
3738function JSContext.NewInt32ArrayWithBuffer(var arrayBuffer: PJSObject;
3739 byteOffset: uint32; length: int32): PJSObject;
3740begin
3741 Result := JS_NewInt32ArrayWithBuffer(@Self, arrayBuffer, byteOffset, length);
3742end;
3743
3744function JSContext.NewInt8Array(nelements: uint32): PJSObject;
3745begin
3746 Result := JS_NewInt8Array(@Self, nelements);
3747end;
3748
3749function JSContext.NewInt8ArrayFromArray(var arr: PJSObject): PJSObject;
3750begin
3751 Result := JS_NewInt8ArrayFromArray(@Self, arr);
3752end;
3753
3754function JSContext.NewInt8ArrayWithBuffer(var arrayBuffer: PJSObject;
3755 byteOffset: uint32; length: int32): PJSObject;
3756begin
3757 Result := JS_NewInt8ArrayWithBuffer(@Self, arrayBuffer, byteOffset, length);
3758end;
3759
3760function JSContext.NewJSString(TextWide: PWideChar;
3761 TextLen: integer): PJSString;
3762begin
3763 result := JS_NewUCStringCopyN(@Self, pointer(TextWide), TextLen);
3764end;
3765
3766function JSContext.NewJSString(TextAnsi: PAnsiChar; TextLen,
3767 CodePage: integer): PJSString;
3768var short: array[byte] of CChar16; // to avoid temp allocation on heap
3769 buf: PCChar16;
3770begin
3771 if TextLen<(sizeof(short) div 3) then
3772 buf := @short else
3773 GetMem(buf,TextLen*3+2);
3774 result := JS_NewUCStringCopyN(@Self, buf,
3775 TSynAnsiConvert.Engine(CodePage).AnsiBufferToUnicode(PWideChar(buf),TextAnsi,TextLen)-buf);
3776 if buf<>@short then
3777 FreeMem(buf);
3778end;
3779
3780function JSContext.NewJSString(const Value: SynUnicode): PJSString;
3781begin
3782 result := JS_NewUCStringCopyN(@Self, pointer(Value), Length(Value));
3783end;
3784
3785function JSContext.NewObject(clasp: PJSClass): PJSObject;
3786begin
3787 Result := JS_NewObject(@Self, clasp);
3788end;
3789
3790function JSContext.NewObjectWithGivenProto(clasp: PJSClass; var proto: PJSObject): PJSObject;
3791begin
3792 Result := JS_NewObjectWithGivenProto(@Self, clasp, proto);
3793end;
3794
3795procedure JSContext.ReportError(format: PCChar);
3796begin
3797 JS_ReportError(@Self, format);
3798end;
3799
3800procedure JSContext.ReportErrorNumberUC(errorCallback: JSErrorCallback; userRef: pointer; const erroNubmer: uintN);
3801begin
3802 JS_ReportErrorNumberUC(@Self, errorCallback, userRef, erroNubmer);
3803end;
3804
3805procedure JSContext.ReportOutOfMemory;
3806begin
3807 JS_ReportOutOfMemory(@self);
3808end;
3809
3810procedure JSContext.SetPrivate(const Value: Pointer);
3811begin
3812 JS_SetContextPrivate(@self,Value);
3813end;
3814
3815function JSContext.TypeOfValue(v: jsval): JSType;
3816begin
3817 result := JS_TypeOfValue(@Self, v);
3818end;
3819
3820function JSContext.ValueToId(var v: jsval; out id: jsid): Boolean;
3821begin
3822 Result := JS_ValueToId(@Self, v, id);
3823end;
3824
3825function JSContext.WrapObject(var obj: PJSObject): boolean;
3826begin
3827 Result := JS_WrapObject(@Self, obj);
3828end;
3829
3830procedure JSContext.BeginRequest;
3831begin
3832 JS_BeginRequest(@self);
3833end;
3834
3835procedure JSContext.EndRequest;
3836begin
3837 JS_EndRequest(@self);
3838end;
3839
3840function JSContext.GetArrayBufferViewBuffer(var obj: PJSObject;
3841 out isSharedMemory: Boolean): PJSObject;
3842begin
3843 Result := JS_GetArrayBufferViewBuffer(@self, obj, isSharedMemory);
3844end;
3845
3846function JSContext.GetArrayBufferViewBuffer(var obj: PJSObject): PJSObject;
3847var
3848 isSharedMemory: Boolean;
3849begin
3850 Result := JS_GetArrayBufferViewBuffer(@self, obj, isSharedMemory);
3851end;
3852
3853function JSContext.GetIsRunning: boolean;
3854begin
3855 result := JS_IsRunning(@self);
3856end;
3857
3858procedure JSContext.FreeCompileOptions(opt: PJSCompileOptions);
3859begin
3860 JS_FreeCompileOptions(opt);
3861end;
3862
3863procedure JSContext.FreeRootedObject(obj: PJSRootedObject);
3864var
3865 curr: PJSRootedObject;
3866begin
3867 curr := obj.stack.Last;
3868 while curr.ptr = nil do curr := curr.prev;
3869 if curr <> obj then
3870 raise ESMException.Create('FreeRootedObject Stack error');
3871 JS_FreeRootedObject(obj);
3872end;
3873
3874procedure JSContext.FreeRootedString(str: PJSRootedString);
3875begin
3876 if ppointer(str.stack)^ <> str then
3877 raise ESMException.Create('FreeRootedString Stack error');
3878 JS_FreeRootedString(str);
3879end;
3880
3881procedure JSContext.FreeRootedValue(str: PJSRootedValue);
3882begin
3883 if ppointer(str.stack)^ <> str then
3884 raise ESMException.Create('FreeRootedValue Stack error');
3885 JS_FreeRootedValue(str);
3886end;
3887
3888function JSContext.NewRootedObject(obj: PJSObject): PJSRootedObject;
3889begin
3890 Result := JS_NewRootedObject(@Self, obj);
3891end;
3892
3893function JSContext.NewRootedString(obj: PJSString): PJSRootedString;
3894begin
3895 Result := JS_NewRootedString(@Self, obj)
3896end;
3897
3898function JSContext.NewRootedValue(val: jsval): PJSRootedValue;
3899begin
3900 Result := JS_NewRootedValue(@Self, val._l.asBits)
3901end;
3902
3903function JSContext.NewSharedArrayBuffer(nbytes: uint32): PJSObject;
3904begin
3905 Result := JS_NewSharedArrayBuffer(@Self, nbytes);
3906end;
3907
3908function JSContext.NewUint16Array(nelements: uint32): PJSObject;
3909begin
3910 Result := JS_NewUint16Array(@Self, nelements);
3911end;
3912
3913function JSContext.NewUint16ArrayFromArray(var arr: PJSObject): PJSObject;
3914begin
3915 Result := JS_NewUInt16ArrayFromArray(@Self, arr);
3916end;
3917
3918function JSContext.NewUint16ArrayWithBuffer(var arrayBuffer: PJSObject;
3919 byteOffset: uint32; length: int32): PJSObject;
3920begin
3921 Result := JS_NewUInt16ArrayWithBuffer(@Self, arrayBuffer, byteOffset, length);
3922end;
3923
3924function JSContext.NewUint32Array(nelements: uint32): PJSObject;
3925begin
3926 Result := JS_NewUInt32Array(@Self, nelements);
3927end;
3928
3929function JSContext.NewUint32ArrayFromArray(var arr: PJSObject): PJSObject;
3930begin
3931 Result := JS_NewUInt32ArrayFromArray(@Self, arr);
3932end;
3933
3934function JSContext.NewUint32ArrayWithBuffer(var arrayBuffer: PJSObject;
3935 byteOffset: uint32; length: int32): PJSObject;
3936begin
3937 Result := JS_NewUInt32ArrayWithBuffer(@Self, arrayBuffer, byteOffset, length);
3938end;
3939
3940function JSContext.NewUint8Array(nelements: uint32): PJSObject;
3941begin
3942 Result := JS_NewuInt8Array(@Self, nelements);
3943end;
3944
3945function JSContext.NewUint8ArrayFromArray(var arr: PJSObject): PJSObject;
3946begin
3947 Result := JS_NewUInt8ArrayFromArray(@Self, arr);
3948end;
3949
3950function JSContext.NewUint8ArrayWithBuffer(var arrayBuffer: PJSObject;
3951 byteOffset: uint32; length: int32): PJSObject;
3952begin
3953 Result := JS_NewUInt8ArrayWithBuffer(@Self, arrayBuffer, byteOffset, length);
3954end;
3955
3956function JSContext.NewUint8ClampedArray(nelements: uint32): PJSObject;
3957begin
3958 Result := JS_NewUint8ClampedArray(@Self, nelements);
3959end;
3960
3961function JSContext.NewUint8ClampedArrayFromArray(var arr: PJSObject): PJSObject;
3962begin
3963 Result := JS_NewUint8ClampedArrayFromArray(@Self, arr);
3964end;
3965
3966function JSContext.NewUint8ClampedArrayWithBuffer(var arrayBuffer: PJSObject;
3967 byteOffset: uint32; length: int32): PJSObject;
3968begin
3969 Result := JS_NewUint8ClampedArrayWithBuffer(@Self, arrayBuffer, byteOffset, length);
3970end;
3971
3972procedure strFinalizeOp(fin: PJSStringFinalizer; chars: PCChar16); cdecl;
3973begin
3974
3975end;
3976
3977function JSContext.NewExternalString(const Value: SynUnicode): PJSString;
3978begin
3979 Result := JS_NewExternalString(@Self, pointer(Value), length(Value), @strFinalizer);
3980end;
3981
3982//function JSContext.AtomizeAndPinString(const Value: SynUnicode): PJSString; {$ifdef HASINLINE}inline;{$endif}
3983//begin
3984// Result := JS_AtomizeAndPinStringN(@Self, pointer(Value), length(Value));
3985//end;
3986
3987function JSContext.NewFloat32Array(nelements: uint32): PJSObject;
3988begin
3989 Result := JS_NewFloat32Array(@Self, nelements);
3990end;
3991
3992function JSContext.NewFloat32ArrayFromArray(var arr: PJSObject): PJSObject;
3993begin
3994 Result := JS_NewFloat32ArrayFromArray(@Self, arr);
3995end;
3996
3997function JSContext.NewFloat32ArrayWithBuffer(var arrayBuffer: PJSObject;
3998 byteOffset: uint32; length: int32): PJSObject;
3999begin
4000 Result := JS_NewFloat32ArrayWithBuffer(@Self, arrayBuffer, byteOffset, length);
4001end;
4002
4003function JSContext.NewFloat64Array(nelements: uint32): PJSObject;
4004begin
4005 Result := JS_NewFloat64Array(@Self, nelements);
4006end;
4007
4008function JSContext.NewFloat64ArrayFromArray(var arr: PJSObject): PJSObject;
4009begin
4010 Result := JS_NewFloat64ArrayFromArray(@Self, arr);
4011end;
4012
4013function JSContext.NewFloat64ArrayWithBuffer(var arrayBuffer: PJSObject;
4014 byteOffset: uint32; length: int32): PJSObject;
4015begin
4016 Result := JS_NewFloat64ArrayWithBuffer(@Self, arrayBuffer, byteOffset, length);
4017end;
4018
4019function JSContext.NewFunction(call: JSNative; nargs: uintN; flags: uintN;
4020 name: PCChar): PJSObject;
4021begin
4022 Result := JS_NewFunction(@Self, call, nargs, flags, name);
4023end;
4024
4025function JSContext.DefineDebuggerObject(var obj: PJSObject): boolean;
4026begin
4027 Result := JS_DefineDebuggerObject(@Self, obj);
4028end;
4029
4030function JSContext.NewCompileOptions: PJSCompileOptions;
4031begin
4032 result := JS_NewCompileOptions(@self);
4033end;
4034
4035function JSContext.CompileModule(var obj: PJSObject; opts: PJSCompileOptions;
4036 chars: PCChar16; length: size_t): PJSObject;
4037begin
4038 Result := JS_CompileModule(@Self, obj, opts, chars, length);
4039end;
4040
4041function JSContext.CompileScript(bytes: PCChar;
4042 length: size_t; opts: PJSCompileOptions; out script: PJSScript): boolean;
4043begin
4044 Result := JS_CompileScript(@Self, bytes, length, opts, script);
4045end;
4046
4047function JSContext.CompileUCScript(chars: PCChar16; length: size_t;
4048 opts: PJSCompileOptions; out script: PJSScript): boolean;
4049begin
4050 Result := JS_CompileUCScript(@Self, chars, length, opts, script);
4051end;
4052
4053function JSContext.EvaluateScript(opts: PJSCompileOptions; bytes: PCChar; length: size_t;
4054 out rval: jsval): Boolean;
4055begin
4056 Result := JS_EvaluateScript(@Self, opts, bytes, length, rval);
4057end;
4058
4059function JSContext.EvaluateUCScript(opts: PJSCompileOptions; chars: PCChar16; length: size_t;
4060 out rval: jsval): Boolean;
4061begin
4062 Result := JS_EvaluateUCScript(@Self, opts, chars, length, rval);
4063end;
4064
4065function JSContext.ExecuteScript(var script: PJSScript; out rval: jsval): Boolean;
4066begin
4067 Result := JS_ExecuteScript(@Self, script, rval);
4068end;
4069
4070function JSContext.New(var ctor: PJSObject; argc: uintN; argv: PjsvalVector): PJSObject;
4071var
4072 args: JSHandleValueArray;
4073begin
4074 args.length := argc;
4075 args.elements_ := argv;
4076 Result := JS_New(@self, ctor, args);
4077end;
4078
4079function JSContext.NewArrayBuffer(nbytes: uint32): PJSObject;
4080begin
4081 Result := JS_NewArrayBuffer(@Self, nbytes);
4082end;
4083
4084function JSContext.NewArrayObject(length: size_t;
4085 vector: PjsvalVector): PJSObject;
4086var
4087 contents: JSHandleValueArray;
4088begin
4089 contents.length := length;
4090 contents.elements_ := vector;
4091 Result := JS_NewArrayObject2(@Self, contents);
4092end;
4093
4094function JSContext.NewArrayObject(length: size_t): PJSObject;
4095begin
4096 Result := JS_NewArrayObject(@Self, length);
4097end;
4098
4099function JSContext.InitCTypesClass(var obj: PJSObject): boolean;
4100begin
4101 Result := JS_InitCTypesClass(@Self, obj);
4102end;
4103
4104function JSContext.InitReflectParse(var obj: PJSObject): boolean;
4105begin
4106 Result := JS_InitReflectParse(@Self, obj);
4107end;
4108
4109function JSContext.InitModuleClasses(var obj: PJSObject): boolean;
4110begin
4111 Result := JS_InitModuleClasses(@Self, obj);
4112end;
4113
4114function JSContext.NewJSString(const Value: RawUTF8): PJSString;
4115begin
4116 if Value = '' then
4117 result := JS_GetEmptyString(@self) else
4118 result := JS_NewStringCopyUTF8Z(@self, pointer(Value));
4119end;
4120
4121function JSContextOptions.getOptions(const Index: Integer): Boolean;
4122begin
4123 Result := (pword(@self)^ and (1 shl Index)) <> 0;
4124end;
4125
4126procedure JSContextOptions.setOptions(const Index: Integer;
4127 const Value: Boolean);
4128var
4129 val: uint16;
4130begin
4131 val := 1 shl Index;
4132 if Value then
4133 pword(@self)^ := pword(@self)^ or val
4134 else
4135 pword(@self)^ := pword(@self)^ and (not val);
4136end;
4137
4138procedure JSContext.GC;
4139begin
4140 JS_GC(@self);
4141end;
4142
4143function JSContext.GetEmptyString: PJSString;
4144begin
4145 Result := JS_GetEmptyString(@self);
4146end;
4147
4148function JSContext.GetWarningReporter: JSWarningReporter;
4149begin
4150 Result := JS_GetWarningReporter(@self);
4151end;
4152
4153function JSContext.GetGCParameter(key: JSGCParamKey): uint32;
4154begin
4155 Result := JS_GetGCParameter(@Self, key);
4156end;
4157
4158function JSContext.GetNowMs: int64;
4159begin
4160 Result := JS_Now;
4161end;
4162
4163class function JSContext.CreateNew(maxbytes: uint32; maxNurseryBytes: uint32; parentContext: PJSContext): PJSContext;
4164begin
4165 with TSynFPUException.ForLibraryCode do begin
4166 Result := JS_NewContext(maxbytes, maxNurseryBytes, parentContext);
4167 InitSelfHostedCode(Result);
4168 end;
4169end;
4170
4171function JSContext.GetOptions: PJSContextOptions;
4172begin
4173 Result := JS_GetContextOptions(@self);
4174end;
4175
4176procedure JSContext.RequestInterruptCallback;
4177begin
4178 JS_RequestInterruptCallback(@self);
4179end;
4180
4181procedure JSContext.SetWarningReporter(reporter: JSWarningReporter);
4182begin
4183 JS_SetWarningReporter(@self, reporter);
4184end;
4185
4186procedure JSContext.SetGCParameter(key: JSGCParamKey; const Value: uint32);
4187begin
4188 JS_SetGCParameter(@Self, key, Value);
4189end;
4190
4191procedure JSContext.SetGCParametersBasedOnAvailableMemory(availMem: uint32);
4192begin
4193 JS_SetGCParametersBasedOnAvailableMemory(@Self, availMem);
4194end;
4195
4196procedure JSContext.SetNativeStackQuota(systemCodeStackSize: size_t);
4197begin
4198 JS_SetNativeStackQuota(@Self, systemCodeStackSize);
4199end;
4200
4201{ JSObject }
4202
4203function JSObject.isArray(cx: PJSContext): Boolean;
4204var
4205 _isArray: Boolean;
4206 obj: PJSObject;
4207begin
4208 obj := @Self;
4209 Result := JS_IsArrayObject(cx, obj, _isArray) and _isArray;
4210end;
4211
4212function JSObject.IsArrayBufferObject: Boolean;
4213begin
4214 result := JS_IsArrayBufferObject(@self)
4215end;
4216
4217function JSObject.IsArrayBufferViewObject: Boolean;
4218begin
4219 result := JS_IsArrayBufferViewObject(@self)
4220end;
4221
4222function JSObject.isDate(cx: PJSContext): Boolean;
4223var
4224 _isDate: Boolean;
4225 obj: PJSObject;
4226begin
4227 obj := @Self;
4228 Result := JS_ObjectIsDate(cx, obj, _isDate) and _isDate;
4229end;
4230
4231function JSObject.IsFloat32Array: Boolean;
4232begin
4233 result := JS_IsFloat32Array(@self);
4234end;
4235
4236function JSObject.IsFloat64Array: Boolean;
4237begin
4238 result := JS_IsFloat64Array(@self);
4239end;
4240
4241function JSObject.isFunction(cx: PJSContext): Boolean;
4242begin
4243 Result := JS_ObjectIsFunction(cx, @Self);
4244end;
4245
4246function JSObject.IsInt16Array: Boolean;
4247begin
4248 result := JS_IsInt16Array(@self)
4249end;
4250
4251function JSObject.IsInt32Array: Boolean;
4252begin
4253 result := JS_IsInt32Array(@self)
4254end;
4255
4256function JSObject.IsInt8Array: Boolean;
4257begin
4258 result := JS_IsInt8Array(@self)
4259end;
4260
4261function JSObject.IsMappedArrayBufferObject(obj: PJSObject): Boolean;
4262begin
4263 result := JS_IsMappedArrayBufferObject(@self);
4264end;
4265
4266function JSObject.IsSharedArrayBufferObject: Boolean;
4267begin
4268 result := JS_IsSharedArrayBufferObject(@self)
4269end;
4270
4271function JSObject.IsTypedArrayObject: Boolean;
4272begin
4273 result := JS_IsTypedArrayObject(@self)
4274end;
4275
4276function JSObject.IsUint16Array: Boolean;
4277begin
4278 result := JS_IsUInt16Array(@self)
4279end;
4280
4281function JSObject.IsUint32Array: Boolean;
4282begin
4283 result := JS_IsUInt32Array(@self);
4284end;
4285
4286function JSObject.IsUint8Array: Boolean;
4287begin
4288 result := JS_IsUint8Array(@self)
4289end;
4290
4291function JSObject.IsUint8ClampedArray: Boolean;
4292begin
4293 result := JS_IsUint8ClampedArray(@self)
4294end;
4295
4296function JSObject.GetArrayBufferViewData(out isSharedMemory: Boolean;
4297 nogc: PJSAutoCheckCannotGC): Pointer;
4298begin
4299 result := JS_GetArrayBufferViewData(@self, isSharedMemory, nogc);
4300end;
4301
4302function JSObject.RunMethod(cx: PJSContext; const name: PCChar;
4303 out rval: jsval): Boolean;
4304begin
4305 Result := CallFunctionName(cx, name, 0, nil, rval);
4306end;
4307
4308function JSObject.RunMethod(cx: PJSContext; const name: PCChar; arg: jsval;
4309 out rval: jsval): Boolean;
4310begin
4311 Result := CallFunctionName(cx, name, 1, @arg, rval);
4312end;
4313
4314function JSObject.RunMethod(cx: PJSContext; const name: PCChar;
4315 args: TjsvalDynArray; out rval: jsval): Boolean;
4316begin
4317 Result := CallFunctionName(cx, name, Length(args), @args[0], rval);
4318end;
4319
4320function JSObject.GetInstancePrivate(cx: PJSContext; clasp: PJSClass): Pointer;
4321var
4322 obj: PJSObject;
4323begin
4324 obj := @Self;
4325 result := JS_GetInstancePrivate(cx, obj, clasp, nil);
4326end;
4327
4328function JSObject.GetInt16ArrayData(out isSharedMemory: Boolean;
4329 nogc: PJSAutoCheckCannotGC): Pint16Vector;
4330begin
4331 result := JS_GetInt16ArrayData(@self, isSharedMemory, nogc);
4332end;
4333
4334function JSObject.GetInt32ArrayData(out isSharedMemory: Boolean;
4335 nogc: PJSAutoCheckCannotGC): Pint32Vector;
4336begin
4337 result := JS_GetInt32ArrayData(@self, isSharedMemory, nogc);
4338end;
4339
4340function JSObject.GetInt8ArrayData(out isSharedMemory: Boolean;
4341 nogc: PJSAutoCheckCannotGC): Pint8Vector;
4342begin
4343 result := JS_GetInt8ArrayData(@self, isSharedMemory, nogc);
4344end;
4345
4346function JSObject.GetObjectAsArrayBuffer(out length: uint32;
4347 out Data: Puint8Vector): PJSObject;
4348begin
4349 result := JS_GetObjectAsArrayBuffer(@self, length, data);
4350end;
4351
4352function JSObject.GetObjectAsArrayBufferView(out length: uint32;
4353 out isSharedMemory: Boolean; out Data: Puint8Vector): PJSObject;
4354begin
4355 result := JS_GetObjectAsArrayBufferView(@self, length, isSharedMemory, data);
4356end;
4357
4358function JSObject.GetObjectAsFloat32Array(out length: uint32;
4359 out isSharedMemory: Boolean; out Data: Pfloat32Vector): PJSObject;
4360begin
4361 result := JS_GetObjectAsFloat32Array(@self, length, isSharedMemory, data);
4362end;
4363
4364function JSObject.GetObjectAsFloat64Array(out length: uint32;
4365 out isSharedMemory: Boolean; out Data: Pfloat64Vector): PJSObject;
4366begin
4367 result := JS_GetObjectAsFloat64Array(@self, length, isSharedMemory, data);
4368end;
4369
4370function JSObject.GetObjectAsInt16Array(out length: uint32;
4371 out isSharedMemory: Boolean; out Data: Pint16Vector): PJSObject;
4372begin
4373 result := JS_GetObjectAsInt16Array(@self, length, isSharedMemory, data);
4374end;
4375
4376function JSObject.GetObjectAsInt32Array(out length: uint32;
4377 out isSharedMemory: Boolean; out Data: Pint32Vector): PJSObject;
4378begin
4379 result := JS_GetObjectAsInt32Array(@self, length, isSharedMemory, data);
4380end;
4381
4382function JSObject.GetObjectAsInt8Array(out length: uint32;
4383 out isSharedMemory: Boolean; out Data: Pint8Vector): PJSObject;
4384begin
4385 result := JS_GetObjectAsInt8Array(@self, length, isSharedMemory, data)
4386end;
4387
4388function JSObject.GetObjectAsUint16Array(out length: uint32;
4389 out isSharedMemory: Boolean; out Data: Puint16Vector): PJSObject;
4390begin
4391 result := JS_GetObjectAsUInt16Array(@self, length, isSharedMemory, data);
4392end;
4393
4394function JSObject.GetObjectAsUint32Array(out length: uint32;
4395 out isSharedMemory: Boolean; out Data: Puint32Vector): PJSObject;
4396begin
4397 result := JS_GetObjectAsUint32Array(@self, length, isSharedMemory, data);
4398end;
4399
4400function JSObject.GetObjectAsUint8Array(out length: uint32;
4401 out isSharedMemory: Boolean; out Data: Puint8Vector): PJSObject;
4402begin
4403 result := JS_GetObjectAsUInt8Array(@self, length, isSharedMemory, data)
4404end;
4405
4406function JSObject.GetObjectAsUint8ClampedArray(out length: uint32;
4407 out isSharedMemory: Boolean; out Data: Puint8Vector): PJSObject;
4408begin
4409 result := JS_GetObjectAsUint8ClampedArray(@self, length, isSharedMemory, data)
4410end;
4411
4412function JSObject.GetPrivate: Pointer;
4413begin
4414 Result := JS_GetPrivate(@self);
4415end;
4416
4417function JSObject.GetProperty(cx: PJSContext; const name: PCChar;
4418 out vp: jsval): boolean;
4419var
4420 obj: PJSObject;
4421begin
4422 obj := @Self;
4423 Result := JS_GetProperty(cx, obj, name, vp);
4424end;
4425
4426function JSObject.GetPropertyById(cx: PJSContext; const id: jsid;
4427 out vp: jsval): boolean;
4428var
4429 obj: PJSObject;
4430 _id: jsid;
4431begin
4432 obj := @Self;
4433 _id := id;
4434 Result := JS_GetPropertyById(cx, obj, _id, vp);
4435end;
4436
4437function JSObject.GetPropValue(cx: PJSContext; const name: SynUnicode): jsval;
4438begin
4439 {$ifdef WITHASSERT}
4440 Assert(
4441 {$ENDIF}
4442 GetUCProperty(cx, Pointer(name), Length(name), Result)
4443 {$ifdef WITHASSERT}
4444 );
4445 {$ENDIF}
4446end;
4447
4448function JSObject.GetPrototype(cx: PJSContext; out protop: PJSObject): Boolean;
4449var
4450 obj: PJSObject;
4451begin
4452 obj := @Self;
4453 Result := JS_GetPrototype(cx, obj, protop);
4454end;
4455
4456function JSObject.GetReservedSlot(index: uint32): jsval;
4457begin
4458 result._l.asBits := JS_GetReservedSlot(@Self, index)
4459end;
4460
4461function JSObject.GetSharedArrayBufferByteLength: uint32;
4462begin
4463 result := JS_GetSharedArrayBufferByteLength(@self);
4464end;
4465
4466function JSObject.GetTypedArrayByteLength: uint32;
4467begin
4468 result := JS_GetTypedArrayLength(@self);
4469end;
4470
4471function JSObject.GetTypedArrayByteOffset: uint32;
4472begin
4473 result := JS_GetTypedArrayByteOffset(@self);
4474end;
4475
4476function JSObject.GetTypedArrayLength: uint32;
4477begin
4478 result := JS_GetTypedArrayLength(@self);
4479end;
4480
4481function JSObject.GetTypedArraySharedness: Boolean;
4482begin
4483 result := JS_GetTypedArraySharedness(@self)
4484end;
4485
4486function JSObject.AlreadyHasOwnUCProperty(cx: PJSContext; const name: PCChar16;
4487 namelen: size_t): Boolean;
4488var
4489 obj: PJSObject;
4490 foundp: Boolean;
4491begin
4492 obj := @Self;
4493 Result := JS_AlreadyHasOwnUCProperty(cx, obj, name, namelen, foundp) and foundp;
4494end;
4495
4496function JSObject.ArrayBufferHasData: Boolean;
4497begin
4498 result := JS_ArrayBufferHasData(@self);
4499end;
4500
4501function JSObject.CallFunction(cx: PJSContext; var fun: PJSFunction;
4502 argc: uintN; argv: PjsvalVector; out rval: jsval): Boolean;
4503var obj: PJSObject;
4504 args: JSHandleValueArray;
4505begin
4506 obj := @Self;
4507 args.length := argc;
4508 args.elements_ := argv;
4509 Result := JS_CallFunction(cx, obj, fun, args, rval);
4510end;
4511
4512function JSObject.CallFunctionName(cx: PJSContext; const name: PCChar;
4513 argc: uintN; argv: PjsvalVector; out rval: jsval): Boolean;
4514var obj: PJSObject;
4515 args: JSHandleValueArray;
4516begin
4517 obj := @Self;
4518 args.length := argc;
4519 args.elements_ := argv;
4520 Result := JS_CallFunctionName(cx, obj, name, args, rval);
4521end;
4522
4523function JSObject.CallFunctionValue(cx: PJSContext; val: jsval; argc: uintN;
4524 argv: PjsvalVector; out rval: jsval): Boolean;
4525var obj: PJSObject;
4526 args: JSHandleValueArray;
4527begin
4528 obj := @Self;
4529 args.length := argc;
4530 args.elements_ := argv;
4531 Result := JS_CallFunctionValue(cx, obj, val, args, rval);
4532end;
4533
4534const
4535 /// API extension: OR this into indent to avoid pretty-printing the decompiled
4536 // source resulting from JS_DecompileFunction{,Body}.
4537 JS_DONT_PRETTY_PRINT = $8000;
4538 prettyPrintAr: array[boolean] of uintN = (JS_DONT_PRETTY_PRINT, 0);
4539function JSObject.DecompileFunction(cx: PJSContext;
4540 PrettyPrint: Boolean): PJSString;
4541var
4542 fun: PJSFunction;
4543begin
4544 fun := @self;
4545 Result := JS_DecompileFunction(cx, fun, prettyPrintAr[PrettyPrint]);
4546end;
4547
4548function JSObject.DefineFunction(cx: PJSContext; name: PCChar; call: JSNative;
4549 nargs, attrs: uintN): PJSFunction;
4550var obj: PJSObject;
4551begin
4552 obj := @Self;
4553 Result := JS_DefineFunction(cx, obj, name, call, nargs, attrs);
4554end;
4555
4556function JSObject.DefineFunctions(cx: PJSContext; fs: PJSFunctionSpec;
4557 behavior: JSPropertyDefinitionBehavior): Boolean;
4558var obj: PJSObject;
4559begin
4560 obj := @Self;
4561 Result := JS_DefineFunctions(cx, obj, fs, behavior);
4562end;
4563
4564function JSObject.DefineProperties(cx: PJSContext;
4565 ps: PJSPropertySpec): boolean;
4566var obj: PJSObject;
4567begin
4568 obj := @Self;
4569 result := JS_DefineProperties(cx, obj, ps)
4570end;
4571
4572function JSObject.DefineProperty(cx: PJSContext; const name: PCChar;
4573 const value: jsval; attrs: uint32; getter, setter: JSNative): boolean;
4574var obj: PJSObject;
4575begin
4576 obj := @Self;
4577 result := JS_DefineProperty(cx, obj, name, pjsval(@value)^, attrs, getter, setter)
4578end;
4579
4580function JSObject.DefinePropertyById(cx: PJSContext; var id: jsid;
4581 const value: jsval; attrs: uint32; getter, setter: JSNative): boolean;
4582var obj: PJSObject;
4583begin
4584 obj := @Self;
4585 result := JS_DefinePropertyById(cx, obj, id, pjsval(@value)^, attrs, getter, setter)
4586end;
4587
4588function JSObject.DefineUCFunction(cx: PJSContext; name: PCChar16;
4589 namelen: size_t; call: JSNative; nargs, attrs: uintN): PJSFunction;
4590var obj: PJSObject;
4591begin
4592 obj := @Self;
4593 Result := JS_DefineUCFunction(cx, obj, name, namelen, call, nargs, attrs);
4594end;
4595
4596function JSObject.DefineUCProperty(cx: PJSContext; const name: SynUnicode;
4597 const value: jsval; attrs: uint32; getter, setter: JSNative): Boolean;
4598var obj: PJSObject;
4599begin
4600 obj := @Self;
4601 result := JS_DefineUCProperty(cx, obj, Pointer(name), Length(name), pjsval(@value)^, attrs, getter, setter)
4602end;
4603
4604function JSObject.DefineUCProperty(cx: PJSContext; const name: PCChar16;
4605 namelen: size_t; const value: jsval; attrs: uint32; getter,
4606 setter: JSNative): Boolean;
4607var obj: PJSObject;
4608begin
4609 obj := @Self;
4610 result := JS_DefineUCProperty(cx, obj, name, namelen, pjsval(@value)^, attrs, getter, setter)
4611end;
4612
4613function JSObject.DeleteElement(cx: PJSContext; index: uint32;
4614 out res: JS_ObjectOpResult): Boolean;
4615var obj: PJSObject;
4616begin
4617 obj := @Self;
4618 result := JS_DeleteElement(cx, obj, index, res);
4619end;
4620
4621function JSObject.DeletePropertyById(cx: PJSContext; const id: jsid;
4622 out res: JS_ObjectOpResult): Boolean;
4623var obj: PJSObject;
4624 _id: jsid;
4625begin
4626 obj := @Self;
4627 _id := id;
4628 Result := JS_DeletePropertyById(cx, obj, _id, res);
4629end;
4630
4631function JSObject.Enumerate(cx: PJSContext; out length: size_t; out data: PjsidVector): PJSIdArray;
4632var obj: PJSObject;
4633begin
4634 obj := @Self;
4635 Result := JS_EnumerateToAutoIdVector(cx, obj, length, data);
4636 {$ifdef WITHASSERT}
4637 Assert(Assigned(Result));
4638 {$ENDIF}
4639end;
4640
4641function JSObject.GetUCProperty(cx: PJSContext; const name: PCChar16;
4642 namelen: size_t; out vp: jsval): boolean;
4643var obj: PJSObject;
4644begin
4645 obj := @Self;
4646 Result := JS_GetUCProperty(cx, obj, name, namelen, vp);
4647end;
4648
4649function JSObject.GetUint16ArrayData(out isSharedMemory: Boolean;
4650 nogc: PJSAutoCheckCannotGC): Puint16Vector;
4651begin
4652 result := JS_GetUInt16ArrayData(@self, isSharedMemory, nogc);
4653end;
4654
4655function JSObject.GetUint32ArrayData(out isSharedMemory: Boolean;
4656 nogc: PJSAutoCheckCannotGC): Puint32Vector;
4657begin
4658 result := JS_GetUint32ArrayData(@self, isSharedMemory, nogc);
4659end;
4660
4661function JSObject.GetUint8ArrayData(out isSharedMemory: Boolean;
4662 nogc: PJSAutoCheckCannotGC): Puint8Vector;
4663begin
4664 result := JS_GetUInt8ArrayData(@self, isSharedMemory, nogc);
4665end;
4666
4667function JSObject.GetUint8ArrayData: Puint8Vector;
4668var isShared: Boolean;
4669begin
4670 result := JS_GetUInt8ArrayData(@self, isShared, nil);
4671end;
4672
4673function JSObject.GetUint8ClampedArrayData(out isSharedMemory: Boolean;
4674 nogc: PJSAutoCheckCannotGC): Puint8Vector;
4675begin
4676 result := JS_GetUint8ClampedArrayData(@self, isSharedMemory, nogc);
4677end;
4678
4679function JSObject.HasInstance(cx: PJSContext; var val: jsval): Boolean;
4680var obj: PJSObject;
4681 res: Boolean;
4682begin
4683 obj := @Self;
4684 Result := JS_HasInstance(cx, obj, val, res) and res;
4685end;
4686
4687function JSObject.HasProperty(cx: PJSContext; const name: PCChar): Boolean;
4688var obj: PJSObject;
4689 found: Boolean;
4690begin
4691 obj := @Self;
4692 Result := JS_HasProperty(cx, obj, name, found) and found;
4693end;
4694
4695function JSObject.HasUCProperty(cx: PJSContext; const name: PCChar16;
4696 namelen: size_t; out found: Boolean): Boolean;
4697var obj: PJSObject;
4698begin
4699 obj := @Self;
4700 Result := JS_HasUCProperty(cx, obj, name, namelen, found);
4701end;
4702
4703function JSObject.InitClass(cx: PJSContext; var parent_proto: PJSObject;
4704 clasp: PJSClass; _constructor: JSNative; nargs: Cardinal; ps: PJSPropertySpec;
4705 fs: PJSFunctionSpec; static_ps: PJSPropertySpec;
4706 static_fs: PJSFunctionSpec): PJSObject;
4707var obj: PJSObject;
4708begin
4709 obj := @Self;
4710 Result := JS_InitClass(cx, obj, parent_proto, clasp, _constructor, nargs, ps, fs, static_ps, static_fs);
4711end;
4712
4713function JSObject.GetArrayBufferByteLength: uint32;
4714begin
4715 result := JS_GetArrayBufferByteLength(@self);
4716end;
4717
4718function JSObject.GetArrayBufferData: Puint8Vector;
4719var isShared: Boolean;
4720begin
4721 result := JS_GetArrayBufferData(@self, isShared, nil);
4722end;
4723
4724function JSObject.GetArrayBufferData(out isSharedMemory: Boolean;
4725 nogc: PJSAutoCheckCannotGC): Puint8Vector;
4726begin
4727 result := JS_GetArrayBufferData(@self, isSharedMemory, nogc);
4728end;
4729
4730function JSObject.GetArrayBufferViewByteLength: uint32;
4731begin
4732 result := JS_GetArrayBufferViewByteLength(@self);
4733end;
4734
4735function JSObject.GetArrayBufferViewType: JSArrayBufferViewType;
4736begin
4737 result := JS_GetArrayBufferViewType(@self);
4738end;
4739
4740function JSObject.GetArrayLength(cx: PJSContext; out length: uint32): Boolean;
4741var obj: PJSObject;
4742begin
4743 obj := @Self;
4744 result := JS_GetArrayLength(cx, obj, length);
4745end;
4746
4747function JSObject.GetClass: PJSClass;
4748begin
4749 result := JS_GetClass(@self);
4750end;
4751
4752function JSObject.GetConstructor(cx: PJSContext): PJSObject;
4753var obj: PJSObject;
4754begin
4755 obj := @Self;
4756 Result := JS_GetConstructor(cx, obj);
4757end;
4758
4759function JSObject.GetElement(cx: PJSContext; index: uint32;
4760 out vp: jsval): Boolean;
4761var obj: PJSObject;
4762begin
4763 obj := @Self;
4764 result := JS_GetElement(cx, obj, index, vp);
4765end;
4766
4767function JSObject.GetFloat32ArrayData(out isSharedMemory: Boolean;
4768 nogc: PJSAutoCheckCannotGC): Pfloat32Vector;
4769begin
4770 result := JS_GetFloat32ArrayData(@self, isSharedMemory, nogc);
4771end;
4772
4773function JSObject.GetFloat64ArrayData(out isSharedMemory: Boolean;
4774 nogc: PJSAutoCheckCannotGC): Pfloat64Vector;
4775begin
4776 result := JS_GetFloat64ArrayData(@self, isSharedMemory, nogc);
4777end;
4778
4779function JSObject.GetFunctionId: PJSString;
4780begin
4781 Result := JS_GetFunctionId(@self);
4782end;
4783
4784function JSObject.SetElement(cx: PJSContext; index: uint32;
4785 const vp: jsval): Boolean;
4786var obj: PJSObject;
4787begin
4788 obj := @Self;
4789 result := JS_SetElement(cx, obj, index, pjsval(@vp)^);
4790end;
4791
4792procedure JSObject.SetPrivate(data: Pointer);
4793begin
4794 JS_SetPrivate(@self, data);
4795end;
4796
4797function JSObject.SetProperty(cx: PJSContext; const name: PCChar;
4798 const vp: jsval): Boolean;
4799var obj: PJSObject;
4800begin
4801 obj := @Self;
4802 Result := JS_SetProperty(cx, obj, name, pjsval(@vp)^);
4803end;
4804
4805function JSObject.SetPrototype(cx: PJSContext; var proto: PJSObject): Boolean;
4806var
4807 obj: PJSObject;
4808begin
4809 obj := @Self;
4810 Result := JS_SetPrototype(cx, obj, proto);
4811end;
4812
4813procedure JSObject.SetReservedSlot(index: uint32; v: jsval);
4814begin
4815 JS_SetReservedSlot(@Self, index, v);
4816end;
4817
4818function JSObject.SetUCProperty(cx: PJSContext; const name: PCChar16;
4819 namelen: size_t; const vp: jsval): boolean;
4820var obj: PJSObject;
4821begin
4822 obj := @Self;
4823 Result := JS_SetUCProperty(cx, obj, name, namelen, pjsval(@vp)^);
4824end;
4825
4826function JSObject.ToJSValue: jsval;
4827begin
4828 Result.asObject := @self;
4829end;
4830
4831function JSObject.GetBufferDataAndLength(out data: Puint8Vector; out len: uint32): boolean;
4832var
4833 isShared: boolean;
4834begin
4835 if Self.IsArrayBufferViewObject then begin
4836 Result := Self.GetObjectAsArrayBufferView(len, isShared, data) <> nil;
4837 end else if Self.IsArrayBufferObject then begin
4838 data := Self.GetArrayBufferData;
4839 len := Self.GetArrayBufferByteLength;
4840 Result := True
4841 end else
4842 Result := False;
4843end;
4844
4845{ ESMException }
4846
4847constructor ESMException.CreateWithTrace(const AFileName: RawUTF8; AJSErrorNum, ALineNum: integer; AMessage: string; const AStackTrace: SynUnicode);
4848{$ifndef SM_DEBUG}
4849const
4850 MODULE_START: SynUnicode = #10'Module.';
4851var
4852 appStackEnd: SizeInt;
4853{$endif}
4854begin
4855 Create(AMessage);
4856 FJSErrorNum := AJSErrorNum;
4857 if AFileName='' then
4858 FFileName := '<>'
4859 else
4860 FFileName := AFileName;
4861 FLineNum := ALineNum;
4862 {$ifdef SM_DEBUG}
4863 FJSStackTrace := AStackTrace;
4864 {$else}
4865 if length(AStackTrace) = 0 then
4866 FJSStackTrace := ''
4867 else begin
4868 appStackEnd := Pos(MODULE_START, AStackTrace);
4869 if appStackEnd = 0 then
4870 FJSStackTrace := AStackTrace
4871 else
4872 FJSStackTrace := Copy(AStackTrace, 0, appStackEnd - 1); // last \n
4873 end;
4874 {$endif}
4875end;
4876
4877procedure ESMException.WriteFormatted(WR: TTextWriter);
4878begin
4879 WR.AddJSONEscape(pointer(FileName), Length(fileName));
4880 WR.Add(':'); WR.Add(Line);
4881 WR.AddShort('\n\nError: ');
4882 WR.AddJSONEscapeString(Message); WR.AddShort('\n');
4883 {$ifdef SM_DEBUG}
4884 WR.AddJSONEscapeString(Stack);
4885 {$else}
4886 WR.AddJSONEscapeW(pointer(Stack), length(Stack));
4887 {$endif}
4888end;
4889
4890{$ifndef NOEXCEPTIONINTERCEPT}
4891function ESMException.CustomLog(
4892 WR: TTextWriter; const Context: TSynLogExceptionContext): boolean;
4893begin
4894 (Context.EInstance as ESMException).WriteFormatted(WR);
4895 result := true; // do not append a address
4896end;
4897{$endif}
4898
4899{ JSArgRec }
4900
4901function JSArgRec.getArgv: PjsvalVector;
4902begin
4903 Result := @rec.argv;
4904end;
4905
4906function JSArgRec.getCalleObject: PJSObject;
4907begin
4908 Result := rec.calle.asObject;
4909end;
4910
4911function JSArgRec.GetIsConstructing: Boolean;
4912begin
4913 Result := rec.this.IsMagic;
4914end;
4915
4916function JSArgRec.getThis(cx: PJSContext): jsval;
4917begin
4918 if rec.this.IsPrimitive then
4919 result._l.asBits := JS_ComputeThis(cx, rec.calle) else
4920 result := rec.this;
4921end;
4922
4923function JSArgRec.getThisObject(cx: PJSContext): PJSObject;
4924begin
4925 Result := this[cx].asObject;
4926end;
4927
4928{ jsid }
4929
4930const
4931 JSID_TYPE_MASK = $7;
4932
4933function jsid.isString: Boolean;
4934begin
4935 Result := JSIdType(asBits and JSID_TYPE_MASK) = JSID_TYPE_STRING;
4936end;
4937
4938function jsid.asJSString: PJSString;
4939begin
4940{$ifdef WITHASSERT}
4941 Assert(isString);
4942{$endif}
4943 Result := PJSString(asBits);
4944end;
4945
4946{ jsval }
4947
4948const
4949{$ifdef CPU64}
4950 JSVAL_LOWER_INCL_TAG_OF_OBJ_OR_NULL_SET = JSVAL_TAG_NULL;
4951 JSVAL_UPPER_EXCL_TAG_OF_PRIMITIVE_SET = JSVAL_TAG_OBJECT;
4952
4953 JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_NUMBER_SET = JSVAL_SHIFTED_TAG_UNDEFINED;
4954 JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_PRIMITIVE_SET = JSVAL_SHIFTED_TAG_OBJECT;
4955{$else}
4956 JSVAL_LOWER_INCL_TAG_OF_OBJ_OR_NULL_SET = JSVAL_TAG_NULL;
4957 JSVAL_UPPER_EXCL_TAG_OF_PRIMITIVE_SET = JSVAL_TAG_OBJECT;
4958 JSVAL_UPPER_INCL_TAG_OF_NUMBER_SET = JSVAL_TAG_INT32;
4959 JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET = JSVAL_TAG_STRING;
4960{$endif}
4961
4962function jsval.getAsBoolean: Boolean;
4963begin
4964 {$ifdef WITHASSERT}
4965 assert(isBoolean);
4966 {$endif}
4967 {$ifdef CPU64}
4968 Result := Boolean(_l.asBits and JSVAL_PAYLOAD_MASK)
4969 {$else}
4970 Result := Boolean(_l.s.payload.boo);
4971 {$endif}
4972end;
4973
4974function jsval.getAsDate(cx: PJSContext): TDateTime;
4975var oDate: PJSObject;
4976{$ifdef CONSIDER_TIME_IN_Z} // as defined in SyNode.inc
4977 ms: double;
4978 ms64: Int64;
4979 fval: jsval;
4980{$else}
4981 d, m, Y, h, mn, s, ml: Integer;
4982 v, fval: jsval;
4983 function GetIntFuncPropVal(funcName: PWideChar): Integer;
4984 begin
4985 Result := 0;
4986 if oDate.GetUCProperty(cx, pointer(funcName), Length(funcName), fval) then
4987 if oDate.CallFunctionValue(cx, fval, 0, nil, v) then
4988 Result := v.asInteger;
4989 end;
4990{$endif}
4991begin
4992 oDate := getAsObject;
4993 if not oDate.isDate(cx) then
4994 raise ESMException.create('not a DateTime object');
4995{$ifdef CONSIDER_TIME_IN_Z}
4996 ms := 0;
4997 if oDate.CallFunctionName(cx, PCChar('getTime'), 0, nil, fval) then
4998 ms := fval.asDouble;
4999 if ms = 0 then
5000 raise ESMException.Create('JSDateToDateTime: no getTime() in Date object');
5001 ms64 := Trunc(ms);
5002 // W/O millisec: Result := IncMilliSecond(UnixDateDelta, ms64);
5003 Result := UnixMSTimeToDateTime(ms64);
5004{$else}
5005 d := GetIntFuncPropVal('getDate');
5006 m := GetIntFuncPropVal('getMonth') + 1; //WTF months start from 0
5007 Y := GetIntFuncPropVal('getFullYear');
5008 h := GetIntFuncPropVal('getHours');
5009 mn := GetIntFuncPropVal('getMinutes');
5010 s := GetIntFuncPropVal('getSeconds');
5011 ml := GetIntFuncPropVal('getMilliseconds');
5012 Result := EncodeDateTime(Y, m, d, h, mn, s, ml);
5013{$endif}
5014end;
5015
5016function jsval.getAsDouble: Double;
5017begin
5018 {$ifdef WITHASSERT}
5019 assert(isDouble);
5020 {$endif}
5021 Result := _l.asDouble;
5022end;
5023
5024function jsval.getAsInteger: Integer;
5025begin
5026 {$ifdef WITHASSERT}
5027 assert(isInteger);
5028 {$endif}
5029 {$ifdef CPU64}
5030 Result := int32(_l.asBits);
5031 {$else}
5032 Result := _l.s.payload.i32;
5033 {$endif}
5034end;
5035
5036function writeCallback(const buf: PCChar16; len: uint32; data: pointer): Boolean; cdecl;
5037begin
5038 TTextWriter(data).AddNoJSONEscapeW(pointer(buf),len);
5039 result := true;
5040end;
5041
5042procedure jsval.AddJSON(cx: PJSContext; W: TTextWriter);
5043var
5044// voidVal: jsval;
5045 T: JSType;
5046begin
5047 if @self=nil then
5048 W.AddShort('null')
5049 else begin
5050 T := cx.TypeOfValue(self);
5051 case T of
5052 JSTYPE_VOID,
5053 JSTYPE_NULL:
5054 W.AddShort('null');
5055 JSTYPE_STRING:
5056 asJSString.ToJSONString(cx,W);
5057 JSTYPE_NUMBER:
5058 if isInteger then
5059 W.Add(asInteger) else
5060 W.AddDouble(asDouble);
5061 JSTYPE_BOOLEAN:
5062 W.Add(asBoolean);
5063 JSTYPE_OBJECT,
5064 JSTYPE_FUNCTION: begin
5065 if not Stringify(cx, nullObj, JSVAL_VOID, writeCallback, pointer(W)) then
5066 ;
5067 end
5068 else
5069 raise ESMException.CreateFmt('Unhandled AddJSON(%d)',[ord(T)]);
5070 end;
5071 end;
5072end;
5073
5074function jsval.getAsJson(cx: PJSContext): RawUTF8;
5075var W: TJSONWriter;
5076begin
5077 W := TJSONWriter.CreateOwnedStream;
5078 try
5079 AddJSON(cx,W);
5080 W.SetText(result);
5081 finally
5082 W.Free;
5083 end;
5084end;
5085
5086function jsval.getAsInt64: Int64;
5087begin
5088 if isInteger then
5089 result := asInteger else
5090 {$ifdef WITHASSERT}
5091 if not isDouble then
5092 raise ESMException.Create('jsval.getAsInt64!') else
5093 {$endif}
5094 result := trunc(asDouble);
5095end;
5096
5097function jsval.getAsObject: PJSObject;
5098{$ifdef CPU64}
5099var ptrBits: UInt64 absolute Result;
5100{$endif}
5101begin
5102 {$ifdef WITHASSERT}
5103 assert(isObject);
5104 {$endif}
5105 {$ifdef CPU64}
5106 ptrBits := _l.asBits and JSVAL_PAYLOAD_MASK;
5107 {$ifdef WITHASSERT}
5108 assert(ptrBits and 7 = 0);
5109 {$endif}
5110 {$else}
5111 Result := _l.s.payload.obj;
5112 {$endif}
5113end;
5114
5115function jsval.getIsBoolean: Boolean;
5116begin
5117 {$ifdef CPU64}
5118 Result := _l.asBits shr JSVAL_TAG_SHIFT = JSVAL_TAG_BOOLEAN;
5119 {$else}
5120 Result := _l.s.tag = JSVAL_TAG_BOOLEAN;
5121 {$endif}
5122end;
5123
5124function jsval.getIsDouble: Boolean;
5125begin
5126 {$ifdef CPU64}
5127 Result := _l.asBits <= JSVAL_SHIFTED_TAG_MAX_DOUBLE
5128 {$else}
5129 Result := UInt32(_l.s.tag) <= UInt32(JSVAL_TAG_CLEAR)
5130 {$endif}
5131end;
5132
5133function jsval.getIsInteger: Boolean;
5134begin
5135 {$ifdef CPU64}
5136 Result := _l.asBits shr JSVAL_TAG_SHIFT = JSVAL_TAG_INT32;
5137 {$else}
5138 Result := _l.s.tag = JSVAL_TAG_INT32;
5139 {$endif}
5140end;
5141
5142function jsval.getIsNull: Boolean;
5143begin
5144 {$ifdef CPU64}
5145 Result := _l.asBits = JSVAL_SHIFTED_TAG_NULL;
5146 {$else}
5147 Result := _l.s.tag = JSVAL_TAG_NULL;
5148 {$endif}
5149end;
5150
5151function jsval.getIsNumber: Boolean;
5152begin
5153 {$ifdef CPU64}
5154 Result := _l.asBits < JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_NUMBER_SET;
5155 {$else}
5156 {$ifdef WITHASSERT}
5157 assert(_l.s.tag <> JSVAL_TAG_CLEAR);
5158 {$endif}
5159 Result := (UInt32(_l.s.tag) <= UInt32(JSVAL_UPPER_INCL_TAG_OF_NUMBER_SET));
5160 {$endif}
5161end;
5162
5163function jsval.getIsObject: Boolean;
5164begin
5165 {$ifdef CPU64}
5166 {$ifdef WITHASSERT}
5167 Assert(_l.asBits shr JSVAL_TAG_SHIFT <= JSVAL_TAG_OBJECT);
5168 {$endif}
5169 Result := _l.asBits >= JSVAL_SHIFTED_TAG_OBJECT;
5170 {$else}
5171 {$ifdef WITHASSERT}
5172 Assert(_l.s.tag <= JSVAL_TAG_OBJECT);
5173 {$endif}
5174 Result := (UInt32(_l.s.tag) >= UInt32(JSVAL_LOWER_INCL_TAG_OF_OBJ_OR_NULL_SET));
5175 {$endif}
5176end;
5177
5178function jsval.getIsSimpleVariant(cx: PJSContext): Boolean;
5179var
5180 t: JSType;
5181begin
5182 t := ValType(cx);
5183 Result := (t = JSTYPE_VOID) or (t = JSTYPE_NULL) or (t = JSTYPE_STRING)
5184 or (t = JSTYPE_NUMBER) or (t = JSTYPE_BOOLEAN);
5185end;
5186
5187function jsval.getIsString: Boolean;
5188begin
5189 {$ifdef CPU64}
5190 Result := _l.asBits shr JSVAL_TAG_SHIFT = JSVAL_TAG_STRING;
5191 {$else}
5192 Result := _l.s.tag = JSVAL_TAG_STRING;
5193 {$endif}
5194end;
5195
5196function jsval.getIsVoid: Boolean;
5197begin
5198 {$ifdef CPU64}
5199 Result := _l.asBits = JSVAL_SHIFTED_TAG_UNDEFINED;
5200 {$else}
5201 Result := _l.s.tag = JSVAL_TAG_UNDEFINED;
5202 {$endif}
5203end;
5204
5205function jsval.getJSString: PJSString;
5206begin
5207 {$ifdef CPU64}
5208 Result := PJSString(_l.asBits and JSVAL_PAYLOAD_MASK);
5209 {$else}
5210 {$ifdef WITHASSERT}
5211 Assert(isString);
5212 {$endif}
5213 Result := _l.s.payload.str;
5214 {$endif}
5215end;
5216
5217function jsval.getPrivate: Pointer;
5218begin
5219 {$ifdef CPU64}
5220 {$ifdef WITHASSERT}
5221 Assert(_l.asBits and $8000000000000000 = 0);
5222 {$endif}
5223 Result := Pointer(_l.asBits shl 1);
5224 {$else}
5225 {$ifdef WITHASSERT}
5226 Assert(isDouble);
5227 {$endif}
5228 Result := _l.s.payload.ptr;
5229 {$endif}
5230end;
5231
5232function jsval.getSimpleVariant(cx: PJSContext): Variant;
5233var
5234 t: JSType;
5235begin
5236 t := ValType(cx);
5237 case t of
5238 JSTYPE_VOID:
5239 VarClear(result);
5240 JSTYPE_NULL:
5241 SetVariantNull(result);
5242// JSTYPE_OBJECT:
5243// todo
5244 JSTYPE_STRING:
5245 getJSString.ToVariant(cx,result);
5246 JSTYPE_NUMBER:
5247 if getIsInteger then
5248 result := getAsInteger else
5249 result := getAsDouble;
5250 JSTYPE_BOOLEAN:
5251 result := getAsBoolean;
5252// JSTYPE_FUNCTION:
5253// todo
5254 else
5255 raise ESMException.CreateFmt('Unhandled ToVariant(%d)',[ord(t)]);
5256 end;
5257
5258end;
5259
5260function jsval.IsMagic: Boolean;
5261begin
5262 {$IFDEF CPU64}
5263 Result := _l.asBits shr JSVAL_TAG_SHIFT = JSVAL_TAG_MAGIC;
5264 {$ELSE}
5265 Result := _l.s.tag = JSVAL_TAG_MAGIC;
5266 {$ENDIF}
5267end;
5268
5269function jsval.IsPrimitive: Boolean;
5270begin
5271 {$IFDEF CPU64}
5272 Result := _l.asBits < JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_PRIMITIVE_SET;
5273 {$ELSE}
5274 Result := (UInt32(_l.s.tag) < UInt32(JSVAL_UPPER_EXCL_TAG_OF_PRIMITIVE_SET));
5275 {$ENDIF}
5276end;
5277
5278function doubleIsInt(Value: Double):boolean; {$ifdef HASINLINE}inline;{$endif}
5279var Value_int64:Int64 absolute Value;
5280 len: Int16;
5281begin
5282 len := (Value_int64 shr 52) and $7FF - $3FF;
5283 result := ((len >= 0) and (len < 31) and ((Value_int64 and (QWORD(1) shl (52 - len)-1)) = 0))
5284 or (Value_int64 = 0) or (Value_int64 = $C1E0000000000000);
5285end;
5286
5287function doubleToInt(Value: Double):Integer; {$ifdef HASINLINE}inline;{$endif}
5288var Value_int64:Int64 absolute Value;
5289 len: Smallint;
5290begin
5291 if Value_int64 = 0 then
5292 result := 0
5293 else begin
5294 len := (Value_int64 shr 52) and $7FF - $3FF;
5295 Result := (Value_int64 and $000FFFFFFFFFFFFF or $0010000000000000) shr (52-len);
5296 if (Value_int64 and $8000000000000000)<>0 then
5297 Result := -Result;
5298 end
5299end;
5300
5301procedure jsval.setAsBoolean(const Value: Boolean);
5302begin
5303 {$ifdef CPU64}
5304 _l.asBits := uint64(ord(Value)) or JSVAL_SHIFTED_TAG_BOOLEAN;
5305 {$else}
5306 _l.s.tag := JSVAL_TAG_BOOLEAN;
5307 _l.s.payload.boo := ord(Value);
5308 {$endif}
5309end;
5310
5311procedure jsval.setAsDate(cx: PJSContext; const Value: TDateTime);
5312var dmsec: double;
5313 unixTime: Int64;
5314 {$ifdef CONSIDER_TIME_IN_Z} // as defined in SyNode.inc
5315 oDate: PJSObject;
5316{$else}
5317 // this realisation is buggy - it ignores timezone rules change history
5318 // for server-side realisation the best solution is to use GMT time here
5319 ms: Word;
5320 STLocal, STUtc: TSystemTime;
5321 TZ: TTimeZoneInformation;
5322 AUTCDateTime: TDateTime;
5323{$endif}
5324begin
5325{$ifdef CONSIDER_TIME_IN_Z}
5326 unixTime := DateTimeToUnixMSTime(Value);
5327 dmsec := unixTime-(unixTime mod 1000);
5328 oDate := cx.NewDateObjectMsec(dmsec);
5329 if not oDate.IsDate(cx) then
5330 raise ESMException.CreateFmt('SetDateTime(%g): not a valid date',[Value]);
5331 setAsObject(oDate);
5332{$else}
5333 DateTimeToSystemTime(Value, STLocal);
5334 GetTimeZoneInformation(TZ);
5335 // use TzSpecificLocalTimeToSystemTime?
5336 TZ.Bias := -TZ.Bias;
5337 TZ.StandardBias := -TZ.StandardBias;
5338 TZ.DaylightBias := -TZ.DaylightBias;
5339 SystemTimeToTzSpecificLocalTime(@TZ, STLocal, STUtc);
5340 ms := STUtc.wMilliseconds;
5341 AUTCDateTime := SystemTimeToDateTime(STUtc);
5342 dmSec := DateTimeToUnixMSTime(AUTCDateTime) + ms;
5343 setAsObject(cx.NewDateObjectMsec(dmsec));
5344{$endif}
5345end;
5346
5347procedure jsval.setAsDouble(const Value: Double);
5348begin
5349 if doubleIsInt(Value) then
5350 asInteger := doubleToInt(Value)
5351 else begin
5352 _l.asDouble := Value;
5353 if ((_l.asBits and $7FF0000000000000) = $7FF0000000000000) and
5354 ((_l.asBits and $000FFFFFFFFFFFFF) <> $0000000000000000) then
5355 _l.asBits := JSVAL_NAN_impl; // canonize NaN
5356 end;
5357end;
5358
5359procedure jsval.setAsInteger(const Value: Integer);
5360
5361begin
5362 {$ifdef CPU64}
5363 _l.asBits := Value;
5364 _l.asBits := uint32(Value) or JSVAL_SHIFTED_TAG_INT32;
5365 {$else}
5366 _l.s.tag := JSVAL_TAG_INT32;
5367 _l.s.payload.i32 := Value;
5368 {$endif}
5369end;
5370
5371procedure jsval.setAsJson(cx: PJSContext; const Value: RawUTF8);
5372var tmp: RawUnicode;
5373 len: integer;
5374begin
5375 if Value='' then begin
5376 SetVoid;
5377 end else begin
5378 len := Utf8DecodeToRawUnicodeUI(Value,tmp);
5379 if not JS_ParseJSON(cx, pointer(tmp), len shr 1, self) then
5380 {$ifdef WITHASSERT}
5381 raise ESMException.Create('jsval.setAsJson!') else
5382 {$ELSE}
5383 SetVoid;
5384 {$endif}
5385 end;
5386end;
5387
5388procedure jsval.setAsInt64(const Value: Int64);
5389begin
5390 if (Value>=Low(integer)) and (Value<=High(integer)) then
5391 setAsInteger(Value) else
5392 setAsDouble(Value);
5393end;
5394
5395procedure jsval.setAsObject(const Value: PJSObject);
5396{$ifdef CPU64}
5397var objBits: UInt64 absolute Value;
5398{$endif}
5399begin
5400 {$ifdef CPU64}
5401 {$ifdef WITHASSERT}
5402 Assert(objBits shr JSVAL_TAG_SHIFT = 0);
5403 {$endif}
5404 _l.asBits := QWord(objBits or JSVAL_SHIFTED_TAG_OBJECT);
5405 {$else}
5406 if Value<>nil then begin
5407 _l.s.tag := JSVAL_TAG_OBJECT;
5408 _l.s.payload.obj := Value;
5409 end else
5410 _l.asBits := JSVAL_NULL_impl;
5411 {$endif}
5412end;
5413
5414procedure jsval.setJSString(const Value: PJSString);
5415{$ifdef CPU64}
5416var strBits: UInt64 absolute Value;
5417{$endif}
5418begin
5419 {$ifdef CPU64}
5420 {$ifdef WITHASSERT}
5421 Assert(strBits shr JSVAL_TAG_SHIFT = 0);
5422 {$endif}
5423 _l.asBits := strBits or JSVAL_SHIFTED_TAG_STRING;
5424 {$else}
5425 {$ifdef WITHASSERT}
5426 assert(str<>nil) ;
5427 {$endif}
5428 _l.s.tag := JSVAL_TAG_STRING;
5429 _l.s.payload.str := Value;
5430 {$endif}
5431end;
5432
5433procedure jsval.setNull;
5434begin
5435 _l.asBits := JSVAL_NULL_impl;
5436end;
5437
5438procedure jsval.setPrivate(const Value: Pointer);
5439{$ifdef CPU64}
5440var ptrBits: UInt64 absolute Value;
5441{$endif}
5442begin
5443 {$ifdef CPU64}
5444 {$ifdef WITHASSERT}
5445 Assert(ptrBits and 1 = 0);
5446 {$endif}
5447 _l.asBits := ptrBits shr 1;
5448 {$ifdef WITHASSERT}
5449 assert(isDouble);
5450 {$endif}
5451 {$else}
5452 {$ifdef WITHASSERT}
5453 assert((uint32(ptr) and 1) = 0);
5454 {$endif}
5455 _l.s.tag := JSValueTag(0);
5456 _l.s.payload.ptr := Value;
5457 {$ifdef WITHASSERT}
5458 assert(isDouble);
5459 {$endif}
5460 {$endif}
5461end;
5462
5463procedure jsval.setSimpleVariant(cx: PJSContext; const Value: Variant);
5464begin
5465 with TVarData(Value) do
5466 case VType of
5467 varNull: setNull;
5468 varEmpty: setVoid;
5469 varBoolean: setAsBoolean(VBoolean);
5470 varSmallint: setAsInteger(VSmallInt);
5471 {$ifndef DELPHI5OROLDER}
5472 varShortInt: setAsInteger(VShortInt);
5473 varWord: setAsInteger(VWord);
5474 varLongWord: setAsInt64(VLongWord);
5475 {$endif}
5476 varByte: setAsInteger(VByte);
5477 varInteger: setAsInteger(VInteger);
5478 {$ifdef FPC}varQword,{$endif}
5479 varInt64: setAsInt64(VInt64);
5480
5481 varSingle: setAsDouble(VSingle);
5482 varDouble: setAsDouble(VDouble);
5483 varCurrency: setAsDouble(VCurrency);
5484 varDate: setAsDate(cx, VDate);
5485 varOleStr: setJSString(cx.NewJSString(WideString(VAny)));
5486 varString: setJSString(cx.NewJSString(VAny,length(RawByteString(VAny)),
5487 {$ifndef UNICODE} CP_UTF8));
5488 {$else} StringCodePage(RawByteString(VAny))));
5489 varUString: setJSString(cx.NewJSString(UnicodeString(VAny)));
5490 {$endif}
5491 else
5492 if VType=varByRef or varVariant then
5493 setSimpleVariant(cx,PVariant(VPointer)^) else
5494 if VType=varByRef or varOleStr then
5495 setJSString(cx.NewJSString(PWideString(VAny)^)) else
5496 {$ifdef UNICODE}
5497 if VType=varByRef or varUString then
5498 setJSString(cx.NewJSString(PUnicodeString(VAny)^)) else
5499 {$endif}
5500 raise ESMException.CreateFmt('Unhandled variant type %d',[VType]);
5501 end;
5502end;
5503
5504procedure jsval.setVoid;
5505begin
5506 _l.asBits := JSVAL_VOID_impl;
5507end;
5508
5509function jsval.Stringify(cx: PJSContext; var replacer: PJSObject;
5510 space: jsval; callback: JSONWriteCallback; data: pointer): Boolean;
5511begin
5512 with TSynFPUException.ForLibraryCode do
5513 Result := JS_Stringify(cx, Self, replacer, space, callback, data);
5514end;
5515
5516function jsval.toSource(cx: PJSContext): PJSString;
5517begin
5518 Result := JS_ValueToSource(cx, self);
5519end;
5520
5521function jsval.ValType(cx: PJSContext): JSType;
5522begin
5523 Result := cx.TypeOfValue(self);
5524end;
5525
5526class function jsval.NullValue: jsval;
5527begin
5528 Result.setNull();
5529end;
5530
5531class function jsval.Int32Value(v: integer): jsval;
5532begin
5533 Result.asInteger := v;
5534end;
5535
5536class function jsval.BooleanValue(v: boolean): jsval;
5537begin
5538 Result.asBoolean := v;
5539end;
5540
5541class function jsval.TrueValue: jsval;
5542begin
5543 Result.asBoolean := True;
5544end;
5545
5546class function jsval.FalseValue: jsval;
5547begin
5548 Result.asBoolean := False;
5549end;
5550
5551class function jsval.DoubleValue(v: double): jsval;
5552begin
5553 Result.asDouble := v;
5554end;
5555
5556class function jsval.StringValue(v: PJSString): jsval;
5557begin
5558 Result.asJSString := v;
5559end;
5560
5561class function jsval.ObjectValue(v: PJSObject): jsval;
5562begin
5563 Result.asObject := v;
5564end;
5565
5566class function jsval.Int64Value(v: Int64): jsval;
5567begin
5568 Result.asInt64 := v;
5569end;
5570
5571function SimpleVariantToJSval(cx: PJSContext; val: Variant): jsval;
5572begin
5573 Result.asSimpleVariant[cx] := val;
5574end;
5575
5576initialization
5577 Latin1AnsiConvert := TSynAnsiConvert.Engine(CODEPAGE_LATIN1);
5578end.