@@ -58,9 +58,9 @@ struct Transform<'a> {
58
58
// Indices of items that we have injected or found. This state is maintained
59
59
// during the pass execution.
60
60
table : TableId ,
61
- clone_ref : FunctionId ,
62
- heap_alloc : FunctionId ,
63
- heap_dealloc : FunctionId ,
61
+ clone_ref : Option < FunctionId > ,
62
+ heap_alloc : Option < FunctionId > ,
63
+ heap_dealloc : Option < FunctionId > ,
64
64
stack_pointer : GlobalId ,
65
65
}
66
66
@@ -185,33 +185,34 @@ impl Context {
185
185
_ => { }
186
186
}
187
187
}
188
- let heap_alloc = heap_alloc. ok_or_else ( || anyhow ! ( "failed to find heap alloc" ) ) ?;
189
- let heap_dealloc = heap_dealloc. ok_or_else ( || anyhow ! ( "failed to find heap dealloc" ) ) ?;
190
-
191
- // Create a shim function that looks like:
192
- //
193
- // (func __wbindgen_object_clone_ref (param i32) (result i32)
194
- // (local i32)
195
- // (table.set
196
- // (tee_local 1 (call $heap_alloc))
197
- // (table.get (local.get 0)))
198
- // (local.get 1))
199
- let mut builder =
200
- walrus:: FunctionBuilder :: new ( & mut module. types , & [ ValType :: I32 ] , & [ ValType :: I32 ] ) ;
201
- let arg = module. locals . add ( ValType :: I32 ) ;
202
- let local = module. locals . add ( ValType :: I32 ) ;
203
-
204
- let mut body = builder. func_body ( ) ;
205
- body. call ( heap_alloc)
206
- . local_tee ( local)
207
- . local_get ( arg)
208
- . table_get ( table)
209
- . table_set ( table)
210
- . local_get ( local) ;
211
-
212
- let clone_ref = builder. finish ( vec ! [ arg] , & mut module. funcs ) ;
213
- let name = "__wbindgen_object_clone_ref" . to_string ( ) ;
214
- module. funcs . get_mut ( clone_ref) . name = Some ( name) ;
188
+ let mut clone_ref = None ;
189
+ if let Some ( heap_alloc) = heap_alloc {
190
+ // Create a shim function that looks like:
191
+ //
192
+ // (func __wbindgen_object_clone_ref (param i32) (result i32)
193
+ // (local i32)
194
+ // (table.set
195
+ // (tee_local 1 (call $heap_alloc))
196
+ // (table.get (local.get 0)))
197
+ // (local.get 1))
198
+ let mut builder =
199
+ walrus:: FunctionBuilder :: new ( & mut module. types , & [ ValType :: I32 ] , & [ ValType :: I32 ] ) ;
200
+ let arg = module. locals . add ( ValType :: I32 ) ;
201
+ let local = module. locals . add ( ValType :: I32 ) ;
202
+
203
+ let mut body = builder. func_body ( ) ;
204
+ body. call ( heap_alloc)
205
+ . local_tee ( local)
206
+ . local_get ( arg)
207
+ . table_get ( table)
208
+ . table_set ( table)
209
+ . local_get ( local) ;
210
+
211
+ let func = builder. finish ( vec ! [ arg] , & mut module. funcs ) ;
212
+ let name = "__wbindgen_object_clone_ref" . to_string ( ) ;
213
+ module. funcs . get_mut ( func) . name = Some ( name) ;
214
+ clone_ref = Some ( func) ;
215
+ }
215
216
216
217
// And run the transformation!
217
218
Transform {
@@ -236,9 +237,9 @@ impl Transform<'_> {
236
237
self . find_intrinsics ( module) ?;
237
238
238
239
// Perform transformations of imports, exports, and function pointers.
239
- self . process_imports ( module) ;
240
+ self . process_imports ( module) ? ;
240
241
assert ! ( self . cx. imports. is_empty( ) ) ;
241
- self . process_exports ( module) ;
242
+ self . process_exports ( module) ? ;
242
243
assert ! ( self . cx. exports. is_empty( ) ) ;
243
244
self . process_elements ( module) ?;
244
245
assert ! ( self . cx. elements. is_empty( ) ) ;
@@ -251,7 +252,7 @@ impl Transform<'_> {
251
252
252
253
// Perform all instruction transformations to rewrite calls between
253
254
// functions and make sure everything is still hooked up right.
254
- self . rewrite_calls ( module) ;
255
+ self . rewrite_calls ( module) ? ;
255
256
256
257
Ok ( ( ) )
257
258
}
@@ -297,7 +298,22 @@ impl Transform<'_> {
297
298
Ok ( ( ) )
298
299
}
299
300
300
- fn process_imports ( & mut self , module : & mut Module ) {
301
+ fn heap_alloc ( & self ) -> Result < FunctionId , Error > {
302
+ self . heap_alloc
303
+ . ok_or_else ( || anyhow ! ( "failed to find the `__wbindgen_anyref_table_alloc` function" ) )
304
+ }
305
+
306
+ fn clone_ref ( & self ) -> Result < FunctionId , Error > {
307
+ self . clone_ref
308
+ . ok_or_else ( || anyhow ! ( "failed to find intrinsics to enable `clone_ref` function" ) )
309
+ }
310
+
311
+ fn heap_dealloc ( & self ) -> Result < FunctionId , Error > {
312
+ self . heap_dealloc
313
+ . ok_or_else ( || anyhow ! ( "failed to find the `__wbindgen_anyref_table_dealloc` function" ) )
314
+ }
315
+
316
+ fn process_imports ( & mut self , module : & mut Module ) -> Result < ( ) , Error > {
301
317
for import in module. imports . iter_mut ( ) {
302
318
let f = match import. kind {
303
319
walrus:: ImportKind :: Function ( f) => f,
@@ -315,16 +331,17 @@ impl Transform<'_> {
315
331
& mut module. types ,
316
332
& mut module. funcs ,
317
333
& mut module. locals ,
318
- ) ;
334
+ ) ? ;
319
335
self . import_map . insert ( f, shim) ;
320
336
match & mut module. funcs . get_mut ( f) . kind {
321
337
walrus:: FunctionKind :: Import ( f) => f. ty = anyref_ty,
322
338
_ => unreachable ! ( ) ,
323
339
}
324
340
}
341
+ Ok ( ( ) )
325
342
}
326
343
327
- fn process_exports ( & mut self , module : & mut Module ) {
344
+ fn process_exports ( & mut self , module : & mut Module ) -> Result < ( ) , Error > {
328
345
// let mut new_exports = Vec::new();
329
346
for export in module. exports . iter_mut ( ) {
330
347
let f = match export. item {
@@ -342,9 +359,10 @@ impl Transform<'_> {
342
359
& mut module. types ,
343
360
& mut module. funcs ,
344
361
& mut module. locals ,
345
- ) ;
362
+ ) ? ;
346
363
export. item = shim. into ( ) ;
347
364
}
365
+ Ok ( ( ) )
348
366
}
349
367
350
368
fn process_elements ( & mut self , module : & mut Module ) -> Result < ( ) , Error > {
@@ -372,7 +390,7 @@ impl Transform<'_> {
372
390
& mut module. types ,
373
391
& mut module. funcs ,
374
392
& mut module. locals ,
375
- ) ;
393
+ ) ? ;
376
394
kind. elements . push ( Some ( shim) ) ;
377
395
}
378
396
@@ -393,7 +411,7 @@ impl Transform<'_> {
393
411
types : & mut walrus:: ModuleTypes ,
394
412
funcs : & mut walrus:: ModuleFunctions ,
395
413
locals : & mut walrus:: ModuleLocals ,
396
- ) -> ( FunctionId , TypeId ) {
414
+ ) -> Result < ( FunctionId , TypeId ) , Error > {
397
415
let target = funcs. get_mut ( shim_target) ;
398
416
let ( is_export, ty) = match & target. kind {
399
417
walrus:: FunctionKind :: Import ( f) => ( false , f. ty ) ,
@@ -508,15 +526,15 @@ impl Transform<'_> {
508
526
body. local_get ( params[ i] )
509
527
. table_get ( self . table )
510
528
. local_get ( params[ i] )
511
- . call ( self . heap_dealloc ) ;
529
+ . call ( self . heap_dealloc ( ) ? ) ;
512
530
}
513
531
Convert :: Load { owned : false } => {
514
532
body. local_get ( params[ i] ) . table_get ( self . table ) ;
515
533
}
516
534
Convert :: Store { owned : true } => {
517
535
// Allocate space for the anyref, store it, and then leave
518
536
// the index of the allocated anyref on the stack.
519
- body. call ( self . heap_alloc )
537
+ body. call ( self . heap_alloc ( ) ? )
520
538
. local_tee ( scratch_i32)
521
539
. local_get ( params[ i] )
522
540
. table_set ( self . table )
@@ -559,13 +577,13 @@ impl Transform<'_> {
559
577
body. local_tee ( scratch_i32)
560
578
. table_get ( self . table )
561
579
. local_get ( scratch_i32)
562
- . call ( self . heap_dealloc ) ;
580
+ . call ( self . heap_dealloc ( ) ? ) ;
563
581
} else {
564
582
// Imports are the opposite, we have any anyref on the stack
565
583
// and convert it to an i32 by allocating space for it and
566
584
// storing it there.
567
585
body. local_set ( scratch_anyref)
568
- . call ( self . heap_alloc )
586
+ . call ( self . heap_alloc ( ) ? )
569
587
. local_tee ( scratch_i32)
570
588
. local_get ( scratch_anyref)
571
589
. table_set ( self . table )
@@ -604,20 +622,32 @@ impl Transform<'_> {
604
622
let name = format ! ( "{}_anyref_shim" , name) ;
605
623
funcs. get_mut ( id) . name = Some ( name) ;
606
624
self . shims . insert ( id) ;
607
- ( id, anyref_ty)
625
+ Ok ( ( id, anyref_ty) )
608
626
}
609
627
610
- fn rewrite_calls ( & mut self , module : & mut Module ) {
628
+ fn rewrite_calls ( & mut self , module : & mut Module ) -> Result < ( ) , Error > {
611
629
for ( id, func) in module. funcs . iter_local_mut ( ) {
612
630
if self . shims . contains ( & id) {
613
631
continue ;
614
632
}
615
633
let entry = func. entry_block ( ) ;
616
- dfs_pre_order_mut ( & mut Rewrite { xform : self } , func, entry) ;
634
+ dfs_pre_order_mut (
635
+ & mut Rewrite {
636
+ clone_ref : self . clone_ref ( ) ?,
637
+ heap_dealloc : self . heap_dealloc ( ) ?,
638
+ xform : self ,
639
+ } ,
640
+ func,
641
+ entry,
642
+ ) ;
617
643
}
618
644
645
+ return Ok ( ( ) ) ;
646
+
619
647
struct Rewrite < ' a , ' b > {
620
648
xform : & ' a Transform < ' b > ,
649
+ clone_ref : FunctionId ,
650
+ heap_dealloc : FunctionId ,
621
651
}
622
652
623
653
impl VisitorMut for Rewrite < ' _ , ' _ > {
@@ -664,8 +694,8 @@ impl Transform<'_> {
664
694
seq. instrs
665
695
. insert ( i, ( RefNull { } . into ( ) , InstrLocId :: default ( ) ) ) ;
666
696
}
667
- Intrinsic :: DropRef => call. func = self . xform . heap_dealloc ,
668
- Intrinsic :: CloneRef => call. func = self . xform . clone_ref ,
697
+ Intrinsic :: DropRef => call. func = self . heap_dealloc ,
698
+ Intrinsic :: CloneRef => call. func = self . clone_ref ,
669
699
}
670
700
}
671
701
}
0 commit comments