Skip to content

Commit f09e736

Browse files
committed
[embind] Reuse signature codes from em_asm
Aside from a minor discrepancy, there is no point in maintaining two separate sets of type pack to signature conversions, especially now that they've grown with wasm64 conditionals. Keeping them in one place reduces complexity in bind.h and ensures the signatures stay in sync.
1 parent d0460ec commit f09e736

File tree

1 file changed

+20
-82
lines changed
  • system/include/emscripten

1 file changed

+20
-82
lines changed

system/include/emscripten/bind.h

Lines changed: 20 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
#include <optional>
2323
#endif
2424

25-
#include <emscripten/em_macros.h>
25+
#include <emscripten/em_asm.h>
2626
#include <emscripten/val.h>
2727
#include <emscripten/wire.h>
2828

@@ -565,97 +565,35 @@ struct FunctorInvoker<ReturnPolicy, FunctorType, void, Args...> {
565565

566566
namespace internal {
567567

568-
template<typename T>
569-
struct SignatureCode {};
570-
571-
template<>
572-
struct SignatureCode<int> {
573-
static constexpr char get() {
574-
return 'i';
575-
}
576-
};
577-
578-
template<>
579-
struct SignatureCode<void> {
580-
static constexpr char get() {
581-
return 'v';
582-
}
583-
};
568+
// TODO: this is a historical default, but we should probably use 'p' instead,
569+
// and only enable it for smart_ptr_trait<> descendants.
570+
template<typename T, typename = decltype(__em_asm_sig<int>::value)>
571+
struct SignatureCode : __em_asm_sig<int> {};
584572

585-
template<>
586-
struct SignatureCode<float> {
587-
static constexpr char get() {
588-
return 'f';
589-
}
590-
};
573+
template<typename T>
574+
struct SignatureCode<T, decltype(__em_asm_sig<T>::value)> : __em_asm_sig<T> {};
591575

576+
// TODO: should we add this override to em_asm?
577+
// Most places, including Embind, use `p` for `size_t` (aka `unsigned long`) but
578+
// `em_asm` uses platform-specific code instead which represents `unsigned long`
579+
// as a JavaScript `number` on wasm32 and as a `BigInt` on wasm64.
592580
template<>
593-
struct SignatureCode<double> {
594-
static constexpr char get() {
595-
return 'd';
596-
}
597-
};
581+
struct SignatureCode<size_t> : __em_asm_sig<void*> {};
598582

599-
template<>
600-
struct SignatureCode<void*> {
601-
static constexpr char get() {
602-
return 'p';
603-
}
604-
};
605-
template<>
606-
struct SignatureCode<size_t> {
607-
static constexpr char get() {
608-
return 'p';
609-
}
610-
};
611-
612-
template<>
613-
struct SignatureCode<long long> {
614-
static constexpr char get() {
615-
return 'j';
616-
}
617-
};
583+
template<typename T>
584+
struct SignatureCode<T&> : SignatureCode<T*> {};
618585

619-
#ifdef __wasm64__
620586
template<>
621-
struct SignatureCode<long> {
622-
static constexpr char get() {
623-
return 'j';
624-
}
587+
struct SignatureCode<void> {
588+
static constexpr char value = 'v';
625589
};
626-
#endif
627590

628591
template<typename... Args>
629-
const char* getGenericSignature() {
630-
static constexpr char signature[] = { SignatureCode<Args>::get()..., 0 };
631-
return signature;
632-
}
633-
634-
template<typename T> struct SignatureTranslator { using type = int; };
635-
template<> struct SignatureTranslator<void> { using type = void; };
636-
template<> struct SignatureTranslator<float> { using type = float; };
637-
template<> struct SignatureTranslator<double> { using type = double; };
638-
#ifdef __wasm64__
639-
template<> struct SignatureTranslator<long> { using type = long; };
640-
#endif
641-
template<> struct SignatureTranslator<long long> { using type = long long; };
642-
template<> struct SignatureTranslator<unsigned long long> { using type = long long; };
643-
template<> struct SignatureTranslator<size_t> { using type = size_t; };
644-
template<typename PtrType>
645-
struct SignatureTranslator<PtrType*> { using type = void*; };
646-
template<typename PtrType>
647-
struct SignatureTranslator<PtrType&> { using type = void*; };
648-
template<typename ReturnType, typename... Args>
649-
struct SignatureTranslator<ReturnType (*)(Args...)> { using type = void*; };
650-
651-
template<typename... Args>
652-
EMSCRIPTEN_ALWAYS_INLINE const char* getSpecificSignature() {
653-
return getGenericSignature<typename SignatureTranslator<Args>::type...>();
654-
}
592+
constexpr const char Signature[] = { SignatureCode<Args>::value..., 0 };
655593

656594
template<typename Return, typename... Args>
657-
EMSCRIPTEN_ALWAYS_INLINE const char* getSignature(Return (*)(Args...)) {
658-
return getSpecificSignature<Return, Args...>();
595+
constexpr const char* getSignature(Return (*)(Args...)) {
596+
return Signature<Return, Args...>;
659597
}
660598

661599
} // end namespace internal
@@ -2159,7 +2097,7 @@ struct MapAccess {
21592097

21602098
} // end namespace internal
21612099

2162-
template<typename K, typename V, class Compare = std::less<K>,
2100+
template<typename K, typename V, class Compare = std::less<K>,
21632101
class Allocator = std::allocator<std::pair<const K, V>>>
21642102
class_<std::map<K, V, Compare, Allocator>> register_map(const char* name) {
21652103
typedef std::map<K,V, Compare, Allocator> MapType;

0 commit comments

Comments
 (0)