| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 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 | 
|  | 3 // found in the LICENSE file. | 
|  | 4 | 
|  | 5 #ifndef V8_CCTEST_COMPILER_CALL_TESTER_H_ | 
|  | 6 #define V8_CCTEST_COMPILER_CALL_TESTER_H_ | 
|  | 7 | 
|  | 8 #include "src/v8.h" | 
|  | 9 | 
|  | 10 #include "src/simulator.h" | 
|  | 11 | 
|  | 12 #if V8_TARGET_ARCH_IA32 | 
|  | 13 #if __GNUC__ | 
|  | 14 #define V8_CDECL __attribute__((cdecl)) | 
|  | 15 #else | 
|  | 16 #define V8_CDECL __cdecl | 
|  | 17 #endif | 
|  | 18 #else | 
|  | 19 #define V8_CDECL | 
|  | 20 #endif | 
|  | 21 | 
|  | 22 namespace v8 { | 
|  | 23 namespace internal { | 
|  | 24 namespace compiler { | 
|  | 25 | 
|  | 26 template <typename R> | 
|  | 27 struct ReturnValueTraits { | 
|  | 28   static R Cast(uintptr_t r) { return reinterpret_cast<R>(r); } | 
|  | 29   static MachineRepresentation Representation() { | 
|  | 30     // TODO(dcarney): detect when R is of a subclass of Object* instead of this | 
|  | 31     // type check. | 
|  | 32     while (false) { | 
|  | 33       *(static_cast<Object* volatile*>(0)) = static_cast<R>(0); | 
|  | 34     } | 
|  | 35     return kMachineTagged; | 
|  | 36   } | 
|  | 37 }; | 
|  | 38 | 
|  | 39 template <> | 
|  | 40 struct ReturnValueTraits<int32_t*> { | 
|  | 41   static int32_t* Cast(uintptr_t r) { return reinterpret_cast<int32_t*>(r); } | 
|  | 42   static MachineRepresentation Representation() { | 
|  | 43     return MachineOperatorBuilder::pointer_rep(); | 
|  | 44   } | 
|  | 45 }; | 
|  | 46 | 
|  | 47 template <> | 
|  | 48 struct ReturnValueTraits<void> { | 
|  | 49   static void Cast(uintptr_t r) {} | 
|  | 50   static MachineRepresentation Representation() { | 
|  | 51     return MachineOperatorBuilder::pointer_rep(); | 
|  | 52   } | 
|  | 53 }; | 
|  | 54 | 
|  | 55 template <> | 
|  | 56 struct ReturnValueTraits<bool> { | 
|  | 57   static bool Cast(uintptr_t r) { return static_cast<bool>(r); } | 
|  | 58   static MachineRepresentation Representation() { | 
|  | 59     return MachineOperatorBuilder::pointer_rep(); | 
|  | 60   } | 
|  | 61 }; | 
|  | 62 | 
|  | 63 template <> | 
|  | 64 struct ReturnValueTraits<int32_t> { | 
|  | 65   static int32_t Cast(uintptr_t r) { return static_cast<int32_t>(r); } | 
|  | 66   static MachineRepresentation Representation() { return kMachineWord32; } | 
|  | 67 }; | 
|  | 68 | 
|  | 69 template <> | 
|  | 70 struct ReturnValueTraits<uint32_t> { | 
|  | 71   static uint32_t Cast(uintptr_t r) { return static_cast<uint32_t>(r); } | 
|  | 72   static MachineRepresentation Representation() { return kMachineWord32; } | 
|  | 73 }; | 
|  | 74 | 
|  | 75 template <> | 
|  | 76 struct ReturnValueTraits<int64_t> { | 
|  | 77   static int64_t Cast(uintptr_t r) { return static_cast<int64_t>(r); } | 
|  | 78   static MachineRepresentation Representation() { return kMachineWord64; } | 
|  | 79 }; | 
|  | 80 | 
|  | 81 template <> | 
|  | 82 struct ReturnValueTraits<uint64_t> { | 
|  | 83   static uint64_t Cast(uintptr_t r) { return static_cast<uint64_t>(r); } | 
|  | 84   static MachineRepresentation Representation() { return kMachineWord64; } | 
|  | 85 }; | 
|  | 86 | 
|  | 87 template <> | 
|  | 88 struct ReturnValueTraits<int16_t> { | 
|  | 89   static int16_t Cast(uintptr_t r) { return static_cast<int16_t>(r); } | 
|  | 90   static MachineRepresentation Representation() { | 
|  | 91     return MachineOperatorBuilder::pointer_rep(); | 
|  | 92   } | 
|  | 93 }; | 
|  | 94 | 
|  | 95 template <> | 
|  | 96 struct ReturnValueTraits<int8_t> { | 
|  | 97   static int8_t Cast(uintptr_t r) { return static_cast<int8_t>(r); } | 
|  | 98   static MachineRepresentation Representation() { | 
|  | 99     return MachineOperatorBuilder::pointer_rep(); | 
|  | 100   } | 
|  | 101 }; | 
|  | 102 | 
|  | 103 template <> | 
|  | 104 struct ReturnValueTraits<double> { | 
|  | 105   static double Cast(uintptr_t r) { | 
|  | 106     UNREACHABLE(); | 
|  | 107     return 0.0; | 
|  | 108   } | 
|  | 109 }; | 
|  | 110 | 
|  | 111 | 
|  | 112 template <typename R> | 
|  | 113 struct ParameterTraits { | 
|  | 114   static uintptr_t Cast(R r) { return static_cast<uintptr_t>(r); } | 
|  | 115 }; | 
|  | 116 | 
|  | 117 template <> | 
|  | 118 struct ParameterTraits<int*> { | 
|  | 119   static uintptr_t Cast(int* r) { return reinterpret_cast<uintptr_t>(r); } | 
|  | 120 }; | 
|  | 121 | 
|  | 122 template <typename T> | 
|  | 123 struct ParameterTraits<T*> { | 
|  | 124   static uintptr_t Cast(void* r) { return reinterpret_cast<uintptr_t>(r); } | 
|  | 125 }; | 
|  | 126 | 
|  | 127 class CallHelper { | 
|  | 128  public: | 
|  | 129   explicit CallHelper(Isolate* isolate) : isolate_(isolate) { USE(isolate_); } | 
|  | 130   virtual ~CallHelper() {} | 
|  | 131 | 
|  | 132   static MachineCallDescriptorBuilder* ToCallDescriptorBuilder( | 
|  | 133       Zone* zone, MachineRepresentation return_type, | 
|  | 134       MachineRepresentation p0 = kMachineLast, | 
|  | 135       MachineRepresentation p1 = kMachineLast, | 
|  | 136       MachineRepresentation p2 = kMachineLast, | 
|  | 137       MachineRepresentation p3 = kMachineLast, | 
|  | 138       MachineRepresentation p4 = kMachineLast) { | 
|  | 139     const int kSize = 5; | 
|  | 140     MachineRepresentation* params = | 
|  | 141         zone->NewArray<MachineRepresentation>(kSize); | 
|  | 142     params[0] = p0; | 
|  | 143     params[1] = p1; | 
|  | 144     params[2] = p2; | 
|  | 145     params[3] = p3; | 
|  | 146     params[4] = p4; | 
|  | 147     int parameter_count = 0; | 
|  | 148     for (int i = 0; i < kSize; ++i) { | 
|  | 149       if (params[i] == kMachineLast) { | 
|  | 150         break; | 
|  | 151       } | 
|  | 152       parameter_count++; | 
|  | 153     } | 
|  | 154     return new (zone) | 
|  | 155         MachineCallDescriptorBuilder(return_type, parameter_count, params); | 
|  | 156   } | 
|  | 157 | 
|  | 158  protected: | 
|  | 159   virtual void VerifyParameters(int parameter_count, | 
|  | 160                                 MachineRepresentation* parameters) = 0; | 
|  | 161   virtual byte* Generate() = 0; | 
|  | 162 | 
|  | 163  private: | 
|  | 164 #if USE_SIMULATOR && V8_TARGET_ARCH_ARM64 | 
|  | 165   uintptr_t CallSimulator(byte* f, Simulator::CallArgument* args) { | 
|  | 166     Simulator* simulator = Simulator::current(isolate_); | 
|  | 167     return static_cast<uintptr_t>(simulator->CallInt64(f, args)); | 
|  | 168   } | 
|  | 169 | 
|  | 170   template <typename R, typename F> | 
|  | 171   R DoCall(F* f) { | 
|  | 172     Simulator::CallArgument args[] = {Simulator::CallArgument::End()}; | 
|  | 173     return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f), args)); | 
|  | 174   } | 
|  | 175   template <typename R, typename F, typename P1> | 
|  | 176   R DoCall(F* f, P1 p1) { | 
|  | 177     Simulator::CallArgument args[] = {Simulator::CallArgument(p1), | 
|  | 178                                       Simulator::CallArgument::End()}; | 
|  | 179     return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f), args)); | 
|  | 180   } | 
|  | 181   template <typename R, typename F, typename P1, typename P2> | 
|  | 182   R DoCall(F* f, P1 p1, P2 p2) { | 
|  | 183     Simulator::CallArgument args[] = {Simulator::CallArgument(p1), | 
|  | 184                                       Simulator::CallArgument(p2), | 
|  | 185                                       Simulator::CallArgument::End()}; | 
|  | 186     return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f), args)); | 
|  | 187   } | 
|  | 188   template <typename R, typename F, typename P1, typename P2, typename P3> | 
|  | 189   R DoCall(F* f, P1 p1, P2 p2, P3 p3) { | 
|  | 190     Simulator::CallArgument args[] = { | 
|  | 191         Simulator::CallArgument(p1), Simulator::CallArgument(p2), | 
|  | 192         Simulator::CallArgument(p3), Simulator::CallArgument::End()}; | 
|  | 193     return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f), args)); | 
|  | 194   } | 
|  | 195   template <typename R, typename F, typename P1, typename P2, typename P3, | 
|  | 196             typename P4> | 
|  | 197   R DoCall(F* f, P1 p1, P2 p2, P3 p3, P4 p4) { | 
|  | 198     Simulator::CallArgument args[] = { | 
|  | 199         Simulator::CallArgument(p1), Simulator::CallArgument(p2), | 
|  | 200         Simulator::CallArgument(p3), Simulator::CallArgument(p4), | 
|  | 201         Simulator::CallArgument::End()}; | 
|  | 202     return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f), args)); | 
|  | 203   } | 
|  | 204 #elif USE_SIMULATOR && V8_TARGET_ARCH_ARM | 
|  | 205   uintptr_t CallSimulator(byte* f, int32_t p1 = 0, int32_t p2 = 0, | 
|  | 206                           int32_t p3 = 0, int32_t p4 = 0) { | 
|  | 207     Simulator* simulator = Simulator::current(isolate_); | 
|  | 208     return static_cast<uintptr_t>(simulator->Call(f, 4, p1, p2, p3, p4)); | 
|  | 209   } | 
|  | 210   template <typename R, typename F> | 
|  | 211   R DoCall(F* f) { | 
|  | 212     return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f))); | 
|  | 213   } | 
|  | 214   template <typename R, typename F, typename P1> | 
|  | 215   R DoCall(F* f, P1 p1) { | 
|  | 216     return ReturnValueTraits<R>::Cast( | 
|  | 217         CallSimulator(FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1))); | 
|  | 218   } | 
|  | 219   template <typename R, typename F, typename P1, typename P2> | 
|  | 220   R DoCall(F* f, P1 p1, P2 p2) { | 
|  | 221     return ReturnValueTraits<R>::Cast( | 
|  | 222         CallSimulator(FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1), | 
|  | 223                       ParameterTraits<P2>::Cast(p2))); | 
|  | 224   } | 
|  | 225   template <typename R, typename F, typename P1, typename P2, typename P3> | 
|  | 226   R DoCall(F* f, P1 p1, P2 p2, P3 p3) { | 
|  | 227     return ReturnValueTraits<R>::Cast(CallSimulator( | 
|  | 228         FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1), | 
|  | 229         ParameterTraits<P2>::Cast(p2), ParameterTraits<P3>::Cast(p3))); | 
|  | 230   } | 
|  | 231   template <typename R, typename F, typename P1, typename P2, typename P3, | 
|  | 232             typename P4> | 
|  | 233   R DoCall(F* f, P1 p1, P2 p2, P3 p3, P4 p4) { | 
|  | 234     return ReturnValueTraits<R>::Cast(CallSimulator( | 
|  | 235         FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1), | 
|  | 236         ParameterTraits<P2>::Cast(p2), ParameterTraits<P3>::Cast(p3), | 
|  | 237         ParameterTraits<P4>::Cast(p4))); | 
|  | 238   } | 
|  | 239 #else | 
|  | 240   template <typename R, typename F> | 
|  | 241   R DoCall(F* f) { | 
|  | 242     return f(); | 
|  | 243   } | 
|  | 244   template <typename R, typename F, typename P1> | 
|  | 245   R DoCall(F* f, P1 p1) { | 
|  | 246     return f(p1); | 
|  | 247   } | 
|  | 248   template <typename R, typename F, typename P1, typename P2> | 
|  | 249   R DoCall(F* f, P1 p1, P2 p2) { | 
|  | 250     return f(p1, p2); | 
|  | 251   } | 
|  | 252   template <typename R, typename F, typename P1, typename P2, typename P3> | 
|  | 253   R DoCall(F* f, P1 p1, P2 p2, P3 p3) { | 
|  | 254     return f(p1, p2, p3); | 
|  | 255   } | 
|  | 256   template <typename R, typename F, typename P1, typename P2, typename P3, | 
|  | 257             typename P4> | 
|  | 258   R DoCall(F* f, P1 p1, P2 p2, P3 p3, P4 p4) { | 
|  | 259     return f(p1, p2, p3, p4); | 
|  | 260   } | 
|  | 261 #endif | 
|  | 262 | 
|  | 263 #ifndef DEBUG | 
|  | 264   void VerifyParameters0() {} | 
|  | 265 | 
|  | 266   template <typename P1> | 
|  | 267   void VerifyParameters1() {} | 
|  | 268 | 
|  | 269   template <typename P1, typename P2> | 
|  | 270   void VerifyParameters2() {} | 
|  | 271 | 
|  | 272   template <typename P1, typename P2, typename P3> | 
|  | 273   void VerifyParameters3() {} | 
|  | 274 | 
|  | 275   template <typename P1, typename P2, typename P3, typename P4> | 
|  | 276   void VerifyParameters4() {} | 
|  | 277 #else | 
|  | 278   void VerifyParameters0() { VerifyParameters(0, NULL); } | 
|  | 279 | 
|  | 280   template <typename P1> | 
|  | 281   void VerifyParameters1() { | 
|  | 282     MachineRepresentation parameters[] = { | 
|  | 283         ReturnValueTraits<P1>::Representation()}; | 
|  | 284     VerifyParameters(ARRAY_SIZE(parameters), parameters); | 
|  | 285   } | 
|  | 286 | 
|  | 287   template <typename P1, typename P2> | 
|  | 288   void VerifyParameters2() { | 
|  | 289     MachineRepresentation parameters[] = { | 
|  | 290         ReturnValueTraits<P1>::Representation(), | 
|  | 291         ReturnValueTraits<P2>::Representation()}; | 
|  | 292     VerifyParameters(ARRAY_SIZE(parameters), parameters); | 
|  | 293   } | 
|  | 294 | 
|  | 295   template <typename P1, typename P2, typename P3> | 
|  | 296   void VerifyParameters3() { | 
|  | 297     MachineRepresentation parameters[] = { | 
|  | 298         ReturnValueTraits<P1>::Representation(), | 
|  | 299         ReturnValueTraits<P2>::Representation(), | 
|  | 300         ReturnValueTraits<P3>::Representation()}; | 
|  | 301     VerifyParameters(ARRAY_SIZE(parameters), parameters); | 
|  | 302   } | 
|  | 303 | 
|  | 304   template <typename P1, typename P2, typename P3, typename P4> | 
|  | 305   void VerifyParameters4() { | 
|  | 306     MachineRepresentation parameters[] = { | 
|  | 307         ReturnValueTraits<P1>::Representation(), | 
|  | 308         ReturnValueTraits<P2>::Representation(), | 
|  | 309         ReturnValueTraits<P3>::Representation(), | 
|  | 310         ReturnValueTraits<P4>::Representation()}; | 
|  | 311     VerifyParameters(ARRAY_SIZE(parameters), parameters); | 
|  | 312   } | 
|  | 313 #endif | 
|  | 314 | 
|  | 315   // TODO(dcarney): replace Call() in CallHelper2 with these. | 
|  | 316   template <typename R> | 
|  | 317   R Call0() { | 
|  | 318     typedef R V8_CDECL FType(); | 
|  | 319     VerifyParameters0(); | 
|  | 320     return DoCall<R>(FUNCTION_CAST<FType*>(Generate())); | 
|  | 321   } | 
|  | 322 | 
|  | 323   template <typename R, typename P1> | 
|  | 324   R Call1(P1 p1) { | 
|  | 325     typedef R V8_CDECL FType(P1); | 
|  | 326     VerifyParameters1<P1>(); | 
|  | 327     return DoCall<R>(FUNCTION_CAST<FType*>(Generate()), p1); | 
|  | 328   } | 
|  | 329 | 
|  | 330   template <typename R, typename P1, typename P2> | 
|  | 331   R Call2(P1 p1, P2 p2) { | 
|  | 332     typedef R V8_CDECL FType(P1, P2); | 
|  | 333     VerifyParameters2<P1, P2>(); | 
|  | 334     return DoCall<R>(FUNCTION_CAST<FType*>(Generate()), p1, p2); | 
|  | 335   } | 
|  | 336 | 
|  | 337   template <typename R, typename P1, typename P2, typename P3> | 
|  | 338   R Call3(P1 p1, P2 p2, P3 p3) { | 
|  | 339     typedef R V8_CDECL FType(P1, P2, P3); | 
|  | 340     VerifyParameters3<P1, P2, P3>(); | 
|  | 341     return DoCall<R>(FUNCTION_CAST<FType*>(Generate()), p1, p2, p3); | 
|  | 342   } | 
|  | 343 | 
|  | 344   template <typename R, typename P1, typename P2, typename P3, typename P4> | 
|  | 345   R Call4(P1 p1, P2 p2, P3 p3, P4 p4) { | 
|  | 346     typedef R V8_CDECL FType(P1, P2, P3, P4); | 
|  | 347     VerifyParameters4<P1, P2, P3, P4>(); | 
|  | 348     return DoCall<R>(FUNCTION_CAST<FType*>(Generate()), p1, p2, p3, p4); | 
|  | 349   } | 
|  | 350 | 
|  | 351   template <typename R, typename C> | 
|  | 352   friend class CallHelper2; | 
|  | 353   Isolate* isolate_; | 
|  | 354 }; | 
|  | 355 | 
|  | 356 | 
|  | 357 // TODO(dcarney): replace CallHelper with CallHelper2 and rename. | 
|  | 358 template <typename R, typename C> | 
|  | 359 class CallHelper2 { | 
|  | 360  public: | 
|  | 361   R Call() { return helper()->template Call0<R>(); } | 
|  | 362 | 
|  | 363   template <typename P1> | 
|  | 364   R Call(P1 p1) { | 
|  | 365     return helper()->template Call1<R>(p1); | 
|  | 366   } | 
|  | 367 | 
|  | 368   template <typename P1, typename P2> | 
|  | 369   R Call(P1 p1, P2 p2) { | 
|  | 370     return helper()->template Call2<R>(p1, p2); | 
|  | 371   } | 
|  | 372 | 
|  | 373   template <typename P1, typename P2, typename P3> | 
|  | 374   R Call(P1 p1, P2 p2, P3 p3) { | 
|  | 375     return helper()->template Call3<R>(p1, p2, p3); | 
|  | 376   } | 
|  | 377 | 
|  | 378   template <typename P1, typename P2, typename P3, typename P4> | 
|  | 379   R Call(P1 p1, P2 p2, P3 p3, P4 p4) { | 
|  | 380     return helper()->template Call4<R>(p1, p2, p3, p4); | 
|  | 381   } | 
|  | 382 | 
|  | 383  private: | 
|  | 384   CallHelper* helper() { return static_cast<C*>(this); } | 
|  | 385 }; | 
|  | 386 | 
|  | 387 }  // namespace compiler | 
|  | 388 }  // namespace internal | 
|  | 389 }  // namespace v8 | 
|  | 390 | 
|  | 391 #endif  // V8_CCTEST_COMPILER_CALL_TESTER_H_ | 
| OLD | NEW | 
|---|