| 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 namespace v8 { | 7 namespace v8 { |
| 8 namespace internal { | 8 namespace internal { |
| 9 namespace interpreter { | 9 namespace interpreter { |
| 10 | 10 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 __ Bind(&lower_case); \ | 51 __ Bind(&lower_case); \ |
| 52 if (FLAG_debug_code && expected_arg_count >= 0) { \ | 52 if (FLAG_debug_code && expected_arg_count >= 0) { \ |
| 53 AbortIfArgCountMismatch(expected_arg_count, arg_count); \ | 53 AbortIfArgCountMismatch(expected_arg_count, arg_count); \ |
| 54 } \ | 54 } \ |
| 55 result.Bind(name(first_arg_reg, arg_count, context)); \ | 55 result.Bind(name(first_arg_reg, arg_count, context)); \ |
| 56 __ Goto(&end); | 56 __ Goto(&end); |
| 57 INTRINSICS_LIST(HANDLE_CASE) | 57 INTRINSICS_LIST(HANDLE_CASE) |
| 58 #undef HANDLE_CASE | 58 #undef HANDLE_CASE |
| 59 | 59 |
| 60 __ Bind(&abort); | 60 __ Bind(&abort); |
| 61 __ Abort(BailoutReason::kUnexpectedFunctionIDForInvokeIntrinsic); | 61 { |
| 62 result.Bind(__ UndefinedConstant()); | 62 __ Abort(BailoutReason::kUnexpectedFunctionIDForInvokeIntrinsic); |
| 63 __ Goto(&end); | 63 result.Bind(__ UndefinedConstant()); |
| 64 __ Goto(&end); |
| 65 } |
| 64 | 66 |
| 65 __ Bind(&end); | 67 __ Bind(&end); |
| 66 return result.value(); | 68 return result.value(); |
| 67 } | 69 } |
| 68 | 70 |
| 69 Node* IntrinsicsHelper::CompareInstanceType(Node* map, int type, | 71 Node* IntrinsicsHelper::CompareInstanceType(Node* map, int type, |
| 70 InstanceTypeCompareMode mode) { | 72 InstanceTypeCompareMode mode) { |
| 71 InterpreterAssembler::Variable return_value(assembler_, | 73 InterpreterAssembler::Variable return_value(assembler_, |
| 72 MachineRepresentation::kTagged); | 74 MachineRepresentation::kTagged); |
| 73 Node* instance_type = __ LoadInstanceType(map); | 75 Node* instance_type = __ LoadInstanceType(map); |
| 74 | 76 |
| 75 InterpreterAssembler::Label if_true(assembler_), if_false(assembler_), | 77 InterpreterAssembler::Label if_true(assembler_), if_false(assembler_), |
| 76 end(assembler_); | 78 end(assembler_); |
| 77 Node* condition; | 79 Node* condition; |
| 78 if (mode == kInstanceTypeEqual) { | 80 if (mode == kInstanceTypeEqual) { |
| 79 condition = __ Word32Equal(instance_type, __ Int32Constant(type)); | 81 condition = __ Word32Equal(instance_type, __ Int32Constant(type)); |
| 80 } else { | 82 } else { |
| 81 DCHECK(mode == kInstanceTypeGreaterThanOrEqual); | 83 DCHECK(mode == kInstanceTypeGreaterThanOrEqual); |
| 82 condition = | 84 condition = |
| 83 __ Int32GreaterThanOrEqual(instance_type, __ Int32Constant(type)); | 85 __ Int32GreaterThanOrEqual(instance_type, __ Int32Constant(type)); |
| 84 } | 86 } |
| 85 __ Branch(condition, &if_true, &if_false); | 87 __ Branch(condition, &if_true, &if_false); |
| 86 | 88 |
| 87 __ Bind(&if_true); | 89 __ Bind(&if_true); |
| 88 return_value.Bind(__ BooleanConstant(true)); | 90 { |
| 89 __ Goto(&end); | 91 return_value.Bind(__ BooleanConstant(true)); |
| 92 __ Goto(&end); |
| 93 } |
| 90 | 94 |
| 91 __ Bind(&if_false); | 95 __ Bind(&if_false); |
| 92 return_value.Bind(__ BooleanConstant(false)); | 96 { |
| 93 __ Goto(&end); | 97 return_value.Bind(__ BooleanConstant(false)); |
| 98 __ Goto(&end); |
| 99 } |
| 94 | 100 |
| 95 __ Bind(&end); | 101 __ Bind(&end); |
| 96 return return_value.value(); | 102 return return_value.value(); |
| 103 } |
| 104 |
| 105 Node* IntrinsicsHelper::IsInstanceType(Node* input, int type) { |
| 106 InterpreterAssembler::Variable return_value(assembler_, |
| 107 MachineRepresentation::kTagged); |
| 108 InterpreterAssembler::Label if_smi(assembler_), if_not_smi(assembler_), |
| 109 end(assembler_); |
| 110 Node* arg = __ LoadRegister(input); |
| 111 __ Branch(__ WordIsSmi(arg), &if_smi, &if_not_smi); |
| 112 |
| 113 __ Bind(&if_smi); |
| 114 { |
| 115 return_value.Bind(__ BooleanConstant(false)); |
| 116 __ Goto(&end); |
| 117 } |
| 118 |
| 119 __ Bind(&if_not_smi); |
| 120 { |
| 121 return_value.Bind(CompareInstanceType(arg, type, kInstanceTypeEqual)); |
| 122 __ Goto(&end); |
| 123 } |
| 124 |
| 125 __ Bind(&end); |
| 126 return return_value.value(); |
| 97 } | 127 } |
| 98 | 128 |
| 99 Node* IntrinsicsHelper::IsJSReceiver(Node* input, Node* arg_count, | 129 Node* IntrinsicsHelper::IsJSReceiver(Node* input, Node* arg_count, |
| 100 Node* context) { | 130 Node* context) { |
| 101 InterpreterAssembler::Variable return_value(assembler_, | 131 InterpreterAssembler::Variable return_value(assembler_, |
| 102 MachineRepresentation::kTagged); | 132 MachineRepresentation::kTagged); |
| 103 | |
| 104 InterpreterAssembler::Label if_smi(assembler_), if_not_smi(assembler_), | 133 InterpreterAssembler::Label if_smi(assembler_), if_not_smi(assembler_), |
| 105 end(assembler_); | 134 end(assembler_); |
| 135 |
| 106 Node* arg = __ LoadRegister(input); | 136 Node* arg = __ LoadRegister(input); |
| 137 __ Branch(__ WordIsSmi(arg), &if_smi, &if_not_smi); |
| 107 | 138 |
| 108 __ Branch(__ WordIsSmi(arg), &if_smi, &if_not_smi); | |
| 109 __ Bind(&if_smi); | 139 __ Bind(&if_smi); |
| 110 return_value.Bind(__ BooleanConstant(false)); | 140 { |
| 111 __ Goto(&end); | 141 return_value.Bind(__ BooleanConstant(false)); |
| 142 __ Goto(&end); |
| 143 } |
| 112 | 144 |
| 113 __ Bind(&if_not_smi); | 145 __ Bind(&if_not_smi); |
| 114 STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE); | 146 { |
| 115 return_value.Bind(CompareInstanceType(arg, FIRST_JS_RECEIVER_TYPE, | 147 STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE); |
| 116 kInstanceTypeGreaterThanOrEqual)); | 148 return_value.Bind(CompareInstanceType(arg, FIRST_JS_RECEIVER_TYPE, |
| 117 __ Goto(&end); | 149 kInstanceTypeGreaterThanOrEqual)); |
| 150 __ Goto(&end); |
| 151 } |
| 118 | 152 |
| 119 __ Bind(&end); | 153 __ Bind(&end); |
| 120 return return_value.value(); | 154 return return_value.value(); |
| 121 } | 155 } |
| 122 | 156 |
| 123 Node* IntrinsicsHelper::IsArray(Node* input, Node* arg_count, Node* context) { | 157 Node* IntrinsicsHelper::IsArray(Node* input, Node* arg_count, Node* context) { |
| 158 return IsInstanceType(input, JS_ARRAY_TYPE); |
| 159 } |
| 160 |
| 161 Node* IntrinsicsHelper::IsJSProxy(Node* input, Node* arg_count, Node* context) { |
| 162 return IsInstanceType(input, JS_PROXY_TYPE); |
| 163 } |
| 164 |
| 165 Node* IntrinsicsHelper::IsRegExp(Node* input, Node* arg_count, Node* context) { |
| 166 return IsInstanceType(input, JS_REGEXP_TYPE); |
| 167 } |
| 168 |
| 169 Node* IntrinsicsHelper::IsTypedArray(Node* input, Node* arg_count, |
| 170 Node* context) { |
| 171 return IsInstanceType(input, JS_TYPED_ARRAY_TYPE); |
| 172 } |
| 173 |
| 174 Node* IntrinsicsHelper::IsSmi(Node* input, Node* arg_count, Node* context) { |
| 124 InterpreterAssembler::Variable return_value(assembler_, | 175 InterpreterAssembler::Variable return_value(assembler_, |
| 125 MachineRepresentation::kTagged); | 176 MachineRepresentation::kTagged); |
| 126 | |
| 127 InterpreterAssembler::Label if_smi(assembler_), if_not_smi(assembler_), | 177 InterpreterAssembler::Label if_smi(assembler_), if_not_smi(assembler_), |
| 128 end(assembler_); | 178 end(assembler_); |
| 179 |
| 129 Node* arg = __ LoadRegister(input); | 180 Node* arg = __ LoadRegister(input); |
| 130 | 181 |
| 131 __ Branch(__ WordIsSmi(arg), &if_smi, &if_not_smi); | 182 __ Branch(__ WordIsSmi(arg), &if_smi, &if_not_smi); |
| 132 __ Bind(&if_smi); | 183 __ Bind(&if_smi); |
| 133 return_value.Bind(__ BooleanConstant(false)); | 184 { |
| 134 __ Goto(&end); | 185 return_value.Bind(__ BooleanConstant(true)); |
| 186 __ Goto(&end); |
| 187 } |
| 135 | 188 |
| 136 __ Bind(&if_not_smi); | 189 __ Bind(&if_not_smi); |
| 137 return_value.Bind( | 190 { |
| 138 CompareInstanceType(arg, JS_ARRAY_TYPE, kInstanceTypeEqual)); | 191 return_value.Bind(__ BooleanConstant(false)); |
| 139 __ Goto(&end); | 192 __ Goto(&end); |
| 193 } |
| 140 | 194 |
| 141 __ Bind(&end); | 195 __ Bind(&end); |
| 142 return return_value.value(); | 196 return return_value.value(); |
| 143 } | 197 } |
| 144 | 198 |
| 145 Node* IntrinsicsHelper::Call(Node* args_reg, Node* arg_count, Node* context) { | 199 Node* IntrinsicsHelper::Call(Node* args_reg, Node* arg_count, Node* context) { |
| 146 // First argument register contains the function target. | 200 // First argument register contains the function target. |
| 147 Node* function = __ LoadRegister(args_reg); | 201 Node* function = __ LoadRegister(args_reg); |
| 148 | 202 |
| 149 // Receiver is the second runtime call argument. | 203 // Receiver is the second runtime call argument. |
| (...skipping 23 matching lines...) Expand all Loading... |
| 173 Node* comparison = __ Word32Equal(actual, __ Int32Constant(expected)); | 227 Node* comparison = __ Word32Equal(actual, __ Int32Constant(expected)); |
| 174 __ GotoIf(comparison, &match); | 228 __ GotoIf(comparison, &match); |
| 175 __ Abort(kWrongArgumentCountForInvokeIntrinsic); | 229 __ Abort(kWrongArgumentCountForInvokeIntrinsic); |
| 176 __ Goto(&match); | 230 __ Goto(&match); |
| 177 __ Bind(&match); | 231 __ Bind(&match); |
| 178 } | 232 } |
| 179 | 233 |
| 180 } // namespace interpreter | 234 } // namespace interpreter |
| 181 } // namespace internal | 235 } // namespace internal |
| 182 } // namespace v8 | 236 } // namespace v8 |
| OLD | NEW |