summaryrefslogtreecommitdiffstats
path: root/js/src/jit/Recover.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit/Recover.cpp')
-rw-r--r--js/src/jit/Recover.cpp370
1 files changed, 173 insertions, 197 deletions
diff --git a/js/src/jit/Recover.cpp b/js/src/jit/Recover.cpp
index 220ffe7bb2..4c1ff56436 100644
--- a/js/src/jit/Recover.cpp
+++ b/js/src/jit/Recover.cpp
@@ -6,6 +6,8 @@
#include "jit/Recover.h"
+#include "mozilla/Casting.h"
+
#include "jsmath.h"
#include "builtin/Object.h"
@@ -495,16 +497,15 @@ bool MBigIntAdd::writeRecoverData(CompactBufferWriter& writer) const {
RBigIntAdd::RBigIntAdd(CompactBufferReader& reader) {}
bool RBigIntAdd::recover(JSContext* cx, SnapshotIterator& iter) const {
- RootedValue lhs(cx, iter.read());
- RootedValue rhs(cx, iter.read());
- RootedValue result(cx);
+ Rooted<BigInt*> lhs(cx, iter.readBigInt());
+ Rooted<BigInt*> rhs(cx, iter.readBigInt());
- MOZ_ASSERT(lhs.isBigInt() && rhs.isBigInt());
- if (!js::AddValues(cx, &lhs, &rhs, &result)) {
+ BigInt* result = BigInt::add(cx, lhs, rhs);
+ if (!result) {
return false;
}
- iter.storeInstructionResult(result);
+ iter.storeInstructionResult(BigIntValue(result));
return true;
}
@@ -517,16 +518,15 @@ bool MBigIntSub::writeRecoverData(CompactBufferWriter& writer) const {
RBigIntSub::RBigIntSub(CompactBufferReader& reader) {}
bool RBigIntSub::recover(JSContext* cx, SnapshotIterator& iter) const {
- RootedValue lhs(cx, iter.read());
- RootedValue rhs(cx, iter.read());
- RootedValue result(cx);
+ Rooted<BigInt*> lhs(cx, iter.readBigInt());
+ Rooted<BigInt*> rhs(cx, iter.readBigInt());
- MOZ_ASSERT(lhs.isBigInt() && rhs.isBigInt());
- if (!js::SubValues(cx, &lhs, &rhs, &result)) {
+ BigInt* result = BigInt::sub(cx, lhs, rhs);
+ if (!result) {
return false;
}
- iter.storeInstructionResult(result);
+ iter.storeInstructionResult(BigIntValue(result));
return true;
}
@@ -539,16 +539,15 @@ bool MBigIntMul::writeRecoverData(CompactBufferWriter& writer) const {
RBigIntMul::RBigIntMul(CompactBufferReader& reader) {}
bool RBigIntMul::recover(JSContext* cx, SnapshotIterator& iter) const {
- RootedValue lhs(cx, iter.read());
- RootedValue rhs(cx, iter.read());
- RootedValue result(cx);
+ Rooted<BigInt*> lhs(cx, iter.readBigInt());
+ Rooted<BigInt*> rhs(cx, iter.readBigInt());
- MOZ_ASSERT(lhs.isBigInt() && rhs.isBigInt());
- if (!js::MulValues(cx, &lhs, &rhs, &result)) {
+ BigInt* result = BigInt::mul(cx, lhs, rhs);
+ if (!result) {
return false;
}
- iter.storeInstructionResult(result);
+ iter.storeInstructionResult(BigIntValue(result));
return true;
}
@@ -561,18 +560,17 @@ bool MBigIntDiv::writeRecoverData(CompactBufferWriter& writer) const {
RBigIntDiv::RBigIntDiv(CompactBufferReader& reader) {}
bool RBigIntDiv::recover(JSContext* cx, SnapshotIterator& iter) const {
- RootedValue lhs(cx, iter.read());
- RootedValue rhs(cx, iter.read());
- RootedValue result(cx);
-
- MOZ_ASSERT(lhs.isBigInt() && rhs.isBigInt());
- MOZ_ASSERT(!rhs.toBigInt()->isZero(),
+ Rooted<BigInt*> lhs(cx, iter.readBigInt());
+ Rooted<BigInt*> rhs(cx, iter.readBigInt());
+ MOZ_ASSERT(!rhs->isZero(),
"division by zero throws and therefore can't be recovered");
- if (!js::DivValues(cx, &lhs, &rhs, &result)) {
+
+ BigInt* result = BigInt::div(cx, lhs, rhs);
+ if (!result) {
return false;
}
- iter.storeInstructionResult(result);
+ iter.storeInstructionResult(BigIntValue(result));
return true;
}
@@ -585,18 +583,17 @@ bool MBigIntMod::writeRecoverData(CompactBufferWriter& writer) const {
RBigIntMod::RBigIntMod(CompactBufferReader& reader) {}
bool RBigIntMod::recover(JSContext* cx, SnapshotIterator& iter) const {
- RootedValue lhs(cx, iter.read());
- RootedValue rhs(cx, iter.read());
- RootedValue result(cx);
-
- MOZ_ASSERT(lhs.isBigInt() && rhs.isBigInt());
- MOZ_ASSERT(!rhs.toBigInt()->isZero(),
+ Rooted<BigInt*> lhs(cx, iter.readBigInt());
+ Rooted<BigInt*> rhs(cx, iter.readBigInt());
+ MOZ_ASSERT(!rhs->isZero(),
"division by zero throws and therefore can't be recovered");
- if (!js::ModValues(cx, &lhs, &rhs, &result)) {
+
+ BigInt* result = BigInt::mod(cx, lhs, rhs);
+ if (!result) {
return false;
}
- iter.storeInstructionResult(result);
+ iter.storeInstructionResult(BigIntValue(result));
return true;
}
@@ -609,18 +606,17 @@ bool MBigIntPow::writeRecoverData(CompactBufferWriter& writer) const {
RBigIntPow::RBigIntPow(CompactBufferReader& reader) {}
bool RBigIntPow::recover(JSContext* cx, SnapshotIterator& iter) const {
- RootedValue lhs(cx, iter.read());
- RootedValue rhs(cx, iter.read());
- RootedValue result(cx);
-
- MOZ_ASSERT(lhs.isBigInt() && rhs.isBigInt());
- MOZ_ASSERT(!rhs.toBigInt()->isNegative(),
+ Rooted<BigInt*> lhs(cx, iter.readBigInt());
+ Rooted<BigInt*> rhs(cx, iter.readBigInt());
+ MOZ_ASSERT(!rhs->isNegative(),
"negative exponent throws and therefore can't be recovered");
- if (!js::PowValues(cx, &lhs, &rhs, &result)) {
+
+ BigInt* result = BigInt::pow(cx, lhs, rhs);
+ if (!result) {
return false;
}
- iter.storeInstructionResult(result);
+ iter.storeInstructionResult(BigIntValue(result));
return true;
}
@@ -633,16 +629,15 @@ bool MBigIntBitAnd::writeRecoverData(CompactBufferWriter& writer) const {
RBigIntBitAnd::RBigIntBitAnd(CompactBufferReader& reader) {}
bool RBigIntBitAnd::recover(JSContext* cx, SnapshotIterator& iter) const {
- RootedValue lhs(cx, iter.read());
- RootedValue rhs(cx, iter.read());
- RootedValue result(cx);
+ Rooted<BigInt*> lhs(cx, iter.readBigInt());
+ Rooted<BigInt*> rhs(cx, iter.readBigInt());
- MOZ_ASSERT(lhs.isBigInt() && rhs.isBigInt());
- if (!js::BitAnd(cx, &lhs, &rhs, &result)) {
+ BigInt* result = BigInt::bitAnd(cx, lhs, rhs);
+ if (!result) {
return false;
}
- iter.storeInstructionResult(result);
+ iter.storeInstructionResult(BigIntValue(result));
return true;
}
@@ -655,16 +650,15 @@ bool MBigIntBitOr::writeRecoverData(CompactBufferWriter& writer) const {
RBigIntBitOr::RBigIntBitOr(CompactBufferReader& reader) {}
bool RBigIntBitOr::recover(JSContext* cx, SnapshotIterator& iter) const {
- RootedValue lhs(cx, iter.read());
- RootedValue rhs(cx, iter.read());
- RootedValue result(cx);
+ Rooted<BigInt*> lhs(cx, iter.readBigInt());
+ Rooted<BigInt*> rhs(cx, iter.readBigInt());
- MOZ_ASSERT(lhs.isBigInt() && rhs.isBigInt());
- if (!js::BitOr(cx, &lhs, &rhs, &result)) {
+ BigInt* result = BigInt::bitOr(cx, lhs, rhs);
+ if (!result) {
return false;
}
- iter.storeInstructionResult(result);
+ iter.storeInstructionResult(BigIntValue(result));
return true;
}
@@ -677,16 +671,15 @@ bool MBigIntBitXor::writeRecoverData(CompactBufferWriter& writer) const {
RBigIntBitXor::RBigIntBitXor(CompactBufferReader& reader) {}
bool RBigIntBitXor::recover(JSContext* cx, SnapshotIterator& iter) const {
- RootedValue lhs(cx, iter.read());
- RootedValue rhs(cx, iter.read());
- RootedValue result(cx);
+ Rooted<BigInt*> lhs(cx, iter.readBigInt());
+ Rooted<BigInt*> rhs(cx, iter.readBigInt());
- MOZ_ASSERT(lhs.isBigInt() && rhs.isBigInt());
- if (!js::BitXor(cx, &lhs, &rhs, &result)) {
+ BigInt* result = BigInt::bitXor(cx, lhs, rhs);
+ if (!result) {
return false;
}
- iter.storeInstructionResult(result);
+ iter.storeInstructionResult(BigIntValue(result));
return true;
}
@@ -699,16 +692,15 @@ bool MBigIntLsh::writeRecoverData(CompactBufferWriter& writer) const {
RBigIntLsh::RBigIntLsh(CompactBufferReader& reader) {}
bool RBigIntLsh::recover(JSContext* cx, SnapshotIterator& iter) const {
- RootedValue lhs(cx, iter.read());
- RootedValue rhs(cx, iter.read());
- RootedValue result(cx);
+ Rooted<BigInt*> lhs(cx, iter.readBigInt());
+ Rooted<BigInt*> rhs(cx, iter.readBigInt());
- MOZ_ASSERT(lhs.isBigInt() && rhs.isBigInt());
- if (!js::BitLsh(cx, &lhs, &rhs, &result)) {
+ BigInt* result = BigInt::lsh(cx, lhs, rhs);
+ if (!result) {
return false;
}
- iter.storeInstructionResult(result);
+ iter.storeInstructionResult(BigIntValue(result));
return true;
}
@@ -721,16 +713,15 @@ bool MBigIntRsh::writeRecoverData(CompactBufferWriter& writer) const {
RBigIntRsh::RBigIntRsh(CompactBufferReader& reader) {}
bool RBigIntRsh::recover(JSContext* cx, SnapshotIterator& iter) const {
- RootedValue lhs(cx, iter.read());
- RootedValue rhs(cx, iter.read());
- RootedValue result(cx);
+ Rooted<BigInt*> lhs(cx, iter.readBigInt());
+ Rooted<BigInt*> rhs(cx, iter.readBigInt());
- MOZ_ASSERT(lhs.isBigInt() && rhs.isBigInt());
- if (!js::BitRsh(cx, &lhs, &rhs, &result)) {
+ BigInt* result = BigInt::rsh(cx, lhs, rhs);
+ if (!result) {
return false;
}
- iter.storeInstructionResult(result);
+ iter.storeInstructionResult(BigIntValue(result));
return true;
}
@@ -743,15 +734,14 @@ bool MBigIntIncrement::writeRecoverData(CompactBufferWriter& writer) const {
RBigIntIncrement::RBigIntIncrement(CompactBufferReader& reader) {}
bool RBigIntIncrement::recover(JSContext* cx, SnapshotIterator& iter) const {
- RootedValue operand(cx, iter.read());
- RootedValue result(cx);
+ Rooted<BigInt*> operand(cx, iter.readBigInt());
- MOZ_ASSERT(operand.isBigInt());
- if (!js::IncOperation(cx, operand, &result)) {
+ BigInt* result = BigInt::inc(cx, operand);
+ if (!result) {
return false;
}
- iter.storeInstructionResult(result);
+ iter.storeInstructionResult(BigIntValue(result));
return true;
}
@@ -764,15 +754,14 @@ bool MBigIntDecrement::writeRecoverData(CompactBufferWriter& writer) const {
RBigIntDecrement::RBigIntDecrement(CompactBufferReader& reader) {}
bool RBigIntDecrement::recover(JSContext* cx, SnapshotIterator& iter) const {
- RootedValue operand(cx, iter.read());
- RootedValue result(cx);
+ Rooted<BigInt*> operand(cx, iter.readBigInt());
- MOZ_ASSERT(operand.isBigInt());
- if (!js::DecOperation(cx, operand, &result)) {
+ BigInt* result = BigInt::dec(cx, operand);
+ if (!result) {
return false;
}
- iter.storeInstructionResult(result);
+ iter.storeInstructionResult(BigIntValue(result));
return true;
}
@@ -785,15 +774,14 @@ bool MBigIntNegate::writeRecoverData(CompactBufferWriter& writer) const {
RBigIntNegate::RBigIntNegate(CompactBufferReader& reader) {}
bool RBigIntNegate::recover(JSContext* cx, SnapshotIterator& iter) const {
- RootedValue operand(cx, iter.read());
- RootedValue result(cx);
+ Rooted<BigInt*> operand(cx, iter.readBigInt());
- MOZ_ASSERT(operand.isBigInt());
- if (!js::NegOperation(cx, &operand, &result)) {
+ BigInt* result = BigInt::neg(cx, operand);
+ if (!result) {
return false;
}
- iter.storeInstructionResult(result);
+ iter.storeInstructionResult(BigIntValue(result));
return true;
}
@@ -806,15 +794,14 @@ bool MBigIntBitNot::writeRecoverData(CompactBufferWriter& writer) const {
RBigIntBitNot::RBigIntBitNot(CompactBufferReader& reader) {}
bool RBigIntBitNot::recover(JSContext* cx, SnapshotIterator& iter) const {
- RootedValue operand(cx, iter.read());
- RootedValue result(cx);
+ Rooted<BigInt*> operand(cx, iter.readBigInt());
- MOZ_ASSERT(operand.isBigInt());
- if (!js::BitNot(cx, &operand, &result)) {
+ BigInt* result = BigInt::bitNot(cx, operand);
+ if (!result) {
return false;
}
- iter.storeInstructionResult(result);
+ iter.storeInstructionResult(BigIntValue(result));
return true;
}
@@ -910,7 +897,7 @@ bool RConcat::recover(JSContext* cx, SnapshotIterator& iter) const {
RStringLength::RStringLength(CompactBufferReader& reader) {}
bool RStringLength::recover(JSContext* cx, SnapshotIterator& iter) const {
- JSString* string = iter.read().toString();
+ JSString* string = iter.readString();
static_assert(JSString::MAX_LENGTH <= INT32_MAX,
"Can cast string length to int32_t");
@@ -953,7 +940,7 @@ bool MFloor::writeRecoverData(CompactBufferWriter& writer) const {
RFloor::RFloor(CompactBufferReader& reader) {}
bool RFloor::recover(JSContext* cx, SnapshotIterator& iter) const {
- double num = iter.read().toNumber();
+ double num = iter.readNumber();
double result = js::math_floor_impl(num);
iter.storeInstructionResult(NumberValue(result));
@@ -969,7 +956,7 @@ bool MCeil::writeRecoverData(CompactBufferWriter& writer) const {
RCeil::RCeil(CompactBufferReader& reader) {}
bool RCeil::recover(JSContext* cx, SnapshotIterator& iter) const {
- double num = iter.read().toNumber();
+ double num = iter.readNumber();
double result = js::math_ceil_impl(num);
iter.storeInstructionResult(NumberValue(result));
@@ -985,7 +972,7 @@ bool MRound::writeRecoverData(CompactBufferWriter& writer) const {
RRound::RRound(CompactBufferReader& reader) {}
bool RRound::recover(JSContext* cx, SnapshotIterator& iter) const {
- double num = iter.read().toNumber();
+ double num = iter.readNumber();
double result = js::math_round_impl(num);
iter.storeInstructionResult(NumberValue(result));
@@ -1001,7 +988,7 @@ bool MTrunc::writeRecoverData(CompactBufferWriter& writer) const {
RTrunc::RTrunc(CompactBufferReader& reader) {}
bool RTrunc::recover(JSContext* cx, SnapshotIterator& iter) const {
- double num = iter.read().toNumber();
+ double num = iter.readNumber();
double result = js::math_trunc_impl(num);
iter.storeInstructionResult(NumberValue(result));
@@ -1017,21 +1004,18 @@ bool MCharCodeAt::writeRecoverData(CompactBufferWriter& writer) const {
RCharCodeAt::RCharCodeAt(CompactBufferReader& reader) {}
bool RCharCodeAt::recover(JSContext* cx, SnapshotIterator& iter) const {
- RootedString string(cx, iter.read().toString());
- int32_t index = iter.read().toInt32();
+ JSString* string = iter.readString();
- RootedValue result(cx);
- if (0 <= index && size_t(index) < string->length()) {
- char16_t c;
- if (!string->getChar(cx, index, &c)) {
- return false;
- }
- result.setInt32(c);
- } else {
- result.setNaN();
+ // Int32 because |index| is computed from MBoundsCheck.
+ int32_t index = iter.readInt32();
+ MOZ_RELEASE_ASSERT(0 <= index && size_t(index) < string->length());
+
+ char16_t c;
+ if (!string->getChar(cx, index, &c)) {
+ return false;
}
- iter.storeInstructionResult(result);
+ iter.storeInstructionResult(Int32Value(c));
return true;
}
@@ -1044,7 +1028,8 @@ bool MFromCharCode::writeRecoverData(CompactBufferWriter& writer) const {
RFromCharCode::RFromCharCode(CompactBufferReader& reader) {}
bool RFromCharCode::recover(JSContext* cx, SnapshotIterator& iter) const {
- int32_t charCode = iter.read().toInt32();
+ // Number because |charCode| is computed from (recoverable) user input.
+ int32_t charCode = JS::ToInt32(iter.readNumber());
JSString* str = StringFromCharCode(cx, charCode);
if (!str) {
@@ -1068,7 +1053,8 @@ RFromCharCodeEmptyIfNegative::RFromCharCodeEmptyIfNegative(
bool RFromCharCodeEmptyIfNegative::recover(JSContext* cx,
SnapshotIterator& iter) const {
- int32_t charCode = iter.read().toInt32();
+ // Int32 because |charCode| is computed from MCharCodeAtOrNegative.
+ int32_t charCode = iter.readInt32();
JSString* str;
if (charCode < 0) {
@@ -1093,8 +1079,8 @@ bool MPow::writeRecoverData(CompactBufferWriter& writer) const {
RPow::RPow(CompactBufferReader& reader) {}
bool RPow::recover(JSContext* cx, SnapshotIterator& iter) const {
- double base = iter.read().toNumber();
- double power = iter.read().toNumber();
+ double base = iter.readNumber();
+ double power = iter.readNumber();
double result = ecmaPow(base, power);
iter.storeInstructionResult(NumberValue(result));
@@ -1110,7 +1096,7 @@ bool MPowHalf::writeRecoverData(CompactBufferWriter& writer) const {
RPowHalf::RPowHalf(CompactBufferReader& reader) {}
bool RPowHalf::recover(JSContext* cx, SnapshotIterator& iter) const {
- double base = iter.read().toNumber();
+ double base = iter.readNumber();
double power = 0.5;
double result = ecmaPow(base, power);
@@ -1128,8 +1114,8 @@ bool MMinMax::writeRecoverData(CompactBufferWriter& writer) const {
RMinMax::RMinMax(CompactBufferReader& reader) { isMax_ = reader.readByte(); }
bool RMinMax::recover(JSContext* cx, SnapshotIterator& iter) const {
- double x = iter.read().toNumber();
- double y = iter.read().toNumber();
+ double x = iter.readNumber();
+ double y = iter.readNumber();
double result;
if (isMax_) {
@@ -1151,7 +1137,7 @@ bool MAbs::writeRecoverData(CompactBufferWriter& writer) const {
RAbs::RAbs(CompactBufferReader& reader) {}
bool RAbs::recover(JSContext* cx, SnapshotIterator& iter) const {
- double num = iter.read().toNumber();
+ double num = iter.readNumber();
double result = js::math_abs_impl(num);
iter.storeInstructionResult(NumberValue(result));
@@ -1170,7 +1156,7 @@ RSqrt::RSqrt(CompactBufferReader& reader) {
}
bool RSqrt::recover(JSContext* cx, SnapshotIterator& iter) const {
- double num = iter.read().toNumber();
+ double num = iter.readNumber();
double result = js::math_sqrt_impl(num);
// MIRType::Float32 is a specialization embedding the fact that the result is
@@ -1192,8 +1178,8 @@ bool MAtan2::writeRecoverData(CompactBufferWriter& writer) const {
RAtan2::RAtan2(CompactBufferReader& reader) {}
bool RAtan2::recover(JSContext* cx, SnapshotIterator& iter) const {
- double y = iter.read().toNumber();
- double x = iter.read().toNumber();
+ double y = iter.readNumber();
+ double x = iter.readNumber();
double result = js::ecmaAtan2(y, x);
iter.storeInstructionResult(DoubleValue(result));
@@ -1218,7 +1204,7 @@ bool RHypot::recover(JSContext* cx, SnapshotIterator& iter) const {
}
for (uint32_t i = 0; i < numOperands_; ++i) {
- vec.infallibleAppend(iter.read());
+ vec.infallibleAppend(NumberValue(iter.readNumber()));
}
RootedValue result(cx);
@@ -1265,7 +1251,7 @@ bool MSign::writeRecoverData(CompactBufferWriter& writer) const {
RSign::RSign(CompactBufferReader& reader) {}
bool RSign::recover(JSContext* cx, SnapshotIterator& iter) const {
- double num = iter.read().toNumber();
+ double num = iter.readNumber();
double result = js::math_sign_impl(num);
iter.storeInstructionResult(NumberValue(result));
@@ -1322,7 +1308,7 @@ RMathFunction::RMathFunction(CompactBufferReader& reader) {
}
bool RMathFunction::recover(JSContext* cx, SnapshotIterator& iter) const {
- double num = iter.read().toNumber();
+ double num = iter.readNumber();
double result;
switch (function_) {
@@ -1431,8 +1417,8 @@ bool MStringSplit::writeRecoverData(CompactBufferWriter& writer) const {
RStringSplit::RStringSplit(CompactBufferReader& reader) {}
bool RStringSplit::recover(JSContext* cx, SnapshotIterator& iter) const {
- RootedString str(cx, iter.read().toString());
- RootedString sep(cx, iter.read().toString());
+ RootedString str(cx, iter.readString());
+ RootedString sep(cx, iter.readString());
JSObject* res = StringSplitString(cx, str, sep, INT32_MAX);
if (!res) {
@@ -1452,7 +1438,7 @@ bool MNaNToZero::writeRecoverData(CompactBufferWriter& writer) const {
RNaNToZero::RNaNToZero(CompactBufferReader& reader) {}
bool RNaNToZero::recover(JSContext* cx, SnapshotIterator& iter) const {
- double v = iter.read().toNumber();
+ double v = iter.readNumber();
if (std::isnan(v) || mozilla::IsNegativeZero(v)) {
v = 0.0;
}
@@ -1470,9 +1456,11 @@ bool MRegExpMatcher::writeRecoverData(CompactBufferWriter& writer) const {
RRegExpMatcher::RRegExpMatcher(CompactBufferReader& reader) {}
bool RRegExpMatcher::recover(JSContext* cx, SnapshotIterator& iter) const {
- RootedObject regexp(cx, &iter.read().toObject());
- RootedString input(cx, iter.read().toString());
- int32_t lastIndex = iter.read().toInt32();
+ RootedObject regexp(cx, iter.readObject());
+ RootedString input(cx, iter.readString());
+
+ // Int32 because |lastIndex| is computed from transpiled self-hosted call.
+ int32_t lastIndex = iter.readInt32();
RootedValue result(cx);
if (!RegExpMatcherRaw(cx, regexp, input, lastIndex, nullptr, &result)) {
@@ -1507,7 +1495,8 @@ bool MTypeOfName::writeRecoverData(CompactBufferWriter& writer) const {
RTypeOfName::RTypeOfName(CompactBufferReader& reader) {}
bool RTypeOfName::recover(JSContext* cx, SnapshotIterator& iter) const {
- int32_t type = iter.read().toInt32();
+ // Int32 because |type| is computed from MTypeOf.
+ int32_t type = iter.readInt32();
MOZ_ASSERT(JSTYPE_UNDEFINED <= type && type < JSTYPE_LIMIT);
JSString* name = TypeName(JSType(type), *cx->runtime()->commonNames);
@@ -1548,7 +1537,7 @@ bool MToFloat32::writeRecoverData(CompactBufferWriter& writer) const {
RToFloat32::RToFloat32(CompactBufferReader& reader) {}
bool RToFloat32::recover(JSContext* cx, SnapshotIterator& iter) const {
- double num = iter.read().toNumber();
+ double num = iter.readNumber();
double result = js::RoundFloat32(num);
iter.storeInstructionResult(DoubleValue(result));
@@ -1588,7 +1577,7 @@ bool MNewObject::writeRecoverData(CompactBufferWriter& writer) const {
RNewObject::RNewObject(CompactBufferReader& reader) {}
bool RNewObject::recover(JSContext* cx, SnapshotIterator& iter) const {
- RootedObject templateObject(cx, &iter.read().toObject());
+ RootedObject templateObject(cx, iter.readObject());
// See CodeGenerator::visitNewObjectVMCall.
// Note that recover instructions are only used if mode == ObjectCreate.
@@ -1622,8 +1611,7 @@ RNewPlainObject::RNewPlainObject(CompactBufferReader& reader) {
}
bool RNewPlainObject::recover(JSContext* cx, SnapshotIterator& iter) const {
- Rooted<SharedShape*> shape(cx,
- &iter.read().toGCCellPtr().as<Shape>().asShared());
+ Rooted<SharedShape*> shape(cx, &iter.readGCCellPtr().as<Shape>().asShared());
// See CodeGenerator::visitNewPlainObject.
JSObject* resultObject =
@@ -1676,7 +1664,7 @@ bool MNewTypedArray::writeRecoverData(CompactBufferWriter& writer) const {
RNewTypedArray::RNewTypedArray(CompactBufferReader& reader) {}
bool RNewTypedArray::recover(JSContext* cx, SnapshotIterator& iter) const {
- RootedObject templateObject(cx, &iter.read().toObject());
+ RootedObject templateObject(cx, iter.readObject());
size_t length = templateObject.as<FixedLengthTypedArrayObject>()->length();
MOZ_ASSERT(length <= INT32_MAX,
@@ -1704,7 +1692,7 @@ RNewArray::RNewArray(CompactBufferReader& reader) {
}
bool RNewArray::recover(JSContext* cx, SnapshotIterator& iter) const {
- RootedObject templateObject(cx, &iter.read().toObject());
+ RootedObject templateObject(cx, iter.readObject());
Rooted<Shape*> shape(cx, templateObject->shape());
ArrayObject* resultObject = NewArrayWithShape(cx, count_, shape);
@@ -1728,7 +1716,7 @@ RNewIterator::RNewIterator(CompactBufferReader& reader) {
}
bool RNewIterator::recover(JSContext* cx, SnapshotIterator& iter) const {
- RootedObject templateObject(cx, &iter.read().toObject());
+ RootedObject templateObject(cx, iter.readObject());
JSObject* resultObject = nullptr;
switch (MNewIterator::Type(type_)) {
@@ -1760,8 +1748,8 @@ bool MLambda::writeRecoverData(CompactBufferWriter& writer) const {
RLambda::RLambda(CompactBufferReader& reader) {}
bool RLambda::recover(JSContext* cx, SnapshotIterator& iter) const {
- RootedObject scopeChain(cx, &iter.read().toObject());
- RootedFunction fun(cx, &iter.read().toObject().as<JSFunction>());
+ RootedObject scopeChain(cx, iter.readObject());
+ RootedFunction fun(cx, &iter.readObject()->as<JSFunction>());
JSObject* resultObject = js::Lambda(cx, fun, scopeChain);
if (!resultObject) {
@@ -1781,9 +1769,9 @@ bool MFunctionWithProto::writeRecoverData(CompactBufferWriter& writer) const {
RFunctionWithProto::RFunctionWithProto(CompactBufferReader& reader) {}
bool RFunctionWithProto::recover(JSContext* cx, SnapshotIterator& iter) const {
- RootedObject scopeChain(cx, &iter.read().toObject());
- RootedObject prototype(cx, &iter.read().toObject());
- RootedFunction fun(cx, &iter.read().toObject().as<JSFunction>());
+ RootedObject scopeChain(cx, iter.readObject());
+ RootedObject prototype(cx, iter.readObject());
+ RootedFunction fun(cx, &iter.readObject()->as<JSFunction>());
JSObject* resultObject =
js::FunWithProtoOperation(cx, fun, scopeChain, prototype);
@@ -1804,7 +1792,7 @@ bool MNewCallObject::writeRecoverData(CompactBufferWriter& writer) const {
RNewCallObject::RNewCallObject(CompactBufferReader& reader) {}
bool RNewCallObject::recover(JSContext* cx, SnapshotIterator& iter) const {
- Rooted<CallObject*> templateObj(cx, &iter.read().toObject().as<CallObject>());
+ Rooted<CallObject*> templateObj(cx, &iter.readObject()->as<CallObject>());
Rooted<SharedShape*> shape(cx, templateObj->sharedShape());
@@ -1832,7 +1820,7 @@ bool MObjectKeys::writeRecoverData(CompactBufferWriter& writer) const {
RObjectKeys::RObjectKeys(CompactBufferReader& reader) {}
bool RObjectKeys::recover(JSContext* cx, SnapshotIterator& iter) const {
- Rooted<JSObject*> obj(cx, &iter.read().toObject());
+ Rooted<JSObject*> obj(cx, iter.readObject());
JSObject* resultKeys = ObjectKeys(cx, obj);
if (!resultKeys) {
@@ -1855,7 +1843,7 @@ RObjectState::RObjectState(CompactBufferReader& reader) {
}
bool RObjectState::recover(JSContext* cx, SnapshotIterator& iter) const {
- RootedObject object(cx, &iter.read().toObject());
+ RootedObject object(cx, iter.readObject());
Handle<NativeObject*> nativeObject = object.as<NativeObject>();
MOZ_ASSERT(!Watchtower::watchesPropertyModification(nativeObject));
MOZ_ASSERT(nativeObject->slotSpan() == numSlots());
@@ -1881,8 +1869,10 @@ RArrayState::RArrayState(CompactBufferReader& reader) {
}
bool RArrayState::recover(JSContext* cx, SnapshotIterator& iter) const {
- ArrayObject* object = &iter.read().toObject().as<ArrayObject>();
- uint32_t initLength = iter.read().toInt32();
+ ArrayObject* object = &iter.readObject()->as<ArrayObject>();
+
+ // Int32 because |initLength| is computed from MConstant.
+ uint32_t initLength = iter.readInt32();
MOZ_ASSERT(object->getDenseInitializedLength() == 0,
"initDenseElement call below relies on this");
@@ -1903,37 +1893,6 @@ bool RArrayState::recover(JSContext* cx, SnapshotIterator& iter) const {
return true;
}
-bool MSetArrayLength::writeRecoverData(CompactBufferWriter& writer) const {
- MOZ_ASSERT(canRecoverOnBailout());
- // For simplicity, we capture directly the object instead of the elements
- // pointer.
- MOZ_ASSERT(elements()->type() != MIRType::Elements);
- writer.writeUnsigned(uint32_t(RInstruction::Recover_SetArrayLength));
- return true;
-}
-
-bool MSetArrayLength::canRecoverOnBailout() const {
- return isRecoveredOnBailout();
-}
-
-RSetArrayLength::RSetArrayLength(CompactBufferReader& reader) {}
-
-bool RSetArrayLength::recover(JSContext* cx, SnapshotIterator& iter) const {
- Rooted<ArrayObject*> obj(cx, &iter.read().toObject().as<ArrayObject>());
- RootedValue len(cx, iter.read());
-
- RootedId id(cx, NameToId(cx->names().length));
- Rooted<PropertyDescriptor> desc(
- cx, PropertyDescriptor::Data(len, JS::PropertyAttribute::Writable));
- ObjectOpResult error;
- if (!ArraySetLength(cx, obj, id, desc, error)) {
- return false;
- }
-
- iter.storeInstructionResult(ObjectValue(*obj));
- return true;
-}
-
bool MAssertRecoveredOnBailout::writeRecoverData(
CompactBufferWriter& writer) const {
MOZ_ASSERT(canRecoverOnBailout());
@@ -1966,9 +1925,9 @@ RStringReplace::RStringReplace(CompactBufferReader& reader) {
}
bool RStringReplace::recover(JSContext* cx, SnapshotIterator& iter) const {
- RootedString string(cx, iter.read().toString());
- RootedString pattern(cx, iter.read().toString());
- RootedString replace(cx, iter.read().toString());
+ RootedString string(cx, iter.readString());
+ RootedString pattern(cx, iter.readString());
+ RootedString replace(cx, iter.readString());
JSString* result =
isFlatReplacement_
@@ -1992,9 +1951,20 @@ bool MSubstr::writeRecoverData(CompactBufferWriter& writer) const {
RSubstr::RSubstr(CompactBufferReader& reader) {}
bool RSubstr::recover(JSContext* cx, SnapshotIterator& iter) const {
- RootedString str(cx, iter.read().toString());
- int32_t begin = iter.read().toInt32();
- int32_t length = iter.read().toInt32();
+ RootedString str(cx, iter.readString());
+
+ // Int32 because |begin| is computed from MStringTrimStartIndex, MConstant,
+ // or CallSubstringKernelResult.
+ int32_t begin = iter.readInt32();
+
+ // |length| is computed from MSub(truncated), MStringTrimEndIndex, or
+ // CallSubstringKernelResult. The current MSub inputs won't overflow, so when
+ // RSub recovers the MSub instruction, the input will be representable as an
+ // Int32. This is only true as long as RSub calls |js::SubOperation|, which in
+ // turn calls |JS::Value::setNumber|. We don't want to rely on this exact call
+ // sequence, so instead use |readNumber| here and then release-assert the
+ // number is exactly representable as an Int32.
+ int32_t length = mozilla::ReleaseAssertedCast<int32_t>(iter.readNumber());
JSString* result = SubstringKernel(cx, str, begin, length);
if (!result) {
@@ -2014,10 +1984,11 @@ bool MAtomicIsLockFree::writeRecoverData(CompactBufferWriter& writer) const {
RAtomicIsLockFree::RAtomicIsLockFree(CompactBufferReader& reader) {}
bool RAtomicIsLockFree::recover(JSContext* cx, SnapshotIterator& iter) const {
- Value operand = iter.read();
- MOZ_ASSERT(operand.isInt32());
+ double dsize = JS::ToInteger(iter.readNumber());
- bool result = AtomicOperations::isLockfreeJS(operand.toInt32());
+ int32_t size;
+ bool result = mozilla::NumberEqualsInt32(dsize, &size) &&
+ AtomicOperations::isLockfreeJS(size);
iter.storeInstructionResult(BooleanValue(result));
return true;
}
@@ -2031,10 +2002,12 @@ bool MBigIntAsIntN::writeRecoverData(CompactBufferWriter& writer) const {
RBigIntAsIntN::RBigIntAsIntN(CompactBufferReader& reader) {}
bool RBigIntAsIntN::recover(JSContext* cx, SnapshotIterator& iter) const {
- int32_t bits = iter.read().toInt32();
- RootedBigInt input(cx, iter.read().toBigInt());
-
+ // Int32 because |bits| is computed from MGuardInt32IsNonNegative.
+ int32_t bits = iter.readInt32();
MOZ_ASSERT(bits >= 0);
+
+ RootedBigInt input(cx, iter.readBigInt());
+
BigInt* result = BigInt::asIntN(cx, input, bits);
if (!result) {
return false;
@@ -2053,10 +2026,12 @@ bool MBigIntAsUintN::writeRecoverData(CompactBufferWriter& writer) const {
RBigIntAsUintN::RBigIntAsUintN(CompactBufferReader& reader) {}
bool RBigIntAsUintN::recover(JSContext* cx, SnapshotIterator& iter) const {
- int32_t bits = iter.read().toInt32();
- RootedBigInt input(cx, iter.read().toBigInt());
-
+ // Int32 because |bits| is computed from MGuardInt32IsNonNegative.
+ int32_t bits = iter.readInt32();
MOZ_ASSERT(bits >= 0);
+
+ RootedBigInt input(cx, iter.readBigInt());
+
BigInt* result = BigInt::asUintN(cx, input, bits);
if (!result) {
return false;
@@ -2077,7 +2052,7 @@ RCreateArgumentsObject::RCreateArgumentsObject(CompactBufferReader& reader) {}
bool RCreateArgumentsObject::recover(JSContext* cx,
SnapshotIterator& iter) const {
- RootedObject callObject(cx, &iter.read().toObject());
+ RootedObject callObject(cx, iter.readObject());
RootedObject result(
cx, ArgumentsObject::createForIon(cx, iter.frame(), callObject));
if (!result) {
@@ -2104,8 +2079,8 @@ RCreateInlinedArgumentsObject::RCreateInlinedArgumentsObject(
bool RCreateInlinedArgumentsObject::recover(JSContext* cx,
SnapshotIterator& iter) const {
- RootedObject callObject(cx, &iter.read().toObject());
- RootedFunction callee(cx, &iter.read().toObject().as<JSFunction>());
+ RootedObject callObject(cx, iter.readObject());
+ RootedFunction callee(cx, &iter.readObject()->as<JSFunction>());
JS::RootedValueArray<ArgumentsObject::MaxInlinedArgs> argsArray(cx);
for (uint32_t i = 0; i < numActuals_; i++) {
@@ -2136,7 +2111,8 @@ RRest::RRest(CompactBufferReader& reader) {
bool RRest::recover(JSContext* cx, SnapshotIterator& iter) const {
JitFrameLayout* frame = iter.frame();
- uint32_t numActuals = iter.read().toInt32();
+ // Int32 because |numActuals| is computed from MArgumentsLength.
+ uint32_t numActuals = iter.readInt32();
MOZ_ASSERT(numActuals == frame->numActualArgs());
uint32_t numFormals = numFormals_;