@@ -645,7 +645,7 @@ function getBinarySync(file) {
645645#endif
646646}
647647
648- function getBinaryPromise ( binaryFile ) {
648+ async function getWasmBinary ( binaryFile ) {
649649#if ! SINGLE_FILE
650650 // If we don't have the binary yet, load it asynchronously using readAsync.
651651 if ( ! wasmBinary
@@ -654,16 +654,18 @@ function getBinaryPromise(binaryFile) {
654654#endif
655655 ) {
656656 // Fetch the binary using readAsync
657- return readAsync ( binaryFile ) . then (
658- ( response ) => new Uint8Array ( /** @type {!ArrayBuffer } */ ( response ) ) ,
659- // Fall back to getBinarySync if readAsync fails
660- ( ) => getBinarySync ( binaryFile )
661- ) ;
657+ try {
658+ /** @type {!ArrayBuffer } */
659+ var response = await readAsync ( binaryFile ) ;
660+ return new Uint8Array ( response ) ;
661+ } catch {
662+ // Fall back to getBinarySync below;
663+ }
662664 }
663665#endif
664666
665667 // Otherwise, getBinarySync should be able to get it synchronously
666- return Promise . resolve ( ) . then ( ( ) => getBinarySync ( binaryFile ) ) ;
668+ return getBinarySync ( binaryFile ) ;
667669}
668670
669671#if LOAD_SOURCE_MAP
@@ -771,56 +773,47 @@ function resetPrototype(constructor, attrs) {
771773#endif
772774
773775#if WASM_ASYNC_COMPILATION
774- function instantiateArrayBuffer ( binaryFile , imports ) {
776+ async function instantiateArrayBuffer ( binaryFile , imports ) {
777+ try {
778+ var binary = await getWasmBinary ( binaryFile ) ;
779+ var instance = await WebAssembly . instantiate ( binary , imports ) ;
775780#if USE_OFFSET_CONVERTER
776- var savedBinary ;
781+ // wasmOffsetConverter needs to be assigned before calling resolve.
782+ // See comments below in instantiateAsync.
783+ wasmOffsetConverter = new WasmOffsetConverter ( binary , instance . module ) ;
777784#endif
778- return new Promise ( ( resolve , reject ) => {
779- getBinaryPromise ( binaryFile ) . then ( ( binary ) => {
780- #if USE_OFFSET_CONVERTER
781- savedBinary = binary ;
782- #endif
783- return WebAssembly . instantiate ( binary , imports ) ;
784- #if USE_OFFSET_CONVERTER
785- } ) . then ( ( instance ) => {
786- // wasmOffsetConverter needs to be assigned before calling resolve.
787- // See comments below in instantiateAsync.
788- wasmOffsetConverter = new WasmOffsetConverter ( savedBinary , instance . module ) ;
789- return instance ;
790- #endif
791- } ) . then ( resolve , ( reason ) => {
792- err ( `failed to asynchronously prepare wasm: ${ reason } ` ) ;
793-
785+ return instance ;
786+ } catch ( reason ) {
787+ err ( `failed to asynchronously prepare wasm: ${ reason } ` ) ;
794788#if WASM == 2
795789#if ENVIRONMENT_MAY_BE_NODE || ENVIRONMENT_MAY_BE_SHELL
796- if ( typeof location != 'undefined' ) {
797- #endif
798- // WebAssembly compilation failed, try running the JS fallback instead.
799- var search = location . search ;
800- if ( search . indexOf ( '_rwasm=0' ) < 0 ) {
801- location . href += ( search ? search + '&' : '?' ) + '_rwasm=0' ;
802- // Return here to avoid calling abort() below. The application
803- // still has a chance to start successfully do we don't want to
804- // trigger onAbort or onExit handlers.
805- return ;
806- }
807- #if ENVIRONMENT_MAY_BE_NODE || ENVIRONMENT_MAY_BE_SHELL
790+ if ( typeof location != 'undefined' ) {
791+ #endif
792+ // WebAssembly compilation failed, try running the JS fallback instead.
793+ var search = location . search ;
794+ if ( search . indexOf ( '_rwasm=0' ) < 0 ) {
795+ location . href += ( search ? search + '&' : '?' ) + '_rwasm=0' ;
796+ // Return here to avoid calling abort() below. The application
797+ // still has a chance to start successfully do we don't want to
798+ // trigger onAbort or onExit handlers.
799+ return ;
808800 }
801+ #if ENVIRONMENT_MAY_BE_NODE || ENVIRONMENT_MAY_BE_SHELL
802+ }
809803#endif
810804#endif // WASM == 2
811805
812806#if ASSERTIONS
813- // Warn on some common problems.
814- if ( isFileURI ( wasmBinaryFile ) ) {
815- err ( `warning: Loading from a file URI (${ wasmBinaryFile } ) is not supported in most browsers. See https://emscripten.org/docs/getting_started/FAQ.html#how-do-i-run-a-local-webserver-for-testing-why-does-my-program-stall-in-downloading-or-preparing` ) ;
816- }
807+ // Warn on some common problems.
808+ if ( isFileURI ( wasmBinaryFile ) ) {
809+ err ( `warning: Loading from a file URI (${ wasmBinaryFile } ) is not supported in most browsers. See https://emscripten.org/docs/getting_started/FAQ.html#how-do-i-run-a-local-webserver-for-testing-why-does-my-program-stall-in-downloading-or-preparing` ) ;
810+ }
817811#endif
818- abort ( reason ) ;
819- } ) ;
820- } ) ;
812+ abort ( reason ) ;
813+ }
821814}
822815
823- function instantiateAsync ( binary , binaryFile , imports ) {
816+ async function instantiateAsync ( binary , binaryFile , imports ) {
824817#if ! SINGLE_FILE
825818 if ( ! binary &&
826819 typeof WebAssembly . instantiateStreaming == 'function' &&
@@ -839,56 +832,51 @@ function instantiateAsync(binary, binaryFile, imports) {
839832 ! ENVIRONMENT_IS_NODE &&
840833#endif
841834 typeof fetch == 'function' ) {
842- return new Promise ( ( resolve ) => {
843- fetch ( binaryFile , { { { makeModuleReceiveExpr ( 'fetchSettings' , "{ credentials: 'same-origin' }" ) } } } ) . then ( ( response ) => {
844- // Suppress closure warning here since the upstream definition for
845- // instantiateStreaming only allows Promise<Repsponse> rather than
846- // an actual Response.
847- // TODO(https://github.com/google/closure-compiler/pull/3913): Remove if/when upstream closure is fixed.
848- /** @suppress {checkTypes} */
849- var result = WebAssembly . instantiateStreaming ( response , imports ) ;
835+ try {
836+ var response = await fetch ( binaryFile , { { { makeModuleReceiveExpr ( 'fetchSettings' , "{ credentials: 'same-origin' }" ) } } } ) ;
837+ // Suppress closure warning here since the upstream definition for
838+ // instantiateStreaming only allows Promise<Repsponse> rather than
839+ // an actual Response.
840+ // TODO(https://github.com/google/closure-compiler/pull/3913): Remove if/when upstream closure is fixed.
841+ /** @suppress {checkTypes} */
842+ var result = WebAssembly . instantiateStreaming ( response , imports ) ;
850843
851844#if USE_OFFSET_CONVERTER
852- // We need the wasm binary for the offset converter. Clone the response
853- // in order to get its arrayBuffer (cloning should be more efficient
854- // than doing another entire request).
855- // (We must clone the response now in order to use it later, as if we
856- // try to clone it asynchronously lower down then we will get a
857- // "response was already consumed" error.)
858- var clonedResponsePromise = response . clone ( ) . arrayBuffer ( ) ;
845+ // We need the wasm binary for the offset converter. Clone the response
846+ // in order to get its arrayBuffer (cloning should be more efficient
847+ // than doing another entire request).
848+ // (We must clone the response now in order to use it later, as if we
849+ // try to clone it asynchronously lower down then we will get a
850+ // "response was already consumed" error.)
851+ var clonedResponsePromise = response . clone ( ) . arrayBuffer ( ) ;
859852#endif
860853
861- result . then (
862854#if USE_OFFSET_CONVERTER
863- ( instantiationResult ) => {
864- // When using the offset converter, we must interpose here. First,
865- // the instantiation result must arrive (if it fails, the error
866- // handling later down will handle it). Once it arrives, we can
867- // initialize the offset converter. And only then is it valid to
868- // call receiveInstantiationResult, as that function will use the
869- // offset converter (in the case of pthreads, it will create the
870- // pthreads and send them the offsets along with the wasm instance).
871-
872- clonedResponsePromise . then ( ( arrayBufferResult ) => {
873- wasmOffsetConverter = new WasmOffsetConverter ( new Uint8Array ( arrayBufferResult ) , instantiationResult . module ) ;
874- resolve ( instantiationResult ) ;
875- } ,
876- ( reason ) => err ( `failed to initialize offset-converter: ${ reason } ` )
877- ) ;
878- } ,
879- #else
880- resolve ,
881- #endif
882- ( reason ) => {
883- // We expect the most common failure cause to be a bad MIME type for the binary,
884- // in which case falling back to ArrayBuffer instantiation should work.
885- err ( `wasm streaming compile failed: ${ reason } ` ) ;
886- err ( 'falling back to ArrayBuffer instantiation' ) ;
887- return resolve ( instantiateArrayBuffer ( binaryFile , imports ) ) ;
888- }
889- ) ;
890- } ) ;
891- } ) ;
855+ var instantiationResult = await result ;
856+ // When using the offset converter, we must interpose here. First,
857+ // the instantiation result must arrive (if it fails, the error
858+ // handling later down will handle it). Once it arrives, we can
859+ // initialize the offset converter. And only then is it valid to
860+ // call receiveInstantiationResult, as that function will use the
861+ // offset converter (in the case of pthreads, it will create the
862+ // pthreads and send them the offsets along with the wasm instance).
863+
864+ var arrayBufferResult = await clonedResponsePromise ;
865+ try {
866+ wasmOffsetConverter = new WasmOffsetConverter ( new Uint8Array ( arrayBufferResult ) , instantiationResult . module ) ;
867+ resolve ( instantiationResult ) ;
868+ } catch ( reason ) {
869+ ( reason ) => err ( `failed to initialize offset-converter: ${ reason } ` )
870+ }
871+ #endif
872+ return result ;
873+ } catch ( reason ) {
874+ // We expect the most common failure cause to be a bad MIME type for the binary,
875+ // in which case falling back to ArrayBuffer instantiation should work.
876+ err ( `wasm streaming compile failed: ${ reason } ` ) ;
877+ err ( 'falling back to ArrayBuffer instantiation' ) ;
878+ return instantiateArrayBuffer ( binaryFile , imports ) ;
879+ } ;
892880 }
893881#endif
894882 return instantiateArrayBuffer ( binaryFile , imports ) ;
@@ -934,7 +922,13 @@ function getWasmImports() {
934922
935923// Create the wasm instance.
936924// Receives the wasm imports, returns the exports.
925+ #if WASM_ASYNC_COMPILATION
926+ // Funnily enough in JS the `async` keyword has to be on the same line as the
927+ // function keyword.
928+ async function createWasm ( ) {
929+ #else
937930function createWasm ( ) {
931+ #endif
938932 // Load the wasm module and create an instance of using native support in the JS engine.
939933 // handle a generated wasm instance, receiving its exports and
940934 // performing other necessary setup
@@ -1102,17 +1096,23 @@ function createWasm() {
11021096#if RUNTIME_DEBUG
11031097 dbg ( 'asynchronously preparing wasm' ) ;
11041098#endif
1105- instantiateAsync ( wasmBinary , wasmBinaryFile , info ) . then ( receiveInstantiationResult )
11061099#if MODULARIZE
1107- // If instantiation fails, reject the module ready promise.
1108- . catch ( readyPromiseReject )
1100+ try {
11091101#endif
1110- ;
1102+ var result = await instantiateAsync ( wasmBinary , wasmBinaryFile , info ) ;
1103+ receiveInstantiationResult ( result ) ;
11111104#if LOAD_SOURCE_MAP
1112- getSourceMapPromise ( ) . then ( receiveSourceMapJSON ) ;
1105+ receiveSourceMapJSON ( await getSourceMapPromise ( ) ) ;
11131106#endif
1114- return { } ; // no exports yet; we'll fill them in later
1115- #else
1107+ return result ;
1108+ #if MODULARIZE
1109+ } catch ( e ) {
1110+ // If instantiation fails, reject the module ready promise.
1111+ readyPromiseReject ( e ) ;
1112+ throw e ;
1113+ }
1114+ #endif
1115+ #else // WASM_ASYNC_COMPILATION
11161116 var result = instantiateSync ( wasmBinaryFile , info ) ;
11171117#if PTHREADS || MAIN_MODULE
11181118 return receiveInstance ( result [ 0 ] , result [ 1 ] ) ;
@@ -1122,7 +1122,7 @@ function createWasm() {
11221122 // When the regression is fixed, we can remove this if/else.
11231123 return receiveInstance ( result [ 0 ] ) ;
11241124#endif
1125- #endif
1125+ #endif // WASM_ASYNC_COMPILATION
11261126}
11271127
11281128#if ! WASM_BIGINT
0 commit comments