diff options
author | Alon Zakai <alonzakai@gmail.com> | 2014-04-25 15:47:50 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2014-04-25 15:47:50 -0700 |
commit | 5940f5fc55f36e55466716514945cb6ac54c4634 (patch) | |
tree | 9460c320606b3582b24d24876cebe6bd8f685d77 /system | |
parent | ffa17762a625018c557a39056ac8eb0b54251694 (diff) | |
parent | 9a530d0e76ea951f761d93ce3aa739b5605acb25 (diff) |
Merge pull request #2287 from chadaustin/embind-fastcomp-asm.js
Enable embind in fastcomp/asm.js
Diffstat (limited to 'system')
-rw-r--r-- | system/include/emscripten/bind.h | 305 |
1 files changed, 239 insertions, 66 deletions
diff --git a/system/include/emscripten/bind.h b/system/include/emscripten/bind.h index 0699715c..699e834b 100644 --- a/system/include/emscripten/bind.h +++ b/system/include/emscripten/bind.h @@ -20,6 +20,8 @@ namespace emscripten { namespace internal { typedef long GenericEnumValue; + typedef void (*GenericFunction)(); + // Implemented in JavaScript. Don't call these directly. extern "C" { void _embind_fatal_error( @@ -70,21 +72,26 @@ namespace emscripten { const char* name, unsigned argCount, TYPEID argTypes[], + const char* signature, GenericFunction invoker, GenericFunction function); void _embind_register_value_array( TYPEID tupleType, const char* name, + const char* constructorSignature, GenericFunction constructor, + const char* destructorSignature, GenericFunction destructor); void _embind_register_value_array_element( TYPEID tupleType, TYPEID getterReturnType, + const char* getterSignature, GenericFunction getter, void* getterContext, TYPEID setterArgumentType, + const char* setterSignature, GenericFunction setter, void* setterContext); @@ -93,46 +100,45 @@ namespace emscripten { void _embind_register_value_object( TYPEID structType, const char* fieldName, + const char* constructorSignature, GenericFunction constructor, + const char* destructorSignature, GenericFunction destructor); void _embind_register_value_object_field( TYPEID structType, const char* fieldName, TYPEID getterReturnType, + const char* getterSignature, GenericFunction getter, void* getterContext, TYPEID setterArgumentType, + const char* setterSignature, GenericFunction setter, void* setterContext); void _embind_finalize_value_object(TYPEID structType); - void _embind_register_smart_ptr( - TYPEID pointerType, - TYPEID pointeeType, - const char* pointerName, - sharing_policy sharingPolicy, - GenericFunction getPointee, - GenericFunction constructor, - GenericFunction share, - GenericFunction destructor); - void _embind_register_class( TYPEID classType, TYPEID pointerType, TYPEID constPointerType, TYPEID baseClassType, + const char* getActualTypeSignature, GenericFunction getActualType, + const char* upcastSignature, GenericFunction upcast, + const char* downcastSignature, GenericFunction downcast, const char* className, + const char* destructorSignature, GenericFunction destructor); void _embind_register_class_constructor( TYPEID classType, unsigned argCount, TYPEID argTypes[], + const char* invokerSignature, GenericFunction invoker, GenericFunction constructor); @@ -141,6 +147,7 @@ namespace emscripten { const char* methodName, unsigned argCount, TYPEID argTypes[], + const char* invokerSignature, GenericFunction invoker, void* context); @@ -148,9 +155,11 @@ namespace emscripten { TYPEID classType, const char* fieldName, TYPEID getterReturnType, + const char* getterSignature, GenericFunction getter, void* getterContext, TYPEID setterArgumentType, + const char* setterSignature, GenericFunction setter, void* setterContext); @@ -159,6 +168,7 @@ namespace emscripten { const char* methodName, unsigned argCount, TYPEID argTypes[], + const char* invokerSignature, GenericFunction invoker, GenericFunction method); @@ -168,17 +178,25 @@ namespace emscripten { size_t size, bool isSigned); + void _embind_register_smart_ptr( + TYPEID pointerType, + TYPEID pointeeType, + const char* pointerName, + sharing_policy sharingPolicy, + const char* getPointeeSignature, + GenericFunction getPointee, + const char* constructorSignature, + GenericFunction constructor, + const char* shareSignature, + GenericFunction share, + const char* destructorSignature, + GenericFunction destructor); + void _embind_register_enum_value( TYPEID enumType, const char* valueName, GenericEnumValue value); - void _embind_register_interface( - TYPEID interfaceType, - const char* name, - GenericFunction constructor, - GenericFunction destructor); - void _embind_register_constant( const char* name, TYPEID constantType, @@ -291,6 +309,63 @@ namespace emscripten { } //////////////////////////////////////////////////////////////////////////////// + // SignatureCode, SignatureString + //////////////////////////////////////////////////////////////////////////////// + + namespace internal { + template<typename T> + struct SignatureCode { + static constexpr char get() { + return 'i'; + } + }; + + template<> + struct SignatureCode<void> { + static constexpr char get() { + return 'v'; + } + }; + + template<> + struct SignatureCode<float> { + static constexpr char get() { + return 'd'; + } + }; + + template<> + struct SignatureCode<double> { + static constexpr char get() { + return 'd'; + } + }; + + template<typename... T> + struct SignatureString; + + template<> + struct SignatureString<> { + char c = 0; + }; + + template<typename First, typename... Rest> + struct SignatureString<First, Rest...> { + constexpr SignatureString() + : c(SignatureCode<First>::get()) + {} + char c; + SignatureString<Rest...> rest; + }; + + template<typename Return, typename... Args> + const char* getSignature(Return (*)(Args...)) { + static constexpr SignatureString<Return, Args...> sig; + return &sig.c; + } + } + + //////////////////////////////////////////////////////////////////////////////// // FUNCTIONS //////////////////////////////////////////////////////////////////////////////// @@ -302,11 +377,13 @@ namespace emscripten { void function(const char* name, ReturnType (*fn)(Args...), Policies...) { using namespace internal; typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, Args...> args; + auto invoker = &Invoker<ReturnType, Args...>::invoke; _embind_register_function( name, args.count, args.types, - reinterpret_cast<GenericFunction>(&Invoker<ReturnType, Args...>::invoke), + getSignature(invoker), + reinterpret_cast<GenericFunction>(invoker), reinterpret_cast<GenericFunction>(fn)); } @@ -542,11 +619,16 @@ namespace emscripten { value_array(const char* name) { using namespace internal; + + auto constructor = &raw_constructor<ClassType>; + auto destructor = &raw_destructor<ClassType>; _embind_register_value_array( TypeID<ClassType>::get(), name, - reinterpret_cast<GenericFunction>(&raw_constructor<ClassType>), - reinterpret_cast<GenericFunction>(&raw_destructor<ClassType>)); + getSignature(constructor), + reinterpret_cast<GenericFunction>(constructor), + getSignature(destructor), + reinterpret_cast<GenericFunction>(destructor)); } ~value_array() { @@ -557,17 +639,21 @@ namespace emscripten { template<typename InstanceType, typename ElementType> value_array& element(ElementType InstanceType::*field) { using namespace internal; + + auto getter = &MemberAccess<InstanceType, ElementType> + ::template getWire<ClassType>; + auto setter = &MemberAccess<InstanceType, ElementType> + ::template setWire<ClassType>; + _embind_register_value_array_element( TypeID<ClassType>::get(), TypeID<ElementType>::get(), - reinterpret_cast<GenericFunction>( - &MemberAccess<InstanceType, ElementType> - ::template getWire<ClassType>), + getSignature(getter), + reinterpret_cast<GenericFunction>(getter), getContext(field), TypeID<ElementType>::get(), - reinterpret_cast<GenericFunction>( - &MemberAccess<InstanceType, ElementType> - ::template setWire<ClassType>), + getSignature(setter), + reinterpret_cast<GenericFunction>(setter), getContext(field)); return *this; } @@ -577,13 +663,19 @@ namespace emscripten { using namespace internal; typedef GetterPolicy<Getter> GP; typedef SetterPolicy<Setter> SP; + + auto g = &GP::template get<ClassType>; + auto s = &SP::template set<ClassType>; + _embind_register_value_array_element( TypeID<ClassType>::get(), TypeID<typename GP::ReturnType>::get(), - reinterpret_cast<GenericFunction>(&GP::template get<ClassType>), + getSignature(g), + reinterpret_cast<GenericFunction>(g), GP::getContext(getter), TypeID<typename SP::ArgumentType>::get(), - reinterpret_cast<GenericFunction>(&SP::template set<ClassType>), + getSignature(s), + reinterpret_cast<GenericFunction>(s), SP::getContext(setter)); return *this; } @@ -593,13 +685,18 @@ namespace emscripten { using namespace internal; ClassType* null = 0; typedef typename std::remove_reference<decltype((*null)[Index])>::type ElementType; + auto getter = &internal::get_by_index<ClassType, ElementType>; + auto setter = &internal::set_by_index<ClassType, ElementType>; + _embind_register_value_array_element( TypeID<ClassType>::get(), TypeID<ElementType>::get(), - reinterpret_cast<GenericFunction>(&internal::get_by_index<ClassType, ElementType>), + getSignature(getter), + reinterpret_cast<GenericFunction>(getter), reinterpret_cast<void*>(Index), TypeID<ElementType>::get(), - reinterpret_cast<GenericFunction>(&internal::set_by_index<ClassType, ElementType>), + getSignature(setter), + reinterpret_cast<GenericFunction>(setter), reinterpret_cast<void*>(Index)); return *this; } @@ -616,11 +713,17 @@ namespace emscripten { value_object(const char* name) { using namespace internal; + + auto ctor = &raw_constructor<ClassType>; + auto dtor = &raw_destructor<ClassType>; + _embind_register_value_object( TypeID<ClassType>::get(), name, - reinterpret_cast<GenericFunction>(&raw_constructor<ClassType>), - reinterpret_cast<GenericFunction>(&raw_destructor<ClassType>)); + getSignature(ctor), + reinterpret_cast<GenericFunction>(ctor), + getSignature(dtor), + reinterpret_cast<GenericFunction>(dtor)); } ~value_object() { @@ -630,18 +733,22 @@ namespace emscripten { template<typename InstanceType, typename FieldType> value_object& field(const char* fieldName, FieldType InstanceType::*field) { using namespace internal; + + auto getter = &MemberAccess<InstanceType, FieldType> + ::template getWire<ClassType>; + auto setter = &MemberAccess<InstanceType, FieldType> + ::template setWire<ClassType>; + _embind_register_value_object_field( TypeID<ClassType>::get(), fieldName, TypeID<FieldType>::get(), - reinterpret_cast<GenericFunction>( - &MemberAccess<InstanceType, FieldType> - ::template getWire<ClassType>), + getSignature(getter), + reinterpret_cast<GenericFunction>(getter), getContext(field), TypeID<FieldType>::get(), - reinterpret_cast<GenericFunction>( - &MemberAccess<InstanceType, FieldType> - ::template setWire<ClassType>), + getSignature(setter), + reinterpret_cast<GenericFunction>(setter), getContext(field)); return *this; } @@ -655,14 +762,20 @@ namespace emscripten { using namespace internal; typedef GetterPolicy<Getter> GP; typedef SetterPolicy<Setter> SP; + + auto g = &GP::template get<ClassType>; + auto s = &SP::template set<ClassType>; + _embind_register_value_object_field( TypeID<ClassType>::get(), fieldName, TypeID<typename GP::ReturnType>::get(), - reinterpret_cast<GenericFunction>(&GP::template get<ClassType>), + getSignature(g), + reinterpret_cast<GenericFunction>(g), GP::getContext(getter), TypeID<typename SP::ArgumentType>::get(), - reinterpret_cast<GenericFunction>(&SP::template set<ClassType>), + getSignature(s), + reinterpret_cast<GenericFunction>(s), SP::getContext(setter)); return *this; } @@ -672,14 +785,20 @@ namespace emscripten { using namespace internal; ClassType* null = 0; typedef typename std::remove_reference<decltype((*null)[Index])>::type ElementType; + + auto getter = &internal::get_by_index<ClassType, ElementType>; + auto setter = &internal::set_by_index<ClassType, ElementType>; + _embind_register_value_object_field( TypeID<ClassType>::get(), fieldName, TypeID<ElementType>::get(), - reinterpret_cast<GenericFunction>(&internal::get_by_index<ClassType, ElementType>), + getSignature(getter), + reinterpret_cast<GenericFunction>(getter), reinterpret_cast<void*>(Index), TypeID<ElementType>::get(), - reinterpret_cast<GenericFunction>(&internal::set_by_index<ClassType, ElementType>), + getSignature(setter), + reinterpret_cast<GenericFunction>(setter), reinterpret_cast<void*>(Index)); return *this; } @@ -832,13 +951,19 @@ namespace emscripten { } template<typename ClassType> - static internal::GenericFunction getUpcaster() { - return reinterpret_cast<internal::GenericFunction>(&convertPointer<ClassType, BaseClass>); + using Upcaster = BaseClass* (*)(ClassType*); + + template<typename ClassType> + using Downcaster = ClassType* (*)(BaseClass*); + + template<typename ClassType> + static Upcaster<ClassType> getUpcaster() { + return &convertPointer<ClassType, BaseClass>; } template<typename ClassType> - static internal::GenericFunction getDowncaster() { - return reinterpret_cast<internal::GenericFunction>(&convertPointer<BaseClass, ClassType>); + static Downcaster<ClassType> getDowncaster() { + return &convertPointer<BaseClass, ClassType>; } template<typename From, typename To> @@ -877,16 +1002,25 @@ namespace emscripten { BaseSpecifier::template verify<ClassType>(); + auto _getActualType = &getActualType<ClassType>; + auto upcast = BaseSpecifier::template getUpcaster<ClassType>(); + auto downcast = BaseSpecifier::template getDowncaster<ClassType>(); + auto destructor = &raw_destructor<ClassType>; + _embind_register_class( TypeID<ClassType>::get(), TypeID<AllowedRawPointer<ClassType>>::get(), TypeID<AllowedRawPointer<const ClassType>>::get(), BaseSpecifier::get(), - reinterpret_cast<GenericFunction>(&getActualType<ClassType>), - BaseSpecifier::template getUpcaster<ClassType>(), - BaseSpecifier::template getDowncaster<ClassType>(), + getSignature(_getActualType), + reinterpret_cast<GenericFunction>(_getActualType), + getSignature(upcast), + reinterpret_cast<GenericFunction>(upcast), + getSignature(downcast), + reinterpret_cast<GenericFunction>(downcast), name, - reinterpret_cast<GenericFunction>(&raw_destructor<ClassType>)); + getSignature(destructor), + reinterpret_cast<GenericFunction>(destructor)); } template<typename PointerType> @@ -898,15 +1032,24 @@ namespace emscripten { static_assert(std::is_same<ClassType, typename std::remove_cv<PointeeType>::type>::value, "smart pointer must point to this class"); + auto get = &PointerTrait::get; + auto construct_null = &PointerTrait::construct_null; + auto share = &PointerTrait::share; + auto destructor = &raw_destructor<PointerType>; + _embind_register_smart_ptr( TypeID<PointerType>::get(), TypeID<PointeeType>::get(), name, PointerTrait::get_sharing_policy(), - reinterpret_cast<GenericFunction>(&PointerTrait::get), - reinterpret_cast<GenericFunction>(&PointerTrait::construct_null), - reinterpret_cast<GenericFunction>(&PointerTrait::share), - reinterpret_cast<GenericFunction>(&raw_destructor<PointerType>)); + getSignature(get), + reinterpret_cast<GenericFunction>(get), + getSignature(construct_null), + reinterpret_cast<GenericFunction>(construct_null), + getSignature(share), + reinterpret_cast<GenericFunction>(share), + getSignature(destructor), + reinterpret_cast<GenericFunction>(destructor)); return *this; }; @@ -923,11 +1066,13 @@ namespace emscripten { // TODO: allows all raw pointers... policies need a rethink typename WithPolicies<allow_raw_pointers, Policies...>::template ArgTypeList<ReturnType, Args...> args; + auto invoke = &Invoker<ReturnType, Args...>::invoke; _embind_register_class_constructor( TypeID<ClassType>::get(), args.count, args.types, - reinterpret_cast<GenericFunction>(&Invoker<ReturnType, Args...>::invoke), + getSignature(invoke), + reinterpret_cast<GenericFunction>(invoke), reinterpret_cast<GenericFunction>(factory)); return *this; } @@ -939,11 +1084,13 @@ namespace emscripten { smart_ptr<SmartPtr>(smartPtrName); typename WithPolicies<Policies...>::template ArgTypeList<SmartPtr, Args...> args; + auto invoke = &Invoker<SmartPtr, Args...>::invoke; _embind_register_class_constructor( TypeID<ClassType>::get(), args.count, args.types, - reinterpret_cast<GenericFunction>(&Invoker<SmartPtr, Args...>::invoke), + getSignature(invoke), + reinterpret_cast<GenericFunction>(invoke), reinterpret_cast<GenericFunction>(factory)); return *this; } @@ -966,13 +1113,16 @@ namespace emscripten { EMSCRIPTEN_ALWAYS_INLINE const class_& function(const char* methodName, ReturnType (ClassType::*memberFunction)(Args...), Policies...) const { using namespace internal; + auto invoker = &MethodInvoker<decltype(memberFunction), ReturnType, ClassType*, Args...>::invoke; + typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, AllowedRawPointer<ClassType>, Args...> args; _embind_register_class_function( TypeID<ClassType>::get(), methodName, args.count, args.types, - reinterpret_cast<GenericFunction>(&MethodInvoker<decltype(memberFunction), ReturnType, ClassType*, Args...>::invoke), + getSignature(invoker), + reinterpret_cast<GenericFunction>(invoker), getContext(memberFunction)); return *this; } @@ -981,13 +1131,16 @@ namespace emscripten { EMSCRIPTEN_ALWAYS_INLINE const class_& function(const char* methodName, ReturnType (ClassType::*memberFunction)(Args...) const, Policies...) const { using namespace internal; + auto invoker = &MethodInvoker<decltype(memberFunction), ReturnType, const ClassType*, Args...>::invoke; + typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, AllowedRawPointer<const ClassType>, Args...> args; _embind_register_class_function( TypeID<ClassType>::get(), methodName, args.count, args.types, - reinterpret_cast<GenericFunction>(&MethodInvoker<decltype(memberFunction), ReturnType, const ClassType*, Args...>::invoke), + getSignature(invoker), + reinterpret_cast<GenericFunction>(invoker), getContext(memberFunction)); return *this; } @@ -997,12 +1150,14 @@ namespace emscripten { using namespace internal; typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, ThisType, Args...> args; + auto invoke = &FunctionInvoker<decltype(function), ReturnType, ThisType, Args...>::invoke; _embind_register_class_function( TypeID<ClassType>::get(), methodName, args.count, args.types, - reinterpret_cast<GenericFunction>(&FunctionInvoker<decltype(function), ReturnType, ThisType, Args...>::invoke), + getSignature(invoke), + reinterpret_cast<GenericFunction>(invoke), getContext(function)); return *this; } @@ -1010,15 +1165,18 @@ namespace emscripten { template<typename FieldType, typename = typename std::enable_if<!std::is_function<FieldType>::value>::type> EMSCRIPTEN_ALWAYS_INLINE const class_& property(const char* fieldName, const FieldType ClassType::*field) const { using namespace internal; - + + auto getter = &MemberAccess<ClassType, FieldType>::template getWire<ClassType>; _embind_register_class_property( TypeID<ClassType>::get(), fieldName, TypeID<FieldType>::get(), - reinterpret_cast<GenericFunction>(&MemberAccess<ClassType, FieldType>::template getWire<ClassType>), + getSignature(getter), + reinterpret_cast<GenericFunction>(getter), getContext(field), 0, 0, + 0, 0); return *this; } @@ -1027,14 +1185,18 @@ namespace emscripten { EMSCRIPTEN_ALWAYS_INLINE const class_& property(const char* fieldName, FieldType ClassType::*field) const { using namespace internal; + auto getter = &MemberAccess<ClassType, FieldType>::template getWire<ClassType>; + auto setter = &MemberAccess<ClassType, FieldType>::template setWire<ClassType>; _embind_register_class_property( TypeID<ClassType>::get(), fieldName, TypeID<FieldType>::get(), - reinterpret_cast<GenericFunction>(&MemberAccess<ClassType, FieldType>::template getWire<ClassType>), + getSignature(getter), + reinterpret_cast<GenericFunction>(getter), getContext(field), TypeID<FieldType>::get(), - reinterpret_cast<GenericFunction>(&MemberAccess<ClassType, FieldType>::template setWire<ClassType>), + getSignature(setter), + reinterpret_cast<GenericFunction>(setter), getContext(field)); return *this; } @@ -1043,14 +1205,17 @@ namespace emscripten { EMSCRIPTEN_ALWAYS_INLINE const class_& property(const char* fieldName, Getter getter) const { using namespace internal; typedef GetterPolicy<Getter> GP; + auto gter = &GP::template get<ClassType>; _embind_register_class_property( TypeID<ClassType>::get(), fieldName, TypeID<typename GP::ReturnType>::get(), - reinterpret_cast<GenericFunction>(&GP::template get<ClassType>), + getSignature(gter), + reinterpret_cast<GenericFunction>(gter), GP::getContext(getter), 0, 0, + 0, 0); return *this; } @@ -1060,14 +1225,20 @@ namespace emscripten { using namespace internal; typedef GetterPolicy<Getter> GP; typedef SetterPolicy<Setter> SP; + + auto gter = &GP::template get<ClassType>; + auto ster = &SP::template set<ClassType>; + _embind_register_class_property( TypeID<ClassType>::get(), fieldName, TypeID<typename GP::ReturnType>::get(), - reinterpret_cast<GenericFunction>(&GP::template get<ClassType>), + getSignature(gter), + reinterpret_cast<GenericFunction>(gter), GP::getContext(getter), TypeID<typename SP::ArgumentType>::get(), - reinterpret_cast<GenericFunction>(&SP::template set<ClassType>), + getSignature(ster), + reinterpret_cast<GenericFunction>(ster), SP::getContext(setter)); return *this; } @@ -1077,12 +1248,14 @@ namespace emscripten { using namespace internal; typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, Args...> args; + auto invoke = &internal::Invoker<ReturnType, Args...>::invoke; _embind_register_class_class_function( TypeID<ClassType>::get(), methodName, args.count, args.types, - reinterpret_cast<internal::GenericFunction>(&internal::Invoker<ReturnType, Args...>::invoke), + getSignature(invoke), + reinterpret_cast<internal::GenericFunction>(invoke), reinterpret_cast<GenericFunction>(classMethod)); return *this; } |