2022-08-22 15:42:07 +00:00
|
|
|
// Copyright 2022 the V8 project authors. All rights reserved.
|
2014-08-28 13:17:38 +00:00
|
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
|
|
// found in the LICENSE file.
|
|
|
|
|
2022-08-22 15:42:07 +00:00
|
|
|
#ifndef V8_COMMON_C_SIGNATURE_H_
|
|
|
|
#define V8_COMMON_C_SIGNATURE_H_
|
2014-08-28 13:17:38 +00:00
|
|
|
|
2021-11-22 17:10:53 +00:00
|
|
|
#ifdef V8_USE_SIMULATOR_WITH_GENERIC_C_CALLS
|
|
|
|
#include "include/v8-fast-api-calls.h"
|
|
|
|
#endif // V8_USE_SIMULATOR_WITH_GENERIC_C_CALLS
|
|
|
|
|
2015-12-03 13:33:14 +00:00
|
|
|
#include "src/codegen/machine-type.h"
|
2014-08-28 13:17:38 +00:00
|
|
|
|
|
|
|
namespace v8 {
|
|
|
|
namespace internal {
|
|
|
|
namespace compiler {
|
|
|
|
|
2015-06-01 15:54:53 +00:00
|
|
|
#define FOREACH_CTYPE_MACHINE_TYPE_MAPPING(V) \
|
2015-12-10 09:03:30 +00:00
|
|
|
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())
|
2015-06-01 15:54:53 +00:00
|
|
|
|
2014-08-28 13:17:38 +00:00
|
|
|
template <typename T>
|
2018-01-16 09:26:02 +00:00
|
|
|
inline constexpr MachineType MachineTypeForC() {
|
2018-12-25 00:19:47 +00:00
|
|
|
static_assert(std::is_convertible<T, Object>::value,
|
|
|
|
"all non-specialized types must be convertible to Object");
|
2015-12-10 09:03:30 +00:00
|
|
|
return MachineType::AnyTagged();
|
2014-08-28 13:17:38 +00:00
|
|
|
}
|
|
|
|
|
2018-01-16 09:26:02 +00:00
|
|
|
#define DECLARE_TEMPLATE_SPECIALIZATION(ctype, mtype) \
|
|
|
|
template <> \
|
|
|
|
inline MachineType constexpr MachineTypeForC<ctype>() { \
|
|
|
|
return mtype; \
|
2015-06-01 15:54:53 +00:00
|
|
|
}
|
|
|
|
FOREACH_CTYPE_MACHINE_TYPE_MAPPING(DECLARE_TEMPLATE_SPECIALIZATION)
|
|
|
|
#undef DECLARE_TEMPLATE_SPECIALIZATION
|
2014-08-28 13:17:38 +00:00
|
|
|
|
2021-11-22 17:10:53 +00:00
|
|
|
#ifdef V8_USE_SIMULATOR_WITH_GENERIC_C_CALLS
|
|
|
|
template <>
|
|
|
|
inline MachineType constexpr MachineTypeForC<v8::AnyCType>() {
|
|
|
|
return MachineType::Int64();
|
|
|
|
}
|
|
|
|
#endif // V8_USE_SIMULATOR_WITH_GENERIC_C_CALLS
|
2015-06-01 15:54:53 +00:00
|
|
|
// 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) {}
|
2014-08-28 13:17:38 +00:00
|
|
|
|
2015-06-01 15:54:53 +00:00
|
|
|
public:
|
2020-07-09 10:43:44 +00:00
|
|
|
friend Zone;
|
|
|
|
|
2018-01-16 09:26:02 +00:00
|
|
|
template <typename... Params>
|
2016-02-18 09:55:25 +00:00
|
|
|
static void VerifyParams(MachineSignature* sig) {
|
2018-01-16 09:26:02 +00:00
|
|
|
// Verifies the C signature against the machine types.
|
|
|
|
std::array<MachineType, sizeof...(Params)> params{
|
2018-01-16 15:43:38 +00:00
|
|
|
{MachineTypeForC<Params>()...}};
|
2018-01-16 09:26:02 +00:00
|
|
|
for (size_t p = 0; p < params.size(); ++p) {
|
|
|
|
CHECK_EQ(sig->GetParam(p), params[p]);
|
2015-06-01 15:54:53 +00:00
|
|
|
}
|
|
|
|
}
|
2015-06-02 15:00:55 +00:00
|
|
|
|
2015-08-11 15:23:04 +00:00
|
|
|
static CSignature* FromMachine(Zone* zone, MachineSignature* msig) {
|
|
|
|
return reinterpret_cast<CSignature*>(msig);
|
|
|
|
}
|
|
|
|
|
2018-01-16 09:26:02 +00:00
|
|
|
template <typename... ParamMachineTypes>
|
2015-06-02 15:00:55 +00:00
|
|
|
static CSignature* New(Zone* zone, MachineType ret,
|
2018-01-16 09:26:02 +00:00
|
|
|
ParamMachineTypes... params) {
|
|
|
|
constexpr size_t param_count = sizeof...(params);
|
2018-01-16 15:43:38 +00:00
|
|
|
std::array<MachineType, param_count> param_arr{{params...}};
|
2018-01-16 09:26:02 +00:00
|
|
|
const size_t buffer_size =
|
|
|
|
param_count + (ret == MachineType::None() ? 0 : 1);
|
|
|
|
MachineType* buffer = zone->NewArray<MachineType>(buffer_size);
|
|
|
|
size_t pos = 0;
|
2015-06-02 15:00:55 +00:00
|
|
|
size_t return_count = 0;
|
2015-12-10 09:03:30 +00:00
|
|
|
if (ret != MachineType::None()) {
|
2015-06-02 15:00:55 +00:00
|
|
|
buffer[pos++] = ret;
|
|
|
|
return_count++;
|
|
|
|
}
|
2018-01-16 09:26:02 +00:00
|
|
|
for (MachineType p : param_arr) {
|
|
|
|
// Check that there are no MachineType::None()'s in the parameters.
|
|
|
|
CHECK_NE(MachineType::None(), p);
|
|
|
|
buffer[pos++] = p;
|
2015-06-02 15:00:55 +00:00
|
|
|
}
|
2018-01-16 09:26:02 +00:00
|
|
|
DCHECK_EQ(buffer_size, pos);
|
2020-07-09 10:43:44 +00:00
|
|
|
return zone->New<CSignature>(return_count, param_count, buffer);
|
2015-06-02 15:00:55 +00:00
|
|
|
}
|
2015-06-01 15:54:53 +00:00
|
|
|
};
|
2014-08-28 13:17:38 +00:00
|
|
|
|
|
|
|
// Helper classes for instantiating Signature objects to be callable from C.
|
2018-01-16 09:26:02 +00:00
|
|
|
template <typename Ret, typename... Params>
|
|
|
|
class CSignatureOf : public CSignature {
|
2014-08-28 13:17:38 +00:00
|
|
|
public:
|
2018-01-16 09:26:02 +00:00
|
|
|
CSignatureOf() : CSignature(kReturnCount, kParamCount, storage_) {
|
|
|
|
constexpr std::array<MachineType, kParamCount> param_types{
|
|
|
|
MachineTypeForC<Params>()...};
|
|
|
|
if (kReturnCount == 1) storage_[0] = MachineTypeForC<Ret>();
|
|
|
|
static_assert(
|
|
|
|
std::is_same<decltype(*reps_), decltype(*param_types.data())>::value,
|
|
|
|
"type mismatch, cannot memcpy");
|
2021-02-12 11:17:34 +00:00
|
|
|
if (kParamCount > 0) {
|
2021-11-30 15:23:02 +00:00
|
|
|
#if V8_CC_GNU
|
|
|
|
#pragma GCC diagnostic push
|
|
|
|
#pragma GCC diagnostic ignored "-Wnonnull"
|
|
|
|
#endif
|
2021-02-12 11:17:34 +00:00
|
|
|
memcpy(storage_ + kReturnCount, param_types.data(),
|
|
|
|
sizeof(*storage_) * kParamCount);
|
2021-11-30 15:23:02 +00:00
|
|
|
#if V8_CC_GNU
|
|
|
|
#pragma GCC diagnostic pop
|
|
|
|
#endif
|
2021-02-12 11:17:34 +00:00
|
|
|
}
|
2014-08-28 13:17:38 +00:00
|
|
|
}
|
|
|
|
|
2018-01-16 09:26:02 +00:00
|
|
|
private:
|
|
|
|
static constexpr size_t kReturnCount =
|
|
|
|
MachineTypeForC<Ret>() == MachineType::None() ? 0 : 1;
|
|
|
|
static constexpr size_t kParamCount = sizeof...(Params);
|
2014-08-28 13:17:38 +00:00
|
|
|
|
2018-01-16 09:26:02 +00:00
|
|
|
MachineType storage_[kReturnCount + kParamCount];
|
2014-08-28 13:17:38 +00:00
|
|
|
};
|
|
|
|
|
2019-05-27 11:31:49 +00:00
|
|
|
using CSignature_i_ii = CSignatureOf<int32_t, int32_t, int32_t>;
|
|
|
|
using CSignature_u_uu = CSignatureOf<uint32_t, uint32_t, uint32_t>;
|
|
|
|
using CSignature_f_ff = CSignatureOf<float, float, float>;
|
|
|
|
using CSignature_d_dd = CSignatureOf<double, double, double>;
|
|
|
|
using CSignature_o_oo = CSignatureOf<Object, Object, Object>;
|
2018-01-16 09:26:02 +00:00
|
|
|
|
2015-09-30 13:46:56 +00:00
|
|
|
} // namespace compiler
|
|
|
|
} // namespace internal
|
|
|
|
} // namespace v8
|
2014-08-28 13:17:38 +00:00
|
|
|
|
2022-08-22 15:42:07 +00:00
|
|
|
#endif // V8_COMMON_C_SIGNATURE_H_
|