Skip to content

Commit

Permalink
Remove limits of ES6 feartures in standard library code
Browse files Browse the repository at this point in the history
When transpiling to ES5 use closure with `SIMPLE_OPTIMIZATIONS` rather
then `WHITESPACE_ONLY`.  This means that polyfills cant be included
as needed and removes the limits on what ES6 features we can use.

The downside of this is that is slows down builds for ES5 users but
this seems like a reasonable tradeoff.

Fixes: emscripten-core#11984
  • Loading branch information
sbc100 committed Nov 13, 2023
1 parent 00eae74 commit 3996d49
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 8 deletions.
28 changes: 21 additions & 7 deletions test/test_other.py
Original file line number Diff line number Diff line change
Expand Up @@ -13002,7 +13002,7 @@ def test_hello_function(self):
})
@crossplatform
def test_es5_transpile(self, args):
self.emcc_args += args
self.emcc_args += ['-Wno-transpile'] + args

# Create a library file that uses the following ES6 features
# - let/const
Expand All @@ -13018,6 +13018,11 @@ def test_es5_transpile(self, args):
let obj = Object.assign({}, {prop:1});
err('prop: ' + obj.prop);

// for .. of
for (var elem of [42, 43]) {
err('array elem: ' + elem);
}

// arrow funcs + const
const bar = () => 2;
err('bar: ' + bar());
Expand All @@ -13027,14 +13032,14 @@ def test_es5_transpile(self, args):
var obj2 = {
[key]: 42,
};
err('value: ' + obj2[key]);
err('computed prop: ' + obj2[key]);

// Method syntax
var obj3 = {
myMethod() { return 43 },
};
global['foo'] = obj3;
err('value2: ' + obj3.myMethod());
err('myMethod: ' + obj3.myMethod());

// Nullish coalescing
var definitely = global['maybe'] ?? {};
Expand All @@ -13054,6 +13059,15 @@ def test_es5_transpile(self, args):
}
});
''')
expected = '''\
prop: 1
array elem: 42
array elem: 43
bar: 2
computed prop: 42
myMethod: 43
'''

create_file('test.c', 'extern void foo(); int main() { foo(); }')
self.emcc_args += ['--js-library', 'es6_library.js']
self.uses_es6 = True
Expand Down Expand Up @@ -13085,26 +13099,26 @@ def check_for_es6(filename, expect):
# Check that under normal circumstances none of these features get
# removed / transpiled.
print('base case')
self.do_runf('test.c', 'prop: 1\nbar: 2\n')
self.do_runf('test.c', expected)
check_for_es6('test.js', True)

# If we select and older browser than closure will kick in by default
# to transpile.
print('with old browser')
self.emcc_args.remove('-Werror')
self.set_setting('MIN_CHROME_VERSION', '10')
self.do_runf('test.c', 'prop: 1\nbar: 2\n', output_basename='test_old')
self.do_runf('test.c', expected, output_basename='test_old')
check_for_es6('test_old.js', False)

# If we add `--closure=0` that transpiler (closure) is not run at all
print('with old browser + --closure=0')
self.do_runf('test.c', 'prop: 1\nbar: 2\n', emcc_args=['--closure=0'], output_basename='test_no_closure')
self.do_runf('test.c', expected, emcc_args=['--closure=0'], output_basename='test_no_closure')
check_for_es6('test_no_closure.js', True)

# If we use `--closure=1` closure will run in full optimization mode
# and also transpile to ES5
print('with old browser + --closure=1')
self.do_runf('test.c', 'prop: 1\nbar: 2\n', emcc_args=['--closure=1'], output_basename='test_closure')
self.do_runf('test.c', expected, emcc_args=['--closure=1'], output_basename='test_closure')
check_for_es6('test_closure.js', False)

def test_gmtime_noleak(self):
Expand Down
3 changes: 2 additions & 1 deletion tools/building.py
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,8 @@ def closure_transpile(filename):
user_args = []
closure_cmd, env = get_closure_compiler_and_env(user_args)
closure_cmd += ['--language_out', 'ES5']
closure_cmd += ['--compilation_level', 'WHITESPACE_ONLY']
closure_cmd += ['--compilation_level', 'SIMPLE_OPTIMIZATIONS']
closure_cmd += ['--formatting', 'PRETTY_PRINT']
return run_closure_cmd(closure_cmd, filename, env)


Expand Down

0 comments on commit 3996d49

Please sign in to comment.