Skip to content

Commit 6d61ffd

Browse files
authored
[embind] Allow raw pointers for individual arguments and return values. (#25912)
Previously, allow_raw_pointer<arg<x>> mapped to allow_raw_pointers, which allowed pointers for all arguments. This PR implements the checks to verify just the specified argument or return value are allowed pointers.
1 parent daa0f55 commit 6d61ffd

File tree

5 files changed

+74
-23
lines changed

5 files changed

+74
-23
lines changed

system/include/emscripten/wire.h

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -510,37 +510,38 @@ struct ret_val {
510510
static constexpr int index = 0;
511511
};
512512

513-
/*
513+
namespace internal {
514+
515+
template <typename InputType, bool EnableWrapper>
516+
struct RawPointerTransformer {
517+
// Use decay to handle references to pointers e.g.(T*&)->(T*).
518+
using DecayedType = std::decay_t<InputType>;
519+
static constexpr bool ShouldWrap = EnableWrapper && std::is_pointer_v<DecayedType>;
520+
using type = std::conditional_t<
521+
ShouldWrap,
522+
internal::AllowedRawPointer<std::remove_pointer_t<DecayedType>>,
523+
InputType
524+
>;
525+
};
526+
527+
} // namespace internal
528+
514529
template<typename Slot>
515530
struct allow_raw_pointer {
516531
template<typename InputType, int Index>
517-
struct Transform {
518-
typedef typename std::conditional<
519-
Index == Slot::index,
520-
internal::AllowedRawPointer<typename std::remove_pointer<InputType>::type>,
521-
InputType
522-
>::type type;
523-
};
532+
struct Transform : internal::RawPointerTransformer<
533+
InputType,
534+
Index == Slot::index
535+
> {};
524536
};
525-
*/
526537

527538
// allow all raw pointers
528539
struct allow_raw_pointers {
529540
template<typename InputType, int Index>
530-
struct Transform {
531-
// Use decay to handle references to pointers e.g.(T*&)->(T*).
532-
typedef typename std::decay<InputType>::type DecayedType;
533-
typedef typename std::conditional<
534-
std::is_pointer<DecayedType>::value,
535-
internal::AllowedRawPointer<typename std::remove_pointer<DecayedType>::type>,
536-
InputType
537-
>::type type;
538-
};
539-
};
540-
541-
// this is temporary until arg policies are reworked
542-
template<typename Slot>
543-
struct allow_raw_pointer : public allow_raw_pointers {
541+
struct Transform : internal::RawPointerTransformer<
542+
InputType,
543+
true
544+
> {};
544545
};
545546

546547
struct async {
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#include <emscripten/bind.h>
2+
3+
using namespace emscripten;
4+
5+
class C {};
6+
7+
void onePointerArg(C* ptr) {}
8+
void twoPointerArg(C* ptr1, C* ptr2) {}
9+
void sandwich(int a, C* ptr1, int b) {}
10+
11+
C* pointerRet() { return nullptr; }
12+
C* pointerRetPointerArg(C* ptr) { return nullptr; }
13+
14+
EMSCRIPTEN_BINDINGS(raw_pointers) {
15+
class_<C>("C");
16+
function("onePointerArg", &onePointerArg, allow_raw_pointer<arg<0>>());
17+
function("twoPointerArg", &twoPointerArg, allow_raw_pointer<arg<0>>(), allow_raw_pointer<arg<1>>());
18+
function("sandwich", &sandwich, allow_raw_pointer<arg<1>>());
19+
function("pointerRet", &pointerRet, allow_raw_pointer<ret_val>());
20+
function("pointerRetPointerArg", &pointerRetPointerArg, allow_raw_pointer<ret_val>(), allow_raw_pointer<arg<0>>());
21+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#include <emscripten/bind.h>
2+
3+
using namespace emscripten;
4+
5+
class C {};
6+
7+
void passThrough(int arg0, C* ptr) {}
8+
9+
EMSCRIPTEN_BINDINGS(raw_pointers) {
10+
class_<C>("C");
11+
function("passThrough", &passThrough, allow_raw_pointer<arg<0>>());
12+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#include <emscripten/bind.h>
2+
3+
using namespace emscripten;
4+
5+
class C {};
6+
7+
void passThrough(C* ptr) {}
8+
9+
EMSCRIPTEN_BINDINGS(raw_pointers) {
10+
class_<C>("C");
11+
function("passThrough", &passThrough, allow_raw_pointer<ret_val>());
12+
}

test/test_other.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3362,10 +3362,15 @@ def test_embind_closure_no_dynamic_execution(self):
33623362
'val_invoke': ['embind/test_embind_no_raw_pointers_val_invoke.cpp'],
33633363
'val_call': ['embind/test_embind_no_raw_pointers_val_call.cpp'],
33643364
'val_new': ['embind/test_embind_no_raw_pointers_val_new.cpp'],
3365+
'wrong_ret_allow': ['embind/test_embind_wrong_ret_allow.cpp'],
3366+
'wrong_arg_allow': ['embind/test_embind_wrong_arg_allow.cpp'],
33653367
})
33663368
def test_embind_no_raw_pointers(self, filename):
33673369
self.assert_fail([EMCC, '-lembind', test_file(filename)], 'Implicitly binding raw pointers is illegal')
33683370

3371+
def test_embind_allow_raw_pointer(self):
3372+
self.emcc(test_file('embind/test_embind_allow_raw_pointer.cpp'), ['-lembind'])
3373+
33693374
@is_slow_test
33703375
@parameterized({
33713376
'': [],

0 commit comments

Comments
 (0)