/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 * vim: set ts=8 sts=4 et sw=4 tw=99:
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "jsfriendapi.h"

#include "mozilla/PodOperations.h"
#include "mozilla/StandardInteger.h"

#include "jscntxt.h"
#include "jscompartment.h"
#include "jsgc.h"
#include "jsobj.h"
#include "jswrapper.h"
#include "jsweakmap.h"
#include "jswatchpoint.h"
#include "prmjtime.h"

#include "builtin/TestingFunctions.h"

#include "jsobjinlines.h"

using namespace js;
using namespace JS;

using mozilla::PodArrayZero;

// Required by PerThreadDataFriendFields::getMainThread()
JS_STATIC_ASSERT(offsetof(JSRuntime, mainThread) ==
                 PerThreadDataFriendFields::RuntimeMainThreadOffset);

PerThreadDataFriendFields::PerThreadDataFriendFields()
  : nativeStackLimit(0)
{
#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING)
    PodArrayZero(thingGCRooters);
#endif
#if defined(DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE)
    skipGCRooters = NULL;
#endif
}

JS_FRIEND_API(void)
JS_SetSourceHook(JSRuntime *rt, JS_SourceHook hook)
{
    rt->sourceHook = hook;
}

JS_FRIEND_API(void)
JS_SetGrayGCRootsTracer(JSRuntime *rt, JSTraceDataOp traceOp, void *data)
{
    rt->gcGrayRootTracer.op = traceOp;
    rt->gcGrayRootTracer.data = data;
}

JS_FRIEND_API(JSString *)
JS_GetAnonymousString(JSRuntime *rt)
{
    JS_ASSERT(rt->hasContexts());
    return rt->atomState.anonymous;
}

JS_FRIEND_API(JSObject *)
JS_FindCompilationScope(JSContext *cx, JSObject *objArg)
{
    RootedObject obj(cx, objArg);

    /*
     * We unwrap wrappers here. This is a little weird, but it's what's being
     * asked of us.
     */
    if (obj->isWrapper())
        obj = UncheckedUnwrap(obj);

    /*
     * Innerize the target_obj so that we compile in the correct (inner)
     * scope.
     */
    if (JSObjectOp op = obj->getClass()->ext.innerObject)
        obj = op(cx, obj);
    return obj;
}

JS_FRIEND_API(JSFunction *)
JS_GetObjectFunction(JSObject *obj)
{
    if (obj->is<JSFunction>())
        return &obj->as<JSFunction>();
    return NULL;
}

JS_FRIEND_API(JSBool)
JS_SplicePrototype(JSContext *cx, JSObject *objArg, JSObject *protoArg)
{
    RootedObject obj(cx, objArg);
    RootedObject proto(cx, protoArg);
    /*
     * Change the prototype of an object which hasn't been used anywhere
     * and does not share its type with another object. Unlike JS_SetPrototype,
     * does not nuke type information for the object.
     */
    CHECK_REQUEST(cx);

    if (!obj->hasSingletonType()) {
        /*
         * We can see non-singleton objects when trying to splice prototypes
         * due to mutable __proto__ (ugh).
         */
        return JS_SetPrototype(cx, obj, proto);
    }

    Rooted<TaggedProto> tagged(cx, TaggedProto(proto));
    return obj->splicePrototype(cx, obj->getClass(), tagged);
}

JS_FRIEND_API(JSObject *)
JS_NewObjectWithUniqueType(JSContext *cx, JSClass *clasp, JSObject *protoArg, JSObject *parentArg)
{
    RootedObject proto(cx, protoArg);
    RootedObject parent(cx, parentArg);
    /*
     * Create our object with a null proto and then splice in the correct proto
     * after we setSingletonType, so that we don't pollute the default
     * TypeObject attached to our proto with information about our object, since
     * we're not going to be using that TypeObject anyway.
     */
    RootedObject obj(cx, NewObjectWithGivenProto(cx, (js::Class *)clasp, NULL, parent, SingletonObject));
    if (!obj)
        return NULL;
    if (!JS_SplicePrototype(cx, obj, proto))
        return NULL;
    return obj;
}

JS_FRIEND_API(void)
JS::PrepareZoneForGC(Zone *zone)
{
    zone->scheduleGC();
}

JS_FRIEND_API(void)
JS::PrepareForFullGC(JSRuntime *rt)
{
    for (ZonesIter zone(rt); !zone.done(); zone.next())
        zone->scheduleGC();
}

JS_FRIEND_API(void)
JS::PrepareForIncrementalGC(JSRuntime *rt)
{
    if (!JS::IsIncrementalGCInProgress(rt))
        return;

    for (ZonesIter zone(rt); !zone.done(); zone.next()) {
        if (zone->wasGCStarted())
            PrepareZoneForGC(zone);
    }
}

JS_FRIEND_API(bool)
JS::IsGCScheduled(JSRuntime *rt)
{
    for (ZonesIter zone(rt); !zone.done(); zone.next()) {
        if (zone->isGCScheduled())
            return true;
    }

    return false;
}

JS_FRIEND_API(void)
JS::SkipZoneForGC(Zone *zone)
{
    zone->unscheduleGC();
}

JS_FRIEND_API(void)
JS::GCForReason(JSRuntime *rt, gcreason::Reason reason)
{
    GC(rt, GC_NORMAL, reason);
}

JS_FRIEND_API(void)
JS::ShrinkingGC(JSRuntime *rt, gcreason::Reason reason)
{
    GC(rt, GC_SHRINK, reason);
}

JS_FRIEND_API(void)
JS::IncrementalGC(JSRuntime *rt, gcreason::Reason reason, int64_t millis)
{
    GCSlice(rt, GC_NORMAL, reason, millis);
}

JS_FRIEND_API(void)
JS::FinishIncrementalGC(JSRuntime *rt, gcreason::Reason reason)
{
    GCFinalSlice(rt, GC_NORMAL, reason);
}

JS_FRIEND_API(JSPrincipals *)
JS_GetCompartmentPrincipals(JSCompartment *compartment)
{
    return compartment->principals;
}

JS_FRIEND_API(void)
JS_SetCompartmentPrincipals(JSCompartment *compartment, JSPrincipals *principals)
{
    // Short circuit if there's no change.
    if (principals == compartment->principals)
        return;

    // Any compartment with the trusted principals -- and there can be
    // multiple -- is a system compartment.
    JSPrincipals *trusted = compartment->rt->trustedPrincipals();
    bool isSystem = principals && principals == trusted;

    // Clear out the old principals, if any.
    if (compartment->principals) {
        JS_DropPrincipals(compartment->rt, compartment->principals);
        compartment->principals = NULL;
        // We'd like to assert that our new principals is always same-origin
        // with the old one, but JSPrincipals doesn't give us a way to do that.
        // But we can at least assert that we're not switching between system
        // and non-system.
        JS_ASSERT(compartment->isSystem == isSystem);
    }

    // Set up the new principals.
    if (principals) {
        JS_HoldPrincipals(principals);
        compartment->principals = principals;
    }

    // Update the system flag.
    compartment->isSystem = isSystem;
}

JS_FRIEND_API(JSBool)
JS_WrapPropertyDescriptor(JSContext *cx, js::PropertyDescriptor *desc)
{
    return cx->compartment()->wrap(cx, desc);
}

JS_FRIEND_API(JSBool)
JS_WrapAutoIdVector(JSContext *cx, js::AutoIdVector &props)
{
    return cx->compartment()->wrap(cx, props);
}

JS_FRIEND_API(void)
JS_TraceShapeCycleCollectorChildren(JSTracer *trc, void *shape)
{
    MarkCycleCollectorChildren(trc, static_cast<Shape *>(shape));
}

static bool
DefineHelpProperty(JSContext *cx, HandleObject obj, const char *prop, const char *value)
{
    JSAtom *atom = Atomize(cx, value, strlen(value));
    if (!atom)
        return false;
    jsval v = STRING_TO_JSVAL(atom);
    return JS_DefineProperty(cx, obj, prop, v,
                             JS_PropertyStub, JS_StrictPropertyStub,
                             JSPROP_READONLY | JSPROP_PERMANENT);
}

JS_FRIEND_API(bool)
JS_DefineFunctionsWithHelp(JSContext *cx, JSObject *objArg, const JSFunctionSpecWithHelp *fs)
{
    RootedObject obj(cx, objArg);
    JS_ASSERT(cx->compartment() != cx->runtime()->atomsCompartment);

    CHECK_REQUEST(cx);
    assertSameCompartment(cx, obj);
    for (; fs->name; fs++) {
        JSAtom *atom = Atomize(cx, fs->name, strlen(fs->name));
        if (!atom)
            return false;

        Rooted<jsid> id(cx, AtomToId(atom));
        RootedFunction fun(cx, DefineFunction(cx, obj, id, fs->call, fs->nargs, fs->flags));
        if (!fun)
            return false;

        if (fs->usage) {
            if (!DefineHelpProperty(cx, fun, "usage", fs->usage))
                return false;
        }

        if (fs->help) {
            if (!DefineHelpProperty(cx, fun, "help", fs->help))
                return false;
        }
    }

    return true;
}

JS_FRIEND_API(bool)
js_ObjectClassIs(JSContext *cx, HandleObject obj, ESClassValue classValue)
{
    return ObjectClassIs(obj, classValue, cx);
}

JS_FRIEND_API(const char *)
js_ObjectClassName(JSContext *cx, HandleObject obj)
{
    return JSObject::className(cx, obj);
}

JS_FRIEND_API(JS::Zone *)
js::GetCompartmentZone(JSCompartment *comp)
{
    return comp->zone();
}

JS_FRIEND_API(bool)
js::IsSystemCompartment(JSCompartment *comp)
{
    return comp->isSystem;
}

JS_FRIEND_API(bool)
js::IsSystemZone(Zone *zone)
{
    return zone->isSystem;
}

JS_FRIEND_API(bool)
js::IsAtomsCompartment(JSCompartment *comp)
{
    return comp == comp->rt->atomsCompartment;
}

JS_FRIEND_API(bool)
js::IsInNonStrictPropertySet(JSContext *cx)
{
    jsbytecode *pc;
    JSScript *script = cx->currentScript(&pc, JSContext::ALLOW_CROSS_COMPARTMENT);
    return script && !script->strict && (js_CodeSpec[*pc].format & JOF_SET);
}

JS_FRIEND_API(bool)
js::IsFunctionObject(JSObject *obj)
{
    return obj->is<JSFunction>();
}

JS_FRIEND_API(bool)
js::IsScopeObject(JSObject *obj)
{
    return obj->is<ScopeObject>();
}

JS_FRIEND_API(bool)
js::IsCallObject(JSObject *obj)
{
    return obj->is<CallObject>();
}

JS_FRIEND_API(JSObject *)
js::GetObjectParentMaybeScope(JSObject *obj)
{
    return obj->enclosingScope();
}

JS_FRIEND_API(JSObject *)
js::GetGlobalForObjectCrossCompartment(JSObject *obj)
{
    return &obj->global();
}

JS_FRIEND_API(JSObject *)
js::GetDefaultGlobalForContext(JSContext *cx)
{
    return cx->maybeDefaultCompartmentObject();
}

JS_FRIEND_API(void)
js::NotifyAnimationActivity(JSObject *obj)
{
    obj->compartment()->lastAnimationTime = PRMJ_Now();
}

JS_FRIEND_API(uint32_t)
js::GetObjectSlotSpan(JSObject *obj)
{
    return obj->slotSpan();
}

JS_FRIEND_API(bool)
js::IsObjectInContextCompartment(JSObject *obj, const JSContext *cx)
{
    return obj->compartment() == cx->compartment();
}

JS_FRIEND_API(bool)
js::IsOriginalScriptFunction(JSFunction *fun)
{
    return fun->nonLazyScript()->function() == fun;
}

JS_FRIEND_API(JSScript *)
js::GetOutermostEnclosingFunctionOfScriptedCaller(JSContext *cx)
{
    ScriptFrameIter iter(cx);
    if (iter.done())
        return NULL;

    if (!iter.isFunctionFrame())
        return NULL;

    RootedFunction scriptedCaller(cx, iter.callee());
    RootedScript outermost(cx, scriptedCaller->nonLazyScript());
    for (StaticScopeIter i(cx, scriptedCaller); !i.done(); i++) {
        if (i.type() == StaticScopeIter::FUNCTION)
            outermost = i.funScript();
    }
    return outermost;
}

JS_FRIEND_API(JSFunction *)
js::DefineFunctionWithReserved(JSContext *cx, JSObject *objArg, const char *name, JSNative call,
                               unsigned nargs, unsigned attrs)
{
    RootedObject obj(cx, objArg);
    JS_THREADSAFE_ASSERT(cx->compartment() != cx->runtime()->atomsCompartment);
    CHECK_REQUEST(cx);
    assertSameCompartment(cx, obj);
    JSAtom *atom = Atomize(cx, name, strlen(name));
    if (!atom)
        return NULL;
    Rooted<jsid> id(cx, AtomToId(atom));
    return DefineFunction(cx, obj, id, call, nargs, attrs, JSFunction::ExtendedFinalizeKind);
}

JS_FRIEND_API(JSFunction *)
js::NewFunctionWithReserved(JSContext *cx, JSNative native, unsigned nargs, unsigned flags,
                            JSObject *parentArg, const char *name)
{
    RootedObject parent(cx, parentArg);
    JS_THREADSAFE_ASSERT(cx->compartment() != cx->runtime()->atomsCompartment);

    CHECK_REQUEST(cx);
    assertSameCompartment(cx, parent);

    RootedAtom atom(cx);
    if (name) {
        atom = Atomize(cx, name, strlen(name));
        if (!atom)
            return NULL;
    }

    JSFunction::Flags funFlags = JSAPIToJSFunctionFlags(flags);
    return NewFunction(cx, NullPtr(), native, nargs, funFlags, parent, atom,
                       JSFunction::ExtendedFinalizeKind);
}

JS_FRIEND_API(JSFunction *)
js::NewFunctionByIdWithReserved(JSContext *cx, JSNative native, unsigned nargs, unsigned flags, JSObject *parentArg,
                                jsid id)
{
    RootedObject parent(cx, parentArg);
    JS_ASSERT(JSID_IS_STRING(id));
    JS_THREADSAFE_ASSERT(cx->compartment() != cx->runtime()->atomsCompartment);
    CHECK_REQUEST(cx);
    assertSameCompartment(cx, parent);

    RootedAtom atom(cx, JSID_TO_ATOM(id));
    JSFunction::Flags funFlags = JSAPIToJSFunctionFlags(flags);
    return NewFunction(cx, NullPtr(), native, nargs, funFlags, parent, atom,
                       JSFunction::ExtendedFinalizeKind);
}

JS_FRIEND_API(JSObject *)
js::InitClassWithReserved(JSContext *cx, JSObject *objArg, JSObject *parent_protoArg,
                          JSClass *clasp, JSNative constructor, unsigned nargs,
                          const JSPropertySpec *ps, const JSFunctionSpec *fs,
                          const JSPropertySpec *static_ps, const JSFunctionSpec *static_fs)
{
    RootedObject obj(cx, objArg);
    RootedObject parent_proto(cx, parent_protoArg);
    CHECK_REQUEST(cx);
    assertSameCompartment(cx, obj, parent_proto);
    return js_InitClass(cx, obj, parent_proto, Valueify(clasp), constructor,
                        nargs, ps, fs, static_ps, static_fs, NULL,
                        JSFunction::ExtendedFinalizeKind);
}

JS_FRIEND_API(const Value &)
js::GetFunctionNativeReserved(JSObject *fun, size_t which)
{
    JS_ASSERT(fun->as<JSFunction>().isNative());
    return fun->as<JSFunction>().getExtendedSlot(which);
}

JS_FRIEND_API(void)
js::SetFunctionNativeReserved(JSObject *fun, size_t which, const Value &val)
{
    JS_ASSERT(fun->as<JSFunction>().isNative());
    fun->as<JSFunction>().setExtendedSlot(which, val);
}

JS_FRIEND_API(void)
js::SetReservedSlotWithBarrier(JSObject *obj, size_t slot, const js::Value &value)
{
    obj->setSlot(slot, value);
}

JS_FRIEND_API(bool)
js::GetGeneric(JSContext *cx, JSObject *objArg, JSObject *receiverArg, jsid idArg,
               Value *vp)
{
    RootedObject obj(cx, objArg), receiver(cx, receiverArg);
    RootedId id(cx, idArg);
    RootedValue value(cx);
    if (!JSObject::getGeneric(cx, obj, receiver, id, &value))
        return false;
    *vp = value;
    return true;
}

void
js::SetPreserveWrapperCallback(JSRuntime *rt, PreserveWrapperCallback callback)
{
    rt->preserveWrapperCallback = callback;
}

/*
 * The below code is for temporary telemetry use. It can be removed when
 * sufficient data has been harvested.
 */

namespace js {
// Defined in vm/GlobalObject.cpp.
extern size_t sSetProtoCalled;
}

JS_FRIEND_API(size_t)
JS_SetProtoCalled(JSContext *)
{
    return sSetProtoCalled;
}

// Defined in jsiter.cpp.
extern size_t sCustomIteratorCount;

JS_FRIEND_API(size_t)
JS_GetCustomIteratorCount(JSContext *cx)
{
    return sCustomIteratorCount;
}

JS_FRIEND_API(JSBool)
JS_IsDeadWrapper(JSObject *obj)
{
    if (!IsProxy(obj)) {
        return false;
    }

    BaseProxyHandler *handler = GetProxyHandler(obj);
    return handler->family() == &DeadObjectProxy::sDeadObjectFamily;
}

void
js::TraceWeakMaps(WeakMapTracer *trc)
{
    WeakMapBase::traceAllMappings(trc);
    WatchpointMap::traceAll(trc);
}

extern JS_FRIEND_API(bool)
js::AreGCGrayBitsValid(JSRuntime *rt)
{
    return rt->gcGrayBitsValid;
}

JS_FRIEND_API(JSGCTraceKind)
js::GCThingTraceKind(void *thing)
{
    JS_ASSERT(thing);
    return gc::GetGCThingTraceKind(thing);
}

JS_FRIEND_API(void)
js::VisitGrayWrapperTargets(Zone *zone, GCThingCallback callback, void *closure)
{
    for (CompartmentsInZoneIter comp(zone); !comp.done(); comp.next()) {
        for (JSCompartment::WrapperEnum e(comp); !e.empty(); e.popFront()) {
            gc::Cell *thing = e.front().key.wrapped;
            if (thing->isMarked(gc::GRAY))
                callback(closure, thing);
        }
    }
}

JS_FRIEND_API(JSObject *)
js::GetWeakmapKeyDelegate(JSObject *key)
{
    if (JSWeakmapKeyDelegateOp op = key->getClass()->ext.weakmapKeyDelegateOp)
        return op(key);
    return NULL;
}

JS_FRIEND_API(void)
JS_SetAccumulateTelemetryCallback(JSRuntime *rt, JSAccumulateTelemetryDataCallback callback)
{
    rt->telemetryCallback = callback;
}

JS_FRIEND_API(JSObject *)
JS_CloneObject(JSContext *cx, JSObject *obj_, JSObject *proto_, JSObject *parent_)
{
    RootedObject obj(cx, obj_);
    Rooted<js::TaggedProto> proto(cx, proto_);
    RootedObject parent(cx, parent_);
    return CloneObject(cx, obj, proto, parent);
}

#ifdef DEBUG
JS_FRIEND_API(void)
js_DumpString(JSString *str)
{
    str->dump();
}

JS_FRIEND_API(void)
js_DumpAtom(JSAtom *atom)
{
    atom->dump();
}

JS_FRIEND_API(void)
js_DumpChars(const jschar *s, size_t n)
{
    fprintf(stderr, "jschar * (%p) = ", (void *) s);
    JSString::dumpChars(s, n);
    fputc('\n', stderr);
}

JS_FRIEND_API(void)
js_DumpObject(JSObject *obj)
{
    if (!obj) {
        fprintf(stderr, "NULL\n");
        return;
    }
    obj->dump();
}

#endif

struct JSDumpHeapTracer : public JSTracer
{
    FILE   *output;

    JSDumpHeapTracer(FILE *fp)
      : output(fp)
    {}
};

static char
MarkDescriptor(void *thing)
{
    gc::Cell *cell = static_cast<gc::Cell*>(thing);
    if (cell->isMarked(gc::BLACK))
        return cell->isMarked(gc::GRAY) ? 'G' : 'B';
    else
        return cell->isMarked(gc::GRAY) ? 'X' : 'W';
}

static void
DumpHeapVisitZone(JSRuntime *rt, void *data, Zone *zone)
{
    JSDumpHeapTracer *dtrc = static_cast<JSDumpHeapTracer *>(data);
    fprintf(dtrc->output, "# zone %p\n", (void *)zone);
}

static void
DumpHeapVisitCompartment(JSRuntime *rt, void *data, JSCompartment *comp)
{
    char name[1024];
    if (rt->compartmentNameCallback)
        (*rt->compartmentNameCallback)(rt, comp, name, sizeof(name));
    else
        strcpy(name, "<unknown>");

    JSDumpHeapTracer *dtrc = static_cast<JSDumpHeapTracer *>(data);
    fprintf(dtrc->output, "# compartment %s [in zone %p]\n", name, (void *)comp->zone());
}

static void
DumpHeapVisitArena(JSRuntime *rt, void *data, gc::Arena *arena,
                   JSGCTraceKind traceKind, size_t thingSize)
{
    JSDumpHeapTracer *dtrc = static_cast<JSDumpHeapTracer *>(data);
    fprintf(dtrc->output, "# arena allockind=%u size=%u\n",
            unsigned(arena->aheader.getAllocKind()), unsigned(thingSize));
}

static void
DumpHeapVisitCell(JSRuntime *rt, void *data, void *thing,
                  JSGCTraceKind traceKind, size_t thingSize)
{
    JSDumpHeapTracer *dtrc = static_cast<JSDumpHeapTracer *>(data);
    char cellDesc[1024];
    JS_GetTraceThingInfo(cellDesc, sizeof(cellDesc), dtrc, thing, traceKind, true);
    fprintf(dtrc->output, "%p %c %s\n", thing, MarkDescriptor(thing), cellDesc);
    JS_TraceChildren(dtrc, thing, traceKind);
}

static void
DumpHeapVisitChild(JSTracer *trc, void **thingp, JSGCTraceKind kind)
{
    JSDumpHeapTracer *dtrc = static_cast<JSDumpHeapTracer *>(trc);
    char buffer[1024];
    fprintf(dtrc->output, "> %p %c %s\n", *thingp, MarkDescriptor(*thingp),
            JS_GetTraceEdgeName(dtrc, buffer, sizeof(buffer)));
}

static void
DumpHeapVisitRoot(JSTracer *trc, void **thingp, JSGCTraceKind kind)
{
    JSDumpHeapTracer *dtrc = static_cast<JSDumpHeapTracer *>(trc);
    char buffer[1024];
    fprintf(dtrc->output, "%p %c %s\n", *thingp, MarkDescriptor(*thingp),
            JS_GetTraceEdgeName(dtrc, buffer, sizeof(buffer)));
}

void
js::DumpHeapComplete(JSRuntime *rt, FILE *fp)
{
    JSDumpHeapTracer dtrc(fp);

    JS_TracerInit(&dtrc, rt, DumpHeapVisitRoot);
    TraceRuntime(&dtrc);

    fprintf(dtrc.output, "==========\n");

    JS_TracerInit(&dtrc, rt, DumpHeapVisitChild);
    IterateZonesCompartmentsArenasCells(rt, &dtrc,
                                        DumpHeapVisitZone,
                                        DumpHeapVisitCompartment,
                                        DumpHeapVisitArena,
                                        DumpHeapVisitCell);

    fflush(dtrc.output);
}

JS_FRIEND_API(const JSStructuredCloneCallbacks *)
js::GetContextStructuredCloneCallbacks(JSContext *cx)
{
    return cx->runtime()->structuredCloneCallbacks;
}

JS_FRIEND_API(bool)
js::CanCallContextDebugHandler(JSContext *cx)
{
    return !!cx->runtime()->debugHooks.debuggerHandler;
}

JS_FRIEND_API(JSTrapStatus)
js::CallContextDebugHandler(JSContext *cx, JSScript *script, jsbytecode *bc, Value *rval)
{
    if (!cx->runtime()->debugHooks.debuggerHandler)
        return JSTRAP_RETURN;

    return cx->runtime()->debugHooks.debuggerHandler(cx, script, bc, rval,
                                                   cx->runtime()->debugHooks.debuggerHandlerData);
}

#ifdef JS_THREADSAFE
JS_FRIEND_API(bool)
js::ContextHasOutstandingRequests(const JSContext *cx)
{
    return cx->outstandingRequests > 0;
}
#endif

JS_FRIEND_API(bool)
js::HasUnrootedGlobal(const JSContext *cx)
{
    return cx->hasOption(JSOPTION_UNROOTED_GLOBAL);
}

JS_FRIEND_API(void)
js::SetActivityCallback(JSRuntime *rt, ActivityCallback cb, void *arg)
{
    rt->activityCallback = cb;
    rt->activityCallbackArg = arg;
}

JS_FRIEND_API(bool)
js::IsContextRunningJS(JSContext *cx)
{
    return cx->currentlyRunning();
}

JS_FRIEND_API(JS::GCSliceCallback)
JS::SetGCSliceCallback(JSRuntime *rt, GCSliceCallback callback)
{
    JS::GCSliceCallback old = rt->gcSliceCallback;
    rt->gcSliceCallback = callback;
    return old;
}

JS_FRIEND_API(bool)
JS::WasIncrementalGC(JSRuntime *rt)
{
    return rt->gcIsIncremental;
}

jschar *
GCDescription::formatMessage(JSRuntime *rt) const
{
    return rt->gcStats.formatMessage();
}

jschar *
GCDescription::formatJSON(JSRuntime *rt, uint64_t timestamp) const
{
    return rt->gcStats.formatJSON(timestamp);
}

JS_FRIEND_API(AnalysisPurgeCallback)
js::SetAnalysisPurgeCallback(JSRuntime *rt, AnalysisPurgeCallback callback)
{
    AnalysisPurgeCallback old = rt->analysisPurgeCallback;
    rt->analysisPurgeCallback = callback;
    return old;
}

JS_FRIEND_API(void)
JS::NotifyDidPaint(JSRuntime *rt)
{
    if (rt->gcZeal() == gc::ZealFrameVerifierPreValue) {
        gc::VerifyBarriers(rt, gc::PreBarrierVerifier);
        return;
    }

    if (rt->gcZeal() == gc::ZealFrameVerifierPostValue) {
        gc::VerifyBarriers(rt, gc::PostBarrierVerifier);
        return;
    }

    if (rt->gcZeal() == gc::ZealFrameGCValue) {
        PrepareForFullGC(rt);
        GCSlice(rt, GC_NORMAL, gcreason::REFRESH_FRAME);
        return;
    }

    if (JS::IsIncrementalGCInProgress(rt) && !rt->gcInterFrameGC) {
        JS::PrepareForIncrementalGC(rt);
        GCSlice(rt, GC_NORMAL, gcreason::REFRESH_FRAME);
    }

    rt->gcInterFrameGC = false;
}

JS_FRIEND_API(bool)
JS::IsIncrementalGCEnabled(JSRuntime *rt)
{
    return rt->gcIncrementalEnabled && rt->gcMode == JSGC_MODE_INCREMENTAL;
}

JS_FRIEND_API(bool)
JS::IsIncrementalGCInProgress(JSRuntime *rt)
{
    return (rt->gcIncrementalState != gc::NO_INCREMENTAL && !rt->gcVerifyPreData);
}

JS_FRIEND_API(void)
JS::DisableIncrementalGC(JSRuntime *rt)
{
    rt->gcIncrementalEnabled = false;
}

extern JS_FRIEND_API(void)
JS::DisableGenerationalGC(JSRuntime *rt)
{
    rt->gcGenerationalEnabled = false;
#ifdef JSGC_GENERATIONAL
    rt->gcNursery.disable();
    rt->gcStoreBuffer.disable();
#endif
}

JS_FRIEND_API(bool)
JS::IsIncrementalBarrierNeeded(JSRuntime *rt)
{
    return (rt->gcIncrementalState == gc::MARK && !rt->isHeapBusy());
}

JS_FRIEND_API(bool)
JS::IsIncrementalBarrierNeeded(JSContext *cx)
{
    return IsIncrementalBarrierNeeded(cx->runtime());
}

JS_FRIEND_API(void)
JS::IncrementalObjectBarrier(JSObject *obj)
{
    if (!obj)
        return;

    JS_ASSERT(!obj->zone()->rt->isHeapMajorCollecting());

    AutoMarkInDeadZone amn(obj->zone());

    JSObject::writeBarrierPre(obj);
}

JS_FRIEND_API(void)
JS::IncrementalReferenceBarrier(void *ptr, JSGCTraceKind kind)
{
    if (!ptr)
        return;

    gc::Cell *cell = static_cast<gc::Cell *>(ptr);
    Zone *zone = kind == JSTRACE_OBJECT
                 ? static_cast<JSObject *>(cell)->zone()
                 : cell->tenuredZone();

    JS_ASSERT(!zone->rt->isHeapMajorCollecting());

    AutoMarkInDeadZone amn(zone);

    if (kind == JSTRACE_OBJECT)
        JSObject::writeBarrierPre(static_cast<JSObject*>(cell));
    else if (kind == JSTRACE_STRING)
        JSString::writeBarrierPre(static_cast<JSString*>(cell));
    else if (kind == JSTRACE_SCRIPT)
        JSScript::writeBarrierPre(static_cast<JSScript*>(cell));
    else if (kind == JSTRACE_LAZY_SCRIPT)
        LazyScript::writeBarrierPre(static_cast<LazyScript*>(cell));
    else if (kind == JSTRACE_SHAPE)
        Shape::writeBarrierPre(static_cast<Shape*>(cell));
    else if (kind == JSTRACE_BASE_SHAPE)
        BaseShape::writeBarrierPre(static_cast<BaseShape*>(cell));
    else if (kind == JSTRACE_TYPE_OBJECT)
        types::TypeObject::writeBarrierPre((types::TypeObject *) ptr);
    else
        JS_NOT_REACHED("invalid trace kind");
}

JS_FRIEND_API(void)
JS::IncrementalValueBarrier(const Value &v)
{
    js::HeapValue::writeBarrierPre(v);
}

JS_FRIEND_API(void)
JS::PokeGC(JSRuntime *rt)
{
    rt->gcPoke = true;
}

JS_FRIEND_API(JSCompartment *)
js::GetAnyCompartmentInZone(JS::Zone *zone)
{
    CompartmentsInZoneIter comp(zone);
    JS_ASSERT(!comp.done());
    return comp.get();
}

JS_FRIEND_API(JSObject *)
js::GetTestingFunctions(JSContext *cx)
{
    RootedObject obj(cx, JS_NewObject(cx, NULL, NULL, NULL));
    if (!obj)
        return NULL;

    if (!DefineTestingFunctions(cx, obj))
        return NULL;

    return obj;
}

#ifdef DEBUG
JS_FRIEND_API(unsigned)
js::GetEnterCompartmentDepth(JSContext *cx)
{
  return cx->getEnterCompartmentDepth();
}
#endif

JS_FRIEND_API(void)
js::SetRuntimeProfilingStack(JSRuntime *rt, ProfileEntry *stack, uint32_t *size, uint32_t max)
{
    rt->spsProfiler.setProfilingStack(stack, size, max);
}

JS_FRIEND_API(void)
js::EnableRuntimeProfilingStack(JSRuntime *rt, bool enabled)
{
    rt->spsProfiler.enable(enabled);
}

JS_FRIEND_API(jsbytecode*)
js::ProfilingGetPC(JSRuntime *rt, JSScript *script, void *ip)
{
    return rt->spsProfiler.ipToPC(script, size_t(ip));
}

JS_FRIEND_API(void)
js::SetDOMCallbacks(JSRuntime *rt, const DOMCallbacks *callbacks)
{
    rt->DOMcallbacks = callbacks;
}

JS_FRIEND_API(const DOMCallbacks *)
js::GetDOMCallbacks(JSRuntime *rt)
{
    return rt->DOMcallbacks;
}

static void *gDOMProxyHandlerFamily = NULL;
static uint32_t gDOMProxyExpandoSlot = 0;
static DOMProxyShadowsCheck gDOMProxyShadowsCheck;

JS_FRIEND_API(void)
js::SetDOMProxyInformation(void *domProxyHandlerFamily, uint32_t domProxyExpandoSlot,
                           DOMProxyShadowsCheck domProxyShadowsCheck)
{
    gDOMProxyHandlerFamily = domProxyHandlerFamily;
    gDOMProxyExpandoSlot = domProxyExpandoSlot;
    gDOMProxyShadowsCheck = domProxyShadowsCheck;
}

void *
js::GetDOMProxyHandlerFamily()
{
    return gDOMProxyHandlerFamily;
}

uint32_t
js::GetDOMProxyExpandoSlot()
{
    return gDOMProxyExpandoSlot;
}

DOMProxyShadowsCheck
js::GetDOMProxyShadowsCheck()
{
    return gDOMProxyShadowsCheck;
}

JS_FRIEND_API(void)
js::SetCTypesActivityCallback(JSRuntime *rt, CTypesActivityCallback cb)
{
    rt->ctypesActivityCallback = cb;
}

js::AutoCTypesActivityCallback::AutoCTypesActivityCallback(JSContext *cx,
                                                           js::CTypesActivityType beginType,
                                                           js::CTypesActivityType endType
                                                           MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
  : cx(cx), callback(cx->runtime()->ctypesActivityCallback), endType(endType)
{
    MOZ_GUARD_OBJECT_NOTIFIER_INIT;

    if (callback)
        callback(cx, beginType);
}

JS_FRIEND_API(void)
js::SetObjectMetadataCallback(JSContext *cx, ObjectMetadataCallback callback)
{
    // Clear any jitcode in the runtime, which behaves differently depending on
    // whether there is a creation callback.
    ReleaseAllJITCode(cx->runtime()->defaultFreeOp());

    cx->compartment()->objectMetadataCallback = callback;
}

JS_FRIEND_API(bool)
js::SetObjectMetadata(JSContext *cx, HandleObject obj, HandleObject metadata)
{
    return JSObject::setMetadata(cx, obj, metadata);
}

JS_FRIEND_API(JSObject *)
js::GetObjectMetadata(JSObject *obj)
{
    return obj->getMetadata();
}

JS_FRIEND_API(JSBool)
js_DefineOwnProperty(JSContext *cx, JSObject *objArg, jsid idArg,
                     const js::PropertyDescriptor& descriptor, JSBool *bp)
{
    RootedObject obj(cx, objArg);
    RootedId id(cx, idArg);
    JS_ASSERT(cx->runtime()->heapState == js::Idle);
    CHECK_REQUEST(cx);
    assertSameCompartment(cx, obj, id, descriptor.value);
    if (descriptor.attrs & JSPROP_GETTER)
        assertSameCompartment(cx, CastAsObjectJsval(descriptor.getter));
    if (descriptor.attrs & JSPROP_SETTER)
        assertSameCompartment(cx, CastAsObjectJsval(descriptor.setter));

    return DefineOwnProperty(cx, HandleObject(obj), id, descriptor, bp);
}

JS_FRIEND_API(JSBool)
js_ReportIsNotFunction(JSContext *cx, const JS::Value& v)
{
    return ReportIsNotFunction(cx, v);
}

#if defined(DEBUG) && defined(JS_THREADSAFE)
JS_PUBLIC_API(bool)
js::IsInRequest(JSContext *cx)
{
    return !!cx->runtime()->requestDepth;
}
#endif
