mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1092032 - Bias magic uint32s in ArgumentObject forwarded slots by the maximum JSWhyMagic value to distinguish them from the JSWhyMagic-based magic values. (r=luke)
This commit is contained in:
parent
e5309afe00
commit
b6c6dffa24
@ -244,7 +244,8 @@ typedef enum JSWhyMagic
|
||||
JS_OPTIMIZED_OUT, /* optimized out slot */
|
||||
JS_UNINITIALIZED_LEXICAL, /* uninitialized lexical bindings that produce ReferenceError
|
||||
* on touch. */
|
||||
JS_GENERIC_MAGIC /* for local use */
|
||||
JS_GENERIC_MAGIC, /* for local use */
|
||||
JS_WHY_MAGIC_COUNT
|
||||
} JSWhyMagic;
|
||||
|
||||
#if defined(IS_LITTLE_ENDIAN)
|
||||
|
@ -22,7 +22,7 @@ ArgumentsObject::element(uint32_t i) const
|
||||
{
|
||||
MOZ_ASSERT(!isElementDeleted(i));
|
||||
const Value &v = data()->args[i];
|
||||
if (v.isMagic()) {
|
||||
if (IsMagicScopeSlotValue(v)) {
|
||||
CallObject &callobj = getFixedSlot(MAYBE_CALL_SLOT).toObject().as<CallObject>();
|
||||
return callobj.aliasedVarFromArguments(v);
|
||||
}
|
||||
@ -34,8 +34,8 @@ ArgumentsObject::setElement(JSContext *cx, uint32_t i, const Value &v)
|
||||
{
|
||||
MOZ_ASSERT(!isElementDeleted(i));
|
||||
HeapValue &lhs = data()->args[i];
|
||||
if (lhs.isMagic()) {
|
||||
uint32_t slot = lhs.magicUint32();
|
||||
if (IsMagicScopeSlotValue(lhs)) {
|
||||
uint32_t slot = SlotFromMagicScopeSlotValue(lhs);
|
||||
CallObject &callobj = getFixedSlot(MAYBE_CALL_SLOT).toObject().as<CallObject>();
|
||||
for (Shape::Range<NoGC> r(callobj.lastProperty()); !r.empty(); r.popFront()) {
|
||||
if (r.front().slot() == slot) {
|
||||
|
@ -41,7 +41,7 @@ ArgumentsObject::MaybeForwardToCallObject(AbstractFramePtr frame, ArgumentsObjec
|
||||
if (frame.fun()->isHeavyweight() && script->argsObjAliasesFormals()) {
|
||||
obj->initFixedSlot(MAYBE_CALL_SLOT, ObjectValue(frame.callObj()));
|
||||
for (AliasedFormalIter fi(script); fi; fi++)
|
||||
data->args[fi.frameIndex()] = JS::MagicValueUint32(fi.scopeSlot());
|
||||
data->args[fi.frameIndex()] = MagicScopeSlotValue(fi.scopeSlot());
|
||||
}
|
||||
}
|
||||
|
||||
@ -55,7 +55,7 @@ ArgumentsObject::MaybeForwardToCallObject(jit::IonJSFrameLayout *frame, HandleOb
|
||||
MOZ_ASSERT(callObj && callObj->is<CallObject>());
|
||||
obj->initFixedSlot(MAYBE_CALL_SLOT, ObjectValue(*callObj.get()));
|
||||
for (AliasedFormalIter fi(script); fi; fi++)
|
||||
data->args[fi.frameIndex()] = JS::MagicValueUint32(fi.scopeSlot());
|
||||
data->args[fi.frameIndex()] = MagicScopeSlotValue(fi.scopeSlot());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -270,6 +270,25 @@ class ArgumentsObject : public NativeObject
|
||||
return getFixedSlotOffset(INITIAL_LENGTH_SLOT);
|
||||
}
|
||||
|
||||
static Value MagicScopeSlotValue(uint32_t slot) {
|
||||
// When forwarding slots to a backing CallObject, the slot numbers are
|
||||
// stored as uint32 magic values. This raises an ambiguity if we have
|
||||
// also copied JS_OPTIMIZED_OUT magic from a JIT frame or
|
||||
// JS_UNINITIALIZED_LEXICAL magic on the CallObject. To distinguish
|
||||
// normal magic values (those with a JSWhyMagic) and uint32 magic
|
||||
// values, we add the maximum JSWhyMagic value to the slot
|
||||
// number. This is safe as ARGS_LENGTH_MAX is well below UINT32_MAX.
|
||||
JS_STATIC_ASSERT(UINT32_MAX - JS_WHY_MAGIC_COUNT > ARGS_LENGTH_MAX);
|
||||
return JS::MagicValueUint32(slot + JS_WHY_MAGIC_COUNT);
|
||||
}
|
||||
static uint32_t SlotFromMagicScopeSlotValue(const Value &v) {
|
||||
JS_STATIC_ASSERT(UINT32_MAX - JS_WHY_MAGIC_COUNT > ARGS_LENGTH_MAX);
|
||||
return v.magicUint32() - JS_WHY_MAGIC_COUNT;
|
||||
}
|
||||
static bool IsMagicScopeSlotValue(const Value &v) {
|
||||
return v.isMagic() && v.magicUint32() > JS_WHY_MAGIC_COUNT;
|
||||
}
|
||||
|
||||
static void MaybeForwardToCallObject(AbstractFramePtr frame, ArgumentsObject *obj,
|
||||
ArgumentsData *data);
|
||||
static void MaybeForwardToCallObject(jit::IonJSFrameLayout *frame, HandleObject callObj,
|
||||
|
@ -48,7 +48,7 @@ CallObject::setAliasedVar(JSContext *cx, AliasedFormalIter fi, PropertyName *nam
|
||||
inline void
|
||||
CallObject::setAliasedVarFromArguments(JSContext *cx, const Value &argsValue, jsid id, const Value &v)
|
||||
{
|
||||
setSlot(argsValue.magicUint32(), v);
|
||||
setSlot(ArgumentsObject::SlotFromMagicScopeSlotValue(argsValue), v);
|
||||
if (hasSingletonType())
|
||||
types::AddTypePropertyId(cx, this, id, v);
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "jsweakmap.h"
|
||||
|
||||
#include "gc/Barrier.h"
|
||||
#include "vm/ArgumentsObject.h"
|
||||
#include "vm/ProxyObject.h"
|
||||
|
||||
namespace js {
|
||||
@ -301,7 +302,7 @@ class CallObject : public ScopeObject
|
||||
* CallObject to access.
|
||||
*/
|
||||
const Value &aliasedVarFromArguments(const Value &argsValue) {
|
||||
return getSlot(argsValue.magicUint32());
|
||||
return getSlot(ArgumentsObject::SlotFromMagicScopeSlotValue(argsValue));
|
||||
}
|
||||
inline void setAliasedVarFromArguments(JSContext *cx, const Value &argsValue, jsid id,
|
||||
const Value &v);
|
||||
|
Loading…
Reference in New Issue
Block a user