aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2013-02-25 19:23:56 -0500
committerAlon Zakai <alonzakai@gmail.com>2013-02-25 19:23:56 -0500
commit230c0e80dfcd44870bec3254c399db430f6e1d98 (patch)
tree745ec3b082adc222050b4d48a416d7a969dd148d
parent5a99d2567e76f257309cfd225876f3a5402e5f46 (diff)
parent9d4ef477a511ae4136c2d63e0150a4768cbd53ea (diff)
Merge branch 'incoming'
Conflicts: AUTHORS
-rw-r--r--AUTHORS2
-rwxr-xr-xemcc121
-rwxr-xr-xemscripten.py5
-rw-r--r--src/analyzer.js7
-rw-r--r--src/compiler.js8
-rw-r--r--src/corruptionCheck.js98
-rw-r--r--src/jsifier.js26
-rw-r--r--src/library.js225
-rw-r--r--src/library_browser.js19
-rw-r--r--src/library_egl.js41
-rw-r--r--src/library_gl.js311
-rw-r--r--src/library_glut.js6
-rw-r--r--src/library_sdl.js14
-rw-r--r--src/parseTools.js63
-rw-r--r--src/preamble.js170
-rw-r--r--src/runtime.js31
-rw-r--r--src/settings.js40
-rw-r--r--system/lib/libc.symbols5
-rw-r--r--system/lib/libcxx/symbols9
-rw-r--r--system/lib/libcxxabi/symbols7
-rw-r--r--tests/aniso.pngbin35041 -> 26812 bytes
-rw-r--r--tests/cubegeom.c14
-rw-r--r--tests/cubegeom_pre2_vao.c380
-rw-r--r--tests/cubegeom_pre2_vao2.c381
-rw-r--r--tests/cubegeom_pre_vao.c333
-rw-r--r--tests/float_tex.pngbin19944 -> 18869 bytes
-rw-r--r--tests/fuzz/1.c117
-rw-r--r--tests/fuzz/1.c.txt1
-rwxr-xr-xtests/fuzz/creduce_tester.py53
-rw-r--r--tests/fuzz/csmith.h130
-rwxr-xr-xtests/fuzz/csmith_driver.py100
-rw-r--r--tests/fuzz/platform_generic.h132
-rw-r--r--tests/fuzz/random_inc.h129
-rw-r--r--tests/fuzz/safe_math.h947
-rw-r--r--tests/gears.pngbin7832 -> 6407 bytes
-rw-r--r--tests/gl_ps.c3
-rw-r--r--tests/gl_ps.pngbin203535 -> 202598 bytes
-rw-r--r--tests/gl_ps_packed.c230
-rw-r--r--tests/gl_ps_workaround.c230
-rw-r--r--tests/gl_ps_workaround2.c230
-rw-r--r--tests/glbook/CH13_ParticleSystem.pngbin5106 -> 4921 bytes
-rw-r--r--tests/perspective.c408
-rw-r--r--tests/perspective.pngbin0 -> 2477 bytes
-rwxr-xr-xtests/runner.py499
-rw-r--r--tests/s3tc_crunch.pngbin353677 -> 271258 bytes
-rw-r--r--tests/screenshot-fog-density.pngbin154012 -> 157048 bytes
-rw-r--r--tests/screenshot-fog-exp2.pngbin119847 -> 122164 bytes
-rw-r--r--tests/screenshot-fog-linear.pngbin247928 -> 250343 bytes
-rw-r--r--tests/screenshot-fog-negative.pngbin79537 -> 80704 bytes
-rw-r--r--tests/screenshot-fog-simple.pngbin36557 -> 37940 bytes
-rw-r--r--tests/screenshot-gray-purple.pngbin242425 -> 241235 bytes
-rw-r--r--tests/screenshot-gray.pngbin203336 -> 202044 bytes
-rw-r--r--tests/sdl_gl_read.c9
-rw-r--r--tests/sdl_image_jpeg.c45
-rw-r--r--tests/websockets.c2
-rw-r--r--tools/file_packager.py2
-rw-r--r--tools/js-optimizer.js2
-rw-r--r--tools/js_optimizer.py3
-rw-r--r--tools/shared.py61
-rw-r--r--tools/test-js-optimizer-regs-output.js4
-rw-r--r--tools/test-js-optimizer-regs.js6
61 files changed, 5074 insertions, 585 deletions
diff --git a/AUTHORS b/AUTHORS
index b1003dbd..3a7ceb32 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -48,4 +48,6 @@ a license to everyone to use it as detailed in LICENSE.)
* Jasper St. Pierre <jstpierre@mecheye.net>
* Manuel Schölling <manuel.schoelling@gmx.de>
* Bruce Mitchener, Jr. <bruce.mitchener@gmail.com>
+* Michael Bishop <mbtyke@gmail.com>
+* Roger Braun <roger@rogerbraun.net>
diff --git a/emcc b/emcc
index ffce7363..2f4bad2b 100755
--- a/emcc
+++ b/emcc
@@ -119,11 +119,20 @@ if len(sys.argv) == 1:
exit(1)
if sys.argv[1] == '--version':
- print '''emcc (Emscripten GCC-like replacement) 2.0
-Copyright (C) 2012 the Emscripten authors.
+ revision = '(unknown revision)'
+ here = os.getcwd()
+ os.chdir(shared.path_from_root())
+ try:
+ revision = execute(['git', 'show'], stdout=PIPE, stderr=PIPE)[0].split('\n')[0]
+ except:
+ pass
+ finally:
+ os.chdir(here)
+ print '''emcc (Emscripten GCC-like replacement) %s (%s)
+Copyright (C) 2013 the Emscripten authors (see AUTHORS.txt)
This is free and open source software under the MIT license.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- '''
+ ''' % (shared.EMSCRIPTEN_VERSION, revision)
exit(0)
elif sys.argv[1] == '--help':
this = os.path.basename('em++' if os.environ.get('EMMAKEN_CXX') else 'emcc')
@@ -148,14 +157,19 @@ Options that are modified or new in %s include:
compiling to JavaScript, not to intermediate
bitcode.
-O2 As -O1, plus the relooper (loop recreation),
- plus closure compiler advanced opts, plus
- LLVM -O2 optimizations
- Warning: Compiling with this takes a long time!
+ plus LLVM -O2 optimizations
-O3 As -O2, plus dangerous optimizations that may
- break the generated code! This is not
- recommended at all, see the wiki for more
- details (you can try -O2 and then add
- dangerous optimizations one by one).
+ break the generated code! This adds
+
+ -s INLINING_LIMIT=0
+ -s DOUBLE_MODE=0
+ -s PRECISE_I64_MATH=0
+ --closure 1
+
+ This is not recommended at all. A better idea
+ is to try each of these separately on top of
+ -O2 to see what works. See the wiki for more
+ information.
-s OPTION=VALUE JavaScript code generation option passed
into the emscripten compiler. For the
@@ -177,6 +191,12 @@ Options that are modified or new in %s include:
the last compilation phase from bitcode to
JavaScript, or else we will remove it by
default in -O1 and above.
+ In -O0, line numbers wil be shown in the
+ generated code. In -O1 and above, the optimizer
+ removes those comments. This flag does however
+ have the effect of disabling anything that
+ causes name mangling or minification (closure
+ or the registerize pass).
--typed-arrays <mode> 0: No typed arrays
1: Parallel typed arrays
@@ -193,8 +213,17 @@ Options that are modified or new in %s include:
(see --llvm-opts), setting this to 1 has no
effect.
- --closure <on> 0: No closure compiler (default in -O0, -O1)
- 1: Run closure compiler (default in -O2, -O3)
+ --closure <on> 0: No closure compiler (default in -O2 and below)
+ 1: Run closure compiler. This greatly reduces
+ code size and may in some cases increase
+ runtime speed (although the opposite can also
+ occur). Note that it takes time to run, and
+ may require some changes to the code. This
+ is run by default in -O3.
+
+ Note: If closure compiler hits an out-of-memory,
+ try adjusting JAVA_HEAP_SIZE in the environment
+ (for example, to 4096m for 4GB).
--js-transform <cmd> <cmd> will be called on the generated code
before it is optimized. This lets you modify
@@ -600,7 +629,8 @@ try:
ignore_dynamic_linking = False
shell_path = shared.path_from_root('src', 'shell.html')
js_libraries = []
- keep_debug = False
+ keep_llvm_debug = False
+ keep_js_debug = False
bind = False
jcache = False
if use_cxx:
@@ -616,7 +646,8 @@ try:
for i in range(len(newargs)):
newargs[i] = newargs[i].strip() # On Windows Vista (and possibly others), excessive spaces in the command line leak into the items in this array, so trim e.g. 'foo.cpp ' -> 'foo.cpp'
if newargs[i].startswith('-O'):
- requested_level = newargs[i][2]
+ # Let -O default to -O2, which is what gcc does.
+ requested_level = newargs[i][2:] or '2'
if requested_level == 's':
print >> sys.stderr, 'emcc: warning: -Os is ignored (use -O0, -O1, -O2)'
else:
@@ -667,7 +698,8 @@ try:
newargs[i] = ''
newargs[i+1] = ''
elif newargs[i] == '-g':
- keep_debug = True
+ keep_llvm_debug = True
+ keep_js_debug = True
elif newargs[i] == '--bind':
bind = True
newargs[i] = ''
@@ -738,8 +770,9 @@ try:
if llvm_opts is None: llvm_opts = LLVM_OPT_LEVEL[opt_level]
if llvm_lto is None: llvm_lto = llvm_opts > 0
- if closure is None: closure = 1 if opt_level >= 2 else 0
- if opt_level <= 0: keep_debug = True # always keep debug in -O0
+ if opt_level <= 0: keep_llvm_debug = keep_js_debug = True # always keep debug in -O0
+ if opt_level > 0: keep_llvm_debug = False # JS optimizer wipes out llvm debug info from being visible
+ if closure is None and opt_level == 3: closure = True
if DEBUG: start_time = time.time() # done after parsing arguments, which might affect debug state
@@ -879,7 +912,11 @@ try:
shared.Settings.CORRECT_OVERFLOWS = 1
if shared.Settings.CORRECT_SIGNS >= 2 or shared.Settings.CORRECT_OVERFLOWS >= 2 or shared.Settings.CORRECT_ROUNDINGS >= 2:
- keep_debug = True # must keep debug info to do line-by-line operations
+ keep_llvm_debug = True # must keep debug info to do line-by-line operations
+
+ if (keep_llvm_debug or keep_js_debug) and closure:
+ print >> sys.stderr, 'emcc: warning: disabling closure because debug info was requested'
+ closure = False
if minify_whitespace is None:
minify_whitespace = closure # if closure is run, minify whitespace
@@ -984,7 +1021,7 @@ try:
def create_libcxx():
if DEBUG: print >> sys.stderr, 'emcc: building libcxx for cache'
os = []
- for src in ['algorithm.cpp', 'condition_variable.cpp', 'future.cpp', 'iostream.cpp', 'memory.cpp', 'random.cpp', 'stdexcept.cpp', 'system_error.cpp', 'utility.cpp', 'bind.cpp', 'debug.cpp', 'hash.cpp', 'mutex.cpp', 'string.cpp', 'thread.cpp', 'valarray.cpp', 'chrono.cpp', 'exception.cpp', 'ios.cpp', 'locale.cpp', 'regex.cpp', 'strstream.cpp', 'typeinfo.cpp']:
+ for src in ['algorithm.cpp', 'condition_variable.cpp', 'future.cpp', 'iostream.cpp', 'memory.cpp', 'random.cpp', 'stdexcept.cpp', 'system_error.cpp', 'utility.cpp', 'bind.cpp', 'debug.cpp', 'hash.cpp', 'mutex.cpp', 'string.cpp', 'thread.cpp', 'valarray.cpp', 'chrono.cpp', 'exception.cpp', 'ios.cpp', 'locale.cpp', 'regex.cpp', 'strstream.cpp']:
o = in_temp(src + '.o')
execute([shared.PYTHON, shared.EMXX, shared.path_from_root('system', 'lib', 'libcxx', src), '-o', o], stdout=stdout, stderr=stderr)
os.append(o)
@@ -1003,7 +1040,7 @@ try:
def create_libcxxabi():
if DEBUG: print >> sys.stderr, 'emcc: building libcxxabi for cache'
os = []
- for src in ['private_typeinfo.cpp']:
+ for src in ['private_typeinfo.cpp', 'typeinfo.cpp']:
o = in_temp(src + '.o')
execute([shared.PYTHON, shared.EMXX, shared.path_from_root('system', 'lib', 'libcxxabi', 'src', src), '-o', o], stdout=stdout, stderr=stderr)
os.append(o)
@@ -1017,29 +1054,32 @@ try:
libcxxabi_symbols = filter(lambda symbol: symbol not in libc_symbols, libcxxabi_symbols)
libcxxabi_symbols = set(libcxxabi_symbols)
- force = False # If we have libcxx, we must force inclusion of libc, since libcxx uses new internally. Note: this is kind of hacky
-
+ # If we have libcxx, we must force inclusion of libc, since libcxx uses new internally. Note: this is kind of hacky
+ # Settings this in the environment will avoid checking dependencies and make building big projects a little faster
+ force = os.environ.get('EMCC_FORCE_STDLIBS')
+ has = need = None
for name, create, fix, library_symbols in [('libcxx', create_libcxx, fix_libcxx, libcxx_symbols),
('libcxxabi', create_libcxxabi, fix_libcxxabi, libcxxabi_symbols),
('libc', create_libc, fix_libc, libc_symbols)]:
- need = set()
- has = set()
- for temp_file in temp_files:
- symbols = shared.Building.llvm_nm(temp_file)
- for library_symbol in library_symbols:
- if library_symbol in symbols.undefs:
- need.add(library_symbol)
- if library_symbol in symbols.defs:
- has.add(library_symbol)
- for haz in has: # remove symbols that are supplied by another of the inputs
- if haz in need:
- need.remove(haz)
- if DEBUG: print >> sys.stderr, 'emcc: considering including %s: we need %s and have %s' % (name, str(need), str(has))
+ if not force:
+ need = set()
+ has = set()
+ for temp_file in temp_files:
+ symbols = shared.Building.llvm_nm(temp_file)
+ for library_symbol in library_symbols:
+ if library_symbol in symbols.undefs:
+ need.add(library_symbol)
+ if library_symbol in symbols.defs:
+ has.add(library_symbol)
+ for haz in has: # remove symbols that are supplied by another of the inputs
+ if haz in need:
+ need.remove(haz)
+ if DEBUG: print >> sys.stderr, 'emcc: considering including %s: we need %s and have %s' % (name, str(need), str(has))
if force or len(need) > 0:
# We need to build and link the library in
if DEBUG: print >> sys.stderr, 'emcc: including %s' % name
libfile = shared.Cache.get(name, create)
- if len(has) > 0:
+ if has and len(has) > 0:
# remove the symbols we do not need
fixed = in_temp(uniquename(libfile)) + '.bc'
shutil.copyfile(libfile, fixed)
@@ -1049,7 +1089,7 @@ try:
libfile = fixed
extra_files_to_link.append(libfile)
force = True
- if fix:
+ if fix and need:
fix(need)
# First, combine the bitcode files if there are several. We must also link if we have a singleton .a
@@ -1084,7 +1124,7 @@ try:
# Optimize, if asked to
if not LEAVE_INPUTS_RAW:
- link_opts = [] if keep_debug else ['-strip-debug']
+ link_opts = [] if keep_llvm_debug else ['-strip-debug'] # remove LLVM debug info in -O1+, since the optimizer removes it anyhow
if llvm_opts > 0:
shared.Building.llvm_opt(in_temp(target_basename + '.bc'), llvm_opts)
if DEBUG: save_intermediate('opt', 'bc')
@@ -1216,8 +1256,9 @@ try:
if DEBUG: print >> sys.stderr, 'emcc: running closure'
final = shared.Building.closure_compiler(final)
if DEBUG: save_intermediate('closure')
- elif shared.Settings.ASM_JS and shared.Settings.RELOOP:
- js_optimizer_queue += ['registerize'] # we can't use closure in asm, but this does much of the same
+ elif shared.Settings.RELOOP and not closure and not keep_js_debug:
+ # do this if closure is not enabled (it gives similar speedups), and we do not need to keep debug info around
+ js_optimizer_queue += ['registerize']
if opt_level >= 1:
if DEBUG: print >> sys.stderr, 'emcc: running post-closure post-opts'
diff --git a/emscripten.py b/emscripten.py
index af762a21..b3e153c1 100755
--- a/emscripten.py
+++ b/emscripten.py
@@ -322,10 +322,7 @@ def emscript(infile, settings, outfile, libraries=[]):
function_tables_defs = '\n'.join([info[0] for info in infos] + [info[1] for info in infos])
asm_setup = ''
- maths = ['Math.' + func for func in ['floor', 'abs', 'sqrt', 'pow', 'cos', 'sin', 'tan', 'acos', 'asin', 'atan', 'atan2', 'exp', 'log', 'ceil']]
- if settings['USE_MATH_IMUL']:
- maths += ['Math.imul']
- asm_setup += 'if (!Math.imul) Math.imul = function(x, y) { return (x*y)|0 }; // # not a real polyfill since semantics not identical, but close and fairly fast\n'
+ maths = ['Math.' + func for func in ['floor', 'abs', 'sqrt', 'pow', 'cos', 'sin', 'tan', 'acos', 'asin', 'atan', 'atan2', 'exp', 'log', 'ceil', 'imul']]
fundamentals = ['Math', 'Int8Array', 'Int16Array', 'Int32Array', 'Uint8Array', 'Uint16Array', 'Uint32Array', 'Float32Array', 'Float64Array']
math_envs = ['Runtime.bitshift64', 'Math.min'] # TODO: move min to maths
asm_setup += '\n'.join(['var %s = %s;' % (f.replace('.', '_'), f) for f in math_envs])
diff --git a/src/analyzer.js b/src/analyzer.js
index 1c53b76c..c930231f 100644
--- a/src/analyzer.js
+++ b/src/analyzer.js
@@ -223,6 +223,9 @@ function analyzer(data, sidePass) {
for (var i = 0; i < item.params.length; i++) {
if (item.params[i].type == 'i64') item.params[i].type = 'i32';
}
+ } else if (item.intertype == 'inttoptr') {
+ var input = item.params[0];
+ if (input.type == 'i64') input.type = 'i32'; // inttoptr can only care about 32 bits anyhow since pointers are 32-bit
}
if (isIllegalType(item.valueType) || isIllegalType(item.type)) {
isIllegal = true;
@@ -681,9 +684,9 @@ function analyzer(data, sidePass) {
params: [(signed && j + whole > sourceElements.length) ? signedKeepAlive : null],
type: 'i32',
};
- if (j == 0 && isUnsignedOp(value.op) && sourceBits < 32) {
+ if (j == 0 && sourceBits < 32) {
// zext sign correction
- result.ident = makeSignOp(result.ident, 'i' + sourceBits, 'un', 1, 1);
+ result.ident = makeSignOp(result.ident, 'i' + sourceBits, isUnsignedOp(value.op) ? 'un' : 're', 1, 1);
}
if (fraction != 0) {
var other = {
diff --git a/src/compiler.js b/src/compiler.js
index 25c306cf..0b43842e 100644
--- a/src/compiler.js
+++ b/src/compiler.js
@@ -160,12 +160,6 @@ if (SAFE_HEAP >= 2) {
SAFE_HEAP_LINES = set(SAFE_HEAP_LINES); // for fast checking
}
-if (PGO) { // by default, correct everything during PGO
- CORRECT_SIGNS = CORRECT_SIGNS || 1;
- CORRECT_OVERFLOWS = CORRECT_OVERFLOWS || 1;
- CORRECT_ROUNDINGS = CORRECT_ROUNDINGS || 1;
-}
-
EXPORTED_FUNCTIONS = set(EXPORTED_FUNCTIONS);
EXPORTED_GLOBALS = set(EXPORTED_GLOBALS);
EXCEPTION_CATCHING_WHITELIST = set(EXCEPTION_CATCHING_WHITELIST);
@@ -185,7 +179,7 @@ assert(!(!NAMED_GLOBALS && BUILD_AS_SHARED_LIB)); // shared libraries must have
if (phase == 'pre') {
if (!MICRO_OPTS || !RELOOP || ASSERTIONS || CHECK_SIGNS || CHECK_OVERFLOWS || INIT_STACK || INIT_HEAP ||
- !SKIP_STACK_IN_SMALL || SAFE_HEAP || PGO || PROFILE || !DISABLE_EXCEPTION_CATCHING) {
+ !SKIP_STACK_IN_SMALL || SAFE_HEAP || !DISABLE_EXCEPTION_CATCHING) {
print('// Note: Some Emscripten settings will significantly limit the speed of the generated code.');
} else {
print('// Note: For maximum-speed code, see "Optimizing Code" on the Emscripten wiki, https://github.com/kripken/emscripten/wiki/Optimizing-Code');
diff --git a/src/corruptionCheck.js b/src/corruptionCheck.js
new file mode 100644
index 00000000..315f5cf0
--- /dev/null
+++ b/src/corruptionCheck.js
@@ -0,0 +1,98 @@
+
+// See settings.js, CORRUPTION_CHECK
+
+var CorruptionChecker = {
+ BUFFER_FACTOR: Math.round({{{ CORRUPTION_CHECK }}}),
+
+ ptrs: {},
+ checks: 0,
+ checkFrequency: 1,
+
+ init: function() {
+ this.realMalloc = _malloc;
+ _malloc = Module['_malloc'] = this.malloc;
+
+ this.realFree = _free;
+ _free = Module['_free'] = this.free;
+
+ if (typeof _realloc != 'undefined') {
+ this.realRealloc = _realloc;
+ _realloc = Module['_realloc'] = this.realloc;
+ }
+
+ __ATEXIT__.push({ func: function() {
+ Module.printErr('No corruption detected, ran ' + CorruptionChecker.checks + ' checks.');
+ } });
+ },
+ malloc: function(size) {
+ if (size <= 0) size = 1; // malloc(0) sometimes happens - just allocate a larger area, no harm
+ CorruptionChecker.checkAll();
+ size = (size+7)&(~7);
+ var allocation = CorruptionChecker.realMalloc(size*(1+2*CorruptionChecker.BUFFER_FACTOR));
+ var ptr = allocation + size*CorruptionChecker.BUFFER_FACTOR;
+ assert(!CorruptionChecker.ptrs[ptr]);
+ CorruptionChecker.ptrs[ptr] = size;
+ CorruptionChecker.fillBuffer(allocation, size*CorruptionChecker.BUFFER_FACTOR);
+ CorruptionChecker.fillBuffer(allocation + size*(1+CorruptionChecker.BUFFER_FACTOR), size*CorruptionChecker.BUFFER_FACTOR);
+ //Module.printErr('malloc ' + size + ' ==> ' + [ptr, allocation]);
+ return ptr;
+ },
+ free: function(ptr) {
+ if (!ptr) return; // ok to free(NULL), does nothing
+ CorruptionChecker.checkAll();
+ var size = CorruptionChecker.ptrs[ptr];
+ //Module.printErr('free ' + ptr + ' of size ' + size);
+ assert(size);
+ var allocation = ptr - size*CorruptionChecker.BUFFER_FACTOR;
+ //Module.printErr('free ' + ptr + ' of size ' + size + ' and allocation ' + allocation);
+ delete CorruptionChecker.ptrs[ptr];
+ CorruptionChecker.realFree(allocation);
+ },
+ realloc: function(ptr, newSize) {
+ //Module.printErr('realloc ' + ptr + ' to size ' + newSize);
+ if (newSize <= 0) newSize = 1; // like in malloc
+ if (!ptr) return CorruptionChecker.malloc(newSize); // realloc(NULL, size) forwards to malloc according to the spec
+ var size = CorruptionChecker.ptrs[ptr];
+ assert(size);
+ var allocation = ptr - size*CorruptionChecker.BUFFER_FACTOR;
+ var newPtr = CorruptionChecker.malloc(newSize);
+ //Module.printErr('realloc ' + ptr + ' to size ' + newSize + ' is now ' + newPtr);
+ var newAllocation = newPtr + newSize*CorruptionChecker.BUFFER_FACTOR;
+ HEAPU8.set(HEAPU8.subarray(ptr, ptr + Math.min(size, newSize)), newPtr);
+ CorruptionChecker.free(ptr);
+ return newPtr;
+ },
+ canary: function(x) {
+ return (x&127) + 10;
+ },
+ fillBuffer: function(buffer, size) {
+ for (var x = buffer; x < buffer + size; x++) {
+ {{{ makeSetValue('x', 0, 'CorruptionChecker.canary(x)', 'i8') }}};
+ }
+ },
+ checkBuffer: function(buffer, size) {
+ for (var x = buffer; x < buffer + size; x++) {
+ if (({{{ makeGetValue('x', 0, 'i8') }}}&255) != CorruptionChecker.canary(x)) {
+ assert(0, 'Heap corruption detected!' + [x, buffer, size, {{{ makeGetValue('x', 0, 'i8') }}}&255, CorruptionChecker.canary(x)]);
+ }
+ }
+ },
+ checkPtr: function(ptr) {
+ var size = CorruptionChecker.ptrs[ptr];
+ assert(size);
+ var allocation = ptr - size*CorruptionChecker.BUFFER_FACTOR;
+ CorruptionChecker.checkBuffer(allocation, size*CorruptionChecker.BUFFER_FACTOR);
+ CorruptionChecker.checkBuffer(allocation + size*(1+CorruptionChecker.BUFFER_FACTOR), size*CorruptionChecker.BUFFER_FACTOR);
+ },
+ checkAll: function(force) {
+ CorruptionChecker.checks++;
+ if (!force && CorruptionChecker.checks % CorruptionChecker.checkFrequency != 0) return;
+ //Module.printErr('checking for corruption ' + (CorruptionChecker.checks/CorruptionChecker.checkFrequency));
+ for (var ptr in CorruptionChecker.ptrs) {
+ CorruptionChecker.checkPtr(ptr, false);
+ }
+ },
+};
+
+CorruptionChecker.init();
+
diff --git a/src/jsifier.js b/src/jsifier.js
index 761a5fec..4af522b4 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -478,8 +478,7 @@ function JSify(data, functionsOnly, givenFunctions) {
ident = '_' + ident;
}
var depsText = (deps ? '\n' + deps.map(addFromLibrary).filter(function(x) { return x != '' }).join('\n') : '');
- // redirected idents just need a var, but no value assigned to them - it would be unused
- var contentText = isFunction ? snippet : ('var ' + ident + (redirectedIdent ? '' : '=' + snippet) + ';');
+ var contentText = isFunction ? snippet : ('var ' + ident + '=' + snippet + ';');
if (ASM_JS) {
var sig = LibraryManager.library[ident.substr(1) + '__sig'];
if (isFunction && sig && LibraryManager.library[ident.substr(1) + '__asm']) {
@@ -508,7 +507,7 @@ function JSify(data, functionsOnly, givenFunctions) {
item.JS = addFromLibrary(shortident);
} else {
item.JS = 'var ' + item.ident + '; // stub for ' + item.ident;
- if (WARN_ON_UNDEFINED_SYMBOLS) {
+ if (WARN_ON_UNDEFINED_SYMBOLS || ASM_JS) { // always warn on undefs in asm, since it breaks validation
warn('Unresolved symbol: ' + item.ident);
}
}
@@ -631,15 +630,6 @@ function JSify(data, functionsOnly, givenFunctions) {
}
}
- if (PROFILE) {
- func.JS += ' if (PROFILING) { '
- + 'var __parentProfilingNode__ = PROFILING_NODE; PROFILING_NODE = PROFILING_NODE.children["' + func.ident + '"]; '
- + 'if (!PROFILING_NODE) __parentProfilingNode__.children["' + func.ident + '"] = PROFILING_NODE = { time: 0, children: {}, calls: 0 };'
- + 'PROFILING_NODE.calls++; '
- + 'var __profilingStartTime__ = Date.now() '
- + '}\n';
- }
-
if (true) { // TODO: optimize away when not needed
if (CLOSURE_ANNOTATIONS) func.JS += '/** @type {number} */';
func.JS += ' var label = 0;\n';
@@ -1145,12 +1135,6 @@ function JSify(data, functionsOnly, givenFunctions) {
});
makeFuncLineActor('return', function(item) {
var ret = RuntimeGenerator.stackExit(item.funcData.initialStack, item.funcData.otherStackAllocations) + ';\n';
- if (PROFILE) {
- ret += 'if (PROFILING) { '
- + 'PROFILING_NODE.time += Date.now() - __profilingStartTime__; '
- + 'PROFILING_NODE = __parentProfilingNode__ '
- + '}\n';
- }
if (LABEL_DEBUG && functionNameFilterTest(item.funcData.ident)) {
ret += "Module.print(INDENT + 'Exiting: " + item.funcData.ident + "');\n"
+ "INDENT = INDENT.substr(0, INDENT.length-2);\n";
@@ -1527,7 +1511,7 @@ function JSify(data, functionsOnly, givenFunctions) {
print('// ASM_LIBRARY FUNCTIONS');
function fix(f) { // fix indenting to not confuse js optimizer
f = f.substr(f.indexOf('f')); // remove initial spaces before 'function'
- f = f.substr(0, f.lastIndexOf('\n')+1); // remove spaces and last }
+ f = f.substr(0, f.lastIndexOf('\n')+1); // remove spaces and last } XXX assumes function has multiple li