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 */