@@ -243,7 +243,7 @@ impl<'a> Context<'a> {
243
243
ExportJs :: Function ( function) => {
244
244
let body = function. strip_prefix ( "function" ) . unwrap ( ) ;
245
245
if export_name == definition_name {
246
- format ! ( "Module.{} = function{}\n " , export_name, body)
246
+ format ! ( "Module.{} = function{}; \n " , export_name, body)
247
247
} else {
248
248
format ! (
249
249
"function {}{}\n export {{ {} as {} }};\n " ,
@@ -667,8 +667,6 @@ __wbg_set_wasm(wasm);"
667
667
push_with_newline ( "var LibraryWbg = {\n " ) ;
668
668
push_with_newline ( & self . emscripten_library ) ;
669
669
push_with_newline ( & init_js) ;
670
- push_with_newline ( "$initBindgen__deps: ['$addOnInit']," ) ;
671
- push_with_newline ( "$initBindgen__postset: 'addOnInit(initBindgen);'," ) ;
672
670
push_with_newline (
673
671
"$initBindgen: () => {\n
674
672
wasmExports.__wbindgen_start();" ,
@@ -987,7 +985,31 @@ __wbg_set_wasm(wasm);"
987
985
}
988
986
989
987
let js = match & self . config . mode {
990
- OutputMode :: Emscripten => imports_init. to_string ( ) ,
988
+ OutputMode :: Emscripten => {
989
+ let mut global_emscripten_initializer: String = Default :: default ( ) ;
990
+ for global_dep in self . emscripten_deps . iter ( ) {
991
+ let mut global = "" ;
992
+ if global_dep == "'$WASM_VECTOR_LEN'" {
993
+ global = "$WASM_VECTOR_LEN: '0'," ;
994
+ } else if global_dep == "'$TextEncoder'" {
995
+ global = "$textEncoder: \" new TextEncoder()\" ," ;
996
+ }
997
+
998
+ if global != "" {
999
+ global_emscripten_initializer = format ! (
1000
+ "{}{}\n " ,
1001
+ global_emscripten_initializer, global
1002
+ ) ;
1003
+ }
1004
+ }
1005
+ format ! (
1006
+ "\
1007
+ {}
1008
+ {}
1009
+ $initBindgen__deps: ['$addOnInit'],
1010
+ $initBindgen__postset: 'addOnInit(initBindgen);',
1011
+ " , imports_init. to_string( ) , global_emscripten_initializer
1012
+ ) }
991
1013
_ => format ! (
992
1014
"\
993
1015
async function __wbg_load(module, imports) {{
@@ -1520,15 +1542,25 @@ __wbg_set_wasm(wasm);"
1520
1542
) ;
1521
1543
}
1522
1544
1523
- fn expose_wasm_vector_len ( & mut self ) {
1545
+ fn expose_wasm_vector_len ( & mut self , import_deps : & mut HashSet < String > ) {
1546
+ import_deps. insert ( "'$WASM_VECTOR_LEN'" . to_string ( ) ) ;
1524
1547
if !self . should_write_global ( "wasm_vector_len" ) {
1525
1548
return ;
1526
1549
}
1527
- self . global ( "let WASM_VECTOR_LEN = 0;" ) ;
1550
+ if matches ! ( self . config. mode, OutputMode :: Emscripten ) {
1551
+ self . emscripten_deps
1552
+ . insert ( "'$WASM_VECTOR_LEN'" . to_string ( ) ) ;
1553
+ } else {
1554
+ self . global ( "let WASM_VECTOR_LEN = 0;" ) ;
1555
+ }
1528
1556
}
1529
1557
1530
- fn expose_pass_string_to_wasm ( & mut self , memory : MemoryId ) -> Result < MemView , Error > {
1531
- self . expose_wasm_vector_len ( ) ;
1558
+ fn expose_pass_string_to_wasm (
1559
+ & mut self ,
1560
+ memory : MemoryId ,
1561
+ import_deps : & mut HashSet < String > ,
1562
+ ) -> Result < MemView , Error > {
1563
+ self . expose_wasm_vector_len ( import_deps) ;
1532
1564
1533
1565
let debug = if self . config . debug {
1534
1566
"
@@ -1548,55 +1580,101 @@ __wbg_set_wasm(wasm);"
1548
1580
}
1549
1581
self . expose_text_encoder ( ) ?;
1550
1582
1583
+ let mut text_encoder = "cachedTextEncoder" ;
1584
+ let mut mem_formatted = format ! ( "{mem}()" ) ;
1585
+ if matches ! ( self . config. mode, OutputMode :: Emscripten ) {
1586
+ text_encoder = "textEncoder" ;
1587
+ mem_formatted = "HEAP8" . to_string ( ) ;
1588
+ } ;
1551
1589
// The first implementation we have for this is to use
1552
1590
// `TextEncoder#encode` which has been around for quite some time.
1553
- let encode = "function (arg, view) {
1554
- const buf = cachedTextEncoder.encode(arg);
1591
+ let encode = format ! (
1592
+ "function (arg, view) {{
1593
+ const buf = {text_encoder}.encode(arg);
1555
1594
view.set(buf);
1556
- return {
1595
+ return {{
1557
1596
read: arg.length,
1558
1597
written: buf.length
1559
- };
1560
- }" ;
1598
+ }};
1599
+ }}"
1600
+ ) ;
1561
1601
1562
1602
// Another possibility is to use `TextEncoder#encodeInto` which is much
1563
1603
// newer and isn't implemented everywhere yet. It's more efficient,
1564
1604
// however, because it allows us to elide an intermediate allocation.
1565
- let encode_into = "function (arg, view) {
1566
- return cachedTextEncoder.encodeInto(arg, view);
1567
- }" ;
1605
+ let encode_into = format ! (
1606
+ "function (arg, view) {{
1607
+ return {text_encoder}.encodeInto(arg, view);
1608
+ }}"
1609
+ ) ;
1568
1610
1569
1611
// Looks like `encodeInto` doesn't currently work when the memory passed
1570
1612
// in is backed by a `SharedArrayBuffer`, so force usage of `encode` if
1571
1613
// a `SharedArrayBuffer` is in use.
1572
1614
let shared = self . module . memories . get ( memory) . shared ;
1573
1615
1574
- match self . config . encode_into {
1575
- EncodeInto :: Always if !shared => {
1576
- self . global ( & format ! (
1577
- "
1578
- const encodeString = {};
1579
- " ,
1580
- encode_into
1581
- ) ) ;
1582
- }
1583
- EncodeInto :: Test if !shared => {
1584
- self . global ( & format ! (
1585
- "
1586
- const encodeString = (typeof cachedTextEncoder.encodeInto === 'function'
1587
- ? {}
1588
- : {});
1589
- " ,
1590
- encode_into, encode
1591
- ) ) ;
1616
+ if matches ! ( self . config. mode, OutputMode :: Emscripten ) {
1617
+ match self . config . encode_into {
1618
+ EncodeInto :: Always if !shared => {
1619
+ self . emscripten_library . push_str ( & format ! (
1620
+ "
1621
+ $encodeString : {},
1622
+ " ,
1623
+ encode_into
1624
+ ) ) ;
1625
+ }
1626
+ EncodeInto :: Test if !shared => {
1627
+ self . emscripten_library . push_str ( & format ! (
1628
+ "
1629
+ $encodeString : function (arg, view) {{
1630
+ if (typeof TextEncoder.encodeInto === 'function') {{
1631
+ return {}
1632
+ }}
1633
+ return {}
1634
+ }},
1635
+ " ,
1636
+ encode_into, encode
1637
+ ) ) ;
1638
+ }
1639
+ _ => {
1640
+ self . emscripten_library . push_str ( & format ! (
1641
+ "
1642
+ $encodeString : {},
1643
+ " ,
1644
+ encode
1645
+ ) ) ;
1646
+ }
1592
1647
}
1593
- _ => {
1594
- self . global ( & format ! (
1595
- "
1596
- const encodeString = {};
1597
- " ,
1598
- encode
1599
- ) ) ;
1648
+ self . emscripten_library
1649
+ . push_str ( "$encodeString__deps: ['$textEncoder'],\n " ) ;
1650
+ } else {
1651
+ match self . config . encode_into {
1652
+ EncodeInto :: Always if !shared => {
1653
+ self . global ( & format ! (
1654
+ "
1655
+ const encodeString = {};
1656
+ " ,
1657
+ encode_into
1658
+ ) ) ;
1659
+ }
1660
+ EncodeInto :: Test if !shared => {
1661
+ self . global ( & format ! (
1662
+ "
1663
+ const encodeString = (typeof cachedTextEncoder.encodeInto === 'function'
1664
+ ? {}
1665
+ : {});
1666
+ " ,
1667
+ encode_into, encode
1668
+ ) ) ;
1669
+ }
1670
+ _ => {
1671
+ self . global ( & format ! (
1672
+ "
1673
+ const encodeString = {};
1674
+ " ,
1675
+ encode
1676
+ ) ) ;
1677
+ }
1600
1678
}
1601
1679
}
1602
1680
@@ -1612,17 +1690,17 @@ __wbg_set_wasm(wasm);"
1612
1690
let encode_as_ascii = format ! (
1613
1691
"\
1614
1692
if (realloc === undefined) {{
1615
- const buf = cachedTextEncoder .encode(arg);
1693
+ const buf = {text_encoder} .encode(arg);
1616
1694
const ptr = malloc(buf.length, 1) >>> 0;
1617
- {mem}() .subarray(ptr, ptr + buf.length).set(buf);
1695
+ {mem_formatted} .subarray(ptr, ptr + buf.length).set(buf);
1618
1696
WASM_VECTOR_LEN = buf.length;
1619
1697
return ptr;
1620
1698
}}
1621
1699
1622
1700
let len = arg.length;
1623
1701
let ptr = malloc(len, 1) >>> 0;
1624
1702
1625
- const mem = {mem}() ;
1703
+ const mem = {mem_formatted} ;
1626
1704
1627
1705
let offset = 0;
1628
1706
@@ -1631,20 +1709,19 @@ __wbg_set_wasm(wasm);"
1631
1709
if (code > 0x7F) break;
1632
1710
mem[ptr + offset] = code;
1633
1711
}}
1634
- " ,
1635
- mem = mem,
1712
+ "
1636
1713
) ;
1637
-
1638
- self . global ( & format ! (
1639
- "function {name}(arg, malloc, realloc) {{
1714
+ self . write_js_function (
1715
+ & format ! (
1716
+ "
1640
1717
{debug}
1641
1718
{ascii}
1642
1719
if (offset !== len) {{
1643
1720
if (offset !== 0) {{
1644
1721
arg = arg.slice(offset);
1645
1722
}}
1646
1723
ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;
1647
- const view = {mem}() .subarray(ptr + offset, ptr + len);
1724
+ const view = {mem_formatted} .subarray(ptr + offset, ptr + len);
1648
1725
const ret = encodeString(arg, view);
1649
1726
{debug_end}
1650
1727
offset += ret.written;
@@ -1654,51 +1731,86 @@ __wbg_set_wasm(wasm);"
1654
1731
WASM_VECTOR_LEN = offset;
1655
1732
return ptr;
1656
1733
}}" ,
1657
- name = ret,
1658
- debug = debug,
1659
- ascii = encode_as_ascii,
1660
- mem = mem,
1661
- debug_end = if self . config. debug {
1662
- "if (ret.read !== arg.length) throw new Error('failed to pass whole string');"
1663
- } else {
1664
- ""
1665
- } ,
1666
- ) ) ;
1734
+ debug = debug,
1735
+ ascii = encode_as_ascii,
1736
+ mem_formatted = mem_formatted,
1737
+ debug_end = if self . config. debug {
1738
+ "if (ret.read !== arg.length) throw new Error('failed to pass whole string');"
1739
+ } else {
1740
+ ""
1741
+ } ,
1742
+ ) ,
1743
+ & format ! ( "{ret}" ) ,
1744
+ "(arg, malloc, realloc)" ,
1745
+ & vec ! [
1746
+ format!( "'$encodeString'" ) ,
1747
+ format!( "'${text_encoder}'" ) ,
1748
+ format!( "'$WASM_VECTOR_LEN'" ) ,
1749
+ ] ,
1750
+ ) ;
1667
1751
1668
1752
Ok ( ret)
1669
1753
}
1670
1754
1671
- fn expose_pass_array8_to_wasm ( & mut self , memory : MemoryId ) -> Result < MemView , Error > {
1755
+ fn expose_pass_array8_to_wasm (
1756
+ & mut self ,
1757
+ memory : MemoryId ,
1758
+ import_deps : & mut HashSet < String > ,
1759
+ ) -> Result < MemView , Error > {
1672
1760
let view = self . expose_uint8_memory ( memory) ;
1673
- self . pass_array_to_wasm ( "passArray8ToWasm" , view, 1 )
1761
+ self . pass_array_to_wasm ( "passArray8ToWasm" , view, 1 , import_deps )
1674
1762
}
1675
1763
1676
- fn expose_pass_array16_to_wasm ( & mut self , memory : MemoryId ) -> Result < MemView , Error > {
1764
+ fn expose_pass_array16_to_wasm (
1765
+ & mut self ,
1766
+ memory : MemoryId ,
1767
+ import_deps : & mut HashSet < String > ,
1768
+ ) -> Result < MemView , Error > {
1677
1769
let view = self . expose_uint16_memory ( memory) ;
1678
- self . pass_array_to_wasm ( "passArray16ToWasm" , view, 2 )
1770
+ self . pass_array_to_wasm ( "passArray16ToWasm" , view, 2 , import_deps )
1679
1771
}
1680
1772
1681
- fn expose_pass_array32_to_wasm ( & mut self , memory : MemoryId ) -> Result < MemView , Error > {
1773
+ fn expose_pass_array32_to_wasm (
1774
+ & mut self ,
1775
+ memory : MemoryId ,
1776
+ import_deps : & mut HashSet < String > ,
1777
+ ) -> Result < MemView , Error > {
1682
1778
let view = self . expose_uint32_memory ( memory) ;
1683
- self . pass_array_to_wasm ( "passArray32ToWasm" , view, 4 )
1779
+ self . pass_array_to_wasm ( "passArray32ToWasm" , view, 4 , import_deps )
1684
1780
}
1685
1781
1686
- fn expose_pass_array64_to_wasm ( & mut self , memory : MemoryId ) -> Result < MemView , Error > {
1782
+ fn expose_pass_array64_to_wasm (
1783
+ & mut self ,
1784
+ memory : MemoryId ,
1785
+ import_deps : & mut HashSet < String > ,
1786
+ ) -> Result < MemView , Error > {
1687
1787
let view = self . expose_uint64_memory ( memory) ;
1688
- self . pass_array_to_wasm ( "passArray64ToWasm" , view, 8 )
1788
+ self . pass_array_to_wasm ( "passArray64ToWasm" , view, 8 , import_deps )
1689
1789
}
1690
1790
1691
- fn expose_pass_array_f32_to_wasm ( & mut self , memory : MemoryId ) -> Result < MemView , Error > {
1791
+ fn expose_pass_array_f32_to_wasm (
1792
+ & mut self ,
1793
+ memory : MemoryId ,
1794
+ import_deps : & mut HashSet < String > ,
1795
+ ) -> Result < MemView , Error > {
1692
1796
let view = self . expose_f32_memory ( memory) ;
1693
- self . pass_array_to_wasm ( "passArrayF32ToWasm" , view, 4 )
1797
+ self . pass_array_to_wasm ( "passArrayF32ToWasm" , view, 4 , import_deps )
1694
1798
}
1695
1799
1696
- fn expose_pass_array_f64_to_wasm ( & mut self , memory : MemoryId ) -> Result < MemView , Error > {
1800
+ fn expose_pass_array_f64_to_wasm (
1801
+ & mut self ,
1802
+ memory : MemoryId ,
1803
+ import_deps : & mut HashSet < String > ,
1804
+ ) -> Result < MemView , Error > {
1697
1805
let view = self . expose_f64_memory ( memory) ;
1698
- self . pass_array_to_wasm ( "passArrayF64ToWasm" , view, 8 )
1806
+ self . pass_array_to_wasm ( "passArrayF64ToWasm" , view, 8 , import_deps )
1699
1807
}
1700
1808
1701
- fn expose_pass_array_jsvalue_to_wasm ( & mut self , memory : MemoryId ) -> Result < MemView , Error > {
1809
+ fn expose_pass_array_jsvalue_to_wasm (
1810
+ & mut self ,
1811
+ memory : MemoryId ,
1812
+ import_deps : & mut HashSet < String > ,
1813
+ ) -> Result < MemView , Error > {
1702
1814
let mem = self . expose_dataview_memory ( memory) ;
1703
1815
let ret = MemView {
1704
1816
name : "passArrayJsValueToWasm" . into ( ) ,
@@ -1707,15 +1819,15 @@ __wbg_set_wasm(wasm);"
1707
1819
if !self . should_write_global ( ret. to_string ( ) ) {
1708
1820
return Ok ( ret) ;
1709
1821
}
1710
- self . expose_wasm_vector_len ( ) ;
1822
+ self . expose_wasm_vector_len ( import_deps ) ;
1711
1823
match ( self . aux . externref_table , self . aux . externref_alloc ) {
1712
1824
( Some ( table) , Some ( alloc) ) => {
1713
1825
// TODO: using `addToExternrefTable` goes back and forth between wasm
1714
1826
// and JS a lot, we should have a bulk operation for this.
1715
- let add = self . expose_add_to_externref_table ( table, alloc) ?;
1716
- self . global ( & format ! (
1717
- "
1718
- function {ret}(array, malloc) {{
1827
+ let add = self . expose_add_to_externref_table ( table, alloc, import_deps ) ?;
1828
+ self . write_js_function (
1829
+ & format ! (
1830
+ "
1719
1831
const ptr = malloc(array.length * 4, 4) >>> 0;
1720
1832
for (let i = 0; i < array.length; i++) {{
1721
1833
const add = {add}(array[i]);
@@ -1725,7 +1837,11 @@ __wbg_set_wasm(wasm);"
1725
1837
return ptr;
1726
1838
}}
1727
1839
" ,
1728
- ) ) ;
1840
+ ) ,
1841
+ & format ! ( "{ret}" ) ,
1842
+ "(array, malloc)" ,
1843
+ & vec ! [ format!( "'${add}'" ) , format!( "'$WASM_VECTOR_LEN'" ) ] ,
1844
+ ) ;
1729
1845
}
1730
1846
_ => {
1731
1847
self . expose_add_heap_object ( ) ;
@@ -1752,6 +1868,7 @@ __wbg_set_wasm(wasm);"
1752
1868
name : & ' static str ,
1753
1869
view : MemView ,
1754
1870
size : usize ,
1871
+ import_deps : & mut HashSet < String > ,
1755
1872
) -> Result < MemView , Error > {
1756
1873
let ret = MemView {
1757
1874
name : name. into ( ) ,
@@ -1760,7 +1877,7 @@ __wbg_set_wasm(wasm);"
1760
1877
if !self . should_write_global ( ret. to_string ( ) ) {
1761
1878
return Ok ( ret) ;
1762
1879
}
1763
- self . expose_wasm_vector_len ( ) ;
1880
+ self . expose_wasm_vector_len ( import_deps ) ;
1764
1881
self . global ( & format ! (
1765
1882
"
1766
1883
function {}(arg, malloc) {{
@@ -1789,6 +1906,7 @@ __wbg_set_wasm(wasm);"
1789
1906
if !self . should_write_global ( "text_encoder" ) {
1790
1907
return Ok ( ( ) ) ;
1791
1908
}
1909
+ self . emscripten_deps . insert ( "'$TextEncoder'" . to_string ( ) ) ;
1792
1910
self . expose_text_processor ( "TextEncoder" , "encode" , "('utf-8')" , None )
1793
1911
}
1794
1912
@@ -2313,7 +2431,8 @@ __wbg_set_wasm(wasm);"
2313
2431
) ) ;
2314
2432
}
2315
2433
2316
- fn expose_handle_error ( & mut self ) -> Result < ( ) , Error > {
2434
+ fn expose_handle_error ( & mut self , import_deps : & mut HashSet < String > ) -> Result < ( ) , Error > {
2435
+ import_deps. insert ( "'$handleError'" . to_string ( ) ) ;
2317
2436
if !self . should_write_global ( "handle_error" ) {
2318
2437
return Ok ( ( ) ) ;
2319
2438
}
@@ -2324,10 +2443,10 @@ __wbg_set_wasm(wasm);"
2324
2443
let store = self . export_name_of ( store) ;
2325
2444
match ( self . aux . externref_table , self . aux . externref_alloc ) {
2326
2445
( Some ( table) , Some ( alloc) ) => {
2327
- let add = self . expose_add_to_externref_table ( table, alloc) ?;
2328
- self . global ( & format ! (
2329
- " \
2330
- function handleError(f, args) {{
2446
+ let add = self . expose_add_to_externref_table ( table, alloc, import_deps ) ?;
2447
+ self . write_js_function (
2448
+ & format ! (
2449
+ " \
2331
2450
try {{
2332
2451
return f.apply(this, args);
2333
2452
}} catch (e) {{
@@ -2336,13 +2455,18 @@ __wbg_set_wasm(wasm);"
2336
2455
}}
2337
2456
}}
2338
2457
" ,
2339
- add, store,
2340
- ) ) ;
2458
+ add, store,
2459
+ ) ,
2460
+ "handleError" ,
2461
+ "(f, args)" ,
2462
+ & vec ! [ format!( "'${add}'" ) ] ,
2463
+ ) ;
2341
2464
}
2342
2465
_ => {
2343
2466
self . expose_add_heap_object ( ) ;
2344
- self . global ( & format ! (
2345
- "\
2467
+ self . write_js_function (
2468
+ & format ! (
2469
+ "\
2346
2470
function handleError(f, args) {{
2347
2471
try {{
2348
2472
return f.apply(this, args);
@@ -2351,20 +2475,24 @@ __wbg_set_wasm(wasm);"
2351
2475
}}
2352
2476
}}
2353
2477
" ,
2354
- store,
2355
- ) ) ;
2478
+ store,
2479
+ ) ,
2480
+ "handleError" ,
2481
+ "(f, args)" ,
2482
+ & vec ! [ format!( "'$addHeapObject'" ) ] ,
2483
+ ) ;
2356
2484
}
2357
2485
}
2358
2486
Ok ( ( ) )
2359
2487
}
2360
2488
2361
- fn expose_log_error ( & mut self ) {
2489
+ fn expose_log_error ( & mut self , import_deps : & mut HashSet < String > ) {
2490
+ import_deps. insert ( "'$logError'" . to_string ( ) ) ;
2362
2491
if !self . should_write_global ( "log_error" ) {
2363
2492
return ;
2364
2493
}
2365
- self . global (
2494
+ self . write_js_function (
2366
2495
"\
2367
- function logError(f, args) {
2368
2496
try {
2369
2497
return f.apply(this, args);
2370
2498
} catch (e) {
@@ -2384,22 +2512,38 @@ __wbg_set_wasm(wasm);"
2384
2512
}
2385
2513
}
2386
2514
" ,
2515
+ "logError" ,
2516
+ "(f, args)" ,
2517
+ & Default :: default ( ) ,
2387
2518
) ;
2388
2519
}
2389
2520
2390
- fn pass_to_wasm_function ( & mut self , t : VectorKind , memory : MemoryId ) -> Result < MemView , Error > {
2521
+ fn pass_to_wasm_function (
2522
+ & mut self ,
2523
+ t : VectorKind ,
2524
+ memory : MemoryId ,
2525
+ import_deps : & mut HashSet < String > ,
2526
+ ) -> Result < MemView , Error > {
2391
2527
match t {
2392
- VectorKind :: String => self . expose_pass_string_to_wasm ( memory) ,
2528
+ VectorKind :: String => self . expose_pass_string_to_wasm ( memory, import_deps ) ,
2393
2529
VectorKind :: I8 | VectorKind :: U8 | VectorKind :: ClampedU8 => {
2394
- self . expose_pass_array8_to_wasm ( memory)
2530
+ self . expose_pass_array8_to_wasm ( memory, import_deps)
2531
+ }
2532
+ VectorKind :: U16 | VectorKind :: I16 => {
2533
+ self . expose_pass_array16_to_wasm ( memory, import_deps)
2534
+ }
2535
+ VectorKind :: I32 | VectorKind :: U32 => {
2536
+ self . expose_pass_array32_to_wasm ( memory, import_deps)
2537
+ }
2538
+ VectorKind :: I64 | VectorKind :: U64 => {
2539
+ self . expose_pass_array64_to_wasm ( memory, import_deps)
2540
+ }
2541
+ VectorKind :: F32 => self . expose_pass_array_f32_to_wasm ( memory, import_deps) ,
2542
+ VectorKind :: F64 => self . expose_pass_array_f64_to_wasm ( memory, import_deps) ,
2543
+ VectorKind :: Externref => self . expose_pass_array_jsvalue_to_wasm ( memory, import_deps) ,
2544
+ VectorKind :: NamedExternref ( _) => {
2545
+ self . expose_pass_array_jsvalue_to_wasm ( memory, import_deps)
2395
2546
}
2396
- VectorKind :: U16 | VectorKind :: I16 => self . expose_pass_array16_to_wasm ( memory) ,
2397
- VectorKind :: I32 | VectorKind :: U32 => self . expose_pass_array32_to_wasm ( memory) ,
2398
- VectorKind :: I64 | VectorKind :: U64 => self . expose_pass_array64_to_wasm ( memory) ,
2399
- VectorKind :: F32 => self . expose_pass_array_f32_to_wasm ( memory) ,
2400
- VectorKind :: F64 => self . expose_pass_array_f64_to_wasm ( memory) ,
2401
- VectorKind :: Externref => self . expose_pass_array_jsvalue_to_wasm ( memory) ,
2402
- VectorKind :: NamedExternref ( _) => self . expose_pass_array_jsvalue_to_wasm ( memory) ,
2403
2547
}
2404
2548
}
2405
2549
@@ -2453,17 +2597,31 @@ __wbg_set_wasm(wasm);"
2453
2597
) ;
2454
2598
}
2455
2599
2456
- fn expose_is_like_none ( & mut self ) {
2600
+ fn expose_is_like_none ( & mut self , import_deps : & mut HashSet < String > ) {
2601
+ if matches ! ( self . config. mode, OutputMode :: Emscripten ) {
2602
+ import_deps. insert ( "'$isLikeNone'" . to_string ( ) ) ;
2603
+ }
2457
2604
if !self . should_write_global ( "is_like_none" ) {
2458
2605
return ;
2459
2606
}
2460
- self . global (
2461
- "
2462
- function isLikeNone(x) {
2463
- return x === undefined || x === null;
2464
- }
2607
+
2608
+ if matches ! ( self . config. mode, OutputMode :: Emscripten ) {
2609
+ self . emscripten_library . push_str (
2610
+ "
2611
+ $isLikeNone: function(x) {
2612
+ return x == null;
2613
+ },
2465
2614
" ,
2466
- ) ;
2615
+ ) ;
2616
+ } else {
2617
+ self . global (
2618
+ "
2619
+ function isLikeNone(x) {
2620
+ return x == null;
2621
+ }
2622
+ " ,
2623
+ ) ;
2624
+ }
2467
2625
}
2468
2626
2469
2627
fn expose_assert_non_null ( & mut self ) {
@@ -2653,10 +2811,10 @@ __wbg_set_wasm(wasm);"
2653
2811
self . emscripten_library . push_str (
2654
2812
"
2655
2813
$CLOSURE_DTORS: `(typeof FinalizationRegistry === 'undefined')
2656
- ? {{ register: () => {{}} , unregister: () => {{}} } }
2657
- : new FinalizationRegistry(state => {{
2814
+ ? { register: () => {} , unregister: () => {} }
2815
+ : new FinalizationRegistry(state => {
2658
2816
wasmExports.__indirect_function_table.get(state.dtor)(state.a, state.b)
2659
- }} )`,\n
2817
+ })`,\n
2660
2818
" ,
2661
2819
) ;
2662
2820
} else {
@@ -2684,6 +2842,50 @@ __wbg_set_wasm(wasm);"
2684
2842
self . globals . push ( '\n' ) ;
2685
2843
}
2686
2844
2845
+ fn emscripten_library ( & mut self , s : & str ) {
2846
+ let s = s. trim ( ) ;
2847
+
2848
+ // Ensure a blank line between adjacent items, and ensure everything is
2849
+ // terminated with a newline.
2850
+ while !self . emscripten_library . ends_with ( "\n \n \n " )
2851
+ && !self . emscripten_library . ends_with ( "*/\n " )
2852
+ {
2853
+ self . emscripten_library . push ( '\n' ) ;
2854
+ }
2855
+ self . emscripten_library . push_str ( s) ;
2856
+ self . emscripten_library . push ( '\n' ) ;
2857
+ }
2858
+
2859
+ fn write_js_function ( & mut self , body : & str , func_name : & str , args : & str , deps : & Vec < String > ) {
2860
+ if matches ! ( self . config. mode, OutputMode :: Emscripten ) {
2861
+ self . emscripten_library ( & format ! (
2862
+ "
2863
+ ${}: function{} {{
2864
+ {},
2865
+ " ,
2866
+ func_name,
2867
+ args,
2868
+ body. trim( ) . replace( "wasm." , "wasmExports." )
2869
+ ) ) ;
2870
+ if !deps. is_empty ( ) {
2871
+ self . emscripten_library . push_str ( & format ! (
2872
+ "${}_deps: [{}],
2873
+ " ,
2874
+ func_name,
2875
+ deps. join( "," )
2876
+ ) ) ;
2877
+ }
2878
+ } else {
2879
+ self . global ( & format ! (
2880
+ "
2881
+ function {}{} {{
2882
+ {}
2883
+ " ,
2884
+ func_name, args, body
2885
+ ) ) ;
2886
+ }
2887
+ }
2888
+
2687
2889
fn require_class_wrap ( & mut self , name : & str ) {
2688
2890
require_class ( & mut self . exported_classes , name) . wrap_needed = true ;
2689
2891
}
@@ -2869,24 +3071,30 @@ __wbg_set_wasm(wasm);"
2869
3071
& mut self ,
2870
3072
table : TableId ,
2871
3073
alloc : FunctionId ,
3074
+ import_deps : & mut HashSet < String > ,
2872
3075
) -> Result < MemView , Error > {
2873
3076
let view = self . memview_table ( "addToExternrefTable" , table) ;
2874
3077
assert ! ( self . config. externref) ;
3078
+ import_deps. insert ( format ! ( "'${}'" , view) . to_string ( ) ) ;
2875
3079
if !self . should_write_global ( view. to_string ( ) ) {
2876
3080
return Ok ( view) ;
2877
3081
}
2878
3082
let alloc = self . export_name_of ( alloc) ;
2879
3083
let table = self . export_name_of ( table) ;
2880
- self . global ( & format ! (
2881
- "
2882
- function {}(obj) {{
3084
+ self . write_js_function (
3085
+ & format ! (
3086
+ "
2883
3087
const idx = wasm.{}();
2884
3088
wasm.{}.set(idx, obj);
2885
3089
return idx;
2886
3090
}}
2887
3091
" ,
2888
- view, alloc, table,
2889
- ) ) ;
3092
+ alloc, table,
3093
+ ) ,
3094
+ & format ! ( "{}" , view) ,
3095
+ "(obj)" ,
3096
+ & Default :: default ( ) ,
3097
+ ) ;
2890
3098
2891
3099
Ok ( view)
2892
3100
}
@@ -3035,7 +3243,7 @@ __wbg_set_wasm(wasm);"
3035
3243
ContextAdapterKind :: Export ( e) => format ! ( "`{}`" , e. debug_name) ,
3036
3244
ContextAdapterKind :: Adapter => format ! ( "adapter {}" , id. 0 ) ,
3037
3245
} ;
3038
- let mut import_deps: Vec < String > = Default :: default ( ) ;
3246
+ let mut import_deps: HashSet < String > = Default :: default ( ) ;
3039
3247
// Process the `binding` and generate a bunch of JS/TypeScript/etc.
3040
3248
let binding:: JsFunction {
3041
3249
ts_sig,
@@ -3173,7 +3381,7 @@ __wbg_set_wasm(wasm);"
3173
3381
}
3174
3382
}
3175
3383
ContextAdapterKind :: Import ( core) => {
3176
- let code = if catch {
3384
+ let mut code = if catch {
3177
3385
format ! (
3178
3386
"function() {{ return handleError(function {}, arguments) }}" ,
3179
3387
code
@@ -3183,22 +3391,25 @@ __wbg_set_wasm(wasm);"
3183
3391
"function() {{ return logError(function {}, arguments) }}" ,
3184
3392
code
3185
3393
)
3186
- } else if ( matches ! ( self . config. mode, OutputMode :: Emscripten )
3187
- && !import_deps. is_empty ( ) )
3188
- {
3189
- for dep in & import_deps {
3190
- self . emscripten_deps . insert ( dep. clone ( ) ) ;
3191
- }
3192
- format ! (
3193
- "function{},\n {}__deps: [{}]" ,
3194
- code,
3195
- self . module. imports. get( core) . name,
3196
- import_deps. join( "," )
3197
- )
3198
3394
} else {
3199
- format ! ( "function{}\n " , code)
3395
+ format ! ( "function{}" , code)
3200
3396
} ;
3201
3397
3398
+ if matches ! ( self . config. mode, OutputMode :: Emscripten ) && !import_deps. is_empty ( ) {
3399
+ let mut import_deps_vec = import_deps
3400
+ . iter ( )
3401
+ . map ( |s| s. as_str ( ) )
3402
+ . collect :: < Vec < & str > > ( ) ;
3403
+ // sort to generate deterministic output.
3404
+ import_deps_vec. sort ( ) ;
3405
+ let deps: String = format ! (
3406
+ "{}__deps: [{}]\n " ,
3407
+ self . module. imports. get( core) . name,
3408
+ import_deps_vec. join( "," )
3409
+ ) ;
3410
+ code = format ! ( "{},\n {}\n " , code, deps) ;
3411
+ }
3412
+
3202
3413
self . wasm_import_definitions . insert ( core, code) ;
3203
3414
}
3204
3415
ContextAdapterKind :: Adapter => {
@@ -3441,7 +3652,7 @@ __wbg_set_wasm(wasm);"
3441
3652
args : & [ String ] ,
3442
3653
variadic : bool ,
3443
3654
prelude : & mut String ,
3444
- import_deps : & mut Vec < String > ,
3655
+ import_deps : & mut HashSet < String > ,
3445
3656
) -> Result < String , Error > {
3446
3657
let variadic_args = |js_arguments : & [ String ] | {
3447
3658
Ok ( if !variadic {
@@ -3465,7 +3676,7 @@ __wbg_set_wasm(wasm);"
3465
3676
let re = Regex :: new ( r"([a-zA-Z_$][a-zA-Z0-9_$]*)\s*\(" ) . unwrap ( ) ;
3466
3677
for arg in args {
3467
3678
if let Some ( result) = re. captures ( arg) {
3468
- import_deps. push ( format ! ( "'${}'" , & result[ 1 ] ) ) ;
3679
+ import_deps. insert ( format ! ( "'${}'" , & result[ 1 ] ) ) ;
3469
3680
}
3470
3681
}
3471
3682
}
@@ -3581,11 +3792,11 @@ __wbg_set_wasm(wasm);"
3581
3792
assert_eq ! ( args. len( ) , 3 ) ;
3582
3793
3583
3794
let call = self . adapter_name ( * adapter) ;
3584
- import_deps. push ( format ! ( "'${}'" , call) ) ;
3795
+ import_deps. insert ( format ! ( "'${}'" , call) ) ;
3585
3796
if * mutable {
3586
3797
self . expose_make_mut_closure ( ) ?;
3587
3798
if matches ! ( self . config. mode, OutputMode :: Emscripten ) {
3588
- import_deps. push ( "'$makeMutClosure'" . to_string ( ) ) ;
3799
+ import_deps. insert ( "'$makeMutClosure'" . to_string ( ) ) ;
3589
3800
}
3590
3801
Ok ( format ! (
3591
3802
"makeMutClosure({arg0}, {arg1}, {dtor}, {call})" ,
@@ -3597,7 +3808,7 @@ __wbg_set_wasm(wasm);"
3597
3808
} else {
3598
3809
self . expose_make_closure ( ) ?;
3599
3810
if matches ! ( self . config. mode, OutputMode :: Emscripten ) {
3600
- import_deps. push ( "'$makeClosure'" . to_string ( ) ) ;
3811
+ import_deps. insert ( "'$makeClosure'" . to_string ( ) ) ;
3601
3812
}
3602
3813
Ok ( format ! (
3603
3814
"makeClosure({arg0}, {arg1}, {dtor}, {call})" ,
@@ -3719,7 +3930,7 @@ __wbg_set_wasm(wasm);"
3719
3930
AuxImport :: Intrinsic ( intrinsic) => {
3720
3931
assert ! ( kind == AdapterJsImportKind :: Normal ) ;
3721
3932
assert ! ( !variadic) ;
3722
- self . invoke_intrinsic ( intrinsic, args, prelude)
3933
+ self . invoke_intrinsic ( intrinsic, args, prelude, import_deps )
3723
3934
}
3724
3935
3725
3936
AuxImport :: LinkTo ( path, content) => {
@@ -3785,6 +3996,7 @@ __wbg_set_wasm(wasm);"
3785
3996
intrinsic : & Intrinsic ,
3786
3997
args : & [ String ] ,
3787
3998
prelude : & mut String ,
3999
+ import_deps : & mut HashSet < String > ,
3788
4000
) -> Result < String , Error > {
3789
4001
let expr = match intrinsic {
3790
4002
Intrinsic :: JsvalEq => {
@@ -4121,6 +4333,7 @@ __wbg_set_wasm(wasm);"
4121
4333
Intrinsic :: DebugString => {
4122
4334
assert_eq ! ( args. len( ) , 1 ) ;
4123
4335
self . expose_debug_string ( ) ;
4336
+ import_deps. insert ( "'$debugString'" . to_string ( ) ) ;
4124
4337
format ! ( "debugString({})" , args[ 0 ] )
4125
4338
}
4126
4339
@@ -4395,9 +4608,8 @@ __wbg_set_wasm(wasm);"
4395
4608
return ;
4396
4609
}
4397
4610
4398
- self . global (
4611
+ self . write_js_function (
4399
4612
"
4400
- function debugString(val) {
4401
4613
// primitive types
4402
4614
const type = typeof val;
4403
4615
if (type == 'number' || type == 'boolean' || val == null) {
@@ -4462,6 +4674,9 @@ __wbg_set_wasm(wasm);"
4462
4674
return className;
4463
4675
}
4464
4676
" ,
4677
+ "debugString" ,
4678
+ "(val)" ,
4679
+ & Default :: default ( ) ,
4465
4680
) ;
4466
4681
}
4467
4682
0 commit comments