1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2014 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file. 4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifndef V8_COMPILER_C_SIGNATURE_H_ 6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define V8_COMPILER_C_SIGNATURE_H_ 7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/machine-type.h" 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal { 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace compiler { 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 14014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define FOREACH_CTYPE_MACHINE_TYPE_MAPPING(V) \ 15014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(void, MachineType::None()) \ 16014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(bool, MachineType::Uint8()) \ 17014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(int8_t, MachineType::Int8()) \ 18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(uint8_t, MachineType::Uint8()) \ 19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(int16_t, MachineType::Int16()) \ 20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(uint16_t, MachineType::Uint16()) \ 21014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(int32_t, MachineType::Int32()) \ 22014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(uint32_t, MachineType::Uint32()) \ 23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(int64_t, MachineType::Int64()) \ 24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(uint64_t, MachineType::Uint64()) \ 25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(float, MachineType::Float32()) \ 26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(double, MachineType::Float64()) \ 27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(void*, MachineType::Pointer()) \ 28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(int*, MachineType::Pointer()) 29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <typename T> 31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline MachineType MachineTypeForC() { 32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch while (false) { 33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // All other types T must be assignable to Object* 34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch *(static_cast<Object* volatile*>(0)) = static_cast<T>(0); 35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return MachineType::AnyTagged(); 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 39014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DECLARE_TEMPLATE_SPECIALIZATION(ctype, mtype) \ 40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch template <> \ 41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline MachineType MachineTypeForC<ctype>() { \ 42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return mtype; \ 43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochFOREACH_CTYPE_MACHINE_TYPE_MAPPING(DECLARE_TEMPLATE_SPECIALIZATION) 45014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef DECLARE_TEMPLATE_SPECIALIZATION 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 47014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Helper for building machine signatures from C types. 48014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass CSignature : public MachineSignature { 49014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch protected: 50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CSignature(size_t return_count, size_t parameter_count, MachineType* reps) 51014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : MachineSignature(return_count, parameter_count, reps) {} 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch template <typename P1 = void, typename P2 = void, typename P3 = void, 55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch typename P4 = void, typename P5 = void> 56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void VerifyParams() { 57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Verifies the C signature against the machine types. Maximum {5} params. 58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_LT(parameter_count(), 6u); 59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const int kMax = 5; 60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType params[] = {MachineTypeForC<P1>(), MachineTypeForC<P2>(), 61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineTypeForC<P3>(), MachineTypeForC<P4>(), 62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineTypeForC<P5>()}; 63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int p = kMax - 1; p >= 0; p--) { 64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (p < static_cast<int>(parameter_count())) { 65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_EQ(GetParam(p), params[p]); 66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_EQ(MachineType::None(), params[p]); 68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static CSignature* FromMachine(Zone* zone, MachineSignature* msig) { 73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return reinterpret_cast<CSignature*>(msig); 74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static CSignature* New(Zone* zone, MachineType ret, 77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType p1 = MachineType::None(), 78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType p2 = MachineType::None(), 79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType p3 = MachineType::None(), 80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType p4 = MachineType::None(), 81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType p5 = MachineType::None()) { 82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType* buffer = zone->NewArray<MachineType>(6); 83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int pos = 0; 84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t return_count = 0; 85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (ret != MachineType::None()) { 86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch buffer[pos++] = ret; 87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return_count++; 88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch buffer[pos++] = p1; 90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch buffer[pos++] = p2; 91014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch buffer[pos++] = p3; 92014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch buffer[pos++] = p4; 93014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch buffer[pos++] = p5; 94014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t param_count = 5; 95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (p5 == MachineType::None()) param_count--; 96014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (p4 == MachineType::None()) param_count--; 97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (p3 == MachineType::None()) param_count--; 98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (p2 == MachineType::None()) param_count--; 99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (p1 == MachineType::None()) param_count--; 100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (size_t i = 0; i < param_count; i++) { 101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Check that there are no MachineType::None()'s in the middle of 102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // parameters. 103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_NE(MachineType::None(), buffer[return_count + i]); 104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return new (zone) CSignature(return_count, param_count, buffer); 106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <typename Ret, uint16_t kParamCount> 111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass CSignatureOf : public CSignature { 112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected: 113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MachineType storage_[1 + kParamCount]; 114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CSignatureOf() 116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : CSignature(MachineTypeForC<Ret>() != MachineType::None() ? 1 : 0, 117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kParamCount, reinterpret_cast<MachineType*>(&storage_)) { 118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (return_count_ == 1) storage_[0] = MachineTypeForC<Ret>(); 119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Set(int index, MachineType type) { 121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_LE(0, index); 122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_LT(index, kParamCount); 123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reps_[return_count_ + index] = type; 124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Helper classes for instantiating Signature objects to be callable from C. 128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <typename Ret> 129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass CSignature0 : public CSignatureOf<Ret, 0> { 130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CSignature0() : CSignatureOf<Ret, 0>() {} 132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <typename Ret, typename P1> 135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass CSignature1 : public CSignatureOf<Ret, 1> { 136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CSignature1() : CSignatureOf<Ret, 1>() { 138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch this->Set(0, MachineTypeForC<P1>()); 139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <typename Ret, typename P1, typename P2> 143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass CSignature2 : public CSignatureOf<Ret, 2> { 144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CSignature2() : CSignatureOf<Ret, 2>() { 146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch this->Set(0, MachineTypeForC<P1>()); 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch this->Set(1, MachineTypeForC<P2>()); 148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <typename Ret, typename P1, typename P2, typename P3> 152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass CSignature3 : public CSignatureOf<Ret, 3> { 153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CSignature3() : CSignatureOf<Ret, 3>() { 155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch this->Set(0, MachineTypeForC<P1>()); 156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch this->Set(1, MachineTypeForC<P2>()); 157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch this->Set(2, MachineTypeForC<P3>()); 158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtypedef CSignature2<int32_t, int32_t, int32_t> CSignature_i_ii; 162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtypedef CSignature2<uint32_t, uint32_t, uint32_t> CSignature_u_uu; 163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtypedef CSignature2<float, float, float> CSignature_f_ff; 164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtypedef CSignature2<double, double, double> CSignature_d_dd; 165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtypedef CSignature2<Object*, Object*, Object*> CSignature_o_oo; 166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace compiler 167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif // V8_COMPILER_C_SIGNATURE_H_ 171