OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2017 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-generator.h" |
| 6 |
| 7 #include "src/allocation.h" |
| 8 #include "src/builtins/builtins.h" |
| 9 #include "src/code-factory.h" |
| 10 #include "src/frames.h" |
| 11 #include "src/interpreter/bytecodes.h" |
| 12 #include "src/interpreter/interpreter-assembler.h" |
5 #include "src/interpreter/interpreter-intrinsics.h" | 13 #include "src/interpreter/interpreter-intrinsics.h" |
6 | 14 |
7 #include "src/code-factory.h" | |
8 #include "src/objects-inl.h" | |
9 | |
10 namespace v8 { | 15 namespace v8 { |
11 namespace internal { | 16 namespace internal { |
12 namespace interpreter { | 17 namespace interpreter { |
13 | 18 |
14 using compiler::Node; | 19 using compiler::Node; |
15 | 20 |
| 21 class IntrinsicsGenerator { |
| 22 public: |
| 23 explicit IntrinsicsGenerator(InterpreterAssembler* assembler) |
| 24 : isolate_(assembler->isolate()), |
| 25 zone_(assembler->zone()), |
| 26 assembler_(assembler) {} |
| 27 |
| 28 Node* InvokeIntrinsic(Node* function_id, Node* context, Node* first_arg_reg, |
| 29 Node* arg_count); |
| 30 |
| 31 private: |
| 32 enum InstanceTypeCompareMode { |
| 33 kInstanceTypeEqual, |
| 34 kInstanceTypeGreaterThanOrEqual |
| 35 }; |
| 36 |
| 37 Node* IsInstanceType(Node* input, int type); |
| 38 Node* CompareInstanceType(Node* map, int type, InstanceTypeCompareMode mode); |
| 39 Node* IntrinsicAsStubCall(Node* input, Node* context, |
| 40 Callable const& callable); |
| 41 void AbortIfArgCountMismatch(int expected, compiler::Node* actual); |
| 42 |
| 43 #define DECLARE_INTRINSIC_HELPER(name, lower_case, count) \ |
| 44 Node* name(Node* input, Node* arg_count, Node* context); |
| 45 INTRINSICS_LIST(DECLARE_INTRINSIC_HELPER) |
| 46 #undef DECLARE_INTRINSIC_HELPER |
| 47 |
| 48 Isolate* isolate() { return isolate_; } |
| 49 Zone* zone() { return zone_; } |
| 50 |
| 51 Isolate* isolate_; |
| 52 Zone* zone_; |
| 53 InterpreterAssembler* assembler_; |
| 54 |
| 55 DISALLOW_COPY_AND_ASSIGN(IntrinsicsGenerator); |
| 56 }; |
| 57 |
| 58 Node* GenerateInvokeIntrinsic(InterpreterAssembler* assembler, |
| 59 Node* function_id, Node* context, |
| 60 Node* first_arg_reg, Node* arg_count) { |
| 61 IntrinsicsGenerator generator(assembler); |
| 62 return generator.InvokeIntrinsic(function_id, context, first_arg_reg, |
| 63 arg_count); |
| 64 } |
| 65 |
16 #define __ assembler_-> | 66 #define __ assembler_-> |
17 | 67 |
18 IntrinsicsHelper::IntrinsicsHelper(InterpreterAssembler* assembler) | 68 Node* IntrinsicsGenerator::InvokeIntrinsic(Node* function_id, Node* context, |
19 : isolate_(assembler->isolate()), | 69 Node* first_arg_reg, |
20 zone_(assembler->zone()), | 70 Node* arg_count) { |
21 assembler_(assembler) {} | |
22 | |
23 // static | |
24 bool IntrinsicsHelper::IsSupported(Runtime::FunctionId function_id) { | |
25 switch (function_id) { | |
26 #define SUPPORTED(name, lower_case, count) case Runtime::kInline##name: | |
27 INTRINSICS_LIST(SUPPORTED) | |
28 return true; | |
29 #undef SUPPORTED | |
30 default: | |
31 return false; | |
32 } | |
33 } | |
34 | |
35 // static | |
36 IntrinsicsHelper::IntrinsicId IntrinsicsHelper::FromRuntimeId( | |
37 Runtime::FunctionId function_id) { | |
38 switch (function_id) { | |
39 #define TO_RUNTIME_ID(name, lower_case, count) \ | |
40 case Runtime::kInline##name: \ | |
41 return IntrinsicId::k##name; | |
42 INTRINSICS_LIST(TO_RUNTIME_ID) | |
43 #undef TO_RUNTIME_ID | |
44 default: | |
45 UNREACHABLE(); | |
46 return static_cast<IntrinsicsHelper::IntrinsicId>(-1); | |
47 } | |
48 } | |
49 | |
50 // static | |
51 Runtime::FunctionId IntrinsicsHelper::ToRuntimeId( | |
52 IntrinsicsHelper::IntrinsicId intrinsic_id) { | |
53 switch (intrinsic_id) { | |
54 #define TO_INTRINSIC_ID(name, lower_case, count) \ | |
55 case IntrinsicId::k##name: \ | |
56 return Runtime::kInline##name; | |
57 INTRINSICS_LIST(TO_INTRINSIC_ID) | |
58 #undef TO_INTRINSIC_ID | |
59 default: | |
60 UNREACHABLE(); | |
61 return static_cast<Runtime::FunctionId>(-1); | |
62 } | |
63 } | |
64 | |
65 Node* IntrinsicsHelper::InvokeIntrinsic(Node* function_id, Node* context, | |
66 Node* first_arg_reg, Node* arg_count) { | |
67 InterpreterAssembler::Label abort(assembler_), end(assembler_); | 71 InterpreterAssembler::Label abort(assembler_), end(assembler_); |
68 InterpreterAssembler::Variable result(assembler_, | 72 InterpreterAssembler::Variable result(assembler_, |
69 MachineRepresentation::kTagged); | 73 MachineRepresentation::kTagged); |
70 | 74 |
71 #define MAKE_LABEL(name, lower_case, count) \ | 75 #define MAKE_LABEL(name, lower_case, count) \ |
72 InterpreterAssembler::Label lower_case(assembler_); | 76 InterpreterAssembler::Label lower_case(assembler_); |
73 INTRINSICS_LIST(MAKE_LABEL) | 77 INTRINSICS_LIST(MAKE_LABEL) |
74 #undef MAKE_LABEL | 78 #undef MAKE_LABEL |
75 | 79 |
76 #define LABEL_POINTER(name, lower_case, count) &lower_case, | 80 #define LABEL_POINTER(name, lower_case, count) &lower_case, |
77 InterpreterAssembler::Label* labels[] = {INTRINSICS_LIST(LABEL_POINTER)}; | 81 InterpreterAssembler::Label* labels[] = {INTRINSICS_LIST(LABEL_POINTER)}; |
78 #undef LABEL_POINTER | 82 #undef LABEL_POINTER |
79 | 83 |
80 #define CASE(name, lower_case, count) \ | 84 #define CASE(name, lower_case, count) \ |
81 static_cast<int32_t>(IntrinsicId::k##name), | 85 static_cast<int32_t>(IntrinsicsHelper::IntrinsicId::k##name), |
82 int32_t cases[] = {INTRINSICS_LIST(CASE)}; | 86 int32_t cases[] = {INTRINSICS_LIST(CASE)}; |
83 #undef CASE | 87 #undef CASE |
84 | 88 |
85 __ Switch(function_id, &abort, cases, labels, arraysize(cases)); | 89 __ Switch(function_id, &abort, cases, labels, arraysize(cases)); |
86 #define HANDLE_CASE(name, lower_case, expected_arg_count) \ | 90 #define HANDLE_CASE(name, lower_case, expected_arg_count) \ |
87 __ Bind(&lower_case); \ | 91 __ Bind(&lower_case); \ |
88 if (FLAG_debug_code && expected_arg_count >= 0) { \ | 92 if (FLAG_debug_code && expected_arg_count >= 0) { \ |
89 AbortIfArgCountMismatch(expected_arg_count, arg_count); \ | 93 AbortIfArgCountMismatch(expected_arg_count, arg_count); \ |
90 } \ | 94 } \ |
91 result.Bind(name(first_arg_reg, arg_count, context)); \ | 95 result.Bind(name(first_arg_reg, arg_count, context)); \ |
92 __ Goto(&end); | 96 __ Goto(&end); |
93 INTRINSICS_LIST(HANDLE_CASE) | 97 INTRINSICS_LIST(HANDLE_CASE) |
94 #undef HANDLE_CASE | 98 #undef HANDLE_CASE |
95 | 99 |
96 __ Bind(&abort); | 100 __ Bind(&abort); |
97 { | 101 { |
98 __ Abort(BailoutReason::kUnexpectedFunctionIDForInvokeIntrinsic); | 102 __ Abort(BailoutReason::kUnexpectedFunctionIDForInvokeIntrinsic); |
99 result.Bind(__ UndefinedConstant()); | 103 result.Bind(__ UndefinedConstant()); |
100 __ Goto(&end); | 104 __ Goto(&end); |
101 } | 105 } |
102 | 106 |
103 __ Bind(&end); | 107 __ Bind(&end); |
104 return result.value(); | 108 return result.value(); |
105 } | 109 } |
106 | 110 |
107 Node* IntrinsicsHelper::CompareInstanceType(Node* object, int type, | 111 Node* IntrinsicsGenerator::CompareInstanceType(Node* object, int type, |
108 InstanceTypeCompareMode mode) { | 112 InstanceTypeCompareMode mode) { |
109 Node* instance_type = __ LoadInstanceType(object); | 113 Node* instance_type = __ LoadInstanceType(object); |
110 | 114 |
111 if (mode == kInstanceTypeEqual) { | 115 if (mode == kInstanceTypeEqual) { |
112 return __ Word32Equal(instance_type, __ Int32Constant(type)); | 116 return __ Word32Equal(instance_type, __ Int32Constant(type)); |
113 } else { | 117 } else { |
114 DCHECK(mode == kInstanceTypeGreaterThanOrEqual); | 118 DCHECK(mode == kInstanceTypeGreaterThanOrEqual); |
115 return __ Int32GreaterThanOrEqual(instance_type, __ Int32Constant(type)); | 119 return __ Int32GreaterThanOrEqual(instance_type, __ Int32Constant(type)); |
116 } | 120 } |
117 } | 121 } |
118 | 122 |
119 Node* IntrinsicsHelper::IsInstanceType(Node* input, int type) { | 123 Node* IntrinsicsGenerator::IsInstanceType(Node* input, int type) { |
120 InterpreterAssembler::Variable return_value(assembler_, | 124 InterpreterAssembler::Variable return_value(assembler_, |
121 MachineRepresentation::kTagged); | 125 MachineRepresentation::kTagged); |
122 // TODO(ishell): Use Select here. | 126 // TODO(ishell): Use Select here. |
123 InterpreterAssembler::Label if_not_smi(assembler_), return_true(assembler_), | 127 InterpreterAssembler::Label if_not_smi(assembler_), return_true(assembler_), |
124 return_false(assembler_), end(assembler_); | 128 return_false(assembler_), end(assembler_); |
125 Node* arg = __ LoadRegister(input); | 129 Node* arg = __ LoadRegister(input); |
126 __ GotoIf(__ TaggedIsSmi(arg), &return_false); | 130 __ GotoIf(__ TaggedIsSmi(arg), &return_false); |
127 | 131 |
128 Node* condition = CompareInstanceType(arg, type, kInstanceTypeEqual); | 132 Node* condition = CompareInstanceType(arg, type, kInstanceTypeEqual); |
129 __ Branch(condition, &return_true, &return_false); | 133 __ Branch(condition, &return_true, &return_false); |
130 | 134 |
131 __ Bind(&return_true); | 135 __ Bind(&return_true); |
132 { | 136 { |
133 return_value.Bind(__ BooleanConstant(true)); | 137 return_value.Bind(__ BooleanConstant(true)); |
134 __ Goto(&end); | 138 __ Goto(&end); |
135 } | 139 } |
136 | 140 |
137 __ Bind(&return_false); | 141 __ Bind(&return_false); |
138 { | 142 { |
139 return_value.Bind(__ BooleanConstant(false)); | 143 return_value.Bind(__ BooleanConstant(false)); |
140 __ Goto(&end); | 144 __ Goto(&end); |
141 } | 145 } |
142 | 146 |
143 __ Bind(&end); | 147 __ Bind(&end); |
144 return return_value.value(); | 148 return return_value.value(); |
145 } | 149 } |
146 | 150 |
147 Node* IntrinsicsHelper::IsJSReceiver(Node* input, Node* arg_count, | 151 Node* IntrinsicsGenerator::IsJSReceiver(Node* input, Node* arg_count, |
148 Node* context) { | 152 Node* context) { |
149 // TODO(ishell): Use Select here. | 153 // TODO(ishell): Use Select here. |
150 // TODO(ishell): Use CSA::IsJSReceiverInstanceType here. | 154 // TODO(ishell): Use CSA::IsJSReceiverInstanceType here. |
151 InterpreterAssembler::Variable return_value(assembler_, | 155 InterpreterAssembler::Variable return_value(assembler_, |
152 MachineRepresentation::kTagged); | 156 MachineRepresentation::kTagged); |
153 InterpreterAssembler::Label return_true(assembler_), return_false(assembler_), | 157 InterpreterAssembler::Label return_true(assembler_), return_false(assembler_), |
154 end(assembler_); | 158 end(assembler_); |
155 | 159 |
156 Node* arg = __ LoadRegister(input); | 160 Node* arg = __ LoadRegister(input); |
157 __ GotoIf(__ TaggedIsSmi(arg), &return_false); | 161 __ GotoIf(__ TaggedIsSmi(arg), &return_false); |
158 | 162 |
(...skipping 11 matching lines...) Expand all Loading... |
170 __ Bind(&return_false); | 174 __ Bind(&return_false); |
171 { | 175 { |
172 return_value.Bind(__ BooleanConstant(false)); | 176 return_value.Bind(__ BooleanConstant(false)); |
173 __ Goto(&end); | 177 __ Goto(&end); |
174 } | 178 } |
175 | 179 |
176 __ Bind(&end); | 180 __ Bind(&end); |
177 return return_value.value(); | 181 return return_value.value(); |
178 } | 182 } |
179 | 183 |
180 Node* IntrinsicsHelper::IsArray(Node* input, Node* arg_count, Node* context) { | 184 Node* IntrinsicsGenerator::IsArray(Node* input, Node* arg_count, |
| 185 Node* context) { |
181 return IsInstanceType(input, JS_ARRAY_TYPE); | 186 return IsInstanceType(input, JS_ARRAY_TYPE); |
182 } | 187 } |
183 | 188 |
184 Node* IntrinsicsHelper::IsJSProxy(Node* input, Node* arg_count, Node* context) { | 189 Node* IntrinsicsGenerator::IsJSProxy(Node* input, Node* arg_count, |
| 190 Node* context) { |
185 return IsInstanceType(input, JS_PROXY_TYPE); | 191 return IsInstanceType(input, JS_PROXY_TYPE); |
186 } | 192 } |
187 | 193 |
188 Node* IntrinsicsHelper::IsTypedArray(Node* input, Node* arg_count, | 194 Node* IntrinsicsGenerator::IsTypedArray(Node* input, Node* arg_count, |
189 Node* context) { | 195 Node* context) { |
190 return IsInstanceType(input, JS_TYPED_ARRAY_TYPE); | 196 return IsInstanceType(input, JS_TYPED_ARRAY_TYPE); |
191 } | 197 } |
192 | 198 |
193 Node* IntrinsicsHelper::IsSmi(Node* input, Node* arg_count, Node* context) { | 199 Node* IntrinsicsGenerator::IsSmi(Node* input, Node* arg_count, Node* context) { |
194 // TODO(ishell): Use SelectBooleanConstant here. | 200 // TODO(ishell): Use SelectBooleanConstant here. |
195 InterpreterAssembler::Variable return_value(assembler_, | 201 InterpreterAssembler::Variable return_value(assembler_, |
196 MachineRepresentation::kTagged); | 202 MachineRepresentation::kTagged); |
197 InterpreterAssembler::Label if_smi(assembler_), if_not_smi(assembler_), | 203 InterpreterAssembler::Label if_smi(assembler_), if_not_smi(assembler_), |
198 end(assembler_); | 204 end(assembler_); |
199 | 205 |
200 Node* arg = __ LoadRegister(input); | 206 Node* arg = __ LoadRegister(input); |
201 | 207 |
202 __ Branch(__ TaggedIsSmi(arg), &if_smi, &if_not_smi); | 208 __ Branch(__ TaggedIsSmi(arg), &if_smi, &if_not_smi); |
203 __ Bind(&if_smi); | 209 __ Bind(&if_smi); |
204 { | 210 { |
205 return_value.Bind(__ BooleanConstant(true)); | 211 return_value.Bind(__ BooleanConstant(true)); |
206 __ Goto(&end); | 212 __ Goto(&end); |
207 } | 213 } |
208 | 214 |
209 __ Bind(&if_not_smi); | 215 __ Bind(&if_not_smi); |
210 { | 216 { |
211 return_value.Bind(__ BooleanConstant(false)); | 217 return_value.Bind(__ BooleanConstant(false)); |
212 __ Goto(&end); | 218 __ Goto(&end); |
213 } | 219 } |
214 | 220 |
215 __ Bind(&end); | 221 __ Bind(&end); |
216 return return_value.value(); | 222 return return_value.value(); |
217 } | 223 } |
218 | 224 |
219 Node* IntrinsicsHelper::IntrinsicAsStubCall(Node* args_reg, Node* context, | 225 Node* IntrinsicsGenerator::IntrinsicAsStubCall(Node* args_reg, Node* context, |
220 Callable const& callable) { | 226 Callable const& callable) { |
221 int param_count = callable.descriptor().GetParameterCount(); | 227 int param_count = callable.descriptor().GetParameterCount(); |
222 int input_count = param_count + 2; // +2 for target and context | 228 int input_count = param_count + 2; // +2 for target and context |
223 Node** args = zone()->NewArray<Node*>(input_count); | 229 Node** args = zone()->NewArray<Node*>(input_count); |
224 int index = 0; | 230 int index = 0; |
225 args[index++] = __ HeapConstant(callable.code()); | 231 args[index++] = __ HeapConstant(callable.code()); |
226 for (int i = 0; i < param_count; i++) { | 232 for (int i = 0; i < param_count; i++) { |
227 args[index++] = __ LoadRegister(args_reg); | 233 args[index++] = __ LoadRegister(args_reg); |
228 args_reg = __ NextRegister(args_reg); | 234 args_reg = __ NextRegister(args_reg); |
229 } | 235 } |
230 args[index++] = context; | 236 args[index++] = context; |
231 return __ CallStubN(callable.descriptor(), 1, input_count, args); | 237 return __ CallStubN(callable.descriptor(), 1, input_count, args); |
232 } | 238 } |
233 | 239 |
234 Node* IntrinsicsHelper::CreateIterResultObject(Node* input, Node* arg_count, | 240 Node* IntrinsicsGenerator::CreateIterResultObject(Node* input, Node* arg_count, |
235 Node* context) { | 241 Node* context) { |
236 return IntrinsicAsStubCall(input, context, | 242 return IntrinsicAsStubCall(input, context, |
237 CodeFactory::CreateIterResultObject(isolate())); | 243 CodeFactory::CreateIterResultObject(isolate())); |
238 } | 244 } |
239 | 245 |
240 Node* IntrinsicsHelper::HasProperty(Node* input, Node* arg_count, | 246 Node* IntrinsicsGenerator::HasProperty(Node* input, Node* arg_count, |
241 Node* context) { | 247 Node* context) { |
242 return IntrinsicAsStubCall(input, context, | 248 return IntrinsicAsStubCall(input, context, |
243 CodeFactory::HasProperty(isolate())); | 249 CodeFactory::HasProperty(isolate())); |
244 } | 250 } |
245 | 251 |
246 Node* IntrinsicsHelper::SubString(Node* input, Node* arg_count, Node* context) { | 252 Node* IntrinsicsGenerator::SubString(Node* input, Node* arg_count, |
| 253 Node* context) { |
247 return IntrinsicAsStubCall(input, context, CodeFactory::SubString(isolate())); | 254 return IntrinsicAsStubCall(input, context, CodeFactory::SubString(isolate())); |
248 } | 255 } |
249 | 256 |
250 Node* IntrinsicsHelper::ToString(Node* input, Node* arg_count, Node* context) { | 257 Node* IntrinsicsGenerator::ToString(Node* input, Node* arg_count, |
| 258 Node* context) { |
251 return IntrinsicAsStubCall(input, context, CodeFactory::ToString(isolate())); | 259 return IntrinsicAsStubCall(input, context, CodeFactory::ToString(isolate())); |
252 } | 260 } |
253 | 261 |
254 Node* IntrinsicsHelper::ToLength(Node* input, Node* arg_count, Node* context) { | 262 Node* IntrinsicsGenerator::ToLength(Node* input, Node* arg_count, |
| 263 Node* context) { |
255 return IntrinsicAsStubCall(input, context, CodeFactory::ToLength(isolate())); | 264 return IntrinsicAsStubCall(input, context, CodeFactory::ToLength(isolate())); |
256 } | 265 } |
257 | 266 |
258 Node* IntrinsicsHelper::ToInteger(Node* input, Node* arg_count, Node* context) { | 267 Node* IntrinsicsGenerator::ToInteger(Node* input, Node* arg_count, |
| 268 Node* context) { |
259 return IntrinsicAsStubCall(input, context, CodeFactory::ToInteger(isolate())); | 269 return IntrinsicAsStubCall(input, context, CodeFactory::ToInteger(isolate())); |
260 } | 270 } |
261 | 271 |
262 Node* IntrinsicsHelper::ToNumber(Node* input, Node* arg_count, Node* context) { | 272 Node* IntrinsicsGenerator::ToNumber(Node* input, Node* arg_count, |
| 273 Node* context) { |
263 return IntrinsicAsStubCall(input, context, CodeFactory::ToNumber(isolate())); | 274 return IntrinsicAsStubCall(input, context, CodeFactory::ToNumber(isolate())); |
264 } | 275 } |
265 | 276 |
266 Node* IntrinsicsHelper::ToObject(Node* input, Node* arg_count, Node* context) { | 277 Node* IntrinsicsGenerator::ToObject(Node* input, Node* arg_count, |
| 278 Node* context) { |
267 return IntrinsicAsStubCall(input, context, CodeFactory::ToObject(isolate())); | 279 return IntrinsicAsStubCall(input, context, CodeFactory::ToObject(isolate())); |
268 } | 280 } |
269 | 281 |
270 Node* IntrinsicsHelper::Call(Node* args_reg, Node* arg_count, Node* context) { | 282 Node* IntrinsicsGenerator::Call(Node* args_reg, Node* arg_count, |
| 283 Node* context) { |
271 // First argument register contains the function target. | 284 // First argument register contains the function target. |
272 Node* function = __ LoadRegister(args_reg); | 285 Node* function = __ LoadRegister(args_reg); |
273 | 286 |
274 // Receiver is the second runtime call argument. | 287 // Receiver is the second runtime call argument. |
275 Node* receiver_reg = __ NextRegister(args_reg); | 288 Node* receiver_reg = __ NextRegister(args_reg); |
276 Node* receiver_arg = __ RegisterLocation(receiver_reg); | 289 Node* receiver_arg = __ RegisterLocation(receiver_reg); |
277 | 290 |
278 // Subtract function and receiver from arg count. | 291 // Subtract function and receiver from arg count. |
279 Node* function_and_receiver_count = __ Int32Constant(2); | 292 Node* function_and_receiver_count = __ Int32Constant(2); |
280 Node* target_args_count = __ Int32Sub(arg_count, function_and_receiver_count); | 293 Node* target_args_count = __ Int32Sub(arg_count, function_and_receiver_count); |
281 | 294 |
282 if (FLAG_debug_code) { | 295 if (FLAG_debug_code) { |
283 InterpreterAssembler::Label arg_count_positive(assembler_); | 296 InterpreterAssembler::Label arg_count_positive(assembler_); |
284 Node* comparison = __ Int32LessThan(target_args_count, __ Int32Constant(0)); | 297 Node* comparison = __ Int32LessThan(target_args_count, __ Int32Constant(0)); |
285 __ GotoIfNot(comparison, &arg_count_positive); | 298 __ GotoIfNot(comparison, &arg_count_positive); |
286 __ Abort(kWrongArgumentCountForInvokeIntrinsic); | 299 __ Abort(kWrongArgumentCountForInvokeIntrinsic); |
287 __ Goto(&arg_count_positive); | 300 __ Goto(&arg_count_positive); |
288 __ Bind(&arg_count_positive); | 301 __ Bind(&arg_count_positive); |
289 } | 302 } |
290 | 303 |
291 Node* result = __ CallJS(function, context, receiver_arg, target_args_count, | 304 Node* result = __ CallJS(function, context, receiver_arg, target_args_count, |
292 TailCallMode::kDisallow); | 305 TailCallMode::kDisallow); |
293 return result; | 306 return result; |
294 } | 307 } |
295 | 308 |
296 Node* IntrinsicsHelper::ClassOf(Node* args_reg, Node* arg_count, | 309 Node* IntrinsicsGenerator::ClassOf(Node* args_reg, Node* arg_count, |
297 Node* context) { | 310 Node* context) { |
298 Node* value = __ LoadRegister(args_reg); | 311 Node* value = __ LoadRegister(args_reg); |
299 return __ ClassOf(value); | 312 return __ ClassOf(value); |
300 } | 313 } |
301 | 314 |
302 Node* IntrinsicsHelper::CreateAsyncFromSyncIterator(Node* args_reg, | 315 Node* IntrinsicsGenerator::CreateAsyncFromSyncIterator(Node* args_reg, |
303 Node* arg_count, | 316 Node* arg_count, |
304 Node* context) { | 317 Node* context) { |
305 InterpreterAssembler::Label not_receiver( | 318 InterpreterAssembler::Label not_receiver( |
306 assembler_, InterpreterAssembler::Label::kDeferred); | 319 assembler_, InterpreterAssembler::Label::kDeferred); |
307 InterpreterAssembler::Label done(assembler_); | 320 InterpreterAssembler::Label done(assembler_); |
308 InterpreterAssembler::Variable return_value(assembler_, | 321 InterpreterAssembler::Variable return_value(assembler_, |
309 MachineRepresentation::kTagged); | 322 MachineRepresentation::kTagged); |
310 | 323 |
311 Node* sync_iterator = __ LoadRegister(args_reg); | 324 Node* sync_iterator = __ LoadRegister(args_reg); |
312 | 325 |
313 __ GotoIf(__ TaggedIsSmi(sync_iterator), ¬_receiver); | 326 __ GotoIf(__ TaggedIsSmi(sync_iterator), ¬_receiver); |
314 __ GotoIfNot(__ IsJSReceiver(sync_iterator), ¬_receiver); | 327 __ GotoIfNot(__ IsJSReceiver(sync_iterator), ¬_receiver); |
(...skipping 15 matching lines...) Expand all Loading... |
330 __ CallRuntime(Runtime::kThrowSymbolIteratorInvalid, context)); | 343 __ CallRuntime(Runtime::kThrowSymbolIteratorInvalid, context)); |
331 | 344 |
332 // Unreachable due to the Throw in runtime call. | 345 // Unreachable due to the Throw in runtime call. |
333 __ Goto(&done); | 346 __ Goto(&done); |
334 } | 347 } |
335 | 348 |
336 __ Bind(&done); | 349 __ Bind(&done); |
337 return return_value.value(); | 350 return return_value.value(); |
338 } | 351 } |
339 | 352 |
340 void IntrinsicsHelper::AbortIfArgCountMismatch(int expected, Node* actual) { | 353 void IntrinsicsGenerator::AbortIfArgCountMismatch(int expected, Node* actual) { |
341 InterpreterAssembler::Label match(assembler_); | 354 InterpreterAssembler::Label match(assembler_); |
342 Node* comparison = __ Word32Equal(actual, __ Int32Constant(expected)); | 355 Node* comparison = __ Word32Equal(actual, __ Int32Constant(expected)); |
343 __ GotoIf(comparison, &match); | 356 __ GotoIf(comparison, &match); |
344 __ Abort(kWrongArgumentCountForInvokeIntrinsic); | 357 __ Abort(kWrongArgumentCountForInvokeIntrinsic); |
345 __ Goto(&match); | 358 __ Goto(&match); |
346 __ Bind(&match); | 359 __ Bind(&match); |
347 } | 360 } |
348 | 361 |
349 } // namespace interpreter | 362 } // namespace interpreter |
350 } // namespace internal | 363 } // namespace internal |
351 } // namespace v8 | 364 } // namespace v8 |
OLD | NEW |