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