mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-08 16:58:38 +09:00
Bug 1411415.
This commit is contained in:
parent
8ffcc15d3f
commit
66bf4fa8f9
10 changed files with 91 additions and 33 deletions
|
|
@ -259,8 +259,8 @@ TErrorResult<CleanupPolicy>::ThrowJSException(JSContext* cx, JS::Handle<JS::Valu
|
|||
// Make sure mJSException is initialized _before_ we try to root it. But
|
||||
// don't set it to exn yet, because we don't want to do that until after we
|
||||
// root.
|
||||
mJSException.setUndefined();
|
||||
if (!js::AddRawValueRoot(cx, &mJSException, "TErrorResult::mJSException")) {
|
||||
mJSException.asValueRef().setUndefined();
|
||||
if (!js::AddRawValueRoot(cx, &mJSException.asValueRef(), "TErrorResult::mJSException")) {
|
||||
// Don't use NS_ERROR_DOM_JS_EXCEPTION, because that indicates we have
|
||||
// in fact rooted mJSException.
|
||||
mResult = NS_ERROR_OUT_OF_MEMORY;
|
||||
|
|
@ -289,7 +289,7 @@ TErrorResult<CleanupPolicy>::SetPendingJSException(JSContext* cx)
|
|||
mJSException = exception;
|
||||
// If JS_WrapValue failed, not much we can do about it... No matter
|
||||
// what, go ahead and unroot mJSException.
|
||||
js::RemoveRawValueRoot(cx, &mJSException);
|
||||
js::RemoveRawValueRoot(cx, &mJSException.asValueRef());
|
||||
|
||||
mResult = NS_OK;
|
||||
#ifdef DEBUG
|
||||
|
|
@ -395,8 +395,8 @@ TErrorResult<CleanupPolicy>::ClearUnionData()
|
|||
if (IsJSException()) {
|
||||
JSContext* cx = dom::danger::GetJSContext();
|
||||
MOZ_ASSERT(cx);
|
||||
mJSException.setUndefined();
|
||||
js::RemoveRawValueRoot(cx, &mJSException);
|
||||
mJSException.asValueRef().setUndefined();
|
||||
js::RemoveRawValueRoot(cx, &mJSException.asValueRef());
|
||||
#ifdef DEBUG
|
||||
mUnionState = HasNothing;
|
||||
#endif // DEBUG
|
||||
|
|
@ -439,13 +439,13 @@ TErrorResult<CleanupPolicy>::operator=(TErrorResult<CleanupPolicy>&& aRHS)
|
|||
} else if (aRHS.IsJSException()) {
|
||||
JSContext* cx = dom::danger::GetJSContext();
|
||||
MOZ_ASSERT(cx);
|
||||
mJSException.setUndefined();
|
||||
if (!js::AddRawValueRoot(cx, &mJSException, "TErrorResult::mJSException")) {
|
||||
mJSException.asValueRef().setUndefined();
|
||||
if (!js::AddRawValueRoot(cx, &mJSException.asValueRef(), "TErrorResult::mJSException")) {
|
||||
MOZ_CRASH("Could not root mJSException, we're about to OOM");
|
||||
}
|
||||
mJSException = aRHS.mJSException;
|
||||
aRHS.mJSException.setUndefined();
|
||||
js::RemoveRawValueRoot(cx, &aRHS.mJSException);
|
||||
aRHS.mJSException.asValueRef().setUndefined();
|
||||
js::RemoveRawValueRoot(cx, &aRHS.mJSException.asValueRef());
|
||||
} else if (aRHS.IsDOMException()) {
|
||||
mDOMExceptionInfo = aRHS.mDOMExceptionInfo;
|
||||
aRHS.mDOMExceptionInfo = nullptr;
|
||||
|
|
@ -497,7 +497,7 @@ TErrorResult<CleanupPolicy>::CloneTo(TErrorResult& aRv) const
|
|||
aRv.mUnionState = HasJSException;
|
||||
#endif
|
||||
JSContext* cx = dom::danger::GetJSContext();
|
||||
JS::Rooted<JS::Value> exception(cx, mJSException);
|
||||
JS::Rooted<JS::Value> exception(cx, mJSException.asValueRef());
|
||||
aRv.ThrowJSException(cx, exception);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -461,7 +461,7 @@ private:
|
|||
// (and deallocated) by SetPendingDOMException.
|
||||
union {
|
||||
Message* mMessage; // valid when IsErrorWithMessage()
|
||||
JS::Value mJSException; // valid when IsJSException()
|
||||
JS::UninitializedValue mJSException; // valid when IsJSException()
|
||||
DOMExceptionInfo* mDOMExceptionInfo; // valid when IsDOMException()
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -322,7 +322,7 @@ public:
|
|||
void trace(JSTracer* trc) {
|
||||
for (uint8_t i = 0; i < mCount; ++i) {
|
||||
if (mArray[i].type == nsXPTType::T_JSVAL) {
|
||||
JS::UnsafeTraceRoot(trc, &mArray[i].val.j, "txParam value");
|
||||
JS::UnsafeTraceRoot(trc, &mArray[i].val.j.asValueRef(), "txParam value");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -140,12 +140,16 @@ static_assert(sizeof(JSValueShiftedTag) == sizeof(uint64_t),
|
|||
|
||||
#define JSVAL_TYPE_TO_TAG(type) ((JSValueTag)(JSVAL_TAG_CLEAR | (type)))
|
||||
|
||||
#define JSVAL_RAW64_UNDEFINED (uint64_t(JSVAL_TAG_UNDEFINED) << 32)
|
||||
|
||||
#define JSVAL_UPPER_EXCL_TAG_OF_PRIMITIVE_SET JSVAL_TAG_OBJECT
|
||||
#define JSVAL_UPPER_INCL_TAG_OF_NUMBER_SET JSVAL_TAG_INT32
|
||||
#define JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET JSVAL_TAG_STRING
|
||||
|
||||
#elif defined(JS_PUNBOX64)
|
||||
|
||||
#define JSVAL_RAW64_UNDEFINED (uint64_t(JSVAL_TAG_UNDEFINED) << JSVAL_TAG_SHIFT)
|
||||
|
||||
#define JSVAL_PAYLOAD_MASK 0x00007FFFFFFFFFFFLL
|
||||
#define JSVAL_TAG_MASK 0xFFFF800000000000LL
|
||||
#define JSVAL_TYPE_TO_TAG(type) ((JSValueTag)(JSVAL_TAG_MAX_DOUBLE | (type)))
|
||||
|
|
@ -817,7 +821,7 @@ class MOZ_NON_PARAM alignas(8) Value
|
|||
double asDouble;
|
||||
void* asPtr;
|
||||
|
||||
layout() = default;
|
||||
layout() : asBits(JSVAL_RAW64_UNDEFINED) {}
|
||||
explicit constexpr layout(uint64_t bits) : asBits(bits) {}
|
||||
explicit constexpr layout(double d) : asDouble(d) {}
|
||||
} data;
|
||||
|
|
@ -843,7 +847,7 @@ class MOZ_NON_PARAM alignas(8) Value
|
|||
size_t asWord;
|
||||
uintptr_t asUIntPtr;
|
||||
|
||||
layout() = default;
|
||||
layout() : asBits(JSVAL_RAW64_UNDEFINED) {}
|
||||
explicit constexpr layout(uint64_t bits) : asBits(bits) {}
|
||||
explicit constexpr layout(double d) : asDouble(d) {}
|
||||
} data;
|
||||
|
|
@ -871,7 +875,7 @@ class MOZ_NON_PARAM alignas(8) Value
|
|||
double asDouble;
|
||||
void* asPtr;
|
||||
|
||||
layout() = default;
|
||||
layout() : asBits(JSVAL_RAW64_UNDEFINED) {}
|
||||
explicit constexpr layout(uint64_t bits) : asBits(bits) {}
|
||||
explicit constexpr layout(double d) : asDouble(d) {}
|
||||
} data;
|
||||
|
|
@ -895,7 +899,7 @@ class MOZ_NON_PARAM alignas(8) Value
|
|||
size_t asWord;
|
||||
uintptr_t asUIntPtr;
|
||||
|
||||
layout() = default;
|
||||
layout() : asBits(JSVAL_RAW64_UNDEFINED) {}
|
||||
explicit constexpr layout(uint64_t bits) : asBits(bits) {}
|
||||
explicit constexpr layout(double d) : asDouble(d) {}
|
||||
} data;
|
||||
|
|
@ -948,8 +952,51 @@ class MOZ_NON_PARAM alignas(8) Value
|
|||
}
|
||||
} JS_HAZ_GC_POINTER;
|
||||
|
||||
/**
|
||||
* This is a null-constructible structure that can convert to and from
|
||||
* a Value, allowing UninitializedValue to be stored in unions.
|
||||
*/
|
||||
struct MOZ_NON_PARAM alignas(8) UninitializedValue
|
||||
{
|
||||
private:
|
||||
uint64_t bits;
|
||||
|
||||
public:
|
||||
UninitializedValue() = default;
|
||||
UninitializedValue(const UninitializedValue&) = default;
|
||||
MOZ_IMPLICIT UninitializedValue(const Value& val) : bits(val.asRawBits()) {}
|
||||
|
||||
inline uint64_t asRawBits() const {
|
||||
return bits;
|
||||
}
|
||||
|
||||
inline Value& asValueRef() {
|
||||
return *reinterpret_cast<Value*>(this);
|
||||
}
|
||||
inline const Value& asValueRef() const {
|
||||
return *reinterpret_cast<const Value*>(this);
|
||||
}
|
||||
|
||||
inline operator Value&() {
|
||||
return asValueRef();
|
||||
}
|
||||
inline operator Value const&() const {
|
||||
return asValueRef();
|
||||
}
|
||||
inline operator Value() const {
|
||||
return asValueRef();
|
||||
}
|
||||
|
||||
inline void operator=(Value const& other) {
|
||||
asValueRef() = other;
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(sizeof(Value) == 8, "Value size must leave three tag bits, be a binary power, and is ubiquitously depended upon everywhere");
|
||||
|
||||
static_assert(sizeof(UninitializedValue) == sizeof(Value), "Value and UninitializedValue must be the same size");
|
||||
static_assert(alignof(UninitializedValue) == alignof(Value), "Value and UninitializedValue must have same alignment");
|
||||
|
||||
inline bool
|
||||
IsOptimizedPlaceholderMagicValue(const Value& v)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ class StackValue
|
|||
|
||||
union {
|
||||
struct {
|
||||
Value v;
|
||||
JS::UninitializedValue v;
|
||||
} constant;
|
||||
struct {
|
||||
mozilla::AlignedStorage2<ValueOperand> reg;
|
||||
|
|
@ -112,7 +112,7 @@ class StackValue
|
|||
}
|
||||
Value constant() const {
|
||||
MOZ_ASSERT(kind_ == Constant);
|
||||
return data.constant.v;
|
||||
return data.constant.v.asValueRef();
|
||||
}
|
||||
ValueOperand reg() const {
|
||||
MOZ_ASSERT(kind_ == Register);
|
||||
|
|
|
|||
|
|
@ -226,13 +226,13 @@ class ConstantOrRegister
|
|||
|
||||
// Space to hold either a Value or a TypedOrValueRegister.
|
||||
union U {
|
||||
Value constant;
|
||||
JS::UninitializedValue constant;
|
||||
TypedOrValueRegister reg;
|
||||
} data;
|
||||
|
||||
const Value& dataValue() const {
|
||||
Value dataValue() const {
|
||||
MOZ_ASSERT(constant());
|
||||
return data.constant;
|
||||
return data.constant.asValueRef();
|
||||
}
|
||||
void setDataValue(const Value& value) {
|
||||
MOZ_ASSERT(constant());
|
||||
|
|
@ -268,7 +268,7 @@ class ConstantOrRegister
|
|||
return constant_;
|
||||
}
|
||||
|
||||
const Value& value() const {
|
||||
Value value() const {
|
||||
return dataValue();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -61,9 +61,17 @@ RematerializedFrame::New(JSContext* cx, uint8_t* top, InlineFrameIterator& iter,
|
|||
{
|
||||
unsigned numFormals = iter.isFunctionFrame() ? iter.calleeTemplate()->nargs() : 0;
|
||||
unsigned argSlots = Max(numFormals, iter.numActualArgs());
|
||||
size_t numBytes = sizeof(RematerializedFrame) +
|
||||
(argSlots + iter.script()->nfixed()) * sizeof(Value) -
|
||||
sizeof(Value); // 1 Value included in sizeof(RematerializedFrame)
|
||||
unsigned extraSlots = argSlots + iter.script()->nfixed();
|
||||
|
||||
// One Value slot is included in sizeof(RematerializedFrame), so we can
|
||||
// reduce the extra slot count by one. However, if there are zero slot
|
||||
// allocations total, then reducing the slots by one will lead to
|
||||
// the memory allocation being smaller than sizeof(RematerializedFrame).
|
||||
if (extraSlots > 0)
|
||||
extraSlots -= 1;
|
||||
|
||||
size_t numBytes = sizeof(RematerializedFrame) + (extraSlots * sizeof(Value));
|
||||
MOZ_ASSERT(numBytes >= sizeof(RematerializedFrame));
|
||||
|
||||
void* buf = cx->pod_calloc<uint8_t>(numBytes);
|
||||
if (!buf)
|
||||
|
|
|
|||
|
|
@ -857,7 +857,7 @@ class NumLit
|
|||
private:
|
||||
Which which_;
|
||||
union {
|
||||
Value scalar_;
|
||||
JS::UninitializedValue scalar_;
|
||||
SimdConstant simd_;
|
||||
} u;
|
||||
|
||||
|
|
@ -880,7 +880,7 @@ class NumLit
|
|||
|
||||
int32_t toInt32() const {
|
||||
MOZ_ASSERT(which_ == Fixnum || which_ == NegativeInt || which_ == BigUnsigned);
|
||||
return u.scalar_.toInt32();
|
||||
return u.scalar_.asValueRef().toInt32();
|
||||
}
|
||||
|
||||
uint32_t toUint32() const {
|
||||
|
|
@ -889,17 +889,17 @@ class NumLit
|
|||
|
||||
RawF64 toDouble() const {
|
||||
MOZ_ASSERT(which_ == Double);
|
||||
return RawF64(u.scalar_.toDouble());
|
||||
return RawF64(u.scalar_.asValueRef().toDouble());
|
||||
}
|
||||
|
||||
RawF32 toFloat() const {
|
||||
MOZ_ASSERT(which_ == Float);
|
||||
return RawF32(float(u.scalar_.toDouble()));
|
||||
return RawF32(float(u.scalar_.asValueRef().toDouble()));
|
||||
}
|
||||
|
||||
Value scalarValue() const {
|
||||
MOZ_ASSERT(which_ != OutOfRangeInt);
|
||||
return u.scalar_;
|
||||
return u.scalar_.asValueRef();
|
||||
}
|
||||
|
||||
bool isSimd() const
|
||||
|
|
|
|||
|
|
@ -1785,9 +1785,12 @@ CallMethodHelper::ConvertIndependentParam(uint8_t i)
|
|||
// indirectly, regardless of in/out-ness.
|
||||
if (type_tag == nsXPTType::T_JSVAL) {
|
||||
// Root the value.
|
||||
dp->val.j.setUndefined();
|
||||
if (!js::AddRawValueRoot(mCallContext, &dp->val.j, "XPCWrappedNative::CallMethod param"))
|
||||
dp->val.j.asValueRef().setUndefined();
|
||||
if (!js::AddRawValueRoot(mCallContext, &dp->val.j.asValueRef(),
|
||||
"XPCWrappedNative::CallMethod param"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Flag cleanup for anything that isn't self-contained.
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ struct nsXPTCMiniVariant
|
|||
// Types below here are unknown to the assembly implementations, and
|
||||
// therefore _must_ be passed with indirect semantics. We put them in
|
||||
// the union here for type safety, so that we can avoid void* tricks.
|
||||
JS::Value j;
|
||||
JS::UninitializedValue j;
|
||||
} val;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue