@@ -17,7 +17,8 @@ use core::{ffi::c_void, ptr::NonNull};
1717use wasmtime_environ:: FrameTable ;
1818use wasmtime_environ:: {
1919 DefinedFuncIndex , FrameInstPos , FrameStackShape , FrameStateSlot , FrameStateSlotOffset ,
20- FrameTableBreakpointData , FrameTableDescriptorIndex , FrameValType , FuncKey , Trap ,
20+ FrameTableBreakpointData , FrameTableDescriptorIndex , FrameValType , FuncIndex , FuncKey ,
21+ GlobalIndex , MemoryIndex , TableIndex , TagIndex , Trap ,
2122} ;
2223use wasmtime_unwinder:: Frame ;
2324
@@ -65,6 +66,228 @@ impl<'a, T> StoreContextMut<'a, T> {
6566 }
6667}
6768
69+ impl Instance {
70+ /// Get access to a global within this instance's globals index
71+ /// space.
72+ ///
73+ /// This permits accessing globals whether they are exported or
74+ /// not. However, it is only available for purposes of debugging,
75+ /// and so is only permitted when `guest_debug` is enabled in the
76+ /// Engine's configuration. The intent of the Wasmtime API is to
77+ /// enforce the Wasm type system's encapsulation even in the host
78+ /// API, except where necessary for developer tooling.
79+ ///
80+ /// `None` is returned for any global index that is out-of-bounds.
81+ ///
82+ /// `None` is returned if guest-debugging is not enabled in the
83+ /// engine configuration for this Store.
84+ pub fn debug_global (
85+ & self ,
86+ mut store : impl AsContextMut ,
87+ global_index : u32 ,
88+ ) -> Option < crate :: Global > {
89+ let store = store. as_context_mut ( ) . 0 ;
90+ if !store. engine ( ) . tunables ( ) . debug_guest {
91+ return None ;
92+ }
93+
94+ let instance = & store[ self . id ] ;
95+ let env_module = self . module ( & store) . env_module ( ) ;
96+ // N.B.: `from_bits` here rather than `from_u32` so we don't
97+ // panic on `u32::MAX`. A `u32::MAX` will become an invalid
98+ // entity index which will properly return `None` below.
99+ let global = GlobalIndex :: from_bits ( global_index) ;
100+ if env_module. globals . is_valid ( global) {
101+ Some ( instance. get_exported_global ( store. id ( ) , global) )
102+ } else {
103+ None
104+ }
105+ }
106+
107+ /// Get access to a memory (unshared only) within this instance's
108+ /// memory index space.
109+ ///
110+ /// This permits accessing memories whether they are exported or
111+ /// not. However, it is only available for purposes of debugging,
112+ /// and so is only permitted when `guest_debug` is enabled in the
113+ /// Engine's configuration. The intent of the Wasmtime API is to
114+ /// enforce the Wasm type system's encapsulation even in the host
115+ /// API, except where necessary for developer tooling.
116+ ///
117+ /// `None` is returned for any memory index that is out-of-bounds.
118+ ///
119+ /// `None` is returned for any shared memory (use
120+ /// `debug_shared_memory` instead).
121+ ///
122+ /// `None` is returned if guest-debugging is not enabled in the
123+ /// engine configuration for this Store.
124+ pub fn debug_memory (
125+ & self ,
126+ mut store : impl AsContextMut ,
127+ memory_index : u32 ,
128+ ) -> Option < crate :: Memory > {
129+ let store = store. as_context_mut ( ) . 0 ;
130+ if !store. engine ( ) . tunables ( ) . debug_guest {
131+ return None ;
132+ }
133+
134+ let instance = & store[ self . id ] ;
135+ let env_module = self . module ( & store) . env_module ( ) ;
136+ let memory = MemoryIndex :: from_bits ( memory_index) ;
137+ if env_module. memories . is_valid ( memory) {
138+ Some (
139+ instance
140+ . get_exported_memory ( store. id ( ) , memory)
141+ . unshared ( ) ?,
142+ )
143+ } else {
144+ None
145+ }
146+ }
147+
148+ /// Get access to a shared memory within this instance's memory
149+ /// index space.
150+ ///
151+ /// This permits accessing memories whether they are exported or
152+ /// not. However, it is only available for purposes of debugging,
153+ /// and so is only permitted when `guest_debug` is enabled in the
154+ /// Engine's configuration. The intent of the Wasmtime API is to
155+ /// enforce the Wasm type system's encapsulation even in the host
156+ /// API, except where necessary for developer tooling.
157+ ///
158+ /// `None` is returned for any memory index that is out-of-bounds.
159+ ///
160+ /// `None` is returned for any unshared memory (use `debug_memory`
161+ /// instead).
162+ ///
163+ /// `None` is returned if guest-debugging is not enabled in the
164+ /// engine configuration for this Store.
165+ pub fn debug_shared_memory (
166+ & self ,
167+ mut store : impl AsContextMut ,
168+ memory_index : u32 ,
169+ ) -> Option < crate :: SharedMemory > {
170+ let store = store. as_context_mut ( ) . 0 ;
171+ if !store. engine ( ) . tunables ( ) . debug_guest {
172+ return None ;
173+ }
174+
175+ let instance = & store[ self . id ] ;
176+ let env_module = self . module ( & store) . env_module ( ) ;
177+ let memory = MemoryIndex :: from_bits ( memory_index) ;
178+ if env_module. memories . is_valid ( memory) {
179+ Some ( crate :: SharedMemory :: from_raw (
180+ instance. get_exported_memory ( store. id ( ) , memory) . shared ( ) ?,
181+ store. engine ( ) . clone ( ) ,
182+ ) )
183+ } else {
184+ None
185+ }
186+ }
187+
188+ /// Get access to a table within this instance's table index
189+ /// space.
190+ ///
191+ /// This permits accessing tables whether they are exported or
192+ /// not. However, it is only available for purposes of debugging,
193+ /// and so is only permitted when `guest_debug` is enabled in the
194+ /// Engine's configuration. The intent of the Wasmtime API is to
195+ /// enforce the Wasm type system's encapsulation even in the host
196+ /// API, except where necessary for developer tooling.
197+ ///
198+ /// `None` is returned for any table index that is out-of-bounds.
199+ ///
200+ /// `None` is returned if guest-debugging is not enabled in the
201+ /// engine configuration for this Store.
202+ pub fn debug_table (
203+ & self ,
204+ mut store : impl AsContextMut ,
205+ table_index : u32 ,
206+ ) -> Option < crate :: Table > {
207+ let store = store. as_context_mut ( ) . 0 ;
208+ if !store. engine ( ) . tunables ( ) . debug_guest {
209+ return None ;
210+ }
211+
212+ let instance = & store[ self . id ] ;
213+ let env_module = self . module ( & store) . env_module ( ) ;
214+ let table = TableIndex :: from_bits ( table_index) ;
215+ if env_module. tables . is_valid ( table) {
216+ Some ( instance. get_exported_table ( store. id ( ) , table) )
217+ } else {
218+ None
219+ }
220+ }
221+
222+ /// Get access to a function within this instance's function index
223+ /// space.
224+ ///
225+ /// This permits accessing functions whether they are exported or
226+ /// not. However, it is only available for purposes of debugging,
227+ /// and so is only permitted when `guest_debug` is enabled in the
228+ /// Engine's configuration. The intent of the Wasmtime API is to
229+ /// enforce the Wasm type system's encapsulation even in the host
230+ /// API, except where necessary for developer tooling.
231+ ///
232+ /// `None` is returned for any function index that is
233+ /// out-of-bounds.
234+ ///
235+ /// `None` is returned if guest-debugging is not enabled in the
236+ /// engine configuration for this Store.
237+ pub fn debug_function (
238+ & self ,
239+ mut store : impl AsContextMut ,
240+ function_index : u32 ,
241+ ) -> Option < crate :: Func > {
242+ let store = store. as_context_mut ( ) . 0 ;
243+ if !store. engine ( ) . tunables ( ) . debug_guest {
244+ return None ;
245+ }
246+
247+ let env_module = self . module ( & store) . env_module ( ) ;
248+ let func = FuncIndex :: from_bits ( function_index) ;
249+ if env_module. functions . is_valid ( func) {
250+ let store_id = store. id ( ) ;
251+ let ( instance, registry) = store. instance_and_module_registry_mut ( self . id ( ) ) ;
252+ // SAFETY: the `store` and `registry` are associated with
253+ // this instance as we fetched teh instance directly from
254+ // the store above.
255+ unsafe { Some ( instance. get_exported_func ( registry, store_id, func) ) }
256+ } else {
257+ None
258+ }
259+ }
260+
261+ /// Get access to a tag within this instance's tag index space.
262+ ///
263+ /// This permits accessing tags whether they are exported or
264+ /// not. However, it is only available for purposes of debugging,
265+ /// and so is only permitted when `guest_debug` is enabled in the
266+ /// Engine's configuration. The intent of the Wasmtime API is to
267+ /// enforce the Wasm type system's encapsulation even in the host
268+ /// API, except where necessary for developer tooling.
269+ ///
270+ /// `None` is returned for any tag index that is out-of-bounds.
271+ ///
272+ /// `None` is returned if guest-debugging is not enabled in the
273+ /// engine configuration for this Store.
274+ pub fn debug_tag ( & self , mut store : impl AsContextMut , tag_index : u32 ) -> Option < crate :: Tag > {
275+ let store = store. as_context_mut ( ) . 0 ;
276+ if !store. engine ( ) . tunables ( ) . debug_guest {
277+ return None ;
278+ }
279+
280+ let instance = & store[ self . id ] ;
281+ let env_module = self . module ( & store) . env_module ( ) ;
282+ let tag = TagIndex :: from_bits ( tag_index) ;
283+ if env_module. tags . is_valid ( tag) {
284+ Some ( instance. get_exported_tag ( store. id ( ) , tag) )
285+ } else {
286+ None
287+ }
288+ }
289+ }
290+
68291impl < ' a , T > StoreContext < ' a , T > {
69292 /// Return all breakpoints.
70293 pub fn breakpoints ( self ) -> Option < impl Iterator < Item = Breakpoint > + ' a > {
0 commit comments