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