mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 782869 - Fix incorrect |this| parameter passing to specialized DOM methods. (r=dvander)
This commit is contained in:
parent
b95f463253
commit
b1559913eb
@ -582,15 +582,15 @@ CodeGenerator::visitCallDOMNative(LCallDOMNative *call)
|
||||
// Nestle the stack up against the pushed arguments, leaving StackPointer at
|
||||
// &vp[1]
|
||||
masm.adjustStack(unusedStack);
|
||||
masm.movePtr(StackPointer, argObj);
|
||||
// argObj is filled with the extracted object, then returned.
|
||||
Register obj = masm.extractObject(Address(StackPointer, 0), argObj);
|
||||
JS_ASSERT(obj == argObj);
|
||||
|
||||
// Push a Value containing the callee object: natives are allowed to access their callee before
|
||||
// setitng the return value. The StackPointer is moved to &vp[0].
|
||||
masm.Push(ObjectValue(*target));
|
||||
masm.movePtr(StackPointer, argVp);
|
||||
|
||||
// Use argArgc as scratch.
|
||||
Register obj = masm.extractObject(Address(argObj, 0), argArgc);
|
||||
// GetReservedSlot(obj, DOM_PROTO_INSTANCE_CLASS_SLOT).toPrivate()
|
||||
masm.loadPrivate(Address(obj, JSObject::getFixedSlotOffset(0)), argPrivate);
|
||||
|
||||
@ -599,11 +599,17 @@ CodeGenerator::visitCallDOMNative(LCallDOMNative *call)
|
||||
// Push argument into what will become the IonExitFrame
|
||||
masm.Push(argArgc);
|
||||
|
||||
// Push |this| object for passing HandleObject. We push after argc to
|
||||
// maintain the same sp-relative location of the object pointer with other
|
||||
// DOMExitFrames.
|
||||
masm.Push(argObj);
|
||||
masm.movePtr(StackPointer, argObj);
|
||||
|
||||
// Construct native exit frame.
|
||||
uint32 safepointOffset;
|
||||
if (!masm.buildFakeExitFrame(argJSContext, &safepointOffset))
|
||||
return false;
|
||||
masm.enterFakeExitFrame();
|
||||
masm.enterFakeDOMFrame(ION_FRAME_DOMMETHOD);
|
||||
|
||||
if (!markSafepointAt(safepointOffset, call))
|
||||
return false;
|
||||
@ -625,7 +631,7 @@ CodeGenerator::visitCallDOMNative(LCallDOMNative *call)
|
||||
masm.branchTest32(Assembler::Zero, ReturnReg, ReturnReg, &exception);
|
||||
|
||||
// Load the outparam vp[0] into output register(s).
|
||||
masm.loadValue(Address(StackPointer, IonNativeExitFrameLayout::offsetOfResult()), JSReturnOperand);
|
||||
masm.loadValue(Address(StackPointer, IonDOMMethodExitFrameLayout::offsetOfResult()), JSReturnOperand);
|
||||
masm.jump(&success);
|
||||
|
||||
// Handle exception case.
|
||||
@ -639,7 +645,7 @@ CodeGenerator::visitCallDOMNative(LCallDOMNative *call)
|
||||
// is no need for leaveFakeExitFrame.
|
||||
|
||||
// Move the StackPointer back to its original location, unwinding the native exit frame.
|
||||
masm.adjustStack(IonNativeExitFrameLayout::Size() - unusedStack);
|
||||
masm.adjustStack(IonDOMMethodExitFrameLayout::Size() - unusedStack);
|
||||
JS_ASSERT(masm.framePushed() == initialStack);
|
||||
|
||||
dropArguments(call->numStackArgs() + 1);
|
||||
|
@ -123,7 +123,9 @@ IonFrameIterator::isDOMExit() const
|
||||
if (type_ != IonFrame_Exit)
|
||||
return false;
|
||||
IonCode *code = exitFrame()->footer()->ionCode();
|
||||
return code == ION_FRAME_DOMGETTER || code == ION_FRAME_DOMSETTER;
|
||||
return code == ION_FRAME_DOMGETTER ||
|
||||
code == ION_FRAME_DOMSETTER ||
|
||||
code == ION_FRAME_DOMMETHOD;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -517,8 +519,15 @@ MarkIonExitFrame(JSTracer *trc, const IonFrameIterator &frame)
|
||||
if (frame.isDOMExit()) {
|
||||
IonDOMExitFrameLayout *dom = frame.exitFrame()->DOMExit();
|
||||
gc::MarkObjectRoot(trc, dom->thisObjAddress(), "ion-dom-args");
|
||||
if (dom->isSetterFrame())
|
||||
if (dom->isSetterFrame()) {
|
||||
gc::MarkValueRoot(trc, dom->vp(), "ion-dom-args");
|
||||
} else if (dom->isMethodFrame()) {
|
||||
IonDOMMethodExitFrameLayout *method =
|
||||
reinterpret_cast<IonDOMMethodExitFrameLayout *>(dom);
|
||||
size_t len = method->argc() + 2;
|
||||
Value *vp = method->vp();
|
||||
gc::MarkValueRootRange(trc, len, vp, "ion-dom-args");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -254,6 +254,41 @@ class IonDOMExitFrameLayout
|
||||
inline bool isSetterFrame() {
|
||||
return footer_.ionCode() == ION_FRAME_DOMSETTER;
|
||||
}
|
||||
inline bool isMethodFrame() {
|
||||
return footer_.ionCode() == ION_FRAME_DOMMETHOD;
|
||||
}
|
||||
};
|
||||
|
||||
class IonDOMMethodExitFrameLayout
|
||||
{
|
||||
IonExitFooterFrame footer_;
|
||||
IonExitFrameLayout exit_;
|
||||
// This must be the last thing pushed, so as to stay common with
|
||||
// IonDOMExitFrameLayout.
|
||||
JSObject *thisObj_;
|
||||
uintptr_t argc_;
|
||||
|
||||
Value CalleeResult_;
|
||||
|
||||
public:
|
||||
static inline size_t Size() {
|
||||
return sizeof(IonDOMMethodExitFrameLayout);
|
||||
}
|
||||
|
||||
static size_t offsetOfResult() {
|
||||
return offsetof(IonDOMMethodExitFrameLayout, CalleeResult_);
|
||||
}
|
||||
inline Value *vp() {
|
||||
JS_STATIC_ASSERT(offsetof(IonDOMMethodExitFrameLayout, CalleeResult_) ==
|
||||
(offsetof(IonDOMMethodExitFrameLayout, argc_) + sizeof(uintptr_t)));
|
||||
return &CalleeResult_;
|
||||
}
|
||||
inline JSObject **thisObjAddress() {
|
||||
return &thisObj_;
|
||||
}
|
||||
inline uintptr_t argc() {
|
||||
return argc_;
|
||||
}
|
||||
};
|
||||
|
||||
// An invalidation bailout stack is at the stack pointer for the callee frame.
|
||||
|
@ -43,5 +43,6 @@
|
||||
|
||||
#define ION_FRAME_DOMGETTER ((IonCode *)0x1)
|
||||
#define ION_FRAME_DOMSETTER ((IonCode *)0x2)
|
||||
#define ION_FRAME_DOMMETHOD ((IonCode *)0x3)
|
||||
|
||||
#endif
|
||||
|
@ -236,6 +236,41 @@ class IonDOMExitFrameLayout
|
||||
inline bool isSetterFrame() {
|
||||
return footer_.ionCode() == ION_FRAME_DOMSETTER;
|
||||
}
|
||||
inline bool isMethodFrame() {
|
||||
return footer_.ionCode() == ION_FRAME_DOMMETHOD;
|
||||
}
|
||||
};
|
||||
|
||||
class IonDOMMethodExitFrameLayout
|
||||
{
|
||||
IonExitFooterFrame footer_;
|
||||
IonExitFrameLayout exit_;
|
||||
// This must be the last thing pushed, so as to stay common with
|
||||
// IonDOMExitFrameLayout.
|
||||
JSObject *thisObj_;
|
||||
uintptr_t argc_;
|
||||
|
||||
Value CalleeResult_;
|
||||
|
||||
public:
|
||||
static inline size_t Size() {
|
||||
return sizeof(IonDOMMethodExitFrameLayout);
|
||||
}
|
||||
|
||||
static size_t offsetOfResult() {
|
||||
return offsetof(IonDOMMethodExitFrameLayout, CalleeResult_);
|
||||
}
|
||||
inline Value *vp() {
|
||||
JS_STATIC_ASSERT(offsetof(IonDOMMethodExitFrameLayout, CalleeResult_) ==
|
||||
(offsetof(IonDOMMethodExitFrameLayout, argc_) + sizeof(uintptr_t)));
|
||||
return &CalleeResult_;
|
||||
}
|
||||
inline JSObject **thisObjAddress() {
|
||||
return &thisObj_;
|
||||
}
|
||||
inline uintptr_t argc() {
|
||||
return argc_;
|
||||
}
|
||||
};
|
||||
|
||||
class IonOsrFrameLayout : public IonJSFrameLayout
|
||||
|
Loading…
Reference in New Issue
Block a user