Merge.
Merge.
--- a/js/src/jstracer.cpp
+++ b/js/src/jstracer.cpp
@@ -360,17 +360,17 @@ static bool isPromoteInt(LIns* i)
return isi2f(i) || i->isconst() ||
(i->isconstq() && (d = i->constvalf()) == jsdouble(jsint(d)) && !JSDOUBLE_IS_NEGZERO(d));
}
static bool isPromoteUint(LIns* i)
{
jsdouble d;
return isu2f(i) || i->isconst() ||
- (i->isconstq() && ((d = i->constvalf()) == (jsdouble)(jsuint)d));
+ (i->isconstq() && (d = i->constvalf()) == (jsdouble)(jsuint)d && !JSDOUBLE_IS_NEGZERO(d));
}
static bool isPromote(LIns* i)
{
return isPromoteInt(i) || isPromoteUint(i);
}
static bool isconst(LIns* i, int32_t c)
@@ -4791,17 +4791,18 @@ TraceRecorder::record_JSOP_CALL()
JSArena* a = cx->stackPool.current;
if (jsuword(newsp) > a->limit)
ABORT_TRACE("can't grow stack for Function.prototype.apply");
if (jsuword(newsp) > a->avail)
a->avail = jsuword(newsp);
}
jsval* argv = fp->argv;
- for (uintN i = 0; i < JS_MIN(argc, 2); i++) {
+ uintN nargs = JS_MIN((JS_MIN(argc, fp->fun->nargs)), 2);
+ for (uintN i = 0; i < nargs; i++) {
set(&sp[i], get(&argv[i]));
sp[i] = argv[i];
}
applyingArguments = true;
return interpretedFunctionCall(tval, tfun, argc, false);
}
if (aval_ins->fid() != F_Array_1str)
@@ -5827,17 +5828,17 @@ TraceRecorder::record_JSOP_NOP()
}
bool
TraceRecorder::record_JSOP_ARGSUB()
{
JSStackFrame* fp = cx->fp;
if (!(fp->fun->flags & JSFUN_HEAVYWEIGHT)) {
uintN slot = GET_ARGNO(fp->regs->pc);
- if (slot < fp->argc && !fp->argsobj) {
+ if (slot < fp->fun->nargs && slot < fp->argc && !fp->argsobj) {
stack(0, get(&cx->fp->argv[slot]));
return true;
}
}
ABORT_TRACE("can't trace JSOP_ARGSUB hard case");
}
bool
--- a/js/src/trace-test.js
+++ b/js/src/trace-test.js
@@ -1392,11 +1392,47 @@ function testNot() {
for (var i = 0; i < 10; ++i) {
r = [!a, !b, !c, !d, !e, !f, !g, !h, !i, !j, !k];
}
return r.join(",");
}
testNot.expected = "false,true,false,true,false,true,false,true,false,true,true";
test(testNot);
+function doTestDifferingArgc(a, b)
+{
+ var k = 0;
+ for (var i = 0; i < 10; i++)
+ {
+ k += i;
+ }
+ return k;
+}
+function testDifferingArgc()
+{
+ var x = 0;
+ x += doTestDifferingArgc(1, 2);
+ x += doTestDifferingArgc(1);
+ x += doTestDifferingArgc(1, 2, 3);
+ return x;
+}
+testDifferingArgc.expected = 45*3;
+test(testDifferingArgc);
+
+function doTestMoreArgcThanNargs()
+{
+ var x = 0;
+ for (var i = 0; i < 10; i++)
+ {
+ x = x + arguments[3];
+ }
+ return x;
+}
+function testMoreArgcThanNargs()
+{
+ return doTestMoreArgcThanNargs(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+}
+testMoreArgcThanNargs.expected = 4*10;
+test(testMoreArgcThanNargs);
+
/* Keep these at the end so that we can see the summary after the trace-debug spew. */
print("\npassed:", passes.length && passes.join(","));
print("\nFAILED:", fails.length && fails.join(","));