Bug 923765 - Account for __noSuchMethod__ in proxy stubs in GetPropertyIC. (r=djvj)

This commit is contained in:
Eric Faust 2013-10-17 18:13:43 -07:00
parent c614563f22
commit 689f389527
3 changed files with 39 additions and 5 deletions

View File

@ -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<uint32_t> 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);

View File

@ -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)

View File

@ -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;
};