Bug 562991 - Change JS_SetTrap closure argument type from void* to jsval (r=brendan)
authorLuke Wagner <lw@mozilla.com>
Fri, 30 Apr 2010 17:34:54 -0700
changeset 41863 3e73a0559b82f83a5a38c526942221d5d630499f
parent 41862 12049657ec6546d8e9f7a746838fa6cb57bd7f01
child 41864 47d29a5adb38a81d517bc2c35a7ed152f907a820
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersbrendan
bugs562991
milestone1.9.3a5pre
Bug 562991 - Change JS_SetTrap closure argument type from void* to jsval (r=brendan)
js/jsd/jsd_scpt.c
js/src/jsapi-tests/testTrap.cpp
js/src/jscntxt.h
js/src/jsdbgapi.cpp
js/src/jsdbgapi.h
js/src/jsinterp.cpp
js/src/jsops.cpp
js/src/jsprvtd.h
js/src/shell/js.cpp
--- a/js/jsd/jsd_scpt.c
+++ b/js/jsd/jsd_scpt.c
@@ -710,19 +710,19 @@ static JSBool
     }
     JSD_UNLOCK_SCRIPTS(jsdc);
     return JS_FALSE;
 }
 
 
 JSTrapStatus
 jsd_TrapHandler(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval,
-                void *closure)
+                jsval closure)
 {
-    JSDExecHook* jsdhook = (JSDExecHook*) JSVAL_TO_PRIVATE(((jsval)closure));
+    JSDExecHook* jsdhook = (JSDExecHook*) JSVAL_TO_PRIVATE(closure);
     JSD_ExecutionHookProc hook;
     void* hookData;
     JSDContext*  jsdc;
     JSDScript* jsdscript;
 
     JSD_LOCK();
 
     if( NULL == (jsdc = jsd_JSDContextForJSContext(cx)) ||
@@ -794,18 +794,18 @@ jsd_SetExecutionHook(JSDContext*        
         return JS_FALSE;
     }
     jsdhook->jsdscript  = jsdscript;
     jsdhook->pc         = pc;
     jsdhook->hook       = hook;
     jsdhook->callerdata = callerdata;
 
     if( ! JS_SetTrap(jsdc->dumbContext, jsdscript->script, 
-                     (jsbytecode*)pc, jsd_TrapHandler, 
-                     (void*) PRIVATE_TO_JSVAL(jsdhook)) )
+                     (jsbytecode*)pc, jsd_TrapHandler,
+                     PRIVATE_TO_JSVAL(jsdhook)) )
     {
         free(jsdhook);
         JSD_UNLOCK();
         return JS_FALSE;
     }
 
     JS_APPEND_LINK(&jsdhook->links, &jsdscript->hooks);
     JSD_UNLOCK();
--- a/js/src/jsapi-tests/testTrap.cpp
+++ b/js/src/jsapi-tests/testTrap.cpp
@@ -1,19 +1,20 @@
 #include "tests.h"
 #include "jsdbgapi.h"
 
 static int emptyTrapCallCount = 0;
 
 static JSTrapStatus
 EmptyTrapHandler(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval,
-                 void *closure)
+                 jsval closure)
 {
     JS_GC(cx);
-    ++emptyTrapCallCount;
+    if (JSVAL_IS_STRING(closure))
+        ++emptyTrapCallCount;
     return JSTRAP_CONTINUE;
 }
 
 BEGIN_TEST(testTrap_gc)
 {
     static const char source[] =
 "var i = 0;\n"
 "var sum = 0;\n"
@@ -44,18 +45,18 @@ BEGIN_TEST(testTrap_gc)
     CHECK(line2);
 
     jsbytecode *line6 = JS_LineNumberToPC(cx, script, 5);
     CHECK(line2);
 
     static const char trapClosureText[] = "some trap closure";
     JSString *trapClosure = JS_NewStringCopyZ(cx, trapClosureText);
     CHECK(trapClosure);
-    JS_SetTrap(cx, script, line2, EmptyTrapHandler, trapClosure);
-    JS_SetTrap(cx, script, line6, EmptyTrapHandler, trapClosure);
+    JS_SetTrap(cx, script, line2, EmptyTrapHandler, STRING_TO_JSVAL(trapClosure));
+    JS_SetTrap(cx, script, line6, EmptyTrapHandler, STRING_TO_JSVAL(trapClosure));
 
     JS_GC(cx);
 
     CHECK(0 == strcmp(trapClosureText, JS_GetStringBytes(trapClosure)));
 
     // execute
     CHECK(JS_ExecuteScript(cx, global, script, v2.addr()));
     CHECK(emptyTrapCallCount == 11);
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -860,17 +860,17 @@ struct JSRuntime {
     JSCList             contextList;
 
     /* Per runtime debug hooks -- see jsprvtd.h and jsdbgapi.h. */
     JSDebugHooks        globalDebugHooks;
 
 #ifdef JS_TRACER
     /* True if any debug hooks not supported by the JIT are enabled. */
     bool debuggerInhibitsJIT() const {
-        return (globalDebugHooks.interruptHandler ||
+        return (globalDebugHooks.interruptHook ||
                 globalDebugHooks.callHook ||
                 globalDebugHooks.objectHook);
     }
 #endif
 
     /* More debugging state, see jsdbgapi.c. */
     JSCList             trapList;
     JSCList             watchPointList;
--- a/js/src/jsdbgapi.cpp
+++ b/js/src/jsdbgapi.cpp
@@ -72,17 +72,17 @@
 using namespace js;
 
 typedef struct JSTrap {
     JSCList         links;
     JSScript        *script;
     jsbytecode      *pc;
     JSOp            op;
     JSTrapHandler   handler;
-    void            *closure;
+    jsval           closure;
 } JSTrap;
 
 #define DBG_LOCK(rt)            JS_ACQUIRE_LOCK((rt)->debuggerLock)
 #define DBG_UNLOCK(rt)          JS_RELEASE_LOCK((rt)->debuggerLock)
 #define DBG_LOCK_EVAL(rt,expr)  (DBG_LOCK(rt), (expr), DBG_UNLOCK(rt))
 
 /*
  * NB: FindTrap must be called with rt->debuggerLock acquired.
@@ -137,17 +137,17 @@ js_UntrapScriptCode(JSContext *cx, JSScr
         }
     }
     DBG_UNLOCK(rt);
     return code;
 }
 
 JS_PUBLIC_API(JSBool)
 JS_SetTrap(JSContext *cx, JSScript *script, jsbytecode *pc,
-           JSTrapHandler handler, void *closure)
+           JSTrapHandler handler, jsval closure)
 {
     JSTrap *junk, *trap, *twin;
     JSRuntime *rt;
     uint32 sample;
 
     if (script == JSScript::emptyScript()) {
         JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR, js_GetErrorMessage,
                                      NULL, JSMSG_READ_ONLY, "empty script");
@@ -163,17 +163,17 @@ JS_SetTrap(JSContext *cx, JSScript *scri
         JS_ASSERT(trap->script == script && trap->pc == pc);
         JS_ASSERT(*pc == JSOP_TRAP);
     } else {
         sample = rt->debuggerMutations;
         DBG_UNLOCK(rt);
         trap = (JSTrap *) cx->malloc(sizeof *trap);
         if (!trap)
             return JS_FALSE;
-        trap->closure = NULL;
+        trap->closure = JSVAL_NULL;
         DBG_LOCK(rt);
         twin = (rt->debuggerMutations != sample)
                ? FindTrap(rt, script, pc)
                : NULL;
         if (twin) {
             junk = trap;
             trap = twin;
         } else {
@@ -215,26 +215,26 @@ DestroyTrapAndUnlock(JSContext *cx, JSTr
     JS_REMOVE_LINK(&trap->links);
     *trap->pc = (jsbytecode)trap->op;
     DBG_UNLOCK(cx->runtime);
     cx->free(trap);
 }
 
 JS_PUBLIC_API(void)
 JS_ClearTrap(JSContext *cx, JSScript *script, jsbytecode *pc,
-             JSTrapHandler *handlerp, void **closurep)
+             JSTrapHandler *handlerp, jsval *closurep)
 {
     JSTrap *trap;
 
     DBG_LOCK(cx->runtime);
     trap = FindTrap(cx->runtime, script, pc);
     if (handlerp)
         *handlerp = trap ? trap->handler : NULL;
     if (closurep)
-        *closurep = trap ? trap->closure : NULL;
+        *closurep = trap ? trap->closure : JSVAL_NULL;
     if (trap)
         DestroyTrapAndUnlock(cx, trap);
     else
         DBG_UNLOCK(cx->runtime);
 }
 
 JS_PUBLIC_API(void)
 JS_ClearScriptTraps(JSContext *cx, JSScript *script)
@@ -290,20 +290,18 @@ JS_ClearAllTraps(JSContext *cx)
 void
 js_MarkTraps(JSTracer *trc)
 {
     JSRuntime *rt = trc->context->runtime;
 
     for (JSTrap *trap = (JSTrap *) rt->trapList.next;
          &trap->links != &rt->trapList;
          trap = (JSTrap *) trap->links.next) {
-        if (trap->closure) {
-            JS_SET_TRACING_NAME(trc, "trap->closure");
-            js_CallValueTracerIfGCThing(trc, (jsval) trap->closure);
-        }
+        JS_SET_TRACING_NAME(trc, "trap->closure");
+        js_CallValueTracerIfGCThing(trc, trap->closure);
     }
 }
 
 JS_PUBLIC_API(JSTrapStatus)
 JS_HandleTrap(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval)
 {
     JSTrap *trap;
     jsint op;
@@ -370,46 +368,46 @@ LeaveTraceRT(JSRuntime *rt)
     JS_UNLOCK_GC(rt);
 
     if (cx)
         LeaveTrace(cx);
 }
 #endif
 
 JS_PUBLIC_API(JSBool)
-JS_SetInterrupt(JSRuntime *rt, JSTrapHandler handler, void *closure)
+JS_SetInterrupt(JSRuntime *rt, JSInterruptHook hook, void *closure)
 {
 #ifdef JS_TRACER
     {
         AutoLockGC lock(rt);
         bool wasInhibited = rt->debuggerInhibitsJIT();
 #endif
-        rt->globalDebugHooks.interruptHandler = handler;
-        rt->globalDebugHooks.interruptHandlerData = closure;
+        rt->globalDebugHooks.interruptHook = hook;
+        rt->globalDebugHooks.interruptHookData = closure;
 #ifdef JS_TRACER
         JITInhibitingHookChange(rt, wasInhibited);
     }
     LeaveTraceRT(rt);
 #endif
     return JS_TRUE;
 }
 
 JS_PUBLIC_API(JSBool)
-JS_ClearInterrupt(JSRuntime *rt, JSTrapHandler *handlerp, void **closurep)
+JS_ClearInterrupt(JSRuntime *rt, JSInterruptHook *hoop, void **closurep)
 {
 #ifdef JS_TRACER
     AutoLockGC lock(rt);
     bool wasInhibited = rt->debuggerInhibitsJIT();
 #endif
-    if (handlerp)
-        *handlerp = rt->globalDebugHooks.interruptHandler;
+    if (hoop)
+        *hoop = rt->globalDebugHooks.interruptHook;
     if (closurep)
-        *closurep = rt->globalDebugHooks.interruptHandlerData;
-    rt->globalDebugHooks.interruptHandler = 0;
-    rt->globalDebugHooks.interruptHandlerData = 0;
+        *closurep = rt->globalDebugHooks.interruptHookData;
+    rt->globalDebugHooks.interruptHook = 0;
+    rt->globalDebugHooks.interruptHookData = 0;
 #ifdef JS_TRACER
     JITInhibitingHookChange(rt, wasInhibited);
 #endif
     return JS_TRUE;
 }
 
 /************************************************************************/
 
@@ -1556,17 +1554,17 @@ JS_PutPropertyDescArray(JSContext *cx, J
             js_RemoveRoot(cx->runtime, &pd[i].alias);
     }
     cx->free(pd);
 }
 
 /************************************************************************/
 
 JS_PUBLIC_API(JSBool)
-JS_SetDebuggerHandler(JSRuntime *rt, JSTrapHandler handler, void *closure)
+JS_SetDebuggerHandler(JSRuntime *rt, JSDebuggerHandler handler, void *closure)
 {
     rt->globalDebugHooks.debuggerHandler = handler;
     rt->globalDebugHooks.debuggerHandlerData = closure;
     return JS_TRUE;
 }
 
 JS_PUBLIC_API(JSBool)
 JS_SetSourceHandler(JSRuntime *rt, JSSourceHandler handler, void *closure)
@@ -1618,17 +1616,17 @@ JS_SetObjectHook(JSRuntime *rt, JSObject
     }
     if (hook)
         LeaveTraceRT(rt);
 #endif
     return JS_TRUE;
 }
 
 JS_PUBLIC_API(JSBool)
-JS_SetThrowHook(JSRuntime *rt, JSTrapHandler hook, void *closure)
+JS_SetThrowHook(JSRuntime *rt, JSThrowHook hook, void *closure)
 {
     rt->globalDebugHooks.throwHook = hook;
     rt->globalDebugHooks.throwHookData = closure;
     return JS_TRUE;
 }
 
 JS_PUBLIC_API(JSBool)
 JS_SetDebugErrorHook(JSRuntime *rt, JSDebugErrorHook hook, void *closure)
--- a/js/src/jsdbgapi.h
+++ b/js/src/jsdbgapi.h
@@ -52,41 +52,42 @@ JS_BEGIN_EXTERN_C
 /*
  * Unexported library-private helper used to unpatch all traps in a script.
  * Returns script->code if script has no traps, else a JS_malloc'ed copy of
  * script->code which the caller must JS_free, or null on JS_malloc OOM.
  */
 extern jsbytecode *
 js_UntrapScriptCode(JSContext *cx, JSScript *script);
 
+/* The closure argument will be marked. */
 extern JS_PUBLIC_API(JSBool)
 JS_SetTrap(JSContext *cx, JSScript *script, jsbytecode *pc,
-           JSTrapHandler handler, void *closure);
+           JSTrapHandler handler, jsval closure);
 
 extern JS_PUBLIC_API(JSOp)
 JS_GetTrapOpcode(JSContext *cx, JSScript *script, jsbytecode *pc);
 
 extern JS_PUBLIC_API(void)
 JS_ClearTrap(JSContext *cx, JSScript *script, jsbytecode *pc,
-             JSTrapHandler *handlerp, void **closurep);
+             JSTrapHandler *handlerp, jsval *closurep);
 
 extern JS_PUBLIC_API(void)
 JS_ClearScriptTraps(JSContext *cx, JSScript *script);
 
 extern JS_PUBLIC_API(void)
 JS_ClearAllTraps(JSContext *cx);
 
 extern JS_PUBLIC_API(JSTrapStatus)
 JS_HandleTrap(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval);
 
 extern JS_PUBLIC_API(JSBool)
-JS_SetInterrupt(JSRuntime *rt, JSTrapHandler handler, void *closure);
+JS_SetInterrupt(JSRuntime *rt, JSInterruptHook handler, void *closure);
 
 extern JS_PUBLIC_API(JSBool)
-JS_ClearInterrupt(JSRuntime *rt, JSTrapHandler *handlerp, void **closurep);
+JS_ClearInterrupt(JSRuntime *rt, JSInterruptHook *handlerp, void **closurep);
 
 /************************************************************************/
 
 extern JS_PUBLIC_API(JSBool)
 JS_SetWatchPoint(JSContext *cx, JSObject *obj, jsval id,
                  JSWatchPointHandler handler, void *closure);
 
 extern JS_PUBLIC_API(JSBool)
@@ -332,32 +333,32 @@ extern JS_PUBLIC_API(JSBool)
 JS_GetPropertyDescArray(JSContext *cx, JSObject *obj, JSPropertyDescArray *pda);
 
 extern JS_PUBLIC_API(void)
 JS_PutPropertyDescArray(JSContext *cx, JSPropertyDescArray *pda);
 
 /************************************************************************/
 
 extern JS_PUBLIC_API(JSBool)
-JS_SetDebuggerHandler(JSRuntime *rt, JSTrapHandler handler, void *closure);
+JS_SetDebuggerHandler(JSRuntime *rt, JSDebuggerHandler hook, void *closure);
 
 extern JS_PUBLIC_API(JSBool)
 JS_SetSourceHandler(JSRuntime *rt, JSSourceHandler handler, void *closure);
 
 extern JS_PUBLIC_API(JSBool)
 JS_SetExecuteHook(JSRuntime *rt, JSInterpreterHook hook, void *closure);
 
 extern JS_PUBLIC_API(JSBool)
 JS_SetCallHook(JSRuntime *rt, JSInterpreterHook hook, void *closure);
 
 extern JS_PUBLIC_API(JSBool)
 JS_SetObjectHook(JSRuntime *rt, JSObjectHook hook, void *closure);
 
 extern JS_PUBLIC_API(JSBool)
-JS_SetThrowHook(JSRuntime *rt, JSTrapHandler hook, void *closure);
+JS_SetThrowHook(JSRuntime *rt, JSThrowHook hook, void *closure);
 
 extern JS_PUBLIC_API(JSBool)
 JS_SetDebugErrorHook(JSRuntime *rt, JSDebugErrorHook hook, void *closure);
 
 /************************************************************************/
 
 extern JS_PUBLIC_API(size_t)
 JS_GetObjectTotalSize(JSContext *cx, JSObject *obj);
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -2514,17 +2514,17 @@ js_Interpret(JSContext *cx)
     if (script->staticLevel < JS_DISPLAY_SIZE) {
         JSStackFrame **disp = &cx->display[script->staticLevel];
         fp->displaySave = *disp;
         *disp = fp;
     }
 
 # define CHECK_INTERRUPT_HANDLER()                                            \
     JS_BEGIN_MACRO                                                            \
-        if (cx->debugHooks->interruptHandler)                                 \
+        if (cx->debugHooks->interruptHook)                                    \
             ENABLE_INTERRUPTS();                                              \
     JS_END_MACRO
 
     /*
      * Load the debugger's interrupt hook here and after calling out to native
      * functions (but not to getters, setters, or other native hooks), so we do
      * not have to reload it each time through the interpreter loop -- we hope
      * the compiler can keep it in a register when it is non-null.
@@ -2674,17 +2674,17 @@ js_Interpret(JSContext *cx)
     if (TRACE_RECORDER(cx))
         AbortRecording(cx, "error or exception while recording");
 #endif
 
     if (!cx->throwing) {
         /* This is an error, not a catchable exception, quit the frame ASAP. */
         ok = JS_FALSE;
     } else {
-        JSTrapHandler handler;
+        JSThrowHook handler;
         JSTryNote *tn, *tnlimit;
         uint32 offset;
 
         /* Call debugger throw hook if set. */
         handler = cx->debugHooks->throwHook;
         if (handler) {
             switch (handler(cx, script, regs.pc, &rval,
                             cx->debugHooks->throwHookData)) {
--- a/js/src/jsops.cpp
+++ b/js/src/jsops.cpp
@@ -43,24 +43,24 @@
 #if JS_THREADED_INTERP
   interrupt:
 #else /* !JS_THREADED_INTERP */
   case -1:
     JS_ASSERT(switchMask == -1);
 #endif /* !JS_THREADED_INTERP */
     {
         bool moreInterrupts = false;
-        JSTrapHandler handler = cx->debugHooks->interruptHandler;
-        if (handler) {
+        JSInterruptHook hook = cx->debugHooks->interruptHook;
+        if (hook) {
 #ifdef JS_TRACER
             if (TRACE_RECORDER(cx))
-                AbortRecording(cx, "interrupt handler");
+                AbortRecording(cx, "interrupt hook");
 #endif
-            switch (handler(cx, script, regs.pc, &rval,
-                            cx->debugHooks->interruptHandlerData)) {
+            switch (hook(cx, script, regs.pc, &rval,
+                         cx->debugHooks->interruptHookData)) {
               case JSTRAP_ERROR:
                 goto error;
               case JSTRAP_CONTINUE:
                 break;
               case JSTRAP_RETURN:
                 fp->rval = rval;
                 ok = JS_TRUE;
                 goto forced_return;
@@ -3642,17 +3642,17 @@ BEGIN_CASE(JSOP_INSTANCEOF)
         goto error;
     regs.sp--;
     STORE_OPND(-1, BOOLEAN_TO_JSVAL(cond));
 END_CASE(JSOP_INSTANCEOF)
 
 #if JS_HAS_DEBUGGER_KEYWORD
 BEGIN_CASE(JSOP_DEBUGGER)
 {
-    JSTrapHandler handler = cx->debugHooks->debuggerHandler;
+    JSDebuggerHandler handler = cx->debugHooks->debuggerHandler;
     if (handler) {
         switch (handler(cx, script, regs.pc, &rval, cx->debugHooks->debuggerHandlerData)) {
         case JSTRAP_ERROR:
             goto error;
         case JSTRAP_CONTINUE:
             break;
         case JSTRAP_RETURN:
             fp->rval = rval;
--- a/js/src/jsprvtd.h
+++ b/js/src/jsprvtd.h
@@ -207,17 +207,29 @@ typedef enum JSTrapStatus {
     JSTRAP_CONTINUE,
     JSTRAP_RETURN,
     JSTRAP_THROW,
     JSTRAP_LIMIT
 } JSTrapStatus;
 
 typedef JSTrapStatus
 (* JSTrapHandler)(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval,
-                  void *closure);
+                  jsval closure);
+
+typedef JSTrapStatus
+(* JSInterruptHook)(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval,
+                    void *closure);
+
+typedef JSTrapStatus
+(* JSDebuggerHandler)(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval,
+                      void *closure);
+
+typedef JSTrapStatus
+(* JSThrowHook)(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval,
+                void *closure);
 
 typedef JSBool
 (* JSWatchPointHandler)(JSContext *cx, JSObject *obj, jsval id, jsval old,
                         jsval *newp, void *closure);
 
 /* called just after script creation */
 typedef void
 (* JSNewScriptHook)(JSContext  *cx,
@@ -269,33 +281,33 @@ typedef void *
 typedef void
 (* JSObjectHook)(JSContext *cx, JSObject *obj, JSBool isNew, void *closure);
 
 typedef JSBool
 (* JSDebugErrorHook)(JSContext *cx, const char *message, JSErrorReport *report,
                      void *closure);
 
 typedef struct JSDebugHooks {
-    JSTrapHandler       interruptHandler;
-    void                *interruptHandlerData;
+    JSInterruptHook     interruptHook;
+    void                *interruptHookData;
     JSNewScriptHook     newScriptHook;
     void                *newScriptHookData;
     JSDestroyScriptHook destroyScriptHook;
     void                *destroyScriptHookData;
-    JSTrapHandler       debuggerHandler;
+    JSDebuggerHandler   debuggerHandler;
     void                *debuggerHandlerData;
     JSSourceHandler     sourceHandler;
     void                *sourceHandlerData;
     JSInterpreterHook   executeHook;
     void                *executeHookData;
     JSInterpreterHook   callHook;
     void                *callHookData;
     JSObjectHook        objectHook;
     void                *objectHookData;
-    JSTrapHandler       throwHook;
+    JSThrowHook         throwHook;
     void                *throwHookData;
     JSDebugErrorHook    debugErrorHook;
     void                *debugErrorHookData;
 } JSDebugHooks;
 
 /* JSObjectOps function pointer typedefs. */
 
 /*
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -1452,22 +1452,22 @@ GetTrapArgs(JSContext *cx, uintN argc, j
                 return JS_FALSE;
         }
     }
     return JS_TRUE;
 }
 
 static JSTrapStatus
 TrapHandler(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval,
-            void *closure)
+            jsval closure)
 {
     JSString *str;
     JSStackFrame *caller;
 
-    str = (JSString *) closure;
+    str = JSVAL_TO_STRING(closure);
     caller = JS_GetScriptedCaller(cx, NULL);
     if (!JS_EvaluateUCInStackFrame(cx, caller,
                                    JS_GetStringChars(str), JS_GetStringLength(str),
                                    caller->script->filename, caller->script->lineno,
                                    rval)) {
         return JSTRAP_ERROR;
     }
     if (!JSVAL_IS_VOID(*rval))
@@ -1488,17 +1488,17 @@ Trap(JSContext *cx, JSObject *obj, uintN
     }
     argc--;
     str = JS_ValueToString(cx, argv[argc]);
     if (!str)
         return JS_FALSE;
     argv[argc] = STRING_TO_JSVAL(str);
     if (!GetTrapArgs(cx, argc, argv, &script, &i))
         return JS_FALSE;
-    return JS_SetTrap(cx, script, script->code + i, TrapHandler, str);
+    return JS_SetTrap(cx, script, script->code + i, TrapHandler, STRING_TO_JSVAL(str));
 }
 
 static JSBool
 Untrap(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
 {
     JSScript *script;
     int32 i;