From 689f3895274b9cd967098bb01b41f254a25fbae9 Mon Sep 17 00:00:00 2001 From: Eric Faust Date: Thu, 17 Oct 2013 18:13:43 -0700 Subject: [PATCH] Bug 923765 - Account for __noSuchMethod__ in proxy stubs in GetPropertyIC. (r=djvj) --- js/src/jit/IonCaches.cpp | 20 +++++++++++++++----- js/src/jsproxy.cpp | 20 ++++++++++++++++++++ js/src/jsproxy.h | 4 ++++ 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/js/src/jit/IonCaches.cpp b/js/src/jit/IonCaches.cpp index ea2e72353e8..8516e53a830 100644 --- a/js/src/jit/IonCaches.cpp +++ b/js/src/jit/IonCaches.cpp @@ -1304,10 +1304,11 @@ GetPropertyIC::tryAttachTypedArrayLength(JSContext *cx, IonScript *ion, HandleOb return linkAndAttachStub(cx, masm, attacher, ion, "typed array length"); } + static bool EmitCallProxyGet(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &attacher, PropertyName *name, RegisterSet liveRegs, Register object, - TypedOrValueRegister output, void *returnAddr) + TypedOrValueRegister output, jsbytecode *pc, void *returnAddr) { JS_ASSERT(output.hasValue()); // saveLive() @@ -1328,6 +1329,9 @@ EmitCallProxyGet(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &at Register scratch = regSet.takeGeneral(); DebugOnly initialStack = masm.framePushed(); + void *getFunction = JSOp(*pc) == JSOP_CALLPROP ? + JS_FUNC_TO_DATA_PTR(void *, Proxy::callProp) : + JS_FUNC_TO_DATA_PTR(void *, Proxy::get); // Push stubCode for marking. attacher.pushStubCodePointer(masm); @@ -1359,7 +1363,7 @@ EmitCallProxyGet(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &at masm.passABIArg(argProxyReg); masm.passABIArg(argIdReg); masm.passABIArg(argVpReg); - masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, Proxy::get)); + masm.callWithABI(getFunction); // Test for failure. masm.branchIfFalseBool(ReturnReg, masm.exceptionLabel()); @@ -1414,8 +1418,11 @@ GetPropertyIC::tryAttachDOMProxyShadowed(JSContext *cx, IonScript *ion, GenerateDOMProxyChecks(cx, masm, obj, name(), object(), &failures, /*skipExpandoCheck=*/true); - if (!EmitCallProxyGet(cx, masm, attacher, name(), liveRegs_, object(), output(), returnAddr)) + if (!EmitCallProxyGet(cx, masm, attacher, name(), liveRegs_, object(), output(), + pc(), returnAddr)) + { return false; + } // Success. attacher.jumpRejoin(masm); @@ -1514,7 +1521,7 @@ GetPropertyIC::tryAttachDOMProxyUnshadowed(JSContext *cx, IonScript *ion, Handle // proxy get call JS_ASSERT(!idempotent()); if (!EmitCallProxyGet(cx, masm, attacher, name, liveRegs_, object(), output(), - returnAddr)) + pc(), returnAddr)) { return false; } @@ -1603,8 +1610,11 @@ GetPropertyIC::tryAttachGenericProxy(JSContext *cx, IonScript *ion, HandleObject masm.branchTestProxyHandlerFamily(Assembler::Equal, object(), scratchReg, GetDOMProxyHandlerFamily(), &failures); - if (!EmitCallProxyGet(cx, masm, attacher, name, liveRegs_, object(), output(), returnAddr)) + if (!EmitCallProxyGet(cx, masm, attacher, name, liveRegs_, object(), output(), + pc(), returnAddr)) + { return false; + } attacher.jumpRejoin(masm); diff --git a/js/src/jsproxy.cpp b/js/src/jsproxy.cpp index d30aff3231c..0f47f1d57ef 100644 --- a/js/src/jsproxy.cpp +++ b/js/src/jsproxy.cpp @@ -2485,6 +2485,26 @@ Proxy::get(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id INVOKE_ON_PROTOTYPE(cx, handler, proxy, JSObject::getGeneric(cx, proto, receiver, id, vp)); } +bool +Proxy::callProp(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id, + MutableHandleValue vp) +{ + // The inline caches need an access point for JSOP_CALLPROP sites that accounts + // for the possibility of __noSuchMethod__ + if (!Proxy::get(cx, proxy, receiver, id, vp)) + return false; + +#if JS_HAS_NO_SUCH_METHOD + if (JS_UNLIKELY(vp.isPrimitive())) { + if (!OnUnknownMethod(cx, proxy, IdToValue(id), vp)) + return false; + } +#endif + + return true; +} + + bool Proxy::getElementIfPresent(JSContext *cx, HandleObject proxy, HandleObject receiver, uint32_t index, MutableHandleValue vp, bool *present) diff --git a/js/src/jsproxy.h b/js/src/jsproxy.h index 0becf9b6a48..8d8ebe579ad 100644 --- a/js/src/jsproxy.h +++ b/js/src/jsproxy.h @@ -275,6 +275,10 @@ class Proxy static bool defaultValue(JSContext *cx, HandleObject obj, JSType hint, MutableHandleValue vp); static bool getPrototypeOf(JSContext *cx, HandleObject proxy, MutableHandleObject protop); + /* IC entry path for handling __noSuchMethod__ on access. */ + static bool callProp(JSContext *cx, HandleObject proxy, HandleObject reveiver, HandleId id, + MutableHandleValue vp); + static JSObject * const LazyProto; };