aboutsummaryrefslogtreecommitdiff
path: root/emscripten.py
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2014-02-18 16:09:37 -0800
committerAlon Zakai <alonzakai@gmail.com>2014-02-18 16:09:37 -0800
commit565d3bb3d5f8d6ade54a18c30b4f2a27facc8e99 (patch)
treedc2d1ec71507b213c6db3029c4f0ed5ae992f354 /emscripten.py
parent8934707eb63b250bfaca4c0b2761fd32a1755ef3 (diff)
useful info in ASSERTIONS=1 and 2 in fastcomp for bad function pointer calls, and update other.test_dangerous_func_cast to test that
Diffstat (limited to 'emscripten.py')
-rwxr-xr-xemscripten.py50
1 files changed, 41 insertions, 9 deletions
diff --git a/emscripten.py b/emscripten.py
index e90cce2a..59a0666c 100755
--- a/emscripten.py
+++ b/emscripten.py
@@ -918,18 +918,30 @@ def emscript_fast(infile, settings, outfile, libraries=[], compiler_engine=None,
def unfloat(s):
return 'd' if s == 'f' else s # lower float to double for ffis
+ if settings['ASSERTIONS'] >= 2:
+ debug_tables = {}
+
def make_table(sig, raw):
- i = Counter.i
- Counter.i += 1
- bad = 'b' + str(i)
+ Counter.pre = ''
params = ','.join(['p%d' % p for p in range(len(sig)-1)])
coerced_params = ','.join([shared.JS.make_coercion('p%d', unfloat(sig[p+1]), settings) % p for p in range(len(sig)-1)])
coercions = ';'.join(['p%d = %s' % (p, shared.JS.make_coercion('p%d' % p, sig[p+1], settings)) for p in range(len(sig)-1)]) + ';'
def make_func(name, code):
return 'function %s(%s) { %s %s }' % (name, params, coercions, code)
- Counter.pre = [make_func(bad, ('abort' if not settings['ASSERTIONS'] else 'nullFunc') + '(' + str(i) + ');' + (
- '' if sig[0] == 'v' else ('return %s' % shared.JS.make_initializer(sig[0], settings))
- ))]
+ def make_bad(target=None):
+ i = Counter.i
+ Counter.i += 1
+ if target is None: target = i
+ name = 'b' + str(i)
+ if not settings['ASSERTIONS']:
+ code = 'abort(%s);' % target
+ else:
+ code = 'nullFunc_' + sig + '(%d);' % target
+ if sig[0] != 'v':
+ code += 'return %s' % shared.JS.make_initializer(sig[0], settings) + ';'
+ return name, make_func(name, code)
+ bad, bad_func = make_bad() # the default bad func
+ Counter.pre = [bad_func]
start = raw.index('[')
end = raw.rindex(']')
body = raw[start+1:end].split(',')
@@ -941,7 +953,13 @@ def emscript_fast(infile, settings, outfile, libraries=[], compiler_engine=None,
def fix_item(item):
Counter.j += 1
newline = Counter.j % 30 == 29
- if item == '0': return bad if not newline else (bad + '\n')
+ if item == '0':
+ if settings['ASSERTIONS'] <= 1:
+ return bad if not newline else (bad + '\n')
+ else:
+ specific_bad, specific_bad_func = make_bad(Counter.j)
+ Counter.pre.append(specific_bad_func)
+ return specific_bad if not newline else (specific_bad + '\n')
if item not in implemented_functions:
# this is imported into asm, we must wrap it
call_ident = item
@@ -956,6 +974,8 @@ def emscript_fast(infile, settings, outfile, libraries=[], compiler_engine=None,
Counter.pre.append(make_func(item + '__wrapper', code))
return item + '__wrapper'
return item if not newline else (item + '\n')
+ if settings['ASSERTIONS'] >= 2:
+ debug_tables[sig] = body
body = ','.join(map(fix_item, body))
return ('\n'.join(Counter.pre), ''.join([raw[:start+1], body, raw[end:]]))
@@ -977,8 +997,20 @@ def emscript_fast(infile, settings, outfile, libraries=[], compiler_engine=None,
if settings['SAFE_HEAP']: basic_funcs += ['SAFE_HEAP_LOAD', 'SAFE_HEAP_STORE']
if settings['CHECK_HEAP_ALIGN']: basic_funcs += ['CHECK_ALIGN_2', 'CHECK_ALIGN_4', 'CHECK_ALIGN_8']
if settings['ASSERTIONS']:
- basic_funcs += ['nullFunc']
- asm_setup += 'function nullFunc(x) { Module["printErr"]("Invalid function pointer called. Perhaps a miscast function pointer (check compilation warnings) or bad vtable lookup (maybe due to derefing a bad pointer, like NULL)?"); abort(x) }\n'
+ for sig in last_forwarded_json['Functions']['tables'].iterkeys():
+ basic_funcs += ['nullFunc_' + sig]
+ if settings['ASSERTIONS'] <= 1:
+ extra = ' Module["printErr"]("Build with ASSERTIONS=2 for more info.");'
+ pointer = ' '
+ else:
+ pointer = ' \'" + x + "\' '
+ asm_setup += '\nvar debug_table_' + sig + ' = ' + json.dumps(debug_tables[sig]) + ';'
+ extra = ' Module["printErr"]("This pointer might make sense in another type signature: '
+ for other in last_forwarded_json['Functions']['tables'].iterkeys():
+ if other != sig:
+ extra += other + ': " + debug_table_' + other + '[x] + " '
+ extra += '"); '
+ asm_setup += '\nfunction nullFunc_' + sig + '(x) { Module["printErr"]("Invalid function pointer' + pointer + 'called with signature \'' + sig + '\'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an different type, which will fail?"); ' + extra + ' abort(x) }\n'
basic_vars = ['STACKTOP', 'STACK_MAX', 'tempDoublePtr', 'ABORT']
basic_float_vars = ['NaN', 'Infinity']