Skip to content

Remove legacy support for polyfilling Math.clz32, imul, trunc #5837

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Dec 1, 2017
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 src/preamble.js
Original file line number Diff line number Diff line change
Expand Up @@ -1678,6 +1678,7 @@ function writeAsciiToMemory(str, buffer, dontAddNull) {
{{{ unSign }}}
{{{ reSign }}}

#if LEGACY_VM_SUPPORT
// check for imul support, and also for correctness ( https://bugs.webkit.org/show_bug.cgi?id=126345 )
if (!Math['imul'] || Math['imul'](0xffffffff, 5) !== -5) Math['imul'] = function imul(a, b) {
var ah = a >>> 16;
Expand Down Expand Up @@ -1717,6 +1718,9 @@ if (!Math['trunc']) Math['trunc'] = function(x) {
return x < 0 ? Math.ceil(x) : Math.floor(x);
};
Math.trunc = Math['trunc'];
#else // LEGACY_VM_SUPPORT
assert(Math['imul'] && Math['fround'] && Math['clz32'] && Math['trunc'], 'this is a legacy browser, build with LEGACY_VM_SUPPORT');
#endif // LEGACY_VM_SUPPORT

var Math_abs = Math.abs;
var Math_cos = Math.cos;
Expand Down
3 changes: 3 additions & 0 deletions src/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,9 @@ var STB_IMAGE = 0; // Enables building of stb-image, a tiny public-domain librar
// When enabled, stb-image will be used automatically from IMG_Load and IMG_Load_RW. You
// can also call the stbi_* functions directly yourself.

var LEGACY_VM_SUPPORT = 0; // Enable this to get support for non-modern browsers, node.js, etc. This adds:
// * Polyfilling for Math.clz32, Math.trunc, Math.imul, Math.fround

var LZ4 = 0; // Enable this to support lz4-compressed file packages. They are stored compressed in memory, and
// decompressed on the fly, avoiding storing the entire decompressed data in memory at once.
// If you run the file packager separately, you still need to build the main program with this flag,
Expand Down
23 changes: 0 additions & 23 deletions tests/test_browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -2353,29 +2353,6 @@ def test_codemods(self):
self.btest(path_from_root('tests', 'codemods.cpp'), expected='1', args=[opts, '-s', 'PRECISE_F32=1'])
self.btest(path_from_root('tests', 'codemods.cpp'), expected='1', args=[opts, '-s', 'PRECISE_F32=2', '--separate-asm']) # empty polyfill, but browser has support, so semantics are like float

# now use a shell to remove the browser's fround support
open(self.in_dir('shell.html'), 'w').write(open(path_from_root('src', 'shell.html')).read().replace('var Module = {', '''
Math.fround = null;
var Module = {
'''))
self.btest(path_from_root('tests', 'codemods.cpp'), expected='2', args=[opts, '--shell-file', 'shell.html'])
self.btest(path_from_root('tests', 'codemods.cpp'), expected='1', args=[opts, '--shell-file', 'shell.html', '-s', 'PRECISE_F32=1'])
self.btest(path_from_root('tests', 'codemods.cpp'), expected='2', args=[opts, '--shell-file', 'shell.html', '-s', 'PRECISE_F32=2', '--separate-asm']) # empty polyfill, no browser support, so semantics are like double

# finally, remove fround, patch up fround as the code executes (after polyfilling etc.), to verify that we got rid of it entirely on the client side
fixer = 'python fix.py'
open('fix.py', 'w').write(r'''
import sys
filename = sys.argv[1]
js = open(filename).read()
replaced = js.replace("var Math_fround = Math.fround;", "var Math_fround = Math.fround = function(x) { return 0; }")
assert js != replaced
open(filename, 'w').write(replaced)
''')
self.btest(path_from_root('tests', 'codemods.cpp'), expected='2', args=[opts, '--shell-file', 'shell.html', '--js-transform', fixer]) # no fround anyhow
self.btest(path_from_root('tests', 'codemods.cpp'), expected='121378', args=[opts, '--shell-file', 'shell.html', '--js-transform', fixer, '-s', 'PRECISE_F32=1']) # proper polyfill was enstated, then it was replaced by the fix so 0 is returned all the time, hence a different result here
self.btest(path_from_root('tests', 'codemods.cpp'), expected='2', args=[opts, '--shell-file', 'shell.html', '--js-transform', fixer, '-s', 'PRECISE_F32=2', '--separate-asm']) # we should remove the calls to the polyfill ENTIRELY here, on the clientside, so we should NOT see any calls to fround here, and result should be like double

def test_wget(self):
with open(os.path.join(self.get_dir(), 'test.txt'), 'w') as f:
f.write('emscripten')
Expand Down
9 changes: 9 additions & 0 deletions tests/test_other.py
Original file line number Diff line number Diff line change
Expand Up @@ -3117,6 +3117,15 @@ def test_warn_unaligned(self):
assert 'emcc: warning: unaligned store' in output[1], output[1]
assert '@line 11 "src.cpp"' in output[1], output[1]

def test_LEGACY_VM_SUPPORT(self):
# when modern features are lacking, we can polyfill them or at least warn
with open('pre.js', 'w') as f: f.write('Math.imul = undefined;')
def test(expected, opts=[]):
subprocess.check_call([PYTHON, EMCC, path_from_root('tests', 'hello_world.c'), '--pre-js', 'pre.js'] + opts)
self.assertContained(expected, run_js('a.out.js', stderr=PIPE, full_output=True, engine=NODE_JS, assert_returncode=None))
test('this is a legacy browser, build with LEGACY_VM_SUPPORT')
test('hello, world!', ['-s', 'LEGACY_VM_SUPPORT=1'])

def test_on_abort(self):
expected_output = 'Module.onAbort was called'

Expand Down