diff --git a/js/src/jsinterp.cpp b/js/src/jsinterp.cpp index 2ab8b859358b..fb2c1a5b856b 100644 --- a/js/src/jsinterp.cpp +++ b/js/src/jsinterp.cpp @@ -4198,7 +4198,7 @@ BEGIN_CASE(JSOP_CALLPROP) } } #if JS_HAS_NO_SUCH_METHOD - if (JS_UNLIKELY(rval.isUndefined()) && regs.sp[-1].isObject()) { + if (JS_UNLIKELY(rval.isPrimitive()) && regs.sp[-1].isObject()) { LOAD_ATOM(0, atom); regs.sp[-2].setString(atom); if (!js_OnUnknownMethod(cx, regs.sp - 2)) @@ -4458,7 +4458,7 @@ BEGIN_CASE(JSOP_CALLELEM) goto error; #if JS_HAS_NO_SUCH_METHOD - if (JS_UNLIKELY(regs.sp[-2].isUndefined()) && thisv.isObject()) { + if (JS_UNLIKELY(regs.sp[-2].isPrimitive()) && thisv.isObject()) { /* For js_OnUnknownMethod, sp[-2] is the index, and sp[-1] is the object missing it. */ regs.sp[-2] = regs.sp[-1]; regs.sp[-1].setObject(*thisObj); diff --git a/js/src/methodjit/PolyIC.cpp b/js/src/methodjit/PolyIC.cpp index 5f003b3b2570..4dc89e596315 100644 --- a/js/src/methodjit/PolyIC.cpp +++ b/js/src/methodjit/PolyIC.cpp @@ -1850,7 +1850,7 @@ ic::CallProp(VMFrame &f, ic::PICInfo *pic) } #if JS_HAS_NO_SUCH_METHOD - if (JS_UNLIKELY(rval.isUndefined()) && regs.sp[-1].isObject()) { + if (JS_UNLIKELY(rval.isPrimitive()) && regs.sp[-1].isObject()) { regs.sp[-2].setString(pic->atom); if (!js_OnUnknownMethod(cx, regs.sp - 2)) THROW(); @@ -2369,7 +2369,7 @@ ic::CallElement(VMFrame &f, ic::GetElementIC *ic) THROW(); #if JS_HAS_NO_SUCH_METHOD - if (JS_UNLIKELY(f.regs.sp[-2].isUndefined()) && thisv.isObject()) { + if (JS_UNLIKELY(f.regs.sp[-2].isPrimitive()) && thisv.isObject()) { f.regs.sp[-2] = f.regs.sp[-1]; f.regs.sp[-1].setObject(*thisObj); if (!js_OnUnknownMethod(cx, f.regs.sp - 2)) diff --git a/js/src/methodjit/StubCalls.cpp b/js/src/methodjit/StubCalls.cpp index 0b88920369c3..c6ce87246497 100644 --- a/js/src/methodjit/StubCalls.cpp +++ b/js/src/methodjit/StubCalls.cpp @@ -514,7 +514,7 @@ stubs::CallElem(VMFrame &f) THROW(); #if JS_HAS_NO_SUCH_METHOD - if (JS_UNLIKELY(regs.sp[-2].isUndefined()) && thisv.isObject()) { + if (JS_UNLIKELY(regs.sp[-2].isPrimitive()) && thisv.isObject()) { regs.sp[-2] = regs.sp[-1]; regs.sp[-1].setObject(*thisObj); if (!js_OnUnknownMethod(cx, regs.sp - 2)) @@ -1994,7 +1994,7 @@ stubs::CallProp(VMFrame &f, JSAtom *origAtom) } } #if JS_HAS_NO_SUCH_METHOD - if (JS_UNLIKELY(rval.isUndefined()) && regs.sp[-1].isObject()) { + if (JS_UNLIKELY(rval.isPrimitive()) && regs.sp[-1].isObject()) { regs.sp[-2].setString(origAtom); if (!js_OnUnknownMethod(cx, regs.sp - 2)) THROW(); diff --git a/js/src/tests/js1_5/extensions/jstests.list b/js/src/tests/js1_5/extensions/jstests.list index 3816c033c536..1953e18cf6cd 100644 --- a/js/src/tests/js1_5/extensions/jstests.list +++ b/js/src/tests/js1_5/extensions/jstests.list @@ -223,3 +223,4 @@ script scope-001.js fails-if(Android) script toLocaleFormat-01.js fails-if(xulRuntime.OS=="WINNT") script toLocaleFormat-02.js script regress-543839.js +script regress-564577.js diff --git a/js/src/tests/js1_5/extensions/regress-564577.js b/js/src/tests/js1_5/extensions/regress-564577.js new file mode 100644 index 000000000000..64edacdfec60 --- /dev/null +++ b/js/src/tests/js1_5/extensions/regress-564577.js @@ -0,0 +1,79 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: Matthew Draper + */ + +var gTestfile = 'regress-564577.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 564577; +var summary = '__noSuchMethod__ when property exists'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + + + var o = { + aaa: undefined, + bbb: null, + ccc: 77, + ddd: 'foo', + eee: {}, + fff: /./, + __noSuchMethod__: function (id, args) + { + return(id + '('+args.join(',')+') ' + this[id]); + } + }; + + status = summary + ' ' + inSection(1) + ' '; + actual = o.aaa(); + expect = 'aaa() undefined'; + reportCompare(expect, actual, status); + + status = summary + ' ' + inSection(2) + ' '; + actual = o.bbb(); + expect = 'bbb() null'; + reportCompare(expect, actual, status); + + status = summary + ' ' + inSection(3) + ' '; + actual = o.ccc(); + expect = 'ccc() 77'; + reportCompare(expect, actual, status); + + status = summary + ' ' + inSection(4) + ' '; + actual = o.ddd(); + expect = 'ddd() foo'; + reportCompare(expect, actual, status); + + status = summary + ' ' + inSection(5) + ' '; + try { + actual = o.eee(); + } catch(e) { + actual = e + ''; + } + expect = 'TypeError: o.eee is not a function'; + reportCompare(expect, actual, status); + + status = summary + ' ' + inSection(6) + ' '; + try { + actual = o.fff('xyz') + ''; + } catch(e) { + actual = e + ''; + } + expect = 'TypeError: o.fff is not a function'; + reportCompare(expect, actual, status); + + exitFunc('test'); +}