Bug 999655 - Make sure the arguments object usage in a script has been analyzed before the debugger tries to access it, r=jorendorff.
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/bug999655.js
@@ -0,0 +1,11 @@
+
+var g = newGlobal();
+var dbg = new Debugger(g);
+dbg.onNewScript = function(script) {
+ fscript = script.getChildScripts()[0];
+}
+g.eval("function f(x) { arguments[0] = 3; return x }");
+fscript.setBreakpoint(0, {hit:function(frame) {
+ assertEq(frame.arguments[0], 1);
+}});
+g.f(1);
--- a/js/src/jsscript.h
+++ b/js/src/jsscript.h
@@ -1225,22 +1225,22 @@ class JSScript : public js::gc::TenuredC
// so it can only transition from not being a generator.
MOZ_ASSERT(!isGenerator());
generatorKindBits_ = GeneratorKindAsBits(kind);
}
/*
* As an optimization, even when argsHasLocalBinding, the function prologue
* may not need to create an arguments object. This is determined by
- * needsArgsObj which is set by AnalyzeArgumentsUsage before running
- * the script the first time. When !needsArgsObj, the prologue may simply
- * write MagicValue(JS_OPTIMIZED_ARGUMENTS) to 'arguments's slot and any
- * uses of 'arguments' will be guaranteed to handle this magic value.
- * So avoid spurious arguments object creation, we maintain the invariant
- * that needsArgsObj is only called after the script has been analyzed.
+ * needsArgsObj which is set by AnalyzeArgumentsUsage. When !needsArgsObj,
+ * the prologue may simply write MagicValue(JS_OPTIMIZED_ARGUMENTS) to
+ * 'arguments's slot and any uses of 'arguments' will be guaranteed to
+ * handle this magic value. To avoid spurious arguments object creation, we
+ * maintain the invariant that needsArgsObj is only called after the script
+ * has been analyzed.
*/
bool analyzedArgsUsage() const { return !needsArgsAnalysis_; }
inline bool ensureHasAnalyzedArgsUsage(JSContext *cx);
bool needsArgsObj() const {
MOZ_ASSERT(analyzedArgsUsage());
return needsArgsObj_;
}
void setNeedsArgsObj(bool needsArgsObj);
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -4615,16 +4615,18 @@ DebuggerArguments_getArg(JSContext *cx,
* Since getters can be extracted and applied to other objects,
* there is no guarantee this object has an ith argument.
*/
MOZ_ASSERT(i >= 0);
RootedValue arg(cx);
RootedScript script(cx);
if (unsigned(i) < frame.numActualArgs()) {
script = frame.script();
+ if (!script->ensureHasAnalyzedArgsUsage(cx))
+ return false;
if (unsigned(i) < frame.numFormalArgs() && script->formalIsAliased(i)) {
for (AliasedFormalIter fi(script); ; fi++) {
if (fi.frameIndex() == unsigned(i)) {
arg = frame.callObj().aliasedVar(fi);
break;
}
}
} else if (script->argsObjAliasesFormals() && frame.hasArgsObj()) {