| OLD | NEW |
| 1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/builtins/builtins-utils.h" | 5 #include "src/builtins/builtins-utils.h" |
| 6 #include "src/builtins/builtins.h" | 6 #include "src/builtins/builtins.h" |
| 7 #include "src/code-factory.h" | |
| 8 #include "src/code-stub-assembler.h" | |
| 9 #include "src/counters.h" | 7 #include "src/counters.h" |
| 10 #include "src/objects-inl.h" | 8 #include "src/objects-inl.h" |
| 11 | 9 |
| 12 namespace v8 { | 10 namespace v8 { |
| 13 namespace internal { | 11 namespace internal { |
| 14 | 12 |
| 15 // ----------------------------------------------------------------------------- | 13 // ----------------------------------------------------------------------------- |
| 16 // ES6 section 20.2.2 Function Properties of the Math Object | 14 // ES6 section 20.2.2 Function Properties of the Math Object |
| 17 | 15 |
| 18 class MathBuiltinsAssembler : public CodeStubAssembler { | |
| 19 public: | |
| 20 explicit MathBuiltinsAssembler(compiler::CodeAssemblerState* state) | |
| 21 : CodeStubAssembler(state) {} | |
| 22 | |
| 23 protected: | |
| 24 void MathRoundingOperation(Node* (CodeStubAssembler::*float64op)(Node*)); | |
| 25 void MathUnaryOperation(Node* (CodeStubAssembler::*float64op)(Node*)); | |
| 26 void MathMaxMin(Node* (CodeStubAssembler::*float64op)(Node*, Node*), | |
| 27 double default_val); | |
| 28 }; | |
| 29 | |
| 30 // ES6 section - 20.2.2.1 Math.abs ( x ) | |
| 31 TF_BUILTIN(MathAbs, CodeStubAssembler) { | |
| 32 Node* context = Parameter(4); | |
| 33 | |
| 34 // We might need to loop once for ToNumber conversion. | |
| 35 Variable var_x(this, MachineRepresentation::kTagged); | |
| 36 Label loop(this, &var_x); | |
| 37 var_x.Bind(Parameter(1)); | |
| 38 Goto(&loop); | |
| 39 Bind(&loop); | |
| 40 { | |
| 41 // Load the current {x} value. | |
| 42 Node* x = var_x.value(); | |
| 43 | |
| 44 // Check if {x} is a Smi or a HeapObject. | |
| 45 Label if_xissmi(this), if_xisnotsmi(this); | |
| 46 Branch(TaggedIsSmi(x), &if_xissmi, &if_xisnotsmi); | |
| 47 | |
| 48 Bind(&if_xissmi); | |
| 49 { | |
| 50 // Check if {x} is already positive. | |
| 51 Label if_xispositive(this), if_xisnotpositive(this); | |
| 52 BranchIfSmiLessThanOrEqual(SmiConstant(Smi::FromInt(0)), x, | |
| 53 &if_xispositive, &if_xisnotpositive); | |
| 54 | |
| 55 Bind(&if_xispositive); | |
| 56 { | |
| 57 // Just return the input {x}. | |
| 58 Return(x); | |
| 59 } | |
| 60 | |
| 61 Bind(&if_xisnotpositive); | |
| 62 { | |
| 63 // Try to negate the {x} value. | |
| 64 Node* pair = | |
| 65 IntPtrSubWithOverflow(IntPtrConstant(0), BitcastTaggedToWord(x)); | |
| 66 Node* overflow = Projection(1, pair); | |
| 67 Label if_overflow(this, Label::kDeferred), if_notoverflow(this); | |
| 68 Branch(overflow, &if_overflow, &if_notoverflow); | |
| 69 | |
| 70 Bind(&if_notoverflow); | |
| 71 { | |
| 72 // There is a Smi representation for negated {x}. | |
| 73 Node* result = Projection(0, pair); | |
| 74 Return(BitcastWordToTagged(result)); | |
| 75 } | |
| 76 | |
| 77 Bind(&if_overflow); | |
| 78 { Return(NumberConstant(0.0 - Smi::kMinValue)); } | |
| 79 } | |
| 80 } | |
| 81 | |
| 82 Bind(&if_xisnotsmi); | |
| 83 { | |
| 84 // Check if {x} is a HeapNumber. | |
| 85 Label if_xisheapnumber(this), if_xisnotheapnumber(this, Label::kDeferred); | |
| 86 Branch(IsHeapNumberMap(LoadMap(x)), &if_xisheapnumber, | |
| 87 &if_xisnotheapnumber); | |
| 88 | |
| 89 Bind(&if_xisheapnumber); | |
| 90 { | |
| 91 Node* x_value = LoadHeapNumberValue(x); | |
| 92 Node* value = Float64Abs(x_value); | |
| 93 Node* result = AllocateHeapNumberWithValue(value); | |
| 94 Return(result); | |
| 95 } | |
| 96 | |
| 97 Bind(&if_xisnotheapnumber); | |
| 98 { | |
| 99 // Need to convert {x} to a Number first. | |
| 100 Callable callable = CodeFactory::NonNumberToNumber(isolate()); | |
| 101 var_x.Bind(CallStub(callable, context, x)); | |
| 102 Goto(&loop); | |
| 103 } | |
| 104 } | |
| 105 } | |
| 106 } | |
| 107 | |
| 108 void MathBuiltinsAssembler::MathRoundingOperation( | |
| 109 Node* (CodeStubAssembler::*float64op)(Node*)) { | |
| 110 Node* context = Parameter(4); | |
| 111 | |
| 112 // We might need to loop once for ToNumber conversion. | |
| 113 Variable var_x(this, MachineRepresentation::kTagged); | |
| 114 Label loop(this, &var_x); | |
| 115 var_x.Bind(Parameter(1)); | |
| 116 Goto(&loop); | |
| 117 Bind(&loop); | |
| 118 { | |
| 119 // Load the current {x} value. | |
| 120 Node* x = var_x.value(); | |
| 121 | |
| 122 // Check if {x} is a Smi or a HeapObject. | |
| 123 Label if_xissmi(this), if_xisnotsmi(this); | |
| 124 Branch(TaggedIsSmi(x), &if_xissmi, &if_xisnotsmi); | |
| 125 | |
| 126 Bind(&if_xissmi); | |
| 127 { | |
| 128 // Nothing to do when {x} is a Smi. | |
| 129 Return(x); | |
| 130 } | |
| 131 | |
| 132 Bind(&if_xisnotsmi); | |
| 133 { | |
| 134 // Check if {x} is a HeapNumber. | |
| 135 Label if_xisheapnumber(this), if_xisnotheapnumber(this, Label::kDeferred); | |
| 136 Branch(IsHeapNumberMap(LoadMap(x)), &if_xisheapnumber, | |
| 137 &if_xisnotheapnumber); | |
| 138 | |
| 139 Bind(&if_xisheapnumber); | |
| 140 { | |
| 141 Node* x_value = LoadHeapNumberValue(x); | |
| 142 Node* value = (this->*float64op)(x_value); | |
| 143 Node* result = ChangeFloat64ToTagged(value); | |
| 144 Return(result); | |
| 145 } | |
| 146 | |
| 147 Bind(&if_xisnotheapnumber); | |
| 148 { | |
| 149 // Need to convert {x} to a Number first. | |
| 150 Callable callable = CodeFactory::NonNumberToNumber(isolate()); | |
| 151 var_x.Bind(CallStub(callable, context, x)); | |
| 152 Goto(&loop); | |
| 153 } | |
| 154 } | |
| 155 } | |
| 156 } | |
| 157 | |
| 158 void MathBuiltinsAssembler::MathUnaryOperation( | |
| 159 Node* (CodeStubAssembler::*float64op)(Node*)) { | |
| 160 Node* x = Parameter(1); | |
| 161 Node* context = Parameter(4); | |
| 162 Node* x_value = TruncateTaggedToFloat64(context, x); | |
| 163 Node* value = (this->*float64op)(x_value); | |
| 164 Node* result = AllocateHeapNumberWithValue(value); | |
| 165 Return(result); | |
| 166 } | |
| 167 | |
| 168 void MathBuiltinsAssembler::MathMaxMin( | |
| 169 Node* (CodeStubAssembler::*float64op)(Node*, Node*), double default_val) { | |
| 170 Node* argc = Parameter(BuiltinDescriptor::kArgumentsCount); | |
| 171 Node* context = Parameter(BuiltinDescriptor::kContext); | |
| 172 | |
| 173 CodeStubArguments arguments(this, ChangeInt32ToIntPtr(argc)); | |
| 174 argc = arguments.GetLength(); | |
| 175 | |
| 176 Variable result(this, MachineRepresentation::kFloat64); | |
| 177 result.Bind(Float64Constant(default_val)); | |
| 178 | |
| 179 CodeStubAssembler::VariableList vars({&result}, zone()); | |
| 180 arguments.ForEach(vars, [this, float64op, context, &result](Node* arg) { | |
| 181 Node* float_value = TruncateTaggedToFloat64(context, arg); | |
| 182 result.Bind((this->*float64op)(result.value(), float_value)); | |
| 183 }); | |
| 184 | |
| 185 arguments.PopAndReturn(ChangeFloat64ToTagged(result.value())); | |
| 186 } | |
| 187 | |
| 188 // ES6 section 20.2.2.2 Math.acos ( x ) | |
| 189 TF_BUILTIN(MathAcos, MathBuiltinsAssembler) { | |
| 190 MathUnaryOperation(&CodeStubAssembler::Float64Acos); | |
| 191 } | |
| 192 | |
| 193 // ES6 section 20.2.2.3 Math.acosh ( x ) | |
| 194 TF_BUILTIN(MathAcosh, MathBuiltinsAssembler) { | |
| 195 MathUnaryOperation(&CodeStubAssembler::Float64Acosh); | |
| 196 } | |
| 197 | |
| 198 // ES6 section 20.2.2.4 Math.asin ( x ) | |
| 199 TF_BUILTIN(MathAsin, MathBuiltinsAssembler) { | |
| 200 MathUnaryOperation(&CodeStubAssembler::Float64Asin); | |
| 201 } | |
| 202 | |
| 203 // ES6 section 20.2.2.5 Math.asinh ( x ) | |
| 204 TF_BUILTIN(MathAsinh, MathBuiltinsAssembler) { | |
| 205 MathUnaryOperation(&CodeStubAssembler::Float64Asinh); | |
| 206 } | |
| 207 // ES6 section 20.2.2.6 Math.atan ( x ) | |
| 208 TF_BUILTIN(MathAtan, MathBuiltinsAssembler) { | |
| 209 MathUnaryOperation(&CodeStubAssembler::Float64Atan); | |
| 210 } | |
| 211 | |
| 212 // ES6 section 20.2.2.7 Math.atanh ( x ) | |
| 213 TF_BUILTIN(MathAtanh, MathBuiltinsAssembler) { | |
| 214 MathUnaryOperation(&CodeStubAssembler::Float64Atanh); | |
| 215 } | |
| 216 | |
| 217 // ES6 section 20.2.2.8 Math.atan2 ( y, x ) | |
| 218 TF_BUILTIN(MathAtan2, CodeStubAssembler) { | |
| 219 Node* y = Parameter(1); | |
| 220 Node* x = Parameter(2); | |
| 221 Node* context = Parameter(5); | |
| 222 | |
| 223 Node* y_value = TruncateTaggedToFloat64(context, y); | |
| 224 Node* x_value = TruncateTaggedToFloat64(context, x); | |
| 225 Node* value = Float64Atan2(y_value, x_value); | |
| 226 Node* result = AllocateHeapNumberWithValue(value); | |
| 227 Return(result); | |
| 228 } | |
| 229 | |
| 230 // ES6 section 20.2.2.10 Math.ceil ( x ) | |
| 231 TF_BUILTIN(MathCeil, MathBuiltinsAssembler) { | |
| 232 MathRoundingOperation(&CodeStubAssembler::Float64Ceil); | |
| 233 } | |
| 234 | |
| 235 // ES6 section 20.2.2.9 Math.cbrt ( x ) | |
| 236 TF_BUILTIN(MathCbrt, MathBuiltinsAssembler) { | |
| 237 MathUnaryOperation(&CodeStubAssembler::Float64Cbrt); | |
| 238 } | |
| 239 | |
| 240 // ES6 section 20.2.2.11 Math.clz32 ( x ) | |
| 241 TF_BUILTIN(MathClz32, CodeStubAssembler) { | |
| 242 Node* context = Parameter(4); | |
| 243 | |
| 244 // Shared entry point for the clz32 operation. | |
| 245 Variable var_clz32_x(this, MachineRepresentation::kWord32); | |
| 246 Label do_clz32(this); | |
| 247 | |
| 248 // We might need to loop once for ToNumber conversion. | |
| 249 Variable var_x(this, MachineRepresentation::kTagged); | |
| 250 Label loop(this, &var_x); | |
| 251 var_x.Bind(Parameter(1)); | |
| 252 Goto(&loop); | |
| 253 Bind(&loop); | |
| 254 { | |
| 255 // Load the current {x} value. | |
| 256 Node* x = var_x.value(); | |
| 257 | |
| 258 // Check if {x} is a Smi or a HeapObject. | |
| 259 Label if_xissmi(this), if_xisnotsmi(this); | |
| 260 Branch(TaggedIsSmi(x), &if_xissmi, &if_xisnotsmi); | |
| 261 | |
| 262 Bind(&if_xissmi); | |
| 263 { | |
| 264 var_clz32_x.Bind(SmiToWord32(x)); | |
| 265 Goto(&do_clz32); | |
| 266 } | |
| 267 | |
| 268 Bind(&if_xisnotsmi); | |
| 269 { | |
| 270 // Check if {x} is a HeapNumber. | |
| 271 Label if_xisheapnumber(this), if_xisnotheapnumber(this, Label::kDeferred); | |
| 272 Branch(IsHeapNumberMap(LoadMap(x)), &if_xisheapnumber, | |
| 273 &if_xisnotheapnumber); | |
| 274 | |
| 275 Bind(&if_xisheapnumber); | |
| 276 { | |
| 277 var_clz32_x.Bind(TruncateHeapNumberValueToWord32(x)); | |
| 278 Goto(&do_clz32); | |
| 279 } | |
| 280 | |
| 281 Bind(&if_xisnotheapnumber); | |
| 282 { | |
| 283 // Need to convert {x} to a Number first. | |
| 284 Callable callable = CodeFactory::NonNumberToNumber(isolate()); | |
| 285 var_x.Bind(CallStub(callable, context, x)); | |
| 286 Goto(&loop); | |
| 287 } | |
| 288 } | |
| 289 } | |
| 290 | |
| 291 Bind(&do_clz32); | |
| 292 { | |
| 293 Node* x_value = var_clz32_x.value(); | |
| 294 Node* value = Word32Clz(x_value); | |
| 295 Node* result = ChangeInt32ToTagged(value); | |
| 296 Return(result); | |
| 297 } | |
| 298 } | |
| 299 | |
| 300 // ES6 section 20.2.2.12 Math.cos ( x ) | |
| 301 TF_BUILTIN(MathCos, MathBuiltinsAssembler) { | |
| 302 MathUnaryOperation(&CodeStubAssembler::Float64Cos); | |
| 303 } | |
| 304 | |
| 305 // ES6 section 20.2.2.13 Math.cosh ( x ) | |
| 306 TF_BUILTIN(MathCosh, MathBuiltinsAssembler) { | |
| 307 MathUnaryOperation(&CodeStubAssembler::Float64Cosh); | |
| 308 } | |
| 309 | |
| 310 // ES6 section 20.2.2.14 Math.exp ( x ) | |
| 311 TF_BUILTIN(MathExp, MathBuiltinsAssembler) { | |
| 312 MathUnaryOperation(&CodeStubAssembler::Float64Exp); | |
| 313 } | |
| 314 | |
| 315 // ES6 section 20.2.2.15 Math.expm1 ( x ) | |
| 316 TF_BUILTIN(MathExpm1, MathBuiltinsAssembler) { | |
| 317 MathUnaryOperation(&CodeStubAssembler::Float64Expm1); | |
| 318 } | |
| 319 | |
| 320 // ES6 section 20.2.2.16 Math.floor ( x ) | |
| 321 TF_BUILTIN(MathFloor, MathBuiltinsAssembler) { | |
| 322 MathRoundingOperation(&CodeStubAssembler::Float64Floor); | |
| 323 } | |
| 324 | |
| 325 // ES6 section 20.2.2.17 Math.fround ( x ) | |
| 326 TF_BUILTIN(MathFround, CodeStubAssembler) { | |
| 327 Node* x = Parameter(1); | |
| 328 Node* context = Parameter(4); | |
| 329 Node* x_value = TruncateTaggedToFloat64(context, x); | |
| 330 Node* value32 = TruncateFloat64ToFloat32(x_value); | |
| 331 Node* value = ChangeFloat32ToFloat64(value32); | |
| 332 Node* result = AllocateHeapNumberWithValue(value); | |
| 333 Return(result); | |
| 334 } | |
| 335 | |
| 336 // ES6 section 20.2.2.18 Math.hypot ( value1, value2, ...values ) | 16 // ES6 section 20.2.2.18 Math.hypot ( value1, value2, ...values ) |
| 337 BUILTIN(MathHypot) { | 17 BUILTIN(MathHypot) { |
| 338 HandleScope scope(isolate); | 18 HandleScope scope(isolate); |
| 339 int const length = args.length() - 1; | 19 int const length = args.length() - 1; |
| 340 if (length == 0) return Smi::kZero; | 20 if (length == 0) return Smi::kZero; |
| 341 DCHECK_LT(0, length); | 21 DCHECK_LT(0, length); |
| 342 double max = 0; | 22 double max = 0; |
| 343 bool one_arg_is_nan = false; | 23 bool one_arg_is_nan = false; |
| 344 List<double> abs_values(length); | 24 List<double> abs_values(length); |
| 345 for (int i = 0; i < length; i++) { | 25 for (int i = 0; i < length; i++) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 378 double n = abs_values.at(i) / max; | 58 double n = abs_values.at(i) / max; |
| 379 double summand = n * n - compensation; | 59 double summand = n * n - compensation; |
| 380 double preliminary = sum + summand; | 60 double preliminary = sum + summand; |
| 381 compensation = (preliminary - sum) - summand; | 61 compensation = (preliminary - sum) - summand; |
| 382 sum = preliminary; | 62 sum = preliminary; |
| 383 } | 63 } |
| 384 | 64 |
| 385 return *isolate->factory()->NewNumber(std::sqrt(sum) * max); | 65 return *isolate->factory()->NewNumber(std::sqrt(sum) * max); |
| 386 } | 66 } |
| 387 | 67 |
| 388 // ES6 section 20.2.2.19 Math.imul ( x, y ) | |
| 389 TF_BUILTIN(MathImul, CodeStubAssembler) { | |
| 390 Node* x = Parameter(1); | |
| 391 Node* y = Parameter(2); | |
| 392 Node* context = Parameter(5); | |
| 393 Node* x_value = TruncateTaggedToWord32(context, x); | |
| 394 Node* y_value = TruncateTaggedToWord32(context, y); | |
| 395 Node* value = Int32Mul(x_value, y_value); | |
| 396 Node* result = ChangeInt32ToTagged(value); | |
| 397 Return(result); | |
| 398 } | |
| 399 | |
| 400 // ES6 section 20.2.2.20 Math.log ( x ) | |
| 401 TF_BUILTIN(MathLog, MathBuiltinsAssembler) { | |
| 402 MathUnaryOperation(&CodeStubAssembler::Float64Log); | |
| 403 } | |
| 404 | |
| 405 // ES6 section 20.2.2.21 Math.log1p ( x ) | |
| 406 TF_BUILTIN(MathLog1p, MathBuiltinsAssembler) { | |
| 407 MathUnaryOperation(&CodeStubAssembler::Float64Log1p); | |
| 408 } | |
| 409 | |
| 410 // ES6 section 20.2.2.22 Math.log10 ( x ) | |
| 411 TF_BUILTIN(MathLog10, MathBuiltinsAssembler) { | |
| 412 MathUnaryOperation(&CodeStubAssembler::Float64Log10); | |
| 413 } | |
| 414 | |
| 415 // ES6 section 20.2.2.23 Math.log2 ( x ) | |
| 416 TF_BUILTIN(MathLog2, MathBuiltinsAssembler) { | |
| 417 MathUnaryOperation(&CodeStubAssembler::Float64Log2); | |
| 418 } | |
| 419 | |
| 420 // ES6 section 20.2.2.26 Math.pow ( x, y ) | |
| 421 TF_BUILTIN(MathPow, CodeStubAssembler) { | |
| 422 Node* x = Parameter(1); | |
| 423 Node* y = Parameter(2); | |
| 424 Node* context = Parameter(5); | |
| 425 Node* x_value = TruncateTaggedToFloat64(context, x); | |
| 426 Node* y_value = TruncateTaggedToFloat64(context, y); | |
| 427 Node* value = Float64Pow(x_value, y_value); | |
| 428 Node* result = ChangeFloat64ToTagged(value); | |
| 429 Return(result); | |
| 430 } | |
| 431 | |
| 432 // ES6 section 20.2.2.27 Math.random ( ) | |
| 433 TF_BUILTIN(MathRandom, CodeStubAssembler) { | |
| 434 Node* context = Parameter(3); | |
| 435 Node* native_context = LoadNativeContext(context); | |
| 436 | |
| 437 // Load cache index. | |
| 438 Variable smi_index(this, MachineRepresentation::kTagged); | |
| 439 smi_index.Bind( | |
| 440 LoadContextElement(native_context, Context::MATH_RANDOM_INDEX_INDEX)); | |
| 441 | |
| 442 // Cached random numbers are exhausted if index is 0. Go to slow path. | |
| 443 Label if_cached(this); | |
| 444 GotoIf(SmiAbove(smi_index.value(), SmiConstant(Smi::kZero)), &if_cached); | |
| 445 | |
| 446 // Cache exhausted, populate the cache. Return value is the new index. | |
| 447 smi_index.Bind(CallRuntime(Runtime::kGenerateRandomNumbers, context)); | |
| 448 Goto(&if_cached); | |
| 449 | |
| 450 // Compute next index by decrement. | |
| 451 Bind(&if_cached); | |
| 452 Node* new_smi_index = SmiSub(smi_index.value(), SmiConstant(Smi::FromInt(1))); | |
| 453 StoreContextElement(native_context, Context::MATH_RANDOM_INDEX_INDEX, | |
| 454 new_smi_index); | |
| 455 | |
| 456 // Load and return next cached random number. | |
| 457 Node* array = | |
| 458 LoadContextElement(native_context, Context::MATH_RANDOM_CACHE_INDEX); | |
| 459 Node* random = LoadFixedDoubleArrayElement( | |
| 460 array, new_smi_index, MachineType::Float64(), 0, SMI_PARAMETERS); | |
| 461 Return(AllocateHeapNumberWithValue(random)); | |
| 462 } | |
| 463 | |
| 464 // ES6 section 20.2.2.28 Math.round ( x ) | |
| 465 TF_BUILTIN(MathRound, MathBuiltinsAssembler) { | |
| 466 MathRoundingOperation(&CodeStubAssembler::Float64Round); | |
| 467 } | |
| 468 | |
| 469 // ES6 section 20.2.2.29 Math.sign ( x ) | |
| 470 TF_BUILTIN(MathSign, CodeStubAssembler) { | |
| 471 // Convert the {x} value to a Number. | |
| 472 Node* x = Parameter(1); | |
| 473 Node* context = Parameter(4); | |
| 474 Node* x_value = TruncateTaggedToFloat64(context, x); | |
| 475 | |
| 476 // Return -1 if {x} is negative, 1 if {x} is positive, or {x} itself. | |
| 477 Label if_xisnegative(this), if_xispositive(this); | |
| 478 GotoIf(Float64LessThan(x_value, Float64Constant(0.0)), &if_xisnegative); | |
| 479 GotoIf(Float64LessThan(Float64Constant(0.0), x_value), &if_xispositive); | |
| 480 Return(ChangeFloat64ToTagged(x_value)); | |
| 481 | |
| 482 Bind(&if_xisnegative); | |
| 483 Return(SmiConstant(Smi::FromInt(-1))); | |
| 484 | |
| 485 Bind(&if_xispositive); | |
| 486 Return(SmiConstant(Smi::FromInt(1))); | |
| 487 } | |
| 488 | |
| 489 // ES6 section 20.2.2.30 Math.sin ( x ) | |
| 490 TF_BUILTIN(MathSin, MathBuiltinsAssembler) { | |
| 491 MathUnaryOperation(&CodeStubAssembler::Float64Sin); | |
| 492 } | |
| 493 | |
| 494 // ES6 section 20.2.2.31 Math.sinh ( x ) | |
| 495 TF_BUILTIN(MathSinh, MathBuiltinsAssembler) { | |
| 496 MathUnaryOperation(&CodeStubAssembler::Float64Sinh); | |
| 497 } | |
| 498 | |
| 499 // ES6 section 20.2.2.32 Math.sqrt ( x ) | |
| 500 TF_BUILTIN(MathSqrt, MathBuiltinsAssembler) { | |
| 501 MathUnaryOperation(&CodeStubAssembler::Float64Sqrt); | |
| 502 } | |
| 503 | |
| 504 // ES6 section 20.2.2.33 Math.tan ( x ) | |
| 505 TF_BUILTIN(MathTan, MathBuiltinsAssembler) { | |
| 506 MathUnaryOperation(&CodeStubAssembler::Float64Tan); | |
| 507 } | |
| 508 | |
| 509 // ES6 section 20.2.2.34 Math.tanh ( x ) | |
| 510 TF_BUILTIN(MathTanh, MathBuiltinsAssembler) { | |
| 511 MathUnaryOperation(&CodeStubAssembler::Float64Tanh); | |
| 512 } | |
| 513 | |
| 514 // ES6 section 20.2.2.35 Math.trunc ( x ) | |
| 515 TF_BUILTIN(MathTrunc, MathBuiltinsAssembler) { | |
| 516 MathRoundingOperation(&CodeStubAssembler::Float64Trunc); | |
| 517 } | |
| 518 | |
| 519 // ES6 section 20.2.2.24 Math.max ( value1, value2 , ...values ) | |
| 520 TF_BUILTIN(MathMax, MathBuiltinsAssembler) { | |
| 521 MathMaxMin(&CodeStubAssembler::Float64Max, -1.0 * V8_INFINITY); | |
| 522 } | |
| 523 | |
| 524 // ES6 section 20.2.2.25 Math.min ( value1, value2 , ...values ) | |
| 525 TF_BUILTIN(MathMin, MathBuiltinsAssembler) { | |
| 526 MathMaxMin(&CodeStubAssembler::Float64Min, V8_INFINITY); | |
| 527 } | |
| 528 | |
| 529 } // namespace internal | 68 } // namespace internal |
| 530 } // namespace v8 | 69 } // namespace v8 |
| OLD | NEW |