@@ -2032,4 +2032,343 @@ Module['FS_createPreloadedFile'] = FS.createPreloadedFile;
2032
2032
var cyberDWARFFile = '{{{ BUNDLED_CD_DEBUG_FILE }}}' ;
2033
2033
#endif
2034
2034
2035
+ #if BINARYEN
2036
+ function integrateWasmJS ( Module ) {
2037
+ // wasm.js has several methods for creating the compiled code module here:
2038
+ // * 'native-wasm' : use native WebAssembly support in the browser
2039
+ // * 'interpret-s-expr': load s-expression code from a .wast and interpret
2040
+ // * 'interpret-binary': load binary wasm and interpret
2041
+ // * 'interpret-asm2wasm': load asm.js code, translate to wasm, and interpret
2042
+ // * 'asmjs': no wasm, just load the asm.js code and use that (good for testing)
2043
+ // The method can be set at compile time (BINARYEN_METHOD), or runtime by setting Module['wasmJSMethod'].
2044
+ // The method can be a comma-separated list, in which case, we will try the
2045
+ // options one by one. Some of them can fail gracefully, and then we can try
2046
+ // the next.
2047
+
2048
+ // inputs
2049
+
2050
+ var method = Module [ 'wasmJSMethod' ] || '{{{ BINARYEN_METHOD }}}' ;
2051
+ Module [ 'wasmJSMethod' ] = method ;
2052
+
2053
+ var wasmTextFile = Module [ 'wasmTextFile' ] || '{{{ WASM_TEXT_FILE }}}' ;
2054
+ var wasmBinaryFile = Module [ 'wasmBinaryFile' ] || '{{{ WASM_BINARY_FILE }}}' ;
2055
+ var asmjsCodeFile = Module [ 'asmjsCodeFile' ] || '{{{ ASMJS_CODE_FILE }}}' ;
2056
+
2057
+ // utilities
2058
+
2059
+ var wasmPageSize = 64 * 1024 ;
2060
+
2061
+ var asm2wasmImports = { // special asm2wasm imports
2062
+ "f64-rem" : function ( x , y ) {
2063
+ return x % y ;
2064
+ } ,
2065
+ "f64-to-int" : function ( x ) {
2066
+ return x | 0 ;
2067
+ } ,
2068
+ "i32s-div" : function ( x , y ) {
2069
+ return ( ( x | 0 ) / ( y | 0 ) ) | 0 ;
2070
+ } ,
2071
+ "i32u-div" : function ( x , y ) {
2072
+ return ( ( x >>> 0 ) / ( y >>> 0 ) ) >>> 0 ;
2073
+ } ,
2074
+ "i32s-rem" : function ( x , y ) {
2075
+ return ( ( x | 0 ) % ( y | 0 ) ) | 0 ;
2076
+ } ,
2077
+ "i32u-rem" : function ( x , y ) {
2078
+ return ( ( x >>> 0 ) % ( y >>> 0 ) ) >>> 0 ;
2079
+ } ,
2080
+ "debugger" : function ( ) {
2081
+ debugger ;
2082
+ } ,
2083
+ } ;
2084
+
2085
+ var info = {
2086
+ 'global' : null ,
2087
+ 'env' : null ,
2088
+ 'asm2wasm' : asm2wasmImports ,
2089
+ 'parent' : Module // Module inside wasm-js.cpp refers to wasm-js.cpp; this allows access to the outside program.
2090
+ } ;
2091
+
2092
+ var exports = null ;
2093
+
2094
+ function lookupImport ( mod , base ) {
2095
+ var lookup = info ;
2096
+ if ( mod . indexOf ( '.' ) < 0 ) {
2097
+ lookup = ( lookup || { } ) [ mod ] ;
2098
+ } else {
2099
+ var parts = mod . split ( '.' ) ;
2100
+ lookup = ( lookup || { } ) [ parts [ 0 ] ] ;
2101
+ lookup = ( lookup || { } ) [ parts [ 1 ] ] ;
2102
+ }
2103
+ if ( base ) {
2104
+ lookup = ( lookup || { } ) [ base ] ;
2105
+ }
2106
+ if ( lookup === undefined ) {
2107
+ abort ( 'bad lookupImport to (' + mod + ').' + base ) ;
2108
+ }
2109
+ return lookup ;
2110
+ }
2111
+
2112
+ function mergeMemory ( newBuffer ) {
2113
+ // The wasm instance creates its memory. But static init code might have written to
2114
+ // buffer already, including the mem init file, and we must copy it over in a proper merge.
2115
+ // TODO: avoid this copy, by avoiding such static init writes
2116
+ // TODO: in shorter term, just copy up to the last static init write
2117
+ var oldBuffer = Module [ 'buffer' ] ;
2118
+ if ( newBuffer . byteLength < oldBuffer . byteLength ) {
2119
+ Module [ 'printErr' ] ( 'the new buffer in mergeMemory is smaller than the previous one. in native wasm, we should grow memory here' ) ;
2120
+ }
2121
+ var oldView = new Int8Array ( oldBuffer ) ;
2122
+ var newView = new Int8Array ( newBuffer ) ;
2123
+
2124
+ // If we have a mem init file, do not trample it
2125
+ if ( ! memoryInitializer ) {
2126
+ oldView . set ( newView . subarray ( Module [ 'STATIC_BASE' ] , Module [ 'STATIC_BASE' ] + Module [ 'STATIC_BUMP' ] ) , Module [ 'STATIC_BASE' ] ) ;
2127
+ }
2128
+
2129
+ newView . set ( oldView ) ;
2130
+ updateGlobalBuffer ( newBuffer ) ;
2131
+ updateGlobalBufferViews ( ) ;
2132
+ }
2133
+
2134
+ var WasmTypes = {
2135
+ none : 0 ,
2136
+ i32 : 1 ,
2137
+ i64 : 2 ,
2138
+ f32 : 3 ,
2139
+ f64 : 4
2140
+ } ;
2141
+
2142
+ function fixImports ( imports ) {
2143
+ if ( ! { { { WASM_BACKEND } } } ) return imports ;
2144
+ var ret = { } ;
2145
+ for ( var i in imports ) {
2146
+ var fixed = i ;
2147
+ if ( fixed [ 0 ] == '_' ) fixed = fixed . substr ( 1 ) ;
2148
+ ret [ fixed ] = imports [ i ] ;
2149
+ }
2150
+ return ret ;
2151
+ }
2152
+
2153
+ function getBinary ( ) {
2154
+ var binary ;
2155
+ if ( ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER ) {
2156
+ binary = Module [ 'wasmBinary' ] ;
2157
+ assert ( binary , "on the web, we need the wasm binary to be preloaded and set on Module['wasmBinary']. emcc.py will do that for you when generating HTML (but not JS)" ) ;
2158
+ binary = new Uint8Array ( binary ) ;
2159
+ } else {
2160
+ binary = Module [ 'readBinary' ] ( wasmBinaryFile ) ;
2161
+ }
2162
+ return binary ;
2163
+ }
2164
+
2165
+ // do-method functions
2166
+
2167
+ function doJustAsm ( global , env, providedBuffer ) {
2168
+ // if no Module.asm, or it's the method handler helper (see below), then apply
2169
+ // the asmjs
2170
+ if ( typeof Module [ 'asm' ] !== 'function' || Module [ 'asm' ] === methodHandler ) {
2171
+ if ( ! Module [ 'asmPreload' ] ) {
2172
+ // you can load the .asm.js file before this, to avoid this sync xhr and eval
2173
+ eval ( Module [ 'read' ] ( asmjsCodeFile ) ) ; // set Module.asm
2174
+ } else {
2175
+ Module [ 'asm' ] = Module [ 'asmPreload' ] ;
2176
+ }
2177
+ }
2178
+ if ( typeof Module [ 'asm '] !== 'function ') {
2179
+ Module [ 'printErr '] ( 'asm evalling did not set the module properly ') ;
2180
+ return false ;
2181
+ }
2182
+ return Module [ 'asm' ] ( global , env , providedBuffer ) ;
2183
+ }
2184
+
2185
+ function doNativeWasm ( global , env , providedBuffer ) {
2186
+ if ( typeof WebAssembly !== 'object' ) {
2187
+ Module [ 'printErr' ] ( 'no native wasm support detected' ) ;
2188
+ return false ;
2189
+ }
2190
+ // prepare memory import
2191
+ if ( ! ( Module [ 'wasmMemory' ] instanceof WebAssembly . Memory ) ) {
2192
+ Module [ 'printErr' ] ( 'no native wasm Memory in use' ) ;
2193
+ return false ;
2194
+ }
2195
+ env [ 'memory' ] = Module [ 'wasmMemory' ] ;
2196
+ // Load the wasm module and create an instance of using native support in the JS engine.
2197
+ info [ 'global' ] = {
2198
+ 'NaN' : NaN ,
2199
+ 'Infinity' : Infinity
2200
+ } ;
2201
+ info [ 'global.Math' ] = global . Math ;
2202
+ info [ 'env' ] = env ;
2203
+ var instance ;
2204
+ try {
2205
+ instance = new WebAssembly . Instance ( new WebAssembly . Module ( getBinary ( ) ) , info )
2206
+ } catch ( e ) {
2207
+ Module [ 'printErr' ] ( 'failed to compile wasm module: ' + e ) ;
2208
+ if ( e . toString ( ) . indexOf ( 'imported Memory with incompatible size' ) >= 0 ) {
2209
+ Module [ 'printErr' ] ( 'Memory size incompatibility issues may be due to changing TOTAL_MEMORY at runtime to something too large. Use ALLOW_MEMORY_GROWTH to allow any size memory (and also make sure not to set TOTAL_MEMORY at runtime to something smaller than it was at compile time).' ) ;
2210
+ }
2211
+ return false ;
2212
+ }
2213
+ exports = instance . exports ;
2214
+ if ( exports . memory ) mergeMemory ( exports . memory ) ;
2215
+
2216
+ Module [ "usingWasm" ] = true ;
2217
+
2218
+ return exports ;
2219
+ }
2220
+
2221
+ function doWasmPolyfill ( global , env , providedBuffer , method ) {
2222
+ if ( typeof WasmJS !== 'function' ) {
2223
+ Module [ 'printErr' ] ( 'WasmJS not detected - polyfill not bundled?' ) ;
2224
+ return false ;
2225
+ }
2226
+
2227
+ // Use wasm.js to polyfill and execute code in a wasm interpreter.
2228
+ var wasmJS = WasmJS ( { } ) ;
2229
+
2230
+ // XXX don't be confused. Module here is in the outside program. wasmJS is the inner wasm-js.cpp.
2231
+ wasmJS [ 'outside' ] = Module ; // Inside wasm-js.cpp, Module['outside'] reaches the outside module.
2232
+
2233
+ // Information for the instance of the module.
2234
+ wasmJS [ 'info' ] = info ;
2235
+
2236
+ wasmJS [ 'lookupImport' ] = lookupImport ;
2237
+
2238
+ assert ( providedBuffer === Module [ 'buffer' ] ) ; // we should not even need to pass it as a 3rd arg for wasm, but that's the asm.js way.
2239
+
2240
+ info . global = global ;
2241
+ info . env = env ;
2242
+
2243
+ // polyfill interpreter expects an ArrayBuffer
2244
+ assert ( providedBuffer === Module [ 'buffer' ] ) ;
2245
+ env [ 'memory' ] = providedBuffer ;
2246
+ assert ( env [ 'memory' ] instanceof ArrayBuffer ) ;
2247
+
2248
+ wasmJS [ 'providedTotalMemory' ] = Module [ 'buffer' ] . byteLength ;
2249
+
2250
+ // Prepare to generate wasm, using either asm2wasm or s-exprs
2251
+ var code ;
2252
+ if ( method === 'interpret-binary' ) {
2253
+ code = getBinary ( ) ;
2254
+ } else {
2255
+ code = Module [ 'read' ] ( method == 'interpret-asm2wasm' ? asmjsCodeFile : wasmTextFile ) ;
2256
+ }
2257
+ var temp ;
2258
+ if ( method == 'interpret-asm2wasm' ) {
2259
+ temp = wasmJS [ '_malloc' ] ( code . length + 1 ) ;
2260
+ wasmJS [ 'writeAsciiToMemory' ] ( code , temp ) ;
2261
+ wasmJS [ '_load_asm2wasm' ] ( temp ) ;
2262
+ } else if ( method === 'interpret-s-expr' ) {
2263
+ temp = wasmJS [ '_malloc' ] ( code . length + 1 ) ;
2264
+ wasmJS [ 'writeAsciiToMemory' ] ( code , temp ) ;
2265
+ wasmJS [ '_load_s_expr2wasm' ] ( temp ) ;
2266
+ } else if ( method === 'interpret-binary' ) {
2267
+ temp = wasmJS [ '_malloc' ] ( code . length ) ;
2268
+ wasmJS [ 'HEAPU8' ] . set ( code , temp ) ;
2269
+ wasmJS [ '_load_binary2wasm' ] ( temp , code . length ) ;
2270
+ } else {
2271
+ throw 'what? ' + method ;
2272
+ }
2273
+ wasmJS [ '_free' ] ( temp ) ;
2274
+
2275
+ wasmJS [ '_instantiate' ] ( temp ) ;
2276
+
2277
+ if ( Module [ 'newBuffer' ] ) {
2278
+ mergeMemory ( Module [ 'newBuffer' ] ) ;
2279
+ Module [ 'newBuffer' ] = null ;
2280
+ }
2281
+
2282
+ exports = wasmJS [ 'asmExports' ] ;
2283
+
2284
+ return exports ;
2285
+ }
2286
+
2287
+ // We may have a preloaded value in Module.asm, save it
2288
+ Module [ 'asmPreload' ] = Module [ 'asm' ] ;
2289
+
2290
+ // Memory growth integration code
2291
+ Module [ 'reallocBuffer' ] = function ( size ) {
2292
+ size = Math . ceil ( size / wasmPageSize ) * wasmPageSize ; // round up to wasm page size
2293
+ var old = Module [ 'buffer' ] ;
2294
+ var result = exports [ '__growWasmMemory' ] ( size / wasmPageSize ) ; // tiny wasm method that just does grow_memory
2295
+ if ( Module [ "usingWasm" ] ) {
2296
+ if ( result !== ( - 1 | 0 ) ) {
2297
+ // success in native wasm memory growth, get the buffer from the memory
2298
+ return Module [ 'buffer' ] = Module [ 'wasmMemory' ] . buffer ;
2299
+ } else {
2300
+ return null ;
2301
+ }
2302
+ } else {
2303
+ // in interpreter, we replace Module.buffer if we allocate
2304
+ return Module [ 'buffer' ] !== old ? Module [ 'buffer' ] : null ; // if it was reallocated, it changed
2305
+ }
2306
+ } ;
2307
+
2308
+ // Provide an "asm.js function" for the application, called to "link" the asm.js module. We instantiate
2309
+ // the wasm module at that time, and it receives imports and provides exports and so forth, the app
2310
+ // doesn't need to care that it is wasm or olyfilled wasm or asm.js.
2311
+
2312
+ Module [ 'asm' ] = function ( global , env , providedBuffer ) {
2313
+ global = fixImports ( global ) ;
2314
+ env = fixImports ( env ) ;
2315
+
2316
+ // import table
2317
+ if ( ! env [ 'table' ] ) {
2318
+ var TABLE_SIZE = Module [ 'wasmTableSize' ] ;
2319
+ if ( TABLE_SIZE === undefined ) TABLE_SIZE = 1024 ; // works in binaryen interpreter at least
2320
+ var MAX_TABLE_SIZE = Module [ 'wasmMaxTableSize' ] ;
2321
+ if ( typeof WebAssembly === 'object' && typeof WebAssembly . Table === 'function' ) {
2322
+ if ( MAX_TABLE_SIZE !== undefined ) {
2323
+ env [ 'table' ] = new WebAssembly . Table ( { initial : TABLE_SIZE , maximum : MAX_TABLE_SIZE , element : 'anyfunc' } ) ;
2324
+ } else {
2325
+ env [ 'table' ] = new WebAssembly . Table ( { initial : TABLE_SIZE , element : 'anyfunc' } ) ;
2326
+ }
2327
+ } else {
2328
+ env [ 'table' ] = new Array ( TABLE_SIZE ) ; // works in binaryen interpreter at least
2329
+ }
2330
+ Module [ 'wasmTable' ] = env [ 'table' ] ;
2331
+ }
2332
+
2333
+ if ( ! env [ 'memoryBase' ] ) {
2334
+ env [ 'memoryBase' ] = Module [ 'STATIC_BASE' ] ; // tell the memory segments where to place themselves
2335
+ }
2336
+ if ( ! env [ 'tableBase' ] ) {
2337
+ env [ 'tableBase' ] = 0 ; // table starts at 0 by default, in dynamic linking this will change
2338
+ }
2339
+
2340
+ // try the methods. each should return the exports if it succeeded
2341
+
2342
+ var exports ;
2343
+ var methods = method . split ( ',' ) ;
2344
+
2345
+ for ( var i = 0 ; i < methods . length ; i ++ ) {
2346
+ var curr = methods [ i ] ;
2347
+
2348
+ Module [ 'printErr' ] ( 'trying binaryen method: ' + curr ) ;
2349
+
2350
+ if ( curr === 'native-wasm' ) {
2351
+ if ( exports = doNativeWasm ( global , env , providedBuffer ) ) break ;
2352
+ } else if ( curr === 'asmjs' ) {
2353
+ if ( exports = doJustAsm ( global , env , providedBuffer ) ) break ;
2354
+ } else if ( curr === 'interpret-asm2wasm' || curr === 'interpret-s-expr' || curr === 'interpret-binary' ) {
2355
+ if ( exports = doWasmPolyfill ( global , env , providedBuffer , curr ) ) break ;
2356
+ } else {
2357
+ throw 'bad method: ' + curr ;
2358
+ }
2359
+ }
2360
+
2361
+ if ( ! exports ) throw 'no binaryen method succeeded. consider enabling more options, like interpreting, if you want that: https://github.com/kripken/emscripten/wiki/WebAssembly#binaryen-methods' ;
2362
+
2363
+ Module [ 'printErr' ] ( 'binaryen method succeeded.' ) ;
2364
+
2365
+ return exports ;
2366
+ } ;
2367
+
2368
+ var methodHandler = Module [ 'asm' ] ; // note our method handler, as we may modify Module['asm'] later
2369
+ }
2370
+
2371
+ integrateWasmJS ( Module ) ;
2372
+ #endif
2373
+
2035
2374
// === Body ===
0 commit comments