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" | 7 #include "src/code-factory.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
11 | 11 |
12 // ----------------------------------------------------------------------------- | 12 // ----------------------------------------------------------------------------- |
13 // ES6 section 20.1 Number Objects | 13 // ES6 section 20.1 Number Objects |
14 | 14 |
15 // ES6 section 20.1.2.2 Number.isFinite ( number ) | 15 // ES6 section 20.1.2.2 Number.isFinite ( number ) |
16 void Builtins::Generate_NumberIsFinite(CodeStubAssembler* assembler) { | 16 void Builtins::Generate_NumberIsFinite(compiler::CodeAssemblerState* state) { |
17 typedef CodeStubAssembler::Label Label; | 17 typedef CodeStubAssembler::Label Label; |
18 typedef compiler::Node Node; | 18 typedef compiler::Node Node; |
19 | 19 CodeStubAssembler assembler(state); |
20 Node* number = assembler->Parameter(1); | 20 |
21 | 21 Node* number = assembler.Parameter(1); |
22 Label return_true(assembler), return_false(assembler); | 22 |
23 | 23 Label return_true(&assembler), return_false(&assembler); |
24 // Check if {number} is a Smi. | 24 |
25 assembler->GotoIf(assembler->TaggedIsSmi(number), &return_true); | 25 // Check if {number} is a Smi. |
26 | 26 assembler.GotoIf(assembler.TaggedIsSmi(number), &return_true); |
27 // Check if {number} is a HeapNumber. | 27 |
28 assembler->GotoUnless( | 28 // Check if {number} is a HeapNumber. |
29 assembler->WordEqual(assembler->LoadMap(number), | 29 assembler.GotoUnless(assembler.WordEqual(assembler.LoadMap(number), |
30 assembler->HeapNumberMapConstant()), | 30 assembler.HeapNumberMapConstant()), |
| 31 &return_false); |
| 32 |
| 33 // Check if {number} contains a finite, non-NaN value. |
| 34 Node* number_value = assembler.LoadHeapNumberValue(number); |
| 35 assembler.BranchIfFloat64IsNaN( |
| 36 assembler.Float64Sub(number_value, number_value), &return_false, |
| 37 &return_true); |
| 38 |
| 39 assembler.Bind(&return_true); |
| 40 assembler.Return(assembler.BooleanConstant(true)); |
| 41 |
| 42 assembler.Bind(&return_false); |
| 43 assembler.Return(assembler.BooleanConstant(false)); |
| 44 } |
| 45 |
| 46 // ES6 section 20.1.2.3 Number.isInteger ( number ) |
| 47 void Builtins::Generate_NumberIsInteger(compiler::CodeAssemblerState* state) { |
| 48 typedef CodeStubAssembler::Label Label; |
| 49 typedef compiler::Node Node; |
| 50 CodeStubAssembler assembler(state); |
| 51 |
| 52 Node* number = assembler.Parameter(1); |
| 53 |
| 54 Label return_true(&assembler), return_false(&assembler); |
| 55 |
| 56 // Check if {number} is a Smi. |
| 57 assembler.GotoIf(assembler.TaggedIsSmi(number), &return_true); |
| 58 |
| 59 // Check if {number} is a HeapNumber. |
| 60 assembler.GotoUnless(assembler.WordEqual(assembler.LoadMap(number), |
| 61 assembler.HeapNumberMapConstant()), |
| 62 &return_false); |
| 63 |
| 64 // Load the actual value of {number}. |
| 65 Node* number_value = assembler.LoadHeapNumberValue(number); |
| 66 |
| 67 // Truncate the value of {number} to an integer (or an infinity). |
| 68 Node* integer = assembler.Float64Trunc(number_value); |
| 69 |
| 70 // Check if {number}s value matches the integer (ruling out the infinities). |
| 71 assembler.Branch( |
| 72 assembler.Float64Equal(assembler.Float64Sub(number_value, integer), |
| 73 assembler.Float64Constant(0.0)), |
| 74 &return_true, &return_false); |
| 75 |
| 76 assembler.Bind(&return_true); |
| 77 assembler.Return(assembler.BooleanConstant(true)); |
| 78 |
| 79 assembler.Bind(&return_false); |
| 80 assembler.Return(assembler.BooleanConstant(false)); |
| 81 } |
| 82 |
| 83 // ES6 section 20.1.2.4 Number.isNaN ( number ) |
| 84 void Builtins::Generate_NumberIsNaN(compiler::CodeAssemblerState* state) { |
| 85 typedef CodeStubAssembler::Label Label; |
| 86 typedef compiler::Node Node; |
| 87 CodeStubAssembler assembler(state); |
| 88 |
| 89 Node* number = assembler.Parameter(1); |
| 90 |
| 91 Label return_true(&assembler), return_false(&assembler); |
| 92 |
| 93 // Check if {number} is a Smi. |
| 94 assembler.GotoIf(assembler.TaggedIsSmi(number), &return_false); |
| 95 |
| 96 // Check if {number} is a HeapNumber. |
| 97 assembler.GotoUnless(assembler.WordEqual(assembler.LoadMap(number), |
| 98 assembler.HeapNumberMapConstant()), |
| 99 &return_false); |
| 100 |
| 101 // Check if {number} contains a NaN value. |
| 102 Node* number_value = assembler.LoadHeapNumberValue(number); |
| 103 assembler.BranchIfFloat64IsNaN(number_value, &return_true, &return_false); |
| 104 |
| 105 assembler.Bind(&return_true); |
| 106 assembler.Return(assembler.BooleanConstant(true)); |
| 107 |
| 108 assembler.Bind(&return_false); |
| 109 assembler.Return(assembler.BooleanConstant(false)); |
| 110 } |
| 111 |
| 112 // ES6 section 20.1.2.5 Number.isSafeInteger ( number ) |
| 113 void Builtins::Generate_NumberIsSafeInteger( |
| 114 compiler::CodeAssemblerState* state) { |
| 115 typedef CodeStubAssembler::Label Label; |
| 116 typedef compiler::Node Node; |
| 117 CodeStubAssembler assembler(state); |
| 118 |
| 119 Node* number = assembler.Parameter(1); |
| 120 |
| 121 Label return_true(&assembler), return_false(&assembler); |
| 122 |
| 123 // Check if {number} is a Smi. |
| 124 assembler.GotoIf(assembler.TaggedIsSmi(number), &return_true); |
| 125 |
| 126 // Check if {number} is a HeapNumber. |
| 127 assembler.GotoUnless(assembler.WordEqual(assembler.LoadMap(number), |
| 128 assembler.HeapNumberMapConstant()), |
| 129 &return_false); |
| 130 |
| 131 // Load the actual value of {number}. |
| 132 Node* number_value = assembler.LoadHeapNumberValue(number); |
| 133 |
| 134 // Truncate the value of {number} to an integer (or an infinity). |
| 135 Node* integer = assembler.Float64Trunc(number_value); |
| 136 |
| 137 // Check if {number}s value matches the integer (ruling out the infinities). |
| 138 assembler.GotoUnless( |
| 139 assembler.Float64Equal(assembler.Float64Sub(number_value, integer), |
| 140 assembler.Float64Constant(0.0)), |
31 &return_false); | 141 &return_false); |
32 | 142 |
33 // Check if {number} contains a finite, non-NaN value. | |
34 Node* number_value = assembler->LoadHeapNumberValue(number); | |
35 assembler->BranchIfFloat64IsNaN( | |
36 assembler->Float64Sub(number_value, number_value), &return_false, | |
37 &return_true); | |
38 | |
39 assembler->Bind(&return_true); | |
40 assembler->Return(assembler->BooleanConstant(true)); | |
41 | |
42 assembler->Bind(&return_false); | |
43 assembler->Return(assembler->BooleanConstant(false)); | |
44 } | |
45 | |
46 // ES6 section 20.1.2.3 Number.isInteger ( number ) | |
47 void Builtins::Generate_NumberIsInteger(CodeStubAssembler* assembler) { | |
48 typedef CodeStubAssembler::Label Label; | |
49 typedef compiler::Node Node; | |
50 | |
51 Node* number = assembler->Parameter(1); | |
52 | |
53 Label return_true(assembler), return_false(assembler); | |
54 | |
55 // Check if {number} is a Smi. | |
56 assembler->GotoIf(assembler->TaggedIsSmi(number), &return_true); | |
57 | |
58 // Check if {number} is a HeapNumber. | |
59 assembler->GotoUnless( | |
60 assembler->WordEqual(assembler->LoadMap(number), | |
61 assembler->HeapNumberMapConstant()), | |
62 &return_false); | |
63 | |
64 // Load the actual value of {number}. | |
65 Node* number_value = assembler->LoadHeapNumberValue(number); | |
66 | |
67 // Truncate the value of {number} to an integer (or an infinity). | |
68 Node* integer = assembler->Float64Trunc(number_value); | |
69 | |
70 // Check if {number}s value matches the integer (ruling out the infinities). | |
71 assembler->Branch( | |
72 assembler->Float64Equal(assembler->Float64Sub(number_value, integer), | |
73 assembler->Float64Constant(0.0)), | |
74 &return_true, &return_false); | |
75 | |
76 assembler->Bind(&return_true); | |
77 assembler->Return(assembler->BooleanConstant(true)); | |
78 | |
79 assembler->Bind(&return_false); | |
80 assembler->Return(assembler->BooleanConstant(false)); | |
81 } | |
82 | |
83 // ES6 section 20.1.2.4 Number.isNaN ( number ) | |
84 void Builtins::Generate_NumberIsNaN(CodeStubAssembler* assembler) { | |
85 typedef CodeStubAssembler::Label Label; | |
86 typedef compiler::Node Node; | |
87 | |
88 Node* number = assembler->Parameter(1); | |
89 | |
90 Label return_true(assembler), return_false(assembler); | |
91 | |
92 // Check if {number} is a Smi. | |
93 assembler->GotoIf(assembler->TaggedIsSmi(number), &return_false); | |
94 | |
95 // Check if {number} is a HeapNumber. | |
96 assembler->GotoUnless( | |
97 assembler->WordEqual(assembler->LoadMap(number), | |
98 assembler->HeapNumberMapConstant()), | |
99 &return_false); | |
100 | |
101 // Check if {number} contains a NaN value. | |
102 Node* number_value = assembler->LoadHeapNumberValue(number); | |
103 assembler->BranchIfFloat64IsNaN(number_value, &return_true, &return_false); | |
104 | |
105 assembler->Bind(&return_true); | |
106 assembler->Return(assembler->BooleanConstant(true)); | |
107 | |
108 assembler->Bind(&return_false); | |
109 assembler->Return(assembler->BooleanConstant(false)); | |
110 } | |
111 | |
112 // ES6 section 20.1.2.5 Number.isSafeInteger ( number ) | |
113 void Builtins::Generate_NumberIsSafeInteger(CodeStubAssembler* assembler) { | |
114 typedef CodeStubAssembler::Label Label; | |
115 typedef compiler::Node Node; | |
116 | |
117 Node* number = assembler->Parameter(1); | |
118 | |
119 Label return_true(assembler), return_false(assembler); | |
120 | |
121 // Check if {number} is a Smi. | |
122 assembler->GotoIf(assembler->TaggedIsSmi(number), &return_true); | |
123 | |
124 // Check if {number} is a HeapNumber. | |
125 assembler->GotoUnless( | |
126 assembler->WordEqual(assembler->LoadMap(number), | |
127 assembler->HeapNumberMapConstant()), | |
128 &return_false); | |
129 | |
130 // Load the actual value of {number}. | |
131 Node* number_value = assembler->LoadHeapNumberValue(number); | |
132 | |
133 // Truncate the value of {number} to an integer (or an infinity). | |
134 Node* integer = assembler->Float64Trunc(number_value); | |
135 | |
136 // Check if {number}s value matches the integer (ruling out the infinities). | |
137 assembler->GotoUnless( | |
138 assembler->Float64Equal(assembler->Float64Sub(number_value, integer), | |
139 assembler->Float64Constant(0.0)), | |
140 &return_false); | |
141 | |
142 // Check if the {integer} value is in safe integer range. | 143 // Check if the {integer} value is in safe integer range. |
143 assembler->Branch(assembler->Float64LessThanOrEqual( | 144 assembler.Branch(assembler.Float64LessThanOrEqual( |
144 assembler->Float64Abs(integer), | 145 assembler.Float64Abs(integer), |
145 assembler->Float64Constant(kMaxSafeInteger)), | 146 assembler.Float64Constant(kMaxSafeInteger)), |
146 &return_true, &return_false); | 147 &return_true, &return_false); |
147 | 148 |
148 assembler->Bind(&return_true); | 149 assembler.Bind(&return_true); |
149 assembler->Return(assembler->BooleanConstant(true)); | 150 assembler.Return(assembler.BooleanConstant(true)); |
150 | 151 |
151 assembler->Bind(&return_false); | 152 assembler.Bind(&return_false); |
152 assembler->Return(assembler->BooleanConstant(false)); | 153 assembler.Return(assembler.BooleanConstant(false)); |
153 } | 154 } |
154 | 155 |
155 // ES6 section 20.1.2.12 Number.parseFloat ( string ) | 156 // ES6 section 20.1.2.12 Number.parseFloat ( string ) |
156 void Builtins::Generate_NumberParseFloat(CodeStubAssembler* assembler) { | 157 void Builtins::Generate_NumberParseFloat(compiler::CodeAssemblerState* state) { |
157 typedef CodeStubAssembler::Label Label; | 158 typedef CodeStubAssembler::Label Label; |
158 typedef compiler::Node Node; | 159 typedef compiler::Node Node; |
159 typedef CodeStubAssembler::Variable Variable; | 160 typedef CodeStubAssembler::Variable Variable; |
160 | 161 CodeStubAssembler assembler(state); |
161 Node* context = assembler->Parameter(4); | 162 |
| 163 Node* context = assembler.Parameter(4); |
162 | 164 |
163 // We might need to loop once for ToString conversion. | 165 // We might need to loop once for ToString conversion. |
164 Variable var_input(assembler, MachineRepresentation::kTagged); | 166 Variable var_input(&assembler, MachineRepresentation::kTagged); |
165 Label loop(assembler, &var_input); | 167 Label loop(&assembler, &var_input); |
166 var_input.Bind(assembler->Parameter(1)); | 168 var_input.Bind(assembler.Parameter(1)); |
167 assembler->Goto(&loop); | 169 assembler.Goto(&loop); |
168 assembler->Bind(&loop); | 170 assembler.Bind(&loop); |
169 { | 171 { |
170 // Load the current {input} value. | 172 // Load the current {input} value. |
171 Node* input = var_input.value(); | 173 Node* input = var_input.value(); |
172 | 174 |
173 // Check if the {input} is a HeapObject or a Smi. | 175 // Check if the {input} is a HeapObject or a Smi. |
174 Label if_inputissmi(assembler), if_inputisnotsmi(assembler); | 176 Label if_inputissmi(&assembler), if_inputisnotsmi(&assembler); |
175 assembler->Branch(assembler->TaggedIsSmi(input), &if_inputissmi, | 177 assembler.Branch(assembler.TaggedIsSmi(input), &if_inputissmi, |
176 &if_inputisnotsmi); | 178 &if_inputisnotsmi); |
177 | 179 |
178 assembler->Bind(&if_inputissmi); | 180 assembler.Bind(&if_inputissmi); |
179 { | 181 { |
180 // The {input} is already a Number, no need to do anything. | 182 // The {input} is already a Number, no need to do anything. |
181 assembler->Return(input); | 183 assembler.Return(input); |
182 } | 184 } |
183 | 185 |
184 assembler->Bind(&if_inputisnotsmi); | 186 assembler.Bind(&if_inputisnotsmi); |
185 { | 187 { |
186 // The {input} is a HeapObject, check if it's already a String. | 188 // The {input} is a HeapObject, check if it's already a String. |
187 Label if_inputisstring(assembler), if_inputisnotstring(assembler); | 189 Label if_inputisstring(&assembler), if_inputisnotstring(&assembler); |
188 Node* input_map = assembler->LoadMap(input); | 190 Node* input_map = assembler.LoadMap(input); |
189 Node* input_instance_type = assembler->LoadMapInstanceType(input_map); | 191 Node* input_instance_type = assembler.LoadMapInstanceType(input_map); |
190 assembler->Branch(assembler->IsStringInstanceType(input_instance_type), | 192 assembler.Branch(assembler.IsStringInstanceType(input_instance_type), |
191 &if_inputisstring, &if_inputisnotstring); | 193 &if_inputisstring, &if_inputisnotstring); |
192 | 194 |
193 assembler->Bind(&if_inputisstring); | 195 assembler.Bind(&if_inputisstring); |
194 { | 196 { |
195 // The {input} is already a String, check if {input} contains | 197 // The {input} is already a String, check if {input} contains |
196 // a cached array index. | 198 // a cached array index. |
197 Label if_inputcached(assembler), if_inputnotcached(assembler); | 199 Label if_inputcached(&assembler), if_inputnotcached(&assembler); |
198 Node* input_hash = assembler->LoadNameHashField(input); | 200 Node* input_hash = assembler.LoadNameHashField(input); |
199 Node* input_bit = assembler->Word32And( | 201 Node* input_bit = assembler.Word32And( |
200 input_hash, | 202 input_hash, |
201 assembler->Int32Constant(String::kContainsCachedArrayIndexMask)); | 203 assembler.Int32Constant(String::kContainsCachedArrayIndexMask)); |
202 assembler->Branch( | 204 assembler.Branch( |
203 assembler->Word32Equal(input_bit, assembler->Int32Constant(0)), | 205 assembler.Word32Equal(input_bit, assembler.Int32Constant(0)), |
204 &if_inputcached, &if_inputnotcached); | 206 &if_inputcached, &if_inputnotcached); |
205 | 207 |
206 assembler->Bind(&if_inputcached); | 208 assembler.Bind(&if_inputcached); |
207 { | 209 { |
208 // Just return the {input}s cached array index. | 210 // Just return the {input}s cached array index. |
209 Node* input_array_index = | 211 Node* input_array_index = |
210 assembler->DecodeWordFromWord32<String::ArrayIndexValueBits>( | 212 assembler.DecodeWordFromWord32<String::ArrayIndexValueBits>( |
211 input_hash); | 213 input_hash); |
212 assembler->Return(assembler->SmiTag(input_array_index)); | 214 assembler.Return(assembler.SmiTag(input_array_index)); |
213 } | 215 } |
214 | 216 |
215 assembler->Bind(&if_inputnotcached); | 217 assembler.Bind(&if_inputnotcached); |
216 { | 218 { |
217 // Need to fall back to the runtime to convert {input} to double. | 219 // Need to fall back to the runtime to convert {input} to double. |
218 assembler->Return(assembler->CallRuntime(Runtime::kStringParseFloat, | 220 assembler.Return(assembler.CallRuntime(Runtime::kStringParseFloat, |
219 context, input)); | 221 context, input)); |
220 } | 222 } |
221 } | 223 } |
222 | 224 |
223 assembler->Bind(&if_inputisnotstring); | 225 assembler.Bind(&if_inputisnotstring); |
224 { | 226 { |
225 // The {input} is neither a String nor a Smi, check for HeapNumber. | 227 // The {input} is neither a String nor a Smi, check for HeapNumber. |
226 Label if_inputisnumber(assembler), | 228 Label if_inputisnumber(&assembler), |
227 if_inputisnotnumber(assembler, Label::kDeferred); | 229 if_inputisnotnumber(&assembler, Label::kDeferred); |
228 assembler->Branch( | 230 assembler.Branch( |
229 assembler->WordEqual(input_map, assembler->HeapNumberMapConstant()), | 231 assembler.WordEqual(input_map, assembler.HeapNumberMapConstant()), |
230 &if_inputisnumber, &if_inputisnotnumber); | 232 &if_inputisnumber, &if_inputisnotnumber); |
231 | 233 |
232 assembler->Bind(&if_inputisnumber); | 234 assembler.Bind(&if_inputisnumber); |
233 { | 235 { |
234 // The {input} is already a Number, take care of -0. | 236 // The {input} is already a Number, take care of -0. |
235 Label if_inputiszero(assembler), if_inputisnotzero(assembler); | 237 Label if_inputiszero(&assembler), if_inputisnotzero(&assembler); |
236 Node* input_value = assembler->LoadHeapNumberValue(input); | 238 Node* input_value = assembler.LoadHeapNumberValue(input); |
237 assembler->Branch(assembler->Float64Equal( | 239 assembler.Branch(assembler.Float64Equal( |
238 input_value, assembler->Float64Constant(0.0)), | 240 input_value, assembler.Float64Constant(0.0)), |
239 &if_inputiszero, &if_inputisnotzero); | 241 &if_inputiszero, &if_inputisnotzero); |
240 | 242 |
241 assembler->Bind(&if_inputiszero); | 243 assembler.Bind(&if_inputiszero); |
242 assembler->Return(assembler->SmiConstant(0)); | 244 assembler.Return(assembler.SmiConstant(0)); |
243 | 245 |
244 assembler->Bind(&if_inputisnotzero); | 246 assembler.Bind(&if_inputisnotzero); |
245 assembler->Return(input); | 247 assembler.Return(input); |
246 } | 248 } |
247 | 249 |
248 assembler->Bind(&if_inputisnotnumber); | 250 assembler.Bind(&if_inputisnotnumber); |
249 { | 251 { |
250 // Need to convert the {input} to String first. | 252 // Need to convert the {input} to String first. |
251 // TODO(bmeurer): This could be more efficient if necessary. | 253 // TODO(bmeurer): This could be more efficient if necessary. |
252 Callable callable = CodeFactory::ToString(assembler->isolate()); | 254 Callable callable = CodeFactory::ToString(assembler.isolate()); |
253 var_input.Bind(assembler->CallStub(callable, context, input)); | 255 var_input.Bind(assembler.CallStub(callable, context, input)); |
254 assembler->Goto(&loop); | 256 assembler.Goto(&loop); |
255 } | 257 } |
256 } | 258 } |
257 } | 259 } |
258 } | 260 } |
259 } | 261 } |
260 | 262 |
261 // ES6 section 20.1.2.13 Number.parseInt ( string, radix ) | 263 // ES6 section 20.1.2.13 Number.parseInt ( string, radix ) |
262 void Builtins::Generate_NumberParseInt(CodeStubAssembler* assembler) { | 264 void Builtins::Generate_NumberParseInt(compiler::CodeAssemblerState* state) { |
263 typedef CodeStubAssembler::Label Label; | 265 typedef CodeStubAssembler::Label Label; |
264 typedef compiler::Node Node; | 266 typedef compiler::Node Node; |
| 267 CodeStubAssembler assembler(state); |
265 | 268 |
266 Node* input = assembler->Parameter(1); | 269 Node* input = assembler.Parameter(1); |
267 Node* radix = assembler->Parameter(2); | 270 Node* radix = assembler.Parameter(2); |
268 Node* context = assembler->Parameter(5); | 271 Node* context = assembler.Parameter(5); |
269 | 272 |
270 // Check if {radix} is treated as 10 (i.e. undefined, 0 or 10). | 273 // Check if {radix} is treated as 10 (i.e. undefined, 0 or 10). |
271 Label if_radix10(assembler), if_generic(assembler, Label::kDeferred); | 274 Label if_radix10(&assembler), if_generic(&assembler, Label::kDeferred); |
272 assembler->GotoIf(assembler->WordEqual(radix, assembler->UndefinedConstant()), | 275 assembler.GotoIf(assembler.WordEqual(radix, assembler.UndefinedConstant()), |
273 &if_radix10); | 276 &if_radix10); |
274 assembler->GotoIf( | 277 assembler.GotoIf( |
275 assembler->WordEqual(radix, assembler->SmiConstant(Smi::FromInt(10))), | 278 assembler.WordEqual(radix, assembler.SmiConstant(Smi::FromInt(10))), |
276 &if_radix10); | 279 &if_radix10); |
277 assembler->GotoIf( | 280 assembler.GotoIf( |
278 assembler->WordEqual(radix, assembler->SmiConstant(Smi::FromInt(0))), | 281 assembler.WordEqual(radix, assembler.SmiConstant(Smi::FromInt(0))), |
279 &if_radix10); | 282 &if_radix10); |
280 assembler->Goto(&if_generic); | 283 assembler.Goto(&if_generic); |
281 | 284 |
282 assembler->Bind(&if_radix10); | 285 assembler.Bind(&if_radix10); |
283 { | 286 { |
284 // Check if we can avoid the ToString conversion on {input}. | 287 // Check if we can avoid the ToString conversion on {input}. |
285 Label if_inputissmi(assembler), if_inputisheapnumber(assembler), | 288 Label if_inputissmi(&assembler), if_inputisheapnumber(&assembler), |
286 if_inputisstring(assembler); | 289 if_inputisstring(&assembler); |
287 assembler->GotoIf(assembler->TaggedIsSmi(input), &if_inputissmi); | 290 assembler.GotoIf(assembler.TaggedIsSmi(input), &if_inputissmi); |
288 Node* input_map = assembler->LoadMap(input); | 291 Node* input_map = assembler.LoadMap(input); |
289 assembler->GotoIf( | 292 assembler.GotoIf( |
290 assembler->WordEqual(input_map, assembler->HeapNumberMapConstant()), | 293 assembler.WordEqual(input_map, assembler.HeapNumberMapConstant()), |
291 &if_inputisheapnumber); | 294 &if_inputisheapnumber); |
292 Node* input_instance_type = assembler->LoadMapInstanceType(input_map); | 295 Node* input_instance_type = assembler.LoadMapInstanceType(input_map); |
293 assembler->Branch(assembler->IsStringInstanceType(input_instance_type), | 296 assembler.Branch(assembler.IsStringInstanceType(input_instance_type), |
294 &if_inputisstring, &if_generic); | 297 &if_inputisstring, &if_generic); |
295 | 298 |
296 assembler->Bind(&if_inputissmi); | 299 assembler.Bind(&if_inputissmi); |
297 { | 300 { |
298 // Just return the {input}. | 301 // Just return the {input}. |
299 assembler->Return(input); | 302 assembler.Return(input); |
300 } | 303 } |
301 | 304 |
302 assembler->Bind(&if_inputisheapnumber); | 305 assembler.Bind(&if_inputisheapnumber); |
303 { | 306 { |
304 // Check if the {input} value is in Signed32 range. | 307 // Check if the {input} value is in Signed32 range. |
305 Label if_inputissigned32(assembler); | 308 Label if_inputissigned32(&assembler); |
306 Node* input_value = assembler->LoadHeapNumberValue(input); | 309 Node* input_value = assembler.LoadHeapNumberValue(input); |
307 Node* input_value32 = assembler->TruncateFloat64ToWord32(input_value); | 310 Node* input_value32 = assembler.TruncateFloat64ToWord32(input_value); |
308 assembler->GotoIf( | 311 assembler.GotoIf( |
309 assembler->Float64Equal( | 312 assembler.Float64Equal(input_value, |
310 input_value, assembler->ChangeInt32ToFloat64(input_value32)), | 313 assembler.ChangeInt32ToFloat64(input_value32)), |
311 &if_inputissigned32); | 314 &if_inputissigned32); |
312 | 315 |
313 // Check if the absolute {input} value is in the ]0.01,1e9[ range. | 316 // Check if the absolute {input} value is in the ]0.01,1e9[ range. |
314 Node* input_value_abs = assembler->Float64Abs(input_value); | 317 Node* input_value_abs = assembler.Float64Abs(input_value); |
315 | 318 |
316 assembler->GotoUnless( | 319 assembler.GotoUnless(assembler.Float64LessThan( |
317 assembler->Float64LessThan(input_value_abs, | 320 input_value_abs, assembler.Float64Constant(1e9)), |
318 assembler->Float64Constant(1e9)), | 321 &if_generic); |
319 &if_generic); | 322 assembler.Branch(assembler.Float64LessThan( |
320 assembler->Branch(assembler->Float64LessThan( | 323 assembler.Float64Constant(0.01), input_value_abs), |
321 assembler->Float64Constant(0.01), input_value_abs), | 324 &if_inputissigned32, &if_generic); |
322 &if_inputissigned32, &if_generic); | |
323 | 325 |
324 // Return the truncated int32 value, and return the tagged result. | 326 // Return the truncated int32 value, and return the tagged result. |
325 assembler->Bind(&if_inputissigned32); | 327 assembler.Bind(&if_inputissigned32); |
326 Node* result = assembler->ChangeInt32ToTagged(input_value32); | 328 Node* result = assembler.ChangeInt32ToTagged(input_value32); |
327 assembler->Return(result); | 329 assembler.Return(result); |
328 } | 330 } |
329 | 331 |
330 assembler->Bind(&if_inputisstring); | 332 assembler.Bind(&if_inputisstring); |
331 { | 333 { |
332 // Check if the String {input} has a cached array index. | 334 // Check if the String {input} has a cached array index. |
333 Node* input_hash = assembler->LoadNameHashField(input); | 335 Node* input_hash = assembler.LoadNameHashField(input); |
334 Node* input_bit = assembler->Word32And( | 336 Node* input_bit = assembler.Word32And( |
335 input_hash, | 337 input_hash, |
336 assembler->Int32Constant(String::kContainsCachedArrayIndexMask)); | 338 assembler.Int32Constant(String::kContainsCachedArrayIndexMask)); |
337 assembler->GotoIf( | 339 assembler.GotoIf( |
338 assembler->Word32NotEqual(input_bit, assembler->Int32Constant(0)), | 340 assembler.Word32NotEqual(input_bit, assembler.Int32Constant(0)), |
339 &if_generic); | 341 &if_generic); |
340 | 342 |
341 // Return the cached array index as result. | 343 // Return the cached array index as result. |
342 Node* input_index = | 344 Node* input_index = |
343 assembler->DecodeWordFromWord32<String::ArrayIndexValueBits>( | 345 assembler.DecodeWordFromWord32<String::ArrayIndexValueBits>( |
344 input_hash); | 346 input_hash); |
345 Node* result = assembler->SmiTag(input_index); | 347 Node* result = assembler.SmiTag(input_index); |
346 assembler->Return(result); | 348 assembler.Return(result); |
347 } | 349 } |
348 } | 350 } |
349 | 351 |
350 assembler->Bind(&if_generic); | 352 assembler.Bind(&if_generic); |
351 { | 353 { |
352 Node* result = | 354 Node* result = |
353 assembler->CallRuntime(Runtime::kStringParseInt, context, input, radix); | 355 assembler.CallRuntime(Runtime::kStringParseInt, context, input, radix); |
354 assembler->Return(result); | 356 assembler.Return(result); |
355 } | 357 } |
356 } | 358 } |
357 | 359 |
358 // ES6 section 20.1.3.2 Number.prototype.toExponential ( fractionDigits ) | 360 // ES6 section 20.1.3.2 Number.prototype.toExponential ( fractionDigits ) |
359 BUILTIN(NumberPrototypeToExponential) { | 361 BUILTIN(NumberPrototypeToExponential) { |
360 HandleScope scope(isolate); | 362 HandleScope scope(isolate); |
361 Handle<Object> value = args.at<Object>(0); | 363 Handle<Object> value = args.at<Object>(0); |
362 Handle<Object> fraction_digits = args.atOrUndefined(isolate, 1); | 364 Handle<Object> fraction_digits = args.atOrUndefined(isolate, 1); |
363 | 365 |
364 // Unwrap the receiver {value}. | 366 // Unwrap the receiver {value}. |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
557 : isolate->heap()->infinity_string(); | 559 : isolate->heap()->infinity_string(); |
558 } | 560 } |
559 char* const str = | 561 char* const str = |
560 DoubleToRadixCString(value_number, static_cast<int>(radix_number)); | 562 DoubleToRadixCString(value_number, static_cast<int>(radix_number)); |
561 Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str); | 563 Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str); |
562 DeleteArray(str); | 564 DeleteArray(str); |
563 return *result; | 565 return *result; |
564 } | 566 } |
565 | 567 |
566 // ES6 section 20.1.3.7 Number.prototype.valueOf ( ) | 568 // ES6 section 20.1.3.7 Number.prototype.valueOf ( ) |
567 void Builtins::Generate_NumberPrototypeValueOf(CodeStubAssembler* assembler) { | 569 void Builtins::Generate_NumberPrototypeValueOf( |
| 570 compiler::CodeAssemblerState* state) { |
568 typedef compiler::Node Node; | 571 typedef compiler::Node Node; |
569 | 572 CodeStubAssembler assembler(state); |
570 Node* receiver = assembler->Parameter(0); | 573 |
571 Node* context = assembler->Parameter(3); | 574 Node* receiver = assembler.Parameter(0); |
572 | 575 Node* context = assembler.Parameter(3); |
573 Node* result = assembler->ToThisValue( | 576 |
| 577 Node* result = assembler.ToThisValue( |
574 context, receiver, PrimitiveType::kNumber, "Number.prototype.valueOf"); | 578 context, receiver, PrimitiveType::kNumber, "Number.prototype.valueOf"); |
575 assembler->Return(result); | 579 assembler.Return(result); |
576 } | 580 } |
577 | 581 |
578 // static | 582 // static |
579 void Builtins::Generate_Add(CodeStubAssembler* assembler) { | 583 void Builtins::Generate_Add(compiler::CodeAssemblerState* state) { |
580 typedef CodeStubAssembler::Label Label; | 584 typedef CodeStubAssembler::Label Label; |
581 typedef compiler::Node Node; | 585 typedef compiler::Node Node; |
582 typedef CodeStubAssembler::Variable Variable; | 586 typedef CodeStubAssembler::Variable Variable; |
583 | 587 CodeStubAssembler assembler(state); |
584 Node* left = assembler->Parameter(0); | 588 |
585 Node* right = assembler->Parameter(1); | 589 Node* left = assembler.Parameter(0); |
586 Node* context = assembler->Parameter(2); | 590 Node* right = assembler.Parameter(1); |
| 591 Node* context = assembler.Parameter(2); |
587 | 592 |
588 // Shared entry for floating point addition. | 593 // Shared entry for floating point addition. |
589 Label do_fadd(assembler); | 594 Label do_fadd(&assembler); |
590 Variable var_fadd_lhs(assembler, MachineRepresentation::kFloat64), | 595 Variable var_fadd_lhs(&assembler, MachineRepresentation::kFloat64), |
591 var_fadd_rhs(assembler, MachineRepresentation::kFloat64); | 596 var_fadd_rhs(&assembler, MachineRepresentation::kFloat64); |
592 | 597 |
593 // We might need to loop several times due to ToPrimitive, ToString and/or | 598 // We might need to loop several times due to ToPrimitive, ToString and/or |
594 // ToNumber conversions. | 599 // ToNumber conversions. |
595 Variable var_lhs(assembler, MachineRepresentation::kTagged), | 600 Variable var_lhs(&assembler, MachineRepresentation::kTagged), |
596 var_rhs(assembler, MachineRepresentation::kTagged), | 601 var_rhs(&assembler, MachineRepresentation::kTagged), |
597 var_result(assembler, MachineRepresentation::kTagged); | 602 var_result(&assembler, MachineRepresentation::kTagged); |
598 Variable* loop_vars[2] = {&var_lhs, &var_rhs}; | 603 Variable* loop_vars[2] = {&var_lhs, &var_rhs}; |
599 Label loop(assembler, 2, loop_vars), end(assembler), | 604 Label loop(&assembler, 2, loop_vars), end(&assembler), |
600 string_add_convert_left(assembler, Label::kDeferred), | 605 string_add_convert_left(&assembler, Label::kDeferred), |
601 string_add_convert_right(assembler, Label::kDeferred); | 606 string_add_convert_right(&assembler, Label::kDeferred); |
602 var_lhs.Bind(left); | 607 var_lhs.Bind(left); |
603 var_rhs.Bind(right); | 608 var_rhs.Bind(right); |
604 assembler->Goto(&loop); | 609 assembler.Goto(&loop); |
605 assembler->Bind(&loop); | 610 assembler.Bind(&loop); |
606 { | 611 { |
607 // Load the current {lhs} and {rhs} values. | 612 // Load the current {lhs} and {rhs} values. |
608 Node* lhs = var_lhs.value(); | 613 Node* lhs = var_lhs.value(); |
609 Node* rhs = var_rhs.value(); | 614 Node* rhs = var_rhs.value(); |
610 | 615 |
611 // Check if the {lhs} is a Smi or a HeapObject. | 616 // Check if the {lhs} is a Smi or a HeapObject. |
612 Label if_lhsissmi(assembler), if_lhsisnotsmi(assembler); | 617 Label if_lhsissmi(&assembler), if_lhsisnotsmi(&assembler); |
613 assembler->Branch(assembler->TaggedIsSmi(lhs), &if_lhsissmi, | 618 assembler.Branch(assembler.TaggedIsSmi(lhs), &if_lhsissmi, &if_lhsisnotsmi); |
614 &if_lhsisnotsmi); | 619 |
615 | 620 assembler.Bind(&if_lhsissmi); |
616 assembler->Bind(&if_lhsissmi); | |
617 { | 621 { |
618 // Check if the {rhs} is also a Smi. | 622 // Check if the {rhs} is also a Smi. |
619 Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler); | 623 Label if_rhsissmi(&assembler), if_rhsisnotsmi(&assembler); |
620 assembler->Branch(assembler->TaggedIsSmi(rhs), &if_rhsissmi, | 624 assembler.Branch(assembler.TaggedIsSmi(rhs), &if_rhsissmi, |
621 &if_rhsisnotsmi); | 625 &if_rhsisnotsmi); |
622 | 626 |
623 assembler->Bind(&if_rhsissmi); | 627 assembler.Bind(&if_rhsissmi); |
624 { | 628 { |
625 // Try fast Smi addition first. | 629 // Try fast Smi addition first. |
626 Node* pair = assembler->IntPtrAddWithOverflow( | 630 Node* pair = |
627 assembler->BitcastTaggedToWord(lhs), | 631 assembler.IntPtrAddWithOverflow(assembler.BitcastTaggedToWord(lhs), |
628 assembler->BitcastTaggedToWord(rhs)); | 632 assembler.BitcastTaggedToWord(rhs)); |
629 Node* overflow = assembler->Projection(1, pair); | 633 Node* overflow = assembler.Projection(1, pair); |
630 | 634 |
631 // Check if the Smi additon overflowed. | 635 // Check if the Smi additon overflowed. |
632 Label if_overflow(assembler), if_notoverflow(assembler); | 636 Label if_overflow(&assembler), if_notoverflow(&assembler); |
633 assembler->Branch(overflow, &if_overflow, &if_notoverflow); | 637 assembler.Branch(overflow, &if_overflow, &if_notoverflow); |
634 | 638 |
635 assembler->Bind(&if_overflow); | 639 assembler.Bind(&if_overflow); |
636 { | 640 { |
637 var_fadd_lhs.Bind(assembler->SmiToFloat64(lhs)); | 641 var_fadd_lhs.Bind(assembler.SmiToFloat64(lhs)); |
638 var_fadd_rhs.Bind(assembler->SmiToFloat64(rhs)); | 642 var_fadd_rhs.Bind(assembler.SmiToFloat64(rhs)); |
639 assembler->Goto(&do_fadd); | 643 assembler.Goto(&do_fadd); |
640 } | 644 } |
641 | 645 |
642 assembler->Bind(&if_notoverflow); | 646 assembler.Bind(&if_notoverflow); |
643 var_result.Bind(assembler->BitcastWordToTaggedSigned( | 647 var_result.Bind( |
644 assembler->Projection(0, pair))); | 648 assembler.BitcastWordToTaggedSigned(assembler.Projection(0, pair))); |
645 assembler->Goto(&end); | 649 assembler.Goto(&end); |
646 } | 650 } |
647 | 651 |
648 assembler->Bind(&if_rhsisnotsmi); | 652 assembler.Bind(&if_rhsisnotsmi); |
649 { | 653 { |
650 // Load the map of {rhs}. | 654 // Load the map of {rhs}. |
651 Node* rhs_map = assembler->LoadMap(rhs); | 655 Node* rhs_map = assembler.LoadMap(rhs); |
652 | 656 |
653 // Check if the {rhs} is a HeapNumber. | 657 // Check if the {rhs} is a HeapNumber. |
654 Label if_rhsisnumber(assembler), | 658 Label if_rhsisnumber(&assembler), |
655 if_rhsisnotnumber(assembler, Label::kDeferred); | 659 if_rhsisnotnumber(&assembler, Label::kDeferred); |
656 assembler->Branch(assembler->IsHeapNumberMap(rhs_map), &if_rhsisnumber, | 660 assembler.Branch(assembler.IsHeapNumberMap(rhs_map), &if_rhsisnumber, |
657 &if_rhsisnotnumber); | 661 &if_rhsisnotnumber); |
658 | 662 |
659 assembler->Bind(&if_rhsisnumber); | 663 assembler.Bind(&if_rhsisnumber); |
660 { | 664 { |
661 var_fadd_lhs.Bind(assembler->SmiToFloat64(lhs)); | 665 var_fadd_lhs.Bind(assembler.SmiToFloat64(lhs)); |
662 var_fadd_rhs.Bind(assembler->LoadHeapNumberValue(rhs)); | 666 var_fadd_rhs.Bind(assembler.LoadHeapNumberValue(rhs)); |
663 assembler->Goto(&do_fadd); | 667 assembler.Goto(&do_fadd); |
664 } | 668 } |
665 | 669 |
666 assembler->Bind(&if_rhsisnotnumber); | 670 assembler.Bind(&if_rhsisnotnumber); |
667 { | 671 { |
668 // Load the instance type of {rhs}. | 672 // Load the instance type of {rhs}. |
669 Node* rhs_instance_type = assembler->LoadMapInstanceType(rhs_map); | 673 Node* rhs_instance_type = assembler.LoadMapInstanceType(rhs_map); |
670 | 674 |
671 // Check if the {rhs} is a String. | 675 // Check if the {rhs} is a String. |
672 Label if_rhsisstring(assembler, Label::kDeferred), | 676 Label if_rhsisstring(&assembler, Label::kDeferred), |
673 if_rhsisnotstring(assembler, Label::kDeferred); | 677 if_rhsisnotstring(&assembler, Label::kDeferred); |
674 assembler->Branch(assembler->IsStringInstanceType(rhs_instance_type), | 678 assembler.Branch(assembler.IsStringInstanceType(rhs_instance_type), |
675 &if_rhsisstring, &if_rhsisnotstring); | 679 &if_rhsisstring, &if_rhsisnotstring); |
676 | 680 |
677 assembler->Bind(&if_rhsisstring); | 681 assembler.Bind(&if_rhsisstring); |
678 { | 682 { |
679 var_lhs.Bind(lhs); | 683 var_lhs.Bind(lhs); |
680 var_rhs.Bind(rhs); | 684 var_rhs.Bind(rhs); |
681 assembler->Goto(&string_add_convert_left); | 685 assembler.Goto(&string_add_convert_left); |
682 } | 686 } |
683 | 687 |
684 assembler->Bind(&if_rhsisnotstring); | 688 assembler.Bind(&if_rhsisnotstring); |
685 { | 689 { |
686 // Check if {rhs} is a JSReceiver. | 690 // Check if {rhs} is a JSReceiver. |
687 Label if_rhsisreceiver(assembler, Label::kDeferred), | 691 Label if_rhsisreceiver(&assembler, Label::kDeferred), |
688 if_rhsisnotreceiver(assembler, Label::kDeferred); | 692 if_rhsisnotreceiver(&assembler, Label::kDeferred); |
689 assembler->Branch( | 693 assembler.Branch( |
690 assembler->IsJSReceiverInstanceType(rhs_instance_type), | 694 assembler.IsJSReceiverInstanceType(rhs_instance_type), |
691 &if_rhsisreceiver, &if_rhsisnotreceiver); | 695 &if_rhsisreceiver, &if_rhsisnotreceiver); |
692 | 696 |
693 assembler->Bind(&if_rhsisreceiver); | 697 assembler.Bind(&if_rhsisreceiver); |
694 { | 698 { |
695 // Convert {rhs} to a primitive first passing no hint. | 699 // Convert {rhs} to a primitive first passing no hint. |
696 Callable callable = | 700 Callable callable = |
697 CodeFactory::NonPrimitiveToPrimitive(assembler->isolate()); | 701 CodeFactory::NonPrimitiveToPrimitive(assembler.isolate()); |
698 var_rhs.Bind(assembler->CallStub(callable, context, rhs)); | 702 var_rhs.Bind(assembler.CallStub(callable, context, rhs)); |
699 assembler->Goto(&loop); | 703 assembler.Goto(&loop); |
700 } | 704 } |
701 | 705 |
702 assembler->Bind(&if_rhsisnotreceiver); | 706 assembler.Bind(&if_rhsisnotreceiver); |
703 { | 707 { |
704 // Convert {rhs} to a Number first. | 708 // Convert {rhs} to a Number first. |
705 Callable callable = | 709 Callable callable = |
706 CodeFactory::NonNumberToNumber(assembler->isolate()); | 710 CodeFactory::NonNumberToNumber(assembler.isolate()); |
707 var_rhs.Bind(assembler->CallStub(callable, context, rhs)); | 711 var_rhs.Bind(assembler.CallStub(callable, context, rhs)); |
708 assembler->Goto(&loop); | 712 assembler.Goto(&loop); |
709 } | 713 } |
710 } | 714 } |
711 } | 715 } |
712 } | 716 } |
713 } | 717 } |
714 | 718 |
715 assembler->Bind(&if_lhsisnotsmi); | 719 assembler.Bind(&if_lhsisnotsmi); |
716 { | 720 { |
717 // Load the map and instance type of {lhs}. | 721 // Load the map and instance type of {lhs}. |
718 Node* lhs_instance_type = assembler->LoadInstanceType(lhs); | 722 Node* lhs_instance_type = assembler.LoadInstanceType(lhs); |
719 | 723 |
720 // Check if {lhs} is a String. | 724 // Check if {lhs} is a String. |
721 Label if_lhsisstring(assembler), if_lhsisnotstring(assembler); | 725 Label if_lhsisstring(&assembler), if_lhsisnotstring(&assembler); |
722 assembler->Branch(assembler->IsStringInstanceType(lhs_instance_type), | 726 assembler.Branch(assembler.IsStringInstanceType(lhs_instance_type), |
723 &if_lhsisstring, &if_lhsisnotstring); | 727 &if_lhsisstring, &if_lhsisnotstring); |
724 | 728 |
725 assembler->Bind(&if_lhsisstring); | 729 assembler.Bind(&if_lhsisstring); |
726 { | 730 { |
727 var_lhs.Bind(lhs); | 731 var_lhs.Bind(lhs); |
728 var_rhs.Bind(rhs); | 732 var_rhs.Bind(rhs); |
729 assembler->Goto(&string_add_convert_right); | 733 assembler.Goto(&string_add_convert_right); |
730 } | 734 } |
731 | 735 |
732 assembler->Bind(&if_lhsisnotstring); | 736 assembler.Bind(&if_lhsisnotstring); |
733 { | 737 { |
734 // Check if {rhs} is a Smi. | 738 // Check if {rhs} is a Smi. |
735 Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler); | 739 Label if_rhsissmi(&assembler), if_rhsisnotsmi(&assembler); |
736 assembler->Branch(assembler->TaggedIsSmi(rhs), &if_rhsissmi, | 740 assembler.Branch(assembler.TaggedIsSmi(rhs), &if_rhsissmi, |
737 &if_rhsisnotsmi); | 741 &if_rhsisnotsmi); |
738 | 742 |
739 assembler->Bind(&if_rhsissmi); | 743 assembler.Bind(&if_rhsissmi); |
740 { | 744 { |
741 // Check if {lhs} is a Number. | 745 // Check if {lhs} is a Number. |
742 Label if_lhsisnumber(assembler), | 746 Label if_lhsisnumber(&assembler), |
743 if_lhsisnotnumber(assembler, Label::kDeferred); | 747 if_lhsisnotnumber(&assembler, Label::kDeferred); |
744 assembler->Branch(assembler->Word32Equal( | 748 assembler.Branch( |
745 lhs_instance_type, | 749 assembler.Word32Equal(lhs_instance_type, |
746 assembler->Int32Constant(HEAP_NUMBER_TYPE)), | 750 assembler.Int32Constant(HEAP_NUMBER_TYPE)), |
747 &if_lhsisnumber, &if_lhsisnotnumber); | 751 &if_lhsisnumber, &if_lhsisnotnumber); |
748 | 752 |
749 assembler->Bind(&if_lhsisnumber); | 753 assembler.Bind(&if_lhsisnumber); |
750 { | 754 { |
751 // The {lhs} is a HeapNumber, the {rhs} is a Smi, just add them. | 755 // The {lhs} is a HeapNumber, the {rhs} is a Smi, just add them. |
752 var_fadd_lhs.Bind(assembler->LoadHeapNumberValue(lhs)); | 756 var_fadd_lhs.Bind(assembler.LoadHeapNumberValue(lhs)); |
753 var_fadd_rhs.Bind(assembler->SmiToFloat64(rhs)); | 757 var_fadd_rhs.Bind(assembler.SmiToFloat64(rhs)); |
754 assembler->Goto(&do_fadd); | 758 assembler.Goto(&do_fadd); |
755 } | 759 } |
756 | 760 |
757 assembler->Bind(&if_lhsisnotnumber); | 761 assembler.Bind(&if_lhsisnotnumber); |
758 { | 762 { |
759 // The {lhs} is neither a Number nor a String, and the {rhs} is a | 763 // The {lhs} is neither a Number nor a String, and the {rhs} is a |
760 // Smi. | 764 // Smi. |
761 Label if_lhsisreceiver(assembler, Label::kDeferred), | 765 Label if_lhsisreceiver(&assembler, Label::kDeferred), |
762 if_lhsisnotreceiver(assembler, Label::kDeferred); | 766 if_lhsisnotreceiver(&assembler, Label::kDeferred); |
763 assembler->Branch( | 767 assembler.Branch( |
764 assembler->IsJSReceiverInstanceType(lhs_instance_type), | 768 assembler.IsJSReceiverInstanceType(lhs_instance_type), |
765 &if_lhsisreceiver, &if_lhsisnotreceiver); | 769 &if_lhsisreceiver, &if_lhsisnotreceiver); |
766 | 770 |
767 assembler->Bind(&if_lhsisreceiver); | 771 assembler.Bind(&if_lhsisreceiver); |
768 { | 772 { |
769 // Convert {lhs} to a primitive first passing no hint. | 773 // Convert {lhs} to a primitive first passing no hint. |
770 Callable callable = | 774 Callable callable = |
771 CodeFactory::NonPrimitiveToPrimitive(assembler->isolate()); | 775 CodeFactory::NonPrimitiveToPrimitive(assembler.isolate()); |
772 var_lhs.Bind(assembler->CallStub(callable, context, lhs)); | 776 var_lhs.Bind(assembler.CallStub(callable, context, lhs)); |
773 assembler->Goto(&loop); | 777 assembler.Goto(&loop); |
774 } | 778 } |
775 | 779 |
776 assembler->Bind(&if_lhsisnotreceiver); | 780 assembler.Bind(&if_lhsisnotreceiver); |
777 { | 781 { |
778 // Convert {lhs} to a Number first. | 782 // Convert {lhs} to a Number first. |
779 Callable callable = | 783 Callable callable = |
780 CodeFactory::NonNumberToNumber(assembler->isolate()); | 784 CodeFactory::NonNumberToNumber(assembler.isolate()); |
781 var_lhs.Bind(assembler->CallStub(callable, context, lhs)); | 785 var_lhs.Bind(assembler.CallStub(callable, context, lhs)); |
782 assembler->Goto(&loop); | 786 assembler.Goto(&loop); |
783 } | 787 } |
784 } | 788 } |
785 } | 789 } |
786 | 790 |
787 assembler->Bind(&if_rhsisnotsmi); | 791 assembler.Bind(&if_rhsisnotsmi); |
788 { | 792 { |
789 // Load the instance type of {rhs}. | 793 // Load the instance type of {rhs}. |
790 Node* rhs_instance_type = assembler->LoadInstanceType(rhs); | 794 Node* rhs_instance_type = assembler.LoadInstanceType(rhs); |
791 | 795 |
792 // Check if {rhs} is a String. | 796 // Check if {rhs} is a String. |
793 Label if_rhsisstring(assembler), if_rhsisnotstring(assembler); | 797 Label if_rhsisstring(&assembler), if_rhsisnotstring(&assembler); |
794 assembler->Branch(assembler->IsStringInstanceType(rhs_instance_type), | 798 assembler.Branch(assembler.IsStringInstanceType(rhs_instance_type), |
795 &if_rhsisstring, &if_rhsisnotstring); | 799 &if_rhsisstring, &if_rhsisnotstring); |
796 | 800 |
797 assembler->Bind(&if_rhsisstring); | 801 assembler.Bind(&if_rhsisstring); |
798 { | 802 { |
799 var_lhs.Bind(lhs); | 803 var_lhs.Bind(lhs); |
800 var_rhs.Bind(rhs); | 804 var_rhs.Bind(rhs); |
801 assembler->Goto(&string_add_convert_left); | 805 assembler.Goto(&string_add_convert_left); |
802 } | 806 } |
803 | 807 |
804 assembler->Bind(&if_rhsisnotstring); | 808 assembler.Bind(&if_rhsisnotstring); |
805 { | 809 { |
806 // Check if {lhs} is a HeapNumber. | 810 // Check if {lhs} is a HeapNumber. |
807 Label if_lhsisnumber(assembler), if_lhsisnotnumber(assembler); | 811 Label if_lhsisnumber(&assembler), if_lhsisnotnumber(&assembler); |
808 assembler->Branch(assembler->Word32Equal( | 812 assembler.Branch(assembler.Word32Equal( |
809 lhs_instance_type, | 813 lhs_instance_type, |
810 assembler->Int32Constant(HEAP_NUMBER_TYPE)), | 814 assembler.Int32Constant(HEAP_NUMBER_TYPE)), |
811 &if_lhsisnumber, &if_lhsisnotnumber); | 815 &if_lhsisnumber, &if_lhsisnotnumber); |
812 | 816 |
813 assembler->Bind(&if_lhsisnumber); | 817 assembler.Bind(&if_lhsisnumber); |
814 { | 818 { |
815 // Check if {rhs} is also a HeapNumber. | 819 // Check if {rhs} is also a HeapNumber. |
816 Label if_rhsisnumber(assembler), | 820 Label if_rhsisnumber(&assembler), |
817 if_rhsisnotnumber(assembler, Label::kDeferred); | 821 if_rhsisnotnumber(&assembler, Label::kDeferred); |
818 assembler->Branch(assembler->Word32Equal( | 822 assembler.Branch(assembler.Word32Equal( |
819 rhs_instance_type, | 823 rhs_instance_type, |
820 assembler->Int32Constant(HEAP_NUMBER_TYPE)), | 824 assembler.Int32Constant(HEAP_NUMBER_TYPE)), |
821 &if_rhsisnumber, &if_rhsisnotnumber); | 825 &if_rhsisnumber, &if_rhsisnotnumber); |
822 | 826 |
823 assembler->Bind(&if_rhsisnumber); | 827 assembler.Bind(&if_rhsisnumber); |
824 { | 828 { |
825 // Perform a floating point addition. | 829 // Perform a floating point addition. |
826 var_fadd_lhs.Bind(assembler->LoadHeapNumberValue(lhs)); | 830 var_fadd_lhs.Bind(assembler.LoadHeapNumberValue(lhs)); |
827 var_fadd_rhs.Bind(assembler->LoadHeapNumberValue(rhs)); | 831 var_fadd_rhs.Bind(assembler.LoadHeapNumberValue(rhs)); |
828 assembler->Goto(&do_fadd); | 832 assembler.Goto(&do_fadd); |
829 } | 833 } |
830 | 834 |
831 assembler->Bind(&if_rhsisnotnumber); | 835 assembler.Bind(&if_rhsisnotnumber); |
832 { | 836 { |
833 // Check if {rhs} is a JSReceiver. | 837 // Check if {rhs} is a JSReceiver. |
834 Label if_rhsisreceiver(assembler, Label::kDeferred), | 838 Label if_rhsisreceiver(&assembler, Label::kDeferred), |
835 if_rhsisnotreceiver(assembler, Label::kDeferred); | 839 if_rhsisnotreceiver(&assembler, Label::kDeferred); |
836 assembler->Branch( | 840 assembler.Branch( |
837 assembler->IsJSReceiverInstanceType(rhs_instance_type), | 841 assembler.IsJSReceiverInstanceType(rhs_instance_type), |
838 &if_rhsisreceiver, &if_rhsisnotreceiver); | 842 &if_rhsisreceiver, &if_rhsisnotreceiver); |
839 | 843 |
840 assembler->Bind(&if_rhsisreceiver); | 844 assembler.Bind(&if_rhsisreceiver); |
841 { | 845 { |
842 // Convert {rhs} to a primitive first passing no hint. | 846 // Convert {rhs} to a primitive first passing no hint. |
843 Callable callable = CodeFactory::NonPrimitiveToPrimitive( | 847 Callable callable = |
844 assembler->isolate()); | 848 CodeFactory::NonPrimitiveToPrimitive(assembler.isolate()); |
845 var_rhs.Bind(assembler->CallStub(callable, context, rhs)); | 849 var_rhs.Bind(assembler.CallStub(callable, context, rhs)); |
846 assembler->Goto(&loop); | 850 assembler.Goto(&loop); |
847 } | 851 } |
848 | 852 |
849 assembler->Bind(&if_rhsisnotreceiver); | 853 assembler.Bind(&if_rhsisnotreceiver); |
850 { | 854 { |
851 // Convert {rhs} to a Number first. | 855 // Convert {rhs} to a Number first. |
852 Callable callable = | 856 Callable callable = |
853 CodeFactory::NonNumberToNumber(assembler->isolate()); | 857 CodeFactory::NonNumberToNumber(assembler.isolate()); |
854 var_rhs.Bind(assembler->CallStub(callable, context, rhs)); | 858 var_rhs.Bind(assembler.CallStub(callable, context, rhs)); |
855 assembler->Goto(&loop); | 859 assembler.Goto(&loop); |
856 } | 860 } |
857 } | 861 } |
858 } | 862 } |
859 | 863 |
860 assembler->Bind(&if_lhsisnotnumber); | 864 assembler.Bind(&if_lhsisnotnumber); |
861 { | 865 { |
862 // Check if {lhs} is a JSReceiver. | 866 // Check if {lhs} is a JSReceiver. |
863 Label if_lhsisreceiver(assembler, Label::kDeferred), | 867 Label if_lhsisreceiver(&assembler, Label::kDeferred), |
864 if_lhsisnotreceiver(assembler); | 868 if_lhsisnotreceiver(&assembler); |
865 assembler->Branch( | 869 assembler.Branch( |
866 assembler->IsJSReceiverInstanceType(lhs_instance_type), | 870 assembler.IsJSReceiverInstanceType(lhs_instance_type), |
867 &if_lhsisreceiver, &if_lhsisnotreceiver); | 871 &if_lhsisreceiver, &if_lhsisnotreceiver); |
868 | 872 |
869 assembler->Bind(&if_lhsisreceiver); | 873 assembler.Bind(&if_lhsisreceiver); |
870 { | 874 { |
871 // Convert {lhs} to a primitive first passing no hint. | 875 // Convert {lhs} to a primitive first passing no hint. |
872 Callable callable = | 876 Callable callable = |
873 CodeFactory::NonPrimitiveToPrimitive(assembler->isolate()); | 877 CodeFactory::NonPrimitiveToPrimitive(assembler.isolate()); |
874 var_lhs.Bind(assembler->CallStub(callable, context, lhs)); | 878 var_lhs.Bind(assembler.CallStub(callable, context, lhs)); |
875 assembler->Goto(&loop); | 879 assembler.Goto(&loop); |
876 } | 880 } |
877 | 881 |
878 assembler->Bind(&if_lhsisnotreceiver); | 882 assembler.Bind(&if_lhsisnotreceiver); |
879 { | 883 { |
880 // Check if {rhs} is a JSReceiver. | 884 // Check if {rhs} is a JSReceiver. |
881 Label if_rhsisreceiver(assembler, Label::kDeferred), | 885 Label if_rhsisreceiver(&assembler, Label::kDeferred), |
882 if_rhsisnotreceiver(assembler, Label::kDeferred); | 886 if_rhsisnotreceiver(&assembler, Label::kDeferred); |
883 assembler->Branch( | 887 assembler.Branch( |
884 assembler->IsJSReceiverInstanceType(rhs_instance_type), | 888 assembler.IsJSReceiverInstanceType(rhs_instance_type), |
885 &if_rhsisreceiver, &if_rhsisnotreceiver); | 889 &if_rhsisreceiver, &if_rhsisnotreceiver); |
886 | 890 |
887 assembler->Bind(&if_rhsisreceiver); | 891 assembler.Bind(&if_rhsisreceiver); |
888 { | 892 { |
889 // Convert {rhs} to a primitive first passing no hint. | 893 // Convert {rhs} to a primitive first passing no hint. |
890 Callable callable = CodeFactory::NonPrimitiveToPrimitive( | 894 Callable callable = |
891 assembler->isolate()); | 895 CodeFactory::NonPrimitiveToPrimitive(assembler.isolate()); |
892 var_rhs.Bind(assembler->CallStub(callable, context, rhs)); | 896 var_rhs.Bind(assembler.CallStub(callable, context, rhs)); |
893 assembler->Goto(&loop); | 897 assembler.Goto(&loop); |
894 } | 898 } |
895 | 899 |
896 assembler->Bind(&if_rhsisnotreceiver); | 900 assembler.Bind(&if_rhsisnotreceiver); |
897 { | 901 { |
898 // Convert {lhs} to a Number first. | 902 // Convert {lhs} to a Number first. |
899 Callable callable = | 903 Callable callable = |
900 CodeFactory::NonNumberToNumber(assembler->isolate()); | 904 CodeFactory::NonNumberToNumber(assembler.isolate()); |
901 var_lhs.Bind(assembler->CallStub(callable, context, lhs)); | 905 var_lhs.Bind(assembler.CallStub(callable, context, lhs)); |
902 assembler->Goto(&loop); | 906 assembler.Goto(&loop); |
903 } | 907 } |
904 } | 908 } |
905 } | 909 } |
906 } | 910 } |
907 } | 911 } |
908 } | 912 } |
909 } | 913 } |
910 } | 914 } |
911 assembler->Bind(&string_add_convert_left); | 915 assembler.Bind(&string_add_convert_left); |
912 { | 916 { |
913 // Convert {lhs}, which is a Smi, to a String and concatenate the | 917 // Convert {lhs}, which is a Smi, to a String and concatenate the |
914 // resulting string with the String {rhs}. | 918 // resulting string with the String {rhs}. |
915 Callable callable = CodeFactory::StringAdd( | 919 Callable callable = CodeFactory::StringAdd( |
916 assembler->isolate(), STRING_ADD_CONVERT_LEFT, NOT_TENURED); | 920 assembler.isolate(), STRING_ADD_CONVERT_LEFT, NOT_TENURED); |
917 var_result.Bind(assembler->CallStub(callable, context, var_lhs.value(), | 921 var_result.Bind(assembler.CallStub(callable, context, var_lhs.value(), |
918 var_rhs.value())); | 922 var_rhs.value())); |
919 assembler->Goto(&end); | 923 assembler.Goto(&end); |
920 } | 924 } |
921 | 925 |
922 assembler->Bind(&string_add_convert_right); | 926 assembler.Bind(&string_add_convert_right); |
923 { | 927 { |
924 // Convert {lhs}, which is a Smi, to a String and concatenate the | 928 // Convert {lhs}, which is a Smi, to a String and concatenate the |
925 // resulting string with the String {rhs}. | 929 // resulting string with the String {rhs}. |
926 Callable callable = CodeFactory::StringAdd( | 930 Callable callable = CodeFactory::StringAdd( |
927 assembler->isolate(), STRING_ADD_CONVERT_RIGHT, NOT_TENURED); | 931 assembler.isolate(), STRING_ADD_CONVERT_RIGHT, NOT_TENURED); |
928 var_result.Bind(assembler->CallStub(callable, context, var_lhs.value(), | 932 var_result.Bind(assembler.CallStub(callable, context, var_lhs.value(), |
929 var_rhs.value())); | 933 var_rhs.value())); |
930 assembler->Goto(&end); | 934 assembler.Goto(&end); |
931 } | 935 } |
932 | 936 |
933 assembler->Bind(&do_fadd); | 937 assembler.Bind(&do_fadd); |
934 { | 938 { |
935 Node* lhs_value = var_fadd_lhs.value(); | 939 Node* lhs_value = var_fadd_lhs.value(); |
936 Node* rhs_value = var_fadd_rhs.value(); | 940 Node* rhs_value = var_fadd_rhs.value(); |
937 Node* value = assembler->Float64Add(lhs_value, rhs_value); | 941 Node* value = assembler.Float64Add(lhs_value, rhs_value); |
938 Node* result = assembler->AllocateHeapNumberWithValue(value); | 942 Node* result = assembler.AllocateHeapNumberWithValue(value); |
939 var_result.Bind(result); | 943 var_result.Bind(result); |
940 assembler->Goto(&end); | 944 assembler.Goto(&end); |
941 } | 945 } |
942 assembler->Bind(&end); | 946 assembler.Bind(&end); |
943 assembler->Return(var_result.value()); | 947 assembler.Return(var_result.value()); |
944 } | 948 } |
945 | 949 |
946 void Builtins::Generate_Subtract(CodeStubAssembler* assembler) { | 950 void Builtins::Generate_Subtract(compiler::CodeAssemblerState* state) { |
947 typedef CodeStubAssembler::Label Label; | 951 typedef CodeStubAssembler::Label Label; |
948 typedef compiler::Node Node; | 952 typedef compiler::Node Node; |
949 typedef CodeStubAssembler::Variable Variable; | 953 typedef CodeStubAssembler::Variable Variable; |
950 | 954 CodeStubAssembler assembler(state); |
951 Node* left = assembler->Parameter(0); | 955 |
952 Node* right = assembler->Parameter(1); | 956 Node* left = assembler.Parameter(0); |
953 Node* context = assembler->Parameter(2); | 957 Node* right = assembler.Parameter(1); |
| 958 Node* context = assembler.Parameter(2); |
954 | 959 |
955 // Shared entry for floating point subtraction. | 960 // Shared entry for floating point subtraction. |
956 Label do_fsub(assembler), end(assembler); | 961 Label do_fsub(&assembler), end(&assembler); |
957 Variable var_fsub_lhs(assembler, MachineRepresentation::kFloat64), | 962 Variable var_fsub_lhs(&assembler, MachineRepresentation::kFloat64), |
958 var_fsub_rhs(assembler, MachineRepresentation::kFloat64); | 963 var_fsub_rhs(&assembler, MachineRepresentation::kFloat64); |
959 | 964 |
960 // We might need to loop several times due to ToPrimitive and/or ToNumber | 965 // We might need to loop several times due to ToPrimitive and/or ToNumber |
961 // conversions. | 966 // conversions. |
962 Variable var_lhs(assembler, MachineRepresentation::kTagged), | 967 Variable var_lhs(&assembler, MachineRepresentation::kTagged), |
963 var_rhs(assembler, MachineRepresentation::kTagged), | 968 var_rhs(&assembler, MachineRepresentation::kTagged), |
964 var_result(assembler, MachineRepresentation::kTagged); | 969 var_result(&assembler, MachineRepresentation::kTagged); |
965 Variable* loop_vars[2] = {&var_lhs, &var_rhs}; | 970 Variable* loop_vars[2] = {&var_lhs, &var_rhs}; |
966 Label loop(assembler, 2, loop_vars); | 971 Label loop(&assembler, 2, loop_vars); |
967 var_lhs.Bind(left); | 972 var_lhs.Bind(left); |
968 var_rhs.Bind(right); | 973 var_rhs.Bind(right); |
969 assembler->Goto(&loop); | 974 assembler.Goto(&loop); |
970 assembler->Bind(&loop); | 975 assembler.Bind(&loop); |
971 { | 976 { |
972 // Load the current {lhs} and {rhs} values. | 977 // Load the current {lhs} and {rhs} values. |
973 Node* lhs = var_lhs.value(); | 978 Node* lhs = var_lhs.value(); |
974 Node* rhs = var_rhs.value(); | 979 Node* rhs = var_rhs.value(); |
975 | 980 |
976 // Check if the {lhs} is a Smi or a HeapObject. | 981 // Check if the {lhs} is a Smi or a HeapObject. |
977 Label if_lhsissmi(assembler), if_lhsisnotsmi(assembler); | 982 Label if_lhsissmi(&assembler), if_lhsisnotsmi(&assembler); |
978 assembler->Branch(assembler->TaggedIsSmi(lhs), &if_lhsissmi, | 983 assembler.Branch(assembler.TaggedIsSmi(lhs), &if_lhsissmi, &if_lhsisnotsmi); |
979 &if_lhsisnotsmi); | 984 |
980 | 985 assembler.Bind(&if_lhsissmi); |
981 assembler->Bind(&if_lhsissmi); | |
982 { | 986 { |
983 // Check if the {rhs} is also a Smi. | 987 // Check if the {rhs} is also a Smi. |
984 Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler); | 988 Label if_rhsissmi(&assembler), if_rhsisnotsmi(&assembler); |
985 assembler->Branch(assembler->TaggedIsSmi(rhs), &if_rhsissmi, | 989 assembler.Branch(assembler.TaggedIsSmi(rhs), &if_rhsissmi, |
986 &if_rhsisnotsmi); | 990 &if_rhsisnotsmi); |
987 | 991 |
988 assembler->Bind(&if_rhsissmi); | 992 assembler.Bind(&if_rhsissmi); |
989 { | 993 { |
990 // Try a fast Smi subtraction first. | 994 // Try a fast Smi subtraction first. |
991 Node* pair = assembler->IntPtrSubWithOverflow( | 995 Node* pair = |
992 assembler->BitcastTaggedToWord(lhs), | 996 assembler.IntPtrSubWithOverflow(assembler.BitcastTaggedToWord(lhs), |
993 assembler->BitcastTaggedToWord(rhs)); | 997 assembler.BitcastTaggedToWord(rhs)); |
994 Node* overflow = assembler->Projection(1, pair); | 998 Node* overflow = assembler.Projection(1, pair); |
995 | 999 |
996 // Check if the Smi subtraction overflowed. | 1000 // Check if the Smi subtraction overflowed. |
997 Label if_overflow(assembler), if_notoverflow(assembler); | 1001 Label if_overflow(&assembler), if_notoverflow(&assembler); |
998 assembler->Branch(overflow, &if_overflow, &if_notoverflow); | 1002 assembler.Branch(overflow, &if_overflow, &if_notoverflow); |
999 | 1003 |
1000 assembler->Bind(&if_overflow); | 1004 assembler.Bind(&if_overflow); |
1001 { | 1005 { |
1002 // The result doesn't fit into Smi range. | 1006 // The result doesn't fit into Smi range. |
1003 var_fsub_lhs.Bind(assembler->SmiToFloat64(lhs)); | 1007 var_fsub_lhs.Bind(assembler.SmiToFloat64(lhs)); |
1004 var_fsub_rhs.Bind(assembler->SmiToFloat64(rhs)); | 1008 var_fsub_rhs.Bind(assembler.SmiToFloat64(rhs)); |
1005 assembler->Goto(&do_fsub); | 1009 assembler.Goto(&do_fsub); |
1006 } | 1010 } |
1007 | 1011 |
1008 assembler->Bind(&if_notoverflow); | 1012 assembler.Bind(&if_notoverflow); |
1009 var_result.Bind(assembler->BitcastWordToTaggedSigned( | 1013 var_result.Bind( |
1010 assembler->Projection(0, pair))); | 1014 assembler.BitcastWordToTaggedSigned(assembler.Projection(0, pair))); |
1011 assembler->Goto(&end); | 1015 assembler.Goto(&end); |
1012 } | 1016 } |
1013 | 1017 |
1014 assembler->Bind(&if_rhsisnotsmi); | 1018 assembler.Bind(&if_rhsisnotsmi); |
1015 { | 1019 { |
1016 // Load the map of the {rhs}. | 1020 // Load the map of the {rhs}. |
1017 Node* rhs_map = assembler->LoadMap(rhs); | 1021 Node* rhs_map = assembler.LoadMap(rhs); |
1018 | 1022 |
1019 // Check if {rhs} is a HeapNumber. | 1023 // Check if {rhs} is a HeapNumber. |
1020 Label if_rhsisnumber(assembler), | 1024 Label if_rhsisnumber(&assembler), |
1021 if_rhsisnotnumber(assembler, Label::kDeferred); | 1025 if_rhsisnotnumber(&assembler, Label::kDeferred); |
1022 assembler->Branch(assembler->IsHeapNumberMap(rhs_map), &if_rhsisnumber, | 1026 assembler.Branch(assembler.IsHeapNumberMap(rhs_map), &if_rhsisnumber, |
1023 &if_rhsisnotnumber); | 1027 &if_rhsisnotnumber); |
1024 | 1028 |
1025 assembler->Bind(&if_rhsisnumber); | 1029 assembler.Bind(&if_rhsisnumber); |
1026 { | 1030 { |
1027 // Perform a floating point subtraction. | 1031 // Perform a floating point subtraction. |
1028 var_fsub_lhs.Bind(assembler->SmiToFloat64(lhs)); | 1032 var_fsub_lhs.Bind(assembler.SmiToFloat64(lhs)); |
1029 var_fsub_rhs.Bind(assembler->LoadHeapNumberValue(rhs)); | 1033 var_fsub_rhs.Bind(assembler.LoadHeapNumberValue(rhs)); |
1030 assembler->Goto(&do_fsub); | 1034 assembler.Goto(&do_fsub); |
1031 } | 1035 } |
1032 | 1036 |
1033 assembler->Bind(&if_rhsisnotnumber); | 1037 assembler.Bind(&if_rhsisnotnumber); |
1034 { | 1038 { |
1035 // Convert the {rhs} to a Number first. | 1039 // Convert the {rhs} to a Number first. |
1036 Callable callable = | 1040 Callable callable = |
1037 CodeFactory::NonNumberToNumber(assembler->isolate()); | 1041 CodeFactory::NonNumberToNumber(assembler.isolate()); |
1038 var_rhs.Bind(assembler->CallStub(callable, context, rhs)); | 1042 var_rhs.Bind(assembler.CallStub(callable, context, rhs)); |
1039 assembler->Goto(&loop); | 1043 assembler.Goto(&loop); |
1040 } | 1044 } |
1041 } | 1045 } |
1042 } | 1046 } |
1043 | 1047 |
1044 assembler->Bind(&if_lhsisnotsmi); | 1048 assembler.Bind(&if_lhsisnotsmi); |
1045 { | 1049 { |
1046 // Load the map of the {lhs}. | 1050 // Load the map of the {lhs}. |
1047 Node* lhs_map = assembler->LoadMap(lhs); | 1051 Node* lhs_map = assembler.LoadMap(lhs); |
1048 | 1052 |
1049 // Check if the {lhs} is a HeapNumber. | 1053 // Check if the {lhs} is a HeapNumber. |
1050 Label if_lhsisnumber(assembler), | 1054 Label if_lhsisnumber(&assembler), |
1051 if_lhsisnotnumber(assembler, Label::kDeferred); | 1055 if_lhsisnotnumber(&assembler, Label::kDeferred); |
1052 Node* number_map = assembler->HeapNumberMapConstant(); | 1056 Node* number_map = assembler.HeapNumberMapConstant(); |
1053 assembler->Branch(assembler->WordEqual(lhs_map, number_map), | 1057 assembler.Branch(assembler.WordEqual(lhs_map, number_map), |
1054 &if_lhsisnumber, &if_lhsisnotnumber); | 1058 &if_lhsisnumber, &if_lhsisnotnumber); |
1055 | 1059 |
1056 assembler->Bind(&if_lhsisnumber); | 1060 assembler.Bind(&if_lhsisnumber); |
1057 { | 1061 { |
1058 // Check if the {rhs} is a Smi. | 1062 // Check if the {rhs} is a Smi. |
1059 Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler); | 1063 Label if_rhsissmi(&assembler), if_rhsisnotsmi(&assembler); |
1060 assembler->Branch(assembler->TaggedIsSmi(rhs), &if_rhsissmi, | 1064 assembler.Branch(assembler.TaggedIsSmi(rhs), &if_rhsissmi, |
1061 &if_rhsisnotsmi); | 1065 &if_rhsisnotsmi); |
1062 | 1066 |
1063 assembler->Bind(&if_rhsissmi); | 1067 assembler.Bind(&if_rhsissmi); |
1064 { | 1068 { |
1065 // Perform a floating point subtraction. | 1069 // Perform a floating point subtraction. |
1066 var_fsub_lhs.Bind(assembler->LoadHeapNumberValue(lhs)); | 1070 var_fsub_lhs.Bind(assembler.LoadHeapNumberValue(lhs)); |
1067 var_fsub_rhs.Bind(assembler->SmiToFloat64(rhs)); | 1071 var_fsub_rhs.Bind(assembler.SmiToFloat64(rhs)); |
1068 assembler->Goto(&do_fsub); | 1072 assembler.Goto(&do_fsub); |
1069 } | 1073 } |
1070 | 1074 |
1071 assembler->Bind(&if_rhsisnotsmi); | 1075 assembler.Bind(&if_rhsisnotsmi); |
1072 { | 1076 { |
1073 // Load the map of the {rhs}. | 1077 // Load the map of the {rhs}. |
1074 Node* rhs_map = assembler->LoadMap(rhs); | 1078 Node* rhs_map = assembler.LoadMap(rhs); |
1075 | 1079 |
1076 // Check if the {rhs} is a HeapNumber. | 1080 // Check if the {rhs} is a HeapNumber. |
1077 Label if_rhsisnumber(assembler), | 1081 Label if_rhsisnumber(&assembler), |
1078 if_rhsisnotnumber(assembler, Label::kDeferred); | 1082 if_rhsisnotnumber(&assembler, Label::kDeferred); |
1079 assembler->Branch(assembler->WordEqual(rhs_map, number_map), | 1083 assembler.Branch(assembler.WordEqual(rhs_map, number_map), |
1080 &if_rhsisnumber, &if_rhsisnotnumber); | 1084 &if_rhsisnumber, &if_rhsisnotnumber); |
1081 | 1085 |
1082 assembler->Bind(&if_rhsisnumber); | 1086 assembler.Bind(&if_rhsisnumber); |
1083 { | 1087 { |
1084 // Perform a floating point subtraction. | 1088 // Perform a floating point subtraction. |
1085 var_fsub_lhs.Bind(assembler->LoadHeapNumberValue(lhs)); | 1089 var_fsub_lhs.Bind(assembler.LoadHeapNumberValue(lhs)); |
1086 var_fsub_rhs.Bind(assembler->LoadHeapNumberValue(rhs)); | 1090 var_fsub_rhs.Bind(assembler.LoadHeapNumberValue(rhs)); |
1087 assembler->Goto(&do_fsub); | 1091 assembler.Goto(&do_fsub); |
1088 } | 1092 } |
1089 | 1093 |
1090 assembler->Bind(&if_rhsisnotnumber); | 1094 assembler.Bind(&if_rhsisnotnumber); |
1091 { | 1095 { |
1092 // Convert the {rhs} to a Number first. | 1096 // Convert the {rhs} to a Number first. |
1093 Callable callable = | 1097 Callable callable = |
1094 CodeFactory::NonNumberToNumber(assembler->isolate()); | 1098 CodeFactory::NonNumberToNumber(assembler.isolate()); |
1095 var_rhs.Bind(assembler->CallStub(callable, context, rhs)); | 1099 var_rhs.Bind(assembler.CallStub(callable, context, rhs)); |
1096 assembler->Goto(&loop); | 1100 assembler.Goto(&loop); |
1097 } | 1101 } |
1098 } | 1102 } |
1099 } | 1103 } |
1100 | 1104 |
1101 assembler->Bind(&if_lhsisnotnumber); | 1105 assembler.Bind(&if_lhsisnotnumber); |
1102 { | 1106 { |
1103 // Convert the {lhs} to a Number first. | 1107 // Convert the {lhs} to a Number first. |
1104 Callable callable = | 1108 Callable callable = CodeFactory::NonNumberToNumber(assembler.isolate()); |
1105 CodeFactory::NonNumberToNumber(assembler->isolate()); | 1109 var_lhs.Bind(assembler.CallStub(callable, context, lhs)); |
1106 var_lhs.Bind(assembler->CallStub(callable, context, lhs)); | 1110 assembler.Goto(&loop); |
1107 assembler->Goto(&loop); | |
1108 } | 1111 } |
1109 } | 1112 } |
1110 } | 1113 } |
1111 | 1114 |
1112 assembler->Bind(&do_fsub); | 1115 assembler.Bind(&do_fsub); |
1113 { | 1116 { |
1114 Node* lhs_value = var_fsub_lhs.value(); | 1117 Node* lhs_value = var_fsub_lhs.value(); |
1115 Node* rhs_value = var_fsub_rhs.value(); | 1118 Node* rhs_value = var_fsub_rhs.value(); |
1116 Node* value = assembler->Float64Sub(lhs_value, rhs_value); | 1119 Node* value = assembler.Float64Sub(lhs_value, rhs_value); |
1117 var_result.Bind(assembler->AllocateHeapNumberWithValue(value)); | 1120 var_result.Bind(assembler.AllocateHeapNumberWithValue(value)); |
1118 assembler->Goto(&end); | 1121 assembler.Goto(&end); |
1119 } | 1122 } |
1120 assembler->Bind(&end); | 1123 assembler.Bind(&end); |
1121 assembler->Return(var_result.value()); | 1124 assembler.Return(var_result.value()); |
1122 } | 1125 } |
1123 | 1126 |
1124 void Builtins::Generate_Multiply(CodeStubAssembler* assembler) { | 1127 void Builtins::Generate_Multiply(compiler::CodeAssemblerState* state) { |
1125 typedef CodeStubAssembler::Label Label; | 1128 typedef CodeStubAssembler::Label Label; |
1126 typedef compiler::Node Node; | 1129 typedef compiler::Node Node; |
1127 typedef CodeStubAssembler::Variable Variable; | 1130 typedef CodeStubAssembler::Variable Variable; |
1128 | 1131 CodeStubAssembler assembler(state); |
1129 Node* left = assembler->Parameter(0); | 1132 |
1130 Node* right = assembler->Parameter(1); | 1133 Node* left = assembler.Parameter(0); |
1131 Node* context = assembler->Parameter(2); | 1134 Node* right = assembler.Parameter(1); |
| 1135 Node* context = assembler.Parameter(2); |
1132 | 1136 |
1133 // Shared entry point for floating point multiplication. | 1137 // Shared entry point for floating point multiplication. |
1134 Label do_fmul(assembler), return_result(assembler); | 1138 Label do_fmul(&assembler), return_result(&assembler); |
1135 Variable var_lhs_float64(assembler, MachineRepresentation::kFloat64), | 1139 Variable var_lhs_float64(&assembler, MachineRepresentation::kFloat64), |
1136 var_rhs_float64(assembler, MachineRepresentation::kFloat64); | 1140 var_rhs_float64(&assembler, MachineRepresentation::kFloat64); |
1137 | 1141 |
1138 Node* number_map = assembler->HeapNumberMapConstant(); | 1142 Node* number_map = assembler.HeapNumberMapConstant(); |
1139 | 1143 |
1140 // We might need to loop one or two times due to ToNumber conversions. | 1144 // We might need to loop one or two times due to ToNumber conversions. |
1141 Variable var_lhs(assembler, MachineRepresentation::kTagged), | 1145 Variable var_lhs(&assembler, MachineRepresentation::kTagged), |
1142 var_rhs(assembler, MachineRepresentation::kTagged), | 1146 var_rhs(&assembler, MachineRepresentation::kTagged), |
1143 var_result(assembler, MachineRepresentation::kTagged); | 1147 var_result(&assembler, MachineRepresentation::kTagged); |
1144 Variable* loop_variables[] = {&var_lhs, &var_rhs}; | 1148 Variable* loop_variables[] = {&var_lhs, &var_rhs}; |
1145 Label loop(assembler, 2, loop_variables); | 1149 Label loop(&assembler, 2, loop_variables); |
1146 var_lhs.Bind(left); | 1150 var_lhs.Bind(left); |
1147 var_rhs.Bind(right); | 1151 var_rhs.Bind(right); |
1148 assembler->Goto(&loop); | 1152 assembler.Goto(&loop); |
1149 assembler->Bind(&loop); | 1153 assembler.Bind(&loop); |
1150 { | 1154 { |
1151 Node* lhs = var_lhs.value(); | 1155 Node* lhs = var_lhs.value(); |
1152 Node* rhs = var_rhs.value(); | 1156 Node* rhs = var_rhs.value(); |
1153 | 1157 |
1154 Label lhs_is_smi(assembler), lhs_is_not_smi(assembler); | 1158 Label lhs_is_smi(&assembler), lhs_is_not_smi(&assembler); |
1155 assembler->Branch(assembler->TaggedIsSmi(lhs), &lhs_is_smi, | 1159 assembler.Branch(assembler.TaggedIsSmi(lhs), &lhs_is_smi, &lhs_is_not_smi); |
1156 &lhs_is_not_smi); | 1160 |
1157 | 1161 assembler.Bind(&lhs_is_smi); |
1158 assembler->Bind(&lhs_is_smi); | |
1159 { | 1162 { |
1160 Label rhs_is_smi(assembler), rhs_is_not_smi(assembler); | 1163 Label rhs_is_smi(&assembler), rhs_is_not_smi(&assembler); |
1161 assembler->Branch(assembler->TaggedIsSmi(rhs), &rhs_is_smi, | 1164 assembler.Branch(assembler.TaggedIsSmi(rhs), &rhs_is_smi, |
1162 &rhs_is_not_smi); | 1165 &rhs_is_not_smi); |
1163 | 1166 |
1164 assembler->Bind(&rhs_is_smi); | 1167 assembler.Bind(&rhs_is_smi); |
1165 { | 1168 { |
1166 // Both {lhs} and {rhs} are Smis. The result is not necessarily a smi, | 1169 // Both {lhs} and {rhs} are Smis. The result is not necessarily a smi, |
1167 // in case of overflow. | 1170 // in case of overflow. |
1168 var_result.Bind(assembler->SmiMul(lhs, rhs)); | 1171 var_result.Bind(assembler.SmiMul(lhs, rhs)); |
1169 assembler->Goto(&return_result); | 1172 assembler.Goto(&return_result); |
1170 } | 1173 } |
1171 | 1174 |
1172 assembler->Bind(&rhs_is_not_smi); | 1175 assembler.Bind(&rhs_is_not_smi); |
1173 { | 1176 { |
1174 Node* rhs_map = assembler->LoadMap(rhs); | 1177 Node* rhs_map = assembler.LoadMap(rhs); |
1175 | 1178 |
1176 // Check if {rhs} is a HeapNumber. | 1179 // Check if {rhs} is a HeapNumber. |
1177 Label rhs_is_number(assembler), | 1180 Label rhs_is_number(&assembler), |
1178 rhs_is_not_number(assembler, Label::kDeferred); | 1181 rhs_is_not_number(&assembler, Label::kDeferred); |
1179 assembler->Branch(assembler->WordEqual(rhs_map, number_map), | 1182 assembler.Branch(assembler.WordEqual(rhs_map, number_map), |
1180 &rhs_is_number, &rhs_is_not_number); | 1183 &rhs_is_number, &rhs_is_not_number); |
1181 | 1184 |
1182 assembler->Bind(&rhs_is_number); | 1185 assembler.Bind(&rhs_is_number); |
1183 { | 1186 { |
1184 // Convert {lhs} to a double and multiply it with the value of {rhs}. | 1187 // Convert {lhs} to a double and multiply it with the value of {rhs}. |
1185 var_lhs_float64.Bind(assembler->SmiToFloat64(lhs)); | 1188 var_lhs_float64.Bind(assembler.SmiToFloat64(lhs)); |
1186 var_rhs_float64.Bind(assembler->LoadHeapNumberValue(rhs)); | 1189 var_rhs_float64.Bind(assembler.LoadHeapNumberValue(rhs)); |
1187 assembler->Goto(&do_fmul); | 1190 assembler.Goto(&do_fmul); |
1188 } | 1191 } |
1189 | 1192 |
1190 assembler->Bind(&rhs_is_not_number); | 1193 assembler.Bind(&rhs_is_not_number); |
1191 { | 1194 { |
1192 // Multiplication is commutative, swap {lhs} with {rhs} and loop. | 1195 // Multiplication is commutative, swap {lhs} with {rhs} and loop. |
1193 var_lhs.Bind(rhs); | 1196 var_lhs.Bind(rhs); |
1194 var_rhs.Bind(lhs); | 1197 var_rhs.Bind(lhs); |
1195 assembler->Goto(&loop); | 1198 assembler.Goto(&loop); |
1196 } | 1199 } |
1197 } | 1200 } |
1198 } | 1201 } |
1199 | 1202 |
1200 assembler->Bind(&lhs_is_not_smi); | 1203 assembler.Bind(&lhs_is_not_smi); |
1201 { | 1204 { |
1202 Node* lhs_map = assembler->LoadMap(lhs); | 1205 Node* lhs_map = assembler.LoadMap(lhs); |
1203 | 1206 |
1204 // Check if {lhs} is a HeapNumber. | 1207 // Check if {lhs} is a HeapNumber. |
1205 Label lhs_is_number(assembler), | 1208 Label lhs_is_number(&assembler), |
1206 lhs_is_not_number(assembler, Label::kDeferred); | 1209 lhs_is_not_number(&assembler, Label::kDeferred); |
1207 assembler->Branch(assembler->WordEqual(lhs_map, number_map), | 1210 assembler.Branch(assembler.WordEqual(lhs_map, number_map), &lhs_is_number, |
1208 &lhs_is_number, &lhs_is_not_number); | 1211 &lhs_is_not_number); |
1209 | 1212 |
1210 assembler->Bind(&lhs_is_number); | 1213 assembler.Bind(&lhs_is_number); |
1211 { | 1214 { |
1212 // Check if {rhs} is a Smi. | 1215 // Check if {rhs} is a Smi. |
1213 Label rhs_is_smi(assembler), rhs_is_not_smi(assembler); | 1216 Label rhs_is_smi(&assembler), rhs_is_not_smi(&assembler); |
1214 assembler->Branch(assembler->TaggedIsSmi(rhs), &rhs_is_smi, | 1217 assembler.Branch(assembler.TaggedIsSmi(rhs), &rhs_is_smi, |
1215 &rhs_is_not_smi); | 1218 &rhs_is_not_smi); |
1216 | 1219 |
1217 assembler->Bind(&rhs_is_smi); | 1220 assembler.Bind(&rhs_is_smi); |
1218 { | 1221 { |
1219 // Convert {rhs} to a double and multiply it with the value of {lhs}. | 1222 // Convert {rhs} to a double and multiply it with the value of {lhs}. |
1220 var_lhs_float64.Bind(assembler->LoadHeapNumberValue(lhs)); | 1223 var_lhs_float64.Bind(assembler.LoadHeapNumberValue(lhs)); |
1221 var_rhs_float64.Bind(assembler->SmiToFloat64(rhs)); | 1224 var_rhs_float64.Bind(assembler.SmiToFloat64(rhs)); |
1222 assembler->Goto(&do_fmul); | 1225 assembler.Goto(&do_fmul); |
1223 } | 1226 } |
1224 | 1227 |
1225 assembler->Bind(&rhs_is_not_smi); | 1228 assembler.Bind(&rhs_is_not_smi); |
1226 { | 1229 { |
1227 Node* rhs_map = assembler->LoadMap(rhs); | 1230 Node* rhs_map = assembler.LoadMap(rhs); |
1228 | 1231 |
1229 // Check if {rhs} is a HeapNumber. | 1232 // Check if {rhs} is a HeapNumber. |
1230 Label rhs_is_number(assembler), | 1233 Label rhs_is_number(&assembler), |
1231 rhs_is_not_number(assembler, Label::kDeferred); | 1234 rhs_is_not_number(&assembler, Label::kDeferred); |
1232 assembler->Branch(assembler->WordEqual(rhs_map, number_map), | 1235 assembler.Branch(assembler.WordEqual(rhs_map, number_map), |
1233 &rhs_is_number, &rhs_is_not_number); | 1236 &rhs_is_number, &rhs_is_not_number); |
1234 | 1237 |
1235 assembler->Bind(&rhs_is_number); | 1238 assembler.Bind(&rhs_is_number); |
1236 { | 1239 { |
1237 // Both {lhs} and {rhs} are HeapNumbers. Load their values and | 1240 // Both {lhs} and {rhs} are HeapNumbers. Load their values and |
1238 // multiply them. | 1241 // multiply them. |
1239 var_lhs_float64.Bind(assembler->LoadHeapNumberValue(lhs)); | 1242 var_lhs_float64.Bind(assembler.LoadHeapNumberValue(lhs)); |
1240 var_rhs_float64.Bind(assembler->LoadHeapNumberValue(rhs)); | 1243 var_rhs_float64.Bind(assembler.LoadHeapNumberValue(rhs)); |
1241 assembler->Goto(&do_fmul); | 1244 assembler.Goto(&do_fmul); |
1242 } | 1245 } |
1243 | 1246 |
1244 assembler->Bind(&rhs_is_not_number); | 1247 assembler.Bind(&rhs_is_not_number); |
1245 { | 1248 { |
1246 // Multiplication is commutative, swap {lhs} with {rhs} and loop. | 1249 // Multiplication is commutative, swap {lhs} with {rhs} and loop. |
1247 var_lhs.Bind(rhs); | 1250 var_lhs.Bind(rhs); |
1248 var_rhs.Bind(lhs); | 1251 var_rhs.Bind(lhs); |
1249 assembler->Goto(&loop); | 1252 assembler.Goto(&loop); |
1250 } | 1253 } |
1251 } | 1254 } |
1252 } | 1255 } |
1253 | 1256 |
1254 assembler->Bind(&lhs_is_not_number); | 1257 assembler.Bind(&lhs_is_not_number); |
1255 { | 1258 { |
1256 // Convert {lhs} to a Number and loop. | 1259 // Convert {lhs} to a Number and loop. |
1257 Callable callable = | 1260 Callable callable = CodeFactory::NonNumberToNumber(assembler.isolate()); |
1258 CodeFactory::NonNumberToNumber(assembler->isolate()); | 1261 var_lhs.Bind(assembler.CallStub(callable, context, lhs)); |
1259 var_lhs.Bind(assembler->CallStub(callable, context, lhs)); | 1262 assembler.Goto(&loop); |
1260 assembler->Goto(&loop); | |
1261 } | 1263 } |
1262 } | 1264 } |
1263 } | 1265 } |
1264 | 1266 |
1265 assembler->Bind(&do_fmul); | 1267 assembler.Bind(&do_fmul); |
1266 { | 1268 { |
1267 Node* value = | 1269 Node* value = |
1268 assembler->Float64Mul(var_lhs_float64.value(), var_rhs_float64.value()); | 1270 assembler.Float64Mul(var_lhs_float64.value(), var_rhs_float64.value()); |
1269 Node* result = assembler->AllocateHeapNumberWithValue(value); | 1271 Node* result = assembler.AllocateHeapNumberWithValue(value); |
1270 var_result.Bind(result); | 1272 var_result.Bind(result); |
1271 assembler->Goto(&return_result); | 1273 assembler.Goto(&return_result); |
1272 } | 1274 } |
1273 | 1275 |
1274 assembler->Bind(&return_result); | 1276 assembler.Bind(&return_result); |
1275 assembler->Return(var_result.value()); | 1277 assembler.Return(var_result.value()); |
1276 } | 1278 } |
1277 | 1279 |
1278 void Builtins::Generate_Divide(CodeStubAssembler* assembler) { | 1280 void Builtins::Generate_Divide(compiler::CodeAssemblerState* state) { |
1279 typedef CodeStubAssembler::Label Label; | 1281 typedef CodeStubAssembler::Label Label; |
1280 typedef compiler::Node Node; | 1282 typedef compiler::Node Node; |
1281 typedef CodeStubAssembler::Variable Variable; | 1283 typedef CodeStubAssembler::Variable Variable; |
1282 | 1284 CodeStubAssembler assembler(state); |
1283 Node* left = assembler->Parameter(0); | 1285 |
1284 Node* right = assembler->Parameter(1); | 1286 Node* left = assembler.Parameter(0); |
1285 Node* context = assembler->Parameter(2); | 1287 Node* right = assembler.Parameter(1); |
| 1288 Node* context = assembler.Parameter(2); |
1286 | 1289 |
1287 // Shared entry point for floating point division. | 1290 // Shared entry point for floating point division. |
1288 Label do_fdiv(assembler), end(assembler); | 1291 Label do_fdiv(&assembler), end(&assembler); |
1289 Variable var_dividend_float64(assembler, MachineRepresentation::kFloat64), | 1292 Variable var_dividend_float64(&assembler, MachineRepresentation::kFloat64), |
1290 var_divisor_float64(assembler, MachineRepresentation::kFloat64); | 1293 var_divisor_float64(&assembler, MachineRepresentation::kFloat64); |
1291 | 1294 |
1292 Node* number_map = assembler->HeapNumberMapConstant(); | 1295 Node* number_map = assembler.HeapNumberMapConstant(); |
1293 | 1296 |
1294 // We might need to loop one or two times due to ToNumber conversions. | 1297 // We might need to loop one or two times due to ToNumber conversions. |
1295 Variable var_dividend(assembler, MachineRepresentation::kTagged), | 1298 Variable var_dividend(&assembler, MachineRepresentation::kTagged), |
1296 var_divisor(assembler, MachineRepresentation::kTagged), | 1299 var_divisor(&assembler, MachineRepresentation::kTagged), |
1297 var_result(assembler, MachineRepresentation::kTagged); | 1300 var_result(&assembler, MachineRepresentation::kTagged); |
1298 Variable* loop_variables[] = {&var_dividend, &var_divisor}; | 1301 Variable* loop_variables[] = {&var_dividend, &var_divisor}; |
1299 Label loop(assembler, 2, loop_variables); | 1302 Label loop(&assembler, 2, loop_variables); |
1300 var_dividend.Bind(left); | 1303 var_dividend.Bind(left); |
1301 var_divisor.Bind(right); | 1304 var_divisor.Bind(right); |
1302 assembler->Goto(&loop); | 1305 assembler.Goto(&loop); |
1303 assembler->Bind(&loop); | 1306 assembler.Bind(&loop); |
1304 { | 1307 { |
1305 Node* dividend = var_dividend.value(); | 1308 Node* dividend = var_dividend.value(); |
1306 Node* divisor = var_divisor.value(); | 1309 Node* divisor = var_divisor.value(); |
1307 | 1310 |
1308 Label dividend_is_smi(assembler), dividend_is_not_smi(assembler); | 1311 Label dividend_is_smi(&assembler), dividend_is_not_smi(&assembler); |
1309 assembler->Branch(assembler->TaggedIsSmi(dividend), ÷nd_is_smi, | 1312 assembler.Branch(assembler.TaggedIsSmi(dividend), ÷nd_is_smi, |
1310 ÷nd_is_not_smi); | 1313 ÷nd_is_not_smi); |
1311 | 1314 |
1312 assembler->Bind(÷nd_is_smi); | 1315 assembler.Bind(÷nd_is_smi); |
1313 { | 1316 { |
1314 Label divisor_is_smi(assembler), divisor_is_not_smi(assembler); | 1317 Label divisor_is_smi(&assembler), divisor_is_not_smi(&assembler); |
1315 assembler->Branch(assembler->TaggedIsSmi(divisor), &divisor_is_smi, | 1318 assembler.Branch(assembler.TaggedIsSmi(divisor), &divisor_is_smi, |
1316 &divisor_is_not_smi); | 1319 &divisor_is_not_smi); |
1317 | 1320 |
1318 assembler->Bind(&divisor_is_smi); | 1321 assembler.Bind(&divisor_is_smi); |
1319 { | 1322 { |
1320 Label bailout(assembler); | 1323 Label bailout(&assembler); |
1321 | 1324 |
1322 // Do floating point division if {divisor} is zero. | 1325 // Do floating point division if {divisor} is zero. |
1323 assembler->GotoIf( | 1326 assembler.GotoIf( |
1324 assembler->WordEqual(divisor, assembler->IntPtrConstant(0)), | 1327 assembler.WordEqual(divisor, assembler.IntPtrConstant(0)), |
1325 &bailout); | 1328 &bailout); |
1326 | 1329 |
1327 // Do floating point division {dividend} is zero and {divisor} is | 1330 // Do floating point division {dividend} is zero and {divisor} is |
1328 // negative. | 1331 // negative. |
1329 Label dividend_is_zero(assembler), dividend_is_not_zero(assembler); | 1332 Label dividend_is_zero(&assembler), dividend_is_not_zero(&assembler); |
1330 assembler->Branch( | 1333 assembler.Branch( |
1331 assembler->WordEqual(dividend, assembler->IntPtrConstant(0)), | 1334 assembler.WordEqual(dividend, assembler.IntPtrConstant(0)), |
1332 ÷nd_is_zero, ÷nd_is_not_zero); | 1335 ÷nd_is_zero, ÷nd_is_not_zero); |
1333 | 1336 |
1334 assembler->Bind(÷nd_is_zero); | 1337 assembler.Bind(÷nd_is_zero); |
1335 { | 1338 { |
1336 assembler->GotoIf( | 1339 assembler.GotoIf( |
1337 assembler->IntPtrLessThan(divisor, assembler->IntPtrConstant(0)), | 1340 assembler.IntPtrLessThan(divisor, assembler.IntPtrConstant(0)), |
1338 &bailout); | 1341 &bailout); |
1339 assembler->Goto(÷nd_is_not_zero); | 1342 assembler.Goto(÷nd_is_not_zero); |
1340 } | 1343 } |
1341 assembler->Bind(÷nd_is_not_zero); | 1344 assembler.Bind(÷nd_is_not_zero); |
1342 | 1345 |
1343 Node* untagged_divisor = assembler->SmiUntag(divisor); | 1346 Node* untagged_divisor = assembler.SmiUntag(divisor); |
1344 Node* untagged_dividend = assembler->SmiUntag(dividend); | 1347 Node* untagged_dividend = assembler.SmiUntag(dividend); |
1345 | 1348 |
1346 // Do floating point division if {dividend} is kMinInt (or kMinInt - 1 | 1349 // Do floating point division if {dividend} is kMinInt (or kMinInt - 1 |
1347 // if the Smi size is 31) and {divisor} is -1. | 1350 // if the Smi size is 31) and {divisor} is -1. |
1348 Label divisor_is_minus_one(assembler), | 1351 Label divisor_is_minus_one(&assembler), |
1349 divisor_is_not_minus_one(assembler); | 1352 divisor_is_not_minus_one(&assembler); |
1350 assembler->Branch(assembler->Word32Equal(untagged_divisor, | 1353 assembler.Branch(assembler.Word32Equal(untagged_divisor, |
1351 assembler->Int32Constant(-1)), | 1354 assembler.Int32Constant(-1)), |
1352 &divisor_is_minus_one, &divisor_is_not_minus_one); | 1355 &divisor_is_minus_one, &divisor_is_not_minus_one); |
1353 | 1356 |
1354 assembler->Bind(&divisor_is_minus_one); | 1357 assembler.Bind(&divisor_is_minus_one); |
1355 { | 1358 { |
1356 assembler->GotoIf( | 1359 assembler.GotoIf( |
1357 assembler->Word32Equal( | 1360 assembler.Word32Equal( |
1358 untagged_dividend, | 1361 untagged_dividend, |
1359 assembler->Int32Constant( | 1362 assembler.Int32Constant( |
1360 kSmiValueSize == 32 ? kMinInt : (kMinInt >> 1))), | 1363 kSmiValueSize == 32 ? kMinInt : (kMinInt >> 1))), |
1361 &bailout); | 1364 &bailout); |
1362 assembler->Goto(&divisor_is_not_minus_one); | 1365 assembler.Goto(&divisor_is_not_minus_one); |
1363 } | 1366 } |
1364 assembler->Bind(&divisor_is_not_minus_one); | 1367 assembler.Bind(&divisor_is_not_minus_one); |
1365 | 1368 |
1366 // TODO(epertoso): consider adding a machine instruction that returns | 1369 // TODO(epertoso): consider adding a machine instruction that returns |
1367 // both the result and the remainder. | 1370 // both the result and the remainder. |
1368 Node* untagged_result = | 1371 Node* untagged_result = |
1369 assembler->Int32Div(untagged_dividend, untagged_divisor); | 1372 assembler.Int32Div(untagged_dividend, untagged_divisor); |
1370 Node* truncated = | 1373 Node* truncated = assembler.Int32Mul(untagged_result, untagged_divisor); |
1371 assembler->Int32Mul(untagged_result, untagged_divisor); | |
1372 // Do floating point division if the remainder is not 0. | 1374 // Do floating point division if the remainder is not 0. |
1373 assembler->GotoIf( | 1375 assembler.GotoIf(assembler.Word32NotEqual(untagged_dividend, truncated), |
1374 assembler->Word32NotEqual(untagged_dividend, truncated), &bailout); | 1376 &bailout); |
1375 var_result.Bind(assembler->SmiTag(untagged_result)); | 1377 var_result.Bind(assembler.SmiTag(untagged_result)); |
1376 assembler->Goto(&end); | 1378 assembler.Goto(&end); |
1377 | 1379 |
1378 // Bailout: convert {dividend} and {divisor} to double and do double | 1380 // Bailout: convert {dividend} and {divisor} to double and do double |
1379 // division. | 1381 // division. |
1380 assembler->Bind(&bailout); | 1382 assembler.Bind(&bailout); |
1381 { | 1383 { |
1382 var_dividend_float64.Bind(assembler->SmiToFloat64(dividend)); | 1384 var_dividend_float64.Bind(assembler.SmiToFloat64(dividend)); |
1383 var_divisor_float64.Bind(assembler->SmiToFloat64(divisor)); | 1385 var_divisor_float64.Bind(assembler.SmiToFloat64(divisor)); |
1384 assembler->Goto(&do_fdiv); | 1386 assembler.Goto(&do_fdiv); |
1385 } | 1387 } |
1386 } | 1388 } |
1387 | 1389 |
1388 assembler->Bind(&divisor_is_not_smi); | 1390 assembler.Bind(&divisor_is_not_smi); |
1389 { | 1391 { |
1390 Node* divisor_map = assembler->LoadMap(divisor); | 1392 Node* divisor_map = assembler.LoadMap(divisor); |
1391 | 1393 |
1392 // Check if {divisor} is a HeapNumber. | 1394 // Check if {divisor} is a HeapNumber. |
1393 Label divisor_is_number(assembler), | 1395 Label divisor_is_number(&assembler), |
1394 divisor_is_not_number(assembler, Label::kDeferred); | 1396 divisor_is_not_number(&assembler, Label::kDeferred); |
1395 assembler->Branch(assembler->WordEqual(divisor_map, number_map), | 1397 assembler.Branch(assembler.WordEqual(divisor_map, number_map), |
1396 &divisor_is_number, &divisor_is_not_number); | 1398 &divisor_is_number, &divisor_is_not_number); |
1397 | 1399 |
1398 assembler->Bind(&divisor_is_number); | 1400 assembler.Bind(&divisor_is_number); |
1399 { | 1401 { |
1400 // Convert {dividend} to a double and divide it with the value of | 1402 // Convert {dividend} to a double and divide it with the value of |
1401 // {divisor}. | 1403 // {divisor}. |
1402 var_dividend_float64.Bind(assembler->SmiToFloat64(dividend)); | 1404 var_dividend_float64.Bind(assembler.SmiToFloat64(dividend)); |
1403 var_divisor_float64.Bind(assembler->LoadHeapNumberValue(divisor)); | 1405 var_divisor_float64.Bind(assembler.LoadHeapNumberValue(divisor)); |
1404 assembler->Goto(&do_fdiv); | 1406 assembler.Goto(&do_fdiv); |
1405 } | 1407 } |
1406 | 1408 |
1407 assembler->Bind(&divisor_is_not_number); | 1409 assembler.Bind(&divisor_is_not_number); |
1408 { | 1410 { |
1409 // Convert {divisor} to a number and loop. | 1411 // Convert {divisor} to a number and loop. |
1410 Callable callable = | 1412 Callable callable = |
1411 CodeFactory::NonNumberToNumber(assembler->isolate()); | 1413 CodeFactory::NonNumberToNumber(assembler.isolate()); |
1412 var_divisor.Bind(assembler->CallStub(callable, context, divisor)); | 1414 var_divisor.Bind(assembler.CallStub(callable, context, divisor)); |
1413 assembler->Goto(&loop); | 1415 assembler.Goto(&loop); |
1414 } | 1416 } |
1415 } | 1417 } |
1416 } | 1418 } |
1417 | 1419 |
1418 assembler->Bind(÷nd_is_not_smi); | 1420 assembler.Bind(÷nd_is_not_smi); |
1419 { | 1421 { |
1420 Node* dividend_map = assembler->LoadMap(dividend); | 1422 Node* dividend_map = assembler.LoadMap(dividend); |
1421 | 1423 |
1422 // Check if {dividend} is a HeapNumber. | 1424 // Check if {dividend} is a HeapNumber. |
1423 Label dividend_is_number(assembler), | 1425 Label dividend_is_number(&assembler), |
1424 dividend_is_not_number(assembler, Label::kDeferred); | 1426 dividend_is_not_number(&assembler, Label::kDeferred); |
1425 assembler->Branch(assembler->WordEqual(dividend_map, number_map), | 1427 assembler.Branch(assembler.WordEqual(dividend_map, number_map), |
1426 ÷nd_is_number, ÷nd_is_not_number); | 1428 ÷nd_is_number, ÷nd_is_not_number); |
1427 | 1429 |
1428 assembler->Bind(÷nd_is_number); | 1430 assembler.Bind(÷nd_is_number); |
1429 { | 1431 { |
1430 // Check if {divisor} is a Smi. | 1432 // Check if {divisor} is a Smi. |
1431 Label divisor_is_smi(assembler), divisor_is_not_smi(assembler); | 1433 Label divisor_is_smi(&assembler), divisor_is_not_smi(&assembler); |
1432 assembler->Branch(assembler->TaggedIsSmi(divisor), &divisor_is_smi, | 1434 assembler.Branch(assembler.TaggedIsSmi(divisor), &divisor_is_smi, |
1433 &divisor_is_not_smi); | 1435 &divisor_is_not_smi); |
1434 | 1436 |
1435 assembler->Bind(&divisor_is_smi); | 1437 assembler.Bind(&divisor_is_smi); |
1436 { | 1438 { |
1437 // Convert {divisor} to a double and use it for a floating point | 1439 // Convert {divisor} to a double and use it for a floating point |
1438 // division. | 1440 // division. |
1439 var_dividend_float64.Bind(assembler->LoadHeapNumberValue(dividend)); | 1441 var_dividend_float64.Bind(assembler.LoadHeapNumberValue(dividend)); |
1440 var_divisor_float64.Bind(assembler->SmiToFloat64(divisor)); | 1442 var_divisor_float64.Bind(assembler.SmiToFloat64(divisor)); |
1441 assembler->Goto(&do_fdiv); | 1443 assembler.Goto(&do_fdiv); |
1442 } | 1444 } |
1443 | 1445 |
1444 assembler->Bind(&divisor_is_not_smi); | 1446 assembler.Bind(&divisor_is_not_smi); |
1445 { | 1447 { |
1446 Node* divisor_map = assembler->LoadMap(divisor); | 1448 Node* divisor_map = assembler.LoadMap(divisor); |
1447 | 1449 |
1448 // Check if {divisor} is a HeapNumber. | 1450 // Check if {divisor} is a HeapNumber. |
1449 Label divisor_is_number(assembler), | 1451 Label divisor_is_number(&assembler), |
1450 divisor_is_not_number(assembler, Label::kDeferred); | 1452 divisor_is_not_number(&assembler, Label::kDeferred); |
1451 assembler->Branch(assembler->WordEqual(divisor_map, number_map), | 1453 assembler.Branch(assembler.WordEqual(divisor_map, number_map), |
1452 &divisor_is_number, &divisor_is_not_number); | 1454 &divisor_is_number, &divisor_is_not_number); |
1453 | 1455 |
1454 assembler->Bind(&divisor_is_number); | 1456 assembler.Bind(&divisor_is_number); |
1455 { | 1457 { |
1456 // Both {dividend} and {divisor} are HeapNumbers. Load their values | 1458 // Both {dividend} and {divisor} are HeapNumbers. Load their values |
1457 // and divide them. | 1459 // and divide them. |
1458 var_dividend_float64.Bind(assembler->LoadHeapNumberValue(dividend)); | 1460 var_dividend_float64.Bind(assembler.LoadHeapNumberValue(dividend)); |
1459 var_divisor_float64.Bind(assembler->LoadHeapNumberValue(divisor)); | 1461 var_divisor_float64.Bind(assembler.LoadHeapNumberValue(divisor)); |
1460 assembler->Goto(&do_fdiv); | 1462 assembler.Goto(&do_fdiv); |
1461 } | 1463 } |
1462 | 1464 |
1463 assembler->Bind(&divisor_is_not_number); | 1465 assembler.Bind(&divisor_is_not_number); |
1464 { | 1466 { |
1465 // Convert {divisor} to a number and loop. | 1467 // Convert {divisor} to a number and loop. |
1466 Callable callable = | 1468 Callable callable = |
1467 CodeFactory::NonNumberToNumber(assembler->isolate()); | 1469 CodeFactory::NonNumberToNumber(assembler.isolate()); |
1468 var_divisor.Bind(assembler->CallStub(callable, context, divisor)); | 1470 var_divisor.Bind(assembler.CallStub(callable, context, divisor)); |
1469 assembler->Goto(&loop); | 1471 assembler.Goto(&loop); |
1470 } | 1472 } |
1471 } | 1473 } |
1472 } | 1474 } |
1473 | 1475 |
1474 assembler->Bind(÷nd_is_not_number); | 1476 assembler.Bind(÷nd_is_not_number); |
1475 { | 1477 { |
1476 // Convert {dividend} to a Number and loop. | 1478 // Convert {dividend} to a Number and loop. |
1477 Callable callable = | 1479 Callable callable = CodeFactory::NonNumberToNumber(assembler.isolate()); |
1478 CodeFactory::NonNumberToNumber(assembler->isolate()); | 1480 var_dividend.Bind(assembler.CallStub(callable, context, dividend)); |
1479 var_dividend.Bind(assembler->CallStub(callable, context, dividend)); | 1481 assembler.Goto(&loop); |
1480 assembler->Goto(&loop); | |
1481 } | 1482 } |
1482 } | 1483 } |
1483 } | 1484 } |
1484 | 1485 |
1485 assembler->Bind(&do_fdiv); | 1486 assembler.Bind(&do_fdiv); |
1486 { | 1487 { |
1487 Node* value = assembler->Float64Div(var_dividend_float64.value(), | 1488 Node* value = assembler.Float64Div(var_dividend_float64.value(), |
1488 var_divisor_float64.value()); | 1489 var_divisor_float64.value()); |
1489 var_result.Bind(assembler->AllocateHeapNumberWithValue(value)); | 1490 var_result.Bind(assembler.AllocateHeapNumberWithValue(value)); |
1490 assembler->Goto(&end); | 1491 assembler.Goto(&end); |
1491 } | 1492 } |
1492 assembler->Bind(&end); | 1493 assembler.Bind(&end); |
1493 assembler->Return(var_result.value()); | 1494 assembler.Return(var_result.value()); |
1494 } | 1495 } |
1495 | 1496 |
1496 void Builtins::Generate_Modulus(CodeStubAssembler* assembler) { | 1497 void Builtins::Generate_Modulus(compiler::CodeAssemblerState* state) { |
1497 typedef CodeStubAssembler::Label Label; | 1498 typedef CodeStubAssembler::Label Label; |
1498 typedef compiler::Node Node; | 1499 typedef compiler::Node Node; |
1499 typedef CodeStubAssembler::Variable Variable; | 1500 typedef CodeStubAssembler::Variable Variable; |
1500 | 1501 CodeStubAssembler assembler(state); |
1501 Node* left = assembler->Parameter(0); | 1502 |
1502 Node* right = assembler->Parameter(1); | 1503 Node* left = assembler.Parameter(0); |
1503 Node* context = assembler->Parameter(2); | 1504 Node* right = assembler.Parameter(1); |
1504 | 1505 Node* context = assembler.Parameter(2); |
1505 Variable var_result(assembler, MachineRepresentation::kTagged); | 1506 |
1506 Label return_result(assembler, &var_result); | 1507 Variable var_result(&assembler, MachineRepresentation::kTagged); |
| 1508 Label return_result(&assembler, &var_result); |
1507 | 1509 |
1508 // Shared entry point for floating point modulus. | 1510 // Shared entry point for floating point modulus. |
1509 Label do_fmod(assembler); | 1511 Label do_fmod(&assembler); |
1510 Variable var_dividend_float64(assembler, MachineRepresentation::kFloat64), | 1512 Variable var_dividend_float64(&assembler, MachineRepresentation::kFloat64), |
1511 var_divisor_float64(assembler, MachineRepresentation::kFloat64); | 1513 var_divisor_float64(&assembler, MachineRepresentation::kFloat64); |
1512 | 1514 |
1513 Node* number_map = assembler->HeapNumberMapConstant(); | 1515 Node* number_map = assembler.HeapNumberMapConstant(); |
1514 | 1516 |
1515 // We might need to loop one or two times due to ToNumber conversions. | 1517 // We might need to loop one or two times due to ToNumber conversions. |
1516 Variable var_dividend(assembler, MachineRepresentation::kTagged), | 1518 Variable var_dividend(&assembler, MachineRepresentation::kTagged), |
1517 var_divisor(assembler, MachineRepresentation::kTagged); | 1519 var_divisor(&assembler, MachineRepresentation::kTagged); |
1518 Variable* loop_variables[] = {&var_dividend, &var_divisor}; | 1520 Variable* loop_variables[] = {&var_dividend, &var_divisor}; |
1519 Label loop(assembler, 2, loop_variables); | 1521 Label loop(&assembler, 2, loop_variables); |
1520 var_dividend.Bind(left); | 1522 var_dividend.Bind(left); |
1521 var_divisor.Bind(right); | 1523 var_divisor.Bind(right); |
1522 assembler->Goto(&loop); | 1524 assembler.Goto(&loop); |
1523 assembler->Bind(&loop); | 1525 assembler.Bind(&loop); |
1524 { | 1526 { |
1525 Node* dividend = var_dividend.value(); | 1527 Node* dividend = var_dividend.value(); |
1526 Node* divisor = var_divisor.value(); | 1528 Node* divisor = var_divisor.value(); |
1527 | 1529 |
1528 Label dividend_is_smi(assembler), dividend_is_not_smi(assembler); | 1530 Label dividend_is_smi(&assembler), dividend_is_not_smi(&assembler); |
1529 assembler->Branch(assembler->TaggedIsSmi(dividend), ÷nd_is_smi, | 1531 assembler.Branch(assembler.TaggedIsSmi(dividend), ÷nd_is_smi, |
1530 ÷nd_is_not_smi); | 1532 ÷nd_is_not_smi); |
1531 | 1533 |
1532 assembler->Bind(÷nd_is_smi); | 1534 assembler.Bind(÷nd_is_smi); |
1533 { | 1535 { |
1534 Label dividend_is_not_zero(assembler); | 1536 Label dividend_is_not_zero(&assembler); |
1535 Label divisor_is_smi(assembler), divisor_is_not_smi(assembler); | 1537 Label divisor_is_smi(&assembler), divisor_is_not_smi(&assembler); |
1536 assembler->Branch(assembler->TaggedIsSmi(divisor), &divisor_is_smi, | 1538 assembler.Branch(assembler.TaggedIsSmi(divisor), &divisor_is_smi, |
1537 &divisor_is_not_smi); | 1539 &divisor_is_not_smi); |
1538 | 1540 |
1539 assembler->Bind(&divisor_is_smi); | 1541 assembler.Bind(&divisor_is_smi); |
1540 { | 1542 { |
1541 // Compute the modulus of two Smis. | 1543 // Compute the modulus of two Smis. |
1542 var_result.Bind(assembler->SmiMod(dividend, divisor)); | 1544 var_result.Bind(assembler.SmiMod(dividend, divisor)); |
1543 assembler->Goto(&return_result); | 1545 assembler.Goto(&return_result); |
1544 } | 1546 } |
1545 | 1547 |
1546 assembler->Bind(&divisor_is_not_smi); | 1548 assembler.Bind(&divisor_is_not_smi); |
1547 { | 1549 { |
1548 Node* divisor_map = assembler->LoadMap(divisor); | 1550 Node* divisor_map = assembler.LoadMap(divisor); |
1549 | 1551 |
1550 // Check if {divisor} is a HeapNumber. | 1552 // Check if {divisor} is a HeapNumber. |
1551 Label divisor_is_number(assembler), | 1553 Label divisor_is_number(&assembler), |
1552 divisor_is_not_number(assembler, Label::kDeferred); | 1554 divisor_is_not_number(&assembler, Label::kDeferred); |
1553 assembler->Branch(assembler->WordEqual(divisor_map, number_map), | 1555 assembler.Branch(assembler.WordEqual(divisor_map, number_map), |
1554 &divisor_is_number, &divisor_is_not_number); | 1556 &divisor_is_number, &divisor_is_not_number); |
1555 | 1557 |
1556 assembler->Bind(&divisor_is_number); | 1558 assembler.Bind(&divisor_is_number); |
1557 { | 1559 { |
1558 // Convert {dividend} to a double and compute its modulus with the | 1560 // Convert {dividend} to a double and compute its modulus with the |
1559 // value of {dividend}. | 1561 // value of {dividend}. |
1560 var_dividend_float64.Bind(assembler->SmiToFloat64(dividend)); | 1562 var_dividend_float64.Bind(assembler.SmiToFloat64(dividend)); |
1561 var_divisor_float64.Bind(assembler->LoadHeapNumberValue(divisor)); | 1563 var_divisor_float64.Bind(assembler.LoadHeapNumberValue(divisor)); |
1562 assembler->Goto(&do_fmod); | 1564 assembler.Goto(&do_fmod); |
1563 } | 1565 } |
1564 | 1566 |
1565 assembler->Bind(&divisor_is_not_number); | 1567 assembler.Bind(&divisor_is_not_number); |
1566 { | 1568 { |
1567 // Convert {divisor} to a number and loop. | 1569 // Convert {divisor} to a number and loop. |
1568 Callable callable = | 1570 Callable callable = |
1569 CodeFactory::NonNumberToNumber(assembler->isolate()); | 1571 CodeFactory::NonNumberToNumber(assembler.isolate()); |
1570 var_divisor.Bind(assembler->CallStub(callable, context, divisor)); | 1572 var_divisor.Bind(assembler.CallStub(callable, context, divisor)); |
1571 assembler->Goto(&loop); | 1573 assembler.Goto(&loop); |
1572 } | 1574 } |
1573 } | 1575 } |
1574 } | 1576 } |
1575 | 1577 |
1576 assembler->Bind(÷nd_is_not_smi); | 1578 assembler.Bind(÷nd_is_not_smi); |
1577 { | 1579 { |
1578 Node* dividend_map = assembler->LoadMap(dividend); | 1580 Node* dividend_map = assembler.LoadMap(dividend); |
1579 | 1581 |
1580 // Check if {dividend} is a HeapNumber. | 1582 // Check if {dividend} is a HeapNumber. |
1581 Label dividend_is_number(assembler), | 1583 Label dividend_is_number(&assembler), |
1582 dividend_is_not_number(assembler, Label::kDeferred); | 1584 dividend_is_not_number(&assembler, Label::kDeferred); |
1583 assembler->Branch(assembler->WordEqual(dividend_map, number_map), | 1585 assembler.Branch(assembler.WordEqual(dividend_map, number_map), |
1584 ÷nd_is_number, ÷nd_is_not_number); | 1586 ÷nd_is_number, ÷nd_is_not_number); |
1585 | 1587 |
1586 assembler->Bind(÷nd_is_number); | 1588 assembler.Bind(÷nd_is_number); |
1587 { | 1589 { |
1588 // Check if {divisor} is a Smi. | 1590 // Check if {divisor} is a Smi. |
1589 Label divisor_is_smi(assembler), divisor_is_not_smi(assembler); | 1591 Label divisor_is_smi(&assembler), divisor_is_not_smi(&assembler); |
1590 assembler->Branch(assembler->TaggedIsSmi(divisor), &divisor_is_smi, | 1592 assembler.Branch(assembler.TaggedIsSmi(divisor), &divisor_is_smi, |
1591 &divisor_is_not_smi); | 1593 &divisor_is_not_smi); |
1592 | 1594 |
1593 assembler->Bind(&divisor_is_smi); | 1595 assembler.Bind(&divisor_is_smi); |
1594 { | 1596 { |
1595 // Convert {divisor} to a double and compute {dividend}'s modulus with | 1597 // Convert {divisor} to a double and compute {dividend}'s modulus with |
1596 // it. | 1598 // it. |
1597 var_dividend_float64.Bind(assembler->LoadHeapNumberValue(dividend)); | 1599 var_dividend_float64.Bind(assembler.LoadHeapNumberValue(dividend)); |
1598 var_divisor_float64.Bind(assembler->SmiToFloat64(divisor)); | 1600 var_divisor_float64.Bind(assembler.SmiToFloat64(divisor)); |
1599 assembler->Goto(&do_fmod); | 1601 assembler.Goto(&do_fmod); |
1600 } | 1602 } |
1601 | 1603 |
1602 assembler->Bind(&divisor_is_not_smi); | 1604 assembler.Bind(&divisor_is_not_smi); |
1603 { | 1605 { |
1604 Node* divisor_map = assembler->LoadMap(divisor); | 1606 Node* divisor_map = assembler.LoadMap(divisor); |
1605 | 1607 |
1606 // Check if {divisor} is a HeapNumber. | 1608 // Check if {divisor} is a HeapNumber. |
1607 Label divisor_is_number(assembler), | 1609 Label divisor_is_number(&assembler), |
1608 divisor_is_not_number(assembler, Label::kDeferred); | 1610 divisor_is_not_number(&assembler, Label::kDeferred); |
1609 assembler->Branch(assembler->WordEqual(divisor_map, number_map), | 1611 assembler.Branch(assembler.WordEqual(divisor_map, number_map), |
1610 &divisor_is_number, &divisor_is_not_number); | 1612 &divisor_is_number, &divisor_is_not_number); |
1611 | 1613 |
1612 assembler->Bind(&divisor_is_number); | 1614 assembler.Bind(&divisor_is_number); |
1613 { | 1615 { |
1614 // Both {dividend} and {divisor} are HeapNumbers. Load their values | 1616 // Both {dividend} and {divisor} are HeapNumbers. Load their values |
1615 // and compute their modulus. | 1617 // and compute their modulus. |
1616 var_dividend_float64.Bind(assembler->LoadHeapNumberValue(dividend)); | 1618 var_dividend_float64.Bind(assembler.LoadHeapNumberValue(dividend)); |
1617 var_divisor_float64.Bind(assembler->LoadHeapNumberValue(divisor)); | 1619 var_divisor_float64.Bind(assembler.LoadHeapNumberValue(divisor)); |
1618 assembler->Goto(&do_fmod); | 1620 assembler.Goto(&do_fmod); |
1619 } | 1621 } |
1620 | 1622 |
1621 assembler->Bind(&divisor_is_not_number); | 1623 assembler.Bind(&divisor_is_not_number); |
1622 { | 1624 { |
1623 // Convert {divisor} to a number and loop. | 1625 // Convert {divisor} to a number and loop. |
1624 Callable callable = | 1626 Callable callable = |
1625 CodeFactory::NonNumberToNumber(assembler->isolate()); | 1627 CodeFactory::NonNumberToNumber(assembler.isolate()); |
1626 var_divisor.Bind(assembler->CallStub(callable, context, divisor)); | 1628 var_divisor.Bind(assembler.CallStub(callable, context, divisor)); |
1627 assembler->Goto(&loop); | 1629 assembler.Goto(&loop); |
1628 } | 1630 } |
1629 } | 1631 } |
1630 } | 1632 } |
1631 | 1633 |
1632 assembler->Bind(÷nd_is_not_number); | 1634 assembler.Bind(÷nd_is_not_number); |
1633 { | 1635 { |
1634 // Convert {dividend} to a Number and loop. | 1636 // Convert {dividend} to a Number and loop. |
1635 Callable callable = | 1637 Callable callable = CodeFactory::NonNumberToNumber(assembler.isolate()); |
1636 CodeFactory::NonNumberToNumber(assembler->isolate()); | 1638 var_dividend.Bind(assembler.CallStub(callable, context, dividend)); |
1637 var_dividend.Bind(assembler->CallStub(callable, context, dividend)); | 1639 assembler.Goto(&loop); |
1638 assembler->Goto(&loop); | |
1639 } | 1640 } |
1640 } | 1641 } |
1641 } | 1642 } |
1642 | 1643 |
1643 assembler->Bind(&do_fmod); | 1644 assembler.Bind(&do_fmod); |
1644 { | 1645 { |
1645 Node* value = assembler->Float64Mod(var_dividend_float64.value(), | 1646 Node* value = assembler.Float64Mod(var_dividend_float64.value(), |
1646 var_divisor_float64.value()); | 1647 var_divisor_float64.value()); |
1647 var_result.Bind(assembler->AllocateHeapNumberWithValue(value)); | 1648 var_result.Bind(assembler.AllocateHeapNumberWithValue(value)); |
1648 assembler->Goto(&return_result); | 1649 assembler.Goto(&return_result); |
1649 } | 1650 } |
1650 | 1651 |
1651 assembler->Bind(&return_result); | 1652 assembler.Bind(&return_result); |
1652 assembler->Return(var_result.value()); | 1653 assembler.Return(var_result.value()); |
1653 } | 1654 } |
1654 | 1655 |
1655 void Builtins::Generate_ShiftLeft(CodeStubAssembler* assembler) { | 1656 void Builtins::Generate_ShiftLeft(compiler::CodeAssemblerState* state) { |
1656 compiler::Node* left = assembler->Parameter(0); | |
1657 compiler::Node* right = assembler->Parameter(1); | |
1658 compiler::Node* context = assembler->Parameter(2); | |
1659 | |
1660 using compiler::Node; | 1657 using compiler::Node; |
1661 | 1658 CodeStubAssembler assembler(state); |
1662 Node* lhs_value = assembler->TruncateTaggedToWord32(context, left); | 1659 |
1663 Node* rhs_value = assembler->TruncateTaggedToWord32(context, right); | 1660 Node* left = assembler.Parameter(0); |
| 1661 Node* right = assembler.Parameter(1); |
| 1662 Node* context = assembler.Parameter(2); |
| 1663 |
| 1664 Node* lhs_value = assembler.TruncateTaggedToWord32(context, left); |
| 1665 Node* rhs_value = assembler.TruncateTaggedToWord32(context, right); |
1664 Node* shift_count = | 1666 Node* shift_count = |
1665 assembler->Word32And(rhs_value, assembler->Int32Constant(0x1f)); | 1667 assembler.Word32And(rhs_value, assembler.Int32Constant(0x1f)); |
1666 Node* value = assembler->Word32Shl(lhs_value, shift_count); | 1668 Node* value = assembler.Word32Shl(lhs_value, shift_count); |
1667 Node* result = assembler->ChangeInt32ToTagged(value); | 1669 Node* result = assembler.ChangeInt32ToTagged(value); |
1668 assembler->Return(result); | 1670 assembler.Return(result); |
1669 } | 1671 } |
1670 | 1672 |
1671 void Builtins::Generate_ShiftRight(CodeStubAssembler* assembler) { | 1673 void Builtins::Generate_ShiftRight(compiler::CodeAssemblerState* state) { |
1672 compiler::Node* left = assembler->Parameter(0); | |
1673 compiler::Node* right = assembler->Parameter(1); | |
1674 compiler::Node* context = assembler->Parameter(2); | |
1675 | |
1676 using compiler::Node; | 1674 using compiler::Node; |
1677 | 1675 CodeStubAssembler assembler(state); |
1678 Node* lhs_value = assembler->TruncateTaggedToWord32(context, left); | 1676 |
1679 Node* rhs_value = assembler->TruncateTaggedToWord32(context, right); | 1677 Node* left = assembler.Parameter(0); |
| 1678 Node* right = assembler.Parameter(1); |
| 1679 Node* context = assembler.Parameter(2); |
| 1680 |
| 1681 Node* lhs_value = assembler.TruncateTaggedToWord32(context, left); |
| 1682 Node* rhs_value = assembler.TruncateTaggedToWord32(context, right); |
1680 Node* shift_count = | 1683 Node* shift_count = |
1681 assembler->Word32And(rhs_value, assembler->Int32Constant(0x1f)); | 1684 assembler.Word32And(rhs_value, assembler.Int32Constant(0x1f)); |
1682 Node* value = assembler->Word32Sar(lhs_value, shift_count); | 1685 Node* value = assembler.Word32Sar(lhs_value, shift_count); |
1683 Node* result = assembler->ChangeInt32ToTagged(value); | 1686 Node* result = assembler.ChangeInt32ToTagged(value); |
1684 assembler->Return(result); | 1687 assembler.Return(result); |
1685 } | 1688 } |
1686 | 1689 |
1687 void Builtins::Generate_ShiftRightLogical(CodeStubAssembler* assembler) { | 1690 void Builtins::Generate_ShiftRightLogical(compiler::CodeAssemblerState* state) { |
1688 compiler::Node* left = assembler->Parameter(0); | |
1689 compiler::Node* right = assembler->Parameter(1); | |
1690 compiler::Node* context = assembler->Parameter(2); | |
1691 | |
1692 using compiler::Node; | 1691 using compiler::Node; |
1693 | 1692 CodeStubAssembler assembler(state); |
1694 Node* lhs_value = assembler->TruncateTaggedToWord32(context, left); | 1693 |
1695 Node* rhs_value = assembler->TruncateTaggedToWord32(context, right); | 1694 Node* left = assembler.Parameter(0); |
| 1695 Node* right = assembler.Parameter(1); |
| 1696 Node* context = assembler.Parameter(2); |
| 1697 |
| 1698 Node* lhs_value = assembler.TruncateTaggedToWord32(context, left); |
| 1699 Node* rhs_value = assembler.TruncateTaggedToWord32(context, right); |
1696 Node* shift_count = | 1700 Node* shift_count = |
1697 assembler->Word32And(rhs_value, assembler->Int32Constant(0x1f)); | 1701 assembler.Word32And(rhs_value, assembler.Int32Constant(0x1f)); |
1698 Node* value = assembler->Word32Shr(lhs_value, shift_count); | 1702 Node* value = assembler.Word32Shr(lhs_value, shift_count); |
1699 Node* result = assembler->ChangeUint32ToTagged(value); | 1703 Node* result = assembler.ChangeUint32ToTagged(value); |
1700 assembler->Return(result); | 1704 assembler.Return(result); |
1701 } | 1705 } |
1702 | 1706 |
1703 void Builtins::Generate_BitwiseAnd(CodeStubAssembler* assembler) { | 1707 void Builtins::Generate_BitwiseAnd(compiler::CodeAssemblerState* state) { |
1704 compiler::Node* left = assembler->Parameter(0); | 1708 CodeStubAssembler assembler(state); |
1705 compiler::Node* right = assembler->Parameter(1); | |
1706 compiler::Node* context = assembler->Parameter(2); | |
1707 | |
1708 using compiler::Node; | 1709 using compiler::Node; |
1709 | 1710 |
1710 Node* lhs_value = assembler->TruncateTaggedToWord32(context, left); | 1711 Node* left = assembler.Parameter(0); |
1711 Node* rhs_value = assembler->TruncateTaggedToWord32(context, right); | 1712 Node* right = assembler.Parameter(1); |
1712 Node* value = assembler->Word32And(lhs_value, rhs_value); | 1713 Node* context = assembler.Parameter(2); |
1713 Node* result = assembler->ChangeInt32ToTagged(value); | 1714 |
1714 assembler->Return(result); | 1715 Node* lhs_value = assembler.TruncateTaggedToWord32(context, left); |
1715 } | 1716 Node* rhs_value = assembler.TruncateTaggedToWord32(context, right); |
1716 | 1717 Node* value = assembler.Word32And(lhs_value, rhs_value); |
1717 void Builtins::Generate_BitwiseOr(CodeStubAssembler* assembler) { | 1718 Node* result = assembler.ChangeInt32ToTagged(value); |
1718 compiler::Node* left = assembler->Parameter(0); | 1719 assembler.Return(result); |
1719 compiler::Node* right = assembler->Parameter(1); | 1720 } |
1720 compiler::Node* context = assembler->Parameter(2); | 1721 |
1721 | 1722 void Builtins::Generate_BitwiseOr(compiler::CodeAssemblerState* state) { |
| 1723 CodeStubAssembler assembler(state); |
1722 using compiler::Node; | 1724 using compiler::Node; |
1723 | 1725 |
1724 Node* lhs_value = assembler->TruncateTaggedToWord32(context, left); | 1726 Node* left = assembler.Parameter(0); |
1725 Node* rhs_value = assembler->TruncateTaggedToWord32(context, right); | 1727 Node* right = assembler.Parameter(1); |
1726 Node* value = assembler->Word32Or(lhs_value, rhs_value); | 1728 Node* context = assembler.Parameter(2); |
1727 Node* result = assembler->ChangeInt32ToTagged(value); | 1729 |
1728 assembler->Return(result); | 1730 Node* lhs_value = assembler.TruncateTaggedToWord32(context, left); |
1729 } | 1731 Node* rhs_value = assembler.TruncateTaggedToWord32(context, right); |
1730 | 1732 Node* value = assembler.Word32Or(lhs_value, rhs_value); |
1731 void Builtins::Generate_BitwiseXor(CodeStubAssembler* assembler) { | 1733 Node* result = assembler.ChangeInt32ToTagged(value); |
1732 compiler::Node* left = assembler->Parameter(0); | 1734 assembler.Return(result); |
1733 compiler::Node* right = assembler->Parameter(1); | 1735 } |
1734 compiler::Node* context = assembler->Parameter(2); | 1736 |
1735 | 1737 void Builtins::Generate_BitwiseXor(compiler::CodeAssemblerState* state) { |
| 1738 CodeStubAssembler assembler(state); |
1736 using compiler::Node; | 1739 using compiler::Node; |
1737 | 1740 |
1738 Node* lhs_value = assembler->TruncateTaggedToWord32(context, left); | 1741 Node* left = assembler.Parameter(0); |
1739 Node* rhs_value = assembler->TruncateTaggedToWord32(context, right); | 1742 Node* right = assembler.Parameter(1); |
1740 Node* value = assembler->Word32Xor(lhs_value, rhs_value); | 1743 Node* context = assembler.Parameter(2); |
1741 Node* result = assembler->ChangeInt32ToTagged(value); | 1744 |
1742 assembler->Return(result); | 1745 Node* lhs_value = assembler.TruncateTaggedToWord32(context, left); |
1743 } | 1746 Node* rhs_value = assembler.TruncateTaggedToWord32(context, right); |
1744 | 1747 Node* value = assembler.Word32Xor(lhs_value, rhs_value); |
1745 void Builtins::Generate_LessThan(CodeStubAssembler* assembler) { | 1748 Node* result = assembler.ChangeInt32ToTagged(value); |
1746 compiler::Node* lhs = assembler->Parameter(0); | 1749 assembler.Return(result); |
1747 compiler::Node* rhs = assembler->Parameter(1); | 1750 } |
1748 compiler::Node* context = assembler->Parameter(2); | 1751 |
1749 | 1752 void Builtins::Generate_LessThan(compiler::CodeAssemblerState* state) { |
1750 assembler->Return(assembler->RelationalComparison( | 1753 CodeStubAssembler assembler(state); |
1751 CodeStubAssembler::kLessThan, lhs, rhs, context)); | 1754 compiler::Node* lhs = assembler.Parameter(0); |
1752 } | 1755 compiler::Node* rhs = assembler.Parameter(1); |
1753 | 1756 compiler::Node* context = assembler.Parameter(2); |
1754 void Builtins::Generate_LessThanOrEqual(CodeStubAssembler* assembler) { | 1757 |
1755 compiler::Node* lhs = assembler->Parameter(0); | 1758 assembler.Return(assembler.RelationalComparison(CodeStubAssembler::kLessThan, |
1756 compiler::Node* rhs = assembler->Parameter(1); | 1759 lhs, rhs, context)); |
1757 compiler::Node* context = assembler->Parameter(2); | 1760 } |
1758 | 1761 |
1759 assembler->Return(assembler->RelationalComparison( | 1762 void Builtins::Generate_LessThanOrEqual(compiler::CodeAssemblerState* state) { |
| 1763 CodeStubAssembler assembler(state); |
| 1764 compiler::Node* lhs = assembler.Parameter(0); |
| 1765 compiler::Node* rhs = assembler.Parameter(1); |
| 1766 compiler::Node* context = assembler.Parameter(2); |
| 1767 |
| 1768 assembler.Return(assembler.RelationalComparison( |
1760 CodeStubAssembler::kLessThanOrEqual, lhs, rhs, context)); | 1769 CodeStubAssembler::kLessThanOrEqual, lhs, rhs, context)); |
1761 } | 1770 } |
1762 | 1771 |
1763 void Builtins::Generate_GreaterThan(CodeStubAssembler* assembler) { | 1772 void Builtins::Generate_GreaterThan(compiler::CodeAssemblerState* state) { |
1764 compiler::Node* lhs = assembler->Parameter(0); | 1773 CodeStubAssembler assembler(state); |
1765 compiler::Node* rhs = assembler->Parameter(1); | 1774 compiler::Node* lhs = assembler.Parameter(0); |
1766 compiler::Node* context = assembler->Parameter(2); | 1775 compiler::Node* rhs = assembler.Parameter(1); |
1767 | 1776 compiler::Node* context = assembler.Parameter(2); |
1768 assembler->Return(assembler->RelationalComparison( | 1777 |
| 1778 assembler.Return(assembler.RelationalComparison( |
1769 CodeStubAssembler::kGreaterThan, lhs, rhs, context)); | 1779 CodeStubAssembler::kGreaterThan, lhs, rhs, context)); |
1770 } | 1780 } |
1771 | 1781 |
1772 void Builtins::Generate_GreaterThanOrEqual(CodeStubAssembler* assembler) { | 1782 void Builtins::Generate_GreaterThanOrEqual( |
1773 compiler::Node* lhs = assembler->Parameter(0); | 1783 compiler::CodeAssemblerState* state) { |
1774 compiler::Node* rhs = assembler->Parameter(1); | 1784 CodeStubAssembler assembler(state); |
1775 compiler::Node* context = assembler->Parameter(2); | 1785 compiler::Node* lhs = assembler.Parameter(0); |
1776 | 1786 compiler::Node* rhs = assembler.Parameter(1); |
1777 assembler->Return(assembler->RelationalComparison( | 1787 compiler::Node* context = assembler.Parameter(2); |
| 1788 |
| 1789 assembler.Return(assembler.RelationalComparison( |
1778 CodeStubAssembler::kGreaterThanOrEqual, lhs, rhs, context)); | 1790 CodeStubAssembler::kGreaterThanOrEqual, lhs, rhs, context)); |
1779 } | 1791 } |
1780 | 1792 |
1781 void Builtins::Generate_Equal(CodeStubAssembler* assembler) { | 1793 void Builtins::Generate_Equal(compiler::CodeAssemblerState* state) { |
1782 compiler::Node* lhs = assembler->Parameter(0); | 1794 CodeStubAssembler assembler(state); |
1783 compiler::Node* rhs = assembler->Parameter(1); | 1795 compiler::Node* lhs = assembler.Parameter(0); |
1784 compiler::Node* context = assembler->Parameter(2); | 1796 compiler::Node* rhs = assembler.Parameter(1); |
1785 | 1797 compiler::Node* context = assembler.Parameter(2); |
1786 assembler->Return(assembler->Equal(CodeStubAssembler::kDontNegateResult, lhs, | 1798 |
1787 rhs, context)); | 1799 assembler.Return( |
1788 } | 1800 assembler.Equal(CodeStubAssembler::kDontNegateResult, lhs, rhs, context)); |
1789 | 1801 } |
1790 void Builtins::Generate_NotEqual(CodeStubAssembler* assembler) { | 1802 |
1791 compiler::Node* lhs = assembler->Parameter(0); | 1803 void Builtins::Generate_NotEqual(compiler::CodeAssemblerState* state) { |
1792 compiler::Node* rhs = assembler->Parameter(1); | 1804 CodeStubAssembler assembler(state); |
1793 compiler::Node* context = assembler->Parameter(2); | 1805 compiler::Node* lhs = assembler.Parameter(0); |
1794 | 1806 compiler::Node* rhs = assembler.Parameter(1); |
1795 assembler->Return( | 1807 compiler::Node* context = assembler.Parameter(2); |
1796 assembler->Equal(CodeStubAssembler::kNegateResult, lhs, rhs, context)); | 1808 |
1797 } | 1809 assembler.Return( |
1798 | 1810 assembler.Equal(CodeStubAssembler::kNegateResult, lhs, rhs, context)); |
1799 void Builtins::Generate_StrictEqual(CodeStubAssembler* assembler) { | 1811 } |
1800 compiler::Node* lhs = assembler->Parameter(0); | 1812 |
1801 compiler::Node* rhs = assembler->Parameter(1); | 1813 void Builtins::Generate_StrictEqual(compiler::CodeAssemblerState* state) { |
1802 compiler::Node* context = assembler->Parameter(2); | 1814 CodeStubAssembler assembler(state); |
1803 | 1815 compiler::Node* lhs = assembler.Parameter(0); |
1804 assembler->Return(assembler->StrictEqual(CodeStubAssembler::kDontNegateResult, | 1816 compiler::Node* rhs = assembler.Parameter(1); |
1805 lhs, rhs, context)); | 1817 compiler::Node* context = assembler.Parameter(2); |
1806 } | 1818 |
1807 | 1819 assembler.Return(assembler.StrictEqual(CodeStubAssembler::kDontNegateResult, |
1808 void Builtins::Generate_StrictNotEqual(CodeStubAssembler* assembler) { | 1820 lhs, rhs, context)); |
1809 compiler::Node* lhs = assembler->Parameter(0); | 1821 } |
1810 compiler::Node* rhs = assembler->Parameter(1); | 1822 |
1811 compiler::Node* context = assembler->Parameter(2); | 1823 void Builtins::Generate_StrictNotEqual(compiler::CodeAssemblerState* state) { |
1812 | 1824 CodeStubAssembler assembler(state); |
1813 assembler->Return(assembler->StrictEqual(CodeStubAssembler::kNegateResult, | 1825 compiler::Node* lhs = assembler.Parameter(0); |
1814 lhs, rhs, context)); | 1826 compiler::Node* rhs = assembler.Parameter(1); |
| 1827 compiler::Node* context = assembler.Parameter(2); |
| 1828 |
| 1829 assembler.Return(assembler.StrictEqual(CodeStubAssembler::kNegateResult, lhs, |
| 1830 rhs, context)); |
1815 } | 1831 } |
1816 | 1832 |
1817 } // namespace internal | 1833 } // namespace internal |
1818 } // namespace v8 | 1834 } // namespace v8 |
OLD | NEW |