| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/interpreter/interpreter-intrinsics.h" | 5 #include "src/interpreter/interpreter-intrinsics.h" |
| 6 | 6 |
| 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 { |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 104 } | 104 } |
| 105 | 105 |
| 106 Node* IntrinsicsHelper::CompareInstanceType(Node* map, int type, | 106 Node* IntrinsicsHelper::CompareInstanceType(Node* map, int type, |
| 107 InstanceTypeCompareMode mode) { | 107 InstanceTypeCompareMode mode) { |
| 108 InterpreterAssembler::Variable return_value(assembler_, | 108 InterpreterAssembler::Variable return_value(assembler_, |
| 109 MachineRepresentation::kTagged); | 109 MachineRepresentation::kTagged); |
| 110 Node* instance_type = __ LoadInstanceType(map); | 110 Node* instance_type = __ LoadInstanceType(map); |
| 111 | 111 |
| 112 InterpreterAssembler::Label if_true(assembler_), if_false(assembler_), | 112 InterpreterAssembler::Label if_true(assembler_), if_false(assembler_), |
| 113 end(assembler_); | 113 end(assembler_); |
| 114 Node* condition; | |
| 115 if (mode == kInstanceTypeEqual) { | 114 if (mode == kInstanceTypeEqual) { |
| 116 condition = __ Word32Equal(instance_type, __ Int32Constant(type)); | 115 return __ Word32Equal(instance_type, __ Int32Constant(type)); |
| 117 } else { | 116 } else { |
| 118 DCHECK(mode == kInstanceTypeGreaterThanOrEqual); | 117 DCHECK(mode == kInstanceTypeGreaterThanOrEqual); |
| 119 condition = | 118 return __ Int32GreaterThanOrEqual(instance_type, __ Int32Constant(type)); |
| 120 __ Int32GreaterThanOrEqual(instance_type, __ Int32Constant(type)); | |
| 121 } | 119 } |
| 122 __ Branch(condition, &if_true, &if_false); | 120 } |
| 123 | 121 |
| 124 __ Bind(&if_true); | 122 Node* IntrinsicsHelper::IsInstanceType(Node* input, int type) { |
| 123 InterpreterAssembler::Variable return_value(assembler_, |
| 124 MachineRepresentation::kTagged); |
| 125 InterpreterAssembler::Label if_not_smi(assembler_), return_true(assembler_), |
| 126 return_false(assembler_), end(assembler_); |
| 127 Node* arg = __ LoadRegister(input); |
| 128 __ GotoIf(__ WordIsSmi(arg), &return_false); |
| 129 |
| 130 Node* condition = CompareInstanceType(arg, type, kInstanceTypeEqual); |
| 131 __ Branch(condition, &return_true, &return_false); |
| 132 |
| 133 __ Bind(&return_true); |
| 125 { | 134 { |
| 126 return_value.Bind(__ BooleanConstant(true)); | 135 return_value.Bind(__ BooleanConstant(true)); |
| 127 __ Goto(&end); | 136 __ Goto(&end); |
| 128 } | 137 } |
| 129 | 138 |
| 130 __ Bind(&if_false); | 139 __ Bind(&return_false); |
| 131 { | 140 { |
| 132 return_value.Bind(__ BooleanConstant(false)); | 141 return_value.Bind(__ BooleanConstant(false)); |
| 133 __ Goto(&end); | 142 __ Goto(&end); |
| 134 } | 143 } |
| 135 | 144 |
| 136 __ Bind(&end); | |
| 137 return return_value.value(); | |
| 138 } | |
| 139 | |
| 140 Node* IntrinsicsHelper::IsInstanceType(Node* input, int type) { | |
| 141 InterpreterAssembler::Variable return_value(assembler_, | |
| 142 MachineRepresentation::kTagged); | |
| 143 InterpreterAssembler::Label if_smi(assembler_), if_not_smi(assembler_), | |
| 144 end(assembler_); | |
| 145 Node* arg = __ LoadRegister(input); | |
| 146 __ Branch(__ WordIsSmi(arg), &if_smi, &if_not_smi); | |
| 147 | |
| 148 __ Bind(&if_smi); | |
| 149 { | |
| 150 return_value.Bind(__ BooleanConstant(false)); | |
| 151 __ Goto(&end); | |
| 152 } | |
| 153 | |
| 154 __ Bind(&if_not_smi); | |
| 155 { | |
| 156 return_value.Bind(CompareInstanceType(arg, type, kInstanceTypeEqual)); | |
| 157 __ Goto(&end); | |
| 158 } | |
| 159 | |
| 160 __ Bind(&end); | 145 __ Bind(&end); |
| 161 return return_value.value(); | 146 return return_value.value(); |
| 162 } | 147 } |
| 163 | 148 |
| 164 Node* IntrinsicsHelper::IsJSReceiver(Node* input, Node* arg_count, | 149 Node* IntrinsicsHelper::IsJSReceiver(Node* input, Node* arg_count, |
| 165 Node* context) { | 150 Node* context) { |
| 166 InterpreterAssembler::Variable return_value(assembler_, | 151 InterpreterAssembler::Variable return_value(assembler_, |
| 167 MachineRepresentation::kTagged); | 152 MachineRepresentation::kTagged); |
| 168 InterpreterAssembler::Label if_smi(assembler_), if_not_smi(assembler_), | 153 InterpreterAssembler::Label return_true(assembler_), return_false(assembler_), |
| 169 end(assembler_); | 154 end(assembler_); |
| 170 | 155 |
| 171 Node* arg = __ LoadRegister(input); | 156 Node* arg = __ LoadRegister(input); |
| 172 __ Branch(__ WordIsSmi(arg), &if_smi, &if_not_smi); | 157 __ GotoIf(__ WordIsSmi(arg), &return_false); |
| 173 | 158 |
| 174 __ Bind(&if_smi); | 159 STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE); |
| 160 Node* condition = CompareInstanceType(arg, FIRST_JS_RECEIVER_TYPE, |
| 161 kInstanceTypeGreaterThanOrEqual); |
| 162 __ Branch(condition, &return_true, &return_false); |
| 163 |
| 164 __ Bind(&return_true); |
| 165 { |
| 166 return_value.Bind(__ BooleanConstant(true)); |
| 167 __ Goto(&end); |
| 168 } |
| 169 |
| 170 __ Bind(&return_false); |
| 175 { | 171 { |
| 176 return_value.Bind(__ BooleanConstant(false)); | 172 return_value.Bind(__ BooleanConstant(false)); |
| 177 __ Goto(&end); | 173 __ Goto(&end); |
| 178 } | 174 } |
| 179 | 175 |
| 180 __ Bind(&if_not_smi); | |
| 181 { | |
| 182 STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE); | |
| 183 return_value.Bind(CompareInstanceType(arg, FIRST_JS_RECEIVER_TYPE, | |
| 184 kInstanceTypeGreaterThanOrEqual)); | |
| 185 __ Goto(&end); | |
| 186 } | |
| 187 | |
| 188 __ Bind(&end); | 176 __ Bind(&end); |
| 189 return return_value.value(); | 177 return return_value.value(); |
| 190 } | 178 } |
| 191 | 179 |
| 192 Node* IntrinsicsHelper::IsArray(Node* input, Node* arg_count, Node* context) { | 180 Node* IntrinsicsHelper::IsArray(Node* input, Node* arg_count, Node* context) { |
| 193 return IsInstanceType(input, JS_ARRAY_TYPE); | 181 return IsInstanceType(input, JS_ARRAY_TYPE); |
| 194 } | 182 } |
| 195 | 183 |
| 196 Node* IntrinsicsHelper::IsJSProxy(Node* input, Node* arg_count, Node* context) { | 184 Node* IntrinsicsHelper::IsJSProxy(Node* input, Node* arg_count, Node* context) { |
| 197 return IsInstanceType(input, JS_PROXY_TYPE); | 185 return IsInstanceType(input, JS_PROXY_TYPE); |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 324 __ Abort(kWrongArgumentCountForInvokeIntrinsic); | 312 __ Abort(kWrongArgumentCountForInvokeIntrinsic); |
| 325 __ Goto(&arg_count_positive); | 313 __ Goto(&arg_count_positive); |
| 326 __ Bind(&arg_count_positive); | 314 __ Bind(&arg_count_positive); |
| 327 } | 315 } |
| 328 | 316 |
| 329 Node* result = __ CallJS(function, context, receiver_arg, target_args_count, | 317 Node* result = __ CallJS(function, context, receiver_arg, target_args_count, |
| 330 TailCallMode::kDisallow); | 318 TailCallMode::kDisallow); |
| 331 return result; | 319 return result; |
| 332 } | 320 } |
| 333 | 321 |
| 322 Node* IntrinsicsHelper::ValueOf(Node* args_reg, Node* arg_count, |
| 323 Node* context) { |
| 324 InterpreterAssembler::Variable return_value(assembler_, |
| 325 MachineRepresentation::kTagged); |
| 326 InterpreterAssembler::Label done(assembler_); |
| 327 |
| 328 Node* object = __ LoadRegister(args_reg); |
| 329 return_value.Bind(object); |
| 330 |
| 331 // If the object is a smi return the object. |
| 332 __ GotoIf(__ WordIsSmi(object), &done); |
| 333 |
| 334 // If the object is not a value type, return the object. |
| 335 Node* condition = |
| 336 CompareInstanceType(object, JS_VALUE_TYPE, kInstanceTypeEqual); |
| 337 __ GotoUnless(condition, &done); |
| 338 |
| 339 // If the object is a value type, return the value field. |
| 340 return_value.Bind(__ LoadObjectField(object, JSValue::kValueOffset)); |
| 341 __ Goto(&done); |
| 342 |
| 343 __ Bind(&done); |
| 344 return return_value.value(); |
| 345 } |
| 346 |
| 334 void IntrinsicsHelper::AbortIfArgCountMismatch(int expected, Node* actual) { | 347 void IntrinsicsHelper::AbortIfArgCountMismatch(int expected, Node* actual) { |
| 335 InterpreterAssembler::Label match(assembler_); | 348 InterpreterAssembler::Label match(assembler_); |
| 336 Node* comparison = __ Word32Equal(actual, __ Int32Constant(expected)); | 349 Node* comparison = __ Word32Equal(actual, __ Int32Constant(expected)); |
| 337 __ GotoIf(comparison, &match); | 350 __ GotoIf(comparison, &match); |
| 338 __ Abort(kWrongArgumentCountForInvokeIntrinsic); | 351 __ Abort(kWrongArgumentCountForInvokeIntrinsic); |
| 339 __ Goto(&match); | 352 __ Goto(&match); |
| 340 __ Bind(&match); | 353 __ Bind(&match); |
| 341 } | 354 } |
| 342 | 355 |
| 343 } // namespace interpreter | 356 } // namespace interpreter |
| 344 } // namespace internal | 357 } // namespace internal |
| 345 } // namespace v8 | 358 } // namespace v8 |
| OLD | NEW |