diff --git a/js/src/jstracer.cpp b/js/src/jstracer.cpp index 416e4c1f94f1..c6442abafa6e 100644 --- a/js/src/jstracer.cpp +++ b/js/src/jstracer.cpp @@ -2630,8 +2630,10 @@ FlushNativeStackFrame(JSContext* cx, unsigned callDepth, JSTraceType* mp, double for (; n != 0; fp = fp->down) { --n; if (fp->callee) { - if (fp->argsobj) - JS_SetPrivate(cx, JSVAL_TO_OBJECT(fp->argsobj), fp); + // fp->argsobj->getPrivate() is NULL iff we created argsobj on trace. + if (fp->argsobj && !JSVAL_TO_OBJECT(fp->argsobj)->getPrivate()) { + JSVAL_TO_OBJECT(fp->argsobj)->setPrivate(fp); + } /* * We might return from trace with a different callee object, but it still diff --git a/js/src/trace-test/tests/basic/bug510655.js b/js/src/trace-test/tests/basic/bug510655.js new file mode 100644 index 000000000000..3ae8bbec896c --- /dev/null +++ b/js/src/trace-test/tests/basic/bug510655.js @@ -0,0 +1,15 @@ +// This should not crash (or assert in debug builds). + +(function () { + for (b in [0, 0]) { + (eval("\ + [this\ + for (b in [\ + [undefined],\ + arguments,\ + [undefined]\ + ])\ + ]\ + ")) + } +})()