@@ -198,6 +198,11 @@ function callFunc(func) {
198198 return func . apply ( null , args ) ;
199199}
200200
201+ // wasm2js does not define RuntimeError, so use that to check for it. wasm2js
202+ // overrides the entire WebAssembly object with a polyfill, so we know exactly
203+ // what it contains, and we need to handle some things differently below.
204+ var wasm2js = ! WebAssembly . RuntimeError ;
205+
201206// Calls a given function in a try-catch. Return 1 if an exception was thrown.
202207// If |rethrow| is set, and an exception is thrown, it is caught and rethrown.
203208// Wasm traps are not swallowed (see details below).
@@ -213,11 +218,7 @@ function callFunc(func) {
213218
214219 // We only want to catch exceptions, not wasm traps: traps should still
215220 // halt execution. Handling this requires different code in wasm2js, so
216- // check for that first (wasm2js does not define RuntimeError, so use
217- // that for the check - when wasm2js is run, we override the entire
218- // WebAssembly object with a polyfill, so we know exactly what it
219- // contains).
220- var wasm2js = ! WebAssembly . RuntimeError ;
221+ // check for that first.
221222 if ( ! wasm2js ) {
222223 // When running native wasm, we can detect wasm traps.
223224 if ( e instanceof WebAssembly . RuntimeError ) {
@@ -555,13 +556,55 @@ function build(binary, isSecond) {
555556 name = e ;
556557 value = exports [ e ] ;
557558 } else {
558- // We are given an object form exportList, which has both a name and a
559+ // We are given an object from exportList, which has both a name and a
559560 // value.
560561 name = e . name ;
561562 value = e . value ;
562563 }
563564
565+ // Check for a global. Note we must be careful in wasm2js mode, where we
566+ // can't do instanceof here (the wasm polyfill there doesn't have such
567+ // things). In wasm2js we strip global exports to avoid needing to handle
568+ // them here (using stub-unsupported-js).
569+ if ( ! wasm2js && ( value instanceof WebAssembly . Global ) ) {
570+ // We can log a global value and do other operations to check for bugs.
571+ // First, do some operations on the Global wrapper itself.
572+ JSON . stringify ( value ) ;
573+ value . foobar ;
574+
575+ // Log it at the right time later using a lambda. Note that we can't just
576+ // capture |value| for the lambda, as the loop modifies it.
577+ ( ( ) => {
578+ var global = value ;
579+ value = ( ) => {
580+ // Time to log. Look at the exported value itself, not the global
581+ // wrapper.
582+ let actualValue ;
583+ try {
584+ actualValue = global . value ;
585+ } catch ( e ) {
586+ if ( e . message . startsWith ( 'get WebAssembly.Global.value' ) ) {
587+ // Just log a string instead of a value we cannot access from JS,
588+ // like an exnref. Note we don't need matching code on the C++
589+ // side in execution-results.h because illegal exports are pruned
590+ // anyhow if we are going to compare execution in JS to C++.
591+ actualValue = '<illegal value>' ;
592+ } else {
593+ throw e ;
594+ }
595+ }
596+ if ( typeof actualValue === 'object' ) {
597+ // logRef can do a little more than logValue, so use it when possible.
598+ logRef ( actualValue ) ;
599+ } else {
600+ logValue ( actualValue ) ;
601+ }
602+ } ;
603+ } ) ( ) ;
604+ }
605+
564606 if ( typeof value !== 'function' ) {
607+ // Nothing we can call.
565608 continue ;
566609 }
567610
0 commit comments