@@ -2203,21 +2203,28 @@ impl Bindgen for FunctionBindgen<'_> {
22032203 } => {
22042204 let tid = tid. as_u32 ( ) ;
22052205 let rid = rid. as_u32 ( ) ;
2206- if !imported {
2207- if is_own {
2206+
2207+ match ( imported, is_own) {
2208+ // Imported, owned host-provided resource
2209+ ( _imported @ false , _owned @ true ) => {
22082210 let empty_func = self
22092211 . intrinsic ( Intrinsic :: JsHelper ( JsHelperIntrinsic :: EmptyFunc ) ) ;
22102212 uwriteln ! (
2211- self . src,
2212- "var {handle} = {op}[{symbol_resource_handle}];
2213- if (!{handle}) {{
2214- throw new TypeError('Resource error: Not a valid \" {class_name}\" resource.');
2215- }}
2216- finalizationRegistry{tid}.unregister({op});
2217- {op}[{symbol_dispose}] = {empty_func};
2218- {op}[{symbol_resource_handle}] = undefined;" ,
2219- ) ;
2220- } else {
2213+ self . src,
2214+ r#"
2215+ var {handle} = {op}[{symbol_resource_handle}];
2216+ if (!{handle}) {{
2217+ throw new TypeError('Resource error: Not a valid \"{class_name}\" resource.');
2218+ }}
2219+ finalizationRegistry{tid}.unregister({op});
2220+ {op}[{symbol_dispose}] = {empty_func};
2221+ {op}[{symbol_resource_handle}] = undefined;
2222+ "# ,
2223+ ) ;
2224+ }
2225+
2226+ // Imported, borrowed host-provdied resource
2227+ ( _imported @ false , _owned @ false ) => {
22212228 // When expecting a borrow, the JS resource provided will always be an own
22222229 // handle. This is because it is not possible for borrow handles to be passed
22232230 // back reentrantly.
@@ -2226,54 +2233,87 @@ impl Bindgen for FunctionBindgen<'_> {
22262233 ResourceIntrinsic :: ResourceTableFlag ,
22272234 ) ) ;
22282235 let own_handle = format ! ( "handle{}" , self . tmp( ) ) ;
2229- uwriteln ! ( self . src,
2230- "var {own_handle} = {op}[{symbol_resource_handle}];
2231- if (!{own_handle} || (handleTable{tid}[({own_handle} << 1) + 1] & {rsc_flag}) === 0) {{
2232- throw new TypeError('Resource error: Not a valid \" {class_name}\" resource.');
2233- }}
2234- var {handle} = handleTable{tid}[({own_handle} << 1) + 1] & ~{rsc_flag};" ,
2235- ) ;
2236+ uwriteln ! (
2237+ self . src,
2238+ r#"
2239+ var {own_handle} = {op}[{symbol_resource_handle}];
2240+ if (!{own_handle} || (handleTable{tid}[({own_handle} << 1) + 1] & {rsc_flag}) === 0) {{
2241+ throw new TypeError('Resource error: Not a valid \"{class_name}\" resource.');
2242+ }}
2243+ var {handle} = handleTable{tid}[({own_handle} << 1) + 1] & ~{rsc_flag};
2244+ "# ,
2245+ ) ;
22362246 }
2237- } else {
2238- // Imported resources may already have a handle if they were constructed
2239- // by a component and then passed out.
2240- uwriteln ! (
2241- self . src,
2242- "if (!({op} instanceof {local_name})) {{
2243- throw new TypeError('Resource error: Not a valid \" {class_name}\" resource.');
2244- }}
2245- var {handle} = {op}[{symbol_resource_handle}];" ,
2246- ) ;
2247- // Otherwise, in hybrid bindgen we check for a Symbol.for('cabiRep')
2248- // to get the resource rep.
2249- // Fall back to assign a new rep in the capture table, when the imported
2250- // resource was constructed externally.
2251- let symbol_resource_rep = self . intrinsic ( Intrinsic :: SymbolResourceRep ) ;
2252-
2253- // Build the code to initialize the owned/borrowed resource handle
2254- let handle_init_js = if is_own {
2247+
2248+ // Imported, owned guest-provided resource
2249+ ( _imported @ true , _owned @ true ) => {
2250+ // Imported resources may already have a handle if they were constructed
2251+ // by a component and then passed out.
2252+ //
2253+ // If the handle is not present, in hybrid bindgen we check for a Symbol.for('cabiRep')
2254+ // to get the resource rep.
2255+ //
2256+ // Fall back to assign a new rep in the capture table, when the imported
2257+ // resource was constructed externally.
2258+ let symbol_resource_rep =
2259+ self . intrinsic ( Intrinsic :: SymbolResourceRep ) ;
22552260 let create_own_fn = self . intrinsic ( Intrinsic :: Resource (
22562261 ResourceIntrinsic :: ResourceTableCreateOwn ,
22572262 ) ) ;
2258- format ! ( "{handle} = {create_own_fn}(handleTable{tid}, rep);" )
2259- } else {
2263+
2264+ uwriteln ! (
2265+ self . src,
2266+ r#"
2267+ if (!({op} instanceof {local_name})) {{
2268+ throw new TypeError('Resource error: Not a valid \"{class_name}\" resource.');
2269+ }}
2270+ var {handle} = {op}[{symbol_resource_handle}];
2271+ if (!{handle}) {{
2272+ const rep = {op}[{symbol_resource_rep}] || ++captureCnt{rid};
2273+ captureTable{rid}.set(rep, {op});
2274+ {create_own_fn}(handleTable{tid}, rep);
2275+ }}
2276+ "#
2277+ ) ;
2278+ }
2279+
2280+ // Imported, borrowed guest-provided resource
2281+ ( _imported @ true , _owned @ false ) => {
2282+ // Imported resources may already have a handle if they were constructed
2283+ // by a component and then passed out.
2284+ uwriteln ! (
2285+ self . src,
2286+ r#"
2287+ if (!({op} instanceof {local_name})) {{
2288+ throw new TypeError('Resource error: Not a valid \"{class_name}\" resource.');
2289+ }}
2290+ var {handle} = {op}[{symbol_resource_handle}];
2291+ "# ,
2292+ ) ;
2293+ // Otherwise, in hybrid bindgen we check for a Symbol.for('cabiRep')
2294+ // to get the resource rep.
2295+ // Fall back to assign a new rep in the capture table, when the imported
2296+ // resource was constructed externally.
2297+ let symbol_resource_rep =
2298+ self . intrinsic ( Intrinsic :: SymbolResourceRep ) ;
2299+
22602300 let scope_id = self . intrinsic ( Intrinsic :: ScopeId ) ;
22612301 let create_borrow_fn = self . intrinsic ( Intrinsic :: Resource (
22622302 ResourceIntrinsic :: ResourceTableCreateBorrow ,
22632303 ) ) ;
2264- format ! (
2304+ let handle_init_js = format ! (
22652305 "{handle} = {create_borrow_fn}(handleTable{tid}, rep, {scope_id});"
2266- )
2267- } ;
2306+ ) ;
22682307
2269- uwriteln ! (
2270- self . src,
2271- "if (!{handle}) {{
2308+ uwriteln ! (
2309+ self . src,
2310+ "if (!{handle}) {{
22722311 const rep = {op}[{symbol_resource_rep}] || ++captureCnt{rid};
22732312 captureTable{rid}.set(rep, {op});
22742313 {handle_init_js}
22752314 }}"
2276- ) ;
2315+ ) ;
2316+ }
22772317 }
22782318 }
22792319
@@ -2291,48 +2331,61 @@ impl Bindgen for FunctionBindgen<'_> {
22912331 let lower_camel = resource_name. to_lower_camel_case ( ) ;
22922332 let prefix = prefix. as_deref ( ) . unwrap_or ( "" ) ;
22932333
2294- if !imported {
2295- let local_rep = format ! ( "localRep{}" , self . tmp( ) ) ;
2296- uwriteln ! (
2297- self . src,
2298- "if (!({op} instanceof {upper_camel})) {{
2299- throw new TypeError('Resource error: Not a valid \" {upper_camel}\" resource.');
2300- }}
2301- let {handle} = {op}[{symbol_resource_handle}];" ,
2302- ) ;
2334+ let symbol_resource_handle =
2335+ self . intrinsic ( Intrinsic :: SymbolResourceHandle ) ;
23032336
2304- if is_own {
2337+ let tmp = self . tmp ( ) ;
2338+ match ( imported, is_own) {
2339+ // imported owned/borrowed guest resource
2340+ ( _imported @ true , _owned @ _) => {
2341+ uwrite ! (
2342+ self . src,
2343+ r#"
2344+ var {handle} = {op}[{symbol_resource_handle}];
2345+ finalizationRegistry_import${prefix}{lower_camel}.unregister({op});
2346+ "#
2347+ ) ;
2348+ }
2349+
2350+ // Not-imported, borrowed guest resource
2351+ ( _imported @ false , _owned @ false ) => {
2352+ let local_rep = format ! ( "localRep{tmp}" ) ;
23052353 uwriteln ! (
2306- self . src,
2307- "if ({handle} === undefined) {{
2308- var {local_rep} = repCnt++;
2309- repTable.set({local_rep}, {{ rep: {op}, own: true }});
2310- {handle} = $resource_{prefix}new${lower_camel}({local_rep});
2311- {op}[{symbol_resource_handle}] = {handle};
2312- finalizationRegistry_export${prefix}{lower_camel}.register({op}, {handle}, {op});
2313- }}
2314- "
2315- ) ;
2316- } else {
2354+ self . src,
2355+ r#"
2356+ if (!({op} instanceof {upper_camel})) {{
2357+ throw new TypeError('Resource error: Not a valid \"{upper_camel}\" resource.');
2358+ }}
2359+ let {handle} = {op}[{symbol_resource_handle}];
2360+ if ({handle} === undefined) {{
2361+ var {local_rep} = repCnt++;
2362+ repTable.set({local_rep}, {{ rep: {op}, own: false }});
2363+ {op}[{symbol_resource_handle}] = {local_rep};
2364+ }}
2365+ "#
2366+ ) ;
2367+ }
2368+
2369+ // Not-imported, owned guest resource
2370+ ( _imported @ false , _owned @ true ) => {
2371+ let local_rep = format ! ( "localRep{tmp}" ) ;
23172372 uwriteln ! (
23182373 self . src,
2319- "if ({handle} === undefined) {{
2320- var {local_rep} = repCnt++;
2321- repTable.set({local_rep}, {{ rep: {op}, own: false }});
2322- {op}[{symbol_resource_handle}] = {local_rep};
2323- }}
2324- "
2374+ r#"
2375+ if (!({op} instanceof {upper_camel})) {{
2376+ throw new TypeError('Resource error: Not a valid \"{upper_camel}\" resource.');
2377+ }}
2378+ let {handle} = {op}[{symbol_resource_handle}];
2379+ if ({handle} === undefined) {{
2380+ var {local_rep} = repCnt++;
2381+ repTable.set({local_rep}, {{ rep: {op}, own: true }});
2382+ {handle} = $resource_{prefix}new${lower_camel}({local_rep});
2383+ {op}[{symbol_resource_handle}] = {handle};
2384+ finalizationRegistry_export${prefix}{lower_camel}.register({op}, {handle}, {op});
2385+ }}
2386+ "#
23252387 ) ;
23262388 }
2327- } else {
2328- let symbol_resource_handle =
2329- self . intrinsic ( Intrinsic :: SymbolResourceHandle ) ;
2330- uwrite ! (
2331- self . src,
2332- "var {handle} = {op}[{symbol_resource_handle}];
2333- finalizationRegistry_import${prefix}{lower_camel}.unregister({op});
2334- "
2335- ) ;
23362389 }
23372390 }
23382391 }
0 commit comments