File tree Expand file tree Collapse file tree 7 files changed +117
-0
lines changed
examples/explicit-resource-management Expand file tree Collapse file tree 7 files changed +117
-0
lines changed Original file line number Diff line number Diff line change @@ -79,6 +79,7 @@ members = [
79
79
" examples/deno" ,
80
80
" examples/dom" ,
81
81
" examples/duck-typed-interfaces" ,
82
+ " examples/explicit-resource-management" ,
82
83
" examples/fetch" ,
83
84
" examples/guide-supported-types-examples" ,
84
85
" examples/hello_world" ,
Original file line number Diff line number Diff line change
1
+ [package ]
2
+ authors = [" The wasm-bindgen Developers" ]
3
+ edition = " 2021"
4
+ name = " explicit-resource-management"
5
+ publish = false
6
+ version = " 0.0.0"
7
+
8
+ [lib ]
9
+ crate-type = [" cdylib" ]
10
+
11
+ [dependencies ]
12
+ wasm-bindgen = { path = " ../../" }
Original file line number Diff line number Diff line change
1
+ # Using Explicit Resource Management (via Deno)
2
+
3
+ You can build the example with
4
+
5
+ ``` sh
6
+ $ ./build.sh
7
+ ```
8
+
9
+ and test it with
10
+
11
+ ``` sh
12
+ $ deno run --allow-read test.ts
13
+ ```
14
+
15
+ The ` --allow-read ` flag is needed because the Wasm file is read during runtime.
16
+ This will be fixed when https://github.com/denoland/deno/issues/2552 is resolved.
Original file line number Diff line number Diff line change
1
+ #! /bin/sh
2
+
3
+ set -eux
4
+
5
+ cargo build --target wasm32-unknown-unknown --release
6
+ WASM_BINDGEN_SYMBOL_DISPOSE=1 cargo run --package wasm-bindgen-cli --bin wasm-bindgen -- \
7
+ --out-dir pkg --target deno ${CARGO_TARGET_DIR:- ../ ../ target} /wasm32-unknown-unknown/release/explicit_resource_management.wasm
Original file line number Diff line number Diff line change
1
+ /explicit-resource-management.wasm
Original file line number Diff line number Diff line change
1
+ use std:: alloc:: { GlobalAlloc , Layout , System } ;
2
+ use std:: sync:: atomic:: { AtomicUsize , Ordering :: Relaxed } ;
3
+ use wasm_bindgen:: prelude:: * ;
4
+
5
+ // simple counting allocator tracking
6
+ struct Counter ;
7
+
8
+ static ALLOCATED : AtomicUsize = AtomicUsize :: new ( 0 ) ;
9
+
10
+ unsafe impl GlobalAlloc for Counter {
11
+ unsafe fn alloc ( & self , layout : Layout ) -> * mut u8 {
12
+ let ret = System . alloc ( layout) ;
13
+ if !ret. is_null ( ) {
14
+ ALLOCATED . fetch_add ( layout. size ( ) , Relaxed ) ;
15
+ }
16
+ ret
17
+ }
18
+
19
+ unsafe fn dealloc ( & self , ptr : * mut u8 , layout : Layout ) {
20
+ System . dealloc ( ptr, layout) ;
21
+ ALLOCATED . fetch_sub ( layout. size ( ) , Relaxed ) ;
22
+ }
23
+ }
24
+
25
+ #[ global_allocator]
26
+ static A : Counter = Counter ;
27
+
28
+ #[ wasm_bindgen]
29
+ pub fn current_allocation ( ) -> usize {
30
+ ALLOCATED . load ( Relaxed )
31
+ }
32
+
33
+ // lifted from the `console_log` example
34
+ #[ wasm_bindgen]
35
+ extern "C" {
36
+ #[ wasm_bindgen( js_namespace = console) ]
37
+ fn log ( s : & str ) ;
38
+ }
39
+
40
+ #[ wasm_bindgen]
41
+ pub struct MyStruct {
42
+ x : Vec < i64 > ,
43
+ y : Vec < i64 > ,
44
+ name : String ,
45
+ }
46
+
47
+ #[ wasm_bindgen]
48
+ impl MyStruct {
49
+ #[ wasm_bindgen( constructor) ]
50
+ pub fn new ( name : String ) -> MyStruct {
51
+ Self {
52
+ name,
53
+ x : ( 0 ..50 ) . collect ( ) ,
54
+ y : ( 0 ..50 ) . collect ( ) ,
55
+ }
56
+ }
57
+ }
58
+
59
+ impl Drop for MyStruct {
60
+ fn drop ( & mut self ) {
61
+ log ( & format ! ( "Goodbye from {}!" , self . name) ) ; // should output "Goodbye from Rust!"
62
+ }
63
+ }
Original file line number Diff line number Diff line change
1
+ import { current_allocation , MyStruct } from "./pkg/explicit_resource_management.js" ;
2
+
3
+ const initialAllocation = current_allocation ( ) ;
4
+ let referrent = { } ;
5
+ console . log ( 'Before scope: ' , initialAllocation ) ;
6
+
7
+ {
8
+ using foo = new MyStruct ( "Rust" ) ;
9
+ // force foo to be treated as live by implicit memory management (FinalizationRegistry/GC)
10
+ // by retaining a reference that outlives the scope block (for the purposes of proving
11
+ // Symbol.dispose is called on scope exit).
12
+ referrent [ 'foo' ] = foo ;
13
+ console . log ( 'After construction, but before scope exit: ' , current_allocation ( ) ) ;
14
+ }
15
+ const afterDisposeAllocation = current_allocation ( ) ;
16
+ console . log ( 'After scope exit: ' , afterDisposeAllocation ) ;
17
+ console . log ( referrent ) ;
You can’t perform that action at this time.
0 commit comments