1
- # ` host_binding `
1
+ # ` final `
2
2
3
- The ` host_binding ` attribute is the converse of the [ ` structural `
3
+ The ` final ` attribute is the converse of the [ ` structural `
4
4
attribute] ( structural.html ) . It configures how ` wasm-bindgen ` will generate JS
5
- glue to call the imported function. The naming here is intended convey that this
6
- attribute is intended to implement the semantics of the future [ host bindings
7
- proposal] [ host-bindings ] for WebAssembly.
5
+ imports to call the imported function. Notably a function imported by ` final `
6
+ never changes after it was imported, whereas a function imported by default (or
7
+ with ` structural ` ) is subject to runtime lookup rules such as walking the
8
+ prototype chain of an object.
8
9
9
10
[ host-bindings ] : https://github.com/WebAssembly/host-bindings
10
11
[ reference-types ] : https://github.com/WebAssembly/reference-types
11
12
12
- The ` host_binding ` attribute is intended to be purely related to performance. It
13
- ideally has no user-visible effect, and well-typed ` structural ` imports (the
14
- default) should be able to transparently switch to ` host_binding ` eventually.
13
+ The ` final ` attribute is intended to be purely related to performance. It
14
+ ideally has no user-visible effect, and ` structural ` imports (the default)
15
+ should be able to transparently switch to ` host_binding ` eventually.
15
16
16
17
The eventual performance aspect is that with the [ host bindings
17
18
proposal] [ host-bindings ] then ` wasm-bindgen ` will need to generate far fewer JS
18
- shims to import than it does today. For example, consider this import today:
19
+ functino shims to import than it does today. For example, consider this import
20
+ today:
19
21
20
22
``` rust
21
23
#[wasm_bindgen]
@@ -26,28 +28,28 @@ extern {
26
28
}
27
29
```
28
30
29
- ** Without the ` host_binding ` attribute** the generated JS looks like this:
31
+ ** Without the ` final ` attribute** the generated JS looks like this:
30
32
31
33
``` js
32
- // without `host_binding `
34
+ // without `final `
33
35
export function __wbg_bar_a81456386e6b526f (arg0 , arg1 , arg2 ) {
34
36
let varg1 = getStringFromWasm (arg1, arg2);
35
37
return addHeapObject (getObject (arg0).bar (varg1));
36
38
}
37
39
```
38
40
39
- We can see here that this JS shim is required, but it's all relatively
41
+ We can see here that this JS function shim is required, but it's all relatively
40
42
self-contained. It does, however, execute the ` bar ` method in a duck-type-y
41
- fashion in the sense that it never validates ` getObject(arg0) ` is of type
42
- ` Foo ` to actually call the ` Foo.prototype.bar ` method.
43
+ fashion in the sense that it never validates ` getObject(arg0) ` is of type ` Foo `
44
+ to actually call the ` Foo.prototype.bar ` method.
43
45
44
46
If we instead, however, write this:
45
47
46
48
``` rust
47
49
#[wasm_bindgen]
48
50
extern {
49
51
type Foo ;
50
- #[wasm_bindgen(method, host_binding )] // note the change here
52
+ #[wasm_bindgen(method, final )] // note the change here
51
53
fn bar (this : & Foo , argument : & str ) -> JsValue ;
52
54
}
53
55
```
@@ -68,7 +70,7 @@ called is hoisted out of the generated shim and is bound to always be
68
70
` Foo.prototype.bar ` . This then uses the ` Function.call ` method to invoke that
69
71
function with ` getObject(arg0) ` as the receiver.
70
72
71
- But wait, there's still a JS shim here even with ` host_binding ` ! That's true,
73
+ But wait, there's still a JS function shim here even with ` final ` ! That's true,
72
74
and this is simply a fact of future WebAssembly proposals not being implemented
73
75
yet. The semantics, though, match the future [ host bindings
74
76
proposal] [ host-bindings ] because the method being called is determined exactly
@@ -77,8 +79,8 @@ runtime when the function is called.
77
79
78
80
## Interaction with future proposals
79
81
80
- If you're curious to see how our JS shim will be eliminated entirely, let's take
81
- a look at the generated bindings. We're starting off with this:
82
+ If you're curious to see how our JS function shim will be eliminated entirely,
83
+ let's take a look at the generated bindings. We're starting off with this:
82
84
83
85
``` js
84
86
const __wbg_bar_target = Foo .prototype .bar ;
@@ -135,5 +137,18 @@ export const __wbg_bar_a81456386e6b526f = Foo.prototype.bar;
135
137
```
136
138
137
139
and voila! We, with [ reference types] [ reference-types ] and [ host
138
- bindings] [ host-bindings ] , now have no JS shim at all necessary to call the
139
- imported function!
140
+ bindings] [ host-bindings ] , now have no JS function shim at all necessary to call
141
+ the imported function. Additionally future wasm proposals to the ES module
142
+ system may also mean that don't even need the ` export const ... ` here too.
143
+
144
+ It's also worth pointing out that with all these wasm proposals implemented the
145
+ default way to import the ` bar ` function (aka ` structural ` ) would generate a JS
146
+ function shim that looks like:
147
+
148
+ ``` js
149
+ export function __wbg_bar_a81456386e6b526f (varg1 ) {
150
+ return this .bar (varg1);
151
+ }
152
+ ```
153
+
154
+ where this import is still subject to runtime prototype chain lookups and such.
0 commit comments