author | Brian Hackett <bhackett1024@gmail.com> |
Sun, 04 Sep 2011 13:33:04 -0700 | |
changeset 77890 | 77e9502bd20f3c61a639f6533535a4f763b8d792 |
parent 77889 | 8385e0145b8dbcc44b5be0baaf17a05e11af0320 |
child 77891 | aa9f4b139e389262a9e3fcd0583aefe62b20b986 |
push id | 78 |
push user | clegnitto@mozilla.com |
push date | Fri, 16 Dec 2011 17:32:24 +0000 |
treeherder | mozilla-release@79d24e644fdd [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
bugs | 684084 |
milestone | 9.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
new file mode 100644 --- /dev/null +++ b/js/src/jit-test/tests/jaeger/bug684084.js @@ -0,0 +1,7 @@ +// |jit-test| error: TypeError +function Integer( value, exception ) { + try { } catch ( e ) { } + new (value = this)( this.value ); + if ( Math.floor(value) != value || isNaN(value) ) { } +} +new Integer( 3, false );
--- a/js/src/methodjit/Compiler.cpp +++ b/js/src/methodjit/Compiler.cpp @@ -2735,19 +2735,18 @@ mjit::Compiler::generateMethod() } END_CASE(JSOP_DEBUGGER) BEGIN_CASE(JSOP_UNBRAND) jsop_unbrand(); END_CASE(JSOP_UNBRAND) BEGIN_CASE(JSOP_UNBRANDTHIS) - jsop_this(); - jsop_unbrand(); - frame.pop(); + prepareStubCall(Uses(1)); + INLINE_STUBCALL(stubs::UnbrandThis, REJOIN_FALLTHROUGH); END_CASE(JSOP_UNBRANDTHIS) BEGIN_CASE(JSOP_GETGLOBAL) BEGIN_CASE(JSOP_CALLGLOBAL) jsop_getglobal(GET_SLOTNO(PC)); if (op == JSOP_CALLGLOBAL) frame.push(UndefinedValue()); END_CASE(JSOP_GETGLOBAL) @@ -5572,16 +5571,26 @@ mjit::Compiler::jsop_this() if (type != JSVAL_TYPE_OBJECT) { Jump notObj = frame.testObject(Assembler::NotEqual, thisFe); stubcc.linkExit(notObj, Uses(1)); stubcc.leave(); OOL_STUBCALL(stubs::This, REJOIN_FALLTHROUGH); stubcc.rejoin(Changes(1)); } + /* + * Watch out for an obscure case where we don't know we are pushing + * an object: the script has not yet had a 'this' value assigned, + * so no pushed 'this' type has been inferred. Don't mark the type + * as known in this case, preserving the invariant that compiler + * types reflect inferred types. + */ + if (cx->typeInferenceEnabled() && knownPushedType(0) != JSVAL_TYPE_OBJECT) + return; + // Now we know that |this| is an object. frame.pop(); frame.learnThisIsObject(type != JSVAL_TYPE_OBJECT); frame.pushThis(); } JS_ASSERT(thisFe->isType(JSVAL_TYPE_OBJECT)); }
--- a/js/src/methodjit/StubCalls.cpp +++ b/js/src/methodjit/StubCalls.cpp @@ -2191,16 +2191,29 @@ stubs::Unbrand(VMFrame &f) if (!thisv.isObject()) return; JSObject *obj = &thisv.toObject(); if (obj->isNative()) obj->unbrand(f.cx); } void JS_FASTCALL +stubs::UnbrandThis(VMFrame &f) +{ + if (!ComputeThis(f.cx, f.fp())) + THROW(); + Value &thisv = f.fp()->thisValue(); + if (!thisv.isObject()) + return; + JSObject *obj = &thisv.toObject(); + if (obj->isNative()) + obj->unbrand(f.cx); +} + +void JS_FASTCALL stubs::Pos(VMFrame &f) { if (!ToNumber(f.cx, &f.regs.sp[-1])) THROW(); if (!f.regs.sp[-1].isInt32()) TypeScript::MonitorOverflow(f.cx, f.script(), f.pc()); }
--- a/js/src/methodjit/StubCalls.h +++ b/js/src/methodjit/StubCalls.h @@ -195,16 +195,17 @@ JSBool JS_FASTCALL IterMore(VMFrame &f); void JS_FASTCALL EndIter(VMFrame &f); JSBool JS_FASTCALL ValueToBoolean(VMFrame &f); JSString * JS_FASTCALL TypeOf(VMFrame &f); JSBool JS_FASTCALL InstanceOf(VMFrame &f); void JS_FASTCALL FastInstanceOf(VMFrame &f); void JS_FASTCALL ArgCnt(VMFrame &f); void JS_FASTCALL Unbrand(VMFrame &f); +void JS_FASTCALL UnbrandThis(VMFrame &f); /* * Helper for triggering recompilation should a name read miss a type barrier, * produce undefined or -0. */ void JS_FASTCALL TypeBarrierHelper(VMFrame &f, uint32 which); void JS_FASTCALL TypeBarrierReturn(VMFrame &f, Value *vp); void JS_FASTCALL NegZeroHelper(VMFrame &f);