@@ -255,6 +255,11 @@ pub enum Import {
255
255
/// well.
256
256
ExportedTaskReturn ( WorldKey , Option < InterfaceId > , String , Option < Type > ) ,
257
257
258
+ /// The `context.get` intrinsic for the nth slot of storage.
259
+ ContextGet ( u32 ) ,
260
+ /// The `context.set` intrinsic for the nth slot of storage.
261
+ ContextSet ( u32 ) ,
262
+
258
263
/// A `canon backpressure.set` intrinsic.
259
264
///
260
265
/// This allows the guest to dynamically indicate whether it's ready for
@@ -634,6 +639,19 @@ impl ImportMap {
634
639
return Ok ( Import :: ErrorContextDebugMessage { encoding } ) ;
635
640
}
636
641
642
+ if let Some ( i) = names. context_get ( name) {
643
+ validate_not_async ( ) ?;
644
+ let expected = FuncType :: new ( [ ] , [ ValType :: I32 ] ) ;
645
+ validate_func_sig ( name, & expected, ty) ?;
646
+ return Ok ( Import :: ContextGet ( i) ) ;
647
+ }
648
+ if let Some ( i) = names. context_set ( name) {
649
+ validate_not_async ( ) ?;
650
+ let expected = FuncType :: new ( [ ValType :: I32 ] , [ ] ) ;
651
+ validate_func_sig ( name, & expected, ty) ?;
652
+ return Ok ( Import :: ContextSet ( i) ) ;
653
+ }
654
+
637
655
let key = WorldKey :: Name ( name. to_string ( ) ) ;
638
656
if let Some ( WorldItem :: Function ( func) ) = world. imports . get ( & key) {
639
657
validate_func ( resolve, ty, func, abi) ?;
@@ -829,10 +847,8 @@ impl ImportMap {
829
847
let prefixed_payload = |prefix : & str | {
830
848
// parse the `prefix` into `func_name` and `type_index`, bailing out
831
849
// with `None` if anything doesn't match.
832
- let suffix = name. strip_prefix ( prefix) ?;
833
- let index = suffix. find ( ']' ) ?;
834
- let func_name = & suffix[ index + 1 ..] ;
835
- let type_index: usize = suffix[ ..index] . parse ( ) . ok ( ) ?;
850
+ let ( type_index, func_name) = prefixed_integer ( name, prefix) ?;
851
+ let type_index = type_index as usize ;
836
852
837
853
// Double-check that `func_name` is indeed a function name within
838
854
// this interface/world. Then additionally double-check that
@@ -1421,6 +1437,8 @@ trait NameMangling {
1421
1437
fn error_context_new ( & self , s : & str ) -> Option < StringEncoding > ;
1422
1438
fn error_context_debug_message ( & self , s : & str ) -> Option < StringEncoding > ;
1423
1439
fn error_context_drop ( & self ) -> Option < & str > ;
1440
+ fn context_get ( & self , name : & str ) -> Option < u32 > ;
1441
+ fn context_set ( & self , name : & str ) -> Option < u32 > ;
1424
1442
fn module_to_interface (
1425
1443
& self ,
1426
1444
module : & str ,
@@ -1531,6 +1549,12 @@ impl NameMangling for Standard {
1531
1549
fn error_context_drop ( & self ) -> Option < & str > {
1532
1550
None
1533
1551
}
1552
+ fn context_get ( & self , _: & str ) -> Option < u32 > {
1553
+ None
1554
+ }
1555
+ fn context_set ( & self , _: & str ) -> Option < u32 > {
1556
+ None
1557
+ }
1534
1558
fn module_to_interface (
1535
1559
& self ,
1536
1560
interface : & str ,
@@ -1724,6 +1748,22 @@ impl NameMangling for Legacy {
1724
1748
fn error_context_drop ( & self ) -> Option < & str > {
1725
1749
Some ( "[error-context-drop]" )
1726
1750
}
1751
+ fn context_get ( & self , name : & str ) -> Option < u32 > {
1752
+ let ( n, rest) = prefixed_integer ( name, "[context-get-" ) ?;
1753
+ if rest. is_empty ( ) {
1754
+ Some ( n)
1755
+ } else {
1756
+ None
1757
+ }
1758
+ }
1759
+ fn context_set ( & self , name : & str ) -> Option < u32 > {
1760
+ let ( n, rest) = prefixed_integer ( name, "[context-set-" ) ?;
1761
+ if rest. is_empty ( ) {
1762
+ Some ( n)
1763
+ } else {
1764
+ None
1765
+ }
1766
+ }
1727
1767
fn module_to_interface (
1728
1768
& self ,
1729
1769
module : & str ,
@@ -2009,6 +2049,17 @@ fn validate_func_sig(name: &str, expected: &FuncType, ty: &wasmparser::FuncType)
2009
2049
Ok ( ( ) )
2010
2050
}
2011
2051
2052
+ /// Matches `name` as `[${prefix}N]...`, and if found returns `(N, "...")`
2053
+ fn prefixed_integer < ' a > ( name : & ' a str , prefix : & str ) -> Option < ( u32 , & ' a str ) > {
2054
+ assert ! ( prefix. starts_with( "[" ) ) ;
2055
+ assert ! ( prefix. ends_with( "-" ) ) ;
2056
+ let suffix = name. strip_prefix ( prefix) ?;
2057
+ let index = suffix. find ( ']' ) ?;
2058
+ let rest = & suffix[ index + 1 ..] ;
2059
+ let n = suffix[ ..index] . parse ( ) . ok ( ) ?;
2060
+ Some ( ( n, rest) )
2061
+ }
2062
+
2012
2063
fn get_function < ' a > (
2013
2064
resolve : & ' a Resolve ,
2014
2065
world : & ' a World ,
0 commit comments