// Copyright 2014 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef V8_COMPILER_C_SIGNATURE_H_ #define V8_COMPILER_C_SIGNATURE_H_ #include "src/machine-type.h" namespace v8 { namespace internal { namespace compiler { #define FOREACH_CTYPE_MACHINE_TYPE_MAPPING(V) \ V(void, MachineType::None()) \ V(bool, MachineType::Uint8()) \ V(int8_t, MachineType::Int8()) \ V(uint8_t, MachineType::Uint8()) \ V(int16_t, MachineType::Int16()) \ V(uint16_t, MachineType::Uint16()) \ V(int32_t, MachineType::Int32()) \ V(uint32_t, MachineType::Uint32()) \ V(int64_t, MachineType::Int64()) \ V(uint64_t, MachineType::Uint64()) \ V(float, MachineType::Float32()) \ V(double, MachineType::Float64()) \ V(void*, MachineType::Pointer()) \ V(int*, MachineType::Pointer()) template inline MachineType MachineTypeForC() { while (false) { // All other types T must be assignable to Object* *(static_cast(0)) = static_cast(0); } return MachineType::AnyTagged(); } #define DECLARE_TEMPLATE_SPECIALIZATION(ctype, mtype) \ template <> \ inline MachineType MachineTypeForC() { \ return mtype; \ } FOREACH_CTYPE_MACHINE_TYPE_MAPPING(DECLARE_TEMPLATE_SPECIALIZATION) #undef DECLARE_TEMPLATE_SPECIALIZATION // Helper for building machine signatures from C types. class CSignature : public MachineSignature { protected: CSignature(size_t return_count, size_t parameter_count, MachineType* reps) : MachineSignature(return_count, parameter_count, reps) {} public: template static void VerifyParams(MachineSignature* sig) { // Verifies the C signature against the machine types. Maximum {5} params. CHECK_LT(sig->parameter_count(), 6u); const int kMax = 5; MachineType params[] = {MachineTypeForC(), MachineTypeForC(), MachineTypeForC(), MachineTypeForC(), MachineTypeForC()}; for (int p = kMax - 1; p >= 0; p--) { if (p < static_cast(sig->parameter_count())) { CHECK_EQ(sig->GetParam(p), params[p]); } else { CHECK_EQ(MachineType::None(), params[p]); } } } static CSignature* FromMachine(Zone* zone, MachineSignature* msig) { return reinterpret_cast(msig); } static CSignature* New(Zone* zone, MachineType ret, MachineType p1 = MachineType::None(), MachineType p2 = MachineType::None(), MachineType p3 = MachineType::None(), MachineType p4 = MachineType::None(), MachineType p5 = MachineType::None()) { MachineType* buffer = zone->NewArray(6); int pos = 0; size_t return_count = 0; if (ret != MachineType::None()) { buffer[pos++] = ret; return_count++; } buffer[pos++] = p1; buffer[pos++] = p2; buffer[pos++] = p3; buffer[pos++] = p4; buffer[pos++] = p5; size_t param_count = 5; if (p5 == MachineType::None()) param_count--; if (p4 == MachineType::None()) param_count--; if (p3 == MachineType::None()) param_count--; if (p2 == MachineType::None()) param_count--; if (p1 == MachineType::None()) param_count--; for (size_t i = 0; i < param_count; i++) { // Check that there are no MachineType::None()'s in the middle of // parameters. CHECK_NE(MachineType::None(), buffer[return_count + i]); } return new (zone) CSignature(return_count, param_count, buffer); } }; template class CSignatureOf : public CSignature { protected: MachineType storage_[1 + kParamCount]; CSignatureOf() : CSignature(MachineTypeForC() != MachineType::None() ? 1 : 0, kParamCount, reinterpret_cast(&storage_)) { if (return_count_ == 1) storage_[0] = MachineTypeForC(); } void Set(int index, MachineType type) { CHECK_LE(0, index); CHECK_LT(index, kParamCount); reps_[return_count_ + index] = type; } }; // Helper classes for instantiating Signature objects to be callable from C. template class CSignature0 : public CSignatureOf { public: CSignature0() : CSignatureOf() {} }; template class CSignature1 : public CSignatureOf { public: CSignature1() : CSignatureOf() { this->Set(0, MachineTypeForC()); } }; template class CSignature2 : public CSignatureOf { public: CSignature2() : CSignatureOf() { this->Set(0, MachineTypeForC()); this->Set(1, MachineTypeForC()); } }; template class CSignature3 : public CSignatureOf { public: CSignature3() : CSignatureOf() { this->Set(0, MachineTypeForC()); this->Set(1, MachineTypeForC()); this->Set(2, MachineTypeForC()); } }; typedef CSignature2 CSignature_i_ii; typedef CSignature2 CSignature_u_uu; typedef CSignature2 CSignature_f_ff; typedef CSignature2 CSignature_d_dd; typedef CSignature2 CSignature_o_oo; } // namespace compiler } // namespace internal } // namespace v8 #endif // V8_COMPILER_C_SIGNATURE_H_