mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-20 00:35:44 +00:00
Bug 1644425 part 1 - Replace ToLength function in self-hosted code with an intrinsic. r=anba
This fixes a regression from bug 1643680 because the code relied on Math.min/max with int32 and double arguments returning an int32 when possible. Porting this to C++ should make this less brittle. Differential Revision: https://phabricator.services.mozilla.com/D78917
This commit is contained in:
parent
5f046f94b5
commit
96041ddffc
@ -154,7 +154,7 @@ bool js::GetLengthProperty(JSContext* cx, HandleObject obj, uint32_t* lengthp) {
|
||||
}
|
||||
|
||||
// ES2017 7.1.15 ToLength.
|
||||
static bool ToLength(JSContext* cx, HandleValue v, uint64_t* out) {
|
||||
bool js::ToLength(JSContext* cx, HandleValue v, uint64_t* out) {
|
||||
if (v.isInt32()) {
|
||||
int32_t i = v.toInt32();
|
||||
*out = i < 0 ? 0 : i;
|
||||
|
@ -118,6 +118,8 @@ extern ArrayObject* NewArrayWithGroup(JSContext* cx, uint32_t length,
|
||||
HandleObjectGroup group,
|
||||
bool convertDoubleElements);
|
||||
|
||||
extern bool ToLength(JSContext* cx, HandleValue v, uint64_t* out);
|
||||
|
||||
extern bool GetLengthProperty(JSContext* cx, HandleObject obj,
|
||||
uint32_t* lengthp);
|
||||
|
||||
|
@ -75,20 +75,6 @@ function RequireObjectCoercible(v) {
|
||||
ThrowTypeError(JSMSG_CANT_CONVERT_TO, ToString(v), "object");
|
||||
}
|
||||
|
||||
/* Spec: ECMAScript Draft, 6 edition May 22, 2014, 7.1.15 */
|
||||
function ToLength(v) {
|
||||
// Step 1.
|
||||
v = ToInteger(v);
|
||||
|
||||
// Step 2.
|
||||
// Use max(v, 0) here, because it's easier to optimize in Ion.
|
||||
v = std_Math_max(v, 0);
|
||||
|
||||
// Step 3.
|
||||
// Math.pow(2, 53) - 1 = 0x1fffffffffffff
|
||||
return std_Math_min(v, 0x1fffffffffffff);
|
||||
}
|
||||
|
||||
// ES2017 draft rev aebf014403a3e641fb1622aec47c40f051943527
|
||||
// 7.2.10 SameValueZero ( x, y )
|
||||
function SameValueZero(x, y) {
|
||||
|
@ -159,6 +159,26 @@ static bool intrinsic_IsCrossRealmArrayConstructor(JSContext* cx, unsigned argc,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool intrinsic_ToLength(JSContext* cx, unsigned argc, Value* vp) {
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
MOZ_ASSERT(args.length() == 1);
|
||||
|
||||
// Inline fast path for the common case.
|
||||
if (args[0].isInt32()) {
|
||||
int32_t i = args[0].toInt32();
|
||||
args.rval().setInt32(i < 0 ? 0 : i);
|
||||
return true;
|
||||
}
|
||||
|
||||
uint64_t length = 0;
|
||||
if (!ToLength(cx, args[0], &length)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
args.rval().setNumber(double(length));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool intrinsic_ToInteger(JSContext* cx, unsigned argc, Value* vp) {
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
double result;
|
||||
@ -2140,6 +2160,7 @@ static const JSFunctionSpec intrinsic_functions[] = {
|
||||
intrinsic_IsCrossRealmArrayConstructor, 1, 0,
|
||||
IntrinsicIsCrossRealmArrayConstructor),
|
||||
JS_INLINABLE_FN("ToInteger", intrinsic_ToInteger, 1, 0, IntrinsicToInteger),
|
||||
JS_FN("ToLength", intrinsic_ToLength, 1, 0),
|
||||
JS_INLINABLE_FN("ToString", intrinsic_ToString, 1, 0, IntrinsicToString),
|
||||
JS_FN("ToSource", intrinsic_ToSource, 1, 0),
|
||||
JS_FN("ToPropertyKey", intrinsic_ToPropertyKey, 1, 0),
|
||||
|
Loading…
Reference in New Issue
Block a user