js/src/jsfriendapi.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     2  * vim: set ts=8 sts=4 et sw=4 tw=99:
     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 #ifndef jsfriendapi_h
     8 #define jsfriendapi_h
    10 #include "mozilla/Casting.h"
    11 #include "mozilla/MemoryReporting.h"
    12 #include "mozilla/TypedEnum.h"
    14 #include "jsbytecode.h"
    15 #include "jspubtd.h"
    17 #include "js/CallArgs.h"
    18 #include "js/CallNonGenericMethod.h"
    19 #include "js/Class.h"
    21 /*
    22  * This macro checks if the stack pointer has exceeded a given limit. If
    23  * |tolerance| is non-zero, it returns true only if the stack pointer has
    24  * exceeded the limit by more than |tolerance| bytes.
    25  */
    26 #if JS_STACK_GROWTH_DIRECTION > 0
    27 # define JS_CHECK_STACK_SIZE_WITH_TOLERANCE(limit, sp, tolerance)  \
    28     ((uintptr_t)(sp) < (limit)+(tolerance))
    29 #else
    30 # define JS_CHECK_STACK_SIZE_WITH_TOLERANCE(limit, sp, tolerance)  \
    31     ((uintptr_t)(sp) > (limit)-(tolerance))
    32 #endif
    34 #define JS_CHECK_STACK_SIZE(limit, lval) JS_CHECK_STACK_SIZE_WITH_TOLERANCE(limit, lval, 0)
    36 class JSAtom;
    37 struct JSErrorFormatString;
    38 class JSLinearString;
    39 struct JSJitInfo;
    40 class JSErrorReport;
    42 namespace JS {
    43 template <class T>
    44 class Heap;
    45 } /* namespace JS */
    47 namespace js {
    48 class JS_FRIEND_API(BaseProxyHandler);
    49 } /* namespace js */
    51 extern JS_FRIEND_API(void)
    52 JS_SetGrayGCRootsTracer(JSRuntime *rt, JSTraceDataOp traceOp, void *data);
    54 extern JS_FRIEND_API(JSString *)
    55 JS_GetAnonymousString(JSRuntime *rt);
    57 extern JS_FRIEND_API(void)
    58 JS_SetIsWorkerRuntime(JSRuntime *rt);
    60 extern JS_FRIEND_API(JSObject *)
    61 JS_FindCompilationScope(JSContext *cx, JS::HandleObject obj);
    63 extern JS_FRIEND_API(JSFunction *)
    64 JS_GetObjectFunction(JSObject *obj);
    66 extern JS_FRIEND_API(bool)
    67 JS_SplicePrototype(JSContext *cx, JS::HandleObject obj, JS::HandleObject proto);
    69 extern JS_FRIEND_API(JSObject *)
    70 JS_NewObjectWithUniqueType(JSContext *cx, const JSClass *clasp, JS::HandleObject proto,
    71                            JS::HandleObject parent);
    73 extern JS_FRIEND_API(uint32_t)
    74 JS_ObjectCountDynamicSlots(JS::HandleObject obj);
    76 extern JS_FRIEND_API(size_t)
    77 JS_SetProtoCalled(JSContext *cx);
    79 extern JS_FRIEND_API(size_t)
    80 JS_GetCustomIteratorCount(JSContext *cx);
    82 extern JS_FRIEND_API(bool)
    83 JS_NondeterministicGetWeakMapKeys(JSContext *cx, JS::HandleObject obj, JS::MutableHandleObject ret);
    85 /*
    86  * Determine whether the given object is backed by a DeadObjectProxy.
    87  *
    88  * Such objects hold no other objects (they have no outgoing reference edges)
    89  * and will throw if you touch them (e.g. by reading/writing a property).
    90  */
    91 extern JS_FRIEND_API(bool)
    92 JS_IsDeadWrapper(JSObject *obj);
    94 /*
    95  * Used by the cycle collector to trace through the shape and all
    96  * shapes it reaches, marking all non-shape children found in the
    97  * process. Uses bounded stack space.
    98  */
    99 extern JS_FRIEND_API(void)
   100 JS_TraceShapeCycleCollectorChildren(JSTracer *trc, void *shape);
   102 enum {
   103     JS_TELEMETRY_GC_REASON,
   104     JS_TELEMETRY_GC_IS_COMPARTMENTAL,
   105     JS_TELEMETRY_GC_MS,
   106     JS_TELEMETRY_GC_MAX_PAUSE_MS,
   107     JS_TELEMETRY_GC_MARK_MS,
   108     JS_TELEMETRY_GC_SWEEP_MS,
   109     JS_TELEMETRY_GC_MARK_ROOTS_MS,
   110     JS_TELEMETRY_GC_MARK_GRAY_MS,
   111     JS_TELEMETRY_GC_SLICE_MS,
   112     JS_TELEMETRY_GC_MMU_50,
   113     JS_TELEMETRY_GC_RESET,
   114     JS_TELEMETRY_GC_INCREMENTAL_DISABLED,
   115     JS_TELEMETRY_GC_NON_INCREMENTAL,
   116     JS_TELEMETRY_GC_SCC_SWEEP_TOTAL_MS,
   117     JS_TELEMETRY_GC_SCC_SWEEP_MAX_PAUSE_MS
   118 };
   120 typedef void
   121 (* JSAccumulateTelemetryDataCallback)(int id, uint32_t sample);
   123 extern JS_FRIEND_API(void)
   124 JS_SetAccumulateTelemetryCallback(JSRuntime *rt, JSAccumulateTelemetryDataCallback callback);
   126 extern JS_FRIEND_API(JSPrincipals *)
   127 JS_GetCompartmentPrincipals(JSCompartment *compartment);
   129 extern JS_FRIEND_API(void)
   130 JS_SetCompartmentPrincipals(JSCompartment *compartment, JSPrincipals *principals);
   132 /* Safe to call with input obj == nullptr. Returns non-nullptr iff obj != nullptr. */
   133 extern JS_FRIEND_API(JSObject *)
   134 JS_ObjectToInnerObject(JSContext *cx, JS::HandleObject obj);
   136 /* Requires obj != nullptr. */
   137 extern JS_FRIEND_API(JSObject *)
   138 JS_ObjectToOuterObject(JSContext *cx, JS::HandleObject obj);
   140 extern JS_FRIEND_API(JSObject *)
   141 JS_CloneObject(JSContext *cx, JS::HandleObject obj, JS::HandleObject proto,
   142                JS::HandleObject parent);
   144 extern JS_FRIEND_API(JSString *)
   145 JS_BasicObjectToString(JSContext *cx, JS::HandleObject obj);
   147 extern JS_FRIEND_API(bool)
   148 js_GetterOnlyPropertyStub(JSContext *cx, JS::HandleObject obj, JS::HandleId id, bool strict,
   149                           JS::MutableHandleValue vp);
   151 JS_FRIEND_API(void)
   152 js_ReportOverRecursed(JSContext *maybecx);
   154 JS_FRIEND_API(bool)
   155 js_ObjectClassIs(JSContext *cx, JS::HandleObject obj, js::ESClassValue classValue);
   157 JS_FRIEND_API(const char *)
   158 js_ObjectClassName(JSContext *cx, JS::HandleObject obj);
   160 namespace js {
   162 JS_FRIEND_API(bool)
   163 AddRawValueRoot(JSContext *cx, JS::Value *vp, const char *name);
   165 JS_FRIEND_API(void)
   166 RemoveRawValueRoot(JSContext *cx, JS::Value *vp);
   168 } /* namespace js */
   170 #ifdef JS_DEBUG
   172 /*
   173  * Routines to print out values during debugging.  These are FRIEND_API to help
   174  * the debugger find them and to support temporarily hacking js_Dump* calls
   175  * into other code.
   176  */
   178 extern JS_FRIEND_API(void)
   179 js_DumpString(JSString *str);
   181 extern JS_FRIEND_API(void)
   182 js_DumpAtom(JSAtom *atom);
   184 extern JS_FRIEND_API(void)
   185 js_DumpObject(JSObject *obj);
   187 extern JS_FRIEND_API(void)
   188 js_DumpChars(const jschar *s, size_t n);
   189 #endif
   191 /*
   192  * Copies all own properties from |obj| to |target|. |obj| must be a "native"
   193  * object (that is to say, normal-ish - not an Array or a Proxy).
   194  *
   195  * This function immediately enters a compartment, and does not impose any
   196  * restrictions on the compartment of |cx|.
   197  */
   198 extern JS_FRIEND_API(bool)
   199 JS_CopyPropertiesFrom(JSContext *cx, JS::HandleObject target, JS::HandleObject obj);
   201 /*
   202  * Single-property version of the above. This function asserts that an |own|
   203  * property of the given name exists on |obj|.
   204  *
   205  * On entry, |cx| must be same-compartment with |obj|.
   206  */
   207 extern JS_FRIEND_API(bool)
   208 JS_CopyPropertyFrom(JSContext *cx, JS::HandleId id, JS::HandleObject target,
   209                     JS::HandleObject obj);
   211 extern JS_FRIEND_API(bool)
   212 JS_WrapPropertyDescriptor(JSContext *cx, JS::MutableHandle<JSPropertyDescriptor> desc);
   214 extern JS_FRIEND_API(bool)
   215 JS_WrapAutoIdVector(JSContext *cx, JS::AutoIdVector &props);
   217 extern JS_FRIEND_API(bool)
   218 JS_EnumerateState(JSContext *cx, JS::HandleObject obj, JSIterateOp enum_op,
   219                   JS::MutableHandleValue statep, JS::MutableHandleId idp);
   221 struct JSFunctionSpecWithHelp {
   222     const char      *name;
   223     JSNative        call;
   224     uint16_t        nargs;
   225     uint16_t        flags;
   226     const char      *usage;
   227     const char      *help;
   228 };
   230 #define JS_FN_HELP(name,call,nargs,flags,usage,help)                          \
   231     {name, call, nargs, (flags) | JSPROP_ENUMERATE | JSFUN_STUB_GSOPS, usage, help}
   232 #define JS_FS_HELP_END                                                        \
   233     {nullptr, nullptr, 0, 0, nullptr, nullptr}
   235 extern JS_FRIEND_API(bool)
   236 JS_DefineFunctionsWithHelp(JSContext *cx, JS::HandleObject obj, const JSFunctionSpecWithHelp *fs);
   238 namespace js {
   240 /*
   241  * Helper Macros for creating JSClasses that function as proxies.
   242  *
   243  * NB: The macro invocation must be surrounded by braces, so as to
   244  *     allow for potention JSClass extensions.
   245  */
   246 #define PROXY_MAKE_EXT(outerObject, innerObject, iteratorObject,        \
   247                        isWrappedNative)                                 \
   248     {                                                                   \
   249         outerObject,                                                    \
   250         innerObject,                                                    \
   251         iteratorObject,                                                 \
   252         isWrappedNative,                                                \
   253         js::proxy_WeakmapKeyDelegate                                    \
   254     }
   256 #define PROXY_CLASS_WITH_EXT(name, extraSlots, flags, callOp, constructOp, ext)         \
   257     {                                                                                   \
   258         name,                                                                           \
   259         js::Class::NON_NATIVE |                                                         \
   260             JSCLASS_IS_PROXY |                                                          \
   261             JSCLASS_IMPLEMENTS_BARRIERS |                                               \
   262             JSCLASS_HAS_RESERVED_SLOTS(js::PROXY_MINIMUM_SLOTS + (extraSlots)) |        \
   263             flags,                                                                      \
   264         JS_PropertyStub,         /* addProperty */                                      \
   265         JS_DeletePropertyStub,   /* delProperty */                                      \
   266         JS_PropertyStub,         /* getProperty */                                      \
   267         JS_StrictPropertyStub,   /* setProperty */                                      \
   268         JS_EnumerateStub,                                                               \
   269         JS_ResolveStub,                                                                 \
   270         js::proxy_Convert,                                                              \
   271         js::proxy_Finalize,      /* finalize    */                                      \
   272         callOp,                  /* call        */                                      \
   273         js::proxy_HasInstance,   /* hasInstance */                                      \
   274         constructOp,             /* construct   */                                      \
   275         js::proxy_Trace,         /* trace       */                                      \
   276         JS_NULL_CLASS_SPEC,                                                             \
   277         ext,                                                                            \
   278         {                                                                               \
   279             js::proxy_LookupGeneric,                                                    \
   280             js::proxy_LookupProperty,                                                   \
   281             js::proxy_LookupElement,                                                    \
   282             js::proxy_DefineGeneric,                                                    \
   283             js::proxy_DefineProperty,                                                   \
   284             js::proxy_DefineElement,                                                    \
   285             js::proxy_GetGeneric,                                                       \
   286             js::proxy_GetProperty,                                                      \
   287             js::proxy_GetElement,                                                       \
   288             js::proxy_SetGeneric,                                                       \
   289             js::proxy_SetProperty,                                                      \
   290             js::proxy_SetElement,                                                       \
   291             js::proxy_GetGenericAttributes,                                             \
   292             js::proxy_SetGenericAttributes,                                             \
   293             js::proxy_DeleteProperty,                                                   \
   294             js::proxy_DeleteElement,                                                    \
   295             js::proxy_Watch, js::proxy_Unwatch,                                         \
   296             js::proxy_Slice,                                                            \
   297             nullptr,             /* enumerate       */                                  \
   298             nullptr,             /* thisObject      */                                  \
   299         }                                                                               \
   300     }
   302 #define PROXY_CLASS_DEF(name, extraSlots, flags, callOp, constructOp)   \
   303   PROXY_CLASS_WITH_EXT(name, extraSlots, flags, callOp, constructOp,    \
   304                        PROXY_MAKE_EXT(                                  \
   305                          nullptr, /* outerObject */                     \
   306                          nullptr, /* innerObject */                     \
   307                          nullptr, /* iteratorObject */                  \
   308                          false    /* isWrappedNative */                 \
   309                        ))
   311 /*
   312  * Proxy stubs, similar to JS_*Stub, for embedder proxy class definitions.
   313  *
   314  * NB: Should not be called directly.
   315  */
   317 extern JS_FRIEND_API(bool)
   318 proxy_LookupGeneric(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::MutableHandleObject objp,
   319                     JS::MutableHandle<Shape*> propp);
   320 extern JS_FRIEND_API(bool)
   321 proxy_LookupProperty(JSContext *cx, JS::HandleObject obj, JS::Handle<PropertyName*> name,
   322                      JS::MutableHandleObject objp, JS::MutableHandle<Shape*> propp);
   323 extern JS_FRIEND_API(bool)
   324 proxy_LookupElement(JSContext *cx, JS::HandleObject obj, uint32_t index, JS::MutableHandleObject objp,
   325                     JS::MutableHandle<Shape*> propp);
   326 extern JS_FRIEND_API(bool)
   327 proxy_DefineGeneric(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue value,
   328                     JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs);
   329 extern JS_FRIEND_API(bool)
   330 proxy_DefineProperty(JSContext *cx, JS::HandleObject obj, JS::Handle<PropertyName*> name,
   331                      JS::HandleValue value, JSPropertyOp getter, JSStrictPropertyOp setter,
   332                      unsigned attrs);
   333 extern JS_FRIEND_API(bool)
   334 proxy_DefineElement(JSContext *cx, JS::HandleObject obj, uint32_t index, JS::HandleValue value,
   335                     JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs);
   336 extern JS_FRIEND_API(bool)
   337 proxy_GetGeneric(JSContext *cx, JS::HandleObject obj, JS::HandleObject receiver, JS::HandleId id,
   338                  JS::MutableHandleValue vp);
   339 extern JS_FRIEND_API(bool)
   340 proxy_GetProperty(JSContext *cx, JS::HandleObject obj, JS::HandleObject receiver,
   341                   JS::Handle<PropertyName*> name, JS::MutableHandleValue vp);
   342 extern JS_FRIEND_API(bool)
   343 proxy_GetElement(JSContext *cx, JS::HandleObject obj, JS::HandleObject receiver, uint32_t index,
   344                  JS::MutableHandleValue vp);
   345 extern JS_FRIEND_API(bool)
   346 proxy_SetGeneric(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
   347                  JS::MutableHandleValue bp, bool strict);
   348 extern JS_FRIEND_API(bool)
   349 proxy_SetProperty(JSContext *cx, JS::HandleObject obj, JS::Handle<PropertyName*> name,
   350                   JS::MutableHandleValue bp, bool strict);
   351 extern JS_FRIEND_API(bool)
   352 proxy_SetElement(JSContext *cx, JS::HandleObject obj, uint32_t index, JS::MutableHandleValue vp,
   353                  bool strict);
   354 extern JS_FRIEND_API(bool)
   355 proxy_GetGenericAttributes(JSContext *cx, JS::HandleObject obj, JS::HandleId id, unsigned *attrsp);
   356 extern JS_FRIEND_API(bool)
   357 proxy_SetGenericAttributes(JSContext *cx, JS::HandleObject obj, JS::HandleId id, unsigned *attrsp);
   358 extern JS_FRIEND_API(bool)
   359 proxy_DeleteProperty(JSContext *cx, JS::HandleObject obj, JS::Handle<PropertyName*> name,
   360                      bool *succeeded);
   361 extern JS_FRIEND_API(bool)
   362 proxy_DeleteElement(JSContext *cx, JS::HandleObject obj, uint32_t index, bool *succeeded);
   364 extern JS_FRIEND_API(void)
   365 proxy_Trace(JSTracer *trc, JSObject *obj);
   366 extern JS_FRIEND_API(JSObject *)
   367 proxy_WeakmapKeyDelegate(JSObject *obj);
   368 extern JS_FRIEND_API(bool)
   369 proxy_Convert(JSContext *cx, JS::HandleObject proxy, JSType hint, JS::MutableHandleValue vp);
   370 extern JS_FRIEND_API(void)
   371 proxy_Finalize(FreeOp *fop, JSObject *obj);
   372 extern JS_FRIEND_API(bool)
   373 proxy_HasInstance(JSContext *cx, JS::HandleObject proxy, JS::MutableHandleValue v, bool *bp);
   374 extern JS_FRIEND_API(bool)
   375 proxy_Call(JSContext *cx, unsigned argc, JS::Value *vp);
   376 extern JS_FRIEND_API(bool)
   377 proxy_Construct(JSContext *cx, unsigned argc, JS::Value *vp);
   378 extern JS_FRIEND_API(JSObject *)
   379 proxy_innerObject(JSContext *cx, JS::HandleObject obj);
   380 extern JS_FRIEND_API(bool)
   381 proxy_Watch(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject callable);
   382 extern JS_FRIEND_API(bool)
   383 proxy_Unwatch(JSContext *cx, JS::HandleObject obj, JS::HandleId id);
   384 extern JS_FRIEND_API(bool)
   385 proxy_Slice(JSContext *cx, JS::HandleObject proxy, uint32_t begin, uint32_t end,
   386             JS::HandleObject result);
   388 /*
   389  * A class of objects that return source code on demand.
   390  *
   391  * When code is compiled with setSourceIsLazy(true), SpiderMonkey doesn't
   392  * retain the source code (and doesn't do lazy bytecode generation). If we ever
   393  * need the source code, say, in response to a call to Function.prototype.
   394  * toSource or Debugger.Source.prototype.text, then we call the 'load' member
   395  * function of the instance of this class that has hopefully been registered
   396  * with the runtime, passing the code's URL, and hope that it will be able to
   397  * find the source.
   398  */
   399 class SourceHook {
   400   public:
   401     virtual ~SourceHook() { }
   403     /*
   404      * Set |*src| and |*length| to refer to the source code for |filename|.
   405      * On success, the caller owns the buffer to which |*src| points, and
   406      * should use JS_free to free it.
   407      */
   408     virtual bool load(JSContext *cx, const char *filename, jschar **src, size_t *length) = 0;
   409 };
   411 /*
   412  * Have |rt| use |hook| to retrieve lazily-retrieved source code. See the
   413  * comments for SourceHook. The runtime takes ownership of the hook, and
   414  * will delete it when the runtime itself is deleted, or when a new hook is
   415  * set.
   416  */
   417 extern JS_FRIEND_API(void)
   418 SetSourceHook(JSRuntime *rt, SourceHook *hook);
   420 /* Remove |rt|'s source hook, and return it. The caller now owns the hook. */
   421 extern JS_FRIEND_API(SourceHook *)
   422 ForgetSourceHook(JSRuntime *rt);
   424 extern JS_FRIEND_API(JS::Zone *)
   425 GetCompartmentZone(JSCompartment *comp);
   427 typedef bool
   428 (* PreserveWrapperCallback)(JSContext *cx, JSObject *obj);
   430 typedef enum  {
   431     CollectNurseryBeforeDump,
   432     IgnoreNurseryObjects
   433 } DumpHeapNurseryBehaviour;
   435  /*
   436   * Dump the complete object graph of heap-allocated things.
   437   * fp is the file for the dump output.
   438   */
   439 extern JS_FRIEND_API(void)
   440 DumpHeapComplete(JSRuntime *rt, FILE *fp, DumpHeapNurseryBehaviour nurseryBehaviour);
   442 #ifdef JS_OLD_GETTER_SETTER_METHODS
   443 JS_FRIEND_API(bool) obj_defineGetter(JSContext *cx, unsigned argc, JS::Value *vp);
   444 JS_FRIEND_API(bool) obj_defineSetter(JSContext *cx, unsigned argc, JS::Value *vp);
   445 #endif
   447 extern JS_FRIEND_API(bool)
   448 IsSystemCompartment(JSCompartment *comp);
   450 extern JS_FRIEND_API(bool)
   451 IsSystemZone(JS::Zone *zone);
   453 extern JS_FRIEND_API(bool)
   454 IsAtomsCompartment(JSCompartment *comp);
   456 /*
   457  * Check whether it is OK to assign an undeclared variable with the name
   458  * |propname| at the current location in script.  It is not an error if there is
   459  * no current script location, or if that location is not an assignment to an
   460  * undeclared variable.  Reports an error if one needs to be reported (and,
   461  * particularly, always reports when it returns false).
   462  */
   463 extern JS_FRIEND_API(bool)
   464 ReportIfUndeclaredVarAssignment(JSContext *cx, JS::HandleString propname);
   466 /*
   467  * Returns whether we're in a non-strict property set (in that we're in a
   468  * non-strict script and the bytecode we're on is a property set).  The return
   469  * value does NOT indicate any sort of exception was thrown: it's just a
   470  * boolean.
   471  */
   472 extern JS_FRIEND_API(bool)
   473 IsInNonStrictPropertySet(JSContext *cx);
   475 struct WeakMapTracer;
   477 /*
   478  * Weak map tracer callback, called once for every binding of every
   479  * weak map that was live at the time of the last garbage collection.
   480  *
   481  * m will be nullptr if the weak map is not contained in a JS Object.
   482  */
   483 typedef void
   484 (* WeakMapTraceCallback)(WeakMapTracer *trc, JSObject *m,
   485                          void *k, JSGCTraceKind kkind,
   486                          void *v, JSGCTraceKind vkind);
   488 struct WeakMapTracer {
   489     JSRuntime            *runtime;
   490     WeakMapTraceCallback callback;
   492     WeakMapTracer(JSRuntime *rt, WeakMapTraceCallback cb)
   493         : runtime(rt), callback(cb) {}
   494 };
   496 extern JS_FRIEND_API(void)
   497 TraceWeakMaps(WeakMapTracer *trc);
   499 extern JS_FRIEND_API(bool)
   500 AreGCGrayBitsValid(JSRuntime *rt);
   502 extern JS_FRIEND_API(bool)
   503 ZoneGlobalsAreAllGray(JS::Zone *zone);
   505 typedef void
   506 (*GCThingCallback)(void *closure, void *gcthing);
   508 extern JS_FRIEND_API(void)
   509 VisitGrayWrapperTargets(JS::Zone *zone, GCThingCallback callback, void *closure);
   511 extern JS_FRIEND_API(JSObject *)
   512 GetWeakmapKeyDelegate(JSObject *key);
   514 JS_FRIEND_API(JSGCTraceKind)
   515 GCThingTraceKind(void *thing);
   517 /*
   518  * Invoke cellCallback on every gray JS_OBJECT in the given zone.
   519  */
   520 extern JS_FRIEND_API(void)
   521 IterateGrayObjects(JS::Zone *zone, GCThingCallback cellCallback, void *data);
   523 #ifdef JS_HAS_CTYPES
   524 extern JS_FRIEND_API(size_t)
   525 SizeOfDataIfCDataObject(mozilla::MallocSizeOf mallocSizeOf, JSObject *obj);
   526 #endif
   528 extern JS_FRIEND_API(JSCompartment *)
   529 GetAnyCompartmentInZone(JS::Zone *zone);
   531 /*
   532  * Shadow declarations of JS internal structures, for access by inline access
   533  * functions below. Do not use these structures in any other way. When adding
   534  * new fields for access by inline methods, make sure to add static asserts to
   535  * the original header file to ensure that offsets are consistent.
   536  */
   537 namespace shadow {
   539 struct TypeObject {
   540     const Class *clasp;
   541     JSObject    *proto;
   542 };
   544 struct BaseShape {
   545     const js::Class *clasp_;
   546     JSObject *parent;
   547     JSObject *_1;
   548     JSCompartment *compartment;
   549 };
   551 class Shape {
   552 public:
   553     shadow::BaseShape *base;
   554     jsid              _1;
   555     uint32_t          slotInfo;
   557     static const uint32_t FIXED_SLOTS_SHIFT = 27;
   558 };
   560 struct Object {
   561     shadow::Shape      *shape;
   562     shadow::TypeObject *type;
   563     JS::Value          *slots;
   564     JS::Value          *_1;
   566     size_t numFixedSlots() const { return shape->slotInfo >> Shape::FIXED_SLOTS_SHIFT; }
   567     JS::Value *fixedSlots() const {
   568         return (JS::Value *)(uintptr_t(this) + sizeof(shadow::Object));
   569     }
   571     JS::Value &slotRef(size_t slot) const {
   572         size_t nfixed = numFixedSlots();
   573         if (slot < nfixed)
   574             return fixedSlots()[slot];
   575         return slots[slot - nfixed];
   576     }
   578     // Reserved slots with index < MAX_FIXED_SLOTS are guaranteed to
   579     // be fixed slots.
   580     static const uint32_t MAX_FIXED_SLOTS = 16;
   581 };
   583 struct Function {
   584     Object base;
   585     uint16_t nargs;
   586     uint16_t flags;
   587     /* Used only for natives */
   588     JSNative native;
   589     const JSJitInfo *jitinfo;
   590     void *_1;
   591 };
   593 struct Atom {
   594     static const size_t LENGTH_SHIFT = 4;
   595     size_t lengthAndFlags;
   596     const jschar *chars;
   597 };
   599 } /* namespace shadow */
   601 // This is equal to |&JSObject::class_|.  Use it in places where you don't want
   602 // to #include jsobj.h.
   603 extern JS_FRIEND_DATA(const js::Class* const) ObjectClassPtr;
   605 inline const js::Class *
   606 GetObjectClass(JSObject *obj)
   607 {
   608     return reinterpret_cast<const shadow::Object*>(obj)->type->clasp;
   609 }
   611 inline const JSClass *
   612 GetObjectJSClass(JSObject *obj)
   613 {
   614     return js::Jsvalify(GetObjectClass(obj));
   615 }
   617 inline bool
   618 IsInnerObject(JSObject *obj) {
   619     return !!GetObjectClass(obj)->ext.outerObject;
   620 }
   622 inline bool
   623 IsOuterObject(JSObject *obj) {
   624     return !!GetObjectClass(obj)->ext.innerObject;
   625 }
   627 JS_FRIEND_API(bool)
   628 IsFunctionObject(JSObject *obj);
   630 JS_FRIEND_API(bool)
   631 IsScopeObject(JSObject *obj);
   633 JS_FRIEND_API(bool)
   634 IsCallObject(JSObject *obj);
   636 inline JSObject *
   637 GetObjectParent(JSObject *obj)
   638 {
   639     JS_ASSERT(!IsScopeObject(obj));
   640     return reinterpret_cast<shadow::Object*>(obj)->shape->base->parent;
   641 }
   643 static MOZ_ALWAYS_INLINE JSCompartment *
   644 GetObjectCompartment(JSObject *obj)
   645 {
   646     return reinterpret_cast<shadow::Object*>(obj)->shape->base->compartment;
   647 }
   649 JS_FRIEND_API(JSObject *)
   650 GetObjectParentMaybeScope(JSObject *obj);
   652 JS_FRIEND_API(JSObject *)
   653 GetGlobalForObjectCrossCompartment(JSObject *obj);
   655 // Sidestep the activeContext checking implicitly performed in
   656 // JS_SetPendingException.
   657 JS_FRIEND_API(void)
   658 SetPendingExceptionCrossContext(JSContext *cx, JS::HandleValue v);
   660 JS_FRIEND_API(void)
   661 AssertSameCompartment(JSContext *cx, JSObject *obj);
   663 #ifdef JS_DEBUG
   664 JS_FRIEND_API(void)
   665 AssertSameCompartment(JSObject *objA, JSObject *objB);
   666 #else
   667 inline void AssertSameCompartment(JSObject *objA, JSObject *objB) {}
   668 #endif
   670 // For legacy consumers only. This whole concept is going away soon.
   671 JS_FRIEND_API(JSObject *)
   672 DefaultObjectForContextOrNull(JSContext *cx);
   674 JS_FRIEND_API(void)
   675 SetDefaultObjectForContext(JSContext *cx, JSObject *obj);
   677 JS_FRIEND_API(void)
   678 NotifyAnimationActivity(JSObject *obj);
   680 /*
   681  * Return the outermost enclosing function (script) of the scripted caller.
   682  * This function returns nullptr in several cases:
   683  *  - no script is running on the context
   684  *  - the caller is in global or eval code
   685  * In particular, this function will "stop" its outermost search at eval() and
   686  * thus it will really return the outermost enclosing function *since the
   687  * innermost eval*.
   688  */
   689 JS_FRIEND_API(JSScript *)
   690 GetOutermostEnclosingFunctionOfScriptedCaller(JSContext *cx);
   692 JS_FRIEND_API(JSFunction *)
   693 DefineFunctionWithReserved(JSContext *cx, JSObject *obj, const char *name, JSNative call,
   694                            unsigned nargs, unsigned attrs);
   696 JS_FRIEND_API(JSFunction *)
   697 NewFunctionWithReserved(JSContext *cx, JSNative call, unsigned nargs, unsigned flags,
   698                         JSObject *parent, const char *name);
   700 JS_FRIEND_API(JSFunction *)
   701 NewFunctionByIdWithReserved(JSContext *cx, JSNative native, unsigned nargs, unsigned flags,
   702                             JSObject *parent, jsid id);
   704 JS_FRIEND_API(JSObject *)
   705 InitClassWithReserved(JSContext *cx, JSObject *obj, JSObject *parent_proto,
   706                       const JSClass *clasp, JSNative constructor, unsigned nargs,
   707                       const JSPropertySpec *ps, const JSFunctionSpec *fs,
   708                       const JSPropertySpec *static_ps, const JSFunctionSpec *static_fs);
   710 JS_FRIEND_API(const JS::Value &)
   711 GetFunctionNativeReserved(JSObject *fun, size_t which);
   713 JS_FRIEND_API(void)
   714 SetFunctionNativeReserved(JSObject *fun, size_t which, const JS::Value &val);
   716 JS_FRIEND_API(bool)
   717 GetObjectProto(JSContext *cx, JS::HandleObject obj, JS::MutableHandleObject proto);
   719 JS_FRIEND_API(bool)
   720 GetOriginalEval(JSContext *cx, JS::HandleObject scope,
   721                 JS::MutableHandleObject eval);
   723 inline void *
   724 GetObjectPrivate(JSObject *obj)
   725 {
   726     const shadow::Object *nobj = reinterpret_cast<const shadow::Object*>(obj);
   727     void **addr = reinterpret_cast<void**>(&nobj->fixedSlots()[nobj->numFixedSlots()]);
   728     return *addr;
   729 }
   731 /*
   732  * Get a slot that is both reserved for object's clasp *and* is fixed (fits
   733  * within the maximum capacity for the object's fixed slots).
   734  */
   735 inline const JS::Value &
   736 GetReservedSlot(JSObject *obj, size_t slot)
   737 {
   738     JS_ASSERT(slot < JSCLASS_RESERVED_SLOTS(GetObjectClass(obj)));
   739     return reinterpret_cast<const shadow::Object *>(obj)->slotRef(slot);
   740 }
   742 JS_FRIEND_API(void)
   743 SetReservedSlotWithBarrier(JSObject *obj, size_t slot, const JS::Value &value);
   745 inline void
   746 SetReservedSlot(JSObject *obj, size_t slot, const JS::Value &value)
   747 {
   748     JS_ASSERT(slot < JSCLASS_RESERVED_SLOTS(GetObjectClass(obj)));
   749     shadow::Object *sobj = reinterpret_cast<shadow::Object *>(obj);
   750     if (sobj->slotRef(slot).isMarkable()
   751 #ifdef JSGC_GENERATIONAL
   752         || value.isMarkable()
   753 #endif
   754        )
   755     {
   756         SetReservedSlotWithBarrier(obj, slot, value);
   757     } else {
   758         sobj->slotRef(slot) = value;
   759     }
   760 }
   762 JS_FRIEND_API(uint32_t)
   763 GetObjectSlotSpan(JSObject *obj);
   765 inline const JS::Value &
   766 GetObjectSlot(JSObject *obj, size_t slot)
   767 {
   768     JS_ASSERT(slot < GetObjectSlotSpan(obj));
   769     return reinterpret_cast<const shadow::Object *>(obj)->slotRef(slot);
   770 }
   772 inline const jschar *
   773 GetAtomChars(JSAtom *atom)
   774 {
   775     return reinterpret_cast<shadow::Atom *>(atom)->chars;
   776 }
   778 inline size_t
   779 GetAtomLength(JSAtom *atom)
   780 {
   781     using shadow::Atom;
   782     return reinterpret_cast<Atom*>(atom)->lengthAndFlags >> Atom::LENGTH_SHIFT;
   783 }
   785 inline JSLinearString *
   786 AtomToLinearString(JSAtom *atom)
   787 {
   788     return reinterpret_cast<JSLinearString *>(atom);
   789 }
   791 JS_FRIEND_API(bool)
   792 GetPropertyNames(JSContext *cx, JSObject *obj, unsigned flags, JS::AutoIdVector *props);
   794 JS_FRIEND_API(bool)
   795 AppendUnique(JSContext *cx, JS::AutoIdVector &base, JS::AutoIdVector &others);
   797 JS_FRIEND_API(bool)
   798 GetGeneric(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id, JS::Value *vp);
   800 JS_FRIEND_API(bool)
   801 StringIsArrayIndex(JSLinearString *str, uint32_t *indexp);
   803 JS_FRIEND_API(void)
   804 SetPreserveWrapperCallback(JSRuntime *rt, PreserveWrapperCallback callback);
   806 JS_FRIEND_API(bool)
   807 IsObjectInContextCompartment(JSObject *obj, const JSContext *cx);
   809 /*
   810  * NB: these flag bits are encoded into the bytecode stream in the immediate
   811  * operand of JSOP_ITER, so don't change them without advancing vm/Xdr.h's
   812  * XDR_BYTECODE_VERSION.
   813  */
   814 #define JSITER_ENUMERATE  0x1   /* for-in compatible hidden default iterator */
   815 #define JSITER_FOREACH    0x2   /* return [key, value] pair rather than key */
   816 #define JSITER_KEYVALUE   0x4   /* destructuring for-in wants [key, value] */
   817 #define JSITER_OWNONLY    0x8   /* iterate over obj's own properties only */
   818 #define JSITER_HIDDEN     0x10  /* also enumerate non-enumerable properties */
   820 JS_FRIEND_API(bool)
   821 RunningWithTrustedPrincipals(JSContext *cx);
   823 inline uintptr_t
   824 GetNativeStackLimit(JSContext *cx)
   825 {
   826     StackKind kind = RunningWithTrustedPrincipals(cx) ? StackForTrustedScript
   827                                                       : StackForUntrustedScript;
   828     PerThreadDataFriendFields *mainThread =
   829       PerThreadDataFriendFields::getMainThread(GetRuntime(cx));
   830     return mainThread->nativeStackLimit[kind];
   831 }
   833 /*
   834  * These macros report a stack overflow and run |onerror| if we are close to
   835  * using up the C stack. The JS_CHECK_CHROME_RECURSION variant gives us a little
   836  * extra space so that we can ensure that crucial code is able to run.
   837  */
   839 #define JS_CHECK_RECURSION(cx, onerror)                                         \
   840     JS_BEGIN_MACRO                                                              \
   841         int stackDummy_;                                                        \
   842         if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(cx), &stackDummy_)) {  \
   843             js_ReportOverRecursed(cx);                                          \
   844             onerror;                                                            \
   845         }                                                                       \
   846     JS_END_MACRO
   848 #define JS_CHECK_RECURSION_DONT_REPORT(cx, onerror)                             \
   849     JS_BEGIN_MACRO                                                              \
   850         int stackDummy_;                                                        \
   851         if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(cx), &stackDummy_)) {  \
   852             onerror;                                                            \
   853         }                                                                       \
   854     JS_END_MACRO
   856 #define JS_CHECK_RECURSION_WITH_SP_DONT_REPORT(cx, sp, onerror)                 \
   857     JS_BEGIN_MACRO                                                              \
   858         if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(cx), sp)) {            \
   859             onerror;                                                            \
   860         }                                                                       \
   861     JS_END_MACRO
   863 #define JS_CHECK_RECURSION_WITH_SP(cx, sp, onerror)                             \
   864     JS_BEGIN_MACRO                                                              \
   865         if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(cx), sp)) {            \
   866             js_ReportOverRecursed(cx);                                          \
   867             onerror;                                                            \
   868         }                                                                       \
   869     JS_END_MACRO
   871 #define JS_CHECK_CHROME_RECURSION(cx, onerror)                                  \
   872     JS_BEGIN_MACRO                                                              \
   873         int stackDummy_;                                                        \
   874         if (!JS_CHECK_STACK_SIZE_WITH_TOLERANCE(js::GetNativeStackLimit(cx),    \
   875                                                 &stackDummy_,                   \
   876                                                 1024 * sizeof(size_t)))         \
   877         {                                                                       \
   878             js_ReportOverRecursed(cx);                                          \
   879             onerror;                                                            \
   880         }                                                                       \
   881     JS_END_MACRO
   883 JS_FRIEND_API(void)
   884 StartPCCountProfiling(JSContext *cx);
   886 JS_FRIEND_API(void)
   887 StopPCCountProfiling(JSContext *cx);
   889 JS_FRIEND_API(void)
   890 PurgePCCounts(JSContext *cx);
   892 JS_FRIEND_API(size_t)
   893 GetPCCountScriptCount(JSContext *cx);
   895 JS_FRIEND_API(JSString *)
   896 GetPCCountScriptSummary(JSContext *cx, size_t script);
   898 JS_FRIEND_API(JSString *)
   899 GetPCCountScriptContents(JSContext *cx, size_t script);
   901 #ifdef JS_THREADSAFE
   902 JS_FRIEND_API(bool)
   903 ContextHasOutstandingRequests(const JSContext *cx);
   904 #endif
   906 typedef void
   907 (* ActivityCallback)(void *arg, bool active);
   909 /*
   910  * Sets a callback that is run whenever the runtime goes idle - the
   911  * last active request ceases - and begins activity - when it was
   912  * idle and a request begins.
   913  */
   914 JS_FRIEND_API(void)
   915 SetActivityCallback(JSRuntime *rt, ActivityCallback cb, void *arg);
   917 extern JS_FRIEND_API(const JSStructuredCloneCallbacks *)
   918 GetContextStructuredCloneCallbacks(JSContext *cx);
   920 extern JS_FRIEND_API(bool)
   921 IsContextRunningJS(JSContext *cx);
   923 typedef bool
   924 (* DOMInstanceClassMatchesProto)(JSObject *protoObject, uint32_t protoID, uint32_t depth);
   925 struct JSDOMCallbacks {
   926     DOMInstanceClassMatchesProto instanceClassMatchesProto;
   927 };
   928 typedef struct JSDOMCallbacks DOMCallbacks;
   930 extern JS_FRIEND_API(void)
   931 SetDOMCallbacks(JSRuntime *rt, const DOMCallbacks *callbacks);
   933 extern JS_FRIEND_API(const DOMCallbacks *)
   934 GetDOMCallbacks(JSRuntime *rt);
   936 extern JS_FRIEND_API(JSObject *)
   937 GetTestingFunctions(JSContext *cx);
   939 /*
   940  * Helper to convert FreeOp to JSFreeOp when the definition of FreeOp is not
   941  * available and the compiler does not know that FreeOp inherits from
   942  * JSFreeOp.
   943  */
   944 inline JSFreeOp *
   945 CastToJSFreeOp(FreeOp *fop)
   946 {
   947     return reinterpret_cast<JSFreeOp *>(fop);
   948 }
   950 /* Implemented in jsexn.cpp. */
   952 /*
   953  * Get an error type name from a JSExnType constant.
   954  * Returns nullptr for invalid arguments and JSEXN_INTERNALERR
   955  */
   956 extern JS_FRIEND_API(const jschar*)
   957 GetErrorTypeName(JSRuntime* rt, int16_t exnType);
   959 #ifdef JS_DEBUG
   960 extern JS_FRIEND_API(unsigned)
   961 GetEnterCompartmentDepth(JSContext* cx);
   962 #endif
   964 /* Implemented in jswrapper.cpp. */
   965 typedef enum NukeReferencesToWindow {
   966     NukeWindowReferences,
   967     DontNukeWindowReferences
   968 } NukeReferencesToWindow;
   970 /*
   971  * These filters are designed to be ephemeral stack classes, and thus don't
   972  * do any rooting or holding of their members.
   973  */
   974 struct CompartmentFilter {
   975     virtual bool match(JSCompartment *c) const = 0;
   976 };
   978 struct AllCompartments : public CompartmentFilter {
   979     virtual bool match(JSCompartment *c) const { return true; }
   980 };
   982 struct ContentCompartmentsOnly : public CompartmentFilter {
   983     virtual bool match(JSCompartment *c) const {
   984         return !IsSystemCompartment(c);
   985     }
   986 };
   988 struct ChromeCompartmentsOnly : public CompartmentFilter {
   989     virtual bool match(JSCompartment *c) const {
   990         return IsSystemCompartment(c);
   991     }
   992 };
   994 struct SingleCompartment : public CompartmentFilter {
   995     JSCompartment *ours;
   996     SingleCompartment(JSCompartment *c) : ours(c) {}
   997     virtual bool match(JSCompartment *c) const { return c == ours; }
   998 };
  1000 struct CompartmentsWithPrincipals : public CompartmentFilter {
  1001     JSPrincipals *principals;
  1002     CompartmentsWithPrincipals(JSPrincipals *p) : principals(p) {}
  1003     virtual bool match(JSCompartment *c) const {
  1004         return JS_GetCompartmentPrincipals(c) == principals;
  1006 };
  1008 extern JS_FRIEND_API(bool)
  1009 NukeCrossCompartmentWrappers(JSContext* cx,
  1010                              const CompartmentFilter& sourceFilter,
  1011                              const CompartmentFilter& targetFilter,
  1012                              NukeReferencesToWindow nukeReferencesToWindow);
  1014 /* Specify information about DOMProxy proxies in the DOM, for use by ICs. */
  1016 /*
  1017  * The DOMProxyShadowsCheck function will be called to check if the property for
  1018  * id should be gotten from the prototype, or if there is an own property that
  1019  * shadows it.
  1020  * If DoesntShadow is returned then the slot at listBaseExpandoSlot should
  1021  * either be undefined or point to an expando object that would contain the own
  1022  * property.
  1023  * If DoesntShadowUnique is returned then the slot at listBaseExpandoSlot should
  1024  * contain a private pointer to a ExpandoAndGeneration, which contains a
  1025  * JS::Value that should either be undefined or point to an expando object, and
  1026  * a uint32 value. If that value changes then the IC for getting a property will
  1027  * be invalidated.
  1028  */
  1030 struct ExpandoAndGeneration {
  1031   ExpandoAndGeneration()
  1032     : expando(JS::UndefinedValue()),
  1033       generation(0)
  1034   {}
  1036   void Unlink()
  1038       ++generation;
  1039       expando.setUndefined();
  1042   static size_t offsetOfExpando()
  1044       return offsetof(ExpandoAndGeneration, expando);
  1047   static size_t offsetOfGeneration()
  1049       return offsetof(ExpandoAndGeneration, generation);
  1052   JS::Heap<JS::Value> expando;
  1053   uint32_t generation;
  1054 };
  1056 typedef enum DOMProxyShadowsResult {
  1057   ShadowCheckFailed,
  1058   Shadows,
  1059   DoesntShadow,
  1060   DoesntShadowUnique
  1061 } DOMProxyShadowsResult;
  1062 typedef DOMProxyShadowsResult
  1063 (* DOMProxyShadowsCheck)(JSContext* cx, JS::HandleObject object, JS::HandleId id);
  1064 JS_FRIEND_API(void)
  1065 SetDOMProxyInformation(const void *domProxyHandlerFamily, uint32_t domProxyExpandoSlot,
  1066                        DOMProxyShadowsCheck domProxyShadowsCheck);
  1068 const void *GetDOMProxyHandlerFamily();
  1069 uint32_t GetDOMProxyExpandoSlot();
  1070 DOMProxyShadowsCheck GetDOMProxyShadowsCheck();
  1072 } /* namespace js */
  1074 /* Implemented in jsdate.cpp. */
  1076 /*
  1077  * Detect whether the internal date value is NaN.  (Because failure is
  1078  * out-of-band for js_DateGet*)
  1079  */
  1080 extern JS_FRIEND_API(bool)
  1081 js_DateIsValid(JSObject* obj);
  1083 extern JS_FRIEND_API(double)
  1084 js_DateGetMsecSinceEpoch(JSObject *obj);
  1086 /* Implemented in jscntxt.cpp. */
  1088 /*
  1089  * Report an exception, which is currently realized as a printf-style format
  1090  * string and its arguments.
  1091  */
  1092 typedef enum JSErrNum {
  1093 #define MSG_DEF(name, number, count, exception, format) \
  1094     name = number,
  1095 #include "js.msg"
  1096 #undef MSG_DEF
  1097     JSErr_Limit
  1098 } JSErrNum;
  1100 extern JS_FRIEND_API(const JSErrorFormatString *)
  1101 js_GetErrorMessage(void *userRef, const char *locale, const unsigned errorNumber);
  1103 namespace js {
  1105 // Creates a string of the form |ErrorType: ErrorMessage| for a JSErrorReport,
  1106 // which generally matches the toString() behavior of an ErrorObject.
  1107 extern JS_FRIEND_API(JSString *)
  1108 ErrorReportToString(JSContext *cx, JSErrorReport *reportp);
  1110 } /* namespace js */
  1113 /* Implemented in jsclone.cpp. */
  1115 extern JS_FRIEND_API(uint64_t)
  1116 js_GetSCOffset(JSStructuredCloneWriter* writer);
  1118 /* Typed Array functions, implemented in jstypedarray.cpp */
  1120 namespace js {
  1121 namespace ArrayBufferView {
  1123 enum ViewType {
  1124     TYPE_INT8 = 0,
  1125     TYPE_UINT8,
  1126     TYPE_INT16,
  1127     TYPE_UINT16,
  1128     TYPE_INT32,
  1129     TYPE_UINT32,
  1130     TYPE_FLOAT32,
  1131     TYPE_FLOAT64,
  1133     /*
  1134      * Special type that is a uint8_t, but assignments are clamped to [0, 256).
  1135      * Treat the raw data type as a uint8_t.
  1136      */
  1137     TYPE_UINT8_CLAMPED,
  1139     /*
  1140      * Type returned for a DataView. Note that there is no single element type
  1141      * in this case.
  1142      */
  1143     TYPE_DATAVIEW,
  1145     TYPE_MAX
  1146 };
  1148 } /* namespace ArrayBufferView */
  1150 } /* namespace js */
  1152 typedef js::ArrayBufferView::ViewType JSArrayBufferViewType;
  1154 /*
  1155  * Create a new typed array with nelements elements.
  1157  * These functions (except the WithBuffer variants) fill in the array with zeros.
  1158  */
  1160 extern JS_FRIEND_API(JSObject *)
  1161 JS_NewInt8Array(JSContext *cx, uint32_t nelements);
  1162 extern JS_FRIEND_API(JSObject *)
  1163 JS_NewUint8Array(JSContext *cx, uint32_t nelements);
  1164 extern JS_FRIEND_API(JSObject *)
  1165 JS_NewUint8ClampedArray(JSContext *cx, uint32_t nelements);
  1167 extern JS_FRIEND_API(JSObject *)
  1168 JS_NewInt16Array(JSContext *cx, uint32_t nelements);
  1169 extern JS_FRIEND_API(JSObject *)
  1170 JS_NewUint16Array(JSContext *cx, uint32_t nelements);
  1171 extern JS_FRIEND_API(JSObject *)
  1172 JS_NewInt32Array(JSContext *cx, uint32_t nelements);
  1173 extern JS_FRIEND_API(JSObject *)
  1174 JS_NewUint32Array(JSContext *cx, uint32_t nelements);
  1175 extern JS_FRIEND_API(JSObject *)
  1176 JS_NewFloat32Array(JSContext *cx, uint32_t nelements);
  1177 extern JS_FRIEND_API(JSObject *)
  1178 JS_NewFloat64Array(JSContext *cx, uint32_t nelements);
  1180 /*
  1181  * Create a new typed array and copy in values from the given object. The
  1182  * object is used as if it were an array; that is, the new array (if
  1183  * successfully created) will have length given by array.length, and its
  1184  * elements will be those specified by array[0], array[1], and so on, after
  1185  * conversion to the typed array element type.
  1186  */
  1188 extern JS_FRIEND_API(JSObject *)
  1189 JS_NewInt8ArrayFromArray(JSContext *cx, JS::HandleObject array);
  1190 extern JS_FRIEND_API(JSObject *)
  1191 JS_NewUint8ArrayFromArray(JSContext *cx, JS::HandleObject array);
  1192 extern JS_FRIEND_API(JSObject *)
  1193 JS_NewUint8ClampedArrayFromArray(JSContext *cx, JS::HandleObject array);
  1194 extern JS_FRIEND_API(JSObject *)
  1195 JS_NewInt16ArrayFromArray(JSContext *cx, JS::HandleObject array);
  1196 extern JS_FRIEND_API(JSObject *)
  1197 JS_NewUint16ArrayFromArray(JSContext *cx, JS::HandleObject array);
  1198 extern JS_FRIEND_API(JSObject *)
  1199 JS_NewInt32ArrayFromArray(JSContext *cx, JS::HandleObject array);
  1200 extern JS_FRIEND_API(JSObject *)
  1201 JS_NewUint32ArrayFromArray(JSContext *cx, JS::HandleObject array);
  1202 extern JS_FRIEND_API(JSObject *)
  1203 JS_NewFloat32ArrayFromArray(JSContext *cx, JS::HandleObject array);
  1204 extern JS_FRIEND_API(JSObject *)
  1205 JS_NewFloat64ArrayFromArray(JSContext *cx, JS::HandleObject array);
  1207 /*
  1208  * Create a new typed array using the given ArrayBuffer for storage.  The
  1209  * length value is optional; if -1 is passed, enough elements to use up the
  1210  * remainder of the byte array is used as the default value.
  1211  */
  1213 extern JS_FRIEND_API(JSObject *)
  1214 JS_NewInt8ArrayWithBuffer(JSContext *cx, JS::HandleObject arrayBuffer,
  1215                           uint32_t byteOffset, int32_t length);
  1216 extern JS_FRIEND_API(JSObject *)
  1217 JS_NewUint8ArrayWithBuffer(JSContext *cx, JS::HandleObject arrayBuffer,
  1218                            uint32_t byteOffset, int32_t length);
  1219 extern JS_FRIEND_API(JSObject *)
  1220 JS_NewUint8ClampedArrayWithBuffer(JSContext *cx, JS::HandleObject arrayBuffer,
  1221                                   uint32_t byteOffset, int32_t length);
  1222 extern JS_FRIEND_API(JSObject *)
  1223 JS_NewInt16ArrayWithBuffer(JSContext *cx, JS::HandleObject arrayBuffer,
  1224                            uint32_t byteOffset, int32_t length);
  1225 extern JS_FRIEND_API(JSObject *)
  1226 JS_NewUint16ArrayWithBuffer(JSContext *cx, JS::HandleObject arrayBuffer,
  1227                             uint32_t byteOffset, int32_t length);
  1228 extern JS_FRIEND_API(JSObject *)
  1229 JS_NewInt32ArrayWithBuffer(JSContext *cx, JS::HandleObject arrayBuffer,
  1230                            uint32_t byteOffset, int32_t length);
  1231 extern JS_FRIEND_API(JSObject *)
  1232 JS_NewUint32ArrayWithBuffer(JSContext *cx, JS::HandleObject arrayBuffer,
  1233                             uint32_t byteOffset, int32_t length);
  1234 extern JS_FRIEND_API(JSObject *)
  1235 JS_NewFloat32ArrayWithBuffer(JSContext *cx, JS::HandleObject arrayBuffer,
  1236                              uint32_t byteOffset, int32_t length);
  1237 extern JS_FRIEND_API(JSObject *)
  1238 JS_NewFloat64ArrayWithBuffer(JSContext *cx, JS::HandleObject arrayBuffer,
  1239                              uint32_t byteOffset, int32_t length);
  1241 /*
  1242  * Create a new ArrayBuffer with the given byte length.
  1243  */
  1244 extern JS_FRIEND_API(JSObject *)
  1245 JS_NewArrayBuffer(JSContext *cx, uint32_t nbytes);
  1247 /*
  1248  * Check whether obj supports JS_GetTypedArray* APIs. Note that this may return
  1249  * false if a security wrapper is encountered that denies the unwrapping. If
  1250  * this test or one of the JS_Is*Array tests succeeds, then it is safe to call
  1251  * the various accessor JSAPI calls defined below.
  1252  */
  1253 extern JS_FRIEND_API(bool)
  1254 JS_IsTypedArrayObject(JSObject *obj);
  1256 /*
  1257  * Check whether obj supports JS_GetArrayBufferView* APIs. Note that this may
  1258  * return false if a security wrapper is encountered that denies the
  1259  * unwrapping. If this test or one of the more specific tests succeeds, then it
  1260  * is safe to call the various ArrayBufferView accessor JSAPI calls defined
  1261  * below.
  1262  */
  1263 extern JS_FRIEND_API(bool)
  1264 JS_IsArrayBufferViewObject(JSObject *obj);
  1266 /*
  1267  * Test for specific typed array types (ArrayBufferView subtypes)
  1268  */
  1270 extern JS_FRIEND_API(bool)
  1271 JS_IsInt8Array(JSObject *obj);
  1272 extern JS_FRIEND_API(bool)
  1273 JS_IsUint8Array(JSObject *obj);
  1274 extern JS_FRIEND_API(bool)
  1275 JS_IsUint8ClampedArray(JSObject *obj);
  1276 extern JS_FRIEND_API(bool)
  1277 JS_IsInt16Array(JSObject *obj);
  1278 extern JS_FRIEND_API(bool)
  1279 JS_IsUint16Array(JSObject *obj);
  1280 extern JS_FRIEND_API(bool)
  1281 JS_IsInt32Array(JSObject *obj);
  1282 extern JS_FRIEND_API(bool)
  1283 JS_IsUint32Array(JSObject *obj);
  1284 extern JS_FRIEND_API(bool)
  1285 JS_IsFloat32Array(JSObject *obj);
  1286 extern JS_FRIEND_API(bool)
  1287 JS_IsFloat64Array(JSObject *obj);
  1289 /*
  1290  * Test for specific typed array types (ArrayBufferView subtypes) and return
  1291  * the unwrapped object if so, else nullptr.  Never throws.
  1292  */
  1294 namespace js {
  1296 extern JS_FRIEND_API(JSObject *)
  1297 UnwrapInt8Array(JSObject *obj);
  1298 extern JS_FRIEND_API(JSObject *)
  1299 UnwrapUint8Array(JSObject *obj);
  1300 extern JS_FRIEND_API(JSObject *)
  1301 UnwrapUint8ClampedArray(JSObject *obj);
  1302 extern JS_FRIEND_API(JSObject *)
  1303 UnwrapInt16Array(JSObject *obj);
  1304 extern JS_FRIEND_API(JSObject *)
  1305 UnwrapUint16Array(JSObject *obj);
  1306 extern JS_FRIEND_API(JSObject *)
  1307 UnwrapInt32Array(JSObject *obj);
  1308 extern JS_FRIEND_API(JSObject *)
  1309 UnwrapUint32Array(JSObject *obj);
  1310 extern JS_FRIEND_API(JSObject *)
  1311 UnwrapFloat32Array(JSObject *obj);
  1312 extern JS_FRIEND_API(JSObject *)
  1313 UnwrapFloat64Array(JSObject *obj);
  1315 extern JS_FRIEND_API(JSObject *)
  1316 UnwrapArrayBuffer(JSObject *obj);
  1318 extern JS_FRIEND_API(JSObject *)
  1319 UnwrapArrayBufferView(JSObject *obj);
  1321 namespace detail {
  1323 extern JS_FRIEND_DATA(const Class* const) Int8ArrayClassPtr;
  1324 extern JS_FRIEND_DATA(const Class* const) Uint8ArrayClassPtr;
  1325 extern JS_FRIEND_DATA(const Class* const) Uint8ClampedArrayClassPtr;
  1326 extern JS_FRIEND_DATA(const Class* const) Int16ArrayClassPtr;
  1327 extern JS_FRIEND_DATA(const Class* const) Uint16ArrayClassPtr;
  1328 extern JS_FRIEND_DATA(const Class* const) Int32ArrayClassPtr;
  1329 extern JS_FRIEND_DATA(const Class* const) Uint32ArrayClassPtr;
  1330 extern JS_FRIEND_DATA(const Class* const) Float32ArrayClassPtr;
  1331 extern JS_FRIEND_DATA(const Class* const) Float64ArrayClassPtr;
  1333 const size_t TypedArrayLengthSlot = 4;
  1335 } // namespace detail
  1337 /*
  1338  * Test for specific typed array types (ArrayBufferView subtypes) and return
  1339  * the unwrapped object if so, else nullptr.  Never throws.
  1340  */
  1342 #define JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Type, type) \
  1343 inline void \
  1344 Get ## Type ## ArrayLengthAndData(JSObject *obj, uint32_t *length, type **data) \
  1345 { \
  1346     JS_ASSERT(GetObjectClass(obj) == detail::Type ## ArrayClassPtr); \
  1347     const JS::Value &slot = GetReservedSlot(obj, detail::TypedArrayLengthSlot); \
  1348     *length = mozilla::SafeCast<uint32_t>(slot.toInt32()); \
  1349     *data = static_cast<type*>(GetObjectPrivate(obj)); \
  1352 JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Int8, int8_t)
  1353 JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Uint8, uint8_t)
  1354 JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Uint8Clamped, uint8_t)
  1355 JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Int16, int16_t)
  1356 JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Uint16, uint16_t)
  1357 JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Int32, int32_t)
  1358 JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Uint32, uint32_t)
  1359 JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Float32, float)
  1360 JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Float64, double)
  1362 #undef JS_DEFINE_DATA_AND_LENGTH_ACCESSOR
  1364 // This one isn't inlined because it's rather tricky (by dint of having to deal
  1365 // with a dozen-plus classes and varying slot layouts.
  1366 extern JS_FRIEND_API(void)
  1367 GetArrayBufferViewLengthAndData(JSObject *obj, uint32_t *length, uint8_t **data);
  1369 // This one isn't inlined because there are a bunch of different ArrayBuffer
  1370 // classes that would have to be individually handled here.
  1371 extern JS_FRIEND_API(void)
  1372 GetArrayBufferLengthAndData(JSObject *obj, uint32_t *length, uint8_t **data);
  1374 } // namespace js
  1376 /*
  1377  * Unwrap Typed arrays all at once. Return nullptr without throwing if the
  1378  * object cannot be viewed as the correct typed array, or the typed array
  1379  * object on success, filling both outparameters.
  1380  */
  1381 extern JS_FRIEND_API(JSObject *)
  1382 JS_GetObjectAsInt8Array(JSObject *obj, uint32_t *length, int8_t **data);
  1383 extern JS_FRIEND_API(JSObject *)
  1384 JS_GetObjectAsUint8Array(JSObject *obj, uint32_t *length, uint8_t **data);
  1385 extern JS_FRIEND_API(JSObject *)
  1386 JS_GetObjectAsUint8ClampedArray(JSObject *obj, uint32_t *length, uint8_t **data);
  1387 extern JS_FRIEND_API(JSObject *)
  1388 JS_GetObjectAsInt16Array(JSObject *obj, uint32_t *length, int16_t **data);
  1389 extern JS_FRIEND_API(JSObject *)
  1390 JS_GetObjectAsUint16Array(JSObject *obj, uint32_t *length, uint16_t **data);
  1391 extern JS_FRIEND_API(JSObject *)
  1392 JS_GetObjectAsInt32Array(JSObject *obj, uint32_t *length, int32_t **data);
  1393 extern JS_FRIEND_API(JSObject *)
  1394 JS_GetObjectAsUint32Array(JSObject *obj, uint32_t *length, uint32_t **data);
  1395 extern JS_FRIEND_API(JSObject *)
  1396 JS_GetObjectAsFloat32Array(JSObject *obj, uint32_t *length, float **data);
  1397 extern JS_FRIEND_API(JSObject *)
  1398 JS_GetObjectAsFloat64Array(JSObject *obj, uint32_t *length, double **data);
  1399 extern JS_FRIEND_API(JSObject *)
  1400 JS_GetObjectAsArrayBufferView(JSObject *obj, uint32_t *length, uint8_t **data);
  1401 extern JS_FRIEND_API(JSObject *)
  1402 JS_GetObjectAsArrayBuffer(JSObject *obj, uint32_t *length, uint8_t **data);
  1404 /*
  1405  * Get the type of elements in a typed array, or TYPE_DATAVIEW if a DataView.
  1407  * |obj| must have passed a JS_IsArrayBufferView/JS_Is*Array test, or somehow
  1408  * be known that it would pass such a test: it is an ArrayBufferView or a
  1409  * wrapper of an ArrayBufferView, and the unwrapping will succeed.
  1410  */
  1411 extern JS_FRIEND_API(JSArrayBufferViewType)
  1412 JS_GetArrayBufferViewType(JSObject *obj);
  1414 /*
  1415  * Check whether obj supports the JS_GetArrayBuffer* APIs. Note that this may
  1416  * return false if a security wrapper is encountered that denies the
  1417  * unwrapping. If this test succeeds, then it is safe to call the various
  1418  * accessor JSAPI calls defined below.
  1419  */
  1420 extern JS_FRIEND_API(bool)
  1421 JS_IsArrayBufferObject(JSObject *obj);
  1423 /*
  1424  * Return the available byte length of an array buffer.
  1426  * |obj| must have passed a JS_IsArrayBufferObject test, or somehow be known
  1427  * that it would pass such a test: it is an ArrayBuffer or a wrapper of an
  1428  * ArrayBuffer, and the unwrapping will succeed.
  1429  */
  1430 extern JS_FRIEND_API(uint32_t)
  1431 JS_GetArrayBufferByteLength(JSObject *obj);
  1433 /*
  1434  * Check whether the obj is ArrayBufferObject and memory mapped. Note that this
  1435  * may return false if a security wrapper is encountered that denies the
  1436  * unwrapping.
  1437  */
  1438 extern JS_FRIEND_API(bool)
  1439 JS_IsMappedArrayBufferObject(JSObject *obj);
  1441 /*
  1442  * Return the number of elements in a typed array.
  1444  * |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow
  1445  * be known that it would pass such a test: it is a typed array or a wrapper of
  1446  * a typed array, and the unwrapping will succeed.
  1447  */
  1448 extern JS_FRIEND_API(uint32_t)
  1449 JS_GetTypedArrayLength(JSObject *obj);
  1451 /*
  1452  * Return the byte offset from the start of an array buffer to the start of a
  1453  * typed array view.
  1455  * |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow
  1456  * be known that it would pass such a test: it is a typed array or a wrapper of
  1457  * a typed array, and the unwrapping will succeed.
  1458  */
  1459 extern JS_FRIEND_API(uint32_t)
  1460 JS_GetTypedArrayByteOffset(JSObject *obj);
  1462 /*
  1463  * Return the byte length of a typed array.
  1465  * |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow
  1466  * be known that it would pass such a test: it is a typed array or a wrapper of
  1467  * a typed array, and the unwrapping will succeed.
  1468  */
  1469 extern JS_FRIEND_API(uint32_t)
  1470 JS_GetTypedArrayByteLength(JSObject *obj);
  1472 /*
  1473  * Check whether obj supports JS_ArrayBufferView* APIs. Note that this may
  1474  * return false if a security wrapper is encountered that denies the
  1475  * unwrapping.
  1476  */
  1477 extern JS_FRIEND_API(bool)
  1478 JS_IsArrayBufferViewObject(JSObject *obj);
  1480 /*
  1481  * More generic name for JS_GetTypedArrayByteLength to cover DataViews as well
  1482  */
  1483 extern JS_FRIEND_API(uint32_t)
  1484 JS_GetArrayBufferViewByteLength(JSObject *obj);
  1486 /*
  1487  * Return a pointer to the start of the data referenced by a typed array. The
  1488  * data is still owned by the typed array, and should not be modified on
  1489  * another thread. Furthermore, the pointer can become invalid on GC (if the
  1490  * data is small and fits inside the array's GC header), so callers must take
  1491  * care not to hold on across anything that could GC.
  1493  * |obj| must have passed a JS_Is*Array test, or somehow be known that it would
  1494  * pass such a test: it is a typed array or a wrapper of a typed array, and the
  1495  * unwrapping will succeed.
  1496  */
  1498 extern JS_FRIEND_API(uint8_t *)
  1499 JS_GetArrayBufferData(JSObject *obj);
  1500 extern JS_FRIEND_API(int8_t *)
  1501 JS_GetInt8ArrayData(JSObject *obj);
  1502 extern JS_FRIEND_API(uint8_t *)
  1503 JS_GetUint8ArrayData(JSObject *obj);
  1504 extern JS_FRIEND_API(uint8_t *)
  1505 JS_GetUint8ClampedArrayData(JSObject *obj);
  1506 extern JS_FRIEND_API(int16_t *)
  1507 JS_GetInt16ArrayData(JSObject *obj);
  1508 extern JS_FRIEND_API(uint16_t *)
  1509 JS_GetUint16ArrayData(JSObject *obj);
  1510 extern JS_FRIEND_API(int32_t *)
  1511 JS_GetInt32ArrayData(JSObject *obj);
  1512 extern JS_FRIEND_API(uint32_t *)
  1513 JS_GetUint32ArrayData(JSObject *obj);
  1514 extern JS_FRIEND_API(float *)
  1515 JS_GetFloat32ArrayData(JSObject *obj);
  1516 extern JS_FRIEND_API(double *)
  1517 JS_GetFloat64ArrayData(JSObject *obj);
  1519 /*
  1520  * Stable versions of the above functions where the buffer remains valid as long
  1521  * as the object is live.
  1522  */
  1523 extern JS_FRIEND_API(uint8_t *)
  1524 JS_GetStableArrayBufferData(JSContext *cx, JS::HandleObject obj);
  1526 /*
  1527  * Same as above, but for any kind of ArrayBufferView. Prefer the type-specific
  1528  * versions when possible.
  1529  */
  1530 extern JS_FRIEND_API(void *)
  1531 JS_GetArrayBufferViewData(JSObject *obj);
  1533 /*
  1534  * Return the ArrayBuffer underlying an ArrayBufferView. If the buffer has been
  1535  * neutered, this will still return the neutered buffer. |obj| must be an
  1536  * object that would return true for JS_IsArrayBufferViewObject().
  1537  */
  1538 extern JS_FRIEND_API(JSObject *)
  1539 JS_GetArrayBufferViewBuffer(JSContext *cx, JSObject *obj);
  1541 typedef enum {
  1542     ChangeData,
  1543     KeepData
  1544 } NeuterDataDisposition;
  1546 /*
  1547  * Set an ArrayBuffer's length to 0 and neuter all of its views.
  1549  * The |changeData| argument is a hint to inform internal behavior with respect
  1550  * to the internal pointer to the ArrayBuffer's data after being neutered.
  1551  * There is no guarantee it will be respected.  But if it is respected, the
  1552  * ArrayBuffer's internal data pointer will, or will not, have changed
  1553  * accordingly.
  1554  */
  1555 extern JS_FRIEND_API(bool)
  1556 JS_NeuterArrayBuffer(JSContext *cx, JS::HandleObject obj,
  1557                      NeuterDataDisposition changeData);
  1559 /*
  1560  * Check whether obj supports JS_GetDataView* APIs.
  1561  */
  1562 JS_FRIEND_API(bool)
  1563 JS_IsDataViewObject(JSObject *obj);
  1565 /*
  1566  * Return the byte offset of a data view into its array buffer. |obj| must be a
  1567  * DataView.
  1569  * |obj| must have passed a JS_IsDataViewObject test, or somehow be known that
  1570  * it would pass such a test: it is a data view or a wrapper of a data view,
  1571  * and the unwrapping will succeed.
  1572  */
  1573 JS_FRIEND_API(uint32_t)
  1574 JS_GetDataViewByteOffset(JSObject *obj);
  1576 /*
  1577  * Return the byte length of a data view.
  1579  * |obj| must have passed a JS_IsDataViewObject test, or somehow be known that
  1580  * it would pass such a test: it is a data view or a wrapper of a data view,
  1581  * and the unwrapping will succeed. If cx is nullptr, then DEBUG builds may be
  1582  * unable to assert when unwrapping should be disallowed.
  1583  */
  1584 JS_FRIEND_API(uint32_t)
  1585 JS_GetDataViewByteLength(JSObject *obj);
  1587 /*
  1588  * Return a pointer to the beginning of the data referenced by a DataView.
  1590  * |obj| must have passed a JS_IsDataViewObject test, or somehow be known that
  1591  * it would pass such a test: it is a data view or a wrapper of a data view,
  1592  * and the unwrapping will succeed. If cx is nullptr, then DEBUG builds may be
  1593  * unable to assert when unwrapping should be disallowed.
  1594  */
  1595 JS_FRIEND_API(void *)
  1596 JS_GetDataViewData(JSObject *obj);
  1598 namespace js {
  1600 /*
  1601  * Add a watchpoint -- in the Object.prototype.watch sense -- to |obj| for the
  1602  * property |id|, using the callable object |callable| as the function to be
  1603  * called for notifications.
  1605  * This is an internal function exposed -- temporarily -- only so that DOM
  1606  * proxies can be watchable.  Don't use it!  We'll soon kill off the
  1607  * Object.prototype.{,un}watch functions, at which point this will go too.
  1608  */
  1609 extern JS_FRIEND_API(bool)
  1610 WatchGuts(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject callable);
  1612 /*
  1613  * Remove a watchpoint -- in the Object.prototype.watch sense -- from |obj| for
  1614  * the property |id|.
  1616  * This is an internal function exposed -- temporarily -- only so that DOM
  1617  * proxies can be watchable.  Don't use it!  We'll soon kill off the
  1618  * Object.prototype.{,un}watch functions, at which point this will go too.
  1619  */
  1620 extern JS_FRIEND_API(bool)
  1621 UnwatchGuts(JSContext *cx, JS::HandleObject obj, JS::HandleId id);
  1623 } // namespace js
  1625 /*
  1626  * A class, expected to be passed by value, which represents the CallArgs for a
  1627  * JSJitGetterOp.
  1628  */
  1629 class JSJitGetterCallArgs : protected JS::MutableHandleValue
  1631   public:
  1632     explicit JSJitGetterCallArgs(const JS::CallArgs& args)
  1633       : JS::MutableHandleValue(args.rval())
  1634     {}
  1636     explicit JSJitGetterCallArgs(JS::RootedValue* rooted)
  1637       : JS::MutableHandleValue(rooted)
  1638     {}
  1640     JS::MutableHandleValue rval() {
  1641         return *this;
  1643 };
  1645 /*
  1646  * A class, expected to be passed by value, which represents the CallArgs for a
  1647  * JSJitSetterOp.
  1648  */
  1649 class JSJitSetterCallArgs : protected JS::MutableHandleValue
  1651   public:
  1652     explicit JSJitSetterCallArgs(const JS::CallArgs& args)
  1653       : JS::MutableHandleValue(args[0])
  1654     {}
  1656     JS::MutableHandleValue operator[](unsigned i) {
  1657         MOZ_ASSERT(i == 0);
  1658         return *this;
  1661     unsigned length() const { return 1; }
  1663     // Add get() or maybe hasDefined() as needed
  1664 };
  1666 struct JSJitMethodCallArgsTraits;
  1668 /*
  1669  * A class, expected to be passed by reference, which represents the CallArgs
  1670  * for a JSJitMethodOp.
  1671  */
  1672 class JSJitMethodCallArgs : protected JS::detail::CallArgsBase<JS::detail::NoUsedRval>
  1674   private:
  1675     typedef JS::detail::CallArgsBase<JS::detail::NoUsedRval> Base;
  1676     friend struct JSJitMethodCallArgsTraits;
  1678   public:
  1679     explicit JSJitMethodCallArgs(const JS::CallArgs& args) {
  1680         argv_ = args.array();
  1681         argc_ = args.length();
  1684     JS::MutableHandleValue rval() const {
  1685         return Base::rval();
  1688     unsigned length() const { return Base::length(); }
  1690     JS::MutableHandleValue operator[](unsigned i) const {
  1691         return Base::operator[](i);
  1694     bool hasDefined(unsigned i) const {
  1695         return Base::hasDefined(i);
  1698     JSObject &callee() const {
  1699         // We can't use Base::callee() because that will try to poke at
  1700         // this->usedRval_, which we don't have.
  1701         return argv_[-2].toObject();
  1704     // Add get() as needed
  1705 };
  1707 struct JSJitMethodCallArgsTraits
  1709     static const size_t offsetOfArgv = offsetof(JSJitMethodCallArgs, argv_);
  1710     static const size_t offsetOfArgc = offsetof(JSJitMethodCallArgs, argc_);
  1711 };
  1713 /*
  1714  * This struct contains metadata passed from the DOM to the JS Engine for JIT
  1715  * optimizations on DOM property accessors. Eventually, this should be made
  1716  * available to general JSAPI users, but we are not currently ready to do so.
  1717  */
  1718 typedef bool
  1719 (* JSJitGetterOp)(JSContext *cx, JS::HandleObject thisObj,
  1720                   void *specializedThis, JSJitGetterCallArgs args);
  1721 typedef bool
  1722 (* JSJitSetterOp)(JSContext *cx, JS::HandleObject thisObj,
  1723                   void *specializedThis, JSJitSetterCallArgs args);
  1724 typedef bool
  1725 (* JSJitMethodOp)(JSContext *cx, JS::HandleObject thisObj,
  1726                   void *specializedThis, const JSJitMethodCallArgs& args);
  1728 struct JSJitInfo {
  1729     enum OpType {
  1730         Getter,
  1731         Setter,
  1732         Method,
  1733         ParallelNative,
  1734         StaticMethod,
  1735         // Must be last
  1736         OpTypeCount
  1737     };
  1739     enum ArgType {
  1740         // Basic types
  1741         String = (1 << 0),
  1742         Integer = (1 << 1), // Only 32-bit or less
  1743         Double = (1 << 2), // Maybe we want to add Float sometime too
  1744         Boolean = (1 << 3),
  1745         Object = (1 << 4),
  1746         Null = (1 << 5),
  1748         // And derived types
  1749         Numeric = Integer | Double,
  1750         // Should "Primitive" use the WebIDL definition, which
  1751         // excludes string and null, or the typical JS one that includes them?
  1752         Primitive = Numeric | Boolean | Null | String,
  1753         ObjectOrNull = Object | Null,
  1754         Any = ObjectOrNull | Primitive,
  1756         // Our sentinel value.
  1757         ArgTypeListEnd = (1 << 31)
  1758     };
  1760     static_assert(Any & String, "Any must include String.");
  1761     static_assert(Any & Integer, "Any must include Integer.");
  1762     static_assert(Any & Double, "Any must include Double.");
  1763     static_assert(Any & Boolean, "Any must include Boolean.");
  1764     static_assert(Any & Object, "Any must include Object.");
  1765     static_assert(Any & Null, "Any must include Null.");
  1767     enum AliasSet {
  1768         // An enum that describes what this getter/setter/method aliases.  This
  1769         // determines what things can be hoisted past this call, and if this
  1770         // call is movable what it can be hoisted past.
  1772         // Alias nothing: a constant value, getting it can't affect any other
  1773         // values, nothing can affect it.
  1774         AliasNone,
  1776         // Alias things that can modify the DOM but nothing else.  Doing the
  1777         // call can't affect the behavior of any other function.
  1778         AliasDOMSets,
  1780         // Alias the world.  Calling this can change arbitrary values anywhere
  1781         // in the system.  Most things fall in this bucket.
  1782         AliasEverything,
  1784         // Must be last.
  1785         AliasSetCount
  1786     };
  1788     bool hasParallelNative() const
  1790         return type() == ParallelNative;
  1793     bool needsOuterizedThisObject() const
  1795         return type() != Getter && type() != Setter;
  1798     bool isTypedMethodJitInfo() const
  1800         return isTypedMethod;
  1803     OpType type() const
  1805         return OpType(type_);
  1808     AliasSet aliasSet() const
  1810         return AliasSet(aliasSet_);
  1813     JSValueType returnType() const
  1815         return JSValueType(returnType_);
  1818     union {
  1819         JSJitGetterOp getter;
  1820         JSJitSetterOp setter;
  1821         JSJitMethodOp method;
  1822         /* An alternative native that's safe to call in parallel mode. */
  1823         JSParallelNative parallelNative;
  1824         /* A DOM static method, used for Promise wrappers */
  1825         JSNative staticMethod;
  1826     };
  1828     uint16_t protoID;
  1829     uint16_t depth;
  1831     // These fields are carefully packed to take up 4 bytes.  If you need more
  1832     // bits for whatever reason, please see if you can steal bits from existing
  1833     // fields before adding more members to this structure.
  1835 #define JITINFO_OP_TYPE_BITS 4
  1836 #define JITINFO_ALIAS_SET_BITS 4
  1837 #define JITINFO_RETURN_TYPE_BITS 8
  1839     // The OpType that says what sort of function we are.
  1840     uint32_t type_ : JITINFO_OP_TYPE_BITS;
  1842     // The alias set for this op.  This is a _minimal_ alias set; in
  1843     // particular for a method it does not include whatever argument
  1844     // conversions might do.  That's covered by argTypes and runtime
  1845     // analysis of the actual argument types being passed in.
  1846     uint32_t aliasSet_ : JITINFO_ALIAS_SET_BITS;
  1848     // The return type tag.  Might be JSVAL_TYPE_UNKNOWN.
  1849     uint32_t returnType_ : JITINFO_RETURN_TYPE_BITS;
  1851     static_assert(OpTypeCount <= (1 << JITINFO_OP_TYPE_BITS),
  1852                   "Not enough space for OpType");
  1853     static_assert(AliasSetCount <= (1 << JITINFO_ALIAS_SET_BITS),
  1854                   "Not enough space for AliasSet");
  1855     static_assert((sizeof(JSValueType) * 8) <= JITINFO_RETURN_TYPE_BITS,
  1856                   "Not enough space for JSValueType");
  1858 #undef JITINFO_RETURN_TYPE_BITS
  1859 #undef JITINFO_ALIAS_SET_BITS
  1860 #undef JITINFO_OP_TYPE_BITS
  1862     uint32_t isInfallible : 1; /* Is op fallible? False in setters. */
  1863     uint32_t isMovable : 1;    /* Is op movable?  To be movable the op must
  1864                                   not AliasEverything, but even that might
  1865                                   not be enough (e.g. in cases when it can
  1866                                   throw). */
  1867     // XXXbz should we have a JSValueType for the type of the member?
  1868     uint32_t isInSlot : 1;     /* True if this is a getter that can get a member
  1869                                   from a slot of the "this" object directly. */
  1870     uint32_t isTypedMethod : 1; /* True if this is an instance of
  1871                                    JSTypedMethodJitInfo. */
  1872     uint32_t slotIndex : 12;   /* If isInSlot is true, the index of the slot to
  1873                                   get the value from.  Otherwise 0. */
  1874 };
  1876 static_assert(sizeof(JSJitInfo) == (sizeof(void*) + 2 * sizeof(uint32_t)),
  1877               "There are several thousand instances of JSJitInfo stored in "
  1878               "a binary. Please don't increase its space requirements without "
  1879               "verifying that there is no other way forward (better packing, "
  1880               "smaller datatypes for fields, subclassing, etc.).");
  1882 struct JSTypedMethodJitInfo
  1884     // We use C-style inheritance here, rather than C++ style inheritance
  1885     // because not all compilers support brace-initialization for non-aggregate
  1886     // classes. Using C++ style inheritance and constructors instead of
  1887     // brace-initialization would also force the creation of static
  1888     // constructors (on some compilers) when JSJitInfo and JSTypedMethodJitInfo
  1889     // structures are declared. Since there can be several thousand of these
  1890     // structures present and we want to have roughly equivalent performance
  1891     // across a range of compilers, we do things manually.
  1892     JSJitInfo base;
  1894     const JSJitInfo::ArgType* const argTypes; /* For a method, a list of sets of
  1895                                                  types that the function
  1896                                                  expects.  This can be used,
  1897                                                  for example, to figure out
  1898                                                  when argument coercions can
  1899                                                  have side-effects. */
  1900 };
  1902 namespace JS {
  1903 namespace detail {
  1905 /* NEVER DEFINED, DON'T USE.  For use by JS_CAST_PARALLEL_NATIVE_TO only. */
  1906 inline int CheckIsParallelNative(JSParallelNative parallelNative);
  1908 } // namespace detail
  1909 } // namespace JS
  1911 #define JS_CAST_PARALLEL_NATIVE_TO(v, To) \
  1912     (static_cast<void>(sizeof(JS::detail::CheckIsParallelNative(v))), \
  1913      reinterpret_cast<To>(v))
  1915 /*
  1916  * You may ask yourself: why do we define a wrapper around a wrapper here?
  1917  * The answer is that some compilers don't understand initializing a union
  1918  * as we do below with a construct like:
  1920  * reinterpret_cast<JSJitGetterOp>(JSParallelNativeThreadSafeWrapper<op>)
  1922  * (We need the reinterpret_cast because we must initialize the union with
  1923  * a datum of the type of the union's first member.)
  1925  * Presumably this has something to do with template instantiation.
  1926  * Initializing with a normal function pointer seems to work fine. Hence
  1927  * the ugliness that you see before you.
  1928  */
  1929 #define JS_JITINFO_NATIVE_PARALLEL(infoName, parallelOp)                \
  1930     const JSJitInfo infoName =                                          \
  1931         {{JS_CAST_PARALLEL_NATIVE_TO(parallelOp, JSJitGetterOp)},0,0,JSJitInfo::ParallelNative,JSJitInfo::AliasEverything,JSVAL_TYPE_MISSING,false,false,false,false,0}
  1933 #define JS_JITINFO_NATIVE_PARALLEL_THREADSAFE(infoName, wrapperName, serialOp) \
  1934     bool wrapperName##_ParallelNativeThreadSafeWrapper(js::ForkJoinContext *cx, unsigned argc, \
  1935                                                        JS::Value *vp)   \
  1936     {                                                                   \
  1937         return JSParallelNativeThreadSafeWrapper<serialOp>(cx, argc, vp); \
  1938     }                                                                   \
  1939     JS_JITINFO_NATIVE_PARALLEL(infoName, wrapperName##_ParallelNativeThreadSafeWrapper)
  1941 static MOZ_ALWAYS_INLINE const JSJitInfo *
  1942 FUNCTION_VALUE_TO_JITINFO(const JS::Value& v)
  1944     JS_ASSERT(js::GetObjectClass(&v.toObject()) == js::FunctionClassPtr);
  1945     return reinterpret_cast<js::shadow::Function *>(&v.toObject())->jitinfo;
  1948 /* Statically asserted in jsfun.h. */
  1949 static const unsigned JS_FUNCTION_INTERPRETED_BIT = 0x1;
  1951 static MOZ_ALWAYS_INLINE void
  1952 SET_JITINFO(JSFunction * func, const JSJitInfo *info)
  1954     js::shadow::Function *fun = reinterpret_cast<js::shadow::Function *>(func);
  1955     JS_ASSERT(!(fun->flags & JS_FUNCTION_INTERPRETED_BIT));
  1956     fun->jitinfo = info;
  1959 /*
  1960  * Engine-internal extensions of jsid.  This code is here only until we
  1961  * eliminate Gecko's dependencies on it!
  1962  */
  1964 static MOZ_ALWAYS_INLINE jsid
  1965 JSID_FROM_BITS(size_t bits)
  1967     jsid id;
  1968     JSID_BITS(id) = bits;
  1969     return id;
  1972 namespace js {
  1973 namespace detail {
  1974 bool IdMatchesAtom(jsid id, JSAtom *atom);
  1978 /*
  1979  * Must not be used on atoms that are representable as integer jsids.
  1980  * Prefer NameToId or AtomToId over this function:
  1982  * A PropertyName is an atom that does not contain an integer in the range
  1983  * [0, UINT32_MAX]. However, jsid can only hold an integer in the range
  1984  * [0, JSID_INT_MAX] (where JSID_INT_MAX == 2^31-1).  Thus, for the range of
  1985  * integers (JSID_INT_MAX, UINT32_MAX], to represent as a jsid 'id', it must be
  1986  * the case JSID_IS_ATOM(id) and !JSID_TO_ATOM(id)->isPropertyName().  In most
  1987  * cases when creating a jsid, code does not have to care about this corner
  1988  * case because:
  1990  * - When given an arbitrary JSAtom*, AtomToId must be used, which checks for
  1991  *   integer atoms representable as integer jsids, and does this conversion.
  1993  * - When given a PropertyName*, NameToId can be used which which does not need
  1994  *   to do any dynamic checks.
  1996  * Thus, it is only the rare third case which needs this function, which
  1997  * handles any JSAtom* that is known not to be representable with an int jsid.
  1998  */
  1999 static MOZ_ALWAYS_INLINE jsid
  2000 NON_INTEGER_ATOM_TO_JSID(JSAtom *atom)
  2002     JS_ASSERT(((size_t)atom & 0x7) == 0);
  2003     jsid id = JSID_FROM_BITS((size_t)atom);
  2004     JS_ASSERT(js::detail::IdMatchesAtom(id, atom));
  2005     return id;
  2008 /* All strings stored in jsids are atomized, but are not necessarily property names. */
  2009 static MOZ_ALWAYS_INLINE bool
  2010 JSID_IS_ATOM(jsid id)
  2012     return JSID_IS_STRING(id);
  2015 static MOZ_ALWAYS_INLINE bool
  2016 JSID_IS_ATOM(jsid id, JSAtom *atom)
  2018     return id == JSID_FROM_BITS((size_t)atom);
  2021 static MOZ_ALWAYS_INLINE JSAtom *
  2022 JSID_TO_ATOM(jsid id)
  2024     return (JSAtom *)JSID_TO_STRING(id);
  2027 JS_STATIC_ASSERT(sizeof(jsid) == sizeof(void*));
  2029 namespace js {
  2031 static MOZ_ALWAYS_INLINE JS::Value
  2032 IdToValue(jsid id)
  2034     if (JSID_IS_STRING(id))
  2035         return JS::StringValue(JSID_TO_STRING(id));
  2036     if (MOZ_LIKELY(JSID_IS_INT(id)))
  2037         return JS::Int32Value(JSID_TO_INT(id));
  2038     if (MOZ_LIKELY(JSID_IS_OBJECT(id)))
  2039         return JS::ObjectValue(*JSID_TO_OBJECT(id));
  2040     JS_ASSERT(JSID_IS_VOID(id));
  2041     return JS::UndefinedValue();
  2044 extern JS_FRIEND_API(bool)
  2045 IsTypedArrayThisCheck(JS::IsAcceptableThis test);
  2047 /*
  2048  * If the embedder has registered a default JSContext callback, returns the
  2049  * result of the callback. Otherwise, asserts that |rt| has exactly one
  2050  * JSContext associated with it, and returns that context.
  2051  */
  2052 extern JS_FRIEND_API(JSContext *)
  2053 DefaultJSContext(JSRuntime *rt);
  2055 typedef JSContext*
  2056 (* DefaultJSContextCallback)(JSRuntime *rt);
  2058 JS_FRIEND_API(void)
  2059 SetDefaultJSContextCallback(JSRuntime *rt, DefaultJSContextCallback cb);
  2061 /*
  2062  * To help embedders enforce their invariants, we allow them to specify in
  2063  * advance which JSContext should be passed to JSAPI calls. If this is set
  2064  * to a non-null value, the assertSameCompartment machinery does double-
  2065  * duty (in debug builds) to verify that it matches the cx being used.
  2066  */
  2067 #ifdef DEBUG
  2068 JS_FRIEND_API(void)
  2069 Debug_SetActiveJSContext(JSRuntime *rt, JSContext *cx);
  2070 #else
  2071 inline void
  2072 Debug_SetActiveJSContext(JSRuntime *rt, JSContext *cx) {};
  2073 #endif
  2076 enum CTypesActivityType {
  2077     CTYPES_CALL_BEGIN,
  2078     CTYPES_CALL_END,
  2079     CTYPES_CALLBACK_BEGIN,
  2080     CTYPES_CALLBACK_END
  2081 };
  2083 typedef void
  2084 (* CTypesActivityCallback)(JSContext *cx, CTypesActivityType type);
  2086 /*
  2087  * Sets a callback that is run whenever js-ctypes is about to be used when
  2088  * calling into C.
  2089  */
  2090 JS_FRIEND_API(void)
  2091 SetCTypesActivityCallback(JSRuntime *rt, CTypesActivityCallback cb);
  2093 class JS_FRIEND_API(AutoCTypesActivityCallback) {
  2094   private:
  2095     JSContext *cx;
  2096     CTypesActivityCallback callback;
  2097     CTypesActivityType endType;
  2098     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
  2100   public:
  2101     AutoCTypesActivityCallback(JSContext *cx, CTypesActivityType beginType,
  2102                                CTypesActivityType endType
  2103                                MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
  2104     ~AutoCTypesActivityCallback() {
  2105         DoEndCallback();
  2107     void DoEndCallback() {
  2108         if (callback) {
  2109             callback(cx, endType);
  2110             callback = nullptr;
  2113 };
  2115 typedef bool
  2116 (* ObjectMetadataCallback)(JSContext *cx, JSObject **pmetadata);
  2118 /*
  2119  * Specify a callback to invoke when creating each JS object in the current
  2120  * compartment, which may return a metadata object to associate with the
  2121  * object. Objects with different metadata have different shape hierarchies,
  2122  * so for efficiency, objects should generally try to share metadata objects.
  2123  */
  2124 JS_FRIEND_API(void)
  2125 SetObjectMetadataCallback(JSContext *cx, ObjectMetadataCallback callback);
  2127 /* Manipulate the metadata associated with an object. */
  2129 JS_FRIEND_API(bool)
  2130 SetObjectMetadata(JSContext *cx, JS::HandleObject obj, JS::HandleObject metadata);
  2132 JS_FRIEND_API(JSObject *)
  2133 GetObjectMetadata(JSObject *obj);
  2135 JS_FRIEND_API(void)
  2136 UnsafeDefineElement(JSContext *cx, JS::HandleObject obj, uint32_t index, JS::HandleValue value);
  2138 JS_FRIEND_API(bool)
  2139 SliceSlowly(JSContext* cx, JS::HandleObject obj, JS::HandleObject receiver,
  2140             uint32_t begin, uint32_t end, JS::HandleObject result);
  2142 /* ES5 8.12.8. */
  2143 extern JS_FRIEND_API(bool)
  2144 DefaultValue(JSContext *cx, JS::HandleObject obj, JSType hint, JS::MutableHandleValue vp);
  2146 /*
  2147  * Helper function. To approximate a call to the [[DefineOwnProperty]] internal
  2148  * method described in ES5, first call this, then call JS_DefinePropertyById.
  2150  * JS_DefinePropertyById by itself does not enforce the invariants on
  2151  * non-configurable properties when obj->isNative(). This function performs the
  2152  * relevant checks (specified in ES5 8.12.9 [[DefineOwnProperty]] steps 1-11),
  2153  * but only if obj is native.
  2155  * The reason for the messiness here is that ES5 uses [[DefineOwnProperty]] as
  2156  * a sort of extension point, but there is no hook in js::Class,
  2157  * js::ProxyHandler, or the JSAPI with precisely the right semantics for it.
  2158  */
  2159 extern JS_FRIEND_API(bool)
  2160 CheckDefineProperty(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue value,
  2161                     JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs);
  2163 /*
  2164  * Helper function for HTMLDocument and HTMLFormElement.
  2166  * These are the only two interfaces that have [OverrideBuiltins], a named
  2167  * getter, and no named setter. They're implemented as proxies with a custom
  2168  * getOwnPropertyDescriptor() method. Unfortunately, overriding
  2169  * getOwnPropertyDescriptor() automatically affects the behavior of set(),
  2170  * which normally is just common sense but is *not* desired for these two
  2171  * interfaces.
  2173  * The fix is for these two interfaces to override set() to ignore the
  2174  * getOwnPropertyDescriptor() override.
  2176  * SetPropertyIgnoringNamedGetter is exposed to make it easier to override
  2177  * set() in this way.  It carries out all the steps of BaseProxyHandler::set()
  2178  * except the initial getOwnPropertyDescriptor()/getPropertyDescriptor() calls.
  2179  * The caller must supply those results as the 'desc' and 'descIsOwn'
  2180  * parameters.
  2182  * Implemented in jsproxy.cpp.
  2183  */
  2184 JS_FRIEND_API(bool)
  2185 SetPropertyIgnoringNamedGetter(JSContext *cx, BaseProxyHandler *handler,
  2186                                JS::HandleObject proxy, JS::HandleObject receiver,
  2187                                JS::HandleId id, JS::MutableHandle<JSPropertyDescriptor> desc,
  2188                                bool descIsOwn, bool strict, JS::MutableHandleValue vp);
  2190 } /* namespace js */
  2192 extern JS_FRIEND_API(bool)
  2193 js_DefineOwnProperty(JSContext *cx, JSObject *objArg, jsid idArg,
  2194                      JS::Handle<JSPropertyDescriptor> descriptor, bool *bp);
  2196 extern JS_FRIEND_API(bool)
  2197 js_ReportIsNotFunction(JSContext *cx, JS::HandleValue v);
  2199 #ifdef JSGC_GENERATIONAL
  2200 extern JS_FRIEND_API(void)
  2201 JS_StoreObjectPostBarrierCallback(JSContext* cx,
  2202                                   void (*callback)(JSTracer *trc, JSObject *key, void *data),
  2203                                   JSObject *key, void *data);
  2205 extern JS_FRIEND_API(void)
  2206 JS_StoreStringPostBarrierCallback(JSContext* cx,
  2207                                   void (*callback)(JSTracer *trc, JSString *key, void *data),
  2208                                   JSString *key, void *data);
  2209 #else
  2210 inline void
  2211 JS_StoreObjectPostBarrierCallback(JSContext* cx,
  2212                                   void (*callback)(JSTracer *trc, JSObject *key, void *data),
  2213                                   JSObject *key, void *data) {}
  2215 inline void
  2216 JS_StoreStringPostBarrierCallback(JSContext* cx,
  2217                                   void (*callback)(JSTracer *trc, JSString *key, void *data),
  2218                                   JSString *key, void *data) {}
  2219 #endif /* JSGC_GENERATIONAL */
  2221 #endif /* jsfriendapi_h */

mercurial