tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

jsapi.h (39792B)


      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/FloatingPoint.h"
     13 #include "mozilla/Maybe.h"
     14 #include "mozilla/TimeStamp.h"
     15 #include "mozilla/Variant.h"
     16 
     17 #include <stddef.h>
     18 #include <stdint.h>
     19 
     20 #include "jspubtd.h"
     21 
     22 #include "js/AllocPolicy.h"
     23 #include "js/CallAndConstruct.h"  // JS::Call, JS_CallFunction, JS_CallFunctionName, JS_CallFunctionValue
     24 #include "js/CallArgs.h"
     25 #include "js/CharacterEncoding.h"
     26 #include "js/Class.h"
     27 #include "js/CompileOptions.h"
     28 #include "js/Context.h"
     29 #include "js/Debug.h"
     30 #include "js/ErrorInterceptor.h"
     31 #include "js/ErrorReport.h"
     32 #include "js/Exception.h"
     33 #include "js/GCAPI.h"
     34 #include "js/GCVector.h"
     35 #include "js/GlobalObject.h"
     36 #include "js/HashTable.h"
     37 #include "js/Id.h"
     38 #include "js/Interrupt.h"
     39 #include "js/MapAndSet.h"
     40 #include "js/MemoryCallbacks.h"
     41 #include "js/MemoryFunctions.h"
     42 #include "js/Principals.h"
     43 #include "js/PropertyAndElement.h"  // JS_Enumerate
     44 #include "js/PropertyDescriptor.h"
     45 #include "js/PropertySpec.h"
     46 #include "js/Realm.h"
     47 #include "js/RealmIterators.h"
     48 #include "js/RealmOptions.h"
     49 #include "js/RefCounted.h"
     50 #include "js/RootingAPI.h"
     51 #include "js/ScriptPrivate.h"
     52 #include "js/Stack.h"
     53 #include "js/StreamConsumer.h"
     54 #include "js/String.h"
     55 #include "js/TelemetryTimers.h"
     56 #include "js/TracingAPI.h"
     57 #include "js/Transcoding.h"
     58 #include "js/UniquePtr.h"
     59 #include "js/Utility.h"
     60 #include "js/Value.h"
     61 #include "js/ValueArray.h"
     62 #include "js/Vector.h"
     63 #include "js/WaitCallbacks.h"
     64 #include "js/WeakMap.h"
     65 #include "js/WrapperCallbacks.h"
     66 #include "js/Zone.h"
     67 
     68 /************************************************************************/
     69 
     70 struct JSFunctionSpec;
     71 struct JSPropertySpec;
     72 
     73 namespace JS {
     74 
     75 template <typename UnitT>
     76 class SourceText;
     77 
     78 class TwoByteChars;
     79 
     80 using ValueVector = JS::GCVector<JS::Value>;
     81 using IdVector = JS::GCVector<jsid>;
     82 using ScriptVector = JS::GCVector<JSScript*>;
     83 using StringVector = JS::GCVector<JSString*>;
     84 
     85 } /* namespace JS */
     86 
     87 /************************************************************************/
     88 
     89 static MOZ_ALWAYS_INLINE JS::Value JS_NumberValue(double d) {
     90  int32_t i;
     91  d = JS::CanonicalizeNaN(d);
     92  if (mozilla::NumberIsInt32(d, &i)) {
     93    return JS::Int32Value(i);
     94  }
     95  return JS::DoubleValue(d);
     96 }
     97 
     98 /************************************************************************/
     99 
    100 JS_PUBLIC_API bool JS_StringHasBeenPinned(JSContext* cx, JSString* str);
    101 
    102 /************************************************************************/
    103 
    104 /** Microseconds since the epoch, midnight, January 1, 1970 UTC. */
    105 extern JS_PUBLIC_API int64_t JS_Now(void);
    106 
    107 extern JS_PUBLIC_API bool JS_ValueToObject(JSContext* cx, JS::HandleValue v,
    108                                           JS::MutableHandleObject objp);
    109 
    110 extern JS_PUBLIC_API JSFunction* JS_ValueToFunction(JSContext* cx,
    111                                                    JS::HandleValue v);
    112 
    113 extern JS_PUBLIC_API JSFunction* JS_ValueToConstructor(JSContext* cx,
    114                                                       JS::HandleValue v);
    115 
    116 extern JS_PUBLIC_API JSString* JS_ValueToSource(JSContext* cx,
    117                                                JS::Handle<JS::Value> v);
    118 
    119 extern JS_PUBLIC_API bool JS_DoubleIsInt32(double d, int32_t* ip);
    120 
    121 extern JS_PUBLIC_API JSType JS_TypeOfValue(JSContext* cx,
    122                                           JS::Handle<JS::Value> v);
    123 
    124 namespace JS {
    125 
    126 extern JS_PUBLIC_API const char* InformalValueTypeName(const JS::Value& v);
    127 
    128 } /* namespace JS */
    129 
    130 /** True iff fun is the global eval function. */
    131 extern JS_PUBLIC_API bool JS_IsBuiltinEvalFunction(JSFunction* fun);
    132 
    133 /** True iff fun is the Function constructor. */
    134 extern JS_PUBLIC_API bool JS_IsBuiltinFunctionConstructor(JSFunction* fun);
    135 
    136 extern JS_PUBLIC_API const char* JS_GetImplementationVersion(void);
    137 
    138 extern JS_PUBLIC_API void JS_SetWrapObjectCallbacks(
    139    JSContext* cx, const JSWrapObjectCallbacks* callbacks);
    140 
    141 // Examine a value to determine if it is one of the built-in Error types.
    142 // If so, return the error type.
    143 extern JS_PUBLIC_API mozilla::Maybe<JSExnType> JS_GetErrorType(
    144    const JS::Value& val);
    145 
    146 extern JS_PUBLIC_API bool JS_WrapObject(JSContext* cx,
    147                                        JS::MutableHandleObject objp);
    148 
    149 extern JS_PUBLIC_API bool JS_WrapValue(JSContext* cx,
    150                                       JS::MutableHandleValue vp);
    151 
    152 extern JS_PUBLIC_API JSObject* JS_TransplantObject(JSContext* cx,
    153                                                   JS::HandleObject origobj,
    154                                                   JS::HandleObject target);
    155 
    156 /**
    157 * Resolve id, which must contain either a string or an int, to a standard
    158 * class name in obj if possible, defining the class's constructor and/or
    159 * prototype and storing true in *resolved.  If id does not name a standard
    160 * class or a top-level property induced by initializing a standard class,
    161 * store false in *resolved and just return true.  Return false on error,
    162 * as usual for bool result-typed API entry points.
    163 *
    164 * This API can be called directly from a global object class's resolve op,
    165 * to define standard classes lazily. The class should either have an enumerate
    166 * hook that calls JS_EnumerateStandardClasses, or a newEnumerate hook that
    167 * calls JS_NewEnumerateStandardClasses. newEnumerate is preferred because it's
    168 * faster (does not define all standard classes).
    169 */
    170 extern JS_PUBLIC_API bool JS_ResolveStandardClass(JSContext* cx,
    171                                                  JS::HandleObject obj,
    172                                                  JS::HandleId id,
    173                                                  bool* resolved);
    174 
    175 extern JS_PUBLIC_API bool JS_MayResolveStandardClass(const JSAtomState& names,
    176                                                     jsid id,
    177                                                     JSObject* maybeObj);
    178 
    179 extern JS_PUBLIC_API bool JS_EnumerateStandardClasses(JSContext* cx,
    180                                                      JS::HandleObject obj);
    181 
    182 /**
    183 * Fill "properties" with a list of standard class names that have not yet been
    184 * resolved on "obj".  This can be used as (part of) a newEnumerate class hook
    185 * on a global.  Already-resolved things are excluded because they might have
    186 * been deleted by script after being resolved and enumeration considers
    187 * already-defined properties anyway.
    188 */
    189 extern JS_PUBLIC_API bool JS_NewEnumerateStandardClasses(
    190    JSContext* cx, JS::HandleObject obj, JS::MutableHandleIdVector properties,
    191    bool enumerableOnly);
    192 
    193 /**
    194 * Fill "properties" with a list of standard class names.  This can be used for
    195 * proxies that want to define behavior that looks like enumerating a global
    196 * without touching the global itself.
    197 */
    198 extern JS_PUBLIC_API bool JS_NewEnumerateStandardClassesIncludingResolved(
    199    JSContext* cx, JS::HandleObject obj, JS::MutableHandleIdVector properties,
    200    bool enumerableOnly);
    201 
    202 extern JS_PUBLIC_API bool JS_GetClassObject(JSContext* cx, JSProtoKey key,
    203                                            JS::MutableHandle<JSObject*> objp);
    204 
    205 extern JS_PUBLIC_API bool JS_GetClassPrototype(
    206    JSContext* cx, JSProtoKey key, JS::MutableHandle<JSObject*> objp);
    207 
    208 namespace JS {
    209 
    210 /*
    211 * Determine if the given object is an instance/prototype/constructor for a
    212 * standard class. If so, return the associated JSProtoKey. If not, return
    213 * JSProto_Null.
    214 */
    215 
    216 extern JS_PUBLIC_API JSProtoKey IdentifyStandardInstance(JSObject* obj);
    217 
    218 extern JS_PUBLIC_API JSProtoKey IdentifyStandardPrototype(JSObject* obj);
    219 
    220 extern JS_PUBLIC_API JSProtoKey
    221 IdentifyStandardInstanceOrPrototype(JSObject* obj);
    222 
    223 extern JS_PUBLIC_API JSProtoKey IdentifyStandardConstructor(JSObject* obj);
    224 
    225 extern JS_PUBLIC_API void ProtoKeyToId(JSContext* cx, JSProtoKey key,
    226                                       JS::MutableHandleId idp);
    227 
    228 } /* namespace JS */
    229 
    230 extern JS_PUBLIC_API JSProtoKey JS_IdToProtoKey(JSContext* cx, JS::HandleId id);
    231 
    232 extern JS_PUBLIC_API JSObject* JS_GlobalLexicalEnvironment(JSObject* obj);
    233 
    234 extern JS_PUBLIC_API bool JS_HasExtensibleLexicalEnvironment(JSObject* obj);
    235 
    236 extern JS_PUBLIC_API JSObject* JS_ExtensibleLexicalEnvironment(JSObject* obj);
    237 
    238 /**
    239 * Add 'Reflect.parse', a SpiderMonkey extension, to the Reflect object on the
    240 * given global.
    241 */
    242 extern JS_PUBLIC_API bool JS_InitReflectParse(JSContext* cx,
    243                                              JS::HandleObject global);
    244 
    245 /**
    246 * Add various profiling-related functions as properties of the given object.
    247 * Defined in builtin/Profilers.cpp.
    248 */
    249 extern JS_PUBLIC_API bool JS_DefineProfilingFunctions(JSContext* cx,
    250                                                      JS::HandleObject obj);
    251 
    252 namespace JS {
    253 
    254 /**
    255 * Tell JS engine whether Profile Timeline Recording is enabled or not.
    256 * If Profile Timeline Recording is enabled, data shown there like stack won't
    257 * be optimized out.
    258 * This is global state and not associated with specific runtime or context.
    259 */
    260 extern JS_PUBLIC_API void SetProfileTimelineRecordingEnabled(bool enabled);
    261 
    262 extern JS_PUBLIC_API bool IsProfileTimelineRecordingEnabled();
    263 
    264 }  // namespace JS
    265 
    266 /************************************************************************/
    267 
    268 extern JS_PUBLIC_API bool JS_ValueToId(JSContext* cx, JS::HandleValue v,
    269                                       JS::MutableHandleId idp);
    270 
    271 extern JS_PUBLIC_API bool JS_StringToId(JSContext* cx, JS::HandleString s,
    272                                        JS::MutableHandleId idp);
    273 
    274 extern JS_PUBLIC_API bool JS_IdToValue(JSContext* cx, jsid id,
    275                                       JS::MutableHandle<JS::Value> vp);
    276 
    277 namespace JS {
    278 
    279 /**
    280 * Convert obj to a primitive value. On success, store the result in vp and
    281 * return true.
    282 *
    283 * The hint argument must be JSTYPE_STRING, JSTYPE_NUMBER, or
    284 * JSTYPE_UNDEFINED (no hint).
    285 *
    286 * Implements: ES6 7.1.1 ToPrimitive(input, [PreferredType]).
    287 */
    288 extern JS_PUBLIC_API bool ToPrimitive(JSContext* cx, JS::HandleObject obj,
    289                                      JSType hint, JS::MutableHandleValue vp);
    290 
    291 /**
    292 * If args.get(0) is one of the strings "string", "number", or "default", set
    293 * result to JSTYPE_STRING, JSTYPE_NUMBER, or JSTYPE_UNDEFINED accordingly and
    294 * return true. Otherwise, return false with a TypeError pending.
    295 *
    296 * This can be useful in implementing a @@toPrimitive method.
    297 */
    298 extern JS_PUBLIC_API bool GetFirstArgumentAsTypeHint(JSContext* cx,
    299                                                     const CallArgs& args,
    300                                                     JSType* result);
    301 
    302 } /* namespace JS */
    303 
    304 /**
    305 * Defines a builtin constructor and prototype. Returns the prototype object.
    306 *
    307 * - Defines a property named `name` on `obj`, with its value set to a
    308 *   newly-created JS function that invokes the `constructor` JSNative. The
    309 *   `length` of the function is `nargs`.
    310 *
    311 * - Creates a prototype object with proto `protoProto` and class `protoClass`.
    312 *   If `protoProto` is `nullptr`, `Object.prototype` will be used instead.
    313 *   If `protoClass` is `nullptr`, the prototype object will be a plain JS
    314 *   object.
    315 *
    316 * - The `ps` and `fs` properties/functions will be defined on the prototype
    317 *   object.
    318 *
    319 * - The `static_ps` and `static_fs` properties/functions will be defined on the
    320 *   constructor.
    321 */
    322 extern JS_PUBLIC_API JSObject* JS_InitClass(
    323    JSContext* cx, JS::HandleObject obj, const JSClass* protoClass,
    324    JS::HandleObject protoProto, const char* name, JSNative constructor,
    325    unsigned nargs, const JSPropertySpec* ps, const JSFunctionSpec* fs,
    326    const JSPropertySpec* static_ps, const JSFunctionSpec* static_fs);
    327 
    328 /**
    329 * Set up ctor.prototype = proto and proto.constructor = ctor with the
    330 * right property flags.
    331 */
    332 extern JS_PUBLIC_API bool JS_LinkConstructorAndPrototype(
    333    JSContext* cx, JS::Handle<JSObject*> ctor, JS::Handle<JSObject*> proto);
    334 
    335 extern JS_PUBLIC_API bool JS_InstanceOf(JSContext* cx,
    336                                        JS::Handle<JSObject*> obj,
    337                                        const JSClass* clasp,
    338                                        JS::CallArgs* args);
    339 
    340 extern JS_PUBLIC_API bool JS_HasInstance(JSContext* cx,
    341                                         JS::Handle<JSObject*> obj,
    342                                         JS::Handle<JS::Value> v, bool* bp);
    343 
    344 namespace JS {
    345 
    346 // Implementation of
    347 // http://www.ecma-international.org/ecma-262/6.0/#sec-ordinaryhasinstance.  If
    348 // you're looking for the equivalent of "instanceof", you want JS_HasInstance,
    349 // not this function.
    350 extern JS_PUBLIC_API bool OrdinaryHasInstance(JSContext* cx,
    351                                              HandleObject objArg,
    352                                              HandleValue v, bool* bp);
    353 
    354 }  // namespace JS
    355 
    356 extern JS_PUBLIC_API JSObject* JS_GetConstructor(JSContext* cx,
    357                                                 JS::Handle<JSObject*> proto);
    358 
    359 extern JS_PUBLIC_API JSObject* JS_NewObject(JSContext* cx,
    360                                            const JSClass* clasp);
    361 
    362 extern JS_PUBLIC_API bool JS_IsNative(JSObject* obj);
    363 
    364 /**
    365 * Unlike JS_NewObject, JS_NewObjectWithGivenProto does not compute a default
    366 * proto. If proto is nullptr, the JS object will have `null` as [[Prototype]].
    367 */
    368 extern JS_PUBLIC_API JSObject* JS_NewObjectWithGivenProto(
    369    JSContext* cx, const JSClass* clasp, JS::Handle<JSObject*> proto);
    370 
    371 /**
    372 * Creates a new plain object, like `new Object()`, with Object.prototype as
    373 * [[Prototype]].
    374 */
    375 extern JS_PUBLIC_API JSObject* JS_NewPlainObject(JSContext* cx);
    376 
    377 /**
    378 * Freeze obj, and all objects it refers to, recursively. This will not recurse
    379 * through non-extensible objects, on the assumption that those are already
    380 * deep-frozen.
    381 */
    382 extern JS_PUBLIC_API bool JS_DeepFreezeObject(JSContext* cx,
    383                                              JS::Handle<JSObject*> obj);
    384 
    385 /**
    386 * Freezes an object; see ES5's Object.freeze(obj) method.
    387 */
    388 extern JS_PUBLIC_API bool JS_FreezeObject(JSContext* cx,
    389                                          JS::Handle<JSObject*> obj);
    390 
    391 /*** Standard internal methods **********************************************
    392 *
    393 * The functions below are the fundamental operations on objects.
    394 *
    395 * ES6 specifies 14 internal methods that define how objects behave.  The
    396 * standard is actually quite good on this topic, though you may have to read
    397 * it a few times. See ES6 sections 6.1.7.2 and 6.1.7.3.
    398 *
    399 * When 'obj' is an ordinary object, these functions have boring standard
    400 * behavior as specified by ES6 section 9.1; see the section about internal
    401 * methods in js/src/vm/NativeObject.h.
    402 *
    403 * Proxies override the behavior of internal methods. So when 'obj' is a proxy,
    404 * any one of the functions below could do just about anything. See
    405 * js/public/Proxy.h.
    406 */
    407 
    408 /**
    409 * Get the prototype of |obj|, storing it in |proto|.
    410 *
    411 * Implements: ES6 [[GetPrototypeOf]] internal method.
    412 */
    413 extern JS_PUBLIC_API bool JS_GetPrototype(JSContext* cx, JS::HandleObject obj,
    414                                          JS::MutableHandleObject result);
    415 
    416 /**
    417 * If |obj| (underneath any functionally-transparent wrapper proxies) has as
    418 * its [[GetPrototypeOf]] trap the ordinary [[GetPrototypeOf]] behavior defined
    419 * for ordinary objects, set |*isOrdinary = true| and store |obj|'s prototype
    420 * in |result|.  Otherwise set |*isOrdinary = false|.  In case of error, both
    421 * outparams have unspecified value.
    422 */
    423 extern JS_PUBLIC_API bool JS_GetPrototypeIfOrdinary(
    424    JSContext* cx, JS::HandleObject obj, bool* isOrdinary,
    425    JS::MutableHandleObject result);
    426 
    427 /**
    428 * Change the prototype of obj.
    429 *
    430 * Implements: ES6 [[SetPrototypeOf]] internal method.
    431 *
    432 * In cases where ES6 [[SetPrototypeOf]] returns false without an exception,
    433 * JS_SetPrototype throws a TypeError and returns false.
    434 *
    435 * Performance warning: JS_SetPrototype is very bad for performance. It may
    436 * cause compiled jit-code to be invalidated. It also causes not only obj but
    437 * all other objects in the same "group" as obj to be permanently deoptimized.
    438 * It's better to create the object with the right prototype from the start.
    439 */
    440 extern JS_PUBLIC_API bool JS_SetPrototype(JSContext* cx, JS::HandleObject obj,
    441                                          JS::HandleObject proto);
    442 
    443 /**
    444 * Determine whether obj is extensible. Extensible objects can have new
    445 * properties defined on them. Inextensible objects can't, and their
    446 * [[Prototype]] slot is fixed as well.
    447 *
    448 * Implements: ES6 [[IsExtensible]] internal method.
    449 */
    450 extern JS_PUBLIC_API bool JS_IsExtensible(JSContext* cx, JS::HandleObject obj,
    451                                          bool* extensible);
    452 
    453 /**
    454 * Attempt to make |obj| non-extensible.
    455 *
    456 * Not all failures are treated as errors. See the comment on
    457 * JS::ObjectOpResult in js/public/Class.h.
    458 *
    459 * Implements: ES6 [[PreventExtensions]] internal method.
    460 */
    461 extern JS_PUBLIC_API bool JS_PreventExtensions(JSContext* cx,
    462                                               JS::HandleObject obj,
    463                                               JS::ObjectOpResult& result);
    464 
    465 /**
    466 * Attempt to make the [[Prototype]] of |obj| immutable, such that any attempt
    467 * to modify it will fail.  If an error occurs during the attempt, return false
    468 * (with a pending exception set, depending upon the nature of the error).  If
    469 * no error occurs, return true with |*succeeded| set to indicate whether the
    470 * attempt successfully made the [[Prototype]] immutable.
    471 *
    472 * This is a nonstandard internal method.
    473 */
    474 extern JS_PUBLIC_API bool JS_SetImmutablePrototype(JSContext* cx,
    475                                                   JS::HandleObject obj,
    476                                                   bool* succeeded);
    477 
    478 /**
    479 * Equivalent to `Object.assign(target, src)`: Copies the properties from the
    480 * `src` object (which must not be null) to `target` (which also must not be
    481 * null).
    482 */
    483 extern JS_PUBLIC_API bool JS_AssignObject(JSContext* cx,
    484                                          JS::HandleObject target,
    485                                          JS::HandleObject src);
    486 
    487 namespace JS {
    488 
    489 /**
    490 * On success, returns true, setting |*isMap| to true if |obj| is a Map object
    491 * or a wrapper around one, or to false if not.  Returns false on failure.
    492 *
    493 * This method returns true with |*isMap == false| when passed an ES6 proxy
    494 * whose target is a Map, or when passed a revoked proxy.
    495 */
    496 extern JS_PUBLIC_API bool IsMapObject(JSContext* cx, JS::HandleObject obj,
    497                                      bool* isMap);
    498 
    499 /**
    500 * On success, returns true, setting |*isSet| to true if |obj| is a Set object
    501 * or a wrapper around one, or to false if not.  Returns false on failure.
    502 *
    503 * This method returns true with |*isSet == false| when passed an ES6 proxy
    504 * whose target is a Set, or when passed a revoked proxy.
    505 */
    506 extern JS_PUBLIC_API bool IsSetObject(JSContext* cx, JS::HandleObject obj,
    507                                      bool* isSet);
    508 
    509 } /* namespace JS */
    510 
    511 /**
    512 * Assign 'undefined' to all of the object's non-reserved slots. Note: this is
    513 * done for all slots, regardless of the associated property descriptor.
    514 */
    515 JS_PUBLIC_API void JS_SetAllNonReservedSlotsToUndefined(JS::HandleObject obj);
    516 
    517 extern JS_PUBLIC_API void JS_SetReservedSlot(JSObject* obj, uint32_t index,
    518                                             const JS::Value& v);
    519 
    520 extern JS_PUBLIC_API void JS_InitReservedSlot(JSObject* obj, uint32_t index,
    521                                              void* ptr, size_t nbytes,
    522                                              JS::MemoryUse use);
    523 
    524 template <typename T>
    525 void JS_InitReservedSlot(JSObject* obj, uint32_t index, T* ptr,
    526                         JS::MemoryUse use) {
    527  JS_InitReservedSlot(obj, index, ptr, sizeof(T), use);
    528 }
    529 
    530 /************************************************************************/
    531 
    532 /* native that can be called as a ctor */
    533 static constexpr unsigned JSFUN_CONSTRUCTOR = 0x400;
    534 
    535 /* | of all the JSFUN_* flags */
    536 static constexpr unsigned JSFUN_FLAGS_MASK = 0x400;
    537 
    538 static_assert((JSPROP_FLAGS_MASK & JSFUN_FLAGS_MASK) == 0,
    539              "JSFUN_* flags do not overlap JSPROP_* flags, because bits from "
    540              "the two flag-sets appear in the same flag in some APIs");
    541 
    542 /*
    543 * Functions and scripts.
    544 */
    545 extern JS_PUBLIC_API JSFunction* JS_NewFunction(JSContext* cx, JSNative call,
    546                                                unsigned nargs, unsigned flags,
    547                                                const char* name);
    548 
    549 namespace JS {
    550 
    551 extern JS_PUBLIC_API JSFunction* GetSelfHostedFunction(
    552    JSContext* cx, const char* selfHostedName, HandleId id, unsigned nargs);
    553 
    554 /**
    555 * Create a new function based on the given JSFunctionSpec, *fs.
    556 * id is the result of a successful call to
    557 * `PropertySpecNameToId(cx, fs->name, &id)` or
    558   `PropertySpecNameToPermanentId(cx, fs->name, &id)`.
    559 *
    560 * Unlike JS_DefineFunctions, this does not treat fs as an array.
    561 * *fs must not be JS_FS_END.
    562 */
    563 extern JS_PUBLIC_API JSFunction* NewFunctionFromSpec(JSContext* cx,
    564                                                     const JSFunctionSpec* fs,
    565                                                     HandleId id);
    566 
    567 /**
    568 * Same as above, but without an id arg, for callers who don't have
    569 * the id already.
    570 */
    571 extern JS_PUBLIC_API JSFunction* NewFunctionFromSpec(JSContext* cx,
    572                                                     const JSFunctionSpec* fs);
    573 
    574 } /* namespace JS */
    575 
    576 extern JS_PUBLIC_API JSObject* JS_GetFunctionObject(JSFunction* fun);
    577 
    578 /**
    579 * Return the function's identifier as a JSString, or null if fun is unnamed.
    580 *
    581 * The returned string lives as long as fun, so you don't need to root a saved
    582 * reference to it if fun is well-connected or rooted, and provided you bound
    583 * the use of the saved reference by fun's lifetime.
    584 *
    585 * This function returns false if any error happens while generating the
    586 * function name string for a function with lazy name.
    587 */
    588 extern JS_PUBLIC_API bool JS_GetFunctionId(JSContext* cx,
    589                                           JS::Handle<JSFunction*> fun,
    590                                           JS::MutableHandle<JSString*> name);
    591 
    592 /**
    593 * Almost same as JS_GetFunctionId.
    594 *
    595 * If the function has lazy name, this returns partial name, such as the
    596 * function name without "get " or "set " prefix.
    597 */
    598 extern JS_PUBLIC_API JSString* JS_GetMaybePartialFunctionId(JSFunction* fun);
    599 
    600 /**
    601 * Return a function's display name as `name` out-parameter.
    602 *
    603 * This is the defined name if one was given where the function was defined, or
    604 * it could be an inferred name by the JS engine in the case that the function
    605 * was defined to be anonymous.
    606 *
    607 * This can still return nullptr as `name` out-parameter if a useful display
    608 * name could not be inferred.
    609 *
    610 * This function returns false if any error happens while generating the
    611 * function name string for a function with lazy name.
    612 */
    613 extern JS_PUBLIC_API bool JS_GetFunctionDisplayId(
    614    JSContext* cx, JS::Handle<JSFunction*> fun,
    615    JS::MutableHandle<JSString*> name);
    616 
    617 /**
    618 * Almost same as JS_GetFunctionDisplayId.
    619 *
    620 * If the function has lazy name, this returns partial name, such as the
    621 * function name without "get " or "set " prefix.
    622 */
    623 extern JS_PUBLIC_API JSString* JS_GetMaybePartialFunctionDisplayId(JSFunction*);
    624 
    625 /*
    626 * Return the arity of fun, which includes default parameters and rest
    627 * parameter.  This can be used as `nargs` parameter for other functions.
    628 */
    629 extern JS_PUBLIC_API uint16_t JS_GetFunctionArity(JSFunction* fun);
    630 
    631 /*
    632 * Return the length of fun, which is the original value of .length property.
    633 */
    634 JS_PUBLIC_API bool JS_GetFunctionLength(JSContext* cx, JS::HandleFunction fun,
    635                                        uint16_t* length);
    636 
    637 /**
    638 * Infallible predicate to test whether obj is a function object (faster than
    639 * comparing obj's class name to "Function", but equivalent unless someone has
    640 * overwritten the "Function" identifier with a different constructor and then
    641 * created instances using that constructor that might be passed in as obj).
    642 */
    643 extern JS_PUBLIC_API bool JS_ObjectIsFunction(JSObject* obj);
    644 
    645 extern JS_PUBLIC_API bool JS_IsNativeFunction(JSObject* funobj, JSNative call);
    646 
    647 /** Return whether the given function is a valid constructor. */
    648 extern JS_PUBLIC_API bool JS_IsConstructor(JSFunction* fun);
    649 
    650 extern JS_PUBLIC_API bool JS_ObjectIsBoundFunction(JSObject* obj);
    651 
    652 extern JS_PUBLIC_API JSObject* JS_GetBoundFunctionTarget(JSObject* obj);
    653 
    654 extern JS_PUBLIC_API JSObject* JS_GetGlobalFromScript(JSScript* script);
    655 
    656 extern JS_PUBLIC_API const char* JS_GetScriptFilename(JSScript* script);
    657 
    658 extern JS_PUBLIC_API unsigned JS_GetScriptBaseLineNumber(JSContext* cx,
    659                                                         JSScript* script);
    660 
    661 extern JS_PUBLIC_API JSScript* JS_GetFunctionScript(JSContext* cx,
    662                                                    JS::HandleFunction fun);
    663 
    664 extern JS_PUBLIC_API JSString* JS_DecompileScript(JSContext* cx,
    665                                                  JS::Handle<JSScript*> script);
    666 
    667 extern JS_PUBLIC_API JSString* JS_DecompileFunction(
    668    JSContext* cx, JS::Handle<JSFunction*> fun);
    669 
    670 namespace JS {
    671 
    672 /**
    673 * Supply an alternative stack to incorporate into captured SavedFrame
    674 * backtraces as the imputed caller of asynchronous JavaScript calls, like async
    675 * function resumptions and DOM callbacks.
    676 *
    677 * When one async function awaits the result of another, it's natural to think
    678 * of that as a sort of function call: just as execution resumes from an
    679 * ordinary call expression when the callee returns, with the return value
    680 * providing the value of the call expression, execution resumes from an 'await'
    681 * expression after the awaited asynchronous function call returns, passing the
    682 * return value along.
    683 *
    684 * Call the two async functions in such a situation the 'awaiter' and the
    685 * 'awaitee'.
    686 *
    687 * As an async function, the awaitee contains 'await' expressions of its own.
    688 * Whenever it executes after its first 'await', there are never any actual
    689 * frames on the JavaScript stack under it; its awaiter is certainly not there.
    690 * An await expression's continuation is invoked as a promise callback, and
    691 * those are always called directly from the event loop in their own microtick.
    692 * (Ignore unusual cases like nested event loops.)
    693 *
    694 * But because await expressions bear such a strong resemblance to calls (and
    695 * deliberately so!), it would be unhelpful for stacks captured within the
    696 * awaitee to be empty; instead, they should present the awaiter as the caller.
    697 *
    698 * The AutoSetAsyncStackForNewCalls RAII class supplies a SavedFrame stack to
    699 * treat as the caller of any JavaScript invocations that occur within its
    700 * lifetime. Any SavedFrame stack captured during such an invocation uses the
    701 * SavedFrame passed to the constructor's 'stack' parameter as the 'asyncParent'
    702 * property of the SavedFrame for the invocation's oldest frame. Its 'parent'
    703 * property will be null, so stack-walking code can distinguish this
    704 * awaiter/awaitee transition from an ordinary caller/callee transition.
    705 *
    706 * The constructor's 'asyncCause' parameter supplies a string explaining what
    707 * sort of asynchronous call caused 'stack' to be spliced into the backtrace;
    708 * for example, async function resumptions use the string "async". This appears
    709 * as the 'asyncCause' property of the 'asyncParent' SavedFrame.
    710 *
    711 * Async callers are distinguished in the string form of a SavedFrame chain by
    712 * including the 'asyncCause' string in the frame. It appears before the
    713 * function name, with the two separated by a '*'.
    714 *
    715 * Note that, as each compartment has its own set of SavedFrames, the
    716 * 'asyncParent' may actually point to a copy of 'stack', rather than the exact
    717 * SavedFrame object passed.
    718 *
    719 * The youngest frame of 'stack' is not mutated to take the asyncCause string as
    720 * its 'asyncCause' property; SavedFrame objects are immutable. Rather, a fresh
    721 * clone of the frame is created with the needed 'asyncCause' property.
    722 *
    723 * The 'kind' argument specifies how aggressively 'stack' supplants any
    724 * JavaScript frames older than this AutoSetAsyncStackForNewCalls object. If
    725 * 'kind' is 'EXPLICIT', then all captured SavedFrame chains take on 'stack' as
    726 * their 'asyncParent' where the chain crosses this object's scope. If 'kind' is
    727 * 'IMPLICIT', then 'stack' is only included in captured chains if there are no
    728 * other JavaScript frames on the stack --- that is, only if the stack would
    729 * otherwise end at that point.
    730 *
    731 * AutoSetAsyncStackForNewCalls affects only SavedFrame chains; it does not
    732 * affect Debugger.Frame or js::FrameIter. SavedFrame chains are used for
    733 * Error.stack, allocation profiling, Promise debugging, and so on.
    734 *
    735 * See also `js/src/doc/SavedFrame/SavedFrame.md` for documentation on async
    736 * stack frames.
    737 */
    738 class MOZ_STACK_CLASS JS_PUBLIC_API AutoSetAsyncStackForNewCalls {
    739  JSContext* cx;
    740  RootedObject oldAsyncStack;
    741  const char* oldAsyncCause;
    742  bool oldAsyncCallIsExplicit;
    743 
    744 public:
    745  enum class AsyncCallKind {
    746    // The ordinary kind of call, where we may apply an async
    747    // parent if there is no ordinary parent.
    748    IMPLICIT,
    749    // An explicit async parent, e.g., callFunctionWithAsyncStack,
    750    // where we always want to override any ordinary parent.
    751    EXPLICIT
    752  };
    753 
    754  // The stack parameter cannot be null by design, because it would be
    755  // ambiguous whether that would clear any scheduled async stack and make the
    756  // normal stack reappear in the new call, or just keep the async stack
    757  // already scheduled for the new call, if any.
    758  //
    759  // asyncCause is owned by the caller and its lifetime must outlive the
    760  // lifetime of the AutoSetAsyncStackForNewCalls object. It is strongly
    761  // encouraged that asyncCause be a string constant or similar statically
    762  // allocated string.
    763  AutoSetAsyncStackForNewCalls(JSContext* cx, JSObject* stack,
    764                               const char* asyncCause,
    765                               AsyncCallKind kind = AsyncCallKind::IMPLICIT);
    766  ~AutoSetAsyncStackForNewCalls();
    767 };
    768 
    769 }  // namespace JS
    770 
    771 /************************************************************************/
    772 
    773 namespace JS {
    774 
    775 JS_PUBLIC_API bool PropertySpecNameEqualsId(JSPropertySpec::Name name,
    776                                            HandleId id);
    777 
    778 /**
    779 * Create a jsid that does not need to be marked for GC.
    780 *
    781 * 'name' is a JSPropertySpec::name or JSFunctionSpec::name value. The
    782 * resulting jsid, on success, is either an interned string or a well-known
    783 * symbol; either way it is immune to GC so there is no need to visit *idp
    784 * during GC marking.
    785 */
    786 JS_PUBLIC_API bool PropertySpecNameToPermanentId(JSContext* cx,
    787                                                 JSPropertySpec::Name name,
    788                                                 jsid* idp);
    789 
    790 } /* namespace JS */
    791 
    792 /************************************************************************/
    793 
    794 /**
    795 * A JS context always has an "owner thread". The owner thread is set when the
    796 * context is created (to the current thread) and practically all entry points
    797 * into the JS engine check that a context (or anything contained in the
    798 * context: runtime, compartment, object, etc) is only touched by its owner
    799 * thread. Embeddings may check this invariant outside the JS engine by calling
    800 * JS_AbortIfWrongThread (which will abort if not on the owner thread, even for
    801 * non-debug builds).
    802 */
    803 
    804 extern JS_PUBLIC_API void JS_AbortIfWrongThread(JSContext* cx);
    805 
    806 /************************************************************************/
    807 
    808 /**
    809 * A constructor can request that the JS engine create a default new 'this'
    810 * object of the given class, using the callee to determine parentage and
    811 * [[Prototype]].
    812 */
    813 extern JS_PUBLIC_API JSObject* JS_NewObjectForConstructor(
    814    JSContext* cx, const JSClass* clasp, const JS::CallArgs& args);
    815 
    816 /************************************************************************/
    817 
    818 extern JS_PUBLIC_API void JS_SetOffthreadBaselineCompilationEnabled(
    819    JSContext* cx, bool enabled);
    820 extern JS_PUBLIC_API void JS_SetOffthreadIonCompilationEnabled(JSContext* cx,
    821                                                               bool enabled);
    822 
    823 // clang-format off
    824 #define JIT_COMPILER_OPTIONS(Register) \
    825  Register(BASELINE_INTERPRETER_WARMUP_TRIGGER, "blinterp.warmup.trigger") \
    826  Register(BASELINE_WARMUP_TRIGGER, "baseline.warmup.trigger") \
    827  Register(IC_FORCE_MEGAMORPHIC, "ic.force-megamorphic") \
    828  Register(ION_NORMAL_WARMUP_TRIGGER, "ion.warmup.trigger") \
    829  Register(ION_GVN_ENABLE, "ion.gvn.enable") \
    830  Register(ION_FORCE_IC, "ion.forceinlineCaches") \
    831  Register(ION_ENABLE, "ion.enable") \
    832  Register(JIT_TRUSTEDPRINCIPALS_ENABLE, "jit_trustedprincipals.enable") \
    833  Register(ION_CHECK_RANGE_ANALYSIS, "ion.check-range-analysis") \
    834  Register(ION_FREQUENT_BAILOUT_THRESHOLD, "ion.frequent-bailout-threshold") \
    835  Register(BASE_REG_FOR_LOCALS, "base-reg-for-locals") \
    836  Register(INLINING_BYTECODE_MAX_LENGTH, "inlining.bytecode-max-length") \
    837  Register(BASELINE_INTERPRETER_ENABLE, "blinterp.enable") \
    838  Register(BASELINE_ENABLE, "baseline.enable") \
    839  Register(PORTABLE_BASELINE_ENABLE, "pbl.enable") \
    840  Register(PORTABLE_BASELINE_WARMUP_THRESHOLD, "pbl.warmup.threshold") \
    841  Register(OFFTHREAD_COMPILATION_ENABLE, "offthread-compilation.enable")  \
    842  Register(FULL_DEBUG_CHECKS, "jit.full-debug-checks") \
    843  Register(JUMP_THRESHOLD, "jump-threshold") \
    844  Register(NATIVE_REGEXP_ENABLE, "native_regexp.enable") \
    845  Register(JIT_HINTS_ENABLE, "jitHints.enable") \
    846  Register(SIMULATOR_ALWAYS_INTERRUPT, "simulator.always-interrupt")      \
    847  Register(SPECTRE_INDEX_MASKING, "spectre.index-masking") \
    848  Register(SPECTRE_OBJECT_MITIGATIONS, "spectre.object-mitigations") \
    849  Register(SPECTRE_STRING_MITIGATIONS, "spectre.string-mitigations") \
    850  Register(SPECTRE_VALUE_MASKING, "spectre.value-masking") \
    851  Register(SPECTRE_JIT_TO_CXX_CALLS, "spectre.jit-to-cxx-calls") \
    852  Register(WRITE_PROTECT_CODE, "write-protect-code") \
    853  Register(WASM_FOLD_OFFSETS, "wasm.fold-offsets") \
    854  Register(WASM_DELAY_TIER2, "wasm.delay-tier2") \
    855  Register(WASM_JIT_BASELINE, "wasm.baseline") \
    856  Register(WASM_JIT_OPTIMIZING, "wasm.optimizing") \
    857  Register(REGEXP_DUPLICATE_NAMED_GROUPS, "regexp.duplicate-named-groups") \
    858  Register(REGEXP_MODIFIERS, "regexp.modifiers")  // clang-format on
    859 
    860 typedef enum JSJitCompilerOption {
    861 #define JIT_COMPILER_DECLARE(key, str) JSJITCOMPILER_##key,
    862 
    863  JIT_COMPILER_OPTIONS(JIT_COMPILER_DECLARE)
    864 #undef JIT_COMPILER_DECLARE
    865 
    866      JSJITCOMPILER_NOT_AN_OPTION
    867 } JSJitCompilerOption;
    868 
    869 extern JS_PUBLIC_API void JS_SetGlobalJitCompilerOption(JSContext* cx,
    870                                                        JSJitCompilerOption opt,
    871                                                        uint32_t value);
    872 extern JS_PUBLIC_API bool JS_GetGlobalJitCompilerOption(JSContext* cx,
    873                                                        JSJitCompilerOption opt,
    874                                                        uint32_t* valueOut);
    875 
    876 namespace JS {
    877 
    878 // Disable all Spectre mitigations for this process after creating the initial
    879 // JSContext. Must be called on this context's thread.
    880 extern JS_PUBLIC_API void DisableSpectreMitigationsAfterInit();
    881 
    882 };  // namespace JS
    883 
    884 /**
    885 * Convert a uint32_t index into a jsid.
    886 */
    887 extern JS_PUBLIC_API bool JS_IndexToId(JSContext* cx, uint32_t index,
    888                                       JS::MutableHandleId);
    889 
    890 /**
    891 * Convert chars into a jsid.
    892 *
    893 * |chars| may not be an index.
    894 */
    895 extern JS_PUBLIC_API bool JS_CharsToId(JSContext* cx, JS::TwoByteChars chars,
    896                                       JS::MutableHandleId);
    897 
    898 /**
    899 *  Test if the given string is a valid ECMAScript identifier
    900 */
    901 extern JS_PUBLIC_API bool JS_IsIdentifier(JSContext* cx, JS::HandleString str,
    902                                          bool* isIdentifier);
    903 
    904 /**
    905 * Test whether the given chars + length are a valid ECMAScript identifier.
    906 * This version is infallible, so just returns whether the chars are an
    907 * identifier.
    908 */
    909 extern JS_PUBLIC_API bool JS_IsIdentifier(const char16_t* chars, size_t length);
    910 
    911 namespace js {
    912 class ScriptSource;
    913 }  // namespace js
    914 
    915 namespace JS {
    916 
    917 class MOZ_RAII JS_PUBLIC_API AutoFilename {
    918 private:
    919  js::ScriptSource* ss_;
    920  mozilla::Variant<const char*, UniqueChars> filename_;
    921 
    922  AutoFilename(const AutoFilename&) = delete;
    923  AutoFilename& operator=(const AutoFilename&) = delete;
    924 
    925 public:
    926  AutoFilename()
    927      : ss_(nullptr), filename_(mozilla::AsVariant<const char*>(nullptr)) {}
    928 
    929  ~AutoFilename() { reset(); }
    930 
    931  void reset();
    932 
    933  void setOwned(UniqueChars&& filename);
    934  void setUnowned(const char* filename);
    935  void setScriptSource(js::ScriptSource* ss);
    936 
    937  const char* get() const;
    938 };
    939 
    940 /**
    941 * Return the current filename, line number and column number of the most
    942 * currently running frame. Returns true if a scripted frame was found, false
    943 * otherwise.
    944 *
    945 * If a the embedding has hidden the scripted caller for the topmost activation
    946 * record, this will also return false.
    947 *
    948 * This never throws an exception.
    949 */
    950 extern JS_PUBLIC_API bool DescribeScriptedCaller(
    951    AutoFilename* filename, JSContext* cx, uint32_t* lineno = nullptr,
    952    JS::ColumnNumberOneOrigin* column = nullptr);
    953 
    954 extern JS_PUBLIC_API JSObject* GetScriptedCallerGlobal(JSContext* cx);
    955 
    956 /**
    957 * Informs the JS engine that the scripted caller should be hidden. This can be
    958 * used by the embedding to maintain an override of the scripted caller in its
    959 * calculations, by hiding the scripted caller in the JS engine and pushing data
    960 * onto a separate stack, which it inspects when DescribeScriptedCaller returns
    961 * null.
    962 *
    963 * We maintain a counter on each activation record. Add() increments the counter
    964 * of the topmost activation, and Remove() decrements it. The count may never
    965 * drop below zero, and must always be exactly zero when the activation is
    966 * popped from the stack.
    967 */
    968 extern JS_PUBLIC_API void HideScriptedCaller(JSContext* cx);
    969 
    970 extern JS_PUBLIC_API void UnhideScriptedCaller(JSContext* cx);
    971 
    972 class MOZ_RAII AutoHideScriptedCaller {
    973 public:
    974  explicit AutoHideScriptedCaller(JSContext* cx) : mContext(cx) {
    975    HideScriptedCaller(mContext);
    976  }
    977  ~AutoHideScriptedCaller() { UnhideScriptedCaller(mContext); }
    978 
    979 protected:
    980  JSContext* mContext;
    981 };
    982 
    983 /**
    984 * Attempt to disable Wasm's usage of reserving a large virtual memory
    985 * allocation to avoid bounds checking overhead. This must be called before any
    986 * Wasm module or memory is created in this process, or else this function will
    987 * fail.
    988 */
    989 [[nodiscard]] extern JS_PUBLIC_API bool DisableWasmHugeMemory();
    990 
    991 /**
    992 * Return true iff the given object is either a SavedFrame object or wrapper
    993 * around a SavedFrame object, and it is not the SavedFrame.prototype object.
    994 */
    995 extern JS_PUBLIC_API bool IsMaybeWrappedSavedFrame(JSObject* obj);
    996 
    997 /**
    998 * Return true iff the given object is a SavedFrame object and not the
    999 * SavedFrame.prototype object.
   1000 */
   1001 extern JS_PUBLIC_API bool IsUnwrappedSavedFrame(JSObject* obj);
   1002 
   1003 } /* namespace JS */
   1004 
   1005 namespace js {
   1006 
   1007 /**
   1008 * Hint that we expect a crash. Currently, the only thing that cares is the
   1009 * breakpad injector, which (if loaded) will suppress minidump generation.
   1010 */
   1011 extern JS_PUBLIC_API void NoteIntentionalCrash();
   1012 
   1013 } /* namespace js */
   1014 
   1015 #ifdef DEBUG
   1016 namespace JS {
   1017 
   1018 extern JS_PUBLIC_API void SetSupportDifferentialTesting(bool value);
   1019 
   1020 }
   1021 #endif /* DEBUG */
   1022 
   1023 #endif /* jsapi_h */