Skip to content

Commit 400a1f6

Browse files
authored
Remove WASM2C option (#19380)
This was very useful for me personally in exploring the options in the wasm2c space, and in benchmarking in particular, for: https://kripken.github.io/blog/wasm/2020/07/27/wasmboxc.html At this time, however, all known users of wasm2c are using upstream wasm2c from wabt directly. And the benefits of emscripten's integration are diminishing as features like wasm-EH remove the need for emscripten-EH (which wasm2c supported here). So we might as well remove this option to get rid of the complexity, since this is already quite behind upstream wasm2c, and the work to update it is not trival, and not worth it given the lack of users.
1 parent 89c2932 commit 400a1f6

16 files changed

+9
-1056
lines changed

ChangeLog.md

+2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ See docs/process.md for more on how version tagging works.
2323
- The JS `err()` function will now bind to `console.error` by default rather
2424
than `console.warning`. For debugging/tracing/logging we recommend the
2525
`dbg()` function instead. (#19326)
26+
- The `WASM2C` options has been removed. All known users are using upstream wabt
27+
these days anyhow.
2628

2729
3.1.38 - 05/10/23
2830
-----------------

emcc.py

-13
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@
5151
import tools.line_endings
5252
from tools import feature_matrix
5353
from tools import js_manipulation
54-
from tools import wasm2c
5554
from tools import webassembly
5655
from tools import config
5756
from tools import cache
@@ -1898,15 +1897,6 @@ def phase_linker_setup(options, state, newargs):
18981897
settings.STANDALONE_WASM = 1
18991898
settings.WASM_BIGINT = 1
19001899

1901-
if settings.WASM2C:
1902-
# wasm2c only makes sense with standalone wasm - there will be no JS,
1903-
# just wasm and then C
1904-
settings.STANDALONE_WASM = 1
1905-
# wasm2c doesn't need any special handling of i64, we have proper i64
1906-
# handling on the FFI boundary, which is exactly like the case of JS with
1907-
# BigInt support
1908-
settings.WASM_BIGINT = 1
1909-
19101900
if options.no_entry:
19111901
settings.EXPECT_MAIN = 0
19121902
elif settings.STANDALONE_WASM:
@@ -3803,9 +3793,6 @@ def preprocess_wasm2js_script():
38033793
if settings.DEBUG_LEVEL >= 3 and settings.SEPARATE_DWARF and os.path.exists(wasm_target):
38043794
building.emit_debug_on_side(wasm_target)
38053795

3806-
if settings.WASM2C:
3807-
wasm2c.do_wasm2c(wasm_target)
3808-
38093796
# we have finished emitting the wasm, and so intermediate debug info will
38103797
# definitely no longer be used tracking it.
38113798
if debug_info:

package-lock.json

+1-12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-2
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@
1313
"dependencies": {
1414
"acorn": "^8.7.1",
1515
"google-closure-compiler": "20220502.0.0",
16-
"html-minifier-terser": "7.2.0",
17-
"wasm2c": "1.0.0"
16+
"html-minifier-terser": "7.2.0"
1817
},
1918
"scripts": {
2019
"lint": "eslint .",

src/settings.js

-19
Original file line numberDiff line numberDiff line change
@@ -1933,25 +1933,6 @@ var DEFAULT_TO_CXX = true;
19331933
// [link]
19341934
var PRINTF_LONG_DOUBLE = false;
19351935

1936-
// Run wabt's wasm2c tool on the final wasm, and combine that with a C runtime,
1937-
// resulting in a .c file that you can compile with a C compiler to get a
1938-
// native executable that works the same as the normal js+wasm. This will also
1939-
// emit the wasm2c .h file. The output filenames will be X.wasm.c, X.wasm.h
1940-
// if your output is X.js or X.wasm (note the added .wasm. we make sure to emit,
1941-
// which avoids trampling a C file).
1942-
// [link]
1943-
// [experimental]
1944-
var WASM2C = false;
1945-
1946-
// Experimental sandboxing mode, see
1947-
// https://kripken.github.io/blog/wasm/2020/07/27/wasmboxc.html
1948-
//
1949-
// * full: Normal full wasm2c sandboxing. This uses a signal handler if it can.
1950-
// * mask: Masks loads and stores.
1951-
// * none: No sandboxing at all.
1952-
// [experimental]
1953-
var WASM2C_SANDBOXING = 'full';
1954-
19551936
// Setting this affects the path emitted in the wasm that refers to the DWARF
19561937
// file, in -gseparate-dwarf mode. This allows the debugging file to be hosted
19571938
// in a custom location.

test/common.py

-9
Original file line numberDiff line numberDiff line change
@@ -1383,15 +1383,6 @@ def _build_and_run(self, filename, expected_output, args=None, output_nicerizer=
13831383
if not self.wasm_engines:
13841384
logger.warning('no wasm engine was found to run the standalone part of this test')
13851385
engines += self.wasm_engines
1386-
if self.get_setting('WASM2C') and not EMTEST_LACKS_NATIVE_CLANG:
1387-
# compile the c file to a native executable.
1388-
c = shared.replace_suffix(js_file, '.wasm.c')
1389-
executable = shared.replace_suffix(js_file, '.exe')
1390-
cmd = [shared.CLANG_CC, c, '-o', executable] + clang_native.get_clang_native_args()
1391-
self.run_process(cmd, env=clang_native.get_clang_native_env())
1392-
# we can now run the executable directly, without an engine, which
1393-
# we indicate with None as the engine
1394-
engines += [[None]]
13951386
if len(engines) == 0:
13961387
self.skipTest('No JS engine present to run this test with. Check %s and the paths therein.' % config.EM_CONFIG)
13971388
for engine in engines:

test/test_benchmark.py

-42
Original file line numberDiff line numberDiff line change
@@ -244,47 +244,6 @@ def get_output_files(self):
244244
return ret
245245

246246

247-
class EmscriptenWasm2CBenchmarker(EmscriptenBenchmarker):
248-
def __init__(self, name):
249-
super().__init__(name, 'no engine needed')
250-
251-
def build(self, parent, filename, args, shared_args, emcc_args, native_args, native_exec, lib_builder, has_output_parser):
252-
# wasm2c doesn't want minimal runtime which the normal emscripten
253-
# benchmarker defaults to, as we don't have any JS anyhow
254-
emcc_args = emcc_args + [
255-
'-sSTANDALONE_WASM',
256-
'-sMINIMAL_RUNTIME=0',
257-
'-sWASM2C'
258-
]
259-
260-
global LLVM_FEATURE_FLAGS
261-
old_flags = LLVM_FEATURE_FLAGS
262-
try:
263-
# wasm2c does not support anything beyond MVP
264-
LLVM_FEATURE_FLAGS = []
265-
super().build(parent, filename, args, shared_args, emcc_args, native_args, native_exec, lib_builder, has_output_parser)
266-
finally:
267-
LLVM_FEATURE_FLAGS = old_flags
268-
269-
# move the JS away so there is no chance we run it by mistake
270-
shutil.move(self.filename, self.filename + '.old.js')
271-
272-
c = shared.replace_suffix(self.filenmame, '.wasm.c')
273-
native = shared.replace_suffix(self.filenmame, '.exe')
274-
275-
run_process(['clang', c, '-o', native, OPTIMIZATIONS, '-lm',
276-
'-DWASM_RT_MAX_CALL_STACK_DEPTH=8000']) # for havlak
277-
278-
self.filename = native
279-
280-
def run(self, args):
281-
return run_process([self.filename] + args, stdout=PIPE, stderr=PIPE, check=False).stdout
282-
283-
def get_output_files(self):
284-
# return the native code. c size may also be interesting.
285-
return [self.filename]
286-
287-
288247
CHEERP_BIN = '/opt/cheerp/bin/'
289248

290249

@@ -375,7 +334,6 @@ def get_output_files(self):
375334
EmscriptenBenchmarker(default_v8_name, aot_v8),
376335
EmscriptenBenchmarker(default_v8_name + '-lto', aot_v8, ['-flto']),
377336
EmscriptenBenchmarker(default_v8_name + '-ctors', aot_v8, ['-sEVAL_CTORS']),
378-
# EmscriptenWasm2CBenchmarker('wasm2c')
379337
]
380338
if os.path.exists(CHEERP_BIN):
381339
benchmarkers += [

test/test_core.py

+5-37
Original file line numberDiff line numberDiff line change
@@ -154,11 +154,6 @@ def metafunc(self, rawfs):
154154
return metafunc
155155

156156

157-
def can_do_wasm2c(self):
158-
# the npm version of wasm2c does not support MEMORY64
159-
return not self.get_setting('MEMORY64')
160-
161-
162157
def can_do_standalone(self, impure=False):
163158
# Pure standalone engines don't support MEMORY64 yet. Even with MEMORY64=2 (lowered)
164159
# the WASI APIs that take pointer values don't have 64-bit variants yet.
@@ -202,7 +197,7 @@ def decorated(self):
202197

203198
# Impure means a test that cannot run in a wasm VM yet, as it is not 100%
204199
# standalone. We can still run them with the JS code though.
205-
def also_with_standalone_wasm(wasm2c=False, impure=False):
200+
def also_with_standalone_wasm(impure=False):
206201
def decorated(func):
207202
def metafunc(self, standalone):
208203
if not standalone:
@@ -221,11 +216,6 @@ def metafunc(self, standalone):
221216
self.wasm_engines = []
222217
self.node_args += shared.node_bigint_flags()
223218
func(self)
224-
if wasm2c and can_do_wasm2c(self):
225-
print('wasm2c')
226-
self.set_setting('WASM2C')
227-
self.wasm_engines = []
228-
func(self)
229219

230220
metafunc._parameterize = {'': (False,),
231221
'standalone': (True,)}
@@ -610,7 +600,7 @@ def test_cube2md5(self):
610600
shutil.copyfile(test_file('cube2md5.txt'), 'cube2md5.txt')
611601
self.do_run_from_file(test_file('cube2md5.cpp'), test_file('cube2md5.ok'), assert_returncode=NON_ZERO)
612602

613-
@also_with_standalone_wasm(wasm2c=True)
603+
@also_with_standalone_wasm()
614604
@needs_make('make')
615605
def test_cube2hash(self):
616606
# A good test of i64 math
@@ -1089,7 +1079,7 @@ def test_regex(self):
10891079
self.do_core_test('test_regex.c')
10901080

10911081
@crossplatform
1092-
@also_with_standalone_wasm(wasm2c=True, impure=True)
1082+
@also_with_standalone_wasm(impure=True)
10931083
def test_longjmp_standalone(self):
10941084
self.do_core_test('test_longjmp.c')
10951085

@@ -6304,7 +6294,7 @@ def test_unistd_misc(self, fs):
63046294
self.emcc_args += ['-lnodefs.js']
63056295
self.do_run_in_out_file_test('unistd/misc.c', interleaved_output=False)
63066296

6307-
@also_with_standalone_wasm(wasm2c=True)
6297+
@also_with_standalone_wasm()
63086298
def test_posixtime(self):
63096299
self.do_core_test('test_posixtime.c')
63106300

@@ -7122,7 +7112,7 @@ def do_test():
71227112
else:
71237113
do_test_openjpeg()
71247114

7125-
@also_with_standalone_wasm(wasm2c=True, impure=True)
7115+
@also_with_standalone_wasm(impure=True)
71267116
@no_asan('autodebug logging interferes with asan')
71277117
@with_env_modify({'EMCC_AUTODEBUG': '1'})
71287118
def test_autodebug_wasm(self):
@@ -7134,28 +7124,6 @@ def test_autodebug_wasm(self):
71347124
for msg in ['log_execution', 'get_i32', 'set_i32', 'load_ptr', 'load_val', 'store_ptr', 'store_val']:
71357125
self.assertIn(msg, output)
71367126

7137-
@parameterized({
7138-
'full': ('full',),
7139-
'mask': ('mask',),
7140-
'none': ('none',),
7141-
})
7142-
def test_wasm2c_sandboxing(self, mode):
7143-
if self.get_setting('WASMFS'):
7144-
# wasm2c disables JS legalization since we are building in standalone
7145-
# mode. this happens to work without wasmfs, but with wasmfs we get the
7146-
# time when we create/update a file, which uses clock_time_get that has an
7147-
# i64 param. For such an import to work we need wasm-bigint support.
7148-
self.node_args += shared.node_bigint_flags()
7149-
if not can_do_standalone(self):
7150-
return self.skipTest('standalone mode not supported')
7151-
if not can_do_wasm2c(self):
7152-
return self.skipTest('wasm2c not supported')
7153-
self.set_setting('STANDALONE_WASM')
7154-
self.set_setting('WASM2C')
7155-
self.set_setting('WASM2C_SANDBOXING', mode)
7156-
self.wasm_engines = []
7157-
self.do_core_test('test_hello_world.c')
7158-
71597127
### Integration tests
71607128

71617129
@crossplatform

test/test_other.py

-44
Original file line numberDiff line numberDiff line change
@@ -11189,50 +11189,6 @@ def test_standalone_syscalls(self):
1118911189
for engine in config.WASM_ENGINES:
1119011190
self.assertContained(expected, self.run_js('test.wasm', engine))
1119111191

11192-
@requires_native_clang
11193-
def test_wasm2c_reactor(self):
11194-
# test compiling an unsafe library using wasm2c, then using it from a
11195-
# main program. this shows it is easy to use wasm2c as a sandboxing
11196-
# mechanism.
11197-
11198-
# first compile the library with emcc, getting a .c and .h
11199-
self.run_process([EMCC,
11200-
test_file('other/wasm2c/unsafe-library.c'),
11201-
'-O3', '-o', 'lib.wasm', '-sWASM2C', '--no-entry'])
11202-
# compile the main program natively normally, together with the unsafe
11203-
# library
11204-
self.run_process([CLANG_CC,
11205-
test_file('other/wasm2c/my-code.c'),
11206-
'lib.wasm.c', '-O3', '-o', 'program.exe'] +
11207-
clang_native.get_clang_native_args(),
11208-
env=clang_native.get_clang_native_env())
11209-
output = self.run_process([os.path.abspath('program.exe')], stdout=PIPE).stdout
11210-
self.assertEqual(output, read_file(test_file('other/wasm2c/output.txt')))
11211-
11212-
@requires_native_clang
11213-
def test_wasm2c_multi_lib(self):
11214-
# compile two libraries to object files
11215-
for lib in ['a', 'b']:
11216-
self.run_process([EMCC,
11217-
test_file('other/wasm2c', f'unsafe-library-{lib}.c'),
11218-
'-O3', '-o', f'lib{lib}.wasm', '-sWASM2C', '--no-entry'])
11219-
# build with a different WASM_RT_MODULE_PREFIX for each library, so that
11220-
# they do not have colliding symbols
11221-
self.run_process([CLANG_CC, f'lib{lib}.wasm.c', '-O3', '-c',
11222-
f'-DWASM_RT_MODULE_PREFIX={lib}_'] +
11223-
clang_native.get_clang_native_args(),
11224-
env=clang_native.get_clang_native_env())
11225-
11226-
# compile the main program with the wasmboxed libraries
11227-
self.run_process([CLANG_CC,
11228-
test_file('other/wasm2c/my-code-multi.c'),
11229-
'liba.wasm.o', 'libb.wasm.o',
11230-
'-O3', '-o', 'program.exe'] +
11231-
clang_native.get_clang_native_args(),
11232-
env=clang_native.get_clang_native_env())
11233-
output = self.run_process([os.path.abspath('program.exe')], stdout=PIPE).stdout
11234-
self.assertEqual(output, read_file(test_file('other/wasm2c/output-multi.txt')))
11235-
1123611192
@parameterized({
1123711193
'wasm2js': (['-sWASM=0'], ''),
1123811194
'modularize': (['-sMODULARIZE'], 'Module()'),

0 commit comments

Comments
 (0)