@@ -20,6 +20,7 @@ use std::cmp;
20
20
use std:: collections:: { BTreeMap , HashMap , HashSet } ;
21
21
use std:: mem;
22
22
use walrus:: ir:: * ;
23
+ use walrus:: { ExportId , ImportId } ;
23
24
use walrus:: { FunctionId , GlobalId , InitExpr , Module , TableId , ValType } ;
24
25
25
26
// must be kept in sync with src/lib.rs and ANYREF_HEAP_START
@@ -32,8 +33,8 @@ pub struct Context {
32
33
// Functions within the module that we're gonna be wrapping, organized by
33
34
// type. The `Function` contains information about what arguments/return
34
35
// values in the function signature should turn into anyref.
35
- imports : HashMap < String , HashMap < String , Function > > ,
36
- exports : HashMap < String , Function > ,
36
+ imports : HashMap < ImportId , Function > ,
37
+ exports : HashMap < ExportId , Function > ,
37
38
elements : BTreeMap < u32 , ( u32 , Function ) > ,
38
39
39
40
// When wrapping closures with new shims, this is the index of the next
@@ -42,9 +43,6 @@ pub struct Context {
42
43
43
44
// The anyref table we'll be using, injected after construction
44
45
table : Option < TableId > ,
45
-
46
- // Whether or not the transformation will actually be run at the end
47
- pub enabled : bool ,
48
46
}
49
47
50
48
struct Transform < ' a > {
@@ -68,7 +66,6 @@ struct Transform<'a> {
68
66
}
69
67
70
68
struct Function {
71
- name : String ,
72
69
// A map of argument index to whether it's an owned or borrowed anyref
73
70
// (owned = true)
74
71
args : HashMap < usize , bool > ,
@@ -87,10 +84,6 @@ impl Context {
87
84
/// large the function table is so we know what indexes to hand out when
88
85
/// we're appending entries.
89
86
pub fn prepare ( & mut self , module : & mut Module ) -> Result < ( ) , Error > {
90
- if !self . enabled {
91
- return Ok ( ( ) ) ;
92
- }
93
-
94
87
// Figure out what the maximum index of functions pointers are. We'll
95
88
// be adding new entries to the function table later (maybe) so
96
89
// precalculate this ahead of time.
@@ -118,35 +111,27 @@ impl Context {
118
111
/// transformed. The actual transformation happens later during `run`.
119
112
pub fn import_xform (
120
113
& mut self ,
121
- module : & str ,
122
- name : & str ,
114
+ id : ImportId ,
123
115
anyref : & [ ( usize , bool ) ] ,
124
116
ret_anyref : bool ,
125
117
) -> & mut Self {
126
- if ! self . enabled {
127
- return self ;
118
+ if let Some ( f ) = self . function ( anyref , ret_anyref ) {
119
+ self . imports . insert ( id , f ) ;
128
120
}
129
- let f = self . function ( name, anyref, ret_anyref) ;
130
- self . imports
131
- . entry ( module. to_string ( ) )
132
- . or_insert_with ( Default :: default)
133
- . insert ( name. to_string ( ) , f) ;
134
121
self
135
122
}
136
123
137
124
/// Store information about an exported function that needs to be
138
125
/// transformed. The actual transformation happens later during `run`.
139
126
pub fn export_xform (
140
127
& mut self ,
141
- name : & str ,
128
+ id : ExportId ,
142
129
anyref : & [ ( usize , bool ) ] ,
143
130
ret_anyref : bool ,
144
131
) -> & mut Self {
145
- if ! self . enabled {
146
- return self ;
132
+ if let Some ( f ) = self . function ( anyref , ret_anyref ) {
133
+ self . exports . insert ( id , f ) ;
147
134
}
148
- let f = self . function ( name, anyref, ret_anyref) ;
149
- self . exports . insert ( name. to_string ( ) , f) ;
150
135
self
151
136
}
152
137
@@ -158,34 +143,26 @@ impl Context {
158
143
idx : u32 ,
159
144
anyref : & [ ( usize , bool ) ] ,
160
145
ret_anyref : bool ,
161
- ) -> u32 {
162
- if !self . enabled {
163
- return idx;
164
- }
165
- let name = format ! ( "closure{}" , idx) ;
166
- let f = self . function ( & name, anyref, ret_anyref) ;
167
- let ret = self . next_element ;
168
- self . next_element += 1 ;
169
- self . elements . insert ( ret, ( idx, f) ) ;
170
- ret
146
+ ) -> Option < u32 > {
147
+ self . function ( anyref, ret_anyref) . map ( |f| {
148
+ let ret = self . next_element ;
149
+ self . next_element += 1 ;
150
+ self . elements . insert ( ret, ( idx, f) ) ;
151
+ ret
152
+ } )
171
153
}
172
154
173
- fn function ( & self , name : & str , anyref : & [ ( usize , bool ) ] , ret_anyref : bool ) -> Function {
174
- Function {
175
- name : name. to_string ( ) ,
155
+ fn function ( & self , anyref : & [ ( usize , bool ) ] , ret_anyref : bool ) -> Option < Function > {
156
+ if !ret_anyref && anyref. len ( ) == 0 {
157
+ return None ;
158
+ }
159
+ Some ( Function {
176
160
args : anyref. iter ( ) . cloned ( ) . collect ( ) ,
177
161
ret_anyref,
178
- }
179
- }
180
-
181
- pub fn anyref_table_id ( & self ) -> TableId {
182
- self . table . unwrap ( )
162
+ } )
183
163
}
184
164
185
165
pub fn run ( & mut self , module : & mut Module ) -> Result < ( ) , Error > {
186
- if !self . enabled {
187
- return Ok ( ( ) ) ;
188
- }
189
166
let table = self . table . unwrap ( ) ;
190
167
191
168
// Inject a stack pointer global which will be used for managing the
@@ -261,9 +238,7 @@ impl Transform<'_> {
261
238
262
239
// Perform transformations of imports, exports, and function pointers.
263
240
self . process_imports ( module) ;
264
- for m in self . cx . imports . values ( ) {
265
- assert ! ( m. is_empty( ) ) ;
266
- }
241
+ assert ! ( self . cx. imports. is_empty( ) ) ;
267
242
self . process_exports ( module) ;
268
243
assert ! ( self . cx. exports. is_empty( ) ) ;
269
244
self . process_elements ( module) ?;
@@ -333,20 +308,15 @@ impl Transform<'_> {
333
308
walrus:: ImportKind :: Function ( f) => f,
334
309
_ => continue ,
335
310
} ;
336
- let import = {
337
- let entries = match self . cx . imports . get_mut ( & import. module ) {
338
- Some ( s) => s,
339
- None => continue ,
340
- } ;
341
- match entries. remove ( & import. name ) {
342
- Some ( s) => s,
343
- None => continue ,
344
- }
311
+ let func = match self . cx . imports . remove ( & import. id ( ) ) {
312
+ Some ( s) => s,
313
+ None => continue ,
345
314
} ;
346
315
347
316
let shim = self . append_shim (
348
317
f,
349
- import,
318
+ & import. name ,
319
+ func,
350
320
& mut module. types ,
351
321
& mut module. funcs ,
352
322
& mut module. locals ,
@@ -356,29 +326,25 @@ impl Transform<'_> {
356
326
}
357
327
358
328
fn process_exports ( & mut self , module : & mut Module ) {
359
- let mut new_exports = Vec :: new ( ) ;
360
- for export in module. exports . iter ( ) {
329
+ // let mut new_exports = Vec::new();
330
+ for export in module. exports . iter_mut ( ) {
361
331
let f = match export. item {
362
332
walrus:: ExportItem :: Function ( f) => f,
363
333
_ => continue ,
364
334
} ;
365
- let function = match self . cx . exports . remove ( & export. name ) {
335
+ let function = match self . cx . exports . remove ( & export. id ( ) ) {
366
336
Some ( s) => s,
367
337
None => continue ,
368
338
} ;
369
339
let shim = self . append_shim (
370
340
f,
341
+ & export. name ,
371
342
function,
372
343
& mut module. types ,
373
344
& mut module. funcs ,
374
345
& mut module. locals ,
375
346
) ;
376
- new_exports. push ( ( export. name . to_string ( ) , shim, export. id ( ) ) ) ;
377
- }
378
-
379
- for ( name, shim, old_id) in new_exports {
380
- module. exports . add ( & name, shim) ;
381
- module. exports . delete ( old_id) ;
347
+ export. item = shim. into ( ) ;
382
348
}
383
349
}
384
350
@@ -402,6 +368,7 @@ impl Transform<'_> {
402
368
let target = kind. elements [ idx as usize ] . unwrap ( ) ;
403
369
let shim = self . append_shim (
404
370
target,
371
+ & format ! ( "closure{}" , idx) ,
405
372
function,
406
373
& mut module. types ,
407
374
& mut module. funcs ,
@@ -422,6 +389,7 @@ impl Transform<'_> {
422
389
fn append_shim (
423
390
& mut self ,
424
391
shim_target : FunctionId ,
392
+ name : & str ,
425
393
mut func : Function ,
426
394
types : & mut walrus:: ModuleTypes ,
427
395
funcs : & mut walrus:: ModuleFunctions ,
@@ -625,7 +593,7 @@ impl Transform<'_> {
625
593
// nice name for debugging and then we're good to go!
626
594
let expr = builder. with_side_effects ( before, result, after) ;
627
595
let id = builder. finish_parts ( shim_ty, params, vec ! [ expr] , types, funcs) ;
628
- let name = format ! ( "{}_anyref_shim" , func . name) ;
596
+ let name = format ! ( "{}_anyref_shim" , name) ;
629
597
funcs. get_mut ( id) . name = Some ( name) ;
630
598
self . shims . insert ( id) ;
631
599
return id;
0 commit comments