/* -*- 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/. */

/*
 * JS debugging API.
 */

#include "jsdbgapi.h"

#include <string.h>

#include "jsprvtd.h"
#include "jstypes.h"
#include "jsapi.h"
#include "jscntxt.h"
#include "jsfun.h"
#include "jsgc.h"
#include "jsobj.h"
#include "jsopcode.h"
#include "jsscript.h"
#include "jsstr.h"
#include "jswatchpoint.h"

#include "frontend/SourceNotes.h"
#include "jit/AsmJS.h"
#include "vm/Debugger.h"
#include "vm/Interpreter.h"
#include "vm/Shape.h"

#ifdef JS_ION
#include "jit/AsmJSModule.h"
#endif

#include "jsatominlines.h"
#include "jsinferinlines.h"
#include "jsscriptinlines.h"

#include "vm/Debugger-inl.h"
#include "vm/Interpreter-inl.h"
#include "vm/Stack-inl.h"

using namespace js;
using namespace js::gc;

using mozilla::PodZero;

JS_PUBLIC_API(JSBool)
JS_GetDebugMode(JSContext *cx)
{
    return cx->compartment()->debugMode();
}

JS_PUBLIC_API(JSBool)
JS_SetDebugMode(JSContext *cx, JSBool debug)
{
    return JS_SetDebugModeForCompartment(cx, cx->compartment(), debug);
}

JS_PUBLIC_API(void)
JS_SetRuntimeDebugMode(JSRuntime *rt, JSBool debug)
{
    rt->debugMode = !!debug;
}

static bool
IsTopFrameConstructing(JSContext *cx, AbstractFramePtr frame)
{
    ScriptFrameIter iter(cx);
    JS_ASSERT(iter.abstractFramePtr() == frame);
    return iter.isConstructing();
}

JSTrapStatus
js::ScriptDebugPrologue(JSContext *cx, AbstractFramePtr frame)
{
    JS_ASSERT_IF(frame.isStackFrame(), frame.asStackFrame() == cx->interpreterFrame());

    if (!frame.script()->selfHosted) {
        if (frame.isFramePushedByExecute()) {
            if (JSInterpreterHook hook = cx->runtime()->debugHooks.executeHook)
                frame.setHookData(hook(cx, Jsvalify(frame), IsTopFrameConstructing(cx, frame),
                                       true, 0, cx->runtime()->debugHooks.executeHookData));
        } else {
            if (JSInterpreterHook hook = cx->runtime()->debugHooks.callHook)
                frame.setHookData(hook(cx, Jsvalify(frame), IsTopFrameConstructing(cx, frame),
                                       true, 0, cx->runtime()->debugHooks.callHookData));
        }
    }

    RootedValue rval(cx);
    JSTrapStatus status = Debugger::onEnterFrame(cx, frame, &rval);
    switch (status) {
      case JSTRAP_CONTINUE:
        break;
      case JSTRAP_THROW:
        cx->setPendingException(rval);
        break;
      case JSTRAP_ERROR:
        cx->clearPendingException();
        break;
      case JSTRAP_RETURN:
        frame.setReturnValue(rval);
        break;
      default:
        JS_NOT_REACHED("bad Debugger::onEnterFrame JSTrapStatus value");
    }
    return status;
}

bool
js::ScriptDebugEpilogue(JSContext *cx, AbstractFramePtr frame, bool okArg)
{
    JS_ASSERT_IF(frame.isStackFrame(), frame.asStackFrame() == cx->interpreterFrame());

    JSBool ok = okArg;

    // We don't add hook data for self-hosted scripts, so we don't need to check for them, here.
    if (void *hookData = frame.maybeHookData()) {
        if (frame.isFramePushedByExecute()) {
            if (JSInterpreterHook hook = cx->runtime()->debugHooks.executeHook)
                hook(cx, Jsvalify(frame), IsTopFrameConstructing(cx, frame), false, &ok, hookData);
        } else {
            if (JSInterpreterHook hook = cx->runtime()->debugHooks.callHook)
                hook(cx, Jsvalify(frame), IsTopFrameConstructing(cx, frame), false, &ok, hookData);
        }
    }

    return Debugger::onLeaveFrame(cx, frame, ok);
}

JSTrapStatus
js::DebugExceptionUnwind(JSContext *cx, AbstractFramePtr frame, jsbytecode *pc)
{
    JS_ASSERT(cx->compartment()->debugMode());

    if (!cx->runtime()->debugHooks.throwHook && cx->compartment()->getDebuggees().empty())
        return JSTRAP_CONTINUE;

    /* Call debugger throw hook if set. */
    RootedValue rval(cx);
    JSTrapStatus status = Debugger::onExceptionUnwind(cx, &rval);
    if (status == JSTRAP_CONTINUE) {
        if (JSThrowHook handler = cx->runtime()->debugHooks.throwHook) {
            RootedScript script(cx, frame.script());
            status = handler(cx, script, pc, rval.address(), cx->runtime()->debugHooks.throwHookData);
        }
    }

    switch (status) {
      case JSTRAP_ERROR:
        cx->clearPendingException();
        break;

      case JSTRAP_RETURN:
        cx->clearPendingException();
        frame.setReturnValue(rval);
        break;

      case JSTRAP_THROW:
        cx->setPendingException(rval);
        break;

      case JSTRAP_CONTINUE:
        break;

      default:
        JS_NOT_REACHED("Invalid trap status");
    }

    return status;
}

JS_FRIEND_API(JSBool)
JS_SetDebugModeForAllCompartments(JSContext *cx, JSBool debug)
{
    AutoDebugModeGC dmgc(cx->runtime());

    for (CompartmentsIter c(cx->runtime()); !c.done(); c.next()) {
        // Ignore special compartments (atoms, JSD compartments)
        if (c->principals) {
            if (!c->setDebugModeFromC(cx, !!debug, dmgc))
                return false;
        }
    }
    return true;
}

JS_FRIEND_API(JSBool)
JS_SetDebugModeForCompartment(JSContext *cx, JSCompartment *comp, JSBool debug)
{
    AutoDebugModeGC dmgc(cx->runtime());
    return comp->setDebugModeFromC(cx, !!debug, dmgc);
}

static JSBool
CheckDebugMode(JSContext *cx)
{
    JSBool debugMode = JS_GetDebugMode(cx);
    /*
     * :TODO:
     * This probably should be an assertion, since it's indicative of a severe
     * API misuse.
     */
    if (!debugMode) {
        JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR, js_GetErrorMessage,
                                     NULL, JSMSG_NEED_DEBUG_MODE);
    }
    return debugMode;
}

JS_PUBLIC_API(JSBool)
JS_SetSingleStepMode(JSContext *cx, JSScript *scriptArg, JSBool singleStep)
{
    RootedScript script(cx, scriptArg);
    assertSameCompartment(cx, script);

    if (!CheckDebugMode(cx))
        return JS_FALSE;

    return script->setStepModeFlag(cx, singleStep);
}

JS_PUBLIC_API(JSBool)
JS_SetTrap(JSContext *cx, JSScript *scriptArg, jsbytecode *pc, JSTrapHandler handler, jsval closureArg)
{
    RootedScript script(cx, scriptArg);
    RootedValue closure(cx, closureArg);
    assertSameCompartment(cx, script, closure);

    if (!CheckDebugMode(cx))
        return false;

    BreakpointSite *site = script->getOrCreateBreakpointSite(cx, pc);
    if (!site)
        return false;
    site->setTrap(cx->runtime()->defaultFreeOp(), handler, closure);
    return true;
}

JS_PUBLIC_API(void)
JS_ClearTrap(JSContext *cx, JSScript *script, jsbytecode *pc,
             JSTrapHandler *handlerp, jsval *closurep)
{
    if (BreakpointSite *site = script->getBreakpointSite(pc)) {
        site->clearTrap(cx->runtime()->defaultFreeOp(), handlerp, closurep);
    } else {
        if (handlerp)
            *handlerp = NULL;
        if (closurep)
            *closurep = JSVAL_VOID;
    }
}

JS_PUBLIC_API(void)
JS_ClearScriptTraps(JSRuntime *rt, JSScript *script)
{
    script->clearTraps(rt->defaultFreeOp());
}

JS_PUBLIC_API(void)
JS_ClearAllTrapsForCompartment(JSContext *cx)
{
    cx->compartment()->clearTraps(cx->runtime()->defaultFreeOp());
}

JS_PUBLIC_API(JSBool)
JS_SetInterrupt(JSRuntime *rt, JSInterruptHook hook, void *closure)
{
    rt->debugHooks.interruptHook = hook;
    rt->debugHooks.interruptHookData = closure;
    for (InterpreterFrames *f = rt->interpreterFrames; f; f = f->older)
        f->enableInterruptsUnconditionally();
    return true;
}

JS_PUBLIC_API(JSBool)
JS_ClearInterrupt(JSRuntime *rt, JSInterruptHook *hoop, void **closurep)
{
    if (hoop)
        *hoop = rt->debugHooks.interruptHook;
    if (closurep)
        *closurep = rt->debugHooks.interruptHookData;
    rt->debugHooks.interruptHook = 0;
    rt->debugHooks.interruptHookData = 0;
    return JS_TRUE;
}

/************************************************************************/

JS_PUBLIC_API(JSBool)
JS_SetWatchPoint(JSContext *cx, JSObject *obj_, jsid id_,
                 JSWatchPointHandler handler, JSObject *closure_)
{
    assertSameCompartment(cx, obj_);

    RootedId id(cx, id_);
    RootedObject origobj(cx, obj_), closure(cx, closure_);
    RootedObject obj(cx, GetInnerObject(cx, origobj));
    if (!obj)
        return false;

    RootedValue v(cx);
    unsigned attrs;

    RootedId propid(cx);

    if (JSID_IS_INT(id)) {
        propid = id;
    } else if (JSID_IS_OBJECT(id)) {
        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_WATCH_PROP);
        return false;
    } else {
        RootedValue val(cx, IdToValue(id));
        if (!ValueToId<CanGC>(cx, val, &propid))
            return false;
    }

    /*
     * If, by unwrapping and innerizing, we changed the object, check
     * again to make sure that we're allowed to set a watch point.
     */
    if (origobj != obj && !CheckAccess(cx, obj, propid, JSACC_WATCH, &v, &attrs))
        return false;

    if (!obj->isNative()) {
        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_WATCH,
                             obj->getClass()->name);
        return false;
    }

    /*
     * Use sparse indexes for watched objects, as dense elements can be written
     * to without checking the watchpoint map.
     */
    if (!JSObject::sparsifyDenseElements(cx, obj))
        return false;

    types::MarkTypePropertyConfigured(cx, obj, propid);

    WatchpointMap *wpmap = cx->compartment()->watchpointMap;
    if (!wpmap) {
        wpmap = cx->runtime()->new_<WatchpointMap>();
        if (!wpmap || !wpmap->init()) {
            js_ReportOutOfMemory(cx);
            return false;
        }
        cx->compartment()->watchpointMap = wpmap;
    }
    return wpmap->watch(cx, obj, propid, handler, closure);
}

JS_PUBLIC_API(JSBool)
JS_ClearWatchPoint(JSContext *cx, JSObject *obj, jsid id,
                   JSWatchPointHandler *handlerp, JSObject **closurep)
{
    assertSameCompartment(cx, obj, id);

    if (WatchpointMap *wpmap = cx->compartment()->watchpointMap)
        wpmap->unwatch(obj, id, handlerp, closurep);
    return true;
}

JS_PUBLIC_API(JSBool)
JS_ClearWatchPointsForObject(JSContext *cx, JSObject *obj)
{
    assertSameCompartment(cx, obj);

    if (WatchpointMap *wpmap = cx->compartment()->watchpointMap)
        wpmap->unwatchObject(obj);
    return true;
}

JS_PUBLIC_API(JSBool)
JS_ClearAllWatchPoints(JSContext *cx)
{
    if (JSCompartment *comp = cx->compartment()) {
        if (WatchpointMap *wpmap = comp->watchpointMap)
            wpmap->clear();
    }
    return true;
}

/************************************************************************/

JS_PUBLIC_API(unsigned)
JS_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc)
{
    return js::PCToLineNumber(script, pc);
}

JS_PUBLIC_API(jsbytecode *)
JS_LineNumberToPC(JSContext *cx, JSScript *script, unsigned lineno)
{
    return js_LineNumberToPC(script, lineno);
}

JS_PUBLIC_API(jsbytecode *)
JS_EndPC(JSContext *cx, JSScript *script)
{
    return script->code + script->length;
}

JS_PUBLIC_API(JSBool)
JS_GetLinePCs(JSContext *cx, JSScript *script,
              unsigned startLine, unsigned maxLines,
              unsigned* count, unsigned** retLines, jsbytecode*** retPCs)
{
    size_t len = (script->length > maxLines ? maxLines : script->length);
    unsigned *lines = cx->pod_malloc<unsigned>(len);
    if (!lines)
        return JS_FALSE;

    jsbytecode **pcs = cx->pod_malloc<jsbytecode*>(len);
    if (!pcs) {
        js_free(lines);
        return JS_FALSE;
    }

    unsigned lineno = script->lineno;
    unsigned offset = 0;
    unsigned i = 0;
    for (jssrcnote *sn = script->notes(); !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) {
        offset += SN_DELTA(sn);
        SrcNoteType type = (SrcNoteType) SN_TYPE(sn);
        if (type == SRC_SETLINE || type == SRC_NEWLINE) {
            if (type == SRC_SETLINE)
                lineno = (unsigned) js_GetSrcNoteOffset(sn, 0);
            else
                lineno++;

            if (lineno >= startLine) {
                lines[i] = lineno;
                pcs[i] = script->code + offset;
                if (++i >= maxLines)
                    break;
            }
        }
    }

    *count = i;
    if (retLines)
        *retLines = lines;
    else
        js_free(lines);

    if (retPCs)
        *retPCs = pcs;
    else
        js_free(pcs);

    return JS_TRUE;
}

JS_PUBLIC_API(unsigned)
JS_GetFunctionArgumentCount(JSContext *cx, JSFunction *fun)
{
    return fun->nargs;
}

JS_PUBLIC_API(JSBool)
JS_FunctionHasLocalNames(JSContext *cx, JSFunction *fun)
{
    return fun->nonLazyScript()->bindings.count() > 0;
}

extern JS_PUBLIC_API(uintptr_t *)
JS_GetFunctionLocalNameArray(JSContext *cx, JSFunction *fun, void **memp)
{
    RootedScript script(cx, fun->nonLazyScript());
    BindingVector bindings(cx);
    if (!FillBindingVector(script, &bindings))
        return NULL;

    LifoAlloc &lifo = cx->tempLifoAlloc();

    // Store the LifoAlloc::Mark right before the allocation.
    LifoAlloc::Mark mark = lifo.mark();
    void *mem = lifo.alloc(sizeof(LifoAlloc::Mark) + bindings.length() * sizeof(uintptr_t));
    if (!mem) {
        js_ReportOutOfMemory(cx);
        return NULL;
    }
    *memp = mem;
    *reinterpret_cast<LifoAlloc::Mark*>(mem) = mark;

    // Munge data into the API this method implements.  Avert your eyes!
    uintptr_t *names = reinterpret_cast<uintptr_t*>((char*)mem + sizeof(LifoAlloc::Mark));
    for (size_t i = 0; i < bindings.length(); i++)
        names[i] = reinterpret_cast<uintptr_t>(bindings[i].name());

    return names;
}

extern JS_PUBLIC_API(JSAtom *)
JS_LocalNameToAtom(uintptr_t w)
{
    return reinterpret_cast<JSAtom *>(w);
}

extern JS_PUBLIC_API(JSString *)
JS_AtomKey(JSAtom *atom)
{
    return atom;
}

extern JS_PUBLIC_API(void)
JS_ReleaseFunctionLocalNameArray(JSContext *cx, void *mem)
{
    cx->tempLifoAlloc().release(*reinterpret_cast<LifoAlloc::Mark*>(mem));
}

JS_PUBLIC_API(JSScript *)
JS_GetFunctionScript(JSContext *cx, JSFunction *fun)
{
    if (fun->isNative())
        return NULL;
    if (fun->isInterpretedLazy()) {
        RootedFunction rootedFun(cx, fun);
        AutoCompartment funCompartment(cx, rootedFun);
        JSScript *script = rootedFun->getOrCreateScript(cx);
        if (!script)
            MOZ_CRASH();
        return script;
    }
    return fun->nonLazyScript();
}

JS_PUBLIC_API(JSNative)
JS_GetFunctionNative(JSContext *cx, JSFunction *fun)
{
    return fun->maybeNative();
}

JS_PUBLIC_API(JSPrincipals *)
JS_GetScriptPrincipals(JSScript *script)
{
    return script->principals();
}

JS_PUBLIC_API(JSPrincipals *)
JS_GetScriptOriginPrincipals(JSScript *script)
{
    return script->originPrincipals;
}

/************************************************************************/

JS_PUBLIC_API(JSFunction *)
JS_GetScriptFunction(JSContext *cx, JSScript *script)
{
    return script->function();
}

JS_PUBLIC_API(JSObject *)
JS_GetParentOrScopeChain(JSContext *cx, JSObject *obj)
{
    return obj->enclosingScope();
}

JS_PUBLIC_API(const char *)
JS_GetDebugClassName(JSObject *obj)
{
    if (obj->is<DebugScopeObject>())
        return obj->as<DebugScopeObject>().scope().getClass()->name;
    return obj->getClass()->name;
}

/************************************************************************/

JS_PUBLIC_API(const char *)
JS_GetScriptFilename(JSContext *cx, JSScript *script)
{
    return script->filename();
}

JS_PUBLIC_API(const jschar *)
JS_GetScriptSourceMap(JSContext *cx, JSScript *script)
{
    ScriptSource *source = script->scriptSource();
    JS_ASSERT(source);
    return source->hasSourceMap() ? source->sourceMap() : NULL;
}

JS_PUBLIC_API(unsigned)
JS_GetScriptBaseLineNumber(JSContext *cx, JSScript *script)
{
    return script->lineno;
}

JS_PUBLIC_API(unsigned)
JS_GetScriptLineExtent(JSContext *cx, JSScript *script)
{
    return js_GetScriptLineExtent(script);
}

JS_PUBLIC_API(JSVersion)
JS_GetScriptVersion(JSContext *cx, JSScript *script)
{
    return VersionNumber(script->getVersion());
}

JS_PUBLIC_API(bool)
JS_GetScriptIsSelfHosted(JSScript *script)
{
    return script->selfHosted;
}

/***************************************************************************/

JS_PUBLIC_API(void)
JS_SetNewScriptHook(JSRuntime *rt, JSNewScriptHook hook, void *callerdata)
{
    rt->debugHooks.newScriptHook = hook;
    rt->debugHooks.newScriptHookData = callerdata;
}

JS_PUBLIC_API(void)
JS_SetDestroyScriptHook(JSRuntime *rt, JSDestroyScriptHook hook,
                        void *callerdata)
{
    rt->debugHooks.destroyScriptHook = hook;
    rt->debugHooks.destroyScriptHookData = callerdata;
}

/***************************************************************************/

/* This all should be reworked to avoid requiring JSScopeProperty types. */

static JSBool
GetPropertyDesc(JSContext *cx, JSObject *obj_, HandleShape shape, JSPropertyDesc *pd)
{
    assertSameCompartment(cx, obj_);
    pd->id = IdToJsval(shape->propid());

    RootedObject obj(cx, obj_);

    JSBool wasThrowing = cx->isExceptionPending();
    RootedValue lastException(cx, UndefinedValue());
    if (wasThrowing)
        lastException = cx->getPendingException();
    cx->clearPendingException();

    Rooted<jsid> id(cx, shape->propid());
    RootedValue value(cx);
    if (!baseops::GetProperty(cx, obj, id, &value)) {
        if (!cx->isExceptionPending()) {
            pd->flags = JSPD_ERROR;
            pd->value = JSVAL_VOID;
        } else {
            pd->flags = JSPD_EXCEPTION;
            pd->value = cx->getPendingException();
        }
    } else {
        pd->flags = 0;
        pd->value = value;
    }

    if (wasThrowing)
        cx->setPendingException(lastException);

    pd->flags |= (shape->enumerable() ? JSPD_ENUMERATE : 0)
              |  (!shape->writable()  ? JSPD_READONLY  : 0)
              |  (!shape->configurable() ? JSPD_PERMANENT : 0);
    pd->spare = 0;
    pd->alias = JSVAL_VOID;

    return JS_TRUE;
}

JS_PUBLIC_API(JSBool)
JS_GetPropertyDescArray(JSContext *cx, JSObject *obj_, JSPropertyDescArray *pda)
{
    RootedObject obj(cx, obj_);

    assertSameCompartment(cx, obj);
    uint32_t i = 0;
    JSPropertyDesc *pd = NULL;

    if (obj->is<DebugScopeObject>()) {
        AutoIdVector props(cx);
        if (!Proxy::enumerate(cx, obj, props))
            return false;

        pd = cx->pod_calloc<JSPropertyDesc>(props.length());
        if (!pd)
            return false;

        for (i = 0; i < props.length(); ++i) {
            pd[i].id = JSVAL_NULL;
            pd[i].value = JSVAL_NULL;
            if (!AddValueRoot(cx, &pd[i].id, NULL))
                goto bad;
            pd[i].id = IdToValue(props[i]);
            if (!AddValueRoot(cx, &pd[i].value, NULL))
                goto bad;
            if (!Proxy::get(cx, obj, obj, props.handleAt(i), MutableHandleValue::fromMarkedLocation(&pd[i].value)))
                goto bad;
        }

        pda->length = props.length();
        pda->array = pd;
        return true;
    }

    Class *clasp;
    clasp = obj->getClass();
    if (!obj->isNative() || (clasp->flags & JSCLASS_NEW_ENUMERATE)) {
        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
                             JSMSG_CANT_DESCRIBE_PROPS, clasp->name);
        return false;
    }
    if (!clasp->enumerate(cx, obj))
        return false;

    /* Return an empty pda early if obj has no own properties. */
    if (obj->nativeEmpty()) {
        pda->length = 0;
        pda->array = NULL;
        return true;
    }

    pd = cx->pod_malloc<JSPropertyDesc>(obj->propertyCount());
    if (!pd)
        return false;

    {
        Shape::Range<CanGC> r(cx, obj->lastProperty());
        RootedShape shape(cx);
        for (; !r.empty(); r.popFront()) {
            pd[i].id = JSVAL_NULL;
            pd[i].value = JSVAL_NULL;
            pd[i].alias = JSVAL_NULL;
            if (!AddValueRoot(cx, &pd[i].id, NULL))
                goto bad;
            if (!AddValueRoot(cx, &pd[i].value, NULL))
                goto bad;
            shape = const_cast<Shape *>(&r.front());
            if (!GetPropertyDesc(cx, obj, shape, &pd[i]))
                goto bad;
            if ((pd[i].flags & JSPD_ALIAS) && !AddValueRoot(cx, &pd[i].alias, NULL))
                goto bad;
            if (++i == obj->propertyCount())
                break;
        }
    }

    pda->length = i;
    pda->array = pd;
    return true;

bad:
    pda->length = i + 1;
    pda->array = pd;
    JS_PutPropertyDescArray(cx, pda);
    return false;
}

JS_PUBLIC_API(void)
JS_PutPropertyDescArray(JSContext *cx, JSPropertyDescArray *pda)
{
    JSPropertyDesc *pd;
    uint32_t i;

    pd = pda->array;
    for (i = 0; i < pda->length; i++) {
        js_RemoveRoot(cx->runtime(), &pd[i].id);
        js_RemoveRoot(cx->runtime(), &pd[i].value);
        if (pd[i].flags & JSPD_ALIAS)
            js_RemoveRoot(cx->runtime(), &pd[i].alias);
    }
    js_free(pd);
    pda->array = NULL;
    pda->length = 0;
}

/************************************************************************/

JS_PUBLIC_API(JSBool)
JS_SetDebuggerHandler(JSRuntime *rt, JSDebuggerHandler handler, void *closure)
{
    rt->debugHooks.debuggerHandler = handler;
    rt->debugHooks.debuggerHandlerData = closure;
    return JS_TRUE;
}

JS_PUBLIC_API(JSBool)
JS_SetSourceHandler(JSRuntime *rt, JSSourceHandler handler, void *closure)
{
    rt->debugHooks.sourceHandler = handler;
    rt->debugHooks.sourceHandlerData = closure;
    return JS_TRUE;
}

JS_PUBLIC_API(JSBool)
JS_SetExecuteHook(JSRuntime *rt, JSInterpreterHook hook, void *closure)
{
    rt->debugHooks.executeHook = hook;
    rt->debugHooks.executeHookData = closure;
    return JS_TRUE;
}

JS_PUBLIC_API(JSBool)
JS_SetCallHook(JSRuntime *rt, JSInterpreterHook hook, void *closure)
{
    rt->debugHooks.callHook = hook;
    rt->debugHooks.callHookData = closure;
    return JS_TRUE;
}

JS_PUBLIC_API(JSBool)
JS_SetThrowHook(JSRuntime *rt, JSThrowHook hook, void *closure)
{
    rt->debugHooks.throwHook = hook;
    rt->debugHooks.throwHookData = closure;
    return JS_TRUE;
}

JS_PUBLIC_API(JSBool)
JS_SetDebugErrorHook(JSRuntime *rt, JSDebugErrorHook hook, void *closure)
{
    rt->debugHooks.debugErrorHook = hook;
    rt->debugHooks.debugErrorHookData = closure;
    return JS_TRUE;
}

/************************************************************************/

JS_PUBLIC_API(const JSDebugHooks *)
JS_GetGlobalDebugHooks(JSRuntime *rt)
{
    return &rt->debugHooks;
}

/************************************************************************/

JS_PUBLIC_API(void)
JS_DumpBytecode(JSContext *cx, JSScript *scriptArg)
{
#if defined(DEBUG)
    Rooted<JSScript*> script(cx, scriptArg);

    Sprinter sprinter(cx);
    if (!sprinter.init())
        return;

    fprintf(stdout, "--- SCRIPT %s:%d ---\n", script->filename(), script->lineno);
    js_Disassemble(cx, script, true, &sprinter);
    fputs(sprinter.string(), stdout);
    fprintf(stdout, "--- END SCRIPT %s:%d ---\n", script->filename(), script->lineno);
#endif
}

extern JS_PUBLIC_API(void)
JS_DumpPCCounts(JSContext *cx, JSScript *scriptArg)
{
#if defined(DEBUG)
    Rooted<JSScript*> script(cx, scriptArg);
    JS_ASSERT(script->hasScriptCounts);

    Sprinter sprinter(cx);
    if (!sprinter.init())
        return;

    fprintf(stdout, "--- SCRIPT %s:%d ---\n", script->filename(), script->lineno);
    js_DumpPCCounts(cx, script, &sprinter);
    fputs(sprinter.string(), stdout);
    fprintf(stdout, "--- END SCRIPT %s:%d ---\n", script->filename(), script->lineno);
#endif
}

namespace {

typedef Vector<JSScript *, 0, SystemAllocPolicy> ScriptsToDump;

static void
DumpBytecodeScriptCallback(JSRuntime *rt, void *data, JSScript *script)
{
    static_cast<ScriptsToDump *>(data)->append(script);
}

} /* anonymous namespace */

JS_PUBLIC_API(void)
JS_DumpCompartmentBytecode(JSContext *cx)
{
    ScriptsToDump scripts;
    IterateScripts(cx->runtime(), cx->compartment(), &scripts, DumpBytecodeScriptCallback);

    for (size_t i = 0; i < scripts.length(); i++) {
        if (scripts[i]->enclosingScriptsCompiledSuccessfully())
            JS_DumpBytecode(cx, scripts[i]);
    }
}

JS_PUBLIC_API(void)
JS_DumpCompartmentPCCounts(JSContext *cx)
{
    for (CellIter i(cx->zone(), gc::FINALIZE_SCRIPT); !i.done(); i.next()) {
        JSScript *script = i.get<JSScript>();
        if (script->compartment() != cx->compartment())
            continue;

        if (script->hasScriptCounts && script->enclosingScriptsCompiledSuccessfully())
            JS_DumpPCCounts(cx, script);
    }

#if defined(JS_ION) && defined(DEBUG)
    for (unsigned thingKind = FINALIZE_OBJECT0; thingKind < FINALIZE_OBJECT_LIMIT; thingKind++) {
        for (CellIter i(cx->zone(), (AllocKind) thingKind); !i.done(); i.next()) {
            JSObject *obj = i.get<JSObject>();
            if (obj->compartment() != cx->compartment())
                continue;

            if (IsAsmJSModuleObject(obj)) {
                AsmJSModule &module = AsmJSModuleObjectToModule(obj);

                Sprinter sprinter(cx);
                if (!sprinter.init())
                    return;

                fprintf(stdout, "--- Asm.js Module ---\n");

                for (size_t i = 0; i < module.numFunctionCounts(); i++) {
                    jit::IonScriptCounts *counts = module.functionCounts(i);
                    DumpIonScriptCounts(&sprinter, counts);
                }

                fputs(sprinter.string(), stdout);
                fprintf(stdout, "--- END Asm.js Module ---\n");
            }
        }
    }
#endif
}

JS_FRIEND_API(JSBool)
js_CallContextDebugHandler(JSContext *cx)
{
    NonBuiltinScriptFrameIter iter(cx);
    JS_ASSERT(!iter.done());

    RootedValue rval(cx);
    RootedScript script(cx, iter.script());
    switch (js::CallContextDebugHandler(cx, script, iter.pc(), rval.address())) {
      case JSTRAP_ERROR:
        JS_ClearPendingException(cx);
        return JS_FALSE;
      case JSTRAP_THROW:
        JS_SetPendingException(cx, rval);
        return JS_FALSE;
      case JSTRAP_RETURN:
      case JSTRAP_CONTINUE:
      default:
        return JS_TRUE;
    }
}

JS_PUBLIC_API(JS::StackDescription *)
JS::DescribeStack(JSContext *cx, unsigned maxFrames)
{
    Vector<FrameDescription> frames(cx);

    for (NonBuiltinScriptFrameIter i(cx); !i.done(); ++i) {
        FrameDescription desc;
        desc.script = i.script();
        unsigned column = 0;
        desc.lineno = PCToLineNumber(i.script(), i.pc(), &column);
        desc.fun = i.maybeCallee();
        // Don't zero index.
        desc.columnno = column + 1;
        if (!frames.append(desc))
            return NULL;
        if (frames.length() == maxFrames)
            break;
    }

    JS::StackDescription *desc = js_new<JS::StackDescription>();
    if (!desc)
        return NULL;

    desc->nframes = frames.length();
    desc->frames = frames.extractRawBuffer();
    return desc;
}

JS_PUBLIC_API(void)
JS::FreeStackDescription(JSContext *cx, JS::StackDescription *desc)
{
    js_delete(desc->frames);
    js_delete(desc);
}

class AutoPropertyDescArray
{
    JSContext *cx_;
    JSPropertyDescArray descArray_;

  public:
    AutoPropertyDescArray(JSContext *cx)
      : cx_(cx)
    {
        PodZero(&descArray_);
    }
    ~AutoPropertyDescArray()
    {
        if (descArray_.array)
            JS_PutPropertyDescArray(cx_, &descArray_);
    }

    void fetch(JSObject *obj) {
        JS_ASSERT(!descArray_.array);
        if (!JS_GetPropertyDescArray(cx_, obj, &descArray_))
            descArray_.array = NULL;
    }

    JSPropertyDescArray * operator ->() {
        return &descArray_;
    }
};

static const char *
FormatValue(JSContext *cx, const Value &vArg, JSAutoByteString &bytes)
{
    RootedValue v(cx, vArg);
    JSString *str = ToString<CanGC>(cx, v);
    if (!str)
        return NULL;
    const char *buf = bytes.encodeLatin1(cx, str);
    if (!buf)
        return NULL;
    const char *found = strstr(buf, "function ");
    if (found && (found - buf <= 2))
        return "[function]";
    return buf;
}

static char *
FormatFrame(JSContext *cx, const NonBuiltinScriptFrameIter &iter, char *buf, int num,
            JSBool showArgs, JSBool showLocals, JSBool showThisProps)
{
    RootedScript script(cx, iter.script());
    jsbytecode* pc = iter.pc();

    RootedObject scopeChain(cx, iter.scopeChain());
    JSAutoCompartment ac(cx, scopeChain);

    const char *filename = script->filename();
    unsigned lineno = PCToLineNumber(script, pc);
    RootedFunction fun(cx, iter.maybeCallee());
    RootedString funname(cx);
    if (fun)
        funname = fun->atom();

    RootedObject callObj(cx);
    AutoPropertyDescArray callProps(cx);

    if (!iter.isJit() && (showArgs || showLocals)) {
        JSAbstractFramePtr frame(Jsvalify(iter.abstractFramePtr()));
        callObj = frame.callObject(cx);
        if (callObj)
            callProps.fetch(callObj);
    }

    RootedValue thisVal(cx);
    AutoPropertyDescArray thisProps(cx);
    if (iter.computeThis(cx)) {
        thisVal = iter.thisv();
        if (showThisProps && !thisVal.isPrimitive())
            thisProps.fetch(&thisVal.toObject());
    }

    // print the frame number and function name
    if (funname) {
        JSAutoByteString funbytes;
        buf = JS_sprintf_append(buf, "%d %s(", num, funbytes.encodeLatin1(cx, funname));
    } else if (fun) {
        buf = JS_sprintf_append(buf, "%d anonymous(", num);
    } else {
        buf = JS_sprintf_append(buf, "%d <TOP LEVEL>", num);
    }
    if (!buf)
        return buf;

    // print the function arguments
    if (showArgs && callObj) {
        uint32_t namedArgCount = 0;
        for (uint32_t i = 0; i < callProps->length; i++) {
            JSPropertyDesc* desc = &callProps->array[i];
            JSAutoByteString nameBytes;
            const char *name = NULL;
            if (JSVAL_IS_STRING(desc->id))
                name = FormatValue(cx, desc->id, nameBytes);

            JSAutoByteString valueBytes;
            const char *value = FormatValue(cx, desc->value, valueBytes);

            buf = JS_sprintf_append(buf, "%s%s%s%s%s%s",
                                    namedArgCount ? ", " : "",
                                    name ? name :"",
                                    name ? " = " : "",
                                    desc->value.isString() ? "\"" : "",
                                    value ? value : "?unknown?",
                                    desc->value.isString() ? "\"" : "");
            if (!buf)
                return buf;
            namedArgCount++;
        }

        // print any unnamed trailing args (found in 'arguments' object)
        RootedValue val(cx);
        if (JS_GetProperty(cx, callObj, "arguments", val.address()) && val.isObject()) {
            uint32_t argCount;
            RootedObject argsObj(cx, &val.toObject());
            if (JS_GetProperty(cx, argsObj, "length", val.address()) &&
                ToUint32(cx, val, &argCount) &&
                argCount > namedArgCount)
            {
                for (uint32_t k = namedArgCount; k < argCount; k++) {
                    char number[8];
                    JS_snprintf(number, 8, "%d", (int) k);

                    if (JS_GetProperty(cx, argsObj, number, val.address())) {
                        JSAutoByteString valueBytes;
                        const char *value = FormatValue(cx, val, valueBytes);
                        buf = JS_sprintf_append(buf, "%s%s%s%s",
                                                k ? ", " : "",
                                                val.isString() ? "\"" : "",
                                                value ? value : "?unknown?",
                                                val.isString() ? "\"" : "");
                        if (!buf)
                            return buf;
                    }
                }
            }
        }
    }

    // print filename and line number
    buf = JS_sprintf_append(buf, "%s [\"%s\":%d]\n",
                            fun ? ")" : "",
                            filename ? filename : "<unknown>",
                            lineno);
    if (!buf)
        return buf;

    // print local variables
    if (showLocals && callProps->array) {
        for (uint32_t i = 0; i < callProps->length; i++) {
            JSPropertyDesc* desc = &callProps->array[i];
            JSAutoByteString nameBytes;
            JSAutoByteString valueBytes;
            const char *name = FormatValue(cx, desc->id, nameBytes);
            const char *value = FormatValue(cx, desc->value, valueBytes);

            if (name && value) {
                buf = JS_sprintf_append(buf, "    %s = %s%s%s\n",
                                        name,
                                        desc->value.isString() ? "\"" : "",
                                        value,
                                        desc->value.isString() ? "\"" : "");
                if (!buf)
                    return buf;
            }
        }
    }

    // print the value of 'this'
    if (showLocals) {
        if (!thisVal.isUndefined()) {
            JSAutoByteString thisValBytes;
            RootedString thisValStr(cx, ToString<CanGC>(cx, thisVal));
            if (thisValStr) {
                if (const char *str = thisValBytes.encodeLatin1(cx, thisValStr)) {
                    buf = JS_sprintf_append(buf, "    this = %s\n", str);
                    if (!buf)
                        return buf;
                }
            }
        } else {
            buf = JS_sprintf_append(buf, "    <failed to get 'this' value>\n");
        }
    }

    // print the properties of 'this', if it is an object
    if (showThisProps && thisProps->array) {
        for (uint32_t i = 0; i < thisProps->length; i++) {
            JSPropertyDesc* desc = &thisProps->array[i];
            if (desc->flags & JSPD_ENUMERATE) {
                JSAutoByteString nameBytes;
                JSAutoByteString valueBytes;
                const char *name = FormatValue(cx, desc->id, nameBytes);
                const char *value = FormatValue(cx, desc->value, valueBytes);
                if (name && value) {
                    buf = JS_sprintf_append(buf, "    this.%s = %s%s%s\n",
                                            name,
                                            desc->value.isString() ? "\"" : "",
                                            value,
                                            desc->value.isString() ? "\"" : "");
                    if (!buf)
                        return buf;
                }
            }
        }
    }

    return buf;
}

JS_PUBLIC_API(char *)
JS::FormatStackDump(JSContext *cx, char *buf,
                      JSBool showArgs, JSBool showLocals,
                      JSBool showThisProps)
{
    int num = 0;

    for (NonBuiltinScriptFrameIter i(cx); !i.done(); ++i) {
        buf = FormatFrame(cx, i, buf, num, showArgs, showLocals, showThisProps);
        num++;
    }

    if (!num)
        buf = JS_sprintf_append(buf, "JavaScript stack is empty\n");

    return buf;
}

JSAbstractFramePtr::JSAbstractFramePtr(void *raw)
  : ptr_(uintptr_t(raw))
{ }

JSObject *
JSAbstractFramePtr::scopeChain(JSContext *cx)
{
    AbstractFramePtr frame = Valueify(*this);
    RootedObject scopeChain(cx, frame.scopeChain());
    AutoCompartment ac(cx, scopeChain);
    return GetDebugScopeForFrame(cx, frame);
}

JSObject *
JSAbstractFramePtr::callObject(JSContext *cx)
{
    AbstractFramePtr frame = Valueify(*this);
    if (!frame.isFunctionFrame())
        return NULL;

    JSObject *o = GetDebugScopeForFrame(cx, frame);

    /*
     * Given that fp is a function frame and GetDebugScopeForFrame always fills
     * in missing scopes, we can expect to find fp's CallObject on 'o'. Note:
     *  - GetDebugScopeForFrame wraps every ScopeObject (missing or not) with
     *    a DebugScopeObject proxy.
     *  - If fp is an eval-in-function, then fp has no callobj of its own and
     *    JS_GetFrameCallObject will return the innermost function's callobj.
     */
    while (o) {
        ScopeObject &scope = o->as<DebugScopeObject>().scope();
        if (scope.is<CallObject>())
            return o;
        o = o->enclosingScope();
    }
    return NULL;
}

JSFunction *
JSAbstractFramePtr::maybeFun()
{
    AbstractFramePtr frame = Valueify(*this);
    return frame.maybeFun();
}

JSScript *
JSAbstractFramePtr::script()
{
    AbstractFramePtr frame = Valueify(*this);
    return frame.script();
}

bool
JSAbstractFramePtr::getThisValue(JSContext *cx, MutableHandleValue thisv)
{
    AbstractFramePtr frame = Valueify(*this);

    RootedObject scopeChain(cx, frame.scopeChain());
    js::AutoCompartment ac(cx, scopeChain);
    if (!ComputeThis(cx, frame))
        return false;

    thisv.set(frame.thisValue());
    return true;
}

bool
JSAbstractFramePtr::isDebuggerFrame()
{
    AbstractFramePtr frame = Valueify(*this);
    return frame.isDebuggerFrame();
}

bool
JSAbstractFramePtr::evaluateInStackFrame(JSContext *cx,
                                         const char *bytes, unsigned length,
                                         const char *filename, unsigned lineno,
                                         MutableHandleValue rval)
{
    if (!CheckDebugMode(cx))
        return false;

    size_t len = length;
    jschar *chars = InflateString(cx, bytes, &len);
    if (!chars)
        return false;
    length = (unsigned) len;

    bool ok = evaluateUCInStackFrame(cx, chars, length, filename, lineno, rval);
    js_free(chars);

    return ok;
}

bool
JSAbstractFramePtr::evaluateUCInStackFrame(JSContext *cx,
                                           const jschar *chars, unsigned length,
                                           const char *filename, unsigned lineno,
                                           MutableHandleValue rval)
{
    if (!CheckDebugMode(cx))
        return false;

    RootedObject scope(cx, scopeChain(cx));
    Rooted<Env*> env(cx, scope);
    if (!env)
        return false;

    AbstractFramePtr frame = Valueify(*this);
    if (!ComputeThis(cx, frame))
        return false;
    RootedValue thisv(cx, frame.thisValue());

    js::AutoCompartment ac(cx, env);
    return EvaluateInEnv(cx, env, thisv, frame, StableCharPtr(chars, length), length,
                         filename, lineno, rval);
}

JSBrokenFrameIterator::JSBrokenFrameIterator(JSContext *cx)
{
    NonBuiltinScriptFrameIter iter(cx);
    data_ = iter.copyData();
}

JSBrokenFrameIterator::~JSBrokenFrameIterator()
{
    js_free((ScriptFrameIter::Data *)data_);
}

bool
JSBrokenFrameIterator::done() const
{
    NonBuiltinScriptFrameIter iter(*(ScriptFrameIter::Data *)data_);
    return iter.done();
}

JSBrokenFrameIterator &
JSBrokenFrameIterator::operator++()
{
    ScriptFrameIter::Data *data = (ScriptFrameIter::Data *)data_;
    NonBuiltinScriptFrameIter iter(*data);
    ++iter;
    *data = iter.data_;
    return *this;
}

JSAbstractFramePtr
JSBrokenFrameIterator::abstractFramePtr() const
{
    NonBuiltinScriptFrameIter iter(*(ScriptFrameIter::Data *)data_);
    return Jsvalify(iter.abstractFramePtr());
}

jsbytecode *
JSBrokenFrameIterator::pc() const
{
    NonBuiltinScriptFrameIter iter(*(ScriptFrameIter::Data *)data_);
    return iter.pc();
}

bool
JSBrokenFrameIterator::isConstructing() const
{
    NonBuiltinScriptFrameIter iter(*(ScriptFrameIter::Data *)data_);
    return iter.isConstructing();
}
