Skip to content

Commit f69847b

Browse files
committed
Merge remote-tracking branch 'origin/main' into roll
2 parents 76c586c + e574381 commit f69847b

File tree

12 files changed

+58
-106
lines changed

12 files changed

+58
-106
lines changed

.circleci/config.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -753,6 +753,7 @@ jobs:
753753
test_targets: "
754754
other.test_gen_struct_info
755755
other.test_native_call_before_init
756+
other.test_js_optimizer_verbose
756757
other.test_node_unhandled_rejection
757758
other.test_full_js_library*
758759
core2.test_hello_world"
@@ -768,6 +769,7 @@ jobs:
768769
other.test_gen_struct_info
769770
other.test_native_call_before_init
770771
other.test_node_unhandled_rejection
772+
other.test_js_optimizer_verbose
771773
other.test_min_node_version
772774
other.test_node_emscripten_num_logical_cores
773775
core2.test_pthread_create

src/library_getvalue.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ var LibraryMemOps = {
6262

6363
#if SAFE_HEAP
6464
// The same as the above two functions, but known to the safeHeap pass
65-
// in tools/acorn-optimizer.js. The heap accesses within these two
65+
// in tools/acorn-optimizer.mjs. The heap accesses within these two
6666
// functions will *not* get re-written.
6767
// Note that we do not use the alias mechanism here since we need separate
6868
// instances of above setValueImpl/getValueImpl functions.

test/common.py

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import time
2929
import webbrowser
3030
import unittest
31+
import queue
3132

3233
import clang_native
3334
import jsrun
@@ -76,6 +77,7 @@
7677
NON_ZERO = -1
7778

7879
TEST_ROOT = path_from_root('test')
80+
LAST_TEST = path_from_root('out/last_test.txt')
7981

8082
WEBIDL_BINDER = shared.bat_suffix(path_from_root('tools/webidl_binder'))
8183

@@ -901,6 +903,7 @@ def setUp(self):
901903
else:
902904
print('Creating new test output directory')
903905
ensure_dir(self.working_dir)
906+
utils.write_file(LAST_TEST, self.id() + '\n')
904907
os.chdir(self.working_dir)
905908

906909
def runningInParallel(self):
@@ -1956,25 +1959,21 @@ def run_browser(self, html_file, expected=None, message=None, timeout=None, extr
19561959
'http://localhost:%s/%s' % (self.port, html_file),
19571960
self.get_dir()
19581961
))
1959-
received_output = False
1960-
output = '[no http server activity]'
1961-
start = time.time()
19621962
if timeout is None:
19631963
timeout = self.browser_timeout
1964-
while time.time() - start < timeout:
1965-
if not self.harness_out_queue.empty():
1966-
output = self.harness_out_queue.get()
1967-
received_output = True
1968-
break
1969-
time.sleep(0.1)
1970-
if not received_output:
1964+
try:
1965+
output = self.harness_out_queue.get(block=True, timeout=timeout)
1966+
except queue.Empty:
19711967
BrowserCore.unresponsive_tests += 1
19721968
print('[unresponsive tests: %d]' % BrowserCore.unresponsive_tests)
19731969
self.browser_restart()
1970+
# Rather than fail the test here, let fail on the `assertContained` so
1971+
# that the test can be retried via `extra_tries`
1972+
output = '[no http server activity]'
19741973
if output is None:
19751974
# the browser harness reported an error already, and sent a None to tell
19761975
# us to also fail the test
1977-
raise Exception('failing test due to browser harness error')
1976+
self.fail('browser harness error')
19781977
if output.startswith('/report_result?skipped:'):
19791978
self.skipTest(unquote(output[len('/report_result?skipped:'):]).strip())
19801979
else:

test/runner.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,9 @@ def parse_args(args):
382382
parser.add_argument('tests', nargs='*')
383383
parser.add_argument('--failfast', action='store_const', const=True, default=False)
384384
parser.add_argument('--start-at', metavar='NAME', help='Skip all tests up until <NAME>')
385+
parser.add_argument('--continue', dest='_continue', action='store_true',
386+
help='Resume from the last run test.'
387+
'Useful when combined with --failfast')
385388
parser.add_argument('--force64', action='store_const', const=True, default=None)
386389
parser.add_argument('--crossplatform-only', action='store_true')
387390
return parser.parse_args()
@@ -465,6 +468,11 @@ def prepend_default(arg):
465468
tests = tests_with_expanded_wildcards(tests, all_tests)
466469
tests = skip_requested_tests(tests, modules)
467470
tests = args_for_random_tests(tests, modules)
471+
472+
if not options.start_at and options._continue:
473+
if os.path.exists(common.LAST_TEST):
474+
options.start_at = utils.read_file(common.LAST_TEST).strip()
475+
468476
suites, unmatched_tests = load_test_suites(tests, modules, options.start_at)
469477
if unmatched_tests:
470478
print('ERROR: could not find the following tests: ' + ' '.join(unmatched_tests))

test/test_core.py

Lines changed: 6 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -597,71 +597,7 @@ def test_cube2hash(self):
597597
('64bitisslow', '64D8470573635EC354FEE7B7F87C566FCAF1EFB491041670')]:
598598
self.do_run('src.js', 'hash value: ' + output, args=[text], no_build=True)
599599

600-
def test_unaligned(self):
601-
self.skipTest('LLVM marks the reads of s as fully aligned, making this test invalid')
602-
src = r'''
603-
#include <stdio.h>
604-
605-
struct S {
606-
double x;
607-
int y;
608-
};
609-
610-
int main() {
611-
// the 64-bit value here will not be 8-byte aligned
612-
S s0[3] = { {0x12a751f430142, 22}, {0x17a5c85bad144, 98}, {1, 1}};
613-
char buffer[10*sizeof(S)];
614-
int b = int(buffer);
615-
S *s = (S*)(b + 4-b%8);
616-
s[0] = s0[0];
617-
s[1] = s0[1];
618-
s[2] = s0[2];
619-
620-
printf("*%d : %d : %d\n", sizeof(S), ((unsigned long)&s[0]) % 8 != ((unsigned long)&s[1]) % 8,
621-
((unsigned long)&s[1]) - ((unsigned long)&s[0]));
622-
s[0].x++;
623-
s[0].y++;
624-
s[1].x++;
625-
s[1].y++;
626-
printf("%.1f,%d,%.1f,%d\n", s[0].x, s[0].y, s[1].x, s[1].y);
627-
return 0;
628-
}
629-
'''
630-
631-
# TODO: A version of this with int64s as well
632-
633-
self.do_run(src, '*12 : 1 : 12\n328157500735811.0,23,416012775903557.0,99\n')
634-
635-
return # TODO: continue to the next part here
636-
637-
# Test for undefined behavior in C. This is not legitimate code, but does exist
638-
639-
src = r'''
640-
#include <stdio.h>
641-
642-
int main()
643-
{
644-
int x[10];
645-
char *p = (char*)&x[0];
646-
p++;
647-
short *q = (short*)p;
648-
*q = 300;
649-
printf("*%d:%ld*\n", *q, ((long)q)%2);
650-
int *r = (int*)p;
651-
*r = 515559;
652-
printf("*%d*\n", *r);
653-
long long *t = (long long*)p;
654-
*t = 42949672960;
655-
printf("*%lld*\n", *t);
656-
return 0;
657-
}
658-
'''
659-
660-
try:
661-
self.do_run(src, '*300:1*\n*515559*\n*42949672960*\n')
662-
except Exception as e:
663-
assert 'must be aligned' in str(e), e # expected to fail without emulation
664-
600+
@only_wasm2js('tests 64-bit alignment of structs')
665601
def test_align64(self):
666602
src = r'''
667603
#include <stdio.h>
@@ -710,12 +646,7 @@ def test_align64(self):
710646
0.00,10,123.46,0.00 : 0.00,10,123.46,0.00
711647
''')
712648

713-
@no_asan('asan errors on corner cases we check')
714-
@no_lsan('lsan errors on corner cases we check')
715-
def test_aligned_alloc(self):
716-
self.do_runf('test_aligned_alloc.c', '',
717-
emcc_args=['-Wno-non-power-of-two-alignment'])
718-
649+
@only_wasm2js('tests signed vs unsigned values')
719650
def test_unsigned(self):
720651
src = '''
721652
#include <stdio.h>
@@ -801,22 +732,26 @@ def test_unsigned(self):
801732
'''
802733
self.do_run(src, '*255*\n*65535*\n*-1*\n*-1*\n*-1*')
803734

735+
@only_wasm2js('tests 1-bit fields')
804736
def test_bitfields(self):
805737
self.do_core_test('test_bitfields.c')
806738

807739
def test_floatvars(self):
808740
self.do_core_test('test_floatvars.cpp')
809741

742+
@only_wasm2js('tests pointer casts')
810743
def test_closebitcasts(self):
811744
self.do_core_test('closebitcasts.c')
812745

813746
def test_fast_math(self):
814747
self.emcc_args += ['-ffast-math']
815748
self.do_core_test('test_fast_math.c', args=['5', '6', '8'])
816749

750+
@only_wasm2js('tests division by zero')
817751
def test_zerodiv(self):
818752
self.do_core_test('test_zerodiv.c')
819753

754+
@only_wasm2js('tests multiplication by zero')
820755
def test_zero_multiplication(self):
821756
# needs to flush stdio streams
822757
self.set_setting('EXIT_RUNTIME')

test/test_other.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2617,7 +2617,7 @@ def test_js_optimizer(self, input, passes):
26172617
input = test_file(input)
26182618
expected_file = os.path.splitext(input)[0] + '-output.js'
26192619
# test calling optimizer
2620-
js = self.run_process(config.NODE_JS + [path_from_root('tools/acorn-optimizer.js'), input] + passes, stdin=PIPE, stdout=PIPE).stdout
2620+
js = self.run_process(config.NODE_JS + [path_from_root('tools/acorn-optimizer.mjs'), input] + passes, stdin=PIPE, stdout=PIPE).stdout
26212621
if common.EMTEST_REBASELINE:
26222622
write_file(expected_file, js)
26232623
else:
@@ -14241,3 +14241,7 @@ def test_sysroot_includes_first(self):
1424114241
def test_force_filesystem_error(self):
1424214242
err = self.expect_fail([EMCC, test_file('hello_world.c'), '-sFILESYSTEM=0', '-sFORCE_FILESYSTEM'])
1424314243
self.assertContained('emcc: error: `-sFORCE_FILESYSTEM` cannot be used with `-sFILESYSTEM=0`', err)
14244+
14245+
def test_aligned_alloc(self):
14246+
self.do_runf('test_aligned_alloc.c', '',
14247+
emcc_args=['-Wno-non-power-of-two-alignment'])

third_party/terser/terser.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6706,7 +6706,7 @@ const _NOINLINE = 0b00000100;
67066706
const _KEY = 0b00001000;
67076707
const _MANGLEPROP = 0b00010000;
67086708

6709-
// XXX Emscripten: export TreeWalker for walking through AST in acorn-optimizer.js.
6709+
// XXX Emscripten: export TreeWalker for walking through AST in acorn-optimizer.mjs.
67106710
exports.TreeWalker = TreeWalker;
67116711

67126712
/***********************************************************************

tools/acorn-optimizer.js renamed to tools/acorn-optimizer.mjs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
#!/usr/bin/env node
22

3-
'use strict';
4-
5-
const acorn = require('acorn');
6-
const terser = require('../third_party/terser/terser');
7-
const fs = require('fs');
3+
import * as acorn from 'acorn';
4+
import * as terser from '../third_party/terser/terser.js';
5+
import * as fs from 'fs';
86

97
// Utilities
108

tools/building.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ def js_optimizer(filename, passes):
349349

350350
# run JS optimizer on some JS, ignoring asm.js contents if any - just run on it all
351351
def acorn_optimizer(filename, passes, extra_info=None, return_output=False):
352-
optimizer = path_from_root('tools/acorn-optimizer.js')
352+
optimizer = path_from_root('tools/acorn-optimizer.mjs')
353353
original_filename = filename
354354
if extra_info is not None:
355355
temp_files = shared.get_temp_files()
@@ -579,7 +579,7 @@ def closure_compiler(filename, advanced=True, extra_closure_args=None):
579579
CLOSURE_EXTERNS += [path_from_root('src/closure-externs/minimal_runtime_worker_externs.js')]
580580

581581
args = ['--compilation_level', 'ADVANCED_OPTIMIZATIONS' if advanced else 'SIMPLE_OPTIMIZATIONS']
582-
# Keep in sync with ecmaVersion in tools/acorn-optimizer.js
582+
# Keep in sync with ecmaVersion in tools/acorn-optimizer.mjs
583583
args += ['--language_in', 'ECMASCRIPT_2021']
584584
# Tell closure not to do any transpiling or inject any polyfills.
585585
# At some point we may want to look into using this as way to convert to ES5 but

tools/js_optimizer.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
temp_files = shared.get_temp_files()
2323

2424

25-
ACORN_OPTIMIZER = path_from_root('tools/acorn-optimizer.js')
25+
ACORN_OPTIMIZER = path_from_root('tools/acorn-optimizer.mjs')
2626

2727
NUM_CHUNKS_PER_CORE = 3
2828
MIN_CHUNK_SIZE = int(os.environ.get('EMCC_JSOPT_MIN_CHUNK_SIZE') or 512 * 1024) # configuring this is just for debugging purposes
@@ -65,7 +65,7 @@ def split_funcs(js):
6565

6666
class Minifier:
6767
"""minification support. We calculate minification of
68-
globals here, then pass that into the parallel acorn-optimizer.js runners which
68+
globals here, then pass that into the parallel acorn-optimizer.mjs runners which
6969
perform minification of locals.
7070
"""
7171

@@ -75,7 +75,7 @@ def __init__(self, js):
7575
self.profiling_funcs = False
7676

7777
def minify_shell(self, shell, minify_whitespace):
78-
# Run through acorn-optimizer.js to find and minify the global symbols
78+
# Run through acorn-optimizer.mjs to find and minify the global symbols
7979
# We send it the globals, which it parses at the proper time. JS decides how
8080
# to minify all global names, we receive a dictionary back, which is then
8181
# used by the function processors

tools/preprocessor.js renamed to tools/preprocessor.mjs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,29 @@
1414

1515
'use strict';
1616

17-
const fs = require('fs');
18-
const path = require('path');
19-
global.vm = require('vm');
17+
import * as fs from 'fs';
18+
import * as path from 'path';
19+
import * as vm from 'vm';
20+
import assert from 'assert';
21+
import * as url from 'url';
2022

21-
const arguments_ = process.argv.slice(2);
23+
const args = process.argv.slice(2);
2224
const debug = false;
2325

26+
// Anything needed by the script that we load below must be added to the
27+
// global object. These, for example, are all needed by parseTools.js.
28+
global.vm = vm;
29+
global.assert = assert;
2430
global.print = (x) => {
2531
process.stdout.write(x + '\n');
2632
};
2733
global.printErr = (x) => {
2834
process.stderr.write(x + '\n');
2935
};
3036

31-
global.assert = require('assert');
32-
3337
function find(filename) {
34-
const prefixes = [process.cwd(), path.join(__dirname, '..', 'src')];
38+
const dirname = url.fileURLToPath(new URL('.', import.meta.url));
39+
const prefixes = [process.cwd(), path.join(dirname, '..', 'src')];
3540
for (let i = 0; i < prefixes.length; ++i) {
3641
const combined = path.join(prefixes[i], filename);
3742
if (fs.existsSync(combined)) {
@@ -50,9 +55,10 @@ global.load = (f) => {
5055
(0, eval)(read(f) + '//# sourceURL=' + find(f));
5156
};
5257

53-
const settingsFile = arguments_[0];
54-
const inputFile = arguments_[1];
55-
const expandMacros = arguments_.includes('--expandMacros');
58+
assert(args.length >= 2);
59+
const settingsFile = args[0];
60+
const inputFile = args[1];
61+
const expandMacros = args.includes('--expandMacros');
5662

5763
load(settingsFile);
5864
load('utility.js');

tools/shared.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -762,7 +762,7 @@ def read_and_preprocess(filename, expand_macros=False):
762762
if expand_macros:
763763
args += ['--expandMacros']
764764

765-
run_js_tool(path_from_root('tools/preprocessor.js'), args, stdout=open(stdout, 'w'), cwd=dirname)
765+
run_js_tool(path_from_root('tools/preprocessor.mjs'), args, stdout=open(stdout, 'w'), cwd=dirname)
766766
out = utils.read_file(stdout)
767767

768768
return out

0 commit comments

Comments
 (0)