js/src/jsfriendapi.cpp

changeset 0
6474c204b198
     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 */

mercurial