• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3 // found in the LICENSE file.
4 
5 #include "src/builtins/builtins-utils-gen.h"
6 #include "src/builtins/builtins.h"
7 #include "src/code-stub-assembler.h"
8 
9 namespace v8 {
10 namespace internal {
11 
12 // ES #sec-isfinite-number
TF_BUILTIN(GlobalIsFinite,CodeStubAssembler)13 TF_BUILTIN(GlobalIsFinite, CodeStubAssembler) {
14   Node* context = Parameter(Descriptor::kContext);
15 
16   Label return_true(this), return_false(this);
17 
18   // We might need to loop once for ToNumber conversion.
19   VARIABLE(var_num, MachineRepresentation::kTagged);
20   Label loop(this, &var_num);
21   var_num.Bind(Parameter(Descriptor::kNumber));
22   Goto(&loop);
23   BIND(&loop);
24   {
25     Node* num = var_num.value();
26 
27     // Check if {num} is a Smi or a HeapObject.
28     GotoIf(TaggedIsSmi(num), &return_true);
29 
30     // Check if {num} is a HeapNumber.
31     Label if_numisheapnumber(this),
32         if_numisnotheapnumber(this, Label::kDeferred);
33     Branch(IsHeapNumber(num), &if_numisheapnumber, &if_numisnotheapnumber);
34 
35     BIND(&if_numisheapnumber);
36     {
37       // Check if {num} contains a finite, non-NaN value.
38       Node* num_value = LoadHeapNumberValue(num);
39       BranchIfFloat64IsNaN(Float64Sub(num_value, num_value), &return_false,
40                            &return_true);
41     }
42 
43     BIND(&if_numisnotheapnumber);
44     {
45       // Need to convert {num} to a Number first.
46       var_num.Bind(CallBuiltin(Builtins::kNonNumberToNumber, context, num));
47       Goto(&loop);
48     }
49   }
50 
51   BIND(&return_true);
52   Return(TrueConstant());
53 
54   BIND(&return_false);
55   Return(FalseConstant());
56 }
57 
58 // ES6 #sec-isnan-number
TF_BUILTIN(GlobalIsNaN,CodeStubAssembler)59 TF_BUILTIN(GlobalIsNaN, CodeStubAssembler) {
60   Node* context = Parameter(Descriptor::kContext);
61 
62   Label return_true(this), return_false(this);
63 
64   // We might need to loop once for ToNumber conversion.
65   VARIABLE(var_num, MachineRepresentation::kTagged);
66   Label loop(this, &var_num);
67   var_num.Bind(Parameter(Descriptor::kNumber));
68   Goto(&loop);
69   BIND(&loop);
70   {
71     Node* num = var_num.value();
72 
73     // Check if {num} is a Smi or a HeapObject.
74     GotoIf(TaggedIsSmi(num), &return_false);
75 
76     // Check if {num} is a HeapNumber.
77     Label if_numisheapnumber(this),
78         if_numisnotheapnumber(this, Label::kDeferred);
79     Branch(IsHeapNumber(num), &if_numisheapnumber, &if_numisnotheapnumber);
80 
81     BIND(&if_numisheapnumber);
82     {
83       // Check if {num} contains a NaN.
84       Node* num_value = LoadHeapNumberValue(num);
85       BranchIfFloat64IsNaN(num_value, &return_true, &return_false);
86     }
87 
88     BIND(&if_numisnotheapnumber);
89     {
90       // Need to convert {num} to a Number first.
91       var_num.Bind(CallBuiltin(Builtins::kNonNumberToNumber, context, num));
92       Goto(&loop);
93     }
94   }
95 
96   BIND(&return_true);
97   Return(TrueConstant());
98 
99   BIND(&return_false);
100   Return(FalseConstant());
101 }
102 
103 }  // namespace internal
104 }  // namespace v8
105