⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jsdbgapi.c

📁 Swfdec still is development software, but has also followed a rigid no-crashes-allowed policy. I b
💻 C
📖 第 1 页 / 共 3 页
字号:
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is Mozilla Communicator client code, released * March 31, 1998. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** *//* * JS debugging API. */#include "jsstddef.h"#include <string.h>#include "jstypes.h"#include "jsutil.h" /* Added by JSIFY */#include "jsclist.h"#include "jsapi.h"#include "jscntxt.h"#include "jsconfig.h"#include "jsdbgapi.h"#include "jsfun.h"#include "jsgc.h"#include "jsinterp.h"#include "jslock.h"#include "jsobj.h"#include "jsopcode.h"#include "jsscope.h"#include "jsscript.h"#include "jsstr.h"typedef struct JSTrap {    JSCList         links;    JSScript        *script;    jsbytecode      *pc;    JSOp            op;    JSTrapHandler   handler;    void            *closure;} JSTrap;static JSTrap *FindTrap(JSRuntime *rt, JSScript *script, jsbytecode *pc){    JSTrap *trap;    for (trap = (JSTrap *)rt->trapList.next;         trap != (JSTrap *)&rt->trapList;         trap = (JSTrap *)trap->links.next) {        if (trap->script == script && trap->pc == pc)            return trap;    }    return NULL;}voidjs_PatchOpcode(JSContext *cx, JSScript *script, jsbytecode *pc, JSOp op){    JSTrap *trap;    trap = FindTrap(cx->runtime, script, pc);    if (trap)        trap->op = op;    else        *pc = (jsbytecode)op;}JS_PUBLIC_API(JSBool)JS_SetTrap(JSContext *cx, JSScript *script, jsbytecode *pc,           JSTrapHandler handler, void *closure){    JSRuntime *rt;    JSTrap *trap;    rt = cx->runtime;    trap = FindTrap(rt, script, pc);    if (trap) {        JS_ASSERT(trap->script == script && trap->pc == pc);        JS_ASSERT(*pc == JSOP_TRAP);    } else {        trap = (JSTrap *) JS_malloc(cx, sizeof *trap);        if (!trap || !js_AddRoot(cx, &trap->closure, "trap->closure")) {            if (trap)                JS_free(cx, trap);            return JS_FALSE;        }        JS_APPEND_LINK(&trap->links, &rt->trapList);        trap->script = script;        trap->pc = pc;        trap->op = (JSOp)*pc;        *pc = JSOP_TRAP;    }    trap->handler = handler;    trap->closure = closure;    return JS_TRUE;}JS_PUBLIC_API(JSOp)JS_GetTrapOpcode(JSContext *cx, JSScript *script, jsbytecode *pc){    JSTrap *trap;    trap = FindTrap(cx->runtime, script, pc);    if (!trap) {        JS_ASSERT(0);   /* XXX can't happen */        return JSOP_LIMIT;    }    return trap->op;}static voidDestroyTrap(JSContext *cx, JSTrap *trap){    JS_REMOVE_LINK(&trap->links);    *trap->pc = (jsbytecode)trap->op;    js_RemoveRoot(cx->runtime, &trap->closure);    JS_free(cx, trap);}JS_PUBLIC_API(void)JS_ClearTrap(JSContext *cx, JSScript *script, jsbytecode *pc,             JSTrapHandler *handlerp, void **closurep){    JSTrap *trap;    trap = FindTrap(cx->runtime, script, pc);    if (handlerp)        *handlerp = trap ? trap->handler : NULL;    if (closurep)        *closurep = trap ? trap->closure : NULL;    if (trap)        DestroyTrap(cx, trap);}JS_PUBLIC_API(void)JS_ClearScriptTraps(JSContext *cx, JSScript *script){    JSRuntime *rt;    JSTrap *trap, *next;    rt = cx->runtime;    for (trap = (JSTrap *)rt->trapList.next;         trap != (JSTrap *)&rt->trapList;         trap = next) {        next = (JSTrap *)trap->links.next;        if (trap->script == script)            DestroyTrap(cx, trap);    }}JS_PUBLIC_API(void)JS_ClearAllTraps(JSContext *cx){    JSRuntime *rt;    JSTrap *trap, *next;    rt = cx->runtime;    for (trap = (JSTrap *)rt->trapList.next;         trap != (JSTrap *)&rt->trapList;         trap = next) {        next = (JSTrap *)trap->links.next;        DestroyTrap(cx, trap);    }}JS_PUBLIC_API(JSTrapStatus)JS_HandleTrap(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval){    JSTrap *trap;    JSTrapStatus status;    jsint op;    trap = FindTrap(cx->runtime, script, pc);    if (!trap) {        JS_ASSERT(0);   /* XXX can't happen */        return JSTRAP_ERROR;    }    /*     * It's important that we not use 'trap->' after calling the callback --     * the callback might remove the trap!     */    op = (jsint)trap->op;    status = trap->handler(cx, script, pc, rval, trap->closure);    if (status == JSTRAP_CONTINUE) {        /* By convention, return the true op to the interpreter in rval. */        *rval = INT_TO_JSVAL(op);    }    return status;}JS_PUBLIC_API(JSBool)JS_SetInterrupt(JSRuntime *rt, JSTrapHandler handler, void *closure){    rt->interruptHandler = handler;    rt->interruptHandlerData = closure;    return JS_TRUE;}JS_PUBLIC_API(JSBool)JS_ClearInterrupt(JSRuntime *rt, JSTrapHandler *handlerp, void **closurep){    if (handlerp)        *handlerp = (JSTrapHandler)rt->interruptHandler;    if (closurep)        *closurep = rt->interruptHandlerData;    rt->interruptHandler = 0;    rt->interruptHandlerData = 0;    return JS_TRUE;}/************************************************************************/typedef struct JSWatchPoint {    JSCList             links;    JSObject            *object;        /* weak link, see js_FinalizeObject */    JSScopeProperty     *sprop;    JSPropertyOp        setter;    JSWatchPointHandler handler;    void                *closure;    jsrefcount          nrefs;} JSWatchPoint;#define HoldWatchPoint(wp) ((wp)->nrefs++)static JSBoolDropWatchPoint(JSContext *cx, JSWatchPoint *wp){    JSScopeProperty *sprop;    if (--wp->nrefs != 0)        return JS_TRUE;    /*     * Remove wp from the list, then if there are no other watchpoints for     * wp->sprop in any scope, restore wp->sprop->setter from wp.     */    JS_REMOVE_LINK(&wp->links);    sprop = wp->sprop;    if (!js_GetWatchedSetter(cx->runtime, NULL, sprop)) {        sprop = js_ChangeNativePropertyAttrs(cx, wp->object, sprop,                                             0, sprop->attrs,                                             sprop->getter, wp->setter);        if (!sprop)            return JS_FALSE;    }    js_RemoveRoot(cx->runtime, &wp->closure);    JS_free(cx, wp);    return JS_TRUE;}voidjs_MarkWatchPoints(JSRuntime *rt){    JSWatchPoint *wp;    for (wp = (JSWatchPoint *)rt->watchPointList.next;         wp != (JSWatchPoint *)&rt->watchPointList;         wp = (JSWatchPoint *)wp->links.next) {        MARK_SCOPE_PROPERTY(wp->sprop);    }}static JSWatchPoint *FindWatchPoint(JSRuntime *rt, JSScope *scope, jsid id){    JSWatchPoint *wp;    for (wp = (JSWatchPoint *)rt->watchPointList.next;         wp != (JSWatchPoint *)&rt->watchPointList;         wp = (JSWatchPoint *)wp->links.next) {        if (wp->object == scope->object && wp->sprop->id == id)            return wp;    }    return NULL;}JSScopeProperty *js_FindWatchPoint(JSRuntime *rt, JSScope *scope, jsid id){    JSWatchPoint *wp;    wp = FindWatchPoint(rt, scope, id);    if (!wp)        return NULL;    return wp->sprop;}JSPropertyOpjs_GetWatchedSetter(JSRuntime *rt, JSScope *scope,                    const JSScopeProperty *sprop){    JSWatchPoint *wp;    for (wp = (JSWatchPoint *)rt->watchPointList.next;         wp != (JSWatchPoint *)&rt->watchPointList;         wp = (JSWatchPoint *)wp->links.next) {        if ((!scope || wp->object == scope->object) && wp->sprop == sprop)            return wp->setter;    }    return NULL;}JSBool JS_DLL_CALLBACKjs_watch_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp){    JSRuntime *rt;    JSWatchPoint *wp;    JSScopeProperty *sprop;    jsval userid;    JSScope *scope;    JSBool ok;    rt = cx->runtime;    for (wp = (JSWatchPoint *)rt->watchPointList.next;         wp != (JSWatchPoint *)&rt->watchPointList;         wp = (JSWatchPoint *)wp->links.next) {        sprop = wp->sprop;        if (wp->object == obj && SPROP_USERID(sprop) == id) {            JS_LOCK_OBJ(cx, obj);            userid = SPROP_USERID(sprop);            scope = OBJ_SCOPE(obj);            JS_UNLOCK_OBJ(cx, obj);            HoldWatchPoint(wp);            ok = wp->handler(cx, obj, userid,                             SPROP_HAS_VALID_SLOT(sprop, scope)                             ? OBJ_GET_SLOT(cx, obj, wp->sprop->slot)                             : JSVAL_VOID,                             vp, wp->closure);            if (ok) {                /*                 * Create pseudo-frame for call to setter so that any                 * stack-walking security code in the setter will correctly                 * identify the guilty party.                 */                JSObject *funobj = (JSObject *) wp->closure;                JSFunction *fun = (JSFunction *) JS_GetPrivate(cx, funobj);                JSStackFrame frame;                memset(&frame, 0, sizeof(frame));                frame.script = fun->script;                frame.fun = fun;                frame.down = cx->fp;                cx->fp = &frame;                ok = !wp->setter ||                     ((sprop->attrs & JSPROP_SETTER)                      ? js_InternalCall(cx, obj, OBJECT_TO_JSVAL(wp->setter),                                        1, vp, vp)                      : wp->setter(cx, OBJ_THIS_OBJECT(cx, obj), userid, vp));                cx->fp = frame.down;            }            return DropWatchPoint(cx, wp);        }    }    JS_ASSERT(0);       /* XXX can't happen */    return JS_FALSE;}JSBool JS_DLL_CALLBACKjs_watch_set_wrapper(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,                     jsval *rval){    JSObject *funobj;    JSFunction *wrapper;    jsval userid;    funobj = JSVAL_TO_OBJECT(argv[-2]);    wrapper = (JSFunction *) JS_GetPrivate(cx, funobj);    userid = ATOM_KEY(wrapper->atom);    *rval = argv[0];    return js_watch_set(cx, obj, userid, rval);}JSPropertyOpjs_WrapWatchedSetter(JSContext *cx, jsid id, uintN attrs, JSPropertyOp setter){    JSAtom *atom;    JSFunction *wrapper;    if (!(attrs & JSPROP_SETTER))        return &js_watch_set;   /* & to silence schoolmarmish MSVC */    if (!JSVAL_IS_INT(id)) {        atom = (JSAtom *)id;    } else {        atom = js_AtomizeInt(cx, JSVAL_TO_INT(id), 0);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -