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