Commit f97ed07e authored by bmeurer's avatar bmeurer Committed by Commit bot

[builtins] Migrate a bunch of Math builtins to C++.

Migrate Math.imul, Math.fround, Math.acos, Math.asin and Math.atan to
C++ builtins, as these ones call into C++ anyway and so there's no
need to have this extra wrapper around it.

R=yangguo@chromium.org

Review URL: https://codereview.chromium.org/1731543004

Cr-Commit-Position: refs/heads/master@{#34274}
parent fcb83f20
......@@ -1560,6 +1560,11 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
Handle<JSObject> math = factory->NewJSObject(cons, TENURED);
DCHECK(math->IsJSObject());
JSObject::AddProperty(global, name, math, DONT_ENUM);
SimpleInstallFunction(math, "acos", Builtins::kMathAcos, 1, true);
SimpleInstallFunction(math, "asin", Builtins::kMathAsin, 1, true);
SimpleInstallFunction(math, "atan", Builtins::kMathAtan, 1, true);
SimpleInstallFunction(math, "fround", Builtins::kMathFround, 1, true);
SimpleInstallFunction(math, "imul", Builtins::kMathImul, 2, true);
SimpleInstallFunction(math, "max", Builtins::kMathMax, 2, false);
SimpleInstallFunction(math, "min", Builtins::kMathMin, 2, false);
}
......
......@@ -1938,6 +1938,68 @@ BUILTIN(GlobalEval) {
}
// -----------------------------------------------------------------------------
// ES6 section 20.2.2 Function Properties of the Math Object
// 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()));
}
// 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()));
}
// ES6 section 20.2.2.6 Math.atan ( x )
BUILTIN(MathAtan) {
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::atan(x->Number()));
}
// ES6 section 20.2.2.17 Math.fround ( x )
BUILTIN(MathFround) {
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);
}
// 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);
}
// -----------------------------------------------------------------------------
// ES6 section 26.1 The Reflect Object
// ES6 section 26.1.3 Reflect.defineProperty
BUILTIN(ReflectDefineProperty) {
HandleScope scope(isolate);
......
......@@ -116,6 +116,12 @@ inline bool operator&(BuiltinExtraArguments lhs, BuiltinExtraArguments rhs) {
\
V(GlobalEval, kTarget) \
\
V(MathAcos, kNone) \
V(MathAsin, kNone) \
V(MathAtan, kNone) \
V(MathFround, kNone) \
V(MathImul, kNone) \
\
V(ObjectAssign, kNone) \
V(ObjectCreate, kNone) \
V(ObjectFreeze, kNone) \
......
......@@ -1587,9 +1587,6 @@ Type* Typer::Visitor::TypeJSCallRuntime(Node* node) {
case Runtime::kInlineConstructDouble:
case Runtime::kInlineMathFloor:
case Runtime::kInlineMathSqrt:
case Runtime::kInlineMathAcos:
case Runtime::kInlineMathAsin:
case Runtime::kInlineMathAtan:
case Runtime::kInlineMathAtan2:
return Type::Number();
case Runtime::kInlineMathClz32:
......
......@@ -742,9 +742,6 @@ class RuntimeCallTimerScope {
SC(regexp_entry_native, V8.RegExpEntryNative) \
SC(number_to_string_native, V8.NumberToStringNative) \
SC(number_to_string_runtime, V8.NumberToStringRuntime) \
SC(math_acos_runtime, V8.MathAcosRuntime) \
SC(math_asin_runtime, V8.MathAsinRuntime) \
SC(math_atan_runtime, V8.MathAtanRuntime) \
SC(math_atan2_runtime, V8.MathAtan2Runtime) \
SC(math_clz32_runtime, V8.MathClz32Runtime) \
SC(math_exp_runtime, V8.MathExpRuntime) \
......
......@@ -31,28 +31,13 @@ function MathAbs(x) {
return (x > 0) ? x : 0 - x;
}
// ECMA 262 - 15.8.2.2
function MathAcosJS(x) {
return %_MathAcos(+x);
}
// ECMA 262 - 15.8.2.3
function MathAsinJS(x) {
return %_MathAsin(+x);
}
// ECMA 262 - 15.8.2.4
function MathAtanJS(x) {
return %_MathAtan(+x);
}
// ECMA 262 - 15.8.2.5
// The naming of y and x matches the spec, as does the order in which
// ToNumber (valueOf) is called.
function MathAtan2JS(y, x) {
y = +y;
x = +x;
return %_MathAtan2(y, x);
return %MathAtan2(y, x);
}
// ECMA 262 - 15.8.2.6
......@@ -107,11 +92,6 @@ function MathSqrtJS(x) {
return %_MathSqrt(+x);
}
// Non-standard extension.
function MathImul(x, y) {
return %NumberImul(TO_NUMBER(x), TO_NUMBER(y));
}
// ES6 draft 09-27-13, section 20.2.2.28.
function MathSign(x) {
x = +x;
......@@ -188,11 +168,6 @@ function MathHypot(x, y) { // Function length is 2.
return %_MathSqrt(sum) * max;
}
// ES6 draft 09-27-13, section 20.2.2.16.
function MathFroundJS(x) {
return %MathFround(TO_NUMBER(x));
}
// ES6 draft 07-18-14, section 20.2.2.11
function MathClz32JS(x) {
return %_MathClz32(x >>> 0);
......@@ -246,9 +221,6 @@ utils.InstallConstants(GlobalMath, [
utils.InstallFunctions(GlobalMath, DONT_ENUM, [
"random", MathRandom,
"abs", MathAbs,
"acos", MathAcosJS,
"asin", MathAsinJS,
"atan", MathAtanJS,
"ceil", MathCeil,
"exp", MathExp,
"floor", MathFloorJS,
......@@ -257,22 +229,17 @@ utils.InstallFunctions(GlobalMath, DONT_ENUM, [
"sqrt", MathSqrtJS,
"atan2", MathAtan2JS,
"pow", MathPowJS,
"imul", MathImul,
"sign", MathSign,
"trunc", MathTrunc,
"asinh", MathAsinh,
"acosh", MathAcosh,
"atanh", MathAtanh,
"hypot", MathHypot,
"fround", MathFroundJS,
"clz32", MathClz32JS,
"cbrt", MathCbrt
]);
%SetForceInlineFlag(MathAbs);
%SetForceInlineFlag(MathAcosJS);
%SetForceInlineFlag(MathAsinJS);
%SetForceInlineFlag(MathAtanJS);
%SetForceInlineFlag(MathAtan2JS);
%SetForceInlineFlag(MathCeil);
%SetForceInlineFlag(MathClz32JS);
......
......@@ -23,9 +23,6 @@ namespace internal {
return *isolate->factory()->NewHeapNumber(std::name(x)); \
}
RUNTIME_UNARY_MATH(Acos, acos)
RUNTIME_UNARY_MATH(Asin, asin)
RUNTIME_UNARY_MATH(Atan, atan)
RUNTIME_UNARY_MATH(LogRT, log)
#undef RUNTIME_UNARY_MATH
......@@ -228,16 +225,6 @@ RUNTIME_FUNCTION(Runtime_MathSqrt) {
}
RUNTIME_FUNCTION(Runtime_MathFround) {
HandleScope scope(isolate);
DCHECK(args.length() == 1);
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
float xf = DoubleToFloat32(x);
return *isolate->factory()->NewNumber(xf);
}
RUNTIME_FUNCTION(Runtime_GenerateRandomNumbers) {
HandleScope scope(isolate);
DCHECK(args.length() == 1);
......
......@@ -208,19 +208,6 @@ RUNTIME_FUNCTION(Runtime_NumberToSmi) {
}
RUNTIME_FUNCTION(Runtime_NumberImul) {
HandleScope scope(isolate);
DCHECK(args.length() == 2);
// We rely on implementation-defined behavior below, but at least not on
// undefined behavior.
CONVERT_NUMBER_CHECKED(uint32_t, x, Int32, args[0]);
CONVERT_NUMBER_CHECKED(uint32_t, y, Int32, args[1]);
int32_t product = static_cast<int32_t>(x * y);
return *isolate->factory()->NewNumberFromInt(product);
}
// Compare two Smis as if they were converted to strings and then
// compared lexicographically.
RUNTIME_FUNCTION(Runtime_SmiLexicographicCompare) {
......
......@@ -369,9 +369,6 @@ namespace internal {
#define FOR_EACH_INTRINSIC_MATHS(F) \
F(MathAcos, 1, 1) \
F(MathAsin, 1, 1) \
F(MathAtan, 1, 1) \
F(MathLogRT, 1, 1) \
F(DoubleHi, 1, 1) \
F(DoubleLo, 1, 1) \
......@@ -385,7 +382,6 @@ namespace internal {
F(MathPowRT, 2, 1) \
F(RoundNumber, 1, 1) \
F(MathSqrt, 1, 1) \
F(MathFround, 1, 1) \
F(GenerateRandomNumbers, 1, 1)
......@@ -402,7 +398,6 @@ namespace internal {
F(NumberToStringSkipCache, 1, 1) \
F(NumberToIntegerMapMinusZero, 1, 1) \
F(NumberToSmi, 1, 1) \
F(NumberImul, 2, 1) \
F(SmiLexicographicCompare, 2, 1) \
F(MaxSmi, 0, 1) \
F(IsSmi, 1, 1) \
......
......@@ -129,12 +129,18 @@ TEST(ConstructorCall) {
}
TEST(RuntimeCallCPP2) {
TEST(RuntimeCall) {
FLAG_allow_natives_syntax = true;
FunctionTester T("(function(a,b) { return %NumberImul(a, b); })");
FunctionTester T("(function(a) { return %IsJSReceiver(a); })");
T.CheckCall(T.Val(2730), T.Val(42), T.Val(65));
T.CheckCall(T.Val(798), T.Val(42), T.Val(19));
T.CheckCall(T.false_value(), T.Val(23), T.undefined());
T.CheckCall(T.false_value(), T.Val(4.2), T.undefined());
T.CheckCall(T.false_value(), T.Val("str"), T.undefined());
T.CheckCall(T.false_value(), T.true_value(), T.undefined());
T.CheckCall(T.false_value(), T.false_value(), T.undefined());
T.CheckCall(T.false_value(), T.undefined(), T.undefined());
T.CheckCall(T.true_value(), T.NewObject("({})"), T.undefined());
T.CheckCall(T.true_value(), T.NewObject("([])"), T.undefined());
}
......
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