@@ -70,6 +70,15 @@ use std::sync::Arc;
70
70
/// point only the [`Store`] that owns the [`Global`] can be used to instantiate
71
71
/// modules.
72
72
///
73
+ /// ## Multiple `Engine`s
74
+ ///
75
+ /// The [`Linker`] type is not compatible with usage between multiple [`Engine`]
76
+ /// values. An [`Engine`] is provided when a [`Linker`] is created and only
77
+ /// stores and items which originate from that [`Engine`] can be used with this
78
+ /// [`Linker`]. If more than one [`Engine`] is used with a [`Linker`] then that
79
+ /// may cause a panic at runtime, similar to how if a [`Func`] is used with the
80
+ /// wrong [`Store`] that can also panic at runtime.
81
+ ///
73
82
/// [`Store`]: crate::Store
74
83
/// [`Global`]: crate::Global
75
84
pub struct Linker < T > {
@@ -150,6 +159,11 @@ macro_rules! generate_wrap_async_func {
150
159
151
160
impl < T > Linker < T > {
152
161
/// Creates a new [`Linker`].
162
+ ///
163
+ /// The linker will define functions within the context of the `engine`
164
+ /// provided and can only instantiate modules for a [`Store`] that is also
165
+ /// defined within the same [`Engine`]. Usage of stores with different
166
+ /// [`Engine`]s may cause a panic when used with this [`Linker`].
153
167
pub fn new ( engine : & Engine ) -> Linker < T > {
154
168
Linker {
155
169
engine : engine. clone ( ) ,
@@ -236,9 +250,6 @@ impl<T> Linker<T> {
236
250
/// of the same type as the `item` provided and if shadowing is disallowed.
237
251
/// For more information see the documentation on [`Linker`].
238
252
///
239
- /// Also returns an error if `item` comes from a different store than this
240
- /// [`Linker`] was created with.
241
- ///
242
253
/// # Examples
243
254
///
244
255
/// ```
@@ -417,6 +428,11 @@ impl<T> Linker<T> {
417
428
/// for each export is `module_name`, and the name for each export is the
418
429
/// name in the instance itself.
419
430
///
431
+ /// Note that when this API is used the [`Linker`] is no longer compatible
432
+ /// with multi-[`Store` ] instantiation because the items defined within
433
+ /// this store will belong to the `store` provided, and only the `store`
434
+ /// provided.
435
+ ///
420
436
/// # Errors
421
437
///
422
438
/// Returns an error if the any item is redefined twice in this linker (for
@@ -505,7 +521,8 @@ impl<T> Linker<T> {
505
521
/// # Panics
506
522
///
507
523
/// Panics if any item used to instantiate the provided [`Module`] is not
508
- /// owned by `store`.
524
+ /// owned by `store`, or if the `store` provided comes from a different
525
+ /// [`Engine`] than this [`Linker`].
509
526
///
510
527
/// # Examples
511
528
///
@@ -602,6 +619,15 @@ impl<T> Linker<T> {
602
619
{
603
620
// NB: this is intended to function the same as `Linker::module_async`,
604
621
// they should be kept in sync.
622
+
623
+ // This assert isn't strictly necessary since it'll bottom out in the
624
+ // `HostFunc::to_func` method anyway. This is placed earlier for this
625
+ // function though to prevent the functions created here from delaying
626
+ // the panic until they're called.
627
+ assert ! (
628
+ Engine :: same( & self . engine, store. as_context( ) . engine( ) ) ,
629
+ "different engines for this linker and the store provided"
630
+ ) ;
605
631
match ModuleKind :: categorize ( module) ? {
606
632
ModuleKind :: Command => {
607
633
self . command (
@@ -672,6 +698,10 @@ impl<T> Linker<T> {
672
698
{
673
699
// NB: this is intended to function the same as `Linker::module`, they
674
700
// should be kept in sync.
701
+ assert ! (
702
+ Engine :: same( & self . engine, store. as_context( ) . engine( ) ) ,
703
+ "different engines for this linker and the store provided"
704
+ ) ;
675
705
match ModuleKind :: categorize ( module) ? {
676
706
ModuleKind :: Command => self . command (
677
707
store,
@@ -899,7 +929,8 @@ impl<T> Linker<T> {
899
929
/// # Panics
900
930
///
901
931
/// Panics if any item used to instantiate `module` is not owned by
902
- /// `store`.
932
+ /// `store`. Additionally this will panic if the [`Engine`] that the `store`
933
+ /// belongs to is different than this [`Linker`].
903
934
///
904
935
/// # Examples
905
936
///
@@ -958,7 +989,9 @@ impl<T> Linker<T> {
958
989
/// # Panics
959
990
///
960
991
/// This method will panic if any item defined in this linker used by
961
- /// `module` is not owned by `store`.
992
+ /// `module` is not owned by `store`. Additionally this will panic if the
993
+ /// [`Engine`] that the `store` belongs to is different than this
994
+ /// [`Linker`].
962
995
///
963
996
/// # Examples
964
997
///
@@ -1027,6 +1060,11 @@ impl<T> Linker<T> {
1027
1060
///
1028
1061
/// Note that multiple `Extern` items may be defined for the same
1029
1062
/// module/name pair.
1063
+ ///
1064
+ /// # Panics
1065
+ ///
1066
+ /// This function will panic if the `store` provided does not come from the
1067
+ /// same [`Engine`] that this linker was created with.
1030
1068
pub fn iter < ' a : ' p , ' p > (
1031
1069
& ' a self ,
1032
1070
mut store : impl AsContextMut < Data = T > + ' p ,
@@ -1047,6 +1085,11 @@ impl<T> Linker<T> {
1047
1085
///
1048
1086
/// Returns `None` if this name was not previously defined in this
1049
1087
/// [`Linker`].
1088
+ ///
1089
+ /// # Panics
1090
+ ///
1091
+ /// This function will panic if the `store` provided does not come from the
1092
+ /// same [`Engine`] that this linker was created with.
1050
1093
pub fn get (
1051
1094
& self ,
1052
1095
mut store : impl AsContextMut < Data = T > ,
@@ -1073,6 +1116,11 @@ impl<T> Linker<T> {
1073
1116
/// provided.
1074
1117
///
1075
1118
/// Returns `None` if no match was found.
1119
+ ///
1120
+ /// # Panics
1121
+ ///
1122
+ /// This function will panic if the `store` provided does not come from the
1123
+ /// same [`Engine`] that this linker was created with.
1076
1124
pub fn get_by_import (
1077
1125
& self ,
1078
1126
mut store : impl AsContextMut < Data = T > ,
@@ -1126,7 +1174,9 @@ impl<T> Linker<T> {
1126
1174
///
1127
1175
/// # Panics
1128
1176
///
1129
- /// Panics if the default function found is not owned by `store`.
1177
+ /// Panics if the default function found is not owned by `store`. This
1178
+ /// function will also panic if the `store` provided does not come from the
1179
+ /// same [`Engine`] that this linker was created with.
1130
1180
pub fn get_default (
1131
1181
& self ,
1132
1182
mut store : impl AsContextMut < Data = T > ,
0 commit comments