Skip to content

Commit 8e5a806

Browse files
refactor(bindgen): move resouce scope tracking
1 parent 39e6972 commit 8e5a806

4 files changed

Lines changed: 46 additions & 45 deletions

File tree

crates/js-component-bindgen/src/function_bindgen.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1467,6 +1467,33 @@ impl Bindgen for FunctionBindgen<'_> {
14671467
uwriteln!(self.src, "const started = task.enterSync();",);
14681468
}
14691469

1470+
// Set up resource scope tracking, if we're in a resource call
1471+
if self.callee_resource_dynamic {
1472+
let resource_borrows =
1473+
self.intrinsic(Intrinsic::Resource(ResourceIntrinsic::ResourceCallBorrows));
1474+
let handle_tables = self.intrinsic(Intrinsic::HandleTables);
1475+
let scope_id = self.intrinsic(Intrinsic::ScopeId);
1476+
uwriteln!(
1477+
self.src,
1478+
r#"
1479+
{scope_id}++;
1480+
task.registerOnResolveHandler(() => {{
1481+
{scope_id}--;
1482+
for (const {{ rid, handle }} of {resource_borrows}) {{
1483+
const storedScopeId = {handle_tables}[rid][handle << 1]
1484+
if (storedScopeId === {scope_id}) {{
1485+
throw new TypeError('borrows not dropped for resource call');
1486+
}}
1487+
}}
1488+
{resource_borrows} = [];
1489+
}}
1490+
1491+
}});
1492+
"#
1493+
);
1494+
uwriteln!(self.src, "{scope_id}++;");
1495+
}
1496+
14701497
// Save the memory for this task,
14711498
// which will be used for any subtasks that might be spawned
14721499
if let Some(mem_idx) = self.canon_opts.memory() {

crates/js-component-bindgen/src/intrinsics/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1066,7 +1066,7 @@ pub struct RenderIntrinsicsArgs<'a> {
10661066
}
10671067

10681068
/// Intrinsics that should be rendered as early as possible
1069-
const EARLY_INTRINSICS: [Intrinsic; 36] = [
1069+
const EARLY_INTRINSICS: [Intrinsic; 37] = [
10701070
Intrinsic::PromiseWithResolversPonyfill,
10711071
Intrinsic::SymbolDispose,
10721072
Intrinsic::SymbolAsyncIterator,
@@ -1092,6 +1092,8 @@ const EARLY_INTRINSICS: [Intrinsic; 36] = [
10921092
Intrinsic::Conversion(ConversionIntrinsic::RequireValidNumericPrimitive),
10931093
Intrinsic::TypeCheckValidI32,
10941094
Intrinsic::TypeCheckAsyncFn,
1095+
// Resources
1096+
Intrinsic::Resource(ResourceIntrinsic::ResourceCallBorrows),
10951097
// Async helpers
10961098
Intrinsic::AsyncFunctionCtor,
10971099
Intrinsic::AsyncTask(AsyncTaskIntrinsic::ClearCurrentTask),

crates/js-component-bindgen/src/intrinsics/resource.rs

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -72,23 +72,24 @@ impl ResourceIntrinsic {
7272
/// Retrieve global names for
7373
pub fn get_global_names() -> impl IntoIterator<Item = &'static str> {
7474
[
75-
"resourceCallBorrows",
76-
"resourceTransferBorrow",
77-
"resourceTransferBorrowValidLifting",
78-
"resourceTransferOwn",
79-
"rscTableCreateBorrow",
80-
"rscTableCreateOwn",
81-
"rscTableGet",
82-
"rscTableRemove",
83-
"rscTableTryGet",
84-
"curResourceBorrows",
75+
Self::ResourceCallBorrows.name(),
76+
Self::ResourceTableFlag.name(),
77+
Self::ResourceTableCreateBorrow.name(),
78+
Self::ResourceTableCreateOwn.name(),
79+
Self::ResourceTableGet.name(),
80+
Self::ResourceTableEnsureBorrowDrop.name(),
81+
Self::ResourceTableRemove.name(),
82+
Self::ResourceTransferBorrow.name(),
83+
Self::ResourceTransferBorrowValidLifting.name(),
84+
Self::ResourceTransferOwn.name(),
85+
Self::CurResourceBorrows.name(),
8586
]
8687
}
8788

8889
/// Get the name for the intrinsic
8990
pub fn name(&self) -> &'static str {
9091
match self {
91-
Self::ResourceCallBorrows => "resourceCallBorrows",
92+
Self::ResourceCallBorrows => "RESOURCE_CALL_BORROWS",
9293
Self::ResourceTableFlag => "T_FLAG",
9394
Self::ResourceTableCreateBorrow => "rscTableCreateBorrow",
9495
Self::ResourceTableCreateOwn => "rscTableCreateOwn",
@@ -247,7 +248,10 @@ impl ResourceIntrinsic {
247248
"));
248249
}
249250

250-
Self::ResourceCallBorrows => output.push_str("let resourceCallBorrows = [];"),
251+
Self::ResourceCallBorrows => {
252+
let name = self.name();
253+
output.push_str(&format!("let {name} = [];"));
254+
}
251255
}
252256
}
253257
}

crates/js-component-bindgen/src/transpile_bindgen.rs

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2316,38 +2316,6 @@ impl<'a> Instantiator<'a, '_> {
23162316
uwriteln!(self.src.js, "const trampoline{i} = {resource_transfer};");
23172317
}
23182318

2319-
// TODO: we need to do this? does this mean we need to start keeping track of when we
2320-
// enter a call on a resource explicitly?
2321-
2322-
// Trampoline::ResourceEnterCall => {
2323-
// let scope_id = self.bindgen.intrinsic(Intrinsic::ScopeId);
2324-
// uwrite!(self.src.js, "function trampoline{i}() {{ {scope_id}++; }}");
2325-
// }
2326-
2327-
// Trampoline::ResourceExitCall => {
2328-
// let scope_id = self.bindgen.intrinsic(Intrinsic::ScopeId);
2329-
// let resource_borrows = self
2330-
// .bindgen
2331-
// .intrinsic(Intrinsic::Resource(ResourceIntrinsic::ResourceCallBorrows));
2332-
// let handle_tables = self.bindgen.intrinsic(Intrinsic::HandleTables);
2333-
// // To verify that borrows are dropped, it is enough to verify that the handle
2334-
// // either no longer exists (part of free list) or belongs to another scope, since
2335-
// // the enter call closed off the ability to create new handles in the parent scope
2336-
// uwrite!(
2337-
// self.src.js,
2338-
// r#"function trampoline{i}() {{
2339-
// {scope_id}--;
2340-
// for (const {{ rid, handle }} of {resource_borrows}) {{
2341-
// const storedScopeId = {handle_tables}[rid][handle << 1]
2342-
// if (storedScopeId === {scope_id}) {{
2343-
// throw new TypeError('borrows not dropped for resource call');
2344-
// }}
2345-
// }}
2346-
// {resource_borrows} = [];
2347-
// }}
2348-
// "#,
2349-
// );
2350-
// }
23512319
Trampoline::ContextSet { instance, slot, .. } => {
23522320
let context_set_fn = self
23532321
.bindgen

0 commit comments

Comments
 (0)