diff --git a/system/include/emscripten/wire.h b/system/include/emscripten/wire.h index 03838d6af57e7..ec4eb484246b9 100644 --- a/system/include/emscripten/wire.h +++ b/system/include/emscripten/wire.h @@ -510,37 +510,38 @@ struct ret_val { static constexpr int index = 0; }; -/* +namespace internal { + +template +struct RawPointerTransformer { + // Use decay to handle references to pointers e.g.(T*&)->(T*). + using DecayedType = std::decay_t; + static constexpr bool ShouldWrap = EnableWrapper && std::is_pointer_v; + using type = std::conditional_t< + ShouldWrap, + internal::AllowedRawPointer>, + InputType + >; +}; + +} // namespace internal + template struct allow_raw_pointer { template - struct Transform { - typedef typename std::conditional< - Index == Slot::index, - internal::AllowedRawPointer::type>, - InputType - >::type type; - }; + struct Transform : internal::RawPointerTransformer< + InputType, + Index == Slot::index + > {}; }; -*/ // allow all raw pointers struct allow_raw_pointers { template - struct Transform { - // Use decay to handle references to pointers e.g.(T*&)->(T*). - typedef typename std::decay::type DecayedType; - typedef typename std::conditional< - std::is_pointer::value, - internal::AllowedRawPointer::type>, - InputType - >::type type; - }; -}; - -// this is temporary until arg policies are reworked -template -struct allow_raw_pointer : public allow_raw_pointers { + struct Transform : internal::RawPointerTransformer< + InputType, + true + > {}; }; struct async { diff --git a/test/embind/test_embind_allow_raw_pointer.cpp b/test/embind/test_embind_allow_raw_pointer.cpp new file mode 100644 index 0000000000000..a86aa618fdba5 --- /dev/null +++ b/test/embind/test_embind_allow_raw_pointer.cpp @@ -0,0 +1,21 @@ +#include + +using namespace emscripten; + +class C {}; + +void onePointerArg(C* ptr) {} +void twoPointerArg(C* ptr1, C* ptr2) {} +void sandwich(int a, C* ptr1, int b) {} + +C* pointerRet() { return nullptr; } +C* pointerRetPointerArg(C* ptr) { return nullptr; } + +EMSCRIPTEN_BINDINGS(raw_pointers) { + class_("C"); + function("onePointerArg", &onePointerArg, allow_raw_pointer>()); + function("twoPointerArg", &twoPointerArg, allow_raw_pointer>(), allow_raw_pointer>()); + function("sandwich", &sandwich, allow_raw_pointer>()); + function("pointerRet", &pointerRet, allow_raw_pointer()); + function("pointerRetPointerArg", &pointerRetPointerArg, allow_raw_pointer(), allow_raw_pointer>()); +} diff --git a/test/embind/test_embind_wrong_arg_allow.cpp b/test/embind/test_embind_wrong_arg_allow.cpp new file mode 100644 index 0000000000000..162ecfb73105a --- /dev/null +++ b/test/embind/test_embind_wrong_arg_allow.cpp @@ -0,0 +1,12 @@ +#include + +using namespace emscripten; + +class C {}; + +void passThrough(int arg0, C* ptr) {} + +EMSCRIPTEN_BINDINGS(raw_pointers) { + class_("C"); + function("passThrough", &passThrough, allow_raw_pointer>()); +} diff --git a/test/embind/test_embind_wrong_ret_allow.cpp b/test/embind/test_embind_wrong_ret_allow.cpp new file mode 100644 index 0000000000000..85d4faff5ffb3 --- /dev/null +++ b/test/embind/test_embind_wrong_ret_allow.cpp @@ -0,0 +1,12 @@ +#include + +using namespace emscripten; + +class C {}; + +void passThrough(C* ptr) {} + +EMSCRIPTEN_BINDINGS(raw_pointers) { + class_("C"); + function("passThrough", &passThrough, allow_raw_pointer()); +} diff --git a/test/test_other.py b/test/test_other.py index 3842ba77b06ba..fb45ed8238a28 100644 --- a/test/test_other.py +++ b/test/test_other.py @@ -3362,10 +3362,15 @@ def test_embind_closure_no_dynamic_execution(self): 'val_invoke': ['embind/test_embind_no_raw_pointers_val_invoke.cpp'], 'val_call': ['embind/test_embind_no_raw_pointers_val_call.cpp'], 'val_new': ['embind/test_embind_no_raw_pointers_val_new.cpp'], + 'wrong_ret_allow': ['embind/test_embind_wrong_ret_allow.cpp'], + 'wrong_arg_allow': ['embind/test_embind_wrong_arg_allow.cpp'], }) def test_embind_no_raw_pointers(self, filename): self.assert_fail([EMCC, '-lembind', test_file(filename)], 'Implicitly binding raw pointers is illegal') + def test_embind_allow_raw_pointer(self): + self.emcc(test_file('embind/test_embind_allow_raw_pointer.cpp'), ['-lembind']) + @is_slow_test @parameterized({ '': [],