| OLD | NEW |
| 1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2017 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-gen.h" |
| 6 #include "src/builtins/builtins.h" | 6 #include "src/builtins/builtins.h" |
| 7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
| 8 #include "src/code-stub-assembler.h" | 8 #include "src/code-stub-assembler.h" |
| 9 #include "src/counters.h" | |
| 10 #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 { | 16 class MathBuiltinsAssembler : public CodeStubAssembler { |
| 19 public: | 17 public: |
| 20 explicit MathBuiltinsAssembler(compiler::CodeAssemblerState* state) | 18 explicit MathBuiltinsAssembler(compiler::CodeAssemblerState* state) |
| (...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 326 TF_BUILTIN(MathFround, CodeStubAssembler) { | 324 TF_BUILTIN(MathFround, CodeStubAssembler) { |
| 327 Node* x = Parameter(1); | 325 Node* x = Parameter(1); |
| 328 Node* context = Parameter(4); | 326 Node* context = Parameter(4); |
| 329 Node* x_value = TruncateTaggedToFloat64(context, x); | 327 Node* x_value = TruncateTaggedToFloat64(context, x); |
| 330 Node* value32 = TruncateFloat64ToFloat32(x_value); | 328 Node* value32 = TruncateFloat64ToFloat32(x_value); |
| 331 Node* value = ChangeFloat32ToFloat64(value32); | 329 Node* value = ChangeFloat32ToFloat64(value32); |
| 332 Node* result = AllocateHeapNumberWithValue(value); | 330 Node* result = AllocateHeapNumberWithValue(value); |
| 333 Return(result); | 331 Return(result); |
| 334 } | 332 } |
| 335 | 333 |
| 336 // ES6 section 20.2.2.18 Math.hypot ( value1, value2, ...values ) | |
| 337 BUILTIN(MathHypot) { | |
| 338 HandleScope scope(isolate); | |
| 339 int const length = args.length() - 1; | |
| 340 if (length == 0) return Smi::kZero; | |
| 341 DCHECK_LT(0, length); | |
| 342 double max = 0; | |
| 343 bool one_arg_is_nan = false; | |
| 344 List<double> abs_values(length); | |
| 345 for (int i = 0; i < length; i++) { | |
| 346 Handle<Object> x = args.at(i + 1); | |
| 347 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, x, Object::ToNumber(x)); | |
| 348 double abs_value = std::abs(x->Number()); | |
| 349 | |
| 350 if (std::isnan(abs_value)) { | |
| 351 one_arg_is_nan = true; | |
| 352 } else { | |
| 353 abs_values.Add(abs_value); | |
| 354 if (max < abs_value) { | |
| 355 max = abs_value; | |
| 356 } | |
| 357 } | |
| 358 } | |
| 359 | |
| 360 if (max == V8_INFINITY) { | |
| 361 return *isolate->factory()->NewNumber(V8_INFINITY); | |
| 362 } | |
| 363 | |
| 364 if (one_arg_is_nan) { | |
| 365 return isolate->heap()->nan_value(); | |
| 366 } | |
| 367 | |
| 368 if (max == 0) { | |
| 369 return Smi::kZero; | |
| 370 } | |
| 371 DCHECK_GT(max, 0); | |
| 372 | |
| 373 // Kahan summation to avoid rounding errors. | |
| 374 // Normalize the numbers to the largest one to avoid overflow. | |
| 375 double sum = 0; | |
| 376 double compensation = 0; | |
| 377 for (int i = 0; i < length; i++) { | |
| 378 double n = abs_values.at(i) / max; | |
| 379 double summand = n * n - compensation; | |
| 380 double preliminary = sum + summand; | |
| 381 compensation = (preliminary - sum) - summand; | |
| 382 sum = preliminary; | |
| 383 } | |
| 384 | |
| 385 return *isolate->factory()->NewNumber(std::sqrt(sum) * max); | |
| 386 } | |
| 387 | |
| 388 // ES6 section 20.2.2.19 Math.imul ( x, y ) | 334 // ES6 section 20.2.2.19 Math.imul ( x, y ) |
| 389 TF_BUILTIN(MathImul, CodeStubAssembler) { | 335 TF_BUILTIN(MathImul, CodeStubAssembler) { |
| 390 Node* x = Parameter(1); | 336 Node* x = Parameter(1); |
| 391 Node* y = Parameter(2); | 337 Node* y = Parameter(2); |
| 392 Node* context = Parameter(5); | 338 Node* context = Parameter(5); |
| 393 Node* x_value = TruncateTaggedToWord32(context, x); | 339 Node* x_value = TruncateTaggedToWord32(context, x); |
| 394 Node* y_value = TruncateTaggedToWord32(context, y); | 340 Node* y_value = TruncateTaggedToWord32(context, y); |
| 395 Node* value = Int32Mul(x_value, y_value); | 341 Node* value = Int32Mul(x_value, y_value); |
| 396 Node* result = ChangeInt32ToTagged(value); | 342 Node* result = ChangeInt32ToTagged(value); |
| 397 Return(result); | 343 Return(result); |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 521 MathMaxMin(&CodeStubAssembler::Float64Max, -1.0 * V8_INFINITY); | 467 MathMaxMin(&CodeStubAssembler::Float64Max, -1.0 * V8_INFINITY); |
| 522 } | 468 } |
| 523 | 469 |
| 524 // ES6 section 20.2.2.25 Math.min ( value1, value2 , ...values ) | 470 // ES6 section 20.2.2.25 Math.min ( value1, value2 , ...values ) |
| 525 TF_BUILTIN(MathMin, MathBuiltinsAssembler) { | 471 TF_BUILTIN(MathMin, MathBuiltinsAssembler) { |
| 526 MathMaxMin(&CodeStubAssembler::Float64Min, V8_INFINITY); | 472 MathMaxMin(&CodeStubAssembler::Float64Min, V8_INFINITY); |
| 527 } | 473 } |
| 528 | 474 |
| 529 } // namespace internal | 475 } // namespace internal |
| 530 } // namespace v8 | 476 } // namespace v8 |
| OLD | NEW |