@@ -1667,7 +1667,7 @@ def handle(self, wasm):
16671667 run ([in_bin ('wasm-opt' ), abspath ('a.wast' )] + FEATURE_OPTS )
16681668
16691669
1670- # The error shown when a module fails to instantiate.
1670+ # The error shown in V8 when a module fails to instantiate.
16711671INSTANTIATE_ERROR = 'exception thrown: failed to instantiate module'
16721672
16731673
@@ -1787,7 +1787,9 @@ def ensure(self):
17871787# anything. This is similar to Split(), but rather than split a wasm file into
17881788# two and link them at runtime, this starts with two separate wasm files.
17891789class Two (TestCaseHandler ):
1790- frequency = 0.2
1790+ # Run at relatively high priority, as this is the main place we check cross-
1791+ # module interactions.
1792+ frequency = 1
17911793
17921794 def handle (self , wasm ):
17931795 # Generate a second wasm file, unless we were given one (useful during
@@ -1798,56 +1800,48 @@ def handle(self, wasm):
17981800 # TODO: should we de-nan this etc. as with the primary?
17991801 shutil .copyfile (given , second_wasm )
18001802 else :
1803+ # generate a second wasm file to merge. pick a smaller size when
1804+ # the main wasm file is smaller, so reduction shrinks this too.
1805+ wasm_size = os .stat (wasm ).st_size
1806+ second_size = min (wasm_size , random_size ())
1807+
18011808 second_input = abspath ('second_input.dat' )
1802- make_random_input (random_size () , second_input )
1809+ make_random_input (second_size , second_input )
18031810 args = [second_input , '-ttf' , '-o' , second_wasm ]
18041811 # Most of the time, use the first wasm as an import to the second.
18051812 if random .random () < 0.8 :
18061813 args += ['--fuzz-import=' + wasm ]
18071814 run ([in_bin ('wasm-opt' )] + args + GEN_ARGS + FEATURE_OPTS )
18081815
1809- # The binaryen interpreter only supports a single file, so we run them
1810- # from JS using fuzz_shell.js's support for two files.
1816+ # Run the wasm.
18111817 #
18121818 # Note that we *cannot* run each wasm file separately and compare those
18131819 # to the combined output, as fuzz_shell.js intentionally allows calls
18141820 # *between* the wasm files, through JS APIs like call-export*. So all we
18151821 # do here is see the combined, linked behavior, and then later below we
18161822 # see that that behavior remains even after optimizations.
1817- output = run_d8_wasm (wasm , args = [second_wasm ])
1818-
1819- if output == IGNORE :
1820- # There is no point to continue since we can't compare this output
1821- # to anything.
1822- return
1823+ output = run_bynterp (wasm , args = ['--fuzz-exec-before' , f'--fuzz-exec-second={ second_wasm } ' ])
18231824
1824- if output .startswith (INSTANTIATE_ERROR ):
1825+ # Check if we trapped during instantiation.
1826+ if traps_in_instantiation (output ):
18251827 # We may fail to instantiate the modules for valid reasons, such as
18261828 # an active segment being out of bounds. There is no point to
18271829 # continue in such cases, as no exports are called.
1828-
1829- # But, check 'primary' is not in the V8 error. That might indicate a
1830- # problem in the imports of --fuzz-import. To do this, run the d8
1831- # command directly, without the usual filtering of run_d8_wasm.
1832- cmd = [shared .V8 ] + shared .V8_OPTS + get_v8_extra_flags () + [
1833- get_fuzz_shell_js (),
1834- '--' ,
1835- wasm ,
1836- second_wasm
1837- ]
1838- out = run (cmd )
1839- assert '"primary"' not in out , out
1840-
18411830 note_ignored_vm_run ('Two instantiate error' )
18421831 return
18431832
1844- # Make sure that fuzz_shell.js actually executed all exports from both
1833+ if output == IGNORE :
1834+ # There is no point to continue since we can't compare this output
1835+ # to anything.
1836+ return
1837+
1838+ # Make sure that we actually executed all exports from both
18451839 # wasm files.
18461840 exports = get_exports (wasm , ['func' ]) + get_exports (second_wasm , ['func' ])
18471841 calls_in_output = output .count (FUZZ_EXEC_CALL_PREFIX )
18481842 if calls_in_output == 0 :
18491843 print (f'warning: no calls in output. output:\n { output } ' )
1850- assert calls_in_output == len (exports )
1844+ assert calls_in_output == len (exports ), exports
18511845
18521846 output = fix_output (output )
18531847
@@ -1862,22 +1856,39 @@ def handle(self, wasm):
18621856 wasms [wasm_index ] = new_name
18631857
18641858 # Run again, and compare the output
1865- optimized_output = run_d8_wasm (wasms [0 ], args = [wasms [1 ]])
1859+ optimized_output = run_bynterp (wasms [0 ], args = ['--fuzz-exec-before' , f'--fuzz-exec-second= { wasms [1 ]} ' ])
18661860 optimized_output = fix_output (optimized_output )
18671861
18681862 compare (output , optimized_output , 'Two' )
18691863
1864+ # If we can, also test in V8. We also cannot compare if there are NaNs
1865+ # (as optimizations can lead to different outputs), and we must
1866+ # disallow some features.
1867+ # TODO: relax some of these
1868+ if NANS or not all_disallowed (['shared-everything' , 'strings' , 'stack-switching' ]):
1869+ return
1870+
1871+ output = run_d8_wasm (wasm , args = [second_wasm ])
1872+
1873+ if output == IGNORE :
1874+ return
1875+
1876+ # We ruled out things we must ignore, like host limitations, and also
1877+ # exited earlier on a deterministic instantiation error, so there should
1878+ # be no such error in V8.
1879+ assert not output .startswith (INSTANTIATE_ERROR )
1880+
1881+ output = fix_output (output )
1882+
1883+ optimized_output = run_d8_wasm (wasms [0 ], args = [wasms [1 ]])
1884+ optimized_output = fix_output (optimized_output )
1885+
1886+ compare (output , optimized_output , 'Two-V8' )
1887+
18701888 def can_run_on_wasm (self , wasm ):
18711889 # We cannot optimize wasm files we are going to link in closed world
1872- # mode. We also cannot run shared-everything code in d8 yet. We also
1873- # cannot compare if there are NaNs (as optimizations can lead to
1874- # different outputs).
1875- # TODO: relax some of these
1876- if CLOSED_WORLD :
1877- return False
1878- if NANS :
1879- return False
1880- return all_disallowed (['shared-everything' , 'strings' , 'stack-switching' ])
1890+ # mode.
1891+ return not CLOSED_WORLD
18811892
18821893
18831894# Test --fuzz-preserve-imports-exports, which never modifies imports or exports.
0 commit comments