1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/src/jsfriendapi.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1262 @@ 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 +#include "jsfriendapi.h" 1.11 + 1.12 +#include "mozilla/PodOperations.h" 1.13 + 1.14 +#include <stdint.h> 1.15 + 1.16 +#include "jscntxt.h" 1.17 +#include "jscompartment.h" 1.18 +#include "jsgc.h" 1.19 +#include "jsobj.h" 1.20 +#include "jsproxy.h" 1.21 +#include "jswatchpoint.h" 1.22 +#include "jsweakmap.h" 1.23 +#include "jswrapper.h" 1.24 +#include "prmjtime.h" 1.25 + 1.26 +#include "builtin/TestingFunctions.h" 1.27 +#include "vm/WrapperObject.h" 1.28 + 1.29 +#include "jsobjinlines.h" 1.30 + 1.31 +#include "vm/ScopeObject-inl.h" 1.32 + 1.33 +using namespace js; 1.34 +using namespace JS; 1.35 + 1.36 +using mozilla::PodArrayZero; 1.37 + 1.38 +// Required by PerThreadDataFriendFields::getMainThread() 1.39 +JS_STATIC_ASSERT(offsetof(JSRuntime, mainThread) == 1.40 + PerThreadDataFriendFields::RuntimeMainThreadOffset); 1.41 + 1.42 +PerThreadDataFriendFields::PerThreadDataFriendFields() 1.43 +{ 1.44 + PodArrayZero(nativeStackLimit); 1.45 +#if JS_STACK_GROWTH_DIRECTION > 0 1.46 + for (int i=0; i<StackKindCount; i++) 1.47 + nativeStackLimit[i] = UINTPTR_MAX; 1.48 +#endif 1.49 +#if defined(JSGC_USE_EXACT_ROOTING) 1.50 + PodArrayZero(thingGCRooters); 1.51 +#endif 1.52 +} 1.53 + 1.54 +JS_FRIEND_API(void) 1.55 +js::SetSourceHook(JSRuntime *rt, SourceHook *hook) 1.56 +{ 1.57 + rt->sourceHook = hook; 1.58 +} 1.59 + 1.60 +JS_FRIEND_API(SourceHook *) 1.61 +js::ForgetSourceHook(JSRuntime *rt) 1.62 +{ 1.63 + return rt->sourceHook.forget(); 1.64 +} 1.65 + 1.66 +JS_FRIEND_API(void) 1.67 +JS_SetGrayGCRootsTracer(JSRuntime *rt, JSTraceDataOp traceOp, void *data) 1.68 +{ 1.69 + rt->gcGrayRootTracer.op = traceOp; 1.70 + rt->gcGrayRootTracer.data = data; 1.71 +} 1.72 + 1.73 +JS_FRIEND_API(JSString *) 1.74 +JS_GetAnonymousString(JSRuntime *rt) 1.75 +{ 1.76 + JS_ASSERT(rt->hasContexts()); 1.77 + return rt->commonNames->anonymous; 1.78 +} 1.79 + 1.80 +JS_FRIEND_API(void) 1.81 +JS_SetIsWorkerRuntime(JSRuntime *rt) 1.82 +{ 1.83 + rt->setIsWorkerRuntime(); 1.84 +} 1.85 + 1.86 +JS_FRIEND_API(JSObject *) 1.87 +JS_FindCompilationScope(JSContext *cx, HandleObject objArg) 1.88 +{ 1.89 + RootedObject obj(cx, objArg); 1.90 + 1.91 + /* 1.92 + * We unwrap wrappers here. This is a little weird, but it's what's being 1.93 + * asked of us. 1.94 + */ 1.95 + if (obj->is<WrapperObject>()) 1.96 + obj = UncheckedUnwrap(obj); 1.97 + 1.98 + /* 1.99 + * Innerize the target_obj so that we compile in the correct (inner) 1.100 + * scope. 1.101 + */ 1.102 + if (JSObjectOp op = obj->getClass()->ext.innerObject) 1.103 + obj = op(cx, obj); 1.104 + return obj; 1.105 +} 1.106 + 1.107 +JS_FRIEND_API(JSFunction *) 1.108 +JS_GetObjectFunction(JSObject *obj) 1.109 +{ 1.110 + if (obj->is<JSFunction>()) 1.111 + return &obj->as<JSFunction>(); 1.112 + return nullptr; 1.113 +} 1.114 + 1.115 +JS_FRIEND_API(bool) 1.116 +JS_SplicePrototype(JSContext *cx, HandleObject obj, HandleObject proto) 1.117 +{ 1.118 + /* 1.119 + * Change the prototype of an object which hasn't been used anywhere 1.120 + * and does not share its type with another object. Unlike JS_SetPrototype, 1.121 + * does not nuke type information for the object. 1.122 + */ 1.123 + CHECK_REQUEST(cx); 1.124 + 1.125 + if (!obj->hasSingletonType()) { 1.126 + /* 1.127 + * We can see non-singleton objects when trying to splice prototypes 1.128 + * due to mutable __proto__ (ugh). 1.129 + */ 1.130 + return JS_SetPrototype(cx, obj, proto); 1.131 + } 1.132 + 1.133 + Rooted<TaggedProto> tagged(cx, TaggedProto(proto)); 1.134 + return obj->splicePrototype(cx, obj->getClass(), tagged); 1.135 +} 1.136 + 1.137 +JS_FRIEND_API(JSObject *) 1.138 +JS_NewObjectWithUniqueType(JSContext *cx, const JSClass *clasp, HandleObject proto, 1.139 + HandleObject parent) 1.140 +{ 1.141 + /* 1.142 + * Create our object with a null proto and then splice in the correct proto 1.143 + * after we setSingletonType, so that we don't pollute the default 1.144 + * TypeObject attached to our proto with information about our object, since 1.145 + * we're not going to be using that TypeObject anyway. 1.146 + */ 1.147 + RootedObject obj(cx, NewObjectWithGivenProto(cx, (const js::Class *)clasp, nullptr, 1.148 + parent, SingletonObject)); 1.149 + if (!obj) 1.150 + return nullptr; 1.151 + if (!JS_SplicePrototype(cx, obj, proto)) 1.152 + return nullptr; 1.153 + return obj; 1.154 +} 1.155 + 1.156 +JS_FRIEND_API(void) 1.157 +JS::PrepareZoneForGC(Zone *zone) 1.158 +{ 1.159 + zone->scheduleGC(); 1.160 +} 1.161 + 1.162 +JS_FRIEND_API(void) 1.163 +JS::PrepareForFullGC(JSRuntime *rt) 1.164 +{ 1.165 + for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) 1.166 + zone->scheduleGC(); 1.167 +} 1.168 + 1.169 +JS_FRIEND_API(void) 1.170 +JS::PrepareForIncrementalGC(JSRuntime *rt) 1.171 +{ 1.172 + if (!JS::IsIncrementalGCInProgress(rt)) 1.173 + return; 1.174 + 1.175 + for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) { 1.176 + if (zone->wasGCStarted()) 1.177 + PrepareZoneForGC(zone); 1.178 + } 1.179 +} 1.180 + 1.181 +JS_FRIEND_API(bool) 1.182 +JS::IsGCScheduled(JSRuntime *rt) 1.183 +{ 1.184 + for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) { 1.185 + if (zone->isGCScheduled()) 1.186 + return true; 1.187 + } 1.188 + 1.189 + return false; 1.190 +} 1.191 + 1.192 +JS_FRIEND_API(void) 1.193 +JS::SkipZoneForGC(Zone *zone) 1.194 +{ 1.195 + zone->unscheduleGC(); 1.196 +} 1.197 + 1.198 +JS_FRIEND_API(void) 1.199 +JS::GCForReason(JSRuntime *rt, gcreason::Reason reason) 1.200 +{ 1.201 + GC(rt, GC_NORMAL, reason); 1.202 +} 1.203 + 1.204 +JS_FRIEND_API(void) 1.205 +JS::ShrinkingGC(JSRuntime *rt, gcreason::Reason reason) 1.206 +{ 1.207 + GC(rt, GC_SHRINK, reason); 1.208 +} 1.209 + 1.210 +JS_FRIEND_API(void) 1.211 +JS::IncrementalGC(JSRuntime *rt, gcreason::Reason reason, int64_t millis) 1.212 +{ 1.213 + GCSlice(rt, GC_NORMAL, reason, millis); 1.214 +} 1.215 + 1.216 +JS_FRIEND_API(void) 1.217 +JS::FinishIncrementalGC(JSRuntime *rt, gcreason::Reason reason) 1.218 +{ 1.219 + GCFinalSlice(rt, GC_NORMAL, reason); 1.220 +} 1.221 + 1.222 +JS_FRIEND_API(JSPrincipals *) 1.223 +JS_GetCompartmentPrincipals(JSCompartment *compartment) 1.224 +{ 1.225 + return compartment->principals; 1.226 +} 1.227 + 1.228 +JS_FRIEND_API(void) 1.229 +JS_SetCompartmentPrincipals(JSCompartment *compartment, JSPrincipals *principals) 1.230 +{ 1.231 + // Short circuit if there's no change. 1.232 + if (principals == compartment->principals) 1.233 + return; 1.234 + 1.235 + // Any compartment with the trusted principals -- and there can be 1.236 + // multiple -- is a system compartment. 1.237 + const JSPrincipals *trusted = compartment->runtimeFromMainThread()->trustedPrincipals(); 1.238 + bool isSystem = principals && principals == trusted; 1.239 + 1.240 + // Clear out the old principals, if any. 1.241 + if (compartment->principals) { 1.242 + JS_DropPrincipals(compartment->runtimeFromMainThread(), compartment->principals); 1.243 + compartment->principals = nullptr; 1.244 + // We'd like to assert that our new principals is always same-origin 1.245 + // with the old one, but JSPrincipals doesn't give us a way to do that. 1.246 + // But we can at least assert that we're not switching between system 1.247 + // and non-system. 1.248 + JS_ASSERT(compartment->isSystem == isSystem); 1.249 + } 1.250 + 1.251 + // Set up the new principals. 1.252 + if (principals) { 1.253 + JS_HoldPrincipals(principals); 1.254 + compartment->principals = principals; 1.255 + } 1.256 + 1.257 + // Update the system flag. 1.258 + compartment->isSystem = isSystem; 1.259 +} 1.260 + 1.261 +JS_FRIEND_API(bool) 1.262 +JS_WrapPropertyDescriptor(JSContext *cx, JS::MutableHandle<js::PropertyDescriptor> desc) 1.263 +{ 1.264 + return cx->compartment()->wrap(cx, desc); 1.265 +} 1.266 + 1.267 +JS_FRIEND_API(bool) 1.268 +JS_WrapAutoIdVector(JSContext *cx, js::AutoIdVector &props) 1.269 +{ 1.270 + return cx->compartment()->wrap(cx, props); 1.271 +} 1.272 + 1.273 +JS_FRIEND_API(void) 1.274 +JS_TraceShapeCycleCollectorChildren(JSTracer *trc, void *shape) 1.275 +{ 1.276 + MarkCycleCollectorChildren(trc, static_cast<Shape *>(shape)); 1.277 +} 1.278 + 1.279 +static bool 1.280 +DefineHelpProperty(JSContext *cx, HandleObject obj, const char *prop, const char *value) 1.281 +{ 1.282 + RootedAtom atom(cx, Atomize(cx, value, strlen(value))); 1.283 + if (!atom) 1.284 + return false; 1.285 + return JS_DefineProperty(cx, obj, prop, atom, JSPROP_READONLY | JSPROP_PERMANENT, 1.286 + JS_PropertyStub, JS_StrictPropertyStub); 1.287 +} 1.288 + 1.289 +JS_FRIEND_API(bool) 1.290 +JS_DefineFunctionsWithHelp(JSContext *cx, HandleObject obj, const JSFunctionSpecWithHelp *fs) 1.291 +{ 1.292 + JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment())); 1.293 + 1.294 + CHECK_REQUEST(cx); 1.295 + assertSameCompartment(cx, obj); 1.296 + for (; fs->name; fs++) { 1.297 + JSAtom *atom = Atomize(cx, fs->name, strlen(fs->name)); 1.298 + if (!atom) 1.299 + return false; 1.300 + 1.301 + Rooted<jsid> id(cx, AtomToId(atom)); 1.302 + RootedFunction fun(cx, DefineFunction(cx, obj, id, fs->call, fs->nargs, fs->flags)); 1.303 + if (!fun) 1.304 + return false; 1.305 + 1.306 + if (fs->usage) { 1.307 + if (!DefineHelpProperty(cx, fun, "usage", fs->usage)) 1.308 + return false; 1.309 + } 1.310 + 1.311 + if (fs->help) { 1.312 + if (!DefineHelpProperty(cx, fun, "help", fs->help)) 1.313 + return false; 1.314 + } 1.315 + } 1.316 + 1.317 + return true; 1.318 +} 1.319 + 1.320 +JS_FRIEND_API(bool) 1.321 +js_ObjectClassIs(JSContext *cx, HandleObject obj, ESClassValue classValue) 1.322 +{ 1.323 + return ObjectClassIs(obj, classValue, cx); 1.324 +} 1.325 + 1.326 +JS_FRIEND_API(const char *) 1.327 +js_ObjectClassName(JSContext *cx, HandleObject obj) 1.328 +{ 1.329 + return JSObject::className(cx, obj); 1.330 +} 1.331 + 1.332 +JS_FRIEND_API(JS::Zone *) 1.333 +js::GetCompartmentZone(JSCompartment *comp) 1.334 +{ 1.335 + return comp->zone(); 1.336 +} 1.337 + 1.338 +JS_FRIEND_API(bool) 1.339 +js::IsSystemCompartment(JSCompartment *comp) 1.340 +{ 1.341 + return comp->isSystem; 1.342 +} 1.343 + 1.344 +JS_FRIEND_API(bool) 1.345 +js::IsSystemZone(Zone *zone) 1.346 +{ 1.347 + return zone->isSystem; 1.348 +} 1.349 + 1.350 +JS_FRIEND_API(bool) 1.351 +js::IsAtomsCompartment(JSCompartment *comp) 1.352 +{ 1.353 + return comp->runtimeFromAnyThread()->isAtomsCompartment(comp); 1.354 +} 1.355 + 1.356 +JS_FRIEND_API(bool) 1.357 +js::IsInNonStrictPropertySet(JSContext *cx) 1.358 +{ 1.359 + jsbytecode *pc; 1.360 + JSScript *script = cx->currentScript(&pc, JSContext::ALLOW_CROSS_COMPARTMENT); 1.361 + return script && !script->strict() && (js_CodeSpec[*pc].format & JOF_SET); 1.362 +} 1.363 + 1.364 +JS_FRIEND_API(bool) 1.365 +js::IsFunctionObject(JSObject *obj) 1.366 +{ 1.367 + return obj->is<JSFunction>(); 1.368 +} 1.369 + 1.370 +JS_FRIEND_API(bool) 1.371 +js::IsScopeObject(JSObject *obj) 1.372 +{ 1.373 + return obj->is<ScopeObject>(); 1.374 +} 1.375 + 1.376 +JS_FRIEND_API(bool) 1.377 +js::IsCallObject(JSObject *obj) 1.378 +{ 1.379 + return obj->is<CallObject>(); 1.380 +} 1.381 + 1.382 +JS_FRIEND_API(JSObject *) 1.383 +js::GetObjectParentMaybeScope(JSObject *obj) 1.384 +{ 1.385 + return obj->enclosingScope(); 1.386 +} 1.387 + 1.388 +JS_FRIEND_API(JSObject *) 1.389 +js::GetGlobalForObjectCrossCompartment(JSObject *obj) 1.390 +{ 1.391 + return &obj->global(); 1.392 +} 1.393 + 1.394 +JS_FRIEND_API(void) 1.395 +js::SetPendingExceptionCrossContext(JSContext *cx, JS::HandleValue v) 1.396 +{ 1.397 + cx->setPendingException(v); 1.398 +} 1.399 + 1.400 +JS_FRIEND_API(void) 1.401 +js::AssertSameCompartment(JSContext *cx, JSObject *obj) 1.402 +{ 1.403 + assertSameCompartment(cx, obj); 1.404 +} 1.405 + 1.406 +#ifdef DEBUG 1.407 +JS_FRIEND_API(void) 1.408 +js::AssertSameCompartment(JSObject *objA, JSObject *objB) 1.409 +{ 1.410 + JS_ASSERT(objA->compartment() == objB->compartment()); 1.411 +} 1.412 +#endif 1.413 + 1.414 +JS_FRIEND_API(JSObject *) 1.415 +js::DefaultObjectForContextOrNull(JSContext *cx) 1.416 +{ 1.417 + if (cx->options().noDefaultCompartmentObject()) 1.418 + return nullptr; 1.419 + return cx->maybeDefaultCompartmentObject(); 1.420 +} 1.421 + 1.422 +JS_FRIEND_API(void) 1.423 +js::SetDefaultObjectForContext(JSContext *cx, JSObject *obj) 1.424 +{ 1.425 + cx->setDefaultCompartmentObject(obj); 1.426 +} 1.427 + 1.428 +JS_FRIEND_API(void) 1.429 +js::NotifyAnimationActivity(JSObject *obj) 1.430 +{ 1.431 + obj->compartment()->lastAnimationTime = PRMJ_Now(); 1.432 +} 1.433 + 1.434 +JS_FRIEND_API(uint32_t) 1.435 +js::GetObjectSlotSpan(JSObject *obj) 1.436 +{ 1.437 + return obj->slotSpan(); 1.438 +} 1.439 + 1.440 +JS_FRIEND_API(bool) 1.441 +js::IsObjectInContextCompartment(JSObject *obj, const JSContext *cx) 1.442 +{ 1.443 + return obj->compartment() == cx->compartment(); 1.444 +} 1.445 + 1.446 +JS_FRIEND_API(bool) 1.447 +js::RunningWithTrustedPrincipals(JSContext *cx) 1.448 +{ 1.449 + return cx->runningWithTrustedPrincipals(); 1.450 +} 1.451 + 1.452 +JS_FRIEND_API(JSScript *) 1.453 +js::GetOutermostEnclosingFunctionOfScriptedCaller(JSContext *cx) 1.454 +{ 1.455 + ScriptFrameIter iter(cx); 1.456 + if (iter.done()) 1.457 + return nullptr; 1.458 + 1.459 + if (!iter.isFunctionFrame()) 1.460 + return nullptr; 1.461 + 1.462 + RootedFunction scriptedCaller(cx, iter.callee()); 1.463 + RootedScript outermost(cx, scriptedCaller->nonLazyScript()); 1.464 + for (StaticScopeIter<NoGC> i(scriptedCaller); !i.done(); i++) { 1.465 + if (i.type() == StaticScopeIter<NoGC>::FUNCTION) 1.466 + outermost = i.funScript(); 1.467 + } 1.468 + return outermost; 1.469 +} 1.470 + 1.471 +JS_FRIEND_API(JSFunction *) 1.472 +js::DefineFunctionWithReserved(JSContext *cx, JSObject *objArg, const char *name, JSNative call, 1.473 + unsigned nargs, unsigned attrs) 1.474 +{ 1.475 + RootedObject obj(cx, objArg); 1.476 + JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment())); 1.477 + CHECK_REQUEST(cx); 1.478 + assertSameCompartment(cx, obj); 1.479 + JSAtom *atom = Atomize(cx, name, strlen(name)); 1.480 + if (!atom) 1.481 + return nullptr; 1.482 + Rooted<jsid> id(cx, AtomToId(atom)); 1.483 + return DefineFunction(cx, obj, id, call, nargs, attrs, JSFunction::ExtendedFinalizeKind); 1.484 +} 1.485 + 1.486 +JS_FRIEND_API(JSFunction *) 1.487 +js::NewFunctionWithReserved(JSContext *cx, JSNative native, unsigned nargs, unsigned flags, 1.488 + JSObject *parentArg, const char *name) 1.489 +{ 1.490 + RootedObject parent(cx, parentArg); 1.491 + JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment())); 1.492 + 1.493 + CHECK_REQUEST(cx); 1.494 + assertSameCompartment(cx, parent); 1.495 + 1.496 + RootedAtom atom(cx); 1.497 + if (name) { 1.498 + atom = Atomize(cx, name, strlen(name)); 1.499 + if (!atom) 1.500 + return nullptr; 1.501 + } 1.502 + 1.503 + JSFunction::Flags funFlags = JSAPIToJSFunctionFlags(flags); 1.504 + return NewFunction(cx, NullPtr(), native, nargs, funFlags, parent, atom, 1.505 + JSFunction::ExtendedFinalizeKind); 1.506 +} 1.507 + 1.508 +JS_FRIEND_API(JSFunction *) 1.509 +js::NewFunctionByIdWithReserved(JSContext *cx, JSNative native, unsigned nargs, unsigned flags, JSObject *parentArg, 1.510 + jsid id) 1.511 +{ 1.512 + RootedObject parent(cx, parentArg); 1.513 + JS_ASSERT(JSID_IS_STRING(id)); 1.514 + JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment())); 1.515 + CHECK_REQUEST(cx); 1.516 + assertSameCompartment(cx, parent); 1.517 + 1.518 + RootedAtom atom(cx, JSID_TO_ATOM(id)); 1.519 + JSFunction::Flags funFlags = JSAPIToJSFunctionFlags(flags); 1.520 + return NewFunction(cx, NullPtr(), native, nargs, funFlags, parent, atom, 1.521 + JSFunction::ExtendedFinalizeKind); 1.522 +} 1.523 + 1.524 +JS_FRIEND_API(JSObject *) 1.525 +js::InitClassWithReserved(JSContext *cx, JSObject *objArg, JSObject *parent_protoArg, 1.526 + const JSClass *clasp, JSNative constructor, unsigned nargs, 1.527 + const JSPropertySpec *ps, const JSFunctionSpec *fs, 1.528 + const JSPropertySpec *static_ps, const JSFunctionSpec *static_fs) 1.529 +{ 1.530 + RootedObject obj(cx, objArg); 1.531 + RootedObject parent_proto(cx, parent_protoArg); 1.532 + CHECK_REQUEST(cx); 1.533 + assertSameCompartment(cx, obj, parent_proto); 1.534 + return js_InitClass(cx, obj, parent_proto, Valueify(clasp), constructor, 1.535 + nargs, ps, fs, static_ps, static_fs, nullptr, 1.536 + JSFunction::ExtendedFinalizeKind); 1.537 +} 1.538 + 1.539 +JS_FRIEND_API(const Value &) 1.540 +js::GetFunctionNativeReserved(JSObject *fun, size_t which) 1.541 +{ 1.542 + JS_ASSERT(fun->as<JSFunction>().isNative()); 1.543 + return fun->as<JSFunction>().getExtendedSlot(which); 1.544 +} 1.545 + 1.546 +JS_FRIEND_API(void) 1.547 +js::SetFunctionNativeReserved(JSObject *fun, size_t which, const Value &val) 1.548 +{ 1.549 + JS_ASSERT(fun->as<JSFunction>().isNative()); 1.550 + MOZ_ASSERT_IF(val.isObject(), val.toObject().compartment() == fun->compartment()); 1.551 + fun->as<JSFunction>().setExtendedSlot(which, val); 1.552 +} 1.553 + 1.554 +JS_FRIEND_API(bool) 1.555 +js::GetObjectProto(JSContext *cx, JS::Handle<JSObject*> obj, JS::MutableHandle<JSObject*> proto) 1.556 +{ 1.557 + if (IsProxy(obj)) 1.558 + return JS_GetPrototype(cx, obj, proto); 1.559 + 1.560 + proto.set(reinterpret_cast<const shadow::Object*>(obj.get())->type->proto); 1.561 + return true; 1.562 +} 1.563 + 1.564 +JS_FRIEND_API(bool) 1.565 +js::GetOriginalEval(JSContext *cx, HandleObject scope, MutableHandleObject eval) 1.566 +{ 1.567 + assertSameCompartment(cx, scope); 1.568 + Rooted<GlobalObject *> global(cx, &scope->global()); 1.569 + return GlobalObject::getOrCreateEval(cx, global, eval); 1.570 +} 1.571 + 1.572 +JS_FRIEND_API(void) 1.573 +js::SetReservedSlotWithBarrier(JSObject *obj, size_t slot, const js::Value &value) 1.574 +{ 1.575 + obj->setSlot(slot, value); 1.576 +} 1.577 + 1.578 +JS_FRIEND_API(bool) 1.579 +js::GetGeneric(JSContext *cx, JSObject *objArg, JSObject *receiverArg, jsid idArg, 1.580 + Value *vp) 1.581 +{ 1.582 + RootedObject obj(cx, objArg), receiver(cx, receiverArg); 1.583 + RootedId id(cx, idArg); 1.584 + RootedValue value(cx); 1.585 + if (!JSObject::getGeneric(cx, obj, receiver, id, &value)) 1.586 + return false; 1.587 + *vp = value; 1.588 + return true; 1.589 +} 1.590 + 1.591 +void 1.592 +js::SetPreserveWrapperCallback(JSRuntime *rt, PreserveWrapperCallback callback) 1.593 +{ 1.594 + rt->preserveWrapperCallback = callback; 1.595 +} 1.596 + 1.597 +/* 1.598 + * The below code is for temporary telemetry use. It can be removed when 1.599 + * sufficient data has been harvested. 1.600 + */ 1.601 + 1.602 +namespace js { 1.603 +// Defined in vm/GlobalObject.cpp. 1.604 +extern size_t sSetProtoCalled; 1.605 +} 1.606 + 1.607 +JS_FRIEND_API(size_t) 1.608 +JS_SetProtoCalled(JSContext *) 1.609 +{ 1.610 + return sSetProtoCalled; 1.611 +} 1.612 + 1.613 +// Defined in jsiter.cpp. 1.614 +extern size_t sCustomIteratorCount; 1.615 + 1.616 +JS_FRIEND_API(size_t) 1.617 +JS_GetCustomIteratorCount(JSContext *cx) 1.618 +{ 1.619 + return sCustomIteratorCount; 1.620 +} 1.621 + 1.622 +JS_FRIEND_API(bool) 1.623 +JS_IsDeadWrapper(JSObject *obj) 1.624 +{ 1.625 + if (!obj->is<ProxyObject>()) { 1.626 + return false; 1.627 + } 1.628 + 1.629 + return obj->as<ProxyObject>().handler()->family() == &DeadObjectProxy::sDeadObjectFamily; 1.630 +} 1.631 + 1.632 +void 1.633 +js::TraceWeakMaps(WeakMapTracer *trc) 1.634 +{ 1.635 + WeakMapBase::traceAllMappings(trc); 1.636 + WatchpointMap::traceAll(trc); 1.637 +} 1.638 + 1.639 +extern JS_FRIEND_API(bool) 1.640 +js::AreGCGrayBitsValid(JSRuntime *rt) 1.641 +{ 1.642 + return rt->gcGrayBitsValid; 1.643 +} 1.644 + 1.645 +JS_FRIEND_API(bool) 1.646 +js::ZoneGlobalsAreAllGray(JS::Zone *zone) 1.647 +{ 1.648 + for (CompartmentsInZoneIter comp(zone); !comp.done(); comp.next()) { 1.649 + JSObject *obj = comp->maybeGlobal(); 1.650 + if (!obj || !JS::GCThingIsMarkedGray(obj)) 1.651 + return false; 1.652 + } 1.653 + return true; 1.654 +} 1.655 + 1.656 +JS_FRIEND_API(JSGCTraceKind) 1.657 +js::GCThingTraceKind(void *thing) 1.658 +{ 1.659 + JS_ASSERT(thing); 1.660 + return gc::GetGCThingTraceKind(thing); 1.661 +} 1.662 + 1.663 +JS_FRIEND_API(void) 1.664 +js::VisitGrayWrapperTargets(Zone *zone, GCThingCallback callback, void *closure) 1.665 +{ 1.666 + JSRuntime *rt = zone->runtimeFromMainThread(); 1.667 + for (CompartmentsInZoneIter comp(zone); !comp.done(); comp.next()) { 1.668 + for (JSCompartment::WrapperEnum e(comp); !e.empty(); e.popFront()) { 1.669 + gc::Cell *thing = e.front().key().wrapped; 1.670 + if (!IsInsideNursery(rt, thing) && thing->isMarked(gc::GRAY)) 1.671 + callback(closure, thing); 1.672 + } 1.673 + } 1.674 +} 1.675 + 1.676 +JS_FRIEND_API(JSObject *) 1.677 +js::GetWeakmapKeyDelegate(JSObject *key) 1.678 +{ 1.679 + if (JSWeakmapKeyDelegateOp op = key->getClass()->ext.weakmapKeyDelegateOp) 1.680 + return op(key); 1.681 + return nullptr; 1.682 +} 1.683 + 1.684 +JS_FRIEND_API(void) 1.685 +JS_SetAccumulateTelemetryCallback(JSRuntime *rt, JSAccumulateTelemetryDataCallback callback) 1.686 +{ 1.687 + rt->telemetryCallback = callback; 1.688 +} 1.689 + 1.690 +JS_FRIEND_API(JSObject *) 1.691 +JS_CloneObject(JSContext *cx, HandleObject obj, HandleObject protoArg, HandleObject parent) 1.692 +{ 1.693 + Rooted<js::TaggedProto> proto(cx, protoArg.get()); 1.694 + return CloneObject(cx, obj, proto, parent); 1.695 +} 1.696 + 1.697 +#ifdef DEBUG 1.698 +JS_FRIEND_API(void) 1.699 +js_DumpString(JSString *str) 1.700 +{ 1.701 + str->dump(); 1.702 +} 1.703 + 1.704 +JS_FRIEND_API(void) 1.705 +js_DumpAtom(JSAtom *atom) 1.706 +{ 1.707 + atom->dump(); 1.708 +} 1.709 + 1.710 +JS_FRIEND_API(void) 1.711 +js_DumpChars(const jschar *s, size_t n) 1.712 +{ 1.713 + fprintf(stderr, "jschar * (%p) = ", (void *) s); 1.714 + JSString::dumpChars(s, n); 1.715 + fputc('\n', stderr); 1.716 +} 1.717 + 1.718 +JS_FRIEND_API(void) 1.719 +js_DumpObject(JSObject *obj) 1.720 +{ 1.721 + if (!obj) { 1.722 + fprintf(stderr, "NULL\n"); 1.723 + return; 1.724 + } 1.725 + obj->dump(); 1.726 +} 1.727 + 1.728 +#endif 1.729 + 1.730 +struct DumpHeapTracer : public JSTracer 1.731 +{ 1.732 + FILE *output; 1.733 + 1.734 + DumpHeapTracer(FILE *fp, JSRuntime *rt, JSTraceCallback callback, 1.735 + WeakMapTraceKind weakTraceKind) 1.736 + : JSTracer(rt, callback, weakTraceKind), output(fp) 1.737 + {} 1.738 +}; 1.739 + 1.740 +static char 1.741 +MarkDescriptor(void *thing) 1.742 +{ 1.743 + gc::Cell *cell = static_cast<gc::Cell*>(thing); 1.744 + if (cell->isMarked(gc::BLACK)) 1.745 + return cell->isMarked(gc::GRAY) ? 'G' : 'B'; 1.746 + else 1.747 + return cell->isMarked(gc::GRAY) ? 'X' : 'W'; 1.748 +} 1.749 + 1.750 +static void 1.751 +DumpHeapVisitZone(JSRuntime *rt, void *data, Zone *zone) 1.752 +{ 1.753 + DumpHeapTracer *dtrc = static_cast<DumpHeapTracer *>(data); 1.754 + fprintf(dtrc->output, "# zone %p\n", (void *)zone); 1.755 +} 1.756 + 1.757 +static void 1.758 +DumpHeapVisitCompartment(JSRuntime *rt, void *data, JSCompartment *comp) 1.759 +{ 1.760 + char name[1024]; 1.761 + if (rt->compartmentNameCallback) 1.762 + (*rt->compartmentNameCallback)(rt, comp, name, sizeof(name)); 1.763 + else 1.764 + strcpy(name, "<unknown>"); 1.765 + 1.766 + DumpHeapTracer *dtrc = static_cast<DumpHeapTracer *>(data); 1.767 + fprintf(dtrc->output, "# compartment %s [in zone %p]\n", name, (void *)comp->zone()); 1.768 +} 1.769 + 1.770 +static void 1.771 +DumpHeapVisitArena(JSRuntime *rt, void *data, gc::Arena *arena, 1.772 + JSGCTraceKind traceKind, size_t thingSize) 1.773 +{ 1.774 + DumpHeapTracer *dtrc = static_cast<DumpHeapTracer *>(data); 1.775 + fprintf(dtrc->output, "# arena allockind=%u size=%u\n", 1.776 + unsigned(arena->aheader.getAllocKind()), unsigned(thingSize)); 1.777 +} 1.778 + 1.779 +static void 1.780 +DumpHeapVisitCell(JSRuntime *rt, void *data, void *thing, 1.781 + JSGCTraceKind traceKind, size_t thingSize) 1.782 +{ 1.783 + DumpHeapTracer *dtrc = static_cast<DumpHeapTracer *>(data); 1.784 + char cellDesc[1024 * 32]; 1.785 + JS_GetTraceThingInfo(cellDesc, sizeof(cellDesc), dtrc, thing, traceKind, true); 1.786 + fprintf(dtrc->output, "%p %c %s\n", thing, MarkDescriptor(thing), cellDesc); 1.787 + JS_TraceChildren(dtrc, thing, traceKind); 1.788 +} 1.789 + 1.790 +static void 1.791 +DumpHeapVisitChild(JSTracer *trc, void **thingp, JSGCTraceKind kind) 1.792 +{ 1.793 + if (gc::IsInsideNursery(trc->runtime(), *thingp)) 1.794 + return; 1.795 + 1.796 + DumpHeapTracer *dtrc = static_cast<DumpHeapTracer *>(trc); 1.797 + char buffer[1024]; 1.798 + fprintf(dtrc->output, "> %p %c %s\n", *thingp, MarkDescriptor(*thingp), 1.799 + dtrc->getTracingEdgeName(buffer, sizeof(buffer))); 1.800 +} 1.801 + 1.802 +static void 1.803 +DumpHeapVisitRoot(JSTracer *trc, void **thingp, JSGCTraceKind kind) 1.804 +{ 1.805 + if (gc::IsInsideNursery(trc->runtime(), *thingp)) 1.806 + return; 1.807 + 1.808 + DumpHeapTracer *dtrc = static_cast<DumpHeapTracer *>(trc); 1.809 + char buffer[1024]; 1.810 + fprintf(dtrc->output, "%p %c %s\n", *thingp, MarkDescriptor(*thingp), 1.811 + dtrc->getTracingEdgeName(buffer, sizeof(buffer))); 1.812 +} 1.813 + 1.814 +void 1.815 +js::DumpHeapComplete(JSRuntime *rt, FILE *fp, js::DumpHeapNurseryBehaviour nurseryBehaviour) 1.816 +{ 1.817 +#ifdef JSGC_GENERATIONAL 1.818 + if (nurseryBehaviour == js::CollectNurseryBeforeDump) 1.819 + MinorGC(rt, JS::gcreason::API); 1.820 +#endif 1.821 + 1.822 + DumpHeapTracer dtrc(fp, rt, DumpHeapVisitRoot, TraceWeakMapKeysValues); 1.823 + TraceRuntime(&dtrc); 1.824 + 1.825 + fprintf(dtrc.output, "==========\n"); 1.826 + 1.827 + dtrc.setTraceCallback(DumpHeapVisitChild); 1.828 + IterateZonesCompartmentsArenasCells(rt, &dtrc, 1.829 + DumpHeapVisitZone, 1.830 + DumpHeapVisitCompartment, 1.831 + DumpHeapVisitArena, 1.832 + DumpHeapVisitCell); 1.833 + 1.834 + fflush(dtrc.output); 1.835 +} 1.836 + 1.837 +JS_FRIEND_API(const JSStructuredCloneCallbacks *) 1.838 +js::GetContextStructuredCloneCallbacks(JSContext *cx) 1.839 +{ 1.840 + return cx->runtime()->structuredCloneCallbacks; 1.841 +} 1.842 + 1.843 +#ifdef JS_THREADSAFE 1.844 +JS_FRIEND_API(bool) 1.845 +js::ContextHasOutstandingRequests(const JSContext *cx) 1.846 +{ 1.847 + return cx->outstandingRequests > 0; 1.848 +} 1.849 +#endif 1.850 + 1.851 +JS_FRIEND_API(void) 1.852 +js::SetActivityCallback(JSRuntime *rt, ActivityCallback cb, void *arg) 1.853 +{ 1.854 + rt->activityCallback = cb; 1.855 + rt->activityCallbackArg = arg; 1.856 +} 1.857 + 1.858 +JS_FRIEND_API(bool) 1.859 +js::IsContextRunningJS(JSContext *cx) 1.860 +{ 1.861 + return cx->currentlyRunning(); 1.862 +} 1.863 + 1.864 +JS_FRIEND_API(JS::GCSliceCallback) 1.865 +JS::SetGCSliceCallback(JSRuntime *rt, GCSliceCallback callback) 1.866 +{ 1.867 + JS::GCSliceCallback old = rt->gcSliceCallback; 1.868 + rt->gcSliceCallback = callback; 1.869 + return old; 1.870 +} 1.871 + 1.872 +JS_FRIEND_API(bool) 1.873 +JS::WasIncrementalGC(JSRuntime *rt) 1.874 +{ 1.875 + return rt->gcIsIncremental; 1.876 +} 1.877 + 1.878 +jschar * 1.879 +GCDescription::formatMessage(JSRuntime *rt) const 1.880 +{ 1.881 + return rt->gcStats.formatMessage(); 1.882 +} 1.883 + 1.884 +jschar * 1.885 +GCDescription::formatJSON(JSRuntime *rt, uint64_t timestamp) const 1.886 +{ 1.887 + return rt->gcStats.formatJSON(timestamp); 1.888 +} 1.889 + 1.890 +JS_FRIEND_API(void) 1.891 +JS::NotifyDidPaint(JSRuntime *rt) 1.892 +{ 1.893 + if (rt->gcZeal() == gc::ZealFrameVerifierPreValue) { 1.894 + gc::VerifyBarriers(rt, gc::PreBarrierVerifier); 1.895 + return; 1.896 + } 1.897 + 1.898 + if (rt->gcZeal() == gc::ZealFrameVerifierPostValue) { 1.899 + gc::VerifyBarriers(rt, gc::PostBarrierVerifier); 1.900 + return; 1.901 + } 1.902 + 1.903 + if (rt->gcZeal() == gc::ZealFrameGCValue) { 1.904 + PrepareForFullGC(rt); 1.905 + GCSlice(rt, GC_NORMAL, gcreason::REFRESH_FRAME); 1.906 + return; 1.907 + } 1.908 + 1.909 + if (JS::IsIncrementalGCInProgress(rt) && !rt->gcInterFrameGC) { 1.910 + JS::PrepareForIncrementalGC(rt); 1.911 + GCSlice(rt, GC_NORMAL, gcreason::REFRESH_FRAME); 1.912 + } 1.913 + 1.914 + rt->gcInterFrameGC = false; 1.915 +} 1.916 + 1.917 +JS_FRIEND_API(bool) 1.918 +JS::IsIncrementalGCEnabled(JSRuntime *rt) 1.919 +{ 1.920 + return rt->gcIncrementalEnabled && rt->gcMode() == JSGC_MODE_INCREMENTAL; 1.921 +} 1.922 + 1.923 +JS_FRIEND_API(bool) 1.924 +JS::IsIncrementalGCInProgress(JSRuntime *rt) 1.925 +{ 1.926 + return rt->gcIncrementalState != gc::NO_INCREMENTAL && !rt->gcVerifyPreData; 1.927 +} 1.928 + 1.929 +JS_FRIEND_API(void) 1.930 +JS::DisableIncrementalGC(JSRuntime *rt) 1.931 +{ 1.932 + rt->gcIncrementalEnabled = false; 1.933 +} 1.934 + 1.935 +JS::AutoDisableGenerationalGC::AutoDisableGenerationalGC(JSRuntime *rt) 1.936 + : runtime(rt) 1.937 +#if defined(JSGC_GENERATIONAL) && defined(JS_GC_ZEAL) 1.938 + , restartVerifier(rt->gcVerifyPostData) 1.939 +#endif 1.940 +{ 1.941 +#ifdef JSGC_GENERATIONAL 1.942 + if (IsGenerationalGCEnabled(rt)) { 1.943 +#ifdef JS_GC_ZEAL 1.944 + if (restartVerifier) 1.945 + gc::EndVerifyPostBarriers(rt); 1.946 +#endif 1.947 + MinorGC(rt, JS::gcreason::API); 1.948 + rt->gcNursery.disable(); 1.949 + rt->gcStoreBuffer.disable(); 1.950 + } 1.951 +#endif 1.952 + ++rt->gcGenerationalDisabled; 1.953 +} 1.954 + 1.955 +JS::AutoDisableGenerationalGC::~AutoDisableGenerationalGC() 1.956 +{ 1.957 + JS_ASSERT(runtime->gcGenerationalDisabled > 0); 1.958 + --runtime->gcGenerationalDisabled; 1.959 +#ifdef JSGC_GENERATIONAL 1.960 + if (runtime->gcGenerationalDisabled == 0) { 1.961 + runtime->gcNursery.enable(); 1.962 + runtime->gcStoreBuffer.enable(); 1.963 +#ifdef JS_GC_ZEAL 1.964 + if (restartVerifier) 1.965 + gc::StartVerifyPostBarriers(runtime); 1.966 +#endif 1.967 + } 1.968 +#endif 1.969 +} 1.970 + 1.971 +extern JS_FRIEND_API(bool) 1.972 +JS::IsGenerationalGCEnabled(JSRuntime *rt) 1.973 +{ 1.974 + return rt->gcGenerationalDisabled == 0; 1.975 +} 1.976 + 1.977 +JS_FRIEND_API(bool) 1.978 +JS::IsIncrementalBarrierNeeded(JSRuntime *rt) 1.979 +{ 1.980 + return rt->gcIncrementalState == gc::MARK && !rt->isHeapBusy(); 1.981 +} 1.982 + 1.983 +JS_FRIEND_API(bool) 1.984 +JS::IsIncrementalBarrierNeeded(JSContext *cx) 1.985 +{ 1.986 + return IsIncrementalBarrierNeeded(cx->runtime()); 1.987 +} 1.988 + 1.989 +JS_FRIEND_API(void) 1.990 +JS::IncrementalObjectBarrier(JSObject *obj) 1.991 +{ 1.992 + if (!obj) 1.993 + return; 1.994 + 1.995 + JS_ASSERT(!obj->zone()->runtimeFromMainThread()->isHeapMajorCollecting()); 1.996 + 1.997 + AutoMarkInDeadZone amn(obj->zone()); 1.998 + 1.999 + JSObject::writeBarrierPre(obj); 1.1000 +} 1.1001 + 1.1002 +JS_FRIEND_API(void) 1.1003 +JS::IncrementalReferenceBarrier(void *ptr, JSGCTraceKind kind) 1.1004 +{ 1.1005 + if (!ptr) 1.1006 + return; 1.1007 + 1.1008 + if (kind == JSTRACE_STRING && StringIsPermanentAtom(static_cast<JSString *>(ptr))) 1.1009 + return; 1.1010 + 1.1011 + gc::Cell *cell = static_cast<gc::Cell *>(ptr); 1.1012 + Zone *zone = kind == JSTRACE_OBJECT 1.1013 + ? static_cast<JSObject *>(cell)->zone() 1.1014 + : cell->tenuredZone(); 1.1015 + 1.1016 + JS_ASSERT(!zone->runtimeFromMainThread()->isHeapMajorCollecting()); 1.1017 + 1.1018 + AutoMarkInDeadZone amn(zone); 1.1019 + 1.1020 + if (kind == JSTRACE_OBJECT) 1.1021 + JSObject::writeBarrierPre(static_cast<JSObject*>(cell)); 1.1022 + else if (kind == JSTRACE_STRING) 1.1023 + JSString::writeBarrierPre(static_cast<JSString*>(cell)); 1.1024 + else if (kind == JSTRACE_SCRIPT) 1.1025 + JSScript::writeBarrierPre(static_cast<JSScript*>(cell)); 1.1026 + else if (kind == JSTRACE_LAZY_SCRIPT) 1.1027 + LazyScript::writeBarrierPre(static_cast<LazyScript*>(cell)); 1.1028 + else if (kind == JSTRACE_SHAPE) 1.1029 + Shape::writeBarrierPre(static_cast<Shape*>(cell)); 1.1030 + else if (kind == JSTRACE_BASE_SHAPE) 1.1031 + BaseShape::writeBarrierPre(static_cast<BaseShape*>(cell)); 1.1032 + else if (kind == JSTRACE_TYPE_OBJECT) 1.1033 + types::TypeObject::writeBarrierPre((types::TypeObject *) ptr); 1.1034 + else 1.1035 + MOZ_ASSUME_UNREACHABLE("invalid trace kind"); 1.1036 +} 1.1037 + 1.1038 +JS_FRIEND_API(void) 1.1039 +JS::IncrementalValueBarrier(const Value &v) 1.1040 +{ 1.1041 + js::HeapValue::writeBarrierPre(v); 1.1042 +} 1.1043 + 1.1044 +JS_FRIEND_API(void) 1.1045 +JS::PokeGC(JSRuntime *rt) 1.1046 +{ 1.1047 + rt->gcPoke = true; 1.1048 +} 1.1049 + 1.1050 +JS_FRIEND_API(JSCompartment *) 1.1051 +js::GetAnyCompartmentInZone(JS::Zone *zone) 1.1052 +{ 1.1053 + CompartmentsInZoneIter comp(zone); 1.1054 + JS_ASSERT(!comp.done()); 1.1055 + return comp.get(); 1.1056 +} 1.1057 + 1.1058 +bool 1.1059 +JS::ObjectPtr::isAboutToBeFinalized() 1.1060 +{ 1.1061 + return JS_IsAboutToBeFinalized(&value); 1.1062 +} 1.1063 + 1.1064 +void 1.1065 +JS::ObjectPtr::trace(JSTracer *trc, const char *name) 1.1066 +{ 1.1067 + JS_CallHeapObjectTracer(trc, &value, name); 1.1068 +} 1.1069 + 1.1070 +JS_FRIEND_API(JSObject *) 1.1071 +js::GetTestingFunctions(JSContext *cx) 1.1072 +{ 1.1073 + RootedObject obj(cx, JS_NewObject(cx, nullptr, NullPtr(), NullPtr())); 1.1074 + if (!obj) 1.1075 + return nullptr; 1.1076 + 1.1077 + if (!DefineTestingFunctions(cx, obj, false)) 1.1078 + return nullptr; 1.1079 + 1.1080 + return obj; 1.1081 +} 1.1082 + 1.1083 +#ifdef DEBUG 1.1084 +JS_FRIEND_API(unsigned) 1.1085 +js::GetEnterCompartmentDepth(JSContext *cx) 1.1086 +{ 1.1087 + return cx->getEnterCompartmentDepth(); 1.1088 +} 1.1089 +#endif 1.1090 + 1.1091 +JS_FRIEND_API(void) 1.1092 +js::SetDOMCallbacks(JSRuntime *rt, const DOMCallbacks *callbacks) 1.1093 +{ 1.1094 + rt->DOMcallbacks = callbacks; 1.1095 +} 1.1096 + 1.1097 +JS_FRIEND_API(const DOMCallbacks *) 1.1098 +js::GetDOMCallbacks(JSRuntime *rt) 1.1099 +{ 1.1100 + return rt->DOMcallbacks; 1.1101 +} 1.1102 + 1.1103 +static const void *gDOMProxyHandlerFamily = nullptr; 1.1104 +static uint32_t gDOMProxyExpandoSlot = 0; 1.1105 +static DOMProxyShadowsCheck gDOMProxyShadowsCheck; 1.1106 + 1.1107 +JS_FRIEND_API(void) 1.1108 +js::SetDOMProxyInformation(const void *domProxyHandlerFamily, uint32_t domProxyExpandoSlot, 1.1109 + DOMProxyShadowsCheck domProxyShadowsCheck) 1.1110 +{ 1.1111 + gDOMProxyHandlerFamily = domProxyHandlerFamily; 1.1112 + gDOMProxyExpandoSlot = domProxyExpandoSlot; 1.1113 + gDOMProxyShadowsCheck = domProxyShadowsCheck; 1.1114 +} 1.1115 + 1.1116 +const void * 1.1117 +js::GetDOMProxyHandlerFamily() 1.1118 +{ 1.1119 + return gDOMProxyHandlerFamily; 1.1120 +} 1.1121 + 1.1122 +uint32_t 1.1123 +js::GetDOMProxyExpandoSlot() 1.1124 +{ 1.1125 + return gDOMProxyExpandoSlot; 1.1126 +} 1.1127 + 1.1128 +DOMProxyShadowsCheck 1.1129 +js::GetDOMProxyShadowsCheck() 1.1130 +{ 1.1131 + return gDOMProxyShadowsCheck; 1.1132 +} 1.1133 + 1.1134 +bool 1.1135 +js::detail::IdMatchesAtom(jsid id, JSAtom *atom) 1.1136 +{ 1.1137 + return id == INTERNED_STRING_TO_JSID(nullptr, atom); 1.1138 +} 1.1139 + 1.1140 +JS_FRIEND_API(JSContext *) 1.1141 +js::DefaultJSContext(JSRuntime *rt) 1.1142 +{ 1.1143 + if (rt->defaultJSContextCallback) { 1.1144 + JSContext *cx = rt->defaultJSContextCallback(rt); 1.1145 + JS_ASSERT(cx); 1.1146 + return cx; 1.1147 + } 1.1148 + JS_ASSERT(rt->contextList.getFirst() == rt->contextList.getLast()); 1.1149 + return rt->contextList.getFirst(); 1.1150 +} 1.1151 + 1.1152 +JS_FRIEND_API(void) 1.1153 +js::SetDefaultJSContextCallback(JSRuntime *rt, DefaultJSContextCallback cb) 1.1154 +{ 1.1155 + rt->defaultJSContextCallback = cb; 1.1156 +} 1.1157 + 1.1158 +#ifdef DEBUG 1.1159 +JS_FRIEND_API(void) 1.1160 +js::Debug_SetActiveJSContext(JSRuntime *rt, JSContext *cx) 1.1161 +{ 1.1162 + rt->activeContext = cx; 1.1163 +} 1.1164 +#endif 1.1165 + 1.1166 +JS_FRIEND_API(void) 1.1167 +js::SetCTypesActivityCallback(JSRuntime *rt, CTypesActivityCallback cb) 1.1168 +{ 1.1169 + rt->ctypesActivityCallback = cb; 1.1170 +} 1.1171 + 1.1172 +js::AutoCTypesActivityCallback::AutoCTypesActivityCallback(JSContext *cx, 1.1173 + js::CTypesActivityType beginType, 1.1174 + js::CTypesActivityType endType 1.1175 + MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL) 1.1176 + : cx(cx), callback(cx->runtime()->ctypesActivityCallback), endType(endType) 1.1177 +{ 1.1178 + MOZ_GUARD_OBJECT_NOTIFIER_INIT; 1.1179 + 1.1180 + if (callback) 1.1181 + callback(cx, beginType); 1.1182 +} 1.1183 + 1.1184 +JS_FRIEND_API(void) 1.1185 +js::SetObjectMetadataCallback(JSContext *cx, ObjectMetadataCallback callback) 1.1186 +{ 1.1187 + cx->compartment()->setObjectMetadataCallback(callback); 1.1188 +} 1.1189 + 1.1190 +JS_FRIEND_API(bool) 1.1191 +js::SetObjectMetadata(JSContext *cx, HandleObject obj, HandleObject metadata) 1.1192 +{ 1.1193 + return JSObject::setMetadata(cx, obj, metadata); 1.1194 +} 1.1195 + 1.1196 +JS_FRIEND_API(JSObject *) 1.1197 +js::GetObjectMetadata(JSObject *obj) 1.1198 +{ 1.1199 + return obj->getMetadata(); 1.1200 +} 1.1201 + 1.1202 +JS_FRIEND_API(void) 1.1203 +js::UnsafeDefineElement(JSContext *cx, JS::HandleObject obj, uint32_t index, JS::HandleValue value) 1.1204 +{ 1.1205 + JS_ASSERT(obj->isNative()); 1.1206 + JS_ASSERT(index < obj->getDenseInitializedLength()); 1.1207 + obj->setDenseElementWithType(cx, index, value); 1.1208 +} 1.1209 + 1.1210 +JS_FRIEND_API(bool) 1.1211 +js_DefineOwnProperty(JSContext *cx, JSObject *objArg, jsid idArg, 1.1212 + JS::Handle<js::PropertyDescriptor> descriptor, bool *bp) 1.1213 +{ 1.1214 + RootedObject obj(cx, objArg); 1.1215 + RootedId id(cx, idArg); 1.1216 + JS_ASSERT(cx->runtime()->heapState == js::Idle); 1.1217 + CHECK_REQUEST(cx); 1.1218 + assertSameCompartment(cx, obj, id, descriptor.value()); 1.1219 + if (descriptor.hasGetterObject()) 1.1220 + assertSameCompartment(cx, descriptor.getterObject()); 1.1221 + if (descriptor.hasSetterObject()) 1.1222 + assertSameCompartment(cx, descriptor.setterObject()); 1.1223 + 1.1224 + return DefineOwnProperty(cx, HandleObject(obj), id, descriptor, bp); 1.1225 +} 1.1226 + 1.1227 +JS_FRIEND_API(bool) 1.1228 +js_ReportIsNotFunction(JSContext *cx, JS::HandleValue v) 1.1229 +{ 1.1230 + return ReportIsNotFunction(cx, v); 1.1231 +} 1.1232 + 1.1233 +#ifdef DEBUG 1.1234 +JS_PUBLIC_API(bool) 1.1235 +js::IsInRequest(JSContext *cx) 1.1236 +{ 1.1237 +#ifdef JS_THREADSAFE 1.1238 + return !!cx->runtime()->requestDepth; 1.1239 +#else 1.1240 + return true; 1.1241 +#endif 1.1242 +} 1.1243 +#endif 1.1244 + 1.1245 +#ifdef JSGC_GENERATIONAL 1.1246 +JS_FRIEND_API(void) 1.1247 +JS_StoreObjectPostBarrierCallback(JSContext* cx, 1.1248 + void (*callback)(JSTracer *trc, JSObject *key, void *data), 1.1249 + JSObject *key, void *data) 1.1250 +{ 1.1251 + JSRuntime *rt = cx->runtime(); 1.1252 + if (IsInsideNursery(rt, key)) 1.1253 + rt->gcStoreBuffer.putCallback(callback, key, data); 1.1254 +} 1.1255 + 1.1256 +extern JS_FRIEND_API(void) 1.1257 +JS_StoreStringPostBarrierCallback(JSContext* cx, 1.1258 + void (*callback)(JSTracer *trc, JSString *key, void *data), 1.1259 + JSString *key, void *data) 1.1260 +{ 1.1261 + JSRuntime *rt = cx->runtime(); 1.1262 + if (IsInsideNursery(rt, key)) 1.1263 + rt->gcStoreBuffer.putCallback(callback, key, data); 1.1264 +} 1.1265 +#endif /* JSGC_GENERATIONAL */