add a whitelist option for the emterpreter; #3129

This commit is contained in:
Alon Zakai 2015-01-21 17:56:11 -08:00
Родитель 4482858955
Коммит 7d5be1566c
4 изменённых файлов: 40 добавлений и 3 удалений

4
emcc
Просмотреть файл

@ -70,7 +70,7 @@ LIB_PREFIXES = ('', 'lib')
JS_CONTAINING_SUFFIXES = ('js', 'html')
DEFERRED_REPONSE_FILES = ('EMTERPRETIFY_BLACKLIST',)
DEFERRED_REPONSE_FILES = ('EMTERPRETIFY_BLACKLIST', 'EMTERPRETIFY_WHITELIST')
# Mapping of emcc opt levels to llvm opt levels. We use llvm opt level 3 in emcc opt
# levels 2 and 3 (emcc 3 is unsafe opts, so unsuitable for the only level to get
@ -1555,7 +1555,7 @@ try:
try:
# move temp js to final position, alongside its mem init file
shutil.move(final, js_target)
args = [shared.PYTHON, shared.path_from_root('tools', 'emterpretify.py'), js_target, final + '.em.js', memfile, json.dumps(shared.Settings.EMTERPRETIFY_BLACKLIST)]
args = [shared.PYTHON, shared.path_from_root('tools', 'emterpretify.py'), js_target, final + '.em.js', memfile, json.dumps(shared.Settings.EMTERPRETIFY_BLACKLIST), json.dumps(shared.Settings.EMTERPRETIFY_WHITELIST)]
if shared.Settings.EMTERPRETIFY_ASYNC:
args += ['ASYNC=1']
if profiling:

Просмотреть файл

@ -576,6 +576,8 @@ var NO_DYNAMIC_EXECUTION = 0; // When enabled, we do not emit eval() and new Fun
var EMTERPRETIFY = 0; // Runs tools/emterpretify on the compiler output
var EMTERPRETIFY_BLACKLIST = []; // Functions to not emterpret, that is, to run normally at full speed
var EMTERPRETIFY_WHITELIST = []; // If this contains any functions, then only the functions in this list
// are emterpreted (as if all the rest are blacklisted; this overrides the BLACKLIST)
var EMTERPRETIFY_ASYNC = 0; // Allows sync code in the emterpreter, by saving the call stack, doing an async delay, and resuming it
var RUNNING_JS_OPTS = 0; // whether js opts will be run, after the main compiler

Просмотреть файл

@ -4378,6 +4378,29 @@ pass: error == ENOTDIR
assert 'emterpret' not in get_func(src, '_main'), 'main is NOT emterpreted, it was blacklisted'
assert 'emterpret' not in get_func(src, '_atoi'), 'atoi is NOT emterpreted either'
print 'whitelisting'
do_emcc_test('fannkuch.cpp', ['5'], 'Pfannkuchen(5) = 7.', ['-s', 'EMTERPRETIFY_WHITELIST=[]'])
src = open('a.out.js').read()
assert 'emterpret' in get_func(src, '_main'), 'main is emterpreted'
assert 'function _atoi(' not in src, 'atoi is emterpreted and does not even have a trampoline, since only other emterpreted can reach it'
do_emcc_test('fannkuch.cpp', ['5'], 'Pfannkuchen(5) = 7.', ['-s', 'EMTERPRETIFY_WHITELIST=["_main"]'])
src = open('a.out.js').read()
assert 'emterpret' in get_func(src, '_main')
assert 'emterpret' not in get_func(src, '_atoi'), 'atoi is not in whitelist, so it is not emterpreted'
do_emcc_test('fannkuch.cpp', ['5'], 'Pfannkuchen(5) = 7.', ['-s', 'EMTERPRETIFY_WHITELIST=["_main", "_atoi"]'])
src = open('a.out.js').read()
assert 'emterpret' in get_func(src, '_main')
assert 'function _atoi(' not in src, 'atoi is emterpreted and does not even have a trampoline, since only other emterpreted can reach it'
open('whitelist.txt', 'w').write('["_main"]')
do_emcc_test('fannkuch.cpp', ['5'], 'Pfannkuchen(5) = 7.', ['-s', 'EMTERPRETIFY_WHITELIST=@whitelist.txt'])
src = open('a.out.js').read()
assert 'emterpret' in get_func(src, '_main')
assert 'emterpret' not in get_func(src, '_atoi'), 'atoi is not in whitelist, so it is not emterpreted'
do_test(r'''
#include<stdio.h>

Просмотреть файл

@ -41,6 +41,7 @@ sys.argv = filter(handle_arg, sys.argv)
# consts
BLACKLIST = set(['_malloc', '_free', '_memcpy', '_memmove', '_memset', 'copyTempDouble', 'copyTempFloat', '_strlen', 'stackAlloc', 'setThrew', 'stackRestore', 'setTempRet0', 'getTempRet0', 'stackSave', 'runPostSets', '_emscripten_autodebug_double', '_emscripten_autodebug_float', '_emscripten_autodebug_i8', '_emscripten_autodebug_i16', '_emscripten_autodebug_i32', '_emscripten_autodebug_i64', '_strncpy', '_strcpy', '_strcat', '_saveSetjmp', '_testSetjmp', '_emscripten_replace_memory', '_bitshift64Shl', '_bitshift64Ashr', '_bitshift64Lshr', 'setAsyncState', 'emtStackSave'])
WHITELIST = []
OPCODES = [ # l, lx, ly etc - one of 256 locals
'SET', # [lx, ly, 0] lx = ly (int or float, not double)
@ -645,6 +646,13 @@ if __name__ == '__main__':
assert temp[1] == '@'
temp = open(temp[2:-1]).read()
extra_blacklist = json.loads(temp)
if len(sys.argv) >= 6:
temp = sys.argv[5]
if temp[0] == '"':
# response file
assert temp[1] == '@'
temp = open(temp[2:-1]).read()
WHITELIST = json.loads(temp)
BLACKLIST = set(list(BLACKLIST) + extra_blacklist)
@ -655,11 +663,15 @@ if __name__ == '__main__':
asm = asm_module.AsmModule(infile)
# sanity check on blacklist
# process blacklist
for func in extra_blacklist:
assert func in asm.funcs, 'requested blacklist of %s but it does not exist' % func
if len(WHITELIST) > 0:
# we are using a whitelist: fill the blacklist with everything not whitelisted
BLACKLIST = set([func for func in asm.funcs if func not in WHITELIST])
# decide which functions will be emterpreted, and find which are externally reachable (from outside other emterpreted code; those will need trampolines)
emterpreted_funcs = set([func for func in asm.funcs if func not in BLACKLIST and not func.startswith('dynCall_')])