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 |