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

Unified Diff: src/builtins/builtins-math.cc

Issue 2165593002: [builtins] Move builtins into own files (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Remove builtins-error.cc from BUILD.gn Created 4 years, 5 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
« no previous file with comments | « src/builtins/builtins-json.cc ('k') | src/builtins/builtins-number.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/builtins/builtins-math.cc
diff --git a/src/builtins/builtins-math.cc b/src/builtins/builtins-math.cc
new file mode 100644
index 0000000000000000000000000000000000000000..e8d429ebac92d969e09d5fc6b7dbeee056627e2b
--- /dev/null
+++ b/src/builtins/builtins-math.cc
@@ -0,0 +1,561 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/builtins/builtins.h"
+#include "src/builtins/builtins-utils.h"
+
+#include "src/code-factory.h"
+
+namespace v8 {
+namespace internal {
+
+// -----------------------------------------------------------------------------
+// ES6 section 20.2.2 Function Properties of the Math Object
+
+// 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;
+
+ 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;
+
+ 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);
+}
+
+// ES6 section 20.2.2.6 Math.atan ( x )
+void Builtins::Generate_MathAtan(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* result = assembler->ChangeFloat64ToTagged(value);
+ assembler->Return(result);
+}
+
+// ES6 section 20.2.2.7 Math.atanh ( x )
+void Builtins::Generate_MathAtanh(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->Float64Atanh(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) {
+ 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(
+ CodeStubAssembler* assembler,
+ compiler::Node* (CodeStubAssembler::*float64op)(compiler::Node*)) {
+ typedef CodeStubAssembler::Label Label;
+ typedef compiler::Node Node;
+ typedef CodeStubAssembler::Variable Variable;
+
+ Node* context = assembler->Parameter(4);
+
+ // 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();
+
+ // Check if {x} is a Smi or a HeapObject.
+ Label if_xissmi(assembler), if_xisnotsmi(assembler);
+ assembler->Branch(assembler->WordIsSmi(x), &if_xissmi, &if_xisnotsmi);
+
+ assembler->Bind(&if_xissmi);
+ {
+ // Nothing to do when {x} is a Smi.
+ assembler->Return(x);
+ }
+
+ 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);
+
+ assembler->Bind(&if_xisheapnumber);
+ {
+ Node* x_value = assembler->LoadHeapNumberValue(x);
+ Node* value = (assembler->*float64op)(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
+
+// ES6 section 20.2.2.10 Math.ceil ( x )
+void Builtins::Generate_MathCeil(CodeStubAssembler* assembler) {
+ Generate_MathRoundingOperation(assembler, &CodeStubAssembler::Float64Ceil);
+}
+
+// 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);
+}
+
+// ES6 section 20.2.2.11 Math.clz32 ( x )
+void Builtins::Generate_MathClz32(CodeStubAssembler* assembler) {
+ typedef CodeStubAssembler::Label Label;
+ typedef compiler::Node Node;
+ typedef CodeStubAssembler::Variable Variable;
+
+ Node* context = assembler->Parameter(4);
+
+ // Shared entry point for the clz32 operation.
+ Variable var_clz32_x(assembler, MachineRepresentation::kWord32);
+ Label do_clz32(assembler);
+
+ // 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();
+
+ // Check if {x} is a Smi or a HeapObject.
+ Label if_xissmi(assembler), if_xisnotsmi(assembler);
+ assembler->Branch(assembler->WordIsSmi(x), &if_xissmi, &if_xisnotsmi);
+
+ assembler->Bind(&if_xissmi);
+ {
+ var_clz32_x.Bind(assembler->SmiToWord32(x));
+ assembler->Goto(&do_clz32);
+ }
+
+ 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);
+
+ assembler->Bind(&if_xisheapnumber);
+ {
+ var_clz32_x.Bind(assembler->TruncateHeapNumberValueToWord32(x));
+ assembler->Goto(&do_clz32);
+ }
+
+ 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);
+ }
+ }
+ }
+
+ assembler->Bind(&do_clz32);
+ {
+ Node* x_value = var_clz32_x.value();
+ Node* value = assembler->Word32Clz(x_value);
+ Node* result = assembler->ChangeInt32ToTagged(value);
+ assembler->Return(result);
+ }
+}
+
+// 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);
+}
+
+// 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);
+}
+
+// ES6 section 20.2.2.14 Math.exp ( x )
+void Builtins::Generate_MathExp(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->Float64Exp(x_value);
+ Node* result = assembler->ChangeFloat64ToTagged(value);
+ assembler->Return(result);
+}
+
+// ES6 section 20.2.2.16 Math.floor ( x )
+void Builtins::Generate_MathFloor(CodeStubAssembler* assembler) {
+ Generate_MathRoundingOperation(assembler, &CodeStubAssembler::Float64Floor);
+}
+
+// ES6 section 20.2.2.17 Math.fround ( x )
+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);
+ 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 )
+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 )
+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);
+}
+
+// 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);
+}
+
+// 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);
+}
+
+// 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);
+}
+
+// ES6 section 20.2.2.26 Math.pow ( x, y )
+void Builtins::Generate_MathPow(CodeStubAssembler* assembler) {
+ using compiler::Node;
+
+ Node* x = assembler->Parameter(1);
+ Node* y = assembler->Parameter(2);
+ Node* context = assembler->Parameter(5);
+ Node* x_value = assembler->TruncateTaggedToFloat64(context, x);
+ Node* y_value = assembler->TruncateTaggedToFloat64(context, y);
+ Node* value = assembler->Float64Pow(x_value, y_value);
+ Node* result = assembler->ChangeFloat64ToTagged(value);
+ 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));
+
+ 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;
+
+ 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);
+}
+
+// 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);
+}
+
+// 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);
+}
+
+// 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);
+}
+
+// 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);
+}
+
+// ES6 section 20.2.2.35 Math.trunc ( x )
+void Builtins::Generate_MathTrunc(CodeStubAssembler* assembler) {
+ Generate_MathRoundingOperation(assembler, &CodeStubAssembler::Float64Trunc);
+}
+
+void Builtins::Generate_MathMax(MacroAssembler* masm) {
+ Generate_MathMaxMin(masm, MathMaxMinKind::kMax);
+}
+
+void Builtins::Generate_MathMin(MacroAssembler* masm) {
+ Generate_MathMaxMin(masm, MathMaxMinKind::kMin);
+}
+
+} // namespace internal
+} // namespace v8
« no previous file with comments | « src/builtins/builtins-json.cc ('k') | src/builtins/builtins-number.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698