@@ -4,12 +4,10 @@ import { asbindInstantiate, asbindInstantiateSync } from "./instantiate";
4
4
import { bindImportFunction , bindExportFunction } from "./bind-function" ;
5
5
import { isReservedExportKey } from "./reserved-export-keys" ;
6
6
7
+ const SECTION_NAME = "as-bind_bindings" ;
8
+
7
9
// Need to traverse the importObject and bind all import functions
8
- const traverseObjectAndRunCallbackForFunctions = (
9
- baseObject ,
10
- keys ,
11
- callback
12
- ) => {
10
+ function traverseObjectAndRunCallbackForFunctions ( baseObject , keys , callback ) {
13
11
if ( ! baseObject ) {
14
12
return ;
15
13
}
@@ -26,7 +24,32 @@ const traverseObjectAndRunCallbackForFunctions = (
26
24
) ;
27
25
}
28
26
} ) ;
29
- } ;
27
+ }
28
+
29
+ async function compileStreaming ( source ) {
30
+ if ( WebAssembly . compileStreaming ) {
31
+ return WebAssembly . compileStreaming ( source ) ;
32
+ }
33
+ source = await Promise . resolve ( souce ) ;
34
+ if ( source instanceof Response ) {
35
+ source = await source . arrayBuffer ( ) ;
36
+ }
37
+ return WebAssembly . compile ( source ) ;
38
+ }
39
+
40
+ function extractTypeDescriptor ( module ) {
41
+ const sections = WebAssembly . Module . customSections ( module , SECTION_NAME ) ;
42
+ console . assert (
43
+ sections . length === 1 ,
44
+ `Need exactly one custom section ${ JSON . stringify ( SECTION_NAME ) } `
45
+ ) ;
46
+ const str = new TextDecoder ( "utf8" ) . decode ( new Uint8Array ( sections [ 0 ] ) ) ;
47
+ try {
48
+ return JSON . parse ( str ) ;
49
+ } catch ( e ) {
50
+ throw Error ( `Couldn’t decode type descriptor: ${ e . message } ` ) ;
51
+ }
52
+ }
30
53
31
54
export default class AsbindInstance {
32
55
constructor ( ) {
@@ -35,26 +58,47 @@ export default class AsbindInstance {
35
58
this . importObject = { } ;
36
59
}
37
60
61
+ _validate ( ) {
62
+ if (
63
+ ! WebAssembly . Module . exports ( this . module ) . find ( exp => exp . name === "__new" )
64
+ ) {
65
+ throw Error (
66
+ "The AssemblyScript wasm module was not built with --exportRuntime, which is required."
67
+ ) ;
68
+ }
69
+ if (
70
+ ! WebAssembly . Module . exports ( this . module ) . find (
71
+ exp => exp . name === "__asbind_entryfile_flaga"
72
+ )
73
+ ) {
74
+ throw new Error (
75
+ "The AssemblyScript wasm module was not built with the as-bind entryfile. Please see the as-bind documentation (Quick Start), and rebuild your AssemblyScript wasm module."
76
+ ) ;
77
+ }
78
+ }
79
+
38
80
async _instantiate ( source , importObject ) {
81
+ this . module = await compileStreaming ( source ) ;
82
+ this . _validate ( ) ;
83
+ this . typeDescriptor = extractTypeDescriptor ( this . module ) ;
39
84
// Bind our import function
40
85
this . _instantiateBindImportFunctions ( importObject ) ;
41
86
42
87
// Instantiate the module through the loader
43
- const unboundExports = await asbindInstantiate ( source , this . importObject ) ;
88
+ this . loadedModule = await asbindInstantiate ( this . module , this . importObject ) ;
44
89
45
90
// Bind our unbound exports
46
- this . _instantiateBindUnboundExports ( unboundExports ) ;
91
+ this . _instantiateBindUnboundExports ( ) ;
47
92
}
48
93
49
94
_instantiateSync ( source , importObject ) {
50
- // Bind our import function
95
+ this . module = new WebAssembly . Module ( source ) ;
96
+ this . _validate ( ) ;
97
+ this . typeDescriptor = extractTypeDescriptor ( this . module ) ;
51
98
this . _instantiateBindImportFunctions ( importObject ) ;
52
99
53
- // Instantiate the module through the loader
54
- const unboundExports = asbindInstantiateSync ( source , this . importObject ) ;
55
-
56
- // Bind our unbound exports
57
- this . _instantiateBindUnboundExports ( unboundExports ) ;
100
+ this . loadedModule = asbindInstantiateSync ( this . module , this . importObject ) ;
101
+ this . _instantiateBindUnboundExports ( ) ;
58
102
}
59
103
60
104
_instantiateBindImportFunctions ( importObject ) {
@@ -78,25 +122,18 @@ export default class AsbindInstance {
78
122
) ;
79
123
}
80
124
81
- _instantiateBindUnboundExports ( unboundExports ) {
82
- // Set our unbound exports
83
- this . unboundExports = unboundExports ;
84
-
125
+ _instantiateBindUnboundExports ( ) {
85
126
// Ensure that the AS Wasm was built with the as-bind entryfile
86
- if (
87
- ! this . unboundExports . __asbind_entryfile_flag ||
88
- this . unboundExports . __asbind_entryfile_flag === 0
89
- ) {
90
- throw new Error (
91
- "as-bind: The instantiated AssemblyScript wasm module was not built with the as-bind entryfile. Please see the as-bind documentation (Quick Start), and rebuild your AssemblyScript wasm module."
92
- ) ;
127
+ if ( this . loadedModule . exports ?. __asbind_entryfile_flag ?. value !== 1 ) {
93
128
}
94
129
95
130
// Wrap appropriate the appropriate export functions
131
+ const unboundExports = this . loadedModule . exports ;
96
132
this . exports = { } ;
97
- Object . keys ( this . unboundExports ) . forEach ( unboundExportKey => {
133
+
134
+ Object . keys ( unboundExports ) . forEach ( unboundExportKey => {
98
135
if (
99
- typeof this . unboundExports [ unboundExportKey ] === "function" &&
136
+ typeof unboundExports [ unboundExportKey ] === "function" &&
100
137
! isReservedExportKey ( unboundExportKey )
101
138
) {
102
139
// Wrap the export
@@ -105,66 +142,8 @@ export default class AsbindInstance {
105
142
unboundExportKey
106
143
) ;
107
144
} else {
108
- this . exports [ unboundExportKey ] = this . unboundExports [ unboundExportKey ] ;
109
- }
110
- } ) ;
111
- }
112
-
113
- enableExportFunctionTypeCaching ( ) {
114
- Object . keys ( this . exports ) . forEach ( exportKey => {
115
- if ( this . exports [ exportKey ] ) {
116
- this . exports [ exportKey ] . shouldCacheTypes = true ;
145
+ this . exports [ unboundExportKey ] = unboundExports [ unboundExportKey ] ;
117
146
}
118
147
} ) ;
119
148
}
120
-
121
- disableExportFunctionTypeCaching ( ) {
122
- Object . keys ( this . exports ) . forEach ( exportKey => {
123
- if ( this . exports [ exportKey ] ) {
124
- this . exports [ exportKey ] . shouldCacheTypes = false ;
125
- }
126
- } ) ;
127
- }
128
-
129
- enableExportFunctionUnsafeReturnValue ( ) {
130
- Object . keys ( this . exports ) . forEach ( exportKey => {
131
- if ( this . exports [ exportKey ] ) {
132
- this . exports [ exportKey ] . unsafeReturnValue = true ;
133
- }
134
- } ) ;
135
- }
136
-
137
- disableExportFunctionUnsafeReturnValue ( ) {
138
- Object . keys ( this . exports ) . forEach ( exportKey => {
139
- if ( this . exports [ exportKey ] ) {
140
- this . exports [ exportKey ] . unsafeReturnValue = false ;
141
- }
142
- } ) ;
143
- }
144
-
145
- enableImportFunctionTypeCaching ( ) {
146
- // Need to traverse the importObject and bind all import functions
147
- traverseObjectAndRunCallbackForFunctions (
148
- this . importObject ,
149
- [ ] ,
150
- ( baseObject , keys , baseObjectKey ) => {
151
- // Wrap the original key, but then expose a new key for the unbound import
152
- let importFunction = baseObject [ baseObjectKey ] ;
153
- importFunction . shouldCacheTypes = true ;
154
- }
155
- ) ;
156
- }
157
-
158
- disableImportFunctionTypeCaching ( ) {
159
- // Need to traverse the importObject and bind all import functions
160
- traverseObjectAndRunCallbackForFunctions (
161
- this . importObject ,
162
- [ ] ,
163
- ( baseObject , keys , baseObjectKey ) => {
164
- // Wrap the original key, but then expose a new key for the unbound import
165
- let importFunction = baseObject [ baseObjectKey ] ;
166
- importFunction . shouldCacheTypes = false ;
167
- }
168
- ) ;
169
- }
170
149
}
0 commit comments