1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/src/jsfriendapi.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,2221 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- 1.5 + * vim: set ts=8 sts=4 et sw=4 tw=99: 1.6 + * This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#ifndef jsfriendapi_h 1.11 +#define jsfriendapi_h 1.12 + 1.13 +#include "mozilla/Casting.h" 1.14 +#include "mozilla/MemoryReporting.h" 1.15 +#include "mozilla/TypedEnum.h" 1.16 + 1.17 +#include "jsbytecode.h" 1.18 +#include "jspubtd.h" 1.19 + 1.20 +#include "js/CallArgs.h" 1.21 +#include "js/CallNonGenericMethod.h" 1.22 +#include "js/Class.h" 1.23 + 1.24 +/* 1.25 + * This macro checks if the stack pointer has exceeded a given limit. If 1.26 + * |tolerance| is non-zero, it returns true only if the stack pointer has 1.27 + * exceeded the limit by more than |tolerance| bytes. 1.28 + */ 1.29 +#if JS_STACK_GROWTH_DIRECTION > 0 1.30 +# define JS_CHECK_STACK_SIZE_WITH_TOLERANCE(limit, sp, tolerance) \ 1.31 + ((uintptr_t)(sp) < (limit)+(tolerance)) 1.32 +#else 1.33 +# define JS_CHECK_STACK_SIZE_WITH_TOLERANCE(limit, sp, tolerance) \ 1.34 + ((uintptr_t)(sp) > (limit)-(tolerance)) 1.35 +#endif 1.36 + 1.37 +#define JS_CHECK_STACK_SIZE(limit, lval) JS_CHECK_STACK_SIZE_WITH_TOLERANCE(limit, lval, 0) 1.38 + 1.39 +class JSAtom; 1.40 +struct JSErrorFormatString; 1.41 +class JSLinearString; 1.42 +struct JSJitInfo; 1.43 +class JSErrorReport; 1.44 + 1.45 +namespace JS { 1.46 +template <class T> 1.47 +class Heap; 1.48 +} /* namespace JS */ 1.49 + 1.50 +namespace js { 1.51 +class JS_FRIEND_API(BaseProxyHandler); 1.52 +} /* namespace js */ 1.53 + 1.54 +extern JS_FRIEND_API(void) 1.55 +JS_SetGrayGCRootsTracer(JSRuntime *rt, JSTraceDataOp traceOp, void *data); 1.56 + 1.57 +extern JS_FRIEND_API(JSString *) 1.58 +JS_GetAnonymousString(JSRuntime *rt); 1.59 + 1.60 +extern JS_FRIEND_API(void) 1.61 +JS_SetIsWorkerRuntime(JSRuntime *rt); 1.62 + 1.63 +extern JS_FRIEND_API(JSObject *) 1.64 +JS_FindCompilationScope(JSContext *cx, JS::HandleObject obj); 1.65 + 1.66 +extern JS_FRIEND_API(JSFunction *) 1.67 +JS_GetObjectFunction(JSObject *obj); 1.68 + 1.69 +extern JS_FRIEND_API(bool) 1.70 +JS_SplicePrototype(JSContext *cx, JS::HandleObject obj, JS::HandleObject proto); 1.71 + 1.72 +extern JS_FRIEND_API(JSObject *) 1.73 +JS_NewObjectWithUniqueType(JSContext *cx, const JSClass *clasp, JS::HandleObject proto, 1.74 + JS::HandleObject parent); 1.75 + 1.76 +extern JS_FRIEND_API(uint32_t) 1.77 +JS_ObjectCountDynamicSlots(JS::HandleObject obj); 1.78 + 1.79 +extern JS_FRIEND_API(size_t) 1.80 +JS_SetProtoCalled(JSContext *cx); 1.81 + 1.82 +extern JS_FRIEND_API(size_t) 1.83 +JS_GetCustomIteratorCount(JSContext *cx); 1.84 + 1.85 +extern JS_FRIEND_API(bool) 1.86 +JS_NondeterministicGetWeakMapKeys(JSContext *cx, JS::HandleObject obj, JS::MutableHandleObject ret); 1.87 + 1.88 +/* 1.89 + * Determine whether the given object is backed by a DeadObjectProxy. 1.90 + * 1.91 + * Such objects hold no other objects (they have no outgoing reference edges) 1.92 + * and will throw if you touch them (e.g. by reading/writing a property). 1.93 + */ 1.94 +extern JS_FRIEND_API(bool) 1.95 +JS_IsDeadWrapper(JSObject *obj); 1.96 + 1.97 +/* 1.98 + * Used by the cycle collector to trace through the shape and all 1.99 + * shapes it reaches, marking all non-shape children found in the 1.100 + * process. Uses bounded stack space. 1.101 + */ 1.102 +extern JS_FRIEND_API(void) 1.103 +JS_TraceShapeCycleCollectorChildren(JSTracer *trc, void *shape); 1.104 + 1.105 +enum { 1.106 + JS_TELEMETRY_GC_REASON, 1.107 + JS_TELEMETRY_GC_IS_COMPARTMENTAL, 1.108 + JS_TELEMETRY_GC_MS, 1.109 + JS_TELEMETRY_GC_MAX_PAUSE_MS, 1.110 + JS_TELEMETRY_GC_MARK_MS, 1.111 + JS_TELEMETRY_GC_SWEEP_MS, 1.112 + JS_TELEMETRY_GC_MARK_ROOTS_MS, 1.113 + JS_TELEMETRY_GC_MARK_GRAY_MS, 1.114 + JS_TELEMETRY_GC_SLICE_MS, 1.115 + JS_TELEMETRY_GC_MMU_50, 1.116 + JS_TELEMETRY_GC_RESET, 1.117 + JS_TELEMETRY_GC_INCREMENTAL_DISABLED, 1.118 + JS_TELEMETRY_GC_NON_INCREMENTAL, 1.119 + JS_TELEMETRY_GC_SCC_SWEEP_TOTAL_MS, 1.120 + JS_TELEMETRY_GC_SCC_SWEEP_MAX_PAUSE_MS 1.121 +}; 1.122 + 1.123 +typedef void 1.124 +(* JSAccumulateTelemetryDataCallback)(int id, uint32_t sample); 1.125 + 1.126 +extern JS_FRIEND_API(void) 1.127 +JS_SetAccumulateTelemetryCallback(JSRuntime *rt, JSAccumulateTelemetryDataCallback callback); 1.128 + 1.129 +extern JS_FRIEND_API(JSPrincipals *) 1.130 +JS_GetCompartmentPrincipals(JSCompartment *compartment); 1.131 + 1.132 +extern JS_FRIEND_API(void) 1.133 +JS_SetCompartmentPrincipals(JSCompartment *compartment, JSPrincipals *principals); 1.134 + 1.135 +/* Safe to call with input obj == nullptr. Returns non-nullptr iff obj != nullptr. */ 1.136 +extern JS_FRIEND_API(JSObject *) 1.137 +JS_ObjectToInnerObject(JSContext *cx, JS::HandleObject obj); 1.138 + 1.139 +/* Requires obj != nullptr. */ 1.140 +extern JS_FRIEND_API(JSObject *) 1.141 +JS_ObjectToOuterObject(JSContext *cx, JS::HandleObject obj); 1.142 + 1.143 +extern JS_FRIEND_API(JSObject *) 1.144 +JS_CloneObject(JSContext *cx, JS::HandleObject obj, JS::HandleObject proto, 1.145 + JS::HandleObject parent); 1.146 + 1.147 +extern JS_FRIEND_API(JSString *) 1.148 +JS_BasicObjectToString(JSContext *cx, JS::HandleObject obj); 1.149 + 1.150 +extern JS_FRIEND_API(bool) 1.151 +js_GetterOnlyPropertyStub(JSContext *cx, JS::HandleObject obj, JS::HandleId id, bool strict, 1.152 + JS::MutableHandleValue vp); 1.153 + 1.154 +JS_FRIEND_API(void) 1.155 +js_ReportOverRecursed(JSContext *maybecx); 1.156 + 1.157 +JS_FRIEND_API(bool) 1.158 +js_ObjectClassIs(JSContext *cx, JS::HandleObject obj, js::ESClassValue classValue); 1.159 + 1.160 +JS_FRIEND_API(const char *) 1.161 +js_ObjectClassName(JSContext *cx, JS::HandleObject obj); 1.162 + 1.163 +namespace js { 1.164 + 1.165 +JS_FRIEND_API(bool) 1.166 +AddRawValueRoot(JSContext *cx, JS::Value *vp, const char *name); 1.167 + 1.168 +JS_FRIEND_API(void) 1.169 +RemoveRawValueRoot(JSContext *cx, JS::Value *vp); 1.170 + 1.171 +} /* namespace js */ 1.172 + 1.173 +#ifdef JS_DEBUG 1.174 + 1.175 +/* 1.176 + * Routines to print out values during debugging. These are FRIEND_API to help 1.177 + * the debugger find them and to support temporarily hacking js_Dump* calls 1.178 + * into other code. 1.179 + */ 1.180 + 1.181 +extern JS_FRIEND_API(void) 1.182 +js_DumpString(JSString *str); 1.183 + 1.184 +extern JS_FRIEND_API(void) 1.185 +js_DumpAtom(JSAtom *atom); 1.186 + 1.187 +extern JS_FRIEND_API(void) 1.188 +js_DumpObject(JSObject *obj); 1.189 + 1.190 +extern JS_FRIEND_API(void) 1.191 +js_DumpChars(const jschar *s, size_t n); 1.192 +#endif 1.193 + 1.194 +/* 1.195 + * Copies all own properties from |obj| to |target|. |obj| must be a "native" 1.196 + * object (that is to say, normal-ish - not an Array or a Proxy). 1.197 + * 1.198 + * This function immediately enters a compartment, and does not impose any 1.199 + * restrictions on the compartment of |cx|. 1.200 + */ 1.201 +extern JS_FRIEND_API(bool) 1.202 +JS_CopyPropertiesFrom(JSContext *cx, JS::HandleObject target, JS::HandleObject obj); 1.203 + 1.204 +/* 1.205 + * Single-property version of the above. This function asserts that an |own| 1.206 + * property of the given name exists on |obj|. 1.207 + * 1.208 + * On entry, |cx| must be same-compartment with |obj|. 1.209 + */ 1.210 +extern JS_FRIEND_API(bool) 1.211 +JS_CopyPropertyFrom(JSContext *cx, JS::HandleId id, JS::HandleObject target, 1.212 + JS::HandleObject obj); 1.213 + 1.214 +extern JS_FRIEND_API(bool) 1.215 +JS_WrapPropertyDescriptor(JSContext *cx, JS::MutableHandle<JSPropertyDescriptor> desc); 1.216 + 1.217 +extern JS_FRIEND_API(bool) 1.218 +JS_WrapAutoIdVector(JSContext *cx, JS::AutoIdVector &props); 1.219 + 1.220 +extern JS_FRIEND_API(bool) 1.221 +JS_EnumerateState(JSContext *cx, JS::HandleObject obj, JSIterateOp enum_op, 1.222 + JS::MutableHandleValue statep, JS::MutableHandleId idp); 1.223 + 1.224 +struct JSFunctionSpecWithHelp { 1.225 + const char *name; 1.226 + JSNative call; 1.227 + uint16_t nargs; 1.228 + uint16_t flags; 1.229 + const char *usage; 1.230 + const char *help; 1.231 +}; 1.232 + 1.233 +#define JS_FN_HELP(name,call,nargs,flags,usage,help) \ 1.234 + {name, call, nargs, (flags) | JSPROP_ENUMERATE | JSFUN_STUB_GSOPS, usage, help} 1.235 +#define JS_FS_HELP_END \ 1.236 + {nullptr, nullptr, 0, 0, nullptr, nullptr} 1.237 + 1.238 +extern JS_FRIEND_API(bool) 1.239 +JS_DefineFunctionsWithHelp(JSContext *cx, JS::HandleObject obj, const JSFunctionSpecWithHelp *fs); 1.240 + 1.241 +namespace js { 1.242 + 1.243 +/* 1.244 + * Helper Macros for creating JSClasses that function as proxies. 1.245 + * 1.246 + * NB: The macro invocation must be surrounded by braces, so as to 1.247 + * allow for potention JSClass extensions. 1.248 + */ 1.249 +#define PROXY_MAKE_EXT(outerObject, innerObject, iteratorObject, \ 1.250 + isWrappedNative) \ 1.251 + { \ 1.252 + outerObject, \ 1.253 + innerObject, \ 1.254 + iteratorObject, \ 1.255 + isWrappedNative, \ 1.256 + js::proxy_WeakmapKeyDelegate \ 1.257 + } 1.258 + 1.259 +#define PROXY_CLASS_WITH_EXT(name, extraSlots, flags, callOp, constructOp, ext) \ 1.260 + { \ 1.261 + name, \ 1.262 + js::Class::NON_NATIVE | \ 1.263 + JSCLASS_IS_PROXY | \ 1.264 + JSCLASS_IMPLEMENTS_BARRIERS | \ 1.265 + JSCLASS_HAS_RESERVED_SLOTS(js::PROXY_MINIMUM_SLOTS + (extraSlots)) | \ 1.266 + flags, \ 1.267 + JS_PropertyStub, /* addProperty */ \ 1.268 + JS_DeletePropertyStub, /* delProperty */ \ 1.269 + JS_PropertyStub, /* getProperty */ \ 1.270 + JS_StrictPropertyStub, /* setProperty */ \ 1.271 + JS_EnumerateStub, \ 1.272 + JS_ResolveStub, \ 1.273 + js::proxy_Convert, \ 1.274 + js::proxy_Finalize, /* finalize */ \ 1.275 + callOp, /* call */ \ 1.276 + js::proxy_HasInstance, /* hasInstance */ \ 1.277 + constructOp, /* construct */ \ 1.278 + js::proxy_Trace, /* trace */ \ 1.279 + JS_NULL_CLASS_SPEC, \ 1.280 + ext, \ 1.281 + { \ 1.282 + js::proxy_LookupGeneric, \ 1.283 + js::proxy_LookupProperty, \ 1.284 + js::proxy_LookupElement, \ 1.285 + js::proxy_DefineGeneric, \ 1.286 + js::proxy_DefineProperty, \ 1.287 + js::proxy_DefineElement, \ 1.288 + js::proxy_GetGeneric, \ 1.289 + js::proxy_GetProperty, \ 1.290 + js::proxy_GetElement, \ 1.291 + js::proxy_SetGeneric, \ 1.292 + js::proxy_SetProperty, \ 1.293 + js::proxy_SetElement, \ 1.294 + js::proxy_GetGenericAttributes, \ 1.295 + js::proxy_SetGenericAttributes, \ 1.296 + js::proxy_DeleteProperty, \ 1.297 + js::proxy_DeleteElement, \ 1.298 + js::proxy_Watch, js::proxy_Unwatch, \ 1.299 + js::proxy_Slice, \ 1.300 + nullptr, /* enumerate */ \ 1.301 + nullptr, /* thisObject */ \ 1.302 + } \ 1.303 + } 1.304 + 1.305 +#define PROXY_CLASS_DEF(name, extraSlots, flags, callOp, constructOp) \ 1.306 + PROXY_CLASS_WITH_EXT(name, extraSlots, flags, callOp, constructOp, \ 1.307 + PROXY_MAKE_EXT( \ 1.308 + nullptr, /* outerObject */ \ 1.309 + nullptr, /* innerObject */ \ 1.310 + nullptr, /* iteratorObject */ \ 1.311 + false /* isWrappedNative */ \ 1.312 + )) 1.313 + 1.314 +/* 1.315 + * Proxy stubs, similar to JS_*Stub, for embedder proxy class definitions. 1.316 + * 1.317 + * NB: Should not be called directly. 1.318 + */ 1.319 + 1.320 +extern JS_FRIEND_API(bool) 1.321 +proxy_LookupGeneric(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::MutableHandleObject objp, 1.322 + JS::MutableHandle<Shape*> propp); 1.323 +extern JS_FRIEND_API(bool) 1.324 +proxy_LookupProperty(JSContext *cx, JS::HandleObject obj, JS::Handle<PropertyName*> name, 1.325 + JS::MutableHandleObject objp, JS::MutableHandle<Shape*> propp); 1.326 +extern JS_FRIEND_API(bool) 1.327 +proxy_LookupElement(JSContext *cx, JS::HandleObject obj, uint32_t index, JS::MutableHandleObject objp, 1.328 + JS::MutableHandle<Shape*> propp); 1.329 +extern JS_FRIEND_API(bool) 1.330 +proxy_DefineGeneric(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue value, 1.331 + JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs); 1.332 +extern JS_FRIEND_API(bool) 1.333 +proxy_DefineProperty(JSContext *cx, JS::HandleObject obj, JS::Handle<PropertyName*> name, 1.334 + JS::HandleValue value, JSPropertyOp getter, JSStrictPropertyOp setter, 1.335 + unsigned attrs); 1.336 +extern JS_FRIEND_API(bool) 1.337 +proxy_DefineElement(JSContext *cx, JS::HandleObject obj, uint32_t index, JS::HandleValue value, 1.338 + JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs); 1.339 +extern JS_FRIEND_API(bool) 1.340 +proxy_GetGeneric(JSContext *cx, JS::HandleObject obj, JS::HandleObject receiver, JS::HandleId id, 1.341 + JS::MutableHandleValue vp); 1.342 +extern JS_FRIEND_API(bool) 1.343 +proxy_GetProperty(JSContext *cx, JS::HandleObject obj, JS::HandleObject receiver, 1.344 + JS::Handle<PropertyName*> name, JS::MutableHandleValue vp); 1.345 +extern JS_FRIEND_API(bool) 1.346 +proxy_GetElement(JSContext *cx, JS::HandleObject obj, JS::HandleObject receiver, uint32_t index, 1.347 + JS::MutableHandleValue vp); 1.348 +extern JS_FRIEND_API(bool) 1.349 +proxy_SetGeneric(JSContext *cx, JS::HandleObject obj, JS::HandleId id, 1.350 + JS::MutableHandleValue bp, bool strict); 1.351 +extern JS_FRIEND_API(bool) 1.352 +proxy_SetProperty(JSContext *cx, JS::HandleObject obj, JS::Handle<PropertyName*> name, 1.353 + JS::MutableHandleValue bp, bool strict); 1.354 +extern JS_FRIEND_API(bool) 1.355 +proxy_SetElement(JSContext *cx, JS::HandleObject obj, uint32_t index, JS::MutableHandleValue vp, 1.356 + bool strict); 1.357 +extern JS_FRIEND_API(bool) 1.358 +proxy_GetGenericAttributes(JSContext *cx, JS::HandleObject obj, JS::HandleId id, unsigned *attrsp); 1.359 +extern JS_FRIEND_API(bool) 1.360 +proxy_SetGenericAttributes(JSContext *cx, JS::HandleObject obj, JS::HandleId id, unsigned *attrsp); 1.361 +extern JS_FRIEND_API(bool) 1.362 +proxy_DeleteProperty(JSContext *cx, JS::HandleObject obj, JS::Handle<PropertyName*> name, 1.363 + bool *succeeded); 1.364 +extern JS_FRIEND_API(bool) 1.365 +proxy_DeleteElement(JSContext *cx, JS::HandleObject obj, uint32_t index, bool *succeeded); 1.366 + 1.367 +extern JS_FRIEND_API(void) 1.368 +proxy_Trace(JSTracer *trc, JSObject *obj); 1.369 +extern JS_FRIEND_API(JSObject *) 1.370 +proxy_WeakmapKeyDelegate(JSObject *obj); 1.371 +extern JS_FRIEND_API(bool) 1.372 +proxy_Convert(JSContext *cx, JS::HandleObject proxy, JSType hint, JS::MutableHandleValue vp); 1.373 +extern JS_FRIEND_API(void) 1.374 +proxy_Finalize(FreeOp *fop, JSObject *obj); 1.375 +extern JS_FRIEND_API(bool) 1.376 +proxy_HasInstance(JSContext *cx, JS::HandleObject proxy, JS::MutableHandleValue v, bool *bp); 1.377 +extern JS_FRIEND_API(bool) 1.378 +proxy_Call(JSContext *cx, unsigned argc, JS::Value *vp); 1.379 +extern JS_FRIEND_API(bool) 1.380 +proxy_Construct(JSContext *cx, unsigned argc, JS::Value *vp); 1.381 +extern JS_FRIEND_API(JSObject *) 1.382 +proxy_innerObject(JSContext *cx, JS::HandleObject obj); 1.383 +extern JS_FRIEND_API(bool) 1.384 +proxy_Watch(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject callable); 1.385 +extern JS_FRIEND_API(bool) 1.386 +proxy_Unwatch(JSContext *cx, JS::HandleObject obj, JS::HandleId id); 1.387 +extern JS_FRIEND_API(bool) 1.388 +proxy_Slice(JSContext *cx, JS::HandleObject proxy, uint32_t begin, uint32_t end, 1.389 + JS::HandleObject result); 1.390 + 1.391 +/* 1.392 + * A class of objects that return source code on demand. 1.393 + * 1.394 + * When code is compiled with setSourceIsLazy(true), SpiderMonkey doesn't 1.395 + * retain the source code (and doesn't do lazy bytecode generation). If we ever 1.396 + * need the source code, say, in response to a call to Function.prototype. 1.397 + * toSource or Debugger.Source.prototype.text, then we call the 'load' member 1.398 + * function of the instance of this class that has hopefully been registered 1.399 + * with the runtime, passing the code's URL, and hope that it will be able to 1.400 + * find the source. 1.401 + */ 1.402 +class SourceHook { 1.403 + public: 1.404 + virtual ~SourceHook() { } 1.405 + 1.406 + /* 1.407 + * Set |*src| and |*length| to refer to the source code for |filename|. 1.408 + * On success, the caller owns the buffer to which |*src| points, and 1.409 + * should use JS_free to free it. 1.410 + */ 1.411 + virtual bool load(JSContext *cx, const char *filename, jschar **src, size_t *length) = 0; 1.412 +}; 1.413 + 1.414 +/* 1.415 + * Have |rt| use |hook| to retrieve lazily-retrieved source code. See the 1.416 + * comments for SourceHook. The runtime takes ownership of the hook, and 1.417 + * will delete it when the runtime itself is deleted, or when a new hook is 1.418 + * set. 1.419 + */ 1.420 +extern JS_FRIEND_API(void) 1.421 +SetSourceHook(JSRuntime *rt, SourceHook *hook); 1.422 + 1.423 +/* Remove |rt|'s source hook, and return it. The caller now owns the hook. */ 1.424 +extern JS_FRIEND_API(SourceHook *) 1.425 +ForgetSourceHook(JSRuntime *rt); 1.426 + 1.427 +extern JS_FRIEND_API(JS::Zone *) 1.428 +GetCompartmentZone(JSCompartment *comp); 1.429 + 1.430 +typedef bool 1.431 +(* PreserveWrapperCallback)(JSContext *cx, JSObject *obj); 1.432 + 1.433 +typedef enum { 1.434 + CollectNurseryBeforeDump, 1.435 + IgnoreNurseryObjects 1.436 +} DumpHeapNurseryBehaviour; 1.437 + 1.438 + /* 1.439 + * Dump the complete object graph of heap-allocated things. 1.440 + * fp is the file for the dump output. 1.441 + */ 1.442 +extern JS_FRIEND_API(void) 1.443 +DumpHeapComplete(JSRuntime *rt, FILE *fp, DumpHeapNurseryBehaviour nurseryBehaviour); 1.444 + 1.445 +#ifdef JS_OLD_GETTER_SETTER_METHODS 1.446 +JS_FRIEND_API(bool) obj_defineGetter(JSContext *cx, unsigned argc, JS::Value *vp); 1.447 +JS_FRIEND_API(bool) obj_defineSetter(JSContext *cx, unsigned argc, JS::Value *vp); 1.448 +#endif 1.449 + 1.450 +extern JS_FRIEND_API(bool) 1.451 +IsSystemCompartment(JSCompartment *comp); 1.452 + 1.453 +extern JS_FRIEND_API(bool) 1.454 +IsSystemZone(JS::Zone *zone); 1.455 + 1.456 +extern JS_FRIEND_API(bool) 1.457 +IsAtomsCompartment(JSCompartment *comp); 1.458 + 1.459 +/* 1.460 + * Check whether it is OK to assign an undeclared variable with the name 1.461 + * |propname| at the current location in script. It is not an error if there is 1.462 + * no current script location, or if that location is not an assignment to an 1.463 + * undeclared variable. Reports an error if one needs to be reported (and, 1.464 + * particularly, always reports when it returns false). 1.465 + */ 1.466 +extern JS_FRIEND_API(bool) 1.467 +ReportIfUndeclaredVarAssignment(JSContext *cx, JS::HandleString propname); 1.468 + 1.469 +/* 1.470 + * Returns whether we're in a non-strict property set (in that we're in a 1.471 + * non-strict script and the bytecode we're on is a property set). The return 1.472 + * value does NOT indicate any sort of exception was thrown: it's just a 1.473 + * boolean. 1.474 + */ 1.475 +extern JS_FRIEND_API(bool) 1.476 +IsInNonStrictPropertySet(JSContext *cx); 1.477 + 1.478 +struct WeakMapTracer; 1.479 + 1.480 +/* 1.481 + * Weak map tracer callback, called once for every binding of every 1.482 + * weak map that was live at the time of the last garbage collection. 1.483 + * 1.484 + * m will be nullptr if the weak map is not contained in a JS Object. 1.485 + */ 1.486 +typedef void 1.487 +(* WeakMapTraceCallback)(WeakMapTracer *trc, JSObject *m, 1.488 + void *k, JSGCTraceKind kkind, 1.489 + void *v, JSGCTraceKind vkind); 1.490 + 1.491 +struct WeakMapTracer { 1.492 + JSRuntime *runtime; 1.493 + WeakMapTraceCallback callback; 1.494 + 1.495 + WeakMapTracer(JSRuntime *rt, WeakMapTraceCallback cb) 1.496 + : runtime(rt), callback(cb) {} 1.497 +}; 1.498 + 1.499 +extern JS_FRIEND_API(void) 1.500 +TraceWeakMaps(WeakMapTracer *trc); 1.501 + 1.502 +extern JS_FRIEND_API(bool) 1.503 +AreGCGrayBitsValid(JSRuntime *rt); 1.504 + 1.505 +extern JS_FRIEND_API(bool) 1.506 +ZoneGlobalsAreAllGray(JS::Zone *zone); 1.507 + 1.508 +typedef void 1.509 +(*GCThingCallback)(void *closure, void *gcthing); 1.510 + 1.511 +extern JS_FRIEND_API(void) 1.512 +VisitGrayWrapperTargets(JS::Zone *zone, GCThingCallback callback, void *closure); 1.513 + 1.514 +extern JS_FRIEND_API(JSObject *) 1.515 +GetWeakmapKeyDelegate(JSObject *key); 1.516 + 1.517 +JS_FRIEND_API(JSGCTraceKind) 1.518 +GCThingTraceKind(void *thing); 1.519 + 1.520 +/* 1.521 + * Invoke cellCallback on every gray JS_OBJECT in the given zone. 1.522 + */ 1.523 +extern JS_FRIEND_API(void) 1.524 +IterateGrayObjects(JS::Zone *zone, GCThingCallback cellCallback, void *data); 1.525 + 1.526 +#ifdef JS_HAS_CTYPES 1.527 +extern JS_FRIEND_API(size_t) 1.528 +SizeOfDataIfCDataObject(mozilla::MallocSizeOf mallocSizeOf, JSObject *obj); 1.529 +#endif 1.530 + 1.531 +extern JS_FRIEND_API(JSCompartment *) 1.532 +GetAnyCompartmentInZone(JS::Zone *zone); 1.533 + 1.534 +/* 1.535 + * Shadow declarations of JS internal structures, for access by inline access 1.536 + * functions below. Do not use these structures in any other way. When adding 1.537 + * new fields for access by inline methods, make sure to add static asserts to 1.538 + * the original header file to ensure that offsets are consistent. 1.539 + */ 1.540 +namespace shadow { 1.541 + 1.542 +struct TypeObject { 1.543 + const Class *clasp; 1.544 + JSObject *proto; 1.545 +}; 1.546 + 1.547 +struct BaseShape { 1.548 + const js::Class *clasp_; 1.549 + JSObject *parent; 1.550 + JSObject *_1; 1.551 + JSCompartment *compartment; 1.552 +}; 1.553 + 1.554 +class Shape { 1.555 +public: 1.556 + shadow::BaseShape *base; 1.557 + jsid _1; 1.558 + uint32_t slotInfo; 1.559 + 1.560 + static const uint32_t FIXED_SLOTS_SHIFT = 27; 1.561 +}; 1.562 + 1.563 +struct Object { 1.564 + shadow::Shape *shape; 1.565 + shadow::TypeObject *type; 1.566 + JS::Value *slots; 1.567 + JS::Value *_1; 1.568 + 1.569 + size_t numFixedSlots() const { return shape->slotInfo >> Shape::FIXED_SLOTS_SHIFT; } 1.570 + JS::Value *fixedSlots() const { 1.571 + return (JS::Value *)(uintptr_t(this) + sizeof(shadow::Object)); 1.572 + } 1.573 + 1.574 + JS::Value &slotRef(size_t slot) const { 1.575 + size_t nfixed = numFixedSlots(); 1.576 + if (slot < nfixed) 1.577 + return fixedSlots()[slot]; 1.578 + return slots[slot - nfixed]; 1.579 + } 1.580 + 1.581 + // Reserved slots with index < MAX_FIXED_SLOTS are guaranteed to 1.582 + // be fixed slots. 1.583 + static const uint32_t MAX_FIXED_SLOTS = 16; 1.584 +}; 1.585 + 1.586 +struct Function { 1.587 + Object base; 1.588 + uint16_t nargs; 1.589 + uint16_t flags; 1.590 + /* Used only for natives */ 1.591 + JSNative native; 1.592 + const JSJitInfo *jitinfo; 1.593 + void *_1; 1.594 +}; 1.595 + 1.596 +struct Atom { 1.597 + static const size_t LENGTH_SHIFT = 4; 1.598 + size_t lengthAndFlags; 1.599 + const jschar *chars; 1.600 +}; 1.601 + 1.602 +} /* namespace shadow */ 1.603 + 1.604 +// This is equal to |&JSObject::class_|. Use it in places where you don't want 1.605 +// to #include jsobj.h. 1.606 +extern JS_FRIEND_DATA(const js::Class* const) ObjectClassPtr; 1.607 + 1.608 +inline const js::Class * 1.609 +GetObjectClass(JSObject *obj) 1.610 +{ 1.611 + return reinterpret_cast<const shadow::Object*>(obj)->type->clasp; 1.612 +} 1.613 + 1.614 +inline const JSClass * 1.615 +GetObjectJSClass(JSObject *obj) 1.616 +{ 1.617 + return js::Jsvalify(GetObjectClass(obj)); 1.618 +} 1.619 + 1.620 +inline bool 1.621 +IsInnerObject(JSObject *obj) { 1.622 + return !!GetObjectClass(obj)->ext.outerObject; 1.623 +} 1.624 + 1.625 +inline bool 1.626 +IsOuterObject(JSObject *obj) { 1.627 + return !!GetObjectClass(obj)->ext.innerObject; 1.628 +} 1.629 + 1.630 +JS_FRIEND_API(bool) 1.631 +IsFunctionObject(JSObject *obj); 1.632 + 1.633 +JS_FRIEND_API(bool) 1.634 +IsScopeObject(JSObject *obj); 1.635 + 1.636 +JS_FRIEND_API(bool) 1.637 +IsCallObject(JSObject *obj); 1.638 + 1.639 +inline JSObject * 1.640 +GetObjectParent(JSObject *obj) 1.641 +{ 1.642 + JS_ASSERT(!IsScopeObject(obj)); 1.643 + return reinterpret_cast<shadow::Object*>(obj)->shape->base->parent; 1.644 +} 1.645 + 1.646 +static MOZ_ALWAYS_INLINE JSCompartment * 1.647 +GetObjectCompartment(JSObject *obj) 1.648 +{ 1.649 + return reinterpret_cast<shadow::Object*>(obj)->shape->base->compartment; 1.650 +} 1.651 + 1.652 +JS_FRIEND_API(JSObject *) 1.653 +GetObjectParentMaybeScope(JSObject *obj); 1.654 + 1.655 +JS_FRIEND_API(JSObject *) 1.656 +GetGlobalForObjectCrossCompartment(JSObject *obj); 1.657 + 1.658 +// Sidestep the activeContext checking implicitly performed in 1.659 +// JS_SetPendingException. 1.660 +JS_FRIEND_API(void) 1.661 +SetPendingExceptionCrossContext(JSContext *cx, JS::HandleValue v); 1.662 + 1.663 +JS_FRIEND_API(void) 1.664 +AssertSameCompartment(JSContext *cx, JSObject *obj); 1.665 + 1.666 +#ifdef JS_DEBUG 1.667 +JS_FRIEND_API(void) 1.668 +AssertSameCompartment(JSObject *objA, JSObject *objB); 1.669 +#else 1.670 +inline void AssertSameCompartment(JSObject *objA, JSObject *objB) {} 1.671 +#endif 1.672 + 1.673 +// For legacy consumers only. This whole concept is going away soon. 1.674 +JS_FRIEND_API(JSObject *) 1.675 +DefaultObjectForContextOrNull(JSContext *cx); 1.676 + 1.677 +JS_FRIEND_API(void) 1.678 +SetDefaultObjectForContext(JSContext *cx, JSObject *obj); 1.679 + 1.680 +JS_FRIEND_API(void) 1.681 +NotifyAnimationActivity(JSObject *obj); 1.682 + 1.683 +/* 1.684 + * Return the outermost enclosing function (script) of the scripted caller. 1.685 + * This function returns nullptr in several cases: 1.686 + * - no script is running on the context 1.687 + * - the caller is in global or eval code 1.688 + * In particular, this function will "stop" its outermost search at eval() and 1.689 + * thus it will really return the outermost enclosing function *since the 1.690 + * innermost eval*. 1.691 + */ 1.692 +JS_FRIEND_API(JSScript *) 1.693 +GetOutermostEnclosingFunctionOfScriptedCaller(JSContext *cx); 1.694 + 1.695 +JS_FRIEND_API(JSFunction *) 1.696 +DefineFunctionWithReserved(JSContext *cx, JSObject *obj, const char *name, JSNative call, 1.697 + unsigned nargs, unsigned attrs); 1.698 + 1.699 +JS_FRIEND_API(JSFunction *) 1.700 +NewFunctionWithReserved(JSContext *cx, JSNative call, unsigned nargs, unsigned flags, 1.701 + JSObject *parent, const char *name); 1.702 + 1.703 +JS_FRIEND_API(JSFunction *) 1.704 +NewFunctionByIdWithReserved(JSContext *cx, JSNative native, unsigned nargs, unsigned flags, 1.705 + JSObject *parent, jsid id); 1.706 + 1.707 +JS_FRIEND_API(JSObject *) 1.708 +InitClassWithReserved(JSContext *cx, JSObject *obj, JSObject *parent_proto, 1.709 + const JSClass *clasp, JSNative constructor, unsigned nargs, 1.710 + const JSPropertySpec *ps, const JSFunctionSpec *fs, 1.711 + const JSPropertySpec *static_ps, const JSFunctionSpec *static_fs); 1.712 + 1.713 +JS_FRIEND_API(const JS::Value &) 1.714 +GetFunctionNativeReserved(JSObject *fun, size_t which); 1.715 + 1.716 +JS_FRIEND_API(void) 1.717 +SetFunctionNativeReserved(JSObject *fun, size_t which, const JS::Value &val); 1.718 + 1.719 +JS_FRIEND_API(bool) 1.720 +GetObjectProto(JSContext *cx, JS::HandleObject obj, JS::MutableHandleObject proto); 1.721 + 1.722 +JS_FRIEND_API(bool) 1.723 +GetOriginalEval(JSContext *cx, JS::HandleObject scope, 1.724 + JS::MutableHandleObject eval); 1.725 + 1.726 +inline void * 1.727 +GetObjectPrivate(JSObject *obj) 1.728 +{ 1.729 + const shadow::Object *nobj = reinterpret_cast<const shadow::Object*>(obj); 1.730 + void **addr = reinterpret_cast<void**>(&nobj->fixedSlots()[nobj->numFixedSlots()]); 1.731 + return *addr; 1.732 +} 1.733 + 1.734 +/* 1.735 + * Get a slot that is both reserved for object's clasp *and* is fixed (fits 1.736 + * within the maximum capacity for the object's fixed slots). 1.737 + */ 1.738 +inline const JS::Value & 1.739 +GetReservedSlot(JSObject *obj, size_t slot) 1.740 +{ 1.741 + JS_ASSERT(slot < JSCLASS_RESERVED_SLOTS(GetObjectClass(obj))); 1.742 + return reinterpret_cast<const shadow::Object *>(obj)->slotRef(slot); 1.743 +} 1.744 + 1.745 +JS_FRIEND_API(void) 1.746 +SetReservedSlotWithBarrier(JSObject *obj, size_t slot, const JS::Value &value); 1.747 + 1.748 +inline void 1.749 +SetReservedSlot(JSObject *obj, size_t slot, const JS::Value &value) 1.750 +{ 1.751 + JS_ASSERT(slot < JSCLASS_RESERVED_SLOTS(GetObjectClass(obj))); 1.752 + shadow::Object *sobj = reinterpret_cast<shadow::Object *>(obj); 1.753 + if (sobj->slotRef(slot).isMarkable() 1.754 +#ifdef JSGC_GENERATIONAL 1.755 + || value.isMarkable() 1.756 +#endif 1.757 + ) 1.758 + { 1.759 + SetReservedSlotWithBarrier(obj, slot, value); 1.760 + } else { 1.761 + sobj->slotRef(slot) = value; 1.762 + } 1.763 +} 1.764 + 1.765 +JS_FRIEND_API(uint32_t) 1.766 +GetObjectSlotSpan(JSObject *obj); 1.767 + 1.768 +inline const JS::Value & 1.769 +GetObjectSlot(JSObject *obj, size_t slot) 1.770 +{ 1.771 + JS_ASSERT(slot < GetObjectSlotSpan(obj)); 1.772 + return reinterpret_cast<const shadow::Object *>(obj)->slotRef(slot); 1.773 +} 1.774 + 1.775 +inline const jschar * 1.776 +GetAtomChars(JSAtom *atom) 1.777 +{ 1.778 + return reinterpret_cast<shadow::Atom *>(atom)->chars; 1.779 +} 1.780 + 1.781 +inline size_t 1.782 +GetAtomLength(JSAtom *atom) 1.783 +{ 1.784 + using shadow::Atom; 1.785 + return reinterpret_cast<Atom*>(atom)->lengthAndFlags >> Atom::LENGTH_SHIFT; 1.786 +} 1.787 + 1.788 +inline JSLinearString * 1.789 +AtomToLinearString(JSAtom *atom) 1.790 +{ 1.791 + return reinterpret_cast<JSLinearString *>(atom); 1.792 +} 1.793 + 1.794 +JS_FRIEND_API(bool) 1.795 +GetPropertyNames(JSContext *cx, JSObject *obj, unsigned flags, JS::AutoIdVector *props); 1.796 + 1.797 +JS_FRIEND_API(bool) 1.798 +AppendUnique(JSContext *cx, JS::AutoIdVector &base, JS::AutoIdVector &others); 1.799 + 1.800 +JS_FRIEND_API(bool) 1.801 +GetGeneric(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id, JS::Value *vp); 1.802 + 1.803 +JS_FRIEND_API(bool) 1.804 +StringIsArrayIndex(JSLinearString *str, uint32_t *indexp); 1.805 + 1.806 +JS_FRIEND_API(void) 1.807 +SetPreserveWrapperCallback(JSRuntime *rt, PreserveWrapperCallback callback); 1.808 + 1.809 +JS_FRIEND_API(bool) 1.810 +IsObjectInContextCompartment(JSObject *obj, const JSContext *cx); 1.811 + 1.812 +/* 1.813 + * NB: these flag bits are encoded into the bytecode stream in the immediate 1.814 + * operand of JSOP_ITER, so don't change them without advancing vm/Xdr.h's 1.815 + * XDR_BYTECODE_VERSION. 1.816 + */ 1.817 +#define JSITER_ENUMERATE 0x1 /* for-in compatible hidden default iterator */ 1.818 +#define JSITER_FOREACH 0x2 /* return [key, value] pair rather than key */ 1.819 +#define JSITER_KEYVALUE 0x4 /* destructuring for-in wants [key, value] */ 1.820 +#define JSITER_OWNONLY 0x8 /* iterate over obj's own properties only */ 1.821 +#define JSITER_HIDDEN 0x10 /* also enumerate non-enumerable properties */ 1.822 + 1.823 +JS_FRIEND_API(bool) 1.824 +RunningWithTrustedPrincipals(JSContext *cx); 1.825 + 1.826 +inline uintptr_t 1.827 +GetNativeStackLimit(JSContext *cx) 1.828 +{ 1.829 + StackKind kind = RunningWithTrustedPrincipals(cx) ? StackForTrustedScript 1.830 + : StackForUntrustedScript; 1.831 + PerThreadDataFriendFields *mainThread = 1.832 + PerThreadDataFriendFields::getMainThread(GetRuntime(cx)); 1.833 + return mainThread->nativeStackLimit[kind]; 1.834 +} 1.835 + 1.836 +/* 1.837 + * These macros report a stack overflow and run |onerror| if we are close to 1.838 + * using up the C stack. The JS_CHECK_CHROME_RECURSION variant gives us a little 1.839 + * extra space so that we can ensure that crucial code is able to run. 1.840 + */ 1.841 + 1.842 +#define JS_CHECK_RECURSION(cx, onerror) \ 1.843 + JS_BEGIN_MACRO \ 1.844 + int stackDummy_; \ 1.845 + if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(cx), &stackDummy_)) { \ 1.846 + js_ReportOverRecursed(cx); \ 1.847 + onerror; \ 1.848 + } \ 1.849 + JS_END_MACRO 1.850 + 1.851 +#define JS_CHECK_RECURSION_DONT_REPORT(cx, onerror) \ 1.852 + JS_BEGIN_MACRO \ 1.853 + int stackDummy_; \ 1.854 + if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(cx), &stackDummy_)) { \ 1.855 + onerror; \ 1.856 + } \ 1.857 + JS_END_MACRO 1.858 + 1.859 +#define JS_CHECK_RECURSION_WITH_SP_DONT_REPORT(cx, sp, onerror) \ 1.860 + JS_BEGIN_MACRO \ 1.861 + if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(cx), sp)) { \ 1.862 + onerror; \ 1.863 + } \ 1.864 + JS_END_MACRO 1.865 + 1.866 +#define JS_CHECK_RECURSION_WITH_SP(cx, sp, onerror) \ 1.867 + JS_BEGIN_MACRO \ 1.868 + if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(cx), sp)) { \ 1.869 + js_ReportOverRecursed(cx); \ 1.870 + onerror; \ 1.871 + } \ 1.872 + JS_END_MACRO 1.873 + 1.874 +#define JS_CHECK_CHROME_RECURSION(cx, onerror) \ 1.875 + JS_BEGIN_MACRO \ 1.876 + int stackDummy_; \ 1.877 + if (!JS_CHECK_STACK_SIZE_WITH_TOLERANCE(js::GetNativeStackLimit(cx), \ 1.878 + &stackDummy_, \ 1.879 + 1024 * sizeof(size_t))) \ 1.880 + { \ 1.881 + js_ReportOverRecursed(cx); \ 1.882 + onerror; \ 1.883 + } \ 1.884 + JS_END_MACRO 1.885 + 1.886 +JS_FRIEND_API(void) 1.887 +StartPCCountProfiling(JSContext *cx); 1.888 + 1.889 +JS_FRIEND_API(void) 1.890 +StopPCCountProfiling(JSContext *cx); 1.891 + 1.892 +JS_FRIEND_API(void) 1.893 +PurgePCCounts(JSContext *cx); 1.894 + 1.895 +JS_FRIEND_API(size_t) 1.896 +GetPCCountScriptCount(JSContext *cx); 1.897 + 1.898 +JS_FRIEND_API(JSString *) 1.899 +GetPCCountScriptSummary(JSContext *cx, size_t script); 1.900 + 1.901 +JS_FRIEND_API(JSString *) 1.902 +GetPCCountScriptContents(JSContext *cx, size_t script); 1.903 + 1.904 +#ifdef JS_THREADSAFE 1.905 +JS_FRIEND_API(bool) 1.906 +ContextHasOutstandingRequests(const JSContext *cx); 1.907 +#endif 1.908 + 1.909 +typedef void 1.910 +(* ActivityCallback)(void *arg, bool active); 1.911 + 1.912 +/* 1.913 + * Sets a callback that is run whenever the runtime goes idle - the 1.914 + * last active request ceases - and begins activity - when it was 1.915 + * idle and a request begins. 1.916 + */ 1.917 +JS_FRIEND_API(void) 1.918 +SetActivityCallback(JSRuntime *rt, ActivityCallback cb, void *arg); 1.919 + 1.920 +extern JS_FRIEND_API(const JSStructuredCloneCallbacks *) 1.921 +GetContextStructuredCloneCallbacks(JSContext *cx); 1.922 + 1.923 +extern JS_FRIEND_API(bool) 1.924 +IsContextRunningJS(JSContext *cx); 1.925 + 1.926 +typedef bool 1.927 +(* DOMInstanceClassMatchesProto)(JSObject *protoObject, uint32_t protoID, uint32_t depth); 1.928 +struct JSDOMCallbacks { 1.929 + DOMInstanceClassMatchesProto instanceClassMatchesProto; 1.930 +}; 1.931 +typedef struct JSDOMCallbacks DOMCallbacks; 1.932 + 1.933 +extern JS_FRIEND_API(void) 1.934 +SetDOMCallbacks(JSRuntime *rt, const DOMCallbacks *callbacks); 1.935 + 1.936 +extern JS_FRIEND_API(const DOMCallbacks *) 1.937 +GetDOMCallbacks(JSRuntime *rt); 1.938 + 1.939 +extern JS_FRIEND_API(JSObject *) 1.940 +GetTestingFunctions(JSContext *cx); 1.941 + 1.942 +/* 1.943 + * Helper to convert FreeOp to JSFreeOp when the definition of FreeOp is not 1.944 + * available and the compiler does not know that FreeOp inherits from 1.945 + * JSFreeOp. 1.946 + */ 1.947 +inline JSFreeOp * 1.948 +CastToJSFreeOp(FreeOp *fop) 1.949 +{ 1.950 + return reinterpret_cast<JSFreeOp *>(fop); 1.951 +} 1.952 + 1.953 +/* Implemented in jsexn.cpp. */ 1.954 + 1.955 +/* 1.956 + * Get an error type name from a JSExnType constant. 1.957 + * Returns nullptr for invalid arguments and JSEXN_INTERNALERR 1.958 + */ 1.959 +extern JS_FRIEND_API(const jschar*) 1.960 +GetErrorTypeName(JSRuntime* rt, int16_t exnType); 1.961 + 1.962 +#ifdef JS_DEBUG 1.963 +extern JS_FRIEND_API(unsigned) 1.964 +GetEnterCompartmentDepth(JSContext* cx); 1.965 +#endif 1.966 + 1.967 +/* Implemented in jswrapper.cpp. */ 1.968 +typedef enum NukeReferencesToWindow { 1.969 + NukeWindowReferences, 1.970 + DontNukeWindowReferences 1.971 +} NukeReferencesToWindow; 1.972 + 1.973 +/* 1.974 + * These filters are designed to be ephemeral stack classes, and thus don't 1.975 + * do any rooting or holding of their members. 1.976 + */ 1.977 +struct CompartmentFilter { 1.978 + virtual bool match(JSCompartment *c) const = 0; 1.979 +}; 1.980 + 1.981 +struct AllCompartments : public CompartmentFilter { 1.982 + virtual bool match(JSCompartment *c) const { return true; } 1.983 +}; 1.984 + 1.985 +struct ContentCompartmentsOnly : public CompartmentFilter { 1.986 + virtual bool match(JSCompartment *c) const { 1.987 + return !IsSystemCompartment(c); 1.988 + } 1.989 +}; 1.990 + 1.991 +struct ChromeCompartmentsOnly : public CompartmentFilter { 1.992 + virtual bool match(JSCompartment *c) const { 1.993 + return IsSystemCompartment(c); 1.994 + } 1.995 +}; 1.996 + 1.997 +struct SingleCompartment : public CompartmentFilter { 1.998 + JSCompartment *ours; 1.999 + SingleCompartment(JSCompartment *c) : ours(c) {} 1.1000 + virtual bool match(JSCompartment *c) const { return c == ours; } 1.1001 +}; 1.1002 + 1.1003 +struct CompartmentsWithPrincipals : public CompartmentFilter { 1.1004 + JSPrincipals *principals; 1.1005 + CompartmentsWithPrincipals(JSPrincipals *p) : principals(p) {} 1.1006 + virtual bool match(JSCompartment *c) const { 1.1007 + return JS_GetCompartmentPrincipals(c) == principals; 1.1008 + } 1.1009 +}; 1.1010 + 1.1011 +extern JS_FRIEND_API(bool) 1.1012 +NukeCrossCompartmentWrappers(JSContext* cx, 1.1013 + const CompartmentFilter& sourceFilter, 1.1014 + const CompartmentFilter& targetFilter, 1.1015 + NukeReferencesToWindow nukeReferencesToWindow); 1.1016 + 1.1017 +/* Specify information about DOMProxy proxies in the DOM, for use by ICs. */ 1.1018 + 1.1019 +/* 1.1020 + * The DOMProxyShadowsCheck function will be called to check if the property for 1.1021 + * id should be gotten from the prototype, or if there is an own property that 1.1022 + * shadows it. 1.1023 + * If DoesntShadow is returned then the slot at listBaseExpandoSlot should 1.1024 + * either be undefined or point to an expando object that would contain the own 1.1025 + * property. 1.1026 + * If DoesntShadowUnique is returned then the slot at listBaseExpandoSlot should 1.1027 + * contain a private pointer to a ExpandoAndGeneration, which contains a 1.1028 + * JS::Value that should either be undefined or point to an expando object, and 1.1029 + * a uint32 value. If that value changes then the IC for getting a property will 1.1030 + * be invalidated. 1.1031 + */ 1.1032 + 1.1033 +struct ExpandoAndGeneration { 1.1034 + ExpandoAndGeneration() 1.1035 + : expando(JS::UndefinedValue()), 1.1036 + generation(0) 1.1037 + {} 1.1038 + 1.1039 + void Unlink() 1.1040 + { 1.1041 + ++generation; 1.1042 + expando.setUndefined(); 1.1043 + } 1.1044 + 1.1045 + static size_t offsetOfExpando() 1.1046 + { 1.1047 + return offsetof(ExpandoAndGeneration, expando); 1.1048 + } 1.1049 + 1.1050 + static size_t offsetOfGeneration() 1.1051 + { 1.1052 + return offsetof(ExpandoAndGeneration, generation); 1.1053 + } 1.1054 + 1.1055 + JS::Heap<JS::Value> expando; 1.1056 + uint32_t generation; 1.1057 +}; 1.1058 + 1.1059 +typedef enum DOMProxyShadowsResult { 1.1060 + ShadowCheckFailed, 1.1061 + Shadows, 1.1062 + DoesntShadow, 1.1063 + DoesntShadowUnique 1.1064 +} DOMProxyShadowsResult; 1.1065 +typedef DOMProxyShadowsResult 1.1066 +(* DOMProxyShadowsCheck)(JSContext* cx, JS::HandleObject object, JS::HandleId id); 1.1067 +JS_FRIEND_API(void) 1.1068 +SetDOMProxyInformation(const void *domProxyHandlerFamily, uint32_t domProxyExpandoSlot, 1.1069 + DOMProxyShadowsCheck domProxyShadowsCheck); 1.1070 + 1.1071 +const void *GetDOMProxyHandlerFamily(); 1.1072 +uint32_t GetDOMProxyExpandoSlot(); 1.1073 +DOMProxyShadowsCheck GetDOMProxyShadowsCheck(); 1.1074 + 1.1075 +} /* namespace js */ 1.1076 + 1.1077 +/* Implemented in jsdate.cpp. */ 1.1078 + 1.1079 +/* 1.1080 + * Detect whether the internal date value is NaN. (Because failure is 1.1081 + * out-of-band for js_DateGet*) 1.1082 + */ 1.1083 +extern JS_FRIEND_API(bool) 1.1084 +js_DateIsValid(JSObject* obj); 1.1085 + 1.1086 +extern JS_FRIEND_API(double) 1.1087 +js_DateGetMsecSinceEpoch(JSObject *obj); 1.1088 + 1.1089 +/* Implemented in jscntxt.cpp. */ 1.1090 + 1.1091 +/* 1.1092 + * Report an exception, which is currently realized as a printf-style format 1.1093 + * string and its arguments. 1.1094 + */ 1.1095 +typedef enum JSErrNum { 1.1096 +#define MSG_DEF(name, number, count, exception, format) \ 1.1097 + name = number, 1.1098 +#include "js.msg" 1.1099 +#undef MSG_DEF 1.1100 + JSErr_Limit 1.1101 +} JSErrNum; 1.1102 + 1.1103 +extern JS_FRIEND_API(const JSErrorFormatString *) 1.1104 +js_GetErrorMessage(void *userRef, const char *locale, const unsigned errorNumber); 1.1105 + 1.1106 +namespace js { 1.1107 + 1.1108 +// Creates a string of the form |ErrorType: ErrorMessage| for a JSErrorReport, 1.1109 +// which generally matches the toString() behavior of an ErrorObject. 1.1110 +extern JS_FRIEND_API(JSString *) 1.1111 +ErrorReportToString(JSContext *cx, JSErrorReport *reportp); 1.1112 + 1.1113 +} /* namespace js */ 1.1114 + 1.1115 + 1.1116 +/* Implemented in jsclone.cpp. */ 1.1117 + 1.1118 +extern JS_FRIEND_API(uint64_t) 1.1119 +js_GetSCOffset(JSStructuredCloneWriter* writer); 1.1120 + 1.1121 +/* Typed Array functions, implemented in jstypedarray.cpp */ 1.1122 + 1.1123 +namespace js { 1.1124 +namespace ArrayBufferView { 1.1125 + 1.1126 +enum ViewType { 1.1127 + TYPE_INT8 = 0, 1.1128 + TYPE_UINT8, 1.1129 + TYPE_INT16, 1.1130 + TYPE_UINT16, 1.1131 + TYPE_INT32, 1.1132 + TYPE_UINT32, 1.1133 + TYPE_FLOAT32, 1.1134 + TYPE_FLOAT64, 1.1135 + 1.1136 + /* 1.1137 + * Special type that is a uint8_t, but assignments are clamped to [0, 256). 1.1138 + * Treat the raw data type as a uint8_t. 1.1139 + */ 1.1140 + TYPE_UINT8_CLAMPED, 1.1141 + 1.1142 + /* 1.1143 + * Type returned for a DataView. Note that there is no single element type 1.1144 + * in this case. 1.1145 + */ 1.1146 + TYPE_DATAVIEW, 1.1147 + 1.1148 + TYPE_MAX 1.1149 +}; 1.1150 + 1.1151 +} /* namespace ArrayBufferView */ 1.1152 + 1.1153 +} /* namespace js */ 1.1154 + 1.1155 +typedef js::ArrayBufferView::ViewType JSArrayBufferViewType; 1.1156 + 1.1157 +/* 1.1158 + * Create a new typed array with nelements elements. 1.1159 + * 1.1160 + * These functions (except the WithBuffer variants) fill in the array with zeros. 1.1161 + */ 1.1162 + 1.1163 +extern JS_FRIEND_API(JSObject *) 1.1164 +JS_NewInt8Array(JSContext *cx, uint32_t nelements); 1.1165 +extern JS_FRIEND_API(JSObject *) 1.1166 +JS_NewUint8Array(JSContext *cx, uint32_t nelements); 1.1167 +extern JS_FRIEND_API(JSObject *) 1.1168 +JS_NewUint8ClampedArray(JSContext *cx, uint32_t nelements); 1.1169 + 1.1170 +extern JS_FRIEND_API(JSObject *) 1.1171 +JS_NewInt16Array(JSContext *cx, uint32_t nelements); 1.1172 +extern JS_FRIEND_API(JSObject *) 1.1173 +JS_NewUint16Array(JSContext *cx, uint32_t nelements); 1.1174 +extern JS_FRIEND_API(JSObject *) 1.1175 +JS_NewInt32Array(JSContext *cx, uint32_t nelements); 1.1176 +extern JS_FRIEND_API(JSObject *) 1.1177 +JS_NewUint32Array(JSContext *cx, uint32_t nelements); 1.1178 +extern JS_FRIEND_API(JSObject *) 1.1179 +JS_NewFloat32Array(JSContext *cx, uint32_t nelements); 1.1180 +extern JS_FRIEND_API(JSObject *) 1.1181 +JS_NewFloat64Array(JSContext *cx, uint32_t nelements); 1.1182 + 1.1183 +/* 1.1184 + * Create a new typed array and copy in values from the given object. The 1.1185 + * object is used as if it were an array; that is, the new array (if 1.1186 + * successfully created) will have length given by array.length, and its 1.1187 + * elements will be those specified by array[0], array[1], and so on, after 1.1188 + * conversion to the typed array element type. 1.1189 + */ 1.1190 + 1.1191 +extern JS_FRIEND_API(JSObject *) 1.1192 +JS_NewInt8ArrayFromArray(JSContext *cx, JS::HandleObject array); 1.1193 +extern JS_FRIEND_API(JSObject *) 1.1194 +JS_NewUint8ArrayFromArray(JSContext *cx, JS::HandleObject array); 1.1195 +extern JS_FRIEND_API(JSObject *) 1.1196 +JS_NewUint8ClampedArrayFromArray(JSContext *cx, JS::HandleObject array); 1.1197 +extern JS_FRIEND_API(JSObject *) 1.1198 +JS_NewInt16ArrayFromArray(JSContext *cx, JS::HandleObject array); 1.1199 +extern JS_FRIEND_API(JSObject *) 1.1200 +JS_NewUint16ArrayFromArray(JSContext *cx, JS::HandleObject array); 1.1201 +extern JS_FRIEND_API(JSObject *) 1.1202 +JS_NewInt32ArrayFromArray(JSContext *cx, JS::HandleObject array); 1.1203 +extern JS_FRIEND_API(JSObject *) 1.1204 +JS_NewUint32ArrayFromArray(JSContext *cx, JS::HandleObject array); 1.1205 +extern JS_FRIEND_API(JSObject *) 1.1206 +JS_NewFloat32ArrayFromArray(JSContext *cx, JS::HandleObject array); 1.1207 +extern JS_FRIEND_API(JSObject *) 1.1208 +JS_NewFloat64ArrayFromArray(JSContext *cx, JS::HandleObject array); 1.1209 + 1.1210 +/* 1.1211 + * Create a new typed array using the given ArrayBuffer for storage. The 1.1212 + * length value is optional; if -1 is passed, enough elements to use up the 1.1213 + * remainder of the byte array is used as the default value. 1.1214 + */ 1.1215 + 1.1216 +extern JS_FRIEND_API(JSObject *) 1.1217 +JS_NewInt8ArrayWithBuffer(JSContext *cx, JS::HandleObject arrayBuffer, 1.1218 + uint32_t byteOffset, int32_t length); 1.1219 +extern JS_FRIEND_API(JSObject *) 1.1220 +JS_NewUint8ArrayWithBuffer(JSContext *cx, JS::HandleObject arrayBuffer, 1.1221 + uint32_t byteOffset, int32_t length); 1.1222 +extern JS_FRIEND_API(JSObject *) 1.1223 +JS_NewUint8ClampedArrayWithBuffer(JSContext *cx, JS::HandleObject arrayBuffer, 1.1224 + uint32_t byteOffset, int32_t length); 1.1225 +extern JS_FRIEND_API(JSObject *) 1.1226 +JS_NewInt16ArrayWithBuffer(JSContext *cx, JS::HandleObject arrayBuffer, 1.1227 + uint32_t byteOffset, int32_t length); 1.1228 +extern JS_FRIEND_API(JSObject *) 1.1229 +JS_NewUint16ArrayWithBuffer(JSContext *cx, JS::HandleObject arrayBuffer, 1.1230 + uint32_t byteOffset, int32_t length); 1.1231 +extern JS_FRIEND_API(JSObject *) 1.1232 +JS_NewInt32ArrayWithBuffer(JSContext *cx, JS::HandleObject arrayBuffer, 1.1233 + uint32_t byteOffset, int32_t length); 1.1234 +extern JS_FRIEND_API(JSObject *) 1.1235 +JS_NewUint32ArrayWithBuffer(JSContext *cx, JS::HandleObject arrayBuffer, 1.1236 + uint32_t byteOffset, int32_t length); 1.1237 +extern JS_FRIEND_API(JSObject *) 1.1238 +JS_NewFloat32ArrayWithBuffer(JSContext *cx, JS::HandleObject arrayBuffer, 1.1239 + uint32_t byteOffset, int32_t length); 1.1240 +extern JS_FRIEND_API(JSObject *) 1.1241 +JS_NewFloat64ArrayWithBuffer(JSContext *cx, JS::HandleObject arrayBuffer, 1.1242 + uint32_t byteOffset, int32_t length); 1.1243 + 1.1244 +/* 1.1245 + * Create a new ArrayBuffer with the given byte length. 1.1246 + */ 1.1247 +extern JS_FRIEND_API(JSObject *) 1.1248 +JS_NewArrayBuffer(JSContext *cx, uint32_t nbytes); 1.1249 + 1.1250 +/* 1.1251 + * Check whether obj supports JS_GetTypedArray* APIs. Note that this may return 1.1252 + * false if a security wrapper is encountered that denies the unwrapping. If 1.1253 + * this test or one of the JS_Is*Array tests succeeds, then it is safe to call 1.1254 + * the various accessor JSAPI calls defined below. 1.1255 + */ 1.1256 +extern JS_FRIEND_API(bool) 1.1257 +JS_IsTypedArrayObject(JSObject *obj); 1.1258 + 1.1259 +/* 1.1260 + * Check whether obj supports JS_GetArrayBufferView* APIs. Note that this may 1.1261 + * return false if a security wrapper is encountered that denies the 1.1262 + * unwrapping. If this test or one of the more specific tests succeeds, then it 1.1263 + * is safe to call the various ArrayBufferView accessor JSAPI calls defined 1.1264 + * below. 1.1265 + */ 1.1266 +extern JS_FRIEND_API(bool) 1.1267 +JS_IsArrayBufferViewObject(JSObject *obj); 1.1268 + 1.1269 +/* 1.1270 + * Test for specific typed array types (ArrayBufferView subtypes) 1.1271 + */ 1.1272 + 1.1273 +extern JS_FRIEND_API(bool) 1.1274 +JS_IsInt8Array(JSObject *obj); 1.1275 +extern JS_FRIEND_API(bool) 1.1276 +JS_IsUint8Array(JSObject *obj); 1.1277 +extern JS_FRIEND_API(bool) 1.1278 +JS_IsUint8ClampedArray(JSObject *obj); 1.1279 +extern JS_FRIEND_API(bool) 1.1280 +JS_IsInt16Array(JSObject *obj); 1.1281 +extern JS_FRIEND_API(bool) 1.1282 +JS_IsUint16Array(JSObject *obj); 1.1283 +extern JS_FRIEND_API(bool) 1.1284 +JS_IsInt32Array(JSObject *obj); 1.1285 +extern JS_FRIEND_API(bool) 1.1286 +JS_IsUint32Array(JSObject *obj); 1.1287 +extern JS_FRIEND_API(bool) 1.1288 +JS_IsFloat32Array(JSObject *obj); 1.1289 +extern JS_FRIEND_API(bool) 1.1290 +JS_IsFloat64Array(JSObject *obj); 1.1291 + 1.1292 +/* 1.1293 + * Test for specific typed array types (ArrayBufferView subtypes) and return 1.1294 + * the unwrapped object if so, else nullptr. Never throws. 1.1295 + */ 1.1296 + 1.1297 +namespace js { 1.1298 + 1.1299 +extern JS_FRIEND_API(JSObject *) 1.1300 +UnwrapInt8Array(JSObject *obj); 1.1301 +extern JS_FRIEND_API(JSObject *) 1.1302 +UnwrapUint8Array(JSObject *obj); 1.1303 +extern JS_FRIEND_API(JSObject *) 1.1304 +UnwrapUint8ClampedArray(JSObject *obj); 1.1305 +extern JS_FRIEND_API(JSObject *) 1.1306 +UnwrapInt16Array(JSObject *obj); 1.1307 +extern JS_FRIEND_API(JSObject *) 1.1308 +UnwrapUint16Array(JSObject *obj); 1.1309 +extern JS_FRIEND_API(JSObject *) 1.1310 +UnwrapInt32Array(JSObject *obj); 1.1311 +extern JS_FRIEND_API(JSObject *) 1.1312 +UnwrapUint32Array(JSObject *obj); 1.1313 +extern JS_FRIEND_API(JSObject *) 1.1314 +UnwrapFloat32Array(JSObject *obj); 1.1315 +extern JS_FRIEND_API(JSObject *) 1.1316 +UnwrapFloat64Array(JSObject *obj); 1.1317 + 1.1318 +extern JS_FRIEND_API(JSObject *) 1.1319 +UnwrapArrayBuffer(JSObject *obj); 1.1320 + 1.1321 +extern JS_FRIEND_API(JSObject *) 1.1322 +UnwrapArrayBufferView(JSObject *obj); 1.1323 + 1.1324 +namespace detail { 1.1325 + 1.1326 +extern JS_FRIEND_DATA(const Class* const) Int8ArrayClassPtr; 1.1327 +extern JS_FRIEND_DATA(const Class* const) Uint8ArrayClassPtr; 1.1328 +extern JS_FRIEND_DATA(const Class* const) Uint8ClampedArrayClassPtr; 1.1329 +extern JS_FRIEND_DATA(const Class* const) Int16ArrayClassPtr; 1.1330 +extern JS_FRIEND_DATA(const Class* const) Uint16ArrayClassPtr; 1.1331 +extern JS_FRIEND_DATA(const Class* const) Int32ArrayClassPtr; 1.1332 +extern JS_FRIEND_DATA(const Class* const) Uint32ArrayClassPtr; 1.1333 +extern JS_FRIEND_DATA(const Class* const) Float32ArrayClassPtr; 1.1334 +extern JS_FRIEND_DATA(const Class* const) Float64ArrayClassPtr; 1.1335 + 1.1336 +const size_t TypedArrayLengthSlot = 4; 1.1337 + 1.1338 +} // namespace detail 1.1339 + 1.1340 +/* 1.1341 + * Test for specific typed array types (ArrayBufferView subtypes) and return 1.1342 + * the unwrapped object if so, else nullptr. Never throws. 1.1343 + */ 1.1344 + 1.1345 +#define JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Type, type) \ 1.1346 +inline void \ 1.1347 +Get ## Type ## ArrayLengthAndData(JSObject *obj, uint32_t *length, type **data) \ 1.1348 +{ \ 1.1349 + JS_ASSERT(GetObjectClass(obj) == detail::Type ## ArrayClassPtr); \ 1.1350 + const JS::Value &slot = GetReservedSlot(obj, detail::TypedArrayLengthSlot); \ 1.1351 + *length = mozilla::SafeCast<uint32_t>(slot.toInt32()); \ 1.1352 + *data = static_cast<type*>(GetObjectPrivate(obj)); \ 1.1353 +} 1.1354 + 1.1355 +JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Int8, int8_t) 1.1356 +JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Uint8, uint8_t) 1.1357 +JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Uint8Clamped, uint8_t) 1.1358 +JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Int16, int16_t) 1.1359 +JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Uint16, uint16_t) 1.1360 +JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Int32, int32_t) 1.1361 +JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Uint32, uint32_t) 1.1362 +JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Float32, float) 1.1363 +JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Float64, double) 1.1364 + 1.1365 +#undef JS_DEFINE_DATA_AND_LENGTH_ACCESSOR 1.1366 + 1.1367 +// This one isn't inlined because it's rather tricky (by dint of having to deal 1.1368 +// with a dozen-plus classes and varying slot layouts. 1.1369 +extern JS_FRIEND_API(void) 1.1370 +GetArrayBufferViewLengthAndData(JSObject *obj, uint32_t *length, uint8_t **data); 1.1371 + 1.1372 +// This one isn't inlined because there are a bunch of different ArrayBuffer 1.1373 +// classes that would have to be individually handled here. 1.1374 +extern JS_FRIEND_API(void) 1.1375 +GetArrayBufferLengthAndData(JSObject *obj, uint32_t *length, uint8_t **data); 1.1376 + 1.1377 +} // namespace js 1.1378 + 1.1379 +/* 1.1380 + * Unwrap Typed arrays all at once. Return nullptr without throwing if the 1.1381 + * object cannot be viewed as the correct typed array, or the typed array 1.1382 + * object on success, filling both outparameters. 1.1383 + */ 1.1384 +extern JS_FRIEND_API(JSObject *) 1.1385 +JS_GetObjectAsInt8Array(JSObject *obj, uint32_t *length, int8_t **data); 1.1386 +extern JS_FRIEND_API(JSObject *) 1.1387 +JS_GetObjectAsUint8Array(JSObject *obj, uint32_t *length, uint8_t **data); 1.1388 +extern JS_FRIEND_API(JSObject *) 1.1389 +JS_GetObjectAsUint8ClampedArray(JSObject *obj, uint32_t *length, uint8_t **data); 1.1390 +extern JS_FRIEND_API(JSObject *) 1.1391 +JS_GetObjectAsInt16Array(JSObject *obj, uint32_t *length, int16_t **data); 1.1392 +extern JS_FRIEND_API(JSObject *) 1.1393 +JS_GetObjectAsUint16Array(JSObject *obj, uint32_t *length, uint16_t **data); 1.1394 +extern JS_FRIEND_API(JSObject *) 1.1395 +JS_GetObjectAsInt32Array(JSObject *obj, uint32_t *length, int32_t **data); 1.1396 +extern JS_FRIEND_API(JSObject *) 1.1397 +JS_GetObjectAsUint32Array(JSObject *obj, uint32_t *length, uint32_t **data); 1.1398 +extern JS_FRIEND_API(JSObject *) 1.1399 +JS_GetObjectAsFloat32Array(JSObject *obj, uint32_t *length, float **data); 1.1400 +extern JS_FRIEND_API(JSObject *) 1.1401 +JS_GetObjectAsFloat64Array(JSObject *obj, uint32_t *length, double **data); 1.1402 +extern JS_FRIEND_API(JSObject *) 1.1403 +JS_GetObjectAsArrayBufferView(JSObject *obj, uint32_t *length, uint8_t **data); 1.1404 +extern JS_FRIEND_API(JSObject *) 1.1405 +JS_GetObjectAsArrayBuffer(JSObject *obj, uint32_t *length, uint8_t **data); 1.1406 + 1.1407 +/* 1.1408 + * Get the type of elements in a typed array, or TYPE_DATAVIEW if a DataView. 1.1409 + * 1.1410 + * |obj| must have passed a JS_IsArrayBufferView/JS_Is*Array test, or somehow 1.1411 + * be known that it would pass such a test: it is an ArrayBufferView or a 1.1412 + * wrapper of an ArrayBufferView, and the unwrapping will succeed. 1.1413 + */ 1.1414 +extern JS_FRIEND_API(JSArrayBufferViewType) 1.1415 +JS_GetArrayBufferViewType(JSObject *obj); 1.1416 + 1.1417 +/* 1.1418 + * Check whether obj supports the JS_GetArrayBuffer* APIs. Note that this may 1.1419 + * return false if a security wrapper is encountered that denies the 1.1420 + * unwrapping. If this test succeeds, then it is safe to call the various 1.1421 + * accessor JSAPI calls defined below. 1.1422 + */ 1.1423 +extern JS_FRIEND_API(bool) 1.1424 +JS_IsArrayBufferObject(JSObject *obj); 1.1425 + 1.1426 +/* 1.1427 + * Return the available byte length of an array buffer. 1.1428 + * 1.1429 + * |obj| must have passed a JS_IsArrayBufferObject test, or somehow be known 1.1430 + * that it would pass such a test: it is an ArrayBuffer or a wrapper of an 1.1431 + * ArrayBuffer, and the unwrapping will succeed. 1.1432 + */ 1.1433 +extern JS_FRIEND_API(uint32_t) 1.1434 +JS_GetArrayBufferByteLength(JSObject *obj); 1.1435 + 1.1436 +/* 1.1437 + * Check whether the obj is ArrayBufferObject and memory mapped. Note that this 1.1438 + * may return false if a security wrapper is encountered that denies the 1.1439 + * unwrapping. 1.1440 + */ 1.1441 +extern JS_FRIEND_API(bool) 1.1442 +JS_IsMappedArrayBufferObject(JSObject *obj); 1.1443 + 1.1444 +/* 1.1445 + * Return the number of elements in a typed array. 1.1446 + * 1.1447 + * |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow 1.1448 + * be known that it would pass such a test: it is a typed array or a wrapper of 1.1449 + * a typed array, and the unwrapping will succeed. 1.1450 + */ 1.1451 +extern JS_FRIEND_API(uint32_t) 1.1452 +JS_GetTypedArrayLength(JSObject *obj); 1.1453 + 1.1454 +/* 1.1455 + * Return the byte offset from the start of an array buffer to the start of a 1.1456 + * typed array view. 1.1457 + * 1.1458 + * |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow 1.1459 + * be known that it would pass such a test: it is a typed array or a wrapper of 1.1460 + * a typed array, and the unwrapping will succeed. 1.1461 + */ 1.1462 +extern JS_FRIEND_API(uint32_t) 1.1463 +JS_GetTypedArrayByteOffset(JSObject *obj); 1.1464 + 1.1465 +/* 1.1466 + * Return the byte length of a typed array. 1.1467 + * 1.1468 + * |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow 1.1469 + * be known that it would pass such a test: it is a typed array or a wrapper of 1.1470 + * a typed array, and the unwrapping will succeed. 1.1471 + */ 1.1472 +extern JS_FRIEND_API(uint32_t) 1.1473 +JS_GetTypedArrayByteLength(JSObject *obj); 1.1474 + 1.1475 +/* 1.1476 + * Check whether obj supports JS_ArrayBufferView* APIs. Note that this may 1.1477 + * return false if a security wrapper is encountered that denies the 1.1478 + * unwrapping. 1.1479 + */ 1.1480 +extern JS_FRIEND_API(bool) 1.1481 +JS_IsArrayBufferViewObject(JSObject *obj); 1.1482 + 1.1483 +/* 1.1484 + * More generic name for JS_GetTypedArrayByteLength to cover DataViews as well 1.1485 + */ 1.1486 +extern JS_FRIEND_API(uint32_t) 1.1487 +JS_GetArrayBufferViewByteLength(JSObject *obj); 1.1488 + 1.1489 +/* 1.1490 + * Return a pointer to the start of the data referenced by a typed array. The 1.1491 + * data is still owned by the typed array, and should not be modified on 1.1492 + * another thread. Furthermore, the pointer can become invalid on GC (if the 1.1493 + * data is small and fits inside the array's GC header), so callers must take 1.1494 + * care not to hold on across anything that could GC. 1.1495 + * 1.1496 + * |obj| must have passed a JS_Is*Array test, or somehow be known that it would 1.1497 + * pass such a test: it is a typed array or a wrapper of a typed array, and the 1.1498 + * unwrapping will succeed. 1.1499 + */ 1.1500 + 1.1501 +extern JS_FRIEND_API(uint8_t *) 1.1502 +JS_GetArrayBufferData(JSObject *obj); 1.1503 +extern JS_FRIEND_API(int8_t *) 1.1504 +JS_GetInt8ArrayData(JSObject *obj); 1.1505 +extern JS_FRIEND_API(uint8_t *) 1.1506 +JS_GetUint8ArrayData(JSObject *obj); 1.1507 +extern JS_FRIEND_API(uint8_t *) 1.1508 +JS_GetUint8ClampedArrayData(JSObject *obj); 1.1509 +extern JS_FRIEND_API(int16_t *) 1.1510 +JS_GetInt16ArrayData(JSObject *obj); 1.1511 +extern JS_FRIEND_API(uint16_t *) 1.1512 +JS_GetUint16ArrayData(JSObject *obj); 1.1513 +extern JS_FRIEND_API(int32_t *) 1.1514 +JS_GetInt32ArrayData(JSObject *obj); 1.1515 +extern JS_FRIEND_API(uint32_t *) 1.1516 +JS_GetUint32ArrayData(JSObject *obj); 1.1517 +extern JS_FRIEND_API(float *) 1.1518 +JS_GetFloat32ArrayData(JSObject *obj); 1.1519 +extern JS_FRIEND_API(double *) 1.1520 +JS_GetFloat64ArrayData(JSObject *obj); 1.1521 + 1.1522 +/* 1.1523 + * Stable versions of the above functions where the buffer remains valid as long 1.1524 + * as the object is live. 1.1525 + */ 1.1526 +extern JS_FRIEND_API(uint8_t *) 1.1527 +JS_GetStableArrayBufferData(JSContext *cx, JS::HandleObject obj); 1.1528 + 1.1529 +/* 1.1530 + * Same as above, but for any kind of ArrayBufferView. Prefer the type-specific 1.1531 + * versions when possible. 1.1532 + */ 1.1533 +extern JS_FRIEND_API(void *) 1.1534 +JS_GetArrayBufferViewData(JSObject *obj); 1.1535 + 1.1536 +/* 1.1537 + * Return the ArrayBuffer underlying an ArrayBufferView. If the buffer has been 1.1538 + * neutered, this will still return the neutered buffer. |obj| must be an 1.1539 + * object that would return true for JS_IsArrayBufferViewObject(). 1.1540 + */ 1.1541 +extern JS_FRIEND_API(JSObject *) 1.1542 +JS_GetArrayBufferViewBuffer(JSContext *cx, JSObject *obj); 1.1543 + 1.1544 +typedef enum { 1.1545 + ChangeData, 1.1546 + KeepData 1.1547 +} NeuterDataDisposition; 1.1548 + 1.1549 +/* 1.1550 + * Set an ArrayBuffer's length to 0 and neuter all of its views. 1.1551 + * 1.1552 + * The |changeData| argument is a hint to inform internal behavior with respect 1.1553 + * to the internal pointer to the ArrayBuffer's data after being neutered. 1.1554 + * There is no guarantee it will be respected. But if it is respected, the 1.1555 + * ArrayBuffer's internal data pointer will, or will not, have changed 1.1556 + * accordingly. 1.1557 + */ 1.1558 +extern JS_FRIEND_API(bool) 1.1559 +JS_NeuterArrayBuffer(JSContext *cx, JS::HandleObject obj, 1.1560 + NeuterDataDisposition changeData); 1.1561 + 1.1562 +/* 1.1563 + * Check whether obj supports JS_GetDataView* APIs. 1.1564 + */ 1.1565 +JS_FRIEND_API(bool) 1.1566 +JS_IsDataViewObject(JSObject *obj); 1.1567 + 1.1568 +/* 1.1569 + * Return the byte offset of a data view into its array buffer. |obj| must be a 1.1570 + * DataView. 1.1571 + * 1.1572 + * |obj| must have passed a JS_IsDataViewObject test, or somehow be known that 1.1573 + * it would pass such a test: it is a data view or a wrapper of a data view, 1.1574 + * and the unwrapping will succeed. 1.1575 + */ 1.1576 +JS_FRIEND_API(uint32_t) 1.1577 +JS_GetDataViewByteOffset(JSObject *obj); 1.1578 + 1.1579 +/* 1.1580 + * Return the byte length of a data view. 1.1581 + * 1.1582 + * |obj| must have passed a JS_IsDataViewObject test, or somehow be known that 1.1583 + * it would pass such a test: it is a data view or a wrapper of a data view, 1.1584 + * and the unwrapping will succeed. If cx is nullptr, then DEBUG builds may be 1.1585 + * unable to assert when unwrapping should be disallowed. 1.1586 + */ 1.1587 +JS_FRIEND_API(uint32_t) 1.1588 +JS_GetDataViewByteLength(JSObject *obj); 1.1589 + 1.1590 +/* 1.1591 + * Return a pointer to the beginning of the data referenced by a DataView. 1.1592 + * 1.1593 + * |obj| must have passed a JS_IsDataViewObject test, or somehow be known that 1.1594 + * it would pass such a test: it is a data view or a wrapper of a data view, 1.1595 + * and the unwrapping will succeed. If cx is nullptr, then DEBUG builds may be 1.1596 + * unable to assert when unwrapping should be disallowed. 1.1597 + */ 1.1598 +JS_FRIEND_API(void *) 1.1599 +JS_GetDataViewData(JSObject *obj); 1.1600 + 1.1601 +namespace js { 1.1602 + 1.1603 +/* 1.1604 + * Add a watchpoint -- in the Object.prototype.watch sense -- to |obj| for the 1.1605 + * property |id|, using the callable object |callable| as the function to be 1.1606 + * called for notifications. 1.1607 + * 1.1608 + * This is an internal function exposed -- temporarily -- only so that DOM 1.1609 + * proxies can be watchable. Don't use it! We'll soon kill off the 1.1610 + * Object.prototype.{,un}watch functions, at which point this will go too. 1.1611 + */ 1.1612 +extern JS_FRIEND_API(bool) 1.1613 +WatchGuts(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject callable); 1.1614 + 1.1615 +/* 1.1616 + * Remove a watchpoint -- in the Object.prototype.watch sense -- from |obj| for 1.1617 + * the property |id|. 1.1618 + * 1.1619 + * This is an internal function exposed -- temporarily -- only so that DOM 1.1620 + * proxies can be watchable. Don't use it! We'll soon kill off the 1.1621 + * Object.prototype.{,un}watch functions, at which point this will go too. 1.1622 + */ 1.1623 +extern JS_FRIEND_API(bool) 1.1624 +UnwatchGuts(JSContext *cx, JS::HandleObject obj, JS::HandleId id); 1.1625 + 1.1626 +} // namespace js 1.1627 + 1.1628 +/* 1.1629 + * A class, expected to be passed by value, which represents the CallArgs for a 1.1630 + * JSJitGetterOp. 1.1631 + */ 1.1632 +class JSJitGetterCallArgs : protected JS::MutableHandleValue 1.1633 +{ 1.1634 + public: 1.1635 + explicit JSJitGetterCallArgs(const JS::CallArgs& args) 1.1636 + : JS::MutableHandleValue(args.rval()) 1.1637 + {} 1.1638 + 1.1639 + explicit JSJitGetterCallArgs(JS::RootedValue* rooted) 1.1640 + : JS::MutableHandleValue(rooted) 1.1641 + {} 1.1642 + 1.1643 + JS::MutableHandleValue rval() { 1.1644 + return *this; 1.1645 + } 1.1646 +}; 1.1647 + 1.1648 +/* 1.1649 + * A class, expected to be passed by value, which represents the CallArgs for a 1.1650 + * JSJitSetterOp. 1.1651 + */ 1.1652 +class JSJitSetterCallArgs : protected JS::MutableHandleValue 1.1653 +{ 1.1654 + public: 1.1655 + explicit JSJitSetterCallArgs(const JS::CallArgs& args) 1.1656 + : JS::MutableHandleValue(args[0]) 1.1657 + {} 1.1658 + 1.1659 + JS::MutableHandleValue operator[](unsigned i) { 1.1660 + MOZ_ASSERT(i == 0); 1.1661 + return *this; 1.1662 + } 1.1663 + 1.1664 + unsigned length() const { return 1; } 1.1665 + 1.1666 + // Add get() or maybe hasDefined() as needed 1.1667 +}; 1.1668 + 1.1669 +struct JSJitMethodCallArgsTraits; 1.1670 + 1.1671 +/* 1.1672 + * A class, expected to be passed by reference, which represents the CallArgs 1.1673 + * for a JSJitMethodOp. 1.1674 + */ 1.1675 +class JSJitMethodCallArgs : protected JS::detail::CallArgsBase<JS::detail::NoUsedRval> 1.1676 +{ 1.1677 + private: 1.1678 + typedef JS::detail::CallArgsBase<JS::detail::NoUsedRval> Base; 1.1679 + friend struct JSJitMethodCallArgsTraits; 1.1680 + 1.1681 + public: 1.1682 + explicit JSJitMethodCallArgs(const JS::CallArgs& args) { 1.1683 + argv_ = args.array(); 1.1684 + argc_ = args.length(); 1.1685 + } 1.1686 + 1.1687 + JS::MutableHandleValue rval() const { 1.1688 + return Base::rval(); 1.1689 + } 1.1690 + 1.1691 + unsigned length() const { return Base::length(); } 1.1692 + 1.1693 + JS::MutableHandleValue operator[](unsigned i) const { 1.1694 + return Base::operator[](i); 1.1695 + } 1.1696 + 1.1697 + bool hasDefined(unsigned i) const { 1.1698 + return Base::hasDefined(i); 1.1699 + } 1.1700 + 1.1701 + JSObject &callee() const { 1.1702 + // We can't use Base::callee() because that will try to poke at 1.1703 + // this->usedRval_, which we don't have. 1.1704 + return argv_[-2].toObject(); 1.1705 + } 1.1706 + 1.1707 + // Add get() as needed 1.1708 +}; 1.1709 + 1.1710 +struct JSJitMethodCallArgsTraits 1.1711 +{ 1.1712 + static const size_t offsetOfArgv = offsetof(JSJitMethodCallArgs, argv_); 1.1713 + static const size_t offsetOfArgc = offsetof(JSJitMethodCallArgs, argc_); 1.1714 +}; 1.1715 + 1.1716 +/* 1.1717 + * This struct contains metadata passed from the DOM to the JS Engine for JIT 1.1718 + * optimizations on DOM property accessors. Eventually, this should be made 1.1719 + * available to general JSAPI users, but we are not currently ready to do so. 1.1720 + */ 1.1721 +typedef bool 1.1722 +(* JSJitGetterOp)(JSContext *cx, JS::HandleObject thisObj, 1.1723 + void *specializedThis, JSJitGetterCallArgs args); 1.1724 +typedef bool 1.1725 +(* JSJitSetterOp)(JSContext *cx, JS::HandleObject thisObj, 1.1726 + void *specializedThis, JSJitSetterCallArgs args); 1.1727 +typedef bool 1.1728 +(* JSJitMethodOp)(JSContext *cx, JS::HandleObject thisObj, 1.1729 + void *specializedThis, const JSJitMethodCallArgs& args); 1.1730 + 1.1731 +struct JSJitInfo { 1.1732 + enum OpType { 1.1733 + Getter, 1.1734 + Setter, 1.1735 + Method, 1.1736 + ParallelNative, 1.1737 + StaticMethod, 1.1738 + // Must be last 1.1739 + OpTypeCount 1.1740 + }; 1.1741 + 1.1742 + enum ArgType { 1.1743 + // Basic types 1.1744 + String = (1 << 0), 1.1745 + Integer = (1 << 1), // Only 32-bit or less 1.1746 + Double = (1 << 2), // Maybe we want to add Float sometime too 1.1747 + Boolean = (1 << 3), 1.1748 + Object = (1 << 4), 1.1749 + Null = (1 << 5), 1.1750 + 1.1751 + // And derived types 1.1752 + Numeric = Integer | Double, 1.1753 + // Should "Primitive" use the WebIDL definition, which 1.1754 + // excludes string and null, or the typical JS one that includes them? 1.1755 + Primitive = Numeric | Boolean | Null | String, 1.1756 + ObjectOrNull = Object | Null, 1.1757 + Any = ObjectOrNull | Primitive, 1.1758 + 1.1759 + // Our sentinel value. 1.1760 + ArgTypeListEnd = (1 << 31) 1.1761 + }; 1.1762 + 1.1763 + static_assert(Any & String, "Any must include String."); 1.1764 + static_assert(Any & Integer, "Any must include Integer."); 1.1765 + static_assert(Any & Double, "Any must include Double."); 1.1766 + static_assert(Any & Boolean, "Any must include Boolean."); 1.1767 + static_assert(Any & Object, "Any must include Object."); 1.1768 + static_assert(Any & Null, "Any must include Null."); 1.1769 + 1.1770 + enum AliasSet { 1.1771 + // An enum that describes what this getter/setter/method aliases. This 1.1772 + // determines what things can be hoisted past this call, and if this 1.1773 + // call is movable what it can be hoisted past. 1.1774 + 1.1775 + // Alias nothing: a constant value, getting it can't affect any other 1.1776 + // values, nothing can affect it. 1.1777 + AliasNone, 1.1778 + 1.1779 + // Alias things that can modify the DOM but nothing else. Doing the 1.1780 + // call can't affect the behavior of any other function. 1.1781 + AliasDOMSets, 1.1782 + 1.1783 + // Alias the world. Calling this can change arbitrary values anywhere 1.1784 + // in the system. Most things fall in this bucket. 1.1785 + AliasEverything, 1.1786 + 1.1787 + // Must be last. 1.1788 + AliasSetCount 1.1789 + }; 1.1790 + 1.1791 + bool hasParallelNative() const 1.1792 + { 1.1793 + return type() == ParallelNative; 1.1794 + } 1.1795 + 1.1796 + bool needsOuterizedThisObject() const 1.1797 + { 1.1798 + return type() != Getter && type() != Setter; 1.1799 + } 1.1800 + 1.1801 + bool isTypedMethodJitInfo() const 1.1802 + { 1.1803 + return isTypedMethod; 1.1804 + } 1.1805 + 1.1806 + OpType type() const 1.1807 + { 1.1808 + return OpType(type_); 1.1809 + } 1.1810 + 1.1811 + AliasSet aliasSet() const 1.1812 + { 1.1813 + return AliasSet(aliasSet_); 1.1814 + } 1.1815 + 1.1816 + JSValueType returnType() const 1.1817 + { 1.1818 + return JSValueType(returnType_); 1.1819 + } 1.1820 + 1.1821 + union { 1.1822 + JSJitGetterOp getter; 1.1823 + JSJitSetterOp setter; 1.1824 + JSJitMethodOp method; 1.1825 + /* An alternative native that's safe to call in parallel mode. */ 1.1826 + JSParallelNative parallelNative; 1.1827 + /* A DOM static method, used for Promise wrappers */ 1.1828 + JSNative staticMethod; 1.1829 + }; 1.1830 + 1.1831 + uint16_t protoID; 1.1832 + uint16_t depth; 1.1833 + 1.1834 + // These fields are carefully packed to take up 4 bytes. If you need more 1.1835 + // bits for whatever reason, please see if you can steal bits from existing 1.1836 + // fields before adding more members to this structure. 1.1837 + 1.1838 +#define JITINFO_OP_TYPE_BITS 4 1.1839 +#define JITINFO_ALIAS_SET_BITS 4 1.1840 +#define JITINFO_RETURN_TYPE_BITS 8 1.1841 + 1.1842 + // The OpType that says what sort of function we are. 1.1843 + uint32_t type_ : JITINFO_OP_TYPE_BITS; 1.1844 + 1.1845 + // The alias set for this op. This is a _minimal_ alias set; in 1.1846 + // particular for a method it does not include whatever argument 1.1847 + // conversions might do. That's covered by argTypes and runtime 1.1848 + // analysis of the actual argument types being passed in. 1.1849 + uint32_t aliasSet_ : JITINFO_ALIAS_SET_BITS; 1.1850 + 1.1851 + // The return type tag. Might be JSVAL_TYPE_UNKNOWN. 1.1852 + uint32_t returnType_ : JITINFO_RETURN_TYPE_BITS; 1.1853 + 1.1854 + static_assert(OpTypeCount <= (1 << JITINFO_OP_TYPE_BITS), 1.1855 + "Not enough space for OpType"); 1.1856 + static_assert(AliasSetCount <= (1 << JITINFO_ALIAS_SET_BITS), 1.1857 + "Not enough space for AliasSet"); 1.1858 + static_assert((sizeof(JSValueType) * 8) <= JITINFO_RETURN_TYPE_BITS, 1.1859 + "Not enough space for JSValueType"); 1.1860 + 1.1861 +#undef JITINFO_RETURN_TYPE_BITS 1.1862 +#undef JITINFO_ALIAS_SET_BITS 1.1863 +#undef JITINFO_OP_TYPE_BITS 1.1864 + 1.1865 + uint32_t isInfallible : 1; /* Is op fallible? False in setters. */ 1.1866 + uint32_t isMovable : 1; /* Is op movable? To be movable the op must 1.1867 + not AliasEverything, but even that might 1.1868 + not be enough (e.g. in cases when it can 1.1869 + throw). */ 1.1870 + // XXXbz should we have a JSValueType for the type of the member? 1.1871 + uint32_t isInSlot : 1; /* True if this is a getter that can get a member 1.1872 + from a slot of the "this" object directly. */ 1.1873 + uint32_t isTypedMethod : 1; /* True if this is an instance of 1.1874 + JSTypedMethodJitInfo. */ 1.1875 + uint32_t slotIndex : 12; /* If isInSlot is true, the index of the slot to 1.1876 + get the value from. Otherwise 0. */ 1.1877 +}; 1.1878 + 1.1879 +static_assert(sizeof(JSJitInfo) == (sizeof(void*) + 2 * sizeof(uint32_t)), 1.1880 + "There are several thousand instances of JSJitInfo stored in " 1.1881 + "a binary. Please don't increase its space requirements without " 1.1882 + "verifying that there is no other way forward (better packing, " 1.1883 + "smaller datatypes for fields, subclassing, etc.)."); 1.1884 + 1.1885 +struct JSTypedMethodJitInfo 1.1886 +{ 1.1887 + // We use C-style inheritance here, rather than C++ style inheritance 1.1888 + // because not all compilers support brace-initialization for non-aggregate 1.1889 + // classes. Using C++ style inheritance and constructors instead of 1.1890 + // brace-initialization would also force the creation of static 1.1891 + // constructors (on some compilers) when JSJitInfo and JSTypedMethodJitInfo 1.1892 + // structures are declared. Since there can be several thousand of these 1.1893 + // structures present and we want to have roughly equivalent performance 1.1894 + // across a range of compilers, we do things manually. 1.1895 + JSJitInfo base; 1.1896 + 1.1897 + const JSJitInfo::ArgType* const argTypes; /* For a method, a list of sets of 1.1898 + types that the function 1.1899 + expects. This can be used, 1.1900 + for example, to figure out 1.1901 + when argument coercions can 1.1902 + have side-effects. */ 1.1903 +}; 1.1904 + 1.1905 +namespace JS { 1.1906 +namespace detail { 1.1907 + 1.1908 +/* NEVER DEFINED, DON'T USE. For use by JS_CAST_PARALLEL_NATIVE_TO only. */ 1.1909 +inline int CheckIsParallelNative(JSParallelNative parallelNative); 1.1910 + 1.1911 +} // namespace detail 1.1912 +} // namespace JS 1.1913 + 1.1914 +#define JS_CAST_PARALLEL_NATIVE_TO(v, To) \ 1.1915 + (static_cast<void>(sizeof(JS::detail::CheckIsParallelNative(v))), \ 1.1916 + reinterpret_cast<To>(v)) 1.1917 + 1.1918 +/* 1.1919 + * You may ask yourself: why do we define a wrapper around a wrapper here? 1.1920 + * The answer is that some compilers don't understand initializing a union 1.1921 + * as we do below with a construct like: 1.1922 + * 1.1923 + * reinterpret_cast<JSJitGetterOp>(JSParallelNativeThreadSafeWrapper<op>) 1.1924 + * 1.1925 + * (We need the reinterpret_cast because we must initialize the union with 1.1926 + * a datum of the type of the union's first member.) 1.1927 + * 1.1928 + * Presumably this has something to do with template instantiation. 1.1929 + * Initializing with a normal function pointer seems to work fine. Hence 1.1930 + * the ugliness that you see before you. 1.1931 + */ 1.1932 +#define JS_JITINFO_NATIVE_PARALLEL(infoName, parallelOp) \ 1.1933 + const JSJitInfo infoName = \ 1.1934 + {{JS_CAST_PARALLEL_NATIVE_TO(parallelOp, JSJitGetterOp)},0,0,JSJitInfo::ParallelNative,JSJitInfo::AliasEverything,JSVAL_TYPE_MISSING,false,false,false,false,0} 1.1935 + 1.1936 +#define JS_JITINFO_NATIVE_PARALLEL_THREADSAFE(infoName, wrapperName, serialOp) \ 1.1937 + bool wrapperName##_ParallelNativeThreadSafeWrapper(js::ForkJoinContext *cx, unsigned argc, \ 1.1938 + JS::Value *vp) \ 1.1939 + { \ 1.1940 + return JSParallelNativeThreadSafeWrapper<serialOp>(cx, argc, vp); \ 1.1941 + } \ 1.1942 + JS_JITINFO_NATIVE_PARALLEL(infoName, wrapperName##_ParallelNativeThreadSafeWrapper) 1.1943 + 1.1944 +static MOZ_ALWAYS_INLINE const JSJitInfo * 1.1945 +FUNCTION_VALUE_TO_JITINFO(const JS::Value& v) 1.1946 +{ 1.1947 + JS_ASSERT(js::GetObjectClass(&v.toObject()) == js::FunctionClassPtr); 1.1948 + return reinterpret_cast<js::shadow::Function *>(&v.toObject())->jitinfo; 1.1949 +} 1.1950 + 1.1951 +/* Statically asserted in jsfun.h. */ 1.1952 +static const unsigned JS_FUNCTION_INTERPRETED_BIT = 0x1; 1.1953 + 1.1954 +static MOZ_ALWAYS_INLINE void 1.1955 +SET_JITINFO(JSFunction * func, const JSJitInfo *info) 1.1956 +{ 1.1957 + js::shadow::Function *fun = reinterpret_cast<js::shadow::Function *>(func); 1.1958 + JS_ASSERT(!(fun->flags & JS_FUNCTION_INTERPRETED_BIT)); 1.1959 + fun->jitinfo = info; 1.1960 +} 1.1961 + 1.1962 +/* 1.1963 + * Engine-internal extensions of jsid. This code is here only until we 1.1964 + * eliminate Gecko's dependencies on it! 1.1965 + */ 1.1966 + 1.1967 +static MOZ_ALWAYS_INLINE jsid 1.1968 +JSID_FROM_BITS(size_t bits) 1.1969 +{ 1.1970 + jsid id; 1.1971 + JSID_BITS(id) = bits; 1.1972 + return id; 1.1973 +} 1.1974 + 1.1975 +namespace js { 1.1976 +namespace detail { 1.1977 +bool IdMatchesAtom(jsid id, JSAtom *atom); 1.1978 +} 1.1979 +} 1.1980 + 1.1981 +/* 1.1982 + * Must not be used on atoms that are representable as integer jsids. 1.1983 + * Prefer NameToId or AtomToId over this function: 1.1984 + * 1.1985 + * A PropertyName is an atom that does not contain an integer in the range 1.1986 + * [0, UINT32_MAX]. However, jsid can only hold an integer in the range 1.1987 + * [0, JSID_INT_MAX] (where JSID_INT_MAX == 2^31-1). Thus, for the range of 1.1988 + * integers (JSID_INT_MAX, UINT32_MAX], to represent as a jsid 'id', it must be 1.1989 + * the case JSID_IS_ATOM(id) and !JSID_TO_ATOM(id)->isPropertyName(). In most 1.1990 + * cases when creating a jsid, code does not have to care about this corner 1.1991 + * case because: 1.1992 + * 1.1993 + * - When given an arbitrary JSAtom*, AtomToId must be used, which checks for 1.1994 + * integer atoms representable as integer jsids, and does this conversion. 1.1995 + * 1.1996 + * - When given a PropertyName*, NameToId can be used which which does not need 1.1997 + * to do any dynamic checks. 1.1998 + * 1.1999 + * Thus, it is only the rare third case which needs this function, which 1.2000 + * handles any JSAtom* that is known not to be representable with an int jsid. 1.2001 + */ 1.2002 +static MOZ_ALWAYS_INLINE jsid 1.2003 +NON_INTEGER_ATOM_TO_JSID(JSAtom *atom) 1.2004 +{ 1.2005 + JS_ASSERT(((size_t)atom & 0x7) == 0); 1.2006 + jsid id = JSID_FROM_BITS((size_t)atom); 1.2007 + JS_ASSERT(js::detail::IdMatchesAtom(id, atom)); 1.2008 + return id; 1.2009 +} 1.2010 + 1.2011 +/* All strings stored in jsids are atomized, but are not necessarily property names. */ 1.2012 +static MOZ_ALWAYS_INLINE bool 1.2013 +JSID_IS_ATOM(jsid id) 1.2014 +{ 1.2015 + return JSID_IS_STRING(id); 1.2016 +} 1.2017 + 1.2018 +static MOZ_ALWAYS_INLINE bool 1.2019 +JSID_IS_ATOM(jsid id, JSAtom *atom) 1.2020 +{ 1.2021 + return id == JSID_FROM_BITS((size_t)atom); 1.2022 +} 1.2023 + 1.2024 +static MOZ_ALWAYS_INLINE JSAtom * 1.2025 +JSID_TO_ATOM(jsid id) 1.2026 +{ 1.2027 + return (JSAtom *)JSID_TO_STRING(id); 1.2028 +} 1.2029 + 1.2030 +JS_STATIC_ASSERT(sizeof(jsid) == sizeof(void*)); 1.2031 + 1.2032 +namespace js { 1.2033 + 1.2034 +static MOZ_ALWAYS_INLINE JS::Value 1.2035 +IdToValue(jsid id) 1.2036 +{ 1.2037 + if (JSID_IS_STRING(id)) 1.2038 + return JS::StringValue(JSID_TO_STRING(id)); 1.2039 + if (MOZ_LIKELY(JSID_IS_INT(id))) 1.2040 + return JS::Int32Value(JSID_TO_INT(id)); 1.2041 + if (MOZ_LIKELY(JSID_IS_OBJECT(id))) 1.2042 + return JS::ObjectValue(*JSID_TO_OBJECT(id)); 1.2043 + JS_ASSERT(JSID_IS_VOID(id)); 1.2044 + return JS::UndefinedValue(); 1.2045 +} 1.2046 + 1.2047 +extern JS_FRIEND_API(bool) 1.2048 +IsTypedArrayThisCheck(JS::IsAcceptableThis test); 1.2049 + 1.2050 +/* 1.2051 + * If the embedder has registered a default JSContext callback, returns the 1.2052 + * result of the callback. Otherwise, asserts that |rt| has exactly one 1.2053 + * JSContext associated with it, and returns that context. 1.2054 + */ 1.2055 +extern JS_FRIEND_API(JSContext *) 1.2056 +DefaultJSContext(JSRuntime *rt); 1.2057 + 1.2058 +typedef JSContext* 1.2059 +(* DefaultJSContextCallback)(JSRuntime *rt); 1.2060 + 1.2061 +JS_FRIEND_API(void) 1.2062 +SetDefaultJSContextCallback(JSRuntime *rt, DefaultJSContextCallback cb); 1.2063 + 1.2064 +/* 1.2065 + * To help embedders enforce their invariants, we allow them to specify in 1.2066 + * advance which JSContext should be passed to JSAPI calls. If this is set 1.2067 + * to a non-null value, the assertSameCompartment machinery does double- 1.2068 + * duty (in debug builds) to verify that it matches the cx being used. 1.2069 + */ 1.2070 +#ifdef DEBUG 1.2071 +JS_FRIEND_API(void) 1.2072 +Debug_SetActiveJSContext(JSRuntime *rt, JSContext *cx); 1.2073 +#else 1.2074 +inline void 1.2075 +Debug_SetActiveJSContext(JSRuntime *rt, JSContext *cx) {}; 1.2076 +#endif 1.2077 + 1.2078 + 1.2079 +enum CTypesActivityType { 1.2080 + CTYPES_CALL_BEGIN, 1.2081 + CTYPES_CALL_END, 1.2082 + CTYPES_CALLBACK_BEGIN, 1.2083 + CTYPES_CALLBACK_END 1.2084 +}; 1.2085 + 1.2086 +typedef void 1.2087 +(* CTypesActivityCallback)(JSContext *cx, CTypesActivityType type); 1.2088 + 1.2089 +/* 1.2090 + * Sets a callback that is run whenever js-ctypes is about to be used when 1.2091 + * calling into C. 1.2092 + */ 1.2093 +JS_FRIEND_API(void) 1.2094 +SetCTypesActivityCallback(JSRuntime *rt, CTypesActivityCallback cb); 1.2095 + 1.2096 +class JS_FRIEND_API(AutoCTypesActivityCallback) { 1.2097 + private: 1.2098 + JSContext *cx; 1.2099 + CTypesActivityCallback callback; 1.2100 + CTypesActivityType endType; 1.2101 + MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER 1.2102 + 1.2103 + public: 1.2104 + AutoCTypesActivityCallback(JSContext *cx, CTypesActivityType beginType, 1.2105 + CTypesActivityType endType 1.2106 + MOZ_GUARD_OBJECT_NOTIFIER_PARAM); 1.2107 + ~AutoCTypesActivityCallback() { 1.2108 + DoEndCallback(); 1.2109 + } 1.2110 + void DoEndCallback() { 1.2111 + if (callback) { 1.2112 + callback(cx, endType); 1.2113 + callback = nullptr; 1.2114 + } 1.2115 + } 1.2116 +}; 1.2117 + 1.2118 +typedef bool 1.2119 +(* ObjectMetadataCallback)(JSContext *cx, JSObject **pmetadata); 1.2120 + 1.2121 +/* 1.2122 + * Specify a callback to invoke when creating each JS object in the current 1.2123 + * compartment, which may return a metadata object to associate with the 1.2124 + * object. Objects with different metadata have different shape hierarchies, 1.2125 + * so for efficiency, objects should generally try to share metadata objects. 1.2126 + */ 1.2127 +JS_FRIEND_API(void) 1.2128 +SetObjectMetadataCallback(JSContext *cx, ObjectMetadataCallback callback); 1.2129 + 1.2130 +/* Manipulate the metadata associated with an object. */ 1.2131 + 1.2132 +JS_FRIEND_API(bool) 1.2133 +SetObjectMetadata(JSContext *cx, JS::HandleObject obj, JS::HandleObject metadata); 1.2134 + 1.2135 +JS_FRIEND_API(JSObject *) 1.2136 +GetObjectMetadata(JSObject *obj); 1.2137 + 1.2138 +JS_FRIEND_API(void) 1.2139 +UnsafeDefineElement(JSContext *cx, JS::HandleObject obj, uint32_t index, JS::HandleValue value); 1.2140 + 1.2141 +JS_FRIEND_API(bool) 1.2142 +SliceSlowly(JSContext* cx, JS::HandleObject obj, JS::HandleObject receiver, 1.2143 + uint32_t begin, uint32_t end, JS::HandleObject result); 1.2144 + 1.2145 +/* ES5 8.12.8. */ 1.2146 +extern JS_FRIEND_API(bool) 1.2147 +DefaultValue(JSContext *cx, JS::HandleObject obj, JSType hint, JS::MutableHandleValue vp); 1.2148 + 1.2149 +/* 1.2150 + * Helper function. To approximate a call to the [[DefineOwnProperty]] internal 1.2151 + * method described in ES5, first call this, then call JS_DefinePropertyById. 1.2152 + * 1.2153 + * JS_DefinePropertyById by itself does not enforce the invariants on 1.2154 + * non-configurable properties when obj->isNative(). This function performs the 1.2155 + * relevant checks (specified in ES5 8.12.9 [[DefineOwnProperty]] steps 1-11), 1.2156 + * but only if obj is native. 1.2157 + * 1.2158 + * The reason for the messiness here is that ES5 uses [[DefineOwnProperty]] as 1.2159 + * a sort of extension point, but there is no hook in js::Class, 1.2160 + * js::ProxyHandler, or the JSAPI with precisely the right semantics for it. 1.2161 + */ 1.2162 +extern JS_FRIEND_API(bool) 1.2163 +CheckDefineProperty(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue value, 1.2164 + JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs); 1.2165 + 1.2166 +/* 1.2167 + * Helper function for HTMLDocument and HTMLFormElement. 1.2168 + * 1.2169 + * These are the only two interfaces that have [OverrideBuiltins], a named 1.2170 + * getter, and no named setter. They're implemented as proxies with a custom 1.2171 + * getOwnPropertyDescriptor() method. Unfortunately, overriding 1.2172 + * getOwnPropertyDescriptor() automatically affects the behavior of set(), 1.2173 + * which normally is just common sense but is *not* desired for these two 1.2174 + * interfaces. 1.2175 + * 1.2176 + * The fix is for these two interfaces to override set() to ignore the 1.2177 + * getOwnPropertyDescriptor() override. 1.2178 + * 1.2179 + * SetPropertyIgnoringNamedGetter is exposed to make it easier to override 1.2180 + * set() in this way. It carries out all the steps of BaseProxyHandler::set() 1.2181 + * except the initial getOwnPropertyDescriptor()/getPropertyDescriptor() calls. 1.2182 + * The caller must supply those results as the 'desc' and 'descIsOwn' 1.2183 + * parameters. 1.2184 + * 1.2185 + * Implemented in jsproxy.cpp. 1.2186 + */ 1.2187 +JS_FRIEND_API(bool) 1.2188 +SetPropertyIgnoringNamedGetter(JSContext *cx, BaseProxyHandler *handler, 1.2189 + JS::HandleObject proxy, JS::HandleObject receiver, 1.2190 + JS::HandleId id, JS::MutableHandle<JSPropertyDescriptor> desc, 1.2191 + bool descIsOwn, bool strict, JS::MutableHandleValue vp); 1.2192 + 1.2193 +} /* namespace js */ 1.2194 + 1.2195 +extern JS_FRIEND_API(bool) 1.2196 +js_DefineOwnProperty(JSContext *cx, JSObject *objArg, jsid idArg, 1.2197 + JS::Handle<JSPropertyDescriptor> descriptor, bool *bp); 1.2198 + 1.2199 +extern JS_FRIEND_API(bool) 1.2200 +js_ReportIsNotFunction(JSContext *cx, JS::HandleValue v); 1.2201 + 1.2202 +#ifdef JSGC_GENERATIONAL 1.2203 +extern JS_FRIEND_API(void) 1.2204 +JS_StoreObjectPostBarrierCallback(JSContext* cx, 1.2205 + void (*callback)(JSTracer *trc, JSObject *key, void *data), 1.2206 + JSObject *key, void *data); 1.2207 + 1.2208 +extern JS_FRIEND_API(void) 1.2209 +JS_StoreStringPostBarrierCallback(JSContext* cx, 1.2210 + void (*callback)(JSTracer *trc, JSString *key, void *data), 1.2211 + JSString *key, void *data); 1.2212 +#else 1.2213 +inline void 1.2214 +JS_StoreObjectPostBarrierCallback(JSContext* cx, 1.2215 + void (*callback)(JSTracer *trc, JSObject *key, void *data), 1.2216 + JSObject *key, void *data) {} 1.2217 + 1.2218 +inline void 1.2219 +JS_StoreStringPostBarrierCallback(JSContext* cx, 1.2220 + void (*callback)(JSTracer *trc, JSString *key, void *data), 1.2221 + JSString *key, void *data) {} 1.2222 +#endif /* JSGC_GENERATIONAL */ 1.2223 + 1.2224 +#endif /* jsfriendapi_h */