Commit dec3de8a authored by Igor Sheludko's avatar Igor Sheludko Committed by Commit Bot

[builtins] Make ToIndex() uintptr index friendly

The new ToIndex() must eventually replace ToSmiIndex().

The CL fixes the following abstract operations:
  GetViewValue(view, requestIndex, isLittleEndian, type)
  SetViewValue(view, requestIndex, isLittleEndian, type, value)

and the following builtins:
  DataView.prototype.getXXX
  DataView.prototype.setXXX

where XXX are all typed elements.

Bug: v8:4153
Change-Id: Ic2f33e91b59426deb0efa28bb4c15253e80a299c
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1874345
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64506}
parent 1e256fc3
......@@ -1407,6 +1407,7 @@ const kArrayBufferMaxByteLength:
const kMaxTypedArrayInHeap:
constexpr int31 generates 'JSTypedArray::kMaxSizeInHeap';
const kMaxSafeInteger: constexpr float64 generates 'kMaxSafeInteger';
const kMaxUInt32Double: constexpr float64 generates 'kMaxUInt32Double';
const kSmiMaxValue: constexpr uintptr generates 'kSmiMaxValue';
const kSmiMax: uintptr = kSmiMaxValue;
// TODO(v8:8996): Use uintptr version instead and drop this one.
......@@ -1854,6 +1855,7 @@ extern transitioning macro ToInteger_Inline(
Context, JSAny, constexpr ToIntegerTruncationMode): Number;
extern transitioning macro ToLength_Inline(Context, JSAny): Number;
extern transitioning macro ToNumber_Inline(Context, JSAny): Number;
// TODO(v8:4153): Use ToIndex() instead.
extern transitioning macro ToSmiIndex(implicit context: Context)(JSAny):
PositiveSmi labels IfRangeError;
extern transitioning macro ToSmiLength(implicit context: Context)(JSAny):
......@@ -3615,18 +3617,46 @@ macro SameValue(a: JSAny, b: JSAny): bool {
BranchIfSameValue(a, b) otherwise return true, return false;
}
transitioning macro ToIndex(input: JSAny, context: Context): Number
labels RangeError {
if (input == Undefined) {
return 0;
}
// https://tc39.github.io/ecma262/#sec-toindex
@export
transitioning macro ToIndex(implicit context: Context)(value: JSAny):
uintptr labels IfRangeError {
if (value == Undefined) return 0;
const indexNumber = ToInteger_Inline(context, value, kTruncateMinusZero);
return ToIndex(indexNumber) otherwise IfRangeError;
}
const value: Number = ToInteger_Inline(context, input, kTruncateMinusZero);
if (value < 0 || value > kMaxSafeInteger) {
goto RangeError;
}
// https://tc39.github.io/ecma262/#sec-toindex
// Same as the version above but for Number arguments.
macro ToIndex(indexNumber: Number): uintptr labels IfRangeError {
typeswitch (indexNumber) {
case (indexSmi: Smi): {
if (indexSmi < 0) goto IfRangeError;
const index: uintptr = Unsigned(Convert<intptr>(indexSmi));
// Positive Smi values definitely fit into both [0, kMaxSafeInteger] and
// [0, kMaxUintPtr] ranges.
return index;
}
case (indexHeapNumber: HeapNumber): {
assert(IsNumberNormalized(indexHeapNumber));
const indexDouble: float64 = Convert<float64>(indexHeapNumber);
// NaNs must already be handled by ToIndex() version above accepting
// JSAny indices.
assert(!Float64IsNaN(indexDouble));
if (indexDouble < 0) goto IfRangeError;
return value;
if constexpr (Is64()) {
if (indexDouble > kMaxSafeInteger) goto IfRangeError;
} else {
// On 32-bit architectures not all safe integers fit into uintptr but
// callers handle this case the same way as the safe integer range
// overflow case so we don't need special handling for the values in
// (kMaxUInt32, kMaxSafeInteger] range.
if (indexDouble > kMaxUInt32Double) goto IfRangeError;
}
return ChangeFloat64ToUintPtr(indexDouble);
}
}
}
transitioning macro GetLengthProperty(implicit context: Context)(o: JSAny):
......@@ -3694,7 +3724,7 @@ macro ConvertToRelativeIndex(indexNumber: Number, length: uintptr): uintptr {
const indexDouble: float64 = Convert<float64>(indexHeapNumber);
// NaNs must already be handled by ConvertToRelativeIndex() version
// above accepting JSAny indices.
assert(indexDouble == indexDouble);
assert(!Float64IsNaN(indexDouble));
const lengthDouble: float64 = Convert<float64>(length);
assert(lengthDouble <= kMaxSafeInteger);
if (indexDouble < 0) {
......
This diff is collapsed.
......@@ -212,17 +212,12 @@ namespace typed_array {
map: Map, buffer: JSArrayBuffer, byteOffset: JSAny, length: JSAny,
elementsInfo: typed_array::TypedArrayElementsInfo): JSTypedArray {
try {
let offset: uintptr = 0;
if (byteOffset != Undefined) {
// 6. Let offset be ? ToIndex(byteOffset).
offset = TryNumberToUintPtr(
ToInteger_Inline(context, byteOffset, kTruncateMinusZero))
otherwise goto IfInvalidOffset;
// 7. If offset modulo elementSize ≠ 0, throw a RangeError exception.
if (elementsInfo.IsUnaligned(offset)) {
goto IfInvalidAlignment('start offset');
}
// 6. Let offset be ? ToIndex(byteOffset).
const offset: uintptr = ToIndex(byteOffset) otherwise IfInvalidOffset;
// 7. If offset modulo elementSize ≠ 0, throw a RangeError exception.
if (elementsInfo.IsUnaligned(offset)) {
goto IfInvalidAlignment('start offset');
}
let newLength: PositiveSmi = 0;
......
......@@ -2664,6 +2664,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
};
// ES6 7.1.17 ToIndex, but jumps to range_error if the result is not a Smi.
// TODO(v8:4153): Use ToIndex() instead.
TNode<Smi> ToSmiIndex(TNode<Context> context, TNode<Object> input,
Label* range_error);
......
......@@ -1043,6 +1043,8 @@ constexpr uint64_t kHoleNanInt64 =
// ES6 section 20.1.2.6 Number.MAX_SAFE_INTEGER
constexpr double kMaxSafeInteger = 9007199254740991.0; // 2^53-1
constexpr double kMaxUInt32Double = double{kMaxUInt32};
// The order of this enum has to be kept in sync with the predicates below.
enum class VariableMode : uint8_t {
// User declared variables:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment