1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 /* JavaScript API. */
8
9 #ifndef jsapi_h
10 #define jsapi_h
11
12 #include "mozilla/AlreadyAddRefed.h"
13 #include "mozilla/FloatingPoint.h"
14 #include "mozilla/Maybe.h"
15 #include "mozilla/MemoryReporting.h"
16 #include "mozilla/RangedPtr.h"
17 #include "mozilla/RefPtr.h"
18 #include "mozilla/TimeStamp.h"
19 #include "mozilla/Utf8.h"
20 #include "mozilla/Variant.h"
21
22 #include <stdarg.h>
23 #include <stddef.h>
24 #include <stdint.h>
25 #include <stdio.h>
26
27 #include "jspubtd.h"
28
29 #include "js/AllocPolicy.h"
30 #include "js/CallArgs.h"
31 #include "js/CharacterEncoding.h"
32 #include "js/Class.h"
33 #include "js/CompileOptions.h"
34 #include "js/Context.h"
35 #include "js/ErrorReport.h"
36 #include "js/Exception.h"
37 #include "js/GCAPI.h"
38 #include "js/GCVector.h"
39 #include "js/HashTable.h"
40 #include "js/Id.h"
41 #include "js/MapAndSet.h"
42 #include "js/MemoryFunctions.h"
43 #include "js/OffThreadScriptCompilation.h"
44 #include "js/Principals.h"
45 #include "js/PropertyDescriptor.h"
46 #include "js/PropertySpec.h"
47 #include "js/Realm.h"
48 #include "js/RealmIterators.h"
49 #include "js/RealmOptions.h"
50 #include "js/RefCounted.h"
51 #include "js/RootingAPI.h"
52 #include "js/String.h"
53 #include "js/TracingAPI.h"
54 #include "js/Transcoding.h"
55 #include "js/UniquePtr.h"
56 #include "js/Utility.h"
57 #include "js/Value.h"
58 #include "js/ValueArray.h"
59 #include "js/Vector.h"
60 #include "js/WeakMap.h"
61 #include "js/Zone.h"
62
63 /************************************************************************/
64
65 namespace JS {
66 /**
67 * Tell JS engine whether to use fdlibm for Math.sin, Math.cos, and Math.tan.
68 * Using fdlibm ensures that we don't expose a math fingerprint.
69 */
70 extern JS_PUBLIC_API void SetUseFdlibmForSinCosTan(bool value);
71 } // namespace JS
72
73 /************************************************************************/
74
75 struct JSFunctionSpec;
76 struct JSPropertySpec;
77
78 namespace JS {
79
80 template <typename UnitT>
81 class SourceText;
82
83 class TwoByteChars;
84
85 using ValueVector = JS::GCVector<JS::Value>;
86 using IdVector = JS::GCVector<jsid>;
87 using ScriptVector = JS::GCVector<JSScript*>;
88 using StringVector = JS::GCVector<JSString*>;
89
90 } /* namespace JS */
91
92 /* Callbacks and their arguments. */
93
94 /************************************************************************/
95
96 // Callback for the embedding to map from a ScriptSourceObject private-value to
97 // an object that is exposed as the source "element" in debugger API. This hook
98 // must be infallible, but can return nullptr if no such element exists.
99 using JSSourceElementCallback = JSObject* (*)(JSContext*, JS::HandleValue);
100
101 using JSInterruptCallback = bool (*)(JSContext*);
102
103 /**
104 * Callback used to ask the embedding for the cross compartment wrapper handler
105 * that implements the desired prolicy for this kind of object in the
106 * destination compartment. |obj| is the object to be wrapped. If |existing| is
107 * non-nullptr, it will point to an existing wrapper object that should be
108 * re-used if possible. |existing| is guaranteed to be a cross-compartment
109 * wrapper with a lazily-defined prototype and the correct global. It is
110 * guaranteed not to wrap a function.
111 */
112 using JSWrapObjectCallback = JSObject* (*)(JSContext*, JS::HandleObject,
113 JS::HandleObject);
114
115 /**
116 * Callback used by the wrap hook to ask the embedding to prepare an object
117 * for wrapping in a context. This might include unwrapping other wrappers
118 * or even finding a more suitable object for the new compartment. If |origObj|
119 * is non-null, then it is the original object we are going to swap into during
120 * a transplant.
121 */
122 using JSPreWrapCallback = void (*)(JSContext*, JS::HandleObject,
123 JS::HandleObject, JS::HandleObject,
124 JS::HandleObject, JS::MutableHandleObject);
125
126 struct JSWrapObjectCallbacks {
127 JSWrapObjectCallback wrap;
128 JSPreWrapCallback preWrap;
129 };
130
131 /**
132 * Callback used to intercept JavaScript errors.
133 */
134 struct JSErrorInterceptor {
135 /**
136 * This method is called whenever an error has been raised from JS code.
137 *
138 * This method MUST be infallible.
139 */
140 virtual void interceptError(JSContext* cx, JS::HandleValue error) = 0;
141 };
142
143 /************************************************************************/
144
JS_NumberValue(double d)145 static MOZ_ALWAYS_INLINE JS::Value JS_NumberValue(double d) {
146 int32_t i;
147 d = JS::CanonicalizeNaN(d);
148 if (mozilla::NumberIsInt32(d, &i)) {
149 return JS::Int32Value(i);
150 }
151 return JS::DoubleValue(d);
152 }
153
154 /************************************************************************/
155
156 JS_PUBLIC_API bool JS_StringHasBeenPinned(JSContext* cx, JSString* str);
157
158 /************************************************************************/
159
160 /** Microseconds since the epoch, midnight, January 1, 1970 UTC. */
161 extern JS_PUBLIC_API int64_t JS_Now(void);
162
163 extern JS_PUBLIC_API bool JS_ValueToObject(JSContext* cx, JS::HandleValue v,
164 JS::MutableHandleObject objp);
165
166 extern JS_PUBLIC_API JSFunction* JS_ValueToFunction(JSContext* cx,
167 JS::HandleValue v);
168
169 extern JS_PUBLIC_API JSFunction* JS_ValueToConstructor(JSContext* cx,
170 JS::HandleValue v);
171
172 extern JS_PUBLIC_API JSString* JS_ValueToSource(JSContext* cx,
173 JS::Handle<JS::Value> v);
174
175 extern JS_PUBLIC_API bool JS_DoubleIsInt32(double d, int32_t* ip);
176
177 extern JS_PUBLIC_API JSType JS_TypeOfValue(JSContext* cx,
178 JS::Handle<JS::Value> v);
179
180 namespace JS {
181
182 extern JS_PUBLIC_API const char* InformalValueTypeName(const JS::Value& v);
183
184 /** Timing information for telemetry purposes **/
185 struct JSTimers {
186 mozilla::TimeDuration executionTime; // Total time spent executing
187 mozilla::TimeDuration delazificationTime; // Total time spent delazifying
188 mozilla::TimeDuration xdrEncodingTime; // Total time spent XDR encoding
189 mozilla::TimeDuration gcTime; // Total time spent in GC
190 mozilla::TimeDuration
191 protectTime; // Total time spent protecting JIT executable memory
192 mozilla::TimeDuration
193 baselineCompileTime; // Total time spent in baseline compiler
194 };
195
196 extern JS_PUBLIC_API JSTimers GetJSTimers(JSContext* cx);
197
198 } /* namespace JS */
199
200 /** True iff fun is the global eval function. */
201 extern JS_PUBLIC_API bool JS_IsBuiltinEvalFunction(JSFunction* fun);
202
203 /** True iff fun is the Function constructor. */
204 extern JS_PUBLIC_API bool JS_IsBuiltinFunctionConstructor(JSFunction* fun);
205
206 extern JS_PUBLIC_API const char* JS_GetImplementationVersion(void);
207
208 extern JS_PUBLIC_API void JS_SetWrapObjectCallbacks(
209 JSContext* cx, const JSWrapObjectCallbacks* callbacks);
210
211 // Set a callback that will be called whenever an error
212 // is thrown in this runtime. This is designed as a mechanism
213 // for logging errors. Note that the VM makes no attempt to sanitize
214 // the contents of the error (so it may contain private data)
215 // or to sort out among errors (so it may not be the error you
216 // are interested in or for the component in which you are
217 // interested).
218 //
219 // If the callback sets a new error, this new error
220 // will replace the original error.
221 //
222 // May be `nullptr`.
223 // This is a no-op if built without NIGHTLY_BUILD.
224 extern JS_PUBLIC_API void JS_SetErrorInterceptorCallback(
225 JSRuntime*, JSErrorInterceptor* callback);
226
227 // This returns nullptr if built without NIGHTLY_BUILD.
228 extern JS_PUBLIC_API JSErrorInterceptor* JS_GetErrorInterceptorCallback(
229 JSRuntime*);
230
231 // Examine a value to determine if it is one of the built-in Error types.
232 // If so, return the error type.
233 extern JS_PUBLIC_API mozilla::Maybe<JSExnType> JS_GetErrorType(
234 const JS::Value& val);
235
236 extern JS_PUBLIC_API bool JS_WrapObject(JSContext* cx,
237 JS::MutableHandleObject objp);
238
239 extern JS_PUBLIC_API bool JS_WrapValue(JSContext* cx,
240 JS::MutableHandleValue vp);
241
242 extern JS_PUBLIC_API JSObject* JS_TransplantObject(JSContext* cx,
243 JS::HandleObject origobj,
244 JS::HandleObject target);
245
246 /**
247 * Resolve id, which must contain either a string or an int, to a standard
248 * class name in obj if possible, defining the class's constructor and/or
249 * prototype and storing true in *resolved. If id does not name a standard
250 * class or a top-level property induced by initializing a standard class,
251 * store false in *resolved and just return true. Return false on error,
252 * as usual for bool result-typed API entry points.
253 *
254 * This API can be called directly from a global object class's resolve op,
255 * to define standard classes lazily. The class should either have an enumerate
256 * hook that calls JS_EnumerateStandardClasses, or a newEnumerate hook that
257 * calls JS_NewEnumerateStandardClasses. newEnumerate is preferred because it's
258 * faster (does not define all standard classes).
259 */
260 extern JS_PUBLIC_API bool JS_ResolveStandardClass(JSContext* cx,
261 JS::HandleObject obj,
262 JS::HandleId id,
263 bool* resolved);
264
265 extern JS_PUBLIC_API bool JS_MayResolveStandardClass(const JSAtomState& names,
266 jsid id,
267 JSObject* maybeObj);
268
269 extern JS_PUBLIC_API bool JS_EnumerateStandardClasses(JSContext* cx,
270 JS::HandleObject obj);
271
272 /**
273 * Fill "properties" with a list of standard class names that have not yet been
274 * resolved on "obj". This can be used as (part of) a newEnumerate class hook
275 * on a global. Already-resolved things are excluded because they might have
276 * been deleted by script after being resolved and enumeration considers
277 * already-defined properties anyway.
278 */
279 extern JS_PUBLIC_API bool JS_NewEnumerateStandardClasses(
280 JSContext* cx, JS::HandleObject obj, JS::MutableHandleIdVector properties,
281 bool enumerableOnly);
282
283 /**
284 * Fill "properties" with a list of standard class names. This can be used for
285 * proxies that want to define behavior that looks like enumerating a global
286 * without touching the global itself.
287 */
288 extern JS_PUBLIC_API bool JS_NewEnumerateStandardClassesIncludingResolved(
289 JSContext* cx, JS::HandleObject obj, JS::MutableHandleIdVector properties,
290 bool enumerableOnly);
291
292 extern JS_PUBLIC_API bool JS_GetClassObject(JSContext* cx, JSProtoKey key,
293 JS::MutableHandle<JSObject*> objp);
294
295 extern JS_PUBLIC_API bool JS_GetClassPrototype(
296 JSContext* cx, JSProtoKey key, JS::MutableHandle<JSObject*> objp);
297
298 namespace JS {
299
300 /*
301 * Determine if the given object is an instance/prototype/constructor for a
302 * standard class. If so, return the associated JSProtoKey. If not, return
303 * JSProto_Null.
304 */
305
306 extern JS_PUBLIC_API JSProtoKey IdentifyStandardInstance(JSObject* obj);
307
308 extern JS_PUBLIC_API JSProtoKey IdentifyStandardPrototype(JSObject* obj);
309
310 extern JS_PUBLIC_API JSProtoKey
311 IdentifyStandardInstanceOrPrototype(JSObject* obj);
312
313 extern JS_PUBLIC_API JSProtoKey IdentifyStandardConstructor(JSObject* obj);
314
315 extern JS_PUBLIC_API void ProtoKeyToId(JSContext* cx, JSProtoKey key,
316 JS::MutableHandleId idp);
317
318 } /* namespace JS */
319
320 extern JS_PUBLIC_API JSProtoKey JS_IdToProtoKey(JSContext* cx, JS::HandleId id);
321
322 extern JS_PUBLIC_API bool JS_IsGlobalObject(JSObject* obj);
323
324 extern JS_PUBLIC_API JSObject* JS_GlobalLexicalEnvironment(JSObject* obj);
325
326 extern JS_PUBLIC_API bool JS_HasExtensibleLexicalEnvironment(JSObject* obj);
327
328 extern JS_PUBLIC_API JSObject* JS_ExtensibleLexicalEnvironment(JSObject* obj);
329
330 namespace JS {
331
332 /**
333 * Get the current realm's global. Returns nullptr if no realm has been
334 * entered.
335 */
336 extern JS_PUBLIC_API JSObject* CurrentGlobalOrNull(JSContext* cx);
337
338 /**
339 * Get the global object associated with an object's realm. The object must not
340 * be a cross-compartment wrapper (because CCWs are shared by all realms in the
341 * compartment).
342 */
343 extern JS_PUBLIC_API JSObject* GetNonCCWObjectGlobal(JSObject* obj);
344
345 } // namespace JS
346
347 /**
348 * Add 'Reflect.parse', a SpiderMonkey extension, to the Reflect object on the
349 * given global.
350 */
351 extern JS_PUBLIC_API bool JS_InitReflectParse(JSContext* cx,
352 JS::HandleObject global);
353
354 /**
355 * Add various profiling-related functions as properties of the given object.
356 * Defined in builtin/Profilers.cpp.
357 */
358 extern JS_PUBLIC_API bool JS_DefineProfilingFunctions(JSContext* cx,
359 JS::HandleObject obj);
360
361 /* Defined in vm/Debugger.cpp. */
362 extern JS_PUBLIC_API bool JS_DefineDebuggerObject(JSContext* cx,
363 JS::HandleObject obj);
364
365 namespace JS {
366
367 /**
368 * Tell JS engine whether Profile Timeline Recording is enabled or not.
369 * If Profile Timeline Recording is enabled, data shown there like stack won't
370 * be optimized out.
371 * This is global state and not associated with specific runtime or context.
372 */
373 extern JS_PUBLIC_API void SetProfileTimelineRecordingEnabled(bool enabled);
374
375 extern JS_PUBLIC_API bool IsProfileTimelineRecordingEnabled();
376
377 } // namespace JS
378
379 /**
380 * Set the size of the native stack that should not be exceed. To disable
381 * stack size checking pass 0.
382 *
383 * SpiderMonkey allows for a distinction between system code (such as GCs, which
384 * may incidentally be triggered by script but are not strictly performed on
385 * behalf of such script), trusted script (as determined by
386 * JS_SetTrustedPrincipals), and untrusted script. Each kind of code may have a
387 * different stack quota, allowing embedders to keep higher-priority machinery
388 * running in the face of scripted stack exhaustion by something else.
389 *
390 * The stack quotas for each kind of code should be monotonically descending,
391 * and may be specified with this function. If 0 is passed for a given kind
392 * of code, it defaults to the value of the next-highest-priority kind.
393 *
394 * This function may only be called immediately after the runtime is initialized
395 * and before any code is executed and/or interrupts requested.
396 */
397 extern JS_PUBLIC_API void JS_SetNativeStackQuota(
398 JSContext* cx, size_t systemCodeStackSize,
399 size_t trustedScriptStackSize = 0, size_t untrustedScriptStackSize = 0);
400
401 /************************************************************************/
402
403 extern JS_PUBLIC_API bool JS_ValueToId(JSContext* cx, JS::HandleValue v,
404 JS::MutableHandleId idp);
405
406 extern JS_PUBLIC_API bool JS_StringToId(JSContext* cx, JS::HandleString s,
407 JS::MutableHandleId idp);
408
409 extern JS_PUBLIC_API bool JS_IdToValue(JSContext* cx, jsid id,
410 JS::MutableHandle<JS::Value> vp);
411
412 namespace JS {
413
414 /**
415 * Convert obj to a primitive value. On success, store the result in vp and
416 * return true.
417 *
418 * The hint argument must be JSTYPE_STRING, JSTYPE_NUMBER, or
419 * JSTYPE_UNDEFINED (no hint).
420 *
421 * Implements: ES6 7.1.1 ToPrimitive(input, [PreferredType]).
422 */
423 extern JS_PUBLIC_API bool ToPrimitive(JSContext* cx, JS::HandleObject obj,
424 JSType hint, JS::MutableHandleValue vp);
425
426 /**
427 * If args.get(0) is one of the strings "string", "number", or "default", set
428 * result to JSTYPE_STRING, JSTYPE_NUMBER, or JSTYPE_UNDEFINED accordingly and
429 * return true. Otherwise, return false with a TypeError pending.
430 *
431 * This can be useful in implementing a @@toPrimitive method.
432 */
433 extern JS_PUBLIC_API bool GetFirstArgumentAsTypeHint(JSContext* cx,
434 CallArgs args,
435 JSType* result);
436
437 } /* namespace JS */
438
439 extern JS_PUBLIC_API JSObject* JS_InitClass(
440 JSContext* cx, JS::HandleObject obj, JS::HandleObject parent_proto,
441 const JSClass* clasp, JSNative constructor, unsigned nargs,
442 const JSPropertySpec* ps, const JSFunctionSpec* fs,
443 const JSPropertySpec* static_ps, const JSFunctionSpec* static_fs);
444
445 /**
446 * Set up ctor.prototype = proto and proto.constructor = ctor with the
447 * right property flags.
448 */
449 extern JS_PUBLIC_API bool JS_LinkConstructorAndPrototype(
450 JSContext* cx, JS::Handle<JSObject*> ctor, JS::Handle<JSObject*> proto);
451
452 extern JS_PUBLIC_API bool JS_InstanceOf(JSContext* cx,
453 JS::Handle<JSObject*> obj,
454 const JSClass* clasp,
455 JS::CallArgs* args);
456
457 extern JS_PUBLIC_API bool JS_HasInstance(JSContext* cx,
458 JS::Handle<JSObject*> obj,
459 JS::Handle<JS::Value> v, bool* bp);
460
461 namespace JS {
462
463 // Implementation of
464 // http://www.ecma-international.org/ecma-262/6.0/#sec-ordinaryhasinstance. If
465 // you're looking for the equivalent of "instanceof", you want JS_HasInstance,
466 // not this function.
467 extern JS_PUBLIC_API bool OrdinaryHasInstance(JSContext* cx,
468 HandleObject objArg,
469 HandleValue v, bool* bp);
470
471 // Implementation of
472 // https://www.ecma-international.org/ecma-262/6.0/#sec-instanceofoperator
473 // This is almost identical to JS_HasInstance, except the latter may call a
474 // custom hasInstance class op instead of InstanceofOperator.
475 extern JS_PUBLIC_API bool InstanceofOperator(JSContext* cx, HandleObject obj,
476 HandleValue v, bool* bp);
477
478 } // namespace JS
479
480 extern JS_PUBLIC_API void JS_InitPrivate(JSObject* obj, void* data,
481 size_t nbytes, JS::MemoryUse use);
482
483 extern JS_PUBLIC_API void* JS_GetInstancePrivate(JSContext* cx,
484 JS::Handle<JSObject*> obj,
485 const JSClass* clasp,
486 JS::CallArgs* args);
487
488 extern JS_PUBLIC_API JSObject* JS_GetConstructor(JSContext* cx,
489 JS::Handle<JSObject*> proto);
490
491 namespace JS {
492
493 /**
494 * During global creation, we fire notifications to callbacks registered
495 * via the Debugger API. These callbacks are arbitrary script, and can touch
496 * the global in arbitrary ways. When that happens, the global should not be
497 * in a half-baked state. But this creates a problem for consumers that need
498 * to set slots on the global to put it in a consistent state.
499 *
500 * This API provides a way for consumers to set slots atomically (immediately
501 * after the global is created), before any debugger hooks are fired. It's
502 * unfortunately on the clunky side, but that's the way the cookie crumbles.
503 *
504 * If callers have no additional state on the global to set up, they may pass
505 * |FireOnNewGlobalHook| to JS_NewGlobalObject, which causes that function to
506 * fire the hook as its final act before returning. Otherwise, callers should
507 * pass |DontFireOnNewGlobalHook|, which means that they are responsible for
508 * invoking JS_FireOnNewGlobalObject upon successfully creating the global. If
509 * an error occurs and the operation aborts, callers should skip firing the
510 * hook. But otherwise, callers must take care to fire the hook exactly once
511 * before compiling any script in the global's scope (we have assertions in
512 * place to enforce this). This lets us be sure that debugger clients never miss
513 * breakpoints.
514 */
515 enum OnNewGlobalHookOption { FireOnNewGlobalHook, DontFireOnNewGlobalHook };
516
517 } /* namespace JS */
518
519 extern JS_PUBLIC_API JSObject* JS_NewGlobalObject(
520 JSContext* cx, const JSClass* clasp, JSPrincipals* principals,
521 JS::OnNewGlobalHookOption hookOption, const JS::RealmOptions& options);
522 /**
523 * Spidermonkey does not have a good way of keeping track of what compartments
524 * should be marked on their own. We can mark the roots unconditionally, but
525 * marking GC things only relevant in live compartments is hard. To mitigate
526 * this, we create a static trace hook, installed on each global object, from
527 * which we can be sure the compartment is relevant, and mark it.
528 *
529 * It is still possible to specify custom trace hooks for global object classes.
530 * They can be provided via the RealmOptions passed to JS_NewGlobalObject.
531 */
532 extern JS_PUBLIC_API void JS_GlobalObjectTraceHook(JSTracer* trc,
533 JSObject* global);
534
535 namespace JS {
536
537 /**
538 * This allows easily constructing a global object without having to deal with
539 * JSClassOps, forgetting to add JS_GlobalObjectTraceHook, or forgetting to call
540 * JS::InitRealmStandardClasses(). Example:
541 *
542 * const JSClass globalClass = { "MyGlobal", JSCLASS_GLOBAL_FLAGS,
543 * &JS::DefaultGlobalClassOps };
544 * JS_NewGlobalObject(cx, &globalClass, ...);
545 */
546 extern JS_PUBLIC_DATA const JSClassOps DefaultGlobalClassOps;
547
548 } // namespace JS
549
550 extern JS_PUBLIC_API void JS_FireOnNewGlobalObject(JSContext* cx,
551 JS::HandleObject global);
552
553 extern JS_PUBLIC_API JSObject* JS_NewObject(JSContext* cx,
554 const JSClass* clasp);
555
556 extern JS_PUBLIC_API bool JS_IsNative(JSObject* obj);
557
558 /**
559 * Unlike JS_NewObject, JS_NewObjectWithGivenProto does not compute a default
560 * proto. If proto is nullptr, the JS object will have `null` as [[Prototype]].
561 */
562 extern JS_PUBLIC_API JSObject* JS_NewObjectWithGivenProto(
563 JSContext* cx, const JSClass* clasp, JS::Handle<JSObject*> proto);
564
565 /**
566 * Creates a new plain object, like `new Object()`, with Object.prototype as
567 * [[Prototype]].
568 */
569 extern JS_PUBLIC_API JSObject* JS_NewPlainObject(JSContext* cx);
570
571 /**
572 * Freeze obj, and all objects it refers to, recursively. This will not recurse
573 * through non-extensible objects, on the assumption that those are already
574 * deep-frozen.
575 */
576 extern JS_PUBLIC_API bool JS_DeepFreezeObject(JSContext* cx,
577 JS::Handle<JSObject*> obj);
578
579 /**
580 * Freezes an object; see ES5's Object.freeze(obj) method.
581 */
582 extern JS_PUBLIC_API bool JS_FreezeObject(JSContext* cx,
583 JS::Handle<JSObject*> obj);
584
585 /*** Standard internal methods **********************************************
586 *
587 * The functions below are the fundamental operations on objects.
588 *
589 * ES6 specifies 14 internal methods that define how objects behave. The
590 * standard is actually quite good on this topic, though you may have to read
591 * it a few times. See ES6 sections 6.1.7.2 and 6.1.7.3.
592 *
593 * When 'obj' is an ordinary object, these functions have boring standard
594 * behavior as specified by ES6 section 9.1; see the section about internal
595 * methods in js/src/vm/NativeObject.h.
596 *
597 * Proxies override the behavior of internal methods. So when 'obj' is a proxy,
598 * any one of the functions below could do just about anything. See
599 * js/public/Proxy.h.
600 */
601
602 /**
603 * Get the prototype of |obj|, storing it in |proto|.
604 *
605 * Implements: ES6 [[GetPrototypeOf]] internal method.
606 */
607 extern JS_PUBLIC_API bool JS_GetPrototype(JSContext* cx, JS::HandleObject obj,
608 JS::MutableHandleObject result);
609
610 /**
611 * If |obj| (underneath any functionally-transparent wrapper proxies) has as
612 * its [[GetPrototypeOf]] trap the ordinary [[GetPrototypeOf]] behavior defined
613 * for ordinary objects, set |*isOrdinary = true| and store |obj|'s prototype
614 * in |result|. Otherwise set |*isOrdinary = false|. In case of error, both
615 * outparams have unspecified value.
616 */
617 extern JS_PUBLIC_API bool JS_GetPrototypeIfOrdinary(
618 JSContext* cx, JS::HandleObject obj, bool* isOrdinary,
619 JS::MutableHandleObject result);
620
621 /**
622 * Change the prototype of obj.
623 *
624 * Implements: ES6 [[SetPrototypeOf]] internal method.
625 *
626 * In cases where ES6 [[SetPrototypeOf]] returns false without an exception,
627 * JS_SetPrototype throws a TypeError and returns false.
628 *
629 * Performance warning: JS_SetPrototype is very bad for performance. It may
630 * cause compiled jit-code to be invalidated. It also causes not only obj but
631 * all other objects in the same "group" as obj to be permanently deoptimized.
632 * It's better to create the object with the right prototype from the start.
633 */
634 extern JS_PUBLIC_API bool JS_SetPrototype(JSContext* cx, JS::HandleObject obj,
635 JS::HandleObject proto);
636
637 /**
638 * Determine whether obj is extensible. Extensible objects can have new
639 * properties defined on them. Inextensible objects can't, and their
640 * [[Prototype]] slot is fixed as well.
641 *
642 * Implements: ES6 [[IsExtensible]] internal method.
643 */
644 extern JS_PUBLIC_API bool JS_IsExtensible(JSContext* cx, JS::HandleObject obj,
645 bool* extensible);
646
647 /**
648 * Attempt to make |obj| non-extensible.
649 *
650 * Not all failures are treated as errors. See the comment on
651 * JS::ObjectOpResult in js/public/Class.h.
652 *
653 * Implements: ES6 [[PreventExtensions]] internal method.
654 */
655 extern JS_PUBLIC_API bool JS_PreventExtensions(JSContext* cx,
656 JS::HandleObject obj,
657 JS::ObjectOpResult& result);
658
659 /**
660 * Attempt to make the [[Prototype]] of |obj| immutable, such that any attempt
661 * to modify it will fail. If an error occurs during the attempt, return false
662 * (with a pending exception set, depending upon the nature of the error). If
663 * no error occurs, return true with |*succeeded| set to indicate whether the
664 * attempt successfully made the [[Prototype]] immutable.
665 *
666 * This is a nonstandard internal method.
667 */
668 extern JS_PUBLIC_API bool JS_SetImmutablePrototype(JSContext* cx,
669 JS::HandleObject obj,
670 bool* succeeded);
671
672 /**
673 * Get a description of one of obj's own properties. If no such property exists
674 * on obj, return true with desc.object() set to null.
675 *
676 * Implements: ES6 [[GetOwnProperty]] internal method.
677 */
678 extern JS_PUBLIC_API bool JS_GetOwnPropertyDescriptorById(
679 JSContext* cx, JS::HandleObject obj, JS::HandleId id,
680 JS::MutableHandle<mozilla::Maybe<JS::PropertyDescriptor>> desc);
681
682 extern JS_PUBLIC_API bool JS_GetOwnPropertyDescriptor(
683 JSContext* cx, JS::HandleObject obj, const char* name,
684 JS::MutableHandle<mozilla::Maybe<JS::PropertyDescriptor>> desc);
685
686 extern JS_PUBLIC_API bool JS_GetOwnUCPropertyDescriptor(
687 JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
688 JS::MutableHandle<mozilla::Maybe<JS::PropertyDescriptor>> desc);
689
690 /**
691 * DEPRECATED
692 *
693 * Like JS_GetOwnPropertyDescriptorById, but also searches the prototype chain
694 * if no own property is found directly on obj. The object on which the
695 * property is found is returned in holder. If the property is not found
696 * on the prototype chain, then desc is Nothing.
697 */
698 extern JS_PUBLIC_API bool JS_GetPropertyDescriptorById(
699 JSContext* cx, JS::HandleObject obj, JS::HandleId id,
700 JS::MutableHandle<mozilla::Maybe<JS::PropertyDescriptor>> desc,
701 JS::MutableHandleObject holder);
702
703 extern JS_PUBLIC_API bool JS_GetPropertyDescriptor(
704 JSContext* cx, JS::HandleObject obj, const char* name,
705 JS::MutableHandle<mozilla::Maybe<JS::PropertyDescriptor>> desc,
706 JS::MutableHandleObject holder);
707
708 extern JS_PUBLIC_API bool JS_GetUCPropertyDescriptor(
709 JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
710 JS::MutableHandle<mozilla::Maybe<JS::PropertyDescriptor>> desc,
711 JS::MutableHandleObject holder);
712
713 /**
714 * Define a property on obj.
715 *
716 * This function uses JS::ObjectOpResult to indicate conditions that ES6
717 * specifies as non-error failures. This is inconvenient at best, so use this
718 * function only if you are implementing a proxy handler's defineProperty()
719 * method. For all other purposes, use one of the many DefineProperty functions
720 * below that throw an exception in all failure cases.
721 *
722 * Implements: ES6 [[DefineOwnProperty]] internal method.
723 */
724 extern JS_PUBLIC_API bool JS_DefinePropertyById(
725 JSContext* cx, JS::HandleObject obj, JS::HandleId id,
726 JS::Handle<JS::PropertyDescriptor> desc, JS::ObjectOpResult& result);
727
728 /**
729 * Define a property on obj, throwing a TypeError if the attempt fails.
730 * This is the C++ equivalent of `Object.defineProperty(obj, id, desc)`.
731 */
732 extern JS_PUBLIC_API bool JS_DefinePropertyById(
733 JSContext* cx, JS::HandleObject obj, JS::HandleId id,
734 JS::Handle<JS::PropertyDescriptor> desc);
735
736 extern JS_PUBLIC_API bool JS_DefinePropertyById(JSContext* cx,
737 JS::HandleObject obj,
738 JS::HandleId id,
739 JS::HandleValue value,
740 unsigned attrs);
741
742 extern JS_PUBLIC_API bool JS_DefinePropertyById(
743 JSContext* cx, JS::HandleObject obj, JS::HandleId id, JSNative getter,
744 JSNative setter, unsigned attrs);
745
746 extern JS_PUBLIC_API bool JS_DefinePropertyById(
747 JSContext* cx, JS::HandleObject obj, JS::HandleId id,
748 JS::HandleObject getter, JS::HandleObject setter, unsigned attrs);
749
750 extern JS_PUBLIC_API bool JS_DefinePropertyById(JSContext* cx,
751 JS::HandleObject obj,
752 JS::HandleId id,
753 JS::HandleObject value,
754 unsigned attrs);
755
756 extern JS_PUBLIC_API bool JS_DefinePropertyById(JSContext* cx,
757 JS::HandleObject obj,
758 JS::HandleId id,
759 JS::HandleString value,
760 unsigned attrs);
761
762 extern JS_PUBLIC_API bool JS_DefinePropertyById(JSContext* cx,
763 JS::HandleObject obj,
764 JS::HandleId id, int32_t value,
765 unsigned attrs);
766
767 extern JS_PUBLIC_API bool JS_DefinePropertyById(JSContext* cx,
768 JS::HandleObject obj,
769 JS::HandleId id, uint32_t value,
770 unsigned attrs);
771
772 extern JS_PUBLIC_API bool JS_DefinePropertyById(JSContext* cx,
773 JS::HandleObject obj,
774 JS::HandleId id, double value,
775 unsigned attrs);
776
777 extern JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx, JS::HandleObject obj,
778 const char* name,
779 JS::HandleValue value,
780 unsigned attrs);
781
782 extern JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx, JS::HandleObject obj,
783 const char* name, JSNative getter,
784 JSNative setter, unsigned attrs);
785
786 extern JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx, JS::HandleObject obj,
787 const char* name,
788 JS::HandleObject getter,
789 JS::HandleObject setter,
790 unsigned attrs);
791
792 extern JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx, JS::HandleObject obj,
793 const char* name,
794 JS::HandleObject value,
795 unsigned attrs);
796
797 extern JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx, JS::HandleObject obj,
798 const char* name,
799 JS::HandleString value,
800 unsigned attrs);
801
802 extern JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx, JS::HandleObject obj,
803 const char* name, int32_t value,
804 unsigned attrs);
805
806 extern JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx, JS::HandleObject obj,
807 const char* name, uint32_t value,
808 unsigned attrs);
809
810 extern JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx, JS::HandleObject obj,
811 const char* name, double value,
812 unsigned attrs);
813
814 extern JS_PUBLIC_API bool JS_DefineUCProperty(
815 JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
816 JS::Handle<JS::PropertyDescriptor> desc, JS::ObjectOpResult& result);
817
818 extern JS_PUBLIC_API bool JS_DefineUCProperty(
819 JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
820 JS::Handle<JS::PropertyDescriptor> desc);
821
822 extern JS_PUBLIC_API bool JS_DefineUCProperty(
823 JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
824 JS::HandleValue value, unsigned attrs);
825
826 extern JS_PUBLIC_API bool JS_DefineUCProperty(
827 JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
828 JS::HandleObject getter, JS::HandleObject setter, unsigned attrs);
829
830 extern JS_PUBLIC_API bool JS_DefineUCProperty(
831 JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
832 JS::HandleObject value, unsigned attrs);
833
834 extern JS_PUBLIC_API bool JS_DefineUCProperty(
835 JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
836 JS::HandleString value, unsigned attrs);
837
838 extern JS_PUBLIC_API bool JS_DefineUCProperty(JSContext* cx,
839 JS::HandleObject obj,
840 const char16_t* name,
841 size_t namelen, int32_t value,
842 unsigned attrs);
843
844 extern JS_PUBLIC_API bool JS_DefineUCProperty(JSContext* cx,
845 JS::HandleObject obj,
846 const char16_t* name,
847 size_t namelen, uint32_t value,
848 unsigned attrs);
849
850 extern JS_PUBLIC_API bool JS_DefineUCProperty(JSContext* cx,
851 JS::HandleObject obj,
852 const char16_t* name,
853 size_t namelen, double value,
854 unsigned attrs);
855
856 extern JS_PUBLIC_API bool JS_DefineElement(JSContext* cx, JS::HandleObject obj,
857 uint32_t index,
858 JS::HandleValue value,
859 unsigned attrs);
860
861 extern JS_PUBLIC_API bool JS_DefineElement(JSContext* cx, JS::HandleObject obj,
862 uint32_t index,
863 JS::HandleObject getter,
864 JS::HandleObject setter,
865 unsigned attrs);
866
867 extern JS_PUBLIC_API bool JS_DefineElement(JSContext* cx, JS::HandleObject obj,
868 uint32_t index,
869 JS::HandleObject value,
870 unsigned attrs);
871
872 extern JS_PUBLIC_API bool JS_DefineElement(JSContext* cx, JS::HandleObject obj,
873 uint32_t index,
874 JS::HandleString value,
875 unsigned attrs);
876
877 extern JS_PUBLIC_API bool JS_DefineElement(JSContext* cx, JS::HandleObject obj,
878 uint32_t index, int32_t value,
879 unsigned attrs);
880
881 extern JS_PUBLIC_API bool JS_DefineElement(JSContext* cx, JS::HandleObject obj,
882 uint32_t index, uint32_t value,
883 unsigned attrs);
884
885 extern JS_PUBLIC_API bool JS_DefineElement(JSContext* cx, JS::HandleObject obj,
886 uint32_t index, double value,
887 unsigned attrs);
888
889 /**
890 * Compute the expression `id in obj`.
891 *
892 * If obj has an own or inherited property obj[id], set *foundp = true and
893 * return true. If not, set *foundp = false and return true. On error, return
894 * false with an exception pending.
895 *
896 * Implements: ES6 [[Has]] internal method.
897 */
898 extern JS_PUBLIC_API bool JS_HasPropertyById(JSContext* cx,
899 JS::HandleObject obj,
900 JS::HandleId id, bool* foundp);
901
902 extern JS_PUBLIC_API bool JS_HasProperty(JSContext* cx, JS::HandleObject obj,
903 const char* name, bool* foundp);
904
905 extern JS_PUBLIC_API bool JS_HasUCProperty(JSContext* cx, JS::HandleObject obj,
906 const char16_t* name, size_t namelen,
907 bool* vp);
908
909 extern JS_PUBLIC_API bool JS_HasElement(JSContext* cx, JS::HandleObject obj,
910 uint32_t index, bool* foundp);
911
912 /**
913 * Determine whether obj has an own property with the key `id`.
914 *
915 * Implements: ES6 7.3.11 HasOwnProperty(O, P).
916 */
917 extern JS_PUBLIC_API bool JS_HasOwnPropertyById(JSContext* cx,
918 JS::HandleObject obj,
919 JS::HandleId id, bool* foundp);
920
921 extern JS_PUBLIC_API bool JS_HasOwnProperty(JSContext* cx, JS::HandleObject obj,
922 const char* name, bool* foundp);
923
924 /**
925 * Get the value of the property `obj[id]`, or undefined if no such property
926 * exists. This is the C++ equivalent of `vp = Reflect.get(obj, id, receiver)`.
927 *
928 * Most callers don't need the `receiver` argument. Consider using
929 * JS_GetProperty instead. (But if you're implementing a proxy handler's set()
930 * method, it's often correct to call this function and pass the receiver
931 * through.)
932 *
933 * Implements: ES6 [[Get]] internal method.
934 */
935 extern JS_PUBLIC_API bool JS_ForwardGetPropertyTo(JSContext* cx,
936 JS::HandleObject obj,
937 JS::HandleId id,
938 JS::HandleValue receiver,
939 JS::MutableHandleValue vp);
940
941 extern JS_PUBLIC_API bool JS_ForwardGetElementTo(JSContext* cx,
942 JS::HandleObject obj,
943 uint32_t index,
944 JS::HandleObject receiver,
945 JS::MutableHandleValue vp);
946
947 /**
948 * Get the value of the property `obj[id]`, or undefined if no such property
949 * exists. The result is stored in vp.
950 *
951 * Implements: ES6 7.3.1 Get(O, P).
952 */
953 extern JS_PUBLIC_API bool JS_GetPropertyById(JSContext* cx,
954 JS::HandleObject obj,
955 JS::HandleId id,
956 JS::MutableHandleValue vp);
957
958 extern JS_PUBLIC_API bool JS_GetProperty(JSContext* cx, JS::HandleObject obj,
959 const char* name,
960 JS::MutableHandleValue vp);
961
962 extern JS_PUBLIC_API bool JS_GetUCProperty(JSContext* cx, JS::HandleObject obj,
963 const char16_t* name, size_t namelen,
964 JS::MutableHandleValue vp);
965
966 extern JS_PUBLIC_API bool JS_GetElement(JSContext* cx, JS::HandleObject obj,
967 uint32_t index,
968 JS::MutableHandleValue vp);
969
970 /**
971 * Perform the same property assignment as `Reflect.set(obj, id, v, receiver)`.
972 *
973 * This function has a `receiver` argument that most callers don't need.
974 * Consider using JS_SetProperty instead.
975 *
976 * Implements: ES6 [[Set]] internal method.
977 */
978 extern JS_PUBLIC_API bool JS_ForwardSetPropertyTo(
979 JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue v,
980 JS::HandleValue receiver, JS::ObjectOpResult& result);
981
982 /**
983 * Perform the assignment `obj[id] = v`.
984 *
985 * This function performs non-strict assignment, so if the property is
986 * read-only, nothing happens and no error is thrown.
987 */
988 extern JS_PUBLIC_API bool JS_SetPropertyById(JSContext* cx,
989 JS::HandleObject obj,
990 JS::HandleId id,
991 JS::HandleValue v);
992
993 extern JS_PUBLIC_API bool JS_SetProperty(JSContext* cx, JS::HandleObject obj,
994 const char* name, JS::HandleValue v);
995
996 extern JS_PUBLIC_API bool JS_SetUCProperty(JSContext* cx, JS::HandleObject obj,
997 const char16_t* name, size_t namelen,
998 JS::HandleValue v);
999
1000 extern JS_PUBLIC_API bool JS_SetElement(JSContext* cx, JS::HandleObject obj,
1001 uint32_t index, JS::HandleValue v);
1002
1003 extern JS_PUBLIC_API bool JS_SetElement(JSContext* cx, JS::HandleObject obj,
1004 uint32_t index, JS::HandleObject v);
1005
1006 extern JS_PUBLIC_API bool JS_SetElement(JSContext* cx, JS::HandleObject obj,
1007 uint32_t index, JS::HandleString v);
1008
1009 extern JS_PUBLIC_API bool JS_SetElement(JSContext* cx, JS::HandleObject obj,
1010 uint32_t index, int32_t v);
1011
1012 extern JS_PUBLIC_API bool JS_SetElement(JSContext* cx, JS::HandleObject obj,
1013 uint32_t index, uint32_t v);
1014
1015 extern JS_PUBLIC_API bool JS_SetElement(JSContext* cx, JS::HandleObject obj,
1016 uint32_t index, double v);
1017
1018 /**
1019 * Delete a property. This is the C++ equivalent of
1020 * `result = Reflect.deleteProperty(obj, id)`.
1021 *
1022 * This function has a `result` out parameter that most callers don't need.
1023 * Unless you can pass through an ObjectOpResult provided by your caller, it's
1024 * probably best to use the JS_DeletePropertyById signature with just 3
1025 * arguments.
1026 *
1027 * Implements: ES6 [[Delete]] internal method.
1028 */
1029 extern JS_PUBLIC_API bool JS_DeletePropertyById(JSContext* cx,
1030 JS::HandleObject obj,
1031 JS::HandleId id,
1032 JS::ObjectOpResult& result);
1033
1034 extern JS_PUBLIC_API bool JS_DeleteProperty(JSContext* cx, JS::HandleObject obj,
1035 const char* name,
1036 JS::ObjectOpResult& result);
1037
1038 extern JS_PUBLIC_API bool JS_DeleteUCProperty(JSContext* cx,
1039 JS::HandleObject obj,
1040 const char16_t* name,
1041 size_t namelen,
1042 JS::ObjectOpResult& result);
1043
1044 extern JS_PUBLIC_API bool JS_DeleteElement(JSContext* cx, JS::HandleObject obj,
1045 uint32_t index,
1046 JS::ObjectOpResult& result);
1047
1048 /**
1049 * Delete a property, ignoring strict failures. This is the C++ equivalent of
1050 * the JS `delete obj[id]` in non-strict mode code.
1051 */
1052 extern JS_PUBLIC_API bool JS_DeletePropertyById(JSContext* cx,
1053 JS::HandleObject obj, jsid id);
1054
1055 extern JS_PUBLIC_API bool JS_DeleteProperty(JSContext* cx, JS::HandleObject obj,
1056 const char* name);
1057
1058 extern JS_PUBLIC_API bool JS_DeleteElement(JSContext* cx, JS::HandleObject obj,
1059 uint32_t index);
1060
1061 /**
1062 * Get an array of the non-symbol enumerable properties of obj.
1063 * This function is roughly equivalent to:
1064 *
1065 * var result = [];
1066 * for (key in obj) {
1067 * result.push(key);
1068 * }
1069 * return result;
1070 *
1071 * This is the closest thing we currently have to the ES6 [[Enumerate]]
1072 * internal method.
1073 *
1074 * The array of ids returned by JS_Enumerate must be rooted to protect its
1075 * contents from garbage collection. Use JS::Rooted<JS::IdVector>.
1076 */
1077 extern JS_PUBLIC_API bool JS_Enumerate(JSContext* cx, JS::HandleObject obj,
1078 JS::MutableHandle<JS::IdVector> props);
1079
1080 /**
1081 * Equivalent to `Object.assign(target, src)`: Copies the properties from the
1082 * `src` object (which must not be null) to `target` (which also must not be
1083 * null).
1084 */
1085 extern JS_PUBLIC_API bool JS_AssignObject(JSContext* cx,
1086 JS::HandleObject target,
1087 JS::HandleObject src);
1088
1089 /*
1090 * API for determining callability and constructability. [[Call]] and
1091 * [[Construct]] are internal methods that aren't present on all objects, so it
1092 * is useful to ask if they are there or not. The standard itself asks these
1093 * questions routinely.
1094 */
1095 namespace JS {
1096
1097 /**
1098 * Return true if the given object is callable. In ES6 terms, an object is
1099 * callable if it has a [[Call]] internal method.
1100 *
1101 * Implements: ES6 7.2.3 IsCallable(argument).
1102 *
1103 * Functions are callable. A scripted proxy or wrapper is callable if its
1104 * target is callable. Most other objects aren't callable.
1105 */
1106 extern JS_PUBLIC_API bool IsCallable(JSObject* obj);
1107
1108 /**
1109 * Return true if the given object is a constructor. In ES6 terms, an object is
1110 * a constructor if it has a [[Construct]] internal method. The expression
1111 * `new obj()` throws a TypeError if obj is not a constructor.
1112 *
1113 * Implements: ES6 7.2.4 IsConstructor(argument).
1114 *
1115 * JS functions and classes are constructors. Arrow functions and most builtin
1116 * functions are not. A scripted proxy or wrapper is a constructor if its
1117 * target is a constructor.
1118 */
1119 extern JS_PUBLIC_API bool IsConstructor(JSObject* obj);
1120
1121 } /* namespace JS */
1122
1123 /**
1124 * Call a function, passing a this-value and arguments. This is the C++
1125 * equivalent of `rval = Reflect.apply(fun, obj, args)`.
1126 *
1127 * Implements: ES6 7.3.12 Call(F, V, [argumentsList]).
1128 * Use this function to invoke the [[Call]] internal method.
1129 */
1130 extern JS_PUBLIC_API bool JS_CallFunctionValue(JSContext* cx,
1131 JS::HandleObject obj,
1132 JS::HandleValue fval,
1133 const JS::HandleValueArray& args,
1134 JS::MutableHandleValue rval);
1135
1136 extern JS_PUBLIC_API bool JS_CallFunction(JSContext* cx, JS::HandleObject obj,
1137 JS::HandleFunction fun,
1138 const JS::HandleValueArray& args,
1139 JS::MutableHandleValue rval);
1140
1141 /**
1142 * Perform the method call `rval = obj[name](args)`.
1143 */
1144 extern JS_PUBLIC_API bool JS_CallFunctionName(JSContext* cx,
1145 JS::HandleObject obj,
1146 const char* name,
1147 const JS::HandleValueArray& args,
1148 JS::MutableHandleValue rval);
1149
1150 namespace JS {
1151
Call(JSContext * cx,JS::HandleObject thisObj,JS::HandleFunction fun,const JS::HandleValueArray & args,MutableHandleValue rval)1152 static inline bool Call(JSContext* cx, JS::HandleObject thisObj,
1153 JS::HandleFunction fun,
1154 const JS::HandleValueArray& args,
1155 MutableHandleValue rval) {
1156 return !!JS_CallFunction(cx, thisObj, fun, args, rval);
1157 }
1158
Call(JSContext * cx,JS::HandleObject thisObj,JS::HandleValue fun,const JS::HandleValueArray & args,MutableHandleValue rval)1159 static inline bool Call(JSContext* cx, JS::HandleObject thisObj,
1160 JS::HandleValue fun, const JS::HandleValueArray& args,
1161 MutableHandleValue rval) {
1162 return !!JS_CallFunctionValue(cx, thisObj, fun, args, rval);
1163 }
1164
Call(JSContext * cx,JS::HandleObject thisObj,const char * name,const JS::HandleValueArray & args,MutableHandleValue rval)1165 static inline bool Call(JSContext* cx, JS::HandleObject thisObj,
1166 const char* name, const JS::HandleValueArray& args,
1167 MutableHandleValue rval) {
1168 return !!JS_CallFunctionName(cx, thisObj, name, args, rval);
1169 }
1170
1171 extern JS_PUBLIC_API bool Call(JSContext* cx, JS::HandleValue thisv,
1172 JS::HandleValue fun,
1173 const JS::HandleValueArray& args,
1174 MutableHandleValue rval);
1175
Call(JSContext * cx,JS::HandleValue thisv,JS::HandleObject funObj,const JS::HandleValueArray & args,MutableHandleValue rval)1176 static inline bool Call(JSContext* cx, JS::HandleValue thisv,
1177 JS::HandleObject funObj,
1178 const JS::HandleValueArray& args,
1179 MutableHandleValue rval) {
1180 MOZ_ASSERT(funObj);
1181 JS::RootedValue fun(cx, JS::ObjectValue(*funObj));
1182 return Call(cx, thisv, fun, args, rval);
1183 }
1184
1185 /**
1186 * Invoke a constructor. This is the C++ equivalent of
1187 * `rval = Reflect.construct(fun, args, newTarget)`.
1188 *
1189 * JS::Construct() takes a `newTarget` argument that most callers don't need.
1190 * Consider using the four-argument Construct signature instead. (But if you're
1191 * implementing a subclass or a proxy handler's construct() method, this is the
1192 * right function to call.)
1193 *
1194 * Implements: ES6 7.3.13 Construct(F, [argumentsList], [newTarget]).
1195 * Use this function to invoke the [[Construct]] internal method.
1196 */
1197 extern JS_PUBLIC_API bool Construct(JSContext* cx, JS::HandleValue fun,
1198 HandleObject newTarget,
1199 const JS::HandleValueArray& args,
1200 MutableHandleObject objp);
1201
1202 /**
1203 * Invoke a constructor. This is the C++ equivalent of
1204 * `rval = new fun(...args)`.
1205 *
1206 * Implements: ES6 7.3.13 Construct(F, [argumentsList], [newTarget]), when
1207 * newTarget is omitted.
1208 */
1209 extern JS_PUBLIC_API bool Construct(JSContext* cx, JS::HandleValue fun,
1210 const JS::HandleValueArray& args,
1211 MutableHandleObject objp);
1212
1213 } /* namespace JS */
1214
1215 /*** Other property-defining functions **************************************/
1216
1217 extern JS_PUBLIC_API JSObject* JS_DefineObject(JSContext* cx,
1218 JS::HandleObject obj,
1219 const char* name,
1220 const JSClass* clasp = nullptr,
1221 unsigned attrs = 0);
1222
1223 extern JS_PUBLIC_API bool JS_DefineProperties(JSContext* cx,
1224 JS::HandleObject obj,
1225 const JSPropertySpec* ps);
1226
1227 /* * */
1228
1229 extern JS_PUBLIC_API bool JS_AlreadyHasOwnPropertyById(JSContext* cx,
1230 JS::HandleObject obj,
1231 JS::HandleId id,
1232 bool* foundp);
1233
1234 extern JS_PUBLIC_API bool JS_AlreadyHasOwnProperty(JSContext* cx,
1235 JS::HandleObject obj,
1236 const char* name,
1237 bool* foundp);
1238
1239 extern JS_PUBLIC_API bool JS_AlreadyHasOwnUCProperty(JSContext* cx,
1240 JS::HandleObject obj,
1241 const char16_t* name,
1242 size_t namelen,
1243 bool* foundp);
1244
1245 extern JS_PUBLIC_API bool JS_AlreadyHasOwnElement(JSContext* cx,
1246 JS::HandleObject obj,
1247 uint32_t index, bool* foundp);
1248
1249 namespace JS {
1250
1251 /**
1252 * On success, returns true, setting |*isMap| to true if |obj| is a Map object
1253 * or a wrapper around one, or to false if not. Returns false on failure.
1254 *
1255 * This method returns true with |*isMap == false| when passed an ES6 proxy
1256 * whose target is a Map, or when passed a revoked proxy.
1257 */
1258 extern JS_PUBLIC_API bool IsMapObject(JSContext* cx, JS::HandleObject obj,
1259 bool* isMap);
1260
1261 /**
1262 * On success, returns true, setting |*isSet| to true if |obj| is a Set object
1263 * or a wrapper around one, or to false if not. Returns false on failure.
1264 *
1265 * This method returns true with |*isSet == false| when passed an ES6 proxy
1266 * whose target is a Set, or when passed a revoked proxy.
1267 */
1268 extern JS_PUBLIC_API bool IsSetObject(JSContext* cx, JS::HandleObject obj,
1269 bool* isSet);
1270
1271 } /* namespace JS */
1272
1273 /**
1274 * Assign 'undefined' to all of the object's non-reserved slots. Note: this is
1275 * done for all slots, regardless of the associated property descriptor.
1276 */
1277 JS_PUBLIC_API void JS_SetAllNonReservedSlotsToUndefined(JS::HandleObject obj);
1278
1279 extern JS_PUBLIC_API void JS_SetReservedSlot(JSObject* obj, uint32_t index,
1280 const JS::Value& v);
1281
1282 extern JS_PUBLIC_API void JS_InitReservedSlot(JSObject* obj, uint32_t index,
1283 void* ptr, size_t nbytes,
1284 JS::MemoryUse use);
1285
1286 template <typename T>
JS_InitReservedSlot(JSObject * obj,uint32_t index,T * ptr,JS::MemoryUse use)1287 void JS_InitReservedSlot(JSObject* obj, uint32_t index, T* ptr,
1288 JS::MemoryUse use) {
1289 JS_InitReservedSlot(obj, index, ptr, sizeof(T), use);
1290 }
1291
1292 extern JS_PUBLIC_API void JS_InitPrivate(JSObject* obj, void* data,
1293 size_t nbytes, JS::MemoryUse use);
1294
1295 /************************************************************************/
1296
1297 /* native that can be called as a ctor */
1298 static constexpr unsigned JSFUN_CONSTRUCTOR = 0x400;
1299
1300 /* | of all the JSFUN_* flags */
1301 static constexpr unsigned JSFUN_FLAGS_MASK = 0x400;
1302
1303 static_assert((JSPROP_FLAGS_MASK & JSFUN_FLAGS_MASK) == 0,
1304 "JSFUN_* flags do not overlap JSPROP_* flags, because bits from "
1305 "the two flag-sets appear in the same flag in some APIs");
1306
1307 /*
1308 * Functions and scripts.
1309 */
1310 extern JS_PUBLIC_API JSFunction* JS_NewFunction(JSContext* cx, JSNative call,
1311 unsigned nargs, unsigned flags,
1312 const char* name);
1313
1314 namespace JS {
1315
1316 extern JS_PUBLIC_API JSFunction* GetSelfHostedFunction(
1317 JSContext* cx, const char* selfHostedName, HandleId id, unsigned nargs);
1318
1319 /**
1320 * Create a new function based on the given JSFunctionSpec, *fs.
1321 * id is the result of a successful call to
1322 * `PropertySpecNameToId(cx, fs->name, &id)` or
1323 `PropertySpecNameToPermanentId(cx, fs->name, &id)`.
1324 *
1325 * Unlike JS_DefineFunctions, this does not treat fs as an array.
1326 * *fs must not be JS_FS_END.
1327 */
1328 extern JS_PUBLIC_API JSFunction* NewFunctionFromSpec(JSContext* cx,
1329 const JSFunctionSpec* fs,
1330 HandleId id);
1331
1332 /**
1333 * Same as above, but without an id arg, for callers who don't have
1334 * the id already.
1335 */
1336 extern JS_PUBLIC_API JSFunction* NewFunctionFromSpec(JSContext* cx,
1337 const JSFunctionSpec* fs);
1338
1339 } /* namespace JS */
1340
1341 extern JS_PUBLIC_API JSObject* JS_GetFunctionObject(JSFunction* fun);
1342
1343 /**
1344 * Return the function's identifier as a JSString, or null if fun is unnamed.
1345 * The returned string lives as long as fun, so you don't need to root a saved
1346 * reference to it if fun is well-connected or rooted, and provided you bound
1347 * the use of the saved reference by fun's lifetime.
1348 */
1349 extern JS_PUBLIC_API JSString* JS_GetFunctionId(JSFunction* fun);
1350
1351 /**
1352 * Return a function's display name. This is the defined name if one was given
1353 * where the function was defined, or it could be an inferred name by the JS
1354 * engine in the case that the function was defined to be anonymous. This can
1355 * still return nullptr if a useful display name could not be inferred. The
1356 * same restrictions on rooting as those in JS_GetFunctionId apply.
1357 */
1358 extern JS_PUBLIC_API JSString* JS_GetFunctionDisplayId(JSFunction* fun);
1359
1360 /*
1361 * Return the arity of fun, which includes default parameters and rest
1362 * parameter. This can be used as `nargs` parameter for other functions.
1363 */
1364 extern JS_PUBLIC_API uint16_t JS_GetFunctionArity(JSFunction* fun);
1365
1366 /*
1367 * Return the length of fun, which is the original value of .length property.
1368 */
1369 JS_PUBLIC_API bool JS_GetFunctionLength(JSContext* cx, JS::HandleFunction fun,
1370 uint16_t* length);
1371
1372 /**
1373 * Infallible predicate to test whether obj is a function object (faster than
1374 * comparing obj's class name to "Function", but equivalent unless someone has
1375 * overwritten the "Function" identifier with a different constructor and then
1376 * created instances using that constructor that might be passed in as obj).
1377 */
1378 extern JS_PUBLIC_API bool JS_ObjectIsFunction(JSObject* obj);
1379
1380 extern JS_PUBLIC_API bool JS_IsNativeFunction(JSObject* funobj, JSNative call);
1381
1382 /** Return whether the given function is a valid constructor. */
1383 extern JS_PUBLIC_API bool JS_IsConstructor(JSFunction* fun);
1384
1385 extern JS_PUBLIC_API bool JS_DefineFunctions(JSContext* cx,
1386 JS::Handle<JSObject*> obj,
1387 const JSFunctionSpec* fs);
1388
1389 extern JS_PUBLIC_API JSFunction* JS_DefineFunction(
1390 JSContext* cx, JS::Handle<JSObject*> obj, const char* name, JSNative call,
1391 unsigned nargs, unsigned attrs);
1392
1393 extern JS_PUBLIC_API JSFunction* JS_DefineUCFunction(
1394 JSContext* cx, JS::Handle<JSObject*> obj, const char16_t* name,
1395 size_t namelen, JSNative call, unsigned nargs, unsigned attrs);
1396
1397 extern JS_PUBLIC_API JSFunction* JS_DefineFunctionById(
1398 JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
1399 JSNative call, unsigned nargs, unsigned attrs);
1400
1401 extern JS_PUBLIC_API bool JS_IsFunctionBound(JSFunction* fun);
1402
1403 extern JS_PUBLIC_API JSObject* JS_GetBoundFunctionTarget(JSFunction* fun);
1404
1405 extern JS_PUBLIC_API JSObject* JS_GetGlobalFromScript(JSScript* script);
1406
1407 extern JS_PUBLIC_API const char* JS_GetScriptFilename(JSScript* script);
1408
1409 extern JS_PUBLIC_API unsigned JS_GetScriptBaseLineNumber(JSContext* cx,
1410 JSScript* script);
1411
1412 extern JS_PUBLIC_API JSScript* JS_GetFunctionScript(JSContext* cx,
1413 JS::HandleFunction fun);
1414
1415 extern JS_PUBLIC_API JSString* JS_DecompileScript(JSContext* cx,
1416 JS::Handle<JSScript*> script);
1417
1418 extern JS_PUBLIC_API JSString* JS_DecompileFunction(
1419 JSContext* cx, JS::Handle<JSFunction*> fun);
1420
1421 namespace JS {
1422
1423 /**
1424 * Set a private value associated with a script. Note that this value is shared
1425 * by all nested scripts compiled from a single source file.
1426 */
1427 extern JS_PUBLIC_API void SetScriptPrivate(JSScript* script,
1428 const JS::Value& value);
1429
1430 /**
1431 * Get the private value associated with a script. Note that this value is
1432 * shared by all nested scripts compiled from a single source file.
1433 */
1434 extern JS_PUBLIC_API JS::Value GetScriptPrivate(JSScript* script);
1435
1436 /*
1437 * Return the private value associated with currently executing script or
1438 * module, or undefined if there is no such script.
1439 */
1440 extern JS_PUBLIC_API JS::Value GetScriptedCallerPrivate(JSContext* cx);
1441
1442 /**
1443 * Hooks called when references to a script private value are created or
1444 * destroyed. This allows use of a reference counted object as the
1445 * script private.
1446 */
1447 using ScriptPrivateReferenceHook = void (*)(const JS::Value&);
1448
1449 /**
1450 * Set the script private finalize hook for the runtime to the given function.
1451 */
1452 extern JS_PUBLIC_API void SetScriptPrivateReferenceHooks(
1453 JSRuntime* rt, ScriptPrivateReferenceHook addRefHook,
1454 ScriptPrivateReferenceHook releaseHook);
1455
1456 } /* namespace JS */
1457
1458 extern JS_PUBLIC_API bool JS_CheckForInterrupt(JSContext* cx);
1459
1460 /*
1461 * These functions allow setting an interrupt callback that will be called
1462 * from the JS thread some time after any thread triggered the callback using
1463 * JS_RequestInterruptCallback(cx).
1464 *
1465 * To schedule the GC and for other activities the engine internally triggers
1466 * interrupt callbacks. The embedding should thus not rely on callbacks being
1467 * triggered through the external API only.
1468 *
1469 * Important note: Additional callbacks can occur inside the callback handler
1470 * if it re-enters the JS engine. The embedding must ensure that the callback
1471 * is disconnected before attempting such re-entry.
1472 */
1473 extern JS_PUBLIC_API bool JS_AddInterruptCallback(JSContext* cx,
1474 JSInterruptCallback callback);
1475
1476 extern JS_PUBLIC_API bool JS_DisableInterruptCallback(JSContext* cx);
1477
1478 extern JS_PUBLIC_API void JS_ResetInterruptCallback(JSContext* cx, bool enable);
1479
1480 extern JS_PUBLIC_API void JS_RequestInterruptCallback(JSContext* cx);
1481
1482 extern JS_PUBLIC_API void JS_RequestInterruptCallbackCanWait(JSContext* cx);
1483
1484 namespace JS {
1485
1486 /**
1487 * The ConsumeStreamCallback is called from an active JSContext, passing a
1488 * StreamConsumer that wishes to consume the given host object as a stream of
1489 * bytes with the given MIME type. On failure, the embedding must report the
1490 * appropriate error on 'cx'. On success, the embedding must call
1491 * consumer->consumeChunk() repeatedly on any thread until exactly one of:
1492 * - consumeChunk() returns false
1493 * - the embedding calls consumer->streamEnd()
1494 * - the embedding calls consumer->streamError()
1495 * before JS_DestroyContext(cx) or JS::ShutdownAsyncTasks(cx) is called.
1496 *
1497 * Note: consumeChunk(), streamEnd() and streamError() may be called
1498 * synchronously by ConsumeStreamCallback.
1499 *
1500 * When streamEnd() is called, the embedding may optionally pass an
1501 * OptimizedEncodingListener*, indicating that there is a cache entry associated
1502 * with this stream that can store an optimized encoding of the bytes that were
1503 * just streamed at some point in the future by having SpiderMonkey call
1504 * storeOptimizedEncoding(). Until the optimized encoding is ready, SpiderMonkey
1505 * will hold an outstanding refcount to keep the listener alive.
1506 *
1507 * After storeOptimizedEncoding() is called, on cache hit, the embedding
1508 * may call consumeOptimizedEncoding() instead of consumeChunk()/streamEnd().
1509 * The embedding must ensure that the GetOptimizedEncodingBuildId() (see
1510 * js/BuildId.h) at the time when an optimized encoding is created is the same
1511 * as when it is later consumed.
1512 */
1513
1514 using OptimizedEncodingBytes = js::Vector<uint8_t, 0, js::SystemAllocPolicy>;
1515 using UniqueOptimizedEncodingBytes = js::UniquePtr<OptimizedEncodingBytes>;
1516
1517 class OptimizedEncodingListener {
1518 protected:
1519 virtual ~OptimizedEncodingListener() = default;
1520
1521 public:
1522 // SpiderMonkey will hold an outstanding reference count as long as it holds
1523 // a pointer to OptimizedEncodingListener.
1524 virtual MozExternalRefCountType MOZ_XPCOM_ABI AddRef() = 0;
1525 virtual MozExternalRefCountType MOZ_XPCOM_ABI Release() = 0;
1526
1527 // SpiderMonkey may optionally call storeOptimizedEncoding() after it has
1528 // finished processing a streamed resource.
1529 virtual void storeOptimizedEncoding(UniqueOptimizedEncodingBytes bytes) = 0;
1530 };
1531
1532 class JS_PUBLIC_API StreamConsumer {
1533 protected:
1534 // AsyncStreamConsumers are created and destroyed by SpiderMonkey.
1535 StreamConsumer() = default;
1536 virtual ~StreamConsumer() = default;
1537
1538 public:
1539 // Called by the embedding as each chunk of bytes becomes available.
1540 // If this function returns 'false', the stream must drop all pointers to
1541 // this StreamConsumer.
1542 virtual bool consumeChunk(const uint8_t* begin, size_t length) = 0;
1543
1544 // Called by the embedding when the stream reaches end-of-file, passing the
1545 // listener described above.
1546 virtual void streamEnd(OptimizedEncodingListener* listener = nullptr) = 0;
1547
1548 // Called by the embedding when there is an error during streaming. The
1549 // given error code should be passed to the ReportStreamErrorCallback on the
1550 // main thread to produce the semantically-correct rejection value.
1551 virtual void streamError(size_t errorCode) = 0;
1552
1553 // Called by the embedding *instead of* consumeChunk()/streamEnd() if an
1554 // optimized encoding is available from a previous streaming of the same
1555 // contents with the same optimized build id.
1556 virtual void consumeOptimizedEncoding(const uint8_t* begin,
1557 size_t length) = 0;
1558
1559 // Provides optional stream attributes such as base or source mapping URLs.
1560 // Necessarily called before consumeChunk(), streamEnd(), streamError() or
1561 // consumeOptimizedEncoding(). The caller retains ownership of the strings.
1562 virtual void noteResponseURLs(const char* maybeUrl,
1563 const char* maybeSourceMapUrl) = 0;
1564 };
1565
1566 enum class MimeType { Wasm };
1567
1568 using ConsumeStreamCallback = bool (*)(JSContext*, JS::HandleObject, MimeType,
1569 StreamConsumer*);
1570
1571 using ReportStreamErrorCallback = void (*)(JSContext*, size_t);
1572
1573 extern JS_PUBLIC_API void InitConsumeStreamCallback(
1574 JSContext* cx, ConsumeStreamCallback consume,
1575 ReportStreamErrorCallback report);
1576
1577 /**
1578 * Supply an alternative stack to incorporate into captured SavedFrame
1579 * backtraces as the imputed caller of asynchronous JavaScript calls, like async
1580 * function resumptions and DOM callbacks.
1581 *
1582 * When one async function awaits the result of another, it's natural to think
1583 * of that as a sort of function call: just as execution resumes from an
1584 * ordinary call expression when the callee returns, with the return value
1585 * providing the value of the call expression, execution resumes from an 'await'
1586 * expression after the awaited asynchronous function call returns, passing the
1587 * return value along.
1588 *
1589 * Call the two async functions in such a situation the 'awaiter' and the
1590 * 'awaitee'.
1591 *
1592 * As an async function, the awaitee contains 'await' expressions of its own.
1593 * Whenever it executes after its first 'await', there are never any actual
1594 * frames on the JavaScript stack under it; its awaiter is certainly not there.
1595 * An await expression's continuation is invoked as a promise callback, and
1596 * those are always called directly from the event loop in their own microtick.
1597 * (Ignore unusual cases like nested event loops.)
1598 *
1599 * But because await expressions bear such a strong resemblance to calls (and
1600 * deliberately so!), it would be unhelpful for stacks captured within the
1601 * awaitee to be empty; instead, they should present the awaiter as the caller.
1602 *
1603 * The AutoSetAsyncStackForNewCalls RAII class supplies a SavedFrame stack to
1604 * treat as the caller of any JavaScript invocations that occur within its
1605 * lifetime. Any SavedFrame stack captured during such an invocation uses the
1606 * SavedFrame passed to the constructor's 'stack' parameter as the 'asyncParent'
1607 * property of the SavedFrame for the invocation's oldest frame. Its 'parent'
1608 * property will be null, so stack-walking code can distinguish this
1609 * awaiter/awaitee transition from an ordinary caller/callee transition.
1610 *
1611 * The constructor's 'asyncCause' parameter supplies a string explaining what
1612 * sort of asynchronous call caused 'stack' to be spliced into the backtrace;
1613 * for example, async function resumptions use the string "async". This appears
1614 * as the 'asyncCause' property of the 'asyncParent' SavedFrame.
1615 *
1616 * Async callers are distinguished in the string form of a SavedFrame chain by
1617 * including the 'asyncCause' string in the frame. It appears before the
1618 * function name, with the two separated by a '*'.
1619 *
1620 * Note that, as each compartment has its own set of SavedFrames, the
1621 * 'asyncParent' may actually point to a copy of 'stack', rather than the exact
1622 * SavedFrame object passed.
1623 *
1624 * The youngest frame of 'stack' is not mutated to take the asyncCause string as
1625 * its 'asyncCause' property; SavedFrame objects are immutable. Rather, a fresh
1626 * clone of the frame is created with the needed 'asyncCause' property.
1627 *
1628 * The 'kind' argument specifies how aggressively 'stack' supplants any
1629 * JavaScript frames older than this AutoSetAsyncStackForNewCalls object. If
1630 * 'kind' is 'EXPLICIT', then all captured SavedFrame chains take on 'stack' as
1631 * their 'asyncParent' where the chain crosses this object's scope. If 'kind' is
1632 * 'IMPLICIT', then 'stack' is only included in captured chains if there are no
1633 * other JavaScript frames on the stack --- that is, only if the stack would
1634 * otherwise end at that point.
1635 *
1636 * AutoSetAsyncStackForNewCalls affects only SavedFrame chains; it does not
1637 * affect Debugger.Frame or js::FrameIter. SavedFrame chains are used for
1638 * Error.stack, allocation profiling, Promise debugging, and so on.
1639 *
1640 * See also `js/src/doc/SavedFrame/SavedFrame.md` for documentation on async
1641 * stack frames.
1642 */
1643 class MOZ_STACK_CLASS JS_PUBLIC_API AutoSetAsyncStackForNewCalls {
1644 JSContext* cx;
1645 RootedObject oldAsyncStack;
1646 const char* oldAsyncCause;
1647 bool oldAsyncCallIsExplicit;
1648
1649 public:
1650 enum class AsyncCallKind {
1651 // The ordinary kind of call, where we may apply an async
1652 // parent if there is no ordinary parent.
1653 IMPLICIT,
1654 // An explicit async parent, e.g., callFunctionWithAsyncStack,
1655 // where we always want to override any ordinary parent.
1656 EXPLICIT
1657 };
1658
1659 // The stack parameter cannot be null by design, because it would be
1660 // ambiguous whether that would clear any scheduled async stack and make the
1661 // normal stack reappear in the new call, or just keep the async stack
1662 // already scheduled for the new call, if any.
1663 //
1664 // asyncCause is owned by the caller and its lifetime must outlive the
1665 // lifetime of the AutoSetAsyncStackForNewCalls object. It is strongly
1666 // encouraged that asyncCause be a string constant or similar statically
1667 // allocated string.
1668 AutoSetAsyncStackForNewCalls(JSContext* cx, HandleObject stack,
1669 const char* asyncCause,
1670 AsyncCallKind kind = AsyncCallKind::IMPLICIT);
1671 ~AutoSetAsyncStackForNewCalls();
1672 };
1673
1674 } // namespace JS
1675
1676 /************************************************************************/
1677
1678 namespace JS {
1679
1680 JS_PUBLIC_API bool PropertySpecNameEqualsId(JSPropertySpec::Name name,
1681 HandleId id);
1682
1683 /**
1684 * Create a jsid that does not need to be marked for GC.
1685 *
1686 * 'name' is a JSPropertySpec::name or JSFunctionSpec::name value. The
1687 * resulting jsid, on success, is either an interned string or a well-known
1688 * symbol; either way it is immune to GC so there is no need to visit *idp
1689 * during GC marking.
1690 */
1691 JS_PUBLIC_API bool PropertySpecNameToPermanentId(JSContext* cx,
1692 JSPropertySpec::Name name,
1693 jsid* idp);
1694
1695 } /* namespace JS */
1696
1697 /************************************************************************/
1698
1699 /**
1700 * A JS context always has an "owner thread". The owner thread is set when the
1701 * context is created (to the current thread) and practically all entry points
1702 * into the JS engine check that a context (or anything contained in the
1703 * context: runtime, compartment, object, etc) is only touched by its owner
1704 * thread. Embeddings may check this invariant outside the JS engine by calling
1705 * JS_AbortIfWrongThread (which will abort if not on the owner thread, even for
1706 * non-debug builds).
1707 */
1708
1709 extern JS_PUBLIC_API void JS_AbortIfWrongThread(JSContext* cx);
1710
1711 /************************************************************************/
1712
1713 /**
1714 * A constructor can request that the JS engine create a default new 'this'
1715 * object of the given class, using the callee to determine parentage and
1716 * [[Prototype]].
1717 */
1718 extern JS_PUBLIC_API JSObject* JS_NewObjectForConstructor(
1719 JSContext* cx, const JSClass* clasp, const JS::CallArgs& args);
1720
1721 /************************************************************************/
1722
1723 extern JS_PUBLIC_API void JS_SetParallelParsingEnabled(JSContext* cx,
1724 bool enabled);
1725
1726 extern JS_PUBLIC_API void JS_SetOffthreadIonCompilationEnabled(JSContext* cx,
1727 bool enabled);
1728
1729 // clang-format off
1730 #define JIT_COMPILER_OPTIONS(Register) \
1731 Register(BASELINE_INTERPRETER_WARMUP_TRIGGER, "blinterp.warmup.trigger") \
1732 Register(BASELINE_WARMUP_TRIGGER, "baseline.warmup.trigger") \
1733 Register(IC_FORCE_MEGAMORPHIC, "ic.force-megamorphic") \
1734 Register(ION_NORMAL_WARMUP_TRIGGER, "ion.warmup.trigger") \
1735 Register(ION_GVN_ENABLE, "ion.gvn.enable") \
1736 Register(ION_FORCE_IC, "ion.forceinlineCaches") \
1737 Register(ION_ENABLE, "ion.enable") \
1738 Register(JIT_TRUSTEDPRINCIPALS_ENABLE, "jit_trustedprincipals.enable") \
1739 Register(ION_CHECK_RANGE_ANALYSIS, "ion.check-range-analysis") \
1740 Register(ION_FREQUENT_BAILOUT_THRESHOLD, "ion.frequent-bailout-threshold") \
1741 Register(INLINING_BYTECODE_MAX_LENGTH, "inlining.bytecode-max-length") \
1742 Register(BASELINE_INTERPRETER_ENABLE, "blinterp.enable") \
1743 Register(BASELINE_ENABLE, "baseline.enable") \
1744 Register(OFFTHREAD_COMPILATION_ENABLE, "offthread-compilation.enable") \
1745 Register(FULL_DEBUG_CHECKS, "jit.full-debug-checks") \
1746 Register(JUMP_THRESHOLD, "jump-threshold") \
1747 Register(NATIVE_REGEXP_ENABLE, "native_regexp.enable") \
1748 Register(SIMULATOR_ALWAYS_INTERRUPT, "simulator.always-interrupt") \
1749 Register(SPECTRE_INDEX_MASKING, "spectre.index-masking") \
1750 Register(SPECTRE_OBJECT_MITIGATIONS, "spectre.object-mitigations") \
1751 Register(SPECTRE_STRING_MITIGATIONS, "spectre.string-mitigations") \
1752 Register(SPECTRE_VALUE_MASKING, "spectre.value-masking") \
1753 Register(SPECTRE_JIT_TO_CXX_CALLS, "spectre.jit-to-cxx-calls") \
1754 Register(WASM_FOLD_OFFSETS, "wasm.fold-offsets") \
1755 Register(WASM_DELAY_TIER2, "wasm.delay-tier2") \
1756 Register(WASM_JIT_BASELINE, "wasm.baseline") \
1757 Register(WASM_JIT_OPTIMIZING, "wasm.optimizing") \
1758 // clang-format on
1759
1760 typedef enum JSJitCompilerOption {
1761 #define JIT_COMPILER_DECLARE(key, str) JSJITCOMPILER_##key,
1762
1763 JIT_COMPILER_OPTIONS(JIT_COMPILER_DECLARE)
1764 #undef JIT_COMPILER_DECLARE
1765
1766 JSJITCOMPILER_NOT_AN_OPTION
1767 } JSJitCompilerOption;
1768
1769 extern JS_PUBLIC_API void JS_SetGlobalJitCompilerOption(JSContext* cx,
1770 JSJitCompilerOption opt,
1771 uint32_t value);
1772 extern JS_PUBLIC_API bool JS_GetGlobalJitCompilerOption(JSContext* cx,
1773 JSJitCompilerOption opt,
1774 uint32_t* valueOut);
1775
1776 /**
1777 * Convert a uint32_t index into a jsid.
1778 */
1779 extern JS_PUBLIC_API bool JS_IndexToId(JSContext* cx, uint32_t index,
1780 JS::MutableHandleId);
1781
1782 /**
1783 * Convert chars into a jsid.
1784 *
1785 * |chars| may not be an index.
1786 */
1787 extern JS_PUBLIC_API bool JS_CharsToId(JSContext* cx, JS::TwoByteChars chars,
1788 JS::MutableHandleId);
1789
1790 /**
1791 * Test if the given string is a valid ECMAScript identifier
1792 */
1793 extern JS_PUBLIC_API bool JS_IsIdentifier(JSContext* cx, JS::HandleString str,
1794 bool* isIdentifier);
1795
1796 /**
1797 * Test whether the given chars + length are a valid ECMAScript identifier.
1798 * This version is infallible, so just returns whether the chars are an
1799 * identifier.
1800 */
1801 extern JS_PUBLIC_API bool JS_IsIdentifier(const char16_t* chars, size_t length);
1802
1803 namespace js {
1804 class ScriptSource;
1805 } // namespace js
1806
1807 namespace JS {
1808
1809 class MOZ_RAII JS_PUBLIC_API AutoFilename {
1810 private:
1811 js::ScriptSource* ss_;
1812 mozilla::Variant<const char*, UniqueChars> filename_;
1813
1814 AutoFilename(const AutoFilename&) = delete;
1815 AutoFilename& operator=(const AutoFilename&) = delete;
1816
1817 public:
AutoFilename()1818 AutoFilename()
1819 : ss_(nullptr), filename_(mozilla::AsVariant<const char*>(nullptr)) {}
1820
~AutoFilename()1821 ~AutoFilename() { reset(); }
1822
1823 void reset();
1824
1825 void setOwned(UniqueChars&& filename);
1826 void setUnowned(const char* filename);
1827 void setScriptSource(js::ScriptSource* ss);
1828
1829 const char* get() const;
1830 };
1831
1832 /**
1833 * Return the current filename, line number and column number of the most
1834 * currently running frame. Returns true if a scripted frame was found, false
1835 * otherwise.
1836 *
1837 * If a the embedding has hidden the scripted caller for the topmost activation
1838 * record, this will also return false.
1839 */
1840 extern JS_PUBLIC_API bool DescribeScriptedCaller(
1841 JSContext* cx, AutoFilename* filename = nullptr, unsigned* lineno = nullptr,
1842 unsigned* column = nullptr);
1843
1844 extern JS_PUBLIC_API JSObject* GetScriptedCallerGlobal(JSContext* cx);
1845
1846 /**
1847 * Informs the JS engine that the scripted caller should be hidden. This can be
1848 * used by the embedding to maintain an override of the scripted caller in its
1849 * calculations, by hiding the scripted caller in the JS engine and pushing data
1850 * onto a separate stack, which it inspects when DescribeScriptedCaller returns
1851 * null.
1852 *
1853 * We maintain a counter on each activation record. Add() increments the counter
1854 * of the topmost activation, and Remove() decrements it. The count may never
1855 * drop below zero, and must always be exactly zero when the activation is
1856 * popped from the stack.
1857 */
1858 extern JS_PUBLIC_API void HideScriptedCaller(JSContext* cx);
1859
1860 extern JS_PUBLIC_API void UnhideScriptedCaller(JSContext* cx);
1861
1862 class MOZ_RAII AutoHideScriptedCaller {
1863 public:
AutoHideScriptedCaller(JSContext * cx)1864 explicit AutoHideScriptedCaller(JSContext* cx) : mContext(cx) {
1865 HideScriptedCaller(mContext);
1866 }
~AutoHideScriptedCaller()1867 ~AutoHideScriptedCaller() { UnhideScriptedCaller(mContext); }
1868
1869 protected:
1870 JSContext* mContext;
1871 };
1872
1873 } /* namespace JS */
1874
1875 namespace js {
1876
1877 enum class StackFormat { SpiderMonkey, V8, Default };
1878
1879 /*
1880 * Sets the format used for stringifying Error stacks.
1881 *
1882 * The default format is StackFormat::SpiderMonkey. Use StackFormat::V8
1883 * in order to emulate V8's stack formatting. StackFormat::Default can't be
1884 * used here.
1885 */
1886 extern JS_PUBLIC_API void SetStackFormat(JSContext* cx, StackFormat format);
1887
1888 extern JS_PUBLIC_API StackFormat GetStackFormat(JSContext* cx);
1889
1890 } // namespace js
1891
1892 namespace JS {
1893
1894 /**
1895 * Attempt to disable Wasm's usage of reserving a large virtual memory
1896 * allocation to avoid bounds checking overhead. This must be called before any
1897 * Wasm module or memory is created in this process, or else this function will
1898 * fail.
1899 */
1900 [[nodiscard]] extern JS_PUBLIC_API bool DisableWasmHugeMemory();
1901
1902 /**
1903 * If a large allocation fails when calling pod_{calloc,realloc}CanGC, the JS
1904 * engine may call the large-allocation-failure callback, if set, to allow the
1905 * embedding to flush caches, possibly perform shrinking GCs, etc. to make some
1906 * room. The allocation will then be retried (and may still fail.) This callback
1907 * can be called on any thread and must be set at most once in a process.
1908 */
1909
1910 using LargeAllocationFailureCallback = void (*)();
1911
1912 extern JS_PUBLIC_API void SetProcessLargeAllocationFailureCallback(
1913 LargeAllocationFailureCallback afc);
1914
1915 /**
1916 * Unlike the error reporter, which is only called if the exception for an OOM
1917 * bubbles up and is not caught, the OutOfMemoryCallback is called immediately
1918 * at the OOM site to allow the embedding to capture the current state of heap
1919 * allocation before anything is freed. If the large-allocation-failure callback
1920 * is called at all (not all allocation sites call the large-allocation-failure
1921 * callback on failure), it is called before the out-of-memory callback; the
1922 * out-of-memory callback is only called if the allocation still fails after the
1923 * large-allocation-failure callback has returned.
1924 */
1925
1926 using OutOfMemoryCallback = void (*)(JSContext*, void*);
1927
1928 extern JS_PUBLIC_API void SetOutOfMemoryCallback(JSContext* cx,
1929 OutOfMemoryCallback cb,
1930 void* data);
1931
1932 /**
1933 * When the JSRuntime is about to block in an Atomics.wait() JS call or in a
1934 * `wait` instruction in WebAssembly, it can notify the host by means of a call
1935 * to BeforeWaitCallback. After the wait, it can notify the host by means of a
1936 * call to AfterWaitCallback. Both callbacks must be null, or neither.
1937 *
1938 * (If you change the callbacks from null to not-null or vice versa while some
1939 * thread on the runtime is in a wait, you will be sorry.)
1940 *
1941 * The argument to the BeforeWaitCallback is a pointer to uninitialized
1942 * stack-allocated working memory of size WAIT_CALLBACK_CLIENT_MAXMEM bytes.
1943 * The caller of SetWaitCallback() must pass the amount of memory it will need,
1944 * and this amount will be checked against that limit and the process will crash
1945 * reliably if the check fails.
1946 *
1947 * The value returned by the BeforeWaitCallback will be passed to the
1948 * AfterWaitCallback.
1949 *
1950 * The AfterWaitCallback will be called even if the wakeup is spurious and the
1951 * thread goes right back to waiting again. Of course the thread will call the
1952 * BeforeWaitCallback once more before it goes to sleep in this situation.
1953 */
1954
1955 static constexpr size_t WAIT_CALLBACK_CLIENT_MAXMEM = 32;
1956
1957 using BeforeWaitCallback = void* (*)(uint8_t* memory);
1958 using AfterWaitCallback = void (*)(void* cookie);
1959
1960 extern JS_PUBLIC_API void SetWaitCallback(JSRuntime* rt,
1961 BeforeWaitCallback beforeWait,
1962 AfterWaitCallback afterWait,
1963 size_t requiredMemory);
1964
1965 /**
1966 * Capture all frames.
1967 */
1968 struct AllFrames {};
1969
1970 /**
1971 * Capture at most this many frames.
1972 */
1973 struct MaxFrames {
1974 uint32_t maxFrames;
1975
MaxFramesMaxFrames1976 explicit MaxFrames(uint32_t max) : maxFrames(max) { MOZ_ASSERT(max > 0); }
1977 };
1978
1979 /**
1980 * Capture the first frame with the given principals. By default, do not
1981 * consider self-hosted frames with the given principals as satisfying the stack
1982 * capture.
1983 */
1984 struct JS_PUBLIC_API FirstSubsumedFrame {
1985 JSContext* cx;
1986 JSPrincipals* principals;
1987 bool ignoreSelfHosted;
1988
1989 /**
1990 * Use the cx's current compartment's principals.
1991 */
1992 explicit FirstSubsumedFrame(JSContext* cx,
1993 bool ignoreSelfHostedFrames = true);
1994
1995 explicit FirstSubsumedFrame(JSContext* ctx, JSPrincipals* p,
1996 bool ignoreSelfHostedFrames = true)
cxFirstSubsumedFrame1997 : cx(ctx), principals(p), ignoreSelfHosted(ignoreSelfHostedFrames) {
1998 if (principals) {
1999 JS_HoldPrincipals(principals);
2000 }
2001 }
2002
2003 // No copying because we want to avoid holding and dropping principals
2004 // unnecessarily.
2005 FirstSubsumedFrame(const FirstSubsumedFrame&) = delete;
2006 FirstSubsumedFrame& operator=(const FirstSubsumedFrame&) = delete;
2007
FirstSubsumedFrameFirstSubsumedFrame2008 FirstSubsumedFrame(FirstSubsumedFrame&& rhs)
2009 : principals(rhs.principals), ignoreSelfHosted(rhs.ignoreSelfHosted) {
2010 MOZ_ASSERT(this != &rhs, "self move disallowed");
2011 rhs.principals = nullptr;
2012 }
2013
2014 FirstSubsumedFrame& operator=(FirstSubsumedFrame&& rhs) {
2015 new (this) FirstSubsumedFrame(std::move(rhs));
2016 return *this;
2017 }
2018
~FirstSubsumedFrameFirstSubsumedFrame2019 ~FirstSubsumedFrame() {
2020 if (principals) {
2021 JS_DropPrincipals(cx, principals);
2022 }
2023 }
2024 };
2025
2026 using StackCapture = mozilla::Variant<AllFrames, MaxFrames, FirstSubsumedFrame>;
2027
2028 /**
2029 * Capture the current call stack as a chain of SavedFrame JSObjects, and set
2030 * |stackp| to the SavedFrame for the youngest stack frame, or nullptr if there
2031 * are no JS frames on the stack.
2032 *
2033 * The |capture| parameter describes the portion of the JS stack to capture:
2034 *
2035 * * |JS::AllFrames|: Capture all frames on the stack.
2036 *
2037 * * |JS::MaxFrames|: Capture no more than |JS::MaxFrames::maxFrames| from the
2038 * stack.
2039 *
2040 * * |JS::FirstSubsumedFrame|: Capture the first frame whose principals are
2041 * subsumed by |JS::FirstSubsumedFrame::principals|. By default, do not
2042 * consider self-hosted frames; this can be controlled via the
2043 * |JS::FirstSubsumedFrame::ignoreSelfHosted| flag. Do not capture any async
2044 * stack.
2045 */
2046 extern JS_PUBLIC_API bool CaptureCurrentStack(
2047 JSContext* cx, MutableHandleObject stackp,
2048 StackCapture&& capture = StackCapture(AllFrames()));
2049
2050 /**
2051 * Returns true if capturing stack trace data to associate with an asynchronous
2052 * operation is currently enabled for the current context realm.
2053 *
2054 * Users should check this state before capturing a stack that will be passed
2055 * back to AutoSetAsyncStackForNewCalls later, in order to avoid capturing a
2056 * stack for async use when we don't actually want to capture it.
2057 */
2058 extern JS_PUBLIC_API bool IsAsyncStackCaptureEnabledForRealm(JSContext* cx);
2059
2060 /*
2061 * This is a utility function for preparing an async stack to be used
2062 * by some other object. This may be used when you need to treat a
2063 * given stack trace as an async parent. If you just need to capture
2064 * the current stack, async parents and all, use CaptureCurrentStack
2065 * instead.
2066 *
2067 * Here |asyncStack| is the async stack to prepare. It is copied into
2068 * |cx|'s current compartment, and the newest frame is given
2069 * |asyncCause| as its asynchronous cause. If |maxFrameCount| is
2070 * |Some(n)|, capture at most the youngest |n| frames. The
2071 * new stack object is written to |stackp|. Returns true on success,
2072 * or sets an exception and returns |false| on error.
2073 */
2074 extern JS_PUBLIC_API bool CopyAsyncStack(
2075 JSContext* cx, HandleObject asyncStack, HandleString asyncCause,
2076 MutableHandleObject stackp, const mozilla::Maybe<size_t>& maxFrameCount);
2077
2078 /**
2079 * Given a SavedFrame JSObject stack, stringify it in the same format as
2080 * Error.prototype.stack. The stringified stack out parameter is placed in the
2081 * cx's compartment. Defaults to the empty string.
2082 *
2083 * The same notes above about SavedFrame accessors applies here as well: cx
2084 * doesn't need to be in stack's compartment, and stack can be null, a
2085 * SavedFrame object, or a wrapper (CCW or Xray) around a SavedFrame object.
2086 * SavedFrames not subsumed by |principals| are skipped.
2087 *
2088 * Optional indent parameter specifies the number of white spaces to indent
2089 * each line.
2090 */
2091 extern JS_PUBLIC_API bool BuildStackString(
2092 JSContext* cx, JSPrincipals* principals, HandleObject stack,
2093 MutableHandleString stringp, size_t indent = 0,
2094 js::StackFormat stackFormat = js::StackFormat::Default);
2095
2096 /**
2097 * Return true iff the given object is either a SavedFrame object or wrapper
2098 * around a SavedFrame object, and it is not the SavedFrame.prototype object.
2099 */
2100 extern JS_PUBLIC_API bool IsMaybeWrappedSavedFrame(JSObject* obj);
2101
2102 /**
2103 * Return true iff the given object is a SavedFrame object and not the
2104 * SavedFrame.prototype object.
2105 */
2106 extern JS_PUBLIC_API bool IsUnwrappedSavedFrame(JSObject* obj);
2107
2108 } /* namespace JS */
2109
2110 namespace js {
2111
2112 /**
2113 * Hint that we expect a crash. Currently, the only thing that cares is the
2114 * breakpad injector, which (if loaded) will suppress minidump generation.
2115 */
2116 extern JS_PUBLIC_API void NoteIntentionalCrash();
2117
2118 } /* namespace js */
2119
2120 namespace js {
2121
2122 enum class CompletionKind { Normal, Return, Throw };
2123
2124 } /* namespace js */
2125
2126 #ifdef DEBUG
2127 namespace JS {
2128
2129 extern JS_PUBLIC_API void SetSupportDifferentialTesting(bool value);
2130
2131 }
2132 #endif /* DEBUG */
2133
2134 #endif /* jsapi_h */
2135