diff options
Diffstat (limited to 'js/src/jsopcode.cpp')
-rw-r--r-- | js/src/jsopcode.cpp | 60 |
1 files changed, 56 insertions, 4 deletions
diff --git a/js/src/jsopcode.cpp b/js/src/jsopcode.cpp index 31bbfb471..6adb5401e 100644 --- a/js/src/jsopcode.cpp +++ b/js/src/jsopcode.cpp @@ -92,7 +92,8 @@ const char * const js::CodeName[] = { /************************************************************************/ -#define COUNTS_LEN 16 +static bool +DecompileArgumentFromStack(JSContext* cx, int formalIndex, char** res); size_t js::GetVariableBytecodeLength(jsbytecode* pc) @@ -460,6 +461,34 @@ BytecodeParser::simulateOp(JSOp op, uint32_t offset, uint32_t* offsetStack, uint offsetStack[stackDepth] = tmp; } break; + + case JSOP_PICK: { + jsbytecode* pc = script_->offsetToPC(offset); + unsigned n = GET_UINT8(pc); + MOZ_ASSERT(ndefs == n + 1); + if (offsetStack) { + uint32_t top = stackDepth + n; + uint32_t tmp = offsetStack[stackDepth]; + for (uint32_t i = stackDepth; i < top; i++) + offsetStack[i] = offsetStack[i + 1]; + offsetStack[top] = tmp; + } + break; + } + + case JSOP_UNPICK: { + jsbytecode* pc = script_->offsetToPC(offset); + unsigned n = GET_UINT8(pc); + MOZ_ASSERT(ndefs == n + 1); + if (offsetStack) { + uint32_t top = stackDepth + n; + uint32_t tmp = offsetStack[top]; + for (uint32_t i = top; i > stackDepth; i--) + offsetStack[i] = offsetStack[i - 1]; + offsetStack[stackDepth] = tmp; + } + break; + } } stackDepth += ndefs; return stackDepth; @@ -1230,6 +1259,24 @@ ExpressionDecompiler::decompilePC(jsbytecode* pc) return write(loadAtom(pc)); case JSOP_GETARG: { unsigned slot = GET_ARGNO(pc); + + // For self-hosted scripts that are called from non-self-hosted code, + // decompiling the parameter name in the self-hosted script is + // unhelpful. Decompile the argument name instead. + if (script->selfHosted()) { + char* result; + if (!DecompileArgumentFromStack(cx, slot, &result)) + return false; + + // Note that decompiling the argument in the parent frame might + // not succeed. + if (result) { + bool ok = write(result); + js_free(result); + return ok; + } + } + JSAtom* atom = getArg(slot); if (!atom) return false; @@ -1593,12 +1640,17 @@ DecompileArgumentFromStack(JSContext* cx, int formalIndex, char** res) MOZ_ASSERT(frameIter.script()->selfHosted()); /* - * Get the second-to-top frame, the caller of the builtin that called the - * intrinsic. + * Get the second-to-top frame, the non-self-hosted caller of the builtin + * that called the intrinsic. */ ++frameIter; - if (frameIter.done() || !frameIter.hasScript() || frameIter.compartment() != cx->compartment()) + if (frameIter.done() || + !frameIter.hasScript() || + frameIter.script()->selfHosted() || + frameIter.compartment() != cx->compartment()) + { return true; + } RootedScript script(cx, frameIter.script()); jsbytecode* current = frameIter.pc(); |