[Builtins] Move of Math.max, min, ceil, trunc, floor, round to Torque
Bug: v8:9810 Change-Id: I29bb3db071c1957cc2a94fa7a47109cc0bab56f1 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1916599 Commit-Queue: Michael Stanton <mvstanton@chromium.org> Reviewed-by: Tobias Tebbi <tebbi@chromium.org> Cr-Commit-Position: refs/heads/master@{#64992}
This commit is contained in:
parent
80caf2cf53
commit
a19e76c7a5
@ -194,6 +194,7 @@ const kDoubleSize: constexpr int31 generates 'kDoubleSize';
|
||||
|
||||
const kSmiTagSize: constexpr int31 generates 'kSmiTagSize';
|
||||
const V8_INFINITY: constexpr float64 generates 'V8_INFINITY';
|
||||
const MINUS_V8_INFINITY: constexpr float64 generates '-V8_INFINITY';
|
||||
|
||||
const NO_ELEMENTS: constexpr ElementsKind generates 'NO_ELEMENTS';
|
||||
|
||||
@ -865,6 +866,7 @@ extern macro SmiToInt32(Smi): int32;
|
||||
extern macro RoundIntPtrToFloat64(intptr): float64;
|
||||
extern macro ChangeFloat32ToFloat64(float32): float64;
|
||||
extern macro ChangeNumberToFloat64(Number): float64;
|
||||
extern macro ChangeFloat64ToTagged(float64): Number;
|
||||
extern macro ChangeFloat64ToUintPtr(float64): uintptr;
|
||||
extern macro ChangeInt32ToIntPtr(int32): intptr; // Sign-extends.
|
||||
extern macro ChangeUint32ToWord(uint32): uintptr; // Doesn't sign-extend.
|
||||
|
@ -628,22 +628,8 @@ namespace internal {
|
||||
TFS(MapIteratorToList, kSource) \
|
||||
\
|
||||
/* Math */ \
|
||||
/* ES6 #sec-math.ceil */ \
|
||||
TFJ(MathCeil, 1, kReceiver, kX) \
|
||||
/* ES6 #sec-math.floor */ \
|
||||
TFJ(MathFloor, 1, kReceiver, kX) \
|
||||
/* ES6 #sec-math.max */ \
|
||||
TFJ(MathMax, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
|
||||
/* ES6 #sec-math.min */ \
|
||||
TFJ(MathMin, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
|
||||
/* ES6 #sec-math.pow */ \
|
||||
TFJ(MathPow, 2, kReceiver, kBase, kExponent) \
|
||||
/* ES6 #sec-math.random */ \
|
||||
TFJ(MathRandom, 0, kReceiver) \
|
||||
/* ES6 #sec-math.round */ \
|
||||
TFJ(MathRound, 1, kReceiver, kX) \
|
||||
/* ES6 #sec-math.trunc */ \
|
||||
TFJ(MathTrunc, 1, kReceiver, kX) \
|
||||
\
|
||||
/* Number */ \
|
||||
TFC(AllocateHeapNumber, AllocateHeapNumber) \
|
||||
|
@ -16,86 +16,6 @@ namespace internal {
|
||||
// -----------------------------------------------------------------------------
|
||||
// ES6 section 20.2.2 Function Properties of the Math Object
|
||||
|
||||
void MathBuiltinsAssembler::MathRoundingOperation(
|
||||
TNode<Context> context, TNode<Object> x,
|
||||
TNode<Float64T> (CodeStubAssembler::*float64op)(SloppyTNode<Float64T>)) {
|
||||
// We might need to loop once for ToNumber conversion.
|
||||
TVARIABLE(Object, var_x, x);
|
||||
Label loop(this, &var_x);
|
||||
Goto(&loop);
|
||||
BIND(&loop);
|
||||
{
|
||||
// Load the current {x} value.
|
||||
TNode<Object> x = var_x.value();
|
||||
|
||||
// Check if {x} is a Smi or a HeapObject.
|
||||
Label if_xissmi(this), if_xisnotsmi(this);
|
||||
Branch(TaggedIsSmi(x), &if_xissmi, &if_xisnotsmi);
|
||||
|
||||
BIND(&if_xissmi);
|
||||
{
|
||||
// Nothing to do when {x} is a Smi.
|
||||
Return(x);
|
||||
}
|
||||
|
||||
BIND(&if_xisnotsmi);
|
||||
{
|
||||
// Check if {x} is a HeapNumber.
|
||||
Label if_xisheapnumber(this), if_xisnotheapnumber(this, Label::kDeferred);
|
||||
TNode<HeapObject> x_heap_object = CAST(x);
|
||||
Branch(IsHeapNumber(x_heap_object), &if_xisheapnumber,
|
||||
&if_xisnotheapnumber);
|
||||
|
||||
BIND(&if_xisheapnumber);
|
||||
{
|
||||
TNode<Float64T> x_value = LoadHeapNumberValue(x_heap_object);
|
||||
TNode<Float64T> value = (this->*float64op)(x_value);
|
||||
TNode<Number> result = ChangeFloat64ToTagged(value);
|
||||
Return(result);
|
||||
}
|
||||
|
||||
BIND(&if_xisnotheapnumber);
|
||||
{
|
||||
// Need to convert {x} to a Number first.
|
||||
var_x = CallBuiltin(Builtins::kNonNumberToNumber, context, x);
|
||||
Goto(&loop);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MathBuiltinsAssembler::MathMaxMin(
|
||||
TNode<Context> context, TNode<Int32T> argc,
|
||||
TNode<Float64T> (CodeStubAssembler::*float64op)(SloppyTNode<Float64T>,
|
||||
SloppyTNode<Float64T>),
|
||||
double default_val) {
|
||||
CodeStubArguments arguments(this, argc);
|
||||
|
||||
TVARIABLE(Float64T, result, Float64Constant(default_val));
|
||||
|
||||
CodeStubAssembler::VariableList vars({&result}, zone());
|
||||
arguments.ForEach(vars, [&](TNode<Object> arg) {
|
||||
TNode<Float64T> float_value = TruncateTaggedToFloat64(context, arg);
|
||||
result = (this->*float64op)(result.value(), float_value);
|
||||
});
|
||||
|
||||
arguments.PopAndReturn(ChangeFloat64ToTagged(result.value()));
|
||||
}
|
||||
|
||||
// ES6 #sec-math.ceil
|
||||
TF_BUILTIN(MathCeil, MathBuiltinsAssembler) {
|
||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||
TNode<Object> x = CAST(Parameter(Descriptor::kX));
|
||||
MathRoundingOperation(context, x, &CodeStubAssembler::Float64Ceil);
|
||||
}
|
||||
|
||||
// ES6 #sec-math.floor
|
||||
TF_BUILTIN(MathFloor, MathBuiltinsAssembler) {
|
||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||
TNode<Object> x = CAST(Parameter(Descriptor::kX));
|
||||
MathRoundingOperation(context, x, &CodeStubAssembler::Float64Floor);
|
||||
}
|
||||
|
||||
TNode<Number> MathBuiltinsAssembler::MathPow(TNode<Context> context,
|
||||
TNode<Object> base,
|
||||
TNode<Object> exponent) {
|
||||
@ -105,14 +25,6 @@ TNode<Number> MathBuiltinsAssembler::MathPow(TNode<Context> context,
|
||||
return ChangeFloat64ToTagged(value);
|
||||
}
|
||||
|
||||
// ES6 #sec-math.pow
|
||||
TF_BUILTIN(MathPow, MathBuiltinsAssembler) {
|
||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||
TNode<Object> base = CAST(Parameter(Descriptor::kBase));
|
||||
TNode<Object> exponent = CAST(Parameter(Descriptor::kExponent));
|
||||
Return(MathPow(context, base, exponent));
|
||||
}
|
||||
|
||||
// ES6 #sec-math.random
|
||||
TF_BUILTIN(MathRandom, CodeStubAssembler) {
|
||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||
@ -154,35 +66,5 @@ TF_BUILTIN(MathRandom, CodeStubAssembler) {
|
||||
Return(AllocateHeapNumberWithValue(random));
|
||||
}
|
||||
|
||||
// ES6 #sec-math.round
|
||||
TF_BUILTIN(MathRound, MathBuiltinsAssembler) {
|
||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||
TNode<Object> x = CAST(Parameter(Descriptor::kX));
|
||||
MathRoundingOperation(context, x, &CodeStubAssembler::Float64Round);
|
||||
}
|
||||
|
||||
// ES6 #sec-math.trunc
|
||||
TF_BUILTIN(MathTrunc, MathBuiltinsAssembler) {
|
||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||
TNode<Object> x = CAST(Parameter(Descriptor::kX));
|
||||
MathRoundingOperation(context, x, &CodeStubAssembler::Float64Trunc);
|
||||
}
|
||||
|
||||
// ES6 #sec-math.max
|
||||
TF_BUILTIN(MathMax, MathBuiltinsAssembler) {
|
||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||
TNode<Int32T> argc =
|
||||
UncheckedCast<Int32T>(Parameter(Descriptor::kJSActualArgumentsCount));
|
||||
MathMaxMin(context, argc, &CodeStubAssembler::Float64Max, -1.0 * V8_INFINITY);
|
||||
}
|
||||
|
||||
// ES6 #sec-math.min
|
||||
TF_BUILTIN(MathMin, MathBuiltinsAssembler) {
|
||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||
TNode<Int32T> argc =
|
||||
UncheckedCast<Int32T>(Parameter(Descriptor::kJSActualArgumentsCount));
|
||||
MathMaxMin(context, argc, &CodeStubAssembler::Float64Min, V8_INFINITY);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
@ -17,15 +17,6 @@ class MathBuiltinsAssembler : public CodeStubAssembler {
|
||||
|
||||
TNode<Number> MathPow(TNode<Context> context, TNode<Object> base,
|
||||
TNode<Object> exponent);
|
||||
|
||||
protected:
|
||||
void MathRoundingOperation(
|
||||
TNode<Context> context, TNode<Object> x,
|
||||
TNode<Float64T> (CodeStubAssembler::*float64op)(SloppyTNode<Float64T>));
|
||||
void MathMaxMin(TNode<Context> context, TNode<Int32T> argc,
|
||||
TNode<Float64T> (CodeStubAssembler::*float64op)(
|
||||
SloppyTNode<Float64T>, SloppyTNode<Float64T>),
|
||||
double default_val);
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
@ -208,7 +208,7 @@ Convert<float32, Number>(n: Number): float32 {
|
||||
return Convert<float32>(ChangeNumberToFloat64(n));
|
||||
}
|
||||
Convert<Number, float64>(d: float64): Number {
|
||||
return AllocateHeapNumberWithValue(d);
|
||||
return ChangeFloat64ToTagged(d);
|
||||
}
|
||||
Convert<float64, uintptr>(ui: uintptr): float64 {
|
||||
return ChangeUintPtrToFloat64(ui);
|
||||
|
@ -64,6 +64,104 @@ namespace math {
|
||||
}
|
||||
}
|
||||
|
||||
// ES6 #sec-math.ceil
|
||||
extern macro Float64Ceil(float64): float64;
|
||||
transitioning javascript builtin
|
||||
MathCeil(js-implicit context: Context)(x: JSAny): Number {
|
||||
try {
|
||||
ReduceToSmiOrFloat64(x) otherwise SmiResult, Float64Result;
|
||||
}
|
||||
label SmiResult(s: Smi) {
|
||||
return s;
|
||||
}
|
||||
label Float64Result(f: float64) {
|
||||
return Convert<Number>(Float64Ceil(f));
|
||||
}
|
||||
}
|
||||
|
||||
// ES6 #sec-math.floor
|
||||
extern macro Float64Floor(float64): float64;
|
||||
transitioning javascript builtin
|
||||
MathFloor(js-implicit context: Context)(x: JSAny): Number {
|
||||
try {
|
||||
ReduceToSmiOrFloat64(x) otherwise SmiResult, Float64Result;
|
||||
}
|
||||
label SmiResult(s: Smi) {
|
||||
return s;
|
||||
}
|
||||
label Float64Result(f: float64) {
|
||||
return Convert<Number>(Float64Floor(f));
|
||||
}
|
||||
}
|
||||
|
||||
// ES6 #sec-math.round
|
||||
extern macro Float64Round(float64): float64;
|
||||
transitioning javascript builtin
|
||||
MathRound(js-implicit context: Context)(x: JSAny): Number {
|
||||
try {
|
||||
ReduceToSmiOrFloat64(x) otherwise SmiResult, Float64Result;
|
||||
}
|
||||
label SmiResult(s: Smi) {
|
||||
return s;
|
||||
}
|
||||
label Float64Result(f: float64) {
|
||||
return Convert<Number>(Float64Round(f));
|
||||
}
|
||||
}
|
||||
|
||||
// ES6 #sec-math.trunc
|
||||
extern macro Float64Trunc(float64): float64;
|
||||
transitioning javascript builtin
|
||||
MathTrunc(js-implicit context: Context)(x: JSAny): Number {
|
||||
try {
|
||||
ReduceToSmiOrFloat64(x) otherwise SmiResult, Float64Result;
|
||||
}
|
||||
label SmiResult(s: Smi) {
|
||||
return s;
|
||||
}
|
||||
label Float64Result(f: float64) {
|
||||
return Convert<Number>(Float64Trunc(f));
|
||||
}
|
||||
}
|
||||
|
||||
// ES6 #sec-math.pow
|
||||
extern macro TruncateTaggedToFloat64(implicit context: Context)(JSAny):
|
||||
float64;
|
||||
extern macro Float64Pow(float64, float64): float64;
|
||||
transitioning javascript builtin
|
||||
MathPow(js-implicit context: Context)(base: JSAny, exponent: JSAny): Number {
|
||||
const baseValue: float64 = TruncateTaggedToFloat64(base);
|
||||
const exponentValue: float64 = TruncateTaggedToFloat64(exponent);
|
||||
const result: float64 = Float64Pow(baseValue, exponentValue);
|
||||
return Convert<Number>(result);
|
||||
}
|
||||
|
||||
// ES6 #sec-math.max
|
||||
extern macro Float64Max(float64, float64): float64;
|
||||
transitioning javascript builtin
|
||||
MathMax(js-implicit context: Context)(...arguments): Number {
|
||||
let result: float64 = MINUS_V8_INFINITY;
|
||||
const argCount = arguments.length;
|
||||
for (let i: intptr = 0; i < argCount; i++) {
|
||||
const doubleValue = TruncateTaggedToFloat64(arguments[i]);
|
||||
result = Float64Max(result, doubleValue);
|
||||
}
|
||||
return Convert<Number>(result);
|
||||
}
|
||||
|
||||
// ES6 #sec-math.min
|
||||
extern macro Float64Min(float64, float64): float64;
|
||||
transitioning javascript builtin
|
||||
MathMin(js-implicit context: Context)(...arguments): Number {
|
||||
let result: float64 = V8_INFINITY;
|
||||
const argCount = arguments.length;
|
||||
for (let i: intptr = 0; i < argCount; i++) {
|
||||
const doubleValue = TruncateTaggedToFloat64(arguments[i]);
|
||||
result = Float64Min(result, doubleValue);
|
||||
}
|
||||
return Convert<Number>(result);
|
||||
}
|
||||
|
||||
// ES6 #sec-math.acos
|
||||
extern macro Float64Acos(float64): float64;
|
||||
|
||||
|
@ -19,8 +19,6 @@ namespace number {
|
||||
const kAsciiZero: constexpr int32 = 48; // '0' (ascii)
|
||||
const kAsciiLowerCaseA: constexpr int32 = 97; // 'a' (ascii)
|
||||
|
||||
const MINUS_V8_INFINITY: constexpr float64 generates '-V8_INFINITY';
|
||||
|
||||
transitioning macro ThisNumberValue(implicit context: Context)(
|
||||
receiver: JSAny, method: constexpr string): Number {
|
||||
return UnsafeCast<Number>(ToThisValue(receiver, kNumber, method));
|
||||
|
Loading…
Reference in New Issue
Block a user