OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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 #ifndef V8_CCTEST_COMPILER_CALL_TESTER_H_ | 5 #ifndef V8_CCTEST_COMPILER_CALL_TESTER_H_ |
6 #define V8_CCTEST_COMPILER_CALL_TESTER_H_ | 6 #define V8_CCTEST_COMPILER_CALL_TESTER_H_ |
7 | 7 |
8 #include "src/v8.h" | 8 #include "src/v8.h" |
9 | 9 |
10 #include "src/simulator.h" | 10 #include "src/simulator.h" |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 template <> | 141 template <> |
142 struct ParameterTraits<uint32_t> { | 142 struct ParameterTraits<uint32_t> { |
143 static int64_t Cast(uint32_t r) { | 143 static int64_t Cast(uint32_t r) { |
144 return static_cast<int64_t>(static_cast<int32_t>(r)); | 144 return static_cast<int64_t>(static_cast<int32_t>(r)); |
145 } | 145 } |
146 }; | 146 }; |
147 | 147 |
148 #endif // !V8_TARGET_ARCH_64_BIT | 148 #endif // !V8_TARGET_ARCH_64_BIT |
149 | 149 |
150 | 150 |
| 151 template <typename R> |
151 class CallHelper { | 152 class CallHelper { |
152 public: | 153 public: |
153 explicit CallHelper(Isolate* isolate, MachineSignature* machine_sig) | 154 explicit CallHelper(Isolate* isolate, MachineSignature* machine_sig) |
154 : machine_sig_(machine_sig), isolate_(isolate) { | 155 : machine_sig_(machine_sig), isolate_(isolate) { |
155 USE(isolate_); | 156 USE(isolate_); |
156 } | 157 } |
157 virtual ~CallHelper() {} | 158 virtual ~CallHelper() {} |
158 | 159 |
159 static MachineSignature* MakeMachineSignature( | 160 R Call() { |
160 Zone* zone, MachineType return_type, MachineType p0 = kMachNone, | 161 typedef R V8_CDECL FType(); |
161 MachineType p1 = kMachNone, MachineType p2 = kMachNone, | 162 VerifyParameters0(); |
162 MachineType p3 = kMachNone, MachineType p4 = kMachNone) { | 163 return DoCall(FUNCTION_CAST<FType*>(Generate())); |
163 // Count the number of parameters. | 164 } |
164 size_t param_count = 5; | |
165 MachineType types[] = {p0, p1, p2, p3, p4}; | |
166 while (param_count > 0 && types[param_count - 1] == kMachNone) | |
167 param_count--; | |
168 size_t return_count = return_type == kMachNone ? 0 : 1; | |
169 | 165 |
170 // Build the machine signature. | 166 template <typename P1> |
171 MachineSignature::Builder builder(zone, return_count, param_count); | 167 R Call(P1 p1) { |
172 if (return_count > 0) builder.AddReturn(return_type); | 168 typedef R V8_CDECL FType(P1); |
173 for (size_t i = 0; i < param_count; i++) { | 169 VerifyParameters1<P1>(); |
174 builder.AddParam(types[i]); | 170 return DoCall(FUNCTION_CAST<FType*>(Generate()), p1); |
175 } | 171 } |
176 return builder.Build(); | 172 |
| 173 template <typename P1, typename P2> |
| 174 R Call(P1 p1, P2 p2) { |
| 175 typedef R V8_CDECL FType(P1, P2); |
| 176 VerifyParameters2<P1, P2>(); |
| 177 return DoCall(FUNCTION_CAST<FType*>(Generate()), p1, p2); |
| 178 } |
| 179 |
| 180 template <typename P1, typename P2, typename P3> |
| 181 R Call(P1 p1, P2 p2, P3 p3) { |
| 182 typedef R V8_CDECL FType(P1, P2, P3); |
| 183 VerifyParameters3<P1, P2, P3>(); |
| 184 return DoCall(FUNCTION_CAST<FType*>(Generate()), p1, p2, p3); |
| 185 } |
| 186 |
| 187 template <typename P1, typename P2, typename P3, typename P4> |
| 188 R Call(P1 p1, P2 p2, P3 p3, P4 p4) { |
| 189 typedef R V8_CDECL FType(P1, P2, P3, P4); |
| 190 VerifyParameters4<P1, P2, P3, P4>(); |
| 191 return DoCall(FUNCTION_CAST<FType*>(Generate()), p1, p2, p3, p4); |
177 } | 192 } |
178 | 193 |
179 protected: | 194 protected: |
180 MachineSignature* machine_sig_; | 195 MachineSignature* machine_sig_; |
| 196 |
181 void VerifyParameters(size_t parameter_count, MachineType* parameter_types) { | 197 void VerifyParameters(size_t parameter_count, MachineType* parameter_types) { |
182 CHECK(machine_sig_->parameter_count() == parameter_count); | 198 CHECK(machine_sig_->parameter_count() == parameter_count); |
183 for (size_t i = 0; i < parameter_count; i++) { | 199 for (size_t i = 0; i < parameter_count; i++) { |
184 CHECK_EQ(machine_sig_->GetParam(i), parameter_types[i]); | 200 CHECK_EQ(machine_sig_->GetParam(i), parameter_types[i]); |
185 } | 201 } |
186 } | 202 } |
| 203 |
187 virtual byte* Generate() = 0; | 204 virtual byte* Generate() = 0; |
188 | 205 |
189 private: | 206 private: |
190 #if USE_SIMULATOR && V8_TARGET_ARCH_ARM64 | 207 #if USE_SIMULATOR && V8_TARGET_ARCH_ARM64 |
191 uintptr_t CallSimulator(byte* f, Simulator::CallArgument* args) { | 208 uintptr_t CallSimulator(byte* f, Simulator::CallArgument* args) { |
192 Simulator* simulator = Simulator::current(isolate_); | 209 Simulator* simulator = Simulator::current(isolate_); |
193 return static_cast<uintptr_t>(simulator->CallInt64(f, args)); | 210 return static_cast<uintptr_t>(simulator->CallInt64(f, args)); |
194 } | 211 } |
195 | 212 |
196 template <typename R, typename F> | 213 template <typename F> |
197 R DoCall(F* f) { | 214 R DoCall(F* f) { |
198 Simulator::CallArgument args[] = {Simulator::CallArgument::End()}; | 215 Simulator::CallArgument args[] = {Simulator::CallArgument::End()}; |
199 return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f), args)); | 216 return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f), args)); |
200 } | 217 } |
201 template <typename R, typename F, typename P1> | 218 template <typename F, typename P1> |
202 R DoCall(F* f, P1 p1) { | 219 R DoCall(F* f, P1 p1) { |
203 Simulator::CallArgument args[] = {Simulator::CallArgument(p1), | 220 Simulator::CallArgument args[] = {Simulator::CallArgument(p1), |
204 Simulator::CallArgument::End()}; | 221 Simulator::CallArgument::End()}; |
205 return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f), args)); | 222 return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f), args)); |
206 } | 223 } |
207 template <typename R, typename F, typename P1, typename P2> | 224 template <typename F, typename P1, typename P2> |
208 R DoCall(F* f, P1 p1, P2 p2) { | 225 R DoCall(F* f, P1 p1, P2 p2) { |
209 Simulator::CallArgument args[] = {Simulator::CallArgument(p1), | 226 Simulator::CallArgument args[] = {Simulator::CallArgument(p1), |
210 Simulator::CallArgument(p2), | 227 Simulator::CallArgument(p2), |
211 Simulator::CallArgument::End()}; | 228 Simulator::CallArgument::End()}; |
212 return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f), args)); | 229 return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f), args)); |
213 } | 230 } |
214 template <typename R, typename F, typename P1, typename P2, typename P3> | 231 template <typename F, typename P1, typename P2, typename P3> |
215 R DoCall(F* f, P1 p1, P2 p2, P3 p3) { | 232 R DoCall(F* f, P1 p1, P2 p2, P3 p3) { |
216 Simulator::CallArgument args[] = { | 233 Simulator::CallArgument args[] = { |
217 Simulator::CallArgument(p1), Simulator::CallArgument(p2), | 234 Simulator::CallArgument(p1), Simulator::CallArgument(p2), |
218 Simulator::CallArgument(p3), Simulator::CallArgument::End()}; | 235 Simulator::CallArgument(p3), Simulator::CallArgument::End()}; |
219 return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f), args)); | 236 return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f), args)); |
220 } | 237 } |
221 template <typename R, typename F, typename P1, typename P2, typename P3, | 238 template <typename F, typename P1, typename P2, typename P3, typename P4> |
222 typename P4> | |
223 R DoCall(F* f, P1 p1, P2 p2, P3 p3, P4 p4) { | 239 R DoCall(F* f, P1 p1, P2 p2, P3 p3, P4 p4) { |
224 Simulator::CallArgument args[] = { | 240 Simulator::CallArgument args[] = { |
225 Simulator::CallArgument(p1), Simulator::CallArgument(p2), | 241 Simulator::CallArgument(p1), Simulator::CallArgument(p2), |
226 Simulator::CallArgument(p3), Simulator::CallArgument(p4), | 242 Simulator::CallArgument(p3), Simulator::CallArgument(p4), |
227 Simulator::CallArgument::End()}; | 243 Simulator::CallArgument::End()}; |
228 return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f), args)); | 244 return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f), args)); |
229 } | 245 } |
230 #elif USE_SIMULATOR && (V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_PPC64) | 246 #elif USE_SIMULATOR && (V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_PPC64) |
231 uintptr_t CallSimulator(byte* f, int64_t p1 = 0, int64_t p2 = 0, | 247 uintptr_t CallSimulator(byte* f, int64_t p1 = 0, int64_t p2 = 0, |
232 int64_t p3 = 0, int64_t p4 = 0) { | 248 int64_t p3 = 0, int64_t p4 = 0) { |
233 Simulator* simulator = Simulator::current(isolate_); | 249 Simulator* simulator = Simulator::current(isolate_); |
234 return static_cast<uintptr_t>(simulator->Call(f, 4, p1, p2, p3, p4)); | 250 return static_cast<uintptr_t>(simulator->Call(f, 4, p1, p2, p3, p4)); |
235 } | 251 } |
236 | 252 |
237 | 253 |
238 template <typename R, typename F> | 254 template <typename F> |
239 R DoCall(F* f) { | 255 R DoCall(F* f) { |
240 return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f))); | 256 return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f))); |
241 } | 257 } |
242 template <typename R, typename F, typename P1> | 258 template <typename F, typename P1> |
243 R DoCall(F* f, P1 p1) { | 259 R DoCall(F* f, P1 p1) { |
244 return ReturnValueTraits<R>::Cast( | 260 return ReturnValueTraits<R>::Cast( |
245 CallSimulator(FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1))); | 261 CallSimulator(FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1))); |
246 } | 262 } |
247 template <typename R, typename F, typename P1, typename P2> | 263 template <typename F, typename P1, typename P2> |
248 R DoCall(F* f, P1 p1, P2 p2) { | 264 R DoCall(F* f, P1 p1, P2 p2) { |
249 return ReturnValueTraits<R>::Cast( | 265 return ReturnValueTraits<R>::Cast( |
250 CallSimulator(FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1), | 266 CallSimulator(FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1), |
251 ParameterTraits<P2>::Cast(p2))); | 267 ParameterTraits<P2>::Cast(p2))); |
252 } | 268 } |
253 template <typename R, typename F, typename P1, typename P2, typename P3> | 269 template <typename F, typename P1, typename P2, typename P3> |
254 R DoCall(F* f, P1 p1, P2 p2, P3 p3) { | 270 R DoCall(F* f, P1 p1, P2 p2, P3 p3) { |
255 return ReturnValueTraits<R>::Cast(CallSimulator( | 271 return ReturnValueTraits<R>::Cast(CallSimulator( |
256 FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1), | 272 FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1), |
257 ParameterTraits<P2>::Cast(p2), ParameterTraits<P3>::Cast(p3))); | 273 ParameterTraits<P2>::Cast(p2), ParameterTraits<P3>::Cast(p3))); |
258 } | 274 } |
259 template <typename R, typename F, typename P1, typename P2, typename P3, | 275 template <typename F, typename P1, typename P2, typename P3, typename P4> |
260 typename P4> | |
261 R DoCall(F* f, P1 p1, P2 p2, P3 p3, P4 p4) { | 276 R DoCall(F* f, P1 p1, P2 p2, P3 p3, P4 p4) { |
262 return ReturnValueTraits<R>::Cast(CallSimulator( | 277 return ReturnValueTraits<R>::Cast(CallSimulator( |
263 FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1), | 278 FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1), |
264 ParameterTraits<P2>::Cast(p2), ParameterTraits<P3>::Cast(p3), | 279 ParameterTraits<P2>::Cast(p2), ParameterTraits<P3>::Cast(p3), |
265 ParameterTraits<P4>::Cast(p4))); | 280 ParameterTraits<P4>::Cast(p4))); |
266 } | 281 } |
267 #elif USE_SIMULATOR && \ | 282 #elif USE_SIMULATOR && \ |
268 (V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_PPC) | 283 (V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_PPC) |
269 uintptr_t CallSimulator(byte* f, int32_t p1 = 0, int32_t p2 = 0, | 284 uintptr_t CallSimulator(byte* f, int32_t p1 = 0, int32_t p2 = 0, |
270 int32_t p3 = 0, int32_t p4 = 0) { | 285 int32_t p3 = 0, int32_t p4 = 0) { |
271 Simulator* simulator = Simulator::current(isolate_); | 286 Simulator* simulator = Simulator::current(isolate_); |
272 return static_cast<uintptr_t>(simulator->Call(f, 4, p1, p2, p3, p4)); | 287 return static_cast<uintptr_t>(simulator->Call(f, 4, p1, p2, p3, p4)); |
273 } | 288 } |
274 template <typename R, typename F> | 289 template <typename F> |
275 R DoCall(F* f) { | 290 R DoCall(F* f) { |
276 return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f))); | 291 return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f))); |
277 } | 292 } |
278 template <typename R, typename F, typename P1> | 293 template <typename F, typename P1> |
279 R DoCall(F* f, P1 p1) { | 294 R DoCall(F* f, P1 p1) { |
280 return ReturnValueTraits<R>::Cast( | 295 return ReturnValueTraits<R>::Cast( |
281 CallSimulator(FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1))); | 296 CallSimulator(FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1))); |
282 } | 297 } |
283 template <typename R, typename F, typename P1, typename P2> | 298 template <typename F, typename P1, typename P2> |
284 R DoCall(F* f, P1 p1, P2 p2) { | 299 R DoCall(F* f, P1 p1, P2 p2) { |
285 return ReturnValueTraits<R>::Cast( | 300 return ReturnValueTraits<R>::Cast( |
286 CallSimulator(FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1), | 301 CallSimulator(FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1), |
287 ParameterTraits<P2>::Cast(p2))); | 302 ParameterTraits<P2>::Cast(p2))); |
288 } | 303 } |
289 template <typename R, typename F, typename P1, typename P2, typename P3> | 304 template <typename F, typename P1, typename P2, typename P3> |
290 R DoCall(F* f, P1 p1, P2 p2, P3 p3) { | 305 R DoCall(F* f, P1 p1, P2 p2, P3 p3) { |
291 return ReturnValueTraits<R>::Cast(CallSimulator( | 306 return ReturnValueTraits<R>::Cast(CallSimulator( |
292 FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1), | 307 FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1), |
293 ParameterTraits<P2>::Cast(p2), ParameterTraits<P3>::Cast(p3))); | 308 ParameterTraits<P2>::Cast(p2), ParameterTraits<P3>::Cast(p3))); |
294 } | 309 } |
295 template <typename R, typename F, typename P1, typename P2, typename P3, | 310 template <typename F, typename P1, typename P2, typename P3, typename P4> |
296 typename P4> | |
297 R DoCall(F* f, P1 p1, P2 p2, P3 p3, P4 p4) { | 311 R DoCall(F* f, P1 p1, P2 p2, P3 p3, P4 p4) { |
298 return ReturnValueTraits<R>::Cast(CallSimulator( | 312 return ReturnValueTraits<R>::Cast(CallSimulator( |
299 FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1), | 313 FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1), |
300 ParameterTraits<P2>::Cast(p2), ParameterTraits<P3>::Cast(p3), | 314 ParameterTraits<P2>::Cast(p2), ParameterTraits<P3>::Cast(p3), |
301 ParameterTraits<P4>::Cast(p4))); | 315 ParameterTraits<P4>::Cast(p4))); |
302 } | 316 } |
303 #else | 317 #else |
304 template <typename R, typename F> | 318 template <typename F> |
305 R DoCall(F* f) { | 319 R DoCall(F* f) { |
306 return f(); | 320 return f(); |
307 } | 321 } |
308 template <typename R, typename F, typename P1> | 322 template <typename F, typename P1> |
309 R DoCall(F* f, P1 p1) { | 323 R DoCall(F* f, P1 p1) { |
310 return f(p1); | 324 return f(p1); |
311 } | 325 } |
312 template <typename R, typename F, typename P1, typename P2> | 326 template <typename F, typename P1, typename P2> |
313 R DoCall(F* f, P1 p1, P2 p2) { | 327 R DoCall(F* f, P1 p1, P2 p2) { |
314 return f(p1, p2); | 328 return f(p1, p2); |
315 } | 329 } |
316 template <typename R, typename F, typename P1, typename P2, typename P3> | 330 template <typename F, typename P1, typename P2, typename P3> |
317 R DoCall(F* f, P1 p1, P2 p2, P3 p3) { | 331 R DoCall(F* f, P1 p1, P2 p2, P3 p3) { |
318 return f(p1, p2, p3); | 332 return f(p1, p2, p3); |
319 } | 333 } |
320 template <typename R, typename F, typename P1, typename P2, typename P3, | 334 template <typename F, typename P1, typename P2, typename P3, typename P4> |
321 typename P4> | |
322 R DoCall(F* f, P1 p1, P2 p2, P3 p3, P4 p4) { | 335 R DoCall(F* f, P1 p1, P2 p2, P3 p3, P4 p4) { |
323 return f(p1, p2, p3, p4); | 336 return f(p1, p2, p3, p4); |
324 } | 337 } |
325 #endif | 338 #endif |
326 | 339 |
327 #ifndef DEBUG | 340 #ifndef DEBUG |
328 void VerifyParameters0() {} | 341 void VerifyParameters0() {} |
329 | 342 |
330 template <typename P1> | 343 template <typename P1> |
331 void VerifyParameters1() {} | 344 void VerifyParameters1() {} |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
365 template <typename P1, typename P2, typename P3, typename P4> | 378 template <typename P1, typename P2, typename P3, typename P4> |
366 void VerifyParameters4() { | 379 void VerifyParameters4() { |
367 MachineType parameters[] = {ReturnValueTraits<P1>::Representation(), | 380 MachineType parameters[] = {ReturnValueTraits<P1>::Representation(), |
368 ReturnValueTraits<P2>::Representation(), | 381 ReturnValueTraits<P2>::Representation(), |
369 ReturnValueTraits<P3>::Representation(), | 382 ReturnValueTraits<P3>::Representation(), |
370 ReturnValueTraits<P4>::Representation()}; | 383 ReturnValueTraits<P4>::Representation()}; |
371 VerifyParameters(arraysize(parameters), parameters); | 384 VerifyParameters(arraysize(parameters), parameters); |
372 } | 385 } |
373 #endif | 386 #endif |
374 | 387 |
375 // TODO(dcarney): replace Call() in CallHelper2 with these. | |
376 template <typename R> | |
377 R Call0() { | |
378 typedef R V8_CDECL FType(); | |
379 VerifyParameters0(); | |
380 return DoCall<R>(FUNCTION_CAST<FType*>(Generate())); | |
381 } | |
382 | |
383 template <typename R, typename P1> | |
384 R Call1(P1 p1) { | |
385 typedef R V8_CDECL FType(P1); | |
386 VerifyParameters1<P1>(); | |
387 return DoCall<R>(FUNCTION_CAST<FType*>(Generate()), p1); | |
388 } | |
389 | |
390 template <typename R, typename P1, typename P2> | |
391 R Call2(P1 p1, P2 p2) { | |
392 typedef R V8_CDECL FType(P1, P2); | |
393 VerifyParameters2<P1, P2>(); | |
394 return DoCall<R>(FUNCTION_CAST<FType*>(Generate()), p1, p2); | |
395 } | |
396 | |
397 template <typename R, typename P1, typename P2, typename P3> | |
398 R Call3(P1 p1, P2 p2, P3 p3) { | |
399 typedef R V8_CDECL FType(P1, P2, P3); | |
400 VerifyParameters3<P1, P2, P3>(); | |
401 return DoCall<R>(FUNCTION_CAST<FType*>(Generate()), p1, p2, p3); | |
402 } | |
403 | |
404 template <typename R, typename P1, typename P2, typename P3, typename P4> | |
405 R Call4(P1 p1, P2 p2, P3 p3, P4 p4) { | |
406 typedef R V8_CDECL FType(P1, P2, P3, P4); | |
407 VerifyParameters4<P1, P2, P3, P4>(); | |
408 return DoCall<R>(FUNCTION_CAST<FType*>(Generate()), p1, p2, p3, p4); | |
409 } | |
410 | |
411 template <typename R, typename C> | |
412 friend class CallHelper2; | |
413 Isolate* isolate_; | 388 Isolate* isolate_; |
414 }; | 389 }; |
415 | 390 |
416 | |
417 // TODO(dcarney): replace CallHelper with CallHelper2 and rename. | |
418 template <typename R, typename C> | |
419 class CallHelper2 { | |
420 public: | |
421 R Call() { return helper()->template Call0<R>(); } | |
422 | |
423 template <typename P1> | |
424 R Call(P1 p1) { | |
425 return helper()->template Call1<R>(p1); | |
426 } | |
427 | |
428 template <typename P1, typename P2> | |
429 R Call(P1 p1, P2 p2) { | |
430 return helper()->template Call2<R>(p1, p2); | |
431 } | |
432 | |
433 template <typename P1, typename P2, typename P3> | |
434 R Call(P1 p1, P2 p2, P3 p3) { | |
435 return helper()->template Call3<R>(p1, p2, p3); | |
436 } | |
437 | |
438 template <typename P1, typename P2, typename P3, typename P4> | |
439 R Call(P1 p1, P2 p2, P3 p3, P4 p4) { | |
440 return helper()->template Call4<R>(p1, p2, p3, p4); | |
441 } | |
442 | |
443 private: | |
444 CallHelper* helper() { return static_cast<C*>(this); } | |
445 }; | |
446 | |
447 } // namespace compiler | 391 } // namespace compiler |
448 } // namespace internal | 392 } // namespace internal |
449 } // namespace v8 | 393 } // namespace v8 |
450 | 394 |
451 #endif // V8_CCTEST_COMPILER_CALL_TESTER_H_ | 395 #endif // V8_CCTEST_COMPILER_CALL_TESTER_H_ |
OLD | NEW |