From e0cd2c4078c5dbaecda881c9258f01d5069a1d02 Mon Sep 17 00:00:00 2001 From: ngld Date: Mon, 16 Sep 2013 01:55:55 +0200 Subject: [PATCH 001/165] Started work on #1554 Added a script to extract struct sizes and field offsets as well as constant (#define) values. --- AUTHORS | 2 +- tools/gen_struct_info.py | 368 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 369 insertions(+), 1 deletion(-) create mode 100644 tools/gen_struct_info.py diff --git a/AUTHORS b/AUTHORS index a04756612e6fa..23325a7d68d14 100644 --- a/AUTHORS +++ b/AUTHORS @@ -96,4 +96,4 @@ a license to everyone to use it as detailed in LICENSE.) * Aidan Hobson Sayers * Charlie Birks * Ranger Harke (copyright owned by Autodesk, Inc.) - +* Tobias Vrinssen diff --git a/tools/gen_struct_info.py b/tools/gen_struct_info.py new file mode 100644 index 0000000000000..563b4fa1107de --- /dev/null +++ b/tools/gen_struct_info.py @@ -0,0 +1,368 @@ +# -*- encoding: utf8 -*- + +''' +This tool extracts information about structs and defines from the C headers. +You can pass either the raw header files or JSON files to this script. + +The JSON input format is as follows: +[ + { + 'file': 'some/header.h', + 'structs': { + 'struct_name': [ + 'field1', + 'field2', + 'field3', + { + 'field4': [ + 'nested1', + 'nested2', + { + 'nested3': [ + 'deep_nested1', + ... + ] + } + ... + ] + }, + 'field5' + ], + 'other_struct': [ + 'field1', + 'field2', + ... + ] + }, + 'defines': [ + 'DEFINE_1', + 'DEFINE_2', + ['f', 'FLOAT_DEFINE'], + 'DEFINE_3', + ... + ] + }, + { + 'file': 'some/other/header.h', + ... + } +] + +Please note that the 'f' for 'FLOAT_DEFINE' is just the format passed to printf(), you can put anything printf() understands. +If you call this script with the flag "-f" and pass a header file, it will create an automated boilerplate for you. + +The JSON output format is based on the return value of Runtime.generateStructInfo(). +{ + 'structs': { + 'struct_name': { + '__size__': , + 'field1': , + 'field2': , + 'field3': , + 'field4': { + '__size__': , + 'nested1': , + ... + }, + ... + } + }, + 'defines': { + 'DEFINE_1': , + ... + } +} + +''' + +import sys +import os +import json +import argparse +import tempfile +import subprocess +import shared + +# Try to load pycparser. +try: + import pycparser +except ImportError: + # The import failed, warn the user. + sys.stderr.write('WARN: pycparser isn\'t available. I won\'t be able to parse C files, only .json files.\n') + + def parse_header(path, cpp_opts): + # Tell the user how to get pycparser, if he tries to parse a C file. + sys.stderr.write('ERR: I need pycparser to process C files. \n') + sys.stderr.write(' Use "pip install pycparser" or go to "https://github.com/eliben/pycparser" to install it.\n') + sys.exit(1) +else: + # We successfully imported pycparser, the script will be completely functional. + + class FieldVisitor(pycparser.c_ast.NodeVisitor): + def __init__(self): + self._name = None + self.structs = {} + self.named_structs = {} + + def visit_Struct(self, node): + if node.decls == None: + # Skip empty struct declarations. + return + + fields = [] + for decl in node.decls: + # Look for nested structs. + subwalk = FieldVisitor() + subwalk.visit(decl) + + if subwalk.named_structs: + # Store the nested fields. + fields.append(subwalk.named_structs) + else: + # Just store the field name. + fields.append(decl.name) + + if node.name != None: + self.structs[node.name] = fields + + self.named_structs[self._name] = fields + + def visit_Union(self, node): + self.visit_Struct(node) + + def visit_TypeDecl(self, node): + # Remember the name of this typedef, so we can access it later in visit_Struct(). + old_name = self._name + self._name = node.declname + self.generic_visit(node) + self._name = old_name + + def parse_header(path, cpp_opts): + sys.stderr.write('Parsing header "' + path + '"...\n') + + # Use clang -E as the preprocessor for pycparser. + ast = pycparser.parse_file(path, True, cpp_path=shared.CLANG_CC, cpp_args=['-E'] + cpp_opts) + + # Walk the parsed AST and filter out all the declared structs and their fields. + walker = FieldVisitor() + walker.visit(ast) + return walker.structs + +# The following three functions generate C code. The output of the compiled code will be +# parsed later on and then put back together into a dict structure by parse_c_output(). +def c_set(name, type_, value, code): + code.append('printf("K' + name + '\\n");') + code.append('printf("V' + type_ + '\\n", ' + value + ');') + +def c_descent(name, code): + code.append('printf("D' + name + '\\n");') + +def c_ascent(code): + code.append('printf("A\\n");') + +def parse_c_output(lines): + result = {} + cur_level = result + parent = [] + key = None + + for line in lines: + arg = line[1:].strip() + if line[0] == 'K': + # This is a key + key = arg + elif line[0] == 'V': + # A value + cur_level[key] = int(arg) + elif line[0] == 'D': + # Remember the current level as the last parent. + parent.append(cur_level) + + # We descend one level. + cur_level[arg] = {} + cur_level = cur_level[arg] + elif line[0] == 'A': + # We return to the parent dict. (One level up.) + cur_level = parent.pop() + + return result + +def gen_inspect_code(path, struct, code): + c_descent(path[-1], code) + if len(path) == 1: + c_set('__size__', '%lu', 'sizeof (struct ' + path[0] + ')', code) + else: + c_set('__size__', '%lu', 'sizeof ((struct ' + path[0] + ' *)0)->' + '.'.join(path[1:]), code) + + for field in struct: + if isinstance(field, dict): + # We have to recurse to inspect the nested dict. + fname = field.keys()[0] + gen_inspect_code(path + [fname], field[fname], code) + else: + c_set(field, '%u', 'offsetof(struct ' + path[0] + ', ' + '.'.join(path[1:] + [field]) + ')', code) + + c_ascent(code) + +def inspect_code(headers, cpp_opts, structs, defines): + sys.stderr.write('Generating C code...\n') + + code = ['#include ', '#include '] + # Include all the needed headers. + for path in headers: + code.append('#include "' + path + '"') + + code.append('int main() {') + c_descent('structs', code) + for name, struct in structs.items(): + gen_inspect_code([name], struct, code) + + c_ascent(code) + c_descent('defines', code) + for name in defines: + if isinstance(name, list): + type_, name = name + else: + type_ = 'i' + c_set(name, '%' + type_, name, code) + + code.append('return 0;') + code.append('}') + + # Write the source code to a temporary file. + src_file = tempfile.mkstemp('.c') + bin_file = tempfile.mkstemp() + + os.write(src_file[0], '\n'.join(code)) + + # Close all unneeded FDs. + os.close(src_file[0]) + os.close(bin_file[0]) + + info = [] + try: + # Compile the program. + sys.stderr.write('Compiling generated code...\n') + subprocess.check_call([shared.CLANG_CC] + cpp_opts + ['-o', bin_file[1], src_file[1]]) + + # Run the compiled program. + sys.stderr.write('Calling generated program...\n') + info = subprocess.check_output([bin_file[1]]).splitlines() + except subprocess.CalledProcessError: + if os.path.isfile(bin_file[1]): + sys.stderr.write('FAIL: Running the generated program failed!\n') + else: + sys.stderr.write('FAIL: Compilation failed!\n') + + sys.exit(1) + finally: + # Remove all temporary files. + os.unlink(src_file[1]) + + if os.path.exists(bin_file[1]): + os.unlink(bin_file[1]) + + # Parse the output of the program into a dict. + data = parse_c_output(info) + + # Convert all the define's values into the appropriate python types (based on the type passed to printf). + for name in defines: + if isinstance(name, list): + type_, name = name + else: + type_ = 'i' + + if type_[-1] in ('d', 'i', 'u'): + # Integer + data['defines'][name] = int(data['defines'][name]) + elif type_[-1] in ('x', 'X', 'a', 'A'): + # Hexadecimal + data['defines'][name] = float.fromhex(data['defines'][name]) + elif type_[-1] in ('f', 'F', 'e', 'E', 'g', 'G'): + # Float + data['defines'][name] = float(data['defines'][name]) + # Leave everything else untouched. + + return data + +def main(): + parser = argparse.ArgumentParser(description='Generate JSON infos for structs.') + parser.add_argument('headers', nargs='+', help='A header (.h) file or a JSON file with a list of structs and their fields') + parser.add_argument('-f', dest='list_fields', action='store_true', default=False, help='Output a list of structs and fields for the first header.') + parser.add_argument('-p', dest='pretty_print', action='store_true', default=False, help='Pretty print the outputted JSON.') + parser.add_argument('-o', dest='output', metavar='path', default=None, help='Path to the JSON file that will be written. If omitted, the generated data will be printed to stdout.') + parser.add_argument('-I', dest='includes', metavar='dir', action='append', default=[], help='Add directory to include search path') + parser.add_argument('-D', dest='defines', metavar='define', action='append', default=[], help='Pass a define to the preprocessor') + parser.add_argument('-U', dest='undefines', metavar='undefine', action='append', default=[], help='Pass an undefine to the preprocessor') + args = parser.parse_args() + + # Avoid parsing problems due to gcc specifc syntax. + cpp_opts = ['-U__GNUC__'] + + # Only apply compiler options regarding syntax, includes and defines. + # We have to compile for the current system, we aren't compiling to bitcode after all. + for flag in shared.COMPILER_OPTS: + if flag[:2] in ('-f', '-I', '-i', '-D', '-U'): + cpp_opts.append(flag) + + # Add the user options to the list as well. + for path in args.includes: + cpp_opts.append('-I' + path) + + for arg in args.defines: + cpp_opts.append('-D' + arg) + + for arg in args.undefines: + cpp_opts.append('-U' + arg) + + if args.list_fields: + # Just parse the first header and output the result. + structs = parse_header(args.headers[0], cpp_opts) + data = { + 'file': args.headers[0], + 'structs': structs, + 'defines': [] + } + + if args.output == None: + sys.stdout.write(json.dumps(data, indent=4 if args.pretty_print else None)) + else: + with open(args.output, 'w') as stream: + json.dump(data, stream, indent=4 if args.pretty_print else None) + + sys.exit(0) + + # Look for structs in all passed headers. + header_files = [] + structs = {} + defines = {} + + for header in args.headers: + if header[-5:] == '.json': + # This is a JSON file, simply load it. + with open(header, 'r') as stream: + data = json.load(stream) + + if not isinstance(data, list): + data = [ data ] + + for item in data: + header_files.append(item['file']) + structs.update(item['structs']) + defines.update(item['defines']) + else: + # If the passed file isn't a JSON file, assume it's a header. + header_files.append(header) + structs.update(parse_header(header, cpp_opts)) + + # Inspect all collected structs. + struct_info = inspect_code(header_files, cpp_opts, structs, defines) + + if args.output == None: + sys.stdout.write(json.dumps(struct_info, indent=4 if args.pretty_print else None)) + else: + with open(args.output, 'w') as stream: + json.dump(struct_info, stream, indent=4 if args.pretty_print else None) + +if __name__ == '__main__': + main() \ No newline at end of file From 1600df2e360d0bbfd9195b3523dd3d0b440fe62a Mon Sep 17 00:00:00 2001 From: ngld Date: Mon, 16 Sep 2013 23:49:19 +0200 Subject: [PATCH 002/165] Integrate the new tool into emscripten Automatically compile struct_info.json and save the compiled version in the emscripten cache. --- emscripten.py | 9 +- src/compiler.js | 6 + src/library.js | 593 ++++++++++------------------ src/parseTools.js | 3 +- src/struct_info.json | 822 +++++++++++++++++++++++++++++++++++++++ tools/gen_struct_info.py | 335 +++++++++++----- tools/shared.py | 12 +- 7 files changed, 1298 insertions(+), 482 deletions(-) create mode 100644 src/struct_info.json diff --git a/emscripten.py b/emscripten.py index 4d744fdd64f46..e6a6e1243652b 100755 --- a/emscripten.py +++ b/emscripten.py @@ -709,7 +709,14 @@ def main(args, compiler_engine, cache, jcache, relooper, temp_files, DEBUG, DEBU if not os.path.exists(relooper): from tools import shared shared.Building.ensure_relooper(relooper) - + + settings.setdefault('STRUCT_INFO', cache.get_path('struct_info.compiled.json')) + struct_info = settings.get('STRUCT_INFO') + + if not os.path.exists(struct_info): + from tools import shared + shared.Building.ensure_struct_info(struct_info) + emscript(args.infile, settings, args.outfile, libraries, compiler_engine=compiler_engine, jcache=jcache, temp_files=temp_files, DEBUG=DEBUG, DEBUG_CACHE=DEBUG_CACHE) diff --git a/src/compiler.js b/src/compiler.js index f2b0dcbd07658..6982403515ee8 100644 --- a/src/compiler.js +++ b/src/compiler.js @@ -204,6 +204,12 @@ if (phase == 'pre') { if (VERBOSE) printErr('VERBOSE is on, this generates a lot of output and can slow down compilation'); +// Load struct and define information. +var temp = JSON.parse(read(STRUCT_INFO)); +C_STRUCTS = temp.structs; +// NOTE: This overwrites C_DEFINES from settings.js, should this be fixed or will C_DEFINES in settings.js be deprecated? +C_DEFINES = temp.defines; + // Load compiler code load('framework.js'); diff --git a/src/library.js b/src/library.js index aac5a9dacce4f..b45dd8f5aa041 100644 --- a/src/library.js +++ b/src/library.js @@ -28,13 +28,7 @@ LibraryManager.library = { // dirent.h // ========================================================================== - __dirent_struct_layout: Runtime.generateStructInfo([ - ['i32', 'd_ino'], - ['i32', 'd_off'], - ['i16', 'd_reclen'], - ['i8', 'd_type'], - ['b256', 'd_name']]), - opendir__deps: ['$FS', '__setErrNo', '$ERRNO_CODES', '__dirent_struct_layout', 'open'], + opendir__deps: ['$FS', '__setErrNo', '$ERRNO_CODES', 'open'], opendir: function(dirname) { // DIR *opendir(const char *dirname); // http://pubs.opengroup.org/onlinepubs/007908799/xsh/opendir.html @@ -90,7 +84,7 @@ LibraryManager.library = { // http://pubs.opengroup.org/onlinepubs/007908799/xsh/rewinddir.html _seekdir(dirp, 0); }, - readdir_r__deps: ['$FS', '__setErrNo', '$ERRNO_CODES', '__dirent_struct_layout'], + readdir_r__deps: ['$FS', '__setErrNo', '$ERRNO_CODES'], readdir_r: function(dirp, entry, result) { // int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result); // http://pubs.opengroup.org/onlinepubs/007908799/xsh/readdir_r.html @@ -123,14 +117,14 @@ LibraryManager.library = { FS.isLink(child.mode) ? 10 : // DT_LNK, symbolic link. 8; // DT_REG, regular file. } - {{{ makeSetValue('entry', '___dirent_struct_layout.d_ino', 'id', 'i32') }}} - {{{ makeSetValue('entry', '___dirent_struct_layout.d_off', 'offset', 'i32') }}} - {{{ makeSetValue('entry', '___dirent_struct_layout.d_reclen', 'name.length + 1', 'i32') }}} + {{{ makeSetValue('entry', C_STRUCTS.dirent.d_ino, 'id', 'i32') }}} + {{{ makeSetValue('entry', C_STRUCTS.dirent.d_off, 'offset', 'i32') }}} + {{{ makeSetValue('entry', C_STRUCTS.dirent.d_reclen, 'name.length + 1', 'i32') }}} for (var i = 0; i < name.length; i++) { - {{{ makeSetValue('entry + ___dirent_struct_layout.d_name', 'i', 'name.charCodeAt(i)', 'i8') }}} + {{{ makeSetValue('entry + ' + C_STRUCTS.dirent.d_name, 'i', 'name.charCodeAt(i)', 'i8') }}} } - {{{ makeSetValue('entry + ___dirent_struct_layout.d_name', 'i', '0', 'i8') }}} - {{{ makeSetValue('entry', '___dirent_struct_layout.d_type', 'type', 'i8') }}} + {{{ makeSetValue('entry + ' + C_STRUCTS.dirent.d_name, 'i', '0', 'i8') }}} + {{{ makeSetValue('entry', C_STRUCTS.dirent.d_type, 'type', 'i8') }}} {{{ makeSetValue('result', '0', 'entry', 'i8*') }}} stream.position++; return 0; @@ -145,7 +139,7 @@ LibraryManager.library = { return 0; } // TODO Is it supposed to be safe to execute multiple readdirs? - if (!_readdir.entry) _readdir.entry = _malloc(___dirent_struct_layout.__size__); + if (!_readdir.entry) _readdir.entry = _malloc({{{ C_STRUCTS.dirent.__size__ }}}); if (!_readdir.result) _readdir.result = _malloc(4); var err = _readdir_r(dirp, _readdir.entry, _readdir.result); if (err) { @@ -161,17 +155,14 @@ LibraryManager.library = { // utime.h // ========================================================================== - __utimbuf_struct_layout: Runtime.generateStructInfo([ - ['i32', 'actime'], - ['i32', 'modtime']]), - utime__deps: ['$FS', '__setErrNo', '$ERRNO_CODES', '__utimbuf_struct_layout'], + utime__deps: ['$FS', '__setErrNo', '$ERRNO_CODES'], utime: function(path, times) { // int utime(const char *path, const struct utimbuf *times); // http://pubs.opengroup.org/onlinepubs/009695399/basedefs/utime.h.html var time; if (times) { // NOTE: We don't keep track of access timestamps. - var offset = ___utimbuf_struct_layout.modtime; + var offset = {{{ C_STRUCTS.utimbuf.modtime }}}; time = {{{ makeGetValue('times', 'offset', 'i32') }}} time *= 1000; } else { @@ -253,27 +244,7 @@ LibraryManager.library = { // sys/stat.h // ========================================================================== - __stat_struct_layout: Runtime.generateStructInfo([ - ['i32', 'st_dev'], - ['i32', '__st_dev_padding'], - ['i32', '__st_ino_truncated'], - ['i32', 'st_mode'], - ['i32', 'st_nlink'], - ['i32', 'st_uid'], - ['i32', 'st_gid'], - ['i32', 'st_rdev'], - ['i32', '__st_rdev_padding'], - ['i32', 'st_size'], - ['i32', 'st_blksize'], - ['i32', 'st_blocks'], - ['i32', 'st_atim_secs'], - ['i32', 'st_atim_nsecs'], - ['i32', 'st_mtim_secs'], - ['i32', 'st_mtim_nsecs'], - ['i32', 'st_ctim_secs'], - ['i32', 'st_ctim_nsecs'], - ['i32', 'st_ino']]), - stat__deps: ['$FS', '__stat_struct_layout'], + stat__deps: ['$FS'], stat: function(path, buf, dontResolveLastLink) { // http://pubs.opengroup.org/onlinepubs/7908799/xsh/stat.html // int stat(const char *path, struct stat *buf); @@ -282,25 +253,25 @@ LibraryManager.library = { path = typeof path !== 'string' ? Pointer_stringify(path) : path; try { var stat = dontResolveLastLink ? FS.lstat(path) : FS.stat(path); - {{{ makeSetValue('buf', '___stat_struct_layout.st_dev', 'stat.dev', 'i32') }}}; - {{{ makeSetValue('buf', '___stat_struct_layout.__st_dev_padding', '0', 'i32') }}}; - {{{ makeSetValue('buf', '___stat_struct_layout.__st_ino_truncated', 'stat.ino', 'i32') }}}; - {{{ makeSetValue('buf', '___stat_struct_layout.st_mode', 'stat.mode', 'i32') }}} - {{{ makeSetValue('buf', '___stat_struct_layout.st_nlink', 'stat.nlink', 'i32') }}} - {{{ makeSetValue('buf', '___stat_struct_layout.st_uid', 'stat.uid', 'i32') }}} - {{{ makeSetValue('buf', '___stat_struct_layout.st_gid', 'stat.gid', 'i32') }}} - {{{ makeSetValue('buf', '___stat_struct_layout.st_rdev', 'stat.rdev', 'i32') }}} - {{{ makeSetValue('buf', '___stat_struct_layout.__st_rdev_padding', '0', 'i32') }}}; - {{{ makeSetValue('buf', '___stat_struct_layout.st_size', 'stat.size', 'i32') }}} - {{{ makeSetValue('buf', '___stat_struct_layout.st_blksize', '4096', 'i32') }}} - {{{ makeSetValue('buf', '___stat_struct_layout.st_blocks', 'stat.blocks', 'i32') }}} - {{{ makeSetValue('buf', '___stat_struct_layout.st_atim_secs', 'Math.floor(stat.atime.getTime() / 1000)', 'i32') }}} - {{{ makeSetValue('buf', '___stat_struct_layout.st_atim_nsecs', '0', 'i32') }}} - {{{ makeSetValue('buf', '___stat_struct_layout.st_mtim_secs', 'Math.floor(stat.mtime.getTime() / 1000)', 'i32') }}} - {{{ makeSetValue('buf', '___stat_struct_layout.st_mtim_nsecs', '0', 'i32') }}} - {{{ makeSetValue('buf', '___stat_struct_layout.st_ctim_secs', 'Math.floor(stat.ctime.getTime() / 1000)', 'i32') }}} - {{{ makeSetValue('buf', '___stat_struct_layout.st_ctim_nsecs', '0', 'i32') }}} - {{{ makeSetValue('buf', '___stat_struct_layout.st_ino', 'stat.ino', 'i32') }}} + {{{ makeSetValue('buf', C_STRUCTS.stat.st_dev, 'stat.dev', 'i32') }}}; + {{{ makeSetValue('buf', C_STRUCTS.stat.__st_dev_padding, '0', 'i32') }}}; + {{{ makeSetValue('buf', C_STRUCTS.stat.__st_ino_truncated, 'stat.ino', 'i32') }}}; + {{{ makeSetValue('buf', C_STRUCTS.stat.st_mode, 'stat.mode', 'i32') }}} + {{{ makeSetValue('buf', C_STRUCTS.stat.st_nlink, 'stat.nlink', 'i32') }}} + {{{ makeSetValue('buf', C_STRUCTS.stat.st_uid, 'stat.uid', 'i32') }}} + {{{ makeSetValue('buf', C_STRUCTS.stat.st_gid, 'stat.gid', 'i32') }}} + {{{ makeSetValue('buf', C_STRUCTS.stat.st_rdev, 'stat.rdev', 'i32') }}} + {{{ makeSetValue('buf', C_STRUCTS.stat.__st_rdev_padding, '0', 'i32') }}}; + {{{ makeSetValue('buf', C_STRUCTS.stat.st_size, 'stat.size', 'i32') }}} + {{{ makeSetValue('buf', C_STRUCTS.stat.st_blksize, '4096', 'i32') }}} + {{{ makeSetValue('buf', C_STRUCTS.stat.st_blocks, 'stat.blocks', 'i32') }}} + {{{ makeSetValue('buf', C_STRUCTS.stat.st_atim.tv_sec, 'Math.floor(stat.atime.getTime() / 1000)', 'i32') }}} + {{{ makeSetValue('buf', C_STRUCTS.stat.st_atim.tv_nsec, '0', 'i32') }}} + {{{ makeSetValue('buf', C_STRUCTS.stat.st_mtim.tv_sec, 'Math.floor(stat.mtime.getTime() / 1000)', 'i32') }}} + {{{ makeSetValue('buf', C_STRUCTS.stat.st_mtim.tv_nsec, '0', 'i32') }}} + {{{ makeSetValue('buf', C_STRUCTS.stat.st_ctim.tv_sec, 'Math.floor(stat.ctime.getTime() / 1000)', 'i32') }}} + {{{ makeSetValue('buf', C_STRUCTS.stat.st_ctim.tv_nsec, '0', 'i32') }}} + {{{ makeSetValue('buf', C_STRUCTS.stat.st_ino, 'stat.ino', 'i32') }}} return 0; } catch (e) { FS.handleFSError(e); @@ -436,43 +407,23 @@ LibraryManager.library = { // sys/statvfs.h // ========================================================================== - __statvfs_struct_layout: Runtime.generateStructInfo([ - ['i32', 'f_bsize'], - ['i32', 'f_frsize'], - ['i32', 'f_blocks'], - ['i32', 'f_bfree'], - ['i32', 'f_bavail'], - ['i32', 'f_files'], - ['i32', 'f_ffree'], - ['i32', 'f_favail'], - ['i32', 'f_fsid'], - ['i32', '__padding'], - ['i32', 'f_flag'], - ['i32', 'f_namemax'], - ['i32', '__reserved_1'], - ['i32', '__reserved_2'], - ['i32', '__reserved_3'], - ['i32', '__reserved_4'], - ['i32', '__reserved_5'], - ['i32', '__reserved_6']]), - statvfs__deps: ['$FS', '__statvfs_struct_layout'], + statvfs__deps: ['$FS'], statvfs: function(path, buf) { // http://pubs.opengroup.org/onlinepubs/009695399/functions/statvfs.html // int statvfs(const char *restrict path, struct statvfs *restrict buf); - var offsets = ___statvfs_struct_layout; // NOTE: None of the constants here are true. We're just returning safe and // sane values. - {{{ makeSetValue('buf', 'offsets.f_bsize', '4096', 'i32') }}} - {{{ makeSetValue('buf', 'offsets.f_frsize', '4096', 'i32') }}} - {{{ makeSetValue('buf', 'offsets.f_blocks', '1000000', 'i32') }}} - {{{ makeSetValue('buf', 'offsets.f_bfree', '500000', 'i32') }}} - {{{ makeSetValue('buf', 'offsets.f_bavail', '500000', 'i32') }}} - {{{ makeSetValue('buf', 'offsets.f_files', 'FS.nextInode', 'i32') }}} - {{{ makeSetValue('buf', 'offsets.f_ffree', '1000000', 'i32') }}} - {{{ makeSetValue('buf', 'offsets.f_favail', '1000000', 'i32') }}} - {{{ makeSetValue('buf', 'offsets.f_fsid', '42', 'i32') }}} - {{{ makeSetValue('buf', 'offsets.f_flag', '2', 'i32') }}} // ST_NOSUID - {{{ makeSetValue('buf', 'offsets.f_namemax', '255', 'i32') }}} + {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_bsize, '4096', 'i32') }}} + {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_frsize, '4096', 'i32') }}} + {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_blocks, '1000000', 'i32') }}} + {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_bfree, '500000', 'i32') }}} + {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_bavail, '500000', 'i32') }}} + {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_files, 'FS.nextInode', 'i32') }}} + {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_ffree, '1000000', 'i32') }}} + {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_favail, '1000000', 'i32') }}} + {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_fsid, '42', 'i32') }}} + {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_flag, '2', 'i32') }}} // ST_NOSUID + {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_namemax, '255', 'i32') }}} return 0; }, fstatvfs__deps: ['statvfs'], @@ -488,13 +439,7 @@ LibraryManager.library = { // fcntl.h // ========================================================================== - __flock_struct_layout: Runtime.generateStructInfo([ - ['i16', 'l_type'], - ['i16', 'l_whence'], - ['i32', 'l_start'], - ['i32', 'l_len'], - ['i16', 'l_pid']]), - open__deps: ['$FS', '__setErrNo', '$ERRNO_CODES', '__dirent_struct_layout'], + open__deps: ['$FS', '__setErrNo', '$ERRNO_CODES'], open: function(path, oflag, varargs) { // int open(const char *path, int oflag, ...); // http://pubs.opengroup.org/onlinepubs/009695399/functions/open.html @@ -523,7 +468,7 @@ LibraryManager.library = { writeArrayToMemory(intArrayFromString(c), template + Pointer_stringify(template).indexOf(rep)); return _creat(template, 0600); }, - fcntl__deps: ['$FS', '__setErrNo', '$ERRNO_CODES', '__flock_struct_layout'], + fcntl__deps: ['$FS', '__setErrNo', '$ERRNO_CODES'], fcntl: function(fildes, cmd, varargs, dup2) { // int fcntl(int fildes, int cmd, ...); // http://pubs.opengroup.org/onlinepubs/009695399/functions/fcntl.html @@ -559,7 +504,7 @@ LibraryManager.library = { case {{{ cDefine('F_GETLK') }}}: case {{{ cDefine('F_GETLK64') }}}: var arg = {{{ makeGetValue('varargs', 0, 'i32') }}}; - var offset = ___flock_struct_layout.l_type; + var offset = {{{ C_STRUCTS.flock.l_type }}}; // We're always unlocked. {{{ makeSetValue('arg', 'offset', cDefine('F_UNLCK'), 'i16') }}} return 0; @@ -621,20 +566,15 @@ LibraryManager.library = { // ========================================================================== __DEFAULT_POLLMASK: {{{ cDefine('POLLIN') }}} | {{{ cDefine('POLLOUT') }}}, - __pollfd_struct_layout: Runtime.generateStructInfo([ - ['i32', 'fd'], - ['i16', 'events'], - ['i16', 'revents']]), - poll__deps: ['$FS', '__DEFAULT_POLLMASK', '__pollfd_struct_layout'], + poll__deps: ['$FS', '__DEFAULT_POLLMASK'], poll: function(fds, nfds, timeout) { // int poll(struct pollfd fds[], nfds_t nfds, int timeout); // http://pubs.opengroup.org/onlinepubs/009695399/functions/poll.html - var offsets = ___pollfd_struct_layout; var nonzero = 0; for (var i = 0; i < nfds; i++) { - var pollfd = fds + ___pollfd_struct_layout.__size__ * i; - var fd = {{{ makeGetValue('pollfd', 'offsets.fd', 'i32') }}}; - var events = {{{ makeGetValue('pollfd', 'offsets.events', 'i16') }}}; + var pollfd = fds + {{{ C_STRUCTS.pollfd.__size__ }}} * i; + var fd = {{{ makeGetValue('pollfd', C_STRUCTS.pollfd.fd, 'i32') }}}; + var events = {{{ makeGetValue('pollfd', C_STRUCTS.pollfd.events, 'i16') }}}; var mask = {{{ cDefine('POLLNVAL') }}}; var stream = FS.getStream(fd); if (stream) { @@ -645,7 +585,7 @@ LibraryManager.library = { } mask &= events | {{{ cDefine('POLLERR') }}} | {{{ cDefine('POLLHUP') }}}; if (mask) nonzero++; - {{{ makeSetValue('pollfd', 'offsets.revents', 'mask', 'i16') }}} + {{{ makeSetValue('pollfd', C_STRUCTS.pollfd.revents, 'mask', 'i16') }}} } return nonzero; }, @@ -5010,17 +4950,11 @@ LibraryManager.library = { {{{ makeSetValue('cosine', '0', 'cosineVal', 'float') }}}; }, - __div_t_struct_layout: Runtime.generateStructInfo([ - ['i32', 'quot'], - ['i32', 'rem'], - ]), - div__deps: ['__div_t_struct_layout'], div: function(divt, numer, denom) { var quot = Math.floor(numer / denom); var rem = numer - quot * denom; - var offset = ___div_t_struct_layout.rem; - {{{ makeSetValue('divt', '0', 'quot', 'i32') }}}; - {{{ makeSetValue('divt', 'offset', 'rem', 'i32') }}}; + {{{ makeSetValue('divt', C_STRUCTS.div_t.quot, 'quot', 'i32') }}}; + {{{ makeSetValue('divt', C_STRUCTS.div_t.rem, 'rem', 'i32') }}}; return divt; }, @@ -5039,19 +4973,12 @@ LibraryManager.library = { // sys/utsname.h // ========================================================================== - __utsname_struct_layout: Runtime.generateStructInfo([ - ['b65', 'sysname'], - ['b65', 'nodename'], - ['b65', 'release'], - ['b65', 'version'], - ['b65', 'machine'], - ['b65', 'domainname']]), - uname__deps: ['__utsname_struct_layout'], uname: function(name) { // int uname(struct utsname *name); // http://pubs.opengroup.org/onlinepubs/009695399/functions/uname.html + var layout = {{{ JSON.stringify(C_STRUCTS.utsname) }}}; function copyString(element, value) { - var offset = ___utsname_struct_layout[element]; + var offset = layout[element]; for (var i = 0; i < value.length; i++) { {{{ makeSetValue('name', 'offset + i', 'value.charCodeAt(i)', 'i8') }}} } @@ -5347,62 +5274,48 @@ LibraryManager.library = { return time1 - time0; }, - __tm_struct_layout: Runtime.generateStructInfo([ - ['i32', 'tm_sec'], - ['i32', 'tm_min'], - ['i32', 'tm_hour'], - ['i32', 'tm_mday'], - ['i32', 'tm_mon'], - ['i32', 'tm_year'], - ['i32', 'tm_wday'], - ['i32', 'tm_yday'], - ['i32', 'tm_isdst'], - ['i32', 'tm_gmtoff'], - ['i8*', 'tm_zone']]), - // Statically allocated time struct. + // Statically allocated time struct. (TODO: Shouldn't C_STRUCTS.tm.__size__ be used here?) __tm_current: 'allocate({{{ Runtime.QUANTUM_SIZE }}}*26, "i8", ALLOC_STATIC)', // Statically allocated timezone string. We only use GMT as a timezone. __tm_timezone: 'allocate(intArrayFromString("GMT"), "i8", ALLOC_STATIC)', // Statically allocated time strings. __tm_formatted: 'allocate({{{ Runtime.QUANTUM_SIZE }}}*26, "i8", ALLOC_STATIC)', - mktime__deps: ['__tm_struct_layout', 'tzset'], + mktime__deps: ['tzset'], mktime: function(tmPtr) { _tzset(); - var offsets = ___tm_struct_layout; - var year = {{{ makeGetValue('tmPtr', 'offsets.tm_year', 'i32') }}}; + var year = {{{ makeGetValue('tmPtr', C_STRUCTS.tm.tm_year, 'i32') }}}; var timestamp = new Date(year >= 1900 ? year : year + 1900, - {{{ makeGetValue('tmPtr', 'offsets.tm_mon', 'i32') }}}, - {{{ makeGetValue('tmPtr', 'offsets.tm_mday', 'i32') }}}, - {{{ makeGetValue('tmPtr', 'offsets.tm_hour', 'i32') }}}, - {{{ makeGetValue('tmPtr', 'offsets.tm_min', 'i32') }}}, - {{{ makeGetValue('tmPtr', 'offsets.tm_sec', 'i32') }}}, + {{{ makeGetValue('tmPtr', C_STRUCTS.tm.tm_mon, 'i32') }}}, + {{{ makeGetValue('tmPtr', C_STRUCTS.tm.tm_mday, 'i32') }}}, + {{{ makeGetValue('tmPtr', C_STRUCTS.tm.tm_hour, 'i32') }}}, + {{{ makeGetValue('tmPtr', C_STRUCTS.tm.tm_min, 'i32') }}}, + {{{ makeGetValue('tmPtr', C_STRUCTS.tm.tm_sec, 'i32') }}}, 0).getTime() / 1000; - {{{ makeSetValue('tmPtr', 'offsets.tm_wday', 'new Date(timestamp).getDay()', 'i32') }}} + {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_wday, 'new Date(timestamp).getDay()', 'i32') }}} var yday = Math.round((timestamp - (new Date(year, 0, 1)).getTime()) / (1000 * 60 * 60 * 24)); - {{{ makeSetValue('tmPtr', 'offsets.tm_yday', 'yday', 'i32') }}} + {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_yday, 'yday', 'i32') }}} return timestamp; }, timelocal: 'mktime', - gmtime__deps: ['malloc', '__tm_struct_layout', '__tm_current', 'gmtime_r'], + gmtime__deps: ['malloc', '__tm_current', 'gmtime_r'], gmtime: function(time) { return _gmtime_r(time, ___tm_current); }, - gmtime_r__deps: ['__tm_struct_layout', '__tm_timezone'], + gmtime_r__deps: ['__tm_timezone'], gmtime_r: function(time, tmPtr) { var date = new Date({{{ makeGetValue('time', 0, 'i32') }}}*1000); - var offsets = ___tm_struct_layout; - {{{ makeSetValue('tmPtr', 'offsets.tm_sec', 'date.getUTCSeconds()', 'i32') }}} - {{{ makeSetValue('tmPtr', 'offsets.tm_min', 'date.getUTCMinutes()', 'i32') }}} - {{{ makeSetValue('tmPtr', 'offsets.tm_hour', 'date.getUTCHours()', 'i32') }}} - {{{ makeSetValue('tmPtr', 'offsets.tm_mday', 'date.getUTCDate()', 'i32') }}} - {{{ makeSetValue('tmPtr', 'offsets.tm_mon', 'date.getUTCMonth()', 'i32') }}} - {{{ makeSetValue('tmPtr', 'offsets.tm_year', 'date.getUTCFullYear()-1900', 'i32') }}} - {{{ makeSetValue('tmPtr', 'offsets.tm_wday', 'date.getUTCDay()', 'i32') }}} - {{{ makeSetValue('tmPtr', 'offsets.tm_gmtoff', '0', 'i32') }}} - {{{ makeSetValue('tmPtr', 'offsets.tm_isdst', '0', 'i32') }}} + {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_sec, 'date.getUTCSeconds()', 'i32') }}} + {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_min, 'date.getUTCMinutes()', 'i32') }}} + {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_hour, 'date.getUTCHours()', 'i32') }}} + {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_mday, 'date.getUTCDate()', 'i32') }}} + {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_mon, 'date.getUTCMonth()', 'i32') }}} + {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_year, 'date.getUTCFullYear()-1900', 'i32') }}} + {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_wday, 'date.getUTCDay()', 'i32') }}} + {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_gmtoff, '0', 'i32') }}} + {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_isdst, '0', 'i32') }}} var start = new Date(date); // define date using UTC, start from Jan 01 00:00:00 UTC start.setUTCDate(1); start.setUTCMonth(0); @@ -5411,8 +5324,8 @@ LibraryManager.library = { start.setUTCSeconds(0); start.setUTCMilliseconds(0); var yday = Math.floor((date.getTime() - start.getTime()) / (1000 * 60 * 60 * 24)); - {{{ makeSetValue('tmPtr', 'offsets.tm_yday', 'yday', 'i32') }}} - {{{ makeSetValue('tmPtr', 'offsets.tm_zone', '___tm_timezone', 'i32') }}} + {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_yday, 'yday', 'i32') }}} + {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_zone, '___tm_timezone', 'i32') }}} return tmPtr; }, @@ -5426,33 +5339,32 @@ LibraryManager.library = { return ret; }, - localtime__deps: ['malloc', '__tm_struct_layout', '__tm_current', 'localtime_r'], + localtime__deps: ['malloc', '__tm_current', 'localtime_r'], localtime: function(time) { return _localtime_r(time, ___tm_current); }, - localtime_r__deps: ['__tm_struct_layout', '__tm_timezone', 'tzset'], + localtime_r__deps: ['__tm_timezone', 'tzset'], localtime_r: function(time, tmPtr) { _tzset(); - var offsets = ___tm_struct_layout; var date = new Date({{{ makeGetValue('time', 0, 'i32') }}}*1000); - {{{ makeSetValue('tmPtr', 'offsets.tm_sec', 'date.getSeconds()', 'i32') }}} - {{{ makeSetValue('tmPtr', 'offsets.tm_min', 'date.getMinutes()', 'i32') }}} - {{{ makeSetValue('tmPtr', 'offsets.tm_hour', 'date.getHours()', 'i32') }}} - {{{ makeSetValue('tmPtr', 'offsets.tm_mday', 'date.getDate()', 'i32') }}} - {{{ makeSetValue('tmPtr', 'offsets.tm_mon', 'date.getMonth()', 'i32') }}} - {{{ makeSetValue('tmPtr', 'offsets.tm_year', 'date.getFullYear()-1900', 'i32') }}} - {{{ makeSetValue('tmPtr', 'offsets.tm_wday', 'date.getDay()', 'i32') }}} + {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_sec, 'date.getSeconds()', 'i32') }}} + {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_min, 'date.getMinutes()', 'i32') }}} + {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_hour, 'date.getHours()', 'i32') }}} + {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_mday, 'date.getDate()', 'i32') }}} + {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_mon, 'date.getMonth()', 'i32') }}} + {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_year, 'date.getFullYear()-1900', 'i32') }}} + {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_wday, 'date.getDay()', 'i32') }}} var start = new Date(date.getFullYear(), 0, 1); var yday = Math.floor((date.getTime() - start.getTime()) / (1000 * 60 * 60 * 24)); - {{{ makeSetValue('tmPtr', 'offsets.tm_yday', 'yday', 'i32') }}} - {{{ makeSetValue('tmPtr', 'offsets.tm_gmtoff', 'start.getTimezoneOffset() * 60', 'i32') }}} + {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_yday, 'yday', 'i32') }}} + {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_gmtoff, 'start.getTimezoneOffset() * 60', 'i32') }}} var dst = Number(start.getTimezoneOffset() != date.getTimezoneOffset()); - {{{ makeSetValue('tmPtr', 'offsets.tm_isdst', 'dst', 'i32') }}} + {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_isdst, 'dst', 'i32') }}} - {{{ makeSetValue('tmPtr', 'offsets.tm_zone', '___tm_timezone', 'i32') }}} + {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_zone, '___tm_timezone', 'i32') }}} return tmPtr; }, @@ -5563,21 +5475,21 @@ LibraryManager.library = { return newDate; }, - strftime__deps: ['__tm_struct_layout', '_isLeapYear', '_arraySum', '_addDays', '_MONTH_DAYS_REGULAR', '_MONTH_DAYS_LEAP'], + strftime__deps: ['_isLeapYear', '_arraySum', '_addDays', '_MONTH_DAYS_REGULAR', '_MONTH_DAYS_LEAP'], strftime: function(s, maxsize, format, tm) { // size_t strftime(char *restrict s, size_t maxsize, const char *restrict format, const struct tm *restrict timeptr); // http://pubs.opengroup.org/onlinepubs/009695399/functions/strftime.html var date = { - tm_sec: {{{ makeGetValue('tm', '___tm_struct_layout.tm_sec', 'i32') }}}, - tm_min: {{{ makeGetValue('tm', '___tm_struct_layout.tm_min', 'i32') }}}, - tm_hour: {{{ makeGetValue('tm', '___tm_struct_layout.tm_hour', 'i32') }}}, - tm_mday: {{{ makeGetValue('tm', '___tm_struct_layout.tm_mday', 'i32') }}}, - tm_mon: {{{ makeGetValue('tm', '___tm_struct_layout.tm_mon', 'i32') }}}, - tm_year: {{{ makeGetValue('tm', '___tm_struct_layout.tm_year', 'i32') }}}, - tm_wday: {{{ makeGetValue('tm', '___tm_struct_layout.tm_wday', 'i32') }}}, - tm_yday: {{{ makeGetValue('tm', '___tm_struct_layout.tm_yday', 'i32') }}}, - tm_isdst: {{{ makeGetValue('tm', '___tm_struct_layout.tm_isdst', 'i32') }}} + tm_sec: {{{ makeGetValue('tm', C_STRUCTS.tm.tm_sec, 'i32') }}}, + tm_min: {{{ makeGetValue('tm', C_STRUCTS.tm.tm_min, 'i32') }}}, + tm_hour: {{{ makeGetValue('tm', C_STRUCTS.tm.tm_hour, 'i32') }}}, + tm_mday: {{{ makeGetValue('tm', C_STRUCTS.tm.tm_mday, 'i32') }}}, + tm_mon: {{{ makeGetValue('tm', C_STRUCTS.tm.tm_mon, 'i32') }}}, + tm_year: {{{ makeGetValue('tm', C_STRUCTS.tm.tm_year, 'i32') }}}, + tm_wday: {{{ makeGetValue('tm', C_STRUCTS.tm.tm_wday, 'i32') }}}, + tm_yday: {{{ makeGetValue('tm', C_STRUCTS.tm.tm_yday, 'i32') }}}, + tm_isdst: {{{ makeGetValue('tm', C_STRUCTS.tm.tm_isdst, 'i32') }}} }; var pattern = Pointer_stringify(format); @@ -5860,7 +5772,7 @@ LibraryManager.library = { }, strftime_l: 'strftime', // no locale support yet - strptime__deps: ['__tm_struct_layout', '_isLeapYear', '_arraySum', '_addDays', '_MONTH_DAYS_REGULAR', '_MONTH_DAYS_LEAP'], + strptime__deps: ['_isLeapYear', '_arraySum', '_addDays', '_MONTH_DAYS_REGULAR', '_MONTH_DAYS_LEAP'], strptime: function(buf, format, tm) { // char *strptime(const char *restrict buf, const char *restrict format, struct tm *restrict tm); // http://pubs.opengroup.org/onlinepubs/009695399/functions/strptime.html @@ -5938,12 +5850,12 @@ LibraryManager.library = { return (typeof value !== 'number' || isNaN(value)) ? min : (value>=min ? (value<=max ? value: max): min); }; return { - year: fixup({{{ makeGetValue('tm', '___tm_struct_layout.tm_year', 'i32', 0, 0, 1) }}} + 1900 , 1970, 9999), - month: fixup({{{ makeGetValue('tm', '___tm_struct_layout.tm_mon', 'i32', 0, 0, 1) }}}, 0, 11), - day: fixup({{{ makeGetValue('tm', '___tm_struct_layout.tm_mday', 'i32', 0, 0, 1) }}}, 1, 31), - hour: fixup({{{ makeGetValue('tm', '___tm_struct_layout.tm_hour', 'i32', 0, 0, 1) }}}, 0, 23), - min: fixup({{{ makeGetValue('tm', '___tm_struct_layout.tm_min', 'i32', 0, 0, 1) }}}, 0, 59), - sec: fixup({{{ makeGetValue('tm', '___tm_struct_layout.tm_sec', 'i32', 0, 0, 1) }}}, 0, 59) + year: fixup({{{ makeGetValue('tm', C_STRUCTS.tm.tm_year, 'i32', 0, 0, 1) }}} + 1900 , 1970, 9999), + month: fixup({{{ makeGetValue('tm', C_STRUCTS.tm.tm_mon, 'i32', 0, 0, 1) }}}, 0, 11), + day: fixup({{{ makeGetValue('tm', C_STRUCTS.tm.tm_mday, 'i32', 0, 0, 1) }}}, 1, 31), + hour: fixup({{{ makeGetValue('tm', C_STRUCTS.tm.tm_hour, 'i32', 0, 0, 1) }}}, 0, 23), + min: fixup({{{ makeGetValue('tm', C_STRUCTS.tm.tm_min, 'i32', 0, 0, 1) }}}, 0, 59), + sec: fixup({{{ makeGetValue('tm', C_STRUCTS.tm.tm_sec, 'i32', 0, 0, 1) }}}, 0, 59) }; }; @@ -6083,15 +5995,15 @@ LibraryManager.library = { */ var fullDate = new Date(date.year, date.month, date.day, date.hour, date.min, date.sec, 0); - {{{ makeSetValue('tm', '___tm_struct_layout.tm_sec', 'fullDate.getSeconds()', 'i32') }}} - {{{ makeSetValue('tm', '___tm_struct_layout.tm_min', 'fullDate.getMinutes()', 'i32') }}} - {{{ makeSetValue('tm', '___tm_struct_layout.tm_hour', 'fullDate.getHours()', 'i32') }}} - {{{ makeSetValue('tm', '___tm_struct_layout.tm_mday', 'fullDate.getDate()', 'i32') }}} - {{{ makeSetValue('tm', '___tm_struct_layout.tm_mon', 'fullDate.getMonth()', 'i32') }}} - {{{ makeSetValue('tm', '___tm_struct_layout.tm_year', 'fullDate.getFullYear()-1900', 'i32') }}} - {{{ makeSetValue('tm', '___tm_struct_layout.tm_wday', 'fullDate.getDay()', 'i32') }}} - {{{ makeSetValue('tm', '___tm_struct_layout.tm_yday', '__arraySum(__isLeapYear(fullDate.getFullYear()) ? __MONTH_DAYS_LEAP : __MONTH_DAYS_REGULAR, fullDate.getMonth()-1)+fullDate.getDate()-1', 'i32') }}} - {{{ makeSetValue('tm', '___tm_struct_layout.tm_isdst', '0', 'i32') }}} + {{{ makeSetValue('tm', C_STRUCTS.tm.tm_sec, 'fullDate.getSeconds()', 'i32') }}} + {{{ makeSetValue('tm', C_STRUCTS.tm.tm_min, 'fullDate.getMinutes()', 'i32') }}} + {{{ makeSetValue('tm', C_STRUCTS.tm.tm_hour, 'fullDate.getHours()', 'i32') }}} + {{{ makeSetValue('tm', C_STRUCTS.tm.tm_mday, 'fullDate.getDate()', 'i32') }}} + {{{ makeSetValue('tm', C_STRUCTS.tm.tm_mon, 'fullDate.getMonth()', 'i32') }}} + {{{ makeSetValue('tm', C_STRUCTS.tm.tm_year, 'fullDate.getFullYear()-1900', 'i32') }}} + {{{ makeSetValue('tm', C_STRUCTS.tm.tm_wday, 'fullDate.getDay()', 'i32') }}} + {{{ makeSetValue('tm', C_STRUCTS.tm.tm_yday, '__arraySum(__isLeapYear(fullDate.getFullYear()) ? __MONTH_DAYS_LEAP : __MONTH_DAYS_REGULAR, fullDate.getMonth()-1)+fullDate.getDate()-1', 'i32') }}} + {{{ makeSetValue('tm', C_STRUCTS.tm.tm_isdst, '0', 'i32') }}} // we need to convert the matched sequence into an integer array to take care of UTF-8 characters > 0x7F // TODO: not sure that intArrayFromString handles all unicode characters correctly @@ -6116,25 +6028,21 @@ LibraryManager.library = { // sys/time.h // ========================================================================== - __timespec_struct_layout: Runtime.generateStructInfo([ - ['i32', 'tv_sec'], - ['i32', 'tv_nsec']]), - nanosleep__deps: ['usleep', '__timespec_struct_layout'], + nanosleep__deps: ['usleep'], nanosleep: function(rqtp, rmtp) { // int nanosleep(const struct timespec *rqtp, struct timespec *rmtp); - var seconds = {{{ makeGetValue('rqtp', '___timespec_struct_layout.tv_sec', 'i32') }}}; - var nanoseconds = {{{ makeGetValue('rqtp', '___timespec_struct_layout.tv_nsec', 'i32') }}}; - {{{ makeSetValue('rmtp', '___timespec_struct_layout.tv_sec', '0', 'i32') }}} - {{{ makeSetValue('rmtp', '___timespec_struct_layout.tv_nsec', '0', 'i32') }}} + var seconds = {{{ makeGetValue('rqtp', C_STRUCTS.timespec.tv_sec, 'i32') }}}; + var nanoseconds = {{{ makeGetValue('rqtp', C_STRUCTS.timespec.tv_nsec, 'i32') }}}; + {{{ makeSetValue('rmtp', C_STRUCTS.timespec.tv_sec, '0', 'i32') }}} + {{{ makeSetValue('rmtp', C_STRUCTS.timespec.tv_nsec, '0', 'i32') }}} return _usleep((seconds * 1e6) + (nanoseconds / 1000)); }, // TODO: Implement these for real. - clock_gettime__deps: ['__timespec_struct_layout'], clock_gettime: function(clk_id, tp) { // int clock_gettime(clockid_t clk_id, struct timespec *tp); var now = Date.now(); - {{{ makeSetValue('tp', '___timespec_struct_layout.tv_sec', 'Math.floor(now/1000)', 'i32') }}}; // seconds - {{{ makeSetValue('tp', '___timespec_struct_layout.tv_nsec', '(now % 1000) * 1000 * 1000', 'i32') }}}; // nanoseconds (really milliseconds) + {{{ makeSetValue('tp', C_STRUCTS.timespec.tv_sec, 'Math.floor(now/1000)', 'i32') }}}; // seconds + {{{ makeSetValue('tp', C_STRUCTS.timespec.tv_nsec, '(now % 1000) * 1000 * 1000', 'i32') }}}; // nanoseconds (really milliseconds) return 0; }, clock_settime: function(clk_id, tp) { @@ -6142,28 +6050,26 @@ LibraryManager.library = { // Nothing. return 0; }, - clock_getres__deps: ['__timespec_struct_layout'], clock_getres: function(clk_id, res) { // int clock_getres(clockid_t clk_id, struct timespec *res); - {{{ makeSetValue('res', '___timespec_struct_layout.tv_sec', '1', 'i32') }}} - {{{ makeSetValue('res', '___timespec_struct_layout.tv_nsec', '1000 * 1000', 'i32') }}} // resolution is milliseconds + {{{ makeSetValue('res', C_STRUCTS.timespec.tv_sec, '1', 'i32') }}} + {{{ makeSetValue('res', C_STRUCTS.timespec.tv_nsec, '1000 * 1000', 'i32') }}} // resolution is milliseconds return 0; }, // http://pubs.opengroup.org/onlinepubs/000095399/basedefs/sys/time.h.html gettimeofday: function(ptr) { - // %struct.timeval = type { i32, i32 } - {{{ (LibraryManager.structs.gettimeofday = Runtime.calculateStructAlignment({ fields: ['i32', 'i32'] }), null) }}} var now = Date.now(); - {{{ makeSetValue('ptr', LibraryManager.structs.gettimeofday[0], 'Math.floor(now/1000)', 'i32') }}}; // seconds - {{{ makeSetValue('ptr', LibraryManager.structs.gettimeofday[1], 'Math.floor((now-1000*Math.floor(now/1000))*1000)', 'i32') }}}; // microseconds + {{{ makeSetValue('ptr', C_STRUCTS.timeval.tv_sec, 'Math.floor(now/1000)', 'i32') }}}; // seconds + {{{ makeSetValue('ptr', C_STRUCTS.timeval.tv_usec, 'Math.floor((now-1000*Math.floor(now/1000))*1000)', 'i32') }}}; // microseconds return 0; }, // ========================================================================== // sys/timeb.h // ========================================================================== - + + // TODO: Where did this header go? __timeb_struct_layout: Runtime.generateStructInfo([ ['i32', 'time'], ['i16', 'millitm'], @@ -6184,18 +6090,13 @@ LibraryManager.library = { // sys/times.h // ========================================================================== - __tms_struct_layout: Runtime.generateStructInfo([ - ['i32', 'tms_utime'], - ['i32', 'tms_stime'], - ['i32', 'tms_cutime'], - ['i32', 'tms_cstime']]), - times__deps: ['__tms_struct_layout', 'memset'], + times__deps: ['memset'], times: function(buffer) { // clock_t times(struct tms *buffer); // http://pubs.opengroup.org/onlinepubs/009695399/functions/times.html // NOTE: This is fake, since we can't calculate real CPU time usage in JS. if (buffer !== 0) { - _memset(buffer, 0, ___tms_struct_layout.__size__); + _memset(buffer, 0, {{{ C_STRUCTS.tms.__size__ }}}); } return 0; }, @@ -6853,14 +6754,10 @@ LibraryManager.library = { // ========================================================================== // TODO: Implement for real. - __rlimit_struct_layout: Runtime.generateStructInfo([ - ['i32', 'rlim_cur'], - ['i32', 'rlim_max']]), - getrlimit__deps: ['__rlimit_struct_layout'], getrlimit: function(resource, rlp) { // int getrlimit(int resource, struct rlimit *rlp); - {{{ makeSetValue('rlp', '___rlimit_struct_layout.rlim_cur', '-1', 'i32') }}} // RLIM_INFINITY - {{{ makeSetValue('rlp', '___rlimit_struct_layout.rlim_max', '-1', 'i32') }}} // RLIM_INFINITY + {{{ makeSetValue('rlp', C_STRUCTS.rlimit.rlim_cur, '-1', 'i32') }}} // RLIM_INFINITY + {{{ makeSetValue('rlp', C_STRUCTS.rlimit.rlim_max, '-1', 'i32') }}} // RLIM_INFINITY return 0; }, setrlimit: function(resource, rlp) { @@ -6870,33 +6767,12 @@ LibraryManager.library = { __01getrlimit64_: 'getrlimit', // TODO: Implement for real. We just do time used, and no useful data - __rusage_struct_layout: Runtime.generateStructInfo([ - ['i64', 'ru_utime'], - ['i64', 'ru_stime'], - ['i32', 'ru_maxrss'], - ['i32', 'ru_ixrss'], - ['i32', 'ru_idrss'], - ['i32', 'ru_isrss'], - ['i32', 'ru_minflt'], - ['i32', 'ru_majflt'], - ['i32', 'ru_nswap'], - ['i32', 'ru_inblock'], - ['i32', 'ru_oublock'], - ['i32', 'ru_msgsnd'], - ['i32', 'ru_msgrcv'], - ['i32', 'ru_nsignals'], - ['i32', 'ru_nvcsw'], - ['i32', 'ru_nivcsw']]), - getrusage__deps: ['__rusage_struct_layout'], getrusage: function(resource, rlp) { - // %struct.timeval = type { i32, i32 } - var timeval = Runtime.calculateStructAlignment({ fields: ['i32', 'i32'] }); - // int getrusage(int resource, struct rusage *rlp); - {{{ makeSetValue('rlp', '___rusage_struct_layout.ru_utime+timeval[0]', '1', 'i32') }}} - {{{ makeSetValue('rlp', '___rusage_struct_layout.ru_utime+timeval[1]', '2', 'i32') }}} - {{{ makeSetValue('rlp', '___rusage_struct_layout.ru_stime+timeval[0]', '3', 'i32') }}} - {{{ makeSetValue('rlp', '___rusage_struct_layout.ru_stime+timeval[1]', '4', 'i32') }}} + {{{ makeSetValue('rlp', C_STRUCTS.rusage.ru_utime.tv_sec, '1', 'i32') }}} + {{{ makeSetValue('rlp', C_STRUCTS.rusage.ru_utime.tv_usec, '2', 'i32') }}} + {{{ makeSetValue('rlp', C_STRUCTS.rusage.ru_stime.tv_sec, '3', 'i32') }}} + {{{ makeSetValue('rlp', C_STRUCTS.rusage.ru_stime.tv_usec, '4', 'i32') }}} return 0; }, @@ -7404,25 +7280,6 @@ LibraryManager.library = { }, // note: lots of leaking here! - __hostent_struct_layout: Runtime.generateStructInfo([ - ['i8*', 'h_name'], - ['i8**', 'h_aliases'], - ['i32', 'h_addrtype'], - ['i32', 'h_length'], - ['i8**', 'h_addr_list'], - ]), - - _addrinfo_layout: Runtime.generateStructInfo([ - ['i32', 'ai_flags'], - ['i32', 'ai_family'], - ['i32', 'ai_socktype'], - ['i32', 'ai_protocol'], - ['i32', 'ai_addrlen'], - ['*', 'ai_addr'], - ['*', 'ai_canonname'], - ['*', 'ai_next'] - ]), - gethostbyaddr__deps: ['$DNS', 'gethostbyname', '_inet_ntop4_raw'], gethostbyaddr: function (addr, addrlen, type) { if (type !== {{{ cDefine('AF_INET') }}}) { @@ -7439,40 +7296,40 @@ LibraryManager.library = { return _gethostbyname(hostp); }, - gethostbyname__deps: ['$DNS', '__hostent_struct_layout', '_inet_pton4_raw'], + gethostbyname__deps: ['$DNS', '_inet_pton4_raw'], gethostbyname: function(name) { name = Pointer_stringify(name); // generate hostent - var ret = _malloc(___hostent_struct_layout.__size__); // XXX possibly leaked, as are others here + var ret = _malloc({{{ C_STRUCTS.hostent.__size__ }}}); // XXX possibly leaked, as are others here var nameBuf = _malloc(name.length+1); writeStringToMemory(name, nameBuf); - {{{ makeSetValue('ret', '___hostent_struct_layout.h_name', 'nameBuf', 'i8*') }}} + {{{ makeSetValue('ret', C_STRUCTS.hostent.h_name, 'nameBuf', 'i8*') }}} var aliasesBuf = _malloc(4); {{{ makeSetValue('aliasesBuf', '0', '0', 'i8*') }}} - {{{ makeSetValue('ret', '___hostent_struct_layout.h_aliases', 'aliasesBuf', 'i8**') }}} + {{{ makeSetValue('ret', C_STRUCTS.hostent.h_aliases, 'aliasesBuf', 'i8**') }}} var afinet = {{{ cDefine('AF_INET') }}}; - {{{ makeSetValue('ret', '___hostent_struct_layout.h_addrtype', 'afinet', 'i32') }}} - {{{ makeSetValue('ret', '___hostent_struct_layout.h_length', '4', 'i32') }}} + {{{ makeSetValue('ret', C_STRUCTS.hostent.h_addrtype, 'afinet', 'i32') }}} + {{{ makeSetValue('ret', C_STRUCTS.hostent.h_length, '4', 'i32') }}} var addrListBuf = _malloc(12); {{{ makeSetValue('addrListBuf', '0', 'addrListBuf+8', 'i32*') }}} {{{ makeSetValue('addrListBuf', '4', '0', 'i32*') }}} {{{ makeSetValue('addrListBuf', '8', '__inet_pton4_raw(DNS.lookup_name(name))', 'i32') }}} - {{{ makeSetValue('ret', '___hostent_struct_layout.h_addr_list', 'addrListBuf', 'i8**') }}} + {{{ makeSetValue('ret', C_STRUCTS.hostent.h_addr_list, 'addrListBuf', 'i8**') }}} return ret; }, gethostbyname_r__deps: ['gethostbyname'], gethostbyname_r: function(name, ret, buf, buflen, out, err) { var data = _gethostbyname(name); - _memcpy(ret, data, ___hostent_struct_layout.__size__); + _memcpy(ret, data, {{{ C_STRUCTS.hostent.__size__ }}}); _free(data); {{{ makeSetValue('err', '0', '0', 'i32') }}}; {{{ makeSetValue('out', '0', 'ret', '*') }}}; return 0; }, - getaddrinfo__deps: ['$Sockets', '$DNS', '_addrinfo_layout', '_inet_pton4_raw', '_inet_ntop4_raw', '_inet_pton6_raw', '_inet_ntop6_raw', '_write_sockaddr', 'htonl'], + getaddrinfo__deps: ['$Sockets', '$DNS', '_inet_pton4_raw', '_inet_ntop4_raw', '_inet_pton6_raw', '_inet_ntop6_raw', '_write_sockaddr', 'htonl'], getaddrinfo: function(node, service, hint, out) { var addrs = []; var canon = null; @@ -7489,8 +7346,8 @@ LibraryManager.library = { var res; salen = family === {{{ cDefine('AF_INET6') }}} ? - Sockets.sockaddr_in6_layout.__size__ : - Sockets.sockaddr_in_layout.__size__; + {{{ C_STRUCTS.sockaddr_in6.__size__ }}} : + {{{ C_STRUCTS.sockaddr_in.__size__ }}}; addr = family === {{{ cDefine('AF_INET6') }}} ? __inet_ntop6_raw(addr) : __inet_ntop4_raw(addr); @@ -7498,28 +7355,28 @@ LibraryManager.library = { res = __write_sockaddr(sa, family, addr, port); assert(!res.errno); - ai = _malloc(__addrinfo_layout.__size__); - {{{ makeSetValue('ai', '__addrinfo_layout.ai_family', 'family', 'i32') }}}; - {{{ makeSetValue('ai', '__addrinfo_layout.ai_socktype', 'type', 'i32') }}}; - {{{ makeSetValue('ai', '__addrinfo_layout.ai_protocol', 'proto', 'i32') }}}; + ai = _malloc({{{ C_STRUCTS.addrinfo.__size__ }}}); + {{{ makeSetValue('ai', C_STRUCTS.addrinfo.ai_family, 'family', 'i32') }}}; + {{{ makeSetValue('ai', C_STRUCTS.addrinfo.ai_socktype, 'type', 'i32') }}}; + {{{ makeSetValue('ai', C_STRUCTS.addrinfo.ai_protocol, 'proto', 'i32') }}}; if (canon) { - {{{ makeSetValue('ai', '__addrinfo_layout.ai_canonname', 'canon', 'i32') }}}; + {{{ makeSetValue('ai', C_STRUCTS.addrinfo.ai_canonname, 'canon', 'i32') }}}; } - {{{ makeSetValue('ai', '__addrinfo_layout.ai_addr', 'sa', '*') }}}; + {{{ makeSetValue('ai', C_STRUCTS.addrinfo.ai_addr, 'sa', '*') }}}; if (family === {{{ cDefine('AF_INET6') }}}) { - {{{ makeSetValue('ai', '__addrinfo_layout.ai_addrlen', 'Sockets.sockaddr_in6_layout.__size__', 'i32') }}}; + {{{ makeSetValue('ai', C_STRUCTS.addrinfo.ai_addrlen, C_STRUCTS.sockaddr_in6.__size__, 'i32') }}}; } else { - {{{ makeSetValue('ai', '__addrinfo_layout.ai_addrlen', 'Sockets.sockaddr_in_layout.__size__', 'i32') }}}; + {{{ makeSetValue('ai', C_STRUCTS.addrinfo.ai_addrlen, C_STRUCTS.sockaddr_in.__size__, 'i32') }}}; } return ai; } if (hint) { - flags = {{{ makeGetValue('hint', '__addrinfo_layout.ai_flags', 'i32') }}}; - family = {{{ makeGetValue('hint', '__addrinfo_layout.ai_family', 'i32') }}}; - type = {{{ makeGetValue('hint', '__addrinfo_layout.ai_socktype', 'i32') }}}; - proto = {{{ makeGetValue('hint', '__addrinfo_layout.ai_protocol', 'i32') }}}; + flags = {{{ makeGetValue('hint', C_STRUCTS.addrinfo.ai_flags, 'i32') }}}; + family = {{{ makeGetValue('hint', C_STRUCTS.addrinfo.ai_family, 'i32') }}}; + type = {{{ makeGetValue('hint', C_STRUCTS.addrinfo.ai_socktype, 'i32') }}}; + proto = {{{ makeGetValue('hint', C_STRUCTS.addrinfo.ai_protocol, 'i32') }}}; } if (type && !proto) { proto = type === {{{ cDefine('SOCK_DGRAM') }}} ? {{{ cDefine('IPPROTO_UDP') }}} : {{{ cDefine('IPPROTO_TCP') }}}; @@ -7535,7 +7392,7 @@ LibraryManager.library = { {{{ cDefine('AI_NUMERICSERV') }}}|{{{ cDefine('AI_V4MAPPED') }}}|{{{ cDefine('AI_ALL') }}}|{{{ cDefine('AI_ADDRCONFIG') }}})) { return {{{ cDefine('EAI_BADFLAGS') }}}; } - if (({{{ makeGetValue('hint', '__addrinfo_layout.ai_flags', 'i32') }}} & {{{ cDefine('AI_CANONNAME') }}}) && !node) { + if (({{{ makeGetValue('hint', C_STRUCTS.addrinfo.ai_flags, 'i32') }}} & {{{ cDefine('AI_CANONNAME') }}}) && !node) { return {{{ cDefine('EAI_BADFLAGS') }}}; } if (flags & {{{ cDefine('AI_ADDRCONFIG') }}}) { @@ -7631,14 +7488,14 @@ LibraryManager.library = { return 0; }, - freeaddrinfo__deps: ['$Sockets', '_addrinfo_layout'], + freeaddrinfo__deps: ['$Sockets'], freeaddrinfo: function(ai) { - var sa = {{{ makeGetValue('ai', '__addrinfo_layout.ai_addr', '*') }}}; + var sa = {{{ makeGetValue('ai', C_STRUCTS.addrinfo.ai_addr, '*') }}}; _free(sa); _free(ai); }, - getnameinfo__deps: ['$Sockets', '$DNS', '__hostent_struct_layout', '_read_sockaddr'], + getnameinfo__deps: ['$Sockets', '$DNS', '_read_sockaddr'], getnameinfo: function (sa, salen, node, nodelen, serv, servlen, flags) { var info = __read_sockaddr(sa, salen); if (info.errno) { @@ -7705,33 +7562,7 @@ LibraryManager.library = { localAddr: 0xfe00000a, // Local address is always 10.0.0.254 addrPool: [ 0x0200000a, 0x0300000a, 0x0400000a, 0x0500000a, 0x0600000a, 0x0700000a, 0x0800000a, 0x0900000a, 0x0a00000a, - 0x0b00000a, 0x0c00000a, 0x0d00000a, 0x0e00000a], /* 0x0100000a is reserved */ - sockaddr_in_layout: Runtime.generateStructInfo([ - ['i16', 'sin_family'], - ['i16', 'sin_port'], - ['i32', 'sin_addr'], - ['b8', 'sin_zero'], - ]), - sockaddr_in6_layout: Runtime.generateStructInfo([ - ['i16', 'sin6_family'], - ['i16', 'sin6_port'], - ['i32', 'sin6_flowinfo'], - ['b16', 'sin6_addr'], - ['i32', 'sin6_scope_id'] - ]), - msghdr_layout: Runtime.generateStructInfo([ - ['*', 'msg_name'], - ['i32', 'msg_namelen'], - ['*', 'msg_iov'], - ['i32', 'msg_iovlen'], - ['*', 'msg_control'], - ['i32', 'msg_controllen'], - ['i32', 'msg_flags'], - ]), - iovec_layout: Runtime.generateStructInfo([ - ['i8*', 'iov_base'], - ['i32', 'iov_len'] - ]) + 0x0b00000a, 0x0c00000a, 0x0d00000a, 0x0e00000a] /* 0x0100000a is reserved */ }, #if SOCKET_WEBRTC @@ -7895,8 +7726,8 @@ LibraryManager.library = { var info = FS.getStream(fd); if (!info) return -1; if (addr) { - info.port = _ntohs(getValue(addr + Sockets.sockaddr_in_layout.sin_port, 'i16')); - // info.addr = getValue(addr + Sockets.sockaddr_in_layout.sin_addr, 'i32'); + info.port = _ntohs(getValue(addr + {{{ C_STRUCTS.sockaddr_in.sin_port }}}, 'i16')); + // info.addr = getValue(addr + {{{ C_STRUCTS.sockaddr_in.sin_addr.s_addr }}}, 'i32'); } if (!info.port) { info.port = _mkport(); @@ -7920,10 +7751,10 @@ LibraryManager.library = { _bind(fd); } - var name = {{{ makeGetValue('msg', 'Sockets.msghdr_layout.msg_name', '*') }}}; + var name = {{{ makeGetValue('msg', C_STRUCTS.msghdr.msg_name, '*') }}}; assert(name, 'sendmsg on non-connected socket, and no name/address in the message'); - var port = _ntohs(getValue(name + Sockets.sockaddr_in_layout.sin_port, 'i16')); - var addr = getValue(name + Sockets.sockaddr_in_layout.sin_addr, 'i32'); + var port = _ntohs(getValue(name + {{{ C_STRUCTS.sockaddr_in.sin_port }}}, 'i16')); + var addr = getValue(name + {{{ C_STRUCTS.sockaddr_in.sin_addr.s_addr }}}, 'i32'); var connection = Sockets.connections[addr]; // var host = __inet_ntop4_raw(addr); @@ -7932,8 +7763,8 @@ LibraryManager.library = { return -1; } - var iov = {{{ makeGetValue('msg', 'Sockets.msghdr_layout.msg_iov', 'i8*') }}}; - var num = {{{ makeGetValue('msg', 'Sockets.msghdr_layout.msg_iovlen', 'i32') }}}; + var iov = {{{ makeGetValue('msg', C_STRUCTS.msghdr.msg_iov, 'i8*') }}}; + var num = {{{ makeGetValue('msg', C_STRUCTS.msghdr.msg_iovlen, 'i32') }}}; #if SOCKET_DEBUG Module.print('sendmsg vecs: ' + num); #endif @@ -7994,13 +7825,13 @@ LibraryManager.library = { Module.print('recvmsg bytes: ' + bytes + ' | ' + Array.prototype.slice.call(buffer)); #endif // write source - var name = {{{ makeGetValue('msg', 'Sockets.msghdr_layout.msg_name', '*') }}}; - {{{ makeSetValue('name', 'Sockets.sockaddr_in_layout.sin_addr', 'addr', 'i32') }}}; - {{{ makeSetValue('name', 'Sockets.sockaddr_in_layout.sin_port', '_htons(header[0])', 'i16') }}}; + var name = {{{ makeGetValue('msg', C_STRUCTS.msghdr.msg_name, '*') }}}; + {{{ makeSetValue('name', C_STRUCTS.sockaddr_in.sin_addr.s_addr, 'addr', 'i32') }}}; + {{{ makeSetValue('name', C_STRUCTS.sockaddr_in.sin_port, '_htons(header[0])', 'i16') }}}; // write data var ret = bytes; - var iov = {{{ makeGetValue('msg', 'Sockets.msghdr_layout.msg_iov', 'i8*') }}}; - var num = {{{ makeGetValue('msg', 'Sockets.msghdr_layout.msg_iovlen', 'i32') }}}; + var iov = {{{ makeGetValue('msg', C_STRUCTS.msghdr.msg_iov, 'i8*') }}}; + var num = {{{ makeGetValue('msg', C_STRUCTS.msghdr.msg_iovlen, 'i32') }}}; var bufferPos = 0; for (var i = 0; i < num && bytes > 0; i++) { var currNum = {{{ makeGetValue('iov', '8*i + 4', 'i32') }}}; @@ -8054,9 +7885,9 @@ LibraryManager.library = { var info = FS.getStream(fd); if (!info) return -1; if (addr) { - setValue(addr + Sockets.sockaddr_in_layout.sin_addr, info.addr, 'i32'); - setValue(addr + Sockets.sockaddr_in_layout.sin_port, info.port, 'i32'); - setValue(addrlen, Sockets.sockaddr_in_layout.__size__, 'i32'); + setValue(addr + {{{ C_STRUCTS.sockaddr_in.sin_addr.s_addr }}}, info.addr, 'i32'); + setValue(addr + {{{ C_STRUCTS.sockaddr_in.sin_port }}}, info.port, 'i32'); + setValue(addrlen, {{{ C_STRUCTS.sockaddr_in.__size__ }}}, 'i32'); } return fd; }, @@ -8122,27 +7953,27 @@ LibraryManager.library = { _read_sockaddr__deps: ['$Sockets', '_inet_ntop4_raw', '_inet_ntop6_raw'], _read_sockaddr: function (sa, salen) { // family / port offsets are common to both sockaddr_in and sockaddr_in6 - var family = {{{ makeGetValue('sa', 'Sockets.sockaddr_in_layout.sin_family', 'i16') }}}; - var port = _ntohs({{{ makeGetValue('sa', 'Sockets.sockaddr_in_layout.sin_port', 'i16') }}}); + var family = {{{ makeGetValue('sa', C_STRUCTS.sockaddr_in.sin_family, 'i16') }}}; + var port = _ntohs({{{ makeGetValue('sa', C_STRUCTS.sockaddr_in.sin_port, 'i16') }}}); var addr; switch (family) { case {{{ cDefine('AF_INET') }}}: - if (salen !== Sockets.sockaddr_in_layout.__size__) { + if (salen !== {{{ C_STRUCTS.sockaddr_in.__size__ }}}) { return { errno: ERRNO_CODES.EINVAL }; } - addr = {{{ makeGetValue('sa', 'Sockets.sockaddr_in_layout.sin_addr', 'i32') }}}; + addr = {{{ makeGetValue('sa', C_STRUCTS.sockaddr_in.sin_addr.s_addr, 'i32') }}}; addr = __inet_ntop4_raw(addr); break; case {{{ cDefine('AF_INET6') }}}: - if (salen !== Sockets.sockaddr_in6_layout.__size__) { + if (salen !== {{{ C_STRUCTS.sockaddr_in6.__size__ }}}) { return { errno: ERRNO_CODES.EINVAL }; } addr = [ - {{{ makeGetValue('sa', 'Sockets.sockaddr_in6_layout.sin6_addr+0', 'i32') }}}, - {{{ makeGetValue('sa', 'Sockets.sockaddr_in6_layout.sin6_addr+4', 'i32') }}}, - {{{ makeGetValue('sa', 'Sockets.sockaddr_in6_layout.sin6_addr+8', 'i32') }}}, - {{{ makeGetValue('sa', 'Sockets.sockaddr_in6_layout.sin6_addr+12', 'i32') }}} + {{{ makeGetValue('sa', C_STRUCTS.sockaddr_in6.sin6_addr.__in6_union.__s6_addr+0, 'i32') }}}, + {{{ makeGetValue('sa', C_STRUCTS.sockaddr_in6.sin6_addr.__in6_union.__s6_addr+4, 'i32') }}}, + {{{ makeGetValue('sa', C_STRUCTS.sockaddr_in6.sin6_addr.__in6_union.__s6_addr+8, 'i32') }}}, + {{{ makeGetValue('sa', C_STRUCTS.sockaddr_in6.sin6_addr.__in6_union.__s6_addr+12, 'i32') }}} ]; addr = __inet_ntop6_raw(addr); break; @@ -8157,18 +7988,18 @@ LibraryManager.library = { switch (family) { case {{{ cDefine('AF_INET') }}}: addr = __inet_pton4_raw(addr); - {{{ makeSetValue('sa', 'Sockets.sockaddr_in_layout.sin_family', 'family', 'i16') }}}; - {{{ makeSetValue('sa', 'Sockets.sockaddr_in_layout.sin_addr', 'addr', 'i32') }}}; - {{{ makeSetValue('sa', 'Sockets.sockaddr_in_layout.sin_port', '_htons(port)', 'i16') }}}; + {{{ makeSetValue('sa', C_STRUCTS.sockaddr_in.sin_family, 'family', 'i16') }}}; + {{{ makeSetValue('sa', C_STRUCTS.sockaddr_in.sin_addr.s_addr, 'addr', 'i32') }}}; + {{{ makeSetValue('sa', C_STRUCTS.sockaddr_in.sin_port, '_htons(port)', 'i16') }}}; break; case {{{ cDefine('AF_INET6') }}}: addr = __inet_pton6_raw(addr); - {{{ makeSetValue('sa', 'Sockets.sockaddr_in6_layout.sin6_family', 'family', 'i32') }}}; - {{{ makeSetValue('sa', 'Sockets.sockaddr_in6_layout.sin6_addr+0', 'addr[0]', 'i32') }}}; - {{{ makeSetValue('sa', 'Sockets.sockaddr_in6_layout.sin6_addr+4', 'addr[1]', 'i32') }}}; - {{{ makeSetValue('sa', 'Sockets.sockaddr_in6_layout.sin6_addr+8', 'addr[2]', 'i32') }}}; - {{{ makeSetValue('sa', 'Sockets.sockaddr_in6_layout.sin6_addr+12', 'addr[3]', 'i32') }}}; - {{{ makeSetValue('sa', 'Sockets.sockaddr_in6_layout.sin6_port', '_htons(port)', 'i16') }}}; + {{{ makeSetValue('sa', C_STRUCTS.sockaddr_in6.sin6_family, 'family', 'i32') }}}; + {{{ makeSetValue('sa', C_STRUCTS.sockaddr_in6.sin6_addr.__in6_union.__s6_addr+0, 'addr[0]', 'i32') }}}; + {{{ makeSetValue('sa', C_STRUCTS.sockaddr_in6.sin6_addr.__in6_union.__s6_addr+4, 'addr[1]', 'i32') }}}; + {{{ makeSetValue('sa', C_STRUCTS.sockaddr_in6.sin6_addr.__in6_union.__s6_addr+8, 'addr[2]', 'i32') }}}; + {{{ makeSetValue('sa', C_STRUCTS.sockaddr_in6.sin6_addr.__in6_union.__s6_addr+12, 'addr[3]', 'i32') }}}; + {{{ makeSetValue('sa', C_STRUCTS.sockaddr_in6.sin6_port, '_htons(port)', 'i16') }}}; break; default: return { errno: ERRNO_CODES.EAFNOSUPPORT }; @@ -8414,14 +8245,14 @@ LibraryManager.library = { return -1; } - var iov = {{{ makeGetValue('message', 'Sockets.msghdr_layout.msg_iov', '*') }}}; - var num = {{{ makeGetValue('message', 'Sockets.msghdr_layout.msg_iovlen', 'i32') }}}; + var iov = {{{ makeGetValue('message', C_STRUCTS.msghdr.msg_iov, '*') }}}; + var num = {{{ makeGetValue('message', C_STRUCTS.msghdr.msg_iovlen, 'i32') }}}; // read the address and port to send to var addr; var port; - var name = {{{ makeGetValue('message', 'Sockets.msghdr_layout.msg_name', '*') }}}; - var namelen = {{{ makeGetValue('message', 'Sockets.msghdr_layout.msg_namelen', 'i32') }}}; + var name = {{{ makeGetValue('message', C_STRUCTS.msghdr.msg_name, '*') }}}; + var namelen = {{{ makeGetValue('message', C_STRUCTS.msghdr.msg_namelen, 'i32') }}}; if (name) { var info = __read_sockaddr(name, namelen); if (info.errno) { @@ -8435,13 +8266,13 @@ LibraryManager.library = { // concatenate scatter-gather arrays into one message buffer var total = 0; for (var i = 0; i < num; i++) { - total += {{{ makeGetValue('iov', '(Sockets.iovec_layout.__size__ * i) + Sockets.iovec_layout.iov_len', 'i32') }}}; + total += {{{ makeGetValue('iov', '(' + C_STRUCTS.iovec.__size__ + ' * i) + ' + C_STRUCTS.iovec.iov_len, 'i32') }}}; } var view = new Uint8Array(total); var offset = 0; for (var i = 0; i < num; i++) { - var iovbase = {{{ makeGetValue('iov', '(Sockets.iovec_layout.__size__ * i) + Sockets.iovec_layout.iov_base', 'i8*') }}}; - var iovlen = {{{ makeGetValue('iov', '(Sockets.iovec_layout.__size__ * i) + Sockets.iovec_layout.iov_len', 'i32') }}}; + var iovbase = {{{ makeGetValue('iov', '(' + C_STRUCTS.iovec.__size__ + ' * i) + ' + C_STRUCTS.iovec.iov_base, 'i8*') }}}; + var iovlen = {{{ makeGetValue('iov', '(' + C_STRUCTS.iovec.__size__ + ' * i) + ' + C_STRUCTS.iovec.iov_len, 'i32') }}}; for (var j = 0; j < iovlen; j++) { view[offset++] = {{{ makeGetValue('iovbase', 'j', 'i8') }}}; } @@ -8464,13 +8295,13 @@ LibraryManager.library = { return -1; } - var iov = {{{ makeGetValue('message', 'Sockets.msghdr_layout.msg_iov', 'i8*') }}}; - var num = {{{ makeGetValue('message', 'Sockets.msghdr_layout.msg_iovlen', 'i32') }}}; + var iov = {{{ makeGetValue('message', C_STRUCTS.msghdr.msg_iov, 'i8*') }}}; + var num = {{{ makeGetValue('message', C_STRUCTS.msghdr.msg_iovlen, 'i32') }}}; // get the total amount of data we can read across all arrays var total = 0; for (var i = 0; i < num; i++) { - total += {{{ makeGetValue('iov', '(Sockets.iovec_layout.__size__ * i) + Sockets.iovec_layout.iov_len', 'i32') }}}; + total += {{{ makeGetValue('iov', '(' + C_STRUCTS.iovec.__size__ + ' * i) + ' + C_STRUCTS.iovec.iov_len, 'i32') }}}; } // try to read total data @@ -8496,7 +8327,7 @@ LibraryManager.library = { // Requests that the function block until the full amount of data requested can be returned. The function may return a smaller amount of data if a signal is caught, if the connection is terminated, if MSG_PEEK was specified, or if an error is pending for the socket. // write the source address out - var name = {{{ makeGetValue('message', 'Sockets.msghdr_layout.msg_name', '*') }}}; + var name = {{{ makeGetValue('message', C_STRUCTS.msghdr.msg_name, '*') }}}; if (name) { var res = __write_sockaddr(name, sock.family, DNS.lookup_name(msg.addr), msg.port); assert(!res.errno); @@ -8506,8 +8337,8 @@ LibraryManager.library = { var bytesRemaining = msg.buffer.byteLength; for (var i = 0; bytesRemaining > 0 && i < num; i++) { - var iovbase = {{{ makeGetValue('iov', '(Sockets.iovec_layout.__size__ * i) + Sockets.iovec_layout.iov_base', 'i8*') }}}; - var iovlen = {{{ makeGetValue('iov', '(Sockets.iovec_layout.__size__ * i) + Sockets.iovec_layout.iov_len', 'i32') }}}; + var iovbase = {{{ makeGetValue('iov', '(' + C_STRUCTS.iovec.__size__ + ' * i) + ' + C_STRUCTS.iovec.iov_base, 'i8*') }}}; + var iovlen = {{{ makeGetValue('iov', '(' + C_STRUCTS.iovec.__size__ + ' * i) + ' + C_STRUCTS.iovec.iov_len, 'i32') }}}; if (!iovlen) { continue; } diff --git a/src/parseTools.js b/src/parseTools.js index 90c5acab265a8..2ccf017974f6d 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -5,11 +5,12 @@ // Does simple 'macro' substitution, using Django-like syntax, // {{{ code }}} will be replaced with |eval(code)|. +// NOTE: Be careful with that ret check. If ret is |0|, |ret ? ret.toString() : ''| would result in ''! function processMacros(text) { return text.replace(/{{{([^}]|}(?!}))+}}}/g, function(str) { str = str.substr(3, str.length-6); var ret = eval(str); - return ret ? ret.toString() : ''; + return ret !== null ? ret.toString() : ''; }); } diff --git a/src/struct_info.json b/src/struct_info.json new file mode 100644 index 0000000000000..5b969603c7705 --- /dev/null +++ b/src/struct_info.json @@ -0,0 +1,822 @@ +[ + { + "file": "libc/dirent.h", + "defines": [], + "structs": { + "dirent": [ + "d_ino", + "d_off", + "d_reclen", + "d_type", + "d_name" + ] + } + }, + { + "file": "libc/utime.h", + "defines": [], + "structs": { + "utimbuf": [ + "actime", + "modtime" + ] + } + }, + { + "file": "libc/sys/stat.h", + "defines": [ + "S_IFDIR", + "S_IFREG", + "S_IFMT", + "S_IFIFO", + "S_IFSOCK", + "S_IFBLK", + "S_IFLNK", + "S_IFCHR" + ], + "structs": { + "stat": [ + "st_dev", + "__st_dev_padding", + "__st_ino_truncated", + "st_mode", + "st_nlink", + "st_uid", + "st_gid", + "st_rdev", + "__st_rdev_padding", + "st_size", + "st_blksize", + "st_blocks", + { + "st_atim": [ + "tv_sec", + "tv_nsec" + ] + }, + { + "st_mtim": [ + "tv_sec", + "tv_nsec" + ] + }, + { + "st_ctim": [ + "tv_sec", + "tv_nsec" + ] + }, + "st_ino" + ] + } + }, + { + "file": "libc/sys/statvfs.h", + "defines": [], + "structs": { + "statvfs": [ + "f_bsize", + "f_frsize", + "f_blocks", + "f_bfree", + "f_bavail", + "f_files", + "f_ffree", + "f_favail", + "f_fsid", + "f_flag", + "f_namemax" + ] + } + }, + { + "file": "libc/fcntl.h", + "defines": [ + "F_UNLCK", + "O_RDWR", + "S_IRWXO", + "F_GETLK64", + "F_SETLKW64", + "F_SETLKW", + "F_SETLK64", + "F_GETLK", + "S_ISVTX", + "O_RDONLY", + "O_ACCMODE", + "F_DUPFD", + "F_SETLK", + "O_WRONLY" + ], + "structs": { + "flock": [ + "l_type", + "l_whence", + "l_start", + "l_len", + "l_pid" + ] + } + }, + { + "file": "libc/poll.h", + "defines": [ + "POLLHUP", + "POLLERR", + "POLLRDNORM", + "POLLPRI", + "POLLIN", + "POLLOUT", + "POLLNVAL" + ], + "structs": { + "pollfd": [ + "fd", + "events", + "revents" + ] + } + }, + { + "file": "libc/stdlib.h", + "defines": [], + "structs": { + // NOTE: The hash sign at the end of this name is a hint to the processor that it mustn't prefix "struct " to the name to reference this struct. + // It will be stripped away when writing the compiled JSON file. You can just refer to it as C_STRUCTS.div_t when using it in the JS code. + // For more information see gen_inspect_code() in tools/gen_struct_info.py . + "div_t#": [ + "quot", + "rem" + ] + } + }, + { + "file": "libc/sys/utsname.h", + "defines": [], + "structs": { + "utsname": [ + "sysname", + "nodename", + "release", + "version", + "machine", + "domainname" + ] + } + }, + { + "file": "libc/time.h", + "defines": [ + ["li", "CLOCKS_PER_SEC"] + ], + "structs": { + "timezone": [ + "tz_minuteswest", + "tz_dsttime" + ], + "tm": [ + "tm_sec", + "tm_min", + "tm_hour", + "tm_mday", + "tm_mon", + "tm_year", + "tm_wday", + "tm_yday", + "tm_isdst", + "tm_gmtoff", + "tm_zone" + ], + "itimerspec": [ + { + "it_interval": [ + "tv_sec", + "tv_nsec" + ] + }, + { + "it_value": [ + "tv_sec", + "tv_nsec" + ] + } + ], + "timespec": [ + "tv_sec", + "tv_nsec" + ], + "timeval": [ + "tv_sec", + "tv_usec" + ] + } + }, + { + "file": "libc/sys/times.h", + "defines": [], + "structs": { + "tms": [ + "tms_utime", + "tms_stime", + "tms_cutime", + "tms_cstime" + ] + } + }, + { + "file": "libc/sys/resource.h", + "defines": [], + "structs": { + "rlimit": [ + "rlim_cur", + "rlim_max" + ], + "rusage": [ + { + "ru_utime": [ + "tv_sec", + "tv_usec" + ] + }, + { + "ru_stime": [ + "tv_sec", + "tv_usec" + ] + }, + "ru_maxrss", + "ru_ixrss", + "ru_idrss", + "ru_isrss", + "ru_minflt", + "ru_majflt", + "ru_nswap", + "ru_inblock", + "ru_oublock", + "ru_msgsnd", + "ru_msgrcv", + "ru_nsignals", + "ru_nvcsw", + "ru_nivcsw" + ] + } + }, + { + "file": "libc/netdb.h", + "defines": [ + "AI_V4MAPPED", + "EAI_SERVICE", + "EAI_FAMILY", + "AI_ALL", + "AI_ADDRCONFIG", + "AI_NUMERICSERV", + "NI_NUMERICHOST", + "EAI_OVERFLOW", + "AI_NUMERICHOST", + "AI_CANONNAME", + "AI_PASSIVE", + "NI_NAMEREQD", + "EAI_NONAME", + "EAI_SOCKTYPE", + "EAI_BADFLAGS" + ], + "structs": { + "sockaddr": [ + "sa_family", + "sa_data" + ], + "hostent": [ + "h_name", + "h_aliases", + "h_addrtype", + "h_length", + "h_addr_list" + ], + "addrinfo": [ + "ai_flags", + "ai_family", + "ai_socktype", + "ai_protocol", + "ai_addrlen", + "ai_addr", + "ai_canonname", + "ai_next" + ], + "in_addr": [ + "s_addr" + ], + "linger": [ + "l_onoff", + "l_linger" + ], + "protoent": [ + "p_name", + "p_aliases", + "p_proto" + ], + "sockaddr_in": [ + "sin_family", + "sin_port", + { + "sin_addr": [ + "s_addr" + ] + }, + "sin_zero" + ], + "iovec": [ + "iov_base", + "iov_len" + ], + "cmsghdr": [ + "cmsg_len", + "cmsg_level", + "cmsg_type" + ], + "sockaddr_in6": [ + "sin6_family", + "sin6_port", + "sin6_flowinfo", + { + "sin6_addr": [ + { + "__in6_union": [ + "__s6_addr", + "__s6_addr16", + "__s6_addr32" + ] + } + ] + }, + "sin6_scope_id" + ], + "msghdr": [ + "msg_name", + "msg_namelen", + "msg_iov", + "msg_iovlen", + "msg_control", + "msg_controllen", + "msg_flags" + ], + "in6_addr": [ + { + "__in6_union": [ + "__s6_addr", + "__s6_addr16", + "__s6_addr32" + ] + } + ], + "netent": [ + "n_name", + "n_aliases", + "n_addrtype", + "n_net" + ] + } + }, + { + "file": "libc/netinet/in.h", + "defines": [ + "IPPROTO_UDP", + "IPPROTO_TCP", + "INADDR_LOOPBACK" + ], + "structs": {} + }, + { + "file": "libc/math.h", + "defines": [ + "FP_ZERO", + "FP_NAN", + "FP_INFINITE", + "FP_NORMAL" + ], + "structs": {} + }, + { + "file": "libc/bits/fcntl.h", + "defines": [ + "O_CREAT", + "O_SYNC", + "F_GETFD", + "F_SETFL", + "O_NOFOLLOW", + "O_APPEND", + "F_SETOWN", + "O_TRUNC", + "F_GETOWN", + "F_SETFD", + "O_EXCL", + "F_GETFL" + ], + "structs": {} + }, + { + "file": "libc/sys/socket.h", + "defines": [ + "SOCK_DGRAM", + "SOCK_STREAM", + "AF_INET", + "AF_UNSPEC", + "AF_INET6" + ], + "structs": {} + }, + { + "file": "libc/bits/ioctl.h", + "defines": [ + "FIONREAD" + ], + "structs": {} + }, + { + "file": "libc/unistd.h", + "defines": [ + "_SC_XOPEN_LEGACY", + "_SC_XOPEN_VERSION", + "_SC_BC_DIM_MAX", + "_CS_POSIX_V6_LP64_OFF64_LIBS", + "_PC_REC_MIN_XFER_SIZE", + "_SC_V6_ILP32_OFFBIG", + "_SC_MEMLOCK", + "_SC_THREADS", + "_PC_SOCK_MAXBUF", + "_SC_THREAD_KEYS_MAX", + "_SC_2_PBS", + "_SC_TRACE_INHERIT", + "_SC_REGEXP", + "_CS_POSIX_V6_LP64_OFF64_CFLAGS", + "_SC_VERSION", + "_PC_CHOWN_RESTRICTED", + "_SC_MQ_PRIO_MAX", + "_SC_PAGE_SIZE", + "_SC_BARRIERS", + "_SC_2_LOCALEDEF", + "_SC_STREAM_MAX", + "_SC_TIMERS", + "_PC_PATH_MAX", + "_SC_SPORADIC_SERVER", + "_SC_NPROCESSORS_ONLN", + "_CS_POSIX_V6_LPBIG_OFFBIG_LIBS", + "_PC_MAX_INPUT", + "_SC_CLK_TCK", + "_SC_AIO_MAX", + "_SC_THREAD_PRIO_INHERIT", + "_PC_2_SYMLINKS", + "_SC_SPAWN", + "_CS_POSIX_V6_ILP32_OFF32_LDFLAGS", + "_CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS", + "_SC_TRACE_SYS_MAX", + "_CS_POSIX_V6_WIDTH_RESTRICTED_ENVS", + "_SC_AIO_PRIO_DELTA_MAX", + "_SC_MONOTONIC_CLOCK", + "_SC_XOPEN_ENH_I18N", + "_SC_SPIN_LOCKS", + "_SC_XOPEN_SHM", + "_PC_LINK_MAX", + "_SC_FSYNC", + "_SC_GETGR_R_SIZE_MAX", + "_SC_TRACE_NAME_MAX", + "_SC_BC_BASE_MAX", + "_SC_XOPEN_STREAMS", + "_SC_GETPW_R_SIZE_MAX", + "_SC_CPUTIME", + "_SC_XBS5_ILP32_OFFBIG", + "_SC_TRACE_EVENT_FILTER", + "_SC_OPEN_MAX", + "_SC_2_FORT_RUN", + "_SC_RE_DUP_MAX", + "_SC_THREAD_PRIO_PROTECT", + "_SC_2_PBS_CHECKPOINT", + "_SC_XBS5_LPBIG_OFFBIG", + "_SC_SHARED_MEMORY_OBJECTS", + "_PC_ALLOC_SIZE_MIN", + "_SC_READER_WRITER_LOCKS", + "_SC_MEMLOCK_RANGE", + "_SC_PRIORITY_SCHEDULING", + "_PC_VDISABLE", + "_SC_MESSAGE_PASSING", + "_SC_THREAD_ATTR_STACKADDR", + "_SC_THREAD_THREADS_MAX", + "_SC_LOGIN_NAME_MAX", + "_SC_2_C_BIND", + "_PC_NO_TRUNC", + "_SC_SHELL", + "_SC_V6_LP64_OFF64", + "_CS_GNU_LIBC_VERSION", + "_SC_SEM_VALUE_MAX", + "_SC_MQ_OPEN_MAX", + "_SC_HOST_NAME_MAX", + "_SC_THREAD_STACK_MIN", + "_SC_TIMEOUTS", + "_SC_CHILD_MAX", + "_SC_2_PBS_MESSAGE", + "_SC_2_C_DEV", + "_SC_TIMER_MAX", + "_SC_SYMLOOP_MAX", + "_PC_REC_XFER_ALIGN", + "_SC_REALTIME_SIGNALS", + "_PC_ASYNC_IO", + "_SC_MAPPED_FILES", + "_SC_NGROUPS_MAX", + "_SC_SEMAPHORES", + "_SC_TRACE_LOG", + "_CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS", + "_CS_POSIX_V6_LP64_OFF64_LDFLAGS", + "_SC_THREAD_DESTRUCTOR_ITERATIONS", + "_SC_TRACE_EVENT_NAME_MAX", + "_SC_BC_STRING_MAX", + "_SC_2_SW_DEV", + "_SC_ARG_MAX", + "_SC_THREAD_PRIORITY_SCHEDULING", + "_SC_THREAD_CPUTIME", + "_CS_POSIX_V6_ILP32_OFF32_LIBS", + "_SC_SYNCHRONIZED_IO", + "_CS_POSIX_V6_ILP32_OFF32_CFLAGS", + "_SC_MEMORY_PROTECTION", + "_PC_PRIO_IO", + "_SC_V6_LPBIG_OFFBIG", + "_SC_EXPR_NEST_MAX", + "_CS_POSIX_V6_ILP32_OFFBIG_CFLAGS", + "_PC_REC_MAX_XFER_SIZE", + "_SC_DELAYTIMER_MAX", + "W_OK", + "R_OK", + "_SC_XOPEN_CRYPT", + "_SC_XBS5_LP64_OFF64", + "_SC_SIGQUEUE_MAX", + "_SC_TZNAME_MAX", + "_CS_PATH", + "_PC_MAX_CANON", + "_SC_THREAD_SAFE_FUNCTIONS", + "_PC_NAME_MAX", + "_SC_TRACE_USER_EVENT_MAX", + "_SC_RAW_SOCKETS", + "_SC_RTSIG_MAX", + "_SC_PRIORITIZED_IO", + "_SC_XOPEN_UNIX", + "_PC_REC_INCR_XFER_SIZE", + "_PC_FILESIZEBITS", + "_SC_XBS5_ILP32_OFF32", + "_CS_GNU_LIBPTHREAD_VERSION", + "_SC_2_PBS_LOCATE", + "_SC_V6_ILP32_OFF32", + "_PC_SYNC_IO", + "_SC_2_UPE", + "_SC_SEM_NSEMS_MAX", + "_SC_IOV_MAX", + "_SC_TRACE", + "_CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS", + "_SC_LINE_MAX", + "_CS_POSIX_V6_ILP32_OFFBIG_LIBS", + "_SC_2_FORT_DEV", + "_SC_ATEXIT_MAX", + "_SC_SAVED_IDS", + "_SC_2_PBS_TRACK", + "_SC_THREAD_PROCESS_SHARED", + "_SC_JOB_CONTROL", + "_SC_IPV6", + "_SC_ADVISORY_INFO", + "_SC_XOPEN_REALTIME_THREADS", + "_PC_SYMLINK_MAX", + "X_OK", + "_SC_COLL_WEIGHTS_MAX", + "_SC_CLOCK_SELECTION", + "_SC_XOPEN_REALTIME", + "_PC_PIPE_BUF", + "_SC_2_PBS_ACCOUNTING", + "_SC_THREAD_SPORADIC_SERVER", + "_SC_THREAD_ATTR_STACKSIZE", + "_SC_2_VERSION", + "_SC_TYPED_MEMORY_OBJECTS", + "_SC_ASYNCHRONOUS_IO", + "_SC_2_CHAR_TERM", + "_SC_AIO_LISTIO_MAX", + "_SC_BC_SCALE_MAX", + "_SC_TTY_NAME_MAX" + ], + "structs": {} + }, + { + "file": "libc/bits/errno.h", + "defines": [ + "ETXTBSY", + "ETOOMANYREFS", + "ENAMETOOLONG", + "ENOPKG", + "EL3HLT", + "EINPROGRESS", + "ENOTSOCK", + "ENOTSUP", + "EFBIG", + "ENOLINK", + "EL3RST", + "ENOTUNIQ", + "ELNRNG", + "ENOANO", + "ENOPROTOOPT", + "E2BIG", + "EHOSTDOWN", + "EBFONT", + "ENOTEMPTY", + "EBUSY", + "EADDRINUSE", + "ELIBACC", + "EDQUOT", + "ENOENT", + "ECOMM", + "EXFULL", + "ENOTDIR", + "ENETRESET", + "EAFNOSUPPORT", + "EINVAL", + "ENODEV", + "ENOCSI", + "EPROTONOSUPPORT", + "ETIME", + "ENOTTY", + "EAGAIN", + "EMSGSIZE", + "ELIBEXEC", + "EMLINK", + "ECANCELED", + "EDESTADDRREQ", + "EADDRNOTAVAIL", + "EPERM", + "EPROTOTYPE", + "ENOMEDIUM", + "ELOOP", + "EREMOTE", + "ELIBMAX", + "EMULTIHOP", + "ECONNABORTED", + "EFAULT", + "EBADMSG", + "EDOM", + "EILSEQ", + "EPFNOSUPPORT", + "ENONET", + "ECHRNG", + "ESRCH", + "EHOSTUNREACH", + "EL2HLT", + "EL2NSYNC", + "ENOMSG", + "EISDIR", + "EDEADLOCK", + "ECONNRESET", + "ESTRPIPE", + "ESHUTDOWN", + "EDEADLK", + "EBADRQC", + "EUNATCH", + "ECHILD", + "ETIMEDOUT", + "EALREADY", + "ENXIO", + "EMFILE", + "ENFILE", + "EREMCHG", + "ENOMEM", + "ENOSR", + "EOWNERDEAD", + "ELIBSCN", + "EPIPE", + "EBADSLT", + "ENOSTR", + "EIO", + "EWOULDBLOCK", + "EBADE", + "ENODATA", + "ESOCKTNOSUPPORT", + "ENOLCK", + "EPROTO", + "ESRMNT", + "EXDEV", + "ENOSPC", + "ELIBBAD", + "ERANGE", + "ESTALE", + "ENOTRECOVERABLE", + "ENOBUFS", + "EIDRM", + "EINTR", + "EADV", + "ENOSYS", + "EUSERS", + "EOPNOTSUPP", + "ENOTCONN", + "ENETUNREACH", + "ESPIPE", + "EROFS", + "ECONNREFUSED", + "ENETDOWN", + "ENOEXEC", + "EBADF", + "EDOTDOT", + "EBADFD", + "EBADR", + "EISCONN", + "ENOTBLK", + "EOVERFLOW" + ], + "structs": {} + }, + { + "file": "libc/langinfo.h", + "defines": [ + "ABDAY_7", + "ABDAY_6", + "ABDAY_5", + "ABDAY_4", + "ABDAY_3", + "ABDAY_2", + "ABDAY_1", + "ABMON_1", + "RADIXCHAR", + "ABMON_3", + "AM_STR", + "ALT_DIGITS", + "PM_STR", + "ABMON_9", + "YESEXPR", + "ABMON_2", + "ABMON_7", + "ABMON_6", + "ABMON_5", + "ABMON_4", + "ABMON_8", + "ERA", + "MON_2", + "MON_3", + "MON_1", + "MON_6", + "MON_7", + "MON_4", + "MON_5", + "MON_8", + "MON_9", + "NOEXPR", + "T_FMT_AMPM", + "MON_10", + "MON_11", + "MON_12", + "T_FMT", + "THOUSEP", + "ERA_T_FMT", + "ERA_D_T_FMT", + "D_FMT", + "DAY_2", + "DAY_3", + "DAY_1", + "DAY_6", + "DAY_7", + "DAY_4", + "DAY_5", + "ERA_D_FMT", + "CODESET", + "D_T_FMT", + "CRNCYSTR", + "ABMON_12", + "ABMON_11", + "ABMON_10" + ], + "structs": {} + }, + { + "file": "libc/stdio.h", + "defines": [ + "EOF", + "SEEK_END", + "SEEK_SET" + ], + "structs": {} + }, + { + "file": "libc/arpa/tftp.h", + "defines": [ + "EACCES", + "EEXIST" + ], + "structs": {} + }, + { + "file": "compat/sys/stat.h", + "defines": [ + "S_IALLUGO", + "S_IWUGO", + "S_IRUGO", + "S_IRWXUGO", + "S_IXUGO" + ], + "structs": {} + }, + { + "file": "libc/bits/mman.h", + "defines": [ + "MAP_PRIVATE" + ], + "structs": {} + } +] diff --git a/tools/gen_struct_info.py b/tools/gen_struct_info.py index 563b4fa1107de..203a18ec2fb92 100644 --- a/tools/gen_struct_info.py +++ b/tools/gen_struct_info.py @@ -75,29 +75,38 @@ ''' -import sys -import os -import json -import argparse -import tempfile -import subprocess +import sys, os, re, json, argparse, tempfile, subprocess import shared +QUIET = (__name__ != '__main__') + +def show(msg): + global QUIET + if not QUIET: + sys.stderr.write(msg + '\n') # Try to load pycparser. try: import pycparser except ImportError: # The import failed, warn the user. - sys.stderr.write('WARN: pycparser isn\'t available. I won\'t be able to parse C files, only .json files.\n') + show('WARN: pycparser isn\'t available. I won\'t be able to parse C files, only .json files.') def parse_header(path, cpp_opts): # Tell the user how to get pycparser, if he tries to parse a C file. sys.stderr.write('ERR: I need pycparser to process C files. \n') - sys.stderr.write(' Use "pip install pycparser" or go to "https://github.com/eliben/pycparser" to install it.\n') + sys.stderr.write(' Use "pip install pycparser" to install or download it from "https://github.com/eliben/pycparser".\n') sys.exit(1) else: # We successfully imported pycparser, the script will be completely functional. + class DelayedRef(object): + def __init__(self, dest): + self.dest = dest + + def __str__(self): + return self.dest + + # For a list of node types and their fields, look here: https://github.com/eliben/pycparser/blob/master/pycparser/_c_ast.cfg class FieldVisitor(pycparser.c_ast.NodeVisitor): def __init__(self): self._name = None @@ -106,21 +115,30 @@ def __init__(self): def visit_Struct(self, node): if node.decls == None: - # Skip empty struct declarations. + self.named_structs[self._name] = DelayedRef(node.name) return + fields = [] for decl in node.decls: - # Look for nested structs. - subwalk = FieldVisitor() - subwalk.visit(decl) + if decl.name == None: + # Well, this field doesn't have a name. + continue - if subwalk.named_structs: - # Store the nested fields. - fields.append(subwalk.named_structs) - else: - # Just store the field name. + if decl.type != None and isinstance(decl.type, pycparser.c_ast.PtrDecl): + # This field is a pointer, there's no point in looking for nested structs. fields.append(decl.name) + else: + # Look for nested structs. + subwalk = FieldVisitor() + subwalk.visit(decl) + + if subwalk.named_structs: + # Store the nested fields. + fields.append(subwalk.named_structs) + else: + # Just store the field name. + fields.append(decl.name) if node.name != None: self.structs[node.name] = fields @@ -136,9 +154,68 @@ def visit_TypeDecl(self, node): self._name = node.declname self.generic_visit(node) self._name = old_name - + + # The first parameter is a structure, the second is a path (a list containing all the keys, needed to reach the destination). + # The last parameter is an item to look for. This function will try to follow the path into the given object and then look there for this key. + # As long as the nested object doesn't have the given key, it will descent into the next higher object till it finds the given key. + # + # Example: + # + # res = look_through({ + # 'la1': { + # 'lb1': { + # 'lc1': 99, + # 'lc2': { 'ld1': 11 } + # 'lc2': 200 + # }, + # 'nice': 100 + # }, + # 'nice': 300 + # }, ['la1', 'lb1', 'lc2'], 'nice') + # + # print(res) # Prints 100 . + # + # In this case the function looked inside obj['la1']['lb1']['lc2']['nice'], then obj['la1']['lb1']['nice'] and found the value + # in obj['la1']['nice']. As soon as it finds a value it returns it and stops looking. + def look_through(obj, path, name): + cur_level = obj + path = path[:] + for i, p in enumerate(path): + cur_level = cur_level[p] + path[i] = cur_level + + path = [ obj ] + path + + while len(path) > 0: + if name in path[-1]: + return path[-1][name] + else: + path.pop() + + return None + + # Use the above function to resolve all DelayedRef() inside a list or dict recursively. + def resolve_delayed(item, root=None, path=[]): + if root == None: + root = item + + if isinstance(item, DelayedRef): + if item.dest in path: + show('WARN: Circular reference found! Field "' + path[-1] + '" references "' + item.dest + '"! (Path = ' + '/'.join([str(part) for part in path]) + ')') + return { '__ref__': item.dest } + else: + return look_through(root, path[:-1], item.dest) + elif isinstance(item, dict): + for name, val in item.items(): + item[name] = resolve_delayed(val, root, path + [ name ]) + elif isinstance(item, list): + for i, val in enumerate(item): + item[i] = resolve_delayed(val, root, path + [ i ]) + + return item + def parse_header(path, cpp_opts): - sys.stderr.write('Parsing header "' + path + '"...\n') + show('Parsing header "' + path + '"...') # Use clang -E as the preprocessor for pycparser. ast = pycparser.parse_file(path, True, cpp_path=shared.CLANG_CC, cpp_args=['-E'] + cpp_opts) @@ -146,10 +223,37 @@ def parse_header(path, cpp_opts): # Walk the parsed AST and filter out all the declared structs and their fields. walker = FieldVisitor() walker.visit(ast) - return walker.structs + + walker.structs = resolve_delayed(walker.structs) + with open(path, 'r') as stream: + defines = re.findall(r'(?:^|\n)#define\s+([A-Z|_]+)\s.*', stream.read()) + + return { + 'file': path, + 'defines': defines, + 'structs': walker.structs + } # The following three functions generate C code. The output of the compiled code will be # parsed later on and then put back together into a dict structure by parse_c_output(). +# +# Example: +# c_descent('test1', code) +# c_set('item', 'i%i', '111', code) +# c_set('item2', 'i%i', '9', code) +# c_set('item3', 's%s', '"Hello"', code) +# c_ascent(code) +# c_set('outer', 'f%f', '0.999', code) +# +# Will result in: +# { +# 'test1': { +# 'item': 111, +# 'item2': 9, +# 'item3': 'Hello', +# }, +# 'outer': 0.999 +# } def c_set(name, type_, value, code): code.append('printf("K' + name + '\\n");') code.append('printf("V' + type_ + '\\n", ' + value + ');') @@ -173,7 +277,14 @@ def parse_c_output(lines): key = arg elif line[0] == 'V': # A value - cur_level[key] = int(arg) + if arg[0] == 'i': + arg = int(arg[1:]) + elif arg[0] == 'f': + arg = float(arg[1:]) + elif arg[0] == 's': + arg = arg[1:] + + cur_level[key] = arg elif line[0] == 'D': # Remember the current level as the last parent. parent.append(cur_level) @@ -188,11 +299,19 @@ def parse_c_output(lines): return result def gen_inspect_code(path, struct, code): + if path[0][-1] == '#': + path[0] = path[0][:-1] + prefix = '' + else: + prefix = 'struct ' + c_descent(path[-1], code) + if len(path) == 1: - c_set('__size__', '%lu', 'sizeof (struct ' + path[0] + ')', code) + c_set('__size__', 'i%u', 'sizeof (' + prefix + path[0] + ')', code) else: - c_set('__size__', '%lu', 'sizeof ((struct ' + path[0] + ' *)0)->' + '.'.join(path[1:]), code) + c_set('__size__', 'i%u', 'sizeof ((' + prefix + path[0] + ' *)0)->' + '.'.join(path[1:]), code) + #c_set('__offset__', 'i%u', 'offsetof(' + prefix + path[0] + ', ' + '.'.join(path[1:]) + ')', code) for field in struct: if isinstance(field, dict): @@ -200,12 +319,12 @@ def gen_inspect_code(path, struct, code): fname = field.keys()[0] gen_inspect_code(path + [fname], field[fname], code) else: - c_set(field, '%u', 'offsetof(struct ' + path[0] + ', ' + '.'.join(path[1:] + [field]) + ')', code) + c_set(field, 'i%u', 'offsetof(' + prefix + path[0] + ', ' + '.'.join(path[1:] + [field]) + ')', code) c_ascent(code) def inspect_code(headers, cpp_opts, structs, defines): - sys.stderr.write('Generating C code...\n') + show('Generating C code...') code = ['#include ', '#include '] # Include all the needed headers. @@ -219,19 +338,27 @@ def inspect_code(headers, cpp_opts, structs, defines): c_ascent(code) c_descent('defines', code) - for name in defines: - if isinstance(name, list): - type_, name = name - else: - type_ = 'i' - c_set(name, '%' + type_, name, code) + for name, type_ in defines.items(): + # Add the necessary python type, if missing. + if '%' not in type_: + if type_[-1] in ('d', 'i', 'u'): + # integer + type_ = 'i%' + type_ + elif type_[-1] in ('f', 'F', 'e', 'E', 'g', 'G'): + # float + type_ = 'f%' + type_ + elif type_[-1] in ('x', 'X', 'a', 'A', 'c', 's'): + # hexadecimal or string + type_ = 's%' + type_ + + c_set(name, type_, name, code) code.append('return 0;') code.append('}') # Write the source code to a temporary file. src_file = tempfile.mkstemp('.c') - bin_file = tempfile.mkstemp() + bin_file = tempfile.mkstemp('.ll') os.write(src_file[0], '\n'.join(code)) @@ -239,15 +366,18 @@ def inspect_code(headers, cpp_opts, structs, defines): os.close(src_file[0]) os.close(bin_file[0]) + # NOTE: We can't generate an executable in the next step because it won't run on the current system without changing the target. + # If we change the target, some type sizes will change resulting in wrong data. As a workaround, we will be generating bitcode and + # run that with the LLVM interpreter. That way we can use the default target and still run the code. info = [] try: # Compile the program. - sys.stderr.write('Compiling generated code...\n') - subprocess.check_call([shared.CLANG_CC] + cpp_opts + ['-o', bin_file[1], src_file[1]]) + show('Compiling generated code...') + subprocess.check_call([shared.CLANG_CC, '-emit-llvm', '-S'] + cpp_opts + ['-o', bin_file[1], src_file[1]]) # Run the compiled program. - sys.stderr.write('Calling generated program...\n') - info = subprocess.check_output([bin_file[1]]).splitlines() + show('Calling generated program...') + info = subprocess.check_output([shared.LLVM_INTERPRETER, bin_file[1]]).splitlines() except subprocess.CalledProcessError: if os.path.isfile(bin_file[1]): sys.stderr.write('FAIL: Running the generated program failed!\n') @@ -263,47 +393,75 @@ def inspect_code(headers, cpp_opts, structs, defines): os.unlink(bin_file[1]) # Parse the output of the program into a dict. - data = parse_c_output(info) + return parse_c_output(info) + +def parse_json(path, header_files, structs, defines): + with open(path, 'r') as stream: + # Remove comments before loading the JSON. + data = json.loads(re.sub(r'//.*\n', '', stream.read())) - # Convert all the define's values into the appropriate python types (based on the type passed to printf). - for name in defines: - if isinstance(name, list): - type_, name = name - else: - type_ = 'i' + if not isinstance(data, list): + data = [ data ] + + for item in data: + header_files.append(item['file']) + for name, data in item['structs'].items(): + if name in structs: + show('WARN: Description of struct "' + name + '" in file "' + item['file'] + '" replaces an existing description!') + + structs[name] = data - if type_[-1] in ('d', 'i', 'u'): - # Integer - data['defines'][name] = int(data['defines'][name]) - elif type_[-1] in ('x', 'X', 'a', 'A'): - # Hexadecimal - data['defines'][name] = float.fromhex(data['defines'][name]) - elif type_[-1] in ('f', 'F', 'e', 'E', 'g', 'G'): - # Float - data['defines'][name] = float(data['defines'][name]) - # Leave everything else untouched. - - return data + for part in item['defines']: + if not isinstance(part, list): + # If no type is specified, assume integer. + part = ['i', part] + + if part[1] in defines: + show('WARN: Description of define "' + part[1] + '" in file "' + item['file'] + '" replaces an existing description!') + + defines[part[1]] = part[0] + +def output_json(obj, compressed=True, stream=None): + if stream == None: + stream = sys.stdout + elif isinstance(stream, str): + stream = open(stream, 'w') + + if compressed: + json.dump(obj, stream, separators=(',', ':')) + else: + json.dump(obj, stream, indent=4, sort_keys=True) + + stream.close() + +def filter_opts(opts): + # Only apply compiler options regarding syntax, includes and defines. + # We have to compile for the current system, we aren't compiling to bitcode after all. + out = [] + for flag in opts: + if flag[:2] in ('-f', '-I', '-i', '-D', '-U'): + out.append(flag) + + return out -def main(): +def main(args): + global QUIET + parser = argparse.ArgumentParser(description='Generate JSON infos for structs.') parser.add_argument('headers', nargs='+', help='A header (.h) file or a JSON file with a list of structs and their fields') - parser.add_argument('-f', dest='list_fields', action='store_true', default=False, help='Output a list of structs and fields for the first header.') + parser.add_argument('-q', dest='quiet', action='store_true', default=False, help='Don\'t output anything besides error messages.') + parser.add_argument('-f', dest='list_fields', action='store_true', default=False, help='Output a list of structs and fields for the given headers.') parser.add_argument('-p', dest='pretty_print', action='store_true', default=False, help='Pretty print the outputted JSON.') parser.add_argument('-o', dest='output', metavar='path', default=None, help='Path to the JSON file that will be written. If omitted, the generated data will be printed to stdout.') parser.add_argument('-I', dest='includes', metavar='dir', action='append', default=[], help='Add directory to include search path') parser.add_argument('-D', dest='defines', metavar='define', action='append', default=[], help='Pass a define to the preprocessor') parser.add_argument('-U', dest='undefines', metavar='undefine', action='append', default=[], help='Pass an undefine to the preprocessor') - args = parser.parse_args() + args = parser.parse_args(args) - # Avoid parsing problems due to gcc specifc syntax. - cpp_opts = ['-U__GNUC__'] + QUIET = args.quiet - # Only apply compiler options regarding syntax, includes and defines. - # We have to compile for the current system, we aren't compiling to bitcode after all. - for flag in shared.COMPILER_OPTS: - if flag[:2] in ('-f', '-I', '-i', '-D', '-U'): - cpp_opts.append(flag) + # Avoid parsing problems due to gcc specifc syntax. + cpp_opts = ['-U__GNUC__', '-D_GNU_SOURCE'] + shared.COMPILER_OPTS # Add the user options to the list as well. for path in args.includes: @@ -316,20 +474,15 @@ def main(): cpp_opts.append('-U' + arg) if args.list_fields: - # Just parse the first header and output the result. - structs = parse_header(args.headers[0], cpp_opts) - data = { - 'file': args.headers[0], - 'structs': structs, - 'defines': [] - } - - if args.output == None: - sys.stdout.write(json.dumps(data, indent=4 if args.pretty_print else None)) - else: - with open(args.output, 'w') as stream: - json.dump(data, stream, indent=4 if args.pretty_print else None) + # Just parse the given headers and output the result. + data = [] + for path in args.headers: + if path[-5:] == '.json': + show('WARN: Skipping "' + path + '" because it\'s already a JSON file!') + else: + data.append(parse_header(path, cpp_opts)) + output_json(data, not args.pretty_print, args.output) sys.exit(0) # Look for structs in all passed headers. @@ -339,30 +492,18 @@ def main(): for header in args.headers: if header[-5:] == '.json': - # This is a JSON file, simply load it. - with open(header, 'r') as stream: - data = json.load(stream) - - if not isinstance(data, list): - data = [ data ] - - for item in data: - header_files.append(item['file']) - structs.update(item['structs']) - defines.update(item['defines']) + # This is a JSON file, parse it. + parse_json(header, header_files, structs, defines) else: # If the passed file isn't a JSON file, assume it's a header. header_files.append(header) - structs.update(parse_header(header, cpp_opts)) + data = parse_header(header, cpp_opts) + structs.update(data['structs']) + defines.extend(data['defines']) # Inspect all collected structs. struct_info = inspect_code(header_files, cpp_opts, structs, defines) - - if args.output == None: - sys.stdout.write(json.dumps(struct_info, indent=4 if args.pretty_print else None)) - else: - with open(args.output, 'w') as stream: - json.dump(struct_info, stream, indent=4 if args.pretty_print else None) + output_json(struct_info, not args.pretty_print, args.output) if __name__ == '__main__': - main() \ No newline at end of file + main(sys.argv[1:]) \ No newline at end of file diff --git a/tools/shared.py b/tools/shared.py index a07bdeaf43ae0..76802eaada56d 100644 --- a/tools/shared.py +++ b/tools/shared.py @@ -354,7 +354,7 @@ def check_sanity(force=False): logging.critical('Node.js (%s) does not seem to work, check the paths in %s' % (NODE_JS, EM_CONFIG)) sys.exit(1) - for cmd in [CLANG, LINK_CMD[0], LLVM_AR, LLVM_OPT, LLVM_AS, LLVM_DIS, LLVM_NM]: + for cmd in [CLANG, LINK_CMD[0], LLVM_AR, LLVM_OPT, LLVM_AS, LLVM_DIS, LLVM_NM, LLVM_INTERPRETER]: if not os.path.exists(cmd) and not os.path.exists(cmd + '.exe'): # .exe extension required for Windows logging.critical('Cannot find %s, check the paths in %s' % (cmd, EM_CONFIG)) sys.exit(1) @@ -1445,7 +1445,15 @@ def make(opt_level): if not ok: logging.error('bootstrapping relooper failed. You may need to manually create relooper.js by compiling it, see src/relooper/emscripten') 1/0 - + + @staticmethod + def ensure_struct_info(info_path): + if os.path.exists(info_path): return + Cache.ensure() + + import gen_struct_info + gen_struct_info.main(['-o', info_path, path_from_root('src/struct_info.json')]) + @staticmethod def preprocess(infile, outfile): ''' From 29a62bd92e056800c7bf8f91fbe4c9fc948bf035 Mon Sep 17 00:00:00 2001 From: ngld Date: Tue, 17 Sep 2013 00:44:38 +0200 Subject: [PATCH 003/165] Updated library_sdl.js --- src/library_sdl.js | 187 +++++------------ src/settings.js | 428 +-------------------------------------- src/struct_info.json | 191 +++++++++++++++++ tools/gen_struct_info.py | 2 +- tools/shared.py | 2 +- 5 files changed, 255 insertions(+), 555 deletions(-) diff --git a/src/library_sdl.js b/src/library_sdl.js index 116bf547c4ec9..e9d5a1d9cb14f 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -35,7 +35,7 @@ var LibrarySDL = { volume: 1.0 }, mixerFrequency: 22050, - mixerFormat: 0x8010, // AUDIO_S16LSB + mixerFormat: {{{ cDefine('AUDIO_S16LSB') }}}, //0x8010, // AUDIO_S16LSB mixerNumChannels: 2, mixerChunkSize: 1024, channelMinimumNumber: 0, @@ -151,89 +151,12 @@ var LibrarySDL = { 305: 224, // ctrl 308: 226, // alt }, - - structs: { - Rect: Runtime.generateStructInfo([ - ['i32', 'x'], ['i32', 'y'], ['i32', 'w'], ['i32', 'h'], - ]), - PixelFormat: Runtime.generateStructInfo([ - ['i32', 'format'], - ['void*', 'palette'], ['i8', 'BitsPerPixel'], ['i8', 'BytesPerPixel'], - ['i8', 'padding1'], ['i8', 'padding2'], - ['i32', 'Rmask'], ['i32', 'Gmask'], ['i32', 'Bmask'], ['i32', 'Amask'], - ['i8', 'Rloss'], ['i8', 'Gloss'], ['i8', 'Bloss'], ['i8', 'Aloss'], - ['i8', 'Rshift'], ['i8', 'Gshift'], ['i8', 'Bshift'], ['i8', 'Ashift'] - ]), - KeyboardEvent: Runtime.generateStructInfo([ - ['i32', 'type'], - ['i32', 'windowID'], - ['i8', 'state'], - ['i8', 'repeat'], - ['i8', 'padding2'], - ['i8', 'padding3'], - ['i32', 'keysym'] - ]), - keysym: Runtime.generateStructInfo([ - ['i32', 'scancode'], - ['i32', 'sym'], - ['i16', 'mod'], - ['i32', 'unicode'] - ]), - TextInputEvent: Runtime.generateStructInfo([ - ['i32', 'type'], - ['i32', 'windowID'], - ['b256', 'text'], - ]), - MouseMotionEvent: Runtime.generateStructInfo([ - ['i32', 'type'], - ['i32', 'windowID'], - ['i8', 'state'], - ['i8', 'padding1'], - ['i8', 'padding2'], - ['i8', 'padding3'], - ['i32', 'x'], - ['i32', 'y'], - ['i32', 'xrel'], - ['i32', 'yrel'] - ]), - MouseButtonEvent: Runtime.generateStructInfo([ - ['i32', 'type'], - ['i32', 'windowID'], - ['i8', 'button'], - ['i8', 'state'], - ['i8', 'padding1'], - ['i8', 'padding2'], - ['i32', 'x'], - ['i32', 'y'] - ]), - ResizeEvent: Runtime.generateStructInfo([ - ['i32', 'type'], - ['i32', 'w'], - ['i32', 'h'] - ]), - AudioSpec: Runtime.generateStructInfo([ - ['i32', 'freq'], - ['i16', 'format'], - ['i8', 'channels'], - ['i8', 'silence'], - ['i16', 'samples'], - ['i32', 'size'], - ['void*', 'callback'], - ['void*', 'userdata'] - ]), - version: Runtime.generateStructInfo([ - ['i8', 'major'], - ['i8', 'minor'], - ['i8', 'patch'] - ]) - }, - loadRect: function(rect) { return { - x: {{{ makeGetValue('rect + SDL.structs.Rect.x', '0', 'i32') }}}, - y: {{{ makeGetValue('rect + SDL.structs.Rect.y', '0', 'i32') }}}, - w: {{{ makeGetValue('rect + SDL.structs.Rect.w', '0', 'i32') }}}, - h: {{{ makeGetValue('rect + SDL.structs.Rect.h', '0', 'i32') }}} + x: {{{ makeGetValue('rect + ' + C_STRUCTS.SDL_Rect.x, '0', 'i32') }}}, + y: {{{ makeGetValue('rect + ' + C_STRUCTS.SDL_Rect.y, '0', 'i32') }}}, + w: {{{ makeGetValue('rect + ' + C_STRUCTS.SDL_Rect.w, '0', 'i32') }}}, + h: {{{ makeGetValue('rect + ' + C_STRUCTS.SDL_Rect.h, '0', 'i32') }}} }; }, @@ -281,15 +204,15 @@ var LibrarySDL = { {{{ makeSetValue('surf+Runtime.QUANTUM_SIZE*14', '0', '1', 'i32') }}} - {{{ makeSetValue('pixelFormat + SDL.structs.PixelFormat.format', '0', '-2042224636', 'i32') }}} // SDL_PIXELFORMAT_RGBA8888 - {{{ makeSetValue('pixelFormat + SDL.structs.PixelFormat.palette', '0', '0', 'i32') }}} // TODO - {{{ makeSetValue('pixelFormat + SDL.structs.PixelFormat.BitsPerPixel', '0', 'bpp * 8', 'i8') }}} - {{{ makeSetValue('pixelFormat + SDL.structs.PixelFormat.BytesPerPixel', '0', 'bpp', 'i8') }}} + {{{ makeSetValue('pixelFormat + ' + C_STRUCTS.SDL_PixelFormat.format, '0', '-2042224636', 'i32') }}} // SDL_PIXELFORMAT_RGBA8888 + {{{ makeSetValue('pixelFormat + ' + C_STRUCTS.SDL_PixelFormat.palette, '0', '0', 'i32') }}} // TODO + {{{ makeSetValue('pixelFormat + ' + C_STRUCTS.SDL_PixelFormat.BitsPerPixel, '0', 'bpp * 8', 'i8') }}} + {{{ makeSetValue('pixelFormat + ' + C_STRUCTS.SDL_PixelFormat.BytesPerPixel, '0', 'bpp', 'i8') }}} - {{{ makeSetValue('pixelFormat + SDL.structs.PixelFormat.Rmask', '0', 'rmask || 0x000000ff', 'i32') }}} - {{{ makeSetValue('pixelFormat + SDL.structs.PixelFormat.Gmask', '0', 'gmask || 0x0000ff00', 'i32') }}} - {{{ makeSetValue('pixelFormat + SDL.structs.PixelFormat.Bmask', '0', 'bmask || 0x00ff0000', 'i32') }}} - {{{ makeSetValue('pixelFormat + SDL.structs.PixelFormat.Amask', '0', 'amask || 0xff000000', 'i32') }}} + {{{ makeSetValue('pixelFormat + ' + C_STRUCTS.SDL_PixelFormat.Rmask, '0', 'rmask || 0x000000ff', 'i32') }}} + {{{ makeSetValue('pixelFormat + ' + C_STRUCTS.SDL_PixelFormat.Gmask, '0', 'gmask || 0x0000ff00', 'i32') }}} + {{{ makeSetValue('pixelFormat + ' + C_STRUCTS.SDL_PixelFormat.Bmask, '0', 'bmask || 0x00ff0000', 'i32') }}} + {{{ makeSetValue('pixelFormat + ' + C_STRUCTS.SDL_PixelFormat.Amask, '0', 'amask || 0xff000000', 'i32') }}} // Decide if we want to use WebGL or not var useWebGL = (flags & 0x04000000) != 0; // SDL_OPENGL @@ -608,7 +531,7 @@ var LibrarySDL = { makeCEvent: function(event, ptr) { if (typeof event === 'number') { // This is a pointer to a native C event that was SDL_PushEvent'ed - _memcpy(ptr, event, SDL.structs.KeyboardEvent.__size__); // XXX + _memcpy(ptr, event, {{{ C_STRUCTS.SDL_KeyboardEvent.__size__ }}}); // XXX return; } @@ -631,52 +554,52 @@ var LibrarySDL = { scan = SDL.scanCodes[key] || key; } - {{{ makeSetValue('ptr', 'SDL.structs.KeyboardEvent.type', 'SDL.DOMEventToSDLEvent[event.type]', 'i32') }}} - {{{ makeSetValue('ptr', 'SDL.structs.KeyboardEvent.state', 'down ? 1 : 0', 'i8') }}} - {{{ makeSetValue('ptr', 'SDL.structs.KeyboardEvent.repeat', '0', 'i8') }}} // TODO - {{{ makeSetValue('ptr', 'SDL.structs.KeyboardEvent.keysym + SDL.structs.keysym.scancode', 'scan', 'i32') }}} - {{{ makeSetValue('ptr', 'SDL.structs.KeyboardEvent.keysym + SDL.structs.keysym.sym', 'key', 'i32') }}} - {{{ makeSetValue('ptr', 'SDL.structs.KeyboardEvent.keysym + SDL.structs.keysym.mod', 'SDL.modState', 'i16') }}} + {{{ makeSetValue('ptr', C_STRUCTS.SDL_KeyboardEvent.type, 'SDL.DOMEventToSDLEvent[event.type]', 'i32') }}} + {{{ makeSetValue('ptr', C_STRUCTS.SDL_KeyboardEvent.state, 'down ? 1 : 0', 'i8') }}} + {{{ makeSetValue('ptr', C_STRUCTS.SDL_KeyboardEvent.repeat, '0', 'i8') }}} // TODO + {{{ makeSetValue('ptr', C_STRUCTS.SDL_KeyboardEvent.keysym + C_STRUCTS.SDL_Keysym.scancode, 'scan', 'i32') }}} + {{{ makeSetValue('ptr', C_STRUCTS.SDL_KeyboardEvent.keysym + C_STRUCTS.SDL_Keysym.sym, 'key', 'i32') }}} + {{{ makeSetValue('ptr', C_STRUCTS.SDL_KeyboardEvent.keysym + C_STRUCTS.SDL_Keysym.mod, 'SDL.modState', 'i16') }}} // some non-character keys (e.g. backspace and tab) won't have keypressCharCode set, fill in with the keyCode. - {{{ makeSetValue('ptr', 'SDL.structs.KeyboardEvent.keysym + SDL.structs.keysym.unicode', 'event.keypressCharCode || key', 'i32') }}} + {{{ makeSetValue('ptr', C_STRUCTS.SDL_KeyboardEvent.keysym + C_STRUCTS.SDL_Keysym.unicode, 'event.keypressCharCode || key', 'i32') }}} break; } case 'keypress': { - {{{ makeSetValue('ptr', 'SDL.structs.TextInputEvent.type', 'SDL.DOMEventToSDLEvent[event.type]', 'i32') }}} + {{{ makeSetValue('ptr', C_STRUCTS.SDL_TextInputEvent.type, 'SDL.DOMEventToSDLEvent[event.type]', 'i32') }}} // Not filling in windowID for now var cStr = intArrayFromString(String.fromCharCode(event.charCode)); for (var i = 0; i < cStr.length; ++i) { - {{{ makeSetValue('ptr', 'SDL.structs.TextInputEvent.text + i', 'cStr[i]', 'i8') }}}; + {{{ makeSetValue('ptr', C_STRUCTS.SDL_TextInputEvent.text + ' + i', 'cStr[i]', 'i8') }}}; } break; } case 'mousedown': case 'mouseup': case 'mousemove': { if (event.type != 'mousemove') { var down = event.type === 'mousedown'; - {{{ makeSetValue('ptr', 'SDL.structs.MouseButtonEvent.type', 'SDL.DOMEventToSDLEvent[event.type]', 'i32') }}}; - {{{ makeSetValue('ptr', 'SDL.structs.MouseButtonEvent.button', 'event.button+1', 'i8') }}}; // DOM buttons are 0-2, SDL 1-3 - {{{ makeSetValue('ptr', 'SDL.structs.MouseButtonEvent.state', 'down ? 1 : 0', 'i8') }}}; - {{{ makeSetValue('ptr', 'SDL.structs.MouseButtonEvent.x', 'Browser.mouseX', 'i32') }}}; - {{{ makeSetValue('ptr', 'SDL.structs.MouseButtonEvent.y', 'Browser.mouseY', 'i32') }}}; + {{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseButtonEvent.type, 'SDL.DOMEventToSDLEvent[event.type]', 'i32') }}}; + {{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseButtonEvent.button, 'event.button+1', 'i8') }}}; // DOM buttons are 0-2, SDL 1-3 + {{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseButtonEvent.state, 'down ? 1 : 0', 'i8') }}}; + {{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseButtonEvent.x, 'Browser.mouseX', 'i32') }}}; + {{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseButtonEvent.y, 'Browser.mouseY', 'i32') }}}; } else { - {{{ makeSetValue('ptr', 'SDL.structs.MouseMotionEvent.type', 'SDL.DOMEventToSDLEvent[event.type]', 'i32') }}}; - {{{ makeSetValue('ptr', 'SDL.structs.MouseMotionEvent.state', 'SDL.buttonState', 'i8') }}}; - {{{ makeSetValue('ptr', 'SDL.structs.MouseMotionEvent.x', 'Browser.mouseX', 'i32') }}}; - {{{ makeSetValue('ptr', 'SDL.structs.MouseMotionEvent.y', 'Browser.mouseY', 'i32') }}}; - {{{ makeSetValue('ptr', 'SDL.structs.MouseMotionEvent.xrel', 'Browser.mouseMovementX', 'i32') }}}; - {{{ makeSetValue('ptr', 'SDL.structs.MouseMotionEvent.yrel', 'Browser.mouseMovementY', 'i32') }}}; + {{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseMotionEvent.type, 'SDL.DOMEventToSDLEvent[event.type]', 'i32') }}}; + {{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseMotionEvent.state, 'SDL.buttonState', 'i8') }}}; + {{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseMotionEvent.x, 'Browser.mouseX', 'i32') }}}; + {{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseMotionEvent.y, 'Browser.mouseY', 'i32') }}}; + {{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseMotionEvent.xrel, 'Browser.mouseMovementX', 'i32') }}}; + {{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseMotionEvent.yrel, 'Browser.mouseMovementY', 'i32') }}}; } break; } case 'unload': { - {{{ makeSetValue('ptr', 'SDL.structs.KeyboardEvent.type', 'SDL.DOMEventToSDLEvent[event.type]', 'i32') }}}; + {{{ makeSetValue('ptr', C_STRUCTS.SDL_KeyboardEvent.type, 'SDL.DOMEventToSDLEvent[event.type]', 'i32') }}}; break; } case 'resize': { - {{{ makeSetValue('ptr', 'SDL.structs.KeyboardEvent.type', 'SDL.DOMEventToSDLEvent[event.type]', 'i32') }}}; - {{{ makeSetValue('ptr', 'SDL.structs.ResizeEvent.w', 'event.w', 'i32') }}}; - {{{ makeSetValue('ptr', 'SDL.structs.ResizeEvent.h', 'event.h', 'i32') }}}; + {{{ makeSetValue('ptr', C_STRUCTS.SDL_KeyboardEvent.type, 'SDL.DOMEventToSDLEvent[event.type]', 'i32') }}}; + {{{ makeSetValue('ptr', C_STRUCTS.SDL_ResizeEvent.w, 'event.w', 'i32') }}}; + {{{ makeSetValue('ptr', C_STRUCTS.SDL_ResizeEvent.h, 'event.h', 'i32') }}}; break; } default: throw 'Unhandled SDL event: ' + event.type; @@ -740,10 +663,10 @@ var LibrarySDL = { SDL_Linked_Version: function() { if (SDL.version === null) { - SDL.version = _malloc(SDL.structs.version.__size__); - {{{ makeSetValue('SDL.version + SDL.structs.version.major', '0', '1', 'i8') }}} - {{{ makeSetValue('SDL.version + SDL.structs.version.minor', '0', '3', 'i8') }}} - {{{ makeSetValue('SDL.version + SDL.structs.version.patch', '0', '0', 'i8') }}} + SDL.version = _malloc({{{ C_STRUCTS.SDL_version.__size__ }}}); + {{{ makeSetValue('SDL.version + ' + C_STRUCTS.SDL_version.major, '0', '1', 'i8') }}} + {{{ makeSetValue('SDL.version + ' + C_STRUCTS.SDL_version.minor, '0', '3', 'i8') }}} + {{{ makeSetValue('SDL.version + ' + C_STRUCTS.SDL_version.patch, '0', '0', 'i8') }}} } return SDL.version; }, @@ -1459,24 +1382,24 @@ var LibrarySDL = { SDL.allocateChannels(32); SDL.audio = { - freq: {{{ makeGetValue('desired', 'SDL.structs.AudioSpec.freq', 'i32', 0, 1) }}}, - format: {{{ makeGetValue('desired', 'SDL.structs.AudioSpec.format', 'i16', 0, 1) }}}, - channels: {{{ makeGetValue('desired', 'SDL.structs.AudioSpec.channels', 'i8', 0, 1) }}}, - samples: {{{ makeGetValue('desired', 'SDL.structs.AudioSpec.samples', 'i16', 0, 1) }}}, - callback: {{{ makeGetValue('desired', 'SDL.structs.AudioSpec.callback', 'void*', 0, 1) }}}, - userdata: {{{ makeGetValue('desired', 'SDL.structs.AudioSpec.userdata', 'void*', 0, 1) }}}, + freq: {{{ makeGetValue('desired', C_STRUCTS.SDL_AudioSpec.freq, 'i32', 0, 1) }}}, + format: {{{ makeGetValue('desired', C_STRUCTS.SDL_AudioSpec.format, 'i16', 0, 1) }}}, + channels: {{{ makeGetValue('desired', C_STRUCTS.SDL_AudioSpec.channels, 'i8', 0, 1) }}}, + samples: {{{ makeGetValue('desired', C_STRUCTS.SDL_AudioSpec.samples, 'i16', 0, 1) }}}, + callback: {{{ makeGetValue('desired', C_STRUCTS.SDL_AudioSpec.callback, 'void*', 0, 1) }}}, + userdata: {{{ makeGetValue('desired', C_STRUCTS.SDL_AudioSpec.userdata, 'void*', 0, 1) }}}, paused: true, timer: null }; if (obtained) { - {{{ makeSetValue('obtained', 'SDL.structs.AudioSpec.freq', 'SDL.audio.freq', 'i32') }}}; // no good way for us to know if the browser can really handle this - {{{ makeSetValue('obtained', 'SDL.structs.AudioSpec.format', 33040, 'i16') }}}; // float, signed, 16-bit - {{{ makeSetValue('obtained', 'SDL.structs.AudioSpec.channels', 'SDL.audio.channels', 'i8') }}}; - {{{ makeSetValue('obtained', 'SDL.structs.AudioSpec.silence', makeGetValue('desired', 'SDL.structs.AudioSpec.silence', 'i8', 0, 1), 'i8') }}}; // unclear if browsers can provide this - {{{ makeSetValue('obtained', 'SDL.structs.AudioSpec.samples', 'SDL.audio.samples', 'i16') }}}; - {{{ makeSetValue('obtained', 'SDL.structs.AudioSpec.callback', 'SDL.audio.callback', '*') }}}; - {{{ makeSetValue('obtained', 'SDL.structs.AudioSpec.userdata', 'SDL.audio.userdata', '*') }}}; + {{{ makeSetValue('obtained', C_STRUCTS.SDL_AudioSpec.freq, 'SDL.audio.freq', 'i32') }}}; // no good way for us to know if the browser can really handle this + {{{ makeSetValue('obtained', C_STRUCTS.SDL_AudioSpec.format, 33040, 'i16') }}}; // float, signed, 16-bit + {{{ makeSetValue('obtained', C_STRUCTS.SDL_AudioSpec.channels, 'SDL.audio.channels', 'i8') }}}; + {{{ makeSetValue('obtained', C_STRUCTS.SDL_AudioSpec.silence, makeGetValue('desired', C_STRUCTS.SDL_AudioSpec.silence, 'i8', 0, 1), 'i8') }}}; // unclear if browsers can provide this + {{{ makeSetValue('obtained', C_STRUCTS.SDL_AudioSpec.samples, 'SDL.audio.samples', 'i16') }}}; + {{{ makeSetValue('obtained', C_STRUCTS.SDL_AudioSpec.callback, 'SDL.audio.callback', '*') }}}; + {{{ makeSetValue('obtained', C_STRUCTS.SDL_AudioSpec.userdata, 'SDL.audio.userdata', '*') }}}; } var totalSamples = SDL.audio.samples*SDL.audio.channels; diff --git a/src/settings.js b/src/settings.js index 15bca4db5251c..8d9d4634377f9 100644 --- a/src/settings.js +++ b/src/settings.js @@ -440,425 +440,11 @@ var DEBUG_TAGS_SHOWING = []; // A cached set of defines, generated from the header files. This // lets the emscripten libc (library.js) see the right values. -// If you modify the headers or use different ones, you will need -// to override this. -var C_DEFINES = { - 'ABDAY_1': '131072', - 'ABDAY_2': '131073', - 'ABDAY_3': '131074', - 'ABDAY_4': '131075', - 'ABDAY_5': '131076', - 'ABDAY_6': '131077', - 'ABDAY_7': '131078', - 'ABMON_1': '131086', - 'ABMON_10': '131095', - 'ABMON_11': '131096', - 'ABMON_12': '131097', - 'ABMON_2': '131087', - 'ABMON_3': '131088', - 'ABMON_4': '131089', - 'ABMON_5': '131090', - 'ABMON_6': '131091', - 'ABMON_7': '131092', - 'ABMON_8': '131093', - 'ABMON_9': '131094', - 'AF_INET': '2', - 'AF_INET6': '10', - 'AF_UNSPEC': '0', - 'AI_ADDRCONFIG': '32', - 'AI_ALL': '16', - 'AI_CANONNAME': '2', - 'AI_NUMERICHOST': '4', - 'AI_NUMERICSERV': '1024', - 'AI_PASSIVE': '1', - 'AI_V4MAPPED': '8', - 'ALT_DIGITS': '131119', - 'AM_STR': '131110', - 'CLOCKS_PER_SEC': '1000000', - 'CODESET': '14', - 'CRNCYSTR': '262159', - 'DAY_1': '131079', - 'DAY_2': '131080', - 'DAY_3': '131081', - 'DAY_4': '131082', - 'DAY_5': '131083', - 'DAY_6': '131084', - 'DAY_7': '131085', - 'D_FMT': '131113', - 'D_T_FMT': '131112', - 'E2BIG': '7', - 'EACCES': '13', - 'EADDRINUSE': '98', - 'EADDRNOTAVAIL': '99', - 'EADV': '68', - 'EAFNOSUPPORT': '97', - 'EAGAIN': '11', - 'EAI_BADFLAGS': '-1', - 'EAI_FAMILY': '-6', - 'EAI_NONAME': '-2', - 'EAI_OVERFLOW': '-12', - 'EAI_SERVICE': '-8', - 'EAI_SOCKTYPE': '-7', - 'EALREADY': '114', - 'EBADE': '52', - 'EBADF': '9', - 'EBADFD': '77', - 'EBADMSG': '74', - 'EBADR': '53', - 'EBADRQC': '56', - 'EBADSLT': '57', - 'EBFONT': '59', - 'EBUSY': '16', - 'ECANCELED': '125', - 'ECHILD': '10', - 'ECHRNG': '44', - 'ECOMM': '70', - 'ECONNABORTED': '103', - 'ECONNREFUSED': '111', - 'ECONNRESET': '104', - 'EDEADLK': '35', - 'EDEADLOCK': '35', - 'EDESTADDRREQ': '89', - 'EDOM': '33', - 'EDOTDOT': '73', - 'EDQUOT': '122', - 'EEXIST': '17', - 'EFAULT': '14', - 'EFBIG': '27', - 'EHOSTDOWN': '112', - 'EHOSTUNREACH': '113', - 'EIDRM': '43', - 'EILSEQ': '84', - 'EINPROGRESS': '115', - 'EINTR': '4', - 'EINVAL': '22', - 'EIO': '5', - 'EISCONN': '106', - 'EISDIR': '21', - 'EL2HLT': '51', - 'EL2NSYNC': '45', - 'EL3HLT': '46', - 'EL3RST': '47', - 'ELIBACC': '79', - 'ELIBBAD': '80', - 'ELIBEXEC': '83', - 'ELIBMAX': '82', - 'ELIBSCN': '81', - 'ELNRNG': '48', - 'ELOOP': '40', - 'EMFILE': '24', - 'EMLINK': '31', - 'EMSGSIZE': '90', - 'EMULTIHOP': '72', - 'ENAMETOOLONG': '36', - 'ENETDOWN': '100', - 'ENETRESET': '102', - 'ENETUNREACH': '101', - 'ENFILE': '23', - 'ENOANO': '55', - 'ENOBUFS': '105', - 'ENOCSI': '50', - 'ENODATA': '61', - 'ENODEV': '19', - 'ENOENT': '2', - 'ENOEXEC': '8', - 'ENOLCK': '37', - 'ENOLINK': '67', - 'ENOMEDIUM': '123', - 'ENOMEM': '12', - 'ENOMSG': '42', - 'ENONET': '64', - 'ENOPKG': '65', - 'ENOPROTOOPT': '92', - 'ENOSPC': '28', - 'ENOSR': '63', - 'ENOSTR': '60', - 'ENOSYS': '38', - 'ENOTBLK': '15', - 'ENOTCONN': '107', - 'ENOTDIR': '20', - 'ENOTEMPTY': '39', - 'ENOTRECOVERABLE': '131', - 'ENOTSOCK': '88', - 'ENOTSUP': '95', - 'ENOTTY': '25', - 'ENOTUNIQ': '76', - 'ENXIO': '6', - 'EOF': '-1', - 'EOPNOTSUPP': '95', - 'EOVERFLOW': '75', - 'EOWNERDEAD': '130', - 'EPERM': '1', - 'EPFNOSUPPORT': '96', - 'EPIPE': '32', - 'EPROTO': '71', - 'EPROTONOSUPPORT': '93', - 'EPROTOTYPE': '91', - 'ERA': '131116', - 'ERANGE': '34', - 'ERA_D_FMT': '131118', - 'ERA_D_T_FMT': '131120', - 'ERA_T_FMT': '131121', - 'EREMCHG': '78', - 'EREMOTE': '66', - 'EROFS': '30', - 'ESHUTDOWN': '108', - 'ESOCKTNOSUPPORT': '94', - 'ESPIPE': '29', - 'ESRCH': '3', - 'ESRMNT': '69', - 'ESTALE': '116', - 'ESTRPIPE': '86', - 'ETIME': '62', - 'ETIMEDOUT': '110', - 'ETOOMANYREFS': '109', - 'ETXTBSY': '26', - 'EUNATCH': '49', - 'EUSERS': '87', - 'EWOULDBLOCK': '11', - 'EXDEV': '18', - 'EXFULL': '54', - 'FIONREAD': '21531', - 'FP_INFINITE': '1', - 'FP_NAN': '0', - 'FP_NORMAL': '4', - 'FP_ZERO': '2', - 'F_DUPFD': '0', - 'F_GETFD': '1', - 'F_GETFL': '3', - 'F_GETLK': '12', - 'F_GETLK64': '12', - 'F_GETOWN': '9', - 'F_SETFD': '2', - 'F_SETFL': '4', - 'F_SETLK': '13', - 'F_SETLK64': '13', - 'F_SETLKW': '14', - 'F_SETLKW64': '14', - 'F_SETOWN': '8', - 'F_UNLCK': '2', - 'INADDR_LOOPBACK': '2130706433', - 'IPPROTO_TCP': '6', - 'IPPROTO_UDP': '17', - 'MAP_PRIVATE': '2', - 'MON_1': '131098', - 'MON_10': '131107', - 'MON_11': '131108', - 'MON_12': '131109', - 'MON_2': '131099', - 'MON_3': '131100', - 'MON_4': '131101', - 'MON_5': '131102', - 'MON_6': '131103', - 'MON_7': '131104', - 'MON_8': '131105', - 'MON_9': '131106', - 'NI_NAMEREQD': '8', - 'NI_NUMERICHOST': '1', - 'NOEXPR': '327681', - 'O_ACCMODE': '2097155', - 'O_APPEND': '1024', - 'O_CREAT': '64', - 'O_EXCL': '128', - 'O_NOFOLLOW': '131072', - 'O_RDONLY': '0', - 'O_RDWR': '2', - 'O_SYNC': '1052672', - 'O_TRUNC': '512', - 'O_WRONLY': '1', - 'PM_STR': '131111', - 'POLLERR': '8', - 'POLLHUP': '16', - 'POLLIN': '1', - 'POLLNVAL': '32', - 'POLLOUT': '4', - 'POLLPRI': '2', - 'POLLRDNORM': '64', - 'RADIXCHAR': '65536', - 'R_OK': '4', - 'SEEK_END': '2', - 'SEEK_SET': '0', - 'SOCK_DGRAM': '2', - 'SOCK_STREAM': '1', - 'S_IALLUGO': '4095', - 'S_IFBLK': '24576', - 'S_IFCHR': '8192', - 'S_IFDIR': '16384', - 'S_IFIFO': '4096', - 'S_IFLNK': '40960', - 'S_IFMT': '61440', - 'S_IFREG': '32768', - 'S_IFSOCK': '49152', - 'S_IRUGO': '292', - 'S_IRWXO': '7', - 'S_IRWXUGO': '511', - 'S_ISVTX': '512', - 'S_IWUGO': '146', - 'S_IXUGO': '73', - 'THOUSEP': '65537', - 'T_FMT': '131114', - 'T_FMT_AMPM': '131115', - 'W_OK': '2', - 'X_OK': '1', - 'YESEXPR': '327680', - '_CS_GNU_LIBC_VERSION': '2', - '_CS_GNU_LIBPTHREAD_VERSION': '3', - '_CS_PATH': '0', - '_CS_POSIX_V6_ILP32_OFF32_CFLAGS': '1116', - '_CS_POSIX_V6_ILP32_OFF32_LDFLAGS': '1117', - '_CS_POSIX_V6_ILP32_OFF32_LIBS': '1118', - '_CS_POSIX_V6_ILP32_OFFBIG_CFLAGS': '1120', - '_CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS': '1121', - '_CS_POSIX_V6_ILP32_OFFBIG_LIBS': '1122', - '_CS_POSIX_V6_LP64_OFF64_CFLAGS': '1124', - '_CS_POSIX_V6_LP64_OFF64_LDFLAGS': '1125', - '_CS_POSIX_V6_LP64_OFF64_LIBS': '1126', - '_CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS': '1128', - '_CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS': '1129', - '_CS_POSIX_V6_LPBIG_OFFBIG_LIBS': '1130', - '_CS_POSIX_V6_WIDTH_RESTRICTED_ENVS': '1', - '_PC_2_SYMLINKS': '20', - '_PC_ALLOC_SIZE_MIN': '18', - '_PC_ASYNC_IO': '10', - '_PC_CHOWN_RESTRICTED': '6', - '_PC_FILESIZEBITS': '13', - '_PC_LINK_MAX': '0', - '_PC_MAX_CANON': '1', - '_PC_MAX_INPUT': '2', - '_PC_NAME_MAX': '3', - '_PC_NO_TRUNC': '7', - '_PC_PATH_MAX': '4', - '_PC_PIPE_BUF': '5', - '_PC_PRIO_IO': '11', - '_PC_REC_INCR_XFER_SIZE': '14', - '_PC_REC_MAX_XFER_SIZE': '15', - '_PC_REC_MIN_XFER_SIZE': '16', - '_PC_REC_XFER_ALIGN': '17', - '_PC_SOCK_MAXBUF': '12', - '_PC_SYMLINK_MAX': '19', - '_PC_SYNC_IO': '9', - '_PC_VDISABLE': '8', - '_SC_2_CHAR_TERM': '95', - '_SC_2_C_BIND': '47', - '_SC_2_C_DEV': '48', - '_SC_2_FORT_DEV': '49', - '_SC_2_FORT_RUN': '50', - '_SC_2_LOCALEDEF': '52', - '_SC_2_PBS': '168', - '_SC_2_PBS_ACCOUNTING': '169', - '_SC_2_PBS_CHECKPOINT': '175', - '_SC_2_PBS_LOCATE': '170', - '_SC_2_PBS_MESSAGE': '171', - '_SC_2_PBS_TRACK': '172', - '_SC_2_SW_DEV': '51', - '_SC_2_UPE': '97', - '_SC_2_VERSION': '46', - '_SC_ADVISORY_INFO': '132', - '_SC_AIO_LISTIO_MAX': '23', - '_SC_AIO_MAX': '24', - '_SC_AIO_PRIO_DELTA_MAX': '25', - '_SC_ARG_MAX': '0', - '_SC_ASYNCHRONOUS_IO': '12', - '_SC_ATEXIT_MAX': '87', - '_SC_BARRIERS': '133', - '_SC_BC_BASE_MAX': '36', - '_SC_BC_DIM_MAX': '37', - '_SC_BC_SCALE_MAX': '38', - '_SC_BC_STRING_MAX': '39', - '_SC_CHILD_MAX': '1', - '_SC_CLK_TCK': '2', - '_SC_CLOCK_SELECTION': '137', - '_SC_COLL_WEIGHTS_MAX': '40', - '_SC_CPUTIME': '138', - '_SC_DELAYTIMER_MAX': '26', - '_SC_EXPR_NEST_MAX': '42', - '_SC_FSYNC': '15', - '_SC_GETGR_R_SIZE_MAX': '69', - '_SC_GETPW_R_SIZE_MAX': '70', - '_SC_HOST_NAME_MAX': '180', - '_SC_IOV_MAX': '60', - '_SC_IPV6': '235', - '_SC_JOB_CONTROL': '7', - '_SC_LINE_MAX': '43', - '_SC_LOGIN_NAME_MAX': '71', - '_SC_MAPPED_FILES': '16', - '_SC_MEMLOCK': '17', - '_SC_MEMLOCK_RANGE': '18', - '_SC_MEMORY_PROTECTION': '19', - '_SC_MESSAGE_PASSING': '20', - '_SC_MONOTONIC_CLOCK': '149', - '_SC_MQ_OPEN_MAX': '27', - '_SC_MQ_PRIO_MAX': '28', - '_SC_NGROUPS_MAX': '3', - '_SC_NPROCESSORS_ONLN': '84', - '_SC_OPEN_MAX': '4', - '_SC_PAGE_SIZE': '30', - '_SC_PRIORITIZED_IO': '13', - '_SC_PRIORITY_SCHEDULING': '10', - '_SC_RAW_SOCKETS': '236', - '_SC_READER_WRITER_LOCKS': '153', - '_SC_REALTIME_SIGNALS': '9', - '_SC_REGEXP': '155', - '_SC_RE_DUP_MAX': '44', - '_SC_RTSIG_MAX': '31', - '_SC_SAVED_IDS': '8', - '_SC_SEMAPHORES': '21', - '_SC_SEM_NSEMS_MAX': '32', - '_SC_SEM_VALUE_MAX': '33', - '_SC_SHARED_MEMORY_OBJECTS': '22', - '_SC_SHELL': '157', - '_SC_SIGQUEUE_MAX': '34', - '_SC_SPAWN': '159', - '_SC_SPIN_LOCKS': '154', - '_SC_SPORADIC_SERVER': '160', - '_SC_STREAM_MAX': '5', - '_SC_SYMLOOP_MAX': '173', - '_SC_SYNCHRONIZED_IO': '14', - '_SC_THREADS': '67', - '_SC_THREAD_ATTR_STACKADDR': '77', - '_SC_THREAD_ATTR_STACKSIZE': '78', - '_SC_THREAD_CPUTIME': '139', - '_SC_THREAD_DESTRUCTOR_ITERATIONS': '73', - '_SC_THREAD_KEYS_MAX': '74', - '_SC_THREAD_PRIORITY_SCHEDULING': '79', - '_SC_THREAD_PRIO_INHERIT': '80', - '_SC_THREAD_PRIO_PROTECT': '81', - '_SC_THREAD_PROCESS_SHARED': '82', - '_SC_THREAD_SAFE_FUNCTIONS': '68', - '_SC_THREAD_SPORADIC_SERVER': '161', - '_SC_THREAD_STACK_MIN': '75', - '_SC_THREAD_THREADS_MAX': '76', - '_SC_TIMEOUTS': '164', - '_SC_TIMERS': '11', - '_SC_TIMER_MAX': '35', - '_SC_TRACE': '181', - '_SC_TRACE_EVENT_FILTER': '182', - '_SC_TRACE_EVENT_NAME_MAX': '242', - '_SC_TRACE_INHERIT': '183', - '_SC_TRACE_LOG': '184', - '_SC_TRACE_NAME_MAX': '243', - '_SC_TRACE_SYS_MAX': '244', - '_SC_TRACE_USER_EVENT_MAX': '245', - '_SC_TTY_NAME_MAX': '72', - '_SC_TYPED_MEMORY_OBJECTS': '165', - '_SC_TZNAME_MAX': '6', - '_SC_V6_ILP32_OFF32': '176', - '_SC_V6_ILP32_OFFBIG': '177', - '_SC_V6_LP64_OFF64': '178', - '_SC_V6_LPBIG_OFFBIG': '179', - '_SC_VERSION': '29', - '_SC_XBS5_ILP32_OFF32': '125', - '_SC_XBS5_ILP32_OFFBIG': '126', - '_SC_XBS5_LP64_OFF64': '127', - '_SC_XBS5_LPBIG_OFFBIG': '128', - '_SC_XOPEN_CRYPT': '92', - '_SC_XOPEN_ENH_I18N': '93', - '_SC_XOPEN_LEGACY': '129', - '_SC_XOPEN_REALTIME': '130', - '_SC_XOPEN_REALTIME_THREADS': '131', - '_SC_XOPEN_SHM': '94', - '_SC_XOPEN_STREAMS': '246', - '_SC_XOPEN_UNIX': '91', - '_SC_XOPEN_VERSION': '89' -}; +// The list of defines was moved into struct_info.json in the same directory. +// That file is automatically parsed by tools/gen_struct_info.py. +// If you modify the headers, just clear your cache and emscripten libc should see +// the new values. +// NOTE: Right now this value is ignored. +// TODO: See compiler.js (Should this var be deprecated?) +var C_DEFINES = {}; diff --git a/src/struct_info.json b/src/struct_info.json index 5b969603c7705..2b095a8c5b024 100644 --- a/src/struct_info.json +++ b/src/struct_info.json @@ -1,4 +1,7 @@ [ + // =========================================== + // libc + // =========================================== { "file": "libc/dirent.h", "defines": [], @@ -818,5 +821,193 @@ "MAP_PRIVATE" ], "structs": {} + }, + + // =========================================== + // SDL + // =========================================== + { + "file": "SDL/SDL_rect.h", + "defines": [], + "structs": { + "SDL_Rect": [ + "x", + "y", + "w", + "h" + ] + } + }, + { + "file": "SDL/SDL_keyboard.h", + "defines": [], + "structs": { + "SDL_Keysym": [ + "scancode", + "sym", + "mod", + "unicode" + ] + } + }, + { + "file": "SDL/SDL_pixels.h", + "defines": [], + "structs": { + "SDL_Palette": [ + "ncolors", + "colors", + "version", + "refcount" + ], + "SDL_PixelFormat": [ + "format", + "palette", + "BitsPerPixel", + "BytesPerPixel", + "padding", + "Rmask", + "Gmask", + "Bmask", + "Amask", + "Rloss", + "Gloss", + "Bloss", + "Aloss", + "Rshift", + "Gshift", + "Bshift", + "Ashift", + "refcount", + "next" + ], + "SDL_Color": [ + "r", + "g", + "b", + "unused" + ] + } + }, + { + "file": "SDL/SDL_events.h", + "defines": [], + "structs": { + "SDL_KeyboardEvent": [ + "type", + "windowID", + "state", + "repeat", + "padding2", + "padding3", + "keysym" + ], + "SDL_TextInputEvent": [ + "type", + "windowID", + "text" + ], + "SDL_MouseMotionEvent": [ + "type", + "windowID", + "state", + "padding1", + "padding2", + "padding3", + "x", + "y", + "xrel", + "yrel" + ], + "SDL_MouseButtonEvent": [ + "type", + "windowID", + "button", + "state", + "padding1", + "padding2", + "x", + "y" + ], + "SDL_ResizeEvent": [ + "type", + "w", + "h" + ] + } + }, + { + "file": "SDL_audio.h", + "defines": [ + "SDL_AUDIO_MASK_BITSIZE", + "SDL_AUDIO_MASK_DATATYPE", + "SDL_AUDIO_MASK_ENDIAN", + "SDL_AUDIO_MASK_SIGNED", + "AUDIO_U8", + "AUDIO_S8", + "AUDIO_U16LSB", + "AUDIO_S16LSB", + "AUDIO_U16MSB", + "AUDIO_S16MSB", + "AUDIO_U16", + "AUDIO_S16", + "AUDIO_S32LSB", + "AUDIO_S32MSB", + "AUDIO_S32", + "AUDIO_F32LSB", + "AUDIO_F32MSB", + "AUDIO_F32", + "AUDIO_U16SYS", + "AUDIO_S16SYS", + "AUDIO_S32SYS", + "AUDIO_F32SYS", + "SDL_AUDIO_ALLOW_FREQUENCY_CHANGE", + "SDL_AUDIO_ALLOW_FORMAT_CHANGE", + "SDL_AUDIO_ALLOW_CHANNELS_CHANGE", + "SDL_AUDIO_ALLOW_ANY_CHANGE", + "SDL_MIX_MAXVOLUME" + ], + "structs": { + "SDL_AudioCVT": [ + "needed", + "src_format", + "dst_format", + "rate_incr", + "buf", + "len", + "len_cvt", + "len_mult", + "len_ratio", + "filters", + "filter_index" + ], + "SDL_AudioSpec": [ + "freq", + "format", + "channels", + "silence", + "samples", + "padding", + "size", + "callback", + "userdata" + ] + } + }, + { + "file": "SDL_version.h", + "defines": [ + "SDL_MAJOR_VERSION", + "SDL_MINOR_VERSION", + "SDL_PATCHLEVEL", + "SDL_COMPILEDVERSION" + ], + "structs": { + "SDL_version": [ + "major", + "minor", + "patch" + ] + } } ] diff --git a/tools/gen_struct_info.py b/tools/gen_struct_info.py index 203a18ec2fb92..ccc4aee66c6ae 100644 --- a/tools/gen_struct_info.py +++ b/tools/gen_struct_info.py @@ -226,7 +226,7 @@ def parse_header(path, cpp_opts): walker.structs = resolve_delayed(walker.structs) with open(path, 'r') as stream: - defines = re.findall(r'(?:^|\n)#define\s+([A-Z|_]+)\s.*', stream.read()) + defines = re.findall(r'(?:^|\n)\s*#define\s+([A-Z|_|0-9]+)\s.*', stream.read()) return { 'file': path, diff --git a/tools/shared.py b/tools/shared.py index 76802eaada56d..554813ee635f2 100644 --- a/tools/shared.py +++ b/tools/shared.py @@ -1452,7 +1452,7 @@ def ensure_struct_info(info_path): Cache.ensure() import gen_struct_info - gen_struct_info.main(['-o', info_path, path_from_root('src/struct_info.json')]) + gen_struct_info.main(['-qo', info_path, path_from_root('src/struct_info.json')]) @staticmethod def preprocess(infile, outfile): From 7f4801a3b381f313818b5deecdb428e0269f0224 Mon Sep 17 00:00:00 2001 From: ngld Date: Tue, 17 Sep 2013 13:07:24 +0200 Subject: [PATCH 004/165] Implemented dprintf. (Fixes #1250) --- src/library.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/library.js b/src/library.js index aac5a9dacce4f..aac8c4f0ffb4c 100644 --- a/src/library.js +++ b/src/library.js @@ -2829,6 +2829,13 @@ LibraryManager.library = { asprintf: function(s, format, varargs) { return _sprintf(-s, format, varargs); }, + dprintf__deps: ['_formatString', 'write'], + dprintf: function(fd, format, varargs) { + var result = __formatString(format, varargs); + var stack = Runtime.stackSave(); + var ret = _write(fd, allocate(result, 'i8', ALLOC_STACK), result.length); + Runtime.stackRestore(stack); + }, #if TARGET_X86 // va_arg is just like our varargs @@ -2837,6 +2844,7 @@ LibraryManager.library = { vprintf: 'printf', vsprintf: 'sprintf', vasprintf: 'asprintf', + vdprintf: 'vdprintf', vscanf: 'scanf', vfscanf: 'fscanf', vsscanf: 'sscanf', @@ -2864,6 +2872,10 @@ LibraryManager.library = { vasprintf: function(s, format, va_arg) { return _asprintf(s, format, {{{ makeGetValue('va_arg', 0, '*') }}}); }, + vdprintf__deps: ['dprintf'], + vdprintf: function (fd, format, va_arg) { + return _dprintf(fd, format, {{{ makeGetValue('va_arg', 0, '*') }}}); + }, vscanf__deps: ['scanf'], vscanf: function(format, va_arg) { return _scanf(format, {{{ makeGetValue('va_arg', 0, '*') }}}); From 21efbaf73322c17a62ef28ea0df21515c67c5e2a Mon Sep 17 00:00:00 2001 From: ngld Date: Tue, 17 Sep 2013 21:12:02 +0200 Subject: [PATCH 005/165] Fix #1166: Correct the amount of allocated memory for non-ascii strings in ccallFunc(). --- src/preamble.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/preamble.js b/src/preamble.js index 02935f8f56f79..eb52297596236 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -299,11 +299,10 @@ function ccallFunc(func, returnType, argTypes, args) { function toC(value, type) { if (type == 'string') { if (value === null || value === undefined || value === 0) return 0; // null string - if (!stack) stack = Runtime.stackSave(); - var ret = Runtime.stackAlloc(value.length+1); - writeStringToMemory(value, ret); - return ret; - } else if (type == 'array') { + value = intArrayFromString(value); + type = 'array'; + } + if (type == 'array') { if (!stack) stack = Runtime.stackSave(); var ret = Runtime.stackAlloc(value.length); writeArrayToMemory(value, ret); From f19bb6022d09a207d5948e5a417309cc638ab74c Mon Sep 17 00:00:00 2001 From: ngld Date: Thu, 19 Sep 2013 13:11:20 +0200 Subject: [PATCH 006/165] Correct typo. --- src/library.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/library.js b/src/library.js index aac8c4f0ffb4c..4508d315e3f86 100644 --- a/src/library.js +++ b/src/library.js @@ -2844,7 +2844,7 @@ LibraryManager.library = { vprintf: 'printf', vsprintf: 'sprintf', vasprintf: 'asprintf', - vdprintf: 'vdprintf', + vdprintf: 'dprintf', vscanf: 'scanf', vfscanf: 'fscanf', vsscanf: 'sscanf', From e4678bed92f20ea0b5cd6fa2467cc2b0444511e0 Mon Sep 17 00:00:00 2001 From: Ranger Harke Date: Thu, 19 Sep 2013 16:03:15 -0400 Subject: [PATCH 007/165] Fix bug with zero-padded negative integers The zero padding was before the sign. It should be after. --- src/library.js | 6 ++++++ tests/printf/output.txt | 7 ++++--- tests/printf/output_i64_1.txt | 7 ++++--- tests/printf/test.c | 7 ++++--- 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/library.js b/src/library.js index 5c2c858db05db..0aaef0b22ee4a 100644 --- a/src/library.js +++ b/src/library.js @@ -2166,6 +2166,12 @@ LibraryManager.library = { } } + // Move sign to prefix so we zero-pad after the sign + if (argText.charAt(0) == '-') { + prefix = '-' + prefix; + argText = argText.substr(1); + } + // Add padding. while (prefix.length + argText.length < width) { if (flagLeftAlign) { diff --git a/tests/printf/output.txt b/tests/printf/output.txt index 19a6c1c2b2f24..0f59d9fc760a2 100644 --- a/tests/printf/output.txt +++ b/tests/printf/output.txt @@ -3,10 +3,11 @@ n=7 Characters: a A Decimals: 1977 650000 12 4 -Preceding with blanks: 1977 -Preceding with zeros: 0000001977 +Preceding with blanks: 1977 -1977 +Preceding with zeros: 0000001977 -000001977 Some different radixes: 100 64 144 0x64 0144 -floats: 3.14 +3e+00 3.141600E+00 +floats: 3.14 +3e+00 3.141600E+00 00003.14 +negative floats: -3.14 -3e+00 -3.141600E+00 -0003.14 Width trick: 10 A string % Null string: (null) diff --git a/tests/printf/output_i64_1.txt b/tests/printf/output_i64_1.txt index 775f3f8d01f6a..ca03386fe34f6 100644 --- a/tests/printf/output_i64_1.txt +++ b/tests/printf/output_i64_1.txt @@ -3,10 +3,11 @@ n=7 Characters: a A Decimals: 1977 650000 12 4 -Preceding with blanks: 1977 -Preceding with zeros: 0000001977 +Preceding with blanks: 1977 -1977 +Preceding with zeros: 0000001977 -000001977 Some different radixes: 100 64 144 0x64 0144 -floats: 3.14 +3e+00 3.141600E+00 +floats: 3.14 +3e+00 3.141600E+00 00003.14 +negative floats: -3.14 -3e+00 -3.141600E+00 -0003.14 Width trick: 10 A string % Null string: (null) diff --git a/tests/printf/test.c b/tests/printf/test.c index d05ba0965130b..c5f159f126d8d 100644 --- a/tests/printf/test.c +++ b/tests/printf/test.c @@ -8,10 +8,11 @@ int main() { printf("\n"); printf("Characters: %c %c\n", 'a', 65); printf("Decimals: %d %ld %lld %d\n", 1977, 650000L, 12LL, 4); - printf("Preceding with blanks: %10d\n", 1977); - printf("Preceding with zeros: %010d\n", 1977); + printf("Preceding with blanks: %10d %10d\n", 1977, -1977); + printf("Preceding with zeros: %010d %010d\n", 1977, -1977); printf("Some different radixes: %d %x %o %#x %#o\n", 100, 100, 100, 100, 100); - printf("floats: %4.2f %+.0e %E\n", 3.1416, 3.1416, 3.1416); + printf("floats: %4.2f %+.0e %E %08.2f\n", 3.1416, 3.1416, 3.1416, 3.1416); + printf("negative floats: %4.2f %+.0e %E %08.2f\n", -3.1416, -3.1416, -3.1416, -3.1416); printf("Width trick: %*d\n", 5, 10); printf("%s %%\n", "A string"); printf("Null string: %7s\n", NULL); From b72b6d897250cc7624b66832f720ff3bed6823a6 Mon Sep 17 00:00:00 2001 From: Ranger Harke Date: Thu, 19 Sep 2013 17:09:10 -0400 Subject: [PATCH 008/165] Fix bug with forced display of sign on negative integers The negative sign was displayed twice. --- src/library.js | 8 ++------ tests/printf/output.txt | 1 + tests/printf/output_i64_1.txt | 1 + tests/printf/test.c | 1 + 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/library.js b/src/library.js index 0aaef0b22ee4a..995fa2ab162f7 100644 --- a/src/library.js +++ b/src/library.js @@ -2158,12 +2158,8 @@ LibraryManager.library = { } // Add sign if needed - if (flagAlwaysSigned) { - if (currArg < 0) { - prefix = '-' + prefix; - } else { - prefix = '+' + prefix; - } + if (flagAlwaysSigned && currArg >= 0) { + prefix = '+' + prefix; } // Move sign to prefix so we zero-pad after the sign diff --git a/tests/printf/output.txt b/tests/printf/output.txt index 0f59d9fc760a2..7ca4d88c2b6ab 100644 --- a/tests/printf/output.txt +++ b/tests/printf/output.txt @@ -5,6 +5,7 @@ Characters: a A Decimals: 1977 650000 12 4 Preceding with blanks: 1977 -1977 Preceding with zeros: 0000001977 -000001977 +Force sign: +1977 -1977 +1977 -1977 Some different radixes: 100 64 144 0x64 0144 floats: 3.14 +3e+00 3.141600E+00 00003.14 negative floats: -3.14 -3e+00 -3.141600E+00 -0003.14 diff --git a/tests/printf/output_i64_1.txt b/tests/printf/output_i64_1.txt index ca03386fe34f6..9cd8ed98afd5e 100644 --- a/tests/printf/output_i64_1.txt +++ b/tests/printf/output_i64_1.txt @@ -5,6 +5,7 @@ Characters: a A Decimals: 1977 650000 12 4 Preceding with blanks: 1977 -1977 Preceding with zeros: 0000001977 -000001977 +Force sign: +1977 -1977 +1977 -1977 Some different radixes: 100 64 144 0x64 0144 floats: 3.14 +3e+00 3.141600E+00 00003.14 negative floats: -3.14 -3e+00 -3.141600E+00 -0003.14 diff --git a/tests/printf/test.c b/tests/printf/test.c index c5f159f126d8d..b01a99db527a9 100644 --- a/tests/printf/test.c +++ b/tests/printf/test.c @@ -10,6 +10,7 @@ int main() { printf("Decimals: %d %ld %lld %d\n", 1977, 650000L, 12LL, 4); printf("Preceding with blanks: %10d %10d\n", 1977, -1977); printf("Preceding with zeros: %010d %010d\n", 1977, -1977); + printf("Force sign: %+d %+d %+6d %+6d\n", 1977, -1977, 1977, -1977); printf("Some different radixes: %d %x %o %#x %#o\n", 100, 100, 100, 100, 100); printf("floats: %4.2f %+.0e %E %08.2f\n", 3.1416, 3.1416, 3.1416, 3.1416); printf("negative floats: %4.2f %+.0e %E %08.2f\n", -3.1416, -3.1416, -3.1416, -3.1416); From 61c9d6ede1fe9a91ae501dc019d2e5f97803943a Mon Sep 17 00:00:00 2001 From: Ranger Harke Date: Thu, 19 Sep 2013 17:24:31 -0400 Subject: [PATCH 009/165] Implement missing 'space' formatting flag This flag causes space (padding) to be reserved for the sign even if the number is positive. It is basically the same as the 'plus' flag except that a space is displayed instead of a plus sign. The 'plus' flag takes precedence. --- src/library.js | 20 ++++++++++++++++---- tests/printf/output.txt | 3 +++ tests/printf/output_i64_1.txt | 3 +++ tests/printf/test.c | 3 +++ 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/library.js b/src/library.js index 995fa2ab162f7..2faa40d73d78a 100644 --- a/src/library.js +++ b/src/library.js @@ -1974,6 +1974,7 @@ LibraryManager.library = { var flagLeftAlign = false; var flagAlternative = false; var flagZeroPad = false; + var flagPadSign = false; flagsLoop: while (1) { switch (next) { case {{{ charCode('+') }}}: @@ -1992,6 +1993,9 @@ LibraryManager.library = { flagZeroPad = true; break; } + case {{{ charCode(' ') }}}: + flagPadSign = true; + break; default: break flagsLoop; } @@ -2158,8 +2162,12 @@ LibraryManager.library = { } // Add sign if needed - if (flagAlwaysSigned && currArg >= 0) { - prefix = '+' + prefix; + if (currArg >= 0) { + if (flagAlwaysSigned) { + prefix = '+' + prefix; + } else if (flagPadSign) { + prefix = ' ' + prefix; + } } // Move sign to prefix so we zero-pad after the sign @@ -2250,8 +2258,12 @@ LibraryManager.library = { if (next == {{{ charCode('E') }}}) argText = argText.toUpperCase(); // Add sign. - if (flagAlwaysSigned && currArg >= 0) { - argText = '+' + argText; + if (currArg >= 0) { + if (flagAlwaysSigned) { + argText = '+' + argText; + } else if (flagPadSign) { + argText = ' ' + argText; + } } } diff --git a/tests/printf/output.txt b/tests/printf/output.txt index 7ca4d88c2b6ab..0155f0da7b288 100644 --- a/tests/printf/output.txt +++ b/tests/printf/output.txt @@ -6,9 +6,12 @@ Decimals: 1977 650000 12 4 Preceding with blanks: 1977 -1977 Preceding with zeros: 0000001977 -000001977 Force sign: +1977 -1977 +1977 -1977 +Force sign or space: 1977 -1977 1977 -1977 +Sign overrides space: +1977 -1977 +1977 -1977 Some different radixes: 100 64 144 0x64 0144 floats: 3.14 +3e+00 3.141600E+00 00003.14 negative floats: -3.14 -3e+00 -3.141600E+00 -0003.14 +Force sign or space: 3.14 -3.14 3.14 -3.14 Width trick: 10 A string % Null string: (null) diff --git a/tests/printf/output_i64_1.txt b/tests/printf/output_i64_1.txt index 9cd8ed98afd5e..e38fb78f1881a 100644 --- a/tests/printf/output_i64_1.txt +++ b/tests/printf/output_i64_1.txt @@ -6,9 +6,12 @@ Decimals: 1977 650000 12 4 Preceding with blanks: 1977 -1977 Preceding with zeros: 0000001977 -000001977 Force sign: +1977 -1977 +1977 -1977 +Force sign or space: 1977 -1977 1977 -1977 +Sign overrides space: +1977 -1977 +1977 -1977 Some different radixes: 100 64 144 0x64 0144 floats: 3.14 +3e+00 3.141600E+00 00003.14 negative floats: -3.14 -3e+00 -3.141600E+00 -0003.14 +Force sign or space: 3.14 -3.14 3.14 -3.14 Width trick: 10 A string % Null string: (null) diff --git a/tests/printf/test.c b/tests/printf/test.c index b01a99db527a9..1c8ad9f7691c2 100644 --- a/tests/printf/test.c +++ b/tests/printf/test.c @@ -11,9 +11,12 @@ int main() { printf("Preceding with blanks: %10d %10d\n", 1977, -1977); printf("Preceding with zeros: %010d %010d\n", 1977, -1977); printf("Force sign: %+d %+d %+6d %+6d\n", 1977, -1977, 1977, -1977); + printf("Force sign or space: % d % d % 6d % 6d\n", 1977, -1977, 1977, -1977); + printf("Sign overrides space: % +d % +d % +6d % +6d\n", 1977, -1977, 1977, -1977); printf("Some different radixes: %d %x %o %#x %#o\n", 100, 100, 100, 100, 100); printf("floats: %4.2f %+.0e %E %08.2f\n", 3.1416, 3.1416, 3.1416, 3.1416); printf("negative floats: %4.2f %+.0e %E %08.2f\n", -3.1416, -3.1416, -3.1416, -3.1416); + printf("Force sign or space: % .2f % .2f % 6.2f % 6.2f\n", 3.1416, -3.1416, 3.1416, -3.1416); printf("Width trick: %*d\n", 5, 10); printf("%s %%\n", "A string"); printf("Null string: %7s\n", NULL); From 293c7b4860c3ae33b07011695adc9a6b8ff5ebdb Mon Sep 17 00:00:00 2001 From: Bruce Mitchener Date: Fri, 20 Sep 2013 21:19:28 +0700 Subject: [PATCH 010/165] Fix typo in URL. --- src/parseTools.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/parseTools.js b/src/parseTools.js index 90c5acab265a8..80cccecb313aa 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -1758,7 +1758,7 @@ function checkBitcast(item) { } else { warnOnce('Casting a function pointer type to a potentially incompatible one (use -s VERBOSE=1 to see more)'); } - warnOnce('See https://github.com/kripken/emscripten/wiki/CodeGuidlinesAndLimitations#function-pointer-issues for more information on dangerous function pointer casts'); + warnOnce('See https://github.com/kripken/emscripten/wiki/CodeGuidelinesAndLimitations#function-pointer-issues for more information on dangerous function pointer casts'); if (ASM_JS) warnOnce('Incompatible function pointer casts are very dangerous with ASM_JS=1, you should investigate and correct these'); } if (oldCount != newCount && oldCount && newCount) showWarning(); From 43ed0e83b8f387eb4ca2eb8e491a4c810d74e56b Mon Sep 17 00:00:00 2001 From: ngld Date: Sun, 22 Sep 2013 03:00:39 +0200 Subject: [PATCH 011/165] Remove "-U__GNUC__" flag to avoid incorrect measurements. --- tools/gen_struct_info.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/gen_struct_info.py b/tools/gen_struct_info.py index ccc4aee66c6ae..6c4797474f51d 100644 --- a/tools/gen_struct_info.py +++ b/tools/gen_struct_info.py @@ -37,7 +37,7 @@ 'defines': [ 'DEFINE_1', 'DEFINE_2', - ['f', 'FLOAT_DEFINE'], + ['li', 'FLOAT_DEFINE'], 'DEFINE_3', ... ] @@ -461,7 +461,7 @@ def main(args): QUIET = args.quiet # Avoid parsing problems due to gcc specifc syntax. - cpp_opts = ['-U__GNUC__', '-D_GNU_SOURCE'] + shared.COMPILER_OPTS + cpp_opts = ['-D_GNU_SOURCE'] + shared.COMPILER_OPTS # Add the user options to the list as well. for path in args.includes: @@ -506,4 +506,4 @@ def main(args): output_json(struct_info, not args.pretty_print, args.output) if __name__ == '__main__': - main(sys.argv[1:]) \ No newline at end of file + main(sys.argv[1:]) From d3e5647bd49d2a4861e10531c76a61febe24e848 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Mon, 23 Sep 2013 14:33:51 +0300 Subject: [PATCH 012/165] Make input file parsing in 'emcc' tool stricter. Don't silently fail if a file is missing or is a bitcode file if an archive file was expected, but issue an error and abort. Related to #1648. --- emcc | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/emcc b/emcc index 9a687bd8cd36b..60eaa388c57ba 100755 --- a/emcc +++ b/emcc @@ -976,9 +976,13 @@ try: if (os.path.islink(arg) and os.path.realpath(arg).endswith(SOURCE_SUFFIXES + BITCODE_SUFFIXES + DYNAMICLIB_SUFFIXES + ASSEMBLY_SUFFIXES)): arg = os.path.realpath(arg) - if not arg.startswith('-') and (arg.endswith(SOURCE_SUFFIXES + BITCODE_SUFFIXES + DYNAMICLIB_SUFFIXES + ASSEMBLY_SUFFIXES) or shared.Building.is_ar(arg)): # we already removed -o , so all these should be inputs - newargs[i] = '' - if os.path.exists(arg): + if not arg.startswith('-'): + if not os.path.exists(arg): + logging.error(arg + ': No such file or directory') + exit(1) + + if arg.endswith(SOURCE_SUFFIXES + BITCODE_SUFFIXES + DYNAMICLIB_SUFFIXES + ASSEMBLY_SUFFIXES) or shared.Building.is_ar(arg): # we already removed -o , so all these should be inputs + newargs[i] = '' if arg.endswith(SOURCE_SUFFIXES): input_files.append(arg) has_source_inputs = True @@ -998,8 +1002,15 @@ try: newargs[i] = '' else: logging.warning(arg + ' is not valid LLVM bitcode') + elif arg.endswith(STATICLIB_SUFFIXES): + if not shared.Building.is_ar(arg): + if shared.Building.is_bitcode(arg): + logging.error(arg + ': File has a suffix of a static library ' + str(STATICLIB_SUFFIXES) + ', but instead is an LLVM bitcode file! When linking LLVM bitcode files, use one of the suffixes ' + str(BITCODE_SUFFIXES)) + else: + logging.error(arg + ': Unknown format, not a static library!') + exit(1) else: - logging.error(arg + ': No such file or directory') + logging.error(arg + ": Input file has an unknown suffix, don't know what to do with it!") exit(1) elif arg.startswith('-L'): lib_dirs.append(arg[2:]) From 04a0b8500d902a52d321648ecf99160ad01d40f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Mon, 23 Sep 2013 14:57:57 +0300 Subject: [PATCH 013/165] Fix emcc to properly treat input filenames with Unix-style version information at the end, e.g. 'libz.so.1.2.8'. Do not assume in the source -> LLVM bitcode compilation pass that all untested file suffixes would be assembly files. Related to #1648. --- emcc | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/emcc b/emcc index 60eaa388c57ba..5008a0023460e 100755 --- a/emcc +++ b/emcc @@ -717,6 +717,13 @@ else: def in_temp(name): return os.path.join(temp_dir, os.path.basename(name)) +# Parses the essential suffix of a filename, discarding Unix-style version numbers in the name. For example for 'libz.so.1.2.8' returns '.so' +def filename_type_suffix(filename): + for i in reversed(filename.split('.')[1:]): + if not i.isdigit(): + return '.' + i + return '' + try: call = CXX if use_cxx else CC @@ -981,16 +988,17 @@ try: logging.error(arg + ': No such file or directory') exit(1) - if arg.endswith(SOURCE_SUFFIXES + BITCODE_SUFFIXES + DYNAMICLIB_SUFFIXES + ASSEMBLY_SUFFIXES) or shared.Building.is_ar(arg): # we already removed -o , so all these should be inputs + arg_suffix = filename_type_suffix(arg) + if arg_suffix.endswith(SOURCE_SUFFIXES + BITCODE_SUFFIXES + DYNAMICLIB_SUFFIXES + ASSEMBLY_SUFFIXES) or shared.Building.is_ar(arg): # we already removed -o , so all these should be inputs newargs[i] = '' - if arg.endswith(SOURCE_SUFFIXES): + if arg_suffix.endswith(SOURCE_SUFFIXES): input_files.append(arg) has_source_inputs = True else: # this should be bitcode, make sure it is valid - if arg.endswith(ASSEMBLY_SUFFIXES) or shared.Building.is_bitcode(arg): + if arg_suffix.endswith(ASSEMBLY_SUFFIXES) or shared.Building.is_bitcode(arg): input_files.append(arg) - elif arg.endswith(STATICLIB_SUFFIXES + DYNAMICLIB_SUFFIXES): + elif arg_suffix.endswith(STATICLIB_SUFFIXES + DYNAMICLIB_SUFFIXES): # if it's not, and it's a library, just add it to libs to find later l = unsuffixed_basename(arg) for prefix in LIB_PREFIXES: @@ -1002,7 +1010,7 @@ try: newargs[i] = '' else: logging.warning(arg + ' is not valid LLVM bitcode') - elif arg.endswith(STATICLIB_SUFFIXES): + elif arg_suffix.endswith(STATICLIB_SUFFIXES): if not shared.Building.is_ar(arg): if shared.Building.is_bitcode(arg): logging.error(arg + ': File has a suffix of a static library ' + str(STATICLIB_SUFFIXES) + ', but instead is an LLVM bitcode file! When linking LLVM bitcode files, use one of the suffixes ' + str(BITCODE_SUFFIXES)) @@ -1159,13 +1167,14 @@ try: # First, generate LLVM bitcode. For each input file, we get base.o with bitcode for input_file in input_files: - if input_file.endswith(SOURCE_SUFFIXES): + file_suffix = filename_type_suffix(input_file) + if file_suffix.endswith(SOURCE_SUFFIXES): logging.debug('compiling source file: ' + input_file) input_file = shared.Building.preprocess(input_file, in_temp(uniquename(input_file))) output_file = in_temp(unsuffixed(uniquename(input_file)) + '.o') temp_files.append(output_file) args = newargs + ['-emit-llvm', '-c', input_file, '-o', output_file] - if input_file.endswith(CXX_SUFFIXES): + if file_suffix.endswith(CXX_SUFFIXES): args += shared.EMSDK_CXX_OPTS logging.debug("running: " + call + ' ' + ' '.join(args)) execute([call] + args) # let compiler frontend print directly, so colors are saved (PIPE kills that) @@ -1173,17 +1182,17 @@ try: logging.error('compiler frontend failed to generate LLVM bitcode, halting') sys.exit(1) else: # bitcode - if input_file.endswith(BITCODE_SUFFIXES): + if file_suffix.endswith(BITCODE_SUFFIXES): logging.debug('copying bitcode file: ' + input_file) temp_file = in_temp(unsuffixed(uniquename(input_file)) + '.o') shutil.copyfile(input_file, temp_file) temp_files.append(temp_file) - elif input_file.endswith(DYNAMICLIB_SUFFIXES) or shared.Building.is_ar(input_file): + elif file_suffix.endswith(DYNAMICLIB_SUFFIXES) or shared.Building.is_ar(input_file): logging.debug('copying library file: ' + input_file) temp_file = in_temp(uniquename(input_file)) shutil.copyfile(input_file, temp_file) temp_files.append(temp_file) - else: #.ll + elif file_suffix.endswith(ASSEMBLY_SUFFIXES): if not LEAVE_INPUTS_RAW: # Note that by assembling the .ll file, then disassembling it later, we will # remove annotations which is a good thing for compilation time @@ -1191,6 +1200,9 @@ try: temp_file = in_temp(unsuffixed(uniquename(input_file)) + '.o') shared.Building.llvm_as(input_file, temp_file) temp_files.append(temp_file) + else: + logging.error(input_file + ': Unknown file suffix when compiling to LLVM bitcode!') + sys.exit(1) if not LEAVE_INPUTS_RAW: assert len(temp_files) == len(input_files) @@ -1198,7 +1210,8 @@ try: # Optimize source files if llvm_opts > 0: for i, input_file in enumerate(input_files): - if input_file.endswith(SOURCE_SUFFIXES): + file_suffix = filename_type_suffix(input_file) + if file_suffix.endswith(SOURCE_SUFFIXES): temp_file = temp_files[i] logging.debug('optimizing %s with -O%d' % (input_file, llvm_opts)) shared.Building.llvm_opt(temp_file, llvm_opts) From a507cd8807f1d62f654af3beab15b221252de542 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Mon, 23 Sep 2013 15:01:12 +0300 Subject: [PATCH 014/165] Fix Emscripten CMake toolchain to generate proper static library archive files with the AR tool instead of building LLVM bitcode files for archive files. Fixes #1648. --- cmake/Platform/Emscripten.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/Platform/Emscripten.cmake b/cmake/Platform/Emscripten.cmake index 73f2c8ada714e..7c8e83fa7b1ac 100644 --- a/cmake/Platform/Emscripten.cmake +++ b/cmake/Platform/Emscripten.cmake @@ -104,8 +104,8 @@ set(CMAKE_C_RESPONSE_FILE_LINK_FLAG "@") set(CMAKE_CXX_RESPONSE_FILE_LINK_FLAG "@") # Specify the program to use when building static libraries. Force Emscripten-related command line options to clang. -set(CMAKE_CXX_ARCHIVE_CREATE "${CMAKE_CXX_COMPILER} ${CMAKE_START_TEMP_FILE} -o -emit-llvm ${CMAKE_END_TEMP_FILE}") -set(CMAKE_C_ARCHIVE_CREATE "${CMAKE_C_COMPILER} ${CMAKE_START_TEMP_FILE} -o -emit-llvm ${CMAKE_END_TEMP_FILE}") +set(CMAKE_CXX_ARCHIVE_CREATE "${CMAKE_AR} rc ${CMAKE_START_TEMP_FILE} ${CMAKE_END_TEMP_FILE}") +set(CMAKE_C_ARCHIVE_CREATE "${CMAKE_AR} rc ${CMAKE_START_TEMP_FILE} ${CMAKE_END_TEMP_FILE}") # Set a global EMSCRIPTEN variable that can be used in client CMakeLists.txt to detect when building using Emscripten. # There seems to be some kind of bug with CMake, so you might need to define this manually on the command line with "-DEMSCRIPTEN=1". From 626cdae8b610fbb088c11aeab9a9c8d9b563c7e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Tue, 24 Sep 2013 12:02:56 +0300 Subject: [PATCH 015/165] Enable WEBGL_depth_texture on GL context init. WEBGL_depth_texture is an extension that adds support for 16-bit and 32-bit integer depth formats, as well as the packed d24s8 integer depth+stencil format. See http://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/ --- src/library_gl.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/library_gl.js b/src/library_gl.js index 16ea55313aea5..b6331e57d4aff 100644 --- a/src/library_gl.js +++ b/src/library_gl.js @@ -217,6 +217,23 @@ var LibraryGL = { throw 'Invalid format (' + format + ')'; } break; + case 0x1403 /* GL_UNSIGNED_SHORT */: + if (format == 0x1902 /* GL_DEPTH_COMPONENT */) { + sizePerPixel = 2; + } else { + throw 'Invalid format (' + format + ')'; + } + break; + case 0x1405 /* GL_UNSIGNED_INT */: + if (format == 0x1902 /* GL_DEPTH_COMPONENT */) { + sizePerPixel = 4; + } else { + throw 'Invalid format (' + format + ')'; + } + break; + case 0x84FA /* UNSIGNED_INT_24_8_WEBGL */: + sizePerPixel = 4; + break; case 0x8363 /* GL_UNSIGNED_SHORT_5_6_5 */: case 0x8033 /* GL_UNSIGNED_SHORT_4_4_4_4 */: case 0x8034 /* GL_UNSIGNED_SHORT_5_5_5_1 */: @@ -244,6 +261,8 @@ var LibraryGL = { pixels = {{{ makeHEAPView('U8', 'pixels', 'pixels+bytes') }}}; } else if (type == 0x1406 /* GL_FLOAT */) { pixels = {{{ makeHEAPView('F32', 'pixels', 'pixels+bytes') }}}; + } else if (type == 0x1405 /* GL_UNSIGNED_INT */ || type == 0x84FA /* UNSIGNED_INT_24_8_WEBGL */) { + pixels = {{{ makeHEAPView('U32', 'pixels', 'pixels+bytes') }}}; } else { pixels = {{{ makeHEAPView('U16', 'pixels', 'pixels+bytes') }}}; } @@ -334,6 +353,10 @@ var LibraryGL = { GL.elementIndexUintExt = Module.ctx.getExtension('OES_element_index_uint'); GL.standardDerivativesExt = Module.ctx.getExtension('OES_standard_derivatives'); + + GL.depthTextureExt = Module.ctx.getExtension("WEBGL_depth_texture") || + Module.ctx.getExtension("MOZ_WEBGL_depth_texture") || + Module.ctx.getExtension("WEBKIT_WEBGL_depth_texture"); } }, From f5a688b42f08f0ebeac2ecb3c7172d7c4f65a148 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Tue, 24 Sep 2013 21:48:16 +0300 Subject: [PATCH 016/165] Fix indentation in previous commit. --- src/library_gl.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/library_gl.js b/src/library_gl.js index b6331e57d4aff..32a2596e60241 100644 --- a/src/library_gl.js +++ b/src/library_gl.js @@ -221,14 +221,14 @@ var LibraryGL = { if (format == 0x1902 /* GL_DEPTH_COMPONENT */) { sizePerPixel = 2; } else { - throw 'Invalid format (' + format + ')'; + throw 'Invalid format (' + format + ')'; } break; case 0x1405 /* GL_UNSIGNED_INT */: if (format == 0x1902 /* GL_DEPTH_COMPONENT */) { sizePerPixel = 4; } else { - throw 'Invalid format (' + format + ')'; + throw 'Invalid format (' + format + ')'; } break; case 0x84FA /* UNSIGNED_INT_24_8_WEBGL */: From 604c53552bd172ad0703600350577437a8001ef1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Mon, 23 Sep 2013 18:26:06 +0300 Subject: [PATCH 017/165] Add more validation to the GL layer when GL_ASSERTIONS is enabled. This catches and reports situations where user code passes nonexisting or deleted GL objects to texture/program/shader/framebuffer/renderbuffer functions, and yells out explicitly that the user code is not behaving properly. --- src/library_gl.js | 89 +++++++++++++++++++++++++++++++++++++++++++++++ src/settings.js | 1 + 2 files changed, 90 insertions(+) diff --git a/src/library_gl.js b/src/library_gl.js index 16ea55313aea5..e6cb5f4753103 100644 --- a/src/library_gl.js +++ b/src/library_gl.js @@ -302,6 +302,18 @@ var LibraryGL = { }, #endif +#if GL_ASSERTIONS + validateGLObjectID: function(objectHandleArray, objectID, callerFunctionName, objectReadableType) { + if (objectID != 0) { + if (objectHandleArray[objectID] === null) { + console.error(callerFunctionName + ' called with an already deleted ' + objectReadableType + ' ID ' + objectID + '!'); + } else if (!objectHandleArray[objectID]) { + console.error(callerFunctionName + ' called with an invalid ' + objectReadableType + ' ID ' + objectID + '!'); + } + } + }, +#endif + initExtensions: function() { if (GL.initExtensions.done) return; GL.initExtensions.done = true; @@ -588,6 +600,9 @@ var LibraryGL = { glBindTexture__sig: 'vii', glBindTexture: function(target, texture) { +#if GL_ASSERTIONS + GL.validateGLObjectID(GL.textures, texture, 'glBindTexture', 'texture'); +#endif Module.ctx.bindTexture(target, texture ? GL.textures[texture] : null); }, @@ -710,6 +725,9 @@ var LibraryGL = { glBindRenderbuffer__sig: 'vii', glBindRenderbuffer: function(target, renderbuffer) { +#if GL_ASSERTIONS + GL.validateGLObjectID(GL.renderbuffers, renderbuffer, 'glBindRenderbuffer', 'renderbuffer'); +#endif Module.ctx.bindRenderbuffer(target, renderbuffer ? GL.renderbuffers[renderbuffer] : null); }, @@ -727,6 +745,9 @@ var LibraryGL = { glGetUniformfv__sig: 'viii', glGetUniformfv: function(program, location, params) { +#if GL_ASSERTIONS + GL.validateGLObjectID(GL.programs, program, 'glGetUniformfv', 'program'); +#endif var data = Module.ctx.getUniform(GL.programs[program], GL.uniforms[location]); if (typeof data == 'number') { {{{ makeSetValue('params', '0', 'data', 'float') }}}; @@ -739,6 +760,9 @@ var LibraryGL = { glGetUniformiv__sig: 'viii', glGetUniformiv: function(program, location, params) { +#if GL_ASSERTIONS + GL.validateGLObjectID(GL.programs, program, 'glGetUniformiv', 'program'); +#endif var data = Module.ctx.getUniform(GL.programs[program], GL.uniforms[location]); if (typeof data == 'number' || typeof data == 'boolean') { {{{ makeSetValue('params', '0', 'data', 'i32') }}}; @@ -751,6 +775,9 @@ var LibraryGL = { glGetUniformLocation__sig: 'iii', glGetUniformLocation: function(program, name) { +#if GL_ASSERTIONS + GL.validateGLObjectID(GL.programs, program, 'glGetUniformLocation', 'program'); +#endif name = Pointer_stringify(name); var ptable = GL.uniformTable[program]; if (!ptable) ptable = GL.uniformTable[program] = {}; @@ -810,6 +837,9 @@ var LibraryGL = { glGetActiveUniform__sig: 'viiiiiii', glGetActiveUniform: function(program, index, bufSize, length, size, type, name) { +#if GL_ASSERTIONS + GL.validateGLObjectID(GL.programs, program, 'glGetActiveUniform', 'program'); +#endif program = GL.programs[program]; var info = Module.ctx.getActiveUniform(program, index); @@ -1018,6 +1048,9 @@ var LibraryGL = { glBindBuffer__sig: 'vii', glBindBuffer: function(target, buffer) { +#if GL_ASSERTIONS + GL.validateGLObjectID(GL.buffers, buffer, 'glBindBuffer', 'buffer'); +#endif var bufferObj = buffer ? GL.buffers[buffer] : null; if (target == Module.ctx.ARRAY_BUFFER) { @@ -1062,6 +1095,9 @@ var LibraryGL = { glGetActiveAttrib__sig: 'viiiiiii', glGetActiveAttrib: function(program, index, bufSize, length, size, type, name) { +#if GL_ASSERTIONS + GL.validateGLObjectID(GL.programs, program, 'glGetActiveAttrib', 'program'); +#endif program = GL.programs[program]; var info = Module.ctx.getActiveAttrib(program, index); @@ -1094,6 +1130,9 @@ var LibraryGL = { glGetAttachedShaders__sig: 'viiii', glGetAttachedShaders: function(program, maxCount, count, shaders) { +#if GL_ASSERTIONS + GL.validateGLObjectID(GL.programs, program, 'glGetAttachedShaders', 'program'); +#endif var result = Module.ctx.getAttachedShaders(GL.programs[program]); var len = result.length; if (len > maxCount) { @@ -1109,12 +1148,18 @@ var LibraryGL = { glShaderSource__sig: 'viiii', glShaderSource: function(shader, count, string, length) { +#if GL_ASSERTIONS + GL.validateGLObjectID(GL.shaders, shader, 'glShaderSource', 'shader'); +#endif var source = GL.getSource(shader, count, string, length); Module.ctx.shaderSource(GL.shaders[shader], source); }, glGetShaderSource__sig: 'viiii', glGetShaderSource: function(shader, bufSize, length, source) { +#if GL_ASSERTIONS + GL.validateGLObjectID(GL.shaders, shader, 'glGetShaderSource', 'shader'); +#endif var result = Module.ctx.getShaderSource(GL.shaders[shader]); result = result.slice(0, Math.max(0, bufSize - 1)); writeStringToMemory(result, source); @@ -1125,11 +1170,17 @@ var LibraryGL = { glCompileShader__sig: 'vi', glCompileShader: function(shader) { +#if GL_ASSERTIONS + GL.validateGLObjectID(GL.shaders, shader, 'glCompileShader', 'shader'); +#endif Module.ctx.compileShader(GL.shaders[shader]); }, glGetShaderInfoLog__sig: 'viiii', glGetShaderInfoLog: function(shader, maxLength, length, infoLog) { +#if GL_ASSERTIONS + GL.validateGLObjectID(GL.shaders, shader, 'glGetShaderInfoLog', 'shader'); +#endif var log = Module.ctx.getShaderInfoLog(GL.shaders[shader]); // Work around a bug in Chromium which causes getShaderInfoLog to return null if (!log) { @@ -1144,6 +1195,9 @@ var LibraryGL = { glGetShaderiv__sig: 'viii', glGetShaderiv : function(shader, pname, p) { +#if GL_ASSERTIONS + GL.validateGLObjectID(GL.shaders, shader, 'glGetShaderiv', 'shader'); +#endif if (pname == 0x8B84) { // GL_INFO_LOG_LENGTH {{{ makeSetValue('p', '0', 'Module.ctx.getShaderInfoLog(GL.shaders[shader]).length + 1', 'i32') }}}; } else { @@ -1153,6 +1207,9 @@ var LibraryGL = { glGetProgramiv__sig: 'viii', glGetProgramiv : function(program, pname, p) { +#if GL_ASSERTIONS + GL.validateGLObjectID(GL.programs, program, 'glGetProgramiv', 'program'); +#endif if (pname == 0x8B84) { // GL_INFO_LOG_LENGTH {{{ makeSetValue('p', '0', 'Module.ctx.getProgramInfoLog(GL.programs[program]).length + 1', 'i32') }}}; } else { @@ -1187,12 +1244,20 @@ var LibraryGL = { glAttachShader__sig: 'vii', glAttachShader: function(program, shader) { +#if GL_ASSERTIONS + GL.validateGLObjectID(GL.programs, program, 'glAttachShader', 'program'); + GL.validateGLObjectID(GL.shaders, shader, 'glAttachShader', 'shader'); +#endif Module.ctx.attachShader(GL.programs[program], GL.shaders[shader]); }, glDetachShader__sig: 'vii', glDetachShader: function(program, shader) { +#if GL_ASSERTIONS + GL.validateGLObjectID(GL.programs, program, 'glDetachShader', 'program'); + GL.validateGLObjectID(GL.shaders, shader, 'glDetachShader', 'shader'); +#endif Module.ctx.detachShader(GL.programs[program], GL.shaders[shader]); }, @@ -1206,12 +1271,18 @@ var LibraryGL = { glLinkProgram__sig: 'vi', glLinkProgram: function(program) { +#if GL_ASSERTIONS + GL.validateGLObjectID(GL.programs, program, 'glLinkProgram', 'program'); +#endif Module.ctx.linkProgram(GL.programs[program]); GL.uniformTable[program] = {}; // uniforms no longer keep the same names after linking }, glGetProgramInfoLog__sig: 'viiii', glGetProgramInfoLog: function(program, maxLength, length, infoLog) { +#if GL_ASSERTIONS + GL.validateGLObjectID(GL.programs, program, 'glGetProgramInfoLog', 'program'); +#endif var log = Module.ctx.getProgramInfoLog(GL.programs[program]); // Work around a bug in Chromium which causes getProgramInfoLog to return null if (!log) { @@ -1226,11 +1297,17 @@ var LibraryGL = { glUseProgram__sig: 'vi', glUseProgram: function(program) { +#if GL_ASSERTIONS + GL.validateGLObjectID(GL.programs, program, 'glUseProgram', 'program'); +#endif Module.ctx.useProgram(program ? GL.programs[program] : null); }, glValidateProgram__sig: 'vi', glValidateProgram: function(program) { +#if GL_ASSERTIONS + GL.validateGLObjectID(GL.programs, program, 'glValidateProgram', 'program'); +#endif Module.ctx.validateProgram(GL.programs[program]); }, @@ -1243,12 +1320,18 @@ var LibraryGL = { glBindAttribLocation__sig: 'viii', glBindAttribLocation: function(program, index, name) { +#if GL_ASSERTIONS + GL.validateGLObjectID(GL.programs, program, 'glBindAttribLocation', 'program'); +#endif name = Pointer_stringify(name); Module.ctx.bindAttribLocation(GL.programs[program], index, name); }, glBindFramebuffer__sig: 'vii', glBindFramebuffer: function(target, framebuffer) { +#if GL_ASSERTIONS + GL.validateGLObjectID(GL.framebuffers, framebuffer, 'glBindFramebuffer', 'framebuffer'); +#endif Module.ctx.bindFramebuffer(target, framebuffer ? GL.framebuffers[framebuffer] : null); }, @@ -1276,12 +1359,18 @@ var LibraryGL = { glFramebufferRenderbuffer__sig: 'viiii', glFramebufferRenderbuffer: function(target, attachment, renderbuffertarget, renderbuffer) { +#if GL_ASSERTIONS + GL.validateGLObjectID(GL.renderbuffers, renderbuffer, 'glFramebufferRenderbuffer', 'renderbuffer'); +#endif Module.ctx.framebufferRenderbuffer(target, attachment, renderbuffertarget, GL.renderbuffers[renderbuffer]); }, glFramebufferTexture2D__sig: 'viiiii', glFramebufferTexture2D: function(target, attachment, textarget, texture, level) { +#if GL_ASSERTIONS + GL.validateGLObjectID(GL.textures, texture, 'glFramebufferTexture2D', 'texture'); +#endif Module.ctx.framebufferTexture2D(target, attachment, textarget, GL.textures[texture], level); }, diff --git a/src/settings.js b/src/settings.js index 15bca4db5251c..0daafa352e220 100644 --- a/src/settings.js +++ b/src/settings.js @@ -202,6 +202,7 @@ var SOCKET_WEBRTC = 0; // Select socket backend, either webrtc or websockets. var OPENAL_DEBUG = 0; // Print out debugging information from our OpenAL implementation. +var GL_ASSERTIONS = 0; // Adds extra checks for error situations in the GL library. Can impact performance. var GL_DEBUG = 0; // Print out all calls into WebGL. As with LIBRARY_DEBUG, you can set a runtime // option, in this case GL.debug. var GL_TESTING = 0; // When enabled, sets preserveDrawingBuffer in the context, to allow tests to work (but adds overhead) From aa80b0c6bd30e0cd6a80611548c2a51a3fe6b7ea Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 24 Sep 2013 16:37:12 -0700 Subject: [PATCH 018/165] do not turn 0*x to 0 in the case of floats, since NaNs break there; fixes #1661 --- src/parseTools.js | 4 ++-- tests/test_core.py | 27 +++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/parseTools.js b/src/parseTools.js index c0c8608c98db1..ddfb9d01451a1 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -1520,8 +1520,8 @@ function getFastValue(a, op, b, type) { } return '(Math.imul(' + a + ',' + b + ')|0)'; } - } else { - if (a == '0') { + } else { // div + if (a == '0' && !(type in Runtime.FLOAT_TYPES)) { // careful on floats, since 0*NaN is not 0 return '0'; } else if (b == 1) { return a; diff --git a/tests/test_core.py b/tests/test_core.py index 991f43a938928..ea2fe49e5d9db 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -1372,6 +1372,33 @@ def test_floatvars(self): ''' self.do_run(src, '*1,10,10.5,1,1.2340,0.00*\n0.50, 3.30, 3.30, 3.30\nsmall: 0.0000010000\n') + def test_zerodiv(self): + self.do_run(r''' + #include + int main(int argc, const char* argv[]) + { + float f1 = 1.0f; + float f2 = 0.0f; + float f_zero = 0.0f; + + float f3 = 0.0f / f2; + float f4 = f2 / 0.0f; + float f5 = f2 / f2; + float f6 = f2 / f_zero; + + printf("f3: %f\n", f3); + printf("f4: %f\n", f4); + printf("f5: %f\n", f5); + printf("f6: %f\n", f6); + + return 0; + } + ''', '''f3: nan +f4: nan +f5: nan +f6: nan +''') + def test_isnan(self): src = r''' #include From 061e6255ca15b31d002f22c2ca49eb1197d23f46 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 24 Sep 2013 16:40:52 -0700 Subject: [PATCH 019/165] improve check for Float64Array; fixes #1651 --- src/preamble.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/preamble.js b/src/preamble.js index acff665f8e629..977ce004e774b 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -717,7 +717,7 @@ var FAST_MEMORY = Module['FAST_MEMORY'] || {{{ FAST_MEMORY }}}; // Initialize the runtime's memory #if USE_TYPED_ARRAYS // check for full engine support (use string 'subarray' to avoid closure compiler confusion) -assert(!!Int32Array && !!Float64Array && !!(new Int32Array(1)['subarray']) && !!(new Int32Array(1)['set']), +assert(typeof Int32Array !== 'undefined' && typeof Float64Array !== 'undefined' && !!(new Int32Array(1)['subarray']) && !!(new Int32Array(1)['set']), 'Cannot fallback to non-typed array case: Code is too specialized'); #if USE_TYPED_ARRAYS == 1 From 85462ceea11bdf2a068211797199dabe2bef7135 Mon Sep 17 00:00:00 2001 From: ILOVEPIE Date: Sun, 31 Mar 2013 09:16:03 -0700 Subject: [PATCH 020/165] Added WebAudioAPI output to mixer code --- src/library_sdl.js | 64 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 54 insertions(+), 10 deletions(-) diff --git a/src/library_sdl.js b/src/library_sdl.js index 116bf547c4ec9..a7480afc5df5a 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -1486,17 +1486,54 @@ var LibrarySDL = { Runtime.dynCall('viii', SDL.audio.callback, [SDL.audio.userdata, SDL.audio.buffer, SDL.audio.bufferSize]); SDL.audio.pushAudio(SDL.audio.buffer, SDL.audio.bufferSize); }; - // Mozilla Audio API. TODO: Other audio APIs + // Mozilla Audio API/WebAudioAPI try { - SDL.audio.mozOutput = new Audio(); - SDL.audio.mozOutput['mozSetup'](SDL.audio.channels, SDL.audio.freq); // use string attributes on mozOutput for closure compiler - SDL.audio.mozBuffer = new Float32Array(totalSamples); - SDL.audio.pushAudio = function(ptr, size) { - var mozBuffer = SDL.audio.mozBuffer; - for (var i = 0; i < totalSamples; i++) { - mozBuffer[i] = ({{{ makeGetValue('ptr', 'i*2', 'i16', 0, 0) }}}) / 0x8000; // hardcoded 16-bit audio, signed (TODO: reSign if not ta2?) - } - SDL.audio.mozOutput['mozWriteAudio'](mozBuffer); + SDL.audio.audioOutput = new Audio(); + SDL.audio.hasWebkitAudio = ((typeof(AudioContext) === "function")||(typeof(webkitAudioContext) === "function")); + if(typeof(SDL.audio.audioOutput['mozSetup'])==="function"||!SDL.audio.hasWebkitAudio){ + SDL.audio.audioOutput['mozSetup'](SDL.audio.channels, SDL.audio.freq); // use string attributes on mozOutput for closure compiler + SDL.audio.mozBuffer = new Float32Array(totalSamples); + SDL.audio.pushAudio = function(ptr, size) { + var mozBuffer = SDL.audio.mozBuffer; + for (var i = 0; i < totalSamples; i++) { + mozBuffer[i] = ({{{ makeGetValue('ptr', 'i*2', 'i16', 0, 0) }}}) / 0x8000; // hardcoded 16-bit audio, signed (TODO: reSign if not ta2?) + } + SDL.audio.audioOutput['mozWriteAudio'](mozBuffer); + } + }else{ + if (typeof(AudioContext) === "function") { + SDL.audio.context = new AudioContext(); + } else if (typeof(webkitAudioContext) === "function") { + SDL.audio.context = new webkitAudioContext(); + } + SDL.audio.pushAudio=function(ptr,size){ + SDL.audio.soundSource = SDL.audio.context.createBufferSource(SDL.audio.channels,SDL.audio.samples,SDL.audio.freq); + if(typeof(SDL.audio.context.createScriptProcessor) === "function"){ + SDL.audio.soundInjector = SDL.audio.context.createScriptProcessor(SDL.audio.samples,SDL.audio.channels,SDL.audio.channels); + }else{ + SDL.audio.soundInjector = SDL.audio.context.createJavaScriptNode(SDL.audio.samples,SDL.audio.channels,SDL.audio.channels); + } + SDL.audio.soundInjector.onaudioprocess = function(e) { + SDL.audio.webAudioFunc(SDL.audio.buffer,e); + } + SDL.audio.soundSource.connect(SDL.audio.soundInjector); + SDL.audio.soundInjector.connect(SDL.audio.context.destination); + if(typeof(SDL.audio.soundSource.start)=== "function"){ + SDL.audio.soundSource.start(0); + }else{ + SDL.audio.soundSource.noteOn(0); + } + } + SDL.audio.webAudioFunc = function(ptr,e){ + for(var j = 0; i Date: Mon, 18 Mar 2013 20:50:49 -0700 Subject: [PATCH 021/165] Made the WebAudioAPI support slightly more efficient by removing some unnecessary channels. Signed-off-by: ILOVEPIE --- src/library_sdl.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/library_sdl.js b/src/library_sdl.js index a7480afc5df5a..c5bbb9897902d 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -1507,11 +1507,11 @@ var LibrarySDL = { SDL.audio.context = new webkitAudioContext(); } SDL.audio.pushAudio=function(ptr,size){ - SDL.audio.soundSource = SDL.audio.context.createBufferSource(SDL.audio.channels,SDL.audio.samples,SDL.audio.freq); + SDL.audio.soundSource = SDL.audio.context.createBufferSource(1,SDL.audio.samples,SDL.audio.freq); if(typeof(SDL.audio.context.createScriptProcessor) === "function"){ - SDL.audio.soundInjector = SDL.audio.context.createScriptProcessor(SDL.audio.samples,SDL.audio.channels,SDL.audio.channels); + SDL.audio.soundInjector = SDL.audio.context.createScriptProcessor(SDL.audio.samples,1,SDL.audio.channels); }else{ - SDL.audio.soundInjector = SDL.audio.context.createJavaScriptNode(SDL.audio.samples,SDL.audio.channels,SDL.audio.channels); + SDL.audio.soundInjector = SDL.audio.context.createJavaScriptNode(SDL.audio.samples,1,SDL.audio.channels); } SDL.audio.soundInjector.onaudioprocess = function(e) { SDL.audio.webAudioFunc(SDL.audio.buffer,e); From 0462f14bd6b6bdd9ad6adee0e30bddebab6da144 Mon Sep 17 00:00:00 2001 From: ILOVEPIE Date: Thu, 21 Mar 2013 10:26:51 -0700 Subject: [PATCH 022/165] Rewritten with audioBuffers Added myself to AUTHORS Signed-off-by: ILOVEPIE --- AUTHORS | 1 + src/library_sdl.js | 62 +++++++++++++++++++++++++--------------------- 2 files changed, 35 insertions(+), 28 deletions(-) diff --git a/AUTHORS b/AUTHORS index 604bd6bdf5a8a..8a4dc9d3b1c51 100644 --- a/AUTHORS +++ b/AUTHORS @@ -97,4 +97,5 @@ a license to everyone to use it as detailed in LICENSE.) * Charlie Birks * Ranger Harke (copyright owned by Autodesk, Inc.) * Tobias Vrinssen +* Patrick R. Martin diff --git a/src/library_sdl.js b/src/library_sdl.js index c5bbb9897902d..a2d0457ba4e26 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -1489,8 +1489,8 @@ var LibrarySDL = { // Mozilla Audio API/WebAudioAPI try { SDL.audio.audioOutput = new Audio(); - SDL.audio.hasWebkitAudio = ((typeof(AudioContext) === "function")||(typeof(webkitAudioContext) === "function")); - if(typeof(SDL.audio.audioOutput['mozSetup'])==="function"||!SDL.audio.hasWebkitAudio){ + SDL.audio.hasWebAudio = ((typeof(AudioContext) === "function")||(typeof(webkitAudioContext) === "function")); + if(!SDL.audio.hasWebAudio&&(typeof(SDL.audio.audioOutput['mozSetup'])==="function")){ SDL.audio.audioOutput['mozSetup'](SDL.audio.channels, SDL.audio.freq); // use string attributes on mozOutput for closure compiler SDL.audio.mozBuffer = new Float32Array(totalSamples); SDL.audio.pushAudio = function(ptr, size) { @@ -1503,36 +1503,42 @@ var LibrarySDL = { }else{ if (typeof(AudioContext) === "function") { SDL.audio.context = new AudioContext(); + SDL.audio.soundSource = SDL.audio.context.createBufferSource(); } else if (typeof(webkitAudioContext) === "function") { SDL.audio.context = new webkitAudioContext(); } + SDL.audio.nextSoundSource = 0; + SDL.audio.soundSource = new Array(); + SDL.audio.nextPlayTime = 0; SDL.audio.pushAudio=function(ptr,size){ - SDL.audio.soundSource = SDL.audio.context.createBufferSource(1,SDL.audio.samples,SDL.audio.freq); - if(typeof(SDL.audio.context.createScriptProcessor) === "function"){ - SDL.audio.soundInjector = SDL.audio.context.createScriptProcessor(SDL.audio.samples,1,SDL.audio.channels); - }else{ - SDL.audio.soundInjector = SDL.audio.context.createJavaScriptNode(SDL.audio.samples,1,SDL.audio.channels); - } - SDL.audio.soundInjector.onaudioprocess = function(e) { - SDL.audio.webAudioFunc(SDL.audio.buffer,e); - } - SDL.audio.soundSource.connect(SDL.audio.soundInjector); - SDL.audio.soundInjector.connect(SDL.audio.context.destination); - if(typeof(SDL.audio.soundSource.start)=== "function"){ - SDL.audio.soundSource.start(0); - }else{ - SDL.audio.soundSource.noteOn(0); - } - } - SDL.audio.webAudioFunc = function(ptr,e){ - for(var j = 0; i-1){ + if(SDL.audio.soundSource[SDL.audio.lastSoundSource].playbackState === 3){ + SDL.audio.soundSource = new Array(); + SDL.audio.nextPlayTime = 0; + SDL.audio.lastSoundSource = -1; + SDL.audio.nextSoundSource = 0; + } + } + SDL.audio.soundSource[SDL.audio.nextSoundSource] = SDL.audio.context.createBufferSource(); + SDL.audio.soundSource[SDL.audio.nextSoundSource].connect(SDL.audio.context.destination); + SDL.audio.soundSource[SDL.audio.nextSoundSource].buffer = SDL.audio.context.createBuffer(SDL.audio.channels,(size / totalSamples),SDL.audio.freq); + for(var j = 0; j Date: Sun, 31 Mar 2013 09:20:48 -0700 Subject: [PATCH 023/165] Fixed some stuff I forgot to change. Signed-off-by: ILOVEPIE --- src/library_sdl.js | 27 +++++---- tests/sdl_audio_beep.cpp | 128 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 143 insertions(+), 12 deletions(-) create mode 100644 tests/sdl_audio_beep.cpp diff --git a/src/library_sdl.js b/src/library_sdl.js index a2d0457ba4e26..0e5a5df495b80 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -1465,6 +1465,10 @@ var LibrarySDL = { samples: {{{ makeGetValue('desired', 'SDL.structs.AudioSpec.samples', 'i16', 0, 1) }}}, callback: {{{ makeGetValue('desired', 'SDL.structs.AudioSpec.callback', 'void*', 0, 1) }}}, userdata: {{{ makeGetValue('desired', 'SDL.structs.AudioSpec.userdata', 'void*', 0, 1) }}}, + soundSource: new Array(), + nextSoundSource: 0, + lastSoundSource: -1, + nextPlayTime: 0, paused: true, timer: null }; @@ -1503,10 +1507,11 @@ var LibrarySDL = { }else{ if (typeof(AudioContext) === "function") { SDL.audio.context = new AudioContext(); - SDL.audio.soundSource = SDL.audio.context.createBufferSource(); } else if (typeof(webkitAudioContext) === "function") { SDL.audio.context = new webkitAudioContext(); - } + } else { + throw "no sound!"; + } SDL.audio.nextSoundSource = 0; SDL.audio.soundSource = new Array(); SDL.audio.nextPlayTime = 0; @@ -1531,11 +1536,8 @@ var LibrarySDL = { } SDL.audio.nextPlayTime = SDL.audio.context.currentTime+SDL.audio.soundSource[SDL.audio.nextSoundSource].buffer.duration; - if(typeof(SDL.audio.soundSource.start)=== "function"){ - SDL.audio.soundSource[SDL.audio.nextSoundSource].start(SDL.audio.nextPlayTime); - }else{ - SDL.audio.soundSource[SDL.audio.nextSoundSource].noteOn(SDL.audio.nextPlayTime); - } + + SDL.audio.soundSource[SDL.audio.nextSoundSource].start(SDL.audio.nextPlayTime); SDL.audio.lastSoundSource = SDL.Audio.nextSoundSource; SDL.Audio.nextSoundSource++; @@ -1559,12 +1561,13 @@ var LibrarySDL = { SDL_CloseAudio: function() { if (SDL.audio) { try{ - if(typeof(SDL.audio.soundSource.stop)=== "function"){ - SDL.audio.soundSource.stop(0); - }else{ - SDL.audio.soundSource.noteOff(0); - } + for(var i = 0; i +#include +#include +#include + +const int AMPLITUDE = 28000; +const int FREQUENCY = 44100; + +struct BeepObject +{ + double freq; + int samplesLeft; +}; + +class Beeper +{ +private: + double v; + std::queue beeps; +public: + Beeper(); + ~Beeper(); + void beep(double freq, int duration); + void generateSamples(Sint16 *stream, int length); + void wait(); +}; + +void audio_callback(void*, Uint8*, int); + +Beeper::Beeper() +{ + SDL_AudioSpec desiredSpec; + + desiredSpec.freq = FREQUENCY; + desiredSpec.format = AUDIO_S16SYS; + desiredSpec.channels = 1; + desiredSpec.samples = 2048; + desiredSpec.callback = audio_callback; + desiredSpec.userdata = this; + + SDL_AudioSpec obtainedSpec; + + // you might want to look for errors here + SDL_OpenAudio(&desiredSpec, &obtainedSpec); + + // start play audio + SDL_PauseAudio(0); +} + +Beeper::~Beeper() +{ + SDL_CloseAudio(); +} + +void Beeper::generateSamples(Sint16 *stream, int length) +{ + int i = 0; + while (i < length) { + + if (beeps.empty()) { + while (i < length) { + stream[i] = 0; + i++; + } + return; + } + BeepObject& bo = beeps.front(); + + int samplesToDo = std::min(i + bo.samplesLeft, length); + bo.samplesLeft -= samplesToDo - i; + + while (i < samplesToDo) { + stream[i] = AMPLITUDE * std::sin(v * 2 * M_PI / FREQUENCY); + i++; + v += bo.freq; + } + + if (bo.samplesLeft == 0) { + beeps.pop(); + } + } +} + +void Beeper::beep(double freq, int duration) +{ + BeepObject bo; + bo.freq = freq; + bo.samplesLeft = duration * FREQUENCY / 1000; + + SDL_LockAudio(); + beeps.push(bo); + SDL_UnlockAudio(); +} + +void Beeper::wait() +{ + int size; + do { + SDL_Delay(20); + SDL_LockAudio(); + size = beeps.size(); + SDL_UnlockAudio(); + } while (size > 0); + +} + +void audio_callback(void *_beeper, Uint8 *_stream, int _length) +{ + Sint16 *stream = (Sint16*) _stream; + int length = _length / 2; + Beeper* beeper = (Beeper*) _beeper; + + beeper->generateSamples(stream, length); +} + +int main(int argc, char* argv[]) +{ + SDL_Init(SDL_INIT_AUDIO); + + int duration = 1000; + double Hz = 440; + + Beeper b; + b.beep(Hz, duration); + b.wait(); + + return 0; +} \ No newline at end of file From 6df56c0c5188f2316f75c414ccea9c3f735904ba Mon Sep 17 00:00:00 2001 From: ILOVEPIE Date: Sun, 24 Mar 2013 10:04:26 -0700 Subject: [PATCH 024/165] Switched to single quotes for consistency. Signed-off-by: ILOVEPIE --- src/library_sdl.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/library_sdl.js b/src/library_sdl.js index 0e5a5df495b80..d292f75316ac5 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -1493,8 +1493,8 @@ var LibrarySDL = { // Mozilla Audio API/WebAudioAPI try { SDL.audio.audioOutput = new Audio(); - SDL.audio.hasWebAudio = ((typeof(AudioContext) === "function")||(typeof(webkitAudioContext) === "function")); - if(!SDL.audio.hasWebAudio&&(typeof(SDL.audio.audioOutput['mozSetup'])==="function")){ + SDL.audio.hasWebAudio = ((typeof(AudioContext) === 'function')||(typeof(webkitAudioContext) === 'function')); + if(!SDL.audio.hasWebAudio&&(typeof(SDL.audio.audioOutput['mozSetup'])==='function')){ SDL.audio.audioOutput['mozSetup'](SDL.audio.channels, SDL.audio.freq); // use string attributes on mozOutput for closure compiler SDL.audio.mozBuffer = new Float32Array(totalSamples); SDL.audio.pushAudio = function(ptr, size) { @@ -1505,12 +1505,12 @@ var LibrarySDL = { SDL.audio.audioOutput['mozWriteAudio'](mozBuffer); } }else{ - if (typeof(AudioContext) === "function") { + if (typeof(AudioContext) === 'function') { SDL.audio.context = new AudioContext(); - } else if (typeof(webkitAudioContext) === "function") { + } else if (typeof(webkitAudioContext) === 'function') { SDL.audio.context = new webkitAudioContext(); } else { - throw "no sound!"; + throw 'no sound!'; } SDL.audio.nextSoundSource = 0; SDL.audio.soundSource = new Array(); @@ -1562,7 +1562,7 @@ var LibrarySDL = { if (SDL.audio) { try{ for(var i = 0; i Date: Sun, 16 Jun 2013 14:27:35 +0300 Subject: [PATCH 025/165] Improve SDL_OpenAudio support to work with the newest Web Audio API spec, add better support for different SDL audio formats and sample rates. Add browser test for SDL audio beep sample. --- src/library_sdl.js | 280 +++++++++++++++++++++++++------------ tests/sdl_audio_beep.cpp | 292 +++++++++++++++++++++++++++------------ 2 files changed, 392 insertions(+), 180 deletions(-) diff --git a/src/library_sdl.js b/src/library_sdl.js index d292f75316ac5..2860669c84f9b 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -704,7 +704,7 @@ var LibrarySDL = { // since the browser engine handles that for us. Therefore, in JS we just // maintain a list of channels and return IDs for them to the SDL consumer. allocateChannels: function(num) { // called from Mix_AllocateChannels and init - if (SDL.numChannels && SDL.numChannels >= num) return; + if (SDL.numChannels && SDL.numChannels >= num && num != 0) return; SDL.numChannels = num; SDL.channels = []; for (var i = 0; i < num; i++) { @@ -1454,105 +1454,200 @@ var LibrarySDL = { // SDL_Audio - // TODO fix SDL_OpenAudio, and add some tests for it. It's currently broken. SDL_OpenAudio: function(desired, obtained) { - SDL.allocateChannels(32); - - SDL.audio = { - freq: {{{ makeGetValue('desired', 'SDL.structs.AudioSpec.freq', 'i32', 0, 1) }}}, - format: {{{ makeGetValue('desired', 'SDL.structs.AudioSpec.format', 'i16', 0, 1) }}}, - channels: {{{ makeGetValue('desired', 'SDL.structs.AudioSpec.channels', 'i8', 0, 1) }}}, - samples: {{{ makeGetValue('desired', 'SDL.structs.AudioSpec.samples', 'i16', 0, 1) }}}, - callback: {{{ makeGetValue('desired', 'SDL.structs.AudioSpec.callback', 'void*', 0, 1) }}}, - userdata: {{{ makeGetValue('desired', 'SDL.structs.AudioSpec.userdata', 'void*', 0, 1) }}}, - soundSource: new Array(), - nextSoundSource: 0, - lastSoundSource: -1, - nextPlayTime: 0, - paused: true, - timer: null - }; - - if (obtained) { - {{{ makeSetValue('obtained', 'SDL.structs.AudioSpec.freq', 'SDL.audio.freq', 'i32') }}}; // no good way for us to know if the browser can really handle this - {{{ makeSetValue('obtained', 'SDL.structs.AudioSpec.format', 33040, 'i16') }}}; // float, signed, 16-bit - {{{ makeSetValue('obtained', 'SDL.structs.AudioSpec.channels', 'SDL.audio.channels', 'i8') }}}; - {{{ makeSetValue('obtained', 'SDL.structs.AudioSpec.silence', makeGetValue('desired', 'SDL.structs.AudioSpec.silence', 'i8', 0, 1), 'i8') }}}; // unclear if browsers can provide this - {{{ makeSetValue('obtained', 'SDL.structs.AudioSpec.samples', 'SDL.audio.samples', 'i16') }}}; - {{{ makeSetValue('obtained', 'SDL.structs.AudioSpec.callback', 'SDL.audio.callback', '*') }}}; - {{{ makeSetValue('obtained', 'SDL.structs.AudioSpec.userdata', 'SDL.audio.userdata', '*') }}}; - } - - var totalSamples = SDL.audio.samples*SDL.audio.channels; - SDL.audio.bufferSize = totalSamples*2; // hardcoded 16-bit audio - SDL.audio.buffer = _malloc(SDL.audio.bufferSize); - SDL.audio.caller = function() { - Runtime.dynCall('viii', SDL.audio.callback, [SDL.audio.userdata, SDL.audio.buffer, SDL.audio.bufferSize]); - SDL.audio.pushAudio(SDL.audio.buffer, SDL.audio.bufferSize); - }; - // Mozilla Audio API/WebAudioAPI + // On Firefox, we prefer Mozilla Audio API. Otherwise, use WebAudioAPI. try { + SDL.audio = { + freq: {{{ makeGetValue('desired', 'SDL.structs.AudioSpec.freq', 'i32', 0, 1) }}}, + format: {{{ makeGetValue('desired', 'SDL.structs.AudioSpec.format', 'i16', 0, 1) }}}, + channels: {{{ makeGetValue('desired', 'SDL.structs.AudioSpec.channels', 'i8', 0, 1) }}}, + samples: {{{ makeGetValue('desired', 'SDL.structs.AudioSpec.samples', 'i16', 0, 1) }}}, // Samples in the CB buffer per single sound channel. + callback: {{{ makeGetValue('desired', 'SDL.structs.AudioSpec.callback', 'void*', 0, 1) }}}, + userdata: {{{ makeGetValue('desired', 'SDL.structs.AudioSpec.userdata', 'void*', 0, 1) }}}, + paused: true, + timer: null + }; + // The .silence field tells the constant sample value that corresponds to the safe un-skewed silence value for the wave data. + if (SDL.audio.format == 0x0008 /*AUDIO_U8*/) { + SDL.audio.silence = 128; // Audio ranges in [0, 255], so silence is half-way in between. + } else if (SDL.audio.format == 0x8010 /*AUDIO_S16LSB*/) { + SDL.audio.silence = 0; // Signed data in range [-32768, 32767], silence is 0. + } else { + throw 'Invalid SDL audio format ' + SDL.audio.format + '!'; + } + // Round the desired audio frequency up to the next 'common' frequency value. + // Web Audio API spec states 'An implementation must support sample-rates in at least the range 22050 to 96000.' + if (SDL.audio.freq <= 0) { + throw 'Unsupported sound frequency ' + SDL.audio.freq + '!'; + } else if (SDL.audio.freq <= 22050) { + SDL.audio.freq = 22050; // Take it safe and clamp everything lower than 22kHz to that. + } else if (SDL.audio.freq <= 32000) { + SDL.audio.freq = 32000; + } else if (SDL.audio.freq <= 44100) { + SDL.audio.freq = 44100; + } else if (SDL.audio.freq <= 48000) { + SDL.audio.freq = 48000; + } else if (SDL.audio.freq <= 96000) { + SDL.audio.freq = 96000; + } else { + throw 'Unsupported sound frequency ' + SDL.audio.freq + '!'; + } + if (SDL.audio.channels == 0) { + SDL.audio.channels = 1; // In SDL both 0 and 1 mean mono. + } else if (SDL.audio.channels < 0 || SDL.audio.channels > 32) { + throw 'Unsupported number of audio channels for SDL audio: ' + SDL.audio.channels + '!'; + } else if (SDL.audio.channels != 1 && SDL.audio.channels != 2) { // Unsure what SDL audio spec supports. Web Audio spec supports up to 32 channels. + console.log('Warning: Using untested number of audio channels ' + SDL.audio.channels); + } + if (SDL.audio.samples < 1024 || SDL.audio.samples > 524288 /* arbitrary cap */) { + throw 'Unsupported audio callback buffer size ' + SDL.audio.samples + '!'; + } else if ((SDL.audio.samples & (SDL.audio.samples-1)) != 0) { + throw 'Audio callback buffer size ' + SDL.audio.samples + ' must be a power-of-two!'; + } + + var totalSamples = SDL.audio.samples*SDL.audio.channels; + SDL.audio.bytesPerSample = (SDL.audio.format == 0x0008 /*AUDIO_U8*/ || SDL.audio.format == 0x8008 /*AUDIO_S8*/) ? 1 : 2; + SDL.audio.bufferSize = totalSamples*SDL.audio.bytesPerSample; + SDL.audio.buffer = _malloc(SDL.audio.bufferSize); + + // Create a callback function that will be routinely called to ask more audio data from the user application. + SDL.audio.caller = function() { + if (!SDL.audio) { + return; + } + Runtime.dynCall('viii', SDL.audio.callback, [SDL.audio.userdata, SDL.audio.buffer, SDL.audio.bufferSize]); + SDL.audio.pushAudio(SDL.audio.buffer, SDL.audio.bufferSize); + }; + SDL.audio.audioOutput = new Audio(); - SDL.audio.hasWebAudio = ((typeof(AudioContext) === 'function')||(typeof(webkitAudioContext) === 'function')); - if(!SDL.audio.hasWebAudio&&(typeof(SDL.audio.audioOutput['mozSetup'])==='function')){ - SDL.audio.audioOutput['mozSetup'](SDL.audio.channels, SDL.audio.freq); // use string attributes on mozOutput for closure compiler - SDL.audio.mozBuffer = new Float32Array(totalSamples); - SDL.audio.pushAudio = function(ptr, size) { - var mozBuffer = SDL.audio.mozBuffer; + if (typeof(SDL.audio.audioOutput['mozSetup'])==='function') { // Primarily use Mozilla Audio Data API if available. + SDL.audio.audioOutput['mozSetup'](SDL.audio.channels, SDL.audio.freq); // use string attributes on mozOutput for closure compiler + SDL.audio.mozBuffer = new Float32Array(totalSamples); + SDL.audio.pushAudio = function(ptr, size) { + var mozBuffer = SDL.audio.mozBuffer; + // The input audio data for SDL audio is either 8-bit or 16-bit interleaved across channels, output for Mozilla Audio Data API + // needs to be Float32 interleaved, so perform a sample conversion. + if (SDL.audio.format == 0x8010 /*AUDIO_S16LSB*/) { + for (var i = 0; i < totalSamples; i++) { + mozBuffer[i] = ({{{ makeGetValue('ptr', 'i*2', 'i16', 0, 0) }}}) / 0x8000; + } + } else if (SDL.audio.format == 0x0008 /*AUDIO_U8*/) { for (var i = 0; i < totalSamples; i++) { - mozBuffer[i] = ({{{ makeGetValue('ptr', 'i*2', 'i16', 0, 0) }}}) / 0x8000; // hardcoded 16-bit audio, signed (TODO: reSign if not ta2?) + var v = ({{{ makeGetValue('ptr', 'i', 'i8', 0, 0) }}}); + mozBuffer[i] = ((v >= 0) ? v-128 : v+128) /128; } - SDL.audio.audioOutput['mozWriteAudio'](mozBuffer); } - }else{ - if (typeof(AudioContext) === 'function') { - SDL.audio.context = new AudioContext(); - } else if (typeof(webkitAudioContext) === 'function') { - SDL.audio.context = new webkitAudioContext(); - } else { - throw 'no sound!'; - } - SDL.audio.nextSoundSource = 0; - SDL.audio.soundSource = new Array(); - SDL.audio.nextPlayTime = 0; - SDL.audio.pushAudio=function(ptr,size){ - if(SDL.audio.lastSoundSource>-1){ - if(SDL.audio.soundSource[SDL.audio.lastSoundSource].playbackState === 3){ - SDL.audio.soundSource = new Array(); - SDL.audio.nextPlayTime = 0; - SDL.audio.lastSoundSource = -1; - SDL.audio.nextSoundSource = 0; - } - } - SDL.audio.soundSource[SDL.audio.nextSoundSource] = SDL.audio.context.createBufferSource(); - SDL.audio.soundSource[SDL.audio.nextSoundSource].connect(SDL.audio.context.destination); - SDL.audio.soundSource[SDL.audio.nextSoundSource].buffer = SDL.audio.context.createBuffer(SDL.audio.channels,(size / totalSamples),SDL.audio.freq); - for(var j = 0; j= 0) ? v-128 : v+128) /128; + } + } + } + + // Schedule the generated sample buffer to be played out at the correct time right after the previously scheduled + // sample buffer has finished. + var curtime = SDL.audioContext.currentTime; + if (curtime > SDL.audio.nextPlayTime && SDL.audio.nextPlayTime != 0) { + console.log('warning: Audio callback had starved sending audio by ' + (curtime - SDL.audio.nextPlayTime) + ' seconds.'); + // Immediately queue up an extra buffer to force the sound feeding to be ahead by one sample block: + Browser.safeSetTimeout(SDL.audio.caller, 1); + } + var playtime = Math.max(curtime, SDL.audio.nextPlayTime); + SDL.audio.soundSource[SDL.audio.nextSoundSource].start(playtime); + SDL.audio.nextPlayTime = playtime + SDL.audio.soundSource[SDL.audio.nextSoundSource].buffer.duration; + SDL.audio.nextSoundSource = (SDL.audio.nextSoundSource + 1) % 4; + } catch(e) { + console.log('Web Audio API error playing back audio: ' + e.toString()); + } + } } + + if (obtained) { + // Report back the initialized audio parameters. + {{{ makeSetValue('obtained', 'SDL.structs.AudioSpec.freq', 'SDL.audio.freq', 'i32') }}}; + {{{ makeSetValue('obtained', 'SDL.structs.AudioSpec.format', 'SDL.audio.format', 'i16') }}}; + {{{ makeSetValue('obtained', 'SDL.structs.AudioSpec.channels', 'SDL.audio.channels', 'i8') }}}; + {{{ makeSetValue('obtained', 'SDL.structs.AudioSpec.silence', makeGetValue('desired', 'SDL.structs.AudioSpec.silence', 'i8', 0, 1), 'i8') }}}; // unclear if browsers can provide this + {{{ makeSetValue('obtained', 'SDL.structs.AudioSpec.samples', 'SDL.audio.samples', 'i16') }}}; + {{{ makeSetValue('obtained', 'SDL.structs.AudioSpec.callback', 'SDL.audio.callback', '*') }}}; + {{{ makeSetValue('obtained', 'SDL.structs.AudioSpec.userdata', 'SDL.audio.userdata', '*') }}}; + } + SDL.allocateChannels(32); + } catch(e) { + console.log('Initializing SDL audio threw an exception: "' + e.toString() + '"! Continuing without audio.'); SDL.audio = null; + SDL.allocateChannels(0); + if (obtained) { + {{{ makeSetValue('obtained', 'SDL.structs.AudioSpec.freq', 0, 'i32') }}}; + {{{ makeSetValue('obtained', 'SDL.structs.AudioSpec.format', 0, 'i16') }}}; + {{{ makeSetValue('obtained', 'SDL.structs.AudioSpec.channels', 0, 'i8') }}}; + {{{ makeSetValue('obtained', 'SDL.structs.AudioSpec.silence', 0, 'i8') }}}; + {{{ makeSetValue('obtained', 'SDL.structs.AudioSpec.samples', 0, 'i16') }}}; + {{{ makeSetValue('obtained', 'SDL.structs.AudioSpec.callback', 0, '*') }}}; + {{{ makeSetValue('obtained', 'SDL.structs.AudioSpec.userdata', 0, '*') }}}; + } + } + if (!SDL.audio) { + return -1; } - if (!SDL.audio) return -1; return 0; }, SDL_PauseAudio: function(pauseOn) { + if (!SDL.audio) { + return; + } if (SDL.audio.paused !== pauseOn) { - SDL.audio.timer = pauseOn ? SDL.audio.timer && clearInterval(SDL.audio.timer) : Browser.safeSetInterval(SDL.audio.caller, 1/35); + SDL.audio.timer = pauseOn ? SDL.audio.timer && clearInterval(SDL.audio.timer) : Browser.safeSetInterval(SDL.audio.caller, 1000 * SDL.audio.samples / SDL.audio.freq); + // Immediately queue up a buffer to make the sound feeding to be ahead by one sample block. + Browser.safeSetTimeout(SDL.audio.caller, 1); } SDL.audio.paused = pauseOn; }, @@ -1560,17 +1655,18 @@ var LibrarySDL = { SDL_CloseAudio__deps: ['SDL_PauseAudio', 'free'], SDL_CloseAudio: function() { if (SDL.audio) { - try{ - for(var i = 0; i #include #include +#include +#include -const int AMPLITUDE = 28000; -const int FREQUENCY = 44100; +#ifndef M_PI +#define M_PI 3.14159265358979323846f +#endif -struct BeepObject -{ - double freq; - int samplesLeft; +#ifdef EMSCRIPTEN +#include "emscripten/emscripten.h" +#endif + +#ifdef main +#undef main +#endif + +const int tone_duration = 2000; + +struct BeepObject { + double toneFrequency; + int samplesLeft; }; -class Beeper -{ +class Beeper { private: - double v; - std::queue beeps; + double phase; + int frequency; + int numChannels; + int mutedChannel; public: - Beeper(); - ~Beeper(); - void beep(double freq, int duration); - void generateSamples(Sint16 *stream, int length); - void wait(); + Beeper(int frequency, int numChannels, int sdlAudioFormat); + ~Beeper(); + void beep(double toneFrequency, int durationMSecs); + template + void generateSamples(T *stream, int length); + void wait(); + + std::queue beeps; + int sdlAudioFormat; }; void audio_callback(void*, Uint8*, int); -Beeper::Beeper() -{ - SDL_AudioSpec desiredSpec; +Beeper::Beeper(int frequency_, int numChannels_, int sdlAudioFormat_) { + phase = 0.0; + mutedChannel = 1; - desiredSpec.freq = FREQUENCY; - desiredSpec.format = AUDIO_S16SYS; - desiredSpec.channels = 1; - desiredSpec.samples = 2048; - desiredSpec.callback = audio_callback; - desiredSpec.userdata = this; + SDL_AudioSpec desiredSpec; - SDL_AudioSpec obtainedSpec; + desiredSpec.freq = frequency_; + desiredSpec.format = sdlAudioFormat_; + desiredSpec.channels = numChannels_; + desiredSpec.samples = 1024; // This is samples per channel. + desiredSpec.callback = audio_callback; + desiredSpec.userdata = this; - // you might want to look for errors here - SDL_OpenAudio(&desiredSpec, &obtainedSpec); + SDL_AudioSpec obtainedSpec; - // start play audio - SDL_PauseAudio(0); -} + // you might want to look for errors here + SDL_OpenAudio(&desiredSpec, &obtainedSpec); -Beeper::~Beeper() -{ + // In this test, we require *exactly* the identical SDL result that we provide, since we test + // all various configurations individually. + if (obtainedSpec.freq != desiredSpec.freq || obtainedSpec.format != desiredSpec.format + || obtainedSpec.channels != desiredSpec.channels || obtainedSpec.samples != desiredSpec.samples) { SDL_CloseAudio(); + throw std::runtime_error("Failed to initialize desired SDL_OpenAudio!"); + } + + frequency = obtainedSpec.freq; + numChannels = obtainedSpec.channels; + sdlAudioFormat = obtainedSpec.format; + + // Immediately start producing audio. + SDL_PauseAudio(0); } -void Beeper::generateSamples(Sint16 *stream, int length) -{ - int i = 0; - while (i < length) { - - if (beeps.empty()) { - while (i < length) { - stream[i] = 0; - i++; - } - return; - } - BeepObject& bo = beeps.front(); +Beeper::~Beeper() { + SDL_CloseAudio(); +} + +template +void Beeper::generateSamples(T *stream, int length) { + const int AMPLITUDE = (sizeof(T) == 2) ? 28000 : 120; + const int offset = (sdlAudioFormat == AUDIO_U8) ? 120 : 0; + + int i = 0; + length /= numChannels; + while (i < length) { + if (beeps.empty()) { + memset(stream + numChannels*i, 0, sizeof(T)*numChannels*(length-i)); + return; + } + BeepObject& bo = beeps.front(); - int samplesToDo = std::min(i + bo.samplesLeft, length); - bo.samplesLeft -= samplesToDo - i; + // In Stereo tests, mute one of the channels to be able to distinguish that Stereo output works. + if (bo.samplesLeft > tone_duration * frequency / 2 / 1000) { + mutedChannel = 1; + } else { + mutedChannel = 0; + } - while (i < samplesToDo) { - stream[i] = AMPLITUDE * std::sin(v * 2 * M_PI / FREQUENCY); - i++; - v += bo.freq; - } + int samplesToDo = std::min(i + bo.samplesLeft, length); + bo.samplesLeft -= samplesToDo - i; - if (bo.samplesLeft == 0) { - beeps.pop(); + while (i < samplesToDo) { + for(int j = 0; j < numChannels; ++j) { + stream[numChannels*i+j] = (T)(offset + (int)(AMPLITUDE * std::sin(phase * 2 * M_PI / frequency))); + if (numChannels > 1 && j == mutedChannel) { + stream[numChannels*i+j] = 0; } + } + phase += bo.toneFrequency; + i++; } + + if (bo.samplesLeft == 0) { + beeps.pop(); + } + } } -void Beeper::beep(double freq, int duration) -{ - BeepObject bo; - bo.freq = freq; - bo.samplesLeft = duration * FREQUENCY / 1000; +void Beeper::beep(double toneFrequency, int durationMSecs) { + BeepObject bo; + bo.toneFrequency = toneFrequency; + bo.samplesLeft = durationMSecs * frequency / 1000; + + SDL_LockAudio(); + beeps.push(bo); + SDL_UnlockAudio(); +} - SDL_LockAudio(); - beeps.push(bo); - SDL_UnlockAudio(); +Beeper *beep = 0; + +// Test all kinds of various possible formats. Not all are supported, but running this +// test will report you which work. +const int freqs[] = { 8000, 11025, 16000, 22050, 32000, 44100, 48000, 96000 }; +const int channels[] = { 1, 2 }; +const int sdlAudioFormats[] = { AUDIO_U8, AUDIO_S16LSB /*, AUDIO_S8, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_S16MSB */ }; + +const char *SdlAudioFormatToString(int sdlAudioType) { + switch(sdlAudioType) { + case AUDIO_U8: return "AUDIO_U8"; + case AUDIO_S8: return "AUDIO_S8"; + case AUDIO_U16LSB: return "AUDIO_U16LSB"; + case AUDIO_U16MSB: return "AUDIO_U16MSB"; + case AUDIO_S16LSB: return "AUDIO_S16LSB"; + case AUDIO_S16MSB: return "AUDIO_S16MSB"; + default: return "(unknown)"; + } } -void Beeper::wait() -{ - int size; - do { - SDL_Delay(20); - SDL_LockAudio(); - size = beeps.size(); - SDL_UnlockAudio(); - } while (size > 0); +#define NUM_ELEMS(x) (sizeof(x)/sizeof((x)[0])) + +// Indices to the currently running test. +int f = -1; +int c = 0; +int s = 0; + +void nextTest(void *unused = 0) { + ++f; + if (f >= NUM_ELEMS(freqs)) { + f = 0; + ++c; + if (c >= NUM_ELEMS(channels)) { + c = 0; + ++s; + if (s >= NUM_ELEMS(sdlAudioFormats)) { + printf("All tests done. Quit.\n"); +#ifdef EMSCRIPTEN + emscripten_cancel_main_loop(); + int result = 1; + REPORT_RESULT(); +#endif + return; + } + } + } + + double Hz = 440; + try { + beep = new Beeper(freqs[f], channels[c], sdlAudioFormats[s]); + } catch(...) { + printf("FAILED to play beep for %d msecs at %d Hz tone with audio format %s, %d channels, and %d samples/sec.\n", + tone_duration, (int)Hz, SdlAudioFormatToString(sdlAudioFormats[s]), channels[c], freqs[f]); + nextTest(); + return; + } + + printf("Playing back a beep for %d msecs at %d Hz tone with audio format %s, %d channels, and %d samples/sec.\n", + tone_duration, (int)Hz, SdlAudioFormatToString(sdlAudioFormats[s]), channels[c], freqs[f]); + beep->beep(Hz, tone_duration); +} +void update() { + SDL_LockAudio(); + int size = beep->beeps.size(); + SDL_UnlockAudio(); + if (size == 0 && beep) { + delete beep; + beep = 0; +#ifdef EMSCRIPTEN + emscripten_async_call(nextTest, 0, 500); +#else + SDL_Delay(500); + nextTest(); +#endif + } } -void audio_callback(void *_beeper, Uint8 *_stream, int _length) -{ +void audio_callback(void *_beeper, Uint8 *_stream, int _length) { + Beeper* beeper = (Beeper*) _beeper; + + if (beeper->sdlAudioFormat == AUDIO_U8) { + Uint8 *stream = (Uint8*) _stream; + beeper->generateSamples(stream, _length); + } else if (beeper->sdlAudioFormat == AUDIO_S16LSB) { Sint16 *stream = (Sint16*) _stream; int length = _length / 2; - Beeper* beeper = (Beeper*) _beeper; - beeper->generateSamples(stream, length); + } else { + assert(false && "Audio sample generation not implemented for current format!\n"); + } } -int main(int argc, char* argv[]) -{ - SDL_Init(SDL_INIT_AUDIO); - - int duration = 1000; - double Hz = 440; - - Beeper b; - b.beep(Hz, duration); - b.wait(); - - return 0; -} \ No newline at end of file +int main(int argc, char** argv) { + SDL_Init(SDL_INIT_AUDIO); + + nextTest(); + +#ifdef EMSCRIPTEN + emscripten_set_main_loop(update, 60, 0); +#else + while(beep) { + SDL_Delay(20); + update(); + } +#endif + + return 0; +} From a762e30765e011a7729ed620558b1ce0700084a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Sun, 16 Jun 2013 14:32:14 +0300 Subject: [PATCH 026/165] Fix closure issues with Web Audio support in SDL. --- src/library_sdl.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/library_sdl.js b/src/library_sdl.js index 2860669c84f9b..8b072ff4a7c55 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -1564,17 +1564,17 @@ var LibrarySDL = { throw 'Received mismatching audio buffer size!'; } // Allocate new sound buffer to be played. - var source = SDL.audioContext.createBufferSource(); + var source = SDL.audioContext['createBufferSource'](); SDL.audio.soundSource[SDL.audio.nextSoundSource] = source; - source.buffer = SDL.audioContext.createBuffer(SDL.audio.channels,sizeSamplesPerChannel,SDL.audio.freq); - SDL.audio.soundSource[SDL.audio.nextSoundSource].connect(SDL.audioContext.destination); + source.buffer = SDL.audioContext['createBuffer'](SDL.audio.channels,sizeSamplesPerChannel,SDL.audio.freq); + SDL.audio.soundSource[SDL.audio.nextSoundSource]['connect'](SDL.audioContext['destination']); // The input audio data is interleaved across the channels, i.e. [L, R, L, R, L, R, ...] and is either 8-bit or 16-bit as // supported by the SDL API. The output audio wave data for Web Audio API must be in planar buffers of [-1,1]-normalized Float32 data, // so perform a buffer conversion for the data. var numChannels = SDL.audio.channels; for(var i = 0; i < numChannels; ++i) { - var channelData = SDL.audio.soundSource[SDL.audio.nextSoundSource].buffer.getChannelData(i); + var channelData = SDL.audio.soundSource[SDL.audio.nextSoundSource]['buffer']['getChannelData'](i); if (channelData.length != sizeSamplesPerChannel) { throw 'Web Audio output buffer length mismatch! Destination size: ' + channelData.length + ' samples vs expected ' + sizeSamplesPerChannel + ' samples!'; } @@ -1592,15 +1592,15 @@ var LibrarySDL = { // Schedule the generated sample buffer to be played out at the correct time right after the previously scheduled // sample buffer has finished. - var curtime = SDL.audioContext.currentTime; + var curtime = SDL.audioContext['currentTime']; if (curtime > SDL.audio.nextPlayTime && SDL.audio.nextPlayTime != 0) { console.log('warning: Audio callback had starved sending audio by ' + (curtime - SDL.audio.nextPlayTime) + ' seconds.'); // Immediately queue up an extra buffer to force the sound feeding to be ahead by one sample block: Browser.safeSetTimeout(SDL.audio.caller, 1); } var playtime = Math.max(curtime, SDL.audio.nextPlayTime); - SDL.audio.soundSource[SDL.audio.nextSoundSource].start(playtime); - SDL.audio.nextPlayTime = playtime + SDL.audio.soundSource[SDL.audio.nextSoundSource].buffer.duration; + SDL.audio.soundSource[SDL.audio.nextSoundSource]['start'](playtime); + SDL.audio.nextPlayTime = playtime + SDL.audio.soundSource[SDL.audio.nextSoundSource]['buffer']['duration']; SDL.audio.nextSoundSource = (SDL.audio.nextSoundSource + 1) % 4; } catch(e) { console.log('Web Audio API error playing back audio: ' + e.toString()); From e17329cd47c7c02658355112f7b43a28b693f229 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Sun, 16 Jun 2013 14:33:34 +0300 Subject: [PATCH 027/165] Fix reporting of silence parameter in SDL audio api. --- src/library_sdl.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/library_sdl.js b/src/library_sdl.js index 8b072ff4a7c55..79468af8a486b 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -1613,7 +1613,7 @@ var LibrarySDL = { {{{ makeSetValue('obtained', 'SDL.structs.AudioSpec.freq', 'SDL.audio.freq', 'i32') }}}; {{{ makeSetValue('obtained', 'SDL.structs.AudioSpec.format', 'SDL.audio.format', 'i16') }}}; {{{ makeSetValue('obtained', 'SDL.structs.AudioSpec.channels', 'SDL.audio.channels', 'i8') }}}; - {{{ makeSetValue('obtained', 'SDL.structs.AudioSpec.silence', makeGetValue('desired', 'SDL.structs.AudioSpec.silence', 'i8', 0, 1), 'i8') }}}; // unclear if browsers can provide this + {{{ makeSetValue('obtained', 'SDL.structs.AudioSpec.silence', 'SDL.audio.silence', 'i8') }}}; {{{ makeSetValue('obtained', 'SDL.structs.AudioSpec.samples', 'SDL.audio.samples', 'i16') }}}; {{{ makeSetValue('obtained', 'SDL.structs.AudioSpec.callback', 'SDL.audio.callback', '*') }}}; {{{ makeSetValue('obtained', 'SDL.structs.AudioSpec.userdata', 'SDL.audio.userdata', '*') }}}; From 84c042143b57382e07d1af137d47fd36288b34dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Sun, 16 Jun 2013 15:09:33 +0300 Subject: [PATCH 028/165] Improve the Web Audio callback buffer scheduling logic to stay ahead of buffer underflow by at least more than one sample block. --- src/library_sdl.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/library_sdl.js b/src/library_sdl.js index 79468af8a486b..55e9aa492c7fc 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -1595,13 +1595,17 @@ var LibrarySDL = { var curtime = SDL.audioContext['currentTime']; if (curtime > SDL.audio.nextPlayTime && SDL.audio.nextPlayTime != 0) { console.log('warning: Audio callback had starved sending audio by ' + (curtime - SDL.audio.nextPlayTime) + ' seconds.'); - // Immediately queue up an extra buffer to force the sound feeding to be ahead by one sample block: - Browser.safeSetTimeout(SDL.audio.caller, 1); } var playtime = Math.max(curtime, SDL.audio.nextPlayTime); SDL.audio.soundSource[SDL.audio.nextSoundSource]['start'](playtime); - SDL.audio.nextPlayTime = playtime + SDL.audio.soundSource[SDL.audio.nextSoundSource]['buffer']['duration']; + var buffer_duration = SDL.audio.soundSource[SDL.audio.nextSoundSource]['buffer']['duration']; + SDL.audio.nextPlayTime = playtime + buffer_duration; SDL.audio.nextSoundSource = (SDL.audio.nextSoundSource + 1) % 4; + // Make sure we are always more than one sample block ahead of the current time to avoid starving. + if (curtime + buffer_duration + buffer_duration >= SDL.audio.nextPlayTime) { + // Immediately queue up an extra buffer to force the sound feeding to be ahead by more than one sample block: + Browser.safeSetTimeout(SDL.audio.caller, 1); + } } catch(e) { console.log('Web Audio API error playing back audio: ' + e.toString()); } From 257d5f4d0b4932817b2bbf9071134346ed7f6392 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Sun, 16 Jun 2013 18:30:27 +0300 Subject: [PATCH 029/165] Fix audio callback overflow problems by avoiding using Browser.safeSetTimeout, and instead calling safeSetInterval to control the timing drift explicitly. --- src/library_sdl.js | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/src/library_sdl.js b/src/library_sdl.js index 55e9aa492c7fc..3851caaf76286 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -1523,6 +1523,7 @@ var LibrarySDL = { if (typeof(SDL.audio.audioOutput['mozSetup'])==='function') { // Primarily use Mozilla Audio Data API if available. SDL.audio.audioOutput['mozSetup'](SDL.audio.channels, SDL.audio.freq); // use string attributes on mozOutput for closure compiler SDL.audio.mozBuffer = new Float32Array(totalSamples); + SDL.audio.nextPlayTime = 0; SDL.audio.pushAudio = function(ptr, size) { var mozBuffer = SDL.audio.mozBuffer; // The input audio data for SDL audio is either 8-bit or 16-bit interleaved across channels, output for Mozilla Audio Data API @@ -1537,7 +1538,19 @@ var LibrarySDL = { mozBuffer[i] = ((v >= 0) ? v-128 : v+128) /128; } } + // Submit the audio data to audio device. SDL.audio.audioOutput['mozWriteAudio'](mozBuffer); + + // Compute when the next audio callback should be called. + var curtime = Date.now() / 1000.0 - SDL.audio.startTime; + if (curtime > SDL.audio.nextPlayTime && SDL.audio.nextPlayTime != 0) { + console.log('warning: Audio callback had starved sending audio by ' + (curtime - SDL.audio.nextPlayTime) + ' seconds.'); + } + var playtime = Math.max(curtime, SDL.audio.nextPlayTime); + var buffer_duration = SDL.audio.samples / SDL.audio.freq; + SDL.audio.nextPlayTime = playtime + buffer_duration; + // Schedule the next audio callback call. + SDL.audio.timer = Browser.safeSetTimeout(SDL.audio.caller, 1000.0 * (playtime-curtime)); } } else { // Initialize Web Audio API if we haven't done so yet. Note: Only initialize Web Audio context ever once on the web page, @@ -1598,14 +1611,10 @@ var LibrarySDL = { } var playtime = Math.max(curtime, SDL.audio.nextPlayTime); SDL.audio.soundSource[SDL.audio.nextSoundSource]['start'](playtime); - var buffer_duration = SDL.audio.soundSource[SDL.audio.nextSoundSource]['buffer']['duration']; + var buffer_duration = sizeSamplesPerChannel / SDL.audio.freq; SDL.audio.nextPlayTime = playtime + buffer_duration; SDL.audio.nextSoundSource = (SDL.audio.nextSoundSource + 1) % 4; - // Make sure we are always more than one sample block ahead of the current time to avoid starving. - if (curtime + buffer_duration + buffer_duration >= SDL.audio.nextPlayTime) { - // Immediately queue up an extra buffer to force the sound feeding to be ahead by more than one sample block: - Browser.safeSetTimeout(SDL.audio.caller, 1); - } + SDL.audio.timer = Browser.safeSetTimeout(SDL.audio.caller, 1000*(playtime-curtime)); } catch(e) { console.log('Web Audio API error playing back audio: ' + e.toString()); } @@ -1648,10 +1657,15 @@ var LibrarySDL = { if (!SDL.audio) { return; } - if (SDL.audio.paused !== pauseOn) { - SDL.audio.timer = pauseOn ? SDL.audio.timer && clearInterval(SDL.audio.timer) : Browser.safeSetInterval(SDL.audio.caller, 1000 * SDL.audio.samples / SDL.audio.freq); - // Immediately queue up a buffer to make the sound feeding to be ahead by one sample block. - Browser.safeSetTimeout(SDL.audio.caller, 1); + if (pauseOn) { + if (SDL.audio.timer !== undefined) { + clearTimeout(SDL.audio.timer); + SDL.audio.timer = undefined; + } + } else {// if (SDL.audio.timer === undefined) { + // Start the audio playback timer callback loop. + SDL.audio.timer = Browser.safeSetTimeout(SDL.audio.caller, 1); + SDL.audio.startTime = Date.now() / 1000.0; } SDL.audio.paused = pauseOn; }, From 9447edeb28ff332ca0a9148db66bdf3f2c363e1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Sun, 16 Jun 2013 18:34:48 +0300 Subject: [PATCH 030/165] Explicitly disconnect generated audio buffers with Web Audio API to guarantee no resources will be leaked. (not sure if this is necessary, but it uncovered a timing bug, and doesn't hurt to be safe) --- src/library_sdl.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/library_sdl.js b/src/library_sdl.js index 3851caaf76286..e8c4b6b87d350 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -1578,6 +1578,9 @@ var LibrarySDL = { } // Allocate new sound buffer to be played. var source = SDL.audioContext['createBufferSource'](); + if (SDL.audio.soundSource[SDL.audio.nextSoundSource]) { + SDL.audio.soundSource[SDL.audio.nextSoundSource]['disconnect'](); + } SDL.audio.soundSource[SDL.audio.nextSoundSource] = source; source.buffer = SDL.audioContext['createBuffer'](SDL.audio.channels,sizeSamplesPerChannel,SDL.audio.freq); SDL.audio.soundSource[SDL.audio.nextSoundSource]['connect'](SDL.audioContext['destination']); From 45e01ab4a388c47226af8692149c61362b9102ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Sun, 16 Jun 2013 18:36:46 +0300 Subject: [PATCH 031/165] Make the time periods between beeps longer to be able to distinguish audio quality better. --- tests/sdl_audio_beep.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/sdl_audio_beep.cpp b/tests/sdl_audio_beep.cpp index afe6a61085e53..61011a6081a2e 100644 --- a/tests/sdl_audio_beep.cpp +++ b/tests/sdl_audio_beep.cpp @@ -203,9 +203,9 @@ void update() { delete beep; beep = 0; #ifdef EMSCRIPTEN - emscripten_async_call(nextTest, 0, 500); + emscripten_async_call(nextTest, 0, 1500); #else - SDL_Delay(500); + SDL_Delay(1500); nextTest(); #endif } From ce9057fc48ce6c7fda32b5029f8001e3a2c77685 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Sun, 16 Jun 2013 19:23:22 +0300 Subject: [PATCH 032/165] Fix AUTHORS to have UTF-8 encoding. --- AUTHORS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AUTHORS b/AUTHORS index 8a4dc9d3b1c51..5b4ee949c6315 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,4 +1,4 @@ -The following authors have all licensed their contributions to Emscripten +The following authors have all licensed their contributions to Emscripten under the licensing terms detailed in LICENSE. (Authors keep copyright of their contributions, of course; they just grant From cc19844b5117539c197f19564c04f104df8d9ee8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Mon, 17 Jun 2013 10:18:35 +0300 Subject: [PATCH 033/165] Adjust SDL Web Audio API backend to make it work on Firefox nightly. Note that this path is still disabled for Firefox, since Mozilla Audio Data API gives better sound quality. --- src/library_sdl.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/library_sdl.js b/src/library_sdl.js index e8c4b6b87d350..f06fade785bae 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -1579,10 +1579,10 @@ var LibrarySDL = { // Allocate new sound buffer to be played. var source = SDL.audioContext['createBufferSource'](); if (SDL.audio.soundSource[SDL.audio.nextSoundSource]) { - SDL.audio.soundSource[SDL.audio.nextSoundSource]['disconnect'](); + SDL.audio.soundSource[SDL.audio.nextSoundSource]['disconnect'](); // Explicitly disconnect old source, since we know it shouldn't be running anymore. } SDL.audio.soundSource[SDL.audio.nextSoundSource] = source; - source.buffer = SDL.audioContext['createBuffer'](SDL.audio.channels,sizeSamplesPerChannel,SDL.audio.freq); + var soundBuffer = SDL.audioContext['createBuffer'](SDL.audio.channels,sizeSamplesPerChannel,SDL.audio.freq); SDL.audio.soundSource[SDL.audio.nextSoundSource]['connect'](SDL.audioContext['destination']); // The input audio data is interleaved across the channels, i.e. [L, R, L, R, L, R, ...] and is either 8-bit or 16-bit as @@ -1590,7 +1590,7 @@ var LibrarySDL = { // so perform a buffer conversion for the data. var numChannels = SDL.audio.channels; for(var i = 0; i < numChannels; ++i) { - var channelData = SDL.audio.soundSource[SDL.audio.nextSoundSource]['buffer']['getChannelData'](i); + var channelData = soundBuffer['getChannelData'](i); if (channelData.length != sizeSamplesPerChannel) { throw 'Web Audio output buffer length mismatch! Destination size: ' + channelData.length + ' samples vs expected ' + sizeSamplesPerChannel + ' samples!'; } @@ -1605,6 +1605,8 @@ var LibrarySDL = { } } } + // Workaround https://bugzilla.mozilla.org/show_bug.cgi?id=883675 by setting the buffer only after filling. The order is important here! + source['buffer'] = soundBuffer; // Schedule the generated sample buffer to be played out at the correct time right after the previously scheduled // sample buffer has finished. From a4f4ce25e5f38e89001fcc17f5b0bad503132926 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Mon, 17 Jun 2013 10:45:49 +0300 Subject: [PATCH 034/165] Allow compiling the sdl_audio_beep.cpp sample outside the browser test harness. --- tests/sdl_audio_beep.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/sdl_audio_beep.cpp b/tests/sdl_audio_beep.cpp index 61011a6081a2e..fa8b0a36cf78a 100644 --- a/tests/sdl_audio_beep.cpp +++ b/tests/sdl_audio_beep.cpp @@ -172,8 +172,10 @@ void nextTest(void *unused = 0) { printf("All tests done. Quit.\n"); #ifdef EMSCRIPTEN emscripten_cancel_main_loop(); +#ifdef REPORT_RESULT int result = 1; REPORT_RESULT(); +#endif #endif return; } From 72aaf4a352bfb94726b3710e7824ea3d964c7631 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Tue, 18 Jun 2013 08:37:29 +0300 Subject: [PATCH 035/165] Document Mozilla Audio Data API is used as a workaround. --- src/library_sdl.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/library_sdl.js b/src/library_sdl.js index f06fade785bae..ecfc84cc4c067 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -1455,7 +1455,6 @@ var LibrarySDL = { // SDL_Audio SDL_OpenAudio: function(desired, obtained) { - // On Firefox, we prefer Mozilla Audio API. Otherwise, use WebAudioAPI. try { SDL.audio = { freq: {{{ makeGetValue('desired', 'SDL.structs.AudioSpec.freq', 'i32', 0, 1) }}}, @@ -1520,7 +1519,8 @@ var LibrarySDL = { }; SDL.audio.audioOutput = new Audio(); - if (typeof(SDL.audio.audioOutput['mozSetup'])==='function') { // Primarily use Mozilla Audio Data API if available. + // As a workaround use Mozilla Audio Data API on Firefox until it ships with Web Audio and sound quality issues are fixed. + if (typeof(SDL.audio.audioOutput['mozSetup'])==='function') { SDL.audio.audioOutput['mozSetup'](SDL.audio.channels, SDL.audio.freq); // use string attributes on mozOutput for closure compiler SDL.audio.mozBuffer = new Float32Array(totalSamples); SDL.audio.nextPlayTime = 0; From 7341ab196a003ce5fb67548ba2accaae6a5cd69d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Fri, 30 Aug 2013 15:21:03 +0300 Subject: [PATCH 036/165] Update the sdl audio beep test to new test_browser.py suite after rebase. --- tests/test_browser.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/test_browser.py b/tests/test_browser.py index a3b9a1c31910d..e8cd57e5b2794 100644 --- a/tests/test_browser.py +++ b/tests/test_browser.py @@ -19,6 +19,7 @@ def audio(): 'test_sdl_audio_mix_channels', 'test_sdl_audio_mix', 'test_sdl_audio_quickload', + 'test_sdl_audio_beeps', 'test_openal_playback', 'test_openal_buffers', 'test_freealut' @@ -923,6 +924,13 @@ def test_sdl_audio_quickload(self): Popen([PYTHON, EMCC, '-O2', '--minify', '0', os.path.join(self.get_dir(), 'sdl_audio_quickload.c'), '-o', 'page.html', '-s', 'EXPORTED_FUNCTIONS=["_main", "_play"]']).communicate() self.run_browser('page.html', '', '/report_result?1') + def test_sdl_audio_beeps(self): + open(os.path.join(self.get_dir(), 'sdl_audio_beep.cpp'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl_audio_beep.cpp')).read())) + + # use closure to check for a possible bug with closure minifying away newer Audio() attributes + Popen([PYTHON, EMCC, '-O2', '--closure', '1', '--minify', '0', os.path.join(self.get_dir(), 'sdl_audio_beep.cpp'), '-s', 'DISABLE_EXCEPTION_CATCHING=0', '-o', 'page.html']).communicate() + self.run_browser('page.html', '', '/report_result?1') + def test_sdl_gl_read(self): # SDL, OpenGL, readPixels open(os.path.join(self.get_dir(), 'sdl_gl_read.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl_gl_read.c')).read())) From 4afa3453f3fde6ae5069ec9a9c683a1b3018edb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Fri, 30 Aug 2013 15:21:37 +0300 Subject: [PATCH 037/165] Make the tones shorter in duration to have the test harness not timeout (60 seconds timeout duration) before all the beeps are finished. --- tests/sdl_audio_beep.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/sdl_audio_beep.cpp b/tests/sdl_audio_beep.cpp index fa8b0a36cf78a..95a5a7e8c05f1 100644 --- a/tests/sdl_audio_beep.cpp +++ b/tests/sdl_audio_beep.cpp @@ -17,7 +17,7 @@ #undef main #endif -const int tone_duration = 2000; +const int tone_duration = 1000; struct BeepObject { double toneFrequency; From 87eda4836bfce1a232f96b07d6c6e16dab42e66b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Fri, 30 Aug 2013 16:09:17 +0300 Subject: [PATCH 038/165] Fix bug where resuming SDL audio multiple times could cause multiple audio event loops to be accumulated. Add a mechanism for avoiding buffer starving a bit better with Web Audio. --- src/library_sdl.js | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/library_sdl.js b/src/library_sdl.js index ecfc84cc4c067..4079d3ef8e025 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -1571,6 +1571,8 @@ var LibrarySDL = { // The pushAudio function with a new audio buffer whenever there is new audio data to schedule to be played back on the device. SDL.audio.pushAudio=function(ptr,sizeBytes) { try { + --SDL.audio.numAudioTimersPending; + var sizeSamples = sizeBytes / SDL.audio.bytesPerSample; // How many samples fit in the callback buffer? var sizeSamplesPerChannel = sizeSamples / SDL.audio.channels; // How many samples per a single channel fit in the cb buffer? if (sizeSamplesPerChannel != SDL.audio.samples) { @@ -1619,7 +1621,20 @@ var LibrarySDL = { var buffer_duration = sizeSamplesPerChannel / SDL.audio.freq; SDL.audio.nextPlayTime = playtime + buffer_duration; SDL.audio.nextSoundSource = (SDL.audio.nextSoundSource + 1) % 4; - SDL.audio.timer = Browser.safeSetTimeout(SDL.audio.caller, 1000*(playtime-curtime)); + var secsUntilNextCall = playtime-curtime; + + // Queue the next audio frame push to be performed when the previously queued buffer has finished playing. + if (SDL.audio.numAudioTimersPending == 0) { + var preemptBufferFeedMSecs = buffer_duration/2.0; + SDL.audio.timer = Browser.safeSetTimeout(SDL.audio.caller, Math.max(0.0, 1000.0*secsUntilNextCall-preemptBufferFeedMSecs)); + ++SDL.audio.numAudioTimersPending; + } + + // If we are risking starving, immediately queue an extra second buffer. + if (secsUntilNextCall <= buffer_duration && SDL.audio.numAudioTimersPending <= 1) { + ++SDL.audio.numAudioTimersPending; + Browser.safeSetTimeout(SDL.audio.caller, 1.0); + } } catch(e) { console.log('Web Audio API error playing back audio: ' + e.toString()); } @@ -1665,12 +1680,14 @@ var LibrarySDL = { if (pauseOn) { if (SDL.audio.timer !== undefined) { clearTimeout(SDL.audio.timer); + SDL.audio.numAudioTimersPending = 0; SDL.audio.timer = undefined; } - } else {// if (SDL.audio.timer === undefined) { + } else if (!SDL.audio.timer) { // Start the audio playback timer callback loop. + SDL.audio.numAudioTimersPending = 1; SDL.audio.timer = Browser.safeSetTimeout(SDL.audio.caller, 1); - SDL.audio.startTime = Date.now() / 1000.0; + SDL.audio.startTime = Date.now() / 1000.0; // Only used for Mozilla Audio Data API. Not needed for Web Audio API. } SDL.audio.paused = pauseOn; }, From 2df6b614c001fd7c3c6e8fa13c510c903f09841a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Fri, 30 Aug 2013 16:12:20 +0300 Subject: [PATCH 039/165] Hide logging in Web Audio intended mostly for debugging. --- src/library_sdl.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/library_sdl.js b/src/library_sdl.js index 4079d3ef8e025..d6473df00471f 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -1613,9 +1613,9 @@ var LibrarySDL = { // Schedule the generated sample buffer to be played out at the correct time right after the previously scheduled // sample buffer has finished. var curtime = SDL.audioContext['currentTime']; - if (curtime > SDL.audio.nextPlayTime && SDL.audio.nextPlayTime != 0) { - console.log('warning: Audio callback had starved sending audio by ' + (curtime - SDL.audio.nextPlayTime) + ' seconds.'); - } +// if (curtime > SDL.audio.nextPlayTime && SDL.audio.nextPlayTime != 0) { +// console.log('warning: Audio callback had starved sending audio by ' + (curtime - SDL.audio.nextPlayTime) + ' seconds.'); +// } var playtime = Math.max(curtime, SDL.audio.nextPlayTime); SDL.audio.soundSource[SDL.audio.nextSoundSource]['start'](playtime); var buffer_duration = sizeSamplesPerChannel / SDL.audio.freq; From 4c845acc4c6e370825522076d1528df4daece274 Mon Sep 17 00:00:00 2001 From: Richard Quirk Date: Tue, 24 Sep 2013 21:27:55 +0200 Subject: [PATCH 040/165] Fix entire surface alpha blending with SDL_SetAlpha --- AUTHORS | 1 + src/library_sdl.js | 3 +++ 2 files changed, 4 insertions(+) diff --git a/AUTHORS b/AUTHORS index 5b4ee949c6315..d8f9da02678e3 100644 --- a/AUTHORS +++ b/AUTHORS @@ -98,4 +98,5 @@ a license to everyone to use it as detailed in LICENSE.) * Ranger Harke (copyright owned by Autodesk, Inc.) * Tobias Vrinssen * Patrick R. Martin +* Richard Quirk diff --git a/src/library_sdl.js b/src/library_sdl.js index d6473df00471f..63e8b2b128474 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -1131,7 +1131,10 @@ var LibrarySDL = { } else { dr = { x: 0, y: 0, w: -1, h: -1 }; } + var oldAlpha = dstData.ctx.globalAlpha; + dstData.ctx.globalAlpha = srcData.alpha/255; dstData.ctx.drawImage(srcData.canvas, sr.x, sr.y, sr.w, sr.h, dr.x, dr.y, sr.w, sr.h); + dstData.ctx.globalAlpha = oldAlpha; if (dst != SDL.screen) { // XXX As in IMG_Load, for compatibility we write out |pixels| console.log('WARNING: copying canvas data to memory for compatibility'); From 323b01cf131118ddcd0aa641c5762526f8654edc Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 24 Sep 2013 17:49:32 -0700 Subject: [PATCH 041/165] sdl alpha test --- tests/sdl_canvas_alpha.c | 46 +++++++++++++++++++++++++++++++++++++ tests/sdl_canvas_alpha.png | Bin 0 -> 169826 bytes tests/test_browser.py | 3 +++ 3 files changed, 49 insertions(+) create mode 100644 tests/sdl_canvas_alpha.c create mode 100644 tests/sdl_canvas_alpha.png diff --git a/tests/sdl_canvas_alpha.c b/tests/sdl_canvas_alpha.c new file mode 100644 index 0000000000000..1a41d115b090f --- /dev/null +++ b/tests/sdl_canvas_alpha.c @@ -0,0 +1,46 @@ +#include +#include +#include +#include +#include + + +int main(int argc, char **argv) { + SDL_Init(SDL_INIT_VIDEO); + SDL_Surface *screen = SDL_SetVideoMode(600, 450, 32, SDL_HWSURFACE); + + printf("Init: %d\n", TTF_Init()); + + TTF_Font *font = TTF_OpenFont("sans-serif", 40); + printf("Font: %p\n", font); + + SDL_Color color = { 0xff, 0x99, 0x00, 0xff }; + SDL_Surface *text = TTF_RenderText_Solid(font, "hello orange world", color); + + // render + for (int i = 0; i < 255; i++) { + SDL_Rect dest = { i, i, 0, 0 }; + SDL_SetAlpha(text, 0, (((float)i)/255)*(((float)i)/255)*255); + SDL_BlitSurface (text, NULL, screen, &dest); + } + + SDL_Flip(screen); + + SDL_LockSurface(screen); + + int width, height, isFullscreen; + emscripten_get_canvas_size(&width, &height, &isFullscreen); + + if (width != 600 && height != 450) + { + printf("error: wrong width/height\n"); + abort(); + } + + SDL_Quit(); + + printf("done.\n"); + + return 0; +} + diff --git a/tests/sdl_canvas_alpha.png b/tests/sdl_canvas_alpha.png new file mode 100644 index 0000000000000000000000000000000000000000..fb9d61651fa5ff92903cbade5b5b37c34b06427f GIT binary patch literal 169826 zcmd3OR#7IgvNF&`LB3+VFp2zohoiFDv zINxBH>w0G2_ugx*z4jhr!CK0=SQJ+$+ucHb7ho4hT$Ebv4me`Wpc1HF6{&i~&(TIXy zzk?kygMN2Rn(apQQ{vfZ(ik|MBI?3uTK@zqVhDX2C;6)`8CG8cOTGX1IX^MOnE(5; z$kL>0AP939y*VE)c~OnYd^y1QCm% zBq0VYgb7xe3@hwiBVAz-%`37?Z=sjo9nb2_H%~)Q^dus-wOo}*4hm{n6V0s4!?3(( zItnK7TX1BT)LOQ5eh?R@v28!Q47t2u$v^X)77W&DU%xT)5#bIB^L!8}OhkTqMzj@| zbl1FTY38B6@@;;qnOd5}|KX|j^i6kZCJDun6N|aCH}-!A5(pJ%`K|#ghOiF30YhjG zWoQm#Fe(~380~MydZ~k2<^7Kt<2s02txv~TM3X&iNn_=fuh4u0j(u+)YkyLWQT-rv zb$q=Q%zOm`{tUZ=;CKPElUu~WFD{bW_vQKe9xO7sxS3luS+fMt? zeOk2Aa6z=!cDA{+aC0-dl)k~J#d&inYIqT} zMG8~_xtB{L%aI`%`b?ws9utas$Jgeu9}3>h&`W)}`RzUXTsQIli+qp&OGoz3%smWC zDdjx!k2O}>rbV7My?e3V8Jl~lO$A({lfh@#U5iG|S^-$?K|jRenHP2L)2VO26n~X2 z82@)S|^C_lrm|s&IA&Ise)OYv)@aCRO7)PjQj^*C{s7LW|~Wi%p`u&6r|SUYff? zU)a{TF!9<^X;)mLy9h@pB1?@;R;A9aT^t|#@t8gv{T!AKT|bqnZDuj*ej}tD?KQ4+aOr^+1ao0QRHvINU>y*sYAs~ zVPP>R&o}RA-ieCeg9K>agN6*1i^U9onEBqj&`nL=I>nZ)PkzTnBC0q74y90VgdJb( z9coc{t-W~O-SS7(dIi?J@+Q!18r2qsQ>{BsDl^98-J{7dw52`ev$N`g(UtqVAWqg( znfk)v26ym_ZS_Dd;)(VT)iX_(P5LS~P1qysEH>h))l=;SA&*2-AJ>wd9Mv16|HX9L zEHBRoQwc5YC})$8O4v*AV3{@h!DNq8<%YxV5FNErl0#Hnf#fy0I;|N${Z6R_m#CzY zkJT5`AP-O9qx=DviIERxN5#%S0`|dXLT5Ib!zwV3=sF;2tV?oDsh&AQD+Ol--!@`s z`USeCGRJ{kYV(Ym&x}(z0|E_sYM@hFo*x8HtO<+QM=0L2Gt@ZKGC6(}JXNe$NO?j_ zlyAygmr|mk!H;N9t-dfC5hN*IDyw;Jm7qkAY<$VaG1q}S!fq}O>KY$2#bRLfWiY;C zVq49$4gwuN9xq6)%=2(va(D{RprGJcdA|mb! zA8V{F90`&+$NJ~No_|5dgshs?dMv?yM_$c*ZFtRFNT-&rMW zp{yohwLq&bUCBo}qx8rU7qY0z?_8KT&vRRrJZtiKA99i1e(MPJj?Wx!H zbNiUyoZY-MhLBt_<>3;}KAb4j7cK(uveeOBR_4^uL_M<7fgX6GATluKHTn&YDSi}V zmz(Lx{oNm`6@Px`ARr%A;G>T*XOlEcpO0x=ZPnXB)j*Vp|2u`!{A`upIHeLY+V^pO zXdEvha~16NNgDMco=XtY4qlGaGC{vQVku3rHtJcgM_sLC-uZ|}w>i?$)3}wv$b!Oa zpub5P1u$#Q@Ca9gNsDlpwAJC9PrM7A?TYmlw2?nBhqFUB3PTHD^R8^Hr&xb+Bwc@G zRsPdvPhdh&;$KjFcSo4Y$-X&%MiW@*pt+htI`YyEXVgY|FtJAu)&UNRP= z9WdxjYJ(|r^`LGPvrVCGS@LOZ3Xga_Lhp2b!U6wFvb74 zwPDa_AR^A`R)Ha%&>!|MoBUxFI1BQi%19rh>rS|4bFWJqrsvMP=@bl25wv-LfWag% zpkx$8ybQ3c6@QuSJOyVt6F{)fqNCALFFNR|=Y$(@d}I`i;SMt1E&I0M8*pf0uzWCLNz z&r&mH#ghCxsW~rn3U)c|mgN--YG^=e_zG8|4D-`7Et6)-H-#TNoGPEwj-GGpVP?$SiwT($=4@0->idPGs}vtN34Sx8^;_{SyQ|^ zfGlvanVG+&_a4OX4isP;JG*owaib0&KkFePfL4w5o$nzvPNce&4)B@WFHfc^WREjw zB%Fk-O)`w-Vg+!5TFoC$IK1F+$zZwyL?Thn2NLM> zb;sPdeSkLN_FM6|Q?wTh%VJ~#!1c_;`SCTc62Y{vVoAY0pC>r=P2*$Si3A%yKQq)` zOXdtz9MtJmRiDlr>y88o)mr%i91Kxpmni=AFuJ#oS%WUkoqBk3V_B9OM7yD~^IN<% z;T&F~fZ_2M56g5^mXU4rIOa0RyUxN7D*B+qc81woNQ(X24M!VIqJ}44oy?jOFL42o zyQ`eJOUvBk7<(W(Pe5wV2T4H5DJ zSc7*WdIG(*-P#dRC{l-!zO90;^7S!UGQ$c=@YCO$OG(y2G{DC2l7zPP{ z@;s#FY=W6mL%UQ%Gye`HHD7fh=(cj5L|Xy$HEFPKk)fIiln{P9D*K4B=DE|P9)}l@ z!9e{i2a`#w^wpC^JF}tg{bv43ZU40~+|B8 zOBhE{SeI5DPg!xMh(=glUE<>-5=78f*u2a2$9F`L_xMvWR^+eXN-I!YuO6zTUb|#D z=~*QCPj3XekqOr$a#o;%jr{>p;&rD4se&Yt9t@-P{AEaufG{x*MlAy_^}1h$i#OjT z`WFxWk7EqWxZg7n|ENezwpImmE9K5N5DbdRWZyY_J$=Vw7t*HlGDg=KYD@A^r+OGX3Uh5(& zF5ai|V$dr84<$(qb9+#jb%vR3teK=zeR+>*M6Qdoi<$;gj{<~DyG33%;Z@kR1&3D} z(kzeKy6e>avY*K&yZ}$Vt?ulJOw9JZ4XL^+Nvz1628?WPAoEd`>O;!>*5jRzM|hyV7DrEB63(?3;)jVI4F^-M2e ztuO1OHYIWeeTb--%LK5B741#gzYftac!>k7x{}>4{kj2ONjOcosXDO>edfhm)xk+R zPUBH{SLR2lYe4u|LTx~h!+6&#qPNTB7?_`h@D+KP`-6sxxB^X}WLdSspI!vc zAtuhZr*^DZC&R$)`R~A6C;PV(``>Exz3#%8bxJ_D8sWq1ks~*{-hw#kXI=WF`yn30Ns~~B@tB&llQv*qdw;$0YD#sxPP7A1gOx7w!Y}2d z`EmN!ajGlvnuS(3d(ItjstPc!wR|{g+{5tSP;HYZLDRcFfuJvRaDP?UrFwGa(c$=5{2hoTX6I&7L;uPtkXN7VkY)l4xZV;)Y^rh{N^0Y*a z>ylP9bILDEMQHj^R)<*M;9`dc8Tp&dG>qf7A4sjLc5Jxq(`7zAJ6t{mti4o174p@l zaHbRF4gBTvJY>*%!_8t?XqqrCm?*dE6@P%!$js_DmN3+QBzkHQA)rcXP*rW0n;j=|(!7I290SR!Ki%#T^ z89HU=hFO6By^1~p*UXQD{Dh@M5gy!z@#Go>^|Oqy*9l#p#{0~M-@uHuV-Lzb!MJwu zQODem&1z#Q1#g0KoK=_WbD(4-3Pz+maIWTFEo3-2c+5pOmV^a~iPwDY4U;-nj1Ktc zVou!jR8r5^C2Yz;sOck{(>7Vc88KOJ?n$(}Nrc5A=ex|Qs6PxEM3FaJlO+n#il$=K z09(&o2mWQy0K|W;i|p$7H!H;yqhHKmYnvsYL$n9oN0UNJ@eByClX*Rq7zFCD!9-=I zi{25^(s~gAsjHKE@8j?MZ)y+tn=cVq4tEH)cYluh=cTl&fbNxQqc5NK-MfuXl}TD@ zFEHRouiXSNdFPwpi32DhNu$oON>&}D;o(2v5Tb=&C|3{6MwJrd-o}}OY5!onhyg$X z*w5|tIi&L*;fyd(F~r+AgefPA3`bPGloX1tK{+JBH|J@wRMYX+#-87 zCRry{1WY${^|EQL-*i7ZChBnoaQX){v(I+PTImseuWx5arUh@l%yM$Ygf4~_jg_1=SSgm~s5o!gnycZWh=-Q-bFlZfD#*!}XL zmu;x++^8QLT}-iY0GG%#o6{a17cpTNMpRL35HRHzT}b3L^hP7AzD{s=YZ|}LWwbxA znL77r35B`1DDlgw+G}ey&*;tmTfZnflZZkf8N#d+q_llkv?S-dUu61@v)}jmXt} z+wkaNznhaQ>fn>sN*4fxky(UGe91%^LAi^{{;m2;>=*0yw!5!Kd@2<)*Vh7V7HzHf z(j&JU%Q?p6gKqHzy2Phnuo&JjTxEjDj-sG3OvS#~+gQR45(d)aRp=g`Clx7^$< z>kpI_d~gGOi`iN#TJv}}&m!VqyMZZ>ZB49}0C>UcA@~)n_D{0~ssX>}-bt-ysN)F_1_(dIHiZ_=7r|XxE;9m(r_~x13lw0=2x~TwYD&JZ!9U>_ugtc zpkJt<1)-83G z-=>wT4X8Qr@Enw}0%UZv6sj$V?5W7s4;OU>u zs7Ql>Vt3}ETz?Ps+Iai^6+;H5tE~7XH_ia&!kT9G0d+ReVNtwyXTZOV1{yh*txBT& zds!t7;B4>i0EW(rULI1#&G=A#z|f9I=%0P|ahn0La93i@3t6jQnzucp_R?s?4>Q&} zak!Ymc0DM!-M83%>WcI3UmxJFH?Loj^MTHSIzX zX5Ol#q5?$rY1TjK_Mefd4ML|kA`D#GC*pC`_z5kfiU?vuANE2z-9=gBH}+GFaCO1x zZ4!_>Lh2iJ#Gph6J0B=l++?{Ox%S+wBYBlEml_i+wd1jrX^hcjpj0XfJ=mB;Z20Gi zj^#k5)L&vFd-q5L(A!>ns`c|hm|+#nq~^3-!T~7s{@ZyB{%e0#xM<)KRK0az4R3S-x_2t0~ zeY{%=e>DyPzXH;_f?Z?~Vfr_D+@<13qKi4;ZOE?xD%CXkvgsAY{f~tCR9F2Xly8PD zCGc0*g}2j^>c)Ec3?p(BxC4K^KGuZXvG@y#ZGHFZkuPvNc(*J{H6ZQuR>OaxRisx; zQnIDEzc};5yeK?MRQ} zm`1z|#v~aume(OXiwG8iC;|cq0T0ZOj#3mDJndRvonKGaC#G+;n+_lpF=F9-u$~U0 zz9VYH0wK(}J5J1o_V5H5CWuRCMHyzu(&rAORcyzO@{CBMoG^9d#-#534a!4ZLyyjJ zGbhdr75AlLcFci#^{x1}iDpk7iIMRu5sbwa#cV0=(jR~zDkJ0uK#KsZh#H}{2yt%3 z?LHBc*rwu8*TKOv#KE)0(sHJ88SPVlf|b+Xh4;JpyYz01Pel?;t1l*^WRsM_Hy+ri zxT*fx&4~#zdj_r${d6HF_)Ex}>Oc*z*?JDD|ahhgx zD@)z9n(2#2>8wV2T`9v_Zb**zTx8q1{I`Ypxa4@22MBmRMJX?(hp56NCdIG)NYgV) zHFTLXPGGb{0JuitRR1evBCC%gPIGu1P5olzkx$*7sEZCb8R<$DbKnaHpwvmnM$6wV zodD#f)+finXsj#2$d?uEPmguvTIL3bN>y@{1uR&-P0O(mL(_#iQ@pJik|N0(i@Jbl zx=lsnao`ZPcq0b!* znI;+GohQ5P82pMOP<&!htc2X5F0L#IPY1H+b-SqSF^cz8vDh7 z>Ip`SR}dO|`ld$O;Q*4lp4w(Xq?zJcnmVs`Y~=!U*Mn=X;A)s!TuCa5Um&?r!2^>K zQxDA+x$l2&D~|h%FlN*g9nC>>WH={YA9n^OZTVK2#ofXyjOvOPrYvGdP7 z{n{tzt*_nk?cZ-ppFJJEwExP*c!jcyLW_N|;k+N*?`^~cA770YHZuIeffmg&dZj6V zgWNg%3zFl~*YPd(G8F^8Vw(YUitgIC=M zEi3x)YaSSK74^Oo>p`%(RL~55 zm~XxVagO$G(}pVkXWGeArCX_*M0`OZHSusB*GUrnoPp*Ay3dk_ zPsp$vGg3w@Yxy zJ9B=}Zel1ulv4>p)o&*8>vUg|+Q_jEGCmxlqK!U0H5W=xxmznlC_+|XmW9TN|K&@u zp?UiNEk`*z4RF#lYrmvJ-IPNTjKXn9u#Xrw1lwr$1aTui`TUIZduem}l2Jt+Rm2d* z&uq_F=ri{iMp$C3`|^I|C7erf+w9RXvlourfP;hEBiFHWYJroqtMwH|tR*%Tv!KI~ z-@vD*gEwDG6qbqd2ymZr8azL3wCtgA6?hlU37i7`jskFP6|)mmjWUC=hBZh#E+sK^ zX_^E=S2WvCLR*d7hB^XSIzP{jjQr9dK~u+3GR;i+a2tX&i%x1)!a6qeB!smm{g>tL z)Tb=-H%$MA&Z#v?tw4c&^EDH|!kN>9HG4l~rlJ(;xqE|nB8#h#WxcW43u@d7<9hF+ zB~=VY+)S1BV-Loe7#O{WLEV+QY$6}a+|b3hJ={-76MIA+ILH9QHMq9FEi3$u|BG5c zov~q`9fyQ%(nOllMy@{+W=lYBuo&6pq=C26b|KI9QFEtC<5NBn;l=$vox#gy8)^)i z>Yt45=1xGfDv^Deo7~t>@vZ-HeKo;q*~F?C8%|aVpRw%kBCzp5P)%;r3-x3}M{nv= zb?wzZROYl_h}CQXD++^{K=l8bSd=x*$7kt|uQuxOd(gbNKG91O30-px2zpp18T-)= zTy-FjCrmNi?GIo$5=%01gp|%#wmP9t!7OIJtJ|~I+va0* za1!Ov87JRbDwz|dd{A{9Vu#&fzq`3KLlRlvFAiA1E)u8aOnwd7SlBoVv?Pz0GR-OL z?W1Xz=>w)l#d~Xdtj`u6L_z0Zyyt@!h~vI|B3op!aMb8a#GAF-l3@0*dAuSA1jKnB zu;yRlCNE0dI9aNTAqeTd47{0IDlvU#s<)1Wyw!woxm6djWQ8d3Uy!86;PhAcX+U$m z1BWD_|7NPnKu|ee=w%FFd+HJyOg=8rdCSQCTDtaa*X)~g{6T@ zBa5Ntzyb%)91m}_zcV*Hgg)6Mi03dJsjm_brN*`Iw!5hZtYuN|uXAR(#@;)DabEqq zXA5M7k6G;{NNU4BhjU`uepbOcn}_n7SNkXQCCGpxA_y>~Gf4bm9b;K>7XgF83=NS0 zqMMUlh>6l{ z*X)~NLS0`VNcq#wyCjm5xBGr#$Qwck$(DX(JECg$rAdlacS}};2#Us_0g4XSwQNB$ zG_(?#My;pjAarNs^cu9o{dE73?T!R zh~U>@2QLfE7KJvZ_}R&gLRPW%u9&|v2bF{i7iGKjNf=shUf5VwkWt;vy46^3SCDbI z)|gx8VXym(XargS9%523Dq~`w!e4w&b;b_yS6D1S%|DA*4$cC^fec?NOe@fpzSNy- zpSSxLaR@@@+Z4j;BB#v06QW4Z>sOD5RF8*$38mhpcw6wWY%N&4zV)9?X4-1O>8)!^ z>Us3mn-z>;3#Sld3DHEN^rz3r`-FQlD73`F-TPEr;QUJ8Jb_cFsaFePkh>Xg1)*_q zrD|>?A^UG%fn{Kppqj0)=7W!Wy!%ox5Sj9PR(yuIEeAUGt#su1-!9>8Va%AjS0 z!|Wb*0Rj_h`lQ%!a`;yeY6{%oP<04!X4cdl!{6IxOiVkI1xqqzt@(j zWa3osNJ~cB)`>s=j(`*|47Mecsd+V2Z(R3l>+2(hfVMn*&R#Dy=EalYoXeULvU&ga zI2S5>uaXiSnXh8KR4l|xepvI~C=2Ld$<1)Mj!ZU61am6!eyD%p)TxP`?U`pe8AsN5 zB}BA9HnE>&2YFh}gxkj(vPTdFx4NqWVNwwLXH1T#PaxyMeN%tBd<67eKya0 z`>uJ+&!6v+!fx+D^dQjFs-4>}a7_{)s96lPNHbJ9FKUdjM+@Cgh-B4j5gVR{Aile8 zp;_k9hA*gw2yN@BcefohS6$diB$kNx&hjN#`NRM4EH1%6H>7f;f!)!q-J^|J>FTi& znxMUdxEs=S(1jiM85LZcWeu zVrM80M%Q03J+B!8tD2wdh__Ga+^Csv1^*PQS_Cq4yezW~!jV$FL*1b_IyONR{stI1 zb$j)S`=jb(|KZxaoxgOOR(zWbNEU*vi^g8=f2(qZh|P?~z$*t$xH^tfHb&8lPXOcM z7e*t^B8~5XHIX^PE5=JLvgECqqX?5nc4MR!@?pYQVDNC3)dMVpX?;=thrx zl=>|n4Y%H37ieInhoJ!M;5qD3iy$4(weNC%!l$7KD~fty76{(%=D{OK!D z08FXgx7-52lpkL)lPhJQld03O?%VU@2kpw10V9^w8q}yiOh;}jW@!iyaR}P6cG6$@ zV$cTlsYS05iD;zc^Q6ZnYhv zjyVVWfgw=2C2<=B!++fZG?n4qhL<9X_h2d^_8!sIuu(Qp$#RRkf;+A<@uHg^PqA!< z{I%s(A4y8vdK46%z`HGs+w*#qUruruvq`T$4-n>68QzIpEL&Z9VP_ktD7NVC5w+Ve zErkK#aQ1-qM+9<<0T;&PCFkj>ztdgHG}&hAf*4WCfxXj$ z#!>aY+uY4}j(5$AZd7{$GcgJ)6vrp_L)O@Uwm30;wD+T&9oKl(uHW!`S zAS%+A`ocIgD94u9i(yP>{mh#A{ex5HhoDagACp8e9)6Sb{;rLMnRF)|CI%~bi7Gg$ z&OM~TTnjJnp(MNoM8eoQT}~7!%(Rljj$sSj_nBe60=bpQNhNm)GF` z5==cm7k(Z<vTVXO8hnQSZ}NSW&%GBRciZ<*nYV88^xONLTJDCk=mM?@6Yr zetW&=JVc`#_4=20A2jWS=FEtG{qu-6w$50d#J?JBgxTJ_dc6IukqiTxEyR=wr&P7> zxxQCvw_-2Mj%2{|k<$U_Rg0c5AyRO~NME~Z{axcz1yX)`be_(6O(mrD&o(8QIii-- z?&EBW=X+|;xMU-`+CiMkZ4Uqys=iNZ6T$zwr-?1Z=~Ga~-^A|5{lSTA3O^|0+^M ze?nKL*}dos7qPHV-*Kd^xWEmfo%D-xllvb3CaMMU&?)OdL!KpIkx`T5jPrN~evUyA4;%sF5)0qBUfDjI!_MQyuL91BiZ zkA!tZ)C@1=6os{_P&=H)OGakG8MhrVX8*o_VJ@FtORupGGuJ2$mK?!IE2T^sCF`ps z3gdB0Rh0Oq9%gx{yc>rCmygJPJS!0$bZ0Q+w{Ha~6kfgq6am2#qV7*Dw7o~X^@BFr^see{*Al@8EtgXm4KLi_D8Bs7_#qDw-10j>qUcQ1op}a_6LG-^5e^Hw}4KI*76A4$OsPKP&mqF^QqBrm{ z#P8Ma)Ob)v_ZLEI`L=fEc|Jw@Vnu~t$KhLXr5O6(Wt?hY0rSnw1De0Vd5J&(6WXxk zh6J1{@?BGbjqWKv?<;6mB)cO|pvi`R2jJ5;6{n);t)IzU2cXZ=*Rp^c0P^_~`r^VE z`tkKzlK)UZ1-6A6d`1Gdw;SlH>U)xlqVp#EWv6;4_juqFTS08`lTV5n2+5L&zU2j& zmsxjauPEN`o}hvRM-k^J>gbR6WsNeFKh!e9GnK(BFwiE9tsT-{s35ufy?9?qA*Bx@ zFFZCb{QLN)&atX#?o>&@CrZ#L{p+dXU)m^skAUgeAbLj~*t~%Mza~KbfNt!GfYagq z_O`as;>_!O-{fmPcm9jti4F+!>584N;_nl2l3cESES1r8d|gSbtFAatyk_cpGr8k< zN}pf7KZuzZbI&h-o?A|;)>5C;_)qDDJ7tNaMJ`TSelK&hK~w}rbcUgxk%ZOr^mlur z^d?<#q>aW@!XMq{G8LXi#?C|PBC{ryjG|`&>;9UqBYg;}_JgeA;zt>i7VYR3@q~WI z&tv5``_6N<@vst!Gdw^O6HLq4QyG}`LKF#xkF&Bp1L@I*^*B5~%=&*de7C*I8N>|f zOz(w^mO)bF2mEliS1j&=n~_HdluEvG$nkU4hqeF<5cJ5OuNdCg2fx7NjYP?gX{o04 zQ;jV(BV3sL#R9>a%#rdlh~C<>ZVLETI6eChg|41rq#epxOBfNU& zFT(VraU-0!GtuOhXZb6(Eut2C&nLp|?1OM+j=rZ=s>e(Fh`D?_Roy8=Q?MwhEiMu8 z!moEPDiJdU(?{8WI?Zelsr}Y)oLYvy{SvWo(KRFH`4-wzMUPU`S#4idn6;dVZcJyP zPA`%(v^~O|Uyh_@U?!i|j6eK|HpMmWoVz@nP0PgN67^Ep@{JqSh*qJP#vWkv69qm~l;*6@8;?e*u!;PKn@ z1Wo*;C3Nu7B;7fw`_l7^^>Awt`;c;RZi0*ENYNg7_umD~MLn#^UG)S2F4w0Ha2)iy zWtt9NhHVGyIh0TC_}ncl`MuwIBI`Rk(eP|6RD3E8MJtQ>&_TLlqveGV9Fev4~1v_ z^hNH{Z$({Bfa#xBTq(WedaBXaMZH4!kJ&EK;iS3JIoN+Es;J!dT$OwYP1d zC2g;MB#EI;iEqktsP%E{@+8fwhPYY4@_)E5cSu1YiO^e`>J+M1W%^IFhFc1T_5{#6 z-~_=+1n@ZSjS&Lp;t4;q<=?Z08%iDawXnXI=G(o%RVK0gj#{wZJ6QU{fe;C4Ro3Jf)TmcB$kdlIq^BWK!bPSi5lB#%G#}S(fsI$TQ8Z(h%$^@`|BBv1ooP_EO2Kb8=@;91 zWAIee>ylsF#8l=ZKdcqsgI;?|Q*bE1cs@gi^59DhG%0s$_WpT5dGuVPf#F|Yha_A1 zp=8`x_G$LJ*`w!77wMcowIRz=$TU@jz5tAQpF4xLt%6RRzj_oU|Hi$N7(72ApO57e z)fDU`qYnX$pSaojrbfWy@Ze@99K#reI9E8*w>r-9?rhQJ6FSsYnlLw7kwn7qKHK29 zEA-rnN|~nIEe^{s=eLMCUnr^fqTAIfs-FL!1ja)fp5K5uGiLwQt7FXN50}A4niqs) zaod=9y9}VMms^%&`~)o@wued2>v@uu{ux}tAPZ7RSz9a}F}R`&M;eer`!<({FjA?5 zV2$1HFxD;D4`%^bD(v}EXz7;0Sm%@5;c)e_*!Nyx1AR98Ah8z! z=AL2c*2^B(;xH3Rx$|d)DouA30b@UEU>I8zUZAcJ^m42as*i?9e8!NOD*;$(_21Ms z1W^8(VaXCe>e{3F?_~w{FYUm1#RmR_(0S?7+^C#q2g%s`YpqPwk3>mQhePg%GKA)G zX-)Co%|d{62bdo-hHur`P;3JrE%}4)iqaI<{sQ?OINiQQD2`m=GBW>}{geu2cOJmk z9KImG;AAtE?bIOBKqBQLU1GYrW*W2N!nRx6SKd)WV=-uR{|zDdD1A7zxF~+{F@2!O zzTu9rJ+zL(!*6*ldB_zTHgn0jaG2-xv7JN_97G=6_Dw9g+AO}r{=Kiz5R!m5A0N+! zzuA!?M464MAZ}+j4oAyAz+H~M_A~DYx z6y_4m|I(dESo>L|KBWhG*aKDDf^#P^#t9_p54d%dBJ=1morkf+2goA{Y6hK;dwp?% z<j!J(H;qCJT4qY|9ul`6Um*1*#=Ju!p6I zU+xpF^?IO%#Sp_mX9%iDg<#N9vRdpMnBaQM+|F!bOHYyFBU^HoMv%y9=leF=pIfZ> z66tHB1eyRE^UwjHD0#i5(iD^1qlqFY!E5K27Qvi2x(Q4ofKsTBZkqgT3jPC37IJ$i zSQnTP-AJxSMGjd3Gk^nDps{uCL6gXV*ZbA_^-m zlZEf9Yj`RH9IAM?FDB6tn6zd_iF72YH)S!H@?Z!!O86EK%R%yCL8=xKx21C-hfny| zY8$C_ZJ~73Tgyhf)WM%6+8dYR+wd>_WP2MeqZ1`DLRyF?*HtoEe@th8Q;VF12st`P zjR+~|g9qA6k|}7@@dW9 zP`*+`j22cIhRHL`khUeIJC-pbaAWr3mR{g=#bvWb#q&VHLHSZR`(is3%x)dO)|Y~d+)(yIIXlUy zb0u^|&=ksw$ z77IV8e~y%Gha5zV>5%xvWHDtb3Y~j&qC*drB4$K>9mscnL5HeSWPApeflxQCsSwqX zo(5!e}aimf_;+)`+yNCGLDC&wqut zr8o;D`xWEN3*{|+spWUt?Ob%_*6Ti?J%qgGTJo@4S)RZK%*-Ia>By)9GOh9Jt)ui| zVb*xps)oBNzF5*cZu;Y&%wh%KlK!(n@%&)e8|ZAA8EHriXV!0i=K9V-@cZyl1+-Ys z=jA2u?*CD}L652@qOvzCRi%qU`g%39r8nZd*9Y4jtfL$A9qR6QB#M`)0`@?KErv5j zNjP-RV=n&fLLNyKdcDJEz)rQtUrF-SC-t{ma!awt%_~Mv$Leb1PM}x;(J@U-HSb%x zktLf5$fH)GFg=+VF|sceQgc&yKVn|LP$rTTkwc|wvVoidCAK3UG3@D9Jp^vel-&ZD zR*44p2GPL5G@;BzGT9`AV4miE=PB&Kf5{&QkASQfV)Fuwl~9e!e>^YYlVT%h7_}9| z3jY=Phpdm1oT^4;3)PcixY1vL9nD<<(gPhWdru(JK_nmXI)=3k3f#9qB`->0E|`$YWf=Q0k{j9l z`vN9Q{|=L5Hwwo{1EQ!%W5+{0usLxHmuXG!`<{rDRD1Pfpp3~Pkf{IDyuq&yskm+N zBh|O0UN%wrme83U#mAF!2C>{CXpY^Wo00mrq}|9Bp^O<^%p?#8eder~x774q(>PVTQ% z?`^dVtJqhv?xJLoKJ4QFoP)&V`*U*}p6Bt5Vc|d^(+1u0+ooara%Bv$Z;1La{}FU= zJh5?p^|viO8${(Ae}RYxV6$uL6>bCO9pEgMaz~J~LBuJCQzErGsz-Jz0FE^Bh(Y1U zc-*X6?d}oIjlK`s5EYy_i>wJh@Bj?Nasv@>KA{KIVRWOi@1Fm67k~#?i|``Jrb$3E z9wv{i{@F$$zuO6Tm;d6z#Z@%ANG z_B-7JcNQvkGDMao>xgV0zGW~2N^O4Z_$lG`&M|qTyKl%~T7QoG4QJjp*m@;Z5fPUX zi2{~~>ZB;11g2!5bdKR{DRZ}wnRTG}I1d!|Rmn(x@ArG6u+6u1N6YIjm(_X-KrL_! zP@sX^H^SjS7lDtew|*q!)`h;k?4ocw=;lyKx>^4D4$pkhSHtkTlXJg1F3|5MX?=Zr zhh5c#`PHyAL8T5D6y=472o7F_2@F_FDA-pDmI-jYtGz8f?I%l`8knvIU@saaa5iVy z{*o?<4RByi?DTv}EplWMfoTv>fZ^y?ag6Xn*$D!k3P-Z<4tg&koB5#+mi8e`M?q2# z@d1DCQaC&QT~94Mp_+Y4WhY!#fb*h>qYZRnp-9aP=I60VZiBP~NYB1?t|v`F{B*nw zDR<}0R_x@DbucB_$O?cyI3rHZqY!%i1;#^^k|L$*JMdRYZG%jQiw&?ATky^#9NM_O z2i;>6QhQw!%C1(rGM#8bFb&q1iHR~I9Auy3uD#ItAt&r0JR@S@j>?mZb{=*^kz@$8 z8O%wHKm{prBym@`rPpr3e6!AkSz7O{j3%aBX|-)_VV%2MO8<_^?zj-w zku7~)q|L_Wow-<_IXiLV+i4R(c_8&&BEt-JLFob_m59G^=0q2qD@nkLzzL_pDmh^0 zPV)Uq1j7dPBCXj2i+cWn6Vu7Fx!m~)*5J$TU&|3roe1L0TN^yRIv93lF*`PZAeBBG z^j&zku+61wqqdDQ=+?o|s}|0|CGzQDXhfMjziNNj{{PVQ)=^P?@B6ok zq7w3!E}2?6P$LAtvorBNyA62_r(hLG-5y1QF?=4ml(OoPN^`u21sD zTuUcCx4$D)?f$NT4}6lTK71gYD)e4v5ZSQ>taa|LjePsHk;4XoB$}K<4s)6%VONr+ zqtkyRYS_#eNR()O#A?`629jR3yj(0Hs!`jbNe@HJ`9V5r@(#TPzb7<`!AhR_PT9`$tJM{% ztZ}cMF1#7K-&SdTuIl<6jed?5@qmXNK$HF0v{N{;tkAaScRw)`XUjChugi@t{5rx3 zZ6?Z~)9A+pZ)N^G4ZZNW5LpsD@KmaMp^Q9LOXbPeud({C-q$^aF!K4WI$6O_1iOo? zN35_v?LQ--?xSHsb6Syd-F7Asn|5{$yn?UgcB zSY2(RM6%Q`1%0PY+fus!`ka6F?F^EQSIcZ-k+I!pNODm~I$q2*U>OH(=0#59DT$}G!j%=Nfllg4<%?(z zqbQCM{ll-E7laGmSUmN_Hif)5So@O#_e5N1af-IlQn867_#G*0>=t^5t!v7c8u;P@8dhq9%xAGyFA+m@{?nB)z<2HZezuw4ADYPinXXVQd+225Qz zUX>)fSFKvo$fbMc6XR5=#G@?zV66lc{YTL4LkMPaOGHS1wdjk0&S@WQ+VkB3f^tK4 zms6~TW)(E4H6duvTbO6BS$_SS=zgRoP9pP8`wd4BtniK~B(Y3_!-T*kLI zBe#9BPkrN8iWb3iykl~Bil@oQVSCP|Z)%0E-{8ws7fDF=Gr}hG3iUc+>c}hmg?Mjd zw(SYE;h&+<+Mdv}kQ8DHg{V?|O{JG(X;y4{S?p!q6wByqX_$Q>wyC%|Sl9eGPtHG9 zuJBi`AWXi(Hf?q@gXvz-vTevZQzdD5_vOqQ#I2BU!69H!Pjr9@Jh5=_`Ep7u@tjHT zV2R<2WY)jB=+t+1P?ef?ZewS9>1DIlp{=Z<nz{y6tR>1qrocxO|zUL=Tn?At{Lx znP7Zsz7!MIcu^tGZ#Eu5g`_~a!ZGO+zsP!FQj!LqC<3nXO;ORc&$nCxbyq*2wxBB3 z@L(YV{8s6KBw+o}7BylM+@fd~xFYofS@((1oYd-caQ{}|AO*r^^KiLeCoS$`*T%F>K*6%mrc1c09U$`*@&LLSkDuNfk$7#8W3Q+5-JiS0|T^CWn8M z&Nu4j^guhq+&^YESX;3(63%%At;=x%ZK1t{KdhpJQ^qtH$3`nZ&ZOBt`6RyC&l$P; z|KhBR>uJ#g_1|*oi3{PS*DT*t4^LYa0*xD%w5W z1Iq~g?HTs%4GP%?_EVnRPC@$q#3R!gu<0wV045rkE<1S9C*?>qZr6Rp{c&IZaOIWd z>BoI&J&BRruYNOGJ&vD9&T~lZoV4^d&7NY=xp->zFG+-lOpO)_ZG@x=5nG~(+|Z|V z!$+P+z3)DX1fHYb8eFwPmy``h!B+ls{nu%OIV@ZuN%0wrKfN!=tcmzGz30K7)L!K< zsq+Y*Ah+W}kWQ$2pVd8@p^iYX@#2WqIIq#;wl$Oyjf10!7VH@ix; zg(}sEb%ai3v5u=fJNJe%(zPFw#4z?n8MTfdYAWqVQA$(cnBMZOw(}_B#~)703=WQw zCd;(M+b{XT+nKHs_dy7qb83>p3p=tqAuhM)>IJxvA>F5W5qUg}=GzRg$b8@#OH~Y8 zM}T?kpIZBtfBZ6U#<*lu`XLkjIjTDN(fTT~3i5}~kptW+W}_z0^CEmwKMWrtDW+&Y zzj+!acLj~?O~14@;NE(u>-Eg!X5g`KHXqzz!JFI}-yId8`CpuMI$cOKcvZe$Qx`G{ zkdEpJO?ku|6iw7BVJ+01-%e=$jFdzcC=lX%HZ+($DB?VXVKV?~}Q20ChGoR($Y2|B(@1|c6 zsVlR)33D~kcf|dMBV>^uh`(NStaf_oKzt2P;-!g+_};6|>RdrYwlzY!}K6gE0=;Ry2R zF57#O_|8h(zuSnh`(tA7)h~ptwn#BqpWd|akjytk+9|ufcrKg$NPl^EdrJYOmr z)5XstM?^8uS1%_amn}$Hs_XPRzQ>MsliCGNyo0xUJ}mP3-&(BU_2C)?^)#E)XZ_{1 zZOBAE6Q#*x*cilj{{qAA7agnyUVoY33~W1-SZHy>c^7l;NJ`;wrF^!-5W^gksI@B9 z*+`12mE4uJqHJa8+oDz_m+=gy>mStvZ<}6o5eY)F8_cffX<$3-U<;pJPvb@Gy-79T z|H&PR-OOysRg1S*tuFsKgL0^864A?8&+ix}qD53U>Jfo8D>Mc-sqhGdvZ^mdm{$k{ zDTV~xy8=?Y%8hCw#R<(@|EWjyZ`HQsN4TSTGF>`(QCW+DVoJeG= zASm!-$vX@lg)7XLXVZFoT{KJ1?!@jzTX5ZO1jmO_`GpX0(GKqErU%C52Ezi}@Z*5& zKd;K~XC(%^#JugtEKp~+?4|;g7qff4yU*rq=x@q|73zzJiAOR2iPYn`&8FZe$R=!; zF7ZvkWqELdP|=LD;y8P)8Dp8F2@nkX@rcidT(3VZ`AN^IFRvt`d^21?LP~p`1XfXU zm4aB6xjaeyJW1InmBfWSyRW7TqoRBUJvkX))ssZob*C&==E+>=lZKDu(hfWqI!_GU zFtS(?w5qYzkJHaL(9Mv}JKem*eCZ$CiNTQ4z=9NY`z6q05)H!`nX4@st`Uy=2tTLv z%v;G|XT0DqwyxBZ)y^J&m$qcIN&9EQE&B*b9HNT| zd|n&bd*!pIt*`k7-8t@km{irpGl5dEYY{D#EuY2B*^S>-Wx6os9_!dd)i^iKvyRjzHvA2u4p=S_MN3&xFO?3E^~K|k z|1dAmr%d1!ome(6xX@B(Ow41cAKDs@YmyP9Qz8A7PYO9x5go{U`)2vswFKo@od_yS zC}RI?c#0&)eKdXMsH!{GqciYO^6UEPSjzF(>sOGJ7w?#S^yIEioz*E1G~ zC|k?qS8nuH?n3jH>`S-`!t!`>%yd*C94e{RKkcHY!f(!>ZWO>R^(^16t=pYb6A7N+ zC0t?(UaGn&njYYud_se=#(u@^+US-kX2;}n9Xf%CGknJ6*OPz}CIU;tL=-o6Rpmre zY2!?}C|J1PP}o1XY=?hOnLTvzY6IH8w`f9;xk)I5PNjNlH9{*x{c@L2^&31$nN`Uv z-_{Vg2P3Y_bY0b0+B@GO?j6t7P#F+35pK1BL+XB|;sp&?(G7{s#f_k^-s*7l zcj|{8c8yrUZGNC@W> z`<#6^>a|P5dqt>$|1BaNA(gL{)takTv65*$mc`G({S(@ku}XvWD%@Z>mw7MS)+NmW z4Y%yiV%tOO3S~?k#k5>LVUPqd%uuc}k?MP^>+FyTGBm2=Or$lsdG5Bv{FIdF&Tx@1 zXEZb}HA>t6_FTOasxwUX_|vq6TWtSU{o5PED-taJ_hm%y%Th0i&3vgD{TsekiFV)X zaja@r7)7f|H;zj(Hl$Xtj-;lc-?Ptrj^(3}-GMX0QEik{syL2*E6as-BF(k(>lV!| z>kEETwhzy@!~DBLhvPUF;Wpz;Q15m1}Xpc!yOY9>zQ{;kWA;Dhan)@Sp_R+LzOc)oGP(v{N)Y-nT zj|1IqD~YXnkpw5bq4*)1F;(_4o#8|Ji+3!L&k3gQQcNM`OBpWFVtrfiAV%G+-Fyds zOuWII5_`@_na#UIX72qM^4X#h6)(j0!$}1l+YT28&O;l40C{?iBPN+LAxQq``fUu+ z4$^SnNa|54@?H3iK$-mNWfwMjp0Z2gucUX_0K(ywv z_oTfL7LuQuc#D4J3uaEkN_=0DZqLEsq2!H`_qMxJUDltCl2;G1%qK)XG{~3D<#0#7 z%ABL^yL~>+NMe&+;eH0r9i==Od9AiZh@EN@>%IxGPbOR#QkNpc*$fQX5+caHA@1Fgjx3O$AgtcSCAc%K`_9XKRDRce;eR}u;L z34+C;o(^@y#k7e?QorCJDM!0+X|0d!75^-_6U_-xiI-P}aS}|(((=YWilpsx6^W%7 z&?M*lmAe@uK34a(%b&ySj#rS4@EH|^Y5B{{!!C{VpIU3 zAVcuoxxN>|t7Y=m8Ok61FE(Gv(~8h9Ng~`ms-qEkj)WWP0AxT~x=c)oiKDn2-m&8akKsm0o1<#*ID=gsa)=k@22LXNXbm|MJ%yM4*<_}N26yq0 zJ`*ItQBLE@3zOkNsZ;7**kMBRcz(`jgSN6!@3IqE4^@%Bvgzs7xZp`9puMBFO@N9Y zV&rTvv%tYeg%JmPt5ae>p^gx#WR4*8Q*?Y@nj!`ZlvQHIZ4)W(;5 zUX}TpzaSR8DvuZTDBxAwxk_&tx%01xwJQn|9HK6cdiR}54NS_+>1=(ZRx%LY(FLlaN^I(W?=Xx|rod&>bCT5? zh(q>3kwTym?-LQUyl4VZYu~b7c-y{t6ey8J_hOj%WF$7tl4Z}_q(tsv-@6il84ujd zC&AW;?eD%-m_Ek!=POoakrhX&MMWG_I?n1t1to7C$q@(D!-*Szyc zE7X~w!Br+b&D6hdC_G?&14V)cEp3&X@}Tz z19dlYu@;`*CjCdk_}#ww=Ra`EGDXvG(NLy?&!?sVY6sr=;a=7YKQXV8Pa71x0*y6& z#UI1M)pbrbcCCA`{#O!%7>)qk6n<_bC6~pmiR#E7aZ;_)^nAk&wXG%t|EHEP zX(=KV*lt#h2(_a%rSC3{*$eyR^Ubg9XIbna^eua^^LIREILO5uRY5ZNW`tteaag-Z zmBVMewoyG8TK5xYxYl^2K5K;P*qLvx?_+cS2ZU@<_buGusg^9DQVGo`2%neuRsTO} zNCHU1PZj9kv}TEA_s4AfrhmzXY8#~YRch{O6sRB^+_d^T5Uf|J-vZNBjNc_HBMHHq z@nD36pMmV9o{^W0R8hv z%ytWJ<20%l7pQM8<-%B1s<`DVVywciFkv?oG8lNfdU3r*@xH2{|Fl_-cDCnf=AL0? z@n;C#T|8=e>Pez^Y%!4bV|vZBR%{Xxy1I}rDImjn$IlfWvEhnJ4F~Z(lDpgMG+pRK`_C|l~CxXTf;~*%YRy1#FX57?lhRm-R$@+jS_kN z;FhQlw5Sy{53C*j7q6sO4Q_&)Ni!UV2uVV_eln4=_-3ipFK3?CQ8mX1-nC0ukFcYc z($PZF)lI(xrM3z}Z0J+9^H$=cWmTyvCC(&?Y`AEWh3 z>mQ5FHOuD3qC^w&J-iT!zYuBd`kmE2@Hfi4iOcuq+w{nu(jRgGYUm@=$XCWAJIa`u zqOpx}>j)X1;Ei3n??1&XXLFeMEk8WPxLj_L`qj6IVT(g7Yg~(Ki8)CM;Op{u34biH z&ccuRfS->E89Z#jLuoY3V$`jcN>pkpnCvQGoN(a8`0^1}f+p-4kYVRmfuVmrAYlXPTw&9vjlD2tZaZ|p5zcGbS{%5FvAMy|~u?&~w z*v=L#7_EmW9YBMYsS{$UgIe?ryiyEwvMC2v=!){qVf?&aQ@*Dqmb2S}V1`yBk93or z*C&?w;Iq%Cq3L6yX}R2MnZ9b7%rr)&f6EI+xZ~4!<7t2{v&^Psc=kbXvrcOx@6ZLt zI>Q0a9A@-!6>zPWS4eU<$CC(>>~NtX${e{Zlag*9$~$!8oC?mUFo_+Zj?6qI3^;n* zM*la1LG9%ib_nAwoRN5Neb9wlbA81xXjy`A0o^$MG7_fQ`MuS8l=y6n8e(n8zh!vh z#M#%S-rT92EGH3#P@8-FI|qKZ=-JE0`|AG*M#A*(zx_Ruvj9v|D$q!}<{_S~?vWqS zDDOKieF6o%kD#>Dj+jz%xl81Kpm<%v&3H;Ecckr(pMjFcRVTB7Uybr=vLvM;xU#lM ze%(hmW-{xUTwC1UG|ky4cz=dr7s%Wr-j$@@RzEzfx-XR9e9CiU9S8ZI@578ooAbxs zTtKNuf4xG^cWZjqX_=zTz8ztwR&Pa!tpy|0Ud}mUg1$2Gc#T1@RFGT05QrL|#^&7P zXXs8uIKDxj;lExHQKFZk*(Tp!hol>abk??+Im>U_Wk%<-M{Wt@1l-`mZ1D;v;Wql< z30hlsH?es%6A(T=>Guk$xHB-aV|CC)(kVig=YAqx`ItiK-42(<%$a{vR~bnUjfj?} zb@zo@sz*CAP7Tm~Y0AP93 z2PL0x_m%0!(lL)i#L{03lf8m8Zf)xIci|)2C!VCbG~D4Kz&w#$P8dng}urncQgxX5()vB}eNB?ep!^@H184s91m2;rZz5&9at1_;>6XszL*GtS%Mx zt1|jhu<7hc_w`7+>g~uMqw5VEv+0|HI(B*-@o9VA8khLN~S{g?-EN!4OvDK{iBn{2)h>f zS#P%Vbw2sJ25DRaFj5dZ;ON8cCo08u@ZMF$0rr~e9f~2egdG|3(g}m}b zsDt#^<^a;7j&Pn-z@JplSKJ=YaivrP7ZpB+G2lkvB5`L7IL!*-p>K&+M6!X9J$fcJ zDi$2n5z}VU4V1Pb7ruPwk@e+r-IZgJgt7pL?>ZQtv+aB;EQv=@G(ld8BX|<3Rsd*F zEW$`hq;)$WE`v}P{ut?m^<3dFacZuhVGY}3&&RsS<;EjmJQzRz^{Af| z5sXayyze-1ZbdG$MLjh-N;V+7Y;%zhLNfQ5Jw(h<$M_xCg>HY@eZG$@um@qNdL;^tD#NE6Fbp~)+`hI*lWN;Q!>{{)5N96Hr)a40aUV~)tKn$oc-5q zWBduj7j|%zKbU#mFRBjuYK`_P@9F~zDm0|r+NC~fwlVB0+no~r#(sCr{^jfVw^Q0TsX>D;0)Kr%XO1_Ln>h%PWRgAT^9E}+yX>D2Se!v zgfl(v+`i>WuMxOyZA{HJ?U45WXb#s(S)j^Ly0m|M8y12B5HldUsQje-QJ+oQ*80+| zeC~1|8M5(tx|H-z*n}Ens>Sozmpa|E;sb~z`(Whf@iZt|HWG%G3{cJ+Xizfk&7!lJ zo_l11>}v^m4AOL6^yyjaQw*w* zVfJJ*Ul_C6K4cCSX_VdxA#7TH6!0=NR46{SvO{@(=)<(p=OxqnFrc+H+r9vhYub?z zoBZ`Ilo>wzhO#N@E!OiVmFtw1)LI#!-_v7$Bic!+q(w@%uA&paNJTi!S@pn&E}ZhF zvt|9YS{5JYEqV4Vd7A7b&~0WA`Q`b<-gS1asdMKdClsgo_*JPpycH!O;{BmFhQt!)$nH%k!+}|1S>TJ>?SiOWytCjku*1UD~O} z|4Zl>)q$^Q-)vbj9BRYU#iP5HbPfexl>y;(Rx=JdUe%I+swIThQgYW-Wgg`!xi-i1 zU21xQ{^(jAMG_`(t;y>NujWcyxqCD4I@ZvrK~jTY_N_|Na@nTQ=^J_QzTyn~sTj+V z7`gE#y| z73H^(B}P78@<&=t4z2L3`qEv(g6H?=j$9{>sWqS2mP77aeeAnaCzx)x1+bxKdZF<&E0B6o@tbye)l^ zcT*>>^wEN+z{R2O-|-?7=nZy22+b%lV72Myh)`w>SdY|OjIa?0uZl?F;9cVgyA~I? zc4%C;`2}~-O8^}MunnnGRhCUZUQ$GP2{ypG5`J{-`2-*q9&;YxLPjh`U`3zTBt0AW zD#@-lwyRbGn^z)OvD-XXOHy@VMMgH^E$YPRZ4ixthYWDA2#G0h#h`{ z@o)(6#dBMDrJGKotz9X`9s9@VfieN%Fp2frq*v&X+)h1zUdC-ROiw(kM)`&f;w#E4 z_{ZWf7XfcRk89Dq$Zy<;L(aq@6)`C!IBlwx4);_SGxr6KQSDjAxxt8kDpI{r}i)Zur(%~;`A(^P|Riu zi$@A-k(GQf%EVZo?m>=^gyY0-3H7*la{($~d`pq-G=~J60hVnGvy?zq#M{1O!b82% z!b^CH=|7qEz7QGDyT#D#v4QTWa3dJ;P~{|`QAoCN!19kCnU=Uze#O+z1p~0?kPsOT zbA?7PgMqh>+Ea{c-syYxV8uoB0-#36bNH^P%K;J&+GE4^O@@#Kh7@X(YU)u!wf#6Z z02i<6Z>^TmeA(aHLjVpz>C8|S>YNTedM*PlZAH!}KYGWPC4-}SDgn*>5qnxRRUUvZ zg_Kh`JQg?#poXSO3rn5=t|!0q#QH)XC7gv**O{tZ*7=73sOa9G3OTa-2f=c=g`SFP zd{heHM}9L!01p)Rj7vi`ekp`6mbQGB+4wDC4%s%hkT(VWcILG>bRHdIvjrQ57v74^ z{=0cby2Lhq>E7IqAh6OaJRU}zs>J`?<5TSSdwo%R=PICHKMK~DBrQ@2triNnb|X;m zghj?mZcAXN0to8&yT)~6FViSnr*M8}*F_ed+Pb-+j_roiD648JckxZQYNq@9uL-6# zqFtt7O*P0DRZ_z%#=njY9L*Kd>ue3K4hM+3QYI&Zyp*A1Cr;hX@A4K>7(M60bKJAx zC#xMe0p@WF!Gwg7R40|~JTO%;SS$FBil$SusWBzjrEPuFB(!CkHGJ~H{HTI%XGzrJ zA{r~j=X_JWm}}%eRjV(Hxsql&lE$>W#tGYN`rsg`+&-55!|`aN6X zGeD%+z0Z^8=_C?CwSp1+3XAYaguR%HmW3!w#D1FsbvpctrR zLI`8YmAX?%2;*D(0%ORRQdZ}~5Vo&__>W0z_s(6;K7Q@-OReS(HRbA^;|*xWkB_zb zn$HmseuE$UreLq&4gN5xw@g=<*iu+@zNMeR%jcKDhbQ)#C#ia&C3}gUxi)F9H`#$v zl=v};0FV9IH#rk^ALM(pH0IIVUqUU8egywC^Og!?1f26Ol;TA_qQ(Ev=_qt?DzJq= zm2_!(XH&7cl_b+yq~NpSC3#;g1xpNu1c10hbn`HabvJ zvOS9~XC#(y>ouXotJD!+c~>$USLz0{k`14j04|O7=$T zMyy5;lF)n*dDC7AZ#@(j=h$X7#+mK(h3LX_*I5&sJ)lxiRq$+HTSZ}b9JXC?k>3LQ zt;YL;O56LWV2aa6*Wvxw^>^e%gz?6-{41n}GRWIW zdD10k+m0}_`alphGV?m%|q{qhu+iywHh&^9t)^Kcu_+F*3s}@il?Pd$&=Rl&70M$`Obzn`F}u^0%Iw8a)oMTspC^kc*Sz?V3J}>YrQ@VK|{ND9)3|_4~I;8=~qdB zlh;)8*^B`gB3g}z-Jw5YP3Ne7b%l}nBairn<}cHdWEymxeYI_r2b=P1cJw9#UQG8Y*A z2ppXG(fU!w9HM02zBlkjx~1V-k7|GX4%Il5eJ zY#5^!j(t!skAYDGMLRZ;XW9pr=k>s!orx8L8GC_ApZpsh)DzcEEO!!Fs|e{Pz3I5R z|31|vk^FPkTb=y$RZ|V*Sls8cLliH1+x{>5g!kSG(Q>d!<>Qjx%XUU6;c0NQ@kVVc zj0z7&6zf^v>DsSTbigUi(b((wt$v{D?2;8SC-HN51$8QaG^S^T5|!7!sk#hPTkR9X zaU_=2v*+D9h_yem1ZJXgM@!%Qb@o912UdHH)O{&x=+`sEAJp>Y4doKsr^^k4aQ;_$ zdJA#2?8L>uMBZRr-NtC$etB(LiHk({{Oqc+*PmXQj>d(0CogMX)X3`^3<+tIanN#J z?|4!Rn_|4?f?qLd0bJv1D`v_3!T;>`sWt)6`F)$Aa=nG>&A9vyN<11E^H4*Ntmkq< zq7DFpr`J0R~uzQVx?_Sd~JjkxBlf*BPk}kPf-42Q+l$f#3yUXe+%IOUz2qqUn z60_g2S9|iM%_Rxo!%V^YR0hEkq?QbR4)yp3oTas;z%d8qQtN<54UjzdG5UOJNrArS zjn^srDA6l#E0b;NlD4nVkT3%bR$s|jT!*%sBL)*z9zp9sV}jv$LC{H%E?Dg)!Pt(0 zMHVGg7p7T`SB#U;*WfxxT6lUeVzpQ}i(4m75gf{>7fnAFNf;ptBg%|FFPZwYeT9ML1(_w$3+vTv{P13tR-)JGF2_;CS1x z-ahTV#<-fldqVNL+Bp1r*odHBNjhl7x;d!tUlwr1)FtLRyU15@n5K|A?()?(YHsen zBuEv{mB&;TZM(h)7Vq)(iilL2TnfRJXGhiF0h35%uxEXTenAaTNF$@NajGUxsF(gv zsWJk@C>?s!4fvxkkz+%9PgLc3(08sOk^S4$v}(z~Z9|~O35cMMvz&BIdh9R2?$b%Q zd}Dm%uCw{3rZauF>e8UBqXzg0SW{=0RvNP@i_ItzKe^%!1*eCMVN{FJ{Lo+H@Zw+T z`+9)0glg&$A<5yj8%>|2P{5oEJk+AcNL679V+yudvmD0R8M~pWd==5x&?Q@p8SSZw@~pHm1`R zz8N=MSEgy+yKK2~Nw|;<;Fg4YeB=m$da=mSNiJ{Xfp6BKZ|2b*ed+@Wkf-J%gLT5L zofccp*IWNl)Xws3IbmZWfYdXJ`K;@j>*ETvM63aW9x(=)(ErjcSyqg19}?=$##i23 zhcEfdZeF-s`v?!MX=HvD2GH)5gT!1?C4i60KFIf%^Qr=7L1lDomE>U2PUH4ut%eb# zV#&-*Dr*}UmR%A;{cC%^dnYa0^(m3Xn>5E}AVUNgRrEqcF~{L+87KG|zx$<3aig`- zTF|aRcjO$~k?>t|aQzv%Jo)+OA2G+p~<%$ZD3DC+CIbCJSWE^&9B_| zY)1khA^HhkaT2`Pw!fXYxWPw{P=wP#HYK`OuRH!%KZ1fq4^=UpwS3a=;*@@z)09`w z3jp+r2@^R0y1(UKo5ToT{Roc4t8M4?8p8+(ZQdcd#JpaEnkd1yZT6QIbz{4go08R2*@Nq15 zb9;0YIoIve_!fI3&1bnD{r(kQ%m6t{5K+{-v-58Tz;5dFCo?$qgE2B|;Q8(Xr_syE z(RMaAwGIW+wSJ5ZI}ies$SYnf@SB zktwUB`u__@g84~7Z66R|$l8!<$j>ccB zmA@+1q(}Wqk1B03(lPN-1N?)3>pxnl3SoctCazcPzmx^7=-5ML+Ir}VE>T5a%FZ+2GRJWuQ$U=N}K9#+HMyz3Ug z9!mt64Ej_(i_|y7Lwn4SQe76EH`WT7%)93Air!JH{?fXDR1`Zi5B*b2YZ=f3j!Wn8 zdT2Uk18ZYH7Xf^jgh!Fdr259;bT#79rDq}oDgmUgGq{o5P5pf@_QQpFd<2yGngw-} z8G)Hij(QVPeI+;SNg;R_F{eGNo>EU^bMfJxUFw0Et&gzg3hr}`;>Lnu*MDQQH1XxT zH$TbPRgNm&78R1N?tq|9@w&R;FXxnvK5HUs-oB@31uyD2d|>SQUs$hMfAOQiUC6KA z6K=vG_46!jvYPKHN=ZnYkX8~pD1$m@uv@V-@#2py9|p}0HcvuFVx*oe?-p&W;N8wK z-|tb{V@TQlx;T7eHnDwA7)Dl(k2pQOldMTa}nRmSlz0m z_0tlw`c&y`e3wA$Vq6=5whSb^Zw?z1^9r&KknRO$Sx1t4t)2%tP}$&wW?r(ly$tP1 zXPGyEUg>9^gm4BN>`h%-M75-{CnR$xB-gnInS$qr0;e}-WRR6zc1_9$D7c}xsn5c{ z6=?j_37$buO>Oy*(Jt`jhT$`9!_m)oj{dUCqS!MJhHyop346oeBpsyn@6BPFX4kDE z-jV8F-(J(rsHGRerh@v5=;LiWK+vd1@h=m40xhs6fk|IBLar{?V%&HtT?2=gsZ`Iv zWZ`(h3!uFa8nv?H7}VJfUJ()=g3sB7=TOgE{4%spHXwY55P_>PN7TEA_AXIe-9&D# zytZtIxRpuHw!yGoh8_h*yXcB=?th}_;olOi{OHn~Bg{C4nU&^_a^ofI>qy=!5lk?{cI&R34kPx zPABgtD`?crJ1z<5@%!^}L%xdC(#37oq|dbzK@NY4l(|86A3;;>xoNn`-y6LnCx9qh z4cA$Zu727hvzRs#Fm^ge_Vg#FCnv)kiwk|atPhLqB1`rsJ*%Wl8~20<8L`x*Xq0Jn za(n@>Wd7NyZ$(b%Z!&9uBMRT|fhhH1F!R{)yzsWgLHE&}m+E=~d+HpgD1T6EVQbe8 zaCrjjr?F41Sz9S>T2HU0@gG<}Ic@<2-?{bQZQ6|2n?i0}6|x`v6Ju5(l$8CM`Q?x% z?}_q5Z}gJXXm-1 z(ieGpNkSHcNX6*s0)ciI@a;=N?l-ri-!{4O!cNi}|F{g^hzw2s8i=x1kQgrgBR*mX zn$a{-dEf{+^EdUlB$yoPI0=6geVe^<6aU3o38fOkfy=a`-%`lk)2CLK-$$nQ#beOT zBlE+d_%^z+^lx8yd>jIyEkw)zn?2?v06S?SJ+i{H)8vcP@H@*fnriYFa*B!MiX<{p z;q1XQlRPyP2H<-=h1$o>x=!H-8n+P#{yADl`DUAy(ZP8c&}<5i@!|8lbYX%eBhy)9 z-_VZP3^Vy=qZ3O%_W@Z-Xk4di$O5iiHR#R`UvRt~|7@S*yq{tlN>pc%6_GPC!SfN{ z-k9soiA!4E{?#X$bFPWXW~1rGtqa8^|11ZF?~zag_rclm4#~j||4hlIF5@p(b9OlQ zKRLv>=0Nr~APyMHhdQmgHjSilS#I(7Pdzkv{jMJ1d?aSe9m}}y5EB&`t zhj3*mR7$}jVqssvtvHjLIDQCIgr zbr$w;3HCJ)=9|jm=FCs$K)WJ``VT8Sv;?&zPRi<1`s=THK7ypuO!XLfFtwoWX=48MBewcFORW=hp`qA#Vc1` zkC>ogL9b)`+!|>Ag6pBQxhHf(XgoHC?*q`)-CsxLwu70RS=Me$94fMote7yC zP3@(EE2e5e(HhWTHxi=Xp*PyX_S1iHO0z`4g4#I(Dh>j*?OB@%bLu74 zo;Ers*_aTa^xm^)zN|)`Jl^sks~6zl^0?LF74haa+o10?wB>cR?Hh+}d`+y9HMV1W zVON+0Cokc+#V2ik(FzZ3d$Pmok!h_)jy%}7y9ZZ;}<|4xrEwEn5(<=Mt z!mHv61oZrJek;M{@&WrNe~U72ow1ZsObzssS*awH%v`^x zt#bKpp*g0vob6tQf^DN=8`*pe)~@(xP6{ra!yA-3La!8xvsjn2O*=O}sDI9qf$HqP zs~pc-HBTk=5fvlQORifzVFo)BpoTNOp2W4Mc@cEuES?bCtze(J^_lQUv zBJM&xbDesmpo>kDLdRH$3@vAg+p&*HuJO(r!9jL&8dY_h! zxGNeV&2kRb8Jd%dotn5s+2p?BwJM+FDH_rgP6Tzg)+wW1z3}%9aZztMtXd82<1HaqkULq$oxn z6|lL4{LG)TQ=GSO8O{QydVepx8Xp!|&mEgMRlmlt)L60Nm%bP3-0yD~uUqA*^V1Rk zf_dS&)&Bwp4freF$#o3opjhiug>&4=pa~_xP(RGBK-im>j zEh~1iZQQ@lW*GaA2=Qo4t zT00qEzNzu@62E!j?ol}n=G%Rj+Zi}5dNJGe96NkpTgds(R}El?Nm8dpDIBWOf1xU~ z-vGUDgH6rFycphBsSJ5@t@`-dMDQ<+m?Y(eXB{bGzFY2N=wF?;9yMCd_L&3AwAXnY zu_sZ3b-;)ErZQ38N>w|i(xY8b5U#nbI1Z9mwiZk~Y)^jU&i!sc&%}<`=~m`N19H5j zwrvYSiW$N&`-gP+CMbWtGI4{)F&O#HB1;6(Jz=XNLid?@25xaX<0T< z6_!kGXfu``cj{&5B^>4uol)|)bjc0FRZb38#^ZdGZJ(*IKonN>dH{Q>)B*Ch(`x?; z4f~yse{GHY|A_kTc(&f~?JjK*`fY8Z+FG?|>{1l9_nxt1)Lyk(CEB3W7P0pZL2V@s zB~8p)RcZyLHm&`h{(hhLegF3P94F^I*L`2teO=FUcEzkJnJSVF(kYSM0#j!hk=Ght zkar#ZLAaFC@;TSc78_+bSMiyph*pD`OxkQrXc=uZ{;eY4VPomOsvyoPjlN(Aw0^?4 z`Yq6=AS_$b9*LU2#Nf^4#ga@vKgBO7RV*sKTQn;9Iqa+5FNhsn$*X!-C@W_ioXz%? zC-*qP{&%XQ?(?wD_f4P9mpB~#FFy#@jm`Ue#{ zd;+~XnS7q-R$D^nMW-fy4ZE3+H3FmY(>i|1?~xr z{UH`L@z%cllQY_2Y&WyeITp7+bh(~eU3eMxMkNKI7FiYS>x^=-cj)+Uufcv!!+t4M zA!t97-e^^`ITq5yHr*K8>EAAY#1Q%PPoY)h;@tG^EG<-ZSY~xt-hGY2@}RimAcUin zNqyU1+Yk0CC+@sD;`z>jT7=1L$|lH-S&1vC-H?CHhwir@aw4g~vqy?5j+ShYIsZ7&ZszW6O}}P3b_T%`AE|tEurcAJbzkiXb-w^eh59cC`I~zl z)C|w5Gv13C6f+9a9kc>9Ls7S{5PvwjP9Y-}B|iy$EcEI52gk;z-o?G8p;@KJEO0_C zK)alk^)TP4&`((HPE!kCj25yxN@bQYR?_;{)=yhJ@V)T2yKNc!nU%A*LO&{4zsL>fiduq`s?$4=?*9IBe zdXcZ=ogZ*W(PqSRadNwO+Qhj7C!`zlC#@v2tiUJP4*izZK2BNM*UN|!`-&4Q;}d7% zOPh@_*d;w0`b}VeEnS)iUwUf?#=fWTEdj2sqOGORFxto!cJTQOG~^~oUx{Kcje+iv z#r_zQl4GUX(fZntCr@*yKNtPPt1sRv@w@&CyLqf%?a!CFKYu^UX2FZs2|!S0yo|oA zCvwT>WXP^-u@RHdFLWTf5GEpqF~n%JS&x)^`H1(AVlL87bB$hh_KvUfTYUvjLnKxO z!A^#Jt)aa^gRHs4=e?@F1G2rmHQ*OiV?`5WhOYXmW<20I!NorThg6N(n6y4}Ny8Pkp0J?A?@~vwnVx& zd9Fml^SJ?yKCA5ddsxf3GgQPciQhP6je2&?7OOGaraq2m)a%4$CP47_c3QhHK+t2m(k7kgHX~=pBqSfGSz>+xoFudVBnP~N4PKqqcD zgUhx2ziRUL7-^nqdG0CMRVS}?xr1m=HwH@&UCK&48Os|u;W&x_FolI#dc(+j{#@6=I+TJX{ULl#epq%! zTgTvykt=0@?i>J~Q;#0-j^qfhAK}pMA_jIokNKny-j+Jl7q0Utusn*8XpfN4orhYQ zVfe%p(&d+2=8G52UN4$`Sbm!2IG=*3RESKhJMX#H796p)x|=AF+b!AG2K$hmS_wjT z{*_?4XEPCNOl)cRDZyt&aGQi`|K+OEe1RqbI81}5k;iEtN0_LcdFaS`WF27KRY%iz zN9aUAs*s|)xNk}W?lEvmPUKSJ>H3S2YMYaxD^HBccu5h5_LS>KN(l9><<`Lf&ty^v%6j@KHwLDnMLwyz8D zO>4fK*5t7l<~{Y%%f1DKR#Ad$jPhkr$L37w-;0cIp2NdZRqOGOZ|>9HisQ6qQvd!a z7O6h4Wv>0Z(+4S^4*qNA4Vzg!ueO(SVCNOz=5HrVuWk+NFBkEy<5#vyIKTf8sZ37( zeH`^GGb2YouJVzJ@eH1R651XbS0hFZ83;)%e_OEYz;-JN{&5eY5YRbmCPzG!i*?|M z{ZO3uFfo5@sicWRG9=J8lwBk@`@qk5i^)p|6V#{HU%l*I;aIFSjIqK5)nzbT)+t;y zkG*4f);-OCA&Z?z+aS*I{jY2QBD1l^GeQ&BP{aCHs*m7D2rNd!G@%l3($O8hUZVQVE_@pS?-$?zRN)(Or>%|TEM-_Ku#GPJ@$!`p=B4-DLd6?AS`|*4FJQ5+sFcA_{?&UPJ z81j-EF>l@*kfj7l_rq15riYc&$gdDN$u?jJlP!~23|u8r3Rss=mo7)m;bms6Hxiau zb~TkrqQzP2Ct*&ExgM+b`*vX40j`agfkeu!SLwf2(|3 zVe(wGbN;90Tt{m~T|HsiMyV`4D;^W8$22IjO_!b6`N4dpL8pAY(AQ#S9 zU=v__a(JA0`__9yhUSXwgV7U9!k037Qy1DL^LIpEt#^qml&pdZOGWOxo|P#QvdI#% za!Z?E;xX){zFoHJgxYf4QCRHn^()`42(@QVscTnX=rLd_;%>RNZ3v6P_H|5zbL(1K zzb-U|VR?e0-T?Tu*VZj4?0hzo+B($v;Xes*6OB!K)3U2Q5yd9wjko; z^2+ul&ll#Rzn9)-d-LaV7qZ!9&N;J&&}XDG^z4=IN>>50+}@k~#1Gl&qrLw`*-KBv z>OZ?;Bj0?Z;Z@!lfMBe8965oknY8EQ^LjF|Kskp_LO-X0%W3@uMK;aLrw%en$BBJY z{~a|14HmkqiZGgjErfgWU82rKV!NUXKI%2p8R@Swx%5BE4zP8~DdW#g)HEUUY}R2q z`b?FOb>(+$v3skt*N4(0%l+3RSgZgOmKd*Xtv3cX0Q1nI1ocsZ80j<@DgC7O&ijKJ z)GY|bN#QlOn+-P9&YthNAl#I!#1@HFdMS`V&|28ng1&%qo+AvTxIC-;5DTgL50>NPG(_7sWzp{VRItgAUb3@KvN;JK-cV6Vj$wBX(~{`CL4uvq-F zGxbwO!(a1v3pz2Xrmhif&wRIH5l8k|QhB~i*2cEm05ElX%P*F3LdRrFq;l${4LPJcKC4Yi(n5j&uKb4VjOBG8;Jx-o>L5+pU+`#* z@q;**cn*)Yt?F0`dR>-n z;E*OUGf${95;du9 zxhTe67yzr%&a@A&lbCb*H-@u4j?4FEC2Zj6kxGKBqH$m8M8K51td6HDS`xSnnd|u% z@8#T|=c&C%uGO)u5mxq68yc!b^hIQdi)-30?@A$ld7M)KIe@3g^M;4GV)u;vFHelwshnywrlIZm6Yj zPrBNRz0o=W36(w=vS~eMG`<+5hNrqECV$f&`8wau?gMmQiC{Ct*pBa?+A#)Bcf2VC zCv%TNR8|}p#HT8|^l8r9D?6yXYAd_uq2=D(CXF5Y!9? zCX%jeDHj3Yqdb_)aaUtGd?Hr-n@DV1OI{z7w%WMbP^u%xx|5VVQ6va8(gI-CTOQgX zDiEyTB(|%YY@5mx(WUp3Z?eOdr}eM3qKmm8y-PpJZW~qXNi6-bf1hw)(fxB_i4s~8 zX4w9z(5(+o)KCoYNBzn#edsVI&$p&YP8|br>7`Z>H0dz@AoWeXi$9Uj?mqlO{UiT4 z$-=YT#m|%14~&_Qo>Wv&GX=IS8O4%*l#0Ro$_t;kj#)A!Z2uK! z2(hy#t`^6ar=@pTUn=&P@jago$Bhhn-uLnzYu5JqY$oF&{DEpWsAA-g<{KK!!n5ey7glG#zl)~5uVi8B-{L&X$i#2Grw1C?! z)HIZ=eSBnfk^5Y?=*a_d9h>hu`(GrMPJA2h1OJk1tr+O6E$sUy-GWTCoss677ISfp zpDz^QnEvw)TOS&=8~>ESb-5@xh=PitL84!ozMq2j4OvvK{Rj86?!3+q=^k+e1+~kI zpQ4^qkwYY{cgv0y_J8#iHzaTf1u}EfI)lBud8cV^gx6UgK2Zs2>I|NEM&c$V12!7- zQS|k30*qO-^zm5?PBnk+|hj@?mjcg-{>dhuuQSW5^$S!&nIB=)mm`jlU=huuQ0}Z)UvOAsz^`| zLh+R(<4X{fIQTwiltTzYnM|IV{xNkMJv$jf}}igAz#(sM_(t2jI#madTg&jdAOin3W=`t&mP2O!66Z<;++3~)uUCc2p@EG<athtiBJc~!~AcrAt}-;p_sKpM z6m-AuDsK4p%w=j@m*9?=28bHjtRmU0ib4c(p&V%3>lVUD{^D8Va#>7r5Q4QJ)IHpNVzN4mFj)4b=yBs|mZ0 z2(A;}kLLT|RVUKKB#W67vg&>mcJ~&Xeg~{vzAT@>=<`hqUL=V_KtDTNF|Gi;5LPjG z7|s75C`{Avv`XQoxhc=z9p$d`Ab8psqSBl&R}SzzgS_IX7t(eK`@UB7i(9vh!g<%;J*HOiyS!Xc^LQ^r43B1BMBYr)_Ix&M^%#a4 zJ#eJMn)mD|DQ_F7TPls+g&gz&U`6!2b>!fbwkl@wf!u14xK-K-&TDF+HSMtewKMZ5 z*6)ri_@(sI^O?Ne&5UoqQ%hY2g~2AM=Z}d(2B3Dt1x}usOXY=|r^eWR#p37G#oy-d z6!=k|-~?Fd)n8%~0ktZf?o+^z`Y9v5;|*zwi8$h*gD~~jm@Zed z%OOgol{Jk<4`s0xOmA{rgvqF#vj_=cxHN#38TiTRifo4Do#W`Ox5Bp)8uMkirhjW3 zedYOe4{-$R`4qqCkxR(BhU-zGXU*m}nY>(#d$_>{?m8Zk8qzv87oqv0GW(UAf4nce z)iSje6>Ds1H1ec^5%C>NFhxDCmokC*4IkD=S`23x9E5T)#siO0K(z=_6oOnb?|GNH z2(&*+@M+Mj9naTxd+BF~?44l6-R)Uv@42vd507ogYLBWKddeSI+*7 z=5r-7TJ%c%5Tj;)*i&*Zc1-hHe8+<+OKANG;0TeNYi;*fB1{x&{$Bj=NSR^nPtsx5 z&jMYt`8L~6yo^gR!yO7Hd-Sr8;C)HZ`RaUbXEDYG>CG81HKk5JU71629C=S#=E7nA z=Rpm5Z>nzoj5C#zW#S{2(1OL2G5RM?$-hOi+=F$F*L9B9c$EZk!?KXce7h89c-`I8E(>QN*hybG9->7;2DLhhYYV zXC^8vE`3r`-wyJsXZJA74#~5IYX6Q8nllAX)FL?rTllu>`ILMi8C5KQN`XI#jL7yn z>$yg4@YgGH;NxYUY;|sWD@}k>L*3_siZ5s}z?CmAm8q;C{=rCBOj}6wq(|owC^;-6 zswxD#aivLxT#-=%(CnG7VR|q0g#W9T24|o^Fu_=mBn5{|{%t!)KNZAWGJ*0S|c zLxxsD5G$d87L&CVix`qtE-Bc+`w^d1dKnV|BaJ-r;jL*AE^AG%3lY%WJu%2$(uCaV zDurd9h6})$XR{lL=8Y<3PYe;t4+$$2*y$KJyAU}uZ?({^>P$x$u1~~%I`>G&-8Uw< zhPpFlU?g==XRO`*;L5-s%fV|_ z*K!c8uvGSO$~jMMBuCg^AgS>gzl8=_yR#qrX1l$^CN7>UK$t<$UgiT1)(QjB6&+B`2D#YG)jj5n8DG^yMwNWV+y zGe{h(qw+*R@UAcu=>bSE5gC{Tmze~^!lM=_R4zYqv|}X#wiw&X`pWZ|%6_CZ#(2I| zj#3^&RD~qF$4I!)Gs3%nJ8XBKCwX1`FPgV@axNu5wE^yx-WY0Utn-r^rm8}lA~1#) zq7IA_2@{Qpl|bAi`QudEC-iTc*x!^dFw*?fId$a}-^ZOgHjlMNGxfOAPan&VW%V}_gRjXA;f_43Xm1!YR$ga_6(2Z=X6Js(mR^{m8@2R?E_K^r2- z(fFI3E=ovupKO*8pn9;>3Z{Z1dxjgf=!L=nxeM|fqraZV^ZuD9(a}>-C^f!~n%ybt zJ&#b1A-#19{dG1zVq{@Rq-fC7zhb6)aT@ACdf>-4OqCK+tjDwoxZ23?B@23VGoD9Jrm8$Khe$G%coWxfeJwL+8jNy8{V zNXF`oy4BNQKHc4kYXbu+$shXrV2Jp!MUl;S!LW;Pftb#NAK7`S{1aCEAHb2{hBJk_ z!RTaah{(W}8plT7_*uD6{EF>y?7tC}Z51*?@gkDRp{EY;c8&ksF#}c=G!_Ez#mu}X z`r7@~`7STxU#Hpyn|ME}k-nd7rDbXLR=t)JY!k;DA?oQcn%td9bJi}3{fA+oXn%aR zx8y>nToMte5+=?8IyFG_L?^z!rt(p(L1CdRs6xeZys)OXG;pG@s~62pa?%|~3zaav zb*JVAxhPZD#dvhwkJ}ByeNRh{8zO%>@z~^Zzd6l4BNtF8pm_Iub)U!HLu~lGPTO5@ zJPR``Jl@Aq%=_ZnDalM%K@3)GtNUQ$G7E8)N$~4&tJ&s~K`v=;5=?FEdNcQHg70K# z$7ZXf>QXA9D?Xo{G%V>Za+0-pD2Ll{Li(k_-{`tBUo5e`uFkm0bB4b%59IP$oWX%Z ze_?Ub2XyW-8t1J(TbX&*Tb_ZWTfS6-#}So9G)4kP`T;_ph@274@bGbxX0saTkSXp& z_ePEwee7cLk_h%Vf8j9cjj=sCPJBDVZ7xj9r&}!uWh#DF8OJLwfnV0bXQ2u&aUX5mo5KNOY=aU*DbG-}un7 zXg2CSXpHh^eP06UccEo)ruB-xvE&2~!iQVgI{N(zQU1=QAQS<>m*dpAPg)q}!%teV zxA3je^6oVTS00Q?2fWEes|+nm-I8x^4b~NvC^`;N-OaeqeC+?JuC&LJPTi2TnAnf%wfXGkvU z&V7-$N?1#Cp$wWRN>1t`GWeSkxZ)5%p#Kd5B`^8c%bX?(gv5J#U~yHrC{0d;1OCPn zV|c){2;y>T`*Z!D$L9(H_m8)O{u1lXJEZu`BLR`3_bSH^(Iy?2o>VO0lYNw$D43X7 z8(nyri*+3)g%$iXh*=2BT6p#v8r*09`Op{rR17JO%G5_uF%zAEb3FQ6lhRN;reNL_ ze}RB<^DURdergDYIvj%>VPbPx1({OPF(AUgcPvqFdEXn$#2W!gOet{zYV0()X$%&eB2n$;ARxm16u$VB#plu)G+14W+0@=4{4HEDn=?(C~ZmJ-U)n%{jP%i z7j$S1?o}-8qI%RaL7^FLSkL58uZy7dc!y(oAd2x8@kxPvJ=Irabb*6v4;=nt!f>{Njag<}J9Ak1TB5WSao>l>)=#ji6}7sg zG0|TVHqa!8{ia5zMlTHt|Bjzqw|d}n-dM=vNXY(p!kF18Ex)u%IGY`t1c>DauW9k~ z?e4RsqyXSsF}hSN+cM(>HyH=y>uYhfqq5^pTY4-<3FkU91dP!QrgluGVh6=C?-9&^6lrWH%1vz3YUlV) zB0zRK#Mxo7DYYcW zcg~ID1qvP_|A~RMq`{g@@B0LFxHwk#KxGXGL-U?>b6m+k>n@^?l4CnVrla+__Ys+P z|4lZbNazoZwkR9;865r7=l%rdGbzFkJ`2$zMv-eZI*Z z1!D?%D@VrD+y$fhQU{%}1&jR)-H4fc)H$_7kkSC6 zSxoBTvxNd2Yqy!&?nULs7f3#q7Os(&clQ&q^(is(tM6UV`mm_?Wig3QD)}2Y@l=W~ z9Yx7UY=>)x&}ZC>qI5!zP_R9r3?CQ7n4JbmG>ODssAJ!m6L6U%Alr!#xvIm-s-wfK zBXHmotp19q6g#0p4FSBPe%1*s_sTM=1gN5}hVaiB@K-Ugwey+)jlcYhdf6i1ts`

sIrt$I^t>>I^>^fThL5mSye`WFCof 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ξ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 z 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 Date: Fri, 20 Sep 2013 14:44:52 +0700 Subject: [PATCH 042/165] Simple implementation of newlocale / freelocale. This removes a couple of errors from libcxx test suites. --- src/library.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/library.js b/src/library.js index ca3175d10a7f7..49f8e453b56fa 100644 --- a/src/library.js +++ b/src/library.js @@ -6461,11 +6461,15 @@ LibraryManager.library = { // locale.h // ========================================================================== + newlocale__deps: ['malloc'], newlocale: function(mask, locale, base) { - return 0; + return _malloc({{{ QUANTUM_SIZE}}}); }, - freelocale: function(locale) {}, + freelocale__deps: ['free'], + freelocale: function(locale) { + _free(locale); + }, uselocale: function(locale) { return 0; From afc3adaf66f05c7ef863dbb195e28f46e9ef33b9 Mon Sep 17 00:00:00 2001 From: Bruce Mitchener Date: Fri, 20 Sep 2013 11:02:29 +0700 Subject: [PATCH 043/165] Don't rewrite multiplication by 0 as 0. This isn't safe when floats are involved as -1 * 0 is -0, not 0. --- src/parseTools.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/parseTools.js b/src/parseTools.js index ddfb9d01451a1..8ce83adf7b229 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -1499,7 +1499,9 @@ function getFastValue(a, op, b, type) { } if (op in MUL_DIV) { if (op == '*') { - if (a == 0 || b == 0) { + // We can't eliminate where a or b are 0 as that would break things for creating + // a negative 0. + if ((a == 0 || b == 0) && !(type in Runtime.FLOAT_TYPES)) { return '0'; } else if (a == 1) { return b; From 284026de746adf9ce7aafd5da0ce12fd9a3c94f0 Mon Sep 17 00:00:00 2001 From: Bruce Mitchener Date: Tue, 24 Sep 2013 17:09:12 +0700 Subject: [PATCH 044/165] Add test case for zero multiplication. --- tests/test_core.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/test_core.py b/tests/test_core.py index ea2fe49e5d9db..d1d3bab08e64e 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -1399,6 +1399,23 @@ def test_zerodiv(self): f6: nan ''') + def test_zero_multiplication(self): + src = ''' + #include + int main(int argc, char * argv[]) { + int one = argc; + + printf("%d ", 0 * one); + printf("%d ", 0 * -one); + printf("%d ", -one * 0); + printf("%g ", 0.0 * one); + printf("%g ", 0.0 * -one); + printf("%g", -one * 0.0); + return 0; + } + ''' + self.do_run(src, '0 0 0 0 -0 -0') + def test_isnan(self): src = r''' #include From 794624d29502ab22d520f7a3d986bde403e198eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Mon, 23 Sep 2013 19:41:36 +0300 Subject: [PATCH 045/165] Do not get confused by Apple GCC dylib special '-compatibility_version' and '-current_version' directives when scanning for input files. Fixes test_the_bullet on OSX after the previous commit. --- emcc | 42 ++++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/emcc b/emcc index 5008a0023460e..1c116bf5b9617 100755 --- a/emcc +++ b/emcc @@ -978,7 +978,7 @@ try: if i > 0: prev = newargs[i-1] - if prev in ['-MT', '-MF', '-MQ', '-D', '-U', '-o', '-x', '-Xpreprocessor', '-include', '-imacros', '-idirafter', '-iprefix', '-iwithprefix', '-iwithprefixbefore', '-isysroot', '-imultilib', '-A', '-isystem', '-iquote', '-install_name', '-I', '-L']: continue # ignore this gcc-style argument + if prev in ['-MT', '-MF', '-MQ', '-D', '-U', '-o', '-x', '-Xpreprocessor', '-include', '-imacros', '-idirafter', '-iprefix', '-iwithprefix', '-iwithprefixbefore', '-isysroot', '-imultilib', '-A', '-isystem', '-iquote', '-install_name', '-compatibility_version', '-current_version', '-I', '-L']: continue # ignore this gcc-style argument if (os.path.islink(arg) and os.path.realpath(arg).endswith(SOURCE_SUFFIXES + BITCODE_SUFFIXES + DYNAMICLIB_SUFFIXES + ASSEMBLY_SUFFIXES)): arg = os.path.realpath(arg) @@ -994,29 +994,27 @@ try: if arg_suffix.endswith(SOURCE_SUFFIXES): input_files.append(arg) has_source_inputs = True + elif arg_suffix.endswith(ASSEMBLY_SUFFIXES) or shared.Building.is_bitcode(arg): # this should be bitcode, make sure it is valid + input_files.append(arg) + elif arg_suffix.endswith(STATICLIB_SUFFIXES + DYNAMICLIB_SUFFIXES): + # if it's not, and it's a library, just add it to libs to find later + l = unsuffixed_basename(arg) + for prefix in LIB_PREFIXES: + if not prefix: continue + if l.startswith(prefix): + l = l[len(prefix):] + break + libs.append(l) + newargs[i] = '' else: - # this should be bitcode, make sure it is valid - if arg_suffix.endswith(ASSEMBLY_SUFFIXES) or shared.Building.is_bitcode(arg): - input_files.append(arg) - elif arg_suffix.endswith(STATICLIB_SUFFIXES + DYNAMICLIB_SUFFIXES): - # if it's not, and it's a library, just add it to libs to find later - l = unsuffixed_basename(arg) - for prefix in LIB_PREFIXES: - if not prefix: continue - if l.startswith(prefix): - l = l[len(prefix):] - break - libs.append(l) - newargs[i] = '' - else: - logging.warning(arg + ' is not valid LLVM bitcode') + logging.warning(arg + ' is not valid LLVM bitcode') elif arg_suffix.endswith(STATICLIB_SUFFIXES): - if not shared.Building.is_ar(arg): - if shared.Building.is_bitcode(arg): - logging.error(arg + ': File has a suffix of a static library ' + str(STATICLIB_SUFFIXES) + ', but instead is an LLVM bitcode file! When linking LLVM bitcode files, use one of the suffixes ' + str(BITCODE_SUFFIXES)) - else: - logging.error(arg + ': Unknown format, not a static library!') - exit(1) + if not shared.Building.is_ar(arg): + if shared.Building.is_bitcode(arg): + logging.error(arg + ': File has a suffix of a static library ' + str(STATICLIB_SUFFIXES) + ', but instead is an LLVM bitcode file! When linking LLVM bitcode files, use one of the suffixes ' + str(BITCODE_SUFFIXES)) + else: + logging.error(arg + ': Unknown format, not a static library!') + exit(1) else: logging.error(arg + ": Input file has an unknown suffix, don't know what to do with it!") exit(1) From 6344d99e19495e381e693b14fcccff9576e28384 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Wed, 25 Sep 2013 10:22:29 +0300 Subject: [PATCH 046/165] Add debug check under GL_ASSERTIONS that the alignment restrictions for vertex attribute stride and offset presented in WebGL section 6.4 are satisfied in user code. See http://www.khronos.org/registry/webgl/specs/latest/1.0/#6.4 . --- src/library_gl.js | 48 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/src/library_gl.js b/src/library_gl.js index a4d35aff0d7fc..06f0a117eb15b 100644 --- a/src/library_gl.js +++ b/src/library_gl.js @@ -310,6 +310,9 @@ var LibraryGL = { Module.ctx.bufferSubData(Module.ctx.ARRAY_BUFFER, 0, HEAPU8.subarray(cb.ptr, cb.ptr + size)); +#if GL_ASSERTIONS + GL.validateVertexAttribPointerAlignment(cb.type, cb.stride, 0); +#endif Module.ctx.vertexAttribPointer(i, cb.size, cb.type, cb.normalized, cb.stride, 0); } }, @@ -331,6 +334,36 @@ var LibraryGL = { } } }, + // Validates that user obeys GL spec #6.4: http://www.khronos.org/registry/webgl/specs/latest/1.0/#6.4 + validateVertexAttribPointerAlignment: function(dataType, stride, offset) { + var sizeBytes = 1; + switch(dataType) { + case 0x1400 /* GL_BYTE */: + case 0x1401 /* GL_UNSIGNED_BYTE */: + sizeBytes = 1; + break; + case 0x1402 /* GL_SHORT */: + case 0x1403 /* GL_UNSIGNED_SHORT */: + sizeBytes = 2; + break; + case 0x1404 /* GL_INT */: + case 0x1405 /* GL_UNSIGNED_INT */: + case 0x1406 /* GL_FLOAT */: + sizeBytes = 4; + break; + case 0x140A /* GL_DOUBLE */: + sizeBytes = 8; + break; + default: + console.error('Invalid vertex attribute data type GLenum ' + dataType + ' passed to GL function!'); + } + if (offset % sizeBytes != 0) { + console.error('GL spec section 6.4 error: vertex attribute data offset of ' + offset + ' bytes should have been a multiple of the data type size that was used: GLenum ' + dataType + ' has size of ' + sizeBytes + ' bytes!'); + } + if (stride % sizeBytes != 0) { + console.error('GL spec section 6.4 error: vertex attribute data stride of ' + stride + ' bytes should have been a multiple of the data type size that was used: GLenum ' + dataType + ' has size of ' + sizeBytes + ' bytes!'); + } + }, #endif initExtensions: function() { @@ -3273,6 +3306,9 @@ var LibraryGL = { var clientAttributes = GL.immediate.clientAttributes; +#if GL_ASSERTIONS + GL.validateVertexAttribPointerAlignment(positionType, GL.immediate.stride, clientAttributes[GL.immediate.VERTEX].offset); +#endif Module.ctx.vertexAttribPointer(this.positionLocation, positionSize, positionType, false, GL.immediate.stride, clientAttributes[GL.immediate.VERTEX].offset); Module.ctx.enableVertexAttribArray(this.positionLocation); @@ -3285,6 +3321,9 @@ var LibraryGL = { if (attribLoc === undefined || attribLoc < 0) continue; if (texUnitID < textureSizes.length && textureSizes[texUnitID]) { +#if GL_ASSERTIONS + GL.validateVertexAttribPointerAlignment(textureTypes[texUnitID], GL.immediate.stride, GL.immediate.clientAttributes[GL.immediate.TEXTURE0 + texUnitID].offset); +#endif Module.ctx.vertexAttribPointer(attribLoc, textureSizes[texUnitID], textureTypes[texUnitID], false, GL.immediate.stride, GL.immediate.clientAttributes[GL.immediate.TEXTURE0 + texUnitID].offset); Module.ctx.enableVertexAttribArray(attribLoc); @@ -3301,6 +3340,9 @@ var LibraryGL = { } } if (colorSize) { +#if GL_ASSERTIONS + GL.validateVertexAttribPointerAlignment(colorType, GL.immediate.stride, clientAttributes[GL.immediate.COLOR].offset); +#endif Module.ctx.vertexAttribPointer(this.colorLocation, colorSize, colorType, true, GL.immediate.stride, clientAttributes[GL.immediate.COLOR].offset); Module.ctx.enableVertexAttribArray(this.colorLocation); @@ -3309,6 +3351,9 @@ var LibraryGL = { Module.ctx.vertexAttrib4fv(this.colorLocation, GL.immediate.clientColor); } if (this.hasNormal) { +#if GL_ASSERTIONS + GL.validateVertexAttribPointerAlignment(normalType, GL.immediate.stride, clientAttributes[GL.immediate.NORMAL].offset); +#endif Module.ctx.vertexAttribPointer(this.normalLocation, normalSize, normalType, true, GL.immediate.stride, clientAttributes[GL.immediate.NORMAL].offset); Module.ctx.enableVertexAttribArray(this.normalLocation); @@ -4287,6 +4332,9 @@ var LibraryGL = { return; } cb.clientside = false; +#endif +#if GL_ASSERTIONS + GL.validateVertexAttribPointerAlignment(type, stride, ptr); #endif Module.ctx.vertexAttribPointer(index, size, type, normalized, stride, ptr); }, From 5705b1a9a1f0c985c7d43dd7f9e31e14629e5d50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Wed, 25 Sep 2013 12:19:57 +0300 Subject: [PATCH 047/165] Also validate size and stride parameters in calls to glVertexAttribPointer. --- src/library_gl.js | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/library_gl.js b/src/library_gl.js index 06f0a117eb15b..83e687773a998 100644 --- a/src/library_gl.js +++ b/src/library_gl.js @@ -311,7 +311,7 @@ var LibraryGL = { 0, HEAPU8.subarray(cb.ptr, cb.ptr + size)); #if GL_ASSERTIONS - GL.validateVertexAttribPointerAlignment(cb.type, cb.stride, 0); + GL.validateVertexAttribPointer(cb.size, cb.type, cb.stride, 0); #endif Module.ctx.vertexAttribPointer(i, cb.size, cb.type, cb.normalized, cb.stride, 0); } @@ -335,7 +335,7 @@ var LibraryGL = { } }, // Validates that user obeys GL spec #6.4: http://www.khronos.org/registry/webgl/specs/latest/1.0/#6.4 - validateVertexAttribPointerAlignment: function(dataType, stride, offset) { + validateVertexAttribPointer: function(dimension, dataType, stride, offset) { var sizeBytes = 1; switch(dataType) { case 0x1400 /* GL_BYTE */: @@ -357,6 +357,14 @@ var LibraryGL = { default: console.error('Invalid vertex attribute data type GLenum ' + dataType + ' passed to GL function!'); } + if (dimension == 0x80E1 /* GL_BGRA */) { + console.error('WebGL does not support size=GL_BGRA in a call to glVertexAttribPointer! Please use size=4 and type=GL_UNSIGNED_BYTE instead!'); + } else if (dimension < 1 || dimension > 4) { + console.error('Invalid dimension='+dimension+' in call to glVertexAttribPointer, must be 1,2,3 or 4.'); + } + if (stride < 0 || stride > 255) { + console.error('Invalid stride='+stride+' in call to glVertexAttribPointer. Note that maximum supported stride in WebGL is 255!'); + } if (offset % sizeBytes != 0) { console.error('GL spec section 6.4 error: vertex attribute data offset of ' + offset + ' bytes should have been a multiple of the data type size that was used: GLenum ' + dataType + ' has size of ' + sizeBytes + ' bytes!'); } @@ -3307,7 +3315,7 @@ var LibraryGL = { var clientAttributes = GL.immediate.clientAttributes; #if GL_ASSERTIONS - GL.validateVertexAttribPointerAlignment(positionType, GL.immediate.stride, clientAttributes[GL.immediate.VERTEX].offset); + GL.validateVertexAttribPointer(positionSize, positionType, GL.immediate.stride, clientAttributes[GL.immediate.VERTEX].offset); #endif Module.ctx.vertexAttribPointer(this.positionLocation, positionSize, positionType, false, GL.immediate.stride, clientAttributes[GL.immediate.VERTEX].offset); @@ -3322,7 +3330,7 @@ var LibraryGL = { if (texUnitID < textureSizes.length && textureSizes[texUnitID]) { #if GL_ASSERTIONS - GL.validateVertexAttribPointerAlignment(textureTypes[texUnitID], GL.immediate.stride, GL.immediate.clientAttributes[GL.immediate.TEXTURE0 + texUnitID].offset); + GL.validateVertexAttribPointer(textureSizes[texUnitID], textureTypes[texUnitID], GL.immediate.stride, GL.immediate.clientAttributes[GL.immediate.TEXTURE0 + texUnitID].offset); #endif Module.ctx.vertexAttribPointer(attribLoc, textureSizes[texUnitID], textureTypes[texUnitID], false, GL.immediate.stride, GL.immediate.clientAttributes[GL.immediate.TEXTURE0 + texUnitID].offset); @@ -3341,7 +3349,7 @@ var LibraryGL = { } if (colorSize) { #if GL_ASSERTIONS - GL.validateVertexAttribPointerAlignment(colorType, GL.immediate.stride, clientAttributes[GL.immediate.COLOR].offset); + GL.validateVertexAttribPointer(colorSize, colorType, GL.immediate.stride, clientAttributes[GL.immediate.COLOR].offset); #endif Module.ctx.vertexAttribPointer(this.colorLocation, colorSize, colorType, true, GL.immediate.stride, clientAttributes[GL.immediate.COLOR].offset); @@ -3352,7 +3360,7 @@ var LibraryGL = { } if (this.hasNormal) { #if GL_ASSERTIONS - GL.validateVertexAttribPointerAlignment(normalType, GL.immediate.stride, clientAttributes[GL.immediate.NORMAL].offset); + GL.validateVertexAttribPointer(normalSize, normalType, GL.immediate.stride, clientAttributes[GL.immediate.NORMAL].offset); #endif Module.ctx.vertexAttribPointer(this.normalLocation, normalSize, normalType, true, GL.immediate.stride, clientAttributes[GL.immediate.NORMAL].offset); @@ -4334,7 +4342,7 @@ var LibraryGL = { cb.clientside = false; #endif #if GL_ASSERTIONS - GL.validateVertexAttribPointerAlignment(type, stride, ptr); + GL.validateVertexAttribPointer(size, type, stride, ptr); #endif Module.ctx.vertexAttribPointer(index, size, type, normalized, stride, ptr); }, From 5f726b5af429df683398c454f6cbd0f97228a9d5 Mon Sep 17 00:00:00 2001 From: ngld Date: Wed, 25 Sep 2013 15:57:52 +0200 Subject: [PATCH 048/165] Fix #1668: whiteSpace in _scanString should use only char codes as keys not chars and char codes. --- src/library.js | 8 +------- tests/test_core.py | 2 +- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/library.js b/src/library.js index 49f8e453b56fa..ee38cf5dd8402 100644 --- a/src/library.js +++ b/src/library.js @@ -1660,12 +1660,6 @@ LibraryManager.library = { __scanString.whiteSpace[{{{ charCode('\v') }}}] = 1; __scanString.whiteSpace[{{{ charCode('\f') }}}] = 1; __scanString.whiteSpace[{{{ charCode('\r') }}}] = 1; - __scanString.whiteSpace[' '] = 1; - __scanString.whiteSpace['\t'] = 1; - __scanString.whiteSpace['\n'] = 1; - __scanString.whiteSpace['\v'] = 1; - __scanString.whiteSpace['\f'] = 1; - __scanString.whiteSpace['\r'] = 1; } // Supports %x, %4x, %d.%d, %lld, %s, %f, %lf. // TODO: Support all format specifiers. @@ -1903,7 +1897,7 @@ LibraryManager.library = { break; } fields++; - } else if (format[formatIndex] in __scanString.whiteSpace) { + } else if (format[formatIndex].charCodeAt(0) in __scanString.whiteSpace) { next = get(); while (next in __scanString.whiteSpace) { if (next <= 0) break mainLoop; // End of input. diff --git a/tests/test_core.py b/tests/test_core.py index d1d3bab08e64e..d59fae40b9ecf 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -1788,7 +1788,7 @@ def test_strings(self): int xx, yy, zz; char s[32]; - int cc = sscanf("abc_10.b1_xyz_543_defg", "abc_%d.%2x_xyz_%3d_%3s", &xx, &yy, &zz, s); + int cc = sscanf("abc_10.b1_xyz9_543_defg", "abc_%d.%2x_xyz9_%3d_%3s", &xx, &yy, &zz, s); printf("%d:%d,%d,%d,%s\\n", cc, xx, yy, zz, s); printf("%d\\n", argc); From e9705b2fcb179fd16b60ab35c31bff87a5704743 Mon Sep 17 00:00:00 2001 From: ngld Date: Wed, 25 Sep 2013 16:41:40 +0200 Subject: [PATCH 049/165] Add timeb.h to struct_info.json --- src/library.js | 16 ++++------------ src/struct_info.json | 14 +++++++++++++- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/library.js b/src/library.js index b45dd8f5aa041..2e2298ecaf93b 100644 --- a/src/library.js +++ b/src/library.js @@ -6069,20 +6069,12 @@ LibraryManager.library = { // sys/timeb.h // ========================================================================== - // TODO: Where did this header go? - __timeb_struct_layout: Runtime.generateStructInfo([ - ['i32', 'time'], - ['i16', 'millitm'], - ['i16', 'timezone'], - ['i16', 'dstflag'] - ]), - ftime__deps: ['__timeb_struct_layout'], ftime: function(p) { var millis = Date.now(); - {{{ makeSetValue('p', '___timeb_struct_layout.time', 'Math.floor(millis/1000)', 'i32') }}}; - {{{ makeSetValue('p', '___timeb_struct_layout.millitm', 'millis % 1000', 'i16') }}}; - {{{ makeSetValue('p', '___timeb_struct_layout.timezone', '0', 'i16') }}}; // TODO - {{{ makeSetValue('p', '___timeb_struct_layout.dstflag', '0', 'i16') }}}; // TODO + {{{ makeSetValue('p', C_STRUCTS.timeb.time, 'Math.floor(millis/1000)', 'i32') }}}; + {{{ makeSetValue('p', C_STRUCTS.timeb.millitm, 'millis % 1000', 'i16') }}}; + {{{ makeSetValue('p', C_STRUCTS.timeb.timezone, '0', 'i16') }}}; // TODO + {{{ makeSetValue('p', C_STRUCTS.timeb.dstflag, '0', 'i16') }}}; // TODO return 0; }, diff --git a/src/struct_info.json b/src/struct_info.json index 2b095a8c5b024..28d24279e8717 100644 --- a/src/struct_info.json +++ b/src/struct_info.json @@ -224,7 +224,19 @@ "tms_cstime" ] } - }, + }, + { + "defines": [], + "file": "compat/sys/timeb.h", + "structs": { + "timeb": [ + "time", + "millitm", + "timezone", + "dstflag" + ] + } + }, { "file": "libc/sys/resource.h", "defines": [], From 8481d3023417529839067af4dca9c5484b69c309 Mon Sep 17 00:00:00 2001 From: ngld Date: Wed, 25 Sep 2013 17:33:52 +0200 Subject: [PATCH 050/165] Replace references to QUANTUM_SIZE with C_STRUCTS equivalents. --- src/library.js | 6 +++--- src/library_sdl.js | 40 ++++++++++++++++++++-------------------- src/struct_info.json | 24 ++++++++++++++++++++++-- 3 files changed, 45 insertions(+), 25 deletions(-) diff --git a/src/library.js b/src/library.js index 2e2298ecaf93b..7a14495187c20 100644 --- a/src/library.js +++ b/src/library.js @@ -5274,12 +5274,12 @@ LibraryManager.library = { return time1 - time0; }, - // Statically allocated time struct. (TODO: Shouldn't C_STRUCTS.tm.__size__ be used here?) - __tm_current: 'allocate({{{ Runtime.QUANTUM_SIZE }}}*26, "i8", ALLOC_STATIC)', + // Statically allocated time struct. + __tm_current: 'allocate({{{ C_STRUCTS.tm.__size__ }}}, "i8", ALLOC_STATIC)', // Statically allocated timezone string. We only use GMT as a timezone. __tm_timezone: 'allocate(intArrayFromString("GMT"), "i8", ALLOC_STATIC)', // Statically allocated time strings. - __tm_formatted: 'allocate({{{ Runtime.QUANTUM_SIZE }}}*26, "i8", ALLOC_STATIC)', + __tm_formatted: 'allocate({{{ C_STRUCTS.tm.__size__ }}}, "i8", ALLOC_STATIC)', mktime__deps: ['tzset'], mktime: function(tmPtr) { diff --git a/src/library_sdl.js b/src/library_sdl.js index e9d5a1d9cb14f..656b5a0238825 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -184,35 +184,35 @@ var LibrarySDL = { makeSurface: function(width, height, flags, usePageCanvas, source, rmask, gmask, bmask, amask) { flags = flags || 0; - var surf = _malloc(15*Runtime.QUANTUM_SIZE); // SDL_Surface has 15 fields of quantum size + var surf = _malloc({{{ C_STRUCTS.SDL_Surface.__size__ }}}); // SDL_Surface has 15 fields of quantum size var buffer = _malloc(width*height*4); // TODO: only allocate when locked the first time - var pixelFormat = _malloc(18*Runtime.QUANTUM_SIZE); + var pixelFormat = _malloc({{{ C_STRUCTS.SDL_PixelFormat.__size__ }}}); flags |= 1; // SDL_HWSURFACE - this tells SDL_MUSTLOCK that this needs to be locked //surface with SDL_HWPALETTE flag is 8bpp surface (1 byte) var is_SDL_HWPALETTE = flags & 0x00200000; var bpp = is_SDL_HWPALETTE ? 1 : 4; - {{{ makeSetValue('surf+Runtime.QUANTUM_SIZE*0', '0', 'flags', 'i32') }}} // SDL_Surface.flags - {{{ makeSetValue('surf+Runtime.QUANTUM_SIZE*1', '0', 'pixelFormat', 'void*') }}} // SDL_Surface.format TODO - {{{ makeSetValue('surf+Runtime.QUANTUM_SIZE*2', '0', 'width', 'i32') }}} // SDL_Surface.w - {{{ makeSetValue('surf+Runtime.QUANTUM_SIZE*3', '0', 'height', 'i32') }}} // SDL_Surface.h - {{{ makeSetValue('surf+Runtime.QUANTUM_SIZE*4', '0', 'width * bpp', 'i32') }}} // SDL_Surface.pitch, assuming RGBA or indexed for now, + {{{ makeSetValue('surf', C_STRUCTS.SDL_Surface.flags, 'flags', 'i32') }}} // SDL_Surface.flags + {{{ makeSetValue('surf', C_STRUCTS.SDL_Surface.format, 'pixelFormat', 'void*') }}} // SDL_Surface.format TODO + {{{ makeSetValue('surf', C_STRUCTS.SDL_Surface.w, 'width', 'i32') }}} // SDL_Surface.w + {{{ makeSetValue('surf', C_STRUCTS.SDL_Surface.h, 'height', 'i32') }}} // SDL_Surface.h + {{{ makeSetValue('surf', C_STRUCTS.SDL_Surface.pitch, 'width * bpp', 'i32') }}} // SDL_Surface.pitch, assuming RGBA or indexed for now, // since that is what ImageData gives us in browsers - {{{ makeSetValue('surf+Runtime.QUANTUM_SIZE*5', '0', 'buffer', 'void*') }}} // SDL_Surface.pixels - {{{ makeSetValue('surf+Runtime.QUANTUM_SIZE*6', '0', '0', 'i32*') }}} // SDL_Surface.offset + {{{ makeSetValue('surf', C_STRUCTS.SDL_Surface.pixels, 'buffer', 'void*') }}} // SDL_Surface.pixels + {{{ makeSetValue('surf', C_STRUCTS.SDL_Surface.clip_rect, '0', 'i32*') }}} // SDL_Surface.offset - {{{ makeSetValue('surf+Runtime.QUANTUM_SIZE*14', '0', '1', 'i32') }}} + {{{ makeSetValue('surf', C_STRUCTS.SDL_Surface.refcount, '1', 'i32') }}} - {{{ makeSetValue('pixelFormat + ' + C_STRUCTS.SDL_PixelFormat.format, '0', '-2042224636', 'i32') }}} // SDL_PIXELFORMAT_RGBA8888 - {{{ makeSetValue('pixelFormat + ' + C_STRUCTS.SDL_PixelFormat.palette, '0', '0', 'i32') }}} // TODO - {{{ makeSetValue('pixelFormat + ' + C_STRUCTS.SDL_PixelFormat.BitsPerPixel, '0', 'bpp * 8', 'i8') }}} - {{{ makeSetValue('pixelFormat + ' + C_STRUCTS.SDL_PixelFormat.BytesPerPixel, '0', 'bpp', 'i8') }}} + {{{ makeSetValue('pixelFormat', C_STRUCTS.SDL_PixelFormat.format, cDefine('SDL_PIXELFORMAT_RGBA8888'), 'i32') }}} // SDL_PIXELFORMAT_RGBA8888 + {{{ makeSetValue('pixelFormat', C_STRUCTS.SDL_PixelFormat.palette, '0', 'i32') }}} // TODO + {{{ makeSetValue('pixelFormat', C_STRUCTS.SDL_PixelFormat.BitsPerPixel, 'bpp * 8', 'i8') }}} + {{{ makeSetValue('pixelFormat', C_STRUCTS.SDL_PixelFormat.BytesPerPixel, 'bpp', 'i8') }}} - {{{ makeSetValue('pixelFormat + ' + C_STRUCTS.SDL_PixelFormat.Rmask, '0', 'rmask || 0x000000ff', 'i32') }}} - {{{ makeSetValue('pixelFormat + ' + C_STRUCTS.SDL_PixelFormat.Gmask, '0', 'gmask || 0x0000ff00', 'i32') }}} - {{{ makeSetValue('pixelFormat + ' + C_STRUCTS.SDL_PixelFormat.Bmask, '0', 'bmask || 0x00ff0000', 'i32') }}} - {{{ makeSetValue('pixelFormat + ' + C_STRUCTS.SDL_PixelFormat.Amask, '0', 'amask || 0xff000000', 'i32') }}} + {{{ makeSetValue('pixelFormat', C_STRUCTS.SDL_PixelFormat.Rmask, 'rmask || 0x000000ff', 'i32') }}} + {{{ makeSetValue('pixelFormat', C_STRUCTS.SDL_PixelFormat.Gmask, 'gmask || 0x0000ff00', 'i32') }}} + {{{ makeSetValue('pixelFormat', C_STRUCTS.SDL_PixelFormat.Bmask, 'bmask || 0x00ff0000', 'i32') }}} + {{{ makeSetValue('pixelFormat', C_STRUCTS.SDL_PixelFormat.Amask, 'amask || 0xff000000', 'i32') }}} // Decide if we want to use WebGL or not var useWebGL = (flags & 0x04000000) != 0; // SDL_OPENGL @@ -290,7 +290,7 @@ var LibrarySDL = { }, freeSurface: function(surf) { - var refcountPointer = surf + Runtime.QUANTUM_SIZE * 14; + var refcountPointer = surf + {{{ C_STRUCTS.SDL_Surface.refcount }}}; var refcount = {{{ makeGetValue('refcountPointer', '0', 'i32') }}}; if (refcount > 1) { {{{ makeSetValue('refcountPointer', '0', 'refcount - 1', 'i32') }}}; @@ -810,7 +810,7 @@ var LibrarySDL = { // SDL_Surface has the following fields: Uint32 flags, SDL_PixelFormat *format; int w, h; Uint16 pitch; void *pixels; ... // So we have fields all of the same size, and 5 of them before us. // TODO: Use macros like in library.js - {{{ makeSetValue('surf', '5*Runtime.QUANTUM_SIZE', 'surfData.buffer', 'void*') }}}; + {{{ makeSetValue('surf', C_STRUCTS.SDL_Surface.pixels, 'surfData.buffer', 'void*') }}}; if (surf == SDL.screen && Module.screenIsReadOnly && surfData.image) return 0; diff --git a/src/struct_info.json b/src/struct_info.json index 28d24279e8717..5b4726e8003ee 100644 --- a/src/struct_info.json +++ b/src/struct_info.json @@ -901,6 +901,26 @@ ] } }, + { + "file": "SDL/SDL_surface.h", + "defines": [], + "structs": { + "SDL_Surface": [ + "flags", + "format", + "w", + "h", + "pitch", + "pixels", + "userdata", + "locked", + "lock_data", + "clip_rect", + "map", + "refcount" + ] + } + }, { "file": "SDL/SDL_events.h", "defines": [], @@ -949,7 +969,7 @@ } }, { - "file": "SDL_audio.h", + "file": "SDL/SDL_audio.h", "defines": [ "SDL_AUDIO_MASK_BITSIZE", "SDL_AUDIO_MASK_DATATYPE", @@ -1007,7 +1027,7 @@ } }, { - "file": "SDL_version.h", + "file": "SDL/SDL_version.h", "defines": [ "SDL_MAJOR_VERSION", "SDL_MINOR_VERSION", From 2370dd4b6f32b9be38c736b3060ba690a720483f Mon Sep 17 00:00:00 2001 From: ngld Date: Wed, 25 Sep 2013 17:44:57 +0200 Subject: [PATCH 051/165] Fix some comments and bump EMSCRIPTEN_VERSION --- src/compiler.js | 1 - src/settings.js | 8 +------- tools/gen_struct_info.py | 4 ++-- tools/shared.py | 2 +- 4 files changed, 4 insertions(+), 11 deletions(-) diff --git a/src/compiler.js b/src/compiler.js index 6982403515ee8..f7c6dd5912b3f 100644 --- a/src/compiler.js +++ b/src/compiler.js @@ -207,7 +207,6 @@ if (VERBOSE) printErr('VERBOSE is on, this generates a lot of output and can slo // Load struct and define information. var temp = JSON.parse(read(STRUCT_INFO)); C_STRUCTS = temp.structs; -// NOTE: This overwrites C_DEFINES from settings.js, should this be fixed or will C_DEFINES in settings.js be deprecated? C_DEFINES = temp.defines; // Load compiler code diff --git a/src/settings.js b/src/settings.js index 8d9d4634377f9..8cdf420c38cfe 100644 --- a/src/settings.js +++ b/src/settings.js @@ -438,13 +438,7 @@ var DEBUG_TAGS_SHOWING = []; // metadata // legalizer -// A cached set of defines, generated from the header files. This -// lets the emscripten libc (library.js) see the right values. -// The list of defines was moved into struct_info.json in the same directory. +// The list of defines (C_DEFINES) was moved into struct_info.json in the same directory. // That file is automatically parsed by tools/gen_struct_info.py. // If you modify the headers, just clear your cache and emscripten libc should see // the new values. -// NOTE: Right now this value is ignored. -// TODO: See compiler.js (Should this var be deprecated?) -var C_DEFINES = {}; - diff --git a/tools/gen_struct_info.py b/tools/gen_struct_info.py index 6c4797474f51d..aab128ebc76ce 100644 --- a/tools/gen_struct_info.py +++ b/tools/gen_struct_info.py @@ -37,7 +37,7 @@ 'defines': [ 'DEFINE_1', 'DEFINE_2', - ['li', 'FLOAT_DEFINE'], + ['f', 'FLOAT_DEFINE'], 'DEFINE_3', ... ] @@ -92,7 +92,7 @@ def show(msg): show('WARN: pycparser isn\'t available. I won\'t be able to parse C files, only .json files.') def parse_header(path, cpp_opts): - # Tell the user how to get pycparser, if he tries to parse a C file. + # Tell the user how to get pycparser, if he or she tries to parse a C file. sys.stderr.write('ERR: I need pycparser to process C files. \n') sys.stderr.write(' Use "pip install pycparser" to install or download it from "https://github.com/eliben/pycparser".\n') sys.exit(1) diff --git a/tools/shared.py b/tools/shared.py index 554813ee635f2..53f8318522b55 100644 --- a/tools/shared.py +++ b/tools/shared.py @@ -304,7 +304,7 @@ def find_temp_directory(): # we re-check sanity when the settings are changed) # We also re-check sanity and clear the cache when the version changes -EMSCRIPTEN_VERSION = '1.5.9' +EMSCRIPTEN_VERSION = '1.5.10' def generate_sanity(): return EMSCRIPTEN_VERSION + '|' + get_llvm_target() + '|' + LLVM_ROOT From c2769dda59b300af47af19f342684f40722d6795 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Wed, 25 Sep 2013 14:48:32 -0700 Subject: [PATCH 052/165] loop only on the actually new types in type analysis --- src/analyzer.js | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/analyzer.js b/src/analyzer.js index 750f2a4c41c4f..3fb20253b7f60 100644 --- a/src/analyzer.js +++ b/src/analyzer.js @@ -30,6 +30,8 @@ function analyzer(data, sidePass) { var item = { items: data }; var data = item; + var newTypes = {}; + // Gather // Single-liners ['globalVariable', 'functionStub', 'unparsedFunction', 'unparsedGlobals', 'unparsedTypes', 'alias'].forEach(function(intertype) { @@ -42,6 +44,7 @@ function analyzer(data, sidePass) { temp.splitOut.forEach(function(type) { //dprint('types', 'adding defined type: ' + type.name_); Types.types[type.name_] = type; + newTypes[type.name_] = 1; if (QUANTUM_SIZE === 1) { Types.fatTypes[type.name_] = copy(type); } @@ -897,7 +900,7 @@ function analyzer(data, sidePass) { }); } - function addTypeInternal(type, data) { + function addTypeInternal(type) { if (type.length == 1) return; if (Types.types[type]) return; if (['internal', 'hidden', 'inbounds', 'void'].indexOf(type) != -1) return; @@ -908,8 +911,9 @@ function analyzer(data, sidePass) { // to look at the underlying type - it was not defined explicitly // anywhere else. var nonPointing = removeAllPointing(type); + if (Types.types[nonPointing]) return; var check = /^\[(\d+)\ x\ (.*)\]$/.exec(nonPointing); - if (check && !Types.types[nonPointing]) { + if (check) { var num = parseInt(check[1]); num = Math.max(num, 1); // [0 x something] is used not for allocations and such of course, but // for indexing - for an |array of unknown length|, basically. So we @@ -917,7 +921,7 @@ function analyzer(data, sidePass) { // check that we never allocate with this (either as a child structure // in the analyzer, or in calcSize in alloca). var subType = check[2]; - addTypeInternal(subType, data); // needed for anonymous structure definitions (see below) + addTypeInternal(subType); // needed for anonymous structure definitions (see below) // Huge structural types are represented very inefficiently, both here and in generated JS. Best to avoid them - for example static char x[10*1024*1024]; is bad, while static char *x = malloc(10*1024*1024) is fine. if (num >= 10*1024*1024) warnOnce('warning: very large fixed-size structural type: ' + type + ' - can you reduce it? (compilation may be slow)'); @@ -926,6 +930,7 @@ function analyzer(data, sidePass) { fields: range(num).map(function() { return subType }), lineNum: '?' }; + newTypes[nonPointing] = 1; // Also add a |[0 x type]| type var zerod = '[0 x ' + subType + ']'; if (!Types.types[zerod]) { @@ -934,6 +939,7 @@ function analyzer(data, sidePass) { fields: [subType, subType], // Two, so we get the flatFactor right. We care about the flatFactor, not the size here lineNum: '?' }; + newTypes[zerod] = 1; } return; } @@ -964,6 +970,7 @@ function analyzer(data, sidePass) { packed: packed, lineNum: '?' }; + newTypes[type] = 1; return; } @@ -975,13 +982,14 @@ function analyzer(data, sidePass) { flatSize: 1, lineNum: '?' }; + newTypes[type] = 1; } - function addType(type, data) { - addTypeInternal(type, data); + function addType(type) { + addTypeInternal(type); if (QUANTUM_SIZE === 1) { Types.flipTypes(); - addTypeInternal(type, data); + addTypeInternal(type); Types.flipTypes(); } } @@ -992,7 +1000,7 @@ function analyzer(data, sidePass) { // which handles type definitions, and later. Doing so before the first side pass will result in // making bad guesses about types which are actually defined for (var type in Types.needAnalysis) { - if (type) addType(type, data); + if (type) addType(type); } Types.needAnalysis = {}; } @@ -1021,17 +1029,18 @@ function analyzer(data, sidePass) { var more = true; while (more) { more = false; - for (var typeName in types) { + for (var typeName in newTypes) { var type = types[typeName]; if (type.flatIndexes) continue; var ready = true; type.fields.forEach(function(field) { if (isStructType(field)) { if (!types[field]) { - addType(field, item); + addType(field); ready = false; } else { if (!types[field].flatIndexes) { + newTypes[field] = 1; ready = false; } } @@ -1058,6 +1067,8 @@ function analyzer(data, sidePass) { Runtime.QUANTUM_SIZE = trueQuantumSize; Types.flipTypes(); } + + newTypes = null; } // Variable analyzer From c9e163ac7d2ccb17e455af7f689403c9371c0cec Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Wed, 25 Sep 2013 15:17:47 -0700 Subject: [PATCH 053/165] fix save_debug_files --- tools/tempfiles.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/tempfiles.py b/tools/tempfiles.py index 1721b2bb404fe..27da10829fae6 100644 --- a/tools/tempfiles.py +++ b/tools/tempfiles.py @@ -27,6 +27,7 @@ def get(self, suffix): def clean(self): if self.save_debug_files: + import sys print >> sys.stderr, 'not cleaning up temp files since in debug-save mode, see them in %s' % (self.tmp,) return for filename in self.to_clean: From ac75b943b75f769ba0b754ba4577c8556dcd3047 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Wed, 25 Sep 2013 15:26:10 -0700 Subject: [PATCH 054/165] remove duplicate temp file cleanup --- emscripten.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/emscripten.py b/emscripten.py index 19e2160d4420b..a58baba2ed213 100755 --- a/emscripten.py +++ b/emscripten.py @@ -68,8 +68,6 @@ def process_funcs((i, funcs, meta, settings_file, compiler, forwarded_file, libr except KeyboardInterrupt: # Python 2.7 seems to lock up when a child process throws KeyboardInterrupt raise Exception() - finally: - tempfiles.try_delete(funcs_file) if DEBUG: print >> sys.stderr, '.' return out From 6dda61e5fc7c89b759033319444017aff8e3605f Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Wed, 25 Sep 2013 15:40:06 -0700 Subject: [PATCH 055/165] add option to run funcs stage in the browser --- emscripten.py | 7 ++++++- src/compiler_funcs.html | 26 ++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 src/compiler_funcs.html diff --git a/emscripten.py b/emscripten.py index a58baba2ed213..b95e03a75d21c 100755 --- a/emscripten.py +++ b/emscripten.py @@ -58,6 +58,8 @@ def process_funcs((i, funcs, meta, settings_file, compiler, forwarded_file, libr f.write('\n') f.write(meta) f.close() + #print >> sys.stderr, 'running', str([settings_file, funcs_file, 'funcs', forwarded_file] + libraries).replace("'/", "'") # can use this in src/compiler_funcs.html arguments, + # # just copy temp dir to under this one out = jsrun.run_js( compiler, engine=compiler_engine, @@ -221,6 +223,8 @@ def save_settings(): funcs, chunk_size, jcache.get_cachename('emscript_files') if jcache else None) + #chunks = [chunks[0]] # pick specific chunks for debugging/profiling + funcs = None if jcache: @@ -249,7 +253,8 @@ def load_from_cache(chunk): if DEBUG: print >> sys.stderr, ' emscript: phase 2 working on %d chunks %s (intended chunk size: %.2f MB, meta: %.2f MB, forwarded: %.2f MB, total: %.2f MB)' % (len(chunks), ('using %d cores' % cores) if len(chunks) > 1 else '', chunk_size/(1024*1024.), len(meta)/(1024*1024.), len(forwarded_data)/(1024*1024.), total_ll_size/(1024*1024.)) commands = [ - (i, chunk, meta, settings_file, compiler, forwarded_file, libraries, compiler_engine, temp_files, DEBUG) + (i, chunk, meta, settings_file, compiler, forwarded_file, libraries, compiler_engine,# + ['--prof'], + temp_files, DEBUG) for i, chunk in enumerate(chunks) ] diff --git a/src/compiler_funcs.html b/src/compiler_funcs.html new file mode 100644 index 0000000000000..92553e8a778ec --- /dev/null +++ b/src/compiler_funcs.html @@ -0,0 +1,26 @@ + + +

Run the emscripten compiler in a web page, just for laughs

+Open the web console to see stderr output +
+

+
+
+
+
+

From 3b278b74a6111ece31de29dfec54eae957576a62 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Wed, 25 Sep 2013 15:48:27 -0700
Subject: [PATCH 056/165] try to load relooper for src dir, if not in expected
 location

---
 src/compiler.js | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/src/compiler.js b/src/compiler.js
index 4f16986c572c1..77abd53ba7963 100644
--- a/src/compiler.js
+++ b/src/compiler.js
@@ -215,7 +215,12 @@ load('analyzer.js');
 load('jsifier.js');
 if (phase == 'funcs' && RELOOP) { // XXX handle !singlePhase
   RelooperModule = { TOTAL_MEMORY: ceilPowerOfTwo(2*RELOOPER_BUFFER_SIZE) };
-  load(RELOOPER);
+  try {
+    load(RELOOPER);
+  } catch(e) {
+    printErr('cannot find relooper at ' + RELOOPER + ', trying in current dir');
+    load('relooper.js');
+  }
   assert(typeof Relooper != 'undefined');
 }
 globalEval(processMacros(preprocess(read('runtime.js'))));

From e2614195d865de86046f84fc56e74c4aa338ceb0 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Wed, 25 Sep 2013 15:51:11 -0700
Subject: [PATCH 057/165] hide output by default in compiler_funcs.html, main
 use is profiling

---
 src/compiler_funcs.html | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/src/compiler_funcs.html b/src/compiler_funcs.html
index 92553e8a778ec..f85953030b37f 100644
--- a/src/compiler_funcs.html
+++ b/src/compiler_funcs.html
@@ -5,17 +5,19 @@ 

Run the emscripten compiler in a web page, just for laughs



 

From 7d58080e9354e6e34cb70568ea20cfa410c17cae Mon Sep 17 00:00:00 2001
From: Bruce Mitchener 
Date: Sat, 14 Sep 2013 15:59:03 +0700
Subject: [PATCH 058/165] Add a lot of locale code.

---
 emcc                                          |  34 +++++-
 src/library.js                                |  18 +++-
 .../lib/libc/musl/src/internal/locale_impl.h  |   5 +
 system/lib/libc/musl/src/locale/iswalnum_l.c  |   6 ++
 system/lib/libc/musl/src/locale/iswalpha_l.c  |   6 ++
 system/lib/libc/musl/src/locale/iswblank_l.c  |   6 ++
 system/lib/libc/musl/src/locale/iswcntrl_l.c  |   6 ++
 system/lib/libc/musl/src/locale/iswctype_l.c  |   9 ++
 system/lib/libc/musl/src/locale/iswdigit_l.c  |   6 ++
 system/lib/libc/musl/src/locale/iswgraph_l.c  |   6 ++
 system/lib/libc/musl/src/locale/iswlower_l.c  |   6 ++
 system/lib/libc/musl/src/locale/iswprint_l.c  |   6 ++
 system/lib/libc/musl/src/locale/iswpunct_l.c  |   6 ++
 system/lib/libc/musl/src/locale/iswspace_l.c  |   6 ++
 system/lib/libc/musl/src/locale/iswupper_l.c  |   6 ++
 system/lib/libc/musl/src/locale/iswxdigit_l.c |   6 ++
 system/lib/libc/musl/src/locale/strfmon.c     | 101 ++++++++++++++++++
 system/lib/libc/musl/src/locale/strxfrm.c     |  18 ++++
 system/lib/libc/musl/src/locale/towctrans_l.c |   6 ++
 system/lib/libc/musl/src/locale/towlower_l.c  |   9 ++
 system/lib/libc/musl/src/locale/towupper_l.c  |   9 ++
 system/lib/libc/musl/src/locale/wcscoll.c     |  16 +++
 system/lib/libc/musl/src/locale/wcscoll_l.c   |   6 ++
 system/lib/libc/musl/src/locale/wcsxfrm.c     |  21 ++++
 system/lib/libc/musl/src/locale/wcsxfrm_l.c   |   6 ++
 system/lib/libc/musl/src/locale/wctrans_l.c   |   6 ++
 system/lib/libc/musl/src/locale/wctype_l.c    |   9 ++
 system/lib/libcextra.symbols                  |  35 ++++++
 28 files changed, 375 insertions(+), 5 deletions(-)
 create mode 100644 system/lib/libc/musl/src/internal/locale_impl.h
 create mode 100644 system/lib/libc/musl/src/locale/iswalnum_l.c
 create mode 100644 system/lib/libc/musl/src/locale/iswalpha_l.c
 create mode 100644 system/lib/libc/musl/src/locale/iswblank_l.c
 create mode 100644 system/lib/libc/musl/src/locale/iswcntrl_l.c
 create mode 100644 system/lib/libc/musl/src/locale/iswctype_l.c
 create mode 100644 system/lib/libc/musl/src/locale/iswdigit_l.c
 create mode 100644 system/lib/libc/musl/src/locale/iswgraph_l.c
 create mode 100644 system/lib/libc/musl/src/locale/iswlower_l.c
 create mode 100644 system/lib/libc/musl/src/locale/iswprint_l.c
 create mode 100644 system/lib/libc/musl/src/locale/iswpunct_l.c
 create mode 100644 system/lib/libc/musl/src/locale/iswspace_l.c
 create mode 100644 system/lib/libc/musl/src/locale/iswupper_l.c
 create mode 100644 system/lib/libc/musl/src/locale/iswxdigit_l.c
 create mode 100644 system/lib/libc/musl/src/locale/strfmon.c
 create mode 100644 system/lib/libc/musl/src/locale/strxfrm.c
 create mode 100644 system/lib/libc/musl/src/locale/towctrans_l.c
 create mode 100644 system/lib/libc/musl/src/locale/towlower_l.c
 create mode 100644 system/lib/libc/musl/src/locale/towupper_l.c
 create mode 100644 system/lib/libc/musl/src/locale/wcscoll.c
 create mode 100644 system/lib/libc/musl/src/locale/wcscoll_l.c
 create mode 100644 system/lib/libc/musl/src/locale/wcsxfrm.c
 create mode 100644 system/lib/libc/musl/src/locale/wcsxfrm_l.c
 create mode 100644 system/lib/libc/musl/src/locale/wctrans_l.c
 create mode 100644 system/lib/libc/musl/src/locale/wctype_l.c

diff --git a/emcc b/emcc
index cd42d49a22fdc..6006ab0894948 100755
--- a/emcc
+++ b/emcc
@@ -1282,6 +1282,10 @@ try:
         os.path.join('libc', 'gen', 'vwarnx.c'),
         os.path.join('libc', 'stdlib', 'strtod.c'),
       ]
+      musl_files = [
+      ]
+      for directory, sources in musl_files:
+        libc_files += [os.path.join('libc', 'musl', 'src', directory, source) for source in sources]
       return build_libc('libc.bc', libc_files)
 
     def apply_libc(need):
@@ -1319,6 +1323,32 @@ try:
           'wctrans.c',
           'wcwidth.c',
          ]],
+         ['locale', [
+          'iswalnum_l.c',
+          'iswalpha_l.c',
+          'iswblank_l.c',
+          'iswcntrl_l.c',
+          'iswctype_l.c',
+          'iswdigit_l.c',
+          'iswgraph_l.c',
+          'iswlower_l.c',
+          'iswprint_l.c',
+          'iswpunct_l.c',
+          'iswspace_l.c',
+          'iswupper_l.c',
+          'iswxdigit_l.c',
+          'strfmon.c',
+          'strxfrm.c',
+          'towctrans_l.c',
+          'towlower_l.c',
+          'towupper_l.c',
+          'wcscoll.c',
+          'wcscoll_l.c',
+          'wcsxfrm.c',
+          'wcsxfrm_l.c',
+          'wctrans_l.c',
+          'wctype_l.c',
+         ]],
          ['multibyte', [
           'btowc.c',
           'mblen.c',
@@ -1345,7 +1375,7 @@ try:
            'wcpcpy.c',
            'wcpncpy.c',
            'wcscasecmp.c',
-           # 'wcscasecmp_l.c', # XXX: alltypes.h issue
+           'wcscasecmp_l.c',
            'wcscat.c',
            'wcschr.c',
            'wcscmp.c',
@@ -1354,7 +1384,7 @@ try:
            'wcsdup.c',
            'wcslen.c',
            'wcsncasecmp.c',
-           # 'wcsncasecmp_l.c', # XXX: alltypes.h issue
+           'wcsncasecmp_l.c',
            'wcsncat.c',
            'wcsncmp.c',
            'wcsncpy.c',
diff --git a/src/library.js b/src/library.js
index 49f8e453b56fa..4bbff433ad79b 100644
--- a/src/library.js
+++ b/src/library.js
@@ -4084,6 +4084,7 @@ LibraryManager.library = {
     }
   },
   _toupper: 'toupper',
+  toupper_l: 'toupper',
 
   tolower__asm: true,
   tolower__sig: 'ii',
@@ -4094,54 +4095,65 @@ LibraryManager.library = {
     return (chr - {{{ charCode('A') }}} + {{{ charCode('a') }}})|0;
   },
   _tolower: 'tolower',
+  tolower_l: 'tolower',
 
   // The following functions are defined as macros in glibc.
   islower: function(chr) {
     return chr >= {{{ charCode('a') }}} && chr <= {{{ charCode('z') }}};
   },
+  islower_l: 'islower',
   isupper: function(chr) {
     return chr >= {{{ charCode('A') }}} && chr <= {{{ charCode('Z') }}};
   },
+  isupper_l: 'isupper',
   isalpha: function(chr) {
     return (chr >= {{{ charCode('a') }}} && chr <= {{{ charCode('z') }}}) ||
            (chr >= {{{ charCode('A') }}} && chr <= {{{ charCode('Z') }}});
   },
+  isalpha_l: 'isalpha',
   isdigit: function(chr) {
     return chr >= {{{ charCode('0') }}} && chr <= {{{ charCode('9') }}};
   },
-  isdigit_l: 'isdigit', // no locale support yet
+  isdigit_l: 'isdigit',
   isxdigit: function(chr) {
     return (chr >= {{{ charCode('0') }}} && chr <= {{{ charCode('9') }}}) ||
            (chr >= {{{ charCode('a') }}} && chr <= {{{ charCode('f') }}}) ||
            (chr >= {{{ charCode('A') }}} && chr <= {{{ charCode('F') }}});
   },
-  isxdigit_l: 'isxdigit', // no locale support yet
+  isxdigit_l: 'isxdigit',
   isalnum: function(chr) {
     return (chr >= {{{ charCode('0') }}} && chr <= {{{ charCode('9') }}}) ||
            (chr >= {{{ charCode('a') }}} && chr <= {{{ charCode('z') }}}) ||
            (chr >= {{{ charCode('A') }}} && chr <= {{{ charCode('Z') }}});
   },
+  isalnum_l: 'isalnum',
   ispunct: function(chr) {
     return (chr >= {{{ charCode('!') }}} && chr <= {{{ charCode('/') }}}) ||
            (chr >= {{{ charCode(':') }}} && chr <= {{{ charCode('@') }}}) ||
            (chr >= {{{ charCode('[') }}} && chr <= {{{ charCode('`') }}}) ||
            (chr >= {{{ charCode('{') }}} && chr <= {{{ charCode('~') }}});
   },
+  ispunct_l: 'ispunct',
   isspace: function(chr) {
     return (chr == 32) || (chr >= 9 && chr <= 13);
   },
+  isspace_l: 'isspace',
   isblank: function(chr) {
     return chr == {{{ charCode(' ') }}} || chr == {{{ charCode('\t') }}};
   },
+  isblank_l: 'isblank',
   iscntrl: function(chr) {
     return (0 <= chr && chr <= 0x1F) || chr === 0x7F;
   },
+  iscntrl_l: 'iscntrl',
   isprint: function(chr) {
     return 0x1F < chr && chr < 0x7F;
   },
+  isprint_l: 'isprint',
   isgraph: function(chr) {
     return 0x20 < chr && chr < 0x7F;
   },
+  isgraph_l: 'isgraph',
   // Lookup tables for glibc ctype implementation.
   __ctype_b_loc: function() {
     // http://refspecs.freestandards.org/LSB_3.0.0/LSB-Core-generic/LSB-Core-generic/baselib---ctype-b-loc.html
@@ -8884,7 +8896,7 @@ function autoAddDeps(object, name) {
 }
 
 // Add aborting stubs for various libc stuff needed by libc++
-['pthread_cond_signal', 'pthread_equal', 'wcstol', 'wcstoll', 'wcstoul', 'wcstoull', 'wcstof', 'wcstod', 'wcstold', 'swprintf', 'pthread_join', 'pthread_detach', 'strcoll_l', 'strxfrm_l', 'wcscoll_l', 'toupper_l', 'tolower_l', 'iswspace_l', 'iswprint_l', 'iswcntrl_l', 'iswupper_l', 'iswlower_l', 'iswalpha_l', 'iswdigit_l', 'iswpunct_l', 'iswxdigit_l', 'iswblank_l', 'wcsxfrm_l', 'towupper_l', 'towlower_l', 'catgets', 'catopen', 'catclose'].forEach(function(aborter) {
+['pthread_cond_signal', 'pthread_equal', 'wcstol', 'wcstoll', 'wcstoul', 'wcstoull', 'wcstof', 'wcstod', 'wcstold', 'swprintf', 'pthread_join', 'pthread_detach', 'strcoll_l', 'catgets', 'catopen', 'catclose'].forEach(function(aborter) {
   LibraryManager.library[aborter] = function() { throw 'TODO: ' + aborter };
 });
 
diff --git a/system/lib/libc/musl/src/internal/locale_impl.h b/system/lib/libc/musl/src/internal/locale_impl.h
new file mode 100644
index 0000000000000..c268124fabf24
--- /dev/null
+++ b/system/lib/libc/musl/src/internal/locale_impl.h
@@ -0,0 +1,5 @@
+#include 
+
+struct __locale {
+	int dummy;
+};
diff --git a/system/lib/libc/musl/src/locale/iswalnum_l.c b/system/lib/libc/musl/src/locale/iswalnum_l.c
new file mode 100644
index 0000000000000..c888060c4ce55
--- /dev/null
+++ b/system/lib/libc/musl/src/locale/iswalnum_l.c
@@ -0,0 +1,6 @@
+#include 
+
+int iswalnum_l(wint_t c, locale_t l)
+{
+	return iswalnum(c);
+}
diff --git a/system/lib/libc/musl/src/locale/iswalpha_l.c b/system/lib/libc/musl/src/locale/iswalpha_l.c
new file mode 100644
index 0000000000000..cd2be91e58281
--- /dev/null
+++ b/system/lib/libc/musl/src/locale/iswalpha_l.c
@@ -0,0 +1,6 @@
+#include 
+
+int iswalpha_l(wint_t c, locale_t l)
+{
+	return iswalpha(c);
+}
diff --git a/system/lib/libc/musl/src/locale/iswblank_l.c b/system/lib/libc/musl/src/locale/iswblank_l.c
new file mode 100644
index 0000000000000..f3a2691f581ff
--- /dev/null
+++ b/system/lib/libc/musl/src/locale/iswblank_l.c
@@ -0,0 +1,6 @@
+#include 
+
+int iswblank_l(wint_t c, locale_t l)
+{
+	return iswblank(c);
+}
diff --git a/system/lib/libc/musl/src/locale/iswcntrl_l.c b/system/lib/libc/musl/src/locale/iswcntrl_l.c
new file mode 100644
index 0000000000000..7681fe092b6f8
--- /dev/null
+++ b/system/lib/libc/musl/src/locale/iswcntrl_l.c
@@ -0,0 +1,6 @@
+#include 
+
+int iswcntrl_l(wint_t c, locale_t l)
+{
+	return iswcntrl(c);
+}
diff --git a/system/lib/libc/musl/src/locale/iswctype_l.c b/system/lib/libc/musl/src/locale/iswctype_l.c
new file mode 100644
index 0000000000000..13dfb1ed359f4
--- /dev/null
+++ b/system/lib/libc/musl/src/locale/iswctype_l.c
@@ -0,0 +1,9 @@
+#include 
+#include "libc.h"
+
+int iswctype_l(wint_t c, wctype_t t, locale_t l)
+{
+	return iswctype(c, t);
+}
+
+weak_alias(iswctype_l, __iswctype_l);
diff --git a/system/lib/libc/musl/src/locale/iswdigit_l.c b/system/lib/libc/musl/src/locale/iswdigit_l.c
new file mode 100644
index 0000000000000..3de678c24f132
--- /dev/null
+++ b/system/lib/libc/musl/src/locale/iswdigit_l.c
@@ -0,0 +1,6 @@
+#include 
+
+int iswdigit_l(wint_t c, locale_t l)
+{
+	return iswdigit(c);
+}
diff --git a/system/lib/libc/musl/src/locale/iswgraph_l.c b/system/lib/libc/musl/src/locale/iswgraph_l.c
new file mode 100644
index 0000000000000..34df64fc3ba33
--- /dev/null
+++ b/system/lib/libc/musl/src/locale/iswgraph_l.c
@@ -0,0 +1,6 @@
+#include 
+
+int iswgraph_l(wint_t c, locale_t l)
+{
+	return iswgraph(c);
+}
diff --git a/system/lib/libc/musl/src/locale/iswlower_l.c b/system/lib/libc/musl/src/locale/iswlower_l.c
new file mode 100644
index 0000000000000..c52421a043c86
--- /dev/null
+++ b/system/lib/libc/musl/src/locale/iswlower_l.c
@@ -0,0 +1,6 @@
+#include 
+
+int iswlower_l(wint_t c, locale_t l)
+{
+	return iswlower(c);
+}
diff --git a/system/lib/libc/musl/src/locale/iswprint_l.c b/system/lib/libc/musl/src/locale/iswprint_l.c
new file mode 100644
index 0000000000000..73d83ab356333
--- /dev/null
+++ b/system/lib/libc/musl/src/locale/iswprint_l.c
@@ -0,0 +1,6 @@
+#include 
+
+int iswprint_l(wint_t c, locale_t l)
+{
+	return iswprint(c);
+}
diff --git a/system/lib/libc/musl/src/locale/iswpunct_l.c b/system/lib/libc/musl/src/locale/iswpunct_l.c
new file mode 100644
index 0000000000000..831e0e5441963
--- /dev/null
+++ b/system/lib/libc/musl/src/locale/iswpunct_l.c
@@ -0,0 +1,6 @@
+#include 
+
+int iswpunct_l(wint_t c, locale_t l)
+{
+	return iswpunct(c);
+}
diff --git a/system/lib/libc/musl/src/locale/iswspace_l.c b/system/lib/libc/musl/src/locale/iswspace_l.c
new file mode 100644
index 0000000000000..b507e9e3a613c
--- /dev/null
+++ b/system/lib/libc/musl/src/locale/iswspace_l.c
@@ -0,0 +1,6 @@
+#include 
+
+int iswspace_l(wint_t c, locale_t l)
+{
+	return iswspace(c);
+}
diff --git a/system/lib/libc/musl/src/locale/iswupper_l.c b/system/lib/libc/musl/src/locale/iswupper_l.c
new file mode 100644
index 0000000000000..fc988ef119b49
--- /dev/null
+++ b/system/lib/libc/musl/src/locale/iswupper_l.c
@@ -0,0 +1,6 @@
+#include 
+
+int iswupper_l(wint_t c, locale_t l)
+{
+	return iswupper(c);
+}
diff --git a/system/lib/libc/musl/src/locale/iswxdigit_l.c b/system/lib/libc/musl/src/locale/iswxdigit_l.c
new file mode 100644
index 0000000000000..9527cf3e1d8c6
--- /dev/null
+++ b/system/lib/libc/musl/src/locale/iswxdigit_l.c
@@ -0,0 +1,6 @@
+#include 
+
+int iswxdigit_l(wint_t c, locale_t l)
+{
+	return iswxdigit(c);
+}
diff --git a/system/lib/libc/musl/src/locale/strfmon.c b/system/lib/libc/musl/src/locale/strfmon.c
new file mode 100644
index 0000000000000..f510d9a42f748
--- /dev/null
+++ b/system/lib/libc/musl/src/locale/strfmon.c
@@ -0,0 +1,101 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static ssize_t vstrfmon_l(char *s, size_t n, locale_t loc, const char *fmt, va_list ap)
+{
+	size_t l;
+	double x;
+	int fill, nogrp, negpar, nosym, left, intl;
+	int lp, rp, w, fw;
+	char *s0=s;
+	for (; n && *fmt; ) {
+		if (*fmt != '%') {
+		literal:
+			*s++ = *fmt++;
+			n--;
+			continue;
+		}
+		fmt++;
+		if (*fmt == '%') goto literal;
+
+		fill = ' ';
+		nogrp = 0;
+		negpar = 0;
+		nosym = 0;
+		left = 0;
+		for (; ; fmt++) {
+			switch (*fmt) {
+			case '=':
+				fill = *++fmt;
+				continue;
+			case '^':
+				nogrp = 1;
+				continue;
+			case '(':
+				negpar = 1;
+			case '+':
+				continue;
+			case '!':
+				nosym = 1;
+				continue;
+			case '-':
+				left = 1;
+				continue;
+			}
+			break;
+		}
+
+		for (fw=0; isdigit(*fmt); fmt++)
+			fw = 10*fw + (*fmt-'0');
+		lp = 0;
+		rp = 2;
+		if (*fmt=='#') for (lp=0, fmt++; isdigit(*fmt); fmt++)
+			lp = 10*lp + (*fmt-'0');
+		if (*fmt=='.') for (rp=0, fmt++; isdigit(*fmt); fmt++)
+			rp = 10*rp + (*fmt-'0');
+
+		intl = *fmt++ == 'i';
+
+		w = lp + 1 + rp;
+		if (!left && fw>w) w = fw;
+
+		x = va_arg(ap, double);
+		l = snprintf(s, n, "%*.*f", w, rp, x);
+		if (l >= n) {
+			errno = E2BIG;
+			return -1;
+		}
+		s += l;
+		n -= l;
+	}
+	return s-s0;
+}
+
+ssize_t strfmon_l(char *restrict s, size_t n, locale_t loc, const char *restrict fmt, ...)
+{
+	va_list ap;
+	ssize_t ret;
+
+	va_start(ap, fmt);
+	ret = vstrfmon_l(s, n, loc, fmt, ap);
+	va_end(ap);
+
+	return ret;
+}
+
+
+ssize_t strfmon(char *restrict s, size_t n, const char *restrict fmt, ...)
+{
+	va_list ap;
+	ssize_t ret;
+
+	va_start(ap, fmt);
+	ret = vstrfmon_l(s, n, 0, fmt, ap);
+	va_end(ap);
+
+	return ret;
+}
diff --git a/system/lib/libc/musl/src/locale/strxfrm.c b/system/lib/libc/musl/src/locale/strxfrm.c
new file mode 100644
index 0000000000000..32c461939dd42
--- /dev/null
+++ b/system/lib/libc/musl/src/locale/strxfrm.c
@@ -0,0 +1,18 @@
+#include 
+#include 
+#include "libc.h"
+
+/* collate only by code points */
+size_t __strxfrm_l(char *restrict dest, const char *restrict src, size_t n, locale_t loc)
+{
+	size_t l = strlen(src);
+	if (n > l) strcpy(dest, src);
+	return l;
+}
+
+size_t strxfrm(char *restrict dest, const char *restrict src, size_t n)
+{
+	return __strxfrm_l(dest, src, n, 0);
+}
+
+weak_alias(__strxfrm_l, strxfrm_l);
diff --git a/system/lib/libc/musl/src/locale/towctrans_l.c b/system/lib/libc/musl/src/locale/towctrans_l.c
new file mode 100644
index 0000000000000..6222058c750cf
--- /dev/null
+++ b/system/lib/libc/musl/src/locale/towctrans_l.c
@@ -0,0 +1,6 @@
+#include 
+
+wint_t towctrans_l(wint_t c, wctrans_t t, locale_t l)
+{
+	return towctrans(c, t);
+}
diff --git a/system/lib/libc/musl/src/locale/towlower_l.c b/system/lib/libc/musl/src/locale/towlower_l.c
new file mode 100644
index 0000000000000..aaaea370f81fa
--- /dev/null
+++ b/system/lib/libc/musl/src/locale/towlower_l.c
@@ -0,0 +1,9 @@
+#include 
+#include "libc.h"
+
+wint_t towlower_l(wint_t c, locale_t l)
+{
+	return towlower(c);
+}
+
+weak_alias(towlower_l, __towlower_l);
diff --git a/system/lib/libc/musl/src/locale/towupper_l.c b/system/lib/libc/musl/src/locale/towupper_l.c
new file mode 100644
index 0000000000000..ad02a4beab3ec
--- /dev/null
+++ b/system/lib/libc/musl/src/locale/towupper_l.c
@@ -0,0 +1,9 @@
+#include 
+#include "libc.h"
+
+wint_t towupper_l(wint_t c, locale_t l)
+{
+	return towupper(c);
+}
+
+weak_alias(towupper_l, __towupper_l);
diff --git a/system/lib/libc/musl/src/locale/wcscoll.c b/system/lib/libc/musl/src/locale/wcscoll.c
new file mode 100644
index 0000000000000..20a60900e0386
--- /dev/null
+++ b/system/lib/libc/musl/src/locale/wcscoll.c
@@ -0,0 +1,16 @@
+#include 
+#include 
+#include "libc.h"
+
+/* FIXME: stub */
+int __wcscoll_l(const wchar_t *l, const wchar_t *r, locale_t locale)
+{
+	return wcscmp(l, r);
+}
+
+int wcscoll(const wchar_t *l, const wchar_t *r)
+{
+	return __wcscoll_l(l, r, 0);
+}
+
+weak_alias(__wcscoll_l, wcscoll_l);
diff --git a/system/lib/libc/musl/src/locale/wcscoll_l.c b/system/lib/libc/musl/src/locale/wcscoll_l.c
new file mode 100644
index 0000000000000..f257ec8d98002
--- /dev/null
+++ b/system/lib/libc/musl/src/locale/wcscoll_l.c
@@ -0,0 +1,6 @@
+#include 
+
+int wcscoll_l(const wchar_t *l, const wchar_t *r, locale_t locale)
+{
+	return wcscoll(l, r);
+}
diff --git a/system/lib/libc/musl/src/locale/wcsxfrm.c b/system/lib/libc/musl/src/locale/wcsxfrm.c
new file mode 100644
index 0000000000000..cb79c97e79efd
--- /dev/null
+++ b/system/lib/libc/musl/src/locale/wcsxfrm.c
@@ -0,0 +1,21 @@
+#include 
+#include 
+#include "libc.h"
+
+/* collate only by code points */
+size_t __wcsxfrm_l(wchar_t *restrict dest, const wchar_t *restrict src, size_t n, locale_t loc)
+{
+	size_t l = wcslen(src);
+	if (l >= n) {
+		wmemcpy(dest, src, n-1);
+		dest[n-1] = 0;
+	} else wcscpy(dest, src);
+	return l;
+}
+
+size_t wcsxfrm(wchar_t *restrict dest, const wchar_t *restrict src, size_t n)
+{
+	return __wcsxfrm_l(dest, src, n, 0);
+}
+
+weak_alias(__wcsxfrm_l, wcsxfrm_l);
diff --git a/system/lib/libc/musl/src/locale/wcsxfrm_l.c b/system/lib/libc/musl/src/locale/wcsxfrm_l.c
new file mode 100644
index 0000000000000..66a00193c7827
--- /dev/null
+++ b/system/lib/libc/musl/src/locale/wcsxfrm_l.c
@@ -0,0 +1,6 @@
+#include 
+
+size_t wcsxfrm_l(wchar_t *restrict dest, const wchar_t *restrict src, size_t n, locale_t locale)
+{
+	return wcsxfrm(dest, src, n);
+}
diff --git a/system/lib/libc/musl/src/locale/wctrans_l.c b/system/lib/libc/musl/src/locale/wctrans_l.c
new file mode 100644
index 0000000000000..dae3381e11cf8
--- /dev/null
+++ b/system/lib/libc/musl/src/locale/wctrans_l.c
@@ -0,0 +1,6 @@
+#include 
+
+wctrans_t wctrans_l(const char *s, locale_t l)
+{
+	return wctrans(s);
+}
diff --git a/system/lib/libc/musl/src/locale/wctype_l.c b/system/lib/libc/musl/src/locale/wctype_l.c
new file mode 100644
index 0000000000000..601bab37d163f
--- /dev/null
+++ b/system/lib/libc/musl/src/locale/wctype_l.c
@@ -0,0 +1,9 @@
+#include 
+#include "libc.h"
+
+wctype_t wctype_l(const char *s, locale_t l)
+{
+	return wctype(s);
+}
+
+weak_alias(wctype_l, __wctype_l);
diff --git a/system/lib/libcextra.symbols b/system/lib/libcextra.symbols
index a365271d1f5a7..ba9f491eb077a 100644
--- a/system/lib/libcextra.symbols
+++ b/system/lib/libcextra.symbols
@@ -1,20 +1,40 @@
+         W __iswctype_l
+         T __strxfrm_l
+         W __towlower_l
+         W __towupper_l
+         T __wcscoll_l
+         T __wcsxfrm_l
+         W __wctype_l
          T btowc
          T ecvt
          T fcvt
          T gcvt
          T iswalnum
+         T iswalnum_l
          T iswalpha
+         T iswalpha_l
          T iswblank
+         T iswblank_l
          T iswcntrl
+         T iswcntrl_l
          T iswctype
+         T iswctype_l
          T iswdigit
+         T iswdigit_l
          T iswgraph
+         T iswgraph_l
          T iswlower
+         T iswlower_l
          T iswprint
+         T iswprint_l
          T iswpunct
+         T iswpunct_l
          T iswspace
+         T iswspace_l
          T iswupper
+         T iswupper_l
          T iswxdigit
+         T iswxdigit_l
          T mblen
          T mbrlen
          T mbrtowc
@@ -23,21 +43,32 @@
          T mbsrtowcs
          T mbstowcs
          T mbtowc
+         T strfmon
+         T strfmon_l
+         T strxfrm
+         W strxfrm_l
          T towctrans
+         T towctrans_l
          T towlower
+         T towlower_l
          T towupper
+         T towupper_l
          T wcpcpy
          T wcpncpy
          T wcrtomb
          T wcscasecmp
+         T wcscasecmp_l
          T wcscat
          T wcschr
          T wcscmp
+         T wcscoll
+         T wcscoll_l
          T wcscpy
          T wcscspn
          T wcsdup
          T wcslen
          T wcsncasecmp
+         T wcsncasecmp_l
          T wcsncat
          T wcsncmp
          T wcsncpy
@@ -52,10 +83,14 @@
          T wcstombs
          T wcswcs
          T wcswidth
+         T wcsxfrm
+         T wcsxfrm_l
          T wctob
          T wctomb
          T wctrans
+         T wctrans_l
          T wctype
+         T wctype_l
          T wcwidth
          T wmemchr
          T wmemcmp

From 2fd1d58f178256e16f329af4d40ba140b515b6ce Mon Sep 17 00:00:00 2001
From: Bruce Mitchener 
Date: Fri, 20 Sep 2013 22:03:41 +0700
Subject: [PATCH 059/165] Implement locale-ignoring strcoll_l.

---
 src/library.js | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/library.js b/src/library.js
index 4bbff433ad79b..f313bf972c04c 100644
--- a/src/library.js
+++ b/src/library.js
@@ -3818,6 +3818,7 @@ LibraryManager.library = {
   },
   // We always assume ASCII locale.
   strcoll: 'strcmp',
+  strcoll_l: 'strcmp',
 
   strcasecmp__asm: true,
   strcasecmp__sig: 'iii',
@@ -8896,7 +8897,7 @@ function autoAddDeps(object, name) {
 }
 
 // Add aborting stubs for various libc stuff needed by libc++
-['pthread_cond_signal', 'pthread_equal', 'wcstol', 'wcstoll', 'wcstoul', 'wcstoull', 'wcstof', 'wcstod', 'wcstold', 'swprintf', 'pthread_join', 'pthread_detach', 'strcoll_l', 'catgets', 'catopen', 'catclose'].forEach(function(aborter) {
+['pthread_cond_signal', 'pthread_equal', 'wcstol', 'wcstoll', 'wcstoul', 'wcstoull', 'wcstof', 'wcstod', 'wcstold', 'swprintf', 'pthread_join', 'pthread_detach', 'catgets', 'catopen', 'catclose'].forEach(function(aborter) {
   LibraryManager.library[aborter] = function() { throw 'TODO: ' + aborter };
 });
 

From 894d13a4db38885fc282f1f129b481870dfb1902 Mon Sep 17 00:00:00 2001
From: Bruce Mitchener 
Date: Wed, 25 Sep 2013 11:52:47 +0700
Subject: [PATCH 060/165] Add wprintf, swprintf, vswprintf, vfwprintf, etc.

---
 emcc                                          |   8 +
 src/library.js                                |   2 +-
 .../lib/libc/musl/src/internal/stdio_impl.h   |  92 +++++
 system/lib/libc/musl/src/stdio/fwprintf.c     |  13 +
 system/lib/libc/musl/src/stdio/swprintf.c     |  14 +
 system/lib/libc/musl/src/stdio/vfwprintf.c    | 361 ++++++++++++++++++
 system/lib/libc/musl/src/stdio/vswprintf.c    |  53 +++
 system/lib/libc/musl/src/stdio/vwprintf.c     |   7 +
 system/lib/libc/musl/src/stdio/wprintf.c      |  13 +
 system/lib/libcextra.symbols                  |   6 +
 10 files changed, 568 insertions(+), 1 deletion(-)
 create mode 100644 system/lib/libc/musl/src/internal/stdio_impl.h
 create mode 100644 system/lib/libc/musl/src/stdio/fwprintf.c
 create mode 100644 system/lib/libc/musl/src/stdio/swprintf.c
 create mode 100644 system/lib/libc/musl/src/stdio/vfwprintf.c
 create mode 100644 system/lib/libc/musl/src/stdio/vswprintf.c
 create mode 100644 system/lib/libc/musl/src/stdio/vwprintf.c
 create mode 100644 system/lib/libc/musl/src/stdio/wprintf.c

diff --git a/emcc b/emcc
index 6006ab0894948..95d77f10eb682 100755
--- a/emcc
+++ b/emcc
@@ -1366,6 +1366,14 @@ try:
           'wctob.c',
           'wctomb.c',
          ]],
+         ['stdio', [
+          'fwprintf.c',
+          'swprintf.c',
+          'vfwprintf.c',
+          'vswprintf.c',
+          'vwprintf.c',
+          'wprintf.c',
+         ]],
          ['stdlib', [
            'ecvt.c',
            'fcvt.c',
diff --git a/src/library.js b/src/library.js
index f313bf972c04c..a01153738d128 100644
--- a/src/library.js
+++ b/src/library.js
@@ -8897,7 +8897,7 @@ function autoAddDeps(object, name) {
 }
 
 // Add aborting stubs for various libc stuff needed by libc++
-['pthread_cond_signal', 'pthread_equal', 'wcstol', 'wcstoll', 'wcstoul', 'wcstoull', 'wcstof', 'wcstod', 'wcstold', 'swprintf', 'pthread_join', 'pthread_detach', 'catgets', 'catopen', 'catclose'].forEach(function(aborter) {
+['pthread_cond_signal', 'pthread_equal', 'wcstol', 'wcstoll', 'wcstoul', 'wcstoull', 'wcstof', 'wcstod', 'wcstold', 'pthread_join', 'pthread_detach', 'catgets', 'catopen', 'catclose'].forEach(function(aborter) {
   LibraryManager.library[aborter] = function() { throw 'TODO: ' + aborter };
 });
 
diff --git a/system/lib/libc/musl/src/internal/stdio_impl.h b/system/lib/libc/musl/src/internal/stdio_impl.h
new file mode 100644
index 0000000000000..2083b2fe427d6
--- /dev/null
+++ b/system/lib/libc/musl/src/internal/stdio_impl.h
@@ -0,0 +1,92 @@
+#ifndef _STDIO_IMPL_H
+#define _STDIO_IMPL_H
+
+#include 
+#include "syscall.h"
+#include "libc.h"
+
+#define UNGET 8
+
+#define FFINALLOCK(f) ((f)->lock>=0 ? __lockfile((f)) : 0)
+#define FLOCK(f) int __need_unlock = ((f)->lock>=0 ? __lockfile((f)) : 0)
+#define FUNLOCK(f) if (__need_unlock) __unlockfile((f)); else
+
+#define F_PERM 1
+#define F_NORD 4
+#define F_NOWR 8
+#define F_EOF 16
+#define F_ERR 32
+#define F_SVB 64
+
+struct _IO_FILE {
+	unsigned flags;
+	unsigned char *rpos, *rend;
+	int (*close)(FILE *);
+	unsigned char *wend, *wpos;
+	unsigned char *mustbezero_1;
+	unsigned char *wbase;
+	size_t (*read)(FILE *, unsigned char *, size_t);
+	size_t (*write)(FILE *, const unsigned char *, size_t);
+	off_t (*seek)(FILE *, off_t, int);
+	unsigned char *buf;
+	size_t buf_size;
+	FILE *prev, *next;
+	int fd;
+	int pipe_pid;
+	long lockcount;
+	short dummy3;
+	signed char mode;
+	signed char lbf;
+	int lock;
+	int waiters;
+	void *cookie;
+	off_t off;
+	char *getln_buf;
+	void *mustbezero_2;
+	unsigned char *shend;
+	off_t shlim, shcnt;
+};
+
+size_t __stdio_read(FILE *, unsigned char *, size_t);
+size_t __stdio_write(FILE *, const unsigned char *, size_t);
+size_t __stdout_write(FILE *, const unsigned char *, size_t);
+off_t __stdio_seek(FILE *, off_t, int);
+int __stdio_close(FILE *);
+
+size_t __string_read(FILE *, unsigned char *, size_t);
+
+int __toread(FILE *);
+int __towrite(FILE *);
+
+#if defined(__PIC__) && (100*__GNUC__+__GNUC_MINOR__ >= 303)
+__attribute__((visibility("protected")))
+#endif
+int __overflow(FILE *, int), __uflow(FILE *);
+
+int __fseeko(FILE *, off_t, int);
+int __fseeko_unlocked(FILE *, off_t, int);
+off_t __ftello(FILE *);
+off_t __ftello_unlocked(FILE *);
+size_t __fwritex(const unsigned char *, size_t, FILE *);
+int __putc_unlocked(int, FILE *);
+
+FILE *__fdopen(int, const char *);
+int __fmodeflags(const char *);
+
+#define OFLLOCK() LOCK(libc.ofl_lock)
+#define OFLUNLOCK() UNLOCK(libc.ofl_lock)
+
+#define feof(f) ((f)->flags & F_EOF)
+#define ferror(f) ((f)->flags & F_ERR)
+
+#define getc_unlocked(f) \
+	( ((f)->rpos < (f)->rend) ? *(f)->rpos++ : __uflow((f)) )
+
+#define putc_unlocked(c, f) ( ((c)!=(f)->lbf && (f)->wpos<(f)->wend) \
+	? *(f)->wpos++ = (c) : __overflow((f),(c)) )
+
+/* Caller-allocated FILE * operations */
+FILE *__fopen_rb_ca(const char *, FILE *, unsigned char *, size_t);
+int __fclose_ca(FILE *);
+
+#endif
diff --git a/system/lib/libc/musl/src/stdio/fwprintf.c b/system/lib/libc/musl/src/stdio/fwprintf.c
new file mode 100644
index 0000000000000..9ce4f0102e1b5
--- /dev/null
+++ b/system/lib/libc/musl/src/stdio/fwprintf.c
@@ -0,0 +1,13 @@
+#include 
+#include 
+#include 
+
+int fwprintf(FILE *restrict f, const wchar_t *restrict fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vfwprintf(f, fmt, ap);
+	va_end(ap);
+	return ret;
+}
diff --git a/system/lib/libc/musl/src/stdio/swprintf.c b/system/lib/libc/musl/src/stdio/swprintf.c
new file mode 100644
index 0000000000000..cbf83d235d8e0
--- /dev/null
+++ b/system/lib/libc/musl/src/stdio/swprintf.c
@@ -0,0 +1,14 @@
+#include 
+#include 
+#include 
+
+int swprintf(wchar_t *restrict s, size_t n, const wchar_t *restrict fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vswprintf(s, n, fmt, ap);
+	va_end(ap);
+	return ret;
+}
+
diff --git a/system/lib/libc/musl/src/stdio/vfwprintf.c b/system/lib/libc/musl/src/stdio/vfwprintf.c
new file mode 100644
index 0000000000000..eb0793121ed1b
--- /dev/null
+++ b/system/lib/libc/musl/src/stdio/vfwprintf.c
@@ -0,0 +1,361 @@
+#include "stdio_impl.h"
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* Convenient bit representation for modifier flags, which all fall
+ * within 31 codepoints of the space character. */
+
+#define ALT_FORM   (1U<<'#'-' ')
+#define ZERO_PAD   (1U<<'0'-' ')
+#define LEFT_ADJ   (1U<<'-'-' ')
+#define PAD_POS    (1U<<' '-' ')
+#define MARK_POS   (1U<<'+'-' ')
+#define GROUPED    (1U<<'\''-' ')
+
+#define FLAGMASK (ALT_FORM|ZERO_PAD|LEFT_ADJ|PAD_POS|MARK_POS|GROUPED)
+
+#if UINT_MAX == ULONG_MAX
+#define LONG_IS_INT
+#endif
+
+#if SIZE_MAX != ULONG_MAX || UINTMAX_MAX != ULLONG_MAX
+#define ODD_TYPES
+#endif
+
+/* State machine to accept length modifiers + conversion specifiers.
+ * Result is 0 on failure, or an argument type to pop on success. */
+
+enum {
+	BARE, LPRE, LLPRE, HPRE, HHPRE, BIGLPRE,
+	ZTPRE, JPRE,
+	STOP,
+	PTR, INT, UINT, ULLONG,
+#ifndef LONG_IS_INT
+	LONG, ULONG,
+#else
+#define LONG INT
+#define ULONG UINT
+#endif
+	SHORT, USHORT, CHAR, UCHAR,
+#ifdef ODD_TYPES
+	LLONG, SIZET, IMAX, UMAX, PDIFF, UIPTR,
+#else
+#define LLONG ULLONG
+#define SIZET ULONG
+#define IMAX LLONG
+#define UMAX ULLONG
+#define PDIFF LONG
+#define UIPTR ULONG
+#endif
+	DBL, LDBL,
+	NOARG,
+	MAXSTATE
+};
+
+#define S(x) [(x)-'A']
+
+static const unsigned char states[]['z'-'A'+1] = {
+	{ /* 0: bare types */
+		S('d') = INT, S('i') = INT,
+		S('o') = UINT, S('u') = UINT, S('x') = UINT, S('X') = UINT,
+		S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL,
+		S('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL,
+		S('c') = CHAR, S('C') = INT,
+		S('s') = PTR, S('S') = PTR, S('p') = UIPTR, S('n') = PTR,
+		S('m') = NOARG,
+		S('l') = LPRE, S('h') = HPRE, S('L') = BIGLPRE,
+		S('z') = ZTPRE, S('j') = JPRE, S('t') = ZTPRE,
+	}, { /* 1: l-prefixed */
+		S('d') = LONG, S('i') = LONG,
+		S('o') = ULONG, S('u') = ULONG, S('x') = ULONG, S('X') = ULONG,
+		S('c') = INT, S('s') = PTR, S('n') = PTR,
+		S('l') = LLPRE,
+	}, { /* 2: ll-prefixed */
+		S('d') = LLONG, S('i') = LLONG,
+		S('o') = ULLONG, S('u') = ULLONG,
+		S('x') = ULLONG, S('X') = ULLONG,
+		S('n') = PTR,
+	}, { /* 3: h-prefixed */
+		S('d') = SHORT, S('i') = SHORT,
+		S('o') = USHORT, S('u') = USHORT,
+		S('x') = USHORT, S('X') = USHORT,
+		S('n') = PTR,
+		S('h') = HHPRE,
+	}, { /* 4: hh-prefixed */
+		S('d') = CHAR, S('i') = CHAR,
+		S('o') = UCHAR, S('u') = UCHAR,
+		S('x') = UCHAR, S('X') = UCHAR,
+		S('n') = PTR,
+	}, { /* 5: L-prefixed */
+		S('e') = LDBL, S('f') = LDBL, S('g') = LDBL, S('a') = LDBL,
+		S('E') = LDBL, S('F') = LDBL, S('G') = LDBL, S('A') = LDBL,
+		S('n') = PTR,
+	}, { /* 6: z- or t-prefixed (assumed to be same size) */
+		S('d') = PDIFF, S('i') = PDIFF,
+		S('o') = SIZET, S('u') = SIZET,
+		S('x') = SIZET, S('X') = SIZET,
+		S('n') = PTR,
+	}, { /* 7: j-prefixed */
+		S('d') = IMAX, S('i') = IMAX,
+		S('o') = UMAX, S('u') = UMAX,
+		S('x') = UMAX, S('X') = UMAX,
+		S('n') = PTR,
+	}
+};
+
+#define OOB(x) ((unsigned)(x)-'A' > 'z'-'A')
+
+union arg
+{
+	uintmax_t i;
+	long double f;
+	void *p;
+};
+
+static void pop_arg(union arg *arg, int type, va_list *ap)
+{
+	/* Give the compiler a hint for optimizing the switch. */
+	if ((unsigned)type > MAXSTATE) return;
+	switch (type) {
+	       case PTR:	arg->p = va_arg(*ap, void *);
+	break; case INT:	arg->i = va_arg(*ap, int);
+	break; case UINT:	arg->i = va_arg(*ap, unsigned int);
+#ifndef LONG_IS_INT
+	break; case LONG:	arg->i = va_arg(*ap, long);
+	break; case ULONG:	arg->i = va_arg(*ap, unsigned long);
+#endif
+	break; case ULLONG:	arg->i = va_arg(*ap, unsigned long long);
+	break; case SHORT:	arg->i = (short)va_arg(*ap, int);
+	break; case USHORT:	arg->i = (unsigned short)va_arg(*ap, int);
+	break; case CHAR:	arg->i = (signed char)va_arg(*ap, int);
+	break; case UCHAR:	arg->i = (unsigned char)va_arg(*ap, int);
+#ifdef ODD_TYPES
+	break; case LLONG:	arg->i = va_arg(*ap, long long);
+	break; case SIZET:	arg->i = va_arg(*ap, size_t);
+	break; case IMAX:	arg->i = va_arg(*ap, intmax_t);
+	break; case UMAX:	arg->i = va_arg(*ap, uintmax_t);
+	break; case PDIFF:	arg->i = va_arg(*ap, ptrdiff_t);
+	break; case UIPTR:	arg->i = (uintptr_t)va_arg(*ap, void *);
+#endif
+	break; case DBL:	arg->f = va_arg(*ap, double);
+	break; case LDBL:	arg->f = va_arg(*ap, long double);
+	}
+}
+
+static void out(FILE *f, const wchar_t *s, size_t l)
+{
+	while (l--) fputwc(*s++, f);
+}
+
+static int getint(wchar_t **s) {
+	int i;
+	for (i=0; iswdigit(**s); (*s)++)
+		i = 10*i + (**s-'0');
+	return i;
+}
+
+static const char sizeprefix['y'-'a'] = {
+['a'-'a']='L', ['e'-'a']='L', ['f'-'a']='L', ['g'-'a']='L',
+['d'-'a']='j', ['i'-'a']='j', ['o'-'a']='j', ['u'-'a']='j', ['x'-'a']='j',
+['p'-'a']='j'
+};
+
+static int wprintf_core(FILE *f, const wchar_t *fmt, va_list *ap, union arg *nl_arg, int *nl_type)
+{
+	wchar_t *a, *z, *s=(wchar_t *)fmt, *s0;
+	unsigned l10n=0, litpct, fl;
+	int w, p;
+	union arg arg;
+	int argpos;
+	unsigned st, ps;
+	int cnt=0, l=0;
+	int i;
+	int t;
+	char *bs;
+	char charfmt[16];
+	wchar_t wc;
+
+	for (;;) {
+		/* Update output count, end loop when fmt is exhausted */
+		if (cnt >= 0) {
+			if (l > INT_MAX - cnt) {
+				if (!ferror(f)) errno = EOVERFLOW;
+				cnt = -1;
+			} else cnt += l;
+		}
+		if (!*s) break;
+
+		/* Handle literal text and %% format specifiers */
+		for (a=s; *s && *s!='%'; s++);
+		litpct = wcsspn(s, L"%")/2; /* Optimize %%%% runs */
+		z = s+litpct;
+		s += 2*litpct;
+		l = z-a;
+		if (f) out(f, a, l);
+		if (l) continue;
+
+		if (iswdigit(s[1]) && s[2]=='$') {
+			l10n=1;
+			argpos = s[1]-'0';
+			s+=3;
+		} else {
+			argpos = -1;
+			s++;
+		}
+
+		/* Read modifier flags */
+		for (fl=0; (unsigned)*s-' '<32 && (FLAGMASK&(1U<<*s-' ')); s++)
+			fl |= 1U<<*s-' ';
+
+		/* Read field width */
+		if (*s=='*') {
+			if (iswdigit(s[1]) && s[2]=='$') {
+				l10n=1;
+				nl_type[s[1]-'0'] = INT;
+				w = nl_arg[s[1]-'0'].i;
+				s+=3;
+			} else if (!l10n) {
+				w = f ? va_arg(*ap, int) : 0;
+				s++;
+			} else return -1;
+			if (w<0) fl|=LEFT_ADJ, w=-w;
+		} else if ((w=getint(&s))<0) return -1;
+
+		/* Read precision */
+		if (*s=='.' && s[1]=='*') {
+			if (isdigit(s[2]) && s[3]=='$') {
+				nl_type[s[2]-'0'] = INT;
+				p = nl_arg[s[2]-'0'].i;
+				s+=4;
+			} else if (!l10n) {
+				p = f ? va_arg(*ap, int) : 0;
+				s+=2;
+			} else return -1;
+		} else if (*s=='.') {
+			s++;
+			p = getint(&s);
+		} else p = -1;
+
+		/* Format specifier state machine */
+		s0=s;
+		st=0;
+		do {
+			if (OOB(*s)) return -1;
+			ps=st;
+			st=states[st]S(*s++);
+		} while (st-1=0) return -1;
+			else if (!f) continue;
+		} else {
+			if (argpos>=0) nl_type[argpos]=st, arg=nl_arg[argpos];
+			else if (f) pop_arg(&arg, st, ap);
+			else return 0;
+		}
+
+		if (!f) continue;
+		t = s[-1];
+		if (ps && (t&15)==3) t&=~32;
+
+		switch (t) {
+		case 'n':
+			switch(ps) {
+			case BARE: *(int *)arg.p = cnt; break;
+			case LPRE: *(long *)arg.p = cnt; break;
+			case LLPRE: *(long long *)arg.p = cnt; break;
+			case HPRE: *(unsigned short *)arg.p = cnt; break;
+			case HHPRE: *(unsigned char *)arg.p = cnt; break;
+			case ZTPRE: *(size_t *)arg.p = cnt; break;
+			case JPRE: *(uintmax_t *)arg.p = cnt; break;
+			}
+			continue;
+		case 'c':
+			fputwc(btowc(arg.i), f);
+			l = 1;
+			continue;
+		case 'C':
+			fputwc(arg.i, f);
+			l = 1;
+			continue;
+		case 'S':
+			a = arg.p;
+			z = wmemchr(a, 0, p);
+			if (!z) z=a+p;
+			else p=z-a;
+			if (w0; bs+=i, l++);
+			if (i<0) return -1;
+			p=l;
+			if (w
+#include 
+#include 
+#include 
+#include 
+
+struct cookie {
+	wchar_t *ws;
+	size_t l;
+};
+
+static size_t sw_write(FILE *f, const unsigned char *s, size_t l)
+{
+	size_t l0 = l;
+	int i = 0;
+	struct cookie *c = f->cookie;
+	if (s!=f->wbase && sw_write(f, f->wbase, f->wpos-f->wbase)==-1)
+		return -1;
+	while (c->l && l && (i=mbtowc(c->ws, (void *)s, l))>=0) {
+		s+=i;
+		l-=i;
+		c->l--;
+		c->ws++;
+	}
+	*c->ws = 0;
+	return i<0 ? i : l0;
+}
+
+int vswprintf(wchar_t *restrict s, size_t n, const wchar_t *restrict fmt, va_list ap)
+{
+	int r;
+	FILE f;
+	unsigned char buf[256];
+	struct cookie c = { s, n-1 };
+
+	memset(&f, 0, sizeof(FILE));
+	f.lbf = EOF;
+	f.write = sw_write;
+	f.buf_size = sizeof buf;
+	f.buf = buf;
+	f.lock = -1;
+	f.cookie = &c;
+	if (!n) {
+		return -1;
+	} else if (n > INT_MAX) {
+		errno = EOVERFLOW;
+		return -1;
+	}
+	r = vfwprintf(&f, fmt, ap);
+	sw_write(&f, 0, 0);
+	return r>=n ? -1 : r;
+}
diff --git a/system/lib/libc/musl/src/stdio/vwprintf.c b/system/lib/libc/musl/src/stdio/vwprintf.c
new file mode 100644
index 0000000000000..eeeecdc7c62ae
--- /dev/null
+++ b/system/lib/libc/musl/src/stdio/vwprintf.c
@@ -0,0 +1,7 @@
+#include 
+#include 
+
+int vwprintf(const wchar_t *restrict fmt, va_list ap)
+{
+	return vfwprintf(stdout, fmt, ap);
+}
diff --git a/system/lib/libc/musl/src/stdio/wprintf.c b/system/lib/libc/musl/src/stdio/wprintf.c
new file mode 100644
index 0000000000000..342cd97911d36
--- /dev/null
+++ b/system/lib/libc/musl/src/stdio/wprintf.c
@@ -0,0 +1,13 @@
+#include 
+#include 
+#include 
+
+int wprintf(const wchar_t *restrict fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vwprintf(fmt, ap);
+	va_end(ap);
+	return ret;
+}
diff --git a/system/lib/libcextra.symbols b/system/lib/libcextra.symbols
index ba9f491eb077a..806b49dbe47ee 100644
--- a/system/lib/libcextra.symbols
+++ b/system/lib/libcextra.symbols
@@ -8,6 +8,7 @@
          T btowc
          T ecvt
          T fcvt
+         T fwprintf
          T gcvt
          T iswalnum
          T iswalnum_l
@@ -47,12 +48,16 @@
          T strfmon_l
          T strxfrm
          W strxfrm_l
+         T swprintf
          T towctrans
          T towctrans_l
          T towlower
          T towlower_l
          T towupper
          T towupper_l
+         T vfwprintf
+         T vswprintf
+         T vwprintf
          T wcpcpy
          T wcpncpy
          T wcrtomb
@@ -97,3 +102,4 @@
          T wmemcpy
          T wmemmove
          T wmemset
+         T wprintf

From 0725ff3edc2ddddbd126193ca8ccaf392044b5ab Mon Sep 17 00:00:00 2001
From: Bruce Mitchener 
Date: Wed, 25 Sep 2013 11:58:12 +0700
Subject: [PATCH 061/165] Bump version.

---
 tools/shared.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/shared.py b/tools/shared.py
index 2d9ae9f6704d4..4d0f92b5508b9 100644
--- a/tools/shared.py
+++ b/tools/shared.py
@@ -304,7 +304,7 @@ def find_temp_directory():
 # we re-check sanity when the settings are changed)
 # We also re-check sanity and clear the cache when the version changes
 
-EMSCRIPTEN_VERSION = '1.6.1'
+EMSCRIPTEN_VERSION = '1.6.2'
 
 def generate_sanity():
   return EMSCRIPTEN_VERSION + '|' + get_llvm_target() + '|' + LLVM_ROOT

From 328abc1d77ba78ba2eba6b3df97bd00d9588b881 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Wed, 25 Sep 2013 18:53:16 -0700
Subject: [PATCH 062/165] optimize getFastValue

---
 src/compiler_funcs.html |  2 +-
 src/parseTools.js       | 56 +++++++++++++++++++++++++++++------------
 2 files changed, 41 insertions(+), 17 deletions(-)

diff --git a/src/compiler_funcs.html b/src/compiler_funcs.html
index f85953030b37f..a769955b0c093 100644
--- a/src/compiler_funcs.html
+++ b/src/compiler_funcs.html
@@ -5,7 +5,7 @@ 

Run the emscripten compiler in a web page, just for laughs



 
 
+
 
 
 

From 9dae0267e8a9ac0c28c10247aa46211d84f7e18f Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Thu, 26 Sep 2013 18:09:25 -0700
Subject: [PATCH 075/165] optimize parseLLVMString

---
 src/parseTools.js | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/parseTools.js b/src/parseTools.js
index 849c7cd115b6f..c06d0a0deead8 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -935,12 +935,12 @@ function parseLLVMString(str) {
   var ret = [];
   var i = 0;
   while (i < str.length) {
-    var chr = str[i];
-    if (chr != '\\') {
-      ret.push(chr.charCodeAt(0));
+    var chr = str.charCodeAt(i);
+    if (chr !== 92) { // 92 === '//'.charCodeAt(0)
+      ret.push(chr);
       i++;
     } else {
-      ret.push(eval('0x' + str[i+1]+str[i+2]));
+      ret.push(parseInt(str[i+1]+str[i+2], '16'));
       i += 3;
     }
   }

From 7a840e573cdc0abbca3c1dbf639797082b5124c8 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Thu, 26 Sep 2013 22:03:31 -0700
Subject: [PATCH 076/165] intertyper profiler

---
 src/compiler.js   |  2 ++
 src/intertyper.js | 13 +++++++++++++
 2 files changed, 15 insertions(+)

diff --git a/src/compiler.js b/src/compiler.js
index 77abd53ba7963..94197390f31ff 100644
--- a/src/compiler.js
+++ b/src/compiler.js
@@ -274,6 +274,8 @@ function compile(raw) {
     intertyped = null;
     JSify(analyzed);
 
+    //dumpInterProf();
+
     phase = null;
 
     if (DEBUG_MEMORY) {
diff --git a/src/intertyper.js b/src/intertyper.js
index e43cc298138e1..525096f53ccd3 100644
--- a/src/intertyper.js
+++ b/src/intertyper.js
@@ -987,8 +987,14 @@ function intertyper(lines, sidePass, baseLineNums) {
   // Input
 
   lineSplitter().forEach(function(line) {
+    //var time = Date.now();
+
     var t = tokenizer(line);
     var item = triager(t);
+
+    //var type = item ? item.intertype + (item.op ? ':' + item.op : ''): 'none';
+    //interProf[type] = (interProf[type] || 0) + Date.now() - time;
+
     if (!item) return;
     finalResults.push(item);
     if (item.tokens) item.tokens = null; // We do not need tokens, past the intertyper. Clean them up as soon as possible here.
@@ -996,3 +1002,10 @@ function intertyper(lines, sidePass, baseLineNums) {
   return finalResults;
 }
 
+/*
+var interProf = {};
+function dumpInterProf() {
+  printErr('\nintertyper/' + phase + ' : ' + JSON.stringify(keys(interProf).sort(function(x, y) { return interProf[y] - interProf[x] }).map(function(x) { return x + ':' + interProf[x] }), null, ' ') + '\n');
+}
+*/
+

From 36ab87e2f49682c9b206b17805685a279f7e47fa Mon Sep 17 00:00:00 2001
From: Anthony Pesch 
Date: Fri, 6 Sep 2013 23:43:13 -0700
Subject: [PATCH 077/165]  - made chdir use FS.chdir  - changed direct
 references to FS.currentPath to use FS.cwd()  - fixed mountpoint resolving in
 mount  - added async FS.syncfs

---
 src/library.js    | 25 ++++++------------
 src/library_fs.js | 65 ++++++++++++++++++++++++++++++++++++++---------
 2 files changed, 61 insertions(+), 29 deletions(-)

diff --git a/src/library.js b/src/library.js
index 326369c5eb9c3..6209df284279d 100644
--- a/src/library.js
+++ b/src/library.js
@@ -688,24 +688,13 @@ LibraryManager.library = {
     // http://pubs.opengroup.org/onlinepubs/000095399/functions/chdir.html
     // NOTE: The path argument may be a string, to simplify fchdir().
     if (typeof path !== 'string') path = Pointer_stringify(path);
-    var lookup;
     try {
-      lookup = FS.lookupPath(path, { follow: true });
+      FS.chdir(path);
+      return 0;
     } catch (e) {
       FS.handleFSError(e);
       return -1;
     }
-    if (!FS.isDir(lookup.node.mode)) {
-      ___setErrNo(ERRNO_CODES.ENOTDIR);
-      return -1;
-    }
-    var err = FS.nodePermissions(lookup.node, 'x');
-    if (err) {
-      ___setErrNo(err);
-      return -1;
-    }
-    FS.currentPath = lookup.path;
-    return 0;
   },
   chown__deps: ['$FS', '__setErrNo', '$ERRNO_CODES'],
   chown: function(path, owner, group, dontResolveLastLink) {
@@ -909,12 +898,14 @@ LibraryManager.library = {
     if (size == 0) {
       ___setErrNo(ERRNO_CODES.EINVAL);
       return 0;
-    } else if (size < FS.currentPath.length + 1) {
+    }
+    var cwd = FS.cwd();
+    if (size < cwd.length + 1) {
       ___setErrNo(ERRNO_CODES.ERANGE);
       return 0;
     } else {
-      for (var i = 0; i < FS.currentPath.length; i++) {
-        {{{ makeSetValue('buf', 'i', 'FS.currentPath.charCodeAt(i)', 'i8') }}}
+      for (var i = 0; i < cwd.length; i++) {
+        {{{ makeSetValue('buf', 'i', 'cwd.charCodeAt(i)', 'i8') }}}
       }
       {{{ makeSetValue('buf', 'i', '0', 'i8') }}}
       return buf;
@@ -4249,7 +4240,7 @@ LibraryManager.library = {
   llvm_va_end: function() {},
 
   llvm_va_copy: function(ppdest, ppsrc) {
-  	// copy the list start
+    // copy the list start
     {{{ makeCopyValues('ppdest', 'ppsrc', Runtime.QUANTUM_SIZE, 'null', null, 1) }}};
     
     // copy the list's current offset (will be advanced with each call to va_arg)
diff --git a/src/library_fs.js b/src/library_fs.js
index 84a5245bd380e..983e0d7665b37 100644
--- a/src/library_fs.js
+++ b/src/library_fs.js
@@ -14,6 +14,7 @@ mergeInto(LibraryManager.library, {
                 'Module["FS_createDevice"] = FS.createDevice;',
   $FS: {
     root: null,
+    mounts: [],
     devices: [null],
     streams: [null],
     nextInode: 1,
@@ -50,11 +51,8 @@ mergeInto(LibraryManager.library, {
     //
     // paths
     //
-    cwd: function() {
-      return FS.currentPath;
-    },
     lookupPath: function(path, opts) {
-      path = PATH.resolve(FS.currentPath, path);
+      path = PATH.resolve(FS.cwd(), path);
       opts = opts || { recurse_count: 0 };
 
       if (opts.recurse_count > 8) {  // max recursive lookup of 8
@@ -309,7 +307,7 @@ mergeInto(LibraryManager.library, {
         if (!FS.isDir(node.mode)) {
           return ERRNO_CODES.ENOTDIR;
         }
-        if (FS.isRoot(node) || FS.getPath(node) === FS.currentPath) {
+        if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) {
           return ERRNO_CODES.EBUSY;
         }
       } else {
@@ -422,17 +420,45 @@ mergeInto(LibraryManager.library, {
     //
     // core
     //
+    syncfs: function(populate, callback) {
+      if (typeof(populate) === 'function') {
+        callback = populate;
+        populate = false;
+      }
+
+      var completed = 0;
+      var total = FS.mounts.length;
+      var done = function(err) {
+        if (err) {
+          return callback(err);
+        }
+        if (++completed >= total) {
+          callback(null);
+        }
+      };
+
+      // sync all mounts
+      for (var i = 0; i < FS.mounts.length; i++) {
+        var mount = FS.mounts[i];
+        if (!mount.type.syncfs) {
+          done(null);
+          continue;
+        }
+        mount.type.syncfs(mount, populate, done);
+      }
+    },
     mount: function(type, opts, mountpoint) {
+      var lookup;
+      if (mountpoint) {
+        lookup = FS.lookupPath(mountpoint, { follow: false });
+        mountpoint = lookup.path;  // use the absolute path
+      }
       var mount = {
         type: type,
         opts: opts,
         mountpoint: mountpoint,
         root: null
       };
-      var lookup;
-      if (mountpoint) {
-        lookup = FS.lookupPath(mountpoint, { follow: false });
-      }
       // create a root node for the fs
       var root = type.mount(mount);
       root.mount = mount;
@@ -446,6 +472,8 @@ mergeInto(LibraryManager.library, {
           FS.root = mount.root;
         }
       }
+      // add to our cached list of mounts
+      FS.mounts.push(mount);
       return root;
     },
     lookup: function(parent, name) {
@@ -759,7 +787,6 @@ mergeInto(LibraryManager.library, {
           follow: !(flags & {{{ cDefine('O_NOFOLLOW') }}})
         });
         node = lookup.node;
-        path = lookup.path;
       } catch (e) {
         // ignore
       }
@@ -791,10 +818,11 @@ mergeInto(LibraryManager.library, {
       if ((flags & {{{ cDefine('O_TRUNC')}}})) {
         FS.truncate(node, 0);
       }
+
       // register the stream with the filesystem
       var stream = FS.createStream({
-        path: path,
         node: node,
+        path: FS.getPath(node),  // we want the absolute path to the node
         flags: flags,
         seekable: true,
         position: 0,
@@ -959,8 +987,21 @@ mergeInto(LibraryManager.library, {
 
     //
     // module-level FS code
-    // TODO move to pre/postamble
     //
+    cwd: function() {
+      return FS.currentPath;
+    },
+    chdir: function(path) {
+      var lookup = FS.lookupPath(path, { follow: true });
+      if (!FS.isDir(lookup.node.mode)) {
+        throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR);
+      }
+      var err = FS.nodePermissions(lookup.node, 'x');
+      if (err) {
+        throw new FS.ErrnoError(err);
+      }
+      FS.currentPath = lookup.path;
+    },
     createDefaultDirectories: function() {
       FS.mkdir('/tmp');
     },

From c354b8316cefef8fde6402cf0139f7a64f9b3103 Mon Sep 17 00:00:00 2001
From: Anthony Pesch 
Date: Fri, 6 Sep 2013 23:55:49 -0700
Subject: [PATCH 078/165]  - added idbfs and nodefs  - minor coding convention
 fixes

---
 src/library_fs.js     |   4 +-
 src/library_idbfs.js  | 216 ++++++++++++++++++++++++++++++++++++++
 src/library_memfs.js  |  23 ++---
 src/library_nodefs.js | 234 ++++++++++++++++++++++++++++++++++++++++++
 src/library_sockfs.js |  12 +--
 src/modules.js        |   2 +-
 6 files changed, 471 insertions(+), 20 deletions(-)
 create mode 100644 src/library_idbfs.js
 create mode 100644 src/library_nodefs.js

diff --git a/src/library_fs.js b/src/library_fs.js
index 983e0d7665b37..c4b29227a22c2 100644
--- a/src/library_fs.js
+++ b/src/library_fs.js
@@ -1,5 +1,5 @@
 mergeInto(LibraryManager.library, {
-  $FS__deps: ['$ERRNO_CODES', '$ERRNO_MESSAGES', '__setErrNo', '$VFS', '$PATH', '$TTY', '$MEMFS', 'stdin', 'stdout', 'stderr', 'fflush'],
+  $FS__deps: ['$ERRNO_CODES', '$ERRNO_MESSAGES', '__setErrNo', '$VFS', '$PATH', '$TTY', '$MEMFS', '$IDBFS', '$NODEFS', 'stdin', 'stdout', 'stderr', 'fflush'],
   $FS__postset: 'FS.staticInit();' +
                 '__ATINIT__.unshift({ func: function() { if (!Module["noFSInit"] && !FS.init.initialized) FS.init() } });' +
                 '__ATMAIN__.push({ func: function() { FS.ignorePermissions = false } });' +
@@ -818,6 +818,8 @@ mergeInto(LibraryManager.library, {
       if ((flags & {{{ cDefine('O_TRUNC')}}})) {
         FS.truncate(node, 0);
       }
+      // we've already handled these, don't pass down to the underlying vfs
+      flags &= ~({{{ cDefine('O_EXCL') }}} | {{{ cDefine('O_TRUNC') }}});
 
       // register the stream with the filesystem
       var stream = FS.createStream({
diff --git a/src/library_idbfs.js b/src/library_idbfs.js
new file mode 100644
index 0000000000000..9031bad819729
--- /dev/null
+++ b/src/library_idbfs.js
@@ -0,0 +1,216 @@
+mergeInto(LibraryManager.library, {
+  $IDBFS__deps: ['$FS', '$MEMFS', '$PATH'],
+  $IDBFS: {
+    dbs: {},
+    indexedDB: function() {
+      return window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
+    },
+    DB_VERSION: 20,
+    DB_STORE_NAME: 'FILE_DATA',
+    // reuse all of the core MEMFS functionality
+    mount: function(mount) {
+      return MEMFS.mount.apply(null, arguments);
+    },
+    // the only custom function IDBFS implements is to handle
+    // synchronizing the wrapped MEMFS with a backing IDB instance
+    syncfs: function(mount, populate, callback) {
+      IDBFS.getLocalSet(mount, function(err, local) {
+        if (err) return callback(err);
+
+        IDBFS.getRemoteSet(mount, function(err, remote) {
+          if (err) return callback(err);
+
+          var src = populate ? remote : local;
+          var dst = populate ? local : remote;
+
+          IDBFS.reconcile(src, dst, callback);
+        });
+      });
+    },
+    reconcile: function(src, dst, callback) {
+      var total = 0;
+
+      var create = {};
+      for (var key in src.files) {
+        if (!src.files.hasOwnProperty(key)) continue;
+        var e = src.files[key];
+        var e2 = dst.files[key];
+        if (!e2 || e.timestamp > e2.timestamp) {
+          create[key] = e;
+          total++;
+        }
+      }
+
+      var remove = {};
+      for (var key in dst.files) {
+        if (!dst.files.hasOwnProperty(key)) continue;
+        var e = dst.files[key];
+        var e2 = src.files[key];
+        if (!e2) {
+          remove[key] = e;
+          total++;
+        }
+      }
+
+      if (!total) {
+        // early out
+        return callback(null);
+      }
+
+      var completed = 0;
+      var done = function(err) {
+        if (err) return callback(err);
+        if (++completed >= total) {
+          return callback(null);
+        }
+      };
+
+      // create a single transaction to handle and IDB reads / writes we'll need to do
+      var db = src.type === 'remote' ? src.db : dst.db;
+      var transaction = db.transaction([IDBFS.DB_STORE_NAME], 'readwrite');
+      transaction.onerror = function() { callback(this.error); };
+      var store = transaction.objectStore(IDBFS.DB_STORE_NAME);
+
+      for (var path in create) {
+        if (!create.hasOwnProperty(path)) continue;
+        var entry = create[path];
+
+        if (dst.type === 'local') {
+          // save file to local
+          try {
+            if (FS.isDir(entry.mode)) {
+              FS.mkdir(path, entry.mode);
+            } else if (FS.isFile(entry.mode)) {
+              var stream = FS.open(path, 'w+', 0666);
+              FS.write(stream, entry.contents, 0, entry.contents.length, 0, true /* canOwn */);
+              FS.close(stream);
+            }
+            done(null);
+          } catch (e) {
+            return done(e);
+          }
+        } else {
+          // save file to IDB
+          var req = store.put(entry, path);
+          req.onsuccess = function() { done(null); };
+          req.onerror = function() { done(this.error); };
+        }
+      }
+
+      for (var path in remove) {
+        if (!remove.hasOwnProperty(path)) continue;
+        var entry = remove[path];
+
+        if (dst.type === 'local') {
+          // delete file from local
+          try {
+            if (FS.isDir(entry.mode)) {
+              // TODO recursive delete?
+              FS.rmdir(path);
+            } else if (FS.isFile(entry.mode)) {
+              FS.unlink(path);
+            }
+            done(null);
+          } catch (e) {
+            return done(e);
+          }
+        } else {
+          // delete file from IDB
+          var req = store.delete(path);
+          req.onsuccess = function() { done(null); };
+          req.onerror = function() { done(this.error); };
+        }
+      }
+    },
+    getLocalSet: function(mount, callback) {
+      var files = {};
+
+      var isRealDir = function(p) {
+        return p !== '.' && p !== '..';
+      };
+      var toAbsolute = function(root) {
+        return function(p) {
+          return PATH.join(root, p);
+        }
+      };
+
+      var check = FS.readdir(mount.mountpoint)
+        .filter(isRealDir)
+        .map(toAbsolute(mount.mountpoint));
+
+      while (check.length) {
+        var path = check.pop();
+        var stat, node;
+
+        try {
+          var lookup = FS.lookupPath(path);
+          node = lookup.node;
+          stat = FS.stat(path);
+        } catch (e) {
+          return callback(e);
+        }
+
+        if (FS.isDir(stat.mode)) {
+          check.push.apply(check, FS.readdir(path)
+            .filter(isRealDir)
+            .map(toAbsolute(path)));
+
+          files[path] = { mode: stat.mode, timestamp: stat.mtime };
+        } else if (FS.isFile(stat.mode)) {
+          files[path] = { contents: node.contents, mode: stat.mode, timestamp: stat.mtime };
+        } else {
+          return callback(new Error('node type not supported'));
+        }
+      }
+
+      return callback(null, { type: 'local', files: files });
+    },
+    getDB: function(name, callback) {
+      // look it up in the cache
+      var db = IDBFS.dbs[name];
+      if (db) {
+        return callback(null, db);
+      }
+      var req;
+      try {
+        req = IDBFS.indexedDB().open(name, IDBFS.DB_VERSION);
+      } catch (e) {
+        return onerror(e);
+      }
+      req.onupgradeneeded = function() {
+        db = req.result;
+        db.createObjectStore(IDBFS.DB_STORE_NAME);
+      };
+      req.onsuccess = function() {
+        db = req.result;
+        // add to the cache
+        IDBFS.dbs[name] = db;
+        callback(null, db);
+      };
+      req.onerror = function() {
+        callback(this.error);
+      };
+    },
+    getRemoteSet: function(mount, callback) {
+      var files = {};
+
+      IDBFS.getDB(mount.mountpoint, function(err, db) {
+        if (err) return callback(err);
+
+        var transaction = db.transaction([IDBFS.DB_STORE_NAME], 'readonly');
+        transaction.onerror = function() { callback(this.error); };
+
+        var store = transaction.objectStore(IDBFS.DB_STORE_NAME);
+        store.openCursor().onsuccess = function(event) {
+          var cursor = event.target.result;
+          if (!cursor) {
+            return callback(null, { type: 'remote', db: db, files: files });
+          }
+
+          files[cursor.key] = cursor.value;
+          cursor.continue();
+        };
+      });
+    }
+  }
+});
diff --git a/src/library_memfs.js b/src/library_memfs.js
index 28178d9f26001..4e56d996d47c4 100644
--- a/src/library_memfs.js
+++ b/src/library_memfs.js
@@ -5,18 +5,10 @@ mergeInto(LibraryManager.library, {
     CONTENT_OWNING: 1, // contains a subarray into the heap, and we own it, without copying (note: someone else needs to free() it, if that is necessary)
     CONTENT_FLEXIBLE: 2, // has been modified or never set to anything, and is a flexible js array that can grow/shrink
     CONTENT_FIXED: 3, // contains some fixed-size content written into it, in a typed array
-    ensureFlexible: function(node) {
-      if (node.contentMode !== MEMFS.CONTENT_FLEXIBLE) {
-        var contents = node.contents;
-        node.contents = Array.prototype.slice.call(contents);
-        node.contentMode = MEMFS.CONTENT_FLEXIBLE;
-      }
-    },
-
     mount: function(mount) {
-      return MEMFS.create_node(null, '/', {{{ cDefine('S_IFDIR') }}} | 0777, 0);
+      return MEMFS.createNode(null, '/', {{{ cDefine('S_IFDIR') }}} | 0777, 0);
     },
-    create_node: function(parent, name, mode, dev) {
+    createNode: function(parent, name, mode, dev) {
       if (FS.isBlkdev(mode) || FS.isFIFO(mode)) {
         // no supported
         throw new FS.ErrnoError(ERRNO_CODES.EPERM);
@@ -74,6 +66,13 @@ mergeInto(LibraryManager.library, {
       }
       return node;
     },
+    ensureFlexible: function(node) {
+      if (node.contentMode !== MEMFS.CONTENT_FLEXIBLE) {
+        var contents = node.contents;
+        node.contents = Array.prototype.slice.call(contents);
+        node.contentMode = MEMFS.CONTENT_FLEXIBLE;
+      }
+    },
     node_ops: {
       getattr: function(node) {
         var attr = {};
@@ -121,7 +120,7 @@ mergeInto(LibraryManager.library, {
         throw new FS.ErrnoError(ERRNO_CODES.ENOENT);
       },
       mknod: function(parent, name, mode, dev) {
-        return MEMFS.create_node(parent, name, mode, dev);
+        return MEMFS.createNode(parent, name, mode, dev);
       },
       rename: function(old_node, new_dir, new_name) {
         // if we're overwriting a directory at new_name, make sure it's empty.
@@ -163,7 +162,7 @@ mergeInto(LibraryManager.library, {
         return entries;
       },
       symlink: function(parent, newname, oldpath) {
-        var node = MEMFS.create_node(parent, newname, 0777 | {{{ cDefine('S_IFLNK') }}}, 0);
+        var node = MEMFS.createNode(parent, newname, 0777 | {{{ cDefine('S_IFLNK') }}}, 0);
         node.link = oldpath;
         return node;
       },
diff --git a/src/library_nodefs.js b/src/library_nodefs.js
new file mode 100644
index 0000000000000..d8df16893db95
--- /dev/null
+++ b/src/library_nodefs.js
@@ -0,0 +1,234 @@
+mergeInto(LibraryManager.library, {
+  $NODEFS__deps: ['$FS', '$PATH'],
+  $NODEFS__postset: 'if (ENVIRONMENT_IS_NODE) { var fs = require("fs"); }',
+  $NODEFS: {
+    mount: function (mount) {
+      assert(ENVIRONMENT_IS_NODE);
+      return NODEFS.createNode(null, '/', NODEFS.getMode(mount.opts.root), 0);
+    },
+    createNode: function (parent, name, mode, dev) {
+      if (!FS.isDir(mode) && !FS.isFile(mode) && !FS.isLink(mode)) {
+        throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+      }
+      var node = FS.createNode(parent, name, mode);
+      node.node_ops = NODEFS.node_ops;
+      node.stream_ops = NODEFS.stream_ops;
+      return node;
+    },
+    getMode: function (path) {
+      var stat;
+      try {
+        stat = fs.lstatSync(path);
+      } catch (e) {
+        if (!e.code) throw e;
+        throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+      }
+      return stat.mode;
+    },
+    realPath: function (node) {
+      var parts = [];
+      while (node.parent !== node) {
+        parts.push(node.name);
+        node = node.parent;
+      }
+      parts.push(node.mount.opts.root);
+      parts.reverse();
+      return PATH.join.apply(null, parts);
+    },
+    node_ops: {
+      getattr: function(node) {
+        var path = NODEFS.realPath(node);
+        var stat;
+        try {
+          stat = fs.lstatSync(path);
+        } catch (e) {
+          if (!e.code) throw e;
+          throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+        }
+        return {
+          dev: stat.dev,
+          ino: stat.ino,
+          mode: stat.mode,
+          nlink: stat.nlink,
+          uid: stat.uid,
+          gid: stat.gid,
+          rdev: stat.rdev,
+          size: stat.size,
+          atime: stat.atime,
+          mtime: stat.mtime,
+          ctime: stat.ctime,
+          blksize: stat.blksize,
+          blocks: stat.blocks
+        };
+      },
+      setattr: function(node, attr) {
+        var path = NODEFS.realPath(node);
+        try {
+          if (attr.mode !== undefined) {
+            fs.chmodSync(path, attr.mode);
+            // update the common node structure mode as well
+            node.mode = attr.mode;
+          }
+          if (attr.timestamp !== undefined) {
+            var date = new Date(attr.timestamp);
+            fs.utimesSync(path, date, date);
+          }
+          if (attr.size !== undefined) {
+            fs.truncateSync(path, attr.size);
+          }
+        } catch (e) {
+          if (!e.code) throw e;
+          throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+        }
+      },
+      lookup: function (parent, name) {
+        var path = PATH.join(NODEFS.realPath(parent), name);
+        var mode = NODEFS.getMode(path);
+        return NODEFS.createNode(parent, name, mode);
+      },
+      mknod: function (parent, name, mode, dev) {
+        var node = NODEFS.createNode(parent, name, mode, dev);
+        // create the backing node for this in the fs root as well
+        var path = NODEFS.realPath(node);
+        try {
+          if (FS.isDir(node.mode)) {
+            fs.mkdirSync(path, node.mode);
+          } else {
+            fs.writeFileSync(path, '', { mode: node.mode });
+          }
+        } catch (e) {
+          if (!e.code) throw e;
+          throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+        }
+        return node;
+      },
+      rename: function (oldNode, newDir, newName) {
+        var oldPath = NODEFS.realPath(oldNode);
+        var newPath = PATH.join(NODEFS.realPath(newDir), newName);
+        try {
+          fs.renameSync(oldPath, newPath);
+        } catch (e) {
+          if (!e.code) throw e;
+          throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+        }
+      },
+      unlink: function(parent, name) {
+        var path = PATH.join(NODEFS.realPath(parent), name);
+        try {
+          fs.unlinkSync(path);
+        } catch (e) {
+          if (!e.code) throw e;
+          throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+        }
+      },
+      rmdir: function(parent, name) {
+        var path = PATH.join(NODEFS.realPath(parent), name);
+        try {
+          fs.rmdirSync(path);
+        } catch (e) {
+          if (!e.code) throw e;
+          throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+        }
+      },
+      readdir: function(node) {
+        var path = NODEFS.realPath(node);
+        try {
+          return fs.readdirSync(path);
+        } catch (e) {
+          if (!e.code) throw e;
+          throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+        }
+      },
+      symlink: function(parent, newName, oldPath) {
+        var newPath = PATH.join(NODEFS.realPath(parent), newName);
+        try {
+          fs.symlinkSync(oldPath, newPath);
+        } catch (e) {
+          if (!e.code) throw e;
+          throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+        }
+      },
+      readlink: function(node) {
+        var path = NODEFS.realPath(node);
+        try {
+          return fs.readlinkSync(path);
+        } catch (e) {
+          if (!e.code) throw e;
+          throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+        }
+      },
+    },
+    stream_ops: {
+      open: function (stream) {
+        var path = NODEFS.realPath(stream.node);
+        try {
+          if (FS.isFile(stream.node.mode)) {
+            stream.nfd = fs.openSync(path, stream.flags);
+          }
+        } catch (e) {
+          if (!e.code) throw e;
+          throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+        }
+      },
+      close: function (stream) {
+        try {
+          if (FS.isFile(stream.node.mode)) {
+            fs.closeSync(stream.nfd);
+          }
+        } catch (e) {
+          if (!e.code) throw e;
+          throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+        }
+      },
+      read: function (stream, buffer, offset, length, position) {
+        // FIXME this is terrible.
+        var nbuffer = new Buffer(length);
+        var res;
+        try {
+          res = fs.readSync(stream.nfd, nbuffer, 0, length, position);
+        } catch (e) {
+          throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+        }
+        if (res > 0) {
+          for (var i = 0; i < res; i++) {
+            buffer[offset + i] = nbuffer[i];
+          }
+        }
+        return res;
+      },
+      write: function (stream, buffer, offset, length, position) {
+        // FIXME this is terrible.
+        var nbuffer = new Buffer(buffer.subarray(offset, offset + length));
+        var res;
+        try {
+          res = fs.writeSync(stream.nfd, nbuffer, 0, length, position);
+        } catch (e) {
+          throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+        }
+        return res;
+      },
+      llseek: function (stream, offset, whence) {
+        var position = offset;
+        if (whence === 1) {  // SEEK_CUR.
+          position += stream.position;
+        } else if (whence === 2) {  // SEEK_END.
+          if (FS.isFile(stream.node.mode)) {
+            try {
+              var stat = fs.fstatSync(stream.nfd);
+              position += stat.size;
+            } catch (e) {
+              throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+            }
+          }
+        }
+
+        if (position < 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+
+        stream.position = position;
+        return position;
+      }
+    }
+  }
+});
\ No newline at end of file
diff --git a/src/library_sockfs.js b/src/library_sockfs.js
index b11c649500b48..af29d11bb6286 100644
--- a/src/library_sockfs.js
+++ b/src/library_sockfs.js
@@ -5,12 +5,6 @@ mergeInto(LibraryManager.library, {
     mount: function(mount) {
       return FS.createNode(null, '/', {{{ cDefine('S_IFDIR') }}} | 0777, 0);
     },
-    nextname: function() {
-      if (!SOCKFS.nextname.current) {
-        SOCKFS.nextname.current = 0;
-      }
-      return 'socket[' + (SOCKFS.nextname.current++) + ']';
-    },
     createSocket: function(family, type, protocol) {
       var streaming = type == {{{ cDefine('SOCK_STREAM') }}};
       if (protocol) {
@@ -95,6 +89,12 @@ mergeInto(LibraryManager.library, {
         sock.sock_ops.close(sock);
       }
     },
+    nextname: function() {
+      if (!SOCKFS.nextname.current) {
+        SOCKFS.nextname.current = 0;
+      }
+      return 'socket[' + (SOCKFS.nextname.current++) + ']';
+    },
     // backend-specific stream ops
     websocket_sock_ops: {
       //
diff --git a/src/modules.js b/src/modules.js
index 1029b233ed48d..2757c2cbec2de 100644
--- a/src/modules.js
+++ b/src/modules.js
@@ -422,7 +422,7 @@ var LibraryManager = {
   load: function() {
     if (this.library) return;
 
-    var libraries = ['library.js', 'library_path.js', 'library_fs.js', 'library_memfs.js', 'library_sockfs.js', 'library_tty.js', 'library_browser.js', 'library_sdl.js', 'library_gl.js', 'library_glut.js', 'library_xlib.js', 'library_egl.js', 'library_gc.js', 'library_jansson.js', 'library_openal.js', 'library_glfw.js'].concat(additionalLibraries);
+    var libraries = ['library.js', 'library_path.js', 'library_fs.js', 'library_idbfs.js', 'library_memfs.js', 'library_nodefs.js', 'library_sockfs.js', 'library_tty.js', 'library_browser.js', 'library_sdl.js', 'library_gl.js', 'library_glut.js', 'library_xlib.js', 'library_egl.js', 'library_gc.js', 'library_jansson.js', 'library_openal.js', 'library_glfw.js'].concat(additionalLibraries);
     for (var i = 0; i < libraries.length; i++) {
       eval(processMacros(preprocess(read(libraries[i]))));
     }

From 9eaadf56f58b35376469e9a89373632fd34cf08c Mon Sep 17 00:00:00 2001
From: Anthony Pesch 
Date: Mon, 2 Sep 2013 13:58:39 -0700
Subject: [PATCH 079/165] - updated several unistd tests to test against NODEFS

---
 tests/test_core.py      | 46 ++++++++++++++++++++++++++---------------
 tests/unistd/access.c   | 17 +++++++++------
 tests/unistd/access.out | 40 +++++++++++++++++------------------
 tests/unistd/io.c       | 13 ++++++++----
 tests/unistd/links.c    | 21 ++++++++++++-------
 tests/unistd/links.out  |  6 +++---
 tests/unistd/misc.c     | 24 ++++++++++++++-------
 tests/unistd/truncate.c | 23 +++++++++++++--------
 tests/unistd/unlink.c   | 12 +++++++++++
 9 files changed, 127 insertions(+), 75 deletions(-)

diff --git a/tests/test_core.py b/tests/test_core.py
index d59fae40b9ecf..e78fb5134a206 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -7745,9 +7745,11 @@ def process(filename):
   def test_unistd_access(self):
     if Settings.ASM_JS: Settings.ASM_JS = 2 # skip validation, asm does not support random code
     if not self.is_le32(): return self.skip('le32 needed for inline js')
-    src = open(path_from_root('tests', 'unistd', 'access.c'), 'r').read()
-    expected = open(path_from_root('tests', 'unistd', 'access.out'), 'r').read()
-    self.do_run(src, expected)
+    for fs in ['MEMFS', 'NODEFS']:
+      src = open(path_from_root('tests', 'unistd', 'access.c'), 'r').read()
+      expected = open(path_from_root('tests', 'unistd', 'access.out'), 'r').read()
+      Building.COMPILER_TEST_OPTS = ['-D' + fs]
+      self.do_run(src, expected)
 
   def test_unistd_curdir(self):
     if Settings.ASM_JS: Settings.ASM_JS = 2 # skip validation, asm does not support random code
@@ -7783,9 +7785,11 @@ def test_unistd_pathconf(self):
   def test_unistd_truncate(self):
     if Settings.ASM_JS: Settings.ASM_JS = 2 # skip validation, asm does not support random code
     if not self.is_le32(): return self.skip('le32 needed for inline js')
-    src = open(path_from_root('tests', 'unistd', 'truncate.c'), 'r').read()
-    expected = open(path_from_root('tests', 'unistd', 'truncate.out'), 'r').read()
-    self.do_run(src, expected)
+    for fs in ['MEMFS', 'NODEFS']:
+      src = open(path_from_root('tests', 'unistd', 'truncate.c'), 'r').read()
+      expected = open(path_from_root('tests', 'unistd', 'truncate.out'), 'r').read()
+      Building.COMPILER_TEST_OPTS = ['-D' + fs]
+      self.do_run(src, expected)
 
   def test_unistd_swab(self):
     src = open(path_from_root('tests', 'unistd', 'swab.c'), 'r').read()
@@ -7807,15 +7811,19 @@ def test_unistd_login(self):
     self.do_run(src, expected)
 
   def test_unistd_unlink(self):
-    src = open(path_from_root('tests', 'unistd', 'unlink.c'), 'r').read()
-    self.do_run(src, 'success', force_c=True)
+    for fs in ['MEMFS', 'NODEFS']:
+      src = open(path_from_root('tests', 'unistd', 'unlink.c'), 'r').read()
+      Building.COMPILER_TEST_OPTS = ['-D' + fs]
+      self.do_run(src, 'success', force_c=True)
 
   def test_unistd_links(self):
     if Settings.ASM_JS: Settings.ASM_JS = 2 # skip validation, asm does not support random code
     if not self.is_le32(): return self.skip('le32 needed for inline js')
-    src = open(path_from_root('tests', 'unistd', 'links.c'), 'r').read()
-    expected = open(path_from_root('tests', 'unistd', 'links.out'), 'r').read()
-    self.do_run(src, expected)
+    for fs in ['MEMFS', 'NODEFS']:
+      src = open(path_from_root('tests', 'unistd', 'links.c'), 'r').read()
+      expected = open(path_from_root('tests', 'unistd', 'links.out'), 'r').read()
+      Building.COMPILER_TEST_OPTS = ['-D' + fs]
+      self.do_run(src, expected)
 
   def test_unistd_sleep(self):
     src = open(path_from_root('tests', 'unistd', 'sleep.c'), 'r').read()
@@ -7826,14 +7834,18 @@ def test_unistd_io(self):
     if Settings.ASM_JS: Settings.ASM_JS = 2 # skip validation, asm does not support random code
     if not self.is_le32(): return self.skip('le32 needed for inline js')
     if self.run_name == 'o2': return self.skip('non-asm optimized builds can fail with inline js')
-    src = open(path_from_root('tests', 'unistd', 'io.c'), 'r').read()
-    expected = open(path_from_root('tests', 'unistd', 'io.out'), 'r').read()
-    self.do_run(src, expected)
+    for fs in ['MEMFS', 'NODEFS']:
+      src = open(path_from_root('tests', 'unistd', 'io.c'), 'r').read()
+      expected = open(path_from_root('tests', 'unistd', 'io.out'), 'r').read()
+      Building.COMPILER_TEST_OPTS = ['-D' + fs]
+      self.do_run(src, expected)
 
   def test_unistd_misc(self):
-    src = open(path_from_root('tests', 'unistd', 'misc.c'), 'r').read()
-    expected = open(path_from_root('tests', 'unistd', 'misc.out'), 'r').read()
-    self.do_run(src, expected)
+    for fs in ['MEMFS', 'NODEFS']:
+      src = open(path_from_root('tests', 'unistd', 'misc.c'), 'r').read()
+      expected = open(path_from_root('tests', 'unistd', 'misc.out'), 'r').read()
+      Building.COMPILER_TEST_OPTS = ['-D' + fs]
+      self.do_run(src, expected)
 
   def test_uname(self):
     src = r'''
diff --git a/tests/unistd/access.c b/tests/unistd/access.c
index 4d5ba08e680bc..57d38f5cfc1b1 100644
--- a/tests/unistd/access.c
+++ b/tests/unistd/access.c
@@ -5,14 +5,19 @@
 
 int main() {
   EM_ASM(
-    FS.writeFile('/forbidden', ''); FS.chmod('/forbidden', 0000);
-    FS.writeFile('/readable',  ''); FS.chmod('/readable',  0444);
-    FS.writeFile('/writeable', ''); FS.chmod('/writeable', 0222);
-    FS.writeFile('/allaccess', ''); FS.chmod('/allaccess', 0777);
+    FS.mkdir('working');
+#if NODEFS
+    FS.mount(NODEFS, { root: '.' }, 'working');
+#endif
+    FS.chdir('working');
+    FS.writeFile('forbidden', ''); FS.chmod('forbidden', 0000);
+    FS.writeFile('readable',  ''); FS.chmod('readable',  0444);
+    FS.writeFile('writeable', ''); FS.chmod('writeable', 0222);
+    FS.writeFile('allaccess', ''); FS.chmod('allaccess', 0777);
   );
 
-  char* files[] = {"/readable", "/writeable",
-                   "/allaccess", "/forbidden", "/nonexistent"};
+  char* files[] = {"readable", "writeable",
+                   "allaccess", "forbidden", "nonexistent"};
   for (int i = 0; i < sizeof files / sizeof files[0]; i++) {
     printf("F_OK(%s): %d\n", files[i], access(files[i], F_OK));
     printf("errno: %d\n", errno);
diff --git a/tests/unistd/access.out b/tests/unistd/access.out
index d462e5a574b0c..b5e4a5414ff7b 100644
--- a/tests/unistd/access.out
+++ b/tests/unistd/access.out
@@ -1,45 +1,45 @@
-F_OK(/readable): 0
+F_OK(readable): 0
 errno: 0
-R_OK(/readable): 0
+R_OK(readable): 0
 errno: 0
-X_OK(/readable): -1
+X_OK(readable): -1
 errno: 13
-W_OK(/readable): -1
+W_OK(readable): -1
 errno: 13
 
-F_OK(/writeable): 0
+F_OK(writeable): 0
 errno: 0
-R_OK(/writeable): -1
+R_OK(writeable): -1
 errno: 13
-X_OK(/writeable): -1
+X_OK(writeable): -1
 errno: 13
-W_OK(/writeable): 0
+W_OK(writeable): 0
 errno: 0
 
-F_OK(/allaccess): 0
+F_OK(allaccess): 0
 errno: 0
-R_OK(/allaccess): 0
+R_OK(allaccess): 0
 errno: 0
-X_OK(/allaccess): 0
+X_OK(allaccess): 0
 errno: 0
-W_OK(/allaccess): 0
+W_OK(allaccess): 0
 errno: 0
 
-F_OK(/forbidden): 0
+F_OK(forbidden): 0
 errno: 0
-R_OK(/forbidden): -1
+R_OK(forbidden): -1
 errno: 13
-X_OK(/forbidden): -1
+X_OK(forbidden): -1
 errno: 13
-W_OK(/forbidden): -1
+W_OK(forbidden): -1
 errno: 13
 
-F_OK(/nonexistent): -1
+F_OK(nonexistent): -1
 errno: 2
-R_OK(/nonexistent): -1
+R_OK(nonexistent): -1
 errno: 2
-X_OK(/nonexistent): -1
+X_OK(nonexistent): -1
 errno: 2
-W_OK(/nonexistent): -1
+W_OK(nonexistent): -1
 errno: 2
 
diff --git a/tests/unistd/io.c b/tests/unistd/io.c
index 6bf2259301f02..5dcdbbb67749c 100644
--- a/tests/unistd/io.c
+++ b/tests/unistd/io.c
@@ -7,6 +7,11 @@
 
 int main() {
   EM_ASM(
+    FS.mkdir('/working');
+#if NODEFS
+    FS.mount(NODEFS, { root: '.' }, '/working');
+#endif
+
     var major = 80;
 
     var device = FS.makedev(major++, 0);
@@ -51,14 +56,14 @@ int main() {
     FS.createDevice('/', 'createDevice-read-only', function() {});
     FS.createDevice('/', 'createDevice-write-only', null, function() {});
 
-    FS.mkdir('/folder', 0777);
-    FS.writeFile('/file', '1234567890');
+    FS.mkdir('/working/folder');
+    FS.writeFile('/working/file', '1234567890');
   );
 
   char readBuffer[256] = {0};
   char writeBuffer[] = "writeme";
 
-  int fl = open("/folder", O_RDWR);
+  int fl = open("/working/folder", O_RDWR);
   printf("read from folder: %d\n", read(fl, readBuffer, sizeof readBuffer));
   printf("errno: %d\n", errno);
   errno = 0;
@@ -97,7 +102,7 @@ int main() {
   printf("open write-only device from createDevice for write, errno: %d\n\n", errno);
   errno = 0;
 
-  int f = open("/file", O_RDWR);
+  int f = open("/working/file", O_RDWR);
   printf("read from file: %d\n", read(f, readBuffer, sizeof readBuffer));
   printf("data: %s\n", readBuffer);
   memset(readBuffer, 0, sizeof readBuffer);
diff --git a/tests/unistd/links.c b/tests/unistd/links.c
index 5b403c1fe6e3e..c46c629441fc0 100644
--- a/tests/unistd/links.c
+++ b/tests/unistd/links.c
@@ -5,12 +5,17 @@
 
 int main() {
   EM_ASM(
-    FS.symlink('../test/../there!', '/link');
-    FS.writeFile('/file', 'test');
-    FS.mkdir('/folder');
+    FS.mkdir('working');
+#if NODEFS
+    FS.mount(NODEFS, { root: '.' }, 'working');
+#endif
+    FS.chdir('working');
+    FS.symlink('../test/../there!', 'link');
+    FS.writeFile('file', 'test');
+    FS.mkdir('folder');
   );
 
-  char* files[] = {"/link", "/file", "/folder"};
+  char* files[] = {"link", "file", "folder"};
   char buffer[256] = {0};
 
   for (int i = 0; i < sizeof files / sizeof files[0]; i++) {
@@ -22,23 +27,23 @@ int main() {
   }
 
   printf("symlink/overwrite\n");
-  printf("ret: %d\n", symlink("new-nonexistent-path", "/link"));
+  printf("ret: %d\n", symlink("new-nonexistent-path", "link"));
   printf("errno: %d\n\n", errno);
   errno = 0;
 
   printf("symlink/normal\n");
-  printf("ret: %d\n", symlink("new-nonexistent-path", "/folder/link"));
+  printf("ret: %d\n", symlink("new-nonexistent-path", "folder/link"));
   printf("errno: %d\n", errno);
   errno = 0;
 
   printf("readlink(created link)\n");
-  printf("ret: %d\n", readlink("/folder/link", buffer, 256));
+  printf("ret: %d\n", readlink("folder/link", buffer, 256));
   printf("errno: %d\n", errno);
   printf("result: %s\n\n", buffer);
   errno = 0;
 
   printf("readlink(short buffer)\n");
-  printf("ret: %d\n", readlink("/link", buffer, 4));
+  printf("ret: %d\n", readlink("link", buffer, 4));
   printf("errno: %d\n", errno);
   printf("result: %s\n", buffer);
   errno = 0;
diff --git a/tests/unistd/links.out b/tests/unistd/links.out
index 75e410cbdf134..f2a7aed660918 100644
--- a/tests/unistd/links.out
+++ b/tests/unistd/links.out
@@ -1,14 +1,14 @@
-readlink(/link)
+readlink(link)
 ret: 17
 errno: 0
 result: ../test/../there!
 
-readlink(/file)
+readlink(file)
 ret: -1
 errno: 22
 result: ../test/../there!
 
-readlink(/folder)
+readlink(folder)
 ret: -1
 errno: 22
 result: ../test/../there!
diff --git a/tests/unistd/misc.c b/tests/unistd/misc.c
index 5b0d63d2304ea..2ca5b3907439b 100644
--- a/tests/unistd/misc.c
+++ b/tests/unistd/misc.c
@@ -2,9 +2,17 @@
 #include 
 #include 
 #include 
+#include 
 
 int main() {
-  int f = open("/", O_RDONLY);
+  EM_ASM(
+    FS.mkdir('working');
+#if NODEFS
+    FS.mount(NODEFS, { root: '.' }, 'working');
+#endif
+  );
+
+  int f = open("working", O_RDONLY);
 
   sync();
 
@@ -36,7 +44,7 @@ int main() {
   printf(", errno: %d\n", errno);
   errno = 0;
 
-  printf("link: %d", link("/here", "/there"));
+  printf("link: %d", link("working/here", "working/there"));
   printf(", errno: %d\n", errno);
   errno = 0;
 
@@ -65,10 +73,10 @@ int main() {
 
   char* exec_argv[] = {"arg", 0};
   char* exec_env[] = {"a=b", 0};
-  printf("execl: %d", execl("/program", "arg", 0));
+  printf("execl: %d", execl("working/program", "arg", 0));
   printf(", errno: %d\n", errno);
   errno = 0;
-  printf("execle: %d", execle("/program", "arg", 0, exec_env));
+  printf("execle: %d", execle("working/program", "arg", 0, exec_env));
   printf(", errno: %d\n", errno);
   errno = 0;
   printf("execlp: %d", execlp("program", "arg", 0));
@@ -84,16 +92,16 @@ int main() {
   printf(", errno: %d\n", errno);
   errno = 0;
 
-  printf("chown(good): %d", chown("/", 123, 456));
+  printf("chown(good): %d", chown("working", 123, 456));
   printf(", errno: %d\n", errno);
   errno = 0;
-  printf("chown(bad): %d", chown("/noexist", 123, 456));
+  printf("chown(bad): %d", chown("working/noexist", 123, 456));
   printf(", errno: %d\n", errno);
   errno = 0;
-  printf("lchown(good): %d", lchown("/", 123, 456));
+  printf("lchown(good): %d", lchown("working", 123, 456));
   printf(", errno: %d\n", errno);
   errno = 0;
-  printf("lchown(bad): %d", lchown("/noexist", 123, 456));
+  printf("lchown(bad): %d", lchown("working/noexist", 123, 456));
   printf(", errno: %d\n", errno);
   errno = 0;
   printf("fchown(good): %d", fchown(f, 123, 456));
diff --git a/tests/unistd/truncate.c b/tests/unistd/truncate.c
index b1d9fc9655979..e63a4c13dcb22 100644
--- a/tests/unistd/truncate.c
+++ b/tests/unistd/truncate.c
@@ -8,14 +8,19 @@
 
 int main() {
   EM_ASM(
-    FS.writeFile('/towrite', 'abcdef');
-    FS.writeFile('/toread', 'abcdef');
-    FS.chmod('/toread', 0444);
+    FS.mkdir('working');
+#if NODEFS
+    FS.mount(NODEFS, { root: '.' }, 'working');
+#endif
+    FS.chdir('working');
+    FS.writeFile('towrite', 'abcdef');
+    FS.writeFile('toread', 'abcdef');
+    FS.chmod('toread', 0444);
   );
 
   struct stat s;
-  int f = open("/towrite", O_WRONLY);
-  int f2 = open("/toread", O_RDONLY);
+  int f = open("towrite", O_WRONLY);
+  int f2 = open("toread", O_RDONLY);
   printf("f2: %d\n", f2);
 
   fstat(f, &s);
@@ -48,17 +53,17 @@ int main() {
   errno = 0;
   printf("\n");
 
-  printf("truncate(2): %d\n", truncate("/towrite", 2));
+  printf("truncate(2): %d\n", truncate("towrite", 2));
   printf("errno: %d\n", errno);
-  stat("/towrite", &s);
+  stat("towrite", &s);
   printf("st_size: %d\n", s.st_size);
   memset(&s, 0, sizeof s);
   errno = 0;
   printf("\n");
 
-  printf("truncate(readonly, 2): %d\n", truncate("/toread", 2));
+  printf("truncate(readonly, 2): %d\n", truncate("toread", 2));
   printf("errno: %d\n", errno);
-  stat("/toread", &s);
+  stat("toread", &s);
   printf("st_size: %d\n", s.st_size);
   memset(&s, 0, sizeof s);
   errno = 0;
diff --git a/tests/unistd/unlink.c b/tests/unistd/unlink.c
index f0a8f4dd4a8d7..9f5323253085f 100644
--- a/tests/unistd/unlink.c
+++ b/tests/unistd/unlink.c
@@ -7,6 +7,9 @@
 #include 
 #include 
 #include 
+#if EMSCRIPTEN
+#include 
+#endif
 
 static void create_file(const char *path, const char *buffer, int mode) {
   int fd = open(path, O_WRONLY | O_CREAT | O_EXCL, mode);
@@ -19,6 +22,15 @@ static void create_file(const char *path, const char *buffer, int mode) {
 }
 
 void setup() {
+  mkdir("working", 0777);
+#if EMSCRIPTEN
+  EM_ASM(
+#if NODEFS
+    FS.mount(NODEFS, { root: '.' }, 'working');
+#endif
+  );
+#endif
+  chdir("working");
   create_file("file", "test", 0777);
   create_file("file1", "test", 0777);
   symlink("file1", "file1-link");

From 076828eddb8c5a0fd38b3d3606bcbb7b9f501e56 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Thu, 26 Sep 2013 18:35:00 -0700
Subject: [PATCH 080/165] === in isLocalVar

---
 src/parseTools.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/parseTools.js b/src/parseTools.js
index c06d0a0deead8..385837a5c2daf 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -118,7 +118,7 @@ function isJSVar(ident) {
 }
 
 function isLocalVar(ident) {
-  return ident[0] == '$';
+  return ident[0] === '$';
 }
 
 function isStructPointerType(type) {

From a242ce089084dcfc2557175266a43fc882db2bc4 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Thu, 26 Sep 2013 18:44:55 -0700
Subject: [PATCH 081/165] better check for when things need quoting

---
 src/parseTools.js | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/src/parseTools.js b/src/parseTools.js
index 385837a5c2daf..a5aa7b17f4652 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -121,6 +121,13 @@ function isLocalVar(ident) {
   return ident[0] === '$';
 }
 
+// Simple variables or numbers, or things already quoted, do not need to be quoted
+function needsQuoting(ident) {
+  if (/^[-+]?[$_]?[\w$_\d]*$/.test(ident)) return false; // number or variable
+  if (ident[0] === '(' && ident[ident.length-1] === ')' && ident.indexOf('(', 1) < 0) return false; // already fully quoted
+  return true;
+}
+
 function isStructPointerType(type) {
   // This test is necessary for clang - in llvm-gcc, we
   // could check for %struct. The downside is that %1 can
@@ -2000,7 +2007,7 @@ function makeSignOp(value, type, op, force, ignore) {
         value = '1';
       } else if (value === 'false') {
         value = '0';
-      } else if (!isJSVar(value)) value = '(' + value + ')';
+      } else if (needsQuoting(value)) value = '(' + value + ')';
       if (bits === 32) {
         if (op === 're') {
           return '(' + value + '|0)';

From f6eb863d92b642e254dd86e63f8d6e8434f49276 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Thu, 26 Sep 2013 18:51:13 -0700
Subject: [PATCH 082/165] improve processMathOp quoting

---
 src/parseTools.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/parseTools.js b/src/parseTools.js
index a5aa7b17f4652..e390195404938 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -2108,7 +2108,7 @@ function processMathop(item) {
     if (item.params[i]) {
       paramTypes[i] = item.params[i].type || type;
       idents[i] = finalizeLLVMParameter(item.params[i]);
-      if (!isNumber(idents[i]) && !isNiceIdent(idents[i])) {
+      if (needsQuoting(idents[i])) {
         idents[i] = '(' + idents[i] + ')'; // we may have nested expressions. So enforce the order of operations we want
       }
     } else {

From c2560b71f88d68ec6817f44729cd97517eda512d Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Thu, 26 Sep 2013 18:52:55 -0700
Subject: [PATCH 083/165] debugging stuff

---
 emscripten.py | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/emscripten.py b/emscripten.py
index 1eb486ad85eb6..2d7b3daf2f835 100755
--- a/emscripten.py
+++ b/emscripten.py
@@ -186,6 +186,7 @@ def save_settings():
     if out and DEBUG: logging.debug('  loading pre from jcache')
   if not out:
     open(pre_file, 'w').write(pre_input)
+    #print >> sys.stderr, 'running', str([settings_file, pre_file, 'pre'] + libraries).replace("'/", "'") # see funcs
     out = jsrun.run_js(compiler, compiler_engine, [settings_file, pre_file, 'pre'] + libraries, stdout=subprocess.PIPE, stderr=STDERR_FILE,
                        cwd=path_from_root('src'))
     assert '//FORWARDED_DATA:' in out, 'Did not receive forwarded data in pre output - process failed?'
@@ -223,6 +224,7 @@ def save_settings():
     funcs, chunk_size,
     jcache.get_cachename('emscript_files') if jcache else None)
 
+  #sys.exit(1)
   #chunks = [chunks[0]] # pick specific chunks for debugging/profiling
 
   funcs = None

From 2d45e5d75b9d7b475256415cc2c28225b89d6129 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Fri, 27 Sep 2013 13:15:17 -0700
Subject: [PATCH 084/165] intertyper fast paths setup and proof of concept

---
 src/compiler.js   |  1 +
 src/intertyper.js | 55 +++++++++++++++++++++++++++++++++++++++++------
 src/settings.js   |  2 ++
 3 files changed, 52 insertions(+), 6 deletions(-)

diff --git a/src/compiler.js b/src/compiler.js
index 94197390f31ff..24136551d7ba1 100644
--- a/src/compiler.js
+++ b/src/compiler.js
@@ -275,6 +275,7 @@ function compile(raw) {
     JSify(analyzed);
 
     //dumpInterProf();
+    //printErr('Paths (fast, slow): ' + [fastPaths, slowPaths]);
 
     phase = null;
 
diff --git a/src/intertyper.js b/src/intertyper.js
index 525096f53ccd3..f452c9556a0ae 100644
--- a/src/intertyper.js
+++ b/src/intertyper.js
@@ -3,6 +3,8 @@
 // LLVM assembly => internal intermediate representation, which is ready
 // to be processed by the later stages.
 
+var fastPaths = 0, slowPaths = 0;
+
 // Line tokenizer
 function tokenizer(item, inner) {
   //assert(item.lineNum != 40000);
@@ -373,6 +375,14 @@ function intertyper(lines, sidePass, baseLineNums) {
   // Line parsers to intermediate form
 
   // globals: type or variable
+  function noteGlobalVariable(ret) {
+    if (!NAMED_GLOBALS) {
+      Variables.globals[ret.ident].type = ret.type;
+      Variables.globals[ret.ident].external = ret.external;
+    }
+    Types.needAnalysis[ret.type] = 0;
+  }
+
   function globalHandler(item) {
     function scanConst(value, type) {
       // Gets an array of constant items, separated by ',' tokens
@@ -497,7 +507,6 @@ function intertyper(lines, sidePass, baseLineNums) {
         external = true;
         item.tokens.splice(2, 1);
       }
-      Types.needAnalysis[item.tokens[2].text] = 0;
       var ret = {
         intertype: 'globalVariable',
         ident: toNiceIdent(ident),
@@ -507,11 +516,7 @@ function intertyper(lines, sidePass, baseLineNums) {
         named: named,
         lineNum: item.lineNum
       };
-      if (!NAMED_GLOBALS) {
-        Variables.globals[ret.ident].type = ret.type;
-        Variables.globals[ret.ident].external = external;
-      }
-      Types.needAnalysis[ret.type] = 0;
+      noteGlobalVariable(ret);
       if (ident == '@llvm.global_ctors') {
         ret.ctors = [];
         if (item.tokens[3].item) {
@@ -984,9 +989,47 @@ function intertyper(lines, sidePass, baseLineNums) {
     return ret;
   }
 
+  // Fast paths - quick parses of common patterns, avoid tokenizing entirely
+
+  function tryFastPaths(line) {
+    var m, ret;
+    if (phase === 'pre') {
+      // string constant
+      if (0) { // works, but not worth it   m = /([@\.\w\d_]+) = (private )?(unnamed_addr )?(constant )?(\[\d+ x i8\]) c"([^"]+)".*/.exec(line.lineText)) {
+        if (m[1] === '@llvm.global_ctors') return ret;
+        ret = {
+          intertype: 'globalVariable',
+          ident: toNiceIdent(m[1]),
+          type: m[5],
+          external: false,
+          private_: m[2] !== null,
+          named: m[3] === null,
+          lineNum: line.lineNum,
+          value: {
+            intertype: 'string',
+            text: m[6]
+          }
+        };
+        noteGlobalVariable(ret);
+      }
+    }
+    if (ret) {
+      fastPaths++;
+      if (COMPILER_ASSERTIONS) {
+        //printErr(['\n', JSON.stringify(ret), '\n', JSON.stringify(triager(tokenizer(line)))]);
+        assert(JSON.stringify(ret) === JSON.stringify(triager(tokenizer(line))), 'fast path');
+      }
+      finalResults.push(ret);
+    }
+    return ret;
+  }
+
   // Input
 
   lineSplitter().forEach(function(line) {
+    if (tryFastPaths(line)) return;
+    slowPaths++;
+
     //var time = Date.now();
 
     var t = tokenizer(line);
diff --git a/src/settings.js b/src/settings.js
index 0daafa352e220..0a4765fd114e1 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -426,6 +426,8 @@ var JS_CHUNK_SIZE = 10240; // Used as a maximum size before breaking up expressi
 var EXPORT_NAME = 'Module'; // Global variable to export the module as for environments without a standardized module
                             // loading system (e.g. the browser and SM shell).
 
+var COMPILER_ASSERTIONS = 0; // costly (slow) compile-time assertions
+
 // Compiler debugging options
 var DEBUG_TAGS_SHOWING = [];
   // Some useful items:

From 6cf78084545fca66bac20a047e01312077e0ed7f Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Fri, 27 Sep 2013 14:25:47 -0700
Subject: [PATCH 085/165] fast-path simple geps

---
 src/compiler.js   |  2 +-
 src/intertyper.js | 29 ++++++++++++++++++++++++++++-
 src/utility.js    | 11 +++++++++++
 3 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/src/compiler.js b/src/compiler.js
index 24136551d7ba1..06cbcd1f2e70b 100644
--- a/src/compiler.js
+++ b/src/compiler.js
@@ -275,7 +275,7 @@ function compile(raw) {
     JSify(analyzed);
 
     //dumpInterProf();
-    //printErr('Paths (fast, slow): ' + [fastPaths, slowPaths]);
+    //printErr(phase + ' paths (fast, slow): ' + [fastPaths, slowPaths]);
 
     phase = null;
 
diff --git a/src/intertyper.js b/src/intertyper.js
index f452c9556a0ae..d4e9c7b4ac251 100644
--- a/src/intertyper.js
+++ b/src/intertyper.js
@@ -1012,12 +1012,39 @@ function intertyper(lines, sidePass, baseLineNums) {
         };
         noteGlobalVariable(ret);
       }
+    } else if (phase === 'funcs') {
+      // simple gep
+      if (m = /  (%[\w\d\._]+) = getelementptr (?:inbounds )?([%\w\d\._ ,\*-@]+$)/.exec(line.lineText)) {
+        var params = m[2].split(', ').map(function(param) {
+          var parts = param.split(' ');
+          assert(parts.length === 2);
+          Types.needAnalysis[parts[0]] = 0;
+          return {
+            intertype: 'value',
+            type: parts[0],
+            ident: toNiceIdent(parts[1]),
+            byVal: 0
+          }
+        });
+        ret = {
+          intertype: 'getelementptr',
+          lineNum: line.lineNum,
+          assignTo: toNiceIdent(m[1]),
+          ident: params[0].ident,
+          type: '*',
+          params: params
+        };
+      }
+      // else if (line.lineText.indexOf(' = getelementptr ') > 0) printErr('close: ' + line.lineText);
     }
     if (ret) {
       fastPaths++;
       if (COMPILER_ASSERTIONS) {
         //printErr(['\n', JSON.stringify(ret), '\n', JSON.stringify(triager(tokenizer(line)))]);
-        assert(JSON.stringify(ret) === JSON.stringify(triager(tokenizer(line))), 'fast path');
+        var normal = triager(tokenizer(line));
+        delete normal.tokens;
+        delete normal.indent;
+        assert(sortedJsonCompare(normal, ret), 'fast path: ' + dump(normal) + '\n vs \n' + dump(ret));
       }
       finalResults.push(ret);
     }
diff --git a/src/utility.js b/src/utility.js
index 7d122cef6337f..b793106c2bd32 100644
--- a/src/utility.js
+++ b/src/utility.js
@@ -334,6 +334,17 @@ function jsonCompare(x, y) {
   return JSON.stringify(x) == JSON.stringify(y);
 }
 
+function sortedJsonCompare(x, y) {
+  if (x === null || typeof x !== 'object') return x === y;
+  for (var i in x) {
+    if (!sortedJsonCompare(x[i], y[i])) return false;
+  }
+  for (var i in y) {
+    if (!sortedJsonCompare(x[i], y[i])) return false;
+  }
+  return true;
+}
+
 function stringifyWithFunctions(obj) {
   if (typeof obj === 'function') return obj.toString();
   if (obj === null || typeof obj !== 'object') return JSON.stringify(obj);

From 040aa2d32ae0b891426763ccd80890b5357e70a8 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Fri, 27 Sep 2013 16:04:16 -0700
Subject: [PATCH 086/165] fix fast path regexp

---
 src/intertyper.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/intertyper.js b/src/intertyper.js
index d4e9c7b4ac251..0fe58b7a0409d 100644
--- a/src/intertyper.js
+++ b/src/intertyper.js
@@ -1014,7 +1014,7 @@ function intertyper(lines, sidePass, baseLineNums) {
       }
     } else if (phase === 'funcs') {
       // simple gep
-      if (m = /  (%[\w\d\._]+) = getelementptr (?:inbounds )?([%\w\d\._ ,\*-@]+$)/.exec(line.lineText)) {
+      if (m = /  (%[\w\d\._]+) = getelementptr (?:inbounds )?([%\w\d\._ ,\*\-@]+$)/.exec(line.lineText)) {
         var params = m[2].split(', ').map(function(param) {
           var parts = param.split(' ');
           assert(parts.length === 2);

From 26cab17867e4c5e0ce69c81c1ac05a20d08d8b02 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Fri, 27 Sep 2013 17:37:20 -0700
Subject: [PATCH 087/165] fast-path simple loads

---
 src/intertyper.js | 24 +++++++++++++++++++++++-
 src/parseTools.js |  5 +++++
 2 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/src/intertyper.js b/src/intertyper.js
index 0fe58b7a0409d..53c8482fcecc3 100644
--- a/src/intertyper.js
+++ b/src/intertyper.js
@@ -1035,7 +1035,29 @@ function intertyper(lines, sidePass, baseLineNums) {
           params: params
         };
       }
-      // else if (line.lineText.indexOf(' = getelementptr ') > 0) printErr('close: ' + line.lineText);
+      // simple load
+      else if (m = /  (%[\w\d\._]+) = load ([%\w\d\._\-@\*]+) ([%\w\d\._\-@]+)(, align \d+)?$/.exec(line.lineText)) {
+        var ident = toNiceIdent(m[3]);
+        var type = m[2];
+        assert(type[type.length-1] === '*', type);
+        var valueType = type.substr(0, type.length-1);
+        ret = {
+          intertype: 'load',
+          lineNum: line.lineNum,
+          assignTo: toNiceIdent(m[1]),
+          ident: ident,
+          type: valueType,
+          valueType: valueType,
+          pointerType: type,
+          pointer: {
+            intertype: 'value',
+            ident: ident,
+            type: type,
+          },
+          align: parseAlign(m[4]),
+        };
+      }
+      //else if (line.lineText.indexOf(' = load ') > 0) printErr('close: ' + JSON.stringify(line.lineText));
     }
     if (ret) {
       fastPaths++;
diff --git a/src/parseTools.js b/src/parseTools.js
index e390195404938..470c246f21984 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -2547,3 +2547,8 @@ function makePrintChars(s, sep) {
   return ret;
 }
 
+function parseAlign(text) { // parse ", align \d+"
+  if (!text) return QUANTUM_SIZE;
+  return parseInt(text.substr(8));
+}
+

From f2542d2d65de0be9e4b657a7a6c52e8165d101df Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Fri, 27 Sep 2013 18:16:55 -0700
Subject: [PATCH 088/165] restructure fast paths code flow

---
 src/intertyper.js | 98 ++++++++++++++++++++++++++---------------------
 1 file changed, 55 insertions(+), 43 deletions(-)

diff --git a/src/intertyper.js b/src/intertyper.js
index 53c8482fcecc3..606a15a293f0b 100644
--- a/src/intertyper.js
+++ b/src/intertyper.js
@@ -1013,51 +1013,63 @@ function intertyper(lines, sidePass, baseLineNums) {
         noteGlobalVariable(ret);
       }
     } else if (phase === 'funcs') {
-      // simple gep
-      if (m = /  (%[\w\d\._]+) = getelementptr (?:inbounds )?([%\w\d\._ ,\*\-@]+$)/.exec(line.lineText)) {
-        var params = m[2].split(', ').map(function(param) {
-          var parts = param.split(' ');
-          assert(parts.length === 2);
-          Types.needAnalysis[parts[0]] = 0;
-          return {
-            intertype: 'value',
-            type: parts[0],
-            ident: toNiceIdent(parts[1]),
-            byVal: 0
+      if (m = /^  (%[\w\d\._]+) = (\w+) ([%\w\d\._ ,\*\-@]+)$/.exec(line.lineText)) {
+        var assignTo = m[1];
+        var intertype = m[2];
+        var args = m[3];
+        switch (intertype) {
+          case 'getelementptr': {
+            if (args[0] === 'i' && args.indexOf('inbounds ') === 0) {
+              args = args.substr(9);
+            }
+            var params = args.split(', ').map(function(param) {
+              var parts = param.split(' ');
+              assert(parts.length === 2);
+              Types.needAnalysis[parts[0]] = 0;
+              return {
+                intertype: 'value',
+                type: parts[0],
+                ident: toNiceIdent(parts[1]),
+                byVal: 0
+              }
+            });
+            ret = {
+              intertype: 'getelementptr',
+              lineNum: line.lineNum,
+              assignTo: toNiceIdent(assignTo),
+              ident: params[0].ident,
+              type: '*',
+              params: params
+            };
+            break;
           }
-        });
-        ret = {
-          intertype: 'getelementptr',
-          lineNum: line.lineNum,
-          assignTo: toNiceIdent(m[1]),
-          ident: params[0].ident,
-          type: '*',
-          params: params
-        };
-      }
-      // simple load
-      else if (m = /  (%[\w\d\._]+) = load ([%\w\d\._\-@\*]+) ([%\w\d\._\-@]+)(, align \d+)?$/.exec(line.lineText)) {
-        var ident = toNiceIdent(m[3]);
-        var type = m[2];
-        assert(type[type.length-1] === '*', type);
-        var valueType = type.substr(0, type.length-1);
-        ret = {
-          intertype: 'load',
-          lineNum: line.lineNum,
-          assignTo: toNiceIdent(m[1]),
-          ident: ident,
-          type: valueType,
-          valueType: valueType,
-          pointerType: type,
-          pointer: {
-            intertype: 'value',
-            ident: ident,
-            type: type,
-          },
-          align: parseAlign(m[4]),
-        };
+          case 'load': {
+            if (m = /([%\w\d\._\-@\*]+) ([%\w\d\._\-@]+)(, align \d+)?$/.exec(args)) {
+              var ident = toNiceIdent(m[2]);
+              var type = m[1];
+              assert(type[type.length-1] === '*', type);
+              var valueType = type.substr(0, type.length-1);
+              ret = {
+                intertype: 'load',
+                lineNum: line.lineNum,
+                assignTo: toNiceIdent(assignTo),
+                ident: ident,
+                type: valueType,
+                valueType: valueType,
+                pointerType: type,
+                pointer: {
+                  intertype: 'value',
+                  ident: ident,
+                  type: type,
+                },
+                align: parseAlign(m[3])
+              };
+            }
+            break;
+          }
+        }
+        //else if (line.lineText.indexOf(' = load ') > 0) printErr('close: ' + JSON.stringify(line.lineText));
       }
-      //else if (line.lineText.indexOf(' = load ') > 0) printErr('close: ' + JSON.stringify(line.lineText));
     }
     if (ret) {
       fastPaths++;

From 3d74fe365db4ea47b673925dffea9f2dedf6efc6 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Fri, 27 Sep 2013 18:30:29 -0700
Subject: [PATCH 089/165] better relooper load error

---
 src/compiler.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/compiler.js b/src/compiler.js
index 06cbcd1f2e70b..e42f5e19a3e2a 100644
--- a/src/compiler.js
+++ b/src/compiler.js
@@ -218,7 +218,7 @@ if (phase == 'funcs' && RELOOP) { // XXX handle !singlePhase
   try {
     load(RELOOPER);
   } catch(e) {
-    printErr('cannot find relooper at ' + RELOOPER + ', trying in current dir');
+    printErr('cannot load relooper at ' + RELOOPER + ' : ' + e + ', trying in current dir');
     load('relooper.js');
   }
   assert(typeof Relooper != 'undefined');

From 5ae5fd072b04c8c26fa284f074e28509e0d10438 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Fri, 27 Sep 2013 18:31:09 -0700
Subject: [PATCH 090/165] fix load fast path regexp

---
 src/intertyper.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/intertyper.js b/src/intertyper.js
index 606a15a293f0b..1acad4f2b31db 100644
--- a/src/intertyper.js
+++ b/src/intertyper.js
@@ -1044,7 +1044,7 @@ function intertyper(lines, sidePass, baseLineNums) {
             break;
           }
           case 'load': {
-            if (m = /([%\w\d\._\-@\*]+) ([%\w\d\._\-@]+)(, align \d+)?$/.exec(args)) {
+            if (m = /(^[%\w\d\._\-@\*]+) ([%\w\d\._\-@]+)(, align \d+)?$/.exec(args)) {
               var ident = toNiceIdent(m[2]);
               var type = m[1];
               assert(type[type.length-1] === '*', type);

From 1f2058f6ecb8212986fa6566b966454268bdb972 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Fri, 27 Sep 2013 21:33:56 -0700
Subject: [PATCH 091/165] clean up intertyper paths fork

---
 src/intertyper.js | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/src/intertyper.js b/src/intertyper.js
index 1acad4f2b31db..ce33a2d19ca75 100644
--- a/src/intertyper.js
+++ b/src/intertyper.js
@@ -1072,7 +1072,6 @@ function intertyper(lines, sidePass, baseLineNums) {
       }
     }
     if (ret) {
-      fastPaths++;
       if (COMPILER_ASSERTIONS) {
         //printErr(['\n', JSON.stringify(ret), '\n', JSON.stringify(triager(tokenizer(line)))]);
         var normal = triager(tokenizer(line));
@@ -1080,7 +1079,6 @@ function intertyper(lines, sidePass, baseLineNums) {
         delete normal.indent;
         assert(sortedJsonCompare(normal, ret), 'fast path: ' + dump(normal) + '\n vs \n' + dump(ret));
       }
-      finalResults.push(ret);
     }
     return ret;
   }
@@ -1088,13 +1086,18 @@ function intertyper(lines, sidePass, baseLineNums) {
   // Input
 
   lineSplitter().forEach(function(line) {
-    if (tryFastPaths(line)) return;
+    var item = tryFastPaths(line);
+    if (item) {
+      finalResults.push(item);
+      fastPaths++;
+      return;
+    }
     slowPaths++;
 
     //var time = Date.now();
 
     var t = tokenizer(line);
-    var item = triager(t);
+    item = triager(t);
 
     //var type = item ? item.intertype + (item.op ? ':' + item.op : ''): 'none';
     //interProf[type] = (interProf[type] || 0) + Date.now() - time;

From 9a7389a86d9209e9fdda6da6578a7acdcf590eb1 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Fri, 27 Sep 2013 21:42:06 -0700
Subject: [PATCH 092/165] improve intertyper profiler

---
 src/intertyper.js | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/src/intertyper.js b/src/intertyper.js
index ce33a2d19ca75..5ffc20dd77895 100644
--- a/src/intertyper.js
+++ b/src/intertyper.js
@@ -1099,8 +1099,12 @@ function intertyper(lines, sidePass, baseLineNums) {
     var t = tokenizer(line);
     item = triager(t);
 
-    //var type = item ? item.intertype + (item.op ? ':' + item.op : ''): 'none';
-    //interProf[type] = (interProf[type] || 0) + Date.now() - time;
+    /*
+    var type = item ? item.intertype + (item.op ? ':' + item.op : ''): 'none';
+    if (!interProf[type]) interProf[type] = { ms: 0, n: 0 };
+    interProf[type].ms += Date.now() - time;
+    interProf[type].n++;
+    */
 
     if (!item) return;
     finalResults.push(item);
@@ -1109,10 +1113,12 @@ function intertyper(lines, sidePass, baseLineNums) {
   return finalResults;
 }
 
+// intertyper profiler
+
 /*
 var interProf = {};
 function dumpInterProf() {
-  printErr('\nintertyper/' + phase + ' : ' + JSON.stringify(keys(interProf).sort(function(x, y) { return interProf[y] - interProf[x] }).map(function(x) { return x + ':' + interProf[x] }), null, ' ') + '\n');
+  printErr('\nintertyper/' + phase + ' (ms | n): ' + JSON.stringify(keys(interProf).sort(function(x, y) { return interProf[y].ms - interProf[x].ms }).map(function(x) { return x + ' : ' + interProf[x].ms + ' | ' + interProf[x].n }), null, ' ') + '\n');
 }
 */
 

From 51256ab4452f9b1aa3774ef2eece26faa652ab22 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Fri, 27 Sep 2013 21:51:32 -0700
Subject: [PATCH 093/165] make sure to only fast-path stuff we expect

---
 src/intertyper.js | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/intertyper.js b/src/intertyper.js
index 5ffc20dd77895..07f2020c3290c 100644
--- a/src/intertyper.js
+++ b/src/intertyper.js
@@ -1013,7 +1013,7 @@ function intertyper(lines, sidePass, baseLineNums) {
         noteGlobalVariable(ret);
       }
     } else if (phase === 'funcs') {
-      if (m = /^  (%[\w\d\._]+) = (\w+) ([%\w\d\._ ,\*\-@]+)$/.exec(line.lineText)) {
+      if (m = /^  (%[\w\d\._]+) = (getelementptr|load) ([%\w\d\._ ,\*\-@]+)$/.exec(line.lineText)) {
         var assignTo = m[1];
         var intertype = m[2];
         var args = m[3];
@@ -1067,6 +1067,7 @@ function intertyper(lines, sidePass, baseLineNums) {
             }
             break;
           }
+          default: throw 'unexpected fast path type ' + intertype;
         }
         //else if (line.lineText.indexOf(' = load ') > 0) printErr('close: ' + JSON.stringify(line.lineText));
       }

From 67f4aab994dc04230d96eb0fed7f8bce57f2f188 Mon Sep 17 00:00:00 2001
From: Anthony Pesch 
Date: Thu, 26 Sep 2013 22:40:04 -0700
Subject: [PATCH 094/165]  - added test for FS.syncfs functionality

---
 tests/fs/test_idbfs_sync.c | 48 ++++++++++++++++++++++++++++++++++++++
 tests/test_browser.py      |  5 ++++
 2 files changed, 53 insertions(+)
 create mode 100644 tests/fs/test_idbfs_sync.c

diff --git a/tests/fs/test_idbfs_sync.c b/tests/fs/test_idbfs_sync.c
new file mode 100644
index 0000000000000..ff356416cbc24
--- /dev/null
+++ b/tests/fs/test_idbfs_sync.c
@@ -0,0 +1,48 @@
+#include 
+#include 
+
+#define EM_ASM_REEXPAND(x) EM_ASM(x)
+
+void success() {
+  int result = 1;
+  REPORT_RESULT();
+}
+
+int main() {
+  EM_ASM(
+    FS.mkdir('/working');
+    FS.mount(IDBFS, {}, '/working');
+  );
+
+#if FIRST
+  // store local files to backing IDB
+  EM_ASM_REEXPAND(
+    FS.writeFile('/working/waka.txt', 'az');
+    FS.writeFile('/working/moar.txt', SECRET);
+    FS.syncfs(function (err) {
+      assert(!err);
+
+      ccall('success', 'v', '', []);
+    });
+  );
+#else
+  // load files from backing IDB
+  EM_ASM_REEXPAND(
+    FS.syncfs(true, function (err) {
+      assert(!err);
+
+      var contents = FS.readFile('/working/waka.txt', { encoding: 'utf8' });
+      assert(contents === 'az');
+
+      var secret = FS.readFile('/working/moar.txt', { encoding: 'utf8' });
+      assert(secret === SECRET);
+
+      ccall('success', 'v', '', []);
+    });
+  );
+#endif
+
+  emscripten_exit_with_live_runtime();
+
+  return 0;
+}
diff --git a/tests/test_browser.py b/tests/test_browser.py
index d50488ecd6a4b..799759a11838c 100644
--- a/tests/test_browser.py
+++ b/tests/test_browser.py
@@ -880,6 +880,11 @@ def test_file_db(self):
     self.btest('file_db.cpp', secret, args=['--preload-file', 'moar.txt']) # even with a file there, we load over it
     shutil.move('test.html', 'third.html')
 
+  def test_fs_idbfs_sync(self):
+    secret = str(time.time())
+    self.btest(path_from_root('tests', 'fs', 'test_idbfs_sync.c'), '1', force_c=True, args=['-DFIRST', '-DSECRET=\'' + secret + '\'', '-s', '''EXPORTED_FUNCTIONS=['_main', '_success']'''])
+    self.btest(path_from_root('tests', 'fs', 'test_idbfs_sync.c'), '1', force_c=True, args=['-DSECRET=\'' + secret + '\'', '-s', '''EXPORTED_FUNCTIONS=['_main', '_success']'''])
+
   def test_sdl_pumpevents(self):
     # key events should be detected using SDL_PumpEvents
     open(os.path.join(self.get_dir(), 'pre.js'), 'w').write('''

From 4db117910eb13fc93d632dd4e3fb4cf127544538 Mon Sep 17 00:00:00 2001
From: Anthony Pesch 
Date: Fri, 27 Sep 2013 00:53:28 -0700
Subject: [PATCH 095/165]  - added basic nodefs r/w test

---
 tests/fs/test_nodefs_rw.c | 49 +++++++++++++++++++++++++++++++++++++++
 tests/test_core.py        |  4 ++++
 2 files changed, 53 insertions(+)
 create mode 100644 tests/fs/test_nodefs_rw.c

diff --git a/tests/fs/test_nodefs_rw.c b/tests/fs/test_nodefs_rw.c
new file mode 100644
index 0000000000000..140da33266c66
--- /dev/null
+++ b/tests/fs/test_nodefs_rw.c
@@ -0,0 +1,49 @@
+#include 
+#include 
+#include 
+
+int main() {
+  FILE *file;
+  int res;
+  char buffer[512];
+
+  // write something locally with node
+  EM_ASM(
+    var fs = require('fs');
+    fs.writeFileSync('foobar.txt', 'yeehaw');
+  );
+
+  // mount the current folder as a NODEFS instance
+  // inside of emscripten
+  EM_ASM(
+    FS.mkdir('/working');
+    FS.mount(NODEFS, { root: '.' }, '/working');
+  );
+
+  // read and validate the contents of the file
+  file = fopen("/working/foobar.txt", "r");
+  assert(file);
+  res = fread(buffer, sizeof(char), 6, file);
+  assert(res == 6);
+  fclose(file);
+
+  assert(!strcmp(buffer, "yeehaw"));
+
+  // write out something new
+  file = fopen("/working/foobar.txt", "w");
+  assert(file);
+  res = fwrite("cheez", sizeof(char), 5, file);
+  assert(res == 5);
+  fclose(file);
+
+  // validate the changes were persisted to the underlying fs
+  EM_ASM(
+    var fs = require('fs');
+    var contents = fs.readFileSync('foobar.txt', { encoding: 'utf8' });
+    assert(contents === 'cheez');
+  );
+
+  puts("success");
+
+  return 0;
+}
diff --git a/tests/test_core.py b/tests/test_core.py
index e78fb5134a206..f41d59abf78a6 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -7742,6 +7742,10 @@ def process(filename):
     finally:
       Settings.INCLUDE_FULL_LIBRARY = 0
 
+  def test_fs_nodefs_rw(self):
+    src = open(path_from_root('tests', 'fs', 'test_nodefs_rw.c'), 'r').read()
+    self.do_run(src, 'success', force_c=True)
+
   def test_unistd_access(self):
     if Settings.ASM_JS: Settings.ASM_JS = 2 # skip validation, asm does not support random code
     if not self.is_le32(): return self.skip('le32 needed for inline js')

From 2725cfa316f2749fa6dbedc34e23f5445dfbcf7f Mon Sep 17 00:00:00 2001
From: Anthony Pesch 
Date: Sun, 29 Sep 2013 15:00:41 -0700
Subject: [PATCH 096/165]  - append to Building.COMPILER_TEST_OPTS for unistd
 tests

---
 tests/test_core.py | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/tests/test_core.py b/tests/test_core.py
index f41d59abf78a6..f51c169161cf4 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -7752,7 +7752,7 @@ def test_unistd_access(self):
     for fs in ['MEMFS', 'NODEFS']:
       src = open(path_from_root('tests', 'unistd', 'access.c'), 'r').read()
       expected = open(path_from_root('tests', 'unistd', 'access.out'), 'r').read()
-      Building.COMPILER_TEST_OPTS = ['-D' + fs]
+      Building.COMPILER_TEST_OPTS += ['-D' + fs]
       self.do_run(src, expected)
 
   def test_unistd_curdir(self):
@@ -7792,7 +7792,7 @@ def test_unistd_truncate(self):
     for fs in ['MEMFS', 'NODEFS']:
       src = open(path_from_root('tests', 'unistd', 'truncate.c'), 'r').read()
       expected = open(path_from_root('tests', 'unistd', 'truncate.out'), 'r').read()
-      Building.COMPILER_TEST_OPTS = ['-D' + fs]
+      Building.COMPILER_TEST_OPTS += ['-D' + fs]
       self.do_run(src, expected)
 
   def test_unistd_swab(self):
@@ -7817,7 +7817,7 @@ def test_unistd_login(self):
   def test_unistd_unlink(self):
     for fs in ['MEMFS', 'NODEFS']:
       src = open(path_from_root('tests', 'unistd', 'unlink.c'), 'r').read()
-      Building.COMPILER_TEST_OPTS = ['-D' + fs]
+      Building.COMPILER_TEST_OPTS += ['-D' + fs]
       self.do_run(src, 'success', force_c=True)
 
   def test_unistd_links(self):
@@ -7826,7 +7826,7 @@ def test_unistd_links(self):
     for fs in ['MEMFS', 'NODEFS']:
       src = open(path_from_root('tests', 'unistd', 'links.c'), 'r').read()
       expected = open(path_from_root('tests', 'unistd', 'links.out'), 'r').read()
-      Building.COMPILER_TEST_OPTS = ['-D' + fs]
+      Building.COMPILER_TEST_OPTS += ['-D' + fs]
       self.do_run(src, expected)
 
   def test_unistd_sleep(self):
@@ -7841,14 +7841,14 @@ def test_unistd_io(self):
     for fs in ['MEMFS', 'NODEFS']:
       src = open(path_from_root('tests', 'unistd', 'io.c'), 'r').read()
       expected = open(path_from_root('tests', 'unistd', 'io.out'), 'r').read()
-      Building.COMPILER_TEST_OPTS = ['-D' + fs]
+      Building.COMPILER_TEST_OPTS += ['-D' + fs]
       self.do_run(src, expected)
 
   def test_unistd_misc(self):
     for fs in ['MEMFS', 'NODEFS']:
       src = open(path_from_root('tests', 'unistd', 'misc.c'), 'r').read()
       expected = open(path_from_root('tests', 'unistd', 'misc.out'), 'r').read()
-      Building.COMPILER_TEST_OPTS = ['-D' + fs]
+      Building.COMPILER_TEST_OPTS += ['-D' + fs]
       self.do_run(src, expected)
 
   def test_uname(self):

From af8c0ef4156eedfb1cf0c1ae7f76e3f1580927a6 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Mon, 30 Sep 2013 13:55:01 -0700
Subject: [PATCH 097/165] fix sanity.test_emcc_caching (we now have a cache dir
 earlier on)

---
 tests/test_sanity.py | 1 -
 1 file changed, 1 deletion(-)

diff --git a/tests/test_sanity.py b/tests/test_sanity.py
index 6fdf5ddd2be61..aa3f1242eea28 100644
--- a/tests/test_sanity.py
+++ b/tests/test_sanity.py
@@ -342,7 +342,6 @@ def test_emcc_caching(self):
         assert INCLUDING_MESSAGE.replace('X', 'libc') not in output
         assert BUILDING_MESSAGE.replace('X', 'libc') not in output
         self.assertContained('hello, world!', run_js('a.out.js'))
-        assert not os.path.exists(EMCC_CACHE)
         try_delete('a.out.js')
 
         basebc_name = os.path.join(TEMP_DIR, 'emscripten_temp', 'emcc-0-basebc.bc')

From 5afeeb49b5f2d1155b8d974767159ba346cec3e2 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Mon, 30 Sep 2013 16:41:45 -0700
Subject: [PATCH 098/165] update test_outline

---
 tests/test_other.py | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/tests/test_other.py b/tests/test_other.py
index 9f331439911e2..69823d8e1aed3 100644
--- a/tests/test_other.py
+++ b/tests/test_other.py
@@ -807,10 +807,10 @@ def measure_funcs(filename):
            0: (1500, 5000)
       }),
       (['-O2'], {
-         100: (0, 1500),
-         250: (0, 1500),
-         500: (0, 1500),
-        1000: (0, 1500),
+         100: (0, 1600),
+         250: (0, 1600),
+         500: (0, 1600),
+        1000: (0, 1600),
         2000: (0, 2000),
         5000: (0, 5000),
            0: (0, 5000)

From f717fa82cc598d403eba5ff1b03246b69cd9dca0 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Mon, 30 Sep 2013 17:16:46 -0700
Subject: [PATCH 099/165] fix other.test_static_link

---
 src/library.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/library.js b/src/library.js
index abee70c4216e2..02981a804892f 100644
--- a/src/library.js
+++ b/src/library.js
@@ -8705,7 +8705,7 @@ function autoAddDeps(object, name) {
 }
 
 // Add aborting stubs for various libc stuff needed by libc++
-['pthread_cond_signal', 'pthread_equal', 'wcstol', 'wcstoll', 'wcstoul', 'wcstoull', 'wcstof', 'wcstod', 'wcstold', 'pthread_join', 'pthread_detach', 'catgets', 'catopen', 'catclose'].forEach(function(aborter) {
+['pthread_cond_signal', 'pthread_equal', 'wcstol', 'wcstoll', 'wcstoul', 'wcstoull', 'wcstof', 'wcstod', 'wcstold', 'pthread_join', 'pthread_detach', 'catgets', 'catopen', 'catclose', 'fputwc', '__lockfile', '__unlockfile'].forEach(function(aborter) {
   LibraryManager.library[aborter] = function() { throw 'TODO: ' + aborter };
 });
 

From f3f74a9d68c4f4c04aa1e57d2104b48a90a1333c Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Mon, 30 Sep 2013 17:54:38 -0700
Subject: [PATCH 100/165] run test_fs_nodefs_rw only in node

---
 tests/test_core.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/test_core.py b/tests/test_core.py
index f51c169161cf4..3baad0fd2157a 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -7744,7 +7744,7 @@ def process(filename):
 
   def test_fs_nodefs_rw(self):
     src = open(path_from_root('tests', 'fs', 'test_nodefs_rw.c'), 'r').read()
-    self.do_run(src, 'success', force_c=True)
+    self.do_run(src, 'success', force_c=True, js_engines=[NODE_JS])
 
   def test_unistd_access(self):
     if Settings.ASM_JS: Settings.ASM_JS = 2 # skip validation, asm does not support random code

From 0a8f236b9ebc62b8c6fffd2f6ebdff577a407a0b Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Mon, 30 Sep 2013 18:07:30 -0700
Subject: [PATCH 101/165] update unistd tests to run only on node

---
 tests/test_core.py | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/tests/test_core.py b/tests/test_core.py
index 3baad0fd2157a..d35bec4e73a3c 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -7753,7 +7753,7 @@ def test_unistd_access(self):
       src = open(path_from_root('tests', 'unistd', 'access.c'), 'r').read()
       expected = open(path_from_root('tests', 'unistd', 'access.out'), 'r').read()
       Building.COMPILER_TEST_OPTS += ['-D' + fs]
-      self.do_run(src, expected)
+      self.do_run(src, expected, js_engines=[NODE_JS])
 
   def test_unistd_curdir(self):
     if Settings.ASM_JS: Settings.ASM_JS = 2 # skip validation, asm does not support random code
@@ -7793,7 +7793,7 @@ def test_unistd_truncate(self):
       src = open(path_from_root('tests', 'unistd', 'truncate.c'), 'r').read()
       expected = open(path_from_root('tests', 'unistd', 'truncate.out'), 'r').read()
       Building.COMPILER_TEST_OPTS += ['-D' + fs]
-      self.do_run(src, expected)
+      self.do_run(src, expected, js_engines=[NODE_JS])
 
   def test_unistd_swab(self):
     src = open(path_from_root('tests', 'unistd', 'swab.c'), 'r').read()
@@ -7818,7 +7818,7 @@ def test_unistd_unlink(self):
     for fs in ['MEMFS', 'NODEFS']:
       src = open(path_from_root('tests', 'unistd', 'unlink.c'), 'r').read()
       Building.COMPILER_TEST_OPTS += ['-D' + fs]
-      self.do_run(src, 'success', force_c=True)
+      self.do_run(src, 'success', force_c=True, js_engines=[NODE_JS])
 
   def test_unistd_links(self):
     if Settings.ASM_JS: Settings.ASM_JS = 2 # skip validation, asm does not support random code
@@ -7827,7 +7827,7 @@ def test_unistd_links(self):
       src = open(path_from_root('tests', 'unistd', 'links.c'), 'r').read()
       expected = open(path_from_root('tests', 'unistd', 'links.out'), 'r').read()
       Building.COMPILER_TEST_OPTS += ['-D' + fs]
-      self.do_run(src, expected)
+      self.do_run(src, expected, js_engines=[NODE_JS])
 
   def test_unistd_sleep(self):
     src = open(path_from_root('tests', 'unistd', 'sleep.c'), 'r').read()
@@ -7842,14 +7842,14 @@ def test_unistd_io(self):
       src = open(path_from_root('tests', 'unistd', 'io.c'), 'r').read()
       expected = open(path_from_root('tests', 'unistd', 'io.out'), 'r').read()
       Building.COMPILER_TEST_OPTS += ['-D' + fs]
-      self.do_run(src, expected)
+      self.do_run(src, expected, js_engines=[NODE_JS])
 
   def test_unistd_misc(self):
     for fs in ['MEMFS', 'NODEFS']:
       src = open(path_from_root('tests', 'unistd', 'misc.c'), 'r').read()
       expected = open(path_from_root('tests', 'unistd', 'misc.out'), 'r').read()
       Building.COMPILER_TEST_OPTS += ['-D' + fs]
-      self.do_run(src, expected)
+      self.do_run(src, expected, js_engines=[NODE_JS])
 
   def test_uname(self):
     src = r'''

From 06a06823b740489674b99757ffaa860378e06fb3 Mon Sep 17 00:00:00 2001
From: Bruce Mitchener 
Date: Tue, 1 Oct 2013 14:41:23 +0700
Subject: [PATCH 102/165] Break up mkstemp impl to provide mktemp impl.

The libcxx test suite wants mktemp(), so provide it by pulling
out some of the internals of mkstemp().
---
 src/library.js | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/src/library.js b/src/library.js
index 02981a804892f..3e69cc0875078 100644
--- a/src/library.js
+++ b/src/library.js
@@ -459,14 +459,17 @@ LibraryManager.library = {
     // http://pubs.opengroup.org/onlinepubs/009695399/functions/creat.html
     return _open(path, {{{ cDefine('O_WRONLY') }}} | {{{ cDefine('O_CREAT') }}} | {{{ cDefine('O_TRUNC') }}}, allocate([mode, 0, 0, 0], 'i32', ALLOC_STACK));
   },
-  mkstemp__deps: ['creat'],
-  mkstemp: function(template) {
-    if (!_mkstemp.counter) _mkstemp.counter = 0;
-    var c = (_mkstemp.counter++).toString();
+  mktemp: function(template) {
+    if (!_mktemp.counter) _mktemp.counter = 0;
+    var c = (_mktemp.counter++).toString();
     var rep = 'XXXXXX';
     while (c.length < rep.length) c = '0' + c;
     writeArrayToMemory(intArrayFromString(c), template + Pointer_stringify(template).indexOf(rep));
-    return _creat(template, 0600);
+    return template;
+  },
+  mkstemp__deps: ['creat', 'mktemp'],
+  mkstemp: function(template) {
+    return _creat(_mktemp(template), 0600);
   },
   fcntl__deps: ['$FS', '__setErrNo', '$ERRNO_CODES'],
   fcntl: function(fildes, cmd, varargs, dup2) {

From 7439c4255f8e3c1ab3bcb313095001531e57996d Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Tue, 1 Oct 2013 09:41:03 -0700
Subject: [PATCH 103/165] test runner comment

---
 tests/runner.py | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/tests/runner.py b/tests/runner.py
index ddc97ea4f3201..867f71139e9a2 100755
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -737,13 +737,15 @@ def btest(self, filename, expected=None, reference=None, force_c=False, referenc
     print '''
 ==============================================================================
 Running the main part of the test suite. Don't forget to run the other parts!
+A recommended order is:
 
-  other - tests separate from the main suite
   sanity - tests for first run, etc., modifies ~/.emscripten
-  benchmark - run before and after each set of changes before pushing to
-              master, verify no regressions
+  (the main test suite)
+  other - tests separate from the main suite
   browser - runs pages in a web browser
   sockets - runs websocket networking tests
+  benchmark - run before and after each set of changes before pushing to
+              master, verify no regressions
 
 There are also commands to run specific subsets of the test suite:
 
@@ -799,3 +801,4 @@ def btest(self, filename, expected=None, reference=None, force_c=False, referenc
 
   # Return the number of failures as the process exit code for automating success/failure reporting.
   exit(numFailures)
+

From b71bc9932c22d22f657a02b0c00164c167504b0c Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Tue, 1 Oct 2013 12:17:53 -0700
Subject: [PATCH 104/165] disable some recently-changed tests in modes where
 they need inline js or emcc

---
 tests/test_core.py | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/tests/test_core.py b/tests/test_core.py
index d35bec4e73a3c..11ec8fd20a0ca 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -7743,6 +7743,8 @@ def process(filename):
       Settings.INCLUDE_FULL_LIBRARY = 0
 
   def test_fs_nodefs_rw(self):
+    if self.emcc_args is None: return self.skip('requires emcc')
+    if not self.is_le32(): return self.skip('le32 needed for inline js')
     src = open(path_from_root('tests', 'fs', 'test_nodefs_rw.c'), 'r').read()
     self.do_run(src, 'success', force_c=True, js_engines=[NODE_JS])
 
@@ -7815,6 +7817,8 @@ def test_unistd_login(self):
     self.do_run(src, expected)
 
   def test_unistd_unlink(self):
+    if self.emcc_args is None: return self.skip('requires emcc')
+    if not self.is_le32(): return self.skip('le32 needed for inline js')
     for fs in ['MEMFS', 'NODEFS']:
       src = open(path_from_root('tests', 'unistd', 'unlink.c'), 'r').read()
       Building.COMPILER_TEST_OPTS += ['-D' + fs]
@@ -7838,6 +7842,7 @@ def test_unistd_io(self):
     if Settings.ASM_JS: Settings.ASM_JS = 2 # skip validation, asm does not support random code
     if not self.is_le32(): return self.skip('le32 needed for inline js')
     if self.run_name == 'o2': return self.skip('non-asm optimized builds can fail with inline js')
+    if self.emcc_args is None: return self.skip('requires emcc')
     for fs in ['MEMFS', 'NODEFS']:
       src = open(path_from_root('tests', 'unistd', 'io.c'), 'r').read()
       expected = open(path_from_root('tests', 'unistd', 'io.out'), 'r').read()
@@ -7845,6 +7850,8 @@ def test_unistd_io(self):
       self.do_run(src, expected, js_engines=[NODE_JS])
 
   def test_unistd_misc(self):
+    if self.emcc_args is None: return self.skip('requires emcc')
+    if not self.is_le32(): return self.skip('le32 needed for inline js')
     for fs in ['MEMFS', 'NODEFS']:
       src = open(path_from_root('tests', 'unistd', 'misc.c'), 'r').read()
       expected = open(path_from_root('tests', 'unistd', 'misc.out'), 'r').read()

From a08253a00a0c37563ffabb3163de8088bca23933 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Tue, 1 Oct 2013 12:33:19 -0700
Subject: [PATCH 105/165] fix C_STRUCT usage in sdl

---
 src/library_sdl.js | 40 ++++++++++++++++++++--------------------
 1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/src/library_sdl.js b/src/library_sdl.js
index 1d6a00b628543..27f2c0da42dd3 100644
--- a/src/library_sdl.js
+++ b/src/library_sdl.js
@@ -1383,12 +1383,12 @@ var LibrarySDL = {
   SDL_OpenAudio: function(desired, obtained) {
     try {
       SDL.audio = {
-        freq: {{{ makeGetValue('desired', 'C_STRUCTS.SDL_AudioSpec.freq', 'i32', 0, 1) }}},
-        format: {{{ makeGetValue('desired', 'C_STRUCTS.SDL_AudioSpec.format', 'i16', 0, 1) }}},
-        channels: {{{ makeGetValue('desired', 'C_STRUCTS.SDL_AudioSpec.channels', 'i8', 0, 1) }}},
-        samples: {{{ makeGetValue('desired', 'C_STRUCTS.SDL_AudioSpec.samples', 'i16', 0, 1) }}}, // Samples in the CB buffer per single sound channel.
-        callback: {{{ makeGetValue('desired', 'C_STRUCTS.SDL_AudioSpec.callback', 'void*', 0, 1) }}},
-        userdata: {{{ makeGetValue('desired', 'C_STRUCTS.SDL_AudioSpec.userdata', 'void*', 0, 1) }}},
+        freq: {{{ makeGetValue('desired', C_STRUCTS.SDL_AudioSpec.freq, 'i32', 0, 1) }}},
+        format: {{{ makeGetValue('desired', C_STRUCTS.SDL_AudioSpec.format, 'i16', 0, 1) }}},
+        channels: {{{ makeGetValue('desired', C_STRUCTS.SDL_AudioSpec.channels, 'i8', 0, 1) }}},
+        samples: {{{ makeGetValue('desired', C_STRUCTS.SDL_AudioSpec.samples, 'i16', 0, 1) }}}, // Samples in the CB buffer per single sound channel.
+        callback: {{{ makeGetValue('desired', C_STRUCTS.SDL_AudioSpec.callback, 'void*', 0, 1) }}},
+        userdata: {{{ makeGetValue('desired', C_STRUCTS.SDL_AudioSpec.userdata, 'void*', 0, 1) }}},
         paused: true,
         timer: null
       };
@@ -1569,13 +1569,13 @@ var LibrarySDL = {
 
       if (obtained) {
         // Report back the initialized audio parameters.
-        {{{ makeSetValue('obtained', 'C_STRUCTS.SDL_AudioSpec.freq', 'SDL.audio.freq', 'i32') }}};
-        {{{ makeSetValue('obtained', 'C_STRUCTS.SDL_AudioSpec.format', 'SDL.audio.format', 'i16') }}};
-        {{{ makeSetValue('obtained', 'C_STRUCTS.SDL_AudioSpec.channels', 'SDL.audio.channels', 'i8') }}};
-        {{{ makeSetValue('obtained', 'C_STRUCTS.SDL_AudioSpec.silence', 'SDL.audio.silence', 'i8') }}};
-        {{{ makeSetValue('obtained', 'C_STRUCTS.SDL_AudioSpec.samples', 'SDL.audio.samples', 'i16') }}};
-        {{{ makeSetValue('obtained', 'C_STRUCTS.SDL_AudioSpec.callback', 'SDL.audio.callback', '*') }}};
-        {{{ makeSetValue('obtained', 'C_STRUCTS.SDL_AudioSpec.userdata', 'SDL.audio.userdata', '*') }}};
+        {{{ makeSetValue('obtained', C_STRUCTS.SDL_AudioSpec.freq, 'SDL.audio.freq', 'i32') }}};
+        {{{ makeSetValue('obtained', C_STRUCTS.SDL_AudioSpec.format, 'SDL.audio.format', 'i16') }}};
+        {{{ makeSetValue('obtained', C_STRUCTS.SDL_AudioSpec.channels, 'SDL.audio.channels', 'i8') }}};
+        {{{ makeSetValue('obtained', C_STRUCTS.SDL_AudioSpec.silence, 'SDL.audio.silence', 'i8') }}};
+        {{{ makeSetValue('obtained', C_STRUCTS.SDL_AudioSpec.samples, 'SDL.audio.samples', 'i16') }}};
+        {{{ makeSetValue('obtained', C_STRUCTS.SDL_AudioSpec.callback, 'SDL.audio.callback', '*') }}};
+        {{{ makeSetValue('obtained', C_STRUCTS.SDL_AudioSpec.userdata, 'SDL.audio.userdata', '*') }}};
       }
       SDL.allocateChannels(32);
 
@@ -1584,13 +1584,13 @@ var LibrarySDL = {
       SDL.audio = null;
       SDL.allocateChannels(0);
       if (obtained) {
-        {{{ makeSetValue('obtained', 'C_STRUCTS.SDL_AudioSpec.freq', 0, 'i32') }}};
-        {{{ makeSetValue('obtained', 'C_STRUCTS.SDL_AudioSpec.format', 0, 'i16') }}};
-        {{{ makeSetValue('obtained', 'C_STRUCTS.SDL_AudioSpec.channels', 0, 'i8') }}};
-        {{{ makeSetValue('obtained', 'C_STRUCTS.SDL_AudioSpec.silence', 0, 'i8') }}};
-        {{{ makeSetValue('obtained', 'C_STRUCTS.SDL_AudioSpec.samples', 0, 'i16') }}};
-        {{{ makeSetValue('obtained', 'C_STRUCTS.SDL_AudioSpec.callback', 0, '*') }}};
-        {{{ makeSetValue('obtained', 'C_STRUCTS.SDL_AudioSpec.userdata', 0, '*') }}};
+        {{{ makeSetValue('obtained', C_STRUCTS.SDL_AudioSpec.freq, 0, 'i32') }}};
+        {{{ makeSetValue('obtained', C_STRUCTS.SDL_AudioSpec.format, 0, 'i16') }}};
+        {{{ makeSetValue('obtained', C_STRUCTS.SDL_AudioSpec.channels, 0, 'i8') }}};
+        {{{ makeSetValue('obtained', C_STRUCTS.SDL_AudioSpec.silence, 0, 'i8') }}};
+        {{{ makeSetValue('obtained', C_STRUCTS.SDL_AudioSpec.samples, 0, 'i16') }}};
+        {{{ makeSetValue('obtained', C_STRUCTS.SDL_AudioSpec.callback, 0, '*') }}};
+        {{{ makeSetValue('obtained', C_STRUCTS.SDL_AudioSpec.userdata, 0, '*') }}};
       }
     }
     if (!SDL.audio) {

From 545f0a7bd6623a744ef4dd5b35da01636dda565e Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Tue, 1 Oct 2013 15:28:11 -0700
Subject: [PATCH 106/165] optimize asm function table emitting

---
 emscripten.py       | 13 ++++++++++---
 src/modules.js      |  8 --------
 tools/asm_module.py |  2 ++
 3 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/emscripten.py b/emscripten.py
index b70f2abb870b1..786370e8873a0 100755
--- a/emscripten.py
+++ b/emscripten.py
@@ -410,6 +410,7 @@ def move_preasm(m):
     simple = os.environ.get('EMCC_SIMPLE_ASM')
     class Counter:
       i = 0
+      j = 0
     pre_tables = last_forwarded_json['Functions']['tables']['pre']
     del last_forwarded_json['Functions']['tables']['pre']
 
@@ -425,12 +426,17 @@ def make_table(sig, raw):
       body = raw[start+1:end].split(',')
       for j in range(settings['RESERVED_FUNCTION_POINTERS']):
         body[2 + 2*j] = 'jsCall_%s_%s' % (sig, j)
+      Counter.j = 0
       def fix_item(item):
-        newline = '\n' in item
-        return (bad if item.replace('\n', '') == '0' else item) + ('\n' if newline else '')
+        Counter.j += 1
+        newline = Counter.j % 30 == 1
+        if item == '0': return bad if not newline else (bad + '\n')
+        return item if not newline else (item + '\n')
       body = ','.join(map(fix_item, body))
-      return ('function %s(%s) { %s %s(%d); %s }' % (bad, params, coercions, 'abort' if not settings['ASSERTIONS'] else 'nullFunc', i, ret), raw[:start+1] + body + raw[end:])
+      return ('function %s(%s) { %s %s(%d); %s }' % (bad, params, coercions, 'abort' if not settings['ASSERTIONS'] else 'nullFunc', i, ret), ''.join([raw[:start+1], body, raw[end:]]))
+
     infos = [make_table(sig, raw) for sig, raw in last_forwarded_json['Functions']['tables'].iteritems()]
+
     function_tables_defs = '\n'.join([info[0] for info in infos]) + '\n// EMSCRIPTEN_END_FUNCS\n' + '\n'.join([info[1] for info in infos])
 
     asm_setup = ''
@@ -470,6 +476,7 @@ def asm_coerce(value, sig):
 
     function_tables = ['dynCall_' + table for table in last_forwarded_json['Functions']['tables']]
     function_tables_impls = []
+
     for sig in last_forwarded_json['Functions']['tables'].iterkeys():
       args = ','.join(['a' + str(i) for i in range(1, len(sig))])
       arg_coercions = ' '.join(['a' + str(i) + '=' + asm_coerce('a' + str(i), sig[i]) + ';' for i in range(1, len(sig))])
diff --git a/src/modules.js b/src/modules.js
index 2757c2cbec2de..9662200c13222 100644
--- a/src/modules.js
+++ b/src/modules.js
@@ -373,14 +373,6 @@ var Functions = {
           }
         }
       }
-      if (table.length > 20) {
-        // add some newlines in the table, for readability
-        var j = 10;
-        while (j+10 < table.length) {
-          table[j] += '\n';
-          j += 10;
-        }
-      }
       maxTable = Math.max(maxTable, table.length);
     }
     if (ASM_JS) maxTable = ceilPowerOfTwo(maxTable);
diff --git a/tools/asm_module.py b/tools/asm_module.py
index 226b66b8d4d8f..f383eba611e1a 100644
--- a/tools/asm_module.py
+++ b/tools/asm_module.py
@@ -248,12 +248,14 @@ def parse_tables(self, js):
   def merge_tables(self, table, main, side, replacements, f_bases, f_sizes):
     sig = table.split('_')[-1]
     side = side[1:-1].split(',')
+    side = map(lambda s: s.strip(), side)
     side = map(lambda f: replacements[f] if f in replacements else f, side)
     if not main:
       f_bases[sig] = 0
       f_sizes[table] = len(side)
       return '[' + ','.join(side) + ']'
     main = main[1:-1].split(',')
+    main = map(lambda m: m.strip(), main)
     # TODO: handle non-aliasing case too
     assert len(main) % 2 == 0
     f_bases[sig] = len(main)

From 812bf5108137accbb808172c2f837847a46db5f9 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Tue, 1 Oct 2013 16:04:58 -0700
Subject: [PATCH 107/165] optimize indexize/blockaddrsize in emscripten.py

---
 emscripten.py | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/emscripten.py b/emscripten.py
index 786370e8873a0..dd67aad7f5e1a 100755
--- a/emscripten.py
+++ b/emscripten.py
@@ -353,17 +353,18 @@ def split_32(x):
     return '%d,%d,%d,%d' % (x&255, (x >> 8)&255, (x >> 16)&255, (x >> 24)&255)
 
   indexing = forwarded_json['Functions']['indexedFunctions']
+  def indexize_mem(js):
+    return re.sub(r"\"?'?{{ FI_([\w\d_$]+) }}'?\"?,0,0,0", lambda m: split_32(indexing.get(m.groups(0)[0]) or 0), js)
   def indexize(js):
-    # In the global initial allocation, we need to split up into Uint8 format
-    ret = re.sub(r"\"?'?{{ FI_([\w\d_$]+) }}'?\"?,0,0,0", lambda m: split_32(indexing.get(m.groups(0)[0]) or 0), js)
-    return re.sub(r"'{{ FI_([\w\d_$]+) }}'", lambda m: str(indexing.get(m.groups(0)[0]) or 0), ret)
+    return re.sub(r"'{{ FI_([\w\d_$]+) }}'", lambda m: str(indexing.get(m.groups(0)[0]) or 0), js)
 
   blockaddrs = forwarded_json['Functions']['blockAddresses']
+  def blockaddrsize_mem(js):
+    return re.sub(r'"?{{{ BA_([\w\d_$]+)\|([\w\d_$]+) }}}"?,0,0,0', lambda m: split_32(blockaddrs[m.groups(0)[0]][m.groups(0)[1]]), js)
   def blockaddrsize(js):
-    ret = re.sub(r'"?{{{ BA_([\w\d_$]+)\|([\w\d_$]+) }}}"?,0,0,0', lambda m: split_32(blockaddrs[m.groups(0)[0]][m.groups(0)[1]]), js)
-    return re.sub(r'"?{{{ BA_([\w\d_$]+)\|([\w\d_$]+) }}}"?', lambda m: str(blockaddrs[m.groups(0)[0]][m.groups(0)[1]]), ret)
+    return re.sub(r'"?{{{ BA_([\w\d_$]+)\|([\w\d_$]+) }}}"?', lambda m: str(blockaddrs[m.groups(0)[0]][m.groups(0)[1]]), js)
 
-  pre = blockaddrsize(indexize(pre))
+  pre = blockaddrsize(blockaddrsize_mem(indexize(indexize_mem(pre))))
 
   if settings.get('ASM_JS'):
     # move postsets into the asm module
@@ -692,7 +693,9 @@ def fix(m):
             symbol_table[value] = str(i)
     outfile.write("var SYMBOL_TABLE = %s;" % json.dumps(symbol_table).replace('"', ''))
 
-  for funcs_js_item in funcs_js: # do this loop carefully to save memory
+  for i in range(len(funcs_js)): # do this loop carefully to save memory
+    funcs_js_item = funcs_js[i]
+    funcs_js[i] = None
     funcs_js_item = indexize(funcs_js_item)
     funcs_js_item = blockaddrsize(funcs_js_item)
     outfile.write(funcs_js_item)

From 352f3f4f10f11ed00b8b0df714ef93b92a271758 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Tue, 1 Oct 2013 20:28:02 -0700
Subject: [PATCH 108/165] make function table emitting nicer

---
 emscripten.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/emscripten.py b/emscripten.py
index dd67aad7f5e1a..a6ff73908c75d 100755
--- a/emscripten.py
+++ b/emscripten.py
@@ -430,7 +430,7 @@ def make_table(sig, raw):
       Counter.j = 0
       def fix_item(item):
         Counter.j += 1
-        newline = Counter.j % 30 == 1
+        newline = Counter.j % 30 == 29
         if item == '0': return bad if not newline else (bad + '\n')
         return item if not newline else (item + '\n')
       body = ','.join(map(fix_item, body))

From 44449f648c8f92c37db87f520c8294e02e822c1c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= 
Date: Wed, 2 Oct 2013 13:14:55 +0300
Subject: [PATCH 109/165] Add -s CASE_INSENSITIVE_FS=1 linker option to allow
 VFS to lookup files in case-insensitive mode.

---
 src/library_fs.js | 14 +++++++++++++-
 src/settings.js   |  2 ++
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/src/library_fs.js b/src/library_fs.js
index c4b29227a22c2..dc5c20f82a36b 100644
--- a/src/library_fs.js
+++ b/src/library_fs.js
@@ -120,6 +120,11 @@ mergeInto(LibraryManager.library, {
     //
     hashName: function(parentid, name) {
       var hash = 0;
+
+#if CASE_INSENSITIVE_FS
+      name = name.toLowerCase();
+#endif
+
       for (var i = 0; i < name.length; i++) {
         hash = ((hash << 5) - hash + name.charCodeAt(i)) | 0;
       }
@@ -151,8 +156,15 @@ mergeInto(LibraryManager.library, {
         throw new FS.ErrnoError(err);
       }
       var hash = FS.hashName(parent.id, name);
+#if CASE_INSENSITIVE_FS
+      name = name.toLowerCase();
+#endif
       for (var node = FS.nameTable[hash]; node; node = node.name_next) {
-        if (node.parent.id === parent.id && node.name === name) {
+        var nodeName = node.name;
+#if CASE_INSENSITIVE_FS
+        nodeName = nodeName.toLowerCase();
+#endif
+        if (node.parent.id === parent.id && nodeName === name) {
           return node;
         }
       }
diff --git a/src/settings.js b/src/settings.js
index 6e2b9e6c003a2..5cf054a9734be 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -266,6 +266,8 @@ var CORRECT_ROUNDINGS = 1; // C rounds to 0 (-5.5 to -5, +5.5 to 5), while JS ha
 var FS_LOG = 0; // Log all FS operations.  This is especially helpful when you're porting
                 // a new project and want to see a list of file system operations happening
                 // so that you can create a virtual file system with all of the required files.
+var CASE_INSENSITIVE_FS = 0; // If set to nonzero, the provided virtual filesystem if treated case-insensitive, like
+                             // Windows and OSX do. If set to 0, the VFS is case-sensitive, like on Linux.
 
 var USE_BSS = 1; // https://en.wikipedia.org/wiki/.bss
                  // When enabled, 0-initialized globals are sorted to the end of the globals list,

From 4faa7bd2204efbaad697250180fb4f324fed34ab Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Wed, 2 Oct 2013 10:57:35 -0700
Subject: [PATCH 110/165] make function pointer aliasing configurable

---
 emscripten.py   | 13 +++++++------
 src/modules.js  |  4 ++--
 src/runtime.js  |  7 ++++---
 src/settings.js |  3 +++
 4 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/emscripten.py b/emscripten.py
index a6ff73908c75d..2b62c93a9d9c0 100755
--- a/emscripten.py
+++ b/emscripten.py
@@ -329,8 +329,9 @@ def load_from_cache(chunk):
 
   # calculations on merged forwarded data
   forwarded_json['Functions']['indexedFunctions'] = {}
-  i = 2 # universal counter
-  if settings['ASM_JS']: i += 2*settings['RESERVED_FUNCTION_POINTERS']
+  i = settings['FUNCTION_POINTER_ALIGNMENT'] # universal counter
+  if settings['ASM_JS']: i += settings['RESERVED_FUNCTION_POINTERS']*settings['FUNCTION_POINTER_ALIGNMENT']
+  base_fp = i
   table_counters = {} # table-specific counters
   alias = settings['ASM_JS'] and settings['ALIASING_FUNCTION_POINTERS']
   sig = None
@@ -339,12 +340,12 @@ def load_from_cache(chunk):
       sig = forwarded_json['Functions']['implementedFunctions'].get(indexed) or forwarded_json['Functions']['unimplementedFunctions'].get(indexed)
       assert sig, indexed
       if sig not in table_counters:
-        table_counters[sig] = 2 + 2*settings['RESERVED_FUNCTION_POINTERS']
+        table_counters[sig] = base_fp
       curr = table_counters[sig]
-      table_counters[sig] += 2
+      table_counters[sig] += settings['FUNCTION_POINTER_ALIGNMENT']
     else:
       curr = i
-      i += 2
+      i += settings['FUNCTION_POINTER_ALIGNMENT']
     #logging.debug('function indexing', indexed, curr, sig)
     forwarded_json['Functions']['indexedFunctions'][indexed] = curr # make sure not to modify this python object later - we use it in indexize
 
@@ -426,7 +427,7 @@ def make_table(sig, raw):
       end = raw.rindex(']')
       body = raw[start+1:end].split(',')
       for j in range(settings['RESERVED_FUNCTION_POINTERS']):
-        body[2 + 2*j] = 'jsCall_%s_%s' % (sig, j)
+        body[settings['FUNCTION_POINTER_ALIGNMENT'] * (1 + j)] = 'jsCall_%s_%s' % (sig, j)
       Counter.j = 0
       def fix_item(item):
         Counter.j += 1
diff --git a/src/modules.js b/src/modules.js
index 9662200c13222..d9888c249fd5b 100644
--- a/src/modules.js
+++ b/src/modules.js
@@ -234,7 +234,7 @@ var Types = {
   preciseI64MathUsed: (PRECISE_I64_MATH == 2)
 };
 
-var firstTableIndex = (ASM_JS ? 2*RESERVED_FUNCTION_POINTERS : 0) + 2;
+var firstTableIndex = FUNCTION_POINTER_ALIGNMENT * ((ASM_JS ? RESERVED_FUNCTION_POINTERS : 0) + 1);
 
 var Functions = {
   // All functions that will be implemented in this file. Maps id to signature
@@ -287,7 +287,7 @@ var Functions = {
       ret = this.indexedFunctions[ident];
       if (!ret) {
         ret = this.nextIndex;
-        this.nextIndex += 2; // Need to have indexes be even numbers, see |polymorph| test
+        this.nextIndex += FUNCTION_POINTER_ALIGNMENT;
         this.indexedFunctions[ident] = ret;
       }
       ret = ret.toString();
diff --git a/src/runtime.js b/src/runtime.js
index 00031fed01852..a281045b7944f 100644
--- a/src/runtime.js
+++ b/src/runtime.js
@@ -347,22 +347,23 @@ var Runtime = {
     for (var i = 0; i < Runtime.functionPointers.length; i++) {
       if (!Runtime.functionPointers[i]) {
         Runtime.functionPointers[i] = func;
-        return 2 + 2*i;
+        return {{{ FUNCTION_POINTER_ALIGNMENT }}}*(1 + i);
       }
     }
     throw 'Finished up all reserved function pointers. Use a higher value for RESERVED_FUNCTION_POINTERS.';
 #else
     var table = FUNCTION_TABLE;
     var ret = table.length;
+    assert(ret % {{{ FUNCTION_POINTER_ALIGNMENT }}} === 0);
     table.push(func);
-    table.push(0);
+    for (var i = 0; i < {{{ FUNCTION_POINTER_ALIGNMENT }}}-1; i++) table.push(0);
     return ret;
 #endif
   },
 
   removeFunction: function(index) {
 #if ASM_JS
-    Runtime.functionPointers[(index-2)/2] = null;
+    Runtime.functionPointers[(index-{{{ FUNCTION_POINTER_ALIGNMENT }}})/{{{ FUNCTION_POINTER_ALIGNMENT }}}] = null;
 #else
     var table = FUNCTION_TABLE;
     table[index] = null;
diff --git a/src/settings.js b/src/settings.js
index 5cf054a9734be..3eb43f1c85669 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -170,6 +170,9 @@ var ALIASING_FUNCTION_POINTERS = 0; // Whether to allow function pointers to ali
                                     // a different type. This can greatly decrease table sizes
                                     // in asm.js, but can break code that compares function
                                     // pointers across different types.
+var FUNCTION_POINTER_ALIGNMENT = 2; // Byte alignment of function pointers - we will fill the
+                                    // tables with zeros on aligned values. 1 means all values
+                                    // are aligned and all will be used (which is optimal).
 
 var ASM_HEAP_LOG = 0; // Simple heap logging, like SAFE_HEAP_LOG but cheaper, and in asm.js
 

From c45334e5d31a6ff642d58ff5dc374e7aa5f51ab8 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Wed, 2 Oct 2013 14:44:47 -0700
Subject: [PATCH 111/165] link in files in autodebugger

---
 emcc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/emcc b/emcc
index c528fb9eaa79a..5049648ae16ed 100755
--- a/emcc
+++ b/emcc
@@ -1239,7 +1239,7 @@ try:
 
   extra_files_to_link = []
 
-  if not LEAVE_INPUTS_RAW and not AUTODEBUG and \
+  if not LEAVE_INPUTS_RAW and \
      not shared.Settings.BUILD_AS_SHARED_LIB == 2 and \
      not shared.Settings.SIDE_MODULE: # shared libraries/side modules link no C libraries, need them in parent
 

From 4f6975f249d2f8eaabe66dd8bee5146cd9d74d28 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Wed, 2 Oct 2013 15:50:01 -0700
Subject: [PATCH 112/165] comment on FUNCTION_POINTER_ALIGNMENT

---
 src/settings.js | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/settings.js b/src/settings.js
index 3eb43f1c85669..7a9e6b7608628 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -173,6 +173,9 @@ var ALIASING_FUNCTION_POINTERS = 0; // Whether to allow function pointers to ali
 var FUNCTION_POINTER_ALIGNMENT = 2; // Byte alignment of function pointers - we will fill the
                                     // tables with zeros on aligned values. 1 means all values
                                     // are aligned and all will be used (which is optimal).
+                                    // Sadly 1 breaks on &Class::method function pointer calls,
+                                    // which llvm assumes have the lower bit zero (see
+                                    // test_polymorph and issue #1692).
 
 var ASM_HEAP_LOG = 0; // Simple heap logging, like SAFE_HEAP_LOG but cheaper, and in asm.js
 

From 4b8ff3fb5dcbc1ef61b17f1d7a7ca4bdb3f0b811 Mon Sep 17 00:00:00 2001
From: Dan Gohman 
Date: Wed, 2 Oct 2013 16:11:34 -0700
Subject: [PATCH 113/165] Optimize alignment rounding.

Replace x>>2<<2 and x>>3<<3 with x&-4 and x&-8, respectively, since
an and is cheaper than two shifts.
---
 emscripten.py   | 2 +-
 src/preamble.js | 2 +-
 src/runtime.js  | 3 +--
 3 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/emscripten.py b/emscripten.py
index 2b62c93a9d9c0..2e90fa48207bd 100755
--- a/emscripten.py
+++ b/emscripten.py
@@ -588,7 +588,7 @@ def math_fix(g):
   var ret = 0;
   ret = STACKTOP;
   STACKTOP = (STACKTOP + size)|0;
-''' + ('STACKTOP = ((STACKTOP + 3)>>2)<<2;' if settings['TARGET_X86'] else 'STACKTOP = ((STACKTOP + 7)>>3)<<3;') + '''
+''' + ('STACKTOP = (STACKTOP + 3)&-4;' if settings['TARGET_X86'] else 'STACKTOP = (STACKTOP + 7)&-8;') + '''
   return ret|0;
 }
 function stackSave() {
diff --git a/src/preamble.js b/src/preamble.js
index 183fd0c8340c6..755190949d723 100644
--- a/src/preamble.js
+++ b/src/preamble.js
@@ -644,7 +644,7 @@ Module['stringToUTF32'] = stringToUTF32;
 
 var PAGE_SIZE = 4096;
 function alignMemoryPage(x) {
-  return ((x+4095)>>12)<<12;
+  return (x+4095)&-4096;
 }
 
 var HEAP;
diff --git a/src/runtime.js b/src/runtime.js
index a281045b7944f..dd3958266ad69 100644
--- a/src/runtime.js
+++ b/src/runtime.js
@@ -112,8 +112,7 @@ var Runtime = {
     if (isNumber(target) && isNumber(quantum)) {
       return Math.ceil(target/quantum)*quantum;
     } else if (isNumber(quantum) && isPowerOfTwo(quantum)) {
-      var logg = log2(quantum);
-      return '((((' +target + ')+' + (quantum-1) + ')>>' + logg + ')<<' + logg + ')';
+      return '(((' +target + ')+' + (quantum-1) + ')&' + -quantum + ')';
     }
     return 'Math.ceil((' + target + ')/' + quantum + ')*' + quantum;
   },

From 16f79a38c4839647314c7f007ea11187954d84c9 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Wed, 2 Oct 2013 16:26:17 -0700
Subject: [PATCH 114/165] error on linkable modules without asm

---
 emcc | 1 +
 1 file changed, 1 insertion(+)

diff --git a/emcc b/emcc
index 5049648ae16ed..d6ba8d9ef0b89 100755
--- a/emcc
+++ b/emcc
@@ -1136,6 +1136,7 @@ try:
 
   if shared.Settings.MAIN_MODULE or shared.Settings.SIDE_MODULE:
     assert not memory_init_file, 'memory init file is not supported with module linking'
+    assert shared.Settings.ASM_JS, 'module linking requires asm.js output (-s ASM_JS=1)'
     shared.Settings.LINKABLE = 1 # TODO: add FORCE_DCE option for the brave people that do want to dce here and in side modules
     debug_level = max(debug_level, 2)
 

From e578be3b375c26c0453070cedf89c42e3ac314a8 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Wed, 2 Oct 2013 17:31:10 -0700
Subject: [PATCH 115/165] align function tables in non-asm mode

---
 src/modules.js | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/src/modules.js b/src/modules.js
index d9888c249fd5b..5b7c06d546668 100644
--- a/src/modules.js
+++ b/src/modules.js
@@ -379,13 +379,11 @@ var Functions = {
     for (var t in tables) {
       if (t == 'pre') continue;
       var table = tables[t];
-      if (ASM_JS) {
-        // asm function table mask must be power of two
-        // if nonaliasing, then standardize function table size, to avoid aliasing pointers through the &M mask (in a small table using a big index)
-        var fullSize = ALIASING_FUNCTION_POINTERS ? ceilPowerOfTwo(table.length) : maxTable;
-        for (var i = table.length; i < fullSize; i++) {
-          table[i] = 0;
-        }
+      // asm function table mask must be power of two, and non-asm must be aligned
+      // if nonaliasing, then standardize function table size, to avoid aliasing pointers through the &M mask (in a small table using a big index)
+      var fullSize = ASM_JS ? (ALIASING_FUNCTION_POINTERS ? ceilPowerOfTwo(table.length) : maxTable) : ((table.length+FUNCTION_POINTER_ALIGNMENT-1)&-FUNCTION_POINTER_ALIGNMENT);
+      for (var i = table.length; i < fullSize; i++) {
+        table[i] = 0;
       }
       // finalize table
       var indices = table.toString().replace('"', '');

From 05de5e01b14562c438bec2d90855326ed8091d92 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Sat, 28 Sep 2013 11:00:18 -0700
Subject: [PATCH 116/165] fix intertype of comparisons' last parameter

---
 src/intertyper.js | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/intertyper.js b/src/intertyper.js
index 07f2020c3290c..baf4c93e12534 100644
--- a/src/intertyper.js
+++ b/src/intertyper.js
@@ -850,6 +850,7 @@ function intertyper(lines, sidePass, baseLineNums) {
       // TODO: also remove 2nd param?
     } else if (item.op in LLVM.COMPS) {
       item.type = 'i1';
+      if (item.params[1].intertype === 'type') item.params[1].intertype = 'value'; // parsed as type, but comparisons have just values there
     }
     if (USE_TYPED_ARRAYS == 2) {
       // Some specific corrections, since 'i64' is special

From 7cca6f256323b05ed58fa2bcd4743bfdc6968fda Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Fri, 27 Sep 2013 22:01:55 -0700
Subject: [PATCH 117/165] fast-path simple icmp

---
 src/intertyper.js | 26 ++++++++++++++++++++++++--
 1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/src/intertyper.js b/src/intertyper.js
index baf4c93e12534..d38b32c7ed70b 100644
--- a/src/intertyper.js
+++ b/src/intertyper.js
@@ -1014,7 +1014,7 @@ function intertyper(lines, sidePass, baseLineNums) {
         noteGlobalVariable(ret);
       }
     } else if (phase === 'funcs') {
-      if (m = /^  (%[\w\d\._]+) = (getelementptr|load) ([%\w\d\._ ,\*\-@]+)$/.exec(line.lineText)) {
+      if (m = /^  (%[\w\d\._]+) = (getelementptr|load|icmp) ([%\w\d\._ ,\*\-@]+)$/.exec(line.lineText)) {
         var assignTo = m[1];
         var intertype = m[2];
         var args = m[3];
@@ -1068,6 +1068,28 @@ function intertyper(lines, sidePass, baseLineNums) {
             }
             break;
           }
+          case 'icmp': {
+            var parts = args.split(' ');
+            assert(parts.length === 4);
+            ret = {
+              intertype: 'mathop',
+              op: 'icmp',
+              variant: parts[0],
+              lineNum: line.lineNum,
+              assignTo: toNiceIdent(assignTo),
+              params: [{
+                intertype: 'value',
+                ident: toNiceIdent(parts[2].substr(0, parts[2].length-1)),
+                type: parts[1]
+              }, {
+                intertype: 'value',
+                ident: toNiceIdent(parts[3]),
+                type: parts[1]
+              }],
+              type: 'i1',
+            };
+            break;
+          }
           default: throw 'unexpected fast path type ' + intertype;
         }
         //else if (line.lineText.indexOf(' = load ') > 0) printErr('close: ' + JSON.stringify(line.lineText));
@@ -1075,7 +1097,7 @@ function intertyper(lines, sidePass, baseLineNums) {
     }
     if (ret) {
       if (COMPILER_ASSERTIONS) {
-        //printErr(['\n', JSON.stringify(ret), '\n', JSON.stringify(triager(tokenizer(line)))]);
+        //printErr(['\n', dump(ret), '\n', dump(triager(tokenizer(line)))]);
         var normal = triager(tokenizer(line));
         delete normal.tokens;
         delete normal.indent;

From eb739e39e2aaeeab9da59132c161ef41c5e4639a Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Sat, 28 Sep 2013 11:06:50 -0700
Subject: [PATCH 118/165] debugging aid

---
 src/intertyper.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/intertyper.js b/src/intertyper.js
index d38b32c7ed70b..8eebd22da9544 100644
--- a/src/intertyper.js
+++ b/src/intertyper.js
@@ -1092,8 +1092,8 @@ function intertyper(lines, sidePass, baseLineNums) {
           }
           default: throw 'unexpected fast path type ' + intertype;
         }
-        //else if (line.lineText.indexOf(' = load ') > 0) printErr('close: ' + JSON.stringify(line.lineText));
       }
+      //else if (line.lineText.indexOf(' = icmp ') > 0) printErr('close: ' + JSON.stringify(line.lineText));
     }
     if (ret) {
       if (COMPILER_ASSERTIONS) {

From e04b4ef520ccf56116fc16401b26c5ad6026bbf4 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Sat, 28 Sep 2013 12:03:21 -0700
Subject: [PATCH 119/165] COMPILER_FASTPATHS option

---
 src/intertyper.js | 13 ++++++++-----
 src/settings.js   |  1 +
 2 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/src/intertyper.js b/src/intertyper.js
index 8eebd22da9544..80fcff383698d 100644
--- a/src/intertyper.js
+++ b/src/intertyper.js
@@ -1110,11 +1110,14 @@ function intertyper(lines, sidePass, baseLineNums) {
   // Input
 
   lineSplitter().forEach(function(line) {
-    var item = tryFastPaths(line);
-    if (item) {
-      finalResults.push(item);
-      fastPaths++;
-      return;
+    var item;
+    if (COMPILER_FASTPATHS) {
+      item = tryFastPaths(line);
+      if (item) {
+        finalResults.push(item);
+        fastPaths++;
+        return;
+      }
     }
     slowPaths++;
 
diff --git a/src/settings.js b/src/settings.js
index 7a9e6b7608628..5e5d50f64e652 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -435,6 +435,7 @@ var EXPORT_NAME = 'Module'; // Global variable to export the module as for envir
                             // loading system (e.g. the browser and SM shell).
 
 var COMPILER_ASSERTIONS = 0; // costly (slow) compile-time assertions
+var COMPILER_FASTPATHS = 1; // use fast-paths to speed up compilation
 
 // Compiler debugging options
 var DEBUG_TAGS_SHOWING = [];

From 892ef7930627ebeb4011ba8a99eade5c425aa926 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Sat, 28 Sep 2013 17:20:22 -0700
Subject: [PATCH 120/165] remove unnecessary whitespace in branches

---
 src/jsifier.js | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/jsifier.js b/src/jsifier.js
index 96cb8d9a3d574..7e793472b7185 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -959,7 +959,7 @@ function JSify(data, functionsOnly, givenFunctions) {
       var parts = label.split('|');
       var trueLabel = parts[1] || '';
       var oldLabel = parts[2] || '';
-      var labelSetting = oldLabel ? 'label = ' + getLabelId(oldLabel) + ';' +
+      var labelSetting = oldLabel ? 'label=' + getLabelId(oldLabel) + ';' +
                          (SHOW_LABELS ? ' /* to: ' + getOriginalLabelId(cleanLabel(oldLabel)) + ' */' : '') : ''; // TODO: optimize away the setting
       if (label[1] == 'R') {
         if (label[2] == 'N') { // BRNOL: break, no label setting
@@ -980,7 +980,7 @@ function JSify(data, functionsOnly, givenFunctions) {
       }
     } else {
       if (!labelIsVariable) label = getLabelId(label);
-      return pre + 'label = ' + label + ';' + (SHOW_LABELS ? ' /* to: ' + getOriginalLabelId(cleanLabel(label)) + ' */' : '') + ' break;';
+      return pre + 'label=' + label + ';' + (SHOW_LABELS ? ' /* to: ' + getOriginalLabelId(cleanLabel(label)) + ' */' : '') + 'break;';
     }
   }
 
@@ -1062,10 +1062,10 @@ function JSify(data, functionsOnly, givenFunctions) {
       var labelTrue = (item.labelTrueJS = getPhiSetsForLabel(phiSets, item.labelTrue)) + makeBranch(item.labelTrue, item.currLabelId);
       var labelFalse = (item.labelFalseJS = getPhiSetsForLabel(phiSets, item.labelFalse)) + makeBranch(item.labelFalse, item.currLabelId);
       if (labelTrue == ';' && labelFalse == ';') return ';';
-      var head = 'if (' + condition + ') { ';
-      var head2 = 'if (!(' + condition + ')) { ';
-      var else_ = ' } else { ';
-      var tail = ' }';
+      var head = 'if(' + condition + '){';
+      var head2 = 'if(!(' + condition + ')){';
+      var else_ = '}else{';
+      var tail = '}';
       if (labelTrue == ';') {
         return head2 + labelFalse + tail;
       } else if (labelFalse == ';') {

From 7b8ec6bc773b59d15435ed80566152b10112913b Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Sat, 28 Sep 2013 17:21:48 -0700
Subject: [PATCH 121/165] remove unnecessary whitespace in while(1)

---
 src/jsifier.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/jsifier.js b/src/jsifier.js
index 7e793472b7185..b20aec316cbaf 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -724,7 +724,7 @@ function JSify(data, functionsOnly, givenFunctions) {
               ret += makeSetValue('setjmpTable', '0', '0', 'i32') + ';'; // initialize first entry to 0
             }
           }
-          ret += indent + 'while(1) ';
+          ret += indent + 'while(1)';
           if (func.setjmpTable && !ASM_JS) {
             ret += 'try { ';
           }

From 08c73e4a03c12cb88748364d870f66c79d638f2d Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Sat, 28 Sep 2013 17:26:47 -0700
Subject: [PATCH 122/165] remove whitespace in mathops

---
 src/parseTools.js | 48 +++++++++++++++++++++++------------------------
 1 file changed, 24 insertions(+), 24 deletions(-)

diff --git a/src/parseTools.js b/src/parseTools.js
index 7ebc0de2b6140..e88cafd66fa55 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -1979,7 +1979,7 @@ function makeComparison(a, op, b, type) {
     return asmCoercion(a, type) + op + asmCoercion(b, type);
   } else {
     assert(type == 'i64');
-    return asmCoercion(a + '$0', 'i32') + op + asmCoercion(b + '$0', 'i32') + ' & ' +
+    return asmCoercion(a + '$0', 'i32') + op + asmCoercion(b + '$0', 'i32') + '&' +
            asmCoercion(a + '$1', 'i32') + op + asmCoercion(b + '$1', 'i32');
   }
 }
@@ -2156,7 +2156,7 @@ function processMathop(item) {
       // If this is in legalization mode, steal the assign and assign into two vars
       if (legalizedI64s) {
         assert(item.assignTo);
-        var ret = 'var ' + item.assignTo + '$0 = ' + result[0] + '; var ' + item.assignTo + '$1 = ' + result[1] + ';';
+        var ret = 'var ' + item.assignTo + '$0=' + result[0] + ';var ' + item.assignTo + '$1=' + result[1] + ';';
         item.assignTo = null;
         return ret;
       } else {
@@ -2307,7 +2307,7 @@ function processMathop(item) {
         dprint('Warning: 64 bit OR - precision limit may be hit on llvm line ' + item.lineNum);
         return 'Runtime.or64(' + idents[0] + ', ' + idents[1] + ')';
       }
-      return idents[0] + ' | ' + idents[1];
+      return idents[0] + '|' + idents[1];
     }
     case 'and': {
       if (bits > 32) {
@@ -2315,7 +2315,7 @@ function processMathop(item) {
         dprint('Warning: 64 bit AND - precision limit may be hit on llvm line ' + item.lineNum);
         return 'Runtime.and64(' + idents[0] + ', ' + idents[1] + ')';
       }
-      return idents[0] + ' & ' + idents[1];
+      return idents[0] + '&' + idents[1];
     }
     case 'xor': {
       if (bits > 32) {
@@ -2323,21 +2323,21 @@ function processMathop(item) {
         dprint('Warning: 64 bit XOR - precision limit may be hit on llvm line ' + item.lineNum);
         return 'Runtime.xor64(' + idents[0] + ', ' + idents[1] + ')';
       }
-      return idents[0] + ' ^ ' + idents[1];
+      return idents[0] + '^' + idents[1];
     }
     case 'shl': {
       if (bits > 32) return idents[0] + '*' + getFastValue(2, 'pow', idents[1]);
-      return idents[0] + ' << ' + idents[1];
+      return idents[0] + '<<' + idents[1];
     }
     case 'ashr': {
       if (bits > 32) return integerizeBignum(idents[0] + '/' + getFastValue(2, 'pow', idents[1]));
-      if (bits === 32) return originalIdents[0] + ' >> ' + idents[1]; // No need to reSign in this case
-      return idents[0] + ' >> ' + idents[1];
+      if (bits === 32) return originalIdents[0] + '>>' + idents[1]; // No need to reSign in this case
+      return idents[0] + '>>' + idents[1];
     }
     case 'lshr': {
       if (bits > 32) return integerizeBignum(idents[0] + '/' + getFastValue(2, 'pow', idents[1]));
-      if (bits === 32) return originalIdents[0] + ' >>> ' + idents[1]; // No need to unSign in this case
-      return idents[0] + ' >>> ' + idents[1];
+      if (bits === 32) return originalIdents[0] + '>>>' + idents[1]; // No need to unSign in this case
+      return idents[0] + '>>>' + idents[1];
     }
     // basic float ops
     case 'fadd': return makeFloat(getFastValue(idents[0], '+', idents[1], item.type), item.type);
@@ -2352,10 +2352,10 @@ function processMathop(item) {
     //       Note that with typed arrays, these become 0 when written. So that is a potential difference with non-typed array runs.
     case 'icmp': {
       switch (variant) {
-        case 'uge': case 'sge': return idents[0] + ' >= ' + idents[1];
-        case 'ule': case 'sle': return idents[0] + ' <= ' + idents[1];
-        case 'ugt': case 'sgt': return idents[0] + ' > ' + idents[1];
-        case 'ult': case 'slt': return idents[0] + ' < ' + idents[1];
+        case 'uge': case 'sge': return idents[0] + '>=' + idents[1];
+        case 'ule': case 'sle': return idents[0] + '<=' + idents[1];
+        case 'ugt': case 'sgt': return idents[0] + '>' + idents[1];
+        case 'ult': case 'slt': return idents[0] + '<' + idents[1];
         // We use loose comparisons, which allows false == 0 to be true, etc. Ditto in fcmp
         case 'ne': case 'eq': {
           // We must sign them, so we do not compare -1 to 255 (could have unsigned them both too)
@@ -2371,14 +2371,14 @@ function processMathop(item) {
       switch (variant) {
         // TODO 'o' ones should be 'ordered (no NaN) and',
         //      'u' ones should be 'unordered or'.
-        case 'uge': case 'oge': return idents[0] + ' >= ' + idents[1];
-        case 'ule': case 'ole': return idents[0] + ' <= ' + idents[1];
-        case 'ugt': case 'ogt': return idents[0] + ' > ' + idents[1];
-        case 'ult': case 'olt': return idents[0] + ' < ' + idents[1];
-        case 'une': case 'one': return idents[0] + ' != ' + idents[1];
-        case 'ueq': case 'oeq': return idents[0] + ' == ' + idents[1];
-        case 'ord': return '!' + makeIsNaN(idents[0]) + ' & !' + makeIsNaN(idents[1]);
-        case 'uno': return makeIsNaN(idents[0]) + ' | ' + makeIsNaN(idents[1]);
+        case 'uge': case 'oge': return idents[0] + '>=' + idents[1];
+        case 'ule': case 'ole': return idents[0] + '<=' + idents[1];
+        case 'ugt': case 'ogt': return idents[0] + '>' + idents[1];
+        case 'ult': case 'olt': return idents[0] + '<' + idents[1];
+        case 'une': case 'one': return idents[0] + '!=' + idents[1];
+        case 'ueq': case 'oeq': return idents[0] + '==' + idents[1];
+        case 'ord': return '!' + makeIsNaN(idents[0]) + '&!' + makeIsNaN(idents[1]);
+        case 'uno': return makeIsNaN(idents[0]) + '|' + makeIsNaN(idents[1]);
         case 'true': return '1';
         default: throw 'Unknown fcmp variant: ' + variant;
       }
@@ -2394,7 +2394,7 @@ function processMathop(item) {
     }
     case 'fpext': case 'sext': return idents[0];
     case 'fptrunc': return idents[0];
-    case 'select': return idents[0] + ' ? ' + asmEnsureFloat(idents[1], item.type) + ' : ' + asmEnsureFloat(idents[2], item.type);
+    case 'select': return idents[0] + '?' + asmEnsureFloat(idents[1], item.type) + ':' + asmEnsureFloat(idents[2], item.type);
     case 'ptrtoint': case 'inttoptr': {
       var ret = '';
       if (QUANTUM_SIZE == 1) {
@@ -2412,7 +2412,7 @@ function processMathop(item) {
       // truncating can change the number, e.g. by truncating to an i1
       // in order to get the first bit
       assert(bitsLeft <= 32, 'Cannot truncate to more than 32 bits, since we use a native & op');
-      return '((' + idents[0] + ') & ' + (Math.pow(2, bitsLeft)-1) + ')';
+      return '((' + idents[0] + ')&' + (Math.pow(2, bitsLeft)-1) + ')';
     }
     case 'bitcast': {
       // Most bitcasts are no-ops for us. However, the exception is int to float and float to int

From 8a6713905050aeb491a83720714942aa7b14c32e Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Sat, 28 Sep 2013 17:32:01 -0700
Subject: [PATCH 123/165] remove whitespace in switch

---
 src/jsifier.js | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/src/jsifier.js b/src/jsifier.js
index b20aec316cbaf..f8fa5b4745ce1 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -1112,7 +1112,7 @@ function JSify(data, functionsOnly, givenFunctions) {
       item.groupedLabels = [];
     }
     if (!useIfs) {
-      ret += 'switch(' + signedIdent + ') {\n';
+      ret += 'switch(' + signedIdent + '){\n';
     }
     // process target labels, sorting them so output is consistently ordered
     keys(targetLabels).sort().forEach(function(targetLabel) {
@@ -1125,17 +1125,17 @@ function JSify(data, functionsOnly, givenFunctions) {
       if (useIfs) {
         value = targetLabels[targetLabel].map(function(value) {
           return makeComparison(signedIdent, '==', makeSignOp(value, item.type, 're'), item.type)
-        }).join(' | ');
-        ret += 'if (' + value + ') {\n';
+        }).join('|');
+        ret += 'if(' + value + '){\n';
       } else {
         value = targetLabels[targetLabel].map(function(value) {
           return 'case ' + makeSignOp(value, item.type, 're') + ':';
-        }).join(' ');
+        }).join('');
         ret += value + '{\n';
       }
       var phiSet = getPhiSetsForLabel(phiSets, targetLabel);
       ret += INDENTATION + '' + phiSet + makeBranch(targetLabel, item.currLabelId || null) + '\n';
-      ret += '}\n';
+      ret += '}';
       if (RELOOP) {
         item.groupedLabels.push({
           label: targetLabel,
@@ -1146,15 +1146,15 @@ function JSify(data, functionsOnly, givenFunctions) {
     });
     var phiSet = item.defaultLabelJS = getPhiSetsForLabel(phiSets, item.defaultLabel);
     if (useIfs) {
-      if (item.switchLabels.length > 0) ret += 'else {\n';
+      if (item.switchLabels.length > 0) ret += 'else{\n';
       ret += phiSet + makeBranch(item.defaultLabel, item.currLabelId) + '\n';
       if (item.switchLabels.length > 0) ret += '}\n';
     } else {
-      ret += 'default: {\n';
+      ret += 'default:{\n';
       ret += phiSet + makeBranch(item.defaultLabel, item.currLabelId) + '\n';
       ret += '}\n';
 
-      ret += '} break; \n'; // finish switch and break, to move control flow properly (breaks from makeBranch just broke out of the switch)
+      ret += '}break;\n'; // finish switch and break, to move control flow properly (breaks from makeBranch just broke out of the switch)
     }
     if (item.value) {
       ret += ' ' + toNiceIdent(item.value);

From 222380118bee0b494560b88ef9c2935d0b2b633e Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Sat, 28 Sep 2013 17:35:44 -0700
Subject: [PATCH 124/165] remove whitespace in assignments

---
 src/jsifier.js | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/src/jsifier.js b/src/jsifier.js
index f8fa5b4745ce1..b0b10a7527a75 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -347,7 +347,7 @@ function JSify(data, functionsOnly, givenFunctions) {
       js += 'if (globalScope) { assert(!globalScope["' + item.ident + '"]); globalScope["' + item.ident + '"] = ' + item.ident + ' }';
     }
     if (item.external && !NAMED_GLOBALS) {
-      js = 'var ' + item.ident + ' = ' + js; // force an explicit naming, even if unnamed globals, for asm forwarding
+      js = 'var ' + item.ident + '=' + js; // force an explicit naming, even if unnamed globals, for asm forwarding
     }
     itemsDict.GlobalVariableStub.push({
       intertype: 'GlobalVariable',
@@ -593,7 +593,7 @@ function JSify(data, functionsOnly, givenFunctions) {
     if (ASM_JS) {
       // spell out argument types
       func.params.forEach(function(param) {
-        func.JS += INDENTATION + param.ident + ' = ' + asmCoercion(param.ident, param.type) + ';\n';
+        func.JS += INDENTATION + param.ident + '=' + asmCoercion(param.ident, param.type) + ';\n';
       });
 
       // spell out local variables
@@ -610,7 +610,7 @@ function JSify(data, functionsOnly, givenFunctions) {
           func.JS += INDENTATION + 'var ' + chunks[i].map(function(v) {
             var type = getImplementationType(v);
             if (!isIllegalType(type) || v.ident.indexOf('$', 1) > 0) { // not illegal, or a broken up illegal
-              return v.ident + ' = ' + asmInitializer(type); //, func.variables[v.ident].impl);
+              return v.ident + '=' + asmInitializer(type); //, func.variables[v.ident].impl);
             } else {
               return range(Math.ceil(getBits(type)/32)).map(function(i) {
                 return v.ident + '$' + i + '= 0';
@@ -654,7 +654,7 @@ function JSify(data, functionsOnly, givenFunctions) {
       if (param.byVal) {
         var type = removePointing(param.type);
         var typeInfo = Types.types[type];
-        func.JS += INDENTATION + (ASM_JS ? '' : 'var ') + 'tempParam = ' + param.ident + '; ' + param.ident + ' = ' + RuntimeGenerator.stackAlloc(typeInfo.flatSize) + ';' +
+        func.JS += INDENTATION + (ASM_JS ? '' : 'var ') + 'tempParam = ' + param.ident + '; ' + param.ident + '=' + RuntimeGenerator.stackAlloc(typeInfo.flatSize) + ';' +
                    makeCopyValues(param.ident, 'tempParam', typeInfo.flatSize, 'null', null, param.byVal) + ';\n';
       }
     });
@@ -1002,7 +1002,7 @@ function JSify(data, functionsOnly, givenFunctions) {
     var labelSets = phiSets[label];
     // FIXME: Many of the |var |s here are not needed, but without them we get slowdowns with closure compiler. TODO: remove this workaround.
     if (labelSets.length == 1) {
-      return (ASM_JS ? '' : 'var ') + labelSets[0].ident + ' = ' + labelSets[0].valueJS + ';';
+      return (ASM_JS ? '' : 'var ') + labelSets[0].ident + '=' + labelSets[0].valueJS + ';';
     }
     // TODO: eliminate unneeded sets (to undefined etc.)
     var deps = {}; // for each ident we will set, which others it depends on
@@ -1028,14 +1028,14 @@ function JSify(data, functionsOnly, givenFunctions) {
       }
       for (var i = 0; i < idents.length; i++) {
         if (keys(deps[idents[i]]).length == 0) {
-          post = 'var ' + idents[i] + ' = ' + valueJSes[idents[i]] + ';' + post;
+          post = 'var ' + idents[i] + '=' + valueJSes[idents[i]] + ';' + post;
           remove(idents[i]);
           continue mainLoop;
         }
       }
       // If we got here, we have circular dependencies, and must break at least one.
-      pre += 'var ' + idents[0] + '$phi = ' + valueJSes[idents[0]] + ';';
-      post += 'var ' + idents[0] + ' = ' + idents[0] + '$phi;';
+      pre += 'var ' + idents[0] + '$phi=' + valueJSes[idents[0]] + ';';
+      post += 'var ' + idents[0] + '=' + idents[0] + '$phi;';
       remove(idents[0]);
     }
     return pre + post;
@@ -1217,11 +1217,11 @@ function JSify(data, functionsOnly, givenFunctions) {
     ret = makeVarArgsCleanup(ret);
 
     if (item.assignTo) {
-      ret = 'var ' + item.assignTo + ' = ' + ret;
+      ret = 'var ' + item.assignTo + '=' + ret;
       if (USE_TYPED_ARRAYS == 2 && isIllegalType(item.type)) {
         var bits = getBits(item.type);
         for (var i = 0; i < bits/32; i++) {
-          ret += 'var ' + item.assignTo + '$' + i + ' = ' + (i == 0 ? item.assignTo : 'tempRet' + (i-1)) + ';'
+          ret += 'var ' + item.assignTo + '$' + i + '=' + (i == 0 ? item.assignTo : 'tempRet' + (i-1)) + ';'
         }
       }
       item.assignTo = null;
@@ -1307,7 +1307,7 @@ function JSify(data, functionsOnly, givenFunctions) {
       item.ident = 'tempValue';
       ret += item.ident + ' = [' + makeEmptyStruct(item.type) + '], ';
     }
-    return ret + item.ident + '.f' + item.indexes[0][0].text + ' = ' + finalizeLLVMParameter(item.value) + ', ' + item.ident + ')';
+    return ret + item.ident + '.f' + item.indexes[0][0].text + '=' + finalizeLLVMParameter(item.value) + ', ' + item.ident + ')';
   }
   function indirectbrHandler(item) {
     var phiSets = calcPhiSets(item);

From 374fbf3909507d8e1a48aaacb8e35d2497c301f7 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Sat, 28 Sep 2013 17:37:35 -0700
Subject: [PATCH 125/165] remove whitespace in misc function stuff

---
 src/jsifier.js | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/jsifier.js b/src/jsifier.js
index b0b10a7527a75..e99cfcdd9ec30 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -584,7 +584,7 @@ function JSify(data, functionsOnly, givenFunctions) {
     
     if (DLOPEN_SUPPORT) Functions.getIndex(func.ident);
 
-    func.JS += 'function ' + func.ident + '(' + paramIdents.join(', ') + ') {\n';
+    func.JS += 'function ' + func.ident + '(' + paramIdents.join(',') + '){\n';
 
     if (PGO) {
       func.JS += INDENTATION + 'PGOMonitor.called["' + func.ident + '"] = 1;\n';
@@ -613,17 +613,17 @@ function JSify(data, functionsOnly, givenFunctions) {
               return v.ident + '=' + asmInitializer(type); //, func.variables[v.ident].impl);
             } else {
               return range(Math.ceil(getBits(type)/32)).map(function(i) {
-                return v.ident + '$' + i + '= 0';
+                return v.ident + '$' + i + '=0';
               }).join(',');
             }
-          }).join(', ') + ';\n';
+          }).join(',') + ';\n';
         }
       }
     }
 
     if (true) { // TODO: optimize away when not needed
       if (CLOSURE_ANNOTATIONS) func.JS += '/** @type {number} */';
-      func.JS += INDENTATION + 'var label = 0;\n';
+      func.JS += INDENTATION + 'var label=0;\n';
     }
 
     if (ASM_JS) {
@@ -632,12 +632,12 @@ function JSify(data, functionsOnly, givenFunctions) {
         hasByVal = hasByVal || param.byVal;
       });
       if (hasByVal) {
-        func.JS += INDENTATION + 'var tempParam = 0;\n';
+        func.JS += INDENTATION + 'var tempParam=0;\n';
       }
     }
 
     if (func.hasVarArgsCall) {
-      func.JS += INDENTATION + 'var tempVarArgs = 0;\n';
+      func.JS += INDENTATION + 'var tempVarArgs=0;\n';
     }
 
     // Prepare the stack, if we need one. If we have other stack allocations, force the stack to be set up.

From be0a1bf511d1b50159baf4601962e9fb51ae98c1 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Sat, 28 Sep 2013 17:40:08 -0700
Subject: [PATCH 126/165] bigger var chunks

---
 src/jsifier.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/jsifier.js b/src/jsifier.js
index e99cfcdd9ec30..070513e117976 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -599,7 +599,7 @@ function JSify(data, functionsOnly, givenFunctions) {
       // spell out local variables
       var vars = values(func.variables).filter(function(v) { return v.origin != 'funcparam' });
       if (vars.length > 0) {
-        var chunkSize = 8;
+        var chunkSize = 20;
         var chunks = [];
         var i = 0;
         while (i < vars.length) {

From d0ec198469a05fa4b8e024af8615fb890b89a471 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Sat, 28 Sep 2013 17:43:39 -0700
Subject: [PATCH 127/165] remove whitespace in stack ops

---
 src/runtime.js | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/src/runtime.js b/src/runtime.js
index dd3958266ad69..e36068c8e323f 100644
--- a/src/runtime.js
+++ b/src/runtime.js
@@ -32,8 +32,8 @@ var RuntimeGenerator = {
 
   stackEnter: function(initial, force) {
     if (initial === 0 && SKIP_STACK_IN_SMALL && !force) return '';
-    var ret = 'var sp  = ' + (ASM_JS ? '0; sp = ' : '') + 'STACKTOP';
-    if (initial > 0) ret += '; STACKTOP = (STACKTOP + ' + initial + ')|0';
+    var ret = 'var sp=' + (ASM_JS ? '0;sp=' : '') + 'STACKTOP';
+    if (initial > 0) ret += ';STACKTOP=(STACKTOP+' + initial + ')|0';
     if (USE_TYPED_ARRAYS == 2) {
       assert(initial % Runtime.STACK_ALIGN == 0);
       if (ASSERTIONS && Runtime.STACK_ALIGN == 4) {
@@ -43,9 +43,6 @@ var RuntimeGenerator = {
     if (ASSERTIONS) {
       ret += '; (assert(' + asmCoercion('(STACKTOP|0) < (STACK_MAX|0)', 'i32') + ')|0)';
     }
-    if (false) {
-      ret += '; _memset(' + asmCoercion('sp', 'i32') + ', 0, ' + initial + ')';
-    }
     return ret;
   },
 
@@ -55,7 +52,7 @@ var RuntimeGenerator = {
     if (SAFE_HEAP) {
       ret += 'var i = sp; while ((i|0) < (STACKTOP|0)) { SAFE_HEAP_CLEAR(i|0); i = (i+1)|0 }';
     }
-    return ret += 'STACKTOP = sp';
+    return ret += 'STACKTOP=sp';
   },
 
   // An allocation that cannot normally be free'd (except through sbrk, which once

From 911c1520b1253dcec525da333c83b0c96dd7038b Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Sat, 28 Sep 2013 17:51:27 -0700
Subject: [PATCH 128/165] remove unnecessary function param coercion parens

---
 src/jsifier.js    | 2 +-
 src/parseTools.js | 5 +++++
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/src/jsifier.js b/src/jsifier.js
index 070513e117976..1116c0d169231 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -593,7 +593,7 @@ function JSify(data, functionsOnly, givenFunctions) {
     if (ASM_JS) {
       // spell out argument types
       func.params.forEach(function(param) {
-        func.JS += INDENTATION + param.ident + '=' + asmCoercion(param.ident, param.type) + ';\n';
+        func.JS += INDENTATION + param.ident + '=' + deParen(asmCoercion(param.ident, param.type)) + ';\n';
       });
 
       // spell out local variables
diff --git a/src/parseTools.js b/src/parseTools.js
index e88cafd66fa55..d749fb0a9f3c9 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -2553,3 +2553,8 @@ function parseAlign(text) { // parse ", align \d+"
   return parseInt(text.substr(8));
 }
 
+function deParen(text) {
+  if (text[0] === '(') return text.substr(1, text.length-2);
+  return text;
+}
+

From 0a3f0f082cb0629c23e82553ceb2c1d56163f2c4 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Sat, 28 Sep 2013 17:55:54 -0700
Subject: [PATCH 129/165] remove whitespace in call args

---
 src/jsifier.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/jsifier.js b/src/jsifier.js
index 1116c0d169231..ce23ca2c16e64 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -1526,7 +1526,7 @@ function JSify(data, functionsOnly, givenFunctions) {
       if (!ASM_JS || functionTableCall) callIdent = Functions.getTable(sig) + '[' + callIdent + ']';
     }
 
-    var ret = callIdent + '(' + args.join(', ') + ')';
+    var ret = callIdent + '(' + args.join(',') + ')';
     if (ASM_JS) { // TODO: do only when needed (library functions and Math.*?) XXX && simpleIdent in Functions.libraryFunctions) {
       ret = asmCoercion(ret, returnType);
       if (simpleIdent == 'abort' && funcData.returnType != 'void') {

From 4ce6bfe5d8cb5d1e4c353b97d0c92a465e9e4217 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Sat, 28 Sep 2013 18:00:09 -0700
Subject: [PATCH 130/165] remove whitespace after switch loop

---
 src/jsifier.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/jsifier.js b/src/jsifier.js
index ce23ca2c16e64..8a6255c36b169 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -728,7 +728,7 @@ function JSify(data, functionsOnly, givenFunctions) {
           if (func.setjmpTable && !ASM_JS) {
             ret += 'try { ';
           }
-          ret += 'switch(' + asmCoercion('label', 'i32') + ') {\n';
+          ret += 'switch(' + asmCoercion('label', 'i32') + '){\n';
           ret += block.labels.map(function(label) {
             return indent + INDENTATION + 'case ' + getLabelId(label.ident) + ': ' + (SHOW_LABELS ? '// ' + getOriginalLabelId(label.ident) : '') + '\n'
                           + getLabelLines(label, indent + INDENTATION + INDENTATION);

From 20bd62695eba37d47d4abdae0bd7c314824291d3 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Sat, 28 Sep 2013 18:18:34 -0700
Subject: [PATCH 131/165] remove inter-function indentation

---
 src/jsifier.js | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/src/jsifier.js b/src/jsifier.js
index 8a6255c36b169..37e047c16b47b 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -665,14 +665,14 @@ function JSify(data, functionsOnly, givenFunctions) {
     function walkBlock(block, indent) {
       if (!block) return '';
       dprint('relooping', 'walking block: ' + block.type + ',' + block.entries + ' : ' + block.labels.length);
-      function getLabelLines(label, indent, relooping) {
+      function getLabelLines(label, relooping) {
         if (!label) return '';
         var ret = '';
         if ((LABEL_DEBUG >= 2) && functionNameFilterTest(func.ident)) {
-          ret += indent + "Module.print(INDENT + '" + func.ident + ":" + label.ident + "');\n";
+          ret += INDENTATION + "Module.print(INDENT + '" + func.ident + ":" + label.ident + "');\n";
         }
         if (EXECUTION_TIMEOUT > 0) {
-          ret += indent + 'if (Date.now() - START_TIME >= ' + (EXECUTION_TIMEOUT*1000) + ') throw "Timed out!" + (new Error().stack);\n';
+          ret += INDENTATION + 'if (Date.now() - START_TIME >= ' + (EXECUTION_TIMEOUT*1000) + ') throw "Timed out!" + (new Error().stack);\n';
         }
         
         if (PRINT_SPLIT_FILE_MARKER && Debugging.on && Debugging.getAssociatedSourceFile(label.lines[label.lines.length-1].lineNum)) {
@@ -699,7 +699,7 @@ function JSify(data, functionsOnly, givenFunctions) {
         })
                                 .join('\n')
                                 .split('\n') // some lines include line breaks
-                                .map(function(line) { return indent + line })
+                                .map(function(line) { return relooping ? line : (INDENTATION + line) })
                                 .join('\n');
       }
       var ret = '';
@@ -730,8 +730,8 @@ function JSify(data, functionsOnly, givenFunctions) {
           }
           ret += 'switch(' + asmCoercion('label', 'i32') + '){\n';
           ret += block.labels.map(function(label) {
-            return indent + INDENTATION + 'case ' + getLabelId(label.ident) + ': ' + (SHOW_LABELS ? '// ' + getOriginalLabelId(label.ident) : '') + '\n'
-                          + getLabelLines(label, indent + INDENTATION + INDENTATION);
+            return INDENTATION + 'case ' + getLabelId(label.ident) + ': ' + (SHOW_LABELS ? '// ' + getOriginalLabelId(label.ident) : '') + '\n'
+                          + getLabelLines(label);
           }).join('\n') + '\n';
           if (func.setjmpTable && ASM_JS) {
             // emit a label in which we write to the proper local variable, before jumping to the actual label
@@ -749,7 +749,7 @@ function JSify(data, functionsOnly, givenFunctions) {
             ret += ' } catch(e) { if (!e.longjmp || !(e.id in mySetjmpIds)) throw(e); setjmpTable[setjmpLabels[e.id]](e.value) }';
           }
         } else {
-          ret += (SHOW_LABELS ? indent + '/* ' + block.entries[0] + ' */' : '') + '\n' + getLabelLines(block.labels[0], indent);
+          ret += (SHOW_LABELS ? indent + '/* ' + block.entries[0] + ' */' : '') + '\n' + getLabelLines(block.labels[0]);
         }
         ret += '\n';
       } else {
@@ -764,7 +764,7 @@ function JSify(data, functionsOnly, givenFunctions) {
         // add blocks
         for (var i = 0; i < block.labels.length; i++) {
           var label = block.labels[i];
-          var content = getLabelLines(label, '', true);
+          var content = getLabelLines(label, true);
           //printErr(func.ident + ' : ' + label.ident + ' : ' + content + '\n');
           var last = label.lines[label.lines.length-1];
           if (!last.signedIdent) {

From e8d37f3b2e5f22ea153ee0b5939777246f48691c Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Sat, 28 Sep 2013 18:31:22 -0700
Subject: [PATCH 132/165] remove newlines from function line results, simplify
 joining them

---
 src/jsifier.js | 46 +++++++++++++++++++++++-----------------------
 1 file changed, 23 insertions(+), 23 deletions(-)

diff --git a/src/jsifier.js b/src/jsifier.js
index 37e047c16b47b..613e7909e55ac 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -685,6 +685,7 @@ function JSify(data, functionsOnly, givenFunctions) {
         var i = 0;
         return ret + label.lines.map(function(line) {
           var JS = line.JS;
+          if (!relooping) JS = INDENTATION + JS;
           if (relooping && i == label.lines.length-1) {
             if (line.intertype == 'branch' || line.intertype == 'switch') {
               JS = ''; // just branching operations - done in the relooper, so nothing need be done here
@@ -695,12 +696,10 @@ function JSify(data, functionsOnly, givenFunctions) {
           i++;
           // invoke instructions span two lines, and the debug info is located
           // on the second line, hence the +1
-          return JS + (Debugging.on ? Debugging.getComment(line.lineNum + (line.intertype === 'invoke' ? 1 : 0)) : '');
-        })
-                                .join('\n')
-                                .split('\n') // some lines include line breaks
-                                .map(function(line) { return relooping ? line : (INDENTATION + line) })
-                                .join('\n');
+          if (Debugging.on) JS += Debugging.getComment(line.lineNum + (line.intertype === 'invoke' ? 1 : 0));
+          //assert(JS.indexOf('\n') < 0, JS);
+          return JS;
+        }).join('\n');
       }
       var ret = '';
       if (!RELOOP || func.forceEmulated) { // TODO: also if just 1 label?
@@ -1112,7 +1111,7 @@ function JSify(data, functionsOnly, givenFunctions) {
       item.groupedLabels = [];
     }
     if (!useIfs) {
-      ret += 'switch(' + signedIdent + '){\n';
+      ret += 'switch(' + signedIdent + '){';
     }
     // process target labels, sorting them so output is consistently ordered
     keys(targetLabels).sort().forEach(function(targetLabel) {
@@ -1126,15 +1125,15 @@ function JSify(data, functionsOnly, givenFunctions) {
         value = targetLabels[targetLabel].map(function(value) {
           return makeComparison(signedIdent, '==', makeSignOp(value, item.type, 're'), item.type)
         }).join('|');
-        ret += 'if(' + value + '){\n';
+        ret += 'if(' + value + '){';
       } else {
         value = targetLabels[targetLabel].map(function(value) {
           return 'case ' + makeSignOp(value, item.type, 're') + ':';
         }).join('');
-        ret += value + '{\n';
+        ret += value + '{';
       }
       var phiSet = getPhiSetsForLabel(phiSets, targetLabel);
-      ret += INDENTATION + '' + phiSet + makeBranch(targetLabel, item.currLabelId || null) + '\n';
+      ret += INDENTATION + '' + phiSet + makeBranch(targetLabel, item.currLabelId || null);
       ret += '}';
       if (RELOOP) {
         item.groupedLabels.push({
@@ -1146,15 +1145,15 @@ function JSify(data, functionsOnly, givenFunctions) {
     });
     var phiSet = item.defaultLabelJS = getPhiSetsForLabel(phiSets, item.defaultLabel);
     if (useIfs) {
-      if (item.switchLabels.length > 0) ret += 'else{\n';
-      ret += phiSet + makeBranch(item.defaultLabel, item.currLabelId) + '\n';
-      if (item.switchLabels.length > 0) ret += '}\n';
+      if (item.switchLabels.length > 0) ret += 'else{';
+      ret += phiSet + makeBranch(item.defaultLabel, item.currLabelId) + '';
+      if (item.switchLabels.length > 0) ret += '}';
     } else {
-      ret += 'default:{\n';
-      ret += phiSet + makeBranch(item.defaultLabel, item.currLabelId) + '\n';
-      ret += '}\n';
+      ret += 'default:{';
+      ret += phiSet + makeBranch(item.defaultLabel, item.currLabelId) + '';
+      ret += '}';
 
-      ret += '}break;\n'; // finish switch and break, to move control flow properly (breaks from makeBranch just broke out of the switch)
+      ret += '}break;'; // finish switch and break, to move control flow properly (breaks from makeBranch just broke out of the switch)
     }
     if (item.value) {
       ret += ' ' + toNiceIdent(item.value);
@@ -1162,10 +1161,11 @@ function JSify(data, functionsOnly, givenFunctions) {
     return ret;
   }
   function returnHandler(item) {
-    var ret = RuntimeGenerator.stackExit(item.funcData.initialStack, item.funcData.otherStackAllocations) + ';\n';
+    var ret = RuntimeGenerator.stackExit(item.funcData.initialStack, item.funcData.otherStackAllocations);
+    if (ret.length > 0) ret += ';';
     if (LABEL_DEBUG && functionNameFilterTest(item.funcData.ident)) {
-      ret += "Module.print(INDENT + 'Exiting: " + item.funcData.ident + "');\n"
-          +  "INDENT = INDENT.substr(0, INDENT.length-2);\n";
+      ret += "Module.print(INDENT + 'Exiting: " + item.funcData.ident + "');"
+          +  "INDENT = INDENT.substr(0, INDENT.length-2);";
     }
     ret += 'return';
     var value = item.value ? finalizeLLVMParameter(item.value) : null;
@@ -1311,9 +1311,9 @@ function JSify(data, functionsOnly, givenFunctions) {
   }
   function indirectbrHandler(item) {
     var phiSets = calcPhiSets(item);
-    var js = 'var ibr = ' + finalizeLLVMParameter(item.value) + ';\n';
+    var js = 'var ibr = ' + finalizeLLVMParameter(item.value) + ';';
     for (var targetLabel in phiSets) {
-      js += 'if (' + makeComparison('ibr', '==', targetLabel, 'i32') + ') { ' + getPhiSetsForLabel(phiSets, targetLabel) + ' }\n';
+      js += 'if (' + makeComparison('ibr', '==', targetLabel, 'i32') + ') { ' + getPhiSetsForLabel(phiSets, targetLabel) + ' }';
     }
     return js + makeBranch('ibr', item.currLabelId, true);
   }
@@ -1537,7 +1537,7 @@ function JSify(data, functionsOnly, givenFunctions) {
     if (ASM_JS && funcData.setjmpTable) {
       // check if a longjmp was done. If a setjmp happened, check if ours. If ours, go to a special label to handle it.
       // otherwise, just return - the call to us must also have been an invoke, so the setjmp propagates that way
-      ret += '; if (((__THREW__|0) != 0) & ((threwValue|0) != 0)) { setjmpLabel = ' + asmCoercion('_testSetjmp(' + makeGetValue('__THREW__', 0, 'i32') + ', setjmpTable)', 'i32') + '; if ((setjmpLabel|0) > 0) { label = ' + SETJMP_LABEL + '; break } else return ' + (funcData.returnType != 'void' ? asmCoercion('0', funcData.returnType) : '') + ' } __THREW__ = threwValue = 0;\n';
+      ret += '; if (((__THREW__|0) != 0) & ((threwValue|0) != 0)) { setjmpLabel = ' + asmCoercion('_testSetjmp(' + makeGetValue('__THREW__', 0, 'i32') + ', setjmpTable)', 'i32') + '; if ((setjmpLabel|0) > 0) { label = ' + SETJMP_LABEL + '; break } else return ' + (funcData.returnType != 'void' ? asmCoercion('0', funcData.returnType) : '') + ' } __THREW__ = threwValue = 0;';
     }
 
     return ret;

From bac7ec61d402fc2a84a1fb6549df5d806e6dd8b9 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Sat, 28 Sep 2013 19:24:11 -0700
Subject: [PATCH 133/165] run 'last' js optimization phase if asm.js, even if
 nothing else to run

---
 emcc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/emcc b/emcc
index d6ba8d9ef0b89..18f38b5c3d0c0 100755
--- a/emcc
+++ b/emcc
@@ -1704,7 +1704,7 @@ try:
     global final, js_optimizer_queue, js_optimizer_extra_info
     if len(js_optimizer_extra_info) == 0:
       js_optimizer_extra_info = None
-    if len(js_optimizer_queue) > 0 and not(len(js_optimizer_queue) == 1 and js_optimizer_queue[0] == 'last'):
+    if len(js_optimizer_queue) > 0 and not(not shared.Settings.ASM_JS and len(js_optimizer_queue) == 1 and js_optimizer_queue[0] == 'last'):
       if DEBUG != '2':
         if shared.Settings.ASM_JS:
           js_optimizer_queue = ['asm'] + js_optimizer_queue

From cd760b5a3b02fc38a95593ef37e864c5aa096de8 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Sat, 28 Sep 2013 20:54:23 -0700
Subject: [PATCH 134/165] add final return in non-relooped asm.js output

---
 src/jsifier.js | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/src/jsifier.js b/src/jsifier.js
index 613e7909e55ac..c51f285458931 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -747,6 +747,14 @@ function JSify(data, functionsOnly, givenFunctions) {
           if (func.setjmpTable && !ASM_JS) {
             ret += ' } catch(e) { if (!e.longjmp || !(e.id in mySetjmpIds)) throw(e); setjmpTable[setjmpLabels[e.id]](e.value) }';
           }
+          if (ASM_JS && func.returnType !== 'void') {
+            // Add a return
+            if (func.returnType in Runtime.FLOAT_TYPES) {
+              ret += ' return +0;\n';
+            } else {
+              ret += ' return 0;\n';
+            }
+          }
         } else {
           ret += (SHOW_LABELS ? indent + '/* ' + block.entries[0] + ' */' : '') + '\n' + getLabelLines(block.labels[0]);
         }

From c41746de750ddea1d69955fd17ee85f06c0aeed1 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Sat, 28 Sep 2013 21:53:15 -0700
Subject: [PATCH 135/165] todo

---
 src/intertyper.js | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/intertyper.js b/src/intertyper.js
index 80fcff383698d..09bdaa33804e9 100644
--- a/src/intertyper.js
+++ b/src/intertyper.js
@@ -1014,6 +1014,7 @@ function intertyper(lines, sidePass, baseLineNums) {
         noteGlobalVariable(ret);
       }
     } else if (phase === 'funcs') {
+      // TODO: (void)call, store
       if (m = /^  (%[\w\d\._]+) = (getelementptr|load|icmp) ([%\w\d\._ ,\*\-@]+)$/.exec(line.lineText)) {
         var assignTo = m[1];
         var intertype = m[2];

From 435f17d4955c75e9ccef3fccd991c0da7756d7f0 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Sun, 29 Sep 2013 12:30:52 -0700
Subject: [PATCH 136/165] chunk label init with the rest

---
 src/jsifier.js    |  7 +++++--
 src/parseTools.js | 15 +++++++++++++++
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/src/jsifier.js b/src/jsifier.js
index c51f285458931..efebab623cf1d 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -537,6 +537,7 @@ function JSify(data, functionsOnly, givenFunctions) {
         default: throw 'what is this line? ' + dump(line);
       }
       assert(line.JS);
+      //assert(line.JS.indexOf('var ') < 0, [line.JS, line.intertype]);
       if (line.assignTo) makeAssign(line);
       Framework.currItem = null;
     });
@@ -596,6 +597,8 @@ function JSify(data, functionsOnly, givenFunctions) {
         func.JS += INDENTATION + param.ident + '=' + deParen(asmCoercion(param.ident, param.type)) + ';\n';
       });
 
+      addVariable('label', 'i32', func);
+
       // spell out local variables
       var vars = values(func.variables).filter(function(v) { return v.origin != 'funcparam' });
       if (vars.length > 0) {
@@ -621,8 +624,8 @@ function JSify(data, functionsOnly, givenFunctions) {
       }
     }
 
-    if (true) { // TODO: optimize away when not needed
-      if (CLOSURE_ANNOTATIONS) func.JS += '/** @type {number} */';
+    if (CLOSURE_ANNOTATIONS) func.JS += '/** @type {number} */';
+    if (!ASM_JS) {
       func.JS += INDENTATION + 'var label=0;\n';
     }
 
diff --git a/src/parseTools.js b/src/parseTools.js
index d749fb0a9f3c9..f60c0cc1c83ba 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -2558,3 +2558,18 @@ function deParen(text) {
   return text;
 }
 
+function addVariable(ident, type, funcData) {
+  funcData = funcData || Framework.currItem.funcData;
+  funcData.variables[ident] = {
+    ident: ident,
+    type: type,
+    origin: 'added',
+    lineNum: 0,
+    rawLinesIndex: 0,
+    hasValueTaken: false,
+    pointingLevels: 0,
+    uses: 0,
+    impl: "native"
+  };
+}
+

From 07b106ef35b0b0f82187c59d80960faf0feb9ab8 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Sun, 29 Sep 2013 12:38:56 -0700
Subject: [PATCH 137/165] register phi variables in function

---
 src/jsifier.js    | 10 ++++++----
 src/parseTools.js |  3 ++-
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/src/jsifier.js b/src/jsifier.js
index efebab623cf1d..78183a35b110c 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -1016,10 +1016,10 @@ function JSify(data, functionsOnly, givenFunctions) {
     }
     // TODO: eliminate unneeded sets (to undefined etc.)
     var deps = {}; // for each ident we will set, which others it depends on
-    var valueJSes = {};
+    var map = {};
     labelSets.forEach(function(labelSet) {
       deps[labelSet.ident] = {};
-      valueJSes[labelSet.ident] = labelSet.valueJS;
+      map[labelSet.ident] = labelSet;
     });
     labelSets.forEach(function(labelSet) {
       walkInterdata(labelSet.value, function mark(item) {
@@ -1038,13 +1038,15 @@ function JSify(data, functionsOnly, givenFunctions) {
       }
       for (var i = 0; i < idents.length; i++) {
         if (keys(deps[idents[i]]).length == 0) {
-          post = 'var ' + idents[i] + '=' + valueJSes[idents[i]] + ';' + post;
+          post = idents[i] + '=' + map[idents[i]].valueJS + ';' + post;
+          if (!ASM_JS) post = 'var ' + post;
+          else addVariable(idents[i], map[idents[i]].value.type);
           remove(idents[i]);
           continue mainLoop;
         }
       }
       // If we got here, we have circular dependencies, and must break at least one.
-      pre += 'var ' + idents[0] + '$phi=' + valueJSes[idents[0]] + ';';
+      pre += 'var ' + idents[0] + '$phi=' + map[idents[0]].valueJS + ';';
       post += 'var ' + idents[0] + '=' + idents[0] + '$phi;';
       remove(idents[0]);
     }
diff --git a/src/parseTools.js b/src/parseTools.js
index f60c0cc1c83ba..8dd6dccf4d590 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -2560,6 +2560,7 @@ function deParen(text) {
 
 function addVariable(ident, type, funcData) {
   funcData = funcData || Framework.currItem.funcData;
+  assert(type);
   funcData.variables[ident] = {
     ident: ident,
     type: type,
@@ -2569,7 +2570,7 @@ function addVariable(ident, type, funcData) {
     hasValueTaken: false,
     pointingLevels: 0,
     uses: 0,
-    impl: "native"
+    impl: VAR_EMULATED
   };
 }
 

From f2965d6c365ccd56d8a3ce935b6ab63fb72ca5ea Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Sun, 29 Sep 2013 14:26:27 -0700
Subject: [PATCH 138/165] assert in normalizeAsm

---
 tools/js-optimizer.js | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js
index e567ebff480e2..51a7bdeb0e696 100644
--- a/tools/js-optimizer.js
+++ b/tools/js-optimizer.js
@@ -1593,6 +1593,7 @@ function normalizeAsm(func) {
         data.vars[name] = detectAsmCoercion(value);
         v.length = 1; // make an un-assigning var
       } else {
+        assert(j === 0, 'cannot break in the middle');
         break outer;
       }
     }

From 1a9b9af1c54afd76649715b1f1c8db358bbcdaeb Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Sun, 29 Sep 2013 14:43:28 -0700
Subject: [PATCH 139/165] add explicit vars for illegal mathops and landingpad

---
 src/jsifier.js    | 24 ++++++++++++------------
 src/parseTools.js | 35 +++++++++++++++++++++++------------
 2 files changed, 35 insertions(+), 24 deletions(-)

diff --git a/src/jsifier.js b/src/jsifier.js
index 78183a35b110c..38261de50815d 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -537,7 +537,7 @@ function JSify(data, functionsOnly, givenFunctions) {
         default: throw 'what is this line? ' + dump(line);
       }
       assert(line.JS);
-      //assert(line.JS.indexOf('var ') < 0, [line.JS, line.intertype]);
+      //if (ASM_JS) assert(line.JS.indexOf('var ') < 0, dump(line));
       if (line.assignTo) makeAssign(line);
       Framework.currItem = null;
     });
@@ -600,7 +600,10 @@ function JSify(data, functionsOnly, givenFunctions) {
       addVariable('label', 'i32', func);
 
       // spell out local variables
-      var vars = values(func.variables).filter(function(v) { return v.origin != 'funcparam' });
+      var vars = values(func.variables).filter(function(v) {
+        return v.origin !== 'funcparam' &&
+               (!isIllegalType(getImplementationType(v)) || v.ident.indexOf('$', 1) > 0); // not illegal, or a broken up illegal (we have illegal chunks explicitly anyhow)
+      });
       if (vars.length > 0) {
         var chunkSize = 20;
         var chunks = [];
@@ -611,14 +614,7 @@ function JSify(data, functionsOnly, givenFunctions) {
         }
         for (i = 0; i < chunks.length; i++) {
           func.JS += INDENTATION + 'var ' + chunks[i].map(function(v) {
-            var type = getImplementationType(v);
-            if (!isIllegalType(type) || v.ident.indexOf('$', 1) > 0) { // not illegal, or a broken up illegal
-              return v.ident + '=' + asmInitializer(type); //, func.variables[v.ident].impl);
-            } else {
-              return range(Math.ceil(getBits(type)/32)).map(function(i) {
-                return v.ident + '$' + i + '=0';
-              }).join(',');
-            }
+            return v.ident + '=' + asmInitializer(getImplementationType(v)); //, func.variables[v.ident].impl);
           }).join(',') + ';\n';
         }
       }
@@ -1265,8 +1261,12 @@ function JSify(data, functionsOnly, givenFunctions) {
     }
   }
   function landingpadHandler(item) {
+    if (ASM_JS) {
+      addVariable(item.assignTo + '$0', 'i32');
+      addVariable(item.assignTo + '$1', 'i32');
+    }
     if (DISABLE_EXCEPTION_CATCHING && !(item.funcData.ident in EXCEPTION_CATCHING_WHITELIST) && USE_TYPED_ARRAYS == 2) {
-      ret = makeVarDef(item.assignTo) + '$0 = 0; ' + item.assignTo + '$1 = 0;';
+      ret = makeVarDef(item.assignTo) + '$0 = 0; ' + makeVarDef(item.assignTo) + '$1 = 0;';
       item.assignTo = null;
       if (VERBOSE) warnOnce('landingpad, but exceptions are disabled!');
       return ret;
@@ -1274,7 +1274,7 @@ function JSify(data, functionsOnly, givenFunctions) {
     var catchTypeArray = item.catchables.map(finalizeLLVMParameter).map(function(element) { return asmCoercion(element, 'i32') }).join(',');
     var ret = asmCoercion('___cxa_find_matching_catch(-1, -1' + (catchTypeArray.length > 0 ? ',' + catchTypeArray : '') +')', 'i32');
     if (USE_TYPED_ARRAYS == 2) {
-      ret = makeVarDef(item.assignTo) + '$0 = ' + ret + '; ' + item.assignTo + '$1 = tempRet0;';
+      ret = makeVarDef(item.assignTo) + '$0 = ' + ret + '; ' + makeVarDef(item.assignTo) + '$1 = tempRet0;';
       item.assignTo = null;
     }
     return ret;
diff --git a/src/parseTools.js b/src/parseTools.js
index 8dd6dccf4d590..863d6bba6c5ad 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -2156,7 +2156,13 @@ function processMathop(item) {
       // If this is in legalization mode, steal the assign and assign into two vars
       if (legalizedI64s) {
         assert(item.assignTo);
-        var ret = 'var ' + item.assignTo + '$0=' + result[0] + ';var ' + item.assignTo + '$1=' + result[1] + ';';
+        if (ASM_JS) {
+          var ret = item.assignTo + '$0=' + result[0] + ';' + item.assignTo + '$1=' + result[1] + ';';
+          addVariable(item.assignTo + '$0', 'i32');
+          addVariable(item.assignTo + '$1', 'i32');
+        } else {
+          var ret = 'var ' + item.assignTo + '$0=' + result[0] + ';var ' + item.assignTo + '$1=' + result[1] + ';';
+        } 
         item.assignTo = null;
         return ret;
       } else {
@@ -2561,16 +2567,21 @@ function deParen(text) {
 function addVariable(ident, type, funcData) {
   funcData = funcData || Framework.currItem.funcData;
   assert(type);
-  funcData.variables[ident] = {
-    ident: ident,
-    type: type,
-    origin: 'added',
-    lineNum: 0,
-    rawLinesIndex: 0,
-    hasValueTaken: false,
-    pointingLevels: 0,
-    uses: 0,
-    impl: VAR_EMULATED
-  };
+  var old = funcData.variables[ident];
+  if (old) {
+    assert(old.type === type);
+  } else {
+    funcData.variables[ident] = {
+      ident: ident,
+      type: type,
+      origin: 'added',
+      lineNum: 0,
+      rawLinesIndex: 0,
+      hasValueTaken: false,
+      pointingLevels: 0,
+      uses: 0,
+      impl: VAR_EMULATED
+    };
+  }
 }
 

From 97891d0db52844f5e64a7048674aca9258545db8 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Sun, 29 Sep 2013 14:46:57 -0700
Subject: [PATCH 140/165] add explicit vars for phi dependency breaks

---
 src/jsifier.js | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/jsifier.js b/src/jsifier.js
index 38261de50815d..3a5995780c217 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -1042,8 +1042,10 @@ function JSify(data, functionsOnly, givenFunctions) {
         }
       }
       // If we got here, we have circular dependencies, and must break at least one.
-      pre += 'var ' + idents[0] + '$phi=' + map[idents[0]].valueJS + ';';
-      post += 'var ' + idents[0] + '=' + idents[0] + '$phi;';
+      pre += makeVarDef(idents[0]) + '$phi=' + map[idents[0]].valueJS + ';';
+      post += makeVarDef(idents[0]) + '=' + idents[0] + '$phi;';
+      addVariable(idents[0] + '$phi', map[idents[0]].value.type);
+      addVariable(idents[0], map[idents[0]].value.type);
       remove(idents[0]);
     }
     return pre + post;

From f97e5ca780105ec07aa60124aff1ceec56d9ca4a Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Sun, 29 Sep 2013 15:39:35 -0700
Subject: [PATCH 141/165] add explicit variable for invoke chunks

---
 src/jsifier.js | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/src/jsifier.js b/src/jsifier.js
index 3a5995780c217..223a65512b1eb 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -1228,11 +1228,16 @@ function JSify(data, functionsOnly, givenFunctions) {
     ret = makeVarArgsCleanup(ret);
 
     if (item.assignTo) {
-      ret = 'var ' + item.assignTo + '=' + ret;
-      if (USE_TYPED_ARRAYS == 2 && isIllegalType(item.type)) {
+      var illegal = USE_TYPED_ARRAYS == 2 && isIllegalType(item.type);
+      var assignTo = illegal ? item.assignTo + '$r' : item.assignTo;
+      ret = makeVarDef(assignTo) + '=' + ret;
+      if (ASM_JS) addVariable(assignTo, item.type);
+      if (illegal) {
         var bits = getBits(item.type);
         for (var i = 0; i < bits/32; i++) {
-          ret += 'var ' + item.assignTo + '$' + i + '=' + (i == 0 ? item.assignTo : 'tempRet' + (i-1)) + ';'
+          var v = item.assignTo + '$' + i;
+          ret += makeVarDef(v) + '=' + (i == 0 ? assignTo : 'tempRet' + (i-1)) + ';'
+          if (ASM_JS) addVariable(v, 'i32');
         }
       }
       item.assignTo = null;

From e7515cbf708b6a402a190de9eb3775f19ee2272e Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Sun, 29 Sep 2013 16:11:32 -0700
Subject: [PATCH 142/165] add explicit var to indirectbr

---
 src/jsifier.js | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/jsifier.js b/src/jsifier.js
index 223a65512b1eb..f9f1d9225113b 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -1331,9 +1331,10 @@ function JSify(data, functionsOnly, givenFunctions) {
   }
   function indirectbrHandler(item) {
     var phiSets = calcPhiSets(item);
-    var js = 'var ibr = ' + finalizeLLVMParameter(item.value) + ';';
+    var js = makeVarDef('ibr') + '=' + finalizeLLVMParameter(item.value) + ';';
+    if (ASM_JS) addVariable('ibr', 'i32');
     for (var targetLabel in phiSets) {
-      js += 'if (' + makeComparison('ibr', '==', targetLabel, 'i32') + ') { ' + getPhiSetsForLabel(phiSets, targetLabel) + ' }';
+      js += 'if(' + makeComparison('ibr', '==', targetLabel, 'i32') + '){' + getPhiSetsForLabel(phiSets, targetLabel) + '}';
     }
     return js + makeBranch('ibr', item.currLabelId, true);
   }

From 42dde1ea07e2f8cb2c1dec48f7bee4318b39dc2f Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Sun, 29 Sep 2013 16:21:24 -0700
Subject: [PATCH 143/165] define legalized bitshift vars explicitly

---
 src/analyzer.js | 5 +++--
 src/jsifier.js  | 5 +++++
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/src/analyzer.js b/src/analyzer.js
index 3fb20253b7f60..17ad26adfad8a 100644
--- a/src/analyzer.js
+++ b/src/analyzer.js
@@ -783,13 +783,14 @@ function analyzer(data, sidePass) {
                   assert(PRECISE_I64_MATH, 'Must have precise i64 math for non-constant 64-bit shifts');
                   Types.preciseI64MathUsed = 1;
                   value.intertype = 'value';
-                  value.ident = 'var ' + value.assignTo + '$0 = ' +
+                  value.ident = makeVarDef(value.assignTo) + '$0=' +
                       asmCoercion('_bitshift64' + value.op[0].toUpperCase() + value.op.substr(1) + '(' + 
                         asmCoercion(sourceElements[0].ident, 'i32') + ',' +
                         asmCoercion(sourceElements[1].ident, 'i32') + ',' +
                         asmCoercion(value.params[1].ident + '$0', 'i32') + ')', 'i32'
                       ) + ';' +
-                      'var ' + value.assignTo + '$1 = tempRet0;';
+                      makeVarDef(value.assignTo) + '$1=tempRet0;';
+                  value.vars = [[value.assignTo + '$0', 'i32'], [value.assignTo + '$1', 'i32']];
                   value.assignTo = null;
                   i++;
                   continue;
diff --git a/src/jsifier.js b/src/jsifier.js
index f9f1d9225113b..8e329f8c77589 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -904,6 +904,11 @@ function JSify(data, functionsOnly, givenFunctions) {
 
   // Function lines
   function valueHandler(item) {
+    if (item.vars) {
+      item.vars.forEach(function(v) {
+        addVariable(v[0], v[1]);
+      });
+    }
     return item.ident;
   }
   function noopHandler(item) {

From d229313b7dc08e40a160ace49a38acd5be5503b3 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Sun, 29 Sep 2013 16:50:14 -0700
Subject: [PATCH 144/165] if not running js opts, ensure a . in asmEnsureFloat
 immediately

---
 emcc              |  3 +++
 src/parseTools.js | 17 +++++++++++++++--
 src/settings.js   |  2 ++
 3 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/emcc b/emcc
index 18f38b5c3d0c0..7ae19866dda0c 100755
--- a/emcc
+++ b/emcc
@@ -1161,6 +1161,9 @@ try:
   if proxy_to_worker:
     shared.Settings.PROXY_TO_WORKER = 1
 
+  if js_opts:
+    shared.Settings.RUNNING_JS_OPTS = 1
+
   ## Compile source code to bitcode
 
   logging.debug('compiling to bitcode')
diff --git a/src/parseTools.js b/src/parseTools.js
index 863d6bba6c5ad..7e7a8307aae6e 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -1136,7 +1136,16 @@ function asmEnsureFloat(value, type) { // ensures that a float type has either 5
   if (!ASM_JS) return value;
   // coerce if missing a '.', or if smaller than 1, so could be 1e-5 which has no .
   if (type in Runtime.FLOAT_TYPES && isNumber(value) && (value.toString().indexOf('.') < 0 || Math.abs(value) < 1)) {
-    return '(+(' + value + '))';
+    if (RUNNING_JS_OPTS) {
+      return '(+' + value + ')'; // JS optimizer will run, we must do +x, and it will be corrected later
+    } else {
+      // ensure a .
+      value = value.toString();
+      if (value.indexOf('.') >= 0) return value;
+      var e = value.indexOf('e');
+      if (e < 0) return value + '.0';
+      return value.substr(0, e) + '.0' + value.substr(e);
+    }
   } else {
     return value;
   }
@@ -1144,7 +1153,11 @@ function asmEnsureFloat(value, type) { // ensures that a float type has either 5
 
 function asmInitializer(type, impl) {
   if (type in Runtime.FLOAT_TYPES) {
-    return '+0';
+    if (RUNNING_JS_OPTS) {
+      return '+0';
+    } else {
+      return '.0';
+    }
   } else {
     return '0';
   }
diff --git a/src/settings.js b/src/settings.js
index 5e5d50f64e652..6894b53559055 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -434,6 +434,8 @@ var JS_CHUNK_SIZE = 10240; // Used as a maximum size before breaking up expressi
 var EXPORT_NAME = 'Module'; // Global variable to export the module as for environments without a standardized module
                             // loading system (e.g. the browser and SM shell).
 
+var RUNNING_JS_OPTS = 0; // whether js opts will be run, after the main compiler
+
 var COMPILER_ASSERTIONS = 0; // costly (slow) compile-time assertions
 var COMPILER_FASTPATHS = 1; // use fast-paths to speed up compilation
 

From 6e8ba9140b706ed30977e083f6d25c05af08076e Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Sun, 29 Sep 2013 18:14:35 -0700
Subject: [PATCH 145/165] optimize Math.x to Math_x

---
 src/fastLong.js       |  12 ++---
 src/jsifier.js        |   4 +-
 src/library.js        | 104 +++++++++++++++++++++---------------------
 src/modules.js        |   2 +-
 src/parseTools.js     |  20 ++++----
 src/preamble.js       |  17 +++++++
 tools/js-optimizer.js |   6 ---
 7 files changed, 88 insertions(+), 77 deletions(-)

diff --git a/src/fastLong.js b/src/fastLong.js
index 4f6efd9fdd6fe..2b70b2fb90be2 100644
--- a/src/fastLong.js
+++ b/src/fastLong.js
@@ -5,12 +5,12 @@ function ___muldsi3($a, $b) {
   var $1 = 0, $2 = 0, $3 = 0, $6 = 0, $8 = 0, $11 = 0, $12 = 0;
   $1 = $a & 65535;
   $2 = $b & 65535;
-  $3 = Math.imul($2, $1) | 0;
+  $3 = Math_imul($2, $1) | 0;
   $6 = $a >>> 16;
-  $8 = ($3 >>> 16) + (Math.imul($2, $6) | 0) | 0;
+  $8 = ($3 >>> 16) + (Math_imul($2, $6) | 0) | 0;
   $11 = $b >>> 16;
-  $12 = Math.imul($11, $1) | 0;
-  return (tempRet0 = (($8 >>> 16) + (Math.imul($11, $6) | 0) | 0) + ((($8 & 65535) + $12 | 0) >>> 16) | 0, 0 | ($8 + $12 << 16 | $3 & 65535)) | 0;
+  $12 = Math_imul($11, $1) | 0;
+  return (tempRet0 = (($8 >>> 16) + (Math_imul($11, $6) | 0) | 0) + ((($8 & 65535) + $12 | 0) >>> 16) | 0, 0 | ($8 + $12 << 16 | $3 & 65535)) | 0;
 }
 function ___divdi3($a$0, $a$1, $b$0, $b$1) {
   $a$0 = $a$0 | 0;
@@ -63,8 +63,8 @@ function ___muldi3($a$0, $a$1, $b$0, $b$1) {
   $y_sroa_0_0_extract_trunc = $b$0;
   $1$0 = ___muldsi3($x_sroa_0_0_extract_trunc, $y_sroa_0_0_extract_trunc) | 0;
   $1$1 = tempRet0;
-  $2 = Math.imul($a$1, $y_sroa_0_0_extract_trunc) | 0;
-  return (tempRet0 = ((Math.imul($b$1, $x_sroa_0_0_extract_trunc) | 0) + $2 | 0) + $1$1 | $1$1 & 0, 0 | $1$0 & -1) | 0;
+  $2 = Math_imul($a$1, $y_sroa_0_0_extract_trunc) | 0;
+  return (tempRet0 = ((Math_imul($b$1, $x_sroa_0_0_extract_trunc) | 0) + $2 | 0) + $1$1 | $1$1 & 0, 0 | $1$0 & -1) | 0;
 }
 function ___udivdi3($a$0, $a$1, $b$0, $b$1) {
   $a$0 = $a$0 | 0;
diff --git a/src/jsifier.js b/src/jsifier.js
index 8e329f8c77589..acbcf582dccd4 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -418,7 +418,7 @@ function JSify(data, functionsOnly, givenFunctions) {
         }
         // In asm, we need to know about library functions. If there is a target, though, then no
         // need to consider this a library function - we will call directly to it anyhow
-        if (ASM_JS && !redirectedIdent && (typeof target == 'function' || /Math\.\w+/.exec(snippet))) {
+        if (ASM_JS && !redirectedIdent && (typeof target == 'function' || /Math_\w+/.exec(snippet))) {
           Functions.libraryFunctions[ident] = 1;
         }
       } else if (typeof snippet === 'object') {
@@ -1394,7 +1394,7 @@ function JSify(data, functionsOnly, givenFunctions) {
       var callIdent = LibraryManager.getRootIdent(simpleIdent);
       if (callIdent) {
         simpleIdent = callIdent; // ident may not be in library, if all there is is ident__inline, but in this case it is
-        if (callIdent.indexOf('.') < 0) {
+        if (callIdent.indexOf('Math_') !== 0) {
           callIdent = '_' + callIdent; // Not Math.*, so add the normal prefix
         }
       } else {
diff --git a/src/library.js b/src/library.js
index 3e69cc0875078..b8f5802a9fd63 100644
--- a/src/library.js
+++ b/src/library.js
@@ -3008,8 +3008,8 @@ LibraryManager.library = {
     return ret;
   },
 
-  abs: 'Math.abs',
-  labs: 'Math.abs',
+  abs: 'Math_abs',
+  labs: 'Math_abs',
 #if USE_TYPED_ARRAYS == 2
   llabs__deps: [function() { Types.preciseI64MathUsed = 1 }],
   llabs: function(lo, hi) {
@@ -4702,30 +4702,30 @@ LibraryManager.library = {
   // math.h
   // ==========================================================================
 
-  cos: 'Math.cos',
-  cosf: 'Math.cos',
-  cosl: 'Math.cos',
-  sin: 'Math.sin',
-  sinf: 'Math.sin',
-  sinl: 'Math.sin',
-  tan: 'Math.tan',
-  tanf: 'Math.tan',
-  tanl: 'Math.tan',
-  acos: 'Math.acos',
-  acosf: 'Math.acos',
-  acosl: 'Math.acos',
-  asin: 'Math.asin',
-  asinf: 'Math.asin',
-  asinl: 'Math.asin',
-  atan: 'Math.atan',
-  atanf: 'Math.atan',
-  atanl: 'Math.atan',
-  atan2: 'Math.atan2',
-  atan2f: 'Math.atan2',
-  atan2l: 'Math.atan2',
-  exp: 'Math.exp',
-  expf: 'Math.exp',
-  expl: 'Math.exp',
+  cos: 'Math_cos',
+  cosf: 'Math_cos',
+  cosl: 'Math_cos',
+  sin: 'Math_sin',
+  sinf: 'Math_sin',
+  sinl: 'Math_sin',
+  tan: 'Math_tan',
+  tanf: 'Math_tan',
+  tanl: 'Math_tan',
+  acos: 'Math_acos',
+  acosf: 'Math_acos',
+  acosl: 'Math_acos',
+  asin: 'Math_asin',
+  asinf: 'Math_asin',
+  asinl: 'Math_asin',
+  atan: 'Math_atan',
+  atanf: 'Math_atan',
+  atanl: 'Math_atan',
+  atan2: 'Math_atan2',
+  atan2f: 'Math_atan2',
+  atan2l: 'Math_atan2',
+  exp: 'Math_exp',
+  expf: 'Math_exp',
+  expl: 'Math_exp',
 
   // The erf and erfc functions are inspired from
   // http://www.digitalmars.com/archives/cplusplus/3634.html
@@ -4787,32 +4787,32 @@ LibraryManager.library = {
   },
   erff: 'erf',
   erfl: 'erf',
-  log: 'Math.log',
-  logf: 'Math.log',
-  logl: 'Math.log',
-  sqrt: 'Math.sqrt',
-  sqrtf: 'Math.sqrt',
-  sqrtl: 'Math.sqrt',
-  fabs: 'Math.abs',
-  fabsf: 'Math.abs',
-  fabsl: 'Math.abs',
-  ceil: 'Math.ceil',
-  ceilf: 'Math.ceil',
-  ceill: 'Math.ceil',
-  floor: 'Math.floor',
-  floorf: 'Math.floor',
-  floorl: 'Math.floor',
-  pow: 'Math.pow',
-  powf: 'Math.pow',
-  powl: 'Math.pow',
-  llvm_sqrt_f32: 'Math.sqrt',
-  llvm_sqrt_f64: 'Math.sqrt',
-  llvm_pow_f32: 'Math.pow',
-  llvm_pow_f64: 'Math.pow',
-  llvm_log_f32: 'Math.log',
-  llvm_log_f64: 'Math.log',
-  llvm_exp_f32: 'Math.exp',
-  llvm_exp_f64: 'Math.exp',
+  log: 'Math_log',
+  logf: 'Math_log',
+  logl: 'Math_log',
+  sqrt: 'Math_sqrt',
+  sqrtf: 'Math_sqrt',
+  sqrtl: 'Math_sqrt',
+  fabs: 'Math_abs',
+  fabsf: 'Math_abs',
+  fabsl: 'Math_abs',
+  ceil: 'Math_ceil',
+  ceilf: 'Math_ceil',
+  ceill: 'Math_ceil',
+  floor: 'Math_floor',
+  floorf: 'Math_floor',
+  floorl: 'Math_floor',
+  pow: 'Math_pow',
+  powf: 'Math_pow',
+  powl: 'Math_pow',
+  llvm_sqrt_f32: 'Math_sqrt',
+  llvm_sqrt_f64: 'Math_sqrt',
+  llvm_pow_f32: 'Math_pow',
+  llvm_pow_f64: 'Math_pow',
+  llvm_log_f32: 'Math_log',
+  llvm_log_f64: 'Math_log',
+  llvm_exp_f32: 'Math_exp',
+  llvm_exp_f64: 'Math_exp',
   ldexp: function(x, exp_) {
     return x * Math.pow(2, exp_);
   },
diff --git a/src/modules.js b/src/modules.js
index 5b7c06d546668..cc9ca549ae227 100644
--- a/src/modules.js
+++ b/src/modules.js
@@ -340,7 +340,7 @@ var Functions = {
         if (table[i]) {
           var libName = LibraryManager.getRootIdent(table[i].substr(1));
           if (libName && typeof libName == 'string') {
-            table[i] = (libName.indexOf('.') < 0 ? '_' : '') + libName;
+            table[i] = (libName.indexOf('Math_') < 0 ? '_' : '') + libName;
           }
         }
         if (ASM_JS) {
diff --git a/src/parseTools.js b/src/parseTools.js
index 7e7a8307aae6e..4966417096332 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -763,10 +763,10 @@ function splitI64(value, floatConversion) {
   if (floatConversion && ASM_JS) lowInput = asmFloatToInt(lowInput);
   var low = lowInput + '>>>0';
   var high = makeInlineCalculation(
-    asmCoercion('Math.abs(VALUE)', 'double') + ' >= ' + asmEnsureFloat('1', 'double') + ' ? ' +
+    asmCoercion('Math_abs(VALUE)', 'double') + ' >= ' + asmEnsureFloat('1', 'double') + ' ? ' +
       '(VALUE > ' + asmEnsureFloat('0', 'double') + ' ? ' +
-               asmCoercion('Math.min(' + asmCoercion('Math.floor((VALUE)/' + asmEnsureFloat(4294967296, 'float') + ')', 'double') + ', ' + asmEnsureFloat(4294967295, 'float') + ')', 'i32') + '>>>0' +
-               ' : ' + asmFloatToInt(asmCoercion('Math.ceil((VALUE - +((' + asmFloatToInt('VALUE') + ')>>>0))/' + asmEnsureFloat(4294967296, 'float') + ')', 'double')) + '>>>0' + 
+               asmCoercion('Math_min(' + asmCoercion('Math_floor((VALUE)/' + asmEnsureFloat(4294967296, 'float') + ')', 'double') + ', ' + asmEnsureFloat(4294967295, 'float') + ')', 'i32') + '>>>0' +
+               ' : ' + asmFloatToInt(asmCoercion('Math_ceil((VALUE - +((' + asmFloatToInt('VALUE') + ')>>>0))/' + asmEnsureFloat(4294967296, 'float') + ')', 'double')) + '>>>0' + 
       ')' +
     ' : 0',
     value,
@@ -1532,7 +1532,7 @@ function getFastValue(a, op, b, type) {
     if (a === '2' && isIntImplemented(type)) {
       return '(1 << (' + b + '))';
     }
-    return 'Math.pow(' + a + ', ' + b + ')';
+    return 'Math_pow(' + a + ', ' + b + ')';
   }
   if ((op === '+' || op === '*') && aNumber !== null) { // if one of them is a number, keep it last
     var c = b;
@@ -1564,7 +1564,7 @@ function getFastValue(a, op, b, type) {
       if ((aNumber !== null && Math.abs(a) < TWO_TWENTY) || (bNumber !== null && Math.abs(b) < TWO_TWENTY) || (bits < 32 && !ASM_JS)) {
         return '(((' + a + ')*(' + b + '))&' + ((Math.pow(2, bits)-1)|0) + ')'; // keep a non-eliminatable coercion directly on this
       }
-      return '(Math.imul(' + a + ',' + b + ')|0)';
+      return '(Math_imul(' + a + ',' + b + ')|0)';
     }
   } else if (op === '/') {
     if (a === '0' && !(type in Runtime.FLOAT_TYPES)) { // careful on floats, since 0*NaN is not 0
@@ -2060,12 +2060,12 @@ function makeRounding(value, bits, signed, floatConversion) {
                                                              // as |0, but &-1 hints to the js optimizer that this is a rounding correction
     // Do Math.floor, which is reasonably fast, if we either don't care, or if we can be sure
     // the value is non-negative
-    if (!correctRoundings() || (!signed && !floatConversion)) return 'Math.floor(' + value + ')';
+    if (!correctRoundings() || (!signed && !floatConversion)) return 'Math_floor(' + value + ')';
     // We are left with >32 bits signed, or a float conversion. Check and correct inline
     // Note that if converting a float, we may have the wrong sign at this point! But, we have
     // been rounded properly regardless, and we will be sign-corrected later when actually used, if
     // necessary.
-    return makeInlineCalculation(makeComparison('VALUE', '>=', '0', 'float') + ' ? Math.floor(VALUE) : Math.ceil(VALUE)', value, 'tempBigIntR');
+    return makeInlineCalculation(makeComparison('VALUE', '>=', '0', 'float') + ' ? Math_floor(VALUE) : Math_ceil(VALUE)', value, 'tempBigIntR');
   } else {
     // asm.js mode, cleaner refactoring of this function as well. TODO: use in non-asm case, most of this
     if (floatConversion && bits <= 32) {
@@ -2080,9 +2080,9 @@ function makeRounding(value, bits, signed, floatConversion) {
       }
     }
     // Math.floor is reasonably fast if we don't care about corrections (and even correct if unsigned)
-    if (!correctRoundings() || !signed) return 'Math.floor(' + value + ')';
+    if (!correctRoundings() || !signed) return 'Math_floor(' + value + ')';
     // We are left with >32 bits
-    return makeInlineCalculation(makeComparison('VALUE', '>=', '0', 'float') + ' ? Math.floor(VALUE) : Math.ceil(VALUE)', value, 'tempBigIntR');
+    return makeInlineCalculation(makeComparison('VALUE', '>=', '0', 'float') + ' ? Math_floor(VALUE) : Math_ceil(VALUE)', value, 'tempBigIntR');
   }
 }
 
@@ -2093,7 +2093,7 @@ function makeIsNaN(value) {
 
 function makeFloat(value, type) {
   if (TO_FLOAT32 && type == 'float') {
-    return 'Math.toFloat32(' + value + ')';
+    return 'Math_toFloat32(' + value + ')';
   }
   return value;
 }
diff --git a/src/preamble.js b/src/preamble.js
index 755190949d723..d094b071b5ebd 100644
--- a/src/preamble.js
+++ b/src/preamble.js
@@ -943,6 +943,23 @@ if (!Math['toFloat32']) Math['toFloat32'] = function(x) {
 Math.toFloat32 = Math['toFloat32'];
 #endif
 
+var Math_abs = Math.abs;
+var Math_cos = Math.cos;
+var Math_sin = Math.sin;
+var Math_tan = Math.tan;
+var Math_acos = Math.acos;
+var Math_asin = Math.asin;
+var Math_atan = Math.atan;
+var Math_atan2 = Math.atan2;
+var Math_exp = Math.exp;
+var Math_log = Math.log;
+var Math_sqrt = Math.sqrt;
+var Math_ceil = Math.ceil;
+var Math_floor = Math.floor;
+var Math_pow = Math.pow;
+var Math_imul = Math.imul;
+var Math_toFloat32 = Math.toFloat32;
+
 // A counter of dependencies for calling run(). If we need to
 // do asynchronous work before running, increment this and
 // decrement it. Incrementing must happen in a place like
diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js
index 51a7bdeb0e696..59e3919fcb6d5 100644
--- a/tools/js-optimizer.js
+++ b/tools/js-optimizer.js
@@ -1617,12 +1617,6 @@ function normalizeAsm(func) {
           }
         }
         unVarify(node[1], node);
-      } else if (type === 'dot') {
-        if (node[1][0] === 'name' && node[1][1] === 'Math') {
-          // transform Math.max to Math_max; we forward in the latter version
-          node[0] = 'name';
-          node[1] = 'Math_' + node[2];
-        }
       } else if (type === 'call' && node[1][0] === 'function') {
         assert(!node[1][1]); // anonymous functions only
         data.inlines.push(node[1]);

From de3972ed9812e04c777e0c1cefbe2b4284f85610 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Sun, 29 Sep 2013 18:40:47 -0700
Subject: [PATCH 146/165] when function is actually void, do not capture it's
 output even if llvm mistakenly bitcasts that way

---
 src/jsifier.js | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/src/jsifier.js b/src/jsifier.js
index acbcf582dccd4..41a3d0705b016 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -1207,7 +1207,7 @@ function JSify(data, functionsOnly, givenFunctions) {
     // in an assignment
     var disabled = DISABLE_EXCEPTION_CATCHING == 2  && !(item.funcData.ident in EXCEPTION_CATCHING_WHITELIST); 
     var phiSets = calcPhiSets(item);
-    var call_ = makeFunctionCall(item.ident, item.params, item.funcData, item.type, ASM_JS && !disabled, !!item.assignTo || !item.standalone, true);
+    var call_ = makeFunctionCall(item, item.params, item.funcData, item.type, ASM_JS && !disabled, !!item.assignTo || !item.standalone, true);
 
     var ret;
 
@@ -1375,7 +1375,9 @@ function JSify(data, functionsOnly, givenFunctions) {
     return ret;
   }
 
-  function makeFunctionCall(ident, params, funcData, type, forceByPointer, hasReturn, invoke) {
+  function makeFunctionCall(item, params, funcData, type, forceByPointer, hasReturn, invoke) {
+    var ident = item.ident;
+
     // We cannot compile assembly. See comment in intertyper.js:'Call'
     assert(ident != 'asm', 'Inline assembly cannot be compiled to JavaScript!');
 
@@ -1525,6 +1527,9 @@ function JSify(data, functionsOnly, givenFunctions) {
         if (trueType !== returnType && !isIdenticallyImplemented(trueType, returnType)) {
           if (VERBOSE) warnOnce('Fixing function call based on return type from signature, on ' + [callIdent, returnType, trueType]);
           returnType = trueType;
+          if (trueType === 'void') {
+            item.assignTo = null;
+          }
         }
       }
     }
@@ -1584,7 +1589,7 @@ function JSify(data, functionsOnly, givenFunctions) {
   function getelementptrHandler(item) { return finalizeLLVMFunctionCall(item) }
   function callHandler(item) {
     if (item.standalone && LibraryManager.isStubFunction(item.ident)) return ';';
-    var ret = makeFunctionCall(item.ident, item.params, item.funcData, item.type, false, !!item.assignTo || !item.standalone) + (item.standalone ? ';' : '');
+    var ret = makeFunctionCall(item, item.params, item.funcData, item.type, false, !!item.assignTo || !item.standalone) + (item.standalone ? ';' : '');
     return makeVarArgsCleanup(ret);
   }
 

From db47cbe4a2e89aa20f74ffcd1556ea753eaab170 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Mon, 30 Sep 2013 12:06:56 -0700
Subject: [PATCH 147/165] assert on vars being in front of functions straight
 out of the js compiler

---
 tools/js-optimizer.js | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js
index 59e3919fcb6d5..7df92c6093077 100644
--- a/tools/js-optimizer.js
+++ b/tools/js-optimizer.js
@@ -1603,6 +1603,8 @@ function normalizeAsm(func) {
   while (i < stats.length) {
     traverse(stats[i], function(node, type) {
       if (type === 'var') {
+        assert(0, 'should be no vars to fix! ' + JSON.stringify(node));
+        /*
         for (var j = 0; j < node[1].length; j++) {
           var v = node[1][j];
           var name = v[0];
@@ -1617,6 +1619,7 @@ function normalizeAsm(func) {
           }
         }
         unVarify(node[1], node);
+        */
       } else if (type === 'call' && node[1][0] === 'function') {
         assert(!node[1][1]); // anonymous functions only
         data.inlines.push(node[1]);

From cae8a52b4958aaae7231e0ae25552abb9d543525 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Mon, 30 Sep 2013 12:08:07 -0700
Subject: [PATCH 148/165] move heap align checks to asm2g, keep -O1 pristine

---
 tests/test_core.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tests/test_core.py b/tests/test_core.py
index 11ec8fd20a0ca..98ff678bbbf6e 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -10517,9 +10517,9 @@ def setUp(self):
 o2 = make_run("o2", compiler=CLANG, emcc_args=["-O2", "-s", "ASM_JS=0", "-s", "JS_CHUNK_SIZE=1024"])
 
 # asm.js
-asm1 = make_run("asm1", compiler=CLANG, emcc_args=["-O1", "-s", "CHECK_HEAP_ALIGN=1"])
+asm1 = make_run("asm1", compiler=CLANG, emcc_args=["-O1"])
 asm2 = make_run("asm2", compiler=CLANG, emcc_args=["-O2"])
-asm2g = make_run("asm2g", compiler=CLANG, emcc_args=["-O2", "-g", "-s", "ASSERTIONS=1", "--memory-init-file", "1"])
+asm2g = make_run("asm2g", compiler=CLANG, emcc_args=["-O2", "-g", "-s", "ASSERTIONS=1", "--memory-init-file", "1", "-s", "CHECK_HEAP_ALIGN=1"])
 asm2x86 = make_run("asm2x86", compiler=CLANG, emcc_args=["-O2", "-g", "-s", "CHECK_HEAP_ALIGN=1"], env={"EMCC_LLVM_TARGET": "i386-pc-linux-gnu"})
 
 # Make custom runs with various options

From 3f03cd8e921afe0449e36df7e3b8272ad29e0b11 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Mon, 30 Sep 2013 12:24:36 -0700
Subject: [PATCH 149/165] overflow numbers directly in js compiler

---
 src/parseTools.js | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/parseTools.js b/src/parseTools.js
index 4966417096332..adde8d63326bb 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -1901,8 +1901,10 @@ function handleOverflow(text, bits) {
   if (CHECK_OVERFLOWS) return 'CHECK_OVERFLOW(' + text + ', ' + bits + ', ' + Math.floor(correctSpecificOverflow()) + ')';
   if (!correct) return text;
   if (bits == 32) {
+    if (isNumber(text)) return text | 0;
     return '((' + text + ')|0)';
   } else if (bits < 32) {
+    if (isNumber(text)) return text & (Math.pow(2, bits) - 1);
     return '((' + text + ')&' + (Math.pow(2, bits) - 1) + ')';
   } else {
     return text; // We warned about this earlier

From b61d6eca643d957a255b5c3c8f393e3820d7428d Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Mon, 30 Sep 2013 12:30:29 -0700
Subject: [PATCH 150/165] fix misc library asm validations

---
 src/library.js | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/library.js b/src/library.js
index b8f5802a9fd63..48f613e083808 100644
--- a/src/library.js
+++ b/src/library.js
@@ -3802,8 +3802,8 @@ LibraryManager.library = {
     p1 = p1|0; p2 = p2|0; num = num|0;
     var i = 0, v1 = 0, v2 = 0;
     while ((i|0) < (num|0)) {
-      var v1 = {{{ makeGetValueAsm('p1', 'i', 'i8', true) }}};
-      var v2 = {{{ makeGetValueAsm('p2', 'i', 'i8', true) }}};
+      v1 = {{{ makeGetValueAsm('p1', 'i', 'i8', true) }}};
+      v2 = {{{ makeGetValueAsm('p2', 'i', 'i8', true) }}};
       if ((v1|0) != (v2|0)) return ((v1|0) > (v2|0) ? 1 : -1)|0;
       i = (i+1)|0;
     }
@@ -4227,9 +4227,9 @@ LibraryManager.library = {
     var ret = 0;
     ret = {{{ makeGetValueAsm('ctlz_i8', 'x >>> 24', 'i8') }}};
     if ((ret|0) < 8) return ret|0;
-    var ret = {{{ makeGetValueAsm('ctlz_i8', '(x >> 16)&0xff', 'i8') }}};
+    ret = {{{ makeGetValueAsm('ctlz_i8', '(x >> 16)&0xff', 'i8') }}};
     if ((ret|0) < 8) return (ret + 8)|0;
-    var ret = {{{ makeGetValueAsm('ctlz_i8', '(x >> 8)&0xff', 'i8') }}};
+    ret = {{{ makeGetValueAsm('ctlz_i8', '(x >> 8)&0xff', 'i8') }}};
     if ((ret|0) < 8) return (ret + 16)|0;
     return ({{{ makeGetValueAsm('ctlz_i8', 'x&0xff', 'i8') }}} + 24)|0;
   },
@@ -4263,9 +4263,9 @@ LibraryManager.library = {
     var ret = 0;
     ret = {{{ makeGetValueAsm('cttz_i8', 'x & 0xff', 'i8') }}};
     if ((ret|0) < 8) return ret|0;
-    var ret = {{{ makeGetValueAsm('cttz_i8', '(x >> 8)&0xff', 'i8') }}};
+    ret = {{{ makeGetValueAsm('cttz_i8', '(x >> 8)&0xff', 'i8') }}};
     if ((ret|0) < 8) return (ret + 8)|0;
-    var ret = {{{ makeGetValueAsm('cttz_i8', '(x >> 16)&0xff', 'i8') }}};
+    ret = {{{ makeGetValueAsm('cttz_i8', '(x >> 16)&0xff', 'i8') }}};
     if ((ret|0) < 8) return (ret + 16)|0;
     return ({{{ makeGetValueAsm('cttz_i8', 'x >>> 24', 'i8') }}} + 24)|0;
   },

From 154a96f439191c8422dc339d1ef6eb57d97d0409 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Mon, 30 Sep 2013 12:37:31 -0700
Subject: [PATCH 151/165] explicitly define setjmp helper vars

---
 src/jsifier.js | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/src/jsifier.js b/src/jsifier.js
index 41a3d0705b016..d7f00a1b740cf 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -599,6 +599,11 @@ function JSify(data, functionsOnly, givenFunctions) {
 
       addVariable('label', 'i32', func);
 
+      if (func.setjmpTable) {
+        addVariable('setjmpLabel', 'i32', func);
+        addVariable('setjmpTable', 'i32', func);
+      }
+
       // spell out local variables
       var vars = values(func.variables).filter(function(v) {
         return v.origin !== 'funcparam' &&
@@ -717,8 +722,8 @@ function JSify(data, functionsOnly, givenFunctions) {
               ret += 'dummy: 0';
               ret += '};\n';
             } else {
-              ret += 'var setjmpLabel = 0;\n';
-              ret += 'var setjmpTable = ' + RuntimeGenerator.stackAlloc(4 * (MAX_SETJMPS + 1) * 2) + ';\n';
+              ret += makeVarDef('setjmpLabel') + '=0;\n';
+              ret += makeVarDef('setjmpTable') + '=' + RuntimeGenerator.stackAlloc(4 * (MAX_SETJMPS + 1) * 2) + ';\n';
               ret += makeSetValue('setjmpTable', '0', '0', 'i32') + ';'; // initialize first entry to 0
             }
           }

From d476a5881aa03136ab3ccd2c9002eb289f5b8960 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Mon, 30 Sep 2013 13:34:00 -0700
Subject: [PATCH 152/165] do not remove '.' from floats in parseNumerical

---
 src/parseTools.js | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/parseTools.js b/src/parseTools.js
index adde8d63326bb..801e2e7a3cdc6 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -930,7 +930,10 @@ function parseNumerical(value, type) {
   }
   if (isNumber(value)) {
     var ret = parseFloat(value); // will change e.g. 5.000000e+01 to 50
-    if (type in Runtime.FLOAT_TYPES && value[0] == '-' && ret === 0) return '-0'; // fix negative 0, toString makes it 0
+    if (type in Runtime.FLOAT_TYPES) {
+      if (value[0] === '-' && ret === 0) return '-.0'; // fix negative 0, toString makes it 0
+      if (!RUNNING_JS_OPTS) ret = asmEnsureFloat(ret, type);
+    }
     return ret.toString();
   } else {
     return value;

From b379e05eb67a590ac76e96617263b62b418d977d Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Mon, 30 Sep 2013 13:36:17 -0700
Subject: [PATCH 153/165] remove obsolete fp80 test

---
 tests/cases/fp80_ta2.ll | 21 ---------------------
 1 file changed, 21 deletions(-)
 delete mode 100644 tests/cases/fp80_ta2.ll

diff --git a/tests/cases/fp80_ta2.ll b/tests/cases/fp80_ta2.ll
deleted file mode 100644
index 7fc0db4a07f9f..0000000000000
--- a/tests/cases/fp80_ta2.ll
+++ /dev/null
@@ -1,21 +0,0 @@
-; ModuleID = 'src.cpp.o'
-target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"
-target triple = "i386-pc-linux-gnu"
-
-@.str = private unnamed_addr constant [15 x i8] c"hello, world!\0A\00" ; [#uses=1]
-
-; [#uses=0]
-define i32 @main() {
-entry:
-  %x = zext i32 0 to x86_fp80
-  %1 = bitcast x86_fp80 %x to i80
-  %2 = trunc i80 %1 to i32
-  %retval = alloca i32, align 4                   ; [#uses=1]
-  store i32 0, i32* %retval
-  %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([15 x i8]* @.str, i32 0, i32 0)) ; [#uses=0]
-  ret i32 0
-}
-
-; [#uses=1]
-declare i32 @printf(i8*, ...)
-

From 04732d022bfaa3ea08a78886d0d8dec5658fc58d Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Mon, 30 Sep 2013 14:01:05 -0700
Subject: [PATCH 154/165] do not tack on .0 to Infinity or NaN

---
 src/parseTools.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/parseTools.js b/src/parseTools.js
index 801e2e7a3cdc6..addf0f21ee2a5 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -1144,7 +1144,7 @@ function asmEnsureFloat(value, type) { // ensures that a float type has either 5
     } else {
       // ensure a .
       value = value.toString();
-      if (value.indexOf('.') >= 0) return value;
+      if (value.indexOf('.') >= 0 || /[IN]/.test(value)) return value; // if already dotted, or Infinity or NaN, nothing to do here
       var e = value.indexOf('e');
       if (e < 0) return value + '.0';
       return value.substr(0, e) + '.0' + value.substr(e);

From c182633f18453cd5c46459ccdce2280ccc591644 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Mon, 30 Sep 2013 17:50:39 -0700
Subject: [PATCH 155/165] emit final missing returns in compiler itself

---
 src/jsifier.js        | 14 +++++++++++---
 tests/test_core.py    |  6 ++++++
 tools/js-optimizer.js | 21 ---------------------
 3 files changed, 17 insertions(+), 24 deletions(-)

diff --git a/src/jsifier.js b/src/jsifier.js
index d7f00a1b740cf..64da422800eae 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -821,9 +821,17 @@ function JSify(data, functionsOnly, givenFunctions) {
     // Finalize function
     if (LABEL_DEBUG && functionNameFilterTest(func.ident)) func.JS += "  INDENT = INDENT.substr(0, INDENT.length-2);\n";
     // Ensure a return in a function with a type that returns, even if it lacks a return (e.g., if it aborts())
-    if (RELOOP && func.lines.length > 0 && func.returnType != 'void') {
-      var returns = func.labels.filter(function(label) { return label.lines[label.lines.length-1].intertype == 'return' }).length;
-      if (returns == 0) func.JS += INDENTATION + 'return ' + asmCoercion('0', func.returnType);
+    if (RELOOP && ASM_JS && func.lines.length > 0 && func.returnType != 'void') {
+      var lastCurly = func.JS.lastIndexOf('}');
+      var lastReturn = func.JS.lastIndexOf('return ');
+      if ((lastCurly < 0 && lastReturn < 0) || // no control flow, no return
+          (lastCurly >= 0 && lastReturn < lastCurly)) { // control flow, no return past last join
+        if (func.returnType in Runtime.FLOAT_TYPES) {
+          func.JS += ' return +0;\n';
+        } else {
+          func.JS += ' return 0;\n';
+        }
+      }
     }
     func.JS += '}\n';
     
diff --git a/tests/test_core.py b/tests/test_core.py
index 98ff678bbbf6e..92edbaf434ea5 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -8609,6 +8609,12 @@ def test_cubescript(self):
       assert ' & 255]()' not in original, 'big function table does not exist'
       assert ' & 255]()' in final, 'big function table exists'
 
+    assert 'asm1' in test_modes
+    if self.run_name == 'asm1':
+      assert not Settings.RELOOP
+      Settings.RELOOP = 1 # check for mixing of relooping with asm1
+      self.do_run(path_from_root('tests', 'cubescript'), '*\nTemp is 33\n9\n5\nhello, everyone\n*', main_file='command.cpp')
+
   def test_gcc_unmangler(self):
     Settings.NAMED_GLOBALS = 1 # test coverage for this
 
diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js
index 7df92c6093077..f03c04b8f947b 100644
--- a/tools/js-optimizer.js
+++ b/tools/js-optimizer.js
@@ -768,32 +768,11 @@ function simplifyExpressions(ast) {
     });
   }
 
-  function asmOpts(fun) {
-    // Add final returns when necessary
-    var returnType = null;
-    traverse(fun, function(node, type) {
-      if (type === 'return' && node[1]) {
-        returnType = detectAsmCoercion(node[1]);
-      }
-    });
-    // Add a final return if one is missing.
-    if (returnType !== null) {
-      var stats = getStatements(fun);
-      var last = stats[stats.length-1];
-      if (last[0] != 'return') {
-        var returnValue = ['num', 0];
-        if (returnType === ASM_DOUBLE) returnValue = ['unary-prefix', '+', returnValue];
-        stats.push(['return', returnValue]);
-      }
-    }
-  }
-
   traverseGeneratedFunctions(ast, function(func) {
     simplifyIntegerConversions(func);
     simplifyBitops(func);
     joinAdditions(func);
     // simplifyZeroComp(func); TODO: investigate performance
-    if (asm) asmOpts(func);
     simplifyNotComps(func);
   });
 }

From a859dbb0da4a1545cb3537ce9d495598cecefb60 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Wed, 2 Oct 2013 16:55:28 -0700
Subject: [PATCH 156/165] add missing Math_min definition

---
 src/preamble.js | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/preamble.js b/src/preamble.js
index d094b071b5ebd..88aaff77b714a 100644
--- a/src/preamble.js
+++ b/src/preamble.js
@@ -959,6 +959,7 @@ var Math_floor = Math.floor;
 var Math_pow = Math.pow;
 var Math_imul = Math.imul;
 var Math_toFloat32 = Math.toFloat32;
+var Math_min = Math.min;
 
 // A counter of dependencies for calling run(). If we need to
 // do asynchronous work before running, increment this and

From 8b76d21dae3289848262900a0d4851593136e80b Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Wed, 2 Oct 2013 17:50:59 -0700
Subject: [PATCH 157/165] update js optimizer tests

---
 .../eliminator/asm-eliminator-test-output.js  | 4835 ------------
 tools/eliminator/asm-eliminator-test.js       | 6495 -----------------
 tools/js-optimizer.js                         |    2 +-
 tools/test-js-optimizer-asm-pre-output.js     |   20 -
 tools/test-js-optimizer-asm-pre.js            |   21 -
 tools/test-js-optimizer-asm-regs.js           |    4 +-
 6 files changed, 3 insertions(+), 11374 deletions(-)

diff --git a/tools/eliminator/asm-eliminator-test-output.js b/tools/eliminator/asm-eliminator-test-output.js
index 5cc6238e3a0b4..dda82047ca757 100644
--- a/tools/eliminator/asm-eliminator-test-output.js
+++ b/tools/eliminator/asm-eliminator-test-output.js
@@ -75,18 +75,6 @@ function _vec2Length($this) {
 function exc($this) {
  $this = $this | 0;
  var $1 = 0, $5 = 0;
- $1 = (function() {
-  try {
-   __THREW__ = false;
-   return __ZNSt3__16locale8__globalEv();
-  } catch (e) {
-   if (typeof e != "number") throw e;
-   if (ABORT) throw e;
-   __THREW__ = true;
-   Module.print("Exception: " + e + ", currently at: " + (new Error).stack);
-   return null;
-  }
- })();
  if (!__THREW__) {
   $5 = HEAP32[(($1 | 0) & 16777215) >> 2] | 0;
   HEAP32[(($this | 0) & 16777215) >> 2] = $5;
@@ -122,233 +110,10 @@ function switchy() {
   break;
  }
 }
-function confuusion() {
- var i = +0, j = +0;
- func1(+i);
- j = i;
- func2(+j);
-}
 function tempDouble(a) {
  a = +a;
  f(a * a);
 }
-function _org_apache_harmony_luni_util_NumberConverter_freeFormat__($me) {
- $me = $me | 0;
- var $_r2_sroa_0 = 0, $_r3_sroa_0 = 0, $$etemp$1 = 0, $6 = 0, $7 = 0, $10 = 0, $11 = +0, $15 = 0, $_r2_sroa_0_0_cast283 = 0, $_r3_sroa_0_0_cast247 = 0, $_r3_sroa_0_0_load244 = +0, $_r3_sroa_0_0_load244$$SHADOW$0 = 0, $_r2_sroa_0_0_load = +0, $_r2_sroa_0_0_load$$SHADOW$0 = 0, $trunc297 = 0, $25 = 0, $26 = 0, $smax = 0, $28 = 0, $_r3_sroa_0_0_load239 = +0, $_pre_phi301 = 0, $_r3_sroa_0_0_cast264_pre_phi = 0, $_r2_sroa_0_0_load265 = +0, $33 = 0, $34 = 0, $_r3_sroa_0_0_cast253 = 0, $36 = 0, $37 = 0, $_r3_sroa_0_0_load243 = +0, $_r2_sroa_0_0_cast = 0, $45 = 0, $_sink_in = +0, $_r3_sroa_0_0_load241 = +0, $_r2_sroa_0_0_load266287 = 0, $_r1_sroa_0_0 = +0, $47 = 0, $48$0 = 0, $48$1 = 0, $_r1_sroa_0_0_extract_trunc185 = 0, $_r1_sroa_0_1_in$0 = 0, $_r1_sroa_0_1_in$1 = 0, $_r1_sroa_0_0_extract_trunc169 = 0, $_r1_sroa_0_2 = +0, $64 = 0, $65 = 0, $69 = 0, $76 = 0, $82 = 0, $_r1_sroa_0_0_extract_trunc = 0, $$etemp$15 = 0, $105 = 0, $106 = 0, $107 = 0, $108 = 0, $109 = 0, $110 = 0, $112 = 0, $113 = 0, $118 = 0, $_r3_sroa_0_0_load242 = +0, label = 0, __stackBase__ = 0;
- __stackBase__ = STACKTOP;
- STACKTOP = STACKTOP + 16 | 0;
- $_r2_sroa_0 = __stackBase__ | 0;
- $_r3_sroa_0 = __stackBase__ + 8 | 0;
- if ((HEAP32[(114668 | 0) >> 2] | 0 | 0) == 0) {
-  HEAP32[(114664 | 0) >> 2] = 1;
-  HEAP32[(114668 | 0) >> 2] = 1;
-  $$etemp$1 = 114672 | 0;
-  HEAP32[($$etemp$1 | 0) >> 2] = -1;
-  HEAP32[($$etemp$1 + 4 | 0) >> 2] = -1;
-  HEAP32[(114684 | 0) >> 2] = 25296 | 0;
-  HEAP32[(114704 | 0) >> 2] = 110728;
-  HEAP32[(114712 | 0) >> 2] = 8;
-  HEAP32[(114784 | 0 | 0) >> 2] = HEAP32[(107856 | 0 | 0) >> 2] | 0;
-  HEAP32[(114784 | 0 | 0) + 4 >> 2] = HEAP32[(107856 | 0 | 0) + 4 >> 2] | 0;
-  HEAP32[(114784 | 0 | 0) + 8 >> 2] = HEAP32[(107856 | 0 | 0) + 8 >> 2] | 0;
-  HEAP32[(114784 | 0 | 0) + 12 >> 2] = HEAP32[(107856 | 0 | 0) + 12 >> 2] | 0;
-  HEAP32[(114784 | 0 | 0) + 16 >> 2] = HEAP32[(107856 | 0 | 0) + 16 >> 2] | 0;
-  HEAP32[(114784 | 0 | 0) + 20 >> 2] = HEAP32[(107856 | 0 | 0) + 20 >> 2] | 0;
- }
- $6 = _org_xmlvm_runtime_XMLVMArray_createSingleDimension___java_lang_Class_int(HEAP32[138960 >> 2] | 0, 25) | 0;
- $7 = $me + 8 | 0;
- $10 = HEAP32[($me + 20 | 0) >> 2] | 0;
- $11 = (HEAP32[tempDoublePtr >> 2] = $10, HEAP32[tempDoublePtr + 4 >> 2] = 0, +HEAPF64[tempDoublePtr >> 3]);
- if (($10 | 0) > -1) {
-  HEAP32[$_r2_sroa_0 >> 2] = 0;
-  $_r2_sroa_0_0_load265 = +HEAPF64[$_r2_sroa_0 >> 3];
-  $_r3_sroa_0_0_cast264_pre_phi = $_r3_sroa_0;
-  $_pre_phi301 = $6 + 16 | 0;
- } else {
-  $15 = $6 + 16 | 0;
-  HEAP16[(HEAP32[$15 >> 2] | 0) >> 1] = 48;
-  $_r2_sroa_0_0_cast283 = $_r2_sroa_0;
-  HEAP16[((HEAP32[$15 >> 2] | 0) + 2 | 0) >> 1] = 46;
-  HEAP32[$_r2_sroa_0_0_cast283 >> 2] = 2;
-  $_r3_sroa_0_0_cast247 = $_r3_sroa_0;
-  HEAP32[$_r3_sroa_0_0_cast247 >> 2] = $10 + 1 | 0;
-  $_r3_sroa_0_0_load244 = +HEAPF64[$_r3_sroa_0 >> 3];
-  $_r3_sroa_0_0_load244$$SHADOW$0 = HEAP32[($_r3_sroa_0 | 0) >> 2] | 0;
-  $_r2_sroa_0_0_load = +HEAPF64[$_r2_sroa_0 >> 3];
-  $_r2_sroa_0_0_load$$SHADOW$0 = HEAP32[($_r2_sroa_0 | 0) >> 2] | 0;
-  HEAPF64[$_r3_sroa_0 >> 3] = $_r2_sroa_0_0_load;
-  HEAPF64[$_r2_sroa_0 >> 3] = $_r3_sroa_0_0_load244;
-  $trunc297 = $_r3_sroa_0_0_load244$$SHADOW$0;
-  $25 = $_r2_sroa_0_0_load$$SHADOW$0;
-  if (($trunc297 | 0) < 0) {
-   $26 = $trunc297 + 1 | 0;
-   $smax = ($26 | 0) > 0 ? $26 : 0;
-   $28 = $25 + $smax | 0;
-   $113 = $25;
-   $112 = $trunc297;
-   while (1) {
-    HEAP16[((HEAP32[$15 >> 2] | 0) + ($113 << 1) | 0) >> 1] = 48;
-    $118 = $112 + 1 | 0;
-    if (($118 | 0) < 0) {
-     $113 = $113 + 1 | 0;
-     $112 = $118;
-    } else {
-     break;
-    }
-   }
-   HEAP32[$_r3_sroa_0_0_cast247 >> 2] = $28 - $trunc297 | 0;
-   HEAP32[$_r2_sroa_0_0_cast283 >> 2] = $smax;
-   $_r3_sroa_0_0_load239 = +HEAPF64[$_r3_sroa_0 >> 3];
-  } else {
-   $_r3_sroa_0_0_load239 = $_r2_sroa_0_0_load;
-  }
-  HEAPF64[$_r2_sroa_0 >> 3] = $_r3_sroa_0_0_load239;
-  $_r2_sroa_0_0_load265 = $_r3_sroa_0_0_load239;
-  $_r3_sroa_0_0_cast264_pre_phi = $_r3_sroa_0_0_cast247;
-  $_pre_phi301 = $15;
- }
- $33 = $me + 16 | 0;
- $34 = HEAP32[$33 >> 2] | 0;
- $_r3_sroa_0_0_cast253 = $_r3_sroa_0;
- HEAP32[$_r3_sroa_0_0_cast253 >> 2] = $34;
- $36 = $me + 12 | 0;
- $37 = HEAP32[$36 >> 2] | 0;
- HEAP32[$36 >> 2] = $37 + 1 | 0;
- HEAP32[$_r3_sroa_0_0_cast264_pre_phi >> 2] = HEAP32[((HEAP32[($34 + 16 | 0) >> 2] | 0) + ($37 << 2) | 0) >> 2] | 0;
- $_r3_sroa_0_0_load243 = +HEAPF64[$_r3_sroa_0 >> 3];
- HEAPF64[$_r3_sroa_0 >> 3] = $_r2_sroa_0_0_load265;
- HEAPF64[$_r2_sroa_0 >> 3] = $11;
- $_r2_sroa_0_0_cast = $_r2_sroa_0;
- $45 = $7;
- $_r1_sroa_0_0 = $_r3_sroa_0_0_load243;
- $_r2_sroa_0_0_load266287 = $10;
- $_r3_sroa_0_0_load241 = $_r2_sroa_0_0_load265;
- $_sink_in = $_r2_sroa_0_0_load265;
- while (1) {
-  HEAPF64[tempDoublePtr >> 3] = $_sink_in;
-  $47 = HEAP32[tempDoublePtr >> 2] | 0;
-  HEAPF64[tempDoublePtr >> 3] = $_r1_sroa_0_0;
-  $48$0 = HEAP32[tempDoublePtr >> 2] | 0;
-  $48$1 = HEAP32[tempDoublePtr + 4 >> 2] | 0;
-  $_r1_sroa_0_0_extract_trunc185 = $48$0;
-  do {
-   if (($_r1_sroa_0_0_extract_trunc185 | 0) == -1) {
-    if (($_r2_sroa_0_0_load266287 | 0) < -1) {
-     $_r1_sroa_0_2 = $_r3_sroa_0_0_load241;
-     break;
-    }
-    HEAP16[((HEAP32[$_pre_phi301 >> 2] | 0) + ($47 << 1) | 0) >> 1] = 48;
-    $_r1_sroa_0_1_in$1 = 0 | $48$1 & -1;
-    $_r1_sroa_0_1_in$0 = $47 + 1 | 0 | $48$0 & 0;
-    label = 785;
-    break;
-   } else {
-    HEAP16[((HEAP32[$_pre_phi301 >> 2] | 0) + ($47 << 1) | 0) >> 1] = ($_r1_sroa_0_0_extract_trunc185 + 48 | 0) & 65535;
-    $_r1_sroa_0_1_in$1 = 0;
-    $_r1_sroa_0_1_in$0 = $47 + 1 | 0;
-    label = 785;
-    break;
-   }
-  } while (0);
-  do {
-   if ((label | 0) == 785) {
-    label = 0;
-    if (!(($_r2_sroa_0_0_load266287 | 0) == 0)) {
-     $_r1_sroa_0_2 = (HEAP32[tempDoublePtr >> 2] = $_r1_sroa_0_1_in$0, HEAP32[tempDoublePtr + 4 >> 2] = $_r1_sroa_0_1_in$1, +HEAPF64[tempDoublePtr >> 3]);
-     break;
-    }
-    $_r1_sroa_0_0_extract_trunc169 = $_r1_sroa_0_1_in$0;
-    HEAP32[$_r3_sroa_0_0_cast264_pre_phi >> 2] = $_r1_sroa_0_0_extract_trunc169 + 1 | 0;
-    HEAP16[((HEAP32[$_pre_phi301 >> 2] | 0) + ($_r1_sroa_0_0_extract_trunc169 << 1) | 0) >> 1] = 46;
-    $_r1_sroa_0_2 = +HEAPF64[$_r3_sroa_0 >> 3];
-   }
-  } while (0);
-  $64 = $_r2_sroa_0_0_load266287 - 1 | 0;
-  $65 = HEAP32[$36 >> 2] | 0;
-  HEAP32[$_r3_sroa_0_0_cast264_pre_phi >> 2] = $65;
-  if (($65 | 0) < (HEAP32[$45 >> 2] | 0 | 0)) {
-   $69 = HEAP32[$33 >> 2] | 0;
-   HEAP32[$_r3_sroa_0_0_cast253 >> 2] = $69;
-   HEAP32[$36 >> 2] = $65 + 1 | 0;
-   $76 = HEAP32[((HEAP32[($69 + 16 | 0) >> 2] | 0) + ($65 << 2) | 0) >> 2] | 0;
-   HEAP32[$_r3_sroa_0_0_cast264_pre_phi >> 2] = $76;
-   if (!(($76 | 0) != -1 | ($64 | 0) > -2)) {
-    break;
-   }
-  } else {
-   HEAP32[$_r3_sroa_0_0_cast264_pre_phi >> 2] = -1;
-   if (!(($64 | 0) > -2)) {
-    break;
-   }
-  }
-  $_r3_sroa_0_0_load242 = +HEAPF64[$_r3_sroa_0 >> 3];
-  HEAPF64[$_r3_sroa_0 >> 3] = $_r1_sroa_0_2;
-  $_r1_sroa_0_0 = $_r3_sroa_0_0_load242;
-  $_r2_sroa_0_0_load266287 = $64;
-  $_r3_sroa_0_0_load241 = $_r1_sroa_0_2;
-  $_sink_in = $_r1_sroa_0_2;
- }
- HEAP32[$_r2_sroa_0_0_cast >> 2] = $64;
- if ((HEAP32[(106148 | 0) >> 2] | 0 | 0) == 0) {
-  ___INIT_java_lang_String();
- }
- $82 = _GC_MALLOC(36 | 0) | 0;
- HEAP32[$82 >> 2] = 106144;
- _memset($82 + 4 | 0 | 0 | 0, 0 | 0 | 0, 32 | 0 | 0);
- HEAP32[$_r2_sroa_0 >> 2] = $82;
- HEAPF64[tempDoublePtr >> 3] = $_r1_sroa_0_2;
- $_r1_sroa_0_0_extract_trunc = HEAP32[tempDoublePtr >> 2] | 0;
- HEAP32[($82 + 8 | 0) >> 2] = 0;
- HEAP32[($82 + 12 | 0) >> 2] = 0;
- HEAP32[($82 + 16 | 0) >> 2] = 0;
- if (($_r1_sroa_0_0_extract_trunc | 0) < 0) {
-  _XMLVM_ERROR(16136 | 0, 13208 | 0, 132112 | 0, 830);
-  return 0 | 0;
- }
- if ((HEAP32[($6 + 12 | 0) >> 2] | 0 | 0) < ($_r1_sroa_0_0_extract_trunc | 0)) {
-  _XMLVM_ERROR(16136 | 0, 13208 | 0, 132112 | 0, 830);
-  return 0 | 0;
- }
- HEAP32[($82 + 24 | 0) >> 2] = 0;
- if (!((HEAP32[(114668 | 0) >> 2] | 0 | 0) == 0)) {
-  $105 = HEAP32[138960 >> 2] | 0;
-  $106 = _org_xmlvm_runtime_XMLVMArray_createSingleDimension___java_lang_Class_int($105, $_r1_sroa_0_0_extract_trunc) | 0;
-  $107 = $82 + 20 | 0;
-  $108 = $107;
-  HEAP32[$108 >> 2] = $106;
-  $109 = $82 + 28 | 0;
-  $110 = $109;
-  HEAP32[$110 >> 2] = $_r1_sroa_0_0_extract_trunc;
-  _java_lang_System_arraycopy___java_lang_Object_int_java_lang_Object_int_int($6, 0, $106, 0, $_r1_sroa_0_0_extract_trunc);
-  STACKTOP = __stackBase__;
-  return $82 | 0;
- }
- HEAP32[(114664 | 0) >> 2] = 1;
- HEAP32[(114668 | 0) >> 2] = 1;
- $$etemp$15 = 114672 | 0;
- HEAP32[($$etemp$15 | 0) >> 2] = -1;
- HEAP32[($$etemp$15 + 4 | 0) >> 2] = -1;
- HEAP32[(114684 | 0) >> 2] = 25296 | 0;
- HEAP32[(114704 | 0) >> 2] = 110728;
- HEAP32[(114712 | 0) >> 2] = 8;
- HEAP32[(114784 | 0 | 0) >> 2] = HEAP32[(107856 | 0 | 0) >> 2] | 0;
- HEAP32[(114784 | 0 | 0) + 4 >> 2] = HEAP32[(107856 | 0 | 0) + 4 >> 2] | 0;
- HEAP32[(114784 | 0 | 0) + 8 >> 2] = HEAP32[(107856 | 0 | 0) + 8 >> 2] | 0;
- HEAP32[(114784 | 0 | 0) + 12 >> 2] = HEAP32[(107856 | 0 | 0) + 12 >> 2] | 0;
- HEAP32[(114784 | 0 | 0) + 16 >> 2] = HEAP32[(107856 | 0 | 0) + 16 >> 2] | 0;
- HEAP32[(114784 | 0 | 0) + 20 >> 2] = HEAP32[(107856 | 0 | 0) + 20 >> 2] | 0;
- $105 = HEAP32[138960 >> 2] | 0;
- $106 = _org_xmlvm_runtime_XMLVMArray_createSingleDimension___java_lang_Class_int($105, $_r1_sroa_0_0_extract_trunc) | 0;
- $107 = $82 + 20 | 0;
- $108 = $107;
- HEAP32[$108 >> 2] = $106;
- $109 = $82 + 28 | 0;
- $110 = $109;
- HEAP32[$110 >> 2] = $_r1_sroa_0_0_extract_trunc;
- _java_lang_System_arraycopy___java_lang_Object_int_java_lang_Object_int_int($6, 0, $106, 0, $_r1_sroa_0_0_extract_trunc);
- STACKTOP = __stackBase__;
- return $82 | 0;
-}
 function __ZN23b2EdgeAndPolygonContact8EvaluateEP10b2ManifoldRK11b2TransformS4_($this, $manifold, $xfA, $xfB) {
  $this = $this | 0;
  $manifold = $manifold | 0;
@@ -361,4606 +126,6 @@ function __ZN23b2EdgeAndPolygonContact8EvaluateEP10b2ManifoldRK11b2TransformS4_(
  STACKTOP = __stackBase__;
  return;
 }
-function _java_nio_charset_Charset_forNameInternal___java_lang_String($n1) {
- $n1 = $n1 | 0;
- var $_r0_sroa_0 = 0, $_r0_sroa_1 = 0, $_r1_sroa_0 = 0, $_r2_sroa_0 = 0, $_r3_sroa_0 = 0, $_r3_sroa_1 = 0, $_r5_sroa_0 = 0, $local_env_w4567aaac23b1b6 = 0, $local_env_w4567aaac23b1c16 = 0, $local_env_w4567aaac23b1c22 = 0, $local_env_w4567aaac23b1c24 = 0, $local_env_w4567aaac23b1c26 = 0, $local_env_w4567aaac23b1c29 = 0, $local_env_w4567aaac23b1c31 = 0, $local_env_w4567aaac23b1c35 = 0, $local_env_w4567aaac23b1c40 = 0, $local_env_w4567aaac23b1c42 = 0, $local_env_w4567aaac23b1c44 = 0, $local_env_w4567aaac23b1c48 = 0, $local_env_w4567aaac23b1c50 = 0, $5 = 0, $16 = 0, $18 = 0, $19 = 0, $21 = 0, $25 = 0, $40 = 0, $52 = 0, $57 = 0, $61 = 0, $tib1_0_ph_i543 = 0, $72 = 0, $tib1_0_lcssa_i546 = 0, $dimension_tib1_0_lcssa_i547 = 0, $77 = 0, $79 = 0, $dimension_tib1_029_i549 = 0, $82 = 0, $83 = 0, $86 = 0, $88 = 0, $dimension_tib2_024_i551 = 0, $91 = 0, $92 = 0, $95 = 0, $tib2_0_lcssa_in_i553 = 0, $dimension_tib2_0_lcssa_i554 = 0, $tib2_0_lcssa_i555 = 0, $tib1_121_i558 = 0, $i_0_i561 = 0, $113 = 0, $_r1_sroa_0_0_load600 = 0, $119 = 0, $122 = 0, $139 = 0, $145 = 0, $149 = 0, $151 = 0, $153 = 0, $155 = 0, $159 = 0, $170 = 0, $175 = 0, $179 = 0, $tib1_0_ph_i521 = 0, $190 = 0, $tib1_0_lcssa_i524 = 0, $dimension_tib1_0_lcssa_i525 = 0, $195 = 0, $197 = 0, $dimension_tib1_029_i527 = 0, $200 = 0, $201 = 0, $204 = 0, $206 = 0, $dimension_tib2_024_i529 = 0, $209 = 0, $210 = 0, $213 = 0, $tib2_0_lcssa_in_i531 = 0, $dimension_tib2_0_lcssa_i532 = 0, $tib2_0_lcssa_i533 = 0, $tib1_121_i536 = 0, $i_0_i539 = 0, $231 = 0, $238 = 0, $240 = 0, $_r1_sroa_0_0_load = 0, $246 = 0, $249 = 0, $266 = 0, $273 = 0, $275 = 0, $284 = 0, $286 = 0, $290 = 0, $305 = 0, $310 = 0, $323 = 0, $328 = 0, $332 = 0, $tib1_0_ph_i500 = 0, $343 = 0, $tib1_0_lcssa_i503 = 0, $dimension_tib1_0_lcssa_i504 = 0, $348 = 0, $350 = 0, $dimension_tib1_029_i506 = 0, $353 = 0, $354 = 0, $357 = 0, $359 = 0, $dimension_tib2_024_i508 = 0, $362 = 0, $363 = 0, $366 = 0, $tib2_0_lcssa_in_i510 = 0, $dimension_tib2_0_lcssa_i511 = 0, $tib2_0_lcssa_i512 = 0, $tib1_121_i515 = 0, $i_0_i518 = 0, $384 = 0, $392 = 0, $394 = 0, $395 = 0, $397 = 0, $401 = 0, $416 = 0, $424 = 0, $426 = 0, $427 = 0, $429 = 0, $433 = 0, $446 = 0, $451 = 0, $455 = 0, $tib1_0_ph_i479 = 0, $466 = 0, $tib1_0_lcssa_i482 = 0, $dimension_tib1_0_lcssa_i483 = 0, $471 = 0, $473 = 0, $dimension_tib1_029_i485 = 0, $476 = 0, $477 = 0, $480 = 0, $482 = 0, $dimension_tib2_024_i487 = 0, $485 = 0, $486 = 0, $489 = 0, $tib2_0_lcssa_in_i489 = 0, $dimension_tib2_0_lcssa_i490 = 0, $tib2_0_lcssa_i491 = 0, $tib1_121_i494 = 0, $i_0_i497 = 0, $507 = 0, $519 = 0, $521 = 0, $525 = 0, $534 = 0, $539 = 0, $542 = 0, $546 = 0, $548 = 0, $557 = 0, $562 = 0, $566 = 0, $tib1_0_ph_i458 = 0, $577 = 0, $tib1_0_lcssa_i461 = 0, $dimension_tib1_0_lcssa_i462 = 0, $582 = 0, $584 = 0, $dimension_tib1_029_i464 = 0, $587 = 0, $588 = 0, $591 = 0, $593 = 0, $dimension_tib2_024_i466 = 0, $596 = 0, $597 = 0, $600 = 0, $tib2_0_lcssa_in_i468 = 0, $dimension_tib2_0_lcssa_i469 = 0, $tib2_0_lcssa_i470 = 0, $tib1_121_i473 = 0, $i_0_i476 = 0, $618 = 0, $623 = 0, $625 = 0, $629 = 0, $632 = 0, $643 = 0, $644 = 0, $649 = 0, $653 = 0, $tib1_0_ph_i437 = 0, $664 = 0, $tib1_0_lcssa_i440 = 0, $dimension_tib1_0_lcssa_i441 = 0, $669 = 0, $671 = 0, $dimension_tib1_029_i443 = 0, $674 = 0, $675 = 0, $678 = 0, $680 = 0, $dimension_tib2_024_i445 = 0, $683 = 0, $684 = 0, $687 = 0, $tib2_0_lcssa_in_i447 = 0, $dimension_tib2_0_lcssa_i448 = 0, $tib2_0_lcssa_i449 = 0, $tib1_121_i452 = 0, $i_0_i455 = 0, $705 = 0, $711 = 0, $716 = 0, $720 = 0, $tib1_0_ph_i416 = 0, $731 = 0, $tib1_0_lcssa_i419 = 0, $dimension_tib1_0_lcssa_i420 = 0, $736 = 0, $738 = 0, $dimension_tib1_029_i422 = 0, $741 = 0, $742 = 0, $745 = 0, $747 = 0, $dimension_tib2_024_i424 = 0, $750 = 0, $751 = 0, $754 = 0, $tib2_0_lcssa_in_i426 = 0, $dimension_tib2_0_lcssa_i427 = 0, $tib2_0_lcssa_i428 = 0, $tib1_121_i431 = 0, $i_0_i434 = 0, $772 = 0, $780 = 0, $782 = 0, $783 = 0, $785 = 0, $789 = 0, $798 = 0, $808 = 0, $809 = 0, $814 = 0, $818 = 0, $tib1_0_ph_i395 = 0, $829 = 0, $tib1_0_lcssa_i398 = 0, $dimension_tib1_0_lcssa_i399 = 0, $834 = 0, $836 = 0, $dimension_tib1_029_i401 = 0, $839 = 0, $840 = 0, $843 = 0, $845 = 0, $dimension_tib2_024_i403 = 0, $848 = 0, $849 = 0, $852 = 0, $tib2_0_lcssa_in_i405 = 0, $dimension_tib2_0_lcssa_i406 = 0, $tib2_0_lcssa_i407 = 0, $tib1_121_i410 = 0, $i_0_i413 = 0, $870 = 0, $876 = 0, $881 = 0, $885 = 0, $tib1_0_ph_i374 = 0, $896 = 0, $tib1_0_lcssa_i377 = 0, $dimension_tib1_0_lcssa_i378 = 0, $901 = 0, $903 = 0, $dimension_tib1_029_i380 = 0, $906 = 0, $907 = 0, $910 = 0, $912 = 0, $dimension_tib2_024_i382 = 0, $915 = 0, $916 = 0, $919 = 0, $tib2_0_lcssa_in_i384 = 0, $dimension_tib2_0_lcssa_i385 = 0, $tib2_0_lcssa_i386 = 0, $tib1_121_i389 = 0, $i_0_i392 = 0, $937 = 0, $945 = 0, $947 = 0, $948 = 0, $950 = 0, $954 = 0, $_r0_sroa_0_0_load607 = 0, $969 = 0, $974 = 0, $978 = 0, $tib1_0_ph_i353 = 0, $989 = 0, $tib1_0_lcssa_i356 = 0, $dimension_tib1_0_lcssa_i357 = 0, $994 = 0, $996 = 0, $dimension_tib1_029_i359 = 0, $999 = 0, $1000 = 0, $1003 = 0, $1005 = 0, $dimension_tib2_024_i361 = 0, $1008 = 0, $1009 = 0, $1012 = 0, $tib2_0_lcssa_in_i363 = 0, $dimension_tib2_0_lcssa_i364 = 0, $tib2_0_lcssa_i365 = 0, $tib1_121_i368 = 0, $i_0_i371 = 0, $1030 = 0, $1036 = 0, $1038 = 0, $1042 = 0, $1050 = 0, $1056 = 0, $1064 = 0, $1066 = 0, $1067 = 0, $1069 = 0, $1073 = 0, $1083 = 0, $1084 = 0, $1089 = 0, $1093 = 0, $tib1_0_ph_i332 = 0, $1104 = 0, $tib1_0_lcssa_i335 = 0, $dimension_tib1_0_lcssa_i336 = 0, $1109 = 0, $1111 = 0, $dimension_tib1_029_i338 = 0, $1114 = 0, $1115 = 0, $1118 = 0, $1120 = 0, $dimension_tib2_024_i340 = 0, $1123 = 0, $1124 = 0, $1127 = 0, $tib2_0_lcssa_in_i342 = 0, $dimension_tib2_0_lcssa_i343 = 0, $tib2_0_lcssa_i344 = 0, $tib1_121_i347 = 0, $i_0_i350 = 0, $1145 = 0, $1151 = 0, $1156 = 0, $1160 = 0, $tib1_0_ph_i311 = 0, $1171 = 0, $tib1_0_lcssa_i314 = 0, $dimension_tib1_0_lcssa_i315 = 0, $1176 = 0, $1178 = 0, $dimension_tib1_029_i317 = 0, $1181 = 0, $1182 = 0, $1185 = 0, $1187 = 0, $dimension_tib2_024_i319 = 0, $1190 = 0, $1191 = 0, $1194 = 0, $tib2_0_lcssa_in_i321 = 0, $dimension_tib2_0_lcssa_i322 = 0, $tib2_0_lcssa_i323 = 0, $tib1_121_i326 = 0, $i_0_i329 = 0, $1212 = 0, $1222 = 0, $1232 = 0, $1233 = 0, $1238 = 0, $1242 = 0, $tib1_0_ph_i290 = 0, $1253 = 0, $tib1_0_lcssa_i293 = 0, $dimension_tib1_0_lcssa_i294 = 0, $1258 = 0, $1260 = 0, $dimension_tib1_029_i296 = 0, $1263 = 0, $1264 = 0, $1267 = 0, $1269 = 0, $dimension_tib2_024_i298 = 0, $1272 = 0, $1273 = 0, $1276 = 0, $tib2_0_lcssa_in_i300 = 0, $dimension_tib2_0_lcssa_i301 = 0, $tib2_0_lcssa_i302 = 0, $tib1_121_i305 = 0, $i_0_i308 = 0, $1294 = 0, $1300 = 0, $1305 = 0, $1309 = 0, $tib1_0_ph_i269 = 0, $1320 = 0, $tib1_0_lcssa_i272 = 0, $dimension_tib1_0_lcssa_i273 = 0, $1325 = 0, $1327 = 0, $dimension_tib1_029_i275 = 0, $1330 = 0, $1331 = 0, $1334 = 0, $1336 = 0, $dimension_tib2_024_i277 = 0, $1339 = 0, $1340 = 0, $1343 = 0, $tib2_0_lcssa_in_i279 = 0, $dimension_tib2_0_lcssa_i280 = 0, $tib2_0_lcssa_i281 = 0, $tib1_121_i284 = 0, $i_0_i287 = 0, $1361 = 0, $1369 = 0, $1371 = 0, $1372 = 0, $1374 = 0, $1378 = 0, $_r0_sroa_0_0_load604 = 0, $1391 = 0, $1400 = 0, $1401 = 0, $1406 = 0, $1410 = 0, $tib1_0_ph_i248 = 0, $1421 = 0, $tib1_0_lcssa_i251 = 0, $dimension_tib1_0_lcssa_i252 = 0, $1426 = 0, $1428 = 0, $dimension_tib1_029_i254 = 0, $1431 = 0, $1432 = 0, $1435 = 0, $1437 = 0, $dimension_tib2_024_i256 = 0, $1440 = 0, $1441 = 0, $1444 = 0, $tib2_0_lcssa_in_i258 = 0, $dimension_tib2_0_lcssa_i259 = 0, $tib2_0_lcssa_i260 = 0, $tib1_121_i263 = 0, $i_0_i266 = 0, $1462 = 0, $1468 = 0, $1473 = 0, $1477 = 0, $tib1_0_ph_i227 = 0, $1488 = 0, $tib1_0_lcssa_i230 = 0, $dimension_tib1_0_lcssa_i231 = 0, $1493 = 0, $1495 = 0, $dimension_tib1_029_i233 = 0, $1498 = 0, $1499 = 0, $1502 = 0, $1504 = 0, $dimension_tib2_024_i235 = 0, $1507 = 0, $1508 = 0, $1511 = 0, $tib2_0_lcssa_in_i237 = 0, $dimension_tib2_0_lcssa_i238 = 0, $tib2_0_lcssa_i239 = 0, $tib1_121_i242 = 0, $i_0_i245 = 0, $1529 = 0, $1536 = 0, $1538 = 0, $1539 = 0, $1541 = 0, $1545 = 0, $1551 = 0, $1553 = 0, $_r0_sroa_0_0_load602 = 0, $1570 = 0, $1575 = 0, $1579 = 0, $tib1_0_ph_i185 = 0, $1590 = 0, $tib1_0_lcssa_i188 = 0, $dimension_tib1_0_lcssa_i189 = 0, $1595 = 0, $1597 = 0, $dimension_tib1_029_i191 = 0, $1600 = 0, $1601 = 0, $1604 = 0, $1606 = 0, $dimension_tib2_024_i193 = 0, $1609 = 0, $1610 = 0, $1613 = 0, $tib2_0_lcssa_in_i195 = 0, $dimension_tib2_0_lcssa_i196 = 0, $tib2_0_lcssa_i197 = 0, $tib1_121_i200 = 0, $i_0_i203 = 0, $1631 = 0, $1638 = 0, $1640 = 0, $1641 = 0, $1643 = 0, $1647 = 0, $1653 = 0, $1655 = 0, $_r2_sroa_0_0_load = 0, $1666 = 0, $1668 = 0, $1684 = 0, $1689 = 0, $1693 = 0, $tib1_0_ph_i = 0, $1704 = 0, $tib1_0_lcssa_i = 0, $dimension_tib1_0_lcssa_i = 0, $1709 = 0, $1711 = 0, $dimension_tib1_029_i = 0, $1714 = 0, $1715 = 0, $1718 = 0, $1720 = 0, $dimension_tib2_024_i = 0, $1723 = 0, $1724 = 0, $1727 = 0, $tib2_0_lcssa_in_i = 0, $dimension_tib2_0_lcssa_i = 0, $tib2_0_lcssa_i = 0, $tib1_121_i = 0, $i_0_i = 0, $1745 = 0, label = 0, __stackBase__ = 0, setjmpLabel = 0, setjmpTable = 0;
- __stackBase__ = STACKTOP;
- STACKTOP = STACKTOP + 536 | 0;
- label = 1;
- setjmpLabel = 0;
- setjmpTable = STACKTOP;
- STACKTOP = STACKTOP + 168 | 0;
- HEAP32[setjmpTable >> 2] = 0;
- while (1) switch (label | 0) {
- case 1:
-  $_r0_sroa_1 = __stackBase__ | 0;
-  $_r3_sroa_1 = __stackBase__ + 8 | 0;
-  $local_env_w4567aaac23b1b6 = __stackBase__ + 16 | 0;
-  $local_env_w4567aaac23b1c16 = __stackBase__ + 56 | 0;
-  $local_env_w4567aaac23b1c22 = __stackBase__ + 96 | 0;
-  $local_env_w4567aaac23b1c24 = __stackBase__ + 136 | 0;
-  $local_env_w4567aaac23b1c26 = __stackBase__ + 176 | 0;
-  $local_env_w4567aaac23b1c29 = __stackBase__ + 216 | 0;
-  $local_env_w4567aaac23b1c31 = __stackBase__ + 256 | 0;
-  $local_env_w4567aaac23b1c35 = __stackBase__ + 296 | 0;
-  $local_env_w4567aaac23b1c40 = __stackBase__ + 336 | 0;
-  $local_env_w4567aaac23b1c42 = __stackBase__ + 376 | 0;
-  $local_env_w4567aaac23b1c44 = __stackBase__ + 416 | 0;
-  $local_env_w4567aaac23b1c48 = __stackBase__ + 456 | 0;
-  $local_env_w4567aaac23b1c50 = __stackBase__ + 496 | 0;
-  if ((HEAP32[(98772 | 0) >> 2] | 0 | 0) == 0) {
-   label = 2;
-   break;
-  } else {
-   label = 3;
-   break;
-  }
- case 2:
-  invoke_v(702);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 3;
-  break;
- case 3:
-  $_r5_sroa_0 = $n1;
-  $5 = invoke_ii(556, 709 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $_r0_sroa_0 = $5;
-  if ((HEAP32[(98772 | 0) >> 2] | 0 | 0) == 0) {
-   label = 4;
-   break;
-  } else {
-   label = 5;
-   break;
-  }
- case 4:
-  invoke_v(702);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 5;
-  break;
- case 5:
-  $_r1_sroa_0 = HEAP32[136048 >> 2] | 0;
-  invoke_ii(202, $_r1_sroa_0 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  if ((HEAP32[(105500 | 0) >> 2] | 0 | 0) == 0) {
-   label = 6;
-   break;
-  } else {
-   label = 7;
-   break;
-  }
- case 6:
-  invoke_v(30);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 7;
-  break;
- case 7:
-  $16 = invoke_i(70) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $18 = invoke_iii(364, $16 | 0, 0 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $19 = $local_env_w4567aaac23b1b6;
-  $21 = $18 + 16 | 0;
-  _memcpy($19 | 0, HEAP32[$21 >> 2] | 0 | 0, 40);
-  $25 = _saveSetjmp(HEAP32[$21 >> 2] | 0 | 0, label, setjmpTable) | 0;
-  label = 413;
-  break;
- case 413:
-  if (($25 | 0) == 0) {
-   label = 8;
-   break;
-  } else {
-   label = 11;
-   break;
-  }
- case 8:
-  if ((HEAP32[(98772 | 0) >> 2] | 0 | 0) == 0) {
-   label = 9;
-   break;
-  } else {
-   label = 10;
-   break;
-  }
- case 9:
-  invoke_v(702);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 10;
-  break;
- case 10:
-  $_r0_sroa_0 = HEAP32[140056 >> 2] | 0;
-  $40 = invoke_iii(HEAP32[((HEAP32[($_r0_sroa_0 | 0) >> 2] | 0) + 160 | 0) >> 2] | 0 | 0, $_r0_sroa_0 | 0, $_r5_sroa_0 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $_r0_sroa_0 = $40;
-  $_r0_sroa_0 = $_r0_sroa_0;
-  _memcpy(HEAP32[$21 >> 2] | 0 | 0, $19 | 0, 40);
-  if (($_r0_sroa_0 | 0) == 0) {
-   label = 32;
-   break;
-  } else {
-   label = 28;
-   break;
-  }
- case 11:
-  _memcpy(HEAP32[$21 >> 2] | 0 | 0, $19 | 0, 40);
-  if ((HEAP32[(107740 | 0) >> 2] | 0 | 0) == 0) {
-   label = 12;
-   break;
-  } else {
-   label = 13;
-   break;
-  }
- case 12:
-  invoke_v(374);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 13;
-  break;
- case 13:
-  $52 = HEAP32[($18 + 20 | 0) >> 2] | 0;
-  if (($52 | 0) == 0) {
-   label = 27;
-   break;
-  } else {
-   label = 14;
-   break;
-  }
- case 14:
-  $57 = HEAP32[$52 >> 2] | 0;
-  $61 = HEAP32[((HEAP32[137616 >> 2] | 0) + 8 | 0) >> 2] | 0;
-  if (($57 | 0) == 82712) {
-   label = 15;
-   break;
-  } else {
-   $tib1_0_ph_i543 = $57;
-   label = 16;
-   break;
-  }
- case 15:
-  $tib1_0_ph_i543 = HEAP32[((HEAP32[($52 + 8 | 0) >> 2] | 0) + 8 | 0) >> 2] | 0;
-  label = 16;
-  break;
- case 16:
-  $72 = HEAP32[($tib1_0_ph_i543 + 56 | 0) >> 2] | 0;
-  if (($72 | 0) == 0) {
-   $dimension_tib1_0_lcssa_i547 = 0;
-   $tib1_0_lcssa_i546 = $tib1_0_ph_i543;
-   label = 18;
-   break;
-  } else {
-   $dimension_tib1_029_i549 = 0;
-   $79 = $72;
-   label = 19;
-   break;
-  }
- case 17:
-  $dimension_tib1_0_lcssa_i547 = $83;
-  $tib1_0_lcssa_i546 = $82;
-  label = 18;
-  break;
- case 18:
-  $77 = HEAP32[($61 + 56 | 0) >> 2] | 0;
-  if (($77 | 0) == 0) {
-   $dimension_tib2_0_lcssa_i554 = 0;
-   $tib2_0_lcssa_in_i553 = $61;
-   label = 21;
-   break;
-  } else {
-   $dimension_tib2_024_i551 = 0;
-   $88 = $77;
-   label = 20;
-   break;
-  }
- case 19:
-  $82 = HEAP32[($79 + 8 | 0) >> 2] | 0;
-  $83 = $dimension_tib1_029_i549 + 1 | 0;
-  $86 = HEAP32[($82 + 56 | 0) >> 2] | 0;
-  if (($86 | 0) == 0) {
-   label = 17;
-   break;
-  } else {
-   $dimension_tib1_029_i549 = $83;
-   $79 = $86;
-   label = 19;
-   break;
-  }
- case 20:
-  $91 = HEAP32[($88 + 8 | 0) >> 2] | 0;
-  $92 = $dimension_tib2_024_i551 + 1 | 0;
-  $95 = HEAP32[($91 + 56 | 0) >> 2] | 0;
-  if (($95 | 0) == 0) {
-   $dimension_tib2_0_lcssa_i554 = $92;
-   $tib2_0_lcssa_in_i553 = $91;
-   label = 21;
-   break;
-  } else {
-   $dimension_tib2_024_i551 = $92;
-   $88 = $95;
-   label = 20;
-   break;
-  }
- case 21:
-  $tib2_0_lcssa_i555 = $tib2_0_lcssa_in_i553;
-  if (($dimension_tib1_0_lcssa_i547 | 0) < ($dimension_tib2_0_lcssa_i554 | 0) | ($tib1_0_lcssa_i546 | 0) == 0) {
-   label = 27;
-   break;
-  } else {
-   $tib1_121_i558 = $tib1_0_lcssa_i546;
-   label = 22;
-   break;
-  }
- case 22:
-  if (($tib1_121_i558 | 0) == ($tib2_0_lcssa_i555 | 0)) {
-   label = 54;
-   break;
-  } else {
-   label = 23;
-   break;
-  }
- case 23:
-  $i_0_i561 = 0;
-  label = 24;
-  break;
- case 24:
-  if (($i_0_i561 | 0) < (HEAP32[($tib1_121_i558 + 108 | 0) >> 2] | 0 | 0)) {
-   label = 25;
-   break;
-  } else {
-   label = 26;
-   break;
-  }
- case 25:
-  if ((HEAP32[((HEAP32[($tib1_121_i558 + 112 | 0) >> 2] | 0) + ($i_0_i561 << 2) | 0) >> 2] | 0 | 0) == ($tib2_0_lcssa_i555 | 0)) {
-   label = 54;
-   break;
-  } else {
-   $i_0_i561 = $i_0_i561 + 1 | 0;
-   label = 24;
-   break;
-  }
- case 26:
-  $113 = HEAP32[($tib1_121_i558 + 40 | 0) >> 2] | 0;
-  if (($113 | 0) == 0) {
-   label = 27;
-   break;
-  } else {
-   $tib1_121_i558 = $113;
-   label = 22;
-   break;
-  }
- case 27:
-  invoke_vii(48, HEAP32[$21 >> 2] | 0 | 0, 0 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  return 0 | 0;
- case 28:
-  $_r1_sroa_0_0_load600 = $_r1_sroa_0;
-  $119 = $_r1_sroa_0_0_load600 + 4 | 0;
-  $122 = (HEAP32[$119 >> 2] | 0) + 8 | 0;
-  HEAP32[$122 >> 2] = (HEAP32[$122 >> 2] | 0) - 1 | 0;
-  if ((HEAP32[((HEAP32[$119 >> 2] | 0) + 8 | 0) >> 2] | 0 | 0) == 0) {
-   label = 29;
-   break;
-  } else {
-   label = 31;
-   break;
-  }
- case 29:
-  invoke_vi(28, $_r1_sroa_0_0_load600 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $139;
-  if (($139 | 0) == 0) {
-   label = 31;
-   break;
-  } else {
-   label = 30;
-   break;
-  }
- case 30:
-  invoke_iii(268, 31e3 | 0 | 0, (tempInt = STACKTOP, STACKTOP = STACKTOP + 8 | 0, HEAP32[tempInt >> 2] = $139, tempInt) | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 31;
-  break;
- case 31:
-  STACKTOP = __stackBase__;
-  return $_r0_sroa_0 | 0;
- case 32:
-  $145 = ($_r5_sroa_0 | 0) == 0;
-  if ((HEAP32[(105500 | 0) >> 2] | 0 | 0) == 0) {
-   label = 33;
-   break;
-  } else {
-   label = 34;
-   break;
-  }
- case 33:
-  invoke_v(30);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 34;
-  break;
- case 34:
-  $149 = invoke_i(70) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $151 = invoke_iii(364, $149 | 0, 0 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  if ($145) {
-   label = 35;
-   break;
-  } else {
-   label = 62;
-   break;
-  }
- case 35:
-  $153 = $local_env_w4567aaac23b1c16;
-  $155 = $151 + 16 | 0;
-  _memcpy($153 | 0, HEAP32[$155 >> 2] | 0 | 0, 40);
-  $159 = _saveSetjmp(HEAP32[$155 >> 2] | 0 | 0, label, setjmpTable) | 0;
-  label = 414;
-  break;
- case 414:
-  if (($159 | 0) == 0) {
-   label = 36;
-   break;
-  } else {
-   label = 37;
-   break;
-  }
- case 36:
-  invoke_viiii(14, 16136 | 0 | 0, 11648 | 0 | 0, 126872 | 0 | 0, 1457 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  return 0 | 0;
- case 37:
-  _memcpy(HEAP32[$155 >> 2] | 0 | 0, $153 | 0, 40);
-  if ((HEAP32[(107740 | 0) >> 2] | 0 | 0) == 0) {
-   label = 38;
-   break;
-  } else {
-   label = 39;
-   break;
-  }
- case 38:
-  invoke_v(374);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 39;
-  break;
- case 39:
-  $170 = HEAP32[($151 + 20 | 0) >> 2] | 0;
-  if (($170 | 0) == 0) {
-   label = 53;
-   break;
-  } else {
-   label = 40;
-   break;
-  }
- case 40:
-  $175 = HEAP32[$170 >> 2] | 0;
-  $179 = HEAP32[((HEAP32[137616 >> 2] | 0) + 8 | 0) >> 2] | 0;
-  if (($175 | 0) == 82712) {
-   label = 41;
-   break;
-  } else {
-   $tib1_0_ph_i521 = $175;
-   label = 42;
-   break;
-  }
- case 41:
-  $tib1_0_ph_i521 = HEAP32[((HEAP32[($170 + 8 | 0) >> 2] | 0) + 8 | 0) >> 2] | 0;
-  label = 42;
-  break;
- case 42:
-  $190 = HEAP32[($tib1_0_ph_i521 + 56 | 0) >> 2] | 0;
-  if (($190 | 0) == 0) {
-   $dimension_tib1_0_lcssa_i525 = 0;
-   $tib1_0_lcssa_i524 = $tib1_0_ph_i521;
-   label = 44;
-   break;
-  } else {
-   $dimension_tib1_029_i527 = 0;
-   $197 = $190;
-   label = 45;
-   break;
-  }
- case 43:
-  $dimension_tib1_0_lcssa_i525 = $201;
-  $tib1_0_lcssa_i524 = $200;
-  label = 44;
-  break;
- case 44:
-  $195 = HEAP32[($179 + 56 | 0) >> 2] | 0;
-  if (($195 | 0) == 0) {
-   $dimension_tib2_0_lcssa_i532 = 0;
-   $tib2_0_lcssa_in_i531 = $179;
-   label = 47;
-   break;
-  } else {
-   $dimension_tib2_024_i529 = 0;
-   $206 = $195;
-   label = 46;
-   break;
-  }
- case 45:
-  $200 = HEAP32[($197 + 8 | 0) >> 2] | 0;
-  $201 = $dimension_tib1_029_i527 + 1 | 0;
-  $204 = HEAP32[($200 + 56 | 0) >> 2] | 0;
-  if (($204 | 0) == 0) {
-   label = 43;
-   break;
-  } else {
-   $dimension_tib1_029_i527 = $201;
-   $197 = $204;
-   label = 45;
-   break;
-  }
- case 46:
-  $209 = HEAP32[($206 + 8 | 0) >> 2] | 0;
-  $210 = $dimension_tib2_024_i529 + 1 | 0;
-  $213 = HEAP32[($209 + 56 | 0) >> 2] | 0;
-  if (($213 | 0) == 0) {
-   $dimension_tib2_0_lcssa_i532 = $210;
-   $tib2_0_lcssa_in_i531 = $209;
-   label = 47;
-   break;
-  } else {
-   $dimension_tib2_024_i529 = $210;
-   $206 = $213;
-   label = 46;
-   break;
-  }
- case 47:
-  $tib2_0_lcssa_i533 = $tib2_0_lcssa_in_i531;
-  if (($dimension_tib1_0_lcssa_i525 | 0) < ($dimension_tib2_0_lcssa_i532 | 0) | ($tib1_0_lcssa_i524 | 0) == 0) {
-   label = 53;
-   break;
-  } else {
-   $tib1_121_i536 = $tib1_0_lcssa_i524;
-   label = 48;
-   break;
-  }
- case 48:
-  if (($tib1_121_i536 | 0) == ($tib2_0_lcssa_i533 | 0)) {
-   label = 54;
-   break;
-  } else {
-   label = 49;
-   break;
-  }
- case 49:
-  $i_0_i539 = 0;
-  label = 50;
-  break;
- case 50:
-  if (($i_0_i539 | 0) < (HEAP32[($tib1_121_i536 + 108 | 0) >> 2] | 0 | 0)) {
-   label = 51;
-   break;
-  } else {
-   label = 52;
-   break;
-  }
- case 51:
-  if ((HEAP32[((HEAP32[($tib1_121_i536 + 112 | 0) >> 2] | 0) + ($i_0_i539 << 2) | 0) >> 2] | 0 | 0) == ($tib2_0_lcssa_i533 | 0)) {
-   label = 54;
-   break;
-  } else {
-   $i_0_i539 = $i_0_i539 + 1 | 0;
-   label = 50;
-   break;
-  }
- case 52:
-  $231 = HEAP32[($tib1_121_i536 + 40 | 0) >> 2] | 0;
-  if (($231 | 0) == 0) {
-   label = 53;
-   break;
-  } else {
-   $tib1_121_i536 = $231;
-   label = 48;
-   break;
-  }
- case 53:
-  invoke_vii(48, HEAP32[$155 >> 2] | 0 | 0, 0 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  return 0 | 0;
- case 54:
-  if ((HEAP32[(105500 | 0) >> 2] | 0 | 0) == 0) {
-   label = 55;
-   break;
-  } else {
-   label = 56;
-   break;
-  }
- case 55:
-  invoke_v(30);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 56;
-  break;
- case 56:
-  $238 = invoke_i(70) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $240 = invoke_iii(364, $238 | 0, 0 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $_r0_sroa_0 = HEAP32[($240 + 20 | 0) >> 2] | 0;
-  $_r1_sroa_0_0_load = $_r1_sroa_0;
-  $246 = $_r1_sroa_0_0_load + 4 | 0;
-  $249 = (HEAP32[$246 >> 2] | 0) + 8 | 0;
-  HEAP32[$249 >> 2] = (HEAP32[$249 >> 2] | 0) - 1 | 0;
-  if ((HEAP32[((HEAP32[$246 >> 2] | 0) + 8 | 0) >> 2] | 0 | 0) == 0) {
-   label = 57;
-   break;
-  } else {
-   label = 59;
-   break;
-  }
- case 57:
-  invoke_vi(28, $_r1_sroa_0_0_load | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $266;
-  if (($266 | 0) == 0) {
-   label = 59;
-   break;
-  } else {
-   label = 58;
-   break;
-  }
- case 58:
-  invoke_iii(268, 31e3 | 0 | 0, (tempInt = STACKTOP, STACKTOP = STACKTOP + 8 | 0, HEAP32[tempInt >> 2] = $266, tempInt) | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 59;
-  break;
- case 59:
-  if ((HEAP32[(105500 | 0) >> 2] | 0 | 0) == 0) {
-   label = 60;
-   break;
-  } else {
-   label = 61;
-   break;
-  }
- case 60:
-  invoke_v(30);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 61;
-  break;
- case 61:
-  $273 = invoke_i(70) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $275 = invoke_iii(364, $273 | 0, 0 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  HEAP32[($275 + 20 | 0) >> 2] = $_r0_sroa_0;
-  invoke_vii(48, HEAP32[($275 + 16 | 0) >> 2] | 0 | 0, 0 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  return 0 | 0;
- case 62:
-  $284 = $local_env_w4567aaac23b1c22;
-  $286 = $151 + 16 | 0;
-  _memcpy($284 | 0, HEAP32[$286 >> 2] | 0 | 0, 40);
-  $290 = _saveSetjmp(HEAP32[$286 >> 2] | 0 | 0, label, setjmpTable) | 0;
-  label = 415;
-  break;
- case 415:
-  if (($290 | 0) == 0) {
-   label = 63;
-   break;
-  } else {
-   label = 72;
-   break;
-  }
- case 63:
-  invoke_vi(44, $_r5_sroa_0 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  if ((HEAP32[(98772 | 0) >> 2] | 0 | 0) == 0) {
-   label = 64;
-   break;
-  } else {
-   label = 65;
-   break;
-  }
- case 64:
-  invoke_v(702);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 65;
-  break;
- case 65:
-  $_r0_sroa_0 = HEAP32[140064 >> 2] | 0;
-  if (($_r0_sroa_0 | 0) == 0) {
-   label = 67;
-   break;
-  } else {
-   label = 66;
-   break;
-  }
- case 66:
-  _memcpy(HEAP32[$286 >> 2] | 0 | 0, $284 | 0, 40);
-  label = 89;
-  break;
- case 67:
-  if ((HEAP32[(84292 | 0) >> 2] | 0 | 0) == 0) {
-   label = 68;
-   break;
-  } else {
-   label = 69;
-   break;
-  }
- case 68:
-  invoke_v(584);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 69;
-  break;
- case 69:
-  $305 = invoke_ii(338, 20 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  HEAP32[$305 >> 2] = 84288;
-  _memset($305 + 4 | 0 | 0 | 0, 0 | 0 | 0, 16 | 0 | 0);
-  $_r0_sroa_0 = $305;
-  invoke_vi(34, $_r0_sroa_0 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $310 = $_r0_sroa_0;
-  if ((HEAP32[(98772 | 0) >> 2] | 0 | 0) == 0) {
-   label = 70;
-   break;
-  } else {
-   label = 71;
-   break;
-  }
- case 70:
-  invoke_v(702);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 71;
-  break;
- case 71:
-  HEAP32[140064 >> 2] = $310;
-  _memcpy(HEAP32[$286 >> 2] | 0 | 0, $284 | 0, 40);
-  label = 89;
-  break;
- case 72:
-  _memcpy(HEAP32[$286 >> 2] | 0 | 0, $284 | 0, 40);
-  if ((HEAP32[(107740 | 0) >> 2] | 0 | 0) == 0) {
-   label = 73;
-   break;
-  } else {
-   label = 74;
-   break;
-  }
- case 73:
-  invoke_v(374);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 74;
-  break;
- case 74:
-  $323 = HEAP32[($151 + 20 | 0) >> 2] | 0;
-  if (($323 | 0) == 0) {
-   label = 88;
-   break;
-  } else {
-   label = 75;
-   break;
-  }
- case 75:
-  $328 = HEAP32[$323 >> 2] | 0;
-  $332 = HEAP32[((HEAP32[137616 >> 2] | 0) + 8 | 0) >> 2] | 0;
-  if (($328 | 0) == 82712) {
-   label = 76;
-   break;
-  } else {
-   $tib1_0_ph_i500 = $328;
-   label = 77;
-   break;
-  }
- case 76:
-  $tib1_0_ph_i500 = HEAP32[((HEAP32[($323 + 8 | 0) >> 2] | 0) + 8 | 0) >> 2] | 0;
-  label = 77;
-  break;
- case 77:
-  $343 = HEAP32[($tib1_0_ph_i500 + 56 | 0) >> 2] | 0;
-  if (($343 | 0) == 0) {
-   $dimension_tib1_0_lcssa_i504 = 0;
-   $tib1_0_lcssa_i503 = $tib1_0_ph_i500;
-   label = 79;
-   break;
-  } else {
-   $dimension_tib1_029_i506 = 0;
-   $350 = $343;
-   label = 80;
-   break;
-  }
- case 78:
-  $dimension_tib1_0_lcssa_i504 = $354;
-  $tib1_0_lcssa_i503 = $353;
-  label = 79;
-  break;
- case 79:
-  $348 = HEAP32[($332 + 56 | 0) >> 2] | 0;
-  if (($348 | 0) == 0) {
-   $dimension_tib2_0_lcssa_i511 = 0;
-   $tib2_0_lcssa_in_i510 = $332;
-   label = 82;
-   break;
-  } else {
-   $dimension_tib2_024_i508 = 0;
-   $359 = $348;
-   label = 81;
-   break;
-  }
- case 80:
-  $353 = HEAP32[($350 + 8 | 0) >> 2] | 0;
-  $354 = $dimension_tib1_029_i506 + 1 | 0;
-  $357 = HEAP32[($353 + 56 | 0) >> 2] | 0;
-  if (($357 | 0) == 0) {
-   label = 78;
-   break;
-  } else {
-   $dimension_tib1_029_i506 = $354;
-   $350 = $357;
-   label = 80;
-   break;
-  }
- case 81:
-  $362 = HEAP32[($359 + 8 | 0) >> 2] | 0;
-  $363 = $dimension_tib2_024_i508 + 1 | 0;
-  $366 = HEAP32[($362 + 56 | 0) >> 2] | 0;
-  if (($366 | 0) == 0) {
-   $dimension_tib2_0_lcssa_i511 = $363;
-   $tib2_0_lcssa_in_i510 = $362;
-   label = 82;
-   break;
-  } else {
-   $dimension_tib2_024_i508 = $363;
-   $359 = $366;
-   label = 81;
-   break;
-  }
- case 82:
-  $tib2_0_lcssa_i512 = $tib2_0_lcssa_in_i510;
-  if (($dimension_tib1_0_lcssa_i504 | 0) < ($dimension_tib2_0_lcssa_i511 | 0) | ($tib1_0_lcssa_i503 | 0) == 0) {
-   label = 88;
-   break;
-  } else {
-   $tib1_121_i515 = $tib1_0_lcssa_i503;
-   label = 83;
-   break;
-  }
- case 83:
-  if (($tib1_121_i515 | 0) == ($tib2_0_lcssa_i512 | 0)) {
-   label = 54;
-   break;
-  } else {
-   label = 84;
-   break;
-  }
- case 84:
-  $i_0_i518 = 0;
-  label = 85;
-  break;
- case 85:
-  if (($i_0_i518 | 0) < (HEAP32[($tib1_121_i515 + 108 | 0) >> 2] | 0 | 0)) {
-   label = 86;
-   break;
-  } else {
-   label = 87;
-   break;
-  }
- case 86:
-  if ((HEAP32[((HEAP32[($tib1_121_i515 + 112 | 0) >> 2] | 0) + ($i_0_i518 << 2) | 0) >> 2] | 0 | 0) == ($tib2_0_lcssa_i512 | 0)) {
-   label = 54;
-   break;
-  } else {
-   $i_0_i518 = $i_0_i518 + 1 | 0;
-   label = 85;
-   break;
-  }
- case 87:
-  $384 = HEAP32[($tib1_121_i515 + 40 | 0) >> 2] | 0;
-  if (($384 | 0) == 0) {
-   label = 88;
-   break;
-  } else {
-   $tib1_121_i515 = $384;
-   label = 83;
-   break;
-  }
- case 88:
-  invoke_vii(48, HEAP32[$286 >> 2] | 0 | 0, 0 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  return 0 | 0;
- case 89:
-  if ((HEAP32[(105500 | 0) >> 2] | 0 | 0) == 0) {
-   label = 90;
-   break;
-  } else {
-   label = 91;
-   break;
-  }
- case 90:
-  invoke_v(30);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 91;
-  break;
- case 91:
-  $392 = invoke_i(70) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $394 = invoke_iii(364, $392 | 0, 0 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $395 = $local_env_w4567aaac23b1c24;
-  $397 = $394 + 16 | 0;
-  _memcpy($395 | 0, HEAP32[$397 >> 2] | 0 | 0, 40);
-  $401 = _saveSetjmp(HEAP32[$397 >> 2] | 0 | 0, label, setjmpTable) | 0;
-  label = 416;
-  break;
- case 416:
-  if (($401 | 0) == 0) {
-   label = 92;
-   break;
-  } else {
-   label = 99;
-   break;
-  }
- case 92:
-  if ((HEAP32[(98772 | 0) >> 2] | 0 | 0) == 0) {
-   label = 93;
-   break;
-  } else {
-   label = 94;
-   break;
-  }
- case 93:
-  invoke_v(702);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 94;
-  break;
- case 94:
-  $_r0_sroa_0 = HEAP32[140064 >> 2] | 0;
-  $416 = invoke_iii(HEAP32[((HEAP32[($_r0_sroa_0 | 0) >> 2] | 0) + 144 | 0) >> 2] | 0 | 0, $_r0_sroa_0 | 0, $_r5_sroa_0 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $_r0_sroa_0 = $416;
-  if (($_r0_sroa_0 | 0) == 0) {
-   label = 95;
-   break;
-  } else {
-   label = 98;
-   break;
-  }
- case 95:
-  _memcpy(HEAP32[$397 >> 2] | 0 | 0, $395 | 0, 40);
-  if ((HEAP32[(105500 | 0) >> 2] | 0 | 0) == 0) {
-   label = 96;
-   break;
-  } else {
-   label = 97;
-   break;
-  }
- case 96:
-  invoke_v(30);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 97;
-  break;
- case 97:
-  $424 = invoke_i(70) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $426 = invoke_iii(364, $424 | 0, 0 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $427 = $local_env_w4567aaac23b1c26;
-  $429 = $426 + 16 | 0;
-  _memcpy($427 | 0, HEAP32[$429 >> 2] | 0 | 0, 40);
-  $433 = _saveSetjmp(HEAP32[$429 >> 2] | 0 | 0, label, setjmpTable) | 0;
-  label = 417;
-  break;
- case 417:
-  if (($433 | 0) == 0) {
-   label = 116;
-   break;
-  } else {
-   label = 127;
-   break;
-  }
- case 98:
-  invoke_vii(24, $_r0_sroa_0 | 0, $_r5_sroa_0 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  _memcpy(HEAP32[$397 >> 2] | 0 | 0, $395 | 0, 40);
-  label = 28;
-  break;
- case 99:
-  _memcpy(HEAP32[$397 >> 2] | 0 | 0, $395 | 0, 40);
-  if ((HEAP32[(107740 | 0) >> 2] | 0 | 0) == 0) {
-   label = 100;
-   break;
-  } else {
-   label = 101;
-   break;
-  }
- case 100:
-  invoke_v(374);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 101;
-  break;
- case 101:
-  $446 = HEAP32[($394 + 20 | 0) >> 2] | 0;
-  if (($446 | 0) == 0) {
-   label = 115;
-   break;
-  } else {
-   label = 102;
-   break;
-  }
- case 102:
-  $451 = HEAP32[$446 >> 2] | 0;
-  $455 = HEAP32[((HEAP32[137616 >> 2] | 0) + 8 | 0) >> 2] | 0;
-  if (($451 | 0) == 82712) {
-   label = 103;
-   break;
-  } else {
-   $tib1_0_ph_i479 = $451;
-   label = 104;
-   break;
-  }
- case 103:
-  $tib1_0_ph_i479 = HEAP32[((HEAP32[($446 + 8 | 0) >> 2] | 0) + 8 | 0) >> 2] | 0;
-  label = 104;
-  break;
- case 104:
-  $466 = HEAP32[($tib1_0_ph_i479 + 56 | 0) >> 2] | 0;
-  if (($466 | 0) == 0) {
-   $dimension_tib1_0_lcssa_i483 = 0;
-   $tib1_0_lcssa_i482 = $tib1_0_ph_i479;
-   label = 106;
-   break;
-  } else {
-   $dimension_tib1_029_i485 = 0;
-   $473 = $466;
-   label = 107;
-   break;
-  }
- case 105:
-  $dimension_tib1_0_lcssa_i483 = $477;
-  $tib1_0_lcssa_i482 = $476;
-  label = 106;
-  break;
- case 106:
-  $471 = HEAP32[($455 + 56 | 0) >> 2] | 0;
-  if (($471 | 0) == 0) {
-   $dimension_tib2_0_lcssa_i490 = 0;
-   $tib2_0_lcssa_in_i489 = $455;
-   label = 109;
-   break;
-  } else {
-   $dimension_tib2_024_i487 = 0;
-   $482 = $471;
-   label = 108;
-   break;
-  }
- case 107:
-  $476 = HEAP32[($473 + 8 | 0) >> 2] | 0;
-  $477 = $dimension_tib1_029_i485 + 1 | 0;
-  $480 = HEAP32[($476 + 56 | 0) >> 2] | 0;
-  if (($480 | 0) == 0) {
-   label = 105;
-   break;
-  } else {
-   $dimension_tib1_029_i485 = $477;
-   $473 = $480;
-   label = 107;
-   break;
-  }
- case 108:
-  $485 = HEAP32[($482 + 8 | 0) >> 2] | 0;
-  $486 = $dimension_tib2_024_i487 + 1 | 0;
-  $489 = HEAP32[($485 + 56 | 0) >> 2] | 0;
-  if (($489 | 0) == 0) {
-   $dimension_tib2_0_lcssa_i490 = $486;
-   $tib2_0_lcssa_in_i489 = $485;
-   label = 109;
-   break;
-  } else {
-   $dimension_tib2_024_i487 = $486;
-   $482 = $489;
-   label = 108;
-   break;
-  }
- case 109:
-  $tib2_0_lcssa_i491 = $tib2_0_lcssa_in_i489;
-  if (($dimension_tib1_0_lcssa_i483 | 0) < ($dimension_tib2_0_lcssa_i490 | 0) | ($tib1_0_lcssa_i482 | 0) == 0) {
-   label = 115;
-   break;
-  } else {
-   $tib1_121_i494 = $tib1_0_lcssa_i482;
-   label = 110;
-   break;
-  }
- case 110:
-  if (($tib1_121_i494 | 0) == ($tib2_0_lcssa_i491 | 0)) {
-   label = 54;
-   break;
-  } else {
-   label = 111;
-   break;
-  }
- case 111:
-  $i_0_i497 = 0;
-  label = 112;
-  break;
- case 112:
-  if (($i_0_i497 | 0) < (HEAP32[($tib1_121_i494 + 108 | 0) >> 2] | 0 | 0)) {
-   label = 113;
-   break;
-  } else {
-   label = 114;
-   break;
-  }
- case 113:
-  if ((HEAP32[((HEAP32[($tib1_121_i494 + 112 | 0) >> 2] | 0) + ($i_0_i497 << 2) | 0) >> 2] | 0 | 0) == ($tib2_0_lcssa_i491 | 0)) {
-   label = 54;
-   break;
-  } else {
-   $i_0_i497 = $i_0_i497 + 1 | 0;
-   label = 112;
-   break;
-  }
- case 114:
-  $507 = HEAP32[($tib1_121_i494 + 40 | 0) >> 2] | 0;
-  if (($507 | 0) == 0) {
-   label = 115;
-   break;
-  } else {
-   $tib1_121_i494 = $507;
-   label = 110;
-   break;
-  }
- case 115:
-  invoke_vii(48, HEAP32[$397 >> 2] | 0 | 0, 0 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  return 0 | 0;
- case 116:
-  if ((HEAP32[(98772 | 0) >> 2] | 0 | 0) == 0) {
-   label = 117;
-   break;
-  } else {
-   label = 118;
-   break;
-  }
- case 117:
-  invoke_v(702);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 118;
-  break;
- case 118:
-  if ((HEAP32[(105500 | 0) >> 2] | 0 | 0) == 0) {
-   label = 119;
-   break;
-  } else {
-   label = 120;
-   break;
-  }
- case 119:
-  invoke_v(30);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 120;
-  break;
- case 120:
-  $519 = invoke_i(70) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $521 = invoke_iii(364, $519 | 0, 0 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  if ((HEAP32[(98148 | 0) >> 2] | 0 | 0) == 0) {
-   label = 121;
-   break;
-  } else {
-   label = 122;
-   break;
-  }
- case 121:
-  invoke_v(408);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 122;
-  break;
- case 122:
-  $525 = invoke_ii(338, 12 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  HEAP32[$525 >> 2] = 98144;
-  HEAP32[($525 + 4 | 0) >> 2] = 0;
-  HEAP32[($525 + 8 | 0) >> 2] = $521;
-  if ((HEAP32[(97532 | 0) >> 2] | 0 | 0) == 0) {
-   label = 123;
-   break;
-  } else {
-   $534 = 98144;
-   label = 124;
-   break;
-  }
- case 123:
-  invoke_v(568);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $534 = HEAP32[$525 >> 2] | 0;
-  label = 124;
-  break;
- case 124:
-  $539 = invoke_ii(HEAP32[(HEAP32[($534 + 116 | 0) >> 2] | 0) >> 2] | 0 | 0, $525 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $_r2_sroa_0 = $539;
-  _memcpy(HEAP32[$429 >> 2] | 0 | 0, $427 | 0, 40);
-  $542 = ($_r2_sroa_0 | 0) == 0;
-  if ((HEAP32[(105500 | 0) >> 2] | 0 | 0) == 0) {
-   label = 125;
-   break;
-  } else {
-   label = 126;
-   break;
-  }
- case 125:
-  invoke_v(30);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 126;
-  break;
- case 126:
-  $546 = invoke_i(70) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $548 = invoke_iii(364, $546 | 0, 0 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  if ($542) {
-   label = 240;
-   break;
-  } else {
-   label = 144;
-   break;
-  }
- case 127:
-  _memcpy(HEAP32[$429 >> 2] | 0 | 0, $427 | 0, 40);
-  if ((HEAP32[(107740 | 0) >> 2] | 0 | 0) == 0) {
-   label = 128;
-   break;
-  } else {
-   label = 129;
-   break;
-  }
- case 128:
-  invoke_v(374);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 129;
-  break;
- case 129:
-  $557 = HEAP32[($426 + 20 | 0) >> 2] | 0;
-  if (($557 | 0) == 0) {
-   label = 143;
-   break;
-  } else {
-   label = 130;
-   break;
-  }
- case 130:
-  $562 = HEAP32[$557 >> 2] | 0;
-  $566 = HEAP32[((HEAP32[137616 >> 2] | 0) + 8 | 0) >> 2] | 0;
-  if (($562 | 0) == 82712) {
-   label = 131;
-   break;
-  } else {
-   $tib1_0_ph_i458 = $562;
-   label = 132;
-   break;
-  }
- case 131:
-  $tib1_0_ph_i458 = HEAP32[((HEAP32[($557 + 8 | 0) >> 2] | 0) + 8 | 0) >> 2] | 0;
-  label = 132;
-  break;
- case 132:
-  $577 = HEAP32[($tib1_0_ph_i458 + 56 | 0) >> 2] | 0;
-  if (($577 | 0) == 0) {
-   $dimension_tib1_0_lcssa_i462 = 0;
-   $tib1_0_lcssa_i461 = $tib1_0_ph_i458;
-   label = 134;
-   break;
-  } else {
-   $dimension_tib1_029_i464 = 0;
-   $584 = $577;
-   label = 135;
-   break;
-  }
- case 133:
-  $dimension_tib1_0_lcssa_i462 = $588;
-  $tib1_0_lcssa_i461 = $587;
-  label = 134;
-  break;
- case 134:
-  $582 = HEAP32[($566 + 56 | 0) >> 2] | 0;
-  if (($582 | 0) == 0) {
-   $dimension_tib2_0_lcssa_i469 = 0;
-   $tib2_0_lcssa_in_i468 = $566;
-   label = 137;
-   break;
-  } else {
-   $dimension_tib2_024_i466 = 0;
-   $593 = $582;
-   label = 136;
-   break;
-  }
- case 135:
-  $587 = HEAP32[($584 + 8 | 0) >> 2] | 0;
-  $588 = $dimension_tib1_029_i464 + 1 | 0;
-  $591 = HEAP32[($587 + 56 | 0) >> 2] | 0;
-  if (($591 | 0) == 0) {
-   label = 133;
-   break;
-  } else {
-   $dimension_tib1_029_i464 = $588;
-   $584 = $591;
-   label = 135;
-   break;
-  }
- case 136:
-  $596 = HEAP32[($593 + 8 | 0) >> 2] | 0;
-  $597 = $dimension_tib2_024_i466 + 1 | 0;
-  $600 = HEAP32[($596 + 56 | 0) >> 2] | 0;
-  if (($600 | 0) == 0) {
-   $dimension_tib2_0_lcssa_i469 = $597;
-   $tib2_0_lcssa_in_i468 = $596;
-   label = 137;
-   break;
-  } else {
-   $dimension_tib2_024_i466 = $597;
-   $593 = $600;
-   label = 136;
-   break;
-  }
- case 137:
-  $tib2_0_lcssa_i470 = $tib2_0_lcssa_in_i468;
-  if (($dimension_tib1_0_lcssa_i462 | 0) < ($dimension_tib2_0_lcssa_i469 | 0) | ($tib1_0_lcssa_i461 | 0) == 0) {
-   label = 143;
-   break;
-  } else {
-   $tib1_121_i473 = $tib1_0_lcssa_i461;
-   label = 138;
-   break;
-  }
- case 138:
-  if (($tib1_121_i473 | 0) == ($tib2_0_lcssa_i470 | 0)) {
-   label = 54;
-   break;
-  } else {
-   label = 139;
-   break;
-  }
- case 139:
-  $i_0_i476 = 0;
-  label = 140;
-  break;
- case 140:
-  if (($i_0_i476 | 0) < (HEAP32[($tib1_121_i473 + 108 | 0) >> 2] | 0 | 0)) {
-   label = 141;
-   break;
-  } else {
-   label = 142;
-   break;
-  }
- case 141:
-  if ((HEAP32[((HEAP32[($tib1_121_i473 + 112 | 0) >> 2] | 0) + ($i_0_i476 << 2) | 0) >> 2] | 0 | 0) == ($tib2_0_lcssa_i470 | 0)) {
-   label = 54;
-   break;
-  } else {
-   $i_0_i476 = $i_0_i476 + 1 | 0;
-   label = 140;
-   break;
-  }
- case 142:
-  $618 = HEAP32[($tib1_121_i473 + 40 | 0) >> 2] | 0;
-  if (($618 | 0) == 0) {
-   label = 143;
-   break;
-  } else {
-   $tib1_121_i473 = $618;
-   label = 138;
-   break;
-  }
- case 143:
-  invoke_vii(48, HEAP32[$429 >> 2] | 0 | 0, 0 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  return 0 | 0;
- case 144:
-  $623 = $local_env_w4567aaac23b1c29;
-  $625 = $548 + 16 | 0;
-  _memcpy($623 | 0, HEAP32[$625 >> 2] | 0 | 0, 40);
-  $629 = _saveSetjmp(HEAP32[$625 >> 2] | 0 | 0, label, setjmpTable) | 0;
-  label = 418;
-  break;
- case 418:
-  if (($629 | 0) == 0) {
-   label = 145;
-   break;
-  } else {
-   label = 146;
-   break;
-  }
- case 145:
-  $632 = invoke_ii(556, 709 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $_r0_sroa_0 = $632;
-  $_r0_sroa_0 = 0;
-  $_r3_sroa_0 = $_r0_sroa_0;
-  HEAP32[($_r3_sroa_1 | 0) >> 2] = HEAP32[($_r0_sroa_1 | 0) >> 2] | 0;
-  _memcpy(HEAP32[$625 >> 2] | 0 | 0, $623 | 0, 40);
-  label = 179;
-  break;
- case 146:
-  _memcpy(HEAP32[$625 >> 2] | 0 | 0, $623 | 0, 40);
-  if ((HEAP32[(113236 | 0) >> 2] | 0 | 0) == 0) {
-   label = 147;
-   break;
-  } else {
-   label = 148;
-   break;
-  }
- case 147:
-  invoke_v(538);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 148;
-  break;
- case 148:
-  $643 = $548 + 20 | 0;
-  $644 = HEAP32[$643 >> 2] | 0;
-  if (($644 | 0) == 0) {
-   label = 162;
-   break;
-  } else {
-   label = 149;
-   break;
-  }
- case 149:
-  $649 = HEAP32[$644 >> 2] | 0;
-  $653 = HEAP32[((HEAP32[138672 >> 2] | 0) + 8 | 0) >> 2] | 0;
-  if (($649 | 0) == 82712) {
-   label = 150;
-   break;
-  } else {
-   $tib1_0_ph_i437 = $649;
-   label = 151;
-   break;
-  }
- case 150:
-  $tib1_0_ph_i437 = HEAP32[((HEAP32[($644 + 8 | 0) >> 2] | 0) + 8 | 0) >> 2] | 0;
-  label = 151;
-  break;
- case 151:
-  $664 = HEAP32[($tib1_0_ph_i437 + 56 | 0) >> 2] | 0;
-  if (($664 | 0) == 0) {
-   $dimension_tib1_0_lcssa_i441 = 0;
-   $tib1_0_lcssa_i440 = $tib1_0_ph_i437;
-   label = 153;
-   break;
-  } else {
-   $dimension_tib1_029_i443 = 0;
-   $671 = $664;
-   label = 154;
-   break;
-  }
- case 152:
-  $dimension_tib1_0_lcssa_i441 = $675;
-  $tib1_0_lcssa_i440 = $674;
-  label = 153;
-  break;
- case 153:
-  $669 = HEAP32[($653 + 56 | 0) >> 2] | 0;
-  if (($669 | 0) == 0) {
-   $dimension_tib2_0_lcssa_i448 = 0;
-   $tib2_0_lcssa_in_i447 = $653;
-   label = 156;
-   break;
-  } else {
-   $dimension_tib2_024_i445 = 0;
-   $680 = $669;
-   label = 155;
-   break;
-  }
- case 154:
-  $674 = HEAP32[($671 + 8 | 0) >> 2] | 0;
-  $675 = $dimension_tib1_029_i443 + 1 | 0;
-  $678 = HEAP32[($674 + 56 | 0) >> 2] | 0;
-  if (($678 | 0) == 0) {
-   label = 152;
-   break;
-  } else {
-   $dimension_tib1_029_i443 = $675;
-   $671 = $678;
-   label = 154;
-   break;
-  }
- case 155:
-  $683 = HEAP32[($680 + 8 | 0) >> 2] | 0;
-  $684 = $dimension_tib2_024_i445 + 1 | 0;
-  $687 = HEAP32[($683 + 56 | 0) >> 2] | 0;
-  if (($687 | 0) == 0) {
-   $dimension_tib2_0_lcssa_i448 = $684;
-   $tib2_0_lcssa_in_i447 = $683;
-   label = 156;
-   break;
-  } else {
-   $dimension_tib2_024_i445 = $684;
-   $680 = $687;
-   label = 155;
-   break;
-  }
- case 156:
-  $tib2_0_lcssa_i449 = $tib2_0_lcssa_in_i447;
-  if (($dimension_tib1_0_lcssa_i441 | 0) < ($dimension_tib2_0_lcssa_i448 | 0) | ($tib1_0_lcssa_i440 | 0) == 0) {
-   label = 162;
-   break;
-  } else {
-   $tib1_121_i452 = $tib1_0_lcssa_i440;
-   label = 157;
-   break;
-  }
- case 157:
-  if (($tib1_121_i452 | 0) == ($tib2_0_lcssa_i449 | 0)) {
-   label = 361;
-   break;
-  } else {
-   label = 158;
-   break;
-  }
- case 158:
-  $i_0_i455 = 0;
-  label = 159;
-  break;
- case 159:
-  if (($i_0_i455 | 0) < (HEAP32[($tib1_121_i452 + 108 | 0) >> 2] | 0 | 0)) {
-   label = 160;
-   break;
-  } else {
-   label = 161;
-   break;
-  }
- case 160:
-  if ((HEAP32[((HEAP32[($tib1_121_i452 + 112 | 0) >> 2] | 0) + ($i_0_i455 << 2) | 0) >> 2] | 0 | 0) == ($tib2_0_lcssa_i449 | 0)) {
-   label = 361;
-   break;
-  } else {
-   $i_0_i455 = $i_0_i455 + 1 | 0;
-   label = 159;
-   break;
-  }
- case 161:
-  $705 = HEAP32[($tib1_121_i452 + 40 | 0) >> 2] | 0;
-  if (($705 | 0) == 0) {
-   label = 162;
-   break;
-  } else {
-   $tib1_121_i452 = $705;
-   label = 157;
-   break;
-  }
- case 162:
-  if ((HEAP32[(107740 | 0) >> 2] | 0 | 0) == 0) {
-   label = 163;
-   break;
-  } else {
-   label = 164;
-   break;
-  }
- case 163:
-  invoke_v(374);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 164;
-  break;
- case 164:
-  $711 = HEAP32[$643 >> 2] | 0;
-  if (($711 | 0) == 0) {
-   label = 178;
-   break;
-  } else {
-   label = 165;
-   break;
-  }
- case 165:
-  $716 = HEAP32[$711 >> 2] | 0;
-  $720 = HEAP32[((HEAP32[137616 >> 2] | 0) + 8 | 0) >> 2] | 0;
-  if (($716 | 0) == 82712) {
-   label = 166;
-   break;
-  } else {
-   $tib1_0_ph_i416 = $716;
-   label = 167;
-   break;
-  }
- case 166:
-  $tib1_0_ph_i416 = HEAP32[((HEAP32[($711 + 8 | 0) >> 2] | 0) + 8 | 0) >> 2] | 0;
-  label = 167;
-  break;
- case 167:
-  $731 = HEAP32[($tib1_0_ph_i416 + 56 | 0) >> 2] | 0;
-  if (($731 | 0) == 0) {
-   $dimension_tib1_0_lcssa_i420 = 0;
-   $tib1_0_lcssa_i419 = $tib1_0_ph_i416;
-   label = 169;
-   break;
-  } else {
-   $dimension_tib1_029_i422 = 0;
-   $738 = $731;
-   label = 170;
-   break;
-  }
- case 168:
-  $dimension_tib1_0_lcssa_i420 = $742;
-  $tib1_0_lcssa_i419 = $741;
-  label = 169;
-  break;
- case 169:
-  $736 = HEAP32[($720 + 56 | 0) >> 2] | 0;
-  if (($736 | 0) == 0) {
-   $dimension_tib2_0_lcssa_i427 = 0;
-   $tib2_0_lcssa_in_i426 = $720;
-   label = 172;
-   break;
-  } else {
-   $dimension_tib2_024_i424 = 0;
-   $747 = $736;
-   label = 171;
-   break;
-  }
- case 170:
-  $741 = HEAP32[($738 + 8 | 0) >> 2] | 0;
-  $742 = $dimension_tib1_029_i422 + 1 | 0;
-  $745 = HEAP32[($741 + 56 | 0) >> 2] | 0;
-  if (($745 | 0) == 0) {
-   label = 168;
-   break;
-  } else {
-   $dimension_tib1_029_i422 = $742;
-   $738 = $745;
-   label = 170;
-   break;
-  }
- case 171:
-  $750 = HEAP32[($747 + 8 | 0) >> 2] | 0;
-  $751 = $dimension_tib2_024_i424 + 1 | 0;
-  $754 = HEAP32[($750 + 56 | 0) >> 2] | 0;
-  if (($754 | 0) == 0) {
-   $dimension_tib2_0_lcssa_i427 = $751;
-   $tib2_0_lcssa_in_i426 = $750;
-   label = 172;
-   break;
-  } else {
-   $dimension_tib2_024_i424 = $751;
-   $747 = $754;
-   label = 171;
-   break;
-  }
- case 172:
-  $tib2_0_lcssa_i428 = $tib2_0_lcssa_in_i426;
-  if (($dimension_tib1_0_lcssa_i420 | 0) < ($dimension_tib2_0_lcssa_i427 | 0) | ($tib1_0_lcssa_i419 | 0) == 0) {
-   label = 178;
-   break;
-  } else {
-   $tib1_121_i431 = $tib1_0_lcssa_i419;
-   label = 173;
-   break;
-  }
- case 173:
-  if (($tib1_121_i431 | 0) == ($tib2_0_lcssa_i428 | 0)) {
-   label = 386;
-   break;
-  } else {
-   label = 174;
-   break;
-  }
- case 174:
-  $i_0_i434 = 0;
-  label = 175;
-  break;
- case 175:
-  if (($i_0_i434 | 0) < (HEAP32[($tib1_121_i431 + 108 | 0) >> 2] | 0 | 0)) {
-   label = 176;
-   break;
-  } else {
-   label = 177;
-   break;
-  }
- case 176:
-  if ((HEAP32[((HEAP32[($tib1_121_i431 + 112 | 0) >> 2] | 0) + ($i_0_i434 << 2) | 0) >> 2] | 0 | 0) == ($tib2_0_lcssa_i428 | 0)) {
-   label = 386;
-   break;
-  } else {
-   $i_0_i434 = $i_0_i434 + 1 | 0;
-   label = 175;
-   break;
-  }
- case 177:
-  $772 = HEAP32[($tib1_121_i431 + 40 | 0) >> 2] | 0;
-  if (($772 | 0) == 0) {
-   label = 178;
-   break;
-  } else {
-   $tib1_121_i431 = $772;
-   label = 173;
-   break;
-  }
- case 178:
-  invoke_vii(48, HEAP32[$625 >> 2] | 0 | 0, 0 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  return 0 | 0;
- case 179:
-  if ((HEAP32[(105500 | 0) >> 2] | 0 | 0) == 0) {
-   label = 180;
-   break;
-  } else {
-   label = 181;
-   break;
-  }
- case 180:
-  invoke_v(30);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 181;
-  break;
- case 181:
-  $780 = invoke_i(70) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $782 = invoke_iii(364, $780 | 0, 0 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $783 = $local_env_w4567aaac23b1c31;
-  $785 = $782 + 16 | 0;
-  _memcpy($783 | 0, HEAP32[$785 >> 2] | 0 | 0, 40);
-  $789 = _saveSetjmp(HEAP32[$785 >> 2] | 0 | 0, label, setjmpTable) | 0;
-  label = 419;
-  break;
- case 419:
-  if (($789 | 0) == 0) {
-   label = 182;
-   break;
-  } else {
-   label = 183;
-   break;
-  }
- case 182:
-  $798 = invoke_ii(HEAP32[(HEAP32[((HEAP32[$_r3_sroa_0 >> 2] | 0) + 116 | 0) >> 2] | 0) >> 2] | 0 | 0, $_r3_sroa_0 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $_r0_sroa_0 = $798;
-  _memcpy(HEAP32[$785 >> 2] | 0 | 0, $783 | 0, 40);
-  if (($_r0_sroa_0 | 0) == 0) {
-   label = 216;
-   break;
-  } else {
-   label = 322;
-   break;
-  }
- case 183:
-  _memcpy(HEAP32[$785 >> 2] | 0 | 0, $783 | 0, 40);
-  if ((HEAP32[(113236 | 0) >> 2] | 0 | 0) == 0) {
-   label = 184;
-   break;
-  } else {
-   label = 185;
-   break;
-  }
- case 184:
-  invoke_v(538);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 185;
-  break;
- case 185:
-  $808 = $782 + 20 | 0;
-  $809 = HEAP32[$808 >> 2] | 0;
-  if (($809 | 0) == 0) {
-   label = 199;
-   break;
-  } else {
-   label = 186;
-   break;
-  }
- case 186:
-  $814 = HEAP32[$809 >> 2] | 0;
-  $818 = HEAP32[((HEAP32[138672 >> 2] | 0) + 8 | 0) >> 2] | 0;
-  if (($814 | 0) == 82712) {
-   label = 187;
-   break;
-  } else {
-   $tib1_0_ph_i395 = $814;
-   label = 188;
-   break;
-  }
- case 187:
-  $tib1_0_ph_i395 = HEAP32[((HEAP32[($809 + 8 | 0) >> 2] | 0) + 8 | 0) >> 2] | 0;
-  label = 188;
-  break;
- case 188:
-  $829 = HEAP32[($tib1_0_ph_i395 + 56 | 0) >> 2] | 0;
-  if (($829 | 0) == 0) {
-   $dimension_tib1_0_lcssa_i399 = 0;
-   $tib1_0_lcssa_i398 = $tib1_0_ph_i395;
-   label = 190;
-   break;
-  } else {
-   $dimension_tib1_029_i401 = 0;
-   $836 = $829;
-   label = 191;
-   break;
-  }
- case 189:
-  $dimension_tib1_0_lcssa_i399 = $840;
-  $tib1_0_lcssa_i398 = $839;
-  label = 190;
-  break;
- case 190:
-  $834 = HEAP32[($818 + 56 | 0) >> 2] | 0;
-  if (($834 | 0) == 0) {
-   $dimension_tib2_0_lcssa_i406 = 0;
-   $tib2_0_lcssa_in_i405 = $818;
-   label = 193;
-   break;
-  } else {
-   $dimension_tib2_024_i403 = 0;
-   $845 = $834;
-   label = 192;
-   break;
-  }
- case 191:
-  $839 = HEAP32[($836 + 8 | 0) >> 2] | 0;
-  $840 = $dimension_tib1_029_i401 + 1 | 0;
-  $843 = HEAP32[($839 + 56 | 0) >> 2] | 0;
-  if (($843 | 0) == 0) {
-   label = 189;
-   break;
-  } else {
-   $dimension_tib1_029_i401 = $840;
-   $836 = $843;
-   label = 191;
-   break;
-  }
- case 192:
-  $848 = HEAP32[($845 + 8 | 0) >> 2] | 0;
-  $849 = $dimension_tib2_024_i403 + 1 | 0;
-  $852 = HEAP32[($848 + 56 | 0) >> 2] | 0;
-  if (($852 | 0) == 0) {
-   $dimension_tib2_0_lcssa_i406 = $849;
-   $tib2_0_lcssa_in_i405 = $848;
-   label = 193;
-   break;
-  } else {
-   $dimension_tib2_024_i403 = $849;
-   $845 = $852;
-   label = 192;
-   break;
-  }
- case 193:
-  $tib2_0_lcssa_i407 = $tib2_0_lcssa_in_i405;
-  if (($dimension_tib1_0_lcssa_i399 | 0) < ($dimension_tib2_0_lcssa_i406 | 0) | ($tib1_0_lcssa_i398 | 0) == 0) {
-   label = 199;
-   break;
-  } else {
-   $tib1_121_i410 = $tib1_0_lcssa_i398;
-   label = 194;
-   break;
-  }
- case 194:
-  if (($tib1_121_i410 | 0) == ($tib2_0_lcssa_i407 | 0)) {
-   label = 361;
-   break;
-  } else {
-   label = 195;
-   break;
-  }
- case 195:
-  $i_0_i413 = 0;
-  label = 196;
-  break;
- case 196:
-  if (($i_0_i413 | 0) < (HEAP32[($tib1_121_i410 + 108 | 0) >> 2] | 0 | 0)) {
-   label = 197;
-   break;
-  } else {
-   label = 198;
-   break;
-  }
- case 197:
-  if ((HEAP32[((HEAP32[($tib1_121_i410 + 112 | 0) >> 2] | 0) + ($i_0_i413 << 2) | 0) >> 2] | 0 | 0) == ($tib2_0_lcssa_i407 | 0)) {
-   label = 361;
-   break;
-  } else {
-   $i_0_i413 = $i_0_i413 + 1 | 0;
-   label = 196;
-   break;
-  }
- case 198:
-  $870 = HEAP32[($tib1_121_i410 + 40 | 0) >> 2] | 0;
-  if (($870 | 0) == 0) {
-   label = 199;
-   break;
-  } else {
-   $tib1_121_i410 = $870;
-   label = 194;
-   break;
-  }
- case 199:
-  if ((HEAP32[(107740 | 0) >> 2] | 0 | 0) == 0) {
-   label = 200;
-   break;
-  } else {
-   label = 201;
-   break;
-  }
- case 200:
-  invoke_v(374);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 201;
-  break;
- case 201:
-  $876 = HEAP32[$808 >> 2] | 0;
-  if (($876 | 0) == 0) {
-   label = 215;
-   break;
-  } else {
-   label = 202;
-   break;
-  }
- case 202:
-  $881 = HEAP32[$876 >> 2] | 0;
-  $885 = HEAP32[((HEAP32[137616 >> 2] | 0) + 8 | 0) >> 2] | 0;
-  if (($881 | 0) == 82712) {
-   label = 203;
-   break;
-  } else {
-   $tib1_0_ph_i374 = $881;
-   label = 204;
-   break;
-  }
- case 203:
-  $tib1_0_ph_i374 = HEAP32[((HEAP32[($876 + 8 | 0) >> 2] | 0) + 8 | 0) >> 2] | 0;
-  label = 204;
-  break;
- case 204:
-  $896 = HEAP32[($tib1_0_ph_i374 + 56 | 0) >> 2] | 0;
-  if (($896 | 0) == 0) {
-   $dimension_tib1_0_lcssa_i378 = 0;
-   $tib1_0_lcssa_i377 = $tib1_0_ph_i374;
-   label = 206;
-   break;
-  } else {
-   $dimension_tib1_029_i380 = 0;
-   $903 = $896;
-   label = 207;
-   break;
-  }
- case 205:
-  $dimension_tib1_0_lcssa_i378 = $907;
-  $tib1_0_lcssa_i377 = $906;
-  label = 206;
-  break;
- case 206:
-  $901 = HEAP32[($885 + 56 | 0) >> 2] | 0;
-  if (($901 | 0) == 0) {
-   $dimension_tib2_0_lcssa_i385 = 0;
-   $tib2_0_lcssa_in_i384 = $885;
-   label = 209;
-   break;
-  } else {
-   $dimension_tib2_024_i382 = 0;
-   $912 = $901;
-   label = 208;
-   break;
-  }
- case 207:
-  $906 = HEAP32[($903 + 8 | 0) >> 2] | 0;
-  $907 = $dimension_tib1_029_i380 + 1 | 0;
-  $910 = HEAP32[($906 + 56 | 0) >> 2] | 0;
-  if (($910 | 0) == 0) {
-   label = 205;
-   break;
-  } else {
-   $dimension_tib1_029_i380 = $907;
-   $903 = $910;
-   label = 207;
-   break;
-  }
- case 208:
-  $915 = HEAP32[($912 + 8 | 0) >> 2] | 0;
-  $916 = $dimension_tib2_024_i382 + 1 | 0;
-  $919 = HEAP32[($915 + 56 | 0) >> 2] | 0;
-  if (($919 | 0) == 0) {
-   $dimension_tib2_0_lcssa_i385 = $916;
-   $tib2_0_lcssa_in_i384 = $915;
-   label = 209;
-   break;
-  } else {
-   $dimension_tib2_024_i382 = $916;
-   $912 = $919;
-   label = 208;
-   break;
-  }
- case 209:
-  $tib2_0_lcssa_i386 = $tib2_0_lcssa_in_i384;
-  if (($dimension_tib1_0_lcssa_i378 | 0) < ($dimension_tib2_0_lcssa_i385 | 0) | ($tib1_0_lcssa_i377 | 0) == 0) {
-   label = 215;
-   break;
-  } else {
-   $tib1_121_i389 = $tib1_0_lcssa_i377;
-   label = 210;
-   break;
-  }
- case 210:
-  if (($tib1_121_i389 | 0) == ($tib2_0_lcssa_i386 | 0)) {
-   label = 386;
-   break;
-  } else {
-   label = 211;
-   break;
-  }
- case 211:
-  $i_0_i392 = 0;
-  label = 212;
-  break;
- case 212:
-  if (($i_0_i392 | 0) < (HEAP32[($tib1_121_i389 + 108 | 0) >> 2] | 0 | 0)) {
-   label = 213;
-   break;
-  } else {
-   label = 214;
-   break;
-  }
- case 213:
-  if ((HEAP32[((HEAP32[($tib1_121_i389 + 112 | 0) >> 2] | 0) + ($i_0_i392 << 2) | 0) >> 2] | 0 | 0) == ($tib2_0_lcssa_i386 | 0)) {
-   label = 386;
-   break;
-  } else {
-   $i_0_i392 = $i_0_i392 + 1 | 0;
-   label = 212;
-   break;
-  }
- case 214:
-  $937 = HEAP32[($tib1_121_i389 + 40 | 0) >> 2] | 0;
-  if (($937 | 0) == 0) {
-   label = 215;
-   break;
-  } else {
-   $tib1_121_i389 = $937;
-   label = 210;
-   break;
-  }
- case 215:
-  invoke_vii(48, HEAP32[$785 >> 2] | 0 | 0, 0 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  return 0 | 0;
- case 216:
-  $_r0_sroa_0 = 0;
-  if ((HEAP32[(105500 | 0) >> 2] | 0 | 0) == 0) {
-   label = 217;
-   break;
-  } else {
-   label = 218;
-   break;
-  }
- case 217:
-  invoke_v(30);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 218;
-  break;
- case 218:
-  $945 = invoke_i(70) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $947 = invoke_iii(364, $945 | 0, 0 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $948 = $local_env_w4567aaac23b1c35;
-  $950 = $947 + 16 | 0;
-  _memcpy($948 | 0, HEAP32[$950 >> 2] | 0 | 0, 40);
-  $954 = _saveSetjmp(HEAP32[$950 >> 2] | 0 | 0, label, setjmpTable) | 0;
-  label = 420;
-  break;
- case 420:
-  if (($954 | 0) == 0) {
-   label = 219;
-   break;
-  } else {
-   label = 222;
-   break;
-  }
- case 219:
-  $_r0_sroa_0_0_load607 = $_r0_sroa_0;
-  if ((HEAP32[(98772 | 0) >> 2] | 0 | 0) == 0) {
-   label = 220;
-   break;
-  } else {
-   label = 221;
-   break;
-  }
- case 220:
-  invoke_v(702);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 221;
-  break;
- case 221:
-  HEAP32[140048 >> 2] = $_r0_sroa_0_0_load607;
-  _memcpy(HEAP32[$950 >> 2] | 0 | 0, $948 | 0, 40);
-  label = 239;
-  break;
- case 222:
-  _memcpy(HEAP32[$950 >> 2] | 0 | 0, $948 | 0, 40);
-  if ((HEAP32[(107740 | 0) >> 2] | 0 | 0) == 0) {
-   label = 223;
-   break;
-  } else {
-   label = 224;
-   break;
-  }
- case 223:
-  invoke_v(374);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 224;
-  break;
- case 224:
-  $969 = HEAP32[($947 + 20 | 0) >> 2] | 0;
-  if (($969 | 0) == 0) {
-   label = 238;
-   break;
-  } else {
-   label = 225;
-   break;
-  }
- case 225:
-  $974 = HEAP32[$969 >> 2] | 0;
-  $978 = HEAP32[((HEAP32[137616 >> 2] | 0) + 8 | 0) >> 2] | 0;
-  if (($974 | 0) == 82712) {
-   label = 226;
-   break;
-  } else {
-   $tib1_0_ph_i353 = $974;
-   label = 227;
-   break;
-  }
- case 226:
-  $tib1_0_ph_i353 = HEAP32[((HEAP32[($969 + 8 | 0) >> 2] | 0) + 8 | 0) >> 2] | 0;
-  label = 227;
-  break;
- case 227:
-  $989 = HEAP32[($tib1_0_ph_i353 + 56 | 0) >> 2] | 0;
-  if (($989 | 0) == 0) {
-   $dimension_tib1_0_lcssa_i357 = 0;
-   $tib1_0_lcssa_i356 = $tib1_0_ph_i353;
-   label = 229;
-   break;
-  } else {
-   $dimension_tib1_029_i359 = 0;
-   $996 = $989;
-   label = 230;
-   break;
-  }
- case 228:
-  $dimension_tib1_0_lcssa_i357 = $1000;
-  $tib1_0_lcssa_i356 = $999;
-  label = 229;
-  break;
- case 229:
-  $994 = HEAP32[($978 + 56 | 0) >> 2] | 0;
-  if (($994 | 0) == 0) {
-   $dimension_tib2_0_lcssa_i364 = 0;
-   $tib2_0_lcssa_in_i363 = $978;
-   label = 232;
-   break;
-  } else {
-   $dimension_tib2_024_i361 = 0;
-   $1005 = $994;
-   label = 231;
-   break;
-  }
- case 230:
-  $999 = HEAP32[($996 + 8 | 0) >> 2] | 0;
-  $1000 = $dimension_tib1_029_i359 + 1 | 0;
-  $1003 = HEAP32[($999 + 56 | 0) >> 2] | 0;
-  if (($1003 | 0) == 0) {
-   label = 228;
-   break;
-  } else {
-   $dimension_tib1_029_i359 = $1000;
-   $996 = $1003;
-   label = 230;
-   break;
-  }
- case 231:
-  $1008 = HEAP32[($1005 + 8 | 0) >> 2] | 0;
-  $1009 = $dimension_tib2_024_i361 + 1 | 0;
-  $1012 = HEAP32[($1008 + 56 | 0) >> 2] | 0;
-  if (($1012 | 0) == 0) {
-   $dimension_tib2_0_lcssa_i364 = $1009;
-   $tib2_0_lcssa_in_i363 = $1008;
-   label = 232;
-   break;
-  } else {
-   $dimension_tib2_024_i361 = $1009;
-   $1005 = $1012;
-   label = 231;
-   break;
-  }
- case 232:
-  $tib2_0_lcssa_i365 = $tib2_0_lcssa_in_i363;
-  if (($dimension_tib1_0_lcssa_i357 | 0) < ($dimension_tib2_0_lcssa_i364 | 0) | ($tib1_0_lcssa_i356 | 0) == 0) {
-   label = 238;
-   break;
-  } else {
-   $tib1_121_i368 = $tib1_0_lcssa_i356;
-   label = 233;
-   break;
-  }
- case 233:
-  if (($tib1_121_i368 | 0) == ($tib2_0_lcssa_i365 | 0)) {
-   label = 54;
-   break;
-  } else {
-   label = 234;
-   break;
-  }
- case 234:
-  $i_0_i371 = 0;
-  label = 235;
-  break;
- case 235:
-  if (($i_0_i371 | 0) < (HEAP32[($tib1_121_i368 + 108 | 0) >> 2] | 0 | 0)) {
-   label = 236;
-   break;
-  } else {
-   label = 237;
-   break;
-  }
- case 236:
-  if ((HEAP32[((HEAP32[($tib1_121_i368 + 112 | 0) >> 2] | 0) + ($i_0_i371 << 2) | 0) >> 2] | 0 | 0) == ($tib2_0_lcssa_i365 | 0)) {
-   label = 54;
-   break;
-  } else {
-   $i_0_i371 = $i_0_i371 + 1 | 0;
-   label = 235;
-   break;
-  }
- case 237:
-  $1030 = HEAP32[($tib1_121_i368 + 40 | 0) >> 2] | 0;
-  if (($1030 | 0) == 0) {
-   label = 238;
-   break;
-  } else {
-   $tib1_121_i368 = $1030;
-   label = 233;
-   break;
-  }
- case 238:
-  invoke_vii(48, HEAP32[$950 >> 2] | 0 | 0, 0 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  return 0 | 0;
- case 239:
-  $_r0_sroa_0 = 0;
-  label = 28;
-  break;
- case 240:
-  $1036 = $local_env_w4567aaac23b1c40;
-  $1038 = $548 + 16 | 0;
-  _memcpy($1036 | 0, HEAP32[$1038 >> 2] | 0 | 0, 40);
-  $1042 = _saveSetjmp(HEAP32[$1038 >> 2] | 0 | 0, label, setjmpTable) | 0;
-  label = 421;
-  break;
- case 421:
-  if (($1042 | 0) == 0) {
-   label = 241;
-   break;
-  } else {
-   label = 253;
-   break;
-  }
- case 241:
-  if ((HEAP32[(98772 | 0) >> 2] | 0 | 0) == 0) {
-   label = 242;
-   break;
-  } else {
-   label = 244;
-   break;
-  }
- case 242:
-  invoke_v(702);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  if ((HEAP32[(98772 | 0) >> 2] | 0 | 0) == 0) {
-   label = 243;
-   break;
-  } else {
-   label = 244;
-   break;
-  }
- case 243:
-  invoke_v(702);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 244;
-  break;
- case 244:
-  $1050 = HEAP32[140040 >> 2] | 0;
-  if (($1050 | 0) == 0) {
-   label = 245;
-   break;
-  } else {
-   label = 246;
-   break;
-  }
- case 245:
-  invoke_viiii(14, 16136 | 0 | 0, 11648 | 0 | 0, 126768 | 0 | 0, 573 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  return 0 | 0;
- case 246:
-  if ((HEAP32[(98772 | 0) >> 2] | 0 | 0) == 0) {
-   label = 247;
-   break;
-  } else {
-   $1056 = $1050;
-   label = 248;
-   break;
-  }
- case 247:
-  invoke_v(702);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $1056 = HEAP32[140040 >> 2] | 0;
-  label = 248;
-  break;
- case 248:
-  $_r0_sroa_0 = $1056;
-  if (($_r0_sroa_0 | 0) == 0) {
-   label = 252;
-   break;
-  } else {
-   label = 249;
-   break;
-  }
- case 249:
-  _memcpy(HEAP32[$1038 >> 2] | 0 | 0, $1036 | 0, 40);
-  if ((HEAP32[(105500 | 0) >> 2] | 0 | 0) == 0) {
-   label = 250;
-   break;
-  } else {
-   label = 251;
-   break;
-  }
- case 250:
-  invoke_v(30);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 251;
-  break;
- case 251:
-  $1064 = invoke_i(70) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $1066 = invoke_iii(364, $1064 | 0, 0 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $1067 = $local_env_w4567aaac23b1c42;
-  $1069 = $1066 + 16 | 0;
-  _memcpy($1067 | 0, HEAP32[$1069 >> 2] | 0 | 0, 40);
-  $1073 = _saveSetjmp(HEAP32[$1069 >> 2] | 0 | 0, label, setjmpTable) | 0;
-  label = 422;
-  break;
- case 422:
-  if (($1073 | 0) == 0) {
-   label = 286;
-   break;
-  } else {
-   label = 289;
-   break;
-  }
- case 252:
-  invoke_viiii(14, 16136 | 0 | 0, 11648 | 0 | 0, 126872 | 0 | 0, 1581 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  return 0 | 0;
- case 253:
-  _memcpy(HEAP32[$1038 >> 2] | 0 | 0, $1036 | 0, 40);
-  if ((HEAP32[(113236 | 0) >> 2] | 0 | 0) == 0) {
-   label = 254;
-   break;
-  } else {
-   label = 255;
-   break;
-  }
- case 254:
-  invoke_v(538);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 255;
-  break;
- case 255:
-  $1083 = $548 + 20 | 0;
-  $1084 = HEAP32[$1083 >> 2] | 0;
-  if (($1084 | 0) == 0) {
-   label = 269;
-   break;
-  } else {
-   label = 256;
-   break;
-  }
- case 256:
-  $1089 = HEAP32[$1084 >> 2] | 0;
-  $1093 = HEAP32[((HEAP32[138672 >> 2] | 0) + 8 | 0) >> 2] | 0;
-  if (($1089 | 0) == 82712) {
-   label = 257;
-   break;
-  } else {
-   $tib1_0_ph_i332 = $1089;
-   label = 258;
-   break;
-  }
- case 257:
-  $tib1_0_ph_i332 = HEAP32[((HEAP32[($1084 + 8 | 0) >> 2] | 0) + 8 | 0) >> 2] | 0;
-  label = 258;
-  break;
- case 258:
-  $1104 = HEAP32[($tib1_0_ph_i332 + 56 | 0) >> 2] | 0;
-  if (($1104 | 0) == 0) {
-   $dimension_tib1_0_lcssa_i336 = 0;
-   $tib1_0_lcssa_i335 = $tib1_0_ph_i332;
-   label = 260;
-   break;
-  } else {
-   $dimension_tib1_029_i338 = 0;
-   $1111 = $1104;
-   label = 261;
-   break;
-  }
- case 259:
-  $dimension_tib1_0_lcssa_i336 = $1115;
-  $tib1_0_lcssa_i335 = $1114;
-  label = 260;
-  break;
- case 260:
-  $1109 = HEAP32[($1093 + 56 | 0) >> 2] | 0;
-  if (($1109 | 0) == 0) {
-   $dimension_tib2_0_lcssa_i343 = 0;
-   $tib2_0_lcssa_in_i342 = $1093;
-   label = 263;
-   break;
-  } else {
-   $dimension_tib2_024_i340 = 0;
-   $1120 = $1109;
-   label = 262;
-   break;
-  }
- case 261:
-  $1114 = HEAP32[($1111 + 8 | 0) >> 2] | 0;
-  $1115 = $dimension_tib1_029_i338 + 1 | 0;
-  $1118 = HEAP32[($1114 + 56 | 0) >> 2] | 0;
-  if (($1118 | 0) == 0) {
-   label = 259;
-   break;
-  } else {
-   $dimension_tib1_029_i338 = $1115;
-   $1111 = $1118;
-   label = 261;
-   break;
-  }
- case 262:
-  $1123 = HEAP32[($1120 + 8 | 0) >> 2] | 0;
-  $1124 = $dimension_tib2_024_i340 + 1 | 0;
-  $1127 = HEAP32[($1123 + 56 | 0) >> 2] | 0;
-  if (($1127 | 0) == 0) {
-   $dimension_tib2_0_lcssa_i343 = $1124;
-   $tib2_0_lcssa_in_i342 = $1123;
-   label = 263;
-   break;
-  } else {
-   $dimension_tib2_024_i340 = $1124;
-   $1120 = $1127;
-   label = 262;
-   break;
-  }
- case 263:
-  $tib2_0_lcssa_i344 = $tib2_0_lcssa_in_i342;
-  if (($dimension_tib1_0_lcssa_i336 | 0) < ($dimension_tib2_0_lcssa_i343 | 0) | ($tib1_0_lcssa_i335 | 0) == 0) {
-   label = 269;
-   break;
-  } else {
-   $tib1_121_i347 = $tib1_0_lcssa_i335;
-   label = 264;
-   break;
-  }
- case 264:
-  if (($tib1_121_i347 | 0) == ($tib2_0_lcssa_i344 | 0)) {
-   label = 361;
-   break;
-  } else {
-   label = 265;
-   break;
-  }
- case 265:
-  $i_0_i350 = 0;
-  label = 266;
-  break;
- case 266:
-  if (($i_0_i350 | 0) < (HEAP32[($tib1_121_i347 + 108 | 0) >> 2] | 0 | 0)) {
-   label = 267;
-   break;
-  } else {
-   label = 268;
-   break;
-  }
- case 267:
-  if ((HEAP32[((HEAP32[($tib1_121_i347 + 112 | 0) >> 2] | 0) + ($i_0_i350 << 2) | 0) >> 2] | 0 | 0) == ($tib2_0_lcssa_i344 | 0)) {
-   label = 361;
-   break;
-  } else {
-   $i_0_i350 = $i_0_i350 + 1 | 0;
-   label = 266;
-   break;
-  }
- case 268:
-  $1145 = HEAP32[($tib1_121_i347 + 40 | 0) >> 2] | 0;
-  if (($1145 | 0) == 0) {
-   label = 269;
-   break;
-  } else {
-   $tib1_121_i347 = $1145;
-   label = 264;
-   break;
-  }
- case 269:
-  if ((HEAP32[(107740 | 0) >> 2] | 0 | 0) == 0) {
-   label = 270;
-   break;
-  } else {
-   label = 271;
-   break;
-  }
- case 270:
-  invoke_v(374);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 271;
-  break;
- case 271:
-  $1151 = HEAP32[$1083 >> 2] | 0;
-  if (($1151 | 0) == 0) {
-   label = 285;
-   break;
-  } else {
-   label = 272;
-   break;
-  }
- case 272:
-  $1156 = HEAP32[$1151 >> 2] | 0;
-  $1160 = HEAP32[((HEAP32[137616 >> 2] | 0) + 8 | 0) >> 2] | 0;
-  if (($1156 | 0) == 82712) {
-   label = 273;
-   break;
-  } else {
-   $tib1_0_ph_i311 = $1156;
-   label = 274;
-   break;
-  }
- case 273:
-  $tib1_0_ph_i311 = HEAP32[((HEAP32[($1151 + 8 | 0) >> 2] | 0) + 8 | 0) >> 2] | 0;
-  label = 274;
-  break;
- case 274:
-  $1171 = HEAP32[($tib1_0_ph_i311 + 56 | 0) >> 2] | 0;
-  if (($1171 | 0) == 0) {
-   $dimension_tib1_0_lcssa_i315 = 0;
-   $tib1_0_lcssa_i314 = $tib1_0_ph_i311;
-   label = 276;
-   break;
-  } else {
-   $dimension_tib1_029_i317 = 0;
-   $1178 = $1171;
-   label = 277;
-   break;
-  }
- case 275:
-  $dimension_tib1_0_lcssa_i315 = $1182;
-  $tib1_0_lcssa_i314 = $1181;
-  label = 276;
-  break;
- case 276:
-  $1176 = HEAP32[($1160 + 56 | 0) >> 2] | 0;
-  if (($1176 | 0) == 0) {
-   $dimension_tib2_0_lcssa_i322 = 0;
-   $tib2_0_lcssa_in_i321 = $1160;
-   label = 279;
-   break;
-  } else {
-   $dimension_tib2_024_i319 = 0;
-   $1187 = $1176;
-   label = 278;
-   break;
-  }
- case 277:
-  $1181 = HEAP32[($1178 + 8 | 0) >> 2] | 0;
-  $1182 = $dimension_tib1_029_i317 + 1 | 0;
-  $1185 = HEAP32[($1181 + 56 | 0) >> 2] | 0;
-  if (($1185 | 0) == 0) {
-   label = 275;
-   break;
-  } else {
-   $dimension_tib1_029_i317 = $1182;
-   $1178 = $1185;
-   label = 277;
-   break;
-  }
- case 278:
-  $1190 = HEAP32[($1187 + 8 | 0) >> 2] | 0;
-  $1191 = $dimension_tib2_024_i319 + 1 | 0;
-  $1194 = HEAP32[($1190 + 56 | 0) >> 2] | 0;
-  if (($1194 | 0) == 0) {
-   $dimension_tib2_0_lcssa_i322 = $1191;
-   $tib2_0_lcssa_in_i321 = $1190;
-   label = 279;
-   break;
-  } else {
-   $dimension_tib2_024_i319 = $1191;
-   $1187 = $1194;
-   label = 278;
-   break;
-  }
- case 279:
-  $tib2_0_lcssa_i323 = $tib2_0_lcssa_in_i321;
-  if (($dimension_tib1_0_lcssa_i315 | 0) < ($dimension_tib2_0_lcssa_i322 | 0) | ($tib1_0_lcssa_i314 | 0) == 0) {
-   label = 285;
-   break;
-  } else {
-   $tib1_121_i326 = $tib1_0_lcssa_i314;
-   label = 280;
-   break;
-  }
- case 280:
-  if (($tib1_121_i326 | 0) == ($tib2_0_lcssa_i323 | 0)) {
-   label = 386;
-   break;
-  } else {
-   label = 281;
-   break;
-  }
- case 281:
-  $i_0_i329 = 0;
-  label = 282;
-  break;
- case 282:
-  if (($i_0_i329 | 0) < (HEAP32[($tib1_121_i326 + 108 | 0) >> 2] | 0 | 0)) {
-   label = 283;
-   break;
-  } else {
-   label = 284;
-   break;
-  }
- case 283:
-  if ((HEAP32[((HEAP32[($tib1_121_i326 + 112 | 0) >> 2] | 0) + ($i_0_i329 << 2) | 0) >> 2] | 0 | 0) == ($tib2_0_lcssa_i323 | 0)) {
-   label = 386;
-   break;
-  } else {
-   $i_0_i329 = $i_0_i329 + 1 | 0;
-   label = 282;
-   break;
-  }
- case 284:
-  $1212 = HEAP32[($tib1_121_i326 + 40 | 0) >> 2] | 0;
-  if (($1212 | 0) == 0) {
-   label = 285;
-   break;
-  } else {
-   $tib1_121_i326 = $1212;
-   label = 280;
-   break;
-  }
- case 285:
-  invoke_vii(48, HEAP32[$1038 >> 2] | 0 | 0, 0 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  return 0 | 0;
- case 286:
-  if ((HEAP32[(98772 | 0) >> 2] | 0 | 0) == 0) {
-   label = 287;
-   break;
-  } else {
-   label = 288;
-   break;
-  }
- case 287:
-  invoke_v(702);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 288;
-  break;
- case 288:
-  $_r0_sroa_0 = HEAP32[140040 >> 2] | 0;
-  $1222 = invoke_ii(556, 709 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $_r3_sroa_0 = $1222;
-  $_r0_sroa_0 = 0;
-  $_r3_sroa_0 = $_r0_sroa_0;
-  HEAP32[($_r3_sroa_1 | 0) >> 2] = HEAP32[($_r0_sroa_1 | 0) >> 2] | 0;
-  _memcpy(HEAP32[$1069 >> 2] | 0 | 0, $1067 | 0, 40);
-  label = 179;
-  break;
- case 289:
-  _memcpy(HEAP32[$1069 >> 2] | 0 | 0, $1067 | 0, 40);
-  if ((HEAP32[(113236 | 0) >> 2] | 0 | 0) == 0) {
-   label = 290;
-   break;
-  } else {
-   label = 291;
-   break;
-  }
- case 290:
-  invoke_v(538);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 291;
-  break;
- case 291:
-  $1232 = $1066 + 20 | 0;
-  $1233 = HEAP32[$1232 >> 2] | 0;
-  if (($1233 | 0) == 0) {
-   label = 305;
-   break;
-  } else {
-   label = 292;
-   break;
-  }
- case 292:
-  $1238 = HEAP32[$1233 >> 2] | 0;
-  $1242 = HEAP32[((HEAP32[138672 >> 2] | 0) + 8 | 0) >> 2] | 0;
-  if (($1238 | 0) == 82712) {
-   label = 293;
-   break;
-  } else {
-   $tib1_0_ph_i290 = $1238;
-   label = 294;
-   break;
-  }
- case 293:
-  $tib1_0_ph_i290 = HEAP32[((HEAP32[($1233 + 8 | 0) >> 2] | 0) + 8 | 0) >> 2] | 0;
-  label = 294;
-  break;
- case 294:
-  $1253 = HEAP32[($tib1_0_ph_i290 + 56 | 0) >> 2] | 0;
-  if (($1253 | 0) == 0) {
-   $dimension_tib1_0_lcssa_i294 = 0;
-   $tib1_0_lcssa_i293 = $tib1_0_ph_i290;
-   label = 296;
-   break;
-  } else {
-   $dimension_tib1_029_i296 = 0;
-   $1260 = $1253;
-   label = 297;
-   break;
-  }
- case 295:
-  $dimension_tib1_0_lcssa_i294 = $1264;
-  $tib1_0_lcssa_i293 = $1263;
-  label = 296;
-  break;
- case 296:
-  $1258 = HEAP32[($1242 + 56 | 0) >> 2] | 0;
-  if (($1258 | 0) == 0) {
-   $dimension_tib2_0_lcssa_i301 = 0;
-   $tib2_0_lcssa_in_i300 = $1242;
-   label = 299;
-   break;
-  } else {
-   $dimension_tib2_024_i298 = 0;
-   $1269 = $1258;
-   label = 298;
-   break;
-  }
- case 297:
-  $1263 = HEAP32[($1260 + 8 | 0) >> 2] | 0;
-  $1264 = $dimension_tib1_029_i296 + 1 | 0;
-  $1267 = HEAP32[($1263 + 56 | 0) >> 2] | 0;
-  if (($1267 | 0) == 0) {
-   label = 295;
-   break;
-  } else {
-   $dimension_tib1_029_i296 = $1264;
-   $1260 = $1267;
-   label = 297;
-   break;
-  }
- case 298:
-  $1272 = HEAP32[($1269 + 8 | 0) >> 2] | 0;
-  $1273 = $dimension_tib2_024_i298 + 1 | 0;
-  $1276 = HEAP32[($1272 + 56 | 0) >> 2] | 0;
-  if (($1276 | 0) == 0) {
-   $dimension_tib2_0_lcssa_i301 = $1273;
-   $tib2_0_lcssa_in_i300 = $1272;
-   label = 299;
-   break;
-  } else {
-   $dimension_tib2_024_i298 = $1273;
-   $1269 = $1276;
-   label = 298;
-   break;
-  }
- case 299:
-  $tib2_0_lcssa_i302 = $tib2_0_lcssa_in_i300;
-  if (($dimension_tib1_0_lcssa_i294 | 0) < ($dimension_tib2_0_lcssa_i301 | 0) | ($tib1_0_lcssa_i293 | 0) == 0) {
-   label = 305;
-   break;
-  } else {
-   $tib1_121_i305 = $tib1_0_lcssa_i293;
-   label = 300;
-   break;
-  }
- case 300:
-  if (($tib1_121_i305 | 0) == ($tib2_0_lcssa_i302 | 0)) {
-   label = 361;
-   break;
-  } else {
-   label = 301;
-   break;
-  }
- case 301:
-  $i_0_i308 = 0;
-  label = 302;
-  break;
- case 302:
-  if (($i_0_i308 | 0) < (HEAP32[($tib1_121_i305 + 108 | 0) >> 2] | 0 | 0)) {
-   label = 303;
-   break;
-  } else {
-   label = 304;
-   break;
-  }
- case 303:
-  if ((HEAP32[((HEAP32[($tib1_121_i305 + 112 | 0) >> 2] | 0) + ($i_0_i308 << 2) | 0) >> 2] | 0 | 0) == ($tib2_0_lcssa_i302 | 0)) {
-   label = 361;
-   break;
-  } else {
-   $i_0_i308 = $i_0_i308 + 1 | 0;
-   label = 302;
-   break;
-  }
- case 304:
-  $1294 = HEAP32[($tib1_121_i305 + 40 | 0) >> 2] | 0;
-  if (($1294 | 0) == 0) {
-   label = 305;
-   break;
-  } else {
-   $tib1_121_i305 = $1294;
-   label = 300;
-   break;
-  }
- case 305:
-  if ((HEAP32[(107740 | 0) >> 2] | 0 | 0) == 0) {
-   label = 306;
-   break;
-  } else {
-   label = 307;
-   break;
-  }
- case 306:
-  invoke_v(374);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 307;
-  break;
- case 307:
-  $1300 = HEAP32[$1232 >> 2] | 0;
-  if (($1300 | 0) == 0) {
-   label = 321;
-   break;
-  } else {
-   label = 308;
-   break;
-  }
- case 308:
-  $1305 = HEAP32[$1300 >> 2] | 0;
-  $1309 = HEAP32[((HEAP32[137616 >> 2] | 0) + 8 | 0) >> 2] | 0;
-  if (($1305 | 0) == 82712) {
-   label = 309;
-   break;
-  } else {
-   $tib1_0_ph_i269 = $1305;
-   label = 310;
-   break;
-  }
- case 309:
-  $tib1_0_ph_i269 = HEAP32[((HEAP32[($1300 + 8 | 0) >> 2] | 0) + 8 | 0) >> 2] | 0;
-  label = 310;
-  break;
- case 310:
-  $1320 = HEAP32[($tib1_0_ph_i269 + 56 | 0) >> 2] | 0;
-  if (($1320 | 0) == 0) {
-   $dimension_tib1_0_lcssa_i273 = 0;
-   $tib1_0_lcssa_i272 = $tib1_0_ph_i269;
-   label = 312;
-   break;
-  } else {
-   $dimension_tib1_029_i275 = 0;
-   $1327 = $1320;
-   label = 313;
-   break;
-  }
- case 311:
-  $dimension_tib1_0_lcssa_i273 = $1331;
-  $tib1_0_lcssa_i272 = $1330;
-  label = 312;
-  break;
- case 312:
-  $1325 = HEAP32[($1309 + 56 | 0) >> 2] | 0;
-  if (($1325 | 0) == 0) {
-   $dimension_tib2_0_lcssa_i280 = 0;
-   $tib2_0_lcssa_in_i279 = $1309;
-   label = 315;
-   break;
-  } else {
-   $dimension_tib2_024_i277 = 0;
-   $1336 = $1325;
-   label = 314;
-   break;
-  }
- case 313:
-  $1330 = HEAP32[($1327 + 8 | 0) >> 2] | 0;
-  $1331 = $dimension_tib1_029_i275 + 1 | 0;
-  $1334 = HEAP32[($1330 + 56 | 0) >> 2] | 0;
-  if (($1334 | 0) == 0) {
-   label = 311;
-   break;
-  } else {
-   $dimension_tib1_029_i275 = $1331;
-   $1327 = $1334;
-   label = 313;
-   break;
-  }
- case 314:
-  $1339 = HEAP32[($1336 + 8 | 0) >> 2] | 0;
-  $1340 = $dimension_tib2_024_i277 + 1 | 0;
-  $1343 = HEAP32[($1339 + 56 | 0) >> 2] | 0;
-  if (($1343 | 0) == 0) {
-   $dimension_tib2_0_lcssa_i280 = $1340;
-   $tib2_0_lcssa_in_i279 = $1339;
-   label = 315;
-   break;
-  } else {
-   $dimension_tib2_024_i277 = $1340;
-   $1336 = $1343;
-   label = 314;
-   break;
-  }
- case 315:
-  $tib2_0_lcssa_i281 = $tib2_0_lcssa_in_i279;
-  if (($dimension_tib1_0_lcssa_i273 | 0) < ($dimension_tib2_0_lcssa_i280 | 0) | ($tib1_0_lcssa_i272 | 0) == 0) {
-   label = 321;
-   break;
-  } else {
-   $tib1_121_i284 = $tib1_0_lcssa_i272;
-   label = 316;
-   break;
-  }
- case 316:
-  if (($tib1_121_i284 | 0) == ($tib2_0_lcssa_i281 | 0)) {
-   label = 386;
-   break;
-  } else {
-   label = 317;
-   break;
-  }
- case 317:
-  $i_0_i287 = 0;
-  label = 318;
-  break;
- case 318:
-  if (($i_0_i287 | 0) < (HEAP32[($tib1_121_i284 + 108 | 0) >> 2] | 0 | 0)) {
-   label = 319;
-   break;
-  } else {
-   label = 320;
-   break;
-  }
- case 319:
-  if ((HEAP32[((HEAP32[($tib1_121_i284 + 112 | 0) >> 2] | 0) + ($i_0_i287 << 2) | 0) >> 2] | 0 | 0) == ($tib2_0_lcssa_i281 | 0)) {
-   label = 386;
-   break;
-  } else {
-   $i_0_i287 = $i_0_i287 + 1 | 0;
-   label = 318;
-   break;
-  }
- case 320:
-  $1361 = HEAP32[($tib1_121_i284 + 40 | 0) >> 2] | 0;
-  if (($1361 | 0) == 0) {
-   label = 321;
-   break;
-  } else {
-   $tib1_121_i284 = $1361;
-   label = 316;
-   break;
-  }
- case 321:
-  invoke_vii(48, HEAP32[$1069 >> 2] | 0 | 0, 0 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  return 0 | 0;
- case 322:
-  if ((HEAP32[(105500 | 0) >> 2] | 0 | 0) == 0) {
-   label = 323;
-   break;
-  } else {
-   label = 324;
-   break;
-  }
- case 323:
-  invoke_v(30);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 324;
-  break;
- case 324:
-  $1369 = invoke_i(70) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $1371 = invoke_iii(364, $1369 | 0, 0 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $1372 = $local_env_w4567aaac23b1c44;
-  $1374 = $1371 + 16 | 0;
-  _memcpy($1372 | 0, HEAP32[$1374 >> 2] | 0 | 0, 40);
-  $1378 = _saveSetjmp(HEAP32[$1374 >> 2] | 0 | 0, label, setjmpTable) | 0;
-  label = 423;
-  break;
- case 423:
-  if (($1378 | 0) == 0) {
-   label = 325;
-   break;
-  } else {
-   label = 328;
-   break;
-  }
- case 325:
-  $_r0_sroa_0 = 1;
-  $_r0_sroa_0_0_load604 = $_r0_sroa_0;
-  if ((HEAP32[(98772 | 0) >> 2] | 0 | 0) == 0) {
-   label = 326;
-   break;
-  } else {
-   label = 327;
-   break;
-  }
- case 326:
-  invoke_v(702);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 327;
-  break;
- case 327:
-  HEAP32[140048 >> 2] = $_r0_sroa_0_0_load604;
-  $1391 = invoke_ii(HEAP32[((HEAP32[((HEAP32[$_r3_sroa_0 >> 2] | 0) + 116 | 0) >> 2] | 0) + 4 | 0) >> 2] | 0 | 0, $_r3_sroa_0 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $_r0_sroa_0 = $1391;
-  invoke_viiii(14, 16136 | 0 | 0, 11648 | 0 | 0, 126872 | 0 | 0, 1630 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  return 0 | 0;
- case 328:
-  _memcpy(HEAP32[$1374 >> 2] | 0 | 0, $1372 | 0, 40);
-  if ((HEAP32[(113236 | 0) >> 2] | 0 | 0) == 0) {
-   label = 329;
-   break;
-  } else {
-   label = 330;
-   break;
-  }
- case 329:
-  invoke_v(538);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 330;
-  break;
- case 330:
-  $1400 = $1371 + 20 | 0;
-  $1401 = HEAP32[$1400 >> 2] | 0;
-  if (($1401 | 0) == 0) {
-   label = 344;
-   break;
-  } else {
-   label = 331;
-   break;
-  }
- case 331:
-  $1406 = HEAP32[$1401 >> 2] | 0;
-  $1410 = HEAP32[((HEAP32[138672 >> 2] | 0) + 8 | 0) >> 2] | 0;
-  if (($1406 | 0) == 82712) {
-   label = 332;
-   break;
-  } else {
-   $tib1_0_ph_i248 = $1406;
-   label = 333;
-   break;
-  }
- case 332:
-  $tib1_0_ph_i248 = HEAP32[((HEAP32[($1401 + 8 | 0) >> 2] | 0) + 8 | 0) >> 2] | 0;
-  label = 333;
-  break;
- case 333:
-  $1421 = HEAP32[($tib1_0_ph_i248 + 56 | 0) >> 2] | 0;
-  if (($1421 | 0) == 0) {
-   $dimension_tib1_0_lcssa_i252 = 0;
-   $tib1_0_lcssa_i251 = $tib1_0_ph_i248;
-   label = 335;
-   break;
-  } else {
-   $dimension_tib1_029_i254 = 0;
-   $1428 = $1421;
-   label = 336;
-   break;
-  }
- case 334:
-  $dimension_tib1_0_lcssa_i252 = $1432;
-  $tib1_0_lcssa_i251 = $1431;
-  label = 335;
-  break;
- case 335:
-  $1426 = HEAP32[($1410 + 56 | 0) >> 2] | 0;
-  if (($1426 | 0) == 0) {
-   $dimension_tib2_0_lcssa_i259 = 0;
-   $tib2_0_lcssa_in_i258 = $1410;
-   label = 338;
-   break;
-  } else {
-   $dimension_tib2_024_i256 = 0;
-   $1437 = $1426;
-   label = 337;
-   break;
-  }
- case 336:
-  $1431 = HEAP32[($1428 + 8 | 0) >> 2] | 0;
-  $1432 = $dimension_tib1_029_i254 + 1 | 0;
-  $1435 = HEAP32[($1431 + 56 | 0) >> 2] | 0;
-  if (($1435 | 0) == 0) {
-   label = 334;
-   break;
-  } else {
-   $dimension_tib1_029_i254 = $1432;
-   $1428 = $1435;
-   label = 336;
-   break;
-  }
- case 337:
-  $1440 = HEAP32[($1437 + 8 | 0) >> 2] | 0;
-  $1441 = $dimension_tib2_024_i256 + 1 | 0;
-  $1444 = HEAP32[($1440 + 56 | 0) >> 2] | 0;
-  if (($1444 | 0) == 0) {
-   $dimension_tib2_0_lcssa_i259 = $1441;
-   $tib2_0_lcssa_in_i258 = $1440;
-   label = 338;
-   break;
-  } else {
-   $dimension_tib2_024_i256 = $1441;
-   $1437 = $1444;
-   label = 337;
-   break;
-  }
- case 338:
-  $tib2_0_lcssa_i260 = $tib2_0_lcssa_in_i258;
-  if (($dimension_tib1_0_lcssa_i252 | 0) < ($dimension_tib2_0_lcssa_i259 | 0) | ($tib1_0_lcssa_i251 | 0) == 0) {
-   label = 344;
-   break;
-  } else {
-   $tib1_121_i263 = $tib1_0_lcssa_i251;
-   label = 339;
-   break;
-  }
- case 339:
-  if (($tib1_121_i263 | 0) == ($tib2_0_lcssa_i260 | 0)) {
-   label = 361;
-   break;
-  } else {
-   label = 340;
-   break;
-  }
- case 340:
-  $i_0_i266 = 0;
-  label = 341;
-  break;
- case 341:
-  if (($i_0_i266 | 0) < (HEAP32[($tib1_121_i263 + 108 | 0) >> 2] | 0 | 0)) {
-   label = 342;
-   break;
-  } else {
-   label = 343;
-   break;
-  }
- case 342:
-  if ((HEAP32[((HEAP32[($tib1_121_i263 + 112 | 0) >> 2] | 0) + ($i_0_i266 << 2) | 0) >> 2] | 0 | 0) == ($tib2_0_lcssa_i260 | 0)) {
-   label = 361;
-   break;
-  } else {
-   $i_0_i266 = $i_0_i266 + 1 | 0;
-   label = 341;
-   break;
-  }
- case 343:
-  $1462 = HEAP32[($tib1_121_i263 + 40 | 0) >> 2] | 0;
-  if (($1462 | 0) == 0) {
-   label = 344;
-   break;
-  } else {
-   $tib1_121_i263 = $1462;
-   label = 339;
-   break;
-  }
- case 344:
-  if ((HEAP32[(107740 | 0) >> 2] | 0 | 0) == 0) {
-   label = 345;
-   break;
-  } else {
-   label = 346;
-   break;
-  }
- case 345:
-  invoke_v(374);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 346;
-  break;
- case 346:
-  $1468 = HEAP32[$1400 >> 2] | 0;
-  if (($1468 | 0) == 0) {
-   label = 360;
-   break;
-  } else {
-   label = 347;
-   break;
-  }
- case 347:
-  $1473 = HEAP32[$1468 >> 2] | 0;
-  $1477 = HEAP32[((HEAP32[137616 >> 2] | 0) + 8 | 0) >> 2] | 0;
-  if (($1473 | 0) == 82712) {
-   label = 348;
-   break;
-  } else {
-   $tib1_0_ph_i227 = $1473;
-   label = 349;
-   break;
-  }
- case 348:
-  $tib1_0_ph_i227 = HEAP32[((HEAP32[($1468 + 8 | 0) >> 2] | 0) + 8 | 0) >> 2] | 0;
-  label = 349;
-  break;
- case 349:
-  $1488 = HEAP32[($tib1_0_ph_i227 + 56 | 0) >> 2] | 0;
-  if (($1488 | 0) == 0) {
-   $dimension_tib1_0_lcssa_i231 = 0;
-   $tib1_0_lcssa_i230 = $tib1_0_ph_i227;
-   label = 351;
-   break;
-  } else {
-   $dimension_tib1_029_i233 = 0;
-   $1495 = $1488;
-   label = 352;
-   break;
-  }
- case 350:
-  $dimension_tib1_0_lcssa_i231 = $1499;
-  $tib1_0_lcssa_i230 = $1498;
-  label = 351;
-  break;
- case 351:
-  $1493 = HEAP32[($1477 + 56 | 0) >> 2] | 0;
-  if (($1493 | 0) == 0) {
-   $dimension_tib2_0_lcssa_i238 = 0;
-   $tib2_0_lcssa_in_i237 = $1477;
-   label = 354;
-   break;
-  } else {
-   $dimension_tib2_024_i235 = 0;
-   $1504 = $1493;
-   label = 353;
-   break;
-  }
- case 352:
-  $1498 = HEAP32[($1495 + 8 | 0) >> 2] | 0;
-  $1499 = $dimension_tib1_029_i233 + 1 | 0;
-  $1502 = HEAP32[($1498 + 56 | 0) >> 2] | 0;
-  if (($1502 | 0) == 0) {
-   label = 350;
-   break;
-  } else {
-   $dimension_tib1_029_i233 = $1499;
-   $1495 = $1502;
-   label = 352;
-   break;
-  }
- case 353:
-  $1507 = HEAP32[($1504 + 8 | 0) >> 2] | 0;
-  $1508 = $dimension_tib2_024_i235 + 1 | 0;
-  $1511 = HEAP32[($1507 + 56 | 0) >> 2] | 0;
-  if (($1511 | 0) == 0) {
-   $dimension_tib2_0_lcssa_i238 = $1508;
-   $tib2_0_lcssa_in_i237 = $1507;
-   label = 354;
-   break;
-  } else {
-   $dimension_tib2_024_i235 = $1508;
-   $1504 = $1511;
-   label = 353;
-   break;
-  }
- case 354:
-  $tib2_0_lcssa_i239 = $tib2_0_lcssa_in_i237;
-  if (($dimension_tib1_0_lcssa_i231 | 0) < ($dimension_tib2_0_lcssa_i238 | 0) | ($tib1_0_lcssa_i230 | 0) == 0) {
-   label = 360;
-   break;
-  } else {
-   $tib1_121_i242 = $tib1_0_lcssa_i230;
-   label = 355;
-   break;
-  }
- case 355:
-  if (($tib1_121_i242 | 0) == ($tib2_0_lcssa_i239 | 0)) {
-   label = 386;
-   break;
-  } else {
-   label = 356;
-   break;
-  }
- case 356:
-  $i_0_i245 = 0;
-  label = 357;
-  break;
- case 357:
-  if (($i_0_i245 | 0) < (HEAP32[($tib1_121_i242 + 108 | 0) >> 2] | 0 | 0)) {
-   label = 358;
-   break;
-  } else {
-   label = 359;
-   break;
-  }
- case 358:
-  if ((HEAP32[((HEAP32[($tib1_121_i242 + 112 | 0) >> 2] | 0) + ($i_0_i245 << 2) | 0) >> 2] | 0 | 0) == ($tib2_0_lcssa_i239 | 0)) {
-   label = 386;
-   break;
-  } else {
-   $i_0_i245 = $i_0_i245 + 1 | 0;
-   label = 357;
-   break;
-  }
- case 359:
-  $1529 = HEAP32[($tib1_121_i242 + 40 | 0) >> 2] | 0;
-  if (($1529 | 0) == 0) {
-   label = 360;
-   break;
-  } else {
-   $tib1_121_i242 = $1529;
-   label = 355;
-   break;
-  }
- case 360:
-  invoke_vii(48, HEAP32[$1374 >> 2] | 0 | 0, 0 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  return 0 | 0;
- case 361:
-  if ((HEAP32[(105500 | 0) >> 2] | 0 | 0) == 0) {
-   label = 362;
-   break;
-  } else {
-   label = 363;
-   break;
-  }
- case 362:
-  invoke_v(30);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 363;
-  break;
- case 363:
-  $1536 = invoke_i(70) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $1538 = invoke_iii(364, $1536 | 0, 0 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $1539 = $local_env_w4567aaac23b1c48;
-  $1541 = $1538 + 16 | 0;
-  _memcpy($1539 | 0, HEAP32[$1541 >> 2] | 0 | 0, 40);
-  $1545 = _saveSetjmp(HEAP32[$1541 >> 2] | 0 | 0, label, setjmpTable) | 0;
-  label = 424;
-  break;
- case 424:
-  if (($1545 | 0) == 0) {
-   label = 364;
-   break;
-  } else {
-   label = 369;
-   break;
-  }
- case 364:
-  if ((HEAP32[(105500 | 0) >> 2] | 0 | 0) == 0) {
-   label = 365;
-   break;
-  } else {
-   label = 366;
-   break;
-  }
- case 365:
-  invoke_v(30);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 366;
-  break;
- case 366:
-  $1551 = invoke_i(70) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $1553 = invoke_iii(364, $1551 | 0, 0 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $_r0_sroa_0 = HEAP32[($1553 + 20 | 0) >> 2] | 0;
-  $_r0_sroa_0 = 0;
-  $_r0_sroa_0_0_load602 = $_r0_sroa_0;
-  if ((HEAP32[(98772 | 0) >> 2] | 0 | 0) == 0) {
-   label = 367;
-   break;
-  } else {
-   label = 368;
-   break;
-  }
- case 367:
-  invoke_v(702);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 368;
-  break;
- case 368:
-  HEAP32[140048 >> 2] = $_r0_sroa_0_0_load602;
-  _memcpy(HEAP32[$1541 >> 2] | 0 | 0, $1539 | 0, 40);
-  label = 239;
-  break;
- case 369:
-  _memcpy(HEAP32[$1541 >> 2] | 0 | 0, $1539 | 0, 40);
-  if ((HEAP32[(107740 | 0) >> 2] | 0 | 0) == 0) {
-   label = 370;
-   break;
-  } else {
-   label = 371;
-   break;
-  }
- case 370:
-  invoke_v(374);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 371;
-  break;
- case 371:
-  $1570 = HEAP32[($1538 + 20 | 0) >> 2] | 0;
-  if (($1570 | 0) == 0) {
-   label = 385;
-   break;
-  } else {
-   label = 372;
-   break;
-  }
- case 372:
-  $1575 = HEAP32[$1570 >> 2] | 0;
-  $1579 = HEAP32[((HEAP32[137616 >> 2] | 0) + 8 | 0) >> 2] | 0;
-  if (($1575 | 0) == 82712) {
-   label = 373;
-   break;
-  } else {
-   $tib1_0_ph_i185 = $1575;
-   label = 374;
-   break;
-  }
- case 373:
-  $tib1_0_ph_i185 = HEAP32[((HEAP32[($1570 + 8 | 0) >> 2] | 0) + 8 | 0) >> 2] | 0;
-  label = 374;
-  break;
- case 374:
-  $1590 = HEAP32[($tib1_0_ph_i185 + 56 | 0) >> 2] | 0;
-  if (($1590 | 0) == 0) {
-   $dimension_tib1_0_lcssa_i189 = 0;
-   $tib1_0_lcssa_i188 = $tib1_0_ph_i185;
-   label = 376;
-   break;
-  } else {
-   $dimension_tib1_029_i191 = 0;
-   $1597 = $1590;
-   label = 377;
-   break;
-  }
- case 375:
-  $dimension_tib1_0_lcssa_i189 = $1601;
-  $tib1_0_lcssa_i188 = $1600;
-  label = 376;
-  break;
- case 376:
-  $1595 = HEAP32[($1579 + 56 | 0) >> 2] | 0;
-  if (($1595 | 0) == 0) {
-   $dimension_tib2_0_lcssa_i196 = 0;
-   $tib2_0_lcssa_in_i195 = $1579;
-   label = 379;
-   break;
-  } else {
-   $dimension_tib2_024_i193 = 0;
-   $1606 = $1595;
-   label = 378;
-   break;
-  }
- case 377:
-  $1600 = HEAP32[($1597 + 8 | 0) >> 2] | 0;
-  $1601 = $dimension_tib1_029_i191 + 1 | 0;
-  $1604 = HEAP32[($1600 + 56 | 0) >> 2] | 0;
-  if (($1604 | 0) == 0) {
-   label = 375;
-   break;
-  } else {
-   $dimension_tib1_029_i191 = $1601;
-   $1597 = $1604;
-   label = 377;
-   break;
-  }
- case 378:
-  $1609 = HEAP32[($1606 + 8 | 0) >> 2] | 0;
-  $1610 = $dimension_tib2_024_i193 + 1 | 0;
-  $1613 = HEAP32[($1609 + 56 | 0) >> 2] | 0;
-  if (($1613 | 0) == 0) {
-   $dimension_tib2_0_lcssa_i196 = $1610;
-   $tib2_0_lcssa_in_i195 = $1609;
-   label = 379;
-   break;
-  } else {
-   $dimension_tib2_024_i193 = $1610;
-   $1606 = $1613;
-   label = 378;
-   break;
-  }
- case 379:
-  $tib2_0_lcssa_i197 = $tib2_0_lcssa_in_i195;
-  if (($dimension_tib1_0_lcssa_i189 | 0) < ($dimension_tib2_0_lcssa_i196 | 0) | ($tib1_0_lcssa_i188 | 0) == 0) {
-   label = 385;
-   break;
-  } else {
-   $tib1_121_i200 = $tib1_0_lcssa_i188;
-   label = 380;
-   break;
-  }
- case 380:
-  if (($tib1_121_i200 | 0) == ($tib2_0_lcssa_i197 | 0)) {
-   label = 54;
-   break;
-  } else {
-   label = 381;
-   break;
-  }
- case 381:
-  $i_0_i203 = 0;
-  label = 382;
-  break;
- case 382:
-  if (($i_0_i203 | 0) < (HEAP32[($tib1_121_i200 + 108 | 0) >> 2] | 0 | 0)) {
-   label = 383;
-   break;
-  } else {
-   label = 384;
-   break;
-  }
- case 383:
-  if ((HEAP32[((HEAP32[($tib1_121_i200 + 112 | 0) >> 2] | 0) + ($i_0_i203 << 2) | 0) >> 2] | 0 | 0) == ($tib2_0_lcssa_i197 | 0)) {
-   label = 54;
-   break;
-  } else {
-   $i_0_i203 = $i_0_i203 + 1 | 0;
-   label = 382;
-   break;
-  }
- case 384:
-  $1631 = HEAP32[($tib1_121_i200 + 40 | 0) >> 2] | 0;
-  if (($1631 | 0) == 0) {
-   label = 385;
-   break;
-  } else {
-   $tib1_121_i200 = $1631;
-   label = 380;
-   break;
-  }
- case 385:
-  invoke_vii(48, HEAP32[$1541 >> 2] | 0 | 0, 0 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  return 0 | 0;
- case 386:
-  if ((HEAP32[(105500 | 0) >> 2] | 0 | 0) == 0) {
-   label = 387;
-   break;
-  } else {
-   label = 388;
-   break;
-  }
- case 387:
-  invoke_v(30);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 388;
-  break;
- case 388:
-  $1638 = invoke_i(70) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $1640 = invoke_iii(364, $1638 | 0, 0 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $1641 = $local_env_w4567aaac23b1c50;
-  $1643 = $1640 + 16 | 0;
-  _memcpy($1641 | 0, HEAP32[$1643 >> 2] | 0 | 0, 40);
-  $1647 = _saveSetjmp(HEAP32[$1643 >> 2] | 0 | 0, label, setjmpTable) | 0;
-  label = 425;
-  break;
- case 425:
-  if (($1647 | 0) == 0) {
-   label = 389;
-   break;
-  } else {
-   label = 396;
-   break;
-  }
- case 389:
-  if ((HEAP32[(105500 | 0) >> 2] | 0 | 0) == 0) {
-   label = 390;
-   break;
-  } else {
-   label = 391;
-   break;
-  }
- case 390:
-  invoke_v(30);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 391;
-  break;
- case 391:
-  $1653 = invoke_i(70) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $1655 = invoke_iii(364, $1653 | 0, 0 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $_r0_sroa_0 = HEAP32[($1655 + 20 | 0) >> 2] | 0;
-  $_r2_sroa_0 = 0;
-  $_r2_sroa_0_0_load = $_r2_sroa_0;
-  if ((HEAP32[(98772 | 0) >> 2] | 0 | 0) == 0) {
-   label = 392;
-   break;
-  } else {
-   label = 393;
-   break;
-  }
- case 392:
-  invoke_v(702);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 393;
-  break;
- case 393:
-  HEAP32[140048 >> 2] = $_r2_sroa_0_0_load;
-  if ((HEAP32[(105500 | 0) >> 2] | 0 | 0) == 0) {
-   label = 394;
-   break;
-  } else {
-   label = 395;
-   break;
-  }
- case 394:
-  invoke_v(30);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 395;
-  break;
- case 395:
-  $1666 = invoke_i(70) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $1668 = invoke_iii(364, $1666 | 0, 0 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  HEAP32[($1668 + 20 | 0) >> 2] = $_r0_sroa_0;
-  invoke_vii(48, HEAP32[($1668 + 16 | 0) >> 2] | 0 | 0, 0 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  return 0 | 0;
- case 396:
-  _memcpy(HEAP32[$1643 >> 2] | 0 | 0, $1641 | 0, 40);
-  if ((HEAP32[(107740 | 0) >> 2] | 0 | 0) == 0) {
-   label = 397;
-   break;
-  } else {
-   label = 398;
-   break;
-  }
- case 397:
-  invoke_v(374);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 398;
-  break;
- case 398:
-  $1684 = HEAP32[($1640 + 20 | 0) >> 2] | 0;
-  if (($1684 | 0) == 0) {
-   label = 412;
-   break;
-  } else {
-   label = 399;
-   break;
-  }
- case 399:
-  $1689 = HEAP32[$1684 >> 2] | 0;
-  $1693 = HEAP32[((HEAP32[137616 >> 2] | 0) + 8 | 0) >> 2] | 0;
-  if (($1689 | 0) == 82712) {
-   label = 400;
-   break;
-  } else {
-   $tib1_0_ph_i = $1689;
-   label = 401;
-   break;
-  }
- case 400:
-  $tib1_0_ph_i = HEAP32[((HEAP32[($1684 + 8 | 0) >> 2] | 0) + 8 | 0) >> 2] | 0;
-  label = 401;
-  break;
- case 401:
-  $1704 = HEAP32[($tib1_0_ph_i + 56 | 0) >> 2] | 0;
-  if (($1704 | 0) == 0) {
-   $dimension_tib1_0_lcssa_i = 0;
-   $tib1_0_lcssa_i = $tib1_0_ph_i;
-   label = 403;
-   break;
-  } else {
-   $dimension_tib1_029_i = 0;
-   $1711 = $1704;
-   label = 404;
-   break;
-  }
- case 402:
-  $dimension_tib1_0_lcssa_i = $1715;
-  $tib1_0_lcssa_i = $1714;
-  label = 403;
-  break;
- case 403:
-  $1709 = HEAP32[($1693 + 56 | 0) >> 2] | 0;
-  if (($1709 | 0) == 0) {
-   $dimension_tib2_0_lcssa_i = 0;
-   $tib2_0_lcssa_in_i = $1693;
-   label = 406;
-   break;
-  } else {
-   $dimension_tib2_024_i = 0;
-   $1720 = $1709;
-   label = 405;
-   break;
-  }
- case 404:
-  $1714 = HEAP32[($1711 + 8 | 0) >> 2] | 0;
-  $1715 = $dimension_tib1_029_i + 1 | 0;
-  $1718 = HEAP32[($1714 + 56 | 0) >> 2] | 0;
-  if (($1718 | 0) == 0) {
-   label = 402;
-   break;
-  } else {
-   $dimension_tib1_029_i = $1715;
-   $1711 = $1718;
-   label = 404;
-   break;
-  }
- case 405:
-  $1723 = HEAP32[($1720 + 8 | 0) >> 2] | 0;
-  $1724 = $dimension_tib2_024_i + 1 | 0;
-  $1727 = HEAP32[($1723 + 56 | 0) >> 2] | 0;
-  if (($1727 | 0) == 0) {
-   $dimension_tib2_0_lcssa_i = $1724;
-   $tib2_0_lcssa_in_i = $1723;
-   label = 406;
-   break;
-  } else {
-   $dimension_tib2_024_i = $1724;
-   $1720 = $1727;
-   label = 405;
-   break;
-  }
- case 406:
-  $tib2_0_lcssa_i = $tib2_0_lcssa_in_i;
-  if (($dimension_tib1_0_lcssa_i | 0) < ($dimension_tib2_0_lcssa_i | 0) | ($tib1_0_lcssa_i | 0) == 0) {
-   label = 412;
-   break;
-  } else {
-   $tib1_121_i = $tib1_0_lcssa_i;
-   label = 407;
-   break;
-  }
- case 407:
-  if (($tib1_121_i | 0) == ($tib2_0_lcssa_i | 0)) {
-   label = 54;
-   break;
-  } else {
-   label = 408;
-   break;
-  }
- case 408:
-  $i_0_i = 0;
-  label = 409;
-  break;
- case 409:
-  if (($i_0_i | 0) < (HEAP32[($tib1_121_i + 108 | 0) >> 2] | 0 | 0)) {
-   label = 410;
-   break;
-  } else {
-   label = 411;
-   break;
-  }
- case 410:
-  if ((HEAP32[((HEAP32[($tib1_121_i + 112 | 0) >> 2] | 0) + ($i_0_i << 2) | 0) >> 2] | 0 | 0) == ($tib2_0_lcssa_i | 0)) {
-   label = 54;
-   break;
-  } else {
-   $i_0_i = $i_0_i + 1 | 0;
-   label = 409;
-   break;
-  }
- case 411:
-  $1745 = HEAP32[($tib1_121_i + 40 | 0) >> 2] | 0;
-  if (($1745 | 0) == 0) {
-   label = 412;
-   break;
-  } else {
-   $tib1_121_i = $1745;
-   label = 407;
-   break;
-  }
- case 412:
-  invoke_vii(48, HEAP32[$1643 >> 2] | 0 | 0, 0 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  return 0 | 0;
- case -1111:
-  if ((setjmpLabel | 0) == 7) {
-   $25 = threwValue;
-   label = 413;
-  } else if ((setjmpLabel | 0) == 35) {
-   $159 = threwValue;
-   label = 414;
-  } else if ((setjmpLabel | 0) == 62) {
-   $290 = threwValue;
-   label = 415;
-  } else if ((setjmpLabel | 0) == 91) {
-   $401 = threwValue;
-   label = 416;
-  } else if ((setjmpLabel | 0) == 97) {
-   $433 = threwValue;
-   label = 417;
-  } else if ((setjmpLabel | 0) == 144) {
-   $629 = threwValue;
-   label = 418;
-  } else if ((setjmpLabel | 0) == 181) {
-   $789 = threwValue;
-   label = 419;
-  } else if ((setjmpLabel | 0) == 218) {
-   $954 = threwValue;
-   label = 420;
-  } else if ((setjmpLabel | 0) == 240) {
-   $1042 = threwValue;
-   label = 421;
-  } else if ((setjmpLabel | 0) == 251) {
-   $1073 = threwValue;
-   label = 422;
-  } else if ((setjmpLabel | 0) == 324) {
-   $1378 = threwValue;
-   label = 423;
-  } else if ((setjmpLabel | 0) == 363) {
-   $1545 = threwValue;
-   label = 424;
-  } else if ((setjmpLabel | 0) == 388) {
-   $1647 = threwValue;
-   label = 425;
-  }
-  __THREW__ = threwValue = 0;
-  break;
- }
-}
 function looop2() {
  var i = 0;
  while (1) {
diff --git a/tools/eliminator/asm-eliminator-test.js b/tools/eliminator/asm-eliminator-test.js
index b33c60406f030..6f426150428ff 100644
--- a/tools/eliminator/asm-eliminator-test.js
+++ b/tools/eliminator/asm-eliminator-test.js
@@ -103,18 +103,6 @@ function exc($this) {
  $this = $this | 0;
  var $1 = 0, $3 = 0, $4 = 0, $5 = 0, $6 = 0, $8 = +0, $9 = 0;
  var label = 0;
- var $1 = (function() {
-  try {
-   __THREW__ = false;
-   return __ZNSt3__16locale8__globalEv();
-  } catch (e) {
-   if (typeof e != "number") throw e;
-   if (ABORT) throw e;
-   __THREW__ = true;
-   Module.print("Exception: " + e + ", currently at: " + (new Error).stack);
-   return null;
-  }
- })();
  if (!__THREW__) {
   $3 = $this | 0;
   $4 = $1 | 0;
@@ -161,12 +149,6 @@ function switchy() {
    break;
  }
 }
-function confuusion() {
- var i = +0;
- func1(+i);
- var j = i; // add this var in the middle. should show up with right type later, auto-inferred from i's type
- func2(+j);
-}
 function tempDouble(a) {
  a = +a;
  var x = +0, y = +0;
@@ -175,397 +157,6 @@ function tempDouble(a) {
  y = a*a;
  f(y);
 }
-function _org_apache_harmony_luni_util_NumberConverter_freeFormat__($me) {
- $me = $me | 0;
- var $_r2_sroa_0 = 0, $_r3_sroa_0 = 0, $1 = 0, $2 = 0, $$etemp$1 = 0, $$etemp$0$0 = 0, $$etemp$0$1 = 0, $st$2$0 = 0;
- var $st$3$1 = 0, $5 = 0, $6 = 0, $7 = 0, $8 = 0, $9 = 0, $10 = 0, $_r1_sroa_0_0_insert_ext191$0 = 0;
- var $_r1_sroa_0_0_insert_ext191$1 = 0, $11 = +0, $12 = 0, $14 = 0, $15 = 0, $16 = 0, $17 = 0, $_r2_sroa_0_0_cast283 = 0;
- var $18 = 0, $19 = 0, $20 = 0, $21 = 0, $_r3_sroa_0_0_cast247 = 0, $_r3_sroa_0_0_load244 = +0, $ld$4$0 = 0, $_r3_sroa_0_0_load244$$SHADOW$0 = 0;
- var $ld$5$1 = 0, $_r3_sroa_0_0_load244$$SHADOW$1 = 0, $_r2_sroa_0_0_load = +0, $ld$6$0 = 0, $_r2_sroa_0_0_load$$SHADOW$0 = 0, $ld$7$1 = 0, $_r2_sroa_0_0_load$$SHADOW$1 = 0, $22$0 = 0;
- var $22$1 = 0, $trunc297$0 = 0, $trunc297 = 0, $23 = 0, $24$0 = 0, $24$1 = 0, $25$0 = 0, $25 = 0;
- var $26 = 0, $27 = 0, $smax = 0, $28 = 0, $29 = 0, $_r3_sroa_0_0_load239_pre = +0, $ld$8$0 = 0, $_r3_sroa_0_0_load239_pre$$SHADOW$0 = 0;
- var $ld$9$1 = 0, $_r3_sroa_0_0_load239_pre$$SHADOW$1 = 0, $_r3_sroa_0_0_load239 = +0, $_pre_phi301 = 0, $_r3_sroa_0_0_cast264_pre_phi = 0, $_r2_sroa_0_0_load265 = +0, $32 = 0, $33 = 0;
- var $34 = 0, $_r3_sroa_0_0_cast253 = 0, $35 = 0, $36 = 0, $37 = 0, $38 = 0, $39 = 0, $40 = 0;
- var $41 = 0, $42 = 0, $43 = 0, $44 = 0, $_r3_sroa_0_0_load243 = +0, $ld$10$0 = 0, $_r3_sroa_0_0_load243$$SHADOW$0 = 0, $ld$11$1 = 0;
- var $_r3_sroa_0_0_load243$$SHADOW$1 = 0, $_r2_sroa_0_0_cast = 0, $45 = 0, $_sink_in = +0, $_r3_sroa_0_0_load241 = +0, $_r2_sroa_0_0_load266287 = 0, $_r1_sroa_0_0 = +0, $_sink$0 = 0, $_sink$1 = 0;
- var $47$0 = 0, $47 = 0, $48$0 = 0, $48$1 = 0, $_r1_sroa_0_0_extract_trunc185$0 = 0, $_r1_sroa_0_0_extract_trunc185 = 0, $49 = 0, $51 = 0, $52 = 0;
- var $53 = 0, $54 = 0, $55 = 0, $56 = 0, $_r1_sroa_0_0_insert_ext195$0 = 0, $_r1_sroa_0_0_insert_ext195$1 = 0, $_r1_sroa_0_1_in$0 = 0, $_r1_sroa_0_1_in$1 = 0;
- var $_r1_sroa_0_1 = +0, $58 = 0, $_r1_sroa_0_0_extract_trunc169$0 = 0, $_r1_sroa_0_0_extract_trunc169 = 0, $60 = 0, $61 = 0, $62 = 0, $63 = 0;
- var $_r3_sroa_0_0_load240 = +0, $ld$12$0 = 0, $_r3_sroa_0_0_load240$$SHADOW$0 = 0, $ld$13$1 = 0, $_r3_sroa_0_0_load240$$SHADOW$1 = 0, $_r1_sroa_0_2 = +0, $64 = 0, $65 = 0;
- var $66 = 0, $67 = 0, $69 = 0, $70 = 0, $71 = 0, $72 = 0, $73 = 0, $74 = 0;
- var $75 = 0, $76 = 0, $phitmp = 0, $77 = 0, $or_cond = 0, $79 = 0, $80 = 0, $82 = 0;
- var $83 = 0, $84 = 0, $_r2_sroa_0_0_cast269 = 0, $85$0 = 0, $85$1 = 0, $_r1_sroa_0_0_extract_trunc$0 = 0, $_r1_sroa_0_0_extract_trunc = 0, $86 = 0, $87 = 0;
- var $88 = 0, $89 = 0, $90 = 0, $91 = 0, $92 = 0, $94 = 0, $95 = 0, $96 = 0;
- var $97 = 0, $99 = 0, $100 = 0, $101 = 0, $102 = 0, $$etemp$15 = 0, $$etemp$14$0 = 0, $$etemp$14$1 = 0;
- var $st$16$0 = 0, $st$17$1 = 0, $105 = 0, $106 = 0, $107 = 0, $108 = 0, $109 = 0, $110 = 0;
- var $112 = 0, $113 = 0, $114 = 0, $115 = 0, $116 = 0, $117 = 0, $118 = 0, $119 = 0;
- var $121 = 0, $123 = 0, $_r1_sroa_0_0_insert_ext$0 = 0, $_r1_sroa_0_0_insert_ext$1 = 0, $$etemp$18$0 = 0, $$etemp$18$1 = 0, $_r1_sroa_0_0_insert_mask$0 = 0, $_r1_sroa_0_0_insert_mask$1 = 0;
- var $_r1_sroa_0_0_insert_insert$0 = 0, $_r1_sroa_0_0_insert_insert$1 = 0, $124 = 0, $125 = 0, $126 = 0, $_old = 0, $_r3_sroa_0_0_load242 = +0, $ld$19$0 = 0;
- var $_r3_sroa_0_0_load242$$SHADOW$0 = 0, $ld$20$1 = 0, $_r3_sroa_0_0_load242$$SHADOW$1 = 0, $_r2_sroa_0_0_cast284 = 0, $_r2_sroa_0_0_load265_pre = +0, $ld$21$0 = 0, $_r2_sroa_0_0_load265_pre$$SHADOW$0 = 0, $ld$22$1 = 0;
- var $_r2_sroa_0_0_load265_pre$$SHADOW$1 = 0, $_r3_sroa_0_0_cast264_pre = 0, $_pre = 0, $_pre300 = 0;
- var label = 0;
- var __stackBase__ = 0;
- __stackBase__ = STACKTOP;
- STACKTOP = STACKTOP + 16 | 0;
- $_r2_sroa_0 = __stackBase__ | 0;
- $_r3_sroa_0 = __stackBase__ + 8 | 0;
- $1 = HEAP32[(114668 | 0) >> 2] | 0;
- $2 = ($1 | 0) == 0;
- if ($2) {
-  HEAP32[(114664 | 0) >> 2] = 1;
-  HEAP32[(114668 | 0) >> 2] = 1;
-  $$etemp$1 = 114672 | 0;
-  $$etemp$0$0 = -1;
-  $$etemp$0$1 = -1;
-  $st$2$0 = $$etemp$1 | 0;
-  HEAP32[$st$2$0 >> 2] = $$etemp$0$0;
-  $st$3$1 = $$etemp$1 + 4 | 0;
-  HEAP32[$st$3$1 >> 2] = $$etemp$0$1;
-  HEAP32[(114684 | 0) >> 2] = 25296 | 0;
-  HEAP32[(114704 | 0) >> 2] = 110728;
-  HEAP32[(114712 | 0) >> 2] = 8;
-  HEAP32[(114784 | 0 | 0) >> 2] = HEAP32[(107856 | 0 | 0) >> 2] | 0;
-  HEAP32[(114784 | 0 | 0) + 4 >> 2] = HEAP32[(107856 | 0 | 0) + 4 >> 2] | 0;
-  HEAP32[(114784 | 0 | 0) + 8 >> 2] = HEAP32[(107856 | 0 | 0) + 8 >> 2] | 0;
-  HEAP32[(114784 | 0 | 0) + 12 >> 2] = HEAP32[(107856 | 0 | 0) + 12 >> 2] | 0;
-  HEAP32[(114784 | 0 | 0) + 16 >> 2] = HEAP32[(107856 | 0 | 0) + 16 >> 2] | 0;
-  HEAP32[(114784 | 0 | 0) + 20 >> 2] = HEAP32[(107856 | 0 | 0) + 20 >> 2] | 0;
- }
- $5 = HEAP32[138960 >> 2] | 0;
- $6 = _org_xmlvm_runtime_XMLVMArray_createSingleDimension___java_lang_Class_int($5, 25) | 0;
- $7 = $me + 8 | 0;
- $8 = $me + 20 | 0;
- $9 = $8;
- $10 = HEAP32[$9 >> 2] | 0;
- $_r1_sroa_0_0_insert_ext191$0 = $10;
- $_r1_sroa_0_0_insert_ext191$1 = 0;
- $11 = (HEAP32[tempDoublePtr >> 2] = $_r1_sroa_0_0_insert_ext191$0, HEAP32[tempDoublePtr + 4 >> 2] = $_r1_sroa_0_0_insert_ext191$1, +HEAPF64[tempDoublePtr >> 3]);
- $12 = ($10 | 0) > -1;
- if ($12) {
-  $_r2_sroa_0_0_cast284 = $_r2_sroa_0;
-  HEAP32[$_r2_sroa_0_0_cast284 >> 2] = 0;
-  $_r2_sroa_0_0_load265_pre = +HEAPF64[$_r2_sroa_0 >> 3];
-  $ld$21$0 = $_r2_sroa_0 | 0;
-  $_r2_sroa_0_0_load265_pre$$SHADOW$0 = HEAP32[$ld$21$0 >> 2] | 0;
-  $ld$22$1 = $_r2_sroa_0 + 4 | 0;
-  $_r2_sroa_0_0_load265_pre$$SHADOW$1 = HEAP32[$ld$22$1 >> 2] | 0;
-  $_r3_sroa_0_0_cast264_pre = $_r3_sroa_0;
-  $_pre = $6 + 16 | 0;
-  $_pre300 = $_pre;
-  var $_r2_sroa_0_0_load265 = $_r2_sroa_0_0_load265_pre;
-  var $_r3_sroa_0_0_cast264_pre_phi = $_r3_sroa_0_0_cast264_pre;
-  var $_pre_phi301 = $_pre300;
- } else {
-  $14 = $6 + 16 | 0;
-  $15 = $14;
-  $16 = HEAP32[$15 >> 2] | 0;
-  $17 = $16;
-  HEAP16[$17 >> 1] = 48;
-  $_r2_sroa_0_0_cast283 = $_r2_sroa_0;
-  $18 = HEAP32[$15 >> 2] | 0;
-  $19 = $18 + 2 | 0;
-  $20 = $19;
-  HEAP16[$20 >> 1] = 46;
-  HEAP32[$_r2_sroa_0_0_cast283 >> 2] = 2;
-  $21 = $10 + 1 | 0;
-  $_r3_sroa_0_0_cast247 = $_r3_sroa_0;
-  HEAP32[$_r3_sroa_0_0_cast247 >> 2] = $21;
-  $_r3_sroa_0_0_load244 = +HEAPF64[$_r3_sroa_0 >> 3];
-  $ld$4$0 = $_r3_sroa_0 | 0;
-  $_r3_sroa_0_0_load244$$SHADOW$0 = HEAP32[$ld$4$0 >> 2] | 0;
-  $ld$5$1 = $_r3_sroa_0 + 4 | 0;
-  $_r3_sroa_0_0_load244$$SHADOW$1 = HEAP32[$ld$5$1 >> 2] | 0;
-  $_r2_sroa_0_0_load = +HEAPF64[$_r2_sroa_0 >> 3];
-  $ld$6$0 = $_r2_sroa_0 | 0;
-  $_r2_sroa_0_0_load$$SHADOW$0 = HEAP32[$ld$6$0 >> 2] | 0;
-  $ld$7$1 = $_r2_sroa_0 + 4 | 0;
-  $_r2_sroa_0_0_load$$SHADOW$1 = HEAP32[$ld$7$1 >> 2] | 0;
-  HEAPF64[$_r3_sroa_0 >> 3] = $_r2_sroa_0_0_load;
-  HEAPF64[$_r2_sroa_0 >> 3] = $_r3_sroa_0_0_load244;
-  $22$0 = $_r3_sroa_0_0_load244$$SHADOW$0;
-  $22$1 = $_r3_sroa_0_0_load244$$SHADOW$1;
-  $trunc297$0 = $22$0;
-  $trunc297 = $trunc297$0;
-  $23 = ($trunc297 | 0) < 0;
-  $24$0 = $_r2_sroa_0_0_load$$SHADOW$0;
-  $24$1 = $_r2_sroa_0_0_load$$SHADOW$1;
-  $25$0 = $24$0;
-  $25 = $25$0;
-  if ($23) {
-   $26 = $trunc297 + 1 | 0;
-   $27 = ($26 | 0) > 0;
-   $smax = $27 ? $26 : 0;
-   $28 = $25 + $smax | 0;
-   var $113 = $25;
-   var $112 = $trunc297;
-   while (1) {
-    $114 = $113 + 1 | 0;
-    $115 = HEAP32[$15 >> 2] | 0;
-    $116 = $115;
-    $117 = $116 + ($113 << 1) | 0;
-    HEAP16[$117 >> 1] = 48;
-    $118 = $112 + 1 | 0;
-    $119 = ($118 | 0) < 0;
-    if ($119) {
-     var $113 = $114;
-     var $112 = $118;
-    } else {
-     break;
-    }
-   }
-   $29 = $28 - $trunc297 | 0;
-   HEAP32[$_r3_sroa_0_0_cast247 >> 2] = $29;
-   HEAP32[$_r2_sroa_0_0_cast283 >> 2] = $smax;
-   $_r3_sroa_0_0_load239_pre = +HEAPF64[$_r3_sroa_0 >> 3];
-   $ld$8$0 = $_r3_sroa_0 | 0;
-   $_r3_sroa_0_0_load239_pre$$SHADOW$0 = HEAP32[$ld$8$0 >> 2] | 0;
-   $ld$9$1 = $_r3_sroa_0 + 4 | 0;
-   $_r3_sroa_0_0_load239_pre$$SHADOW$1 = HEAP32[$ld$9$1 >> 2] | 0;
-   $_r3_sroa_0_0_load239 = $_r3_sroa_0_0_load239_pre;
-  } else {
-   $_r3_sroa_0_0_load239 = $_r2_sroa_0_0_load;
-  }
-  HEAPF64[$_r2_sroa_0 >> 3] = $_r3_sroa_0_0_load239;
-  var $_r2_sroa_0_0_load265 = $_r3_sroa_0_0_load239;
-  var $_r3_sroa_0_0_cast264_pre_phi = $_r3_sroa_0_0_cast247;
-  var $_pre_phi301 = $15;
- }
- $32 = $me + 16 | 0;
- $33 = $32;
- $34 = HEAP32[$33 >> 2] | 0;
- $_r3_sroa_0_0_cast253 = $_r3_sroa_0;
- HEAP32[$_r3_sroa_0_0_cast253 >> 2] = $34;
- $35 = $me + 12 | 0;
- $36 = $35;
- $37 = HEAP32[$36 >> 2] | 0;
- $38 = $37 + 1 | 0;
- HEAP32[$36 >> 2] = $38;
- $39 = $34 + 16 | 0;
- $40 = $39;
- $41 = HEAP32[$40 >> 2] | 0;
- $42 = $41;
- $43 = $42 + ($37 << 2) | 0;
- $44 = HEAP32[$43 >> 2] | 0;
- HEAP32[$_r3_sroa_0_0_cast264_pre_phi >> 2] = $44;
- $_r3_sroa_0_0_load243 = +HEAPF64[$_r3_sroa_0 >> 3];
- $ld$10$0 = $_r3_sroa_0 | 0;
- $_r3_sroa_0_0_load243$$SHADOW$0 = HEAP32[$ld$10$0 >> 2] | 0;
- $ld$11$1 = $_r3_sroa_0 + 4 | 0;
- $_r3_sroa_0_0_load243$$SHADOW$1 = HEAP32[$ld$11$1 >> 2] | 0;
- HEAPF64[$_r3_sroa_0 >> 3] = $_r2_sroa_0_0_load265;
- HEAPF64[$_r2_sroa_0 >> 3] = $11;
- $_r2_sroa_0_0_cast = $_r2_sroa_0;
- $45 = $7;
- var $_r1_sroa_0_0 = $_r3_sroa_0_0_load243;
- var $_r2_sroa_0_0_load266287 = $10;
- var $_r3_sroa_0_0_load241 = $_r2_sroa_0_0_load265;
- var $_sink_in = $_r2_sroa_0_0_load265;
- while (1) {
-  HEAPF64[tempDoublePtr >> 3] = $_sink_in;
-  var $_sink$0 = HEAP32[tempDoublePtr >> 2] | 0;
-  var $_sink$1 = HEAP32[tempDoublePtr + 4 >> 2] | 0;
-  $47$0 = $_sink$0;
-  $47 = $47$0;
-  HEAPF64[tempDoublePtr >> 3] = $_r1_sroa_0_0;
-  var $48$0 = HEAP32[tempDoublePtr >> 2] | 0;
-  var $48$1 = HEAP32[tempDoublePtr + 4 >> 2] | 0;
-  $_r1_sroa_0_0_extract_trunc185$0 = $48$0;
-  $_r1_sroa_0_0_extract_trunc185 = $_r1_sroa_0_0_extract_trunc185$0;
-  $49 = ($_r1_sroa_0_0_extract_trunc185 | 0) == -1;
-  do {
-   if ($49) {
-    $121 = ($_r2_sroa_0_0_load266287 | 0) < -1;
-    if ($121) {
-     $_r1_sroa_0_2 = $_r3_sroa_0_0_load241;
-     break;
-    }
-    $123 = $47 + 1 | 0;
-    $_r1_sroa_0_0_insert_ext$0 = $123;
-    $_r1_sroa_0_0_insert_ext$1 = 0;
-    $$etemp$18$0 = 0;
-    $$etemp$18$1 = -1;
-    $_r1_sroa_0_0_insert_mask$0 = $48$0 & $$etemp$18$0;
-    $_r1_sroa_0_0_insert_mask$1 = $48$1 & $$etemp$18$1;
-    $_r1_sroa_0_0_insert_insert$0 = $_r1_sroa_0_0_insert_ext$0 | $_r1_sroa_0_0_insert_mask$0;
-    $_r1_sroa_0_0_insert_insert$1 = $_r1_sroa_0_0_insert_ext$1 | $_r1_sroa_0_0_insert_mask$1;
-    $124 = HEAP32[$_pre_phi301 >> 2] | 0;
-    $125 = $124;
-    $126 = $125 + ($47 << 1) | 0;
-    HEAP16[$126 >> 1] = 48;
-    var $_r1_sroa_0_1_in$1 = $_r1_sroa_0_0_insert_insert$1;
-    var $_r1_sroa_0_1_in$0 = $_r1_sroa_0_0_insert_insert$0;
-    label = 785;
-    break;
-   } else {
-    $51 = $47 + 1 | 0;
-    $52 = $_r1_sroa_0_0_extract_trunc185 + 48 | 0;
-    $53 = $52 & 65535;
-    $54 = HEAP32[$_pre_phi301 >> 2] | 0;
-    $55 = $54;
-    $56 = $55 + ($47 << 1) | 0;
-    HEAP16[$56 >> 1] = $53;
-    $_r1_sroa_0_0_insert_ext195$0 = $51;
-    $_r1_sroa_0_0_insert_ext195$1 = 0;
-    var $_r1_sroa_0_1_in$1 = $_r1_sroa_0_0_insert_ext195$1;
-    var $_r1_sroa_0_1_in$0 = $_r1_sroa_0_0_insert_ext195$0;
-    label = 785;
-    break;
-   }
-  } while (0);
-  do {
-   if ((label | 0) == 785) {
-    label = 0;
-    $_r1_sroa_0_1 = (HEAP32[tempDoublePtr >> 2] = $_r1_sroa_0_1_in$0, HEAP32[tempDoublePtr + 4 >> 2] = $_r1_sroa_0_1_in$1, +HEAPF64[tempDoublePtr >> 3]);
-    $58 = ($_r2_sroa_0_0_load266287 | 0) == 0;
-    if (!$58) {
-     $_r1_sroa_0_2 = $_r1_sroa_0_1;
-     break;
-    }
-    $_r1_sroa_0_0_extract_trunc169$0 = $_r1_sroa_0_1_in$0;
-    $_r1_sroa_0_0_extract_trunc169 = $_r1_sroa_0_0_extract_trunc169$0;
-    $60 = $_r1_sroa_0_0_extract_trunc169 + 1 | 0;
-    HEAP32[$_r3_sroa_0_0_cast264_pre_phi >> 2] = $60;
-    $61 = HEAP32[$_pre_phi301 >> 2] | 0;
-    $62 = $61;
-    $63 = $62 + ($_r1_sroa_0_0_extract_trunc169 << 1) | 0;
-    HEAP16[$63 >> 1] = 46;
-    $_r3_sroa_0_0_load240 = +HEAPF64[$_r3_sroa_0 >> 3];
-    $ld$12$0 = $_r3_sroa_0 | 0;
-    $_r3_sroa_0_0_load240$$SHADOW$0 = HEAP32[$ld$12$0 >> 2] | 0;
-    $ld$13$1 = $_r3_sroa_0 + 4 | 0;
-    $_r3_sroa_0_0_load240$$SHADOW$1 = HEAP32[$ld$13$1 >> 2] | 0;
-    $_r1_sroa_0_2 = $_r3_sroa_0_0_load240;
-   }
-  } while (0);
-  $64 = $_r2_sroa_0_0_load266287 - 1 | 0;
-  $65 = HEAP32[$36 >> 2] | 0;
-  HEAP32[$_r3_sroa_0_0_cast264_pre_phi >> 2] = $65;
-  $66 = HEAP32[$45 >> 2] | 0;
-  $67 = ($65 | 0) < ($66 | 0);
-  if ($67) {
-   $69 = HEAP32[$33 >> 2] | 0;
-   HEAP32[$_r3_sroa_0_0_cast253 >> 2] = $69;
-   $70 = $65 + 1 | 0;
-   HEAP32[$36 >> 2] = $70;
-   $71 = $69 + 16 | 0;
-   $72 = $71;
-   $73 = HEAP32[$72 >> 2] | 0;
-   $74 = $73;
-   $75 = $74 + ($65 << 2) | 0;
-   $76 = HEAP32[$75 >> 2] | 0;
-   HEAP32[$_r3_sroa_0_0_cast264_pre_phi >> 2] = $76;
-   $phitmp = ($76 | 0) != -1;
-   $77 = ($64 | 0) > -2;
-   $or_cond = $phitmp | $77;
-   if (!$or_cond) {
-    break;
-   }
-  } else {
-   HEAP32[$_r3_sroa_0_0_cast264_pre_phi >> 2] = -1;
-   $_old = ($64 | 0) > -2;
-   if (!$_old) {
-    break;
-   }
-  }
-  $_r3_sroa_0_0_load242 = +HEAPF64[$_r3_sroa_0 >> 3];
-  $ld$19$0 = $_r3_sroa_0 | 0;
-  $_r3_sroa_0_0_load242$$SHADOW$0 = HEAP32[$ld$19$0 >> 2] | 0;
-  $ld$20$1 = $_r3_sroa_0 + 4 | 0;
-  $_r3_sroa_0_0_load242$$SHADOW$1 = HEAP32[$ld$20$1 >> 2] | 0;
-  HEAPF64[$_r3_sroa_0 >> 3] = $_r1_sroa_0_2;
-  var $_r1_sroa_0_0 = $_r3_sroa_0_0_load242;
-  var $_r2_sroa_0_0_load266287 = $64;
-  var $_r3_sroa_0_0_load241 = $_r1_sroa_0_2;
-  var $_sink_in = $_r1_sroa_0_2;
- }
- HEAP32[$_r2_sroa_0_0_cast >> 2] = $64;
- $79 = HEAP32[(106148 | 0) >> 2] | 0;
- $80 = ($79 | 0) == 0;
- if ($80) {
-  ___INIT_java_lang_String();
- }
- $82 = _GC_MALLOC(36 | 0) | 0;
- $83 = $82;
- HEAP32[$83 >> 2] = 106144;
- $84 = $82 + 4 | 0;
- _memset($84 | 0 | 0, 0 | 0 | 0, 32 | 0 | 0);
- $_r2_sroa_0_0_cast269 = $_r2_sroa_0;
- HEAP32[$_r2_sroa_0_0_cast269 >> 2] = $82;
- HEAPF64[tempDoublePtr >> 3] = $_r1_sroa_0_2;
- var $85$0 = HEAP32[tempDoublePtr >> 2] | 0;
- var $85$1 = HEAP32[tempDoublePtr + 4 >> 2] | 0;
- $_r1_sroa_0_0_extract_trunc$0 = $85$0;
- $_r1_sroa_0_0_extract_trunc = $_r1_sroa_0_0_extract_trunc$0;
- $86 = $82 + 8 | 0;
- $87 = $86;
- HEAP32[$87 >> 2] = 0;
- $88 = $82 + 12 | 0;
- $89 = $88;
- HEAP32[$89 >> 2] = 0;
- $90 = $82 + 16 | 0;
- $91 = $90;
- HEAP32[$91 >> 2] = 0;
- $92 = ($_r1_sroa_0_0_extract_trunc | 0) < 0;
- if ($92) {
-  _XMLVM_ERROR(16136 | 0, 13208 | 0, 132112 | 0, 830);
-  return 0 | 0;
- }
- $94 = $6 + 12 | 0;
- $95 = $94;
- $96 = HEAP32[$95 >> 2] | 0;
- $97 = ($96 | 0) < ($_r1_sroa_0_0_extract_trunc | 0);
- if ($97) {
-  _XMLVM_ERROR(16136 | 0, 13208 | 0, 132112 | 0, 830);
-  return 0 | 0;
- }
- $99 = $82 + 24 | 0;
- $100 = $99;
- HEAP32[$100 >> 2] = 0;
- $101 = HEAP32[(114668 | 0) >> 2] | 0;
- $102 = ($101 | 0) == 0;
- if (!$102) {
-  $105 = HEAP32[138960 >> 2] | 0;
-  $106 = _org_xmlvm_runtime_XMLVMArray_createSingleDimension___java_lang_Class_int($105, $_r1_sroa_0_0_extract_trunc) | 0;
-  $107 = $82 + 20 | 0;
-  $108 = $107;
-  HEAP32[$108 >> 2] = $106;
-  $109 = $82 + 28 | 0;
-  $110 = $109;
-  HEAP32[$110 >> 2] = $_r1_sroa_0_0_extract_trunc;
-  _java_lang_System_arraycopy___java_lang_Object_int_java_lang_Object_int_int($6, 0, $106, 0, $_r1_sroa_0_0_extract_trunc);
-  STACKTOP = __stackBase__;
-  return $82 | 0;
- }
- HEAP32[(114664 | 0) >> 2] = 1;
- HEAP32[(114668 | 0) >> 2] = 1;
- $$etemp$15 = 114672 | 0;
- $$etemp$14$0 = -1;
- $$etemp$14$1 = -1;
- $st$16$0 = $$etemp$15 | 0;
- HEAP32[$st$16$0 >> 2] = $$etemp$14$0;
- $st$17$1 = $$etemp$15 + 4 | 0;
- HEAP32[$st$17$1 >> 2] = $$etemp$14$1;
- HEAP32[(114684 | 0) >> 2] = 25296 | 0;
- HEAP32[(114704 | 0) >> 2] = 110728;
- HEAP32[(114712 | 0) >> 2] = 8;
- HEAP32[(114784 | 0 | 0) >> 2] = HEAP32[(107856 | 0 | 0) >> 2] | 0;
- HEAP32[(114784 | 0 | 0) + 4 >> 2] = HEAP32[(107856 | 0 | 0) + 4 >> 2] | 0;
- HEAP32[(114784 | 0 | 0) + 8 >> 2] = HEAP32[(107856 | 0 | 0) + 8 >> 2] | 0;
- HEAP32[(114784 | 0 | 0) + 12 >> 2] = HEAP32[(107856 | 0 | 0) + 12 >> 2] | 0;
- HEAP32[(114784 | 0 | 0) + 16 >> 2] = HEAP32[(107856 | 0 | 0) + 16 >> 2] | 0;
- HEAP32[(114784 | 0 | 0) + 20 >> 2] = HEAP32[(107856 | 0 | 0) + 20 >> 2] | 0;
- $105 = HEAP32[138960 >> 2] | 0;
- $106 = _org_xmlvm_runtime_XMLVMArray_createSingleDimension___java_lang_Class_int($105, $_r1_sroa_0_0_extract_trunc) | 0;
- $107 = $82 + 20 | 0;
- $108 = $107;
- HEAP32[$108 >> 2] = $106;
- $109 = $82 + 28 | 0;
- $110 = $109;
- HEAP32[$110 >> 2] = $_r1_sroa_0_0_extract_trunc;
- _java_lang_System_arraycopy___java_lang_Object_int_java_lang_Object_int_int($6, 0, $106, 0, $_r1_sroa_0_0_extract_trunc);
- STACKTOP = __stackBase__;
- return $82 | 0;
-}
 function __ZN23b2EdgeAndPolygonContact8EvaluateEP10b2ManifoldRK11b2TransformS4_($this, $manifold, $xfA, $xfB) {
  $this = $this | 0;
  $manifold = $manifold | 0;
@@ -593,6092 +184,6 @@ function __ZN23b2EdgeAndPolygonContact8EvaluateEP10b2ManifoldRK11b2TransformS4_(
  STACKTOP = __stackBase__;
  return;
 }
-function _java_nio_charset_Charset_forNameInternal___java_lang_String($n1) {
- $n1 = $n1 | 0;
- var $_r0_sroa_0 = 0, $_r0_sroa_1 = 0, $_r1_sroa_0 = 0, $_r2_sroa_0 = 0, $_r3_sroa_0 = 0, $_r3_sroa_1 = 0, $_r5_sroa_0 = 0, $local_env_w4567aaac23b1b6 = 0;
- var $local_env_w4567aaac23b1c16 = 0, $local_env_w4567aaac23b1c22 = 0, $local_env_w4567aaac23b1c24 = 0, $local_env_w4567aaac23b1c26 = 0, $local_env_w4567aaac23b1c29 = 0, $local_env_w4567aaac23b1c31 = 0, $local_env_w4567aaac23b1c35 = 0, $local_env_w4567aaac23b1c40 = 0;
- var $local_env_w4567aaac23b1c42 = 0, $local_env_w4567aaac23b1c44 = 0, $local_env_w4567aaac23b1c48 = 0, $local_env_w4567aaac23b1c50 = 0, $1 = 0, $2 = 0, $5 = 0, $6 = 0;
- var $7 = 0, $8 = 0, $11 = 0, $_r1_sroa_0_0_load601 = 0, $12 = 0, $13 = 0, $14 = 0, $16 = 0;
- var $17$0 = 0, $17$1 = 0, $18 = 0, $19 = 0, $20 = 0, $21 = 0, $22 = 0, $23 = 0;
- var $24 = 0, $25 = 0, $26 = 0, $28 = 0, $29 = 0, $31 = 0, $32 = 0, $_r0_sroa_0_0_load622 = 0;
- var $33 = 0, $34 = 0, $35 = 0, $36 = 0, $37 = 0, $38 = 0, $_r0_sroa_0_0_load621 = 0, $39 = 0;
- var $_r5_sroa_0_0_load592 = 0, $40 = 0, $41 = 0, $_r0_sroa_0_0_load620 = 0, $42 = 0, $_r0_sroa_0_0_load619 = 0, $43 = 0, $45 = 0;
- var $46 = 0, $47 = 0, $50 = 0, $51 = 0, $52 = 0, $53 = 0, $55 = 0, $56 = 0;
- var $57 = 0, $58 = 0, $59 = 0, $60 = 0, $61 = 0, $62 = 0, $64 = 0, $65 = 0;
- var $66 = 0, $67 = 0, $68 = 0, $69 = 0, $70 = 0, $tib1_0_ph_i543 = 0, $71 = 0, $72 = 0;
- var $73 = 0, $74 = 0, $tib1_0_lcssa_i546 = 0, $dimension_tib1_0_lcssa_i547 = 0, $75 = 0, $76 = 0, $77 = 0, $78 = 0;
- var $79 = 0, $dimension_tib1_029_i549 = 0, $80 = 0, $81 = 0, $82 = 0, $83 = 0, $84 = 0, $85 = 0;
- var $86 = 0, $87 = 0, $88 = 0, $dimension_tib2_024_i551 = 0, $89 = 0, $90 = 0, $91 = 0, $92 = 0;
- var $93 = 0, $94 = 0, $95 = 0, $96 = 0, $tib2_0_lcssa_in_i553 = 0, $dimension_tib2_0_lcssa_i554 = 0, $tib2_0_lcssa_i555 = 0, $97 = 0;
- var $98 = 0, $or_cond_i556 = 0, $tib1_121_i558 = 0, $99 = 0, $100 = 0, $101 = 0, $102 = 0, $i_0_i561 = 0;
- var $104 = 0, $106 = 0, $107 = 0, $108 = 0, $109 = 0, $110 = 0, $112 = 0, $113 = 0;
- var $114 = 0, $115 = 0, $116 = 0, $_r1_sroa_0_0_load600 = 0, $118 = 0, $119 = 0, $120 = 0, $121 = 0;
- var $122 = 0, $123 = 0, $124 = 0, $125 = 0, $126 = 0, $127 = 0, $128 = 0, $129 = 0;
- var $131 = 0, $132 = 0, $133 = 0, $134 = 0, $135 = 0, $136 = 0, $137 = 0, $138 = 0;
- var $139 = 0, $140 = 0, $142 = 0, $_r0_sroa_0_0_load618 = 0, $143 = 0, $_r5_sroa_0_0_load591 = 0, $145 = 0, $146 = 0;
- var $147 = 0, $149 = 0, $150$0 = 0, $150$1 = 0, $151 = 0, $153 = 0, $154 = 0, $155 = 0;
- var $156 = 0, $157 = 0, $158 = 0, $159 = 0, $160 = 0, $163 = 0, $164 = 0, $165 = 0;
- var $168 = 0, $169 = 0, $170 = 0, $171 = 0, $173 = 0, $174 = 0, $175 = 0, $176 = 0;
- var $177 = 0, $178 = 0, $179 = 0, $180 = 0, $182 = 0, $183 = 0, $184 = 0, $185 = 0;
- var $186 = 0, $187 = 0, $188 = 0, $tib1_0_ph_i521 = 0, $189 = 0, $190 = 0, $191 = 0, $192 = 0;
- var $tib1_0_lcssa_i524 = 0, $dimension_tib1_0_lcssa_i525 = 0, $193 = 0, $194 = 0, $195 = 0, $196 = 0, $197 = 0, $dimension_tib1_029_i527 = 0;
- var $198 = 0, $199 = 0, $200 = 0, $201 = 0, $202 = 0, $203 = 0, $204 = 0, $205 = 0;
- var $206 = 0, $dimension_tib2_024_i529 = 0, $207 = 0, $208 = 0, $209 = 0, $210 = 0, $211 = 0, $212 = 0;
- var $213 = 0, $214 = 0, $tib2_0_lcssa_in_i531 = 0, $dimension_tib2_0_lcssa_i532 = 0, $tib2_0_lcssa_i533 = 0, $215 = 0, $216 = 0, $or_cond_i534 = 0;
- var $tib1_121_i536 = 0, $217 = 0, $218 = 0, $219 = 0, $220 = 0, $i_0_i539 = 0, $222 = 0, $224 = 0;
- var $225 = 0, $226 = 0, $227 = 0, $228 = 0, $230 = 0, $231 = 0, $232 = 0, $233 = 0;
- var $234 = 0, $235 = 0, $236 = 0, $238 = 0, $239$0 = 0, $239$1 = 0, $240 = 0, $241 = 0;
- var $242 = 0, $243 = 0, $244 = 0, $_r1_sroa_0_0_load = 0, $245 = 0, $246 = 0, $247 = 0, $248 = 0;
- var $249 = 0, $250 = 0, $251 = 0, $252 = 0, $253 = 0, $254 = 0, $255 = 0, $256 = 0;
- var $258 = 0, $259 = 0, $260 = 0, $261 = 0, $262 = 0, $263 = 0, $264 = 0, $265 = 0;
- var $266 = 0, $267 = 0, $269 = 0, $270 = 0, $271 = 0, $273 = 0, $274$0 = 0, $274$1 = 0;
- var $275 = 0, $_r0_sroa_0_0_load617 = 0, $276 = 0, $277 = 0, $278 = 0, $279 = 0, $280 = 0, $281 = 0;
- var $282 = 0, $284 = 0, $285 = 0, $286 = 0, $287 = 0, $288 = 0, $289 = 0, $290 = 0;
- var $291 = 0, $_r5_sroa_0_0_load590 = 0, $293 = 0, $294 = 0, $296 = 0, $297 = 0, $_r0_sroa_0_0_load616 = 0, $298 = 0;
- var $300 = 0, $302 = 0, $303 = 0, $305 = 0, $306 = 0, $307 = 0, $308 = 0, $_r0_sroa_0_0_load615 = 0;
- var $309 = 0, $_r0_sroa_0_0_load614 = 0, $310 = 0, $311 = 0, $312 = 0, $314 = 0, $316 = 0, $317 = 0;
- var $318 = 0, $321 = 0, $322 = 0, $323 = 0, $324 = 0, $326 = 0, $327 = 0, $328 = 0;
- var $329 = 0, $330 = 0, $331 = 0, $332 = 0, $333 = 0, $335 = 0, $336 = 0, $337 = 0;
- var $338 = 0, $339 = 0, $340 = 0, $341 = 0, $tib1_0_ph_i500 = 0, $342 = 0, $343 = 0, $344 = 0;
- var $345 = 0, $tib1_0_lcssa_i503 = 0, $dimension_tib1_0_lcssa_i504 = 0, $346 = 0, $347 = 0, $348 = 0, $349 = 0, $350 = 0;
- var $dimension_tib1_029_i506 = 0, $351 = 0, $352 = 0, $353 = 0, $354 = 0, $355 = 0, $356 = 0, $357 = 0;
- var $358 = 0, $359 = 0, $dimension_tib2_024_i508 = 0, $360 = 0, $361 = 0, $362 = 0, $363 = 0, $364 = 0;
- var $365 = 0, $366 = 0, $367 = 0, $tib2_0_lcssa_in_i510 = 0, $dimension_tib2_0_lcssa_i511 = 0, $tib2_0_lcssa_i512 = 0, $368 = 0, $369 = 0;
- var $or_cond_i513 = 0, $tib1_121_i515 = 0, $370 = 0, $371 = 0, $372 = 0, $373 = 0, $i_0_i518 = 0, $375 = 0;
- var $377 = 0, $378 = 0, $379 = 0, $380 = 0, $381 = 0, $383 = 0, $384 = 0, $385 = 0;
- var $386 = 0, $387 = 0, $389 = 0, $390 = 0, $392 = 0, $393$0 = 0, $393$1 = 0, $394 = 0;
- var $395 = 0, $396 = 0, $397 = 0, $398 = 0, $399 = 0, $400 = 0, $401 = 0, $402 = 0;
- var $404 = 0, $405 = 0, $407 = 0, $408 = 0, $_r0_sroa_0_0_load613 = 0, $409 = 0, $410 = 0, $411 = 0;
- var $412 = 0, $413 = 0, $414 = 0, $_r0_sroa_0_0_load612 = 0, $415 = 0, $_r5_sroa_0_0_load589 = 0, $416 = 0, $417 = 0;
- var $_r0_sroa_0_0_load611 = 0, $418 = 0, $420 = 0, $421 = 0, $422 = 0, $424 = 0, $425$0 = 0, $425$1 = 0;
- var $426 = 0, $427 = 0, $428 = 0, $429 = 0, $430 = 0, $431 = 0, $432 = 0, $433 = 0;
- var $434 = 0, $_r0_sroa_0_0_load610 = 0, $436 = 0, $_r5_sroa_0_0_load588 = 0, $437 = 0, $439 = 0, $440 = 0, $441 = 0;
- var $444 = 0, $445 = 0, $446 = 0, $447 = 0, $449 = 0, $450 = 0, $451 = 0, $452 = 0;
- var $453 = 0, $454 = 0, $455 = 0, $456 = 0, $458 = 0, $459 = 0, $460 = 0, $461 = 0;
- var $462 = 0, $463 = 0, $464 = 0, $tib1_0_ph_i479 = 0, $465 = 0, $466 = 0, $467 = 0, $468 = 0;
- var $tib1_0_lcssa_i482 = 0, $dimension_tib1_0_lcssa_i483 = 0, $469 = 0, $470 = 0, $471 = 0, $472 = 0, $473 = 0, $dimension_tib1_029_i485 = 0;
- var $474 = 0, $475 = 0, $476 = 0, $477 = 0, $478 = 0, $479 = 0, $480 = 0, $481 = 0;
- var $482 = 0, $dimension_tib2_024_i487 = 0, $483 = 0, $484 = 0, $485 = 0, $486 = 0, $487 = 0, $488 = 0;
- var $489 = 0, $490 = 0, $tib2_0_lcssa_in_i489 = 0, $dimension_tib2_0_lcssa_i490 = 0, $tib2_0_lcssa_i491 = 0, $491 = 0, $492 = 0, $or_cond_i492 = 0;
- var $tib1_121_i494 = 0, $493 = 0, $494 = 0, $495 = 0, $496 = 0, $i_0_i497 = 0, $498 = 0, $500 = 0;
- var $501 = 0, $502 = 0, $503 = 0, $504 = 0, $506 = 0, $507 = 0, $508 = 0, $509 = 0;
- var $510 = 0, $512 = 0, $513 = 0, $516 = 0, $517 = 0, $519 = 0, $520$0 = 0, $520$1 = 0;
- var $521 = 0, $522 = 0, $523 = 0, $525 = 0, $526 = 0, $527 = 0, $528 = 0, $529 = 0;
- var $530 = 0, $531 = 0, $532 = 0, $_phi_trans_insert = 0, $_pre = 0, $534 = 0, $535 = 0, $536 = 0;
- var $537 = 0, $538 = 0, $539 = 0, $540 = 0, $541 = 0, $_r2_sroa_0_0_load599 = 0, $542 = 0, $543 = 0;
- var $544 = 0, $546 = 0, $547$0 = 0, $547$1 = 0, $548 = 0, $550 = 0, $551 = 0, $552 = 0;
- var $555 = 0, $556 = 0, $557 = 0, $558 = 0, $560 = 0, $561 = 0, $562 = 0, $563 = 0;
- var $564 = 0, $565 = 0, $566 = 0, $567 = 0, $569 = 0, $570 = 0, $571 = 0, $572 = 0;
- var $573 = 0, $574 = 0, $575 = 0, $tib1_0_ph_i458 = 0, $576 = 0, $577 = 0, $578 = 0, $579 = 0;
- var $tib1_0_lcssa_i461 = 0, $dimension_tib1_0_lcssa_i462 = 0, $580 = 0, $581 = 0, $582 = 0, $583 = 0, $584 = 0, $dimension_tib1_029_i464 = 0;
- var $585 = 0, $586 = 0, $587 = 0, $588 = 0, $589 = 0, $590 = 0, $591 = 0, $592 = 0;
- var $593 = 0, $dimension_tib2_024_i466 = 0, $594 = 0, $595 = 0, $596 = 0, $597 = 0, $598 = 0, $599 = 0;
- var $600 = 0, $601 = 0, $tib2_0_lcssa_in_i468 = 0, $dimension_tib2_0_lcssa_i469 = 0, $tib2_0_lcssa_i470 = 0, $602 = 0, $603 = 0, $or_cond_i471 = 0;
- var $tib1_121_i473 = 0, $604 = 0, $605 = 0, $606 = 0, $607 = 0, $i_0_i476 = 0, $609 = 0, $611 = 0;
- var $612 = 0, $613 = 0, $614 = 0, $615 = 0, $617 = 0, $618 = 0, $619 = 0, $620 = 0;
- var $621 = 0, $623 = 0, $624 = 0, $625 = 0, $626 = 0, $627 = 0, $628 = 0, $629 = 0;
- var $630 = 0, $632 = 0, $633 = 0, $_r2_sroa_0_0_load598 = 0, $_r0_sroa_0_0_load609 = 0, $_r0_sroa_0_0_load624 = 0, $634 = 0, $_r0_sroa_1_4__r3_sroa_1_4_idx108_idx = 0;
- var $_r0_sroa_1_4_idx = 0, $635 = 0, $637 = 0, $638 = 0, $639 = 0, $642 = 0, $643 = 0, $644 = 0;
- var $645 = 0, $647 = 0, $648 = 0, $649 = 0, $650 = 0, $651 = 0, $652 = 0, $653 = 0;
- var $654 = 0, $656 = 0, $657 = 0, $658 = 0, $659 = 0, $660 = 0, $661 = 0, $662 = 0;
- var $tib1_0_ph_i437 = 0, $663 = 0, $664 = 0, $665 = 0, $666 = 0, $tib1_0_lcssa_i440 = 0, $dimension_tib1_0_lcssa_i441 = 0, $667 = 0;
- var $668 = 0, $669 = 0, $670 = 0, $671 = 0, $dimension_tib1_029_i443 = 0, $672 = 0, $673 = 0, $674 = 0;
- var $675 = 0, $676 = 0, $677 = 0, $678 = 0, $679 = 0, $680 = 0, $dimension_tib2_024_i445 = 0, $681 = 0;
- var $682 = 0, $683 = 0, $684 = 0, $685 = 0, $686 = 0, $687 = 0, $688 = 0, $tib2_0_lcssa_in_i447 = 0;
- var $dimension_tib2_0_lcssa_i448 = 0, $tib2_0_lcssa_i449 = 0, $689 = 0, $690 = 0, $or_cond_i450 = 0, $tib1_121_i452 = 0, $691 = 0, $692 = 0;
- var $693 = 0, $694 = 0, $i_0_i455 = 0, $696 = 0, $698 = 0, $699 = 0, $700 = 0, $701 = 0;
- var $702 = 0, $704 = 0, $705 = 0, $706 = 0, $707 = 0, $708 = 0, $711 = 0, $712 = 0;
- var $714 = 0, $715 = 0, $716 = 0, $717 = 0, $718 = 0, $719 = 0, $720 = 0, $721 = 0;
- var $723 = 0, $724 = 0, $725 = 0, $726 = 0, $727 = 0, $728 = 0, $729 = 0, $tib1_0_ph_i416 = 0;
- var $730 = 0, $731 = 0, $732 = 0, $733 = 0, $tib1_0_lcssa_i419 = 0, $dimension_tib1_0_lcssa_i420 = 0, $734 = 0, $735 = 0;
- var $736 = 0, $737 = 0, $738 = 0, $dimension_tib1_029_i422 = 0, $739 = 0, $740 = 0, $741 = 0, $742 = 0;
- var $743 = 0, $744 = 0, $745 = 0, $746 = 0, $747 = 0, $dimension_tib2_024_i424 = 0, $748 = 0, $749 = 0;
- var $750 = 0, $751 = 0, $752 = 0, $753 = 0, $754 = 0, $755 = 0, $tib2_0_lcssa_in_i426 = 0, $dimension_tib2_0_lcssa_i427 = 0;
- var $tib2_0_lcssa_i428 = 0, $756 = 0, $757 = 0, $or_cond_i429 = 0, $tib1_121_i431 = 0, $758 = 0, $759 = 0, $760 = 0;
- var $761 = 0, $i_0_i434 = 0, $763 = 0, $765 = 0, $766 = 0, $767 = 0, $768 = 0, $769 = 0;
- var $771 = 0, $772 = 0, $773 = 0, $774 = 0, $775 = 0, $777 = 0, $778 = 0, $780 = 0;
- var $781$0 = 0, $781$1 = 0, $782 = 0, $783 = 0, $784 = 0, $785 = 0, $786 = 0, $787 = 0;
- var $788 = 0, $789 = 0, $790 = 0, $_r3_sroa_0_0_load596 = 0, $792 = 0, $793 = 0, $794 = 0, $795 = 0;
- var $796 = 0, $797 = 0, $_r3_sroa_0_0_load595 = 0, $798 = 0, $799 = 0, $_r0_sroa_0_0_load608 = 0, $800 = 0, $802 = 0;
- var $803 = 0, $804 = 0, $807 = 0, $808 = 0, $809 = 0, $810 = 0, $812 = 0, $813 = 0;
- var $814 = 0, $815 = 0, $816 = 0, $817 = 0, $818 = 0, $819 = 0, $821 = 0, $822 = 0;
- var $823 = 0, $824 = 0, $825 = 0, $826 = 0, $827 = 0, $tib1_0_ph_i395 = 0, $828 = 0, $829 = 0;
- var $830 = 0, $831 = 0, $tib1_0_lcssa_i398 = 0, $dimension_tib1_0_lcssa_i399 = 0, $832 = 0, $833 = 0, $834 = 0, $835 = 0;
- var $836 = 0, $dimension_tib1_029_i401 = 0, $837 = 0, $838 = 0, $839 = 0, $840 = 0, $841 = 0, $842 = 0;
- var $843 = 0, $844 = 0, $845 = 0, $dimension_tib2_024_i403 = 0, $846 = 0, $847 = 0, $848 = 0, $849 = 0;
- var $850 = 0, $851 = 0, $852 = 0, $853 = 0, $tib2_0_lcssa_in_i405 = 0, $dimension_tib2_0_lcssa_i406 = 0, $tib2_0_lcssa_i407 = 0, $854 = 0;
- var $855 = 0, $or_cond_i408 = 0, $tib1_121_i410 = 0, $856 = 0, $857 = 0, $858 = 0, $859 = 0, $i_0_i413 = 0;
- var $861 = 0, $863 = 0, $864 = 0, $865 = 0, $866 = 0, $867 = 0, $869 = 0, $870 = 0;
- var $871 = 0, $872 = 0, $873 = 0, $876 = 0, $877 = 0, $879 = 0, $880 = 0, $881 = 0;
- var $882 = 0, $883 = 0, $884 = 0, $885 = 0, $886 = 0, $888 = 0, $889 = 0, $890 = 0;
- var $891 = 0, $892 = 0, $893 = 0, $894 = 0, $tib1_0_ph_i374 = 0, $895 = 0, $896 = 0, $897 = 0;
- var $898 = 0, $tib1_0_lcssa_i377 = 0, $dimension_tib1_0_lcssa_i378 = 0, $899 = 0, $900 = 0, $901 = 0, $902 = 0, $903 = 0;
- var $dimension_tib1_029_i380 = 0, $904 = 0, $905 = 0, $906 = 0, $907 = 0, $908 = 0, $909 = 0, $910 = 0;
- var $911 = 0, $912 = 0, $dimension_tib2_024_i382 = 0, $913 = 0, $914 = 0, $915 = 0, $916 = 0, $917 = 0;
- var $918 = 0, $919 = 0, $920 = 0, $tib2_0_lcssa_in_i384 = 0, $dimension_tib2_0_lcssa_i385 = 0, $tib2_0_lcssa_i386 = 0, $921 = 0, $922 = 0;
- var $or_cond_i387 = 0, $tib1_121_i389 = 0, $923 = 0, $924 = 0, $925 = 0, $926 = 0, $i_0_i392 = 0, $928 = 0;
- var $930 = 0, $931 = 0, $932 = 0, $933 = 0, $934 = 0, $936 = 0, $937 = 0, $938 = 0;
- var $939 = 0, $940 = 0, $942 = 0, $943 = 0, $945 = 0, $946$0 = 0, $946$1 = 0, $947 = 0;
- var $948 = 0, $949 = 0, $950 = 0, $951 = 0, $952 = 0, $953 = 0, $954 = 0, $955 = 0;
- var $_r0_sroa_0_0_load607 = 0, $957 = 0, $958 = 0, $960 = 0, $962 = 0, $963 = 0, $964 = 0, $967 = 0;
- var $968 = 0, $969 = 0, $970 = 0, $972 = 0, $973 = 0, $974 = 0, $975 = 0, $976 = 0;
- var $977 = 0, $978 = 0, $979 = 0, $981 = 0, $982 = 0, $983 = 0, $984 = 0, $985 = 0;
- var $986 = 0, $987 = 0, $tib1_0_ph_i353 = 0, $988 = 0, $989 = 0, $990 = 0, $991 = 0, $tib1_0_lcssa_i356 = 0;
- var $dimension_tib1_0_lcssa_i357 = 0, $992 = 0, $993 = 0, $994 = 0, $995 = 0, $996 = 0, $dimension_tib1_029_i359 = 0, $997 = 0;
- var $998 = 0, $999 = 0, $1000 = 0, $1001 = 0, $1002 = 0, $1003 = 0, $1004 = 0, $1005 = 0;
- var $dimension_tib2_024_i361 = 0, $1006 = 0, $1007 = 0, $1008 = 0, $1009 = 0, $1010 = 0, $1011 = 0, $1012 = 0;
- var $1013 = 0, $tib2_0_lcssa_in_i363 = 0, $dimension_tib2_0_lcssa_i364 = 0, $tib2_0_lcssa_i365 = 0, $1014 = 0, $1015 = 0, $or_cond_i366 = 0, $tib1_121_i368 = 0;
- var $1016 = 0, $1017 = 0, $1018 = 0, $1019 = 0, $i_0_i371 = 0, $1021 = 0, $1023 = 0, $1024 = 0;
- var $1025 = 0, $1026 = 0, $1027 = 0, $1029 = 0, $1030 = 0, $1031 = 0, $1032 = 0, $1033 = 0;
- var $1036 = 0, $1037 = 0, $1038 = 0, $1039 = 0, $1040 = 0, $1041 = 0, $1042 = 0, $1043 = 0;
- var $1045 = 0, $1046 = 0, $_pr = 0, $1048 = 0, $1050 = 0, $1051 = 0, $1053 = 0, $1054 = 0;
- var $_pre855 = 0, $1056 = 0, $1057 = 0, $_r0_sroa_0_0_load606 = 0, $1058 = 0, $1060 = 0, $1061 = 0, $1062 = 0;
- var $1064 = 0, $1065$0 = 0, $1065$1 = 0, $1066 = 0, $1067 = 0, $1068 = 0, $1069 = 0, $1070 = 0;
- var $1071 = 0, $1072 = 0, $1073 = 0, $1074 = 0, $1077 = 0, $1078 = 0, $1079 = 0, $1082 = 0;
- var $1083 = 0, $1084 = 0, $1085 = 0, $1087 = 0, $1088 = 0, $1089 = 0, $1090 = 0, $1091 = 0;
- var $1092 = 0, $1093 = 0, $1094 = 0, $1096 = 0, $1097 = 0, $1098 = 0, $1099 = 0, $1100 = 0;
- var $1101 = 0, $1102 = 0, $tib1_0_ph_i332 = 0, $1103 = 0, $1104 = 0, $1105 = 0, $1106 = 0, $tib1_0_lcssa_i335 = 0;
- var $dimension_tib1_0_lcssa_i336 = 0, $1107 = 0, $1108 = 0, $1109 = 0, $1110 = 0, $1111 = 0, $dimension_tib1_029_i338 = 0, $1112 = 0;
- var $1113 = 0, $1114 = 0, $1115 = 0, $1116 = 0, $1117 = 0, $1118 = 0, $1119 = 0, $1120 = 0;
- var $dimension_tib2_024_i340 = 0, $1121 = 0, $1122 = 0, $1123 = 0, $1124 = 0, $1125 = 0, $1126 = 0, $1127 = 0;
- var $1128 = 0, $tib2_0_lcssa_in_i342 = 0, $dimension_tib2_0_lcssa_i343 = 0, $tib2_0_lcssa_i344 = 0, $1129 = 0, $1130 = 0, $or_cond_i345 = 0, $tib1_121_i347 = 0;
- var $1131 = 0, $1132 = 0, $1133 = 0, $1134 = 0, $i_0_i350 = 0, $1136 = 0, $1138 = 0, $1139 = 0;
- var $1140 = 0, $1141 = 0, $1142 = 0, $1144 = 0, $1145 = 0, $1146 = 0, $1147 = 0, $1148 = 0;
- var $1151 = 0, $1152 = 0, $1154 = 0, $1155 = 0, $1156 = 0, $1157 = 0, $1158 = 0, $1159 = 0;
- var $1160 = 0, $1161 = 0, $1163 = 0, $1164 = 0, $1165 = 0, $1166 = 0, $1167 = 0, $1168 = 0;
- var $1169 = 0, $tib1_0_ph_i311 = 0, $1170 = 0, $1171 = 0, $1172 = 0, $1173 = 0, $tib1_0_lcssa_i314 = 0, $dimension_tib1_0_lcssa_i315 = 0;
- var $1174 = 0, $1175 = 0, $1176 = 0, $1177 = 0, $1178 = 0, $dimension_tib1_029_i317 = 0, $1179 = 0, $1180 = 0;
- var $1181 = 0, $1182 = 0, $1183 = 0, $1184 = 0, $1185 = 0, $1186 = 0, $1187 = 0, $dimension_tib2_024_i319 = 0;
- var $1188 = 0, $1189 = 0, $1190 = 0, $1191 = 0, $1192 = 0, $1193 = 0, $1194 = 0, $1195 = 0;
- var $tib2_0_lcssa_in_i321 = 0, $dimension_tib2_0_lcssa_i322 = 0, $tib2_0_lcssa_i323 = 0, $1196 = 0, $1197 = 0, $or_cond_i324 = 0, $tib1_121_i326 = 0, $1198 = 0;
- var $1199 = 0, $1200 = 0, $1201 = 0, $i_0_i329 = 0, $1203 = 0, $1205 = 0, $1206 = 0, $1207 = 0;
- var $1208 = 0, $1209 = 0, $1211 = 0, $1212 = 0, $1213 = 0, $1214 = 0, $1215 = 0, $1217 = 0;
- var $1218 = 0, $1220 = 0, $1221 = 0, $1222 = 0, $_r0_sroa_0_0_load605 = 0, $_r3_sroa_0_0_load594 = 0, $_r0_sroa_0_0_load623 = 0, $1223 = 0;
- var $_r0_sroa_1_4__r3_sroa_1_4_idx_idx = 0, $_r0_sroa_1_4_idx156 = 0, $1224 = 0, $1226 = 0, $1227 = 0, $1228 = 0, $1231 = 0, $1232 = 0;
- var $1233 = 0, $1234 = 0, $1236 = 0, $1237 = 0, $1238 = 0, $1239 = 0, $1240 = 0, $1241 = 0;
- var $1242 = 0, $1243 = 0, $1245 = 0, $1246 = 0, $1247 = 0, $1248 = 0, $1249 = 0, $1250 = 0;
- var $1251 = 0, $tib1_0_ph_i290 = 0, $1252 = 0, $1253 = 0, $1254 = 0, $1255 = 0, $tib1_0_lcssa_i293 = 0, $dimension_tib1_0_lcssa_i294 = 0;
- var $1256 = 0, $1257 = 0, $1258 = 0, $1259 = 0, $1260 = 0, $dimension_tib1_029_i296 = 0, $1261 = 0, $1262 = 0;
- var $1263 = 0, $1264 = 0, $1265 = 0, $1266 = 0, $1267 = 0, $1268 = 0, $1269 = 0, $dimension_tib2_024_i298 = 0;
- var $1270 = 0, $1271 = 0, $1272 = 0, $1273 = 0, $1274 = 0, $1275 = 0, $1276 = 0, $1277 = 0;
- var $tib2_0_lcssa_in_i300 = 0, $dimension_tib2_0_lcssa_i301 = 0, $tib2_0_lcssa_i302 = 0, $1278 = 0, $1279 = 0, $or_cond_i303 = 0, $tib1_121_i305 = 0, $1280 = 0;
- var $1281 = 0, $1282 = 0, $1283 = 0, $i_0_i308 = 0, $1285 = 0, $1287 = 0, $1288 = 0, $1289 = 0;
- var $1290 = 0, $1291 = 0, $1293 = 0, $1294 = 0, $1295 = 0, $1296 = 0, $1297 = 0, $1300 = 0;
- var $1301 = 0, $1303 = 0, $1304 = 0, $1305 = 0, $1306 = 0, $1307 = 0, $1308 = 0, $1309 = 0;
- var $1310 = 0, $1312 = 0, $1313 = 0, $1314 = 0, $1315 = 0, $1316 = 0, $1317 = 0, $1318 = 0;
- var $tib1_0_ph_i269 = 0, $1319 = 0, $1320 = 0, $1321 = 0, $1322 = 0, $tib1_0_lcssa_i272 = 0, $dimension_tib1_0_lcssa_i273 = 0, $1323 = 0;
- var $1324 = 0, $1325 = 0, $1326 = 0, $1327 = 0, $dimension_tib1_029_i275 = 0, $1328 = 0, $1329 = 0, $1330 = 0;
- var $1331 = 0, $1332 = 0, $1333 = 0, $1334 = 0, $1335 = 0, $1336 = 0, $dimension_tib2_024_i277 = 0, $1337 = 0;
- var $1338 = 0, $1339 = 0, $1340 = 0, $1341 = 0, $1342 = 0, $1343 = 0, $1344 = 0, $tib2_0_lcssa_in_i279 = 0;
- var $dimension_tib2_0_lcssa_i280 = 0, $tib2_0_lcssa_i281 = 0, $1345 = 0, $1346 = 0, $or_cond_i282 = 0, $tib1_121_i284 = 0, $1347 = 0, $1348 = 0;
- var $1349 = 0, $1350 = 0, $i_0_i287 = 0, $1352 = 0, $1354 = 0, $1355 = 0, $1356 = 0, $1357 = 0;
- var $1358 = 0, $1360 = 0, $1361 = 0, $1362 = 0, $1363 = 0, $1364 = 0, $1366 = 0, $1367 = 0;
- var $1369 = 0, $1370$0 = 0, $1370$1 = 0, $1371 = 0, $1372 = 0, $1373 = 0, $1374 = 0, $1375 = 0;
- var $1376 = 0, $1377 = 0, $1378 = 0, $1379 = 0, $_r0_sroa_0_0_load604 = 0, $1381 = 0, $1382 = 0, $_r3_sroa_0_0_load593 = 0;
- var $1384 = 0, $1385 = 0, $1386 = 0, $1387 = 0, $1388 = 0, $1389 = 0, $1390 = 0, $_r3_sroa_0_0_load = 0;
- var $1391 = 0, $1392 = 0, $1394 = 0, $1395 = 0, $1396 = 0, $1399 = 0, $1400 = 0, $1401 = 0;
- var $1402 = 0, $1404 = 0, $1405 = 0, $1406 = 0, $1407 = 0, $1408 = 0, $1409 = 0, $1410 = 0;
- var $1411 = 0, $1413 = 0, $1414 = 0, $1415 = 0, $1416 = 0, $1417 = 0, $1418 = 0, $1419 = 0;
- var $tib1_0_ph_i248 = 0, $1420 = 0, $1421 = 0, $1422 = 0, $1423 = 0, $tib1_0_lcssa_i251 = 0, $dimension_tib1_0_lcssa_i252 = 0, $1424 = 0;
- var $1425 = 0, $1426 = 0, $1427 = 0, $1428 = 0, $dimension_tib1_029_i254 = 0, $1429 = 0, $1430 = 0, $1431 = 0;
- var $1432 = 0, $1433 = 0, $1434 = 0, $1435 = 0, $1436 = 0, $1437 = 0, $dimension_tib2_024_i256 = 0, $1438 = 0;
- var $1439 = 0, $1440 = 0, $1441 = 0, $1442 = 0, $1443 = 0, $1444 = 0, $1445 = 0, $tib2_0_lcssa_in_i258 = 0;
- var $dimension_tib2_0_lcssa_i259 = 0, $tib2_0_lcssa_i260 = 0, $1446 = 0, $1447 = 0, $or_cond_i261 = 0, $tib1_121_i263 = 0, $1448 = 0, $1449 = 0;
- var $1450 = 0, $1451 = 0, $i_0_i266 = 0, $1453 = 0, $1455 = 0, $1456 = 0, $1457 = 0, $1458 = 0;
- var $1459 = 0, $1461 = 0, $1462 = 0, $1463 = 0, $1464 = 0, $1465 = 0, $1468 = 0, $1469 = 0;
- var $1471 = 0, $1472 = 0, $1473 = 0, $1474 = 0, $1475 = 0, $1476 = 0, $1477 = 0, $1478 = 0;
- var $1480 = 0, $1481 = 0, $1482 = 0, $1483 = 0, $1484 = 0, $1485 = 0, $1486 = 0, $tib1_0_ph_i227 = 0;
- var $1487 = 0, $1488 = 0, $1489 = 0, $1490 = 0, $tib1_0_lcssa_i230 = 0, $dimension_tib1_0_lcssa_i231 = 0, $1491 = 0, $1492 = 0;
- var $1493 = 0, $1494 = 0, $1495 = 0, $dimension_tib1_029_i233 = 0, $1496 = 0, $1497 = 0, $1498 = 0, $1499 = 0;
- var $1500 = 0, $1501 = 0, $1502 = 0, $1503 = 0, $1504 = 0, $dimension_tib2_024_i235 = 0, $1505 = 0, $1506 = 0;
- var $1507 = 0, $1508 = 0, $1509 = 0, $1510 = 0, $1511 = 0, $1512 = 0, $tib2_0_lcssa_in_i237 = 0, $dimension_tib2_0_lcssa_i238 = 0;
- var $tib2_0_lcssa_i239 = 0, $1513 = 0, $1514 = 0, $or_cond_i240 = 0, $tib1_121_i242 = 0, $1515 = 0, $1516 = 0, $1517 = 0;
- var $1518 = 0, $i_0_i245 = 0, $1520 = 0, $1522 = 0, $1523 = 0, $1524 = 0, $1525 = 0, $1526 = 0;
- var $1528 = 0, $1529 = 0, $1530 = 0, $1531 = 0, $1532 = 0, $1533 = 0, $1534 = 0, $1536 = 0;
- var $1537$0 = 0, $1537$1 = 0, $1538 = 0, $1539 = 0, $1540 = 0, $1541 = 0, $1542 = 0, $1543 = 0;
- var $1544 = 0, $1545 = 0, $1546 = 0, $1548 = 0, $1549 = 0, $1551 = 0, $1552$0 = 0, $1552$1 = 0;
- var $1553 = 0, $1554 = 0, $1555 = 0, $1556 = 0, $1557 = 0, $_r0_sroa_0_0_load602 = 0, $1558 = 0, $1559 = 0;
- var $1561 = 0, $1563 = 0, $1564 = 0, $1565 = 0, $1568 = 0, $1569 = 0, $1570 = 0, $1571 = 0;
- var $1573 = 0, $1574 = 0, $1575 = 0, $1576 = 0, $1577 = 0, $1578 = 0, $1579 = 0, $1580 = 0;
- var $1582 = 0, $1583 = 0, $1584 = 0, $1585 = 0, $1586 = 0, $1587 = 0, $1588 = 0, $tib1_0_ph_i185 = 0;
- var $1589 = 0, $1590 = 0, $1591 = 0, $1592 = 0, $tib1_0_lcssa_i188 = 0, $dimension_tib1_0_lcssa_i189 = 0, $1593 = 0, $1594 = 0;
- var $1595 = 0, $1596 = 0, $1597 = 0, $dimension_tib1_029_i191 = 0, $1598 = 0, $1599 = 0, $1600 = 0, $1601 = 0;
- var $1602 = 0, $1603 = 0, $1604 = 0, $1605 = 0, $1606 = 0, $dimension_tib2_024_i193 = 0, $1607 = 0, $1608 = 0;
- var $1609 = 0, $1610 = 0, $1611 = 0, $1612 = 0, $1613 = 0, $1614 = 0, $tib2_0_lcssa_in_i195 = 0, $dimension_tib2_0_lcssa_i196 = 0;
- var $tib2_0_lcssa_i197 = 0, $1615 = 0, $1616 = 0, $or_cond_i198 = 0, $tib1_121_i200 = 0, $1617 = 0, $1618 = 0, $1619 = 0;
- var $1620 = 0, $i_0_i203 = 0, $1622 = 0, $1624 = 0, $1625 = 0, $1626 = 0, $1627 = 0, $1628 = 0;
- var $1630 = 0, $1631 = 0, $1632 = 0, $1633 = 0, $1634 = 0, $1635 = 0, $1636 = 0, $1638 = 0;
- var $1639$0 = 0, $1639$1 = 0, $1640 = 0, $1641 = 0, $1642 = 0, $1643 = 0, $1644 = 0, $1645 = 0;
- var $1646 = 0, $1647 = 0, $1648 = 0, $1650 = 0, $1651 = 0, $1653 = 0, $1654$0 = 0, $1654$1 = 0;
- var $1655 = 0, $1656 = 0, $1657 = 0, $1658 = 0, $1659 = 0, $_r2_sroa_0_0_load = 0, $1660 = 0, $1661 = 0;
- var $1663 = 0, $1664 = 0, $1666 = 0, $1667$0 = 0, $1667$1 = 0, $1668 = 0, $_r0_sroa_0_0_load = 0, $1669 = 0;
- var $1670 = 0, $1671 = 0, $1672 = 0, $1673 = 0, $1674 = 0, $1675 = 0, $1677 = 0, $1678 = 0;
- var $1679 = 0, $1682 = 0, $1683 = 0, $1684 = 0, $1685 = 0, $1687 = 0, $1688 = 0, $1689 = 0;
- var $1690 = 0, $1691 = 0, $1692 = 0, $1693 = 0, $1694 = 0, $1696 = 0, $1697 = 0, $1698 = 0;
- var $1699 = 0, $1700 = 0, $1701 = 0, $1702 = 0, $tib1_0_ph_i = 0, $1703 = 0, $1704 = 0, $1705 = 0;
- var $1706 = 0, $tib1_0_lcssa_i = 0, $dimension_tib1_0_lcssa_i = 0, $1707 = 0, $1708 = 0, $1709 = 0, $1710 = 0, $1711 = 0;
- var $dimension_tib1_029_i = 0, $1712 = 0, $1713 = 0, $1714 = 0, $1715 = 0, $1716 = 0, $1717 = 0, $1718 = 0;
- var $1719 = 0, $1720 = 0, $dimension_tib2_024_i = 0, $1721 = 0, $1722 = 0, $1723 = 0, $1724 = 0, $1725 = 0;
- var $1726 = 0, $1727 = 0, $1728 = 0, $tib2_0_lcssa_in_i = 0, $dimension_tib2_0_lcssa_i = 0, $tib2_0_lcssa_i = 0, $1729 = 0, $1730 = 0;
- var $or_cond_i = 0, $tib1_121_i = 0, $1731 = 0, $1732 = 0, $1733 = 0, $1734 = 0, $i_0_i = 0, $1736 = 0;
- var $1738 = 0, $1739 = 0, $1740 = 0, $1741 = 0, $1742 = 0, $1744 = 0, $1745 = 0, $1746 = 0;
- var $1747 = 0, $1748 = 0;
- var label = 0;
- var __stackBase__ = 0;
- __stackBase__ = STACKTOP;
- STACKTOP = STACKTOP + 536 | 0;
- label = 1;
- var setjmpLabel = 0;
- var setjmpTable = STACKTOP;
- STACKTOP = STACKTOP + 168 | 0;
- HEAP32[setjmpTable >> 2] = 0;
- while (1) switch (label | 0) {
-  case 1:
-  $_r0_sroa_1 = __stackBase__ | 0;
-  $_r3_sroa_1 = __stackBase__ + 8 | 0;
-  $local_env_w4567aaac23b1b6 = __stackBase__ + 16 | 0;
-  $local_env_w4567aaac23b1c16 = __stackBase__ + 56 | 0;
-  $local_env_w4567aaac23b1c22 = __stackBase__ + 96 | 0;
-  $local_env_w4567aaac23b1c24 = __stackBase__ + 136 | 0;
-  $local_env_w4567aaac23b1c26 = __stackBase__ + 176 | 0;
-  $local_env_w4567aaac23b1c29 = __stackBase__ + 216 | 0;
-  $local_env_w4567aaac23b1c31 = __stackBase__ + 256 | 0;
-  $local_env_w4567aaac23b1c35 = __stackBase__ + 296 | 0;
-  $local_env_w4567aaac23b1c40 = __stackBase__ + 336 | 0;
-  $local_env_w4567aaac23b1c42 = __stackBase__ + 376 | 0;
-  $local_env_w4567aaac23b1c44 = __stackBase__ + 416 | 0;
-  $local_env_w4567aaac23b1c48 = __stackBase__ + 456 | 0;
-  $local_env_w4567aaac23b1c50 = __stackBase__ + 496 | 0;
-  $1 = HEAP32[(98772 | 0) >> 2] | 0;
-  $2 = ($1 | 0) == 0;
-  if ($2) {
-   label = 2;
-   break;
-  } else {
-   label = 3;
-   break;
-  }
-  case 2:
-  invoke_v(702);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 3;
-  break;
-  case 3:
-  $_r5_sroa_0 = $n1;
-  $5 = invoke_ii(556, 709 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $6 = $5;
-  $_r0_sroa_0 = $6;
-  $7 = HEAP32[(98772 | 0) >> 2] | 0;
-  $8 = ($7 | 0) == 0;
-  if ($8) {
-   label = 4;
-   break;
-  } else {
-   label = 5;
-   break;
-  }
-  case 4:
-  invoke_v(702);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 5;
-  break;
-  case 5:
-  $11 = HEAP32[136048 >> 2] | 0;
-  $_r1_sroa_0 = $11;
-  $_r1_sroa_0_0_load601 = $_r1_sroa_0;
-  $12 = invoke_ii(202, $_r1_sroa_0_0_load601 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $13 = HEAP32[(105500 | 0) >> 2] | 0;
-  $14 = ($13 | 0) == 0;
-  if ($14) {
-   label = 6;
-   break;
-  } else {
-   label = 7;
-   break;
-  }
-  case 6:
-  invoke_v(30);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 7;
-  break;
-  case 7:
-  $16 = invoke_i(70) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $17$0 = $16;
-  $17$1 = 0;
-  $18 = invoke_iii(364, $17$0 | 0, $17$1 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $19 = $local_env_w4567aaac23b1b6;
-  $20 = $18 + 16 | 0;
-  $21 = $20;
-  $22 = HEAP32[$21 >> 2] | 0;
-  _memcpy($19 | 0, $22 | 0, 40);
-  $23 = HEAP32[$21 >> 2] | 0;
-  $24 = $23;
-  $25 = _saveSetjmp($24 | 0, label, setjmpTable) | 0;
-  label = 413;
-  break;
-  case 413:
-  $26 = ($25 | 0) == 0;
-  if ($26) {
-   label = 8;
-   break;
-  } else {
-   label = 11;
-   break;
-  }
-  case 8:
-  $28 = HEAP32[(98772 | 0) >> 2] | 0;
-  $29 = ($28 | 0) == 0;
-  if ($29) {
-   label = 9;
-   break;
-  } else {
-   label = 10;
-   break;
-  }
-  case 9:
-  invoke_v(702);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 10;
-  break;
-  case 10:
-  $31 = HEAP32[140056 >> 2] | 0;
-  $32 = $31;
-  $_r0_sroa_0 = $32;
-  $_r0_sroa_0_0_load622 = $_r0_sroa_0;
-  $33 = $_r0_sroa_0_0_load622;
-  $34 = $33 | 0;
-  $35 = HEAP32[$34 >> 2] | 0;
-  $36 = $35 + 160 | 0;
-  $37 = HEAP32[$36 >> 2] | 0;
-  $38 = $37;
-  $_r0_sroa_0_0_load621 = $_r0_sroa_0;
-  $39 = $_r0_sroa_0_0_load621;
-  $_r5_sroa_0_0_load592 = $_r5_sroa_0;
-  $40 = invoke_iii($38 | 0, $39 | 0, $_r5_sroa_0_0_load592 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $41 = $40;
-  $_r0_sroa_0 = $41;
-  $_r0_sroa_0_0_load620 = $_r0_sroa_0;
-  $_r0_sroa_0 = $_r0_sroa_0_0_load620;
-  $42 = HEAP32[$21 >> 2] | 0;
-  _memcpy($42 | 0, $19 | 0, 40);
-  $_r0_sroa_0_0_load619 = $_r0_sroa_0;
-  $43 = ($_r0_sroa_0_0_load619 | 0) == 0;
-  if ($43) {
-   label = 32;
-   break;
-  } else {
-   label = 28;
-   break;
-  }
-  case 11:
-  $45 = HEAP32[$21 >> 2] | 0;
-  _memcpy($45 | 0, $19 | 0, 40);
-  $46 = HEAP32[(107740 | 0) >> 2] | 0;
-  $47 = ($46 | 0) == 0;
-  if ($47) {
-   label = 12;
-   break;
-  } else {
-   label = 13;
-   break;
-  }
-  case 12:
-  invoke_v(374);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 13;
-  break;
-  case 13:
-  $50 = $18 + 20 | 0;
-  $51 = $50;
-  $52 = HEAP32[$51 >> 2] | 0;
-  $53 = ($52 | 0) == 0;
-  if ($53) {
-   label = 27;
-   break;
-  } else {
-   label = 14;
-   break;
-  }
-  case 14:
-  $55 = HEAP32[137616 >> 2] | 0;
-  $56 = $52;
-  $57 = HEAP32[$56 >> 2] | 0;
-  $58 = $57;
-  $59 = $55 + 8 | 0;
-  $60 = $59;
-  $61 = HEAP32[$60 >> 2] | 0;
-  $62 = ($57 | 0) == 82712;
-  if ($62) {
-   label = 15;
-   break;
-  } else {
-   $tib1_0_ph_i543 = $58;
-   label = 16;
-   break;
-  }
-  case 15:
-  $64 = $52 + 8 | 0;
-  $65 = $64;
-  $66 = HEAP32[$65 >> 2] | 0;
-  $67 = $66 + 8 | 0;
-  $68 = $67;
-  $69 = HEAP32[$68 >> 2] | 0;
-  $70 = $69;
-  $tib1_0_ph_i543 = $70;
-  label = 16;
-  break;
-  case 16:
-  $71 = $tib1_0_ph_i543 + 56 | 0;
-  $72 = HEAP32[$71 >> 2] | 0;
-  $73 = ($72 | 0) == 0;
-  if ($73) {
-   var $dimension_tib1_0_lcssa_i547 = 0;
-   var $tib1_0_lcssa_i546 = $tib1_0_ph_i543;
-   label = 18;
-   break;
-  } else {
-   var $dimension_tib1_029_i549 = 0;
-   var $79 = $72;
-   label = 19;
-   break;
-  }
-  case 17:
-  $74 = $82;
-  var $dimension_tib1_0_lcssa_i547 = $83;
-  var $tib1_0_lcssa_i546 = $74;
-  label = 18;
-  break;
-  case 18:
-  $75 = $61 + 56 | 0;
-  $76 = $75;
-  $77 = HEAP32[$76 >> 2] | 0;
-  $78 = ($77 | 0) == 0;
-  if ($78) {
-   var $dimension_tib2_0_lcssa_i554 = 0;
-   var $tib2_0_lcssa_in_i553 = $61;
-   label = 21;
-   break;
-  } else {
-   var $dimension_tib2_024_i551 = 0;
-   var $88 = $77;
-   label = 20;
-   break;
-  }
-  case 19:
-  $80 = $79 + 8 | 0;
-  $81 = $80;
-  $82 = HEAP32[$81 >> 2] | 0;
-  $83 = $dimension_tib1_029_i549 + 1 | 0;
-  $84 = $82 + 56 | 0;
-  $85 = $84;
-  $86 = HEAP32[$85 >> 2] | 0;
-  $87 = ($86 | 0) == 0;
-  if ($87) {
-   label = 17;
-   break;
-  } else {
-   var $dimension_tib1_029_i549 = $83;
-   var $79 = $86;
-   label = 19;
-   break;
-  }
-  case 20:
-  $89 = $88 + 8 | 0;
-  $90 = $89;
-  $91 = HEAP32[$90 >> 2] | 0;
-  $92 = $dimension_tib2_024_i551 + 1 | 0;
-  $93 = $91 + 56 | 0;
-  $94 = $93;
-  $95 = HEAP32[$94 >> 2] | 0;
-  $96 = ($95 | 0) == 0;
-  if ($96) {
-   var $dimension_tib2_0_lcssa_i554 = $92;
-   var $tib2_0_lcssa_in_i553 = $91;
-   label = 21;
-   break;
-  } else {
-   var $dimension_tib2_024_i551 = $92;
-   var $88 = $95;
-   label = 20;
-   break;
-  }
-  case 21:
-  $tib2_0_lcssa_i555 = $tib2_0_lcssa_in_i553;
-  $97 = ($dimension_tib1_0_lcssa_i547 | 0) < ($dimension_tib2_0_lcssa_i554 | 0);
-  $98 = ($tib1_0_lcssa_i546 | 0) == 0;
-  $or_cond_i556 = $97 | $98;
-  if ($or_cond_i556) {
-   label = 27;
-   break;
-  } else {
-   $tib1_121_i558 = $tib1_0_lcssa_i546;
-   label = 22;
-   break;
-  }
-  case 22:
-  $99 = ($tib1_121_i558 | 0) == ($tib2_0_lcssa_i555 | 0);
-  if ($99) {
-   label = 54;
-   break;
-  } else {
-   label = 23;
-   break;
-  }
-  case 23:
-  $100 = $tib1_121_i558 + 108 | 0;
-  $101 = HEAP32[$100 >> 2] | 0;
-  $102 = $tib1_121_i558 + 112 | 0;
-  $i_0_i561 = 0;
-  label = 24;
-  break;
-  case 24:
-  $104 = ($i_0_i561 | 0) < ($101 | 0);
-  if ($104) {
-   label = 25;
-   break;
-  } else {
-   label = 26;
-   break;
-  }
-  case 25:
-  $106 = HEAP32[$102 >> 2] | 0;
-  $107 = $106 + ($i_0_i561 << 2) | 0;
-  $108 = HEAP32[$107 >> 2] | 0;
-  $109 = ($108 | 0) == ($tib2_0_lcssa_i555 | 0);
-  $110 = $i_0_i561 + 1 | 0;
-  if ($109) {
-   label = 54;
-   break;
-  } else {
-   $i_0_i561 = $110;
-   label = 24;
-   break;
-  }
-  case 26:
-  $112 = $tib1_121_i558 + 40 | 0;
-  $113 = HEAP32[$112 >> 2] | 0;
-  $114 = ($113 | 0) == 0;
-  if ($114) {
-   label = 27;
-   break;
-  } else {
-   $tib1_121_i558 = $113;
-   label = 22;
-   break;
-  }
-  case 27:
-  $115 = HEAP32[$21 >> 2] | 0;
-  $116 = $115;
-  invoke_vii(48, $116 | 0, 0 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  return 0 | 0;
-  case 28:
-  $_r1_sroa_0_0_load600 = $_r1_sroa_0;
-  $118 = $_r1_sroa_0_0_load600 + 4 | 0;
-  $119 = $118;
-  $120 = HEAP32[$119 >> 2] | 0;
-  $121 = $120 + 8 | 0;
-  $122 = $121;
-  $123 = HEAP32[$122 >> 2] | 0;
-  $124 = $123 - 1 | 0;
-  HEAP32[$122 >> 2] = $124;
-  $125 = HEAP32[$119 >> 2] | 0;
-  $126 = $125 + 8 | 0;
-  $127 = $126;
-  $128 = HEAP32[$127 >> 2] | 0;
-  $129 = ($128 | 0) == 0;
-  if ($129) {
-   label = 29;
-   break;
-  } else {
-   label = 31;
-   break;
-  }
-  case 29:
-  invoke_vi(28, $_r1_sroa_0_0_load600 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $131 = HEAP32[$119 >> 2] | 0;
-  $132 = $131 + 16 | 0;
-  $133 = $132;
-  $134 = HEAP32[$133 >> 2] | 0;
-  $135 = $134 + 8 | 0;
-  $136 = $135;
-  $137 = HEAP32[$136 >> 2] | 0;
-  $138 = $137;
-  $139;
-  $140 = ($139 | 0) == 0;
-  if ($140) {
-   label = 31;
-   break;
-  } else {
-   label = 30;
-   break;
-  }
-  case 30:
-  $142 = invoke_iii(268, 31e3 | 0 | 0, (tempInt = STACKTOP, STACKTOP = STACKTOP + 8 | 0, HEAP32[tempInt >> 2] = $139, tempInt) | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 31;
-  break;
-  case 31:
-  $_r0_sroa_0_0_load618 = $_r0_sroa_0;
-  $143 = $_r0_sroa_0_0_load618;
-  STACKTOP = __stackBase__;
-  return $143 | 0;
-  case 32:
-  $_r5_sroa_0_0_load591 = $_r5_sroa_0;
-  $145 = ($_r5_sroa_0_0_load591 | 0) == 0;
-  $146 = HEAP32[(105500 | 0) >> 2] | 0;
-  $147 = ($146 | 0) == 0;
-  if ($147) {
-   label = 33;
-   break;
-  } else {
-   label = 34;
-   break;
-  }
-  case 33:
-  invoke_v(30);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 34;
-  break;
-  case 34:
-  $149 = invoke_i(70) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $150$0 = $149;
-  $150$1 = 0;
-  $151 = invoke_iii(364, $150$0 | 0, $150$1 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  if ($145) {
-   label = 35;
-   break;
-  } else {
-   label = 62;
-   break;
-  }
-  case 35:
-  $153 = $local_env_w4567aaac23b1c16;
-  $154 = $151 + 16 | 0;
-  $155 = $154;
-  $156 = HEAP32[$155 >> 2] | 0;
-  _memcpy($153 | 0, $156 | 0, 40);
-  $157 = HEAP32[$155 >> 2] | 0;
-  $158 = $157;
-  $159 = _saveSetjmp($158 | 0, label, setjmpTable) | 0;
-  label = 414;
-  break;
-  case 414:
-  $160 = ($159 | 0) == 0;
-  if ($160) {
-   label = 36;
-   break;
-  } else {
-   label = 37;
-   break;
-  }
-  case 36:
-  invoke_viiii(14, 16136 | 0 | 0, 11648 | 0 | 0, 126872 | 0 | 0, 1457 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  return 0 | 0;
-  case 37:
-  $163 = HEAP32[$155 >> 2] | 0;
-  _memcpy($163 | 0, $153 | 0, 40);
-  $164 = HEAP32[(107740 | 0) >> 2] | 0;
-  $165 = ($164 | 0) == 0;
-  if ($165) {
-   label = 38;
-   break;
-  } else {
-   label = 39;
-   break;
-  }
-  case 38:
-  invoke_v(374);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 39;
-  break;
-  case 39:
-  $168 = $151 + 20 | 0;
-  $169 = $168;
-  $170 = HEAP32[$169 >> 2] | 0;
-  $171 = ($170 | 0) == 0;
-  if ($171) {
-   label = 53;
-   break;
-  } else {
-   label = 40;
-   break;
-  }
-  case 40:
-  $173 = HEAP32[137616 >> 2] | 0;
-  $174 = $170;
-  $175 = HEAP32[$174 >> 2] | 0;
-  $176 = $175;
-  $177 = $173 + 8 | 0;
-  $178 = $177;
-  $179 = HEAP32[$178 >> 2] | 0;
-  $180 = ($175 | 0) == 82712;
-  if ($180) {
-   label = 41;
-   break;
-  } else {
-   $tib1_0_ph_i521 = $176;
-   label = 42;
-   break;
-  }
-  case 41:
-  $182 = $170 + 8 | 0;
-  $183 = $182;
-  $184 = HEAP32[$183 >> 2] | 0;
-  $185 = $184 + 8 | 0;
-  $186 = $185;
-  $187 = HEAP32[$186 >> 2] | 0;
-  $188 = $187;
-  $tib1_0_ph_i521 = $188;
-  label = 42;
-  break;
-  case 42:
-  $189 = $tib1_0_ph_i521 + 56 | 0;
-  $190 = HEAP32[$189 >> 2] | 0;
-  $191 = ($190 | 0) == 0;
-  if ($191) {
-   var $dimension_tib1_0_lcssa_i525 = 0;
-   var $tib1_0_lcssa_i524 = $tib1_0_ph_i521;
-   label = 44;
-   break;
-  } else {
-   var $dimension_tib1_029_i527 = 0;
-   var $197 = $190;
-   label = 45;
-   break;
-  }
-  case 43:
-  $192 = $200;
-  var $dimension_tib1_0_lcssa_i525 = $201;
-  var $tib1_0_lcssa_i524 = $192;
-  label = 44;
-  break;
-  case 44:
-  $193 = $179 + 56 | 0;
-  $194 = $193;
-  $195 = HEAP32[$194 >> 2] | 0;
-  $196 = ($195 | 0) == 0;
-  if ($196) {
-   var $dimension_tib2_0_lcssa_i532 = 0;
-   var $tib2_0_lcssa_in_i531 = $179;
-   label = 47;
-   break;
-  } else {
-   var $dimension_tib2_024_i529 = 0;
-   var $206 = $195;
-   label = 46;
-   break;
-  }
-  case 45:
-  $198 = $197 + 8 | 0;
-  $199 = $198;
-  $200 = HEAP32[$199 >> 2] | 0;
-  $201 = $dimension_tib1_029_i527 + 1 | 0;
-  $202 = $200 + 56 | 0;
-  $203 = $202;
-  $204 = HEAP32[$203 >> 2] | 0;
-  $205 = ($204 | 0) == 0;
-  if ($205) {
-   label = 43;
-   break;
-  } else {
-   var $dimension_tib1_029_i527 = $201;
-   var $197 = $204;
-   label = 45;
-   break;
-  }
-  case 46:
-  $207 = $206 + 8 | 0;
-  $208 = $207;
-  $209 = HEAP32[$208 >> 2] | 0;
-  $210 = $dimension_tib2_024_i529 + 1 | 0;
-  $211 = $209 + 56 | 0;
-  $212 = $211;
-  $213 = HEAP32[$212 >> 2] | 0;
-  $214 = ($213 | 0) == 0;
-  if ($214) {
-   var $dimension_tib2_0_lcssa_i532 = $210;
-   var $tib2_0_lcssa_in_i531 = $209;
-   label = 47;
-   break;
-  } else {
-   var $dimension_tib2_024_i529 = $210;
-   var $206 = $213;
-   label = 46;
-   break;
-  }
-  case 47:
-  $tib2_0_lcssa_i533 = $tib2_0_lcssa_in_i531;
-  $215 = ($dimension_tib1_0_lcssa_i525 | 0) < ($dimension_tib2_0_lcssa_i532 | 0);
-  $216 = ($tib1_0_lcssa_i524 | 0) == 0;
-  $or_cond_i534 = $215 | $216;
-  if ($or_cond_i534) {
-   label = 53;
-   break;
-  } else {
-   $tib1_121_i536 = $tib1_0_lcssa_i524;
-   label = 48;
-   break;
-  }
-  case 48:
-  $217 = ($tib1_121_i536 | 0) == ($tib2_0_lcssa_i533 | 0);
-  if ($217) {
-   label = 54;
-   break;
-  } else {
-   label = 49;
-   break;
-  }
-  case 49:
-  $218 = $tib1_121_i536 + 108 | 0;
-  $219 = HEAP32[$218 >> 2] | 0;
-  $220 = $tib1_121_i536 + 112 | 0;
-  $i_0_i539 = 0;
-  label = 50;
-  break;
-  case 50:
-  $222 = ($i_0_i539 | 0) < ($219 | 0);
-  if ($222) {
-   label = 51;
-   break;
-  } else {
-   label = 52;
-   break;
-  }
-  case 51:
-  $224 = HEAP32[$220 >> 2] | 0;
-  $225 = $224 + ($i_0_i539 << 2) | 0;
-  $226 = HEAP32[$225 >> 2] | 0;
-  $227 = ($226 | 0) == ($tib2_0_lcssa_i533 | 0);
-  $228 = $i_0_i539 + 1 | 0;
-  if ($227) {
-   label = 54;
-   break;
-  } else {
-   $i_0_i539 = $228;
-   label = 50;
-   break;
-  }
-  case 52:
-  $230 = $tib1_121_i536 + 40 | 0;
-  $231 = HEAP32[$230 >> 2] | 0;
-  $232 = ($231 | 0) == 0;
-  if ($232) {
-   label = 53;
-   break;
-  } else {
-   $tib1_121_i536 = $231;
-   label = 48;
-   break;
-  }
-  case 53:
-  $233 = HEAP32[$155 >> 2] | 0;
-  $234 = $233;
-  invoke_vii(48, $234 | 0, 0 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  return 0 | 0;
-  case 54:
-  $235 = HEAP32[(105500 | 0) >> 2] | 0;
-  $236 = ($235 | 0) == 0;
-  if ($236) {
-   label = 55;
-   break;
-  } else {
-   label = 56;
-   break;
-  }
-  case 55:
-  invoke_v(30);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 56;
-  break;
-  case 56:
-  $238 = invoke_i(70) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $239$0 = $238;
-  $239$1 = 0;
-  $240 = invoke_iii(364, $239$0 | 0, $239$1 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $241 = $240 + 20 | 0;
-  $242 = $241;
-  $243 = HEAP32[$242 >> 2] | 0;
-  $244 = $243;
-  $_r0_sroa_0 = $244;
-  $_r1_sroa_0_0_load = $_r1_sroa_0;
-  $245 = $_r1_sroa_0_0_load + 4 | 0;
-  $246 = $245;
-  $247 = HEAP32[$246 >> 2] | 0;
-  $248 = $247 + 8 | 0;
-  $249 = $248;
-  $250 = HEAP32[$249 >> 2] | 0;
-  $251 = $250 - 1 | 0;
-  HEAP32[$249 >> 2] = $251;
-  $252 = HEAP32[$246 >> 2] | 0;
-  $253 = $252 + 8 | 0;
-  $254 = $253;
-  $255 = HEAP32[$254 >> 2] | 0;
-  $256 = ($255 | 0) == 0;
-  if ($256) {
-   label = 57;
-   break;
-  } else {
-   label = 59;
-   break;
-  }
-  case 57:
-  invoke_vi(28, $_r1_sroa_0_0_load | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $258 = HEAP32[$246 >> 2] | 0;
-  $259 = $258 + 16 | 0;
-  $260 = $259;
-  $261 = HEAP32[$260 >> 2] | 0;
-  $262 = $261 + 8 | 0;
-  $263 = $262;
-  $264 = HEAP32[$263 >> 2] | 0;
-  $265 = $264;
-  $266;
-  $267 = ($266 | 0) == 0;
-  if ($267) {
-   label = 59;
-   break;
-  } else {
-   label = 58;
-   break;
-  }
-  case 58:
-  $269 = invoke_iii(268, 31e3 | 0 | 0, (tempInt = STACKTOP, STACKTOP = STACKTOP + 8 | 0, HEAP32[tempInt >> 2] = $266, tempInt) | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 59;
-  break;
-  case 59:
-  $270 = HEAP32[(105500 | 0) >> 2] | 0;
-  $271 = ($270 | 0) == 0;
-  if ($271) {
-   label = 60;
-   break;
-  } else {
-   label = 61;
-   break;
-  }
-  case 60:
-  invoke_v(30);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 61;
-  break;
-  case 61:
-  $273 = invoke_i(70) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $274$0 = $273;
-  $274$1 = 0;
-  $275 = invoke_iii(364, $274$0 | 0, $274$1 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $_r0_sroa_0_0_load617 = $_r0_sroa_0;
-  $276 = $_r0_sroa_0_0_load617;
-  $277 = $275 + 16 | 0;
-  $278 = $275 + 20 | 0;
-  $279 = $278;
-  HEAP32[$279 >> 2] = $276;
-  $280 = $277;
-  $281 = HEAP32[$280 >> 2] | 0;
-  $282 = $281;
-  invoke_vii(48, $282 | 0, 0 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  return 0 | 0;
-  case 62:
-  $284 = $local_env_w4567aaac23b1c22;
-  $285 = $151 + 16 | 0;
-  $286 = $285;
-  $287 = HEAP32[$286 >> 2] | 0;
-  _memcpy($284 | 0, $287 | 0, 40);
-  $288 = HEAP32[$286 >> 2] | 0;
-  $289 = $288;
-  $290 = _saveSetjmp($289 | 0, label, setjmpTable) | 0;
-  label = 415;
-  break;
-  case 415:
-  $291 = ($290 | 0) == 0;
-  if ($291) {
-   label = 63;
-   break;
-  } else {
-   label = 72;
-   break;
-  }
-  case 63:
-  $_r5_sroa_0_0_load590 = $_r5_sroa_0;
-  invoke_vi(44, $_r5_sroa_0_0_load590 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $293 = HEAP32[(98772 | 0) >> 2] | 0;
-  $294 = ($293 | 0) == 0;
-  if ($294) {
-   label = 64;
-   break;
-  } else {
-   label = 65;
-   break;
-  }
-  case 64:
-  invoke_v(702);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 65;
-  break;
-  case 65:
-  $296 = HEAP32[140064 >> 2] | 0;
-  $297 = $296;
-  $_r0_sroa_0 = $297;
-  $_r0_sroa_0_0_load616 = $_r0_sroa_0;
-  $298 = ($_r0_sroa_0_0_load616 | 0) == 0;
-  if ($298) {
-   label = 67;
-   break;
-  } else {
-   label = 66;
-   break;
-  }
-  case 66:
-  $300 = HEAP32[$286 >> 2] | 0;
-  _memcpy($300 | 0, $284 | 0, 40);
-  label = 89;
-  break;
-  case 67:
-  $302 = HEAP32[(84292 | 0) >> 2] | 0;
-  $303 = ($302 | 0) == 0;
-  if ($303) {
-   label = 68;
-   break;
-  } else {
-   label = 69;
-   break;
-  }
-  case 68:
-  invoke_v(584);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 69;
-  break;
-  case 69:
-  $305 = invoke_ii(338, 20 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $306 = $305;
-  HEAP32[$306 >> 2] = 84288;
-  $307 = $305 + 4 | 0;
-  _memset($307 | 0 | 0, 0 | 0 | 0, 16 | 0 | 0);
-  $308 = $305;
-  $_r0_sroa_0 = $308;
-  $_r0_sroa_0_0_load615 = $_r0_sroa_0;
-  $309 = $_r0_sroa_0_0_load615;
-  invoke_vi(34, $309 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $_r0_sroa_0_0_load614 = $_r0_sroa_0;
-  $310 = $_r0_sroa_0_0_load614;
-  $311 = HEAP32[(98772 | 0) >> 2] | 0;
-  $312 = ($311 | 0) == 0;
-  if ($312) {
-   label = 70;
-   break;
-  } else {
-   label = 71;
-   break;
-  }
-  case 70:
-  invoke_v(702);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 71;
-  break;
-  case 71:
-  HEAP32[140064 >> 2] = $310;
-  $314 = HEAP32[$286 >> 2] | 0;
-  _memcpy($314 | 0, $284 | 0, 40);
-  label = 89;
-  break;
-  case 72:
-  $316 = HEAP32[$286 >> 2] | 0;
-  _memcpy($316 | 0, $284 | 0, 40);
-  $317 = HEAP32[(107740 | 0) >> 2] | 0;
-  $318 = ($317 | 0) == 0;
-  if ($318) {
-   label = 73;
-   break;
-  } else {
-   label = 74;
-   break;
-  }
-  case 73:
-  invoke_v(374);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 74;
-  break;
-  case 74:
-  $321 = $151 + 20 | 0;
-  $322 = $321;
-  $323 = HEAP32[$322 >> 2] | 0;
-  $324 = ($323 | 0) == 0;
-  if ($324) {
-   label = 88;
-   break;
-  } else {
-   label = 75;
-   break;
-  }
-  case 75:
-  $326 = HEAP32[137616 >> 2] | 0;
-  $327 = $323;
-  $328 = HEAP32[$327 >> 2] | 0;
-  $329 = $328;
-  $330 = $326 + 8 | 0;
-  $331 = $330;
-  $332 = HEAP32[$331 >> 2] | 0;
-  $333 = ($328 | 0) == 82712;
-  if ($333) {
-   label = 76;
-   break;
-  } else {
-   $tib1_0_ph_i500 = $329;
-   label = 77;
-   break;
-  }
-  case 76:
-  $335 = $323 + 8 | 0;
-  $336 = $335;
-  $337 = HEAP32[$336 >> 2] | 0;
-  $338 = $337 + 8 | 0;
-  $339 = $338;
-  $340 = HEAP32[$339 >> 2] | 0;
-  $341 = $340;
-  $tib1_0_ph_i500 = $341;
-  label = 77;
-  break;
-  case 77:
-  $342 = $tib1_0_ph_i500 + 56 | 0;
-  $343 = HEAP32[$342 >> 2] | 0;
-  $344 = ($343 | 0) == 0;
-  if ($344) {
-   var $dimension_tib1_0_lcssa_i504 = 0;
-   var $tib1_0_lcssa_i503 = $tib1_0_ph_i500;
-   label = 79;
-   break;
-  } else {
-   var $dimension_tib1_029_i506 = 0;
-   var $350 = $343;
-   label = 80;
-   break;
-  }
-  case 78:
-  $345 = $353;
-  var $dimension_tib1_0_lcssa_i504 = $354;
-  var $tib1_0_lcssa_i503 = $345;
-  label = 79;
-  break;
-  case 79:
-  $346 = $332 + 56 | 0;
-  $347 = $346;
-  $348 = HEAP32[$347 >> 2] | 0;
-  $349 = ($348 | 0) == 0;
-  if ($349) {
-   var $dimension_tib2_0_lcssa_i511 = 0;
-   var $tib2_0_lcssa_in_i510 = $332;
-   label = 82;
-   break;
-  } else {
-   var $dimension_tib2_024_i508 = 0;
-   var $359 = $348;
-   label = 81;
-   break;
-  }
-  case 80:
-  $351 = $350 + 8 | 0;
-  $352 = $351;
-  $353 = HEAP32[$352 >> 2] | 0;
-  $354 = $dimension_tib1_029_i506 + 1 | 0;
-  $355 = $353 + 56 | 0;
-  $356 = $355;
-  $357 = HEAP32[$356 >> 2] | 0;
-  $358 = ($357 | 0) == 0;
-  if ($358) {
-   label = 78;
-   break;
-  } else {
-   var $dimension_tib1_029_i506 = $354;
-   var $350 = $357;
-   label = 80;
-   break;
-  }
-  case 81:
-  $360 = $359 + 8 | 0;
-  $361 = $360;
-  $362 = HEAP32[$361 >> 2] | 0;
-  $363 = $dimension_tib2_024_i508 + 1 | 0;
-  $364 = $362 + 56 | 0;
-  $365 = $364;
-  $366 = HEAP32[$365 >> 2] | 0;
-  $367 = ($366 | 0) == 0;
-  if ($367) {
-   var $dimension_tib2_0_lcssa_i511 = $363;
-   var $tib2_0_lcssa_in_i510 = $362;
-   label = 82;
-   break;
-  } else {
-   var $dimension_tib2_024_i508 = $363;
-   var $359 = $366;
-   label = 81;
-   break;
-  }
-  case 82:
-  $tib2_0_lcssa_i512 = $tib2_0_lcssa_in_i510;
-  $368 = ($dimension_tib1_0_lcssa_i504 | 0) < ($dimension_tib2_0_lcssa_i511 | 0);
-  $369 = ($tib1_0_lcssa_i503 | 0) == 0;
-  $or_cond_i513 = $368 | $369;
-  if ($or_cond_i513) {
-   label = 88;
-   break;
-  } else {
-   $tib1_121_i515 = $tib1_0_lcssa_i503;
-   label = 83;
-   break;
-  }
-  case 83:
-  $370 = ($tib1_121_i515 | 0) == ($tib2_0_lcssa_i512 | 0);
-  if ($370) {
-   label = 54;
-   break;
-  } else {
-   label = 84;
-   break;
-  }
-  case 84:
-  $371 = $tib1_121_i515 + 108 | 0;
-  $372 = HEAP32[$371 >> 2] | 0;
-  $373 = $tib1_121_i515 + 112 | 0;
-  $i_0_i518 = 0;
-  label = 85;
-  break;
-  case 85:
-  $375 = ($i_0_i518 | 0) < ($372 | 0);
-  if ($375) {
-   label = 86;
-   break;
-  } else {
-   label = 87;
-   break;
-  }
-  case 86:
-  $377 = HEAP32[$373 >> 2] | 0;
-  $378 = $377 + ($i_0_i518 << 2) | 0;
-  $379 = HEAP32[$378 >> 2] | 0;
-  $380 = ($379 | 0) == ($tib2_0_lcssa_i512 | 0);
-  $381 = $i_0_i518 + 1 | 0;
-  if ($380) {
-   label = 54;
-   break;
-  } else {
-   $i_0_i518 = $381;
-   label = 85;
-   break;
-  }
-  case 87:
-  $383 = $tib1_121_i515 + 40 | 0;
-  $384 = HEAP32[$383 >> 2] | 0;
-  $385 = ($384 | 0) == 0;
-  if ($385) {
-   label = 88;
-   break;
-  } else {
-   $tib1_121_i515 = $384;
-   label = 83;
-   break;
-  }
-  case 88:
-  $386 = HEAP32[$286 >> 2] | 0;
-  $387 = $386;
-  invoke_vii(48, $387 | 0, 0 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  return 0 | 0;
-  case 89:
-  $389 = HEAP32[(105500 | 0) >> 2] | 0;
-  $390 = ($389 | 0) == 0;
-  if ($390) {
-   label = 90;
-   break;
-  } else {
-   label = 91;
-   break;
-  }
-  case 90:
-  invoke_v(30);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 91;
-  break;
-  case 91:
-  $392 = invoke_i(70) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $393$0 = $392;
-  $393$1 = 0;
-  $394 = invoke_iii(364, $393$0 | 0, $393$1 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $395 = $local_env_w4567aaac23b1c24;
-  $396 = $394 + 16 | 0;
-  $397 = $396;
-  $398 = HEAP32[$397 >> 2] | 0;
-  _memcpy($395 | 0, $398 | 0, 40);
-  $399 = HEAP32[$397 >> 2] | 0;
-  $400 = $399;
-  $401 = _saveSetjmp($400 | 0, label, setjmpTable) | 0;
-  label = 416;
-  break;
-  case 416:
-  $402 = ($401 | 0) == 0;
-  if ($402) {
-   label = 92;
-   break;
-  } else {
-   label = 99;
-   break;
-  }
-  case 92:
-  $404 = HEAP32[(98772 | 0) >> 2] | 0;
-  $405 = ($404 | 0) == 0;
-  if ($405) {
-   label = 93;
-   break;
-  } else {
-   label = 94;
-   break;
-  }
-  case 93:
-  invoke_v(702);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 94;
-  break;
-  case 94:
-  $407 = HEAP32[140064 >> 2] | 0;
-  $408 = $407;
-  $_r0_sroa_0 = $408;
-  $_r0_sroa_0_0_load613 = $_r0_sroa_0;
-  $409 = $_r0_sroa_0_0_load613;
-  $410 = $409 | 0;
-  $411 = HEAP32[$410 >> 2] | 0;
-  $412 = $411 + 144 | 0;
-  $413 = HEAP32[$412 >> 2] | 0;
-  $414 = $413;
-  $_r0_sroa_0_0_load612 = $_r0_sroa_0;
-  $415 = $_r0_sroa_0_0_load612;
-  $_r5_sroa_0_0_load589 = $_r5_sroa_0;
-  $416 = invoke_iii($414 | 0, $415 | 0, $_r5_sroa_0_0_load589 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $417 = $416;
-  $_r0_sroa_0 = $417;
-  $_r0_sroa_0_0_load611 = $_r0_sroa_0;
-  $418 = ($_r0_sroa_0_0_load611 | 0) == 0;
-  if ($418) {
-   label = 95;
-   break;
-  } else {
-   label = 98;
-   break;
-  }
-  case 95:
-  $420 = HEAP32[$397 >> 2] | 0;
-  _memcpy($420 | 0, $395 | 0, 40);
-  $421 = HEAP32[(105500 | 0) >> 2] | 0;
-  $422 = ($421 | 0) == 0;
-  if ($422) {
-   label = 96;
-   break;
-  } else {
-   label = 97;
-   break;
-  }
-  case 96:
-  invoke_v(30);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 97;
-  break;
-  case 97:
-  $424 = invoke_i(70) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $425$0 = $424;
-  $425$1 = 0;
-  $426 = invoke_iii(364, $425$0 | 0, $425$1 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $427 = $local_env_w4567aaac23b1c26;
-  $428 = $426 + 16 | 0;
-  $429 = $428;
-  $430 = HEAP32[$429 >> 2] | 0;
-  _memcpy($427 | 0, $430 | 0, 40);
-  $431 = HEAP32[$429 >> 2] | 0;
-  $432 = $431;
-  $433 = _saveSetjmp($432 | 0, label, setjmpTable) | 0;
-  label = 417;
-  break;
-  case 417:
-  $434 = ($433 | 0) == 0;
-  if ($434) {
-   label = 116;
-   break;
-  } else {
-   label = 127;
-   break;
-  }
-  case 98:
-  $_r0_sroa_0_0_load610 = $_r0_sroa_0;
-  $436 = $_r0_sroa_0_0_load610;
-  $_r5_sroa_0_0_load588 = $_r5_sroa_0;
-  invoke_vii(24, $436 | 0, $_r5_sroa_0_0_load588 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $437 = HEAP32[$397 >> 2] | 0;
-  _memcpy($437 | 0, $395 | 0, 40);
-  label = 28;
-  break;
-  case 99:
-  $439 = HEAP32[$397 >> 2] | 0;
-  _memcpy($439 | 0, $395 | 0, 40);
-  $440 = HEAP32[(107740 | 0) >> 2] | 0;
-  $441 = ($440 | 0) == 0;
-  if ($441) {
-   label = 100;
-   break;
-  } else {
-   label = 101;
-   break;
-  }
-  case 100:
-  invoke_v(374);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 101;
-  break;
-  case 101:
-  $444 = $394 + 20 | 0;
-  $445 = $444;
-  $446 = HEAP32[$445 >> 2] | 0;
-  $447 = ($446 | 0) == 0;
-  if ($447) {
-   label = 115;
-   break;
-  } else {
-   label = 102;
-   break;
-  }
-  case 102:
-  $449 = HEAP32[137616 >> 2] | 0;
-  $450 = $446;
-  $451 = HEAP32[$450 >> 2] | 0;
-  $452 = $451;
-  $453 = $449 + 8 | 0;
-  $454 = $453;
-  $455 = HEAP32[$454 >> 2] | 0;
-  $456 = ($451 | 0) == 82712;
-  if ($456) {
-   label = 103;
-   break;
-  } else {
-   $tib1_0_ph_i479 = $452;
-   label = 104;
-   break;
-  }
-  case 103:
-  $458 = $446 + 8 | 0;
-  $459 = $458;
-  $460 = HEAP32[$459 >> 2] | 0;
-  $461 = $460 + 8 | 0;
-  $462 = $461;
-  $463 = HEAP32[$462 >> 2] | 0;
-  $464 = $463;
-  $tib1_0_ph_i479 = $464;
-  label = 104;
-  break;
-  case 104:
-  $465 = $tib1_0_ph_i479 + 56 | 0;
-  $466 = HEAP32[$465 >> 2] | 0;
-  $467 = ($466 | 0) == 0;
-  if ($467) {
-   var $dimension_tib1_0_lcssa_i483 = 0;
-   var $tib1_0_lcssa_i482 = $tib1_0_ph_i479;
-   label = 106;
-   break;
-  } else {
-   var $dimension_tib1_029_i485 = 0;
-   var $473 = $466;
-   label = 107;
-   break;
-  }
-  case 105:
-  $468 = $476;
-  var $dimension_tib1_0_lcssa_i483 = $477;
-  var $tib1_0_lcssa_i482 = $468;
-  label = 106;
-  break;
-  case 106:
-  $469 = $455 + 56 | 0;
-  $470 = $469;
-  $471 = HEAP32[$470 >> 2] | 0;
-  $472 = ($471 | 0) == 0;
-  if ($472) {
-   var $dimension_tib2_0_lcssa_i490 = 0;
-   var $tib2_0_lcssa_in_i489 = $455;
-   label = 109;
-   break;
-  } else {
-   var $dimension_tib2_024_i487 = 0;
-   var $482 = $471;
-   label = 108;
-   break;
-  }
-  case 107:
-  $474 = $473 + 8 | 0;
-  $475 = $474;
-  $476 = HEAP32[$475 >> 2] | 0;
-  $477 = $dimension_tib1_029_i485 + 1 | 0;
-  $478 = $476 + 56 | 0;
-  $479 = $478;
-  $480 = HEAP32[$479 >> 2] | 0;
-  $481 = ($480 | 0) == 0;
-  if ($481) {
-   label = 105;
-   break;
-  } else {
-   var $dimension_tib1_029_i485 = $477;
-   var $473 = $480;
-   label = 107;
-   break;
-  }
-  case 108:
-  $483 = $482 + 8 | 0;
-  $484 = $483;
-  $485 = HEAP32[$484 >> 2] | 0;
-  $486 = $dimension_tib2_024_i487 + 1 | 0;
-  $487 = $485 + 56 | 0;
-  $488 = $487;
-  $489 = HEAP32[$488 >> 2] | 0;
-  $490 = ($489 | 0) == 0;
-  if ($490) {
-   var $dimension_tib2_0_lcssa_i490 = $486;
-   var $tib2_0_lcssa_in_i489 = $485;
-   label = 109;
-   break;
-  } else {
-   var $dimension_tib2_024_i487 = $486;
-   var $482 = $489;
-   label = 108;
-   break;
-  }
-  case 109:
-  $tib2_0_lcssa_i491 = $tib2_0_lcssa_in_i489;
-  $491 = ($dimension_tib1_0_lcssa_i483 | 0) < ($dimension_tib2_0_lcssa_i490 | 0);
-  $492 = ($tib1_0_lcssa_i482 | 0) == 0;
-  $or_cond_i492 = $491 | $492;
-  if ($or_cond_i492) {
-   label = 115;
-   break;
-  } else {
-   $tib1_121_i494 = $tib1_0_lcssa_i482;
-   label = 110;
-   break;
-  }
-  case 110:
-  $493 = ($tib1_121_i494 | 0) == ($tib2_0_lcssa_i491 | 0);
-  if ($493) {
-   label = 54;
-   break;
-  } else {
-   label = 111;
-   break;
-  }
-  case 111:
-  $494 = $tib1_121_i494 + 108 | 0;
-  $495 = HEAP32[$494 >> 2] | 0;
-  $496 = $tib1_121_i494 + 112 | 0;
-  $i_0_i497 = 0;
-  label = 112;
-  break;
-  case 112:
-  $498 = ($i_0_i497 | 0) < ($495 | 0);
-  if ($498) {
-   label = 113;
-   break;
-  } else {
-   label = 114;
-   break;
-  }
-  case 113:
-  $500 = HEAP32[$496 >> 2] | 0;
-  $501 = $500 + ($i_0_i497 << 2) | 0;
-  $502 = HEAP32[$501 >> 2] | 0;
-  $503 = ($502 | 0) == ($tib2_0_lcssa_i491 | 0);
-  $504 = $i_0_i497 + 1 | 0;
-  if ($503) {
-   label = 54;
-   break;
-  } else {
-   $i_0_i497 = $504;
-   label = 112;
-   break;
-  }
-  case 114:
-  $506 = $tib1_121_i494 + 40 | 0;
-  $507 = HEAP32[$506 >> 2] | 0;
-  $508 = ($507 | 0) == 0;
-  if ($508) {
-   label = 115;
-   break;
-  } else {
-   $tib1_121_i494 = $507;
-   label = 110;
-   break;
-  }
-  case 115:
-  $509 = HEAP32[$397 >> 2] | 0;
-  $510 = $509;
-  invoke_vii(48, $510 | 0, 0 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  return 0 | 0;
-  case 116:
-  $512 = HEAP32[(98772 | 0) >> 2] | 0;
-  $513 = ($512 | 0) == 0;
-  if ($513) {
-   label = 117;
-   break;
-  } else {
-   label = 118;
-   break;
-  }
-  case 117:
-  invoke_v(702);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 118;
-  break;
-  case 118:
-  $516 = HEAP32[(105500 | 0) >> 2] | 0;
-  $517 = ($516 | 0) == 0;
-  if ($517) {
-   label = 119;
-   break;
-  } else {
-   label = 120;
-   break;
-  }
-  case 119:
-  invoke_v(30);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 120;
-  break;
-  case 120:
-  $519 = invoke_i(70) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $520$0 = $519;
-  $520$1 = 0;
-  $521 = invoke_iii(364, $520$0 | 0, $520$1 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $522 = HEAP32[(98148 | 0) >> 2] | 0;
-  $523 = ($522 | 0) == 0;
-  if ($523) {
-   label = 121;
-   break;
-  } else {
-   label = 122;
-   break;
-  }
-  case 121:
-  invoke_v(408);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 122;
-  break;
-  case 122:
-  $525 = invoke_ii(338, 12 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $526 = $525;
-  HEAP32[$526 >> 2] = 98144;
-  $527 = $525 + 4 | 0;
-  $528 = $527;
-  HEAP32[$528 >> 2] = 0;
-  $529 = $525 + 8 | 0;
-  $530 = $529;
-  HEAP32[$530 >> 2] = $521;
-  $531 = HEAP32[(97532 | 0) >> 2] | 0;
-  $532 = ($531 | 0) == 0;
-  if ($532) {
-   label = 123;
-   break;
-  } else {
-   $534 = 98144;
-   label = 124;
-   break;
-  }
-  case 123:
-  invoke_v(568);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $_phi_trans_insert = $525;
-  $_pre = HEAP32[$_phi_trans_insert >> 2] | 0;
-  $534 = $_pre;
-  label = 124;
-  break;
-  case 124:
-  $535 = $534 + 116 | 0;
-  $536 = HEAP32[$535 >> 2] | 0;
-  $537 = HEAP32[$536 >> 2] | 0;
-  $538 = $537;
-  $539 = invoke_ii($538 | 0, $525 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $540 = $539;
-  $_r2_sroa_0 = $540;
-  $541 = HEAP32[$429 >> 2] | 0;
-  _memcpy($541 | 0, $427 | 0, 40);
-  $_r2_sroa_0_0_load599 = $_r2_sroa_0;
-  $542 = ($_r2_sroa_0_0_load599 | 0) == 0;
-  $543 = HEAP32[(105500 | 0) >> 2] | 0;
-  $544 = ($543 | 0) == 0;
-  if ($544) {
-   label = 125;
-   break;
-  } else {
-   label = 126;
-   break;
-  }
-  case 125:
-  invoke_v(30);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 126;
-  break;
-  case 126:
-  $546 = invoke_i(70) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $547$0 = $546;
-  $547$1 = 0;
-  $548 = invoke_iii(364, $547$0 | 0, $547$1 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  if ($542) {
-   label = 240;
-   break;
-  } else {
-   label = 144;
-   break;
-  }
-  case 127:
-  $550 = HEAP32[$429 >> 2] | 0;
-  _memcpy($550 | 0, $427 | 0, 40);
-  $551 = HEAP32[(107740 | 0) >> 2] | 0;
-  $552 = ($551 | 0) == 0;
-  if ($552) {
-   label = 128;
-   break;
-  } else {
-   label = 129;
-   break;
-  }
-  case 128:
-  invoke_v(374);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 129;
-  break;
-  case 129:
-  $555 = $426 + 20 | 0;
-  $556 = $555;
-  $557 = HEAP32[$556 >> 2] | 0;
-  $558 = ($557 | 0) == 0;
-  if ($558) {
-   label = 143;
-   break;
-  } else {
-   label = 130;
-   break;
-  }
-  case 130:
-  $560 = HEAP32[137616 >> 2] | 0;
-  $561 = $557;
-  $562 = HEAP32[$561 >> 2] | 0;
-  $563 = $562;
-  $564 = $560 + 8 | 0;
-  $565 = $564;
-  $566 = HEAP32[$565 >> 2] | 0;
-  $567 = ($562 | 0) == 82712;
-  if ($567) {
-   label = 131;
-   break;
-  } else {
-   $tib1_0_ph_i458 = $563;
-   label = 132;
-   break;
-  }
-  case 131:
-  $569 = $557 + 8 | 0;
-  $570 = $569;
-  $571 = HEAP32[$570 >> 2] | 0;
-  $572 = $571 + 8 | 0;
-  $573 = $572;
-  $574 = HEAP32[$573 >> 2] | 0;
-  $575 = $574;
-  $tib1_0_ph_i458 = $575;
-  label = 132;
-  break;
-  case 132:
-  $576 = $tib1_0_ph_i458 + 56 | 0;
-  $577 = HEAP32[$576 >> 2] | 0;
-  $578 = ($577 | 0) == 0;
-  if ($578) {
-   var $dimension_tib1_0_lcssa_i462 = 0;
-   var $tib1_0_lcssa_i461 = $tib1_0_ph_i458;
-   label = 134;
-   break;
-  } else {
-   var $dimension_tib1_029_i464 = 0;
-   var $584 = $577;
-   label = 135;
-   break;
-  }
-  case 133:
-  $579 = $587;
-  var $dimension_tib1_0_lcssa_i462 = $588;
-  var $tib1_0_lcssa_i461 = $579;
-  label = 134;
-  break;
-  case 134:
-  $580 = $566 + 56 | 0;
-  $581 = $580;
-  $582 = HEAP32[$581 >> 2] | 0;
-  $583 = ($582 | 0) == 0;
-  if ($583) {
-   var $dimension_tib2_0_lcssa_i469 = 0;
-   var $tib2_0_lcssa_in_i468 = $566;
-   label = 137;
-   break;
-  } else {
-   var $dimension_tib2_024_i466 = 0;
-   var $593 = $582;
-   label = 136;
-   break;
-  }
-  case 135:
-  $585 = $584 + 8 | 0;
-  $586 = $585;
-  $587 = HEAP32[$586 >> 2] | 0;
-  $588 = $dimension_tib1_029_i464 + 1 | 0;
-  $589 = $587 + 56 | 0;
-  $590 = $589;
-  $591 = HEAP32[$590 >> 2] | 0;
-  $592 = ($591 | 0) == 0;
-  if ($592) {
-   label = 133;
-   break;
-  } else {
-   var $dimension_tib1_029_i464 = $588;
-   var $584 = $591;
-   label = 135;
-   break;
-  }
-  case 136:
-  $594 = $593 + 8 | 0;
-  $595 = $594;
-  $596 = HEAP32[$595 >> 2] | 0;
-  $597 = $dimension_tib2_024_i466 + 1 | 0;
-  $598 = $596 + 56 | 0;
-  $599 = $598;
-  $600 = HEAP32[$599 >> 2] | 0;
-  $601 = ($600 | 0) == 0;
-  if ($601) {
-   var $dimension_tib2_0_lcssa_i469 = $597;
-   var $tib2_0_lcssa_in_i468 = $596;
-   label = 137;
-   break;
-  } else {
-   var $dimension_tib2_024_i466 = $597;
-   var $593 = $600;
-   label = 136;
-   break;
-  }
-  case 137:
-  $tib2_0_lcssa_i470 = $tib2_0_lcssa_in_i468;
-  $602 = ($dimension_tib1_0_lcssa_i462 | 0) < ($dimension_tib2_0_lcssa_i469 | 0);
-  $603 = ($tib1_0_lcssa_i461 | 0) == 0;
-  $or_cond_i471 = $602 | $603;
-  if ($or_cond_i471) {
-   label = 143;
-   break;
-  } else {
-   $tib1_121_i473 = $tib1_0_lcssa_i461;
-   label = 138;
-   break;
-  }
-  case 138:
-  $604 = ($tib1_121_i473 | 0) == ($tib2_0_lcssa_i470 | 0);
-  if ($604) {
-   label = 54;
-   break;
-  } else {
-   label = 139;
-   break;
-  }
-  case 139:
-  $605 = $tib1_121_i473 + 108 | 0;
-  $606 = HEAP32[$605 >> 2] | 0;
-  $607 = $tib1_121_i473 + 112 | 0;
-  $i_0_i476 = 0;
-  label = 140;
-  break;
-  case 140:
-  $609 = ($i_0_i476 | 0) < ($606 | 0);
-  if ($609) {
-   label = 141;
-   break;
-  } else {
-   label = 142;
-   break;
-  }
-  case 141:
-  $611 = HEAP32[$607 >> 2] | 0;
-  $612 = $611 + ($i_0_i476 << 2) | 0;
-  $613 = HEAP32[$612 >> 2] | 0;
-  $614 = ($613 | 0) == ($tib2_0_lcssa_i470 | 0);
-  $615 = $i_0_i476 + 1 | 0;
-  if ($614) {
-   label = 54;
-   break;
-  } else {
-   $i_0_i476 = $615;
-   label = 140;
-   break;
-  }
-  case 142:
-  $617 = $tib1_121_i473 + 40 | 0;
-  $618 = HEAP32[$617 >> 2] | 0;
-  $619 = ($618 | 0) == 0;
-  if ($619) {
-   label = 143;
-   break;
-  } else {
-   $tib1_121_i473 = $618;
-   label = 138;
-   break;
-  }
-  case 143:
-  $620 = HEAP32[$429 >> 2] | 0;
-  $621 = $620;
-  invoke_vii(48, $621 | 0, 0 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  return 0 | 0;
-  case 144:
-  $623 = $local_env_w4567aaac23b1c29;
-  $624 = $548 + 16 | 0;
-  $625 = $624;
-  $626 = HEAP32[$625 >> 2] | 0;
-  _memcpy($623 | 0, $626 | 0, 40);
-  $627 = HEAP32[$625 >> 2] | 0;
-  $628 = $627;
-  $629 = _saveSetjmp($628 | 0, label, setjmpTable) | 0;
-  label = 418;
-  break;
-  case 418:
-  $630 = ($629 | 0) == 0;
-  if ($630) {
-   label = 145;
-   break;
-  } else {
-   label = 146;
-   break;
-  }
-  case 145:
-  $632 = invoke_ii(556, 709 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $633 = $632;
-  $_r0_sroa_0 = $633;
-  $_r2_sroa_0_0_load598 = $_r2_sroa_0;
-  $_r0_sroa_0_0_load609 = $_r0_sroa_0;
-  $_r0_sroa_0 = 0;
-  $_r0_sroa_0_0_load624 = $_r0_sroa_0;
-  $634 = $_r0_sroa_0_0_load624;
-  $_r3_sroa_0 = $634;
-  $_r0_sroa_1_4__r3_sroa_1_4_idx108_idx = $_r3_sroa_1 | 0;
-  $_r0_sroa_1_4_idx = $_r0_sroa_1 | 0;
-  HEAP32[$_r0_sroa_1_4__r3_sroa_1_4_idx108_idx >> 2] = HEAP32[$_r0_sroa_1_4_idx >> 2] | 0;
-  $635 = HEAP32[$625 >> 2] | 0;
-  _memcpy($635 | 0, $623 | 0, 40);
-  label = 179;
-  break;
-  case 146:
-  $637 = HEAP32[$625 >> 2] | 0;
-  _memcpy($637 | 0, $623 | 0, 40);
-  $638 = HEAP32[(113236 | 0) >> 2] | 0;
-  $639 = ($638 | 0) == 0;
-  if ($639) {
-   label = 147;
-   break;
-  } else {
-   label = 148;
-   break;
-  }
-  case 147:
-  invoke_v(538);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 148;
-  break;
-  case 148:
-  $642 = $548 + 20 | 0;
-  $643 = $642;
-  $644 = HEAP32[$643 >> 2] | 0;
-  $645 = ($644 | 0) == 0;
-  if ($645) {
-   label = 162;
-   break;
-  } else {
-   label = 149;
-   break;
-  }
-  case 149:
-  $647 = HEAP32[138672 >> 2] | 0;
-  $648 = $644;
-  $649 = HEAP32[$648 >> 2] | 0;
-  $650 = $649;
-  $651 = $647 + 8 | 0;
-  $652 = $651;
-  $653 = HEAP32[$652 >> 2] | 0;
-  $654 = ($649 | 0) == 82712;
-  if ($654) {
-   label = 150;
-   break;
-  } else {
-   $tib1_0_ph_i437 = $650;
-   label = 151;
-   break;
-  }
-  case 150:
-  $656 = $644 + 8 | 0;
-  $657 = $656;
-  $658 = HEAP32[$657 >> 2] | 0;
-  $659 = $658 + 8 | 0;
-  $660 = $659;
-  $661 = HEAP32[$660 >> 2] | 0;
-  $662 = $661;
-  $tib1_0_ph_i437 = $662;
-  label = 151;
-  break;
-  case 151:
-  $663 = $tib1_0_ph_i437 + 56 | 0;
-  $664 = HEAP32[$663 >> 2] | 0;
-  $665 = ($664 | 0) == 0;
-  if ($665) {
-   var $dimension_tib1_0_lcssa_i441 = 0;
-   var $tib1_0_lcssa_i440 = $tib1_0_ph_i437;
-   label = 153;
-   break;
-  } else {
-   var $dimension_tib1_029_i443 = 0;
-   var $671 = $664;
-   label = 154;
-   break;
-  }
-  case 152:
-  $666 = $674;
-  var $dimension_tib1_0_lcssa_i441 = $675;
-  var $tib1_0_lcssa_i440 = $666;
-  label = 153;
-  break;
-  case 153:
-  $667 = $653 + 56 | 0;
-  $668 = $667;
-  $669 = HEAP32[$668 >> 2] | 0;
-  $670 = ($669 | 0) == 0;
-  if ($670) {
-   var $dimension_tib2_0_lcssa_i448 = 0;
-   var $tib2_0_lcssa_in_i447 = $653;
-   label = 156;
-   break;
-  } else {
-   var $dimension_tib2_024_i445 = 0;
-   var $680 = $669;
-   label = 155;
-   break;
-  }
-  case 154:
-  $672 = $671 + 8 | 0;
-  $673 = $672;
-  $674 = HEAP32[$673 >> 2] | 0;
-  $675 = $dimension_tib1_029_i443 + 1 | 0;
-  $676 = $674 + 56 | 0;
-  $677 = $676;
-  $678 = HEAP32[$677 >> 2] | 0;
-  $679 = ($678 | 0) == 0;
-  if ($679) {
-   label = 152;
-   break;
-  } else {
-   var $dimension_tib1_029_i443 = $675;
-   var $671 = $678;
-   label = 154;
-   break;
-  }
-  case 155:
-  $681 = $680 + 8 | 0;
-  $682 = $681;
-  $683 = HEAP32[$682 >> 2] | 0;
-  $684 = $dimension_tib2_024_i445 + 1 | 0;
-  $685 = $683 + 56 | 0;
-  $686 = $685;
-  $687 = HEAP32[$686 >> 2] | 0;
-  $688 = ($687 | 0) == 0;
-  if ($688) {
-   var $dimension_tib2_0_lcssa_i448 = $684;
-   var $tib2_0_lcssa_in_i447 = $683;
-   label = 156;
-   break;
-  } else {
-   var $dimension_tib2_024_i445 = $684;
-   var $680 = $687;
-   label = 155;
-   break;
-  }
-  case 156:
-  $tib2_0_lcssa_i449 = $tib2_0_lcssa_in_i447;
-  $689 = ($dimension_tib1_0_lcssa_i441 | 0) < ($dimension_tib2_0_lcssa_i448 | 0);
-  $690 = ($tib1_0_lcssa_i440 | 0) == 0;
-  $or_cond_i450 = $689 | $690;
-  if ($or_cond_i450) {
-   label = 162;
-   break;
-  } else {
-   $tib1_121_i452 = $tib1_0_lcssa_i440;
-   label = 157;
-   break;
-  }
-  case 157:
-  $691 = ($tib1_121_i452 | 0) == ($tib2_0_lcssa_i449 | 0);
-  if ($691) {
-   label = 361;
-   break;
-  } else {
-   label = 158;
-   break;
-  }
-  case 158:
-  $692 = $tib1_121_i452 + 108 | 0;
-  $693 = HEAP32[$692 >> 2] | 0;
-  $694 = $tib1_121_i452 + 112 | 0;
-  $i_0_i455 = 0;
-  label = 159;
-  break;
-  case 159:
-  $696 = ($i_0_i455 | 0) < ($693 | 0);
-  if ($696) {
-   label = 160;
-   break;
-  } else {
-   label = 161;
-   break;
-  }
-  case 160:
-  $698 = HEAP32[$694 >> 2] | 0;
-  $699 = $698 + ($i_0_i455 << 2) | 0;
-  $700 = HEAP32[$699 >> 2] | 0;
-  $701 = ($700 | 0) == ($tib2_0_lcssa_i449 | 0);
-  $702 = $i_0_i455 + 1 | 0;
-  if ($701) {
-   label = 361;
-   break;
-  } else {
-   $i_0_i455 = $702;
-   label = 159;
-   break;
-  }
-  case 161:
-  $704 = $tib1_121_i452 + 40 | 0;
-  $705 = HEAP32[$704 >> 2] | 0;
-  $706 = ($705 | 0) == 0;
-  if ($706) {
-   label = 162;
-   break;
-  } else {
-   $tib1_121_i452 = $705;
-   label = 157;
-   break;
-  }
-  case 162:
-  $707 = HEAP32[(107740 | 0) >> 2] | 0;
-  $708 = ($707 | 0) == 0;
-  if ($708) {
-   label = 163;
-   break;
-  } else {
-   label = 164;
-   break;
-  }
-  case 163:
-  invoke_v(374);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 164;
-  break;
-  case 164:
-  $711 = HEAP32[$643 >> 2] | 0;
-  $712 = ($711 | 0) == 0;
-  if ($712) {
-   label = 178;
-   break;
-  } else {
-   label = 165;
-   break;
-  }
-  case 165:
-  $714 = HEAP32[137616 >> 2] | 0;
-  $715 = $711;
-  $716 = HEAP32[$715 >> 2] | 0;
-  $717 = $716;
-  $718 = $714 + 8 | 0;
-  $719 = $718;
-  $720 = HEAP32[$719 >> 2] | 0;
-  $721 = ($716 | 0) == 82712;
-  if ($721) {
-   label = 166;
-   break;
-  } else {
-   $tib1_0_ph_i416 = $717;
-   label = 167;
-   break;
-  }
-  case 166:
-  $723 = $711 + 8 | 0;
-  $724 = $723;
-  $725 = HEAP32[$724 >> 2] | 0;
-  $726 = $725 + 8 | 0;
-  $727 = $726;
-  $728 = HEAP32[$727 >> 2] | 0;
-  $729 = $728;
-  $tib1_0_ph_i416 = $729;
-  label = 167;
-  break;
-  case 167:
-  $730 = $tib1_0_ph_i416 + 56 | 0;
-  $731 = HEAP32[$730 >> 2] | 0;
-  $732 = ($731 | 0) == 0;
-  if ($732) {
-   var $dimension_tib1_0_lcssa_i420 = 0;
-   var $tib1_0_lcssa_i419 = $tib1_0_ph_i416;
-   label = 169;
-   break;
-  } else {
-   var $dimension_tib1_029_i422 = 0;
-   var $738 = $731;
-   label = 170;
-   break;
-  }
-  case 168:
-  $733 = $741;
-  var $dimension_tib1_0_lcssa_i420 = $742;
-  var $tib1_0_lcssa_i419 = $733;
-  label = 169;
-  break;
-  case 169:
-  $734 = $720 + 56 | 0;
-  $735 = $734;
-  $736 = HEAP32[$735 >> 2] | 0;
-  $737 = ($736 | 0) == 0;
-  if ($737) {
-   var $dimension_tib2_0_lcssa_i427 = 0;
-   var $tib2_0_lcssa_in_i426 = $720;
-   label = 172;
-   break;
-  } else {
-   var $dimension_tib2_024_i424 = 0;
-   var $747 = $736;
-   label = 171;
-   break;
-  }
-  case 170:
-  $739 = $738 + 8 | 0;
-  $740 = $739;
-  $741 = HEAP32[$740 >> 2] | 0;
-  $742 = $dimension_tib1_029_i422 + 1 | 0;
-  $743 = $741 + 56 | 0;
-  $744 = $743;
-  $745 = HEAP32[$744 >> 2] | 0;
-  $746 = ($745 | 0) == 0;
-  if ($746) {
-   label = 168;
-   break;
-  } else {
-   var $dimension_tib1_029_i422 = $742;
-   var $738 = $745;
-   label = 170;
-   break;
-  }
-  case 171:
-  $748 = $747 + 8 | 0;
-  $749 = $748;
-  $750 = HEAP32[$749 >> 2] | 0;
-  $751 = $dimension_tib2_024_i424 + 1 | 0;
-  $752 = $750 + 56 | 0;
-  $753 = $752;
-  $754 = HEAP32[$753 >> 2] | 0;
-  $755 = ($754 | 0) == 0;
-  if ($755) {
-   var $dimension_tib2_0_lcssa_i427 = $751;
-   var $tib2_0_lcssa_in_i426 = $750;
-   label = 172;
-   break;
-  } else {
-   var $dimension_tib2_024_i424 = $751;
-   var $747 = $754;
-   label = 171;
-   break;
-  }
-  case 172:
-  $tib2_0_lcssa_i428 = $tib2_0_lcssa_in_i426;
-  $756 = ($dimension_tib1_0_lcssa_i420 | 0) < ($dimension_tib2_0_lcssa_i427 | 0);
-  $757 = ($tib1_0_lcssa_i419 | 0) == 0;
-  $or_cond_i429 = $756 | $757;
-  if ($or_cond_i429) {
-   label = 178;
-   break;
-  } else {
-   $tib1_121_i431 = $tib1_0_lcssa_i419;
-   label = 173;
-   break;
-  }
-  case 173:
-  $758 = ($tib1_121_i431 | 0) == ($tib2_0_lcssa_i428 | 0);
-  if ($758) {
-   label = 386;
-   break;
-  } else {
-   label = 174;
-   break;
-  }
-  case 174:
-  $759 = $tib1_121_i431 + 108 | 0;
-  $760 = HEAP32[$759 >> 2] | 0;
-  $761 = $tib1_121_i431 + 112 | 0;
-  $i_0_i434 = 0;
-  label = 175;
-  break;
-  case 175:
-  $763 = ($i_0_i434 | 0) < ($760 | 0);
-  if ($763) {
-   label = 176;
-   break;
-  } else {
-   label = 177;
-   break;
-  }
-  case 176:
-  $765 = HEAP32[$761 >> 2] | 0;
-  $766 = $765 + ($i_0_i434 << 2) | 0;
-  $767 = HEAP32[$766 >> 2] | 0;
-  $768 = ($767 | 0) == ($tib2_0_lcssa_i428 | 0);
-  $769 = $i_0_i434 + 1 | 0;
-  if ($768) {
-   label = 386;
-   break;
-  } else {
-   $i_0_i434 = $769;
-   label = 175;
-   break;
-  }
-  case 177:
-  $771 = $tib1_121_i431 + 40 | 0;
-  $772 = HEAP32[$771 >> 2] | 0;
-  $773 = ($772 | 0) == 0;
-  if ($773) {
-   label = 178;
-   break;
-  } else {
-   $tib1_121_i431 = $772;
-   label = 173;
-   break;
-  }
-  case 178:
-  $774 = HEAP32[$625 >> 2] | 0;
-  $775 = $774;
-  invoke_vii(48, $775 | 0, 0 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  return 0 | 0;
-  case 179:
-  $777 = HEAP32[(105500 | 0) >> 2] | 0;
-  $778 = ($777 | 0) == 0;
-  if ($778) {
-   label = 180;
-   break;
-  } else {
-   label = 181;
-   break;
-  }
-  case 180:
-  invoke_v(30);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 181;
-  break;
-  case 181:
-  $780 = invoke_i(70) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $781$0 = $780;
-  $781$1 = 0;
-  $782 = invoke_iii(364, $781$0 | 0, $781$1 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $783 = $local_env_w4567aaac23b1c31;
-  $784 = $782 + 16 | 0;
-  $785 = $784;
-  $786 = HEAP32[$785 >> 2] | 0;
-  _memcpy($783 | 0, $786 | 0, 40);
-  $787 = HEAP32[$785 >> 2] | 0;
-  $788 = $787;
-  $789 = _saveSetjmp($788 | 0, label, setjmpTable) | 0;
-  label = 419;
-  break;
-  case 419:
-  $790 = ($789 | 0) == 0;
-  if ($790) {
-   label = 182;
-   break;
-  } else {
-   label = 183;
-   break;
-  }
-  case 182:
-  $_r3_sroa_0_0_load596 = $_r3_sroa_0;
-  $792 = $_r3_sroa_0_0_load596;
-  $793 = HEAP32[$792 >> 2] | 0;
-  $794 = $793 + 116 | 0;
-  $795 = HEAP32[$794 >> 2] | 0;
-  $796 = HEAP32[$795 >> 2] | 0;
-  $797 = $796;
-  $_r3_sroa_0_0_load595 = $_r3_sroa_0;
-  $798 = invoke_ii($797 | 0, $_r3_sroa_0_0_load595 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $_r0_sroa_0 = $798;
-  $799 = HEAP32[$785 >> 2] | 0;
-  _memcpy($799 | 0, $783 | 0, 40);
-  $_r0_sroa_0_0_load608 = $_r0_sroa_0;
-  $800 = ($_r0_sroa_0_0_load608 | 0) == 0;
-  if ($800) {
-   label = 216;
-   break;
-  } else {
-   label = 322;
-   break;
-  }
-  case 183:
-  $802 = HEAP32[$785 >> 2] | 0;
-  _memcpy($802 | 0, $783 | 0, 40);
-  $803 = HEAP32[(113236 | 0) >> 2] | 0;
-  $804 = ($803 | 0) == 0;
-  if ($804) {
-   label = 184;
-   break;
-  } else {
-   label = 185;
-   break;
-  }
-  case 184:
-  invoke_v(538);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 185;
-  break;
-  case 185:
-  $807 = $782 + 20 | 0;
-  $808 = $807;
-  $809 = HEAP32[$808 >> 2] | 0;
-  $810 = ($809 | 0) == 0;
-  if ($810) {
-   label = 199;
-   break;
-  } else {
-   label = 186;
-   break;
-  }
-  case 186:
-  $812 = HEAP32[138672 >> 2] | 0;
-  $813 = $809;
-  $814 = HEAP32[$813 >> 2] | 0;
-  $815 = $814;
-  $816 = $812 + 8 | 0;
-  $817 = $816;
-  $818 = HEAP32[$817 >> 2] | 0;
-  $819 = ($814 | 0) == 82712;
-  if ($819) {
-   label = 187;
-   break;
-  } else {
-   $tib1_0_ph_i395 = $815;
-   label = 188;
-   break;
-  }
-  case 187:
-  $821 = $809 + 8 | 0;
-  $822 = $821;
-  $823 = HEAP32[$822 >> 2] | 0;
-  $824 = $823 + 8 | 0;
-  $825 = $824;
-  $826 = HEAP32[$825 >> 2] | 0;
-  $827 = $826;
-  $tib1_0_ph_i395 = $827;
-  label = 188;
-  break;
-  case 188:
-  $828 = $tib1_0_ph_i395 + 56 | 0;
-  $829 = HEAP32[$828 >> 2] | 0;
-  $830 = ($829 | 0) == 0;
-  if ($830) {
-   var $dimension_tib1_0_lcssa_i399 = 0;
-   var $tib1_0_lcssa_i398 = $tib1_0_ph_i395;
-   label = 190;
-   break;
-  } else {
-   var $dimension_tib1_029_i401 = 0;
-   var $836 = $829;
-   label = 191;
-   break;
-  }
-  case 189:
-  $831 = $839;
-  var $dimension_tib1_0_lcssa_i399 = $840;
-  var $tib1_0_lcssa_i398 = $831;
-  label = 190;
-  break;
-  case 190:
-  $832 = $818 + 56 | 0;
-  $833 = $832;
-  $834 = HEAP32[$833 >> 2] | 0;
-  $835 = ($834 | 0) == 0;
-  if ($835) {
-   var $dimension_tib2_0_lcssa_i406 = 0;
-   var $tib2_0_lcssa_in_i405 = $818;
-   label = 193;
-   break;
-  } else {
-   var $dimension_tib2_024_i403 = 0;
-   var $845 = $834;
-   label = 192;
-   break;
-  }
-  case 191:
-  $837 = $836 + 8 | 0;
-  $838 = $837;
-  $839 = HEAP32[$838 >> 2] | 0;
-  $840 = $dimension_tib1_029_i401 + 1 | 0;
-  $841 = $839 + 56 | 0;
-  $842 = $841;
-  $843 = HEAP32[$842 >> 2] | 0;
-  $844 = ($843 | 0) == 0;
-  if ($844) {
-   label = 189;
-   break;
-  } else {
-   var $dimension_tib1_029_i401 = $840;
-   var $836 = $843;
-   label = 191;
-   break;
-  }
-  case 192:
-  $846 = $845 + 8 | 0;
-  $847 = $846;
-  $848 = HEAP32[$847 >> 2] | 0;
-  $849 = $dimension_tib2_024_i403 + 1 | 0;
-  $850 = $848 + 56 | 0;
-  $851 = $850;
-  $852 = HEAP32[$851 >> 2] | 0;
-  $853 = ($852 | 0) == 0;
-  if ($853) {
-   var $dimension_tib2_0_lcssa_i406 = $849;
-   var $tib2_0_lcssa_in_i405 = $848;
-   label = 193;
-   break;
-  } else {
-   var $dimension_tib2_024_i403 = $849;
-   var $845 = $852;
-   label = 192;
-   break;
-  }
-  case 193:
-  $tib2_0_lcssa_i407 = $tib2_0_lcssa_in_i405;
-  $854 = ($dimension_tib1_0_lcssa_i399 | 0) < ($dimension_tib2_0_lcssa_i406 | 0);
-  $855 = ($tib1_0_lcssa_i398 | 0) == 0;
-  $or_cond_i408 = $854 | $855;
-  if ($or_cond_i408) {
-   label = 199;
-   break;
-  } else {
-   $tib1_121_i410 = $tib1_0_lcssa_i398;
-   label = 194;
-   break;
-  }
-  case 194:
-  $856 = ($tib1_121_i410 | 0) == ($tib2_0_lcssa_i407 | 0);
-  if ($856) {
-   label = 361;
-   break;
-  } else {
-   label = 195;
-   break;
-  }
-  case 195:
-  $857 = $tib1_121_i410 + 108 | 0;
-  $858 = HEAP32[$857 >> 2] | 0;
-  $859 = $tib1_121_i410 + 112 | 0;
-  $i_0_i413 = 0;
-  label = 196;
-  break;
-  case 196:
-  $861 = ($i_0_i413 | 0) < ($858 | 0);
-  if ($861) {
-   label = 197;
-   break;
-  } else {
-   label = 198;
-   break;
-  }
-  case 197:
-  $863 = HEAP32[$859 >> 2] | 0;
-  $864 = $863 + ($i_0_i413 << 2) | 0;
-  $865 = HEAP32[$864 >> 2] | 0;
-  $866 = ($865 | 0) == ($tib2_0_lcssa_i407 | 0);
-  $867 = $i_0_i413 + 1 | 0;
-  if ($866) {
-   label = 361;
-   break;
-  } else {
-   $i_0_i413 = $867;
-   label = 196;
-   break;
-  }
-  case 198:
-  $869 = $tib1_121_i410 + 40 | 0;
-  $870 = HEAP32[$869 >> 2] | 0;
-  $871 = ($870 | 0) == 0;
-  if ($871) {
-   label = 199;
-   break;
-  } else {
-   $tib1_121_i410 = $870;
-   label = 194;
-   break;
-  }
-  case 199:
-  $872 = HEAP32[(107740 | 0) >> 2] | 0;
-  $873 = ($872 | 0) == 0;
-  if ($873) {
-   label = 200;
-   break;
-  } else {
-   label = 201;
-   break;
-  }
-  case 200:
-  invoke_v(374);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 201;
-  break;
-  case 201:
-  $876 = HEAP32[$808 >> 2] | 0;
-  $877 = ($876 | 0) == 0;
-  if ($877) {
-   label = 215;
-   break;
-  } else {
-   label = 202;
-   break;
-  }
-  case 202:
-  $879 = HEAP32[137616 >> 2] | 0;
-  $880 = $876;
-  $881 = HEAP32[$880 >> 2] | 0;
-  $882 = $881;
-  $883 = $879 + 8 | 0;
-  $884 = $883;
-  $885 = HEAP32[$884 >> 2] | 0;
-  $886 = ($881 | 0) == 82712;
-  if ($886) {
-   label = 203;
-   break;
-  } else {
-   $tib1_0_ph_i374 = $882;
-   label = 204;
-   break;
-  }
-  case 203:
-  $888 = $876 + 8 | 0;
-  $889 = $888;
-  $890 = HEAP32[$889 >> 2] | 0;
-  $891 = $890 + 8 | 0;
-  $892 = $891;
-  $893 = HEAP32[$892 >> 2] | 0;
-  $894 = $893;
-  $tib1_0_ph_i374 = $894;
-  label = 204;
-  break;
-  case 204:
-  $895 = $tib1_0_ph_i374 + 56 | 0;
-  $896 = HEAP32[$895 >> 2] | 0;
-  $897 = ($896 | 0) == 0;
-  if ($897) {
-   var $dimension_tib1_0_lcssa_i378 = 0;
-   var $tib1_0_lcssa_i377 = $tib1_0_ph_i374;
-   label = 206;
-   break;
-  } else {
-   var $dimension_tib1_029_i380 = 0;
-   var $903 = $896;
-   label = 207;
-   break;
-  }
-  case 205:
-  $898 = $906;
-  var $dimension_tib1_0_lcssa_i378 = $907;
-  var $tib1_0_lcssa_i377 = $898;
-  label = 206;
-  break;
-  case 206:
-  $899 = $885 + 56 | 0;
-  $900 = $899;
-  $901 = HEAP32[$900 >> 2] | 0;
-  $902 = ($901 | 0) == 0;
-  if ($902) {
-   var $dimension_tib2_0_lcssa_i385 = 0;
-   var $tib2_0_lcssa_in_i384 = $885;
-   label = 209;
-   break;
-  } else {
-   var $dimension_tib2_024_i382 = 0;
-   var $912 = $901;
-   label = 208;
-   break;
-  }
-  case 207:
-  $904 = $903 + 8 | 0;
-  $905 = $904;
-  $906 = HEAP32[$905 >> 2] | 0;
-  $907 = $dimension_tib1_029_i380 + 1 | 0;
-  $908 = $906 + 56 | 0;
-  $909 = $908;
-  $910 = HEAP32[$909 >> 2] | 0;
-  $911 = ($910 | 0) == 0;
-  if ($911) {
-   label = 205;
-   break;
-  } else {
-   var $dimension_tib1_029_i380 = $907;
-   var $903 = $910;
-   label = 207;
-   break;
-  }
-  case 208:
-  $913 = $912 + 8 | 0;
-  $914 = $913;
-  $915 = HEAP32[$914 >> 2] | 0;
-  $916 = $dimension_tib2_024_i382 + 1 | 0;
-  $917 = $915 + 56 | 0;
-  $918 = $917;
-  $919 = HEAP32[$918 >> 2] | 0;
-  $920 = ($919 | 0) == 0;
-  if ($920) {
-   var $dimension_tib2_0_lcssa_i385 = $916;
-   var $tib2_0_lcssa_in_i384 = $915;
-   label = 209;
-   break;
-  } else {
-   var $dimension_tib2_024_i382 = $916;
-   var $912 = $919;
-   label = 208;
-   break;
-  }
-  case 209:
-  $tib2_0_lcssa_i386 = $tib2_0_lcssa_in_i384;
-  $921 = ($dimension_tib1_0_lcssa_i378 | 0) < ($dimension_tib2_0_lcssa_i385 | 0);
-  $922 = ($tib1_0_lcssa_i377 | 0) == 0;
-  $or_cond_i387 = $921 | $922;
-  if ($or_cond_i387) {
-   label = 215;
-   break;
-  } else {
-   $tib1_121_i389 = $tib1_0_lcssa_i377;
-   label = 210;
-   break;
-  }
-  case 210:
-  $923 = ($tib1_121_i389 | 0) == ($tib2_0_lcssa_i386 | 0);
-  if ($923) {
-   label = 386;
-   break;
-  } else {
-   label = 211;
-   break;
-  }
-  case 211:
-  $924 = $tib1_121_i389 + 108 | 0;
-  $925 = HEAP32[$924 >> 2] | 0;
-  $926 = $tib1_121_i389 + 112 | 0;
-  $i_0_i392 = 0;
-  label = 212;
-  break;
-  case 212:
-  $928 = ($i_0_i392 | 0) < ($925 | 0);
-  if ($928) {
-   label = 213;
-   break;
-  } else {
-   label = 214;
-   break;
-  }
-  case 213:
-  $930 = HEAP32[$926 >> 2] | 0;
-  $931 = $930 + ($i_0_i392 << 2) | 0;
-  $932 = HEAP32[$931 >> 2] | 0;
-  $933 = ($932 | 0) == ($tib2_0_lcssa_i386 | 0);
-  $934 = $i_0_i392 + 1 | 0;
-  if ($933) {
-   label = 386;
-   break;
-  } else {
-   $i_0_i392 = $934;
-   label = 212;
-   break;
-  }
-  case 214:
-  $936 = $tib1_121_i389 + 40 | 0;
-  $937 = HEAP32[$936 >> 2] | 0;
-  $938 = ($937 | 0) == 0;
-  if ($938) {
-   label = 215;
-   break;
-  } else {
-   $tib1_121_i389 = $937;
-   label = 210;
-   break;
-  }
-  case 215:
-  $939 = HEAP32[$785 >> 2] | 0;
-  $940 = $939;
-  invoke_vii(48, $940 | 0, 0 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  return 0 | 0;
-  case 216:
-  $_r0_sroa_0 = 0;
-  $942 = HEAP32[(105500 | 0) >> 2] | 0;
-  $943 = ($942 | 0) == 0;
-  if ($943) {
-   label = 217;
-   break;
-  } else {
-   label = 218;
-   break;
-  }
-  case 217:
-  invoke_v(30);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 218;
-  break;
-  case 218:
-  $945 = invoke_i(70) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $946$0 = $945;
-  $946$1 = 0;
-  $947 = invoke_iii(364, $946$0 | 0, $946$1 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $948 = $local_env_w4567aaac23b1c35;
-  $949 = $947 + 16 | 0;
-  $950 = $949;
-  $951 = HEAP32[$950 >> 2] | 0;
-  _memcpy($948 | 0, $951 | 0, 40);
-  $952 = HEAP32[$950 >> 2] | 0;
-  $953 = $952;
-  $954 = _saveSetjmp($953 | 0, label, setjmpTable) | 0;
-  label = 420;
-  break;
-  case 420:
-  $955 = ($954 | 0) == 0;
-  if ($955) {
-   label = 219;
-   break;
-  } else {
-   label = 222;
-   break;
-  }
-  case 219:
-  $_r0_sroa_0_0_load607 = $_r0_sroa_0;
-  $957 = HEAP32[(98772 | 0) >> 2] | 0;
-  $958 = ($957 | 0) == 0;
-  if ($958) {
-   label = 220;
-   break;
-  } else {
-   label = 221;
-   break;
-  }
-  case 220:
-  invoke_v(702);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 221;
-  break;
-  case 221:
-  HEAP32[140048 >> 2] = $_r0_sroa_0_0_load607;
-  $960 = HEAP32[$950 >> 2] | 0;
-  _memcpy($960 | 0, $948 | 0, 40);
-  label = 239;
-  break;
-  case 222:
-  $962 = HEAP32[$950 >> 2] | 0;
-  _memcpy($962 | 0, $948 | 0, 40);
-  $963 = HEAP32[(107740 | 0) >> 2] | 0;
-  $964 = ($963 | 0) == 0;
-  if ($964) {
-   label = 223;
-   break;
-  } else {
-   label = 224;
-   break;
-  }
-  case 223:
-  invoke_v(374);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 224;
-  break;
-  case 224:
-  $967 = $947 + 20 | 0;
-  $968 = $967;
-  $969 = HEAP32[$968 >> 2] | 0;
-  $970 = ($969 | 0) == 0;
-  if ($970) {
-   label = 238;
-   break;
-  } else {
-   label = 225;
-   break;
-  }
-  case 225:
-  $972 = HEAP32[137616 >> 2] | 0;
-  $973 = $969;
-  $974 = HEAP32[$973 >> 2] | 0;
-  $975 = $974;
-  $976 = $972 + 8 | 0;
-  $977 = $976;
-  $978 = HEAP32[$977 >> 2] | 0;
-  $979 = ($974 | 0) == 82712;
-  if ($979) {
-   label = 226;
-   break;
-  } else {
-   $tib1_0_ph_i353 = $975;
-   label = 227;
-   break;
-  }
-  case 226:
-  $981 = $969 + 8 | 0;
-  $982 = $981;
-  $983 = HEAP32[$982 >> 2] | 0;
-  $984 = $983 + 8 | 0;
-  $985 = $984;
-  $986 = HEAP32[$985 >> 2] | 0;
-  $987 = $986;
-  $tib1_0_ph_i353 = $987;
-  label = 227;
-  break;
-  case 227:
-  $988 = $tib1_0_ph_i353 + 56 | 0;
-  $989 = HEAP32[$988 >> 2] | 0;
-  $990 = ($989 | 0) == 0;
-  if ($990) {
-   var $dimension_tib1_0_lcssa_i357 = 0;
-   var $tib1_0_lcssa_i356 = $tib1_0_ph_i353;
-   label = 229;
-   break;
-  } else {
-   var $dimension_tib1_029_i359 = 0;
-   var $996 = $989;
-   label = 230;
-   break;
-  }
-  case 228:
-  $991 = $999;
-  var $dimension_tib1_0_lcssa_i357 = $1000;
-  var $tib1_0_lcssa_i356 = $991;
-  label = 229;
-  break;
-  case 229:
-  $992 = $978 + 56 | 0;
-  $993 = $992;
-  $994 = HEAP32[$993 >> 2] | 0;
-  $995 = ($994 | 0) == 0;
-  if ($995) {
-   var $dimension_tib2_0_lcssa_i364 = 0;
-   var $tib2_0_lcssa_in_i363 = $978;
-   label = 232;
-   break;
-  } else {
-   var $dimension_tib2_024_i361 = 0;
-   var $1005 = $994;
-   label = 231;
-   break;
-  }
-  case 230:
-  $997 = $996 + 8 | 0;
-  $998 = $997;
-  $999 = HEAP32[$998 >> 2] | 0;
-  $1000 = $dimension_tib1_029_i359 + 1 | 0;
-  $1001 = $999 + 56 | 0;
-  $1002 = $1001;
-  $1003 = HEAP32[$1002 >> 2] | 0;
-  $1004 = ($1003 | 0) == 0;
-  if ($1004) {
-   label = 228;
-   break;
-  } else {
-   var $dimension_tib1_029_i359 = $1000;
-   var $996 = $1003;
-   label = 230;
-   break;
-  }
-  case 231:
-  $1006 = $1005 + 8 | 0;
-  $1007 = $1006;
-  $1008 = HEAP32[$1007 >> 2] | 0;
-  $1009 = $dimension_tib2_024_i361 + 1 | 0;
-  $1010 = $1008 + 56 | 0;
-  $1011 = $1010;
-  $1012 = HEAP32[$1011 >> 2] | 0;
-  $1013 = ($1012 | 0) == 0;
-  if ($1013) {
-   var $dimension_tib2_0_lcssa_i364 = $1009;
-   var $tib2_0_lcssa_in_i363 = $1008;
-   label = 232;
-   break;
-  } else {
-   var $dimension_tib2_024_i361 = $1009;
-   var $1005 = $1012;
-   label = 231;
-   break;
-  }
-  case 232:
-  $tib2_0_lcssa_i365 = $tib2_0_lcssa_in_i363;
-  $1014 = ($dimension_tib1_0_lcssa_i357 | 0) < ($dimension_tib2_0_lcssa_i364 | 0);
-  $1015 = ($tib1_0_lcssa_i356 | 0) == 0;
-  $or_cond_i366 = $1014 | $1015;
-  if ($or_cond_i366) {
-   label = 238;
-   break;
-  } else {
-   $tib1_121_i368 = $tib1_0_lcssa_i356;
-   label = 233;
-   break;
-  }
-  case 233:
-  $1016 = ($tib1_121_i368 | 0) == ($tib2_0_lcssa_i365 | 0);
-  if ($1016) {
-   label = 54;
-   break;
-  } else {
-   label = 234;
-   break;
-  }
-  case 234:
-  $1017 = $tib1_121_i368 + 108 | 0;
-  $1018 = HEAP32[$1017 >> 2] | 0;
-  $1019 = $tib1_121_i368 + 112 | 0;
-  $i_0_i371 = 0;
-  label = 235;
-  break;
-  case 235:
-  $1021 = ($i_0_i371 | 0) < ($1018 | 0);
-  if ($1021) {
-   label = 236;
-   break;
-  } else {
-   label = 237;
-   break;
-  }
-  case 236:
-  $1023 = HEAP32[$1019 >> 2] | 0;
-  $1024 = $1023 + ($i_0_i371 << 2) | 0;
-  $1025 = HEAP32[$1024 >> 2] | 0;
-  $1026 = ($1025 | 0) == ($tib2_0_lcssa_i365 | 0);
-  $1027 = $i_0_i371 + 1 | 0;
-  if ($1026) {
-   label = 54;
-   break;
-  } else {
-   $i_0_i371 = $1027;
-   label = 235;
-   break;
-  }
-  case 237:
-  $1029 = $tib1_121_i368 + 40 | 0;
-  $1030 = HEAP32[$1029 >> 2] | 0;
-  $1031 = ($1030 | 0) == 0;
-  if ($1031) {
-   label = 238;
-   break;
-  } else {
-   $tib1_121_i368 = $1030;
-   label = 233;
-   break;
-  }
-  case 238:
-  $1032 = HEAP32[$950 >> 2] | 0;
-  $1033 = $1032;
-  invoke_vii(48, $1033 | 0, 0 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  return 0 | 0;
-  case 239:
-  $_r0_sroa_0 = 0;
-  label = 28;
-  break;
-  case 240:
-  $1036 = $local_env_w4567aaac23b1c40;
-  $1037 = $548 + 16 | 0;
-  $1038 = $1037;
-  $1039 = HEAP32[$1038 >> 2] | 0;
-  _memcpy($1036 | 0, $1039 | 0, 40);
-  $1040 = HEAP32[$1038 >> 2] | 0;
-  $1041 = $1040;
-  $1042 = _saveSetjmp($1041 | 0, label, setjmpTable) | 0;
-  label = 421;
-  break;
-  case 421:
-  $1043 = ($1042 | 0) == 0;
-  if ($1043) {
-   label = 241;
-   break;
-  } else {
-   label = 253;
-   break;
-  }
-  case 241:
-  $1045 = HEAP32[(98772 | 0) >> 2] | 0;
-  $1046 = ($1045 | 0) == 0;
-  if ($1046) {
-   label = 242;
-   break;
-  } else {
-   label = 244;
-   break;
-  }
-  case 242:
-  invoke_v(702);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $_pr = HEAP32[(98772 | 0) >> 2] | 0;
-  $1048 = ($_pr | 0) == 0;
-  if ($1048) {
-   label = 243;
-   break;
-  } else {
-   label = 244;
-   break;
-  }
-  case 243:
-  invoke_v(702);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 244;
-  break;
-  case 244:
-  $1050 = HEAP32[140040 >> 2] | 0;
-  $1051 = ($1050 | 0) == 0;
-  if ($1051) {
-   label = 245;
-   break;
-  } else {
-   label = 246;
-   break;
-  }
-  case 245:
-  invoke_viiii(14, 16136 | 0 | 0, 11648 | 0 | 0, 126768 | 0 | 0, 573 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  return 0 | 0;
-  case 246:
-  $1053 = HEAP32[(98772 | 0) >> 2] | 0;
-  $1054 = ($1053 | 0) == 0;
-  if ($1054) {
-   label = 247;
-   break;
-  } else {
-   $1056 = $1050;
-   label = 248;
-   break;
-  }
-  case 247:
-  invoke_v(702);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $_pre855 = HEAP32[140040 >> 2] | 0;
-  $1056 = $_pre855;
-  label = 248;
-  break;
-  case 248:
-  $1057 = $1056;
-  $_r0_sroa_0 = $1057;
-  $_r0_sroa_0_0_load606 = $_r0_sroa_0;
-  $1058 = ($_r0_sroa_0_0_load606 | 0) == 0;
-  if ($1058) {
-   label = 252;
-   break;
-  } else {
-   label = 249;
-   break;
-  }
-  case 249:
-  $1060 = HEAP32[$1038 >> 2] | 0;
-  _memcpy($1060 | 0, $1036 | 0, 40);
-  $1061 = HEAP32[(105500 | 0) >> 2] | 0;
-  $1062 = ($1061 | 0) == 0;
-  if ($1062) {
-   label = 250;
-   break;
-  } else {
-   label = 251;
-   break;
-  }
-  case 250:
-  invoke_v(30);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 251;
-  break;
-  case 251:
-  $1064 = invoke_i(70) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $1065$0 = $1064;
-  $1065$1 = 0;
-  $1066 = invoke_iii(364, $1065$0 | 0, $1065$1 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $1067 = $local_env_w4567aaac23b1c42;
-  $1068 = $1066 + 16 | 0;
-  $1069 = $1068;
-  $1070 = HEAP32[$1069 >> 2] | 0;
-  _memcpy($1067 | 0, $1070 | 0, 40);
-  $1071 = HEAP32[$1069 >> 2] | 0;
-  $1072 = $1071;
-  $1073 = _saveSetjmp($1072 | 0, label, setjmpTable) | 0;
-  label = 422;
-  break;
-  case 422:
-  $1074 = ($1073 | 0) == 0;
-  if ($1074) {
-   label = 286;
-   break;
-  } else {
-   label = 289;
-   break;
-  }
-  case 252:
-  invoke_viiii(14, 16136 | 0 | 0, 11648 | 0 | 0, 126872 | 0 | 0, 1581 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  return 0 | 0;
-  case 253:
-  $1077 = HEAP32[$1038 >> 2] | 0;
-  _memcpy($1077 | 0, $1036 | 0, 40);
-  $1078 = HEAP32[(113236 | 0) >> 2] | 0;
-  $1079 = ($1078 | 0) == 0;
-  if ($1079) {
-   label = 254;
-   break;
-  } else {
-   label = 255;
-   break;
-  }
-  case 254:
-  invoke_v(538);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 255;
-  break;
-  case 255:
-  $1082 = $548 + 20 | 0;
-  $1083 = $1082;
-  $1084 = HEAP32[$1083 >> 2] | 0;
-  $1085 = ($1084 | 0) == 0;
-  if ($1085) {
-   label = 269;
-   break;
-  } else {
-   label = 256;
-   break;
-  }
-  case 256:
-  $1087 = HEAP32[138672 >> 2] | 0;
-  $1088 = $1084;
-  $1089 = HEAP32[$1088 >> 2] | 0;
-  $1090 = $1089;
-  $1091 = $1087 + 8 | 0;
-  $1092 = $1091;
-  $1093 = HEAP32[$1092 >> 2] | 0;
-  $1094 = ($1089 | 0) == 82712;
-  if ($1094) {
-   label = 257;
-   break;
-  } else {
-   $tib1_0_ph_i332 = $1090;
-   label = 258;
-   break;
-  }
-  case 257:
-  $1096 = $1084 + 8 | 0;
-  $1097 = $1096;
-  $1098 = HEAP32[$1097 >> 2] | 0;
-  $1099 = $1098 + 8 | 0;
-  $1100 = $1099;
-  $1101 = HEAP32[$1100 >> 2] | 0;
-  $1102 = $1101;
-  $tib1_0_ph_i332 = $1102;
-  label = 258;
-  break;
-  case 258:
-  $1103 = $tib1_0_ph_i332 + 56 | 0;
-  $1104 = HEAP32[$1103 >> 2] | 0;
-  $1105 = ($1104 | 0) == 0;
-  if ($1105) {
-   var $dimension_tib1_0_lcssa_i336 = 0;
-   var $tib1_0_lcssa_i335 = $tib1_0_ph_i332;
-   label = 260;
-   break;
-  } else {
-   var $dimension_tib1_029_i338 = 0;
-   var $1111 = $1104;
-   label = 261;
-   break;
-  }
-  case 259:
-  $1106 = $1114;
-  var $dimension_tib1_0_lcssa_i336 = $1115;
-  var $tib1_0_lcssa_i335 = $1106;
-  label = 260;
-  break;
-  case 260:
-  $1107 = $1093 + 56 | 0;
-  $1108 = $1107;
-  $1109 = HEAP32[$1108 >> 2] | 0;
-  $1110 = ($1109 | 0) == 0;
-  if ($1110) {
-   var $dimension_tib2_0_lcssa_i343 = 0;
-   var $tib2_0_lcssa_in_i342 = $1093;
-   label = 263;
-   break;
-  } else {
-   var $dimension_tib2_024_i340 = 0;
-   var $1120 = $1109;
-   label = 262;
-   break;
-  }
-  case 261:
-  $1112 = $1111 + 8 | 0;
-  $1113 = $1112;
-  $1114 = HEAP32[$1113 >> 2] | 0;
-  $1115 = $dimension_tib1_029_i338 + 1 | 0;
-  $1116 = $1114 + 56 | 0;
-  $1117 = $1116;
-  $1118 = HEAP32[$1117 >> 2] | 0;
-  $1119 = ($1118 | 0) == 0;
-  if ($1119) {
-   label = 259;
-   break;
-  } else {
-   var $dimension_tib1_029_i338 = $1115;
-   var $1111 = $1118;
-   label = 261;
-   break;
-  }
-  case 262:
-  $1121 = $1120 + 8 | 0;
-  $1122 = $1121;
-  $1123 = HEAP32[$1122 >> 2] | 0;
-  $1124 = $dimension_tib2_024_i340 + 1 | 0;
-  $1125 = $1123 + 56 | 0;
-  $1126 = $1125;
-  $1127 = HEAP32[$1126 >> 2] | 0;
-  $1128 = ($1127 | 0) == 0;
-  if ($1128) {
-   var $dimension_tib2_0_lcssa_i343 = $1124;
-   var $tib2_0_lcssa_in_i342 = $1123;
-   label = 263;
-   break;
-  } else {
-   var $dimension_tib2_024_i340 = $1124;
-   var $1120 = $1127;
-   label = 262;
-   break;
-  }
-  case 263:
-  $tib2_0_lcssa_i344 = $tib2_0_lcssa_in_i342;
-  $1129 = ($dimension_tib1_0_lcssa_i336 | 0) < ($dimension_tib2_0_lcssa_i343 | 0);
-  $1130 = ($tib1_0_lcssa_i335 | 0) == 0;
-  $or_cond_i345 = $1129 | $1130;
-  if ($or_cond_i345) {
-   label = 269;
-   break;
-  } else {
-   $tib1_121_i347 = $tib1_0_lcssa_i335;
-   label = 264;
-   break;
-  }
-  case 264:
-  $1131 = ($tib1_121_i347 | 0) == ($tib2_0_lcssa_i344 | 0);
-  if ($1131) {
-   label = 361;
-   break;
-  } else {
-   label = 265;
-   break;
-  }
-  case 265:
-  $1132 = $tib1_121_i347 + 108 | 0;
-  $1133 = HEAP32[$1132 >> 2] | 0;
-  $1134 = $tib1_121_i347 + 112 | 0;
-  $i_0_i350 = 0;
-  label = 266;
-  break;
-  case 266:
-  $1136 = ($i_0_i350 | 0) < ($1133 | 0);
-  if ($1136) {
-   label = 267;
-   break;
-  } else {
-   label = 268;
-   break;
-  }
-  case 267:
-  $1138 = HEAP32[$1134 >> 2] | 0;
-  $1139 = $1138 + ($i_0_i350 << 2) | 0;
-  $1140 = HEAP32[$1139 >> 2] | 0;
-  $1141 = ($1140 | 0) == ($tib2_0_lcssa_i344 | 0);
-  $1142 = $i_0_i350 + 1 | 0;
-  if ($1141) {
-   label = 361;
-   break;
-  } else {
-   $i_0_i350 = $1142;
-   label = 266;
-   break;
-  }
-  case 268:
-  $1144 = $tib1_121_i347 + 40 | 0;
-  $1145 = HEAP32[$1144 >> 2] | 0;
-  $1146 = ($1145 | 0) == 0;
-  if ($1146) {
-   label = 269;
-   break;
-  } else {
-   $tib1_121_i347 = $1145;
-   label = 264;
-   break;
-  }
-  case 269:
-  $1147 = HEAP32[(107740 | 0) >> 2] | 0;
-  $1148 = ($1147 | 0) == 0;
-  if ($1148) {
-   label = 270;
-   break;
-  } else {
-   label = 271;
-   break;
-  }
-  case 270:
-  invoke_v(374);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 271;
-  break;
-  case 271:
-  $1151 = HEAP32[$1083 >> 2] | 0;
-  $1152 = ($1151 | 0) == 0;
-  if ($1152) {
-   label = 285;
-   break;
-  } else {
-   label = 272;
-   break;
-  }
-  case 272:
-  $1154 = HEAP32[137616 >> 2] | 0;
-  $1155 = $1151;
-  $1156 = HEAP32[$1155 >> 2] | 0;
-  $1157 = $1156;
-  $1158 = $1154 + 8 | 0;
-  $1159 = $1158;
-  $1160 = HEAP32[$1159 >> 2] | 0;
-  $1161 = ($1156 | 0) == 82712;
-  if ($1161) {
-   label = 273;
-   break;
-  } else {
-   $tib1_0_ph_i311 = $1157;
-   label = 274;
-   break;
-  }
-  case 273:
-  $1163 = $1151 + 8 | 0;
-  $1164 = $1163;
-  $1165 = HEAP32[$1164 >> 2] | 0;
-  $1166 = $1165 + 8 | 0;
-  $1167 = $1166;
-  $1168 = HEAP32[$1167 >> 2] | 0;
-  $1169 = $1168;
-  $tib1_0_ph_i311 = $1169;
-  label = 274;
-  break;
-  case 274:
-  $1170 = $tib1_0_ph_i311 + 56 | 0;
-  $1171 = HEAP32[$1170 >> 2] | 0;
-  $1172 = ($1171 | 0) == 0;
-  if ($1172) {
-   var $dimension_tib1_0_lcssa_i315 = 0;
-   var $tib1_0_lcssa_i314 = $tib1_0_ph_i311;
-   label = 276;
-   break;
-  } else {
-   var $dimension_tib1_029_i317 = 0;
-   var $1178 = $1171;
-   label = 277;
-   break;
-  }
-  case 275:
-  $1173 = $1181;
-  var $dimension_tib1_0_lcssa_i315 = $1182;
-  var $tib1_0_lcssa_i314 = $1173;
-  label = 276;
-  break;
-  case 276:
-  $1174 = $1160 + 56 | 0;
-  $1175 = $1174;
-  $1176 = HEAP32[$1175 >> 2] | 0;
-  $1177 = ($1176 | 0) == 0;
-  if ($1177) {
-   var $dimension_tib2_0_lcssa_i322 = 0;
-   var $tib2_0_lcssa_in_i321 = $1160;
-   label = 279;
-   break;
-  } else {
-   var $dimension_tib2_024_i319 = 0;
-   var $1187 = $1176;
-   label = 278;
-   break;
-  }
-  case 277:
-  $1179 = $1178 + 8 | 0;
-  $1180 = $1179;
-  $1181 = HEAP32[$1180 >> 2] | 0;
-  $1182 = $dimension_tib1_029_i317 + 1 | 0;
-  $1183 = $1181 + 56 | 0;
-  $1184 = $1183;
-  $1185 = HEAP32[$1184 >> 2] | 0;
-  $1186 = ($1185 | 0) == 0;
-  if ($1186) {
-   label = 275;
-   break;
-  } else {
-   var $dimension_tib1_029_i317 = $1182;
-   var $1178 = $1185;
-   label = 277;
-   break;
-  }
-  case 278:
-  $1188 = $1187 + 8 | 0;
-  $1189 = $1188;
-  $1190 = HEAP32[$1189 >> 2] | 0;
-  $1191 = $dimension_tib2_024_i319 + 1 | 0;
-  $1192 = $1190 + 56 | 0;
-  $1193 = $1192;
-  $1194 = HEAP32[$1193 >> 2] | 0;
-  $1195 = ($1194 | 0) == 0;
-  if ($1195) {
-   var $dimension_tib2_0_lcssa_i322 = $1191;
-   var $tib2_0_lcssa_in_i321 = $1190;
-   label = 279;
-   break;
-  } else {
-   var $dimension_tib2_024_i319 = $1191;
-   var $1187 = $1194;
-   label = 278;
-   break;
-  }
-  case 279:
-  $tib2_0_lcssa_i323 = $tib2_0_lcssa_in_i321;
-  $1196 = ($dimension_tib1_0_lcssa_i315 | 0) < ($dimension_tib2_0_lcssa_i322 | 0);
-  $1197 = ($tib1_0_lcssa_i314 | 0) == 0;
-  $or_cond_i324 = $1196 | $1197;
-  if ($or_cond_i324) {
-   label = 285;
-   break;
-  } else {
-   $tib1_121_i326 = $tib1_0_lcssa_i314;
-   label = 280;
-   break;
-  }
-  case 280:
-  $1198 = ($tib1_121_i326 | 0) == ($tib2_0_lcssa_i323 | 0);
-  if ($1198) {
-   label = 386;
-   break;
-  } else {
-   label = 281;
-   break;
-  }
-  case 281:
-  $1199 = $tib1_121_i326 + 108 | 0;
-  $1200 = HEAP32[$1199 >> 2] | 0;
-  $1201 = $tib1_121_i326 + 112 | 0;
-  $i_0_i329 = 0;
-  label = 282;
-  break;
-  case 282:
-  $1203 = ($i_0_i329 | 0) < ($1200 | 0);
-  if ($1203) {
-   label = 283;
-   break;
-  } else {
-   label = 284;
-   break;
-  }
-  case 283:
-  $1205 = HEAP32[$1201 >> 2] | 0;
-  $1206 = $1205 + ($i_0_i329 << 2) | 0;
-  $1207 = HEAP32[$1206 >> 2] | 0;
-  $1208 = ($1207 | 0) == ($tib2_0_lcssa_i323 | 0);
-  $1209 = $i_0_i329 + 1 | 0;
-  if ($1208) {
-   label = 386;
-   break;
-  } else {
-   $i_0_i329 = $1209;
-   label = 282;
-   break;
-  }
-  case 284:
-  $1211 = $tib1_121_i326 + 40 | 0;
-  $1212 = HEAP32[$1211 >> 2] | 0;
-  $1213 = ($1212 | 0) == 0;
-  if ($1213) {
-   label = 285;
-   break;
-  } else {
-   $tib1_121_i326 = $1212;
-   label = 280;
-   break;
-  }
-  case 285:
-  $1214 = HEAP32[$1038 >> 2] | 0;
-  $1215 = $1214;
-  invoke_vii(48, $1215 | 0, 0 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  return 0 | 0;
-  case 286:
-  $1217 = HEAP32[(98772 | 0) >> 2] | 0;
-  $1218 = ($1217 | 0) == 0;
-  if ($1218) {
-   label = 287;
-   break;
-  } else {
-   label = 288;
-   break;
-  }
-  case 287:
-  invoke_v(702);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 288;
-  break;
-  case 288:
-  $1220 = HEAP32[140040 >> 2] | 0;
-  $1221 = $1220;
-  $_r0_sroa_0 = $1221;
-  $1222 = invoke_ii(556, 709 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $_r3_sroa_0 = $1222;
-  $_r0_sroa_0_0_load605 = $_r0_sroa_0;
-  $_r3_sroa_0_0_load594 = $_r3_sroa_0;
-  $_r0_sroa_0 = 0;
-  $_r0_sroa_0_0_load623 = $_r0_sroa_0;
-  $1223 = $_r0_sroa_0_0_load623;
-  $_r3_sroa_0 = $1223;
-  $_r0_sroa_1_4__r3_sroa_1_4_idx_idx = $_r3_sroa_1 | 0;
-  $_r0_sroa_1_4_idx156 = $_r0_sroa_1 | 0;
-  HEAP32[$_r0_sroa_1_4__r3_sroa_1_4_idx_idx >> 2] = HEAP32[$_r0_sroa_1_4_idx156 >> 2] | 0;
-  $1224 = HEAP32[$1069 >> 2] | 0;
-  _memcpy($1224 | 0, $1067 | 0, 40);
-  label = 179;
-  break;
-  case 289:
-  $1226 = HEAP32[$1069 >> 2] | 0;
-  _memcpy($1226 | 0, $1067 | 0, 40);
-  $1227 = HEAP32[(113236 | 0) >> 2] | 0;
-  $1228 = ($1227 | 0) == 0;
-  if ($1228) {
-   label = 290;
-   break;
-  } else {
-   label = 291;
-   break;
-  }
-  case 290:
-  invoke_v(538);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 291;
-  break;
-  case 291:
-  $1231 = $1066 + 20 | 0;
-  $1232 = $1231;
-  $1233 = HEAP32[$1232 >> 2] | 0;
-  $1234 = ($1233 | 0) == 0;
-  if ($1234) {
-   label = 305;
-   break;
-  } else {
-   label = 292;
-   break;
-  }
-  case 292:
-  $1236 = HEAP32[138672 >> 2] | 0;
-  $1237 = $1233;
-  $1238 = HEAP32[$1237 >> 2] | 0;
-  $1239 = $1238;
-  $1240 = $1236 + 8 | 0;
-  $1241 = $1240;
-  $1242 = HEAP32[$1241 >> 2] | 0;
-  $1243 = ($1238 | 0) == 82712;
-  if ($1243) {
-   label = 293;
-   break;
-  } else {
-   $tib1_0_ph_i290 = $1239;
-   label = 294;
-   break;
-  }
-  case 293:
-  $1245 = $1233 + 8 | 0;
-  $1246 = $1245;
-  $1247 = HEAP32[$1246 >> 2] | 0;
-  $1248 = $1247 + 8 | 0;
-  $1249 = $1248;
-  $1250 = HEAP32[$1249 >> 2] | 0;
-  $1251 = $1250;
-  $tib1_0_ph_i290 = $1251;
-  label = 294;
-  break;
-  case 294:
-  $1252 = $tib1_0_ph_i290 + 56 | 0;
-  $1253 = HEAP32[$1252 >> 2] | 0;
-  $1254 = ($1253 | 0) == 0;
-  if ($1254) {
-   var $dimension_tib1_0_lcssa_i294 = 0;
-   var $tib1_0_lcssa_i293 = $tib1_0_ph_i290;
-   label = 296;
-   break;
-  } else {
-   var $dimension_tib1_029_i296 = 0;
-   var $1260 = $1253;
-   label = 297;
-   break;
-  }
-  case 295:
-  $1255 = $1263;
-  var $dimension_tib1_0_lcssa_i294 = $1264;
-  var $tib1_0_lcssa_i293 = $1255;
-  label = 296;
-  break;
-  case 296:
-  $1256 = $1242 + 56 | 0;
-  $1257 = $1256;
-  $1258 = HEAP32[$1257 >> 2] | 0;
-  $1259 = ($1258 | 0) == 0;
-  if ($1259) {
-   var $dimension_tib2_0_lcssa_i301 = 0;
-   var $tib2_0_lcssa_in_i300 = $1242;
-   label = 299;
-   break;
-  } else {
-   var $dimension_tib2_024_i298 = 0;
-   var $1269 = $1258;
-   label = 298;
-   break;
-  }
-  case 297:
-  $1261 = $1260 + 8 | 0;
-  $1262 = $1261;
-  $1263 = HEAP32[$1262 >> 2] | 0;
-  $1264 = $dimension_tib1_029_i296 + 1 | 0;
-  $1265 = $1263 + 56 | 0;
-  $1266 = $1265;
-  $1267 = HEAP32[$1266 >> 2] | 0;
-  $1268 = ($1267 | 0) == 0;
-  if ($1268) {
-   label = 295;
-   break;
-  } else {
-   var $dimension_tib1_029_i296 = $1264;
-   var $1260 = $1267;
-   label = 297;
-   break;
-  }
-  case 298:
-  $1270 = $1269 + 8 | 0;
-  $1271 = $1270;
-  $1272 = HEAP32[$1271 >> 2] | 0;
-  $1273 = $dimension_tib2_024_i298 + 1 | 0;
-  $1274 = $1272 + 56 | 0;
-  $1275 = $1274;
-  $1276 = HEAP32[$1275 >> 2] | 0;
-  $1277 = ($1276 | 0) == 0;
-  if ($1277) {
-   var $dimension_tib2_0_lcssa_i301 = $1273;
-   var $tib2_0_lcssa_in_i300 = $1272;
-   label = 299;
-   break;
-  } else {
-   var $dimension_tib2_024_i298 = $1273;
-   var $1269 = $1276;
-   label = 298;
-   break;
-  }
-  case 299:
-  $tib2_0_lcssa_i302 = $tib2_0_lcssa_in_i300;
-  $1278 = ($dimension_tib1_0_lcssa_i294 | 0) < ($dimension_tib2_0_lcssa_i301 | 0);
-  $1279 = ($tib1_0_lcssa_i293 | 0) == 0;
-  $or_cond_i303 = $1278 | $1279;
-  if ($or_cond_i303) {
-   label = 305;
-   break;
-  } else {
-   $tib1_121_i305 = $tib1_0_lcssa_i293;
-   label = 300;
-   break;
-  }
-  case 300:
-  $1280 = ($tib1_121_i305 | 0) == ($tib2_0_lcssa_i302 | 0);
-  if ($1280) {
-   label = 361;
-   break;
-  } else {
-   label = 301;
-   break;
-  }
-  case 301:
-  $1281 = $tib1_121_i305 + 108 | 0;
-  $1282 = HEAP32[$1281 >> 2] | 0;
-  $1283 = $tib1_121_i305 + 112 | 0;
-  $i_0_i308 = 0;
-  label = 302;
-  break;
-  case 302:
-  $1285 = ($i_0_i308 | 0) < ($1282 | 0);
-  if ($1285) {
-   label = 303;
-   break;
-  } else {
-   label = 304;
-   break;
-  }
-  case 303:
-  $1287 = HEAP32[$1283 >> 2] | 0;
-  $1288 = $1287 + ($i_0_i308 << 2) | 0;
-  $1289 = HEAP32[$1288 >> 2] | 0;
-  $1290 = ($1289 | 0) == ($tib2_0_lcssa_i302 | 0);
-  $1291 = $i_0_i308 + 1 | 0;
-  if ($1290) {
-   label = 361;
-   break;
-  } else {
-   $i_0_i308 = $1291;
-   label = 302;
-   break;
-  }
-  case 304:
-  $1293 = $tib1_121_i305 + 40 | 0;
-  $1294 = HEAP32[$1293 >> 2] | 0;
-  $1295 = ($1294 | 0) == 0;
-  if ($1295) {
-   label = 305;
-   break;
-  } else {
-   $tib1_121_i305 = $1294;
-   label = 300;
-   break;
-  }
-  case 305:
-  $1296 = HEAP32[(107740 | 0) >> 2] | 0;
-  $1297 = ($1296 | 0) == 0;
-  if ($1297) {
-   label = 306;
-   break;
-  } else {
-   label = 307;
-   break;
-  }
-  case 306:
-  invoke_v(374);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 307;
-  break;
-  case 307:
-  $1300 = HEAP32[$1232 >> 2] | 0;
-  $1301 = ($1300 | 0) == 0;
-  if ($1301) {
-   label = 321;
-   break;
-  } else {
-   label = 308;
-   break;
-  }
-  case 308:
-  $1303 = HEAP32[137616 >> 2] | 0;
-  $1304 = $1300;
-  $1305 = HEAP32[$1304 >> 2] | 0;
-  $1306 = $1305;
-  $1307 = $1303 + 8 | 0;
-  $1308 = $1307;
-  $1309 = HEAP32[$1308 >> 2] | 0;
-  $1310 = ($1305 | 0) == 82712;
-  if ($1310) {
-   label = 309;
-   break;
-  } else {
-   $tib1_0_ph_i269 = $1306;
-   label = 310;
-   break;
-  }
-  case 309:
-  $1312 = $1300 + 8 | 0;
-  $1313 = $1312;
-  $1314 = HEAP32[$1313 >> 2] | 0;
-  $1315 = $1314 + 8 | 0;
-  $1316 = $1315;
-  $1317 = HEAP32[$1316 >> 2] | 0;
-  $1318 = $1317;
-  $tib1_0_ph_i269 = $1318;
-  label = 310;
-  break;
-  case 310:
-  $1319 = $tib1_0_ph_i269 + 56 | 0;
-  $1320 = HEAP32[$1319 >> 2] | 0;
-  $1321 = ($1320 | 0) == 0;
-  if ($1321) {
-   var $dimension_tib1_0_lcssa_i273 = 0;
-   var $tib1_0_lcssa_i272 = $tib1_0_ph_i269;
-   label = 312;
-   break;
-  } else {
-   var $dimension_tib1_029_i275 = 0;
-   var $1327 = $1320;
-   label = 313;
-   break;
-  }
-  case 311:
-  $1322 = $1330;
-  var $dimension_tib1_0_lcssa_i273 = $1331;
-  var $tib1_0_lcssa_i272 = $1322;
-  label = 312;
-  break;
-  case 312:
-  $1323 = $1309 + 56 | 0;
-  $1324 = $1323;
-  $1325 = HEAP32[$1324 >> 2] | 0;
-  $1326 = ($1325 | 0) == 0;
-  if ($1326) {
-   var $dimension_tib2_0_lcssa_i280 = 0;
-   var $tib2_0_lcssa_in_i279 = $1309;
-   label = 315;
-   break;
-  } else {
-   var $dimension_tib2_024_i277 = 0;
-   var $1336 = $1325;
-   label = 314;
-   break;
-  }
-  case 313:
-  $1328 = $1327 + 8 | 0;
-  $1329 = $1328;
-  $1330 = HEAP32[$1329 >> 2] | 0;
-  $1331 = $dimension_tib1_029_i275 + 1 | 0;
-  $1332 = $1330 + 56 | 0;
-  $1333 = $1332;
-  $1334 = HEAP32[$1333 >> 2] | 0;
-  $1335 = ($1334 | 0) == 0;
-  if ($1335) {
-   label = 311;
-   break;
-  } else {
-   var $dimension_tib1_029_i275 = $1331;
-   var $1327 = $1334;
-   label = 313;
-   break;
-  }
-  case 314:
-  $1337 = $1336 + 8 | 0;
-  $1338 = $1337;
-  $1339 = HEAP32[$1338 >> 2] | 0;
-  $1340 = $dimension_tib2_024_i277 + 1 | 0;
-  $1341 = $1339 + 56 | 0;
-  $1342 = $1341;
-  $1343 = HEAP32[$1342 >> 2] | 0;
-  $1344 = ($1343 | 0) == 0;
-  if ($1344) {
-   var $dimension_tib2_0_lcssa_i280 = $1340;
-   var $tib2_0_lcssa_in_i279 = $1339;
-   label = 315;
-   break;
-  } else {
-   var $dimension_tib2_024_i277 = $1340;
-   var $1336 = $1343;
-   label = 314;
-   break;
-  }
-  case 315:
-  $tib2_0_lcssa_i281 = $tib2_0_lcssa_in_i279;
-  $1345 = ($dimension_tib1_0_lcssa_i273 | 0) < ($dimension_tib2_0_lcssa_i280 | 0);
-  $1346 = ($tib1_0_lcssa_i272 | 0) == 0;
-  $or_cond_i282 = $1345 | $1346;
-  if ($or_cond_i282) {
-   label = 321;
-   break;
-  } else {
-   $tib1_121_i284 = $tib1_0_lcssa_i272;
-   label = 316;
-   break;
-  }
-  case 316:
-  $1347 = ($tib1_121_i284 | 0) == ($tib2_0_lcssa_i281 | 0);
-  if ($1347) {
-   label = 386;
-   break;
-  } else {
-   label = 317;
-   break;
-  }
-  case 317:
-  $1348 = $tib1_121_i284 + 108 | 0;
-  $1349 = HEAP32[$1348 >> 2] | 0;
-  $1350 = $tib1_121_i284 + 112 | 0;
-  $i_0_i287 = 0;
-  label = 318;
-  break;
-  case 318:
-  $1352 = ($i_0_i287 | 0) < ($1349 | 0);
-  if ($1352) {
-   label = 319;
-   break;
-  } else {
-   label = 320;
-   break;
-  }
-  case 319:
-  $1354 = HEAP32[$1350 >> 2] | 0;
-  $1355 = $1354 + ($i_0_i287 << 2) | 0;
-  $1356 = HEAP32[$1355 >> 2] | 0;
-  $1357 = ($1356 | 0) == ($tib2_0_lcssa_i281 | 0);
-  $1358 = $i_0_i287 + 1 | 0;
-  if ($1357) {
-   label = 386;
-   break;
-  } else {
-   $i_0_i287 = $1358;
-   label = 318;
-   break;
-  }
-  case 320:
-  $1360 = $tib1_121_i284 + 40 | 0;
-  $1361 = HEAP32[$1360 >> 2] | 0;
-  $1362 = ($1361 | 0) == 0;
-  if ($1362) {
-   label = 321;
-   break;
-  } else {
-   $tib1_121_i284 = $1361;
-   label = 316;
-   break;
-  }
-  case 321:
-  $1363 = HEAP32[$1069 >> 2] | 0;
-  $1364 = $1363;
-  invoke_vii(48, $1364 | 0, 0 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  return 0 | 0;
-  case 322:
-  $1366 = HEAP32[(105500 | 0) >> 2] | 0;
-  $1367 = ($1366 | 0) == 0;
-  if ($1367) {
-   label = 323;
-   break;
-  } else {
-   label = 324;
-   break;
-  }
-  case 323:
-  invoke_v(30);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 324;
-  break;
-  case 324:
-  $1369 = invoke_i(70) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $1370$0 = $1369;
-  $1370$1 = 0;
-  $1371 = invoke_iii(364, $1370$0 | 0, $1370$1 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $1372 = $local_env_w4567aaac23b1c44;
-  $1373 = $1371 + 16 | 0;
-  $1374 = $1373;
-  $1375 = HEAP32[$1374 >> 2] | 0;
-  _memcpy($1372 | 0, $1375 | 0, 40);
-  $1376 = HEAP32[$1374 >> 2] | 0;
-  $1377 = $1376;
-  $1378 = _saveSetjmp($1377 | 0, label, setjmpTable) | 0;
-  label = 423;
-  break;
-  case 423:
-  $1379 = ($1378 | 0) == 0;
-  if ($1379) {
-   label = 325;
-   break;
-  } else {
-   label = 328;
-   break;
-  }
-  case 325:
-  $_r0_sroa_0 = 1;
-  $_r0_sroa_0_0_load604 = $_r0_sroa_0;
-  $1381 = HEAP32[(98772 | 0) >> 2] | 0;
-  $1382 = ($1381 | 0) == 0;
-  if ($1382) {
-   label = 326;
-   break;
-  } else {
-   label = 327;
-   break;
-  }
-  case 326:
-  invoke_v(702);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 327;
-  break;
-  case 327:
-  HEAP32[140048 >> 2] = $_r0_sroa_0_0_load604;
-  $_r3_sroa_0_0_load593 = $_r3_sroa_0;
-  $1384 = $_r3_sroa_0_0_load593;
-  $1385 = HEAP32[$1384 >> 2] | 0;
-  $1386 = $1385 + 116 | 0;
-  $1387 = HEAP32[$1386 >> 2] | 0;
-  $1388 = $1387 + 4 | 0;
-  $1389 = HEAP32[$1388 >> 2] | 0;
-  $1390 = $1389;
-  $_r3_sroa_0_0_load = $_r3_sroa_0;
-  $1391 = invoke_ii($1390 | 0, $_r3_sroa_0_0_load | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $1392 = $1391;
-  $_r0_sroa_0 = $1392;
-  invoke_viiii(14, 16136 | 0 | 0, 11648 | 0 | 0, 126872 | 0 | 0, 1630 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  return 0 | 0;
-  case 328:
-  $1394 = HEAP32[$1374 >> 2] | 0;
-  _memcpy($1394 | 0, $1372 | 0, 40);
-  $1395 = HEAP32[(113236 | 0) >> 2] | 0;
-  $1396 = ($1395 | 0) == 0;
-  if ($1396) {
-   label = 329;
-   break;
-  } else {
-   label = 330;
-   break;
-  }
-  case 329:
-  invoke_v(538);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 330;
-  break;
-  case 330:
-  $1399 = $1371 + 20 | 0;
-  $1400 = $1399;
-  $1401 = HEAP32[$1400 >> 2] | 0;
-  $1402 = ($1401 | 0) == 0;
-  if ($1402) {
-   label = 344;
-   break;
-  } else {
-   label = 331;
-   break;
-  }
-  case 331:
-  $1404 = HEAP32[138672 >> 2] | 0;
-  $1405 = $1401;
-  $1406 = HEAP32[$1405 >> 2] | 0;
-  $1407 = $1406;
-  $1408 = $1404 + 8 | 0;
-  $1409 = $1408;
-  $1410 = HEAP32[$1409 >> 2] | 0;
-  $1411 = ($1406 | 0) == 82712;
-  if ($1411) {
-   label = 332;
-   break;
-  } else {
-   $tib1_0_ph_i248 = $1407;
-   label = 333;
-   break;
-  }
-  case 332:
-  $1413 = $1401 + 8 | 0;
-  $1414 = $1413;
-  $1415 = HEAP32[$1414 >> 2] | 0;
-  $1416 = $1415 + 8 | 0;
-  $1417 = $1416;
-  $1418 = HEAP32[$1417 >> 2] | 0;
-  $1419 = $1418;
-  $tib1_0_ph_i248 = $1419;
-  label = 333;
-  break;
-  case 333:
-  $1420 = $tib1_0_ph_i248 + 56 | 0;
-  $1421 = HEAP32[$1420 >> 2] | 0;
-  $1422 = ($1421 | 0) == 0;
-  if ($1422) {
-   var $dimension_tib1_0_lcssa_i252 = 0;
-   var $tib1_0_lcssa_i251 = $tib1_0_ph_i248;
-   label = 335;
-   break;
-  } else {
-   var $dimension_tib1_029_i254 = 0;
-   var $1428 = $1421;
-   label = 336;
-   break;
-  }
-  case 334:
-  $1423 = $1431;
-  var $dimension_tib1_0_lcssa_i252 = $1432;
-  var $tib1_0_lcssa_i251 = $1423;
-  label = 335;
-  break;
-  case 335:
-  $1424 = $1410 + 56 | 0;
-  $1425 = $1424;
-  $1426 = HEAP32[$1425 >> 2] | 0;
-  $1427 = ($1426 | 0) == 0;
-  if ($1427) {
-   var $dimension_tib2_0_lcssa_i259 = 0;
-   var $tib2_0_lcssa_in_i258 = $1410;
-   label = 338;
-   break;
-  } else {
-   var $dimension_tib2_024_i256 = 0;
-   var $1437 = $1426;
-   label = 337;
-   break;
-  }
-  case 336:
-  $1429 = $1428 + 8 | 0;
-  $1430 = $1429;
-  $1431 = HEAP32[$1430 >> 2] | 0;
-  $1432 = $dimension_tib1_029_i254 + 1 | 0;
-  $1433 = $1431 + 56 | 0;
-  $1434 = $1433;
-  $1435 = HEAP32[$1434 >> 2] | 0;
-  $1436 = ($1435 | 0) == 0;
-  if ($1436) {
-   label = 334;
-   break;
-  } else {
-   var $dimension_tib1_029_i254 = $1432;
-   var $1428 = $1435;
-   label = 336;
-   break;
-  }
-  case 337:
-  $1438 = $1437 + 8 | 0;
-  $1439 = $1438;
-  $1440 = HEAP32[$1439 >> 2] | 0;
-  $1441 = $dimension_tib2_024_i256 + 1 | 0;
-  $1442 = $1440 + 56 | 0;
-  $1443 = $1442;
-  $1444 = HEAP32[$1443 >> 2] | 0;
-  $1445 = ($1444 | 0) == 0;
-  if ($1445) {
-   var $dimension_tib2_0_lcssa_i259 = $1441;
-   var $tib2_0_lcssa_in_i258 = $1440;
-   label = 338;
-   break;
-  } else {
-   var $dimension_tib2_024_i256 = $1441;
-   var $1437 = $1444;
-   label = 337;
-   break;
-  }
-  case 338:
-  $tib2_0_lcssa_i260 = $tib2_0_lcssa_in_i258;
-  $1446 = ($dimension_tib1_0_lcssa_i252 | 0) < ($dimension_tib2_0_lcssa_i259 | 0);
-  $1447 = ($tib1_0_lcssa_i251 | 0) == 0;
-  $or_cond_i261 = $1446 | $1447;
-  if ($or_cond_i261) {
-   label = 344;
-   break;
-  } else {
-   $tib1_121_i263 = $tib1_0_lcssa_i251;
-   label = 339;
-   break;
-  }
-  case 339:
-  $1448 = ($tib1_121_i263 | 0) == ($tib2_0_lcssa_i260 | 0);
-  if ($1448) {
-   label = 361;
-   break;
-  } else {
-   label = 340;
-   break;
-  }
-  case 340:
-  $1449 = $tib1_121_i263 + 108 | 0;
-  $1450 = HEAP32[$1449 >> 2] | 0;
-  $1451 = $tib1_121_i263 + 112 | 0;
-  $i_0_i266 = 0;
-  label = 341;
-  break;
-  case 341:
-  $1453 = ($i_0_i266 | 0) < ($1450 | 0);
-  if ($1453) {
-   label = 342;
-   break;
-  } else {
-   label = 343;
-   break;
-  }
-  case 342:
-  $1455 = HEAP32[$1451 >> 2] | 0;
-  $1456 = $1455 + ($i_0_i266 << 2) | 0;
-  $1457 = HEAP32[$1456 >> 2] | 0;
-  $1458 = ($1457 | 0) == ($tib2_0_lcssa_i260 | 0);
-  $1459 = $i_0_i266 + 1 | 0;
-  if ($1458) {
-   label = 361;
-   break;
-  } else {
-   $i_0_i266 = $1459;
-   label = 341;
-   break;
-  }
-  case 343:
-  $1461 = $tib1_121_i263 + 40 | 0;
-  $1462 = HEAP32[$1461 >> 2] | 0;
-  $1463 = ($1462 | 0) == 0;
-  if ($1463) {
-   label = 344;
-   break;
-  } else {
-   $tib1_121_i263 = $1462;
-   label = 339;
-   break;
-  }
-  case 344:
-  $1464 = HEAP32[(107740 | 0) >> 2] | 0;
-  $1465 = ($1464 | 0) == 0;
-  if ($1465) {
-   label = 345;
-   break;
-  } else {
-   label = 346;
-   break;
-  }
-  case 345:
-  invoke_v(374);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 346;
-  break;
-  case 346:
-  $1468 = HEAP32[$1400 >> 2] | 0;
-  $1469 = ($1468 | 0) == 0;
-  if ($1469) {
-   label = 360;
-   break;
-  } else {
-   label = 347;
-   break;
-  }
-  case 347:
-  $1471 = HEAP32[137616 >> 2] | 0;
-  $1472 = $1468;
-  $1473 = HEAP32[$1472 >> 2] | 0;
-  $1474 = $1473;
-  $1475 = $1471 + 8 | 0;
-  $1476 = $1475;
-  $1477 = HEAP32[$1476 >> 2] | 0;
-  $1478 = ($1473 | 0) == 82712;
-  if ($1478) {
-   label = 348;
-   break;
-  } else {
-   $tib1_0_ph_i227 = $1474;
-   label = 349;
-   break;
-  }
-  case 348:
-  $1480 = $1468 + 8 | 0;
-  $1481 = $1480;
-  $1482 = HEAP32[$1481 >> 2] | 0;
-  $1483 = $1482 + 8 | 0;
-  $1484 = $1483;
-  $1485 = HEAP32[$1484 >> 2] | 0;
-  $1486 = $1485;
-  $tib1_0_ph_i227 = $1486;
-  label = 349;
-  break;
-  case 349:
-  $1487 = $tib1_0_ph_i227 + 56 | 0;
-  $1488 = HEAP32[$1487 >> 2] | 0;
-  $1489 = ($1488 | 0) == 0;
-  if ($1489) {
-   var $dimension_tib1_0_lcssa_i231 = 0;
-   var $tib1_0_lcssa_i230 = $tib1_0_ph_i227;
-   label = 351;
-   break;
-  } else {
-   var $dimension_tib1_029_i233 = 0;
-   var $1495 = $1488;
-   label = 352;
-   break;
-  }
-  case 350:
-  $1490 = $1498;
-  var $dimension_tib1_0_lcssa_i231 = $1499;
-  var $tib1_0_lcssa_i230 = $1490;
-  label = 351;
-  break;
-  case 351:
-  $1491 = $1477 + 56 | 0;
-  $1492 = $1491;
-  $1493 = HEAP32[$1492 >> 2] | 0;
-  $1494 = ($1493 | 0) == 0;
-  if ($1494) {
-   var $dimension_tib2_0_lcssa_i238 = 0;
-   var $tib2_0_lcssa_in_i237 = $1477;
-   label = 354;
-   break;
-  } else {
-   var $dimension_tib2_024_i235 = 0;
-   var $1504 = $1493;
-   label = 353;
-   break;
-  }
-  case 352:
-  $1496 = $1495 + 8 | 0;
-  $1497 = $1496;
-  $1498 = HEAP32[$1497 >> 2] | 0;
-  $1499 = $dimension_tib1_029_i233 + 1 | 0;
-  $1500 = $1498 + 56 | 0;
-  $1501 = $1500;
-  $1502 = HEAP32[$1501 >> 2] | 0;
-  $1503 = ($1502 | 0) == 0;
-  if ($1503) {
-   label = 350;
-   break;
-  } else {
-   var $dimension_tib1_029_i233 = $1499;
-   var $1495 = $1502;
-   label = 352;
-   break;
-  }
-  case 353:
-  $1505 = $1504 + 8 | 0;
-  $1506 = $1505;
-  $1507 = HEAP32[$1506 >> 2] | 0;
-  $1508 = $dimension_tib2_024_i235 + 1 | 0;
-  $1509 = $1507 + 56 | 0;
-  $1510 = $1509;
-  $1511 = HEAP32[$1510 >> 2] | 0;
-  $1512 = ($1511 | 0) == 0;
-  if ($1512) {
-   var $dimension_tib2_0_lcssa_i238 = $1508;
-   var $tib2_0_lcssa_in_i237 = $1507;
-   label = 354;
-   break;
-  } else {
-   var $dimension_tib2_024_i235 = $1508;
-   var $1504 = $1511;
-   label = 353;
-   break;
-  }
-  case 354:
-  $tib2_0_lcssa_i239 = $tib2_0_lcssa_in_i237;
-  $1513 = ($dimension_tib1_0_lcssa_i231 | 0) < ($dimension_tib2_0_lcssa_i238 | 0);
-  $1514 = ($tib1_0_lcssa_i230 | 0) == 0;
-  $or_cond_i240 = $1513 | $1514;
-  if ($or_cond_i240) {
-   label = 360;
-   break;
-  } else {
-   $tib1_121_i242 = $tib1_0_lcssa_i230;
-   label = 355;
-   break;
-  }
-  case 355:
-  $1515 = ($tib1_121_i242 | 0) == ($tib2_0_lcssa_i239 | 0);
-  if ($1515) {
-   label = 386;
-   break;
-  } else {
-   label = 356;
-   break;
-  }
-  case 356:
-  $1516 = $tib1_121_i242 + 108 | 0;
-  $1517 = HEAP32[$1516 >> 2] | 0;
-  $1518 = $tib1_121_i242 + 112 | 0;
-  $i_0_i245 = 0;
-  label = 357;
-  break;
-  case 357:
-  $1520 = ($i_0_i245 | 0) < ($1517 | 0);
-  if ($1520) {
-   label = 358;
-   break;
-  } else {
-   label = 359;
-   break;
-  }
-  case 358:
-  $1522 = HEAP32[$1518 >> 2] | 0;
-  $1523 = $1522 + ($i_0_i245 << 2) | 0;
-  $1524 = HEAP32[$1523 >> 2] | 0;
-  $1525 = ($1524 | 0) == ($tib2_0_lcssa_i239 | 0);
-  $1526 = $i_0_i245 + 1 | 0;
-  if ($1525) {
-   label = 386;
-   break;
-  } else {
-   $i_0_i245 = $1526;
-   label = 357;
-   break;
-  }
-  case 359:
-  $1528 = $tib1_121_i242 + 40 | 0;
-  $1529 = HEAP32[$1528 >> 2] | 0;
-  $1530 = ($1529 | 0) == 0;
-  if ($1530) {
-   label = 360;
-   break;
-  } else {
-   $tib1_121_i242 = $1529;
-   label = 355;
-   break;
-  }
-  case 360:
-  $1531 = HEAP32[$1374 >> 2] | 0;
-  $1532 = $1531;
-  invoke_vii(48, $1532 | 0, 0 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  return 0 | 0;
-  case 361:
-  $1533 = HEAP32[(105500 | 0) >> 2] | 0;
-  $1534 = ($1533 | 0) == 0;
-  if ($1534) {
-   label = 362;
-   break;
-  } else {
-   label = 363;
-   break;
-  }
-  case 362:
-  invoke_v(30);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 363;
-  break;
-  case 363:
-  $1536 = invoke_i(70) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $1537$0 = $1536;
-  $1537$1 = 0;
-  $1538 = invoke_iii(364, $1537$0 | 0, $1537$1 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $1539 = $local_env_w4567aaac23b1c48;
-  $1540 = $1538 + 16 | 0;
-  $1541 = $1540;
-  $1542 = HEAP32[$1541 >> 2] | 0;
-  _memcpy($1539 | 0, $1542 | 0, 40);
-  $1543 = HEAP32[$1541 >> 2] | 0;
-  $1544 = $1543;
-  $1545 = _saveSetjmp($1544 | 0, label, setjmpTable) | 0;
-  label = 424;
-  break;
-  case 424:
-  $1546 = ($1545 | 0) == 0;
-  if ($1546) {
-   label = 364;
-   break;
-  } else {
-   label = 369;
-   break;
-  }
-  case 364:
-  $1548 = HEAP32[(105500 | 0) >> 2] | 0;
-  $1549 = ($1548 | 0) == 0;
-  if ($1549) {
-   label = 365;
-   break;
-  } else {
-   label = 366;
-   break;
-  }
-  case 365:
-  invoke_v(30);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 366;
-  break;
-  case 366:
-  $1551 = invoke_i(70) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $1552$0 = $1551;
-  $1552$1 = 0;
-  $1553 = invoke_iii(364, $1552$0 | 0, $1552$1 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $1554 = $1553 + 20 | 0;
-  $1555 = $1554;
-  $1556 = HEAP32[$1555 >> 2] | 0;
-  $1557 = $1556;
-  $_r0_sroa_0 = $1557;
-  $_r0_sroa_0 = 0;
-  $_r0_sroa_0_0_load602 = $_r0_sroa_0;
-  $1558 = HEAP32[(98772 | 0) >> 2] | 0;
-  $1559 = ($1558 | 0) == 0;
-  if ($1559) {
-   label = 367;
-   break;
-  } else {
-   label = 368;
-   break;
-  }
-  case 367:
-  invoke_v(702);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 368;
-  break;
-  case 368:
-  HEAP32[140048 >> 2] = $_r0_sroa_0_0_load602;
-  $1561 = HEAP32[$1541 >> 2] | 0;
-  _memcpy($1561 | 0, $1539 | 0, 40);
-  label = 239;
-  break;
-  case 369:
-  $1563 = HEAP32[$1541 >> 2] | 0;
-  _memcpy($1563 | 0, $1539 | 0, 40);
-  $1564 = HEAP32[(107740 | 0) >> 2] | 0;
-  $1565 = ($1564 | 0) == 0;
-  if ($1565) {
-   label = 370;
-   break;
-  } else {
-   label = 371;
-   break;
-  }
-  case 370:
-  invoke_v(374);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 371;
-  break;
-  case 371:
-  $1568 = $1538 + 20 | 0;
-  $1569 = $1568;
-  $1570 = HEAP32[$1569 >> 2] | 0;
-  $1571 = ($1570 | 0) == 0;
-  if ($1571) {
-   label = 385;
-   break;
-  } else {
-   label = 372;
-   break;
-  }
-  case 372:
-  $1573 = HEAP32[137616 >> 2] | 0;
-  $1574 = $1570;
-  $1575 = HEAP32[$1574 >> 2] | 0;
-  $1576 = $1575;
-  $1577 = $1573 + 8 | 0;
-  $1578 = $1577;
-  $1579 = HEAP32[$1578 >> 2] | 0;
-  $1580 = ($1575 | 0) == 82712;
-  if ($1580) {
-   label = 373;
-   break;
-  } else {
-   $tib1_0_ph_i185 = $1576;
-   label = 374;
-   break;
-  }
-  case 373:
-  $1582 = $1570 + 8 | 0;
-  $1583 = $1582;
-  $1584 = HEAP32[$1583 >> 2] | 0;
-  $1585 = $1584 + 8 | 0;
-  $1586 = $1585;
-  $1587 = HEAP32[$1586 >> 2] | 0;
-  $1588 = $1587;
-  $tib1_0_ph_i185 = $1588;
-  label = 374;
-  break;
-  case 374:
-  $1589 = $tib1_0_ph_i185 + 56 | 0;
-  $1590 = HEAP32[$1589 >> 2] | 0;
-  $1591 = ($1590 | 0) == 0;
-  if ($1591) {
-   var $dimension_tib1_0_lcssa_i189 = 0;
-   var $tib1_0_lcssa_i188 = $tib1_0_ph_i185;
-   label = 376;
-   break;
-  } else {
-   var $dimension_tib1_029_i191 = 0;
-   var $1597 = $1590;
-   label = 377;
-   break;
-  }
-  case 375:
-  $1592 = $1600;
-  var $dimension_tib1_0_lcssa_i189 = $1601;
-  var $tib1_0_lcssa_i188 = $1592;
-  label = 376;
-  break;
-  case 376:
-  $1593 = $1579 + 56 | 0;
-  $1594 = $1593;
-  $1595 = HEAP32[$1594 >> 2] | 0;
-  $1596 = ($1595 | 0) == 0;
-  if ($1596) {
-   var $dimension_tib2_0_lcssa_i196 = 0;
-   var $tib2_0_lcssa_in_i195 = $1579;
-   label = 379;
-   break;
-  } else {
-   var $dimension_tib2_024_i193 = 0;
-   var $1606 = $1595;
-   label = 378;
-   break;
-  }
-  case 377:
-  $1598 = $1597 + 8 | 0;
-  $1599 = $1598;
-  $1600 = HEAP32[$1599 >> 2] | 0;
-  $1601 = $dimension_tib1_029_i191 + 1 | 0;
-  $1602 = $1600 + 56 | 0;
-  $1603 = $1602;
-  $1604 = HEAP32[$1603 >> 2] | 0;
-  $1605 = ($1604 | 0) == 0;
-  if ($1605) {
-   label = 375;
-   break;
-  } else {
-   var $dimension_tib1_029_i191 = $1601;
-   var $1597 = $1604;
-   label = 377;
-   break;
-  }
-  case 378:
-  $1607 = $1606 + 8 | 0;
-  $1608 = $1607;
-  $1609 = HEAP32[$1608 >> 2] | 0;
-  $1610 = $dimension_tib2_024_i193 + 1 | 0;
-  $1611 = $1609 + 56 | 0;
-  $1612 = $1611;
-  $1613 = HEAP32[$1612 >> 2] | 0;
-  $1614 = ($1613 | 0) == 0;
-  if ($1614) {
-   var $dimension_tib2_0_lcssa_i196 = $1610;
-   var $tib2_0_lcssa_in_i195 = $1609;
-   label = 379;
-   break;
-  } else {
-   var $dimension_tib2_024_i193 = $1610;
-   var $1606 = $1613;
-   label = 378;
-   break;
-  }
-  case 379:
-  $tib2_0_lcssa_i197 = $tib2_0_lcssa_in_i195;
-  $1615 = ($dimension_tib1_0_lcssa_i189 | 0) < ($dimension_tib2_0_lcssa_i196 | 0);
-  $1616 = ($tib1_0_lcssa_i188 | 0) == 0;
-  $or_cond_i198 = $1615 | $1616;
-  if ($or_cond_i198) {
-   label = 385;
-   break;
-  } else {
-   $tib1_121_i200 = $tib1_0_lcssa_i188;
-   label = 380;
-   break;
-  }
-  case 380:
-  $1617 = ($tib1_121_i200 | 0) == ($tib2_0_lcssa_i197 | 0);
-  if ($1617) {
-   label = 54;
-   break;
-  } else {
-   label = 381;
-   break;
-  }
-  case 381:
-  $1618 = $tib1_121_i200 + 108 | 0;
-  $1619 = HEAP32[$1618 >> 2] | 0;
-  $1620 = $tib1_121_i200 + 112 | 0;
-  $i_0_i203 = 0;
-  label = 382;
-  break;
-  case 382:
-  $1622 = ($i_0_i203 | 0) < ($1619 | 0);
-  if ($1622) {
-   label = 383;
-   break;
-  } else {
-   label = 384;
-   break;
-  }
-  case 383:
-  $1624 = HEAP32[$1620 >> 2] | 0;
-  $1625 = $1624 + ($i_0_i203 << 2) | 0;
-  $1626 = HEAP32[$1625 >> 2] | 0;
-  $1627 = ($1626 | 0) == ($tib2_0_lcssa_i197 | 0);
-  $1628 = $i_0_i203 + 1 | 0;
-  if ($1627) {
-   label = 54;
-   break;
-  } else {
-   $i_0_i203 = $1628;
-   label = 382;
-   break;
-  }
-  case 384:
-  $1630 = $tib1_121_i200 + 40 | 0;
-  $1631 = HEAP32[$1630 >> 2] | 0;
-  $1632 = ($1631 | 0) == 0;
-  if ($1632) {
-   label = 385;
-   break;
-  } else {
-   $tib1_121_i200 = $1631;
-   label = 380;
-   break;
-  }
-  case 385:
-  $1633 = HEAP32[$1541 >> 2] | 0;
-  $1634 = $1633;
-  invoke_vii(48, $1634 | 0, 0 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  return 0 | 0;
-  case 386:
-  $1635 = HEAP32[(105500 | 0) >> 2] | 0;
-  $1636 = ($1635 | 0) == 0;
-  if ($1636) {
-   label = 387;
-   break;
-  } else {
-   label = 388;
-   break;
-  }
-  case 387:
-  invoke_v(30);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 388;
-  break;
-  case 388:
-  $1638 = invoke_i(70) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $1639$0 = $1638;
-  $1639$1 = 0;
-  $1640 = invoke_iii(364, $1639$0 | 0, $1639$1 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $1641 = $local_env_w4567aaac23b1c50;
-  $1642 = $1640 + 16 | 0;
-  $1643 = $1642;
-  $1644 = HEAP32[$1643 >> 2] | 0;
-  _memcpy($1641 | 0, $1644 | 0, 40);
-  $1645 = HEAP32[$1643 >> 2] | 0;
-  $1646 = $1645;
-  $1647 = _saveSetjmp($1646 | 0, label, setjmpTable) | 0;
-  label = 425;
-  break;
-  case 425:
-  $1648 = ($1647 | 0) == 0;
-  if ($1648) {
-   label = 389;
-   break;
-  } else {
-   label = 396;
-   break;
-  }
-  case 389:
-  $1650 = HEAP32[(105500 | 0) >> 2] | 0;
-  $1651 = ($1650 | 0) == 0;
-  if ($1651) {
-   label = 390;
-   break;
-  } else {
-   label = 391;
-   break;
-  }
-  case 390:
-  invoke_v(30);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 391;
-  break;
-  case 391:
-  $1653 = invoke_i(70) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $1654$0 = $1653;
-  $1654$1 = 0;
-  $1655 = invoke_iii(364, $1654$0 | 0, $1654$1 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $1656 = $1655 + 20 | 0;
-  $1657 = $1656;
-  $1658 = HEAP32[$1657 >> 2] | 0;
-  $1659 = $1658;
-  $_r0_sroa_0 = $1659;
-  $_r2_sroa_0 = 0;
-  $_r2_sroa_0_0_load = $_r2_sroa_0;
-  $1660 = HEAP32[(98772 | 0) >> 2] | 0;
-  $1661 = ($1660 | 0) == 0;
-  if ($1661) {
-   label = 392;
-   break;
-  } else {
-   label = 393;
-   break;
-  }
-  case 392:
-  invoke_v(702);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 393;
-  break;
-  case 393:
-  HEAP32[140048 >> 2] = $_r2_sroa_0_0_load;
-  $1663 = HEAP32[(105500 | 0) >> 2] | 0;
-  $1664 = ($1663 | 0) == 0;
-  if ($1664) {
-   label = 394;
-   break;
-  } else {
-   label = 395;
-   break;
-  }
-  case 394:
-  invoke_v(30);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 395;
-  break;
-  case 395:
-  $1666 = invoke_i(70) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $1667$0 = $1666;
-  $1667$1 = 0;
-  $1668 = invoke_iii(364, $1667$0 | 0, $1667$1 | 0) | 0;
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  $_r0_sroa_0_0_load = $_r0_sroa_0;
-  $1669 = $_r0_sroa_0_0_load;
-  $1670 = $1668 + 16 | 0;
-  $1671 = $1668 + 20 | 0;
-  $1672 = $1671;
-  HEAP32[$1672 >> 2] = $1669;
-  $1673 = $1670;
-  $1674 = HEAP32[$1673 >> 2] | 0;
-  $1675 = $1674;
-  invoke_vii(48, $1675 | 0, 0 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  return 0 | 0;
-  case 396:
-  $1677 = HEAP32[$1643 >> 2] | 0;
-  _memcpy($1677 | 0, $1641 | 0, 40);
-  $1678 = HEAP32[(107740 | 0) >> 2] | 0;
-  $1679 = ($1678 | 0) == 0;
-  if ($1679) {
-   label = 397;
-   break;
-  } else {
-   label = 398;
-   break;
-  }
-  case 397:
-  invoke_v(374);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  label = 398;
-  break;
-  case 398:
-  $1682 = $1640 + 20 | 0;
-  $1683 = $1682;
-  $1684 = HEAP32[$1683 >> 2] | 0;
-  $1685 = ($1684 | 0) == 0;
-  if ($1685) {
-   label = 412;
-   break;
-  } else {
-   label = 399;
-   break;
-  }
-  case 399:
-  $1687 = HEAP32[137616 >> 2] | 0;
-  $1688 = $1684;
-  $1689 = HEAP32[$1688 >> 2] | 0;
-  $1690 = $1689;
-  $1691 = $1687 + 8 | 0;
-  $1692 = $1691;
-  $1693 = HEAP32[$1692 >> 2] | 0;
-  $1694 = ($1689 | 0) == 82712;
-  if ($1694) {
-   label = 400;
-   break;
-  } else {
-   $tib1_0_ph_i = $1690;
-   label = 401;
-   break;
-  }
-  case 400:
-  $1696 = $1684 + 8 | 0;
-  $1697 = $1696;
-  $1698 = HEAP32[$1697 >> 2] | 0;
-  $1699 = $1698 + 8 | 0;
-  $1700 = $1699;
-  $1701 = HEAP32[$1700 >> 2] | 0;
-  $1702 = $1701;
-  $tib1_0_ph_i = $1702;
-  label = 401;
-  break;
-  case 401:
-  $1703 = $tib1_0_ph_i + 56 | 0;
-  $1704 = HEAP32[$1703 >> 2] | 0;
-  $1705 = ($1704 | 0) == 0;
-  if ($1705) {
-   var $dimension_tib1_0_lcssa_i = 0;
-   var $tib1_0_lcssa_i = $tib1_0_ph_i;
-   label = 403;
-   break;
-  } else {
-   var $dimension_tib1_029_i = 0;
-   var $1711 = $1704;
-   label = 404;
-   break;
-  }
-  case 402:
-  $1706 = $1714;
-  var $dimension_tib1_0_lcssa_i = $1715;
-  var $tib1_0_lcssa_i = $1706;
-  label = 403;
-  break;
-  case 403:
-  $1707 = $1693 + 56 | 0;
-  $1708 = $1707;
-  $1709 = HEAP32[$1708 >> 2] | 0;
-  $1710 = ($1709 | 0) == 0;
-  if ($1710) {
-   var $dimension_tib2_0_lcssa_i = 0;
-   var $tib2_0_lcssa_in_i = $1693;
-   label = 406;
-   break;
-  } else {
-   var $dimension_tib2_024_i = 0;
-   var $1720 = $1709;
-   label = 405;
-   break;
-  }
-  case 404:
-  $1712 = $1711 + 8 | 0;
-  $1713 = $1712;
-  $1714 = HEAP32[$1713 >> 2] | 0;
-  $1715 = $dimension_tib1_029_i + 1 | 0;
-  $1716 = $1714 + 56 | 0;
-  $1717 = $1716;
-  $1718 = HEAP32[$1717 >> 2] | 0;
-  $1719 = ($1718 | 0) == 0;
-  if ($1719) {
-   label = 402;
-   break;
-  } else {
-   var $dimension_tib1_029_i = $1715;
-   var $1711 = $1718;
-   label = 404;
-   break;
-  }
-  case 405:
-  $1721 = $1720 + 8 | 0;
-  $1722 = $1721;
-  $1723 = HEAP32[$1722 >> 2] | 0;
-  $1724 = $dimension_tib2_024_i + 1 | 0;
-  $1725 = $1723 + 56 | 0;
-  $1726 = $1725;
-  $1727 = HEAP32[$1726 >> 2] | 0;
-  $1728 = ($1727 | 0) == 0;
-  if ($1728) {
-   var $dimension_tib2_0_lcssa_i = $1724;
-   var $tib2_0_lcssa_in_i = $1723;
-   label = 406;
-   break;
-  } else {
-   var $dimension_tib2_024_i = $1724;
-   var $1720 = $1727;
-   label = 405;
-   break;
-  }
-  case 406:
-  $tib2_0_lcssa_i = $tib2_0_lcssa_in_i;
-  $1729 = ($dimension_tib1_0_lcssa_i | 0) < ($dimension_tib2_0_lcssa_i | 0);
-  $1730 = ($tib1_0_lcssa_i | 0) == 0;
-  $or_cond_i = $1729 | $1730;
-  if ($or_cond_i) {
-   label = 412;
-   break;
-  } else {
-   $tib1_121_i = $tib1_0_lcssa_i;
-   label = 407;
-   break;
-  }
-  case 407:
-  $1731 = ($tib1_121_i | 0) == ($tib2_0_lcssa_i | 0);
-  if ($1731) {
-   label = 54;
-   break;
-  } else {
-   label = 408;
-   break;
-  }
-  case 408:
-  $1732 = $tib1_121_i + 108 | 0;
-  $1733 = HEAP32[$1732 >> 2] | 0;
-  $1734 = $tib1_121_i + 112 | 0;
-  $i_0_i = 0;
-  label = 409;
-  break;
-  case 409:
-  $1736 = ($i_0_i | 0) < ($1733 | 0);
-  if ($1736) {
-   label = 410;
-   break;
-  } else {
-   label = 411;
-   break;
-  }
-  case 410:
-  $1738 = HEAP32[$1734 >> 2] | 0;
-  $1739 = $1738 + ($i_0_i << 2) | 0;
-  $1740 = HEAP32[$1739 >> 2] | 0;
-  $1741 = ($1740 | 0) == ($tib2_0_lcssa_i | 0);
-  $1742 = $i_0_i + 1 | 0;
-  if ($1741) {
-   label = 54;
-   break;
-  } else {
-   $i_0_i = $1742;
-   label = 409;
-   break;
-  }
-  case 411:
-  $1744 = $tib1_121_i + 40 | 0;
-  $1745 = HEAP32[$1744 >> 2] | 0;
-  $1746 = ($1745 | 0) == 0;
-  if ($1746) {
-   label = 412;
-   break;
-  } else {
-   $tib1_121_i = $1745;
-   label = 407;
-   break;
-  }
-  case 412:
-  $1747 = HEAP32[$1643 >> 2] | 0;
-  $1748 = $1747;
-  invoke_vii(48, $1748 | 0, 0 | 0);
-  if ((__THREW__ | 0) != 0 & (threwValue | 0) != 0) {
-   setjmpLabel = _testSetjmp(HEAP32[__THREW__ >> 2] | 0, setjmpTable) | 0;
-   if ((setjmpLabel | 0) > 0) {
-    label = -1111;
-    break;
-   } else return 0 | 0;
-  }
-  __THREW__ = threwValue = 0;
-  return 0 | 0;
-  case -1111:
-  if ((setjmpLabel | 0) == 7) {
-   $25 = threwValue;
-   label = 413;
-  } else if ((setjmpLabel | 0) == 35) {
-   $159 = threwValue;
-   label = 414;
-  } else if ((setjmpLabel | 0) == 62) {
-   $290 = threwValue;
-   label = 415;
-  } else if ((setjmpLabel | 0) == 91) {
-   $401 = threwValue;
-   label = 416;
-  } else if ((setjmpLabel | 0) == 97) {
-   $433 = threwValue;
-   label = 417;
-  } else if ((setjmpLabel | 0) == 144) {
-   $629 = threwValue;
-   label = 418;
-  } else if ((setjmpLabel | 0) == 181) {
-   $789 = threwValue;
-   label = 419;
-  } else if ((setjmpLabel | 0) == 218) {
-   $954 = threwValue;
-   label = 420;
-  } else if ((setjmpLabel | 0) == 240) {
-   $1042 = threwValue;
-   label = 421;
-  } else if ((setjmpLabel | 0) == 251) {
-   $1073 = threwValue;
-   label = 422;
-  } else if ((setjmpLabel | 0) == 324) {
-   $1378 = threwValue;
-   label = 423;
-  } else if ((setjmpLabel | 0) == 363) {
-   $1545 = threwValue;
-   label = 424;
-  } else if ((setjmpLabel | 0) == 388) {
-   $1647 = threwValue;
-   label = 425;
-  }
-  __THREW__ = threwValue = 0;
-  break;
- }
-}
 function looop2() {
  var i = 0, helper = 0;
  while (1) {
diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js
index f03c04b8f947b..10aeda4d74be2 100644
--- a/tools/js-optimizer.js
+++ b/tools/js-optimizer.js
@@ -1582,7 +1582,7 @@ function normalizeAsm(func) {
   while (i < stats.length) {
     traverse(stats[i], function(node, type) {
       if (type === 'var') {
-        assert(0, 'should be no vars to fix! ' + JSON.stringify(node));
+        assert(0, 'should be no vars to fix! ' + func[1] + ' : ' + JSON.stringify(node));
         /*
         for (var j = 0; j < node[1].length; j++) {
           var v = node[1][j];
diff --git a/tools/test-js-optimizer-asm-pre-output.js b/tools/test-js-optimizer-asm-pre-output.js
index b31327f216860..2e3db000968f2 100644
--- a/tools/test-js-optimizer-asm-pre-output.js
+++ b/tools/test-js-optimizer-asm-pre-output.js
@@ -69,26 +69,6 @@ function b($this, $__n) {
  h(~~g ^ -1);
  return;
 }
-function rett() {
- if (f()) {
-  g();
-  return 5;
- }
- return 0;
-}
-function ret2t() {
- if (f()) {
-  g();
-  return;
- }
-}
-function retf() {
- if (f()) {
-  g();
-  return +h();
- }
- return +0;
-}
 function i32_8() {
  if ((HEAP8[$4 & 16777215] | 0) == 0) {
   print(5);
diff --git a/tools/test-js-optimizer-asm-pre.js b/tools/test-js-optimizer-asm-pre.js
index 5c0043428eb00..9e6edf0f97282 100644
--- a/tools/test-js-optimizer-asm-pre.js
+++ b/tools/test-js-optimizer-asm-pre.js
@@ -73,27 +73,6 @@ function b($this, $__n) {
  h((~~g) ^ -1); // do NOT convert this, as it would lead to ~~~ which is confusing in asm, given the role of ~~
  return;
 }
-function rett() {
- if (f()) {
-  g();
-  return 5;
- }
- // missing final return, need to add it
-}
-function ret2t() {
- if (f()) {
-  g();
-  return;
- }
- // missing final return, but no need
-}
-function retf() {
- if (f()) {
-  g();
-  return +h();
- }
- // missing final return, need it as a float
-}
 function i32_8() {
  if (((HEAP8[$4 & 16777215] | 0) << 24 >> 24) == 0) {
   print(5);
diff --git a/tools/test-js-optimizer-asm-regs.js b/tools/test-js-optimizer-asm-regs.js
index cfa7732deb310..b2d97afc109ae 100644
--- a/tools/test-js-optimizer-asm-regs.js
+++ b/tools/test-js-optimizer-asm-regs.js
@@ -4,7 +4,7 @@ function asm(x, y) {
  var int1 = 0, int2 = 0; // do not mix the types!
  var double1 = +0, double2 = +0;
  int1 = (x+x)|0;
- double1 = d(Math.max(10, Math_min(5, f())));
+ double1 = d(Math_max(10, Math_min(5, f())));
  int2 = (int1+2)|0;
  print(int2);
  double2 = double1*5;
@@ -32,7 +32,7 @@ function switchey(x, y) {
  switch(x|0) {
   case 0:
    int1 = (x+x)|0;
-   double1 = d(Math.max(10, Math_min(5, f())));
+   double1 = d(Math_max(10, Math_min(5, f())));
    int2 = (int1+2)|0;
    print(int2);
    double2 = double1*5;

From daae8bdf7894bb4d4e9461b5b841c14019c6559a Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Wed, 2 Oct 2013 17:57:23 -0700
Subject: [PATCH 158/165] update test_emcc

---
 tests/test_other.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/test_other.py b/tests/test_other.py
index 69823d8e1aed3..afad1927b54c2 100644
--- a/tests/test_other.py
+++ b/tests/test_other.py
@@ -175,7 +175,7 @@ def test_emcc(self):
           if opt_level >= 2 and '-g' in params:
             assert re.search('HEAP8\[\$?\w+ ?\+ ?\(+\$?\w+ ?', generated) or re.search('HEAP8\[HEAP32\[', generated), 'eliminator should create compound expressions, and fewer one-time vars' # also in -O1, but easier to test in -O2
           assert ('_puts(' in generated) == (opt_level >= 1), 'with opt >= 1, llvm opts are run and they should optimize printf to puts'
-          if opt_level == 0 or '-g' in params: assert 'function _main() {' in generated, 'Should be unminified, including whitespace'
+          if opt_level == 0 or '-g' in params: assert 'function _main() {' in generated or 'function _main(){' in generated, 'Should be unminified'
           elif opt_level >= 2: assert ('function _main(){' in generated or '"use asm";var a=' in generated), 'Should be whitespace-minified'
 
       # emcc -s RELOOP=1 src.cpp ==> should pass -s to emscripten.py. --typed-arrays is a convenient alias for -s USE_TYPED_ARRAYS

From be93f604b8c5b529814efacd729455856e96ebf0 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Thu, 3 Oct 2013 10:49:08 -0700
Subject: [PATCH 159/165] disable heap align check in test_files, it mixes
 poorly with closure

---
 tests/test_core.py | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tests/test_core.py b/tests/test_core.py
index 92edbaf434ea5..809339379f767 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -7266,6 +7266,7 @@ def test_files(self):
     if self.emcc_args is not None and '-O2' in self.emcc_args:
       self.emcc_args += ['--closure', '1'] # Use closure here, to test we don't break FS stuff
       self.emcc_args = filter(lambda x: x != '-g', self.emcc_args) # ensure we test --closure 1 --memory-init-file 1 (-g would disable closure)
+      self.emcc_args += ["-s", "CHECK_HEAP_ALIGN=0"] # disable heap align check here, it mixes poorly with closure
 
     Settings.CORRECT_SIGNS = 1 # Just so our output is what we expect. Can flip them both.
     post = '''

From e91ceb07780515b60568e81432a0ec0e0ce9f24b Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Thu, 3 Oct 2013 10:57:17 -0700
Subject: [PATCH 160/165] fix js_opts definition

---
 emcc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/emcc b/emcc
index 7ae19866dda0c..63435cc9e89e0 100755
--- a/emcc
+++ b/emcc
@@ -933,7 +933,7 @@ try:
   if default_cxx_std:
     newargs = newargs + [default_cxx_std]
 
-  if js_opts is None: js_opts = True
+  if js_opts is None: js_opts = opt_level >= 1
   if llvm_opts is None: llvm_opts = LLVM_OPT_LEVEL[opt_level]
   if llvm_lto is None and opt_level >= 3: llvm_lto = 3
   if opt_level == 0: debug_level = 4

From 4091984a0c897c53b09de5a7caf64f9819a9be6e Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Mon, 30 Sep 2013 15:20:53 -0700
Subject: [PATCH 161/165] remove unneeded EMIT_GENERATED_FUNCTIONS

---
 src/jsifier.js  | 4 ++--
 src/settings.js | 2 --
 tools/shared.py | 1 -
 3 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/src/jsifier.js b/src/jsifier.js
index 64da422800eae..0e5f8ef380eac 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -1849,14 +1849,14 @@ function JSify(data, functionsOnly, givenFunctions) {
     var shellParts = read(shellFile).split('{{BODY}}');
     print(processMacros(preprocess(shellParts[1])));
     // Print out some useful metadata
-    if (EMIT_GENERATED_FUNCTIONS || PGO) {
+    if (RUNNING_JS_OPTS || PGO) {
       var generatedFunctions = JSON.stringify(keys(Functions.implementedFunctions).filter(function(func) {
         return IGNORED_FUNCTIONS.indexOf(func.ident) < 0;
       }));
       if (PGO) {
         print('PGOMonitor.allGenerated = ' + generatedFunctions + ';\nremoveRunDependency("pgo");\n');
       }
-      if (EMIT_GENERATED_FUNCTIONS) {
+      if (RUNNING_JS_OPTS) {
         print('// EMSCRIPTEN_GENERATED_FUNCTIONS: ' + generatedFunctions + '\n');
       }
     }
diff --git a/src/settings.js b/src/settings.js
index 6894b53559055..d2b47dc88c38f 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -427,8 +427,6 @@ var EXPLICIT_ZEXT = 0; // If 1, generate an explicit conversion of zext i1 to i3
 
 var NECESSARY_BLOCKADDRS = []; // List of (function, block) for all block addresses that are taken.
 
-var EMIT_GENERATED_FUNCTIONS = 0; // whether to emit the list of generated functions, needed for external JS optimization passes
-
 var JS_CHUNK_SIZE = 10240; // Used as a maximum size before breaking up expressions and lines into smaller pieces
 
 var EXPORT_NAME = 'Module'; // Global variable to export the module as for environments without a standardized module
diff --git a/tools/shared.py b/tools/shared.py
index c5df34f13295c..b3c3257b57a60 100644
--- a/tools/shared.py
+++ b/tools/shared.py
@@ -758,7 +758,6 @@ def apply_opt_level(self, opt_level, noisy=False):
         self.attrs['ASM_JS'] = 1
         self.attrs['ASSERTIONS'] = 0
         self.attrs['DISABLE_EXCEPTION_CATCHING'] = 1
-        self.attrs['EMIT_GENERATED_FUNCTIONS'] = 1
       if opt_level >= 2:
         self.attrs['RELOOP'] = 1
         self.attrs['ALIASING_FUNCTION_POINTERS'] = 1

From 800ec1f87be63eda668e0fbde373200ccc88710c Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Sun, 6 Oct 2013 10:33:50 -0700
Subject: [PATCH 162/165] look for metadata in js optimizer starting at the end

---
 tools/js-optimizer.js | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js
index 10aeda4d74be2..e5e0d28725398 100644
--- a/tools/js-optimizer.js
+++ b/tools/js-optimizer.js
@@ -3840,8 +3840,8 @@ arguments_ = arguments_.filter(function (arg) {
 var src = read(arguments_[0]);
 var ast = srcToAst(src);
 //printErr(JSON.stringify(ast)); throw 1;
-generatedFunctions = src.indexOf(GENERATED_FUNCTIONS_MARKER) >= 0;
-var extraInfoStart = src.indexOf('// EXTRA_INFO:')
+generatedFunctions = src.lastIndexOf(GENERATED_FUNCTIONS_MARKER) >= 0;
+var extraInfoStart = src.lastIndexOf('// EXTRA_INFO:')
 if (extraInfoStart > 0) extraInfo = JSON.parse(src.substr(extraInfoStart + 14));
 //printErr(JSON.stringify(extraInfo));
 

From c1dd12998fd862010c7c11e6fa9d003521923a3c Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Sun, 6 Oct 2013 10:34:58 -0700
Subject: [PATCH 163/165] do not run simplifyExpressions in -O1

---
 emcc | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/emcc b/emcc
index 63435cc9e89e0..ff81e42439ae3 100755
--- a/emcc
+++ b/emcc
@@ -1742,7 +1742,10 @@ try:
       else:
         return 'eliminate'
 
-    js_optimizer_queue += [get_eliminate(), 'simplifyExpressions']
+    js_optimizer_queue += [get_eliminate()]
+
+    if opt_level >= 2:
+      js_optimizer_queue += ['simplifyExpressions']
 
   if closure and not shared.Settings.ASM_JS:
     flush_js_optimizer_queue()

From 332325394c20bb4a3972344144803fcd93476b08 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Sun, 6 Oct 2013 17:44:06 -0700
Subject: [PATCH 164/165] make EM_ASM use strings on the heap, so it works in
 asm, and cache the generated functions

---
 src/library.js                         |  9 +++++++++
 system/include/emscripten/emscripten.h | 10 +++++++++-
 tests/test_core.py                     | 25 +++++++++++++------------
 3 files changed, 31 insertions(+), 13 deletions(-)

diff --git a/src/library.js b/src/library.js
index 48f613e083808..5e71b087cbe21 100644
--- a/src/library.js
+++ b/src/library.js
@@ -8613,6 +8613,15 @@ LibraryManager.library = {
     Runtime.stackAlloc(-4*i); // free up the stack space we know is ok to free
   },
 
+  emscripten_asm_const: function(code) {
+    // code is a constant string on the heap, so we can cache these
+    if (!Runtime.asmConstCache) Runtime.asmConstCache = {};
+    var func = Runtime.asmConstCache[code];
+    if (func) return func();
+    func = Runtime.asmConstCache[code] = eval('(function(){ ' + Pointer_stringify(code) + ' })'); // new Function does not allow upvars in node
+    return func();
+  },
+
   //============================
   // i64 math
   //============================
diff --git a/system/include/emscripten/emscripten.h b/system/include/emscripten/emscripten.h
index 430fbc1c7784b..d30620eca762f 100644
--- a/system/include/emscripten/emscripten.h
+++ b/system/include/emscripten/emscripten.h
@@ -23,10 +23,13 @@ extern "C" {
  *
  *    EM_ASM(window.alert('hai'));
  *
+ * This also works with asm.js, as it outlines the code (it
+ * does a function call to reach it).
+ *
  * Note: double-quotes (") are not supported, but you can use
  *       single-quotes (') in js anyhow.
  */
-#define EM_ASM(...) asm(#__VA_ARGS__)
+#define EM_ASM(...) emscripten_asm_const(#__VA_ARGS__)
 
 /*
  * Forces LLVM to not dead-code-eliminate a function. Note that
@@ -376,6 +379,8 @@ int emscripten_get_worker_queue_size(worker_handle worker);
 #define EMSCRIPTEN_NETWORK_WEBRTC     1
 void emscripten_set_network_backend(int backend);
 
+/* Internal APIs. Be careful with these. */
+
 /*
  * Profiling tools.
  * INIT must be called first, with the maximum identifier that
@@ -413,6 +418,9 @@ void emscripten_jcache_printf(const char *format, ...);
 void emscripten_jcache_printf_(...); /* internal use */
 #endif
 
+/* Helper API for EM_ASM - do not call this yourself */
+void emscripten_asm_const(const char *code);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/tests/test_core.py b/tests/test_core.py
index 809339379f767..b46685842c3be 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -3841,25 +3841,26 @@ def test_inlinejs2(self):
       self.do_run(src, '4\n200\ndone\n')
 
   def test_inlinejs3(self):
-      if Settings.ASM_JS: return self.skip('asm does not support random code, TODO: something that works in asm')
-      src = r'''
-        #include 
-        #include 
+    src = r'''
+      #include 
+      #include 
 
-        int main() {
-          EM_ASM(Module.print('hello dere1'));
-          EM_ASM(
-            Module.print('hello dere2');
-          );
+      int main() {
+        EM_ASM(Module.print('hello dere1'));
+        EM_ASM(
+          Module.print('hello dere2');
+        );
+        for (int i = 0; i < 3; i++) {
           EM_ASM(
             Module.print('hello dere3');
             Module.print('hello dere' + 4);
           );
-          return 0;
         }
-        '''
+        return 0;
+      }
+      '''
 
-      self.do_run(src, 'hello dere1\nhello dere2\nhello dere3\nhello dere4\n')
+    self.do_run(src, 'hello dere1\nhello dere2\nhello dere3\nhello dere4\nhello dere3\nhello dere4\nhello dere3\nhello dere4\n')
 
   def test_memorygrowth(self):
     if Settings.USE_TYPED_ARRAYS == 0: return self.skip('memory growth is only supported with typed arrays')

From ae5ef852920ce67449af7693f05a767a87aed976 Mon Sep 17 00:00:00 2001
From: Alon Zakai 
Date: Sun, 6 Oct 2013 19:47:19 -0700
Subject: [PATCH 165/165] enable asm validation checks in unistd tests using
 EM_ASM

---
 tests/test_core.py | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/tests/test_core.py b/tests/test_core.py
index b46685842c3be..c1bfce6f048ce 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -7751,7 +7751,6 @@ def test_fs_nodefs_rw(self):
     self.do_run(src, 'success', force_c=True, js_engines=[NODE_JS])
 
   def test_unistd_access(self):
-    if Settings.ASM_JS: Settings.ASM_JS = 2 # skip validation, asm does not support random code
     if not self.is_le32(): return self.skip('le32 needed for inline js')
     for fs in ['MEMFS', 'NODEFS']:
       src = open(path_from_root('tests', 'unistd', 'access.c'), 'r').read()
@@ -7760,7 +7759,6 @@ def test_unistd_access(self):
       self.do_run(src, expected, js_engines=[NODE_JS])
 
   def test_unistd_curdir(self):
-    if Settings.ASM_JS: Settings.ASM_JS = 2 # skip validation, asm does not support random code
     if not self.is_le32(): return self.skip('le32 needed for inline js')
     src = open(path_from_root('tests', 'unistd', 'curdir.c'), 'r').read()
     expected = open(path_from_root('tests', 'unistd', 'curdir.out'), 'r').read()
@@ -7791,7 +7789,6 @@ def test_unistd_pathconf(self):
     self.do_run(src, expected)
 
   def test_unistd_truncate(self):
-    if Settings.ASM_JS: Settings.ASM_JS = 2 # skip validation, asm does not support random code
     if not self.is_le32(): return self.skip('le32 needed for inline js')
     for fs in ['MEMFS', 'NODEFS']:
       src = open(path_from_root('tests', 'unistd', 'truncate.c'), 'r').read()
@@ -7827,7 +7824,6 @@ def test_unistd_unlink(self):
       self.do_run(src, 'success', force_c=True, js_engines=[NODE_JS])
 
   def test_unistd_links(self):
-    if Settings.ASM_JS: Settings.ASM_JS = 2 # skip validation, asm does not support random code
     if not self.is_le32(): return self.skip('le32 needed for inline js')
     for fs in ['MEMFS', 'NODEFS']:
       src = open(path_from_root('tests', 'unistd', 'links.c'), 'r').read()
@@ -7841,7 +7837,6 @@ def test_unistd_sleep(self):
     self.do_run(src, expected)
 
   def test_unistd_io(self):
-    if Settings.ASM_JS: Settings.ASM_JS = 2 # skip validation, asm does not support random code
     if not self.is_le32(): return self.skip('le32 needed for inline js')
     if self.run_name == 'o2': return self.skip('non-asm optimized builds can fail with inline js')
     if self.emcc_args is None: return self.skip('requires emcc')