Commit c4e944cb authored by Nico Hartmann's avatar Nico Hartmann Committed by Commit Bot

[torque] Port ToInteger to Torque

Bug: v8:10155
Change-Id: I032b27ad7c71d240453e33bef33a447a1530ace9
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2060005
Commit-Queue: Nico Hartmann <nicohartmann@chromium.org>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#66387}
parent 86a6ce45
...@@ -63,7 +63,8 @@ namespace array { ...@@ -63,7 +63,8 @@ namespace array {
// else let n be len - 1. // else let n be len - 1.
const n: Number = arguments.length < 2 ? const n: Number = arguments.length < 2 ?
length - 1 : length - 1 :
ToInteger_Inline(arguments[1], kTruncateMinusZero); ToInteger_Inline(
arguments[1], ToIntegerTruncationMode::kTruncateMinusZero);
// 5. If n >= 0, then. // 5. If n >= 0, then.
let k: Number = SmiConstant(0); let k: Number = SmiConstant(0);
......
...@@ -177,9 +177,6 @@ type Callable = JSFunction|JSBoundFunction|CallableJSProxy|CallableApiObject; ...@@ -177,9 +177,6 @@ type Callable = JSFunction|JSBoundFunction|CallableJSProxy|CallableApiObject;
type WriteBarrierMode type WriteBarrierMode
generates 'TNode<Int32T>' constexpr 'WriteBarrierMode'; generates 'TNode<Int32T>' constexpr 'WriteBarrierMode';
type ToIntegerTruncationMode
constexpr 'CodeStubAssembler::ToIntegerTruncationMode';
extern enum UnicodeEncoding { UTF16, UTF32 } extern enum UnicodeEncoding { UTF16, UTF32 }
// Promise constants // Promise constants
...@@ -345,9 +342,11 @@ const kSloppyArgumentsContextIndex: constexpr int31 ...@@ -345,9 +342,11 @@ const kSloppyArgumentsContextIndex: constexpr int31
const kSloppyArgumentsParameterMapStart: constexpr int31 const kSloppyArgumentsParameterMapStart: constexpr int31
generates 'SloppyArgumentsElements::kParameterMapStart'; generates 'SloppyArgumentsElements::kParameterMapStart';
const kTruncateMinusZero: constexpr ToIntegerTruncationMode extern enum ToIntegerTruncationMode extends int32
generates 'CodeStubAssembler::ToIntegerTruncationMode::kTruncateMinusZero' constexpr 'compiler::CodeAssembler::ToIntegerTruncationMode' {
; kNoTruncation,
kTruncateMinusZero
}
extern enum PrimitiveType { kString, kBoolean, kSymbol, kNumber } extern enum PrimitiveType { kString, kBoolean, kSymbol, kNumber }
...@@ -433,10 +432,71 @@ extern macro Comment(constexpr string); ...@@ -433,10 +432,71 @@ extern macro Comment(constexpr string);
extern macro StaticAssert(bool); extern macro StaticAssert(bool);
extern macro Print(Object); extern macro Print(Object);
extern macro DebugBreak(); extern macro DebugBreak();
extern transitioning macro ToInteger_Inline(implicit context: Context)(JSAny):
Number; // ES6 7.1.4 ToInteger ( argument )
extern transitioning macro ToInteger_Inline(implicit context: Context)( transitioning macro ToIntegerImpl(implicit context: Context)(
JSAny, constexpr ToIntegerTruncationMode): Number; input: Object, mode: constexpr ToIntegerTruncationMode): Number {
let input = input;
while (true) {
typeswitch (input) {
case (s: Smi): {
return s;
}
case (hn: HeapNumber): {
let value = Convert<float64>(hn);
if (Float64IsNaN(value)) return SmiConstant(0);
value = math::Float64Trunc(value);
if constexpr (mode == ToIntegerTruncationMode::kTruncateMinusZero) {
if (value == 0.0) return SmiConstant(0);
}
const result = ChangeFloat64ToTagged(value);
if constexpr (mode == ToIntegerTruncationMode::kTruncateMinusZero) {
assert(IsNumberNormalized(result));
}
return result;
}
case (ho: HeapObject): {
input = math::NonNumberToNumber(ho);
}
}
}
unreachable;
}
transitioning builtin ToInteger(implicit context: Context)(input: Object):
Number {
return ToIntegerImpl(input, ToIntegerTruncationMode::kNoTruncation);
}
transitioning builtin ToInteger_TruncateMinusZero(implicit context: Context)(
input: Object): Number {
return ToIntegerImpl(input, ToIntegerTruncationMode::kTruncateMinusZero);
}
@export
transitioning macro ToInteger_Inline(implicit context: Context)(input: Object):
Number {
return ToInteger_Inline(input, ToIntegerTruncationMode::kNoTruncation);
}
@export
transitioning macro ToInteger_Inline(implicit context: Context)(
input: Object, mode: constexpr ToIntegerTruncationMode): Number {
typeswitch (input) {
case (s: Smi): {
return s;
}
case (ho: HeapObject): {
if constexpr (mode == ToIntegerTruncationMode::kTruncateMinusZero) {
return ToInteger_TruncateMinusZero(ho);
} else {
return ToInteger(ho);
}
}
}
}
extern transitioning macro ToLength_Inline(implicit context: Context)(JSAny): extern transitioning macro ToLength_Inline(implicit context: Context)(JSAny):
Number; Number;
extern transitioning macro ToNumber_Inline(implicit context: Context)(JSAny): extern transitioning macro ToNumber_Inline(implicit context: Context)(JSAny):
...@@ -724,6 +784,10 @@ ConstexprInt31NotEqual(constexpr int31, constexpr int31): constexpr bool; ...@@ -724,6 +784,10 @@ ConstexprInt31NotEqual(constexpr int31, constexpr int31): constexpr bool;
extern operator '>=' macro extern operator '>=' macro
ConstexprInt31GreaterThanEqual( ConstexprInt31GreaterThanEqual(
constexpr int31, constexpr int31): constexpr bool; constexpr int31, constexpr int31): constexpr bool;
extern operator '==' macro ConstexprInt32Equal(
constexpr int32, constexpr int32): constexpr bool;
extern operator '!=' macro ConstexprInt32NotEqual(
constexpr int32, constexpr int32): constexpr bool;
extern operator '==' macro Word32Equal(int32, int32): bool; extern operator '==' macro Word32Equal(int32, int32): bool;
extern operator '==' macro Word32Equal(uint32, uint32): bool; extern operator '==' macro Word32Equal(uint32, uint32): bool;
...@@ -1206,7 +1270,8 @@ macro ChangeSafeIntegerNumberToUintPtr(value: Number): ...@@ -1206,7 +1270,8 @@ macro ChangeSafeIntegerNumberToUintPtr(value: Number):
transitioning macro ToUintPtr(implicit context: Context)(value: JSAny): transitioning macro ToUintPtr(implicit context: Context)(value: JSAny):
uintptr labels IfLessThanZero, IfUIntPtrOverflow, IfSafeIntegerOverflow { uintptr labels IfLessThanZero, IfUIntPtrOverflow, IfSafeIntegerOverflow {
if (value == Undefined) return 0; if (value == Undefined) return 0;
const indexNumber = ToInteger_Inline(value, kTruncateMinusZero); const indexNumber =
ToInteger_Inline(value, ToIntegerTruncationMode::kTruncateMinusZero);
return TryNumberToUintPtr(indexNumber, kModeValueIsAnyNumber) return TryNumberToUintPtr(indexNumber, kModeValueIsAnyNumber)
otherwise IfLessThanZero, IfUIntPtrOverflow, IfSafeIntegerOverflow; otherwise IfLessThanZero, IfUIntPtrOverflow, IfSafeIntegerOverflow;
} }
...@@ -1220,7 +1285,8 @@ transitioning macro ToUintPtr(implicit context: Context)(value: JSAny): ...@@ -1220,7 +1285,8 @@ transitioning macro ToUintPtr(implicit context: Context)(value: JSAny):
transitioning macro ToIndex(implicit context: Context)(value: JSAny): transitioning macro ToIndex(implicit context: Context)(value: JSAny):
uintptr labels IfRangeError { uintptr labels IfRangeError {
if (value == Undefined) return 0; if (value == Undefined) return 0;
const indexNumber = ToInteger_Inline(value, kTruncateMinusZero); const indexNumber =
ToInteger_Inline(value, ToIntegerTruncationMode::kTruncateMinusZero);
// Less than 0 case, uintptr range overflow and safe integer range overflow // Less than 0 case, uintptr range overflow and safe integer range overflow
// imply IfRangeError. // imply IfRangeError.
return TryNumberToUintPtr(indexNumber, kModeValueIsAnyNumber) return TryNumberToUintPtr(indexNumber, kModeValueIsAnyNumber)
...@@ -1293,7 +1359,8 @@ extern macro IsOneByteStringInstanceType(InstanceType): bool; ...@@ -1293,7 +1359,8 @@ extern macro IsOneByteStringInstanceType(InstanceType): bool;
@export @export
transitioning macro ConvertToRelativeIndex(implicit context: Context)( transitioning macro ConvertToRelativeIndex(implicit context: Context)(
index: JSAny, length: uintptr): uintptr { index: JSAny, length: uintptr): uintptr {
const indexNumber: Number = ToInteger_Inline(index, kTruncateMinusZero); const indexNumber: Number =
ToInteger_Inline(index, ToIntegerTruncationMode::kTruncateMinusZero);
return ConvertToRelativeIndex(indexNumber, length); return ConvertToRelativeIndex(indexNumber, length);
} }
...@@ -1340,7 +1407,8 @@ macro ConvertToRelativeIndex(indexNumber: Number, length: uintptr): uintptr { ...@@ -1340,7 +1407,8 @@ macro ConvertToRelativeIndex(indexNumber: Number, length: uintptr): uintptr {
@export @export
transitioning macro ClampToIndexRange(implicit context: Context)( transitioning macro ClampToIndexRange(implicit context: Context)(
index: JSAny, limit: uintptr): uintptr { index: JSAny, limit: uintptr): uintptr {
const indexNumber: Number = ToInteger_Inline(index, kTruncateMinusZero); const indexNumber: Number =
ToInteger_Inline(index, ToIntegerTruncationMode::kTruncateMinusZero);
return ClampToIndexRange(indexNumber, limit); return ClampToIndexRange(indexNumber, limit);
} }
......
...@@ -376,20 +376,6 @@ TF_BUILTIN(ToLength, CodeStubAssembler) { ...@@ -376,20 +376,6 @@ TF_BUILTIN(ToLength, CodeStubAssembler) {
} }
} }
TF_BUILTIN(ToInteger, CodeStubAssembler) {
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
TNode<Object> input = CAST(Parameter(Descriptor::kArgument));
Return(ToInteger(context, input, kNoTruncation));
}
TF_BUILTIN(ToInteger_TruncateMinusZero, CodeStubAssembler) {
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
TNode<Object> input = CAST(Parameter(Descriptor::kArgument));
Return(ToInteger(context, input, kTruncateMinusZero));
}
// ES6 section 7.1.13 ToObject (argument) // ES6 section 7.1.13 ToObject (argument)
TF_BUILTIN(ToObject, CodeStubAssembler) { TF_BUILTIN(ToObject, CodeStubAssembler) {
Label if_smi(this, Label::kDeferred), if_jsreceiver(this), Label if_smi(this, Label::kDeferred), if_jsreceiver(this),
......
...@@ -200,8 +200,6 @@ namespace internal { ...@@ -200,8 +200,6 @@ namespace internal {
TFC(ToNumberConvertBigInt, TypeConversion) \ TFC(ToNumberConvertBigInt, TypeConversion) \
TFC(ToNumeric, TypeConversion) \ TFC(ToNumeric, TypeConversion) \
TFC(NumberToString, TypeConversion) \ TFC(NumberToString, TypeConversion) \
TFC(ToInteger, TypeConversion) \
TFC(ToInteger_TruncateMinusZero, TypeConversion) \
TFC(ToLength, TypeConversion) \ TFC(ToLength, TypeConversion) \
TFC(Typeof, Typeof) \ TFC(Typeof, Typeof) \
TFC(GetSuperConstructor, Typeof) \ TFC(GetSuperConstructor, Typeof) \
......
...@@ -68,7 +68,8 @@ namespace string { ...@@ -68,7 +68,8 @@ namespace string {
const string: String = ToThisString(receiver, methodName); const string: String = ToThisString(receiver, methodName);
// 3. Let position be ? ToInteger(pos). // 3. Let position be ? ToInteger(pos).
const indexNumber: Number = ToInteger_Inline(position, kTruncateMinusZero); const indexNumber: Number =
ToInteger_Inline(position, ToIntegerTruncationMode::kTruncateMinusZero);
// Convert the {position} to a uintptr and check that it's in bounds of // Convert the {position} to a uintptr and check that it's in bounds of
// the {string}. // the {string}.
......
...@@ -33,8 +33,9 @@ namespace number { ...@@ -33,8 +33,9 @@ namespace number {
// 3. Else if radix is undefined, let radixNumber be 10. // 3. Else if radix is undefined, let radixNumber be 10.
// 4. Else, let radixNumber be ? ToInteger(radix). // 4. Else, let radixNumber be ? ToInteger(radix).
const radix: JSAny = arguments[0]; const radix: JSAny = arguments[0];
const radixNumber: Number = const radixNumber: Number = radix == Undefined ?
radix == Undefined ? 10 : ToInteger_Inline(radix, kTruncateMinusZero); 10 :
ToInteger_Inline(radix, ToIntegerTruncationMode::kTruncateMinusZero);
// 5. If radixNumber < 2 or radixNumber > 36, throw a RangeError exception. // 5. If radixNumber < 2 or radixNumber > 36, throw a RangeError exception.
if (radixNumber < 2 || radixNumber > 36) { if (radixNumber < 2 || radixNumber > 36) {
......
...@@ -36,7 +36,8 @@ namespace string { ...@@ -36,7 +36,8 @@ namespace string {
try { try {
// 3. Let n be ? ToInteger(count). // 3. Let n be ? ToInteger(count).
typeswitch (ToInteger_Inline(count, kTruncateMinusZero)) { typeswitch (ToInteger_Inline(
count, ToIntegerTruncationMode::kTruncateMinusZero)) {
case (n: Smi): { case (n: Smi): {
// 4. If n < 0, throw a RangeError exception. // 4. If n < 0, throw a RangeError exception.
if (n < 0) goto InvalidCount; if (n < 0) goto InvalidCount;
......
...@@ -7243,82 +7243,6 @@ TNode<Number> CodeStubAssembler::ToLength_Inline(SloppyTNode<Context> context, ...@@ -7243,82 +7243,6 @@ TNode<Number> CodeStubAssembler::ToLength_Inline(SloppyTNode<Context> context,
[=] { return CAST(CallBuiltin(Builtins::kToLength, context, input)); }); [=] { return CAST(CallBuiltin(Builtins::kToLength, context, input)); });
} }
TNode<Number> CodeStubAssembler::ToInteger_Inline(
SloppyTNode<Context> context, SloppyTNode<Object> input,
ToIntegerTruncationMode mode) {
Builtins::Name builtin = (mode == kNoTruncation)
? Builtins::kToInteger
: Builtins::kToInteger_TruncateMinusZero;
return Select<Number>(
TaggedIsSmi(input), [=] { return CAST(input); },
[=] { return CAST(CallBuiltin(builtin, context, input)); });
}
TNode<Number> CodeStubAssembler::ToInteger(SloppyTNode<Context> context,
SloppyTNode<Object> input,
ToIntegerTruncationMode mode) {
// We might need to loop once for ToNumber conversion.
TVARIABLE(Object, var_arg, input);
Label loop(this, &var_arg), out(this);
Goto(&loop);
BIND(&loop);
{
// Shared entry points.
Label return_zero(this, Label::kDeferred);
// Load the current {arg} value.
TNode<Object> arg = var_arg.value();
// Check if {arg} is a Smi.
GotoIf(TaggedIsSmi(arg), &out);
// Check if {arg} is a HeapNumber.
Label if_argisheapnumber(this),
if_argisnotheapnumber(this, Label::kDeferred);
Branch(IsHeapNumber(CAST(arg)), &if_argisheapnumber,
&if_argisnotheapnumber);
BIND(&if_argisheapnumber);
{
TNode<HeapNumber> arg_hn = CAST(arg);
// Load the floating-point value of {arg}.
TNode<Float64T> arg_value = LoadHeapNumberValue(arg_hn);
// Check if {arg} is NaN.
GotoIfNot(Float64Equal(arg_value, arg_value), &return_zero);
// Truncate {arg} towards zero.
TNode<Float64T> value = Float64Trunc(arg_value);
if (mode == kTruncateMinusZero) {
// Truncate -0.0 to 0.
GotoIf(Float64Equal(value, Float64Constant(0.0)), &return_zero);
}
var_arg = ChangeFloat64ToTagged(value);
Goto(&out);
}
BIND(&if_argisnotheapnumber);
{
// Need to convert {arg} to a Number first.
var_arg = UncheckedCast<Object>(
CallBuiltin(Builtins::kNonNumberToNumber, context, arg));
Goto(&loop);
}
BIND(&return_zero);
var_arg = SmiConstant(0);
Goto(&out);
}
BIND(&out);
if (mode == kTruncateMinusZero) {
CSA_ASSERT(this, IsNumberNormalized(CAST(var_arg.value())));
}
return CAST(var_arg.value());
}
TNode<Uint32T> CodeStubAssembler::DecodeWord32(SloppyTNode<Word32T> word32, TNode<Uint32T> CodeStubAssembler::DecodeWord32(SloppyTNode<Word32T> word32,
uint32_t shift, uint32_t mask) { uint32_t shift, uint32_t mask) {
DCHECK_EQ((mask >> shift) << shift, mask); DCHECK_EQ((mask >> shift) << shift, mask);
......
...@@ -2732,23 +2732,10 @@ class V8_EXPORT_PRIVATE CodeStubAssembler ...@@ -2732,23 +2732,10 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<JSReceiver> ToObject_Inline(TNode<Context> context, TNode<JSReceiver> ToObject_Inline(TNode<Context> context,
TNode<Object> input); TNode<Object> input);
enum ToIntegerTruncationMode {
kNoTruncation,
kTruncateMinusZero,
};
// ES6 7.1.15 ToLength, but with inlined fast path. // ES6 7.1.15 ToLength, but with inlined fast path.
TNode<Number> ToLength_Inline(SloppyTNode<Context> context, TNode<Number> ToLength_Inline(SloppyTNode<Context> context,
SloppyTNode<Object> input); SloppyTNode<Object> input);
// ES6 7.1.4 ToInteger ( argument )
TNode<Number> ToInteger_Inline(SloppyTNode<Context> context,
SloppyTNode<Object> input,
ToIntegerTruncationMode mode = kNoTruncation);
TNode<Number> ToInteger(SloppyTNode<Context> context,
SloppyTNode<Object> input,
ToIntegerTruncationMode mode = kNoTruncation);
// Returns a node that contains a decoded (unsigned!) value of a bit // Returns a node that contains a decoded (unsigned!) value of a bit
// field |BitField| in |word32|. Returns result as an uint32 node. // field |BitField| in |word32|. Returns result as an uint32 node.
template <typename BitField> template <typename BitField>
...@@ -3660,6 +3647,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler ...@@ -3660,6 +3647,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
bool ConstexprInt31Equal(int31_t a, int31_t b) { return a == b; } bool ConstexprInt31Equal(int31_t a, int31_t b) { return a == b; }
bool ConstexprInt31NotEqual(int31_t a, int31_t b) { return a != b; } bool ConstexprInt31NotEqual(int31_t a, int31_t b) { return a != b; }
bool ConstexprInt31GreaterThanEqual(int31_t a, int31_t b) { return a >= b; } bool ConstexprInt31GreaterThanEqual(int31_t a, int31_t b) { return a >= b; }
bool ConstexprInt32Equal(int32_t a, int32_t b) { return a == b; }
bool ConstexprInt32NotEqual(int32_t a, int32_t b) { return a != b; }
bool ConstexprInt32GreaterThanEqual(int32_t a, int32_t b) { return a >= b; } bool ConstexprInt32GreaterThanEqual(int32_t a, int32_t b) { return a >= b; }
uint32_t ConstexprUint32Add(uint32_t a, uint32_t b) { return a + b; } uint32_t ConstexprUint32Add(uint32_t a, uint32_t b) { return a + b; }
int31_t ConstexprInt31Add(int31_t a, int31_t b) { int31_t ConstexprInt31Add(int31_t a, int31_t b) {
......
...@@ -371,6 +371,11 @@ TNode<Float64T> Float64Add(TNode<Float64T> a, TNode<Float64T> b); ...@@ -371,6 +371,11 @@ TNode<Float64T> Float64Add(TNode<Float64T> a, TNode<Float64T> b);
// a CodeAssemblerState instance. // a CodeAssemblerState instance.
class V8_EXPORT_PRIVATE CodeAssembler { class V8_EXPORT_PRIVATE CodeAssembler {
public: public:
enum ToIntegerTruncationMode {
kNoTruncation,
kTruncateMinusZero,
};
explicit CodeAssembler(CodeAssemblerState* state) : state_(state) {} explicit CodeAssembler(CodeAssemblerState* state) : state_(state) {}
~CodeAssembler(); ~CodeAssembler();
......
...@@ -222,7 +222,7 @@ bool IsUpperCamelCase(const std::string& s) { ...@@ -222,7 +222,7 @@ bool IsUpperCamelCase(const std::string& s) {
if (s.empty()) return false; if (s.empty()) return false;
size_t start = 0; size_t start = 0;
if (s[0] == '_') start = 1; if (s[0] == '_') start = 1;
return isupper(s[start]) && !ContainsUnderscore(s.substr(1)); return isupper(s[start]);
} }
bool IsSnakeCase(const std::string& s) { bool IsSnakeCase(const std::string& s) {
......
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