Skip to content

Commit f5bc422

Browse files
committed
Incorporate suggestions from code review
* MEM_INIT_METHOD != 1 with --with-memory-file 1 now triggers an assertion * Consistently return '' instead of m.group(0) if there is no initializer * Strip trailing zeros for emterpreter as well * Include crc32 in literal only if it gets verified * Enable assertions for the asm2m test run in general * Disable assertions for one test case, fnmatch, to cover that as well * Include the asm2m run name in two lists of run modes * Add browser test to verify all pairs of bytes get encoded correctly * Add browser test to verify that a >32M initializer works without chunking * Omit duplicate var declaration for the memoryInitializer variable * Minor comments and syntax improvements * Capture the memory_init_file setting by its MEM_INIT_METHOD value. * Drop special handling for emterpreter, which shouldn't be needed any more.
1 parent e2d59af commit f5bc422

File tree

7 files changed

+84
-32
lines changed

7 files changed

+84
-32
lines changed

emcc

+27-26
Original file line numberDiff line numberDiff line change
@@ -1291,8 +1291,8 @@ try:
12911291
extra_args = [] if not js_libraries else ['--libraries', ','.join(map(os.path.abspath, js_libraries))]
12921292
if memory_init_file:
12931293
shared.Settings.MEM_INIT_METHOD = 1
1294-
elif shared.Settings.MEM_INIT_METHOD == 1:
1295-
shared.Settings.MEM_INIT_METHOD = 0
1294+
else:
1295+
assert shared.Settings.MEM_INIT_METHOD != 1
12961296
final = shared.Building.emscripten(final, append_ext=False, extra_args=extra_args)
12971297
if DEBUG: save_intermediate('original')
12981298

@@ -1344,46 +1344,47 @@ try:
13441344

13451345
js_transform_tempfiles = [final]
13461346

1347-
if memory_init_file or shared.Settings.MEM_INIT_METHOD == 2:
1347+
if shared.Settings.MEM_INIT_METHOD > 0:
13481348
memfile = target + '.mem'
13491349
shared.try_delete(memfile)
13501350
def repl(m):
13511351
# handle chunking of the memory initializer
1352-
s = m.groups(0)[0]
1353-
if len(s) == 0 and not shared.Settings.EMTERPRETIFY: return m.group(0) # emterpreter must have a mem init file; otherwise, don't emit 0-size ones
1352+
s = m.group(1)
1353+
if len(s) == 0: return '' # don't emit 0-size ones
13541354
membytes = [int(x or '0') for x in s.split(',')]
1355-
if not shared.Settings.EMTERPRETIFY:
1356-
while membytes and membytes[-1] == 0:
1357-
membytes.pop()
1358-
if not membytes:
1359-
return '';
1355+
while membytes and membytes[-1] == 0:
1356+
membytes.pop()
1357+
if not membytes: return ''
13601358
if not memory_init_file:
1361-
crcTable = []
1362-
for i in range(256):
1363-
crc = i
1364-
for bit in range(8):
1365-
crc = (crc >> 1) ^ ((crc & 1) * 0xedb88320)
1366-
crcTable.append(crc)
1367-
crc = 0xffffffff
1359+
# memory initializer in a string literal
13681360
s = list(membytes)
1369-
n = len(s)
1370-
crc = crcTable[(crc ^ n) & 0xff] ^ (crc >> 8)
1371-
crc = crcTable[(crc ^ (n >> 8)) & 0xff] ^ (crc >> 8)
1372-
for i in s:
1373-
crc = crcTable[(crc ^ i) & 0xff] ^ (crc >> 8)
1374-
for i in range(4):
1375-
s.append((crc >> (8 * i)) & 0xff)
1361+
if shared.Settings.ASSERTIONS:
1362+
# append checksum of length and content
1363+
crcTable = []
1364+
for i in range(256):
1365+
crc = i
1366+
for bit in range(8):
1367+
crc = (crc >> 1) ^ ((crc & 1) * 0xedb88320)
1368+
crcTable.append(crc)
1369+
crc = 0xffffffff
1370+
n = len(s)
1371+
crc = crcTable[(crc ^ n) & 0xff] ^ (crc >> 8)
1372+
crc = crcTable[(crc ^ (n >> 8)) & 0xff] ^ (crc >> 8)
1373+
for i in s:
1374+
crc = crcTable[(crc ^ i) & 0xff] ^ (crc >> 8)
1375+
for i in range(4):
1376+
s.append((crc >> (8 * i)) & 0xff)
13761377
s = ''.join(map(chr, s))
13771378
s = s.replace('\\', '\\\\').replace("'", "\\'")
13781379
s = s.replace('\n', '\\n').replace('\r', '\\r')
13791380
def escape(x): return '\\x{:02x}'.format(ord(x.group()))
13801381
s = re.sub('[\x80-\xff]', escape, s)
1381-
return "var memoryInitializer = '%s';" % s
1382+
return "memoryInitializer = '%s';" % s
13821383
open(memfile, 'wb').write(''.join(map(chr, membytes)))
13831384
if DEBUG:
13841385
# Copy into temp dir as well, so can be run there too
13851386
shared.safe_copy(memfile, os.path.join(shared.get_emscripten_temp_dir(), os.path.basename(memfile)))
1386-
return 'var memoryInitializer = "%s";' % os.path.basename(memfile)
1387+
return 'memoryInitializer = "%s";' % os.path.basename(memfile)
13871388
src = re.sub(shared.JS.memory_initializer_pattern, repl, open(final).read(), count=1)
13881389
open(final + '.mem.js', 'w').write(src)
13891390
final += '.mem.js'

src/postamble.js

+6-3
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ if (memoryInitializer && !ENVIRONMENT_IS_PTHREAD) (function(s) {
77
#else
88
if (memoryInitializer) (function(s) {
99
#endif
10-
var i, n = s.length - 4;
10+
var i, n = s.length;
1111
#if ASSERTIONS
12+
n -= 4;
1213
var crc, bit, table = new Int32Array(256);
1314
for (i = 0; i < 256; ++i) {
1415
for (crc = i, bit = 0; bit < 8; ++bit)
@@ -18,12 +19,14 @@ if (memoryInitializer) (function(s) {
1819
crc = -1;
1920
crc = table[(crc ^ n) & 0xff] ^ (crc >>> 8);
2021
crc = table[(crc ^ (n >>> 8)) & 0xff] ^ (crc >>> 8);
21-
for (i = 0; i < s.length; ++i)
22+
for (i = 0; i < s.length; ++i) {
2223
crc = table[(crc ^ s.charCodeAt(i)) & 0xff] ^ (crc >>> 8);
24+
}
2325
assert(crc === 0, "memory initializer checksum");
2426
#endif
25-
for (i = 0; i < n; ++i)
27+
for (i = 0; i < n; ++i) {
2628
HEAPU8[STATIC_BASE + i] = s.charCodeAt(i);
29+
}
2730
})(memoryInitializer);
2831
#else
2932
#if MEM_INIT_METHOD == 1

tests/meminit_pairs.c

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
unsigned char problematic[] = { 0x20, 0x7c, 0x02, 0x07, 0x5f, 0xa0, 0xdf };
2+
int main() {
3+
unsigned char a, b;
4+
int result = 0, i, j;
5+
for (i = 0; i < sizeof(problematic); ++i) {
6+
a = problematic[i] ^ 32;
7+
for (j = 0; j < sizeof(problematic); ++j) {
8+
b = problematic[j] ^ 32;
9+
if (((const unsigned char)data[a][2*b]) != a ||
10+
((const unsigned char)data[a][2*b + 1]) != b) {
11+
result = 1;
12+
printf("data[0x%02x][0x%03x]=%x02x\n", a, 2*b, data[a][2*b]);
13+
printf("data[0x%02x][0x%03x]=%x02x\n", a, 2*b + 1, data[a][2*b + 1]);
14+
}
15+
}
16+
}
17+
REPORT_RESULT()
18+
}

tests/parallel_test_core.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
assert not os.environ.get('EM_SAVE_DIR'), 'Need separate directories to avoid the parallel tests clashing'
1515

1616
# run slower ones first, to optimize total time
17-
optimal_order = ['asm3i', 'asm1i', 'asm2nn', 'asm3', 'asm2', 'asm2g', 'asm2f', 'asm1', 'default']
17+
optimal_order = ['asm3i', 'asm1i', 'asm2nn', 'asm3', 'asm2', 'asm2m', 'asm2g', 'asm2f', 'asm1', 'default']
1818
assert set(optimal_order) == set(test_modes), 'need to update the list of slowest modes'
1919

2020
# set up a background thread to report progress

tests/runner.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ def path_from_root(*pathelems):
3838

3939
# Core test runner class, shared between normal tests and benchmarks
4040
checked_sanity = False
41-
test_modes = ['default', 'asm1', 'asm2', 'asm3', 'asm2f', 'asm2g', 'asm1i', 'asm3i', 'asm2nn']
41+
test_modes = ['default', 'asm1', 'asm2', 'asm3', 'asm2f', 'asm2g', 'asm1i', 'asm3i', 'asm2m', 'asm2nn']
4242
test_index = 0
4343

4444
use_all_engines = os.environ.get('EM_ALL_ENGINES') # generally js engines are equivalent, testing 1 is enough. set this

tests/test_browser.py

+23
Original file line numberDiff line numberDiff line change
@@ -2637,3 +2637,26 @@ def test_pthread_file_io(self):
26372637
# Test that it is possible to send a signal via calling alarm(timeout), which in turn calls to the signal handler set by signal(SIGALRM, func);
26382638
def test_sigalrm(self):
26392639
self.btest(path_from_root('tests', 'sigalrm.cpp'), expected='0', args=['-O3'])
2640+
2641+
def test_meminit_pairs(self):
2642+
d = 'const char *data[] = {\n "'
2643+
d += '",\n "'.join(''.join('\\x{:02x}\\x{:02x}'.format(i, j)
2644+
for j in range(256)) for i in range(256))
2645+
with open(path_from_root('tests', 'meminit_pairs.c')) as f:
2646+
d += '"\n};\n' + f.read()
2647+
args = ["-O2", "--memory-init-file", "0", "-s", "MEM_INIT_METHOD=2", "-s", "ASSERTIONS=1"]
2648+
self.btest(d, expected='0', args=args + ["--closure", "0"])
2649+
self.btest(d, expected='0', args=args + ["--closure", "0", "-g"])
2650+
self.btest(d, expected='0', args=args + ["--closure", "1"])
2651+
2652+
def test_meminit_big(self):
2653+
d = 'const char *data[] = {\n "'
2654+
d += '",\n "'.join([''.join('\\x{:02x}\\x{:02x}'.format(i, j)
2655+
for j in range(256)) for i in range(256)]*256)
2656+
with open(path_from_root('tests', 'meminit_pairs.c')) as f:
2657+
d += '"\n};\n' + f.read()
2658+
assert len(d) > (1 << 27) # more than 32M memory initializer
2659+
args = ["-O2", "--memory-init-file", "0", "-s", "MEM_INIT_METHOD=2", "-s", "ASSERTIONS=1"]
2660+
self.btest(d, expected='0', args=args + ["--closure", "0"])
2661+
self.btest(d, expected='0', args=args + ["--closure", "0", "-g"])
2662+
self.btest(d, expected='0', args=args + ["--closure", "1"])

tests/test_core.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -4374,6 +4374,13 @@ def test_strstr(self):
43744374
self.do_run_from_file(src, output)
43754375

43764376
def test_fnmatch(self):
4377+
# Run one test without assertions, for additional coverage
4378+
assert 'asm2m' in test_modes
4379+
if self.run_name == 'asm2m':
4380+
i = self.emcc_args.index('ASSERTIONS=1')
4381+
assert i > 0 and self.emcc_args[i-1] == '-s'
4382+
self.emcc_args[i] = 'ASSERTIONS=0'
4383+
43774384
test_path = path_from_root('tests', 'core', 'fnmatch')
43784385
src, output = (test_path + s for s in ('.c', '.out'))
43794386
self.do_run_from_file(src, output)
@@ -7387,7 +7394,7 @@ def setUp(self):
73877394
asm2g = make_run("asm2g", compiler=CLANG, emcc_args=["-O2", "-g", "-s", "ASSERTIONS=1", "-s", "SAFE_HEAP=1"])
73887395
asm1i = make_run("asm1i", compiler=CLANG, emcc_args=["-O1", '-s', 'EMTERPRETIFY=1'])
73897396
asm3i = make_run("asm3i", compiler=CLANG, emcc_args=["-O3", '-s', 'EMTERPRETIFY=1'])
7390-
asm2m = make_run("asm2m", compiler=CLANG, emcc_args=["-O2", "--memory-init-file", "0", "-s", "MEM_INIT_METHOD=2"])
7397+
asm2m = make_run("asm2m", compiler=CLANG, emcc_args=["-O2", "--memory-init-file", "0", "-s", "MEM_INIT_METHOD=2", "-s", "ASSERTIONS=1"])
73917398

73927399
# Legacy test modes -
73937400
asm2nn = make_run("asm2nn", compiler=CLANG, emcc_args=["-O2"], env={"EMCC_NATIVE_OPTIMIZER": "0"})

0 commit comments

Comments
 (0)