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, ...@@ -1560,6 +1560,11 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
Handle<JSObject> math = factory->NewJSObject(cons, TENURED); Handle<JSObject> math = factory->NewJSObject(cons, TENURED);
DCHECK(math->IsJSObject()); DCHECK(math->IsJSObject());
JSObject::AddProperty(global, name, math, DONT_ENUM); 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, "max", Builtins::kMathMax, 2, false);
SimpleInstallFunction(math, "min", Builtins::kMathMin, 2, false); SimpleInstallFunction(math, "min", Builtins::kMathMin, 2, false);
} }
......
...@@ -1938,6 +1938,68 @@ BUILTIN(GlobalEval) { ...@@ -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 // ES6 section 26.1.3 Reflect.defineProperty
BUILTIN(ReflectDefineProperty) { BUILTIN(ReflectDefineProperty) {
HandleScope scope(isolate); HandleScope scope(isolate);
......
...@@ -116,6 +116,12 @@ inline bool operator&(BuiltinExtraArguments lhs, BuiltinExtraArguments rhs) { ...@@ -116,6 +116,12 @@ inline bool operator&(BuiltinExtraArguments lhs, BuiltinExtraArguments rhs) {
\ \
V(GlobalEval, kTarget) \ V(GlobalEval, kTarget) \
\ \
V(MathAcos, kNone) \
V(MathAsin, kNone) \
V(MathAtan, kNone) \
V(MathFround, kNone) \
V(MathImul, kNone) \
\
V(ObjectAssign, kNone) \ V(ObjectAssign, kNone) \
V(ObjectCreate, kNone) \ V(ObjectCreate, kNone) \
V(ObjectFreeze, kNone) \ V(ObjectFreeze, kNone) \
......
...@@ -1587,9 +1587,6 @@ Type* Typer::Visitor::TypeJSCallRuntime(Node* node) { ...@@ -1587,9 +1587,6 @@ Type* Typer::Visitor::TypeJSCallRuntime(Node* node) {
case Runtime::kInlineConstructDouble: case Runtime::kInlineConstructDouble:
case Runtime::kInlineMathFloor: case Runtime::kInlineMathFloor:
case Runtime::kInlineMathSqrt: case Runtime::kInlineMathSqrt:
case Runtime::kInlineMathAcos:
case Runtime::kInlineMathAsin:
case Runtime::kInlineMathAtan:
case Runtime::kInlineMathAtan2: case Runtime::kInlineMathAtan2:
return Type::Number(); return Type::Number();
case Runtime::kInlineMathClz32: case Runtime::kInlineMathClz32:
......
...@@ -742,9 +742,6 @@ class RuntimeCallTimerScope { ...@@ -742,9 +742,6 @@ class RuntimeCallTimerScope {
SC(regexp_entry_native, V8.RegExpEntryNative) \ SC(regexp_entry_native, V8.RegExpEntryNative) \
SC(number_to_string_native, V8.NumberToStringNative) \ SC(number_to_string_native, V8.NumberToStringNative) \
SC(number_to_string_runtime, V8.NumberToStringRuntime) \ 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_atan2_runtime, V8.MathAtan2Runtime) \
SC(math_clz32_runtime, V8.MathClz32Runtime) \ SC(math_clz32_runtime, V8.MathClz32Runtime) \
SC(math_exp_runtime, V8.MathExpRuntime) \ SC(math_exp_runtime, V8.MathExpRuntime) \
......
...@@ -31,28 +31,13 @@ function MathAbs(x) { ...@@ -31,28 +31,13 @@ function MathAbs(x) {
return (x > 0) ? x : 0 - 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 // ECMA 262 - 15.8.2.5
// The naming of y and x matches the spec, as does the order in which // The naming of y and x matches the spec, as does the order in which
// ToNumber (valueOf) is called. // ToNumber (valueOf) is called.
function MathAtan2JS(y, x) { function MathAtan2JS(y, x) {
y = +y; y = +y;
x = +x; x = +x;
return %_MathAtan2(y, x); return %MathAtan2(y, x);
} }
// ECMA 262 - 15.8.2.6 // ECMA 262 - 15.8.2.6
...@@ -107,11 +92,6 @@ function MathSqrtJS(x) { ...@@ -107,11 +92,6 @@ function MathSqrtJS(x) {
return %_MathSqrt(+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. // ES6 draft 09-27-13, section 20.2.2.28.
function MathSign(x) { function MathSign(x) {
x = +x; x = +x;
...@@ -188,11 +168,6 @@ function MathHypot(x, y) { // Function length is 2. ...@@ -188,11 +168,6 @@ function MathHypot(x, y) { // Function length is 2.
return %_MathSqrt(sum) * max; 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 // ES6 draft 07-18-14, section 20.2.2.11
function MathClz32JS(x) { function MathClz32JS(x) {
return %_MathClz32(x >>> 0); return %_MathClz32(x >>> 0);
...@@ -246,9 +221,6 @@ utils.InstallConstants(GlobalMath, [ ...@@ -246,9 +221,6 @@ utils.InstallConstants(GlobalMath, [
utils.InstallFunctions(GlobalMath, DONT_ENUM, [ utils.InstallFunctions(GlobalMath, DONT_ENUM, [
"random", MathRandom, "random", MathRandom,
"abs", MathAbs, "abs", MathAbs,
"acos", MathAcosJS,
"asin", MathAsinJS,
"atan", MathAtanJS,
"ceil", MathCeil, "ceil", MathCeil,
"exp", MathExp, "exp", MathExp,
"floor", MathFloorJS, "floor", MathFloorJS,
...@@ -257,22 +229,17 @@ utils.InstallFunctions(GlobalMath, DONT_ENUM, [ ...@@ -257,22 +229,17 @@ utils.InstallFunctions(GlobalMath, DONT_ENUM, [
"sqrt", MathSqrtJS, "sqrt", MathSqrtJS,
"atan2", MathAtan2JS, "atan2", MathAtan2JS,
"pow", MathPowJS, "pow", MathPowJS,
"imul", MathImul,
"sign", MathSign, "sign", MathSign,
"trunc", MathTrunc, "trunc", MathTrunc,
"asinh", MathAsinh, "asinh", MathAsinh,
"acosh", MathAcosh, "acosh", MathAcosh,
"atanh", MathAtanh, "atanh", MathAtanh,
"hypot", MathHypot, "hypot", MathHypot,
"fround", MathFroundJS,
"clz32", MathClz32JS, "clz32", MathClz32JS,
"cbrt", MathCbrt "cbrt", MathCbrt
]); ]);
%SetForceInlineFlag(MathAbs); %SetForceInlineFlag(MathAbs);
%SetForceInlineFlag(MathAcosJS);
%SetForceInlineFlag(MathAsinJS);
%SetForceInlineFlag(MathAtanJS);
%SetForceInlineFlag(MathAtan2JS); %SetForceInlineFlag(MathAtan2JS);
%SetForceInlineFlag(MathCeil); %SetForceInlineFlag(MathCeil);
%SetForceInlineFlag(MathClz32JS); %SetForceInlineFlag(MathClz32JS);
......
...@@ -23,9 +23,6 @@ namespace internal { ...@@ -23,9 +23,6 @@ namespace internal {
return *isolate->factory()->NewHeapNumber(std::name(x)); \ 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) RUNTIME_UNARY_MATH(LogRT, log)
#undef RUNTIME_UNARY_MATH #undef RUNTIME_UNARY_MATH
...@@ -228,16 +225,6 @@ RUNTIME_FUNCTION(Runtime_MathSqrt) { ...@@ -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) { RUNTIME_FUNCTION(Runtime_GenerateRandomNumbers) {
HandleScope scope(isolate); HandleScope scope(isolate);
DCHECK(args.length() == 1); DCHECK(args.length() == 1);
......
...@@ -208,19 +208,6 @@ RUNTIME_FUNCTION(Runtime_NumberToSmi) { ...@@ -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 // Compare two Smis as if they were converted to strings and then
// compared lexicographically. // compared lexicographically.
RUNTIME_FUNCTION(Runtime_SmiLexicographicCompare) { RUNTIME_FUNCTION(Runtime_SmiLexicographicCompare) {
......
...@@ -369,9 +369,6 @@ namespace internal { ...@@ -369,9 +369,6 @@ namespace internal {
#define FOR_EACH_INTRINSIC_MATHS(F) \ #define FOR_EACH_INTRINSIC_MATHS(F) \
F(MathAcos, 1, 1) \
F(MathAsin, 1, 1) \
F(MathAtan, 1, 1) \
F(MathLogRT, 1, 1) \ F(MathLogRT, 1, 1) \
F(DoubleHi, 1, 1) \ F(DoubleHi, 1, 1) \
F(DoubleLo, 1, 1) \ F(DoubleLo, 1, 1) \
...@@ -385,7 +382,6 @@ namespace internal { ...@@ -385,7 +382,6 @@ namespace internal {
F(MathPowRT, 2, 1) \ F(MathPowRT, 2, 1) \
F(RoundNumber, 1, 1) \ F(RoundNumber, 1, 1) \
F(MathSqrt, 1, 1) \ F(MathSqrt, 1, 1) \
F(MathFround, 1, 1) \
F(GenerateRandomNumbers, 1, 1) F(GenerateRandomNumbers, 1, 1)
...@@ -402,7 +398,6 @@ namespace internal { ...@@ -402,7 +398,6 @@ namespace internal {
F(NumberToStringSkipCache, 1, 1) \ F(NumberToStringSkipCache, 1, 1) \
F(NumberToIntegerMapMinusZero, 1, 1) \ F(NumberToIntegerMapMinusZero, 1, 1) \
F(NumberToSmi, 1, 1) \ F(NumberToSmi, 1, 1) \
F(NumberImul, 2, 1) \
F(SmiLexicographicCompare, 2, 1) \ F(SmiLexicographicCompare, 2, 1) \
F(MaxSmi, 0, 1) \ F(MaxSmi, 0, 1) \
F(IsSmi, 1, 1) \ F(IsSmi, 1, 1) \
......
...@@ -129,12 +129,18 @@ TEST(ConstructorCall) { ...@@ -129,12 +129,18 @@ TEST(ConstructorCall) {
} }
TEST(RuntimeCallCPP2) { TEST(RuntimeCall) {
FLAG_allow_natives_syntax = true; 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.false_value(), T.Val(23), T.undefined());
T.CheckCall(T.Val(798), T.Val(42), T.Val(19)); 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