Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ See docs/process.md for more on how version tagging works.
`warning: treating 'c' input as 'c++' when in C++ mode`. This also means that
the `DEFAULT_TO_CXX` setting now only applies when linking and not when
compiling. (#20712)
- JavaScript library code can now use the full range ES6 features and we rely
on closure compiler to transpile for ES5 when targetting older browsers.
For those that want to would rather perform transpilation seperately outside
of emscripten you can use the `-sPOLYFILL=0` setting. (#20700)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the connection between transpiling and polyfills? That POLYFILLS disables transpiling seems slightly surprising to me and I think might be for other readers.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I kind of lumped them together.

I do think its somewhat logical though since folks who use -sPOLYFILL=0 are basically saying "I promise to install my own polyfills".. otherwise the code simply won't run, and in almost all cases that I know of polyfills are normally installed by transpilers, so what they are really saying is "I promise to my own transpilation" to ES5 (or whatever).

I've not actually heard of anyone using -sPOLYFILL=0 in the wild, but if we hear back from suchusers that they want to use this setting and still have emscripten take care of transpiling we can consider a separate setting.


3.1.49 - 11/14/23
-----------------
Expand Down
2 changes: 1 addition & 1 deletion emcc.py
Original file line number Diff line number Diff line change
Expand Up @@ -2318,7 +2318,7 @@ def phase_linker_setup(options, state, newargs):

setup_environment_settings()

if options.use_closure_compiler != 0:
if options.use_closure_compiler != 0 and settings.POLYFILL:
# Emscripten requires certain ES6 constructs by default in library code
# - https://caniuse.com/let : EDGE:12 FF:44 CHROME:49 SAFARI:11
# - https://caniuse.com/const : EDGE:12 FF:36 CHROME:49 SAFARI:11
Expand Down
28 changes: 21 additions & 7 deletions test/test_other.py
Original file line number Diff line number Diff line change
Expand Up @@ -12990,7 +12990,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 @@ -13006,6 +13006,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 @@ -13015,14 +13020,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 @@ -13042,6 +13047,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 @@ -13073,26 +13087,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