| Index: src/builtins/builtins-math.cc
|
| diff --git a/src/builtins/builtins-math.cc b/src/builtins/builtins-math.cc
|
| index ee531e4299e9e489c2e2d2348c109a209fa2737a..373b7c2322dade9af40445b1a99fd28ccf293ee1 100644
|
| --- a/src/builtins/builtins-math.cc
|
| +++ b/src/builtins/builtins-math.cc
|
| @@ -15,99 +15,94 @@ namespace internal {
|
|
|
| // ES6 section - 20.2.2.1 Math.abs ( x )
|
| void Builtins::Generate_MathAbs(CodeStubAssembler* assembler) {
|
| - using compiler::Node;
|
| - Node* x = assembler->Parameter(1);
|
| - Node* context = assembler->Parameter(4);
|
| - Node* x_value = assembler->TruncateTaggedToFloat64(context, x);
|
| - Node* value = assembler->Float64Abs(x_value);
|
| - Node* result = assembler->ChangeFloat64ToTagged(value);
|
| - assembler->Return(result);
|
| -}
|
| -
|
| -// ES6 section 20.2.2.2 Math.acos ( x )
|
| -void Builtins::Generate_MathAcos(CodeStubAssembler* assembler) {
|
| - using compiler::Node;
|
| -
|
| - Node* x = assembler->Parameter(1);
|
| - Node* context = assembler->Parameter(4);
|
| - Node* x_value = assembler->TruncateTaggedToFloat64(context, x);
|
| - Node* value = assembler->Float64Acos(x_value);
|
| - Node* result = assembler->ChangeFloat64ToTagged(value);
|
| - assembler->Return(result);
|
| -}
|
| -
|
| -// ES6 section 20.2.2.3 Math.acosh ( x )
|
| -void Builtins::Generate_MathAcosh(CodeStubAssembler* assembler) {
|
| - using compiler::Node;
|
| -
|
| - Node* x = assembler->Parameter(1);
|
| - Node* context = assembler->Parameter(4);
|
| - Node* x_value = assembler->TruncateTaggedToFloat64(context, x);
|
| - Node* value = assembler->Float64Acosh(x_value);
|
| - Node* result = assembler->ChangeFloat64ToTagged(value);
|
| - assembler->Return(result);
|
| -}
|
| -
|
| -// ES6 section 20.2.2.4 Math.asin ( x )
|
| -void Builtins::Generate_MathAsin(CodeStubAssembler* assembler) {
|
| - using compiler::Node;
|
| + typedef CodeStubAssembler::Label Label;
|
| + typedef compiler::Node Node;
|
| + typedef CodeStubAssembler::Variable Variable;
|
|
|
| - Node* x = assembler->Parameter(1);
|
| Node* context = assembler->Parameter(4);
|
| - Node* x_value = assembler->TruncateTaggedToFloat64(context, x);
|
| - Node* value = assembler->Float64Asin(x_value);
|
| - Node* result = assembler->ChangeFloat64ToTagged(value);
|
| - assembler->Return(result);
|
| -}
|
|
|
| -// ES6 section 20.2.2.5 Math.asinh ( x )
|
| -void Builtins::Generate_MathAsinh(CodeStubAssembler* assembler) {
|
| - using compiler::Node;
|
| + // We might need to loop once for ToNumber conversion.
|
| + Variable var_x(assembler, MachineRepresentation::kTagged);
|
| + Label loop(assembler, &var_x);
|
| + var_x.Bind(assembler->Parameter(1));
|
| + assembler->Goto(&loop);
|
| + assembler->Bind(&loop);
|
| + {
|
| + // Load the current {x} value.
|
| + Node* x = var_x.value();
|
|
|
| - Node* x = assembler->Parameter(1);
|
| - Node* context = assembler->Parameter(4);
|
| - Node* x_value = assembler->TruncateTaggedToFloat64(context, x);
|
| - Node* value = assembler->Float64Asinh(x_value);
|
| - Node* result = assembler->ChangeFloat64ToTagged(value);
|
| - assembler->Return(result);
|
| -}
|
| + // Check if {x} is a Smi or a HeapObject.
|
| + Label if_xissmi(assembler), if_xisnotsmi(assembler);
|
| + assembler->Branch(assembler->TaggedIsSmi(x), &if_xissmi, &if_xisnotsmi);
|
|
|
| -// ES6 section 20.2.2.6 Math.atan ( x )
|
| -void Builtins::Generate_MathAtan(CodeStubAssembler* assembler) {
|
| - using compiler::Node;
|
| + assembler->Bind(&if_xissmi);
|
| + {
|
| + // Check if {x} is already positive.
|
| + Label if_xispositive(assembler), if_xisnotpositive(assembler);
|
| + assembler->BranchIfSmiLessThanOrEqual(
|
| + assembler->SmiConstant(Smi::FromInt(0)), x, &if_xispositive,
|
| + &if_xisnotpositive);
|
|
|
| - Node* x = assembler->Parameter(1);
|
| - Node* context = assembler->Parameter(4);
|
| - Node* x_value = assembler->TruncateTaggedToFloat64(context, x);
|
| - Node* value = assembler->Float64Atan(x_value);
|
| - Node* result = assembler->ChangeFloat64ToTagged(value);
|
| - assembler->Return(result);
|
| -}
|
| + assembler->Bind(&if_xispositive);
|
| + {
|
| + // Just return the input {x}.
|
| + assembler->Return(x);
|
| + }
|
|
|
| -// ES6 section 20.2.2.7 Math.atanh ( x )
|
| -void Builtins::Generate_MathAtanh(CodeStubAssembler* assembler) {
|
| - using compiler::Node;
|
| + assembler->Bind(&if_xisnotpositive);
|
| + {
|
| + // Try to negate the {x} value.
|
| + Node* pair = assembler->IntPtrSubWithOverflow(
|
| + assembler->IntPtrConstant(0), assembler->BitcastTaggedToWord(x));
|
| + Node* overflow = assembler->Projection(1, pair);
|
| + Label if_overflow(assembler, Label::kDeferred),
|
| + if_notoverflow(assembler);
|
| + assembler->Branch(overflow, &if_overflow, &if_notoverflow);
|
| +
|
| + assembler->Bind(&if_notoverflow);
|
| + {
|
| + // There is a Smi representation for negated {x}.
|
| + Node* result = assembler->Projection(0, pair);
|
| + result = assembler->BitcastWordToTagged(result);
|
| + assembler->Return(result);
|
| + }
|
| +
|
| + assembler->Bind(&if_overflow);
|
| + {
|
| + Node* result = assembler->NumberConstant(0.0 - Smi::kMinValue);
|
| + assembler->Return(result);
|
| + }
|
| + }
|
| + }
|
|
|
| - Node* x = assembler->Parameter(1);
|
| - Node* context = assembler->Parameter(4);
|
| - Node* x_value = assembler->TruncateTaggedToFloat64(context, x);
|
| - Node* value = assembler->Float64Atanh(x_value);
|
| - Node* result = assembler->ChangeFloat64ToTagged(value);
|
| - assembler->Return(result);
|
| -}
|
| + assembler->Bind(&if_xisnotsmi);
|
| + {
|
| + // Check if {x} is a HeapNumber.
|
| + Label if_xisheapnumber(assembler),
|
| + if_xisnotheapnumber(assembler, Label::kDeferred);
|
| + assembler->Branch(
|
| + assembler->WordEqual(assembler->LoadMap(x),
|
| + assembler->HeapNumberMapConstant()),
|
| + &if_xisheapnumber, &if_xisnotheapnumber);
|
|
|
| -// ES6 section 20.2.2.8 Math.atan2 ( y, x )
|
| -void Builtins::Generate_MathAtan2(CodeStubAssembler* assembler) {
|
| - using compiler::Node;
|
| + assembler->Bind(&if_xisheapnumber);
|
| + {
|
| + Node* x_value = assembler->LoadHeapNumberValue(x);
|
| + Node* value = assembler->Float64Abs(x_value);
|
| + Node* result = assembler->AllocateHeapNumberWithValue(value);
|
| + assembler->Return(result);
|
| + }
|
|
|
| - Node* y = assembler->Parameter(1);
|
| - Node* x = assembler->Parameter(2);
|
| - Node* context = assembler->Parameter(5);
|
| - Node* y_value = assembler->TruncateTaggedToFloat64(context, y);
|
| - Node* x_value = assembler->TruncateTaggedToFloat64(context, x);
|
| - Node* value = assembler->Float64Atan2(y_value, x_value);
|
| - Node* result = assembler->ChangeFloat64ToTagged(value);
|
| - assembler->Return(result);
|
| + assembler->Bind(&if_xisnotheapnumber);
|
| + {
|
| + // Need to convert {x} to a Number first.
|
| + Callable callable =
|
| + CodeFactory::NonNumberToNumber(assembler->isolate());
|
| + var_x.Bind(assembler->CallStub(callable, context, x));
|
| + assembler->Goto(&loop);
|
| + }
|
| + }
|
| + }
|
| }
|
|
|
| namespace {
|
| @@ -171,8 +166,65 @@ void Generate_MathRoundingOperation(
|
| }
|
| }
|
|
|
| +void Generate_MathUnaryOperation(
|
| + CodeStubAssembler* assembler,
|
| + compiler::Node* (CodeStubAssembler::*float64op)(compiler::Node*)) {
|
| + typedef compiler::Node Node;
|
| +
|
| + Node* x = assembler->Parameter(1);
|
| + Node* context = assembler->Parameter(4);
|
| + Node* x_value = assembler->TruncateTaggedToFloat64(context, x);
|
| + Node* value = (assembler->*float64op)(x_value);
|
| + Node* result = assembler->AllocateHeapNumberWithValue(value);
|
| + assembler->Return(result);
|
| +}
|
| +
|
| } // namespace
|
|
|
| +// ES6 section 20.2.2.2 Math.acos ( x )
|
| +void Builtins::Generate_MathAcos(CodeStubAssembler* assembler) {
|
| + Generate_MathUnaryOperation(assembler, &CodeStubAssembler::Float64Acos);
|
| +}
|
| +
|
| +// ES6 section 20.2.2.3 Math.acosh ( x )
|
| +void Builtins::Generate_MathAcosh(CodeStubAssembler* assembler) {
|
| + Generate_MathUnaryOperation(assembler, &CodeStubAssembler::Float64Acosh);
|
| +}
|
| +
|
| +// ES6 section 20.2.2.4 Math.asin ( x )
|
| +void Builtins::Generate_MathAsin(CodeStubAssembler* assembler) {
|
| + Generate_MathUnaryOperation(assembler, &CodeStubAssembler::Float64Asin);
|
| +}
|
| +
|
| +// ES6 section 20.2.2.5 Math.asinh ( x )
|
| +void Builtins::Generate_MathAsinh(CodeStubAssembler* assembler) {
|
| + Generate_MathUnaryOperation(assembler, &CodeStubAssembler::Float64Asinh);
|
| +}
|
| +
|
| +// ES6 section 20.2.2.6 Math.atan ( x )
|
| +void Builtins::Generate_MathAtan(CodeStubAssembler* assembler) {
|
| + Generate_MathUnaryOperation(assembler, &CodeStubAssembler::Float64Atan);
|
| +}
|
| +
|
| +// ES6 section 20.2.2.7 Math.atanh ( x )
|
| +void Builtins::Generate_MathAtanh(CodeStubAssembler* assembler) {
|
| + Generate_MathUnaryOperation(assembler, &CodeStubAssembler::Float64Atanh);
|
| +}
|
| +
|
| +// ES6 section 20.2.2.8 Math.atan2 ( y, x )
|
| +void Builtins::Generate_MathAtan2(CodeStubAssembler* assembler) {
|
| + using compiler::Node;
|
| +
|
| + Node* y = assembler->Parameter(1);
|
| + Node* x = assembler->Parameter(2);
|
| + Node* context = assembler->Parameter(5);
|
| + Node* y_value = assembler->TruncateTaggedToFloat64(context, y);
|
| + Node* x_value = assembler->TruncateTaggedToFloat64(context, x);
|
| + Node* value = assembler->Float64Atan2(y_value, x_value);
|
| + Node* result = assembler->AllocateHeapNumberWithValue(value);
|
| + assembler->Return(result);
|
| +}
|
| +
|
| // ES6 section 20.2.2.10 Math.ceil ( x )
|
| void Builtins::Generate_MathCeil(CodeStubAssembler* assembler) {
|
| Generate_MathRoundingOperation(assembler, &CodeStubAssembler::Float64Ceil);
|
| @@ -180,14 +232,7 @@ void Builtins::Generate_MathCeil(CodeStubAssembler* assembler) {
|
|
|
| // ES6 section 20.2.2.9 Math.cbrt ( x )
|
| void Builtins::Generate_MathCbrt(CodeStubAssembler* assembler) {
|
| - using compiler::Node;
|
| -
|
| - Node* x = assembler->Parameter(1);
|
| - Node* context = assembler->Parameter(4);
|
| - Node* x_value = assembler->TruncateTaggedToFloat64(context, x);
|
| - Node* value = assembler->Float64Cbrt(x_value);
|
| - Node* result = assembler->ChangeFloat64ToTagged(value);
|
| - assembler->Return(result);
|
| + Generate_MathUnaryOperation(assembler, &CodeStubAssembler::Float64Cbrt);
|
| }
|
|
|
| // ES6 section 20.2.2.11 Math.clz32 ( x )
|
| @@ -260,38 +305,22 @@ void Builtins::Generate_MathClz32(CodeStubAssembler* assembler) {
|
|
|
| // ES6 section 20.2.2.12 Math.cos ( x )
|
| void Builtins::Generate_MathCos(CodeStubAssembler* assembler) {
|
| - using compiler::Node;
|
| -
|
| - Node* x = assembler->Parameter(1);
|
| - Node* context = assembler->Parameter(4);
|
| - Node* x_value = assembler->TruncateTaggedToFloat64(context, x);
|
| - Node* value = assembler->Float64Cos(x_value);
|
| - Node* result = assembler->ChangeFloat64ToTagged(value);
|
| - assembler->Return(result);
|
| + Generate_MathUnaryOperation(assembler, &CodeStubAssembler::Float64Cos);
|
| }
|
|
|
| // ES6 section 20.2.2.13 Math.cosh ( x )
|
| void Builtins::Generate_MathCosh(CodeStubAssembler* assembler) {
|
| - using compiler::Node;
|
| -
|
| - Node* x = assembler->Parameter(1);
|
| - Node* context = assembler->Parameter(4);
|
| - Node* x_value = assembler->TruncateTaggedToFloat64(context, x);
|
| - Node* value = assembler->Float64Cosh(x_value);
|
| - Node* result = assembler->ChangeFloat64ToTagged(value);
|
| - assembler->Return(result);
|
| + Generate_MathUnaryOperation(assembler, &CodeStubAssembler::Float64Cosh);
|
| }
|
|
|
| // ES6 section 20.2.2.14 Math.exp ( x )
|
| void Builtins::Generate_MathExp(CodeStubAssembler* assembler) {
|
| - using compiler::Node;
|
| + Generate_MathUnaryOperation(assembler, &CodeStubAssembler::Float64Exp);
|
| +}
|
|
|
| - Node* x = assembler->Parameter(1);
|
| - Node* context = assembler->Parameter(4);
|
| - Node* x_value = assembler->TruncateTaggedToFloat64(context, x);
|
| - Node* value = assembler->Float64Exp(x_value);
|
| - Node* result = assembler->ChangeFloat64ToTagged(value);
|
| - assembler->Return(result);
|
| +// ES6 section 20.2.2.15 Math.expm1 ( x )
|
| +void Builtins::Generate_MathExpm1(CodeStubAssembler* assembler) {
|
| + Generate_MathUnaryOperation(assembler, &CodeStubAssembler::Float64Expm1);
|
| }
|
|
|
| // ES6 section 20.2.2.16 Math.floor ( x )
|
| @@ -308,7 +337,7 @@ void Builtins::Generate_MathFround(CodeStubAssembler* assembler) {
|
| Node* x_value = assembler->TruncateTaggedToFloat64(context, x);
|
| Node* value32 = assembler->TruncateFloat64ToFloat32(x_value);
|
| Node* value = assembler->ChangeFloat32ToFloat64(value32);
|
| - Node* result = assembler->ChangeFloat64ToTagged(value);
|
| + Node* result = assembler->AllocateHeapNumberWithValue(value);
|
| assembler->Return(result);
|
| }
|
|
|
| @@ -380,62 +409,22 @@ void Builtins::Generate_MathImul(CodeStubAssembler* assembler) {
|
|
|
| // ES6 section 20.2.2.20 Math.log ( x )
|
| void Builtins::Generate_MathLog(CodeStubAssembler* assembler) {
|
| - using compiler::Node;
|
| -
|
| - Node* x = assembler->Parameter(1);
|
| - Node* context = assembler->Parameter(4);
|
| - Node* x_value = assembler->TruncateTaggedToFloat64(context, x);
|
| - Node* value = assembler->Float64Log(x_value);
|
| - Node* result = assembler->ChangeFloat64ToTagged(value);
|
| - assembler->Return(result);
|
| + Generate_MathUnaryOperation(assembler, &CodeStubAssembler::Float64Log);
|
| }
|
|
|
| // ES6 section 20.2.2.21 Math.log1p ( x )
|
| void Builtins::Generate_MathLog1p(CodeStubAssembler* assembler) {
|
| - using compiler::Node;
|
| -
|
| - Node* x = assembler->Parameter(1);
|
| - Node* context = assembler->Parameter(4);
|
| - Node* x_value = assembler->TruncateTaggedToFloat64(context, x);
|
| - Node* value = assembler->Float64Log1p(x_value);
|
| - Node* result = assembler->ChangeFloat64ToTagged(value);
|
| - assembler->Return(result);
|
| + Generate_MathUnaryOperation(assembler, &CodeStubAssembler::Float64Log1p);
|
| }
|
|
|
| // ES6 section 20.2.2.22 Math.log10 ( x )
|
| void Builtins::Generate_MathLog10(CodeStubAssembler* assembler) {
|
| - using compiler::Node;
|
| -
|
| - Node* x = assembler->Parameter(1);
|
| - Node* context = assembler->Parameter(4);
|
| - Node* x_value = assembler->TruncateTaggedToFloat64(context, x);
|
| - Node* value = assembler->Float64Log10(x_value);
|
| - Node* result = assembler->ChangeFloat64ToTagged(value);
|
| - assembler->Return(result);
|
| + Generate_MathUnaryOperation(assembler, &CodeStubAssembler::Float64Log10);
|
| }
|
|
|
| // ES6 section 20.2.2.23 Math.log2 ( x )
|
| void Builtins::Generate_MathLog2(CodeStubAssembler* assembler) {
|
| - using compiler::Node;
|
| -
|
| - Node* x = assembler->Parameter(1);
|
| - Node* context = assembler->Parameter(4);
|
| - Node* x_value = assembler->TruncateTaggedToFloat64(context, x);
|
| - Node* value = assembler->Float64Log2(x_value);
|
| - Node* result = assembler->ChangeFloat64ToTagged(value);
|
| - assembler->Return(result);
|
| -}
|
| -
|
| -// ES6 section 20.2.2.15 Math.expm1 ( x )
|
| -void Builtins::Generate_MathExpm1(CodeStubAssembler* assembler) {
|
| - using compiler::Node;
|
| -
|
| - Node* x = assembler->Parameter(1);
|
| - Node* context = assembler->Parameter(4);
|
| - Node* x_value = assembler->TruncateTaggedToFloat64(context, x);
|
| - Node* value = assembler->Float64Expm1(x_value);
|
| - Node* result = assembler->ChangeFloat64ToTagged(value);
|
| - assembler->Return(result);
|
| + Generate_MathUnaryOperation(assembler, &CodeStubAssembler::Float64Log2);
|
| }
|
|
|
| // ES6 section 20.2.2.26 Math.pow ( x, y )
|
| @@ -489,7 +478,7 @@ void Builtins::Generate_MathRandom(CodeStubAssembler* assembler) {
|
| Node* random = assembler->LoadFixedDoubleArrayElement(
|
| array, new_smi_index, MachineType::Float64(), 0,
|
| CodeStubAssembler::SMI_PARAMETERS);
|
| - assembler->Return(assembler->ChangeFloat64ToTagged(random));
|
| + assembler->Return(assembler->AllocateHeapNumberWithValue(random));
|
| }
|
|
|
| // ES6 section 20.2.2.28 Math.round ( x )
|
| @@ -526,62 +515,27 @@ void Builtins::Generate_MathSign(CodeStubAssembler* assembler) {
|
|
|
| // ES6 section 20.2.2.30 Math.sin ( x )
|
| void Builtins::Generate_MathSin(CodeStubAssembler* assembler) {
|
| - using compiler::Node;
|
| -
|
| - Node* x = assembler->Parameter(1);
|
| - Node* context = assembler->Parameter(4);
|
| - Node* x_value = assembler->TruncateTaggedToFloat64(context, x);
|
| - Node* value = assembler->Float64Sin(x_value);
|
| - Node* result = assembler->ChangeFloat64ToTagged(value);
|
| - assembler->Return(result);
|
| + Generate_MathUnaryOperation(assembler, &CodeStubAssembler::Float64Sin);
|
| }
|
|
|
| // ES6 section 20.2.2.31 Math.sinh ( x )
|
| void Builtins::Generate_MathSinh(CodeStubAssembler* assembler) {
|
| - using compiler::Node;
|
| -
|
| - Node* x = assembler->Parameter(1);
|
| - Node* context = assembler->Parameter(4);
|
| - Node* x_value = assembler->TruncateTaggedToFloat64(context, x);
|
| - Node* value = assembler->Float64Sinh(x_value);
|
| - Node* result = assembler->ChangeFloat64ToTagged(value);
|
| - assembler->Return(result);
|
| + Generate_MathUnaryOperation(assembler, &CodeStubAssembler::Float64Sinh);
|
| }
|
|
|
| // ES6 section 20.2.2.32 Math.sqrt ( x )
|
| void Builtins::Generate_MathSqrt(CodeStubAssembler* assembler) {
|
| - using compiler::Node;
|
| -
|
| - Node* x = assembler->Parameter(1);
|
| - Node* context = assembler->Parameter(4);
|
| - Node* x_value = assembler->TruncateTaggedToFloat64(context, x);
|
| - Node* value = assembler->Float64Sqrt(x_value);
|
| - Node* result = assembler->ChangeFloat64ToTagged(value);
|
| - assembler->Return(result);
|
| + Generate_MathUnaryOperation(assembler, &CodeStubAssembler::Float64Sqrt);
|
| }
|
|
|
| // ES6 section 20.2.2.33 Math.tan ( x )
|
| void Builtins::Generate_MathTan(CodeStubAssembler* assembler) {
|
| - using compiler::Node;
|
| -
|
| - Node* x = assembler->Parameter(1);
|
| - Node* context = assembler->Parameter(4);
|
| - Node* x_value = assembler->TruncateTaggedToFloat64(context, x);
|
| - Node* value = assembler->Float64Tan(x_value);
|
| - Node* result = assembler->ChangeFloat64ToTagged(value);
|
| - assembler->Return(result);
|
| + Generate_MathUnaryOperation(assembler, &CodeStubAssembler::Float64Tan);
|
| }
|
|
|
| // ES6 section 20.2.2.34 Math.tanh ( x )
|
| void Builtins::Generate_MathTanh(CodeStubAssembler* assembler) {
|
| - using compiler::Node;
|
| -
|
| - Node* x = assembler->Parameter(1);
|
| - Node* context = assembler->Parameter(4);
|
| - Node* x_value = assembler->TruncateTaggedToFloat64(context, x);
|
| - Node* value = assembler->Float64Tanh(x_value);
|
| - Node* result = assembler->ChangeFloat64ToTagged(value);
|
| - assembler->Return(result);
|
| + Generate_MathUnaryOperation(assembler, &CodeStubAssembler::Float64Tanh);
|
| }
|
|
|
| // ES6 section 20.2.2.35 Math.trunc ( x )
|
|
|