Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(92)

Unified Diff: src/builtins.cc

Issue 2116753002: [builtins] Unify most of the remaining Math builtins. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@2102223005
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/builtins.cc
diff --git a/src/builtins.cc b/src/builtins.cc
index ebb17106df6d9b6bd944d06743e35684827f48b7..527b4e950c26cd4c457a95aa8a7bf86f2159609b 100644
--- a/src/builtins.cc
+++ b/src/builtins.cc
@@ -2252,97 +2252,61 @@ void Builtins::Generate_MathAbs(CodeStubAssembler* assembler) {
}
// ES6 section 20.2.2.2 Math.acos ( x )
-BUILTIN(MathAcos) {
- HandleScope scope(isolate);
- DCHECK_EQ(2, args.length());
- Handle<Object> x = args.at<Object>(1);
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, x, Object::ToNumber(x));
- return *isolate->factory()->NewHeapNumber(std::acos(x->Number()));
-}
+void Builtins::Generate_MathAcos(CodeStubAssembler* assembler) {
+ using compiler::Node;
-// ES6 section 20.2.2.4 Math.asin ( x )
-BUILTIN(MathAsin) {
- HandleScope scope(isolate);
- DCHECK_EQ(2, args.length());
- Handle<Object> x = args.at<Object>(1);
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, x, Object::ToNumber(x));
- return *isolate->factory()->NewHeapNumber(std::asin(x->Number()));
+ 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.18 Math.hypot ( value1, value2, ...values )
-BUILTIN(MathHypot) {
- HandleScope scope(isolate);
- int const length = args.length() - 1;
- if (length == 0) return Smi::FromInt(0);
- DCHECK_LT(0, length);
- double max = 0;
- bool one_arg_is_nan = false;
- List<double> abs_values(length);
- for (int i = 0; i < length; i++) {
- Handle<Object> x = args.at<Object>(i + 1);
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, x, Object::ToNumber(x));
- double abs_value = std::abs(x->Number());
-
- if (std::isnan(abs_value)) {
- one_arg_is_nan = true;
- } else {
- abs_values.Add(abs_value);
- if (max < abs_value) {
- max = abs_value;
- }
- }
- }
-
- if (max == V8_INFINITY) {
- return *isolate->factory()->NewNumber(V8_INFINITY);
- }
-
- if (one_arg_is_nan) {
- return *isolate->factory()->nan_value();
- }
+// ES6 section 20.2.2.3 Math.acosh ( x )
+void Builtins::Generate_MathAcosh(CodeStubAssembler* assembler) {
+ using compiler::Node;
- if (max == 0) {
- return Smi::FromInt(0);
- }
- DCHECK_GT(max, 0);
+ 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);
+}
- // Kahan summation to avoid rounding errors.
- // Normalize the numbers to the largest one to avoid overflow.
- double sum = 0;
- double compensation = 0;
- for (int i = 0; i < length; i++) {
- double n = abs_values.at(i) / max;
- double summand = n * n - compensation;
- double preliminary = sum + summand;
- compensation = (preliminary - sum) - summand;
- sum = preliminary;
- }
+// ES6 section 20.2.2.4 Math.asin ( x )
+void Builtins::Generate_MathAsin(CodeStubAssembler* assembler) {
+ using compiler::Node;
- return *isolate->factory()->NewNumber(std::sqrt(sum) * max);
+ 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.6 Math.atan ( x )
-void Builtins::Generate_MathAtan(CodeStubAssembler* assembler) {
+// ES6 section 20.2.2.5 Math.asinh ( x )
+void Builtins::Generate_MathAsinh(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->Float64Atan(x_value);
+ Node* value = assembler->Float64Asinh(x_value);
Node* result = assembler->ChangeFloat64ToTagged(value);
assembler->Return(result);
}
-// ES6 section 20.2.2.8 Math.atan2 ( y, x )
-void Builtins::Generate_MathAtan2(CodeStubAssembler* assembler) {
+// ES6 section 20.2.2.6 Math.atan ( x )
+void Builtins::Generate_MathAtan(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 = assembler->Parameter(1);
+ Node* context = assembler->Parameter(4);
Node* x_value = assembler->TruncateTaggedToFloat64(context, x);
- Node* value = assembler->Float64Atan2(y_value, x_value);
+ Node* value = assembler->Float64Atan(x_value);
Node* result = assembler->ChangeFloat64ToTagged(value);
assembler->Return(result);
}
@@ -2359,6 +2323,20 @@ void Builtins::Generate_MathAtanh(CodeStubAssembler* assembler) {
assembler->Return(result);
}
+// 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->ChangeFloat64ToTagged(value);
+ assembler->Return(result);
+}
+
namespace {
void Generate_MathRoundingOperation(
@@ -2549,25 +2527,82 @@ void Builtins::Generate_MathFloor(CodeStubAssembler* assembler) {
}
// ES6 section 20.2.2.17 Math.fround ( x )
-BUILTIN(MathFround) {
+void Builtins::Generate_MathFround(CodeStubAssembler* assembler) {
+ using compiler::Node;
+
+ Node* x = assembler->Parameter(1);
+ Node* context = assembler->Parameter(4);
+ Node* x_value = assembler->TruncateTaggedToFloat64(context, x);
+ Node* value32 = assembler->TruncateFloat64ToFloat32(x_value);
+ Node* value = assembler->ChangeFloat32ToFloat64(value32);
+ Node* result = assembler->ChangeFloat64ToTagged(value);
+ assembler->Return(result);
+}
+
+// ES6 section 20.2.2.18 Math.hypot ( value1, value2, ...values )
+BUILTIN(MathHypot) {
HandleScope scope(isolate);
- DCHECK_EQ(2, args.length());
- Handle<Object> x = args.at<Object>(1);
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, x, Object::ToNumber(x));
- float x32 = DoubleToFloat32(x->Number());
- return *isolate->factory()->NewNumber(x32);
+ int const length = args.length() - 1;
+ if (length == 0) return Smi::FromInt(0);
+ DCHECK_LT(0, length);
+ double max = 0;
+ bool one_arg_is_nan = false;
+ List<double> abs_values(length);
+ for (int i = 0; i < length; i++) {
+ Handle<Object> x = args.at<Object>(i + 1);
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, x, Object::ToNumber(x));
+ double abs_value = std::abs(x->Number());
+
+ if (std::isnan(abs_value)) {
+ one_arg_is_nan = true;
+ } else {
+ abs_values.Add(abs_value);
+ if (max < abs_value) {
+ max = abs_value;
+ }
+ }
+ }
+
+ if (max == V8_INFINITY) {
+ return *isolate->factory()->NewNumber(V8_INFINITY);
+ }
+
+ if (one_arg_is_nan) {
+ return *isolate->factory()->nan_value();
+ }
+
+ if (max == 0) {
+ return Smi::FromInt(0);
+ }
+ DCHECK_GT(max, 0);
+
+ // Kahan summation to avoid rounding errors.
+ // Normalize the numbers to the largest one to avoid overflow.
+ double sum = 0;
+ double compensation = 0;
+ for (int i = 0; i < length; i++) {
+ double n = abs_values.at(i) / max;
+ double summand = n * n - compensation;
+ double preliminary = sum + summand;
+ compensation = (preliminary - sum) - summand;
+ sum = preliminary;
+ }
+
+ return *isolate->factory()->NewNumber(std::sqrt(sum) * max);
}
// ES6 section 20.2.2.19 Math.imul ( x, y )
-BUILTIN(MathImul) {
- HandleScope scope(isolate);
- DCHECK_EQ(3, args.length());
- Handle<Object> x = args.at<Object>(1);
- Handle<Object> y = args.at<Object>(2);
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, x, Object::ToNumber(x));
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, y, Object::ToNumber(y));
- int product = static_cast<int>(NumberToUint32(*x) * NumberToUint32(*y));
- return *isolate->factory()->NewNumberFromInt(product);
+void Builtins::Generate_MathImul(CodeStubAssembler* assembler) {
+ using compiler::Node;
+
+ Node* x = assembler->Parameter(1);
+ Node* y = assembler->Parameter(2);
+ Node* context = assembler->Parameter(5);
+ Node* x_value = assembler->TruncateTaggedToWord32(context, x);
+ Node* y_value = assembler->TruncateTaggedToWord32(context, y);
+ Node* value = assembler->Int32Mul(x_value, y_value);
+ Node* result = assembler->ChangeInt32ToTagged(value);
+ assembler->Return(result);
}
// ES6 section 20.2.2.20 Math.log ( x )
@@ -2594,26 +2629,26 @@ void Builtins::Generate_MathLog1p(CodeStubAssembler* assembler) {
assembler->Return(result);
}
-// ES6 section 20.2.2.23 Math.log2 ( x )
-void Builtins::Generate_MathLog2(CodeStubAssembler* assembler) {
+// 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->Float64Log2(x_value);
+ Node* value = assembler->Float64Log10(x_value);
Node* result = assembler->ChangeFloat64ToTagged(value);
assembler->Return(result);
}
-// ES6 section 20.2.2.22 Math.log10 ( x )
-void Builtins::Generate_MathLog10(CodeStubAssembler* assembler) {
+// 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->Float64Log10(x_value);
+ Node* value = assembler->Float64Log2(x_value);
Node* result = assembler->ChangeFloat64ToTagged(value);
assembler->Return(result);
}
@@ -2630,11 +2665,6 @@ void Builtins::Generate_MathExpm1(CodeStubAssembler* assembler) {
assembler->Return(result);
}
-// ES6 section 20.2.2.28 Math.round ( x )
-void Builtins::Generate_MathRound(CodeStubAssembler* assembler) {
- Generate_MathRoundingOperation(assembler, &CodeStubAssembler::Float64Round);
-}
-
// ES6 section 20.2.2.26 Math.pow ( x, y )
void Builtins::Generate_MathPow(CodeStubAssembler* assembler) {
using compiler::Node;
@@ -2649,6 +2679,38 @@ void Builtins::Generate_MathPow(CodeStubAssembler* assembler) {
assembler->Return(result);
}
+// ES6 section 20.2.2.28 Math.round ( x )
+void Builtins::Generate_MathRound(CodeStubAssembler* assembler) {
+ Generate_MathRoundingOperation(assembler, &CodeStubAssembler::Float64Round);
+}
+
+// ES6 section 20.2.2.29 Math.sign ( x )
+void Builtins::Generate_MathSign(CodeStubAssembler* assembler) {
+ typedef CodeStubAssembler::Label Label;
+ using compiler::Node;
+
+ // Convert the {x} value to a Number.
+ Node* x = assembler->Parameter(1);
+ Node* context = assembler->Parameter(4);
+ Node* x_value = assembler->TruncateTaggedToFloat64(context, x);
+
+ // Return -1 if {x} is negative, 1 if {x} is positive, or {x} itself.
+ Label if_xisnegative(assembler), if_xispositive(assembler);
+ assembler->GotoIf(
+ assembler->Float64LessThan(x_value, assembler->Float64Constant(0.0)),
+ &if_xisnegative);
+ assembler->GotoIf(
+ assembler->Float64LessThan(assembler->Float64Constant(0.0), x_value),
+ &if_xispositive);
+ assembler->Return(assembler->ChangeFloat64ToTagged(x_value));
Franzi 2016/07/01 09:09:48 Can we return x instead of converting the float ba
Benedikt Meurer 2016/07/01 10:48:33 No we can't because x can be anything, not even a
+
+ assembler->Bind(&if_xisnegative);
+ assembler->Return(assembler->SmiConstant(Smi::FromInt(-1)));
+
+ assembler->Bind(&if_xispositive);
+ assembler->Return(assembler->SmiConstant(Smi::FromInt(1)));
+}
+
// ES6 section 20.2.2.30 Math.sin ( x )
void Builtins::Generate_MathSin(CodeStubAssembler* assembler) {
using compiler::Node;

Powered by Google App Engine
This is Rietveld 408576698