[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}
This commit is contained in:
parent
fcb83f2015
commit
f97ed07e3a
@ -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());
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user