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 |