@@ -323,17 +323,15 @@ pub fn transpile_bindgen(
323323 instantiator. initialize ( ) ;
324324 instantiator. instantiate ( ) ;
325325
326- let mut intrinsic_definitions = source:: Source :: default ( ) ;
327-
328- instantiator. resource_definitions ( & mut intrinsic_definitions) ;
326+ instantiator. resource_definitions ( ) ;
329327 instantiator. instance_flags ( ) ;
330328
331329 instantiator. bindgen . src . js ( & instantiator. src . js ) ;
332330 instantiator. bindgen . src . js_init ( & instantiator. src . js_init ) ;
333331
334332 instantiator
335333 . bindgen
336- . finish_component ( name, files, & opts, intrinsic_definitions ) ;
334+ . finish_component ( name, files, & opts, source :: Source :: default ( ) ) ;
337335
338336 let exports = instantiator
339337 . bindgen
@@ -956,7 +954,7 @@ impl<'a> Instantiator<'a, '_> {
956954 }
957955 }
958956
959- fn resource_definitions ( & mut self , definitions : & mut source :: Source ) {
957+ fn resource_definitions ( & mut self ) {
960958 // It is theoretically possible for locally defined resources used in no functions
961959 // to still be exported
962960 for resource in 0 ..self . component . num_resources {
@@ -970,30 +968,21 @@ impl<'a> Instantiator<'a, '_> {
970968 }
971969 }
972970
973- // Write out the defined resource table indices for the runtime
974- if self . bindgen . all_intrinsics . contains ( & Intrinsic :: Resource (
975- ResourceIntrinsic :: ResourceTransferBorrow ,
976- ) ) || self . bindgen . all_intrinsics . contains ( & Intrinsic :: Resource (
977- ResourceIntrinsic :: ResourceTransferBorrowValidLifting ,
978- ) ) {
979- let defined_resource_tables = Intrinsic :: DefinedResourceTables . name ( ) ;
980- uwrite ! ( definitions, "const {defined_resource_tables} = [" ) ;
981- // Table per-resource
982- for tidx in 0 ..self . component . num_resources {
983- let tid = TypeResourceTableIndex :: from_u32 ( tidx) ;
984- let resource_table_ty = & self . types [ tid] ;
985- let rid = resource_table_ty. unwrap_concrete_ty ( ) ;
986- if let Some ( defined_index) = self . component . defined_resource_index ( rid) {
987- let instance_idx = resource_table_ty. unwrap_concrete_instance ( ) ;
988- if instance_idx == self . component . defined_resource_instances [ defined_index] {
989- uwrite ! ( definitions, "true," ) ;
990- }
991- } else {
992- uwrite ! ( definitions, "," ) ;
993- } ;
994- }
995- uwrite ! ( definitions, "];\n " ) ;
996- }
971+ // TODO(feat): In the past, we could eagerly build a mapping of resources defined to the tables they correspond to
972+ // to make runtime checks of which table a resource must have been created into first (i.e. the component that implements
973+ // creation of a given resource) a particular resource faster.
974+ //
975+ // This logic was based on component.num_resources and was broken for composed components --
976+ // wasmtime-environ reported a smaller number of resources, and the check was geared towards a *single* component,
977+ // not tying a particular component to a particular table (it is possible for *sub components* to originate different
978+ // resources).
979+ //
980+ // In theory, it should be posible to build this knowledge statically rather than at resource creation,
981+ // so in the future we should attempt to rebulid that code, if possible.
982+ //
983+ // Note that at runtime wasmtime maintains this information and looks it up during a transfer operation, see:
984+ // - https://github.com/bytecodealliance/wasmtime/blob/5f3b67ea055857020bd1ac1f2c3f7fa2e6c31ec0/crates/wasmtime/src/runtime/component/instance.rs#L424
985+ // - https://github.com/bytecodealliance/wasmtime/blob/9c49989a2e71382fd8639288088472f150f2f534/crates/wasmtime/src/runtime/vm/component.rs#L847
997986 }
998987
999988 /// Ensure a component-local `error-context` table has been created
@@ -1078,34 +1067,48 @@ impl<'a> Instantiator<'a, '_> {
10781067 . bindgen
10791068 . intrinsic ( Intrinsic :: Resource ( ResourceIntrinsic :: ResourceTableRemove ) ) ;
10801069
1070+ // Create the relevant handle table
10811071 let rtid = resource_table_idx. as_u32 ( ) ;
10821072 if is_imported {
1073+ // imported
10831074 uwriteln ! (
10841075 self . src. js,
1085- "const handleTable{rtid} = [{rsc_table_flag}, 0];" ,
1076+ r#"
1077+ const handleTable{rtid} = [{rsc_table_flag}, 0];
1078+ handleTable{rtid}._tableID = {rtid};
1079+ handleTable{rtid}._createdReps = new Set();
1080+ "# ,
10861081 ) ;
10871082 if !self . resources_initialized . contains_key ( & resource_idx) {
10881083 let ridx = resource_idx. as_u32 ( ) ;
10891084 uwriteln ! (
10901085 self . src. js,
1091- "const captureTable{ridx} = new Map();
1092- let captureCnt{ridx} = 0;"
1086+ r#"
1087+ const captureTable{ridx} = new Map();
1088+ let captureCnt{ridx} = 0;
1089+ "#
10931090 ) ;
10941091 self . resources_initialized . insert ( resource_idx, true ) ;
10951092 }
10961093 } else {
1094+ // non imported
10971095 let finalization_registry_create = self
10981096 . bindgen
10991097 . intrinsic ( Intrinsic :: FinalizationRegistryCreate ) ;
11001098 uwriteln ! (
11011099 self . src. js,
1102- "const handleTable{rtid} = [{rsc_table_flag}, 0];
1103- const finalizationRegistry{rtid} = {finalization_registry_create}((handle) => {{
1104- const {{ rep }} = {rsc_table_remove}(handleTable{rtid}, handle);{maybe_dtor}
1105- }});
1106- " ,
1100+ r#"
1101+ const handleTable{rtid} = [{rsc_table_flag}, 0];
1102+ handleTable{rtid}._tableID = {rtid};
1103+ handleTable{rtid}._createdReps = new Set();
1104+ const finalizationRegistry{rtid} = {finalization_registry_create}((handle) => {{
1105+ const {{ rep }} = {rsc_table_remove}(handleTable{rtid}, handle);{maybe_dtor}
1106+ }});
1107+ "# ,
11071108 ) ;
11081109 }
1110+
1111+ // Add the handle table to the global list
11091112 uwriteln ! ( self . src. js, "{handle_tables}[{rtid}] = handleTable{rtid};" ) ;
11101113 self . resource_tables_initialized
11111114 . insert ( resource_table_idx, true ) ;
0 commit comments