diff options
author | Alon Zakai <alonzakai@gmail.com> | 2012-12-21 15:54:59 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2012-12-21 15:54:59 -0800 |
commit | 2f4401a79e96917f78876c3e09b8d31754a26f70 (patch) | |
tree | 8ac45e1d7b302a9f0aaa7e9b9e74aff01965a93d | |
parent | 2c8c19f60585d4e8cb78af119faba664a35e2268 (diff) | |
parent | 160cc728e0839e441897d951fa61020bc2176717 (diff) |
Merge branch 'incoming'
65 files changed, 1351 insertions, 827 deletions
@@ -42,4 +42,5 @@ a license to everyone to use it as detailed in LICENSE.) * Manuel Wellmann <manuel.wellmann@autodesk.com> (copyright owned by Autodesk, Inc.) * Xuejie Xiao <xxuejie@gmail.com> * Dominic Wong <dom@slowbunyip.org> +* Alan Kligman <alan.kligman@gmail.com> (copyright owned by Mozilla Foundation) @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 ''' See emcc.py. This script forwards to there, noting that we want C++ and not C by default @@ -8,5 +8,5 @@ import os, subprocess, sys from tools import shared os.environ['EMMAKEN_CXX'] = '1' -exit(subprocess.call(['python', shared.EMCC] + sys.argv[1:])) +exit(subprocess.call([shared.PYTHON, shared.EMCC] + sys.argv[1:])) @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 ''' This is a helper tool which is designed to make it possible @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 ''' emar - ar helper script @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 ''' emcc - compiler helper script @@ -322,11 +322,6 @@ Options that are modified or new in %s include: -v to Clang, and also enable EMCC_DEBUG to details emcc's operations - --remove-duplicates If set, will remove duplicate symbols when - linking. This can be useful because - llvm-link's behavior is not as permissive - as ld is. - --jcache Use a JavaScript cache. This is disabled by default. When enabled, emcc will store the results of compilation in a cache and check @@ -596,7 +591,6 @@ try: ignore_dynamic_linking = False shell_path = shared.path_from_root('src', 'shell.html') js_libraries = [] - remove_duplicates = False keep_debug = False bind = False jcache = False @@ -705,7 +699,7 @@ try: newargs[i] = '' newargs[i+1] = '' elif newargs[i] == '--remove-duplicates': - remove_duplicates = True + print >> sys.stderr, 'emcc: warning: --remove-duplicates is deprecated as it is no longer needed. If you cannot link without it, file a bug with a testcase' newargs[i] = '' elif newargs[i] == '--jcache': jcache = True @@ -912,7 +906,7 @@ try: # We have a specified target (-o <target>), which is not JavaScript or HTML, and # we have multiple files: Link them if DEBUG: print >> sys.stderr, 'emcc: link: ' + str(temp_files), specified_target - shared.Building.link(temp_files, specified_target, remove_duplicates=remove_duplicates) + shared.Building.link(temp_files, specified_target) exit(0) ## Continue on to create JavaScript @@ -931,9 +925,9 @@ try: # dlmalloc def create_dlmalloc(): if DEBUG: print >> sys.stderr, 'emcc: building dlmalloc for cache' - execute(shared.ENV_PREFIX + ['python', shared.EMCC, shared.path_from_root('system', 'lib', 'dlmalloc.c'), '-g', '-o', in_temp('dlmalloc.o')], stdout=stdout, stderr=stderr) + execute([shared.PYTHON, shared.EMCC, shared.path_from_root('system', 'lib', 'dlmalloc.c'), '-g', '-o', in_temp('dlmalloc.o')], stdout=stdout, stderr=stderr) # we include the libc++ new stuff here, so that the common case of using just new/delete is quick to link - execute(shared.ENV_PREFIX + ['python', shared.EMXX, shared.path_from_root('system', 'lib', 'libcxx', 'new.cpp'), '-g', '-o', in_temp('new.o')], stdout=stdout, stderr=stderr) + execute([shared.PYTHON, shared.EMXX, shared.path_from_root('system', 'lib', 'libcxx', 'new.cpp'), '-g', '-o', in_temp('new.o')], stdout=stdout, stderr=stderr) shared.Building.link([in_temp('dlmalloc.o'), in_temp('new.o')], in_temp('dlmalloc_full.o')) return in_temp('dlmalloc_full.o') def fix_dlmalloc(): @@ -956,7 +950,7 @@ try: os = [] for src in ['algorithm.cpp', 'condition_variable.cpp', 'future.cpp', 'iostream.cpp', 'memory.cpp', 'random.cpp', 'stdexcept.cpp', 'system_error.cpp', 'utility.cpp', 'bind.cpp', 'debug.cpp', 'hash.cpp', 'mutex.cpp', 'string.cpp', 'thread.cpp', 'valarray.cpp', 'chrono.cpp', 'exception.cpp', 'ios.cpp', 'locale.cpp', 'regex.cpp', 'strstream.cpp', 'typeinfo.cpp']: o = in_temp(src + '.o') - execute(shared.ENV_PREFIX + ['python', shared.EMXX, shared.path_from_root('system', 'lib', 'libcxx', src), '-o', o], stdout=stdout, stderr=stderr) + execute([shared.PYTHON, shared.EMXX, shared.path_from_root('system', 'lib', 'libcxx', src), '-o', o], stdout=stdout, stderr=stderr) os.append(o) shared.Building.link(os, in_temp('libcxx.bc')) return in_temp('libcxx.bc') @@ -975,7 +969,7 @@ try: os = [] for src in ['private_typeinfo.cpp']: o = in_temp(src + '.o') - execute(shared.ENV_PREFIX + ['python', shared.EMXX, shared.path_from_root('system', 'lib', 'libcxxabi', 'src', src), '-o', o], stdout=stdout, stderr=stderr) + execute([shared.PYTHON, shared.EMXX, shared.path_from_root('system', 'lib', 'libcxxabi', 'src', src), '-o', o], stdout=stdout, stderr=stderr) os.append(o) shared.Building.link(os, in_temp('libcxxabi.bc')) return in_temp('libcxxabi.bc') @@ -1027,7 +1021,7 @@ try: (not LEAVE_INPUTS_RAW and not (suffix(temp_files[0]) in BITCODE_SUFFIXES or suffix(temp_files[0]) in DYNAMICLIB_SUFFIXES) and shared.Building.is_ar(temp_files[0])): linker_inputs = temp_files + extra_files_to_link if DEBUG: print >> sys.stderr, 'emcc: linking: ', linker_inputs - shared.Building.link(linker_inputs, in_temp(target_basename + '.bc'), remove_duplicates=remove_duplicates) + shared.Building.link(linker_inputs, in_temp(target_basename + '.bc')) final = in_temp(target_basename + '.bc') else: if not LEAVE_INPUTS_RAW: @@ -1061,13 +1055,14 @@ try: if DEBUG: save_intermediate('opt', 'bc') # Do LTO in a separate pass to work around LLVM bug XXX (see failure e.g. in cubescript) if shared.Building.can_build_standalone(): + # If we can LTO, do it before dce, since it opens up dce opportunities if llvm_lto and shared.Building.can_use_unsafe_opts(): if not shared.Building.can_inline(): link_opts.append('-disable-inlining') - link_opts.append('-std-link-opts') + # do not internalize in std-link-opts - it ignores internalize-public-api-list - and add a manual internalize + link_opts += ['-disable-internalize'] + shared.Building.get_safe_internalize() + ['-std-link-opts'] else: - # At least remove dead functions etc., this potentially saves a lot in the size of the generated code (and the time to compile it) - link_opts += ['-internalize', '-globaldce'] - if link_opts: + # At minimum remove dead functions etc., this potentially saves a lot in the size of the generated code (and the time to compile it) + link_opts += shared.Building.get_safe_internalize() + ['-globaldce'] if DEBUG: print >> sys.stderr, 'emcc: LLVM linktime:', link_opts shared.Building.llvm_opt(in_temp(target_basename + '.bc'), link_opts) if DEBUG: save_intermediate('linktime', 'bc') @@ -1081,7 +1076,7 @@ try: if AUTODEBUG: if DEBUG: print >> sys.stderr, 'emcc: autodebug' - execute(shared.ENV_PREFIX + ['python', shared.AUTODEBUGGER, final, final + '.ad.ll']) + execute([shared.PYTHON, shared.AUTODEBUGGER, final, final + '.ad.ll']) final += '.ad.ll' if DEBUG: save_intermediate('autodebug', 'll') @@ -1104,7 +1099,7 @@ try: file_args += embed_files if Compression.on: file_args += ['--compress', Compression.encoder, Compression.decoder, Compression.js_name] - code = execute(shared.ENV_PREFIX + ['python', shared.FILE_PACKAGER, unsuffixed(target) + '.data'] + file_args, stdout=PIPE)[0] + code = execute([shared.PYTHON, shared.FILE_PACKAGER, unsuffixed(target) + '.data'] + file_args, stdout=PIPE)[0] src = open(final).read().replace('// {{PRE_RUN_ADDITIONS}}', '// {{PRE_RUN_ADDITIONS}}\n' + code) final += '.files.js' open(final, 'w').write(src) diff --git a/emconfigure b/emconfigure index 64ca8c4f..51e57c64 100755 --- a/emconfigure +++ b/emconfigure @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 ''' This is a helper script. It runs ./configure for you, setting @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 ''' This is a helper script. See emcc. @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 ''' This is a helper script. It runs make for you, setting @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 ''' emcc - ranlib helper script diff --git a/emscripten.py b/emscripten.py index 98dcb6bb..3c636447 100755 --- a/emscripten.py +++ b/emscripten.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 ''' You should normally never use this! Use emcc instead. diff --git a/src/jsifier.js b/src/jsifier.js index 50703b90..4192cd3f 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -486,6 +486,19 @@ function JSify(data, functionsOnly, givenFunctions) { } }); + // function for filtering functions for label debugging + if (LABEL_FUNCTION_FILTERS.length > 0) { + var LABEL_FUNCTION_FILTER_SET = set(LABEL_FUNCTION_FILTERS); + var functionNameFilterTest = function(ident) { + return (ident in LABEL_FUNCTION_FILTER_SET); + }; + } else { + // no filters are specified, all function names are printed + var functionNameFilterTest = function(ident) { + return true; + } + } + // function reconstructor & post-JS optimizer substrate.addActor('FunctionReconstructor', { funcs: {}, @@ -566,7 +579,7 @@ function JSify(data, functionsOnly, givenFunctions) { } }); - if (LABEL_DEBUG) func.JS += " Module.print(INDENT + ' Entering: " + func.ident + ": ' + Array.prototype.slice.call(arguments)); INDENT += ' ';\n"; + if (LABEL_DEBUG && functionNameFilterTest(func.ident)) func.JS += " Module.print(INDENT + ' Entering: " + func.ident + ": ' + Array.prototype.slice.call(arguments)); INDENT += ' ';\n"; if (true) { // TODO: optimize away when not needed if (CLOSURE_ANNOTATIONS) func.JS += '/** @type {number} */'; @@ -580,7 +593,7 @@ function JSify(data, functionsOnly, givenFunctions) { function getLabelLines(label, indent, relooping) { if (!label) return ''; var ret = ''; - if (LABEL_DEBUG >= 2) { + if ((LABEL_DEBUG >= 2) && functionNameFilterTest(func.ident)) { ret += indent + "Module.print(INDENT + '" + func.ident + ":" + label.ident + "');\n"; } if (EXECUTION_TIMEOUT > 0) { @@ -692,7 +705,7 @@ function JSify(data, functionsOnly, givenFunctions) { } func.JS += walkBlock(func.block, ' '); // Finalize function - if (LABEL_DEBUG) func.JS += " INDENT = INDENT.substr(0, INDENT.length-2);\n"; + if (LABEL_DEBUG && functionNameFilterTest(func.ident)) func.JS += " INDENT = INDENT.substr(0, INDENT.length-2);\n"; // Add an unneeded return, needed for strict mode to not throw warnings in some cases. // If we are not relooping, then switches make it unimportant to have this (and, we lack hasReturn anyhow) if (RELOOP && func.lines.length > 0 && func.labels.filter(function(label) { return label.hasReturn }).length > 0) { @@ -1025,7 +1038,7 @@ function JSify(data, functionsOnly, givenFunctions) { + 'PROFILING_NODE = __parentProfilingNode__ ' + '}\n'; } - if (LABEL_DEBUG) { + if (LABEL_DEBUG && functionNameFilterTest(item.funcData.ident)) { ret += "Module.print(INDENT + 'Exiting: " + item.funcData.ident + "');\n" + "INDENT = INDENT.substr(0, INDENT.length-2);\n"; } diff --git a/src/library.js b/src/library.js index 1bdd840d..93d54d68 100644 --- a/src/library.js +++ b/src/library.js @@ -5886,6 +5886,26 @@ LibraryManager.library = { }, // ========================================================================== + // sys/timeb.h + // ========================================================================== + + __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 + return 0; + }, + + // ========================================================================== // sys/times.h // ========================================================================== diff --git a/src/library_gl.js b/src/library_gl.js index b4098813..0f28a6a0 100644 --- a/src/library_gl.js +++ b/src/library_gl.js @@ -2099,6 +2099,11 @@ var LibraryGL = { }, glColor4f: function(r, g, b, a) { + r = Math.max(Math.min(r, 1), 0); + g = Math.max(Math.min(g, 1), 0); + b = Math.max(Math.min(b, 1), 0); + a = Math.max(Math.min(a, 1), 0); + // TODO: make ub the default, not f, save a few mathops if (GL.immediate.mode) { var start = GL.immediate.vertexCounter << 2; diff --git a/src/library_sdl.js b/src/library_sdl.js index 0969f738..1cd99534 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -898,7 +898,7 @@ var LibrarySDL = { }, SDL_GetError: function() { - return allocate(intArrayFromString("SDL is cool"), 'i8'); + return allocate(intArrayFromString("unknown SDL-emscripten error"), 'i8'); }, SDL_CreateRGBSurface: function(flags, width, height, depth, rmask, gmask, bmask, amask) { @@ -1533,6 +1533,12 @@ var LibrarySDL = { SDL_GL_SwapBuffers: function() {}, + // TODO + + SDL_SetGamma: function(r, g, b) { + return -1; + }, + // Misc SDL_InitSubSystem: function(flags) { return 0 }, diff --git a/src/parseTools.js b/src/parseTools.js index 4a76a9a2..b2093da3 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -1328,7 +1328,27 @@ function makePointer(slab, pos, allocator, type, ptr) { types = de[0]; } } - return 'allocate(' + slab + ', ' + JSON.stringify(types) + (allocator ? ', ' + allocator : '') + (allocator == 'ALLOC_NONE' ? ', ' + ptr : '') + ')'; + // JS engines sometimes say array initializers are too large. Work around that by chunking and calling concat to combine at runtime + var chunkSize = 10240; + function chunkify(array) { + // break very large slabs into parts + var ret = ''; + var index = 0; + while (index < array.length) { + ret = (ret ? ret + '.concat(' : '') + '[' + array.slice(index, index + chunkSize).map(JSON.stringify) + ']' + (ret ? ')' : ''); + index += chunkSize; + } + return ret; + } + if (typeof slab == 'string' && evaled && evaled.length > chunkSize) { + slab = chunkify(evaled); + } + if (typeof types != 'string' && types.length > chunkSize) { + types = chunkify(types); + } else { + types = JSON.stringify(types); + } + return 'allocate(' + slab + ', ' + types + (allocator ? ', ' + allocator : '') + (allocator == 'ALLOC_NONE' ? ', ' + ptr : '') + ')'; } function makeGetSlabs(ptr, type, allowMultiple, unsigned) { diff --git a/src/settings.js b/src/settings.js index 1d8805a8..c4d1df48 100644 --- a/src/settings.js +++ b/src/settings.js @@ -132,6 +132,12 @@ var SAFE_HEAP_LOG = 0; // Log out all SAFE_HEAP operations var LABEL_DEBUG = 0; // 1: Print out functions as we enter them // 2: Also print out each label as we enter it +var LABEL_FUNCTION_FILTERS = []; // Filters for function label debug. + // The items for this array will be used + // as filters for function names. Only the + // labels of functions that is equaled to + // one of the filters are printed out + // When the array is empty, the filter is disabled. var EXCEPTION_DEBUG = 1; // Print out exceptions in emscriptened code var LIBRARY_DEBUG = 0; // Print out when we enter a library call (library*.js). You can also unset @@ -201,9 +207,10 @@ var NAMED_GLOBALS = 1; // If 1, we use global variables for globals. Otherwise var PROFILE = 0; // Enables runtime profiling. See test_profiling for a usage example. var EXPORT_ALL = 0; // If true, we export all the symbols -var EXPORTED_FUNCTIONS = ['_main', '_malloc', '_free']; // Functions that are explicitly exported, so they are guaranteed to - // be accessible outside of the generated code even after running closure compiler. - // Note the necessary prefix of "_". +var EXPORTED_FUNCTIONS = ['_main']; // Functions that are explicitly exported. These functions are kept alive + // through LLVM dead code elimination, and also made accessible outside of + // the generated code even after running closure compiler (on "Module"). + // Note the necessary prefix of "_". var DEFAULT_LIBRARY_FUNCS_TO_INCLUDE = ['memcpy', 'memset', 'malloc', 'free', '$Browser']; // JS library functions (C functions implemented in JS) // that we include by default. If you want to make sure diff --git a/system/include/emscripten/bind.h b/system/include/emscripten/bind.h index 8ce95de7..55fda986 100644 --- a/system/include/emscripten/bind.h +++ b/system/include/emscripten/bind.h @@ -445,6 +445,7 @@ namespace emscripten { args.count, args.types, reinterpret_cast<internal::GenericFunction>(&internal::raw_constructor<ClassType, ConstructorArgs...>)); + return *this; } template<typename ReturnType, typename... Args> @@ -557,6 +558,7 @@ namespace emscripten { } new(get()) T(v); initialized = true; + return *this; } private: diff --git a/system/lib/libcxxabi/CREDITS.TXT b/system/lib/libcxxabi/CREDITS.TXT index a99245f7..231dfd33 100644 --- a/system/lib/libcxxabi/CREDITS.TXT +++ b/system/lib/libcxxabi/CREDITS.TXT @@ -13,10 +13,22 @@ E: hhinnant@apple.com D: Architect and primary coauthor of libc++abi N: Marshall Clow -E: marshall@idio.com E: mclow.lists@gmail.com -E: mclow@qualcomm.com +E: marshall@idio.com D: Architect and primary coauthor of libc++abi N: Nick Kledzik E: kledzik@apple.com + +N: Andrew Morrow +E: andrew.c.morrow@gmail.com +D: Minor patches and fixes + +N: Erik Olofsson +E: erik.olofsson@hansoft.se +E: erik@olofsson.info +D: Minor patches and fixes + +N: Nowar Gu +E: wenhan.gu@gmail.com +D: Minor patches and fixes diff --git a/system/lib/libcxxabi/include/cxxabi.h b/system/lib/libcxxabi/include/cxxabi.h index b08fba0e..66ef6d46 100644 --- a/system/lib/libcxxabi/include/cxxabi.h +++ b/system/lib/libcxxabi/include/cxxabi.h @@ -64,7 +64,7 @@ extern LIBCXXABI_NORETURN void __cxa_pure_virtual(void); extern LIBCXXABI_NORETURN void __cxa_deleted_virtual(void); // 3.3.2 One-time Construction API -#ifdef LIBCXXABI_ARMEABI +#if __arm__ extern int __cxa_guard_acquire(uint32_t*); extern void __cxa_guard_release(uint32_t*); extern void __cxa_guard_abort(uint32_t*); diff --git a/system/lib/libcxxabi/lib/buildit b/system/lib/libcxxabi/lib/buildit index d1d2acda..75a7028a 100755 --- a/system/lib/libcxxabi/lib/buildit +++ b/system/lib/libcxxabi/lib/buildit @@ -27,7 +27,12 @@ then RC_ProjectSourceVersion=1 fi -EXTRA_FLAGS="-std=c++0x -stdlib=libc++ -fstrict-aliasing -Wstrict-aliasing=2 -Wnewline-eof" +EXTRA_FLAGS="-std=c++0x -stdlib=libc++ -fstrict-aliasing -Wstrict-aliasing=2 \ + -Wsign-conversion -Wshadow -Wconversion -Wunused-variable \ + -Wmissing-field-initializers -Wchar-subscripts -Wmismatched-tags \ + -Wmissing-braces -Wshorten-64-to-32 -Wsign-compare \ + -Wstrict-aliasing=2 -Wstrict-overflow=4 -Wunused-parameter \ + -Wnewline-eof" case $TRIPLE in *-apple-*) @@ -48,6 +53,10 @@ case $TRIPLE in -compatibility_version 1 \ -install_name /usr/lib/libc++abi.dylib \ -lSystem" + if [ -f "${SDKROOT}/usr/local/lib/libCrashReporterClient.a" ] + then + LDSHARED_FLAGS+=" -lCrashReporterClient" + fi ;; *-*-mingw*) # FIXME: removing libgcc and libsupc++ dependencies means porting libcxxrt and LLVM/compiler-rt diff --git a/system/lib/libcxxabi/readme.txt b/system/lib/libcxxabi/readme.txt index 0be9a318..fde423c0 100644 --- a/system/lib/libcxxabi/readme.txt +++ b/system/lib/libcxxabi/readme.txt @@ -1 +1 @@ -These files are from libcxxabi, svn revision 151132, Feb 22 2012 +These files are from libcxxabi, svn revision 169402, Dec 10 2012 diff --git a/system/lib/libcxxabi/src/abort_message.cpp b/system/lib/libcxxabi/src/abort_message.cpp index 7beb86b5..3da4ef67 100644 --- a/system/lib/libcxxabi/src/abort_message.cpp +++ b/system/lib/libcxxabi/src/abort_message.cpp @@ -18,16 +18,6 @@ # if defined(__has_include) && __has_include(<CrashReporterClient.h>) # define HAVE_CRASHREPORTERCLIENT_H 1 # include <CrashReporterClient.h> - - // If any clients of llvm try to link to libCrashReporterClient.a themselves, - // only one crash info struct will be used. - extern "C" { - CRASH_REPORTER_CLIENT_HIDDEN - struct crashreporter_annotations_t gCRAnnotations - __attribute__((section("__DATA," CRASHREPORTER_ANNOTATIONS_SECTION))) - = { CRASHREPORTER_ANNOTATIONS_VERSION, 0, 0, 0, 0, 0, 0 }; - } - # endif #endif diff --git a/system/lib/libcxxabi/src/cxa_demangle.cpp b/system/lib/libcxxabi/src/cxa_demangle.cpp index 1135c99b..c1e12603 100644 --- a/system/lib/libcxxabi/src/cxa_demangle.cpp +++ b/system/lib/libcxxabi/src/cxa_demangle.cpp @@ -17,7 +17,6 @@ #include <algorithm> #include <assert.h> - #ifdef DEBUGGING #include <string> @@ -42,8 +41,8 @@ public: size_t __size_; __node* __left_; __node* __right_; - long double __value_; long __cached_size_; + long double __value_; public: __node() : __name_(0), __size_(0), __left_(0), __right_(0), __cached_size_(-1) @@ -64,8 +63,8 @@ public: virtual size_t size() const { if (__cached_size_ == -1) - const_cast<long&>(__cached_size_) = first_size() + second_size(); - return __cached_size_; + const_cast<long&>(__cached_size_) = static_cast<long>(first_size() + second_size()); + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const {return buf;} virtual char* second_demangled_name(char* buf) const {return buf;} @@ -79,7 +78,7 @@ public: return get_demangled_name(buf); } - virtual bool ends_with_template(bool parsing = false) const + virtual bool ends_with_template(bool /*parsing*/ = false) const { return false; } @@ -134,9 +133,15 @@ void display(__node* x, int indent = 0) { for (int i = 0; i < 2*indent; ++i) printf(" "); - std::string buf(x->size(), '\0'); - x->get_demangled_name(&buf.front()); - printf("%s %s, %p\n", typeid(*x).name(), buf.c_str(), x); + size_t sz = x->size(); + char* buf = (char*)calloc(sz+10, 1); + x->get_demangled_name(buf); + printf("%s [%ld] %s, %p\n", typeid(*x).name(), sz, buf, x); + if (strlen(buf) != sz) + { + printf("strlen(buf) = %ld and size = %ld\n", strlen(buf), sz); + } + free(buf); display(x->__left_, indent+1); display(x->__right_, indent+1); } @@ -157,8 +162,8 @@ public: virtual size_t first_size() const { if (__cached_size_ == -1) - const_cast<long&>(__cached_size_) = n + __right_->size(); - return __cached_size_; + const_cast<long&>(__cached_size_) = n + static_cast<long>(__right_->size()); + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -188,8 +193,8 @@ public: virtual size_t first_size() const { if (__cached_size_ == -1) - const_cast<long&>(__cached_size_) = n + __right_->size(); - return __cached_size_; + const_cast<long&>(__cached_size_) = n + static_cast<long>(__right_->size()); + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -220,9 +225,9 @@ public: virtual size_t first_size() const { if (__cached_size_ == -1) - const_cast<long&>(__cached_size_) = n + __left_->size() - + __right_->size(); - return __cached_size_; + const_cast<long&>(__cached_size_) = n + static_cast<long>(__left_->size() + + __right_->size()); + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -260,8 +265,8 @@ public: virtual size_t first_size() const { if (__cached_size_ == -1) - const_cast<long&>(__cached_size_) = n + __right_->size(); - return __cached_size_; + const_cast<long&>(__cached_size_) = n + static_cast<long>(__right_->size()); + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -291,8 +296,8 @@ public: virtual size_t first_size() const { if (__cached_size_ == -1) - const_cast<long&>(__cached_size_) = n + __right_->size(); - return __cached_size_; + const_cast<long&>(__cached_size_) = n + static_cast<long>(__right_->size()); + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -322,8 +327,8 @@ public: virtual size_t first_size() const { if (__cached_size_ == -1) - const_cast<long&>(__cached_size_) = n + __right_->size(); - return __cached_size_; + const_cast<long&>(__cached_size_) = n + static_cast<long>(__right_->size()); + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -353,8 +358,8 @@ public: virtual size_t first_size() const { if (__cached_size_ == -1) - const_cast<long&>(__cached_size_) = n + __right_->size(); - return __cached_size_; + const_cast<long&>(__cached_size_) = static_cast<long>(n + __right_->size()); + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -384,8 +389,8 @@ public: virtual size_t first_size() const { if (__cached_size_ == -1) - const_cast<long&>(__cached_size_) = n + __right_->size(); - return __cached_size_; + const_cast<long&>(__cached_size_) = static_cast<long>(n + __right_->size()); + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -415,8 +420,8 @@ public: virtual size_t first_size() const { if (__cached_size_ == -1) - const_cast<long&>(__cached_size_) = n + __right_->size(); - return __cached_size_; + const_cast<long&>(__cached_size_) = static_cast<long>(n + __right_->size()); + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -442,8 +447,8 @@ public: virtual size_t first_size() const { if (__cached_size_ == -1) - const_cast<long&>(__cached_size_) = n + __right_->size(); - return __cached_size_; + const_cast<long&>(__cached_size_) = static_cast<long>(n + __right_->size()); + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -460,7 +465,7 @@ class __source_name : public __node { public: - __source_name(const char* __name, unsigned __size) + __source_name(const char* __name, size_t __size) { __name_ = __name; __size_ = __size; @@ -473,9 +478,9 @@ public: if (__size_ >= 10 && strncmp(__name_, "_GLOBAL__N", 10) == 0) const_cast<long&>(__cached_size_) = 21; else - const_cast<long&>(__cached_size_) = __size_; + const_cast<long&>(__cached_size_) = static_cast<long>(__size_); } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -553,11 +558,13 @@ public: if (__cached_size_ == -1) { if (__left_) - const_cast<long&>(__cached_size_) = __left_->size() + 8 + __right_->size(); + const_cast<long&>(__cached_size_) = static_cast<long>( + __left_->size() + 8 + + __right_->size()); else const_cast<long&>(__cached_size_) = sizeof("operator&&") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -603,11 +610,11 @@ public: if (__cached_size_ == -1) { if (__left_) - const_cast<long&>(__cached_size_) = 3+__left_->size(); + const_cast<long&>(__cached_size_) = static_cast<long>(3 + __left_->size()); else const_cast<long&>(__cached_size_) = sizeof("operator&") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -649,11 +656,13 @@ public: if (__cached_size_ == -1) { if (__left_) - const_cast<long&>(__cached_size_) = __left_->size() + 7 + __right_->size(); + const_cast<long&>(__cached_size_) = static_cast<long>( + __left_->size() + 7 + + __right_->size()); else const_cast<long&>(__cached_size_) = sizeof("operator&") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -700,11 +709,13 @@ public: if (__cached_size_ == -1) { if (__left_) - const_cast<long&>(__cached_size_) = __left_->size() + 8 + __right_->size(); + const_cast<long&>(__cached_size_) = static_cast<long>( + __left_->size() + 8 + + __right_->size()); else const_cast<long&>(__cached_size_) = sizeof("operator&=") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -751,11 +762,13 @@ public: if (__cached_size_ == -1) { if (__left_) - const_cast<long&>(__cached_size_) = __left_->size() + 7 + __right_->size(); + const_cast<long&>(__cached_size_) = static_cast<long>( + __left_->size() + 7 + + __right_->size()); else const_cast<long&>(__cached_size_) = sizeof("operator=") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -801,11 +814,11 @@ public: if (__cached_size_ == -1) { if (__right_) - const_cast<long&>(__cached_size_) = __right_->size() + 10; + const_cast<long&>(__cached_size_) = static_cast<long>(__right_->size() + 10); else const_cast<long&>(__cached_size_) = sizeof("operator alignof") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -846,11 +859,11 @@ public: if (__cached_size_ == -1) { if (__right_) - const_cast<long&>(__cached_size_) = __right_->size() + 10; + const_cast<long&>(__cached_size_) = static_cast<long>(__right_->size() + 10); else const_cast<long&>(__cached_size_) = sizeof("operator alignof") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -905,11 +918,13 @@ public: if (__cached_size_ == -1) { if (__left_) - const_cast<long&>(__cached_size_) = __left_->size() + 7 + __right_->size(); + const_cast<long&>(__cached_size_) = static_cast<long>( + __left_->size() + 7 + + __right_->size()); else const_cast<long&>(__cached_size_) = sizeof("operator,") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -955,11 +970,11 @@ public: if (__cached_size_ == -1) { if (__left_) - const_cast<long&>(__cached_size_) = 3+__left_->size(); + const_cast<long&>(__cached_size_) = static_cast<long>(3 + __left_->size()); else const_cast<long&>(__cached_size_) = sizeof("operator~") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -1015,9 +1030,9 @@ public: } else off = n + __right_->size();; - const_cast<long&>(__cached_size_) = off; + const_cast<long&>(__cached_size_) = static_cast<long>(off); } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -1061,13 +1076,14 @@ public: { __left_ = type; __name_ = f; - __size_ = l - f; + __size_ = static_cast<size_t>(l - f); } virtual size_t first_size() const { if (__cached_size_ == -1) - const_cast<long&>(__cached_size_) = 2 + __left_->size() + __size_; - return __cached_size_; + const_cast<long&>(__cached_size_) = static_cast<long>(2 + + __left_->size() + __size_); + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -1098,11 +1114,11 @@ public: if (__cached_size_ == -1) { if (__left_) - const_cast<long&>(__cached_size_) = 3+__left_->size(); + const_cast<long&>(__cached_size_) = static_cast<long>(3 + __left_->size()); else const_cast<long&>(__cached_size_) = sizeof("operator*") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -1144,11 +1160,13 @@ public: if (__cached_size_ == -1) { if (__left_) - const_cast<long&>(__cached_size_) = __left_->size() + 7 + __right_->size(); + const_cast<long&>(__cached_size_) = static_cast<long>( + __left_->size() + 7 + + __right_->size()); else const_cast<long&>(__cached_size_) = sizeof("operator/") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -1195,11 +1213,13 @@ public: if (__cached_size_ == -1) { if (__left_) - const_cast<long&>(__cached_size_) = __left_->size() + 8 + __right_->size(); + const_cast<long&>(__cached_size_) = static_cast<long>( + __left_->size() + 8 + + __right_->size()); else const_cast<long&>(__cached_size_) = sizeof("operator/=") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -1246,11 +1266,13 @@ public: if (__cached_size_ == -1) { if (__left_) - const_cast<long&>(__cached_size_) = __left_->size() + 7 + __right_->size(); + const_cast<long&>(__cached_size_) = static_cast<long>( + __left_->size() + 7 + + __right_->size()); else const_cast<long&>(__cached_size_) = sizeof("operator^") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -1297,11 +1319,13 @@ public: if (__cached_size_ == -1) { if (__left_) - const_cast<long&>(__cached_size_) = __left_->size() + 8 + __right_->size(); + const_cast<long&>(__cached_size_) = static_cast<long>( + __left_->size() + 8 + + __right_->size()); else const_cast<long&>(__cached_size_) = sizeof("operator^=") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -1348,11 +1372,13 @@ public: if (__cached_size_ == -1) { if (__left_) - const_cast<long&>(__cached_size_) = __left_->size() + 8 + __right_->size(); + const_cast<long&>(__cached_size_) = static_cast<long>( + __left_->size() + 8 + + __right_->size()); else const_cast<long&>(__cached_size_) = sizeof("operator==") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -1399,11 +1425,13 @@ public: if (__cached_size_ == -1) { if (__left_) - const_cast<long&>(__cached_size_) = __left_->size() + 8 + __right_->size(); + const_cast<long&>(__cached_size_) = static_cast<long>( + __left_->size() + 8 + + __right_->size()); else const_cast<long&>(__cached_size_) = sizeof("operator>=") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -1450,11 +1478,13 @@ public: if (__cached_size_ == -1) { if (__left_) - const_cast<long&>(__cached_size_) = __left_->size() + 9 + __right_->size(); + const_cast<long&>(__cached_size_) = static_cast<long>( + __left_->size() + 9 + + __right_->size()); else const_cast<long&>(__cached_size_) = sizeof("operator>") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -1516,11 +1546,13 @@ public: if (__cached_size_ == -1) { if (__left_) - const_cast<long&>(__cached_size_) = __left_->size() + 8 + __right_->size(); + const_cast<long&>(__cached_size_) = static_cast<long>( + __left_->size() + 8 + + __right_->size()); else const_cast<long&>(__cached_size_) = sizeof("operator<=") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -1567,11 +1599,13 @@ public: if (__cached_size_ == -1) { if (__left_) - const_cast<long&>(__cached_size_) = __left_->size() + 7 + __right_->size(); + const_cast<long&>(__cached_size_) = static_cast<long>( + __left_->size() + 7 + + __right_->size()); else const_cast<long&>(__cached_size_) = sizeof("operator<") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -1618,11 +1652,13 @@ public: if (__cached_size_ == -1) { if (__left_) - const_cast<long&>(__cached_size_) = __left_->size() + 8 + __right_->size(); + const_cast<long&>(__cached_size_) = static_cast<long>( + __left_->size() + 8 + + __right_->size()); else const_cast<long&>(__cached_size_) = sizeof("operator<<") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -1669,11 +1705,13 @@ public: if (__cached_size_ == -1) { if (__left_) - const_cast<long&>(__cached_size_) = __left_->size() + 9 + __right_->size(); + const_cast<long&>(__cached_size_) = static_cast<long>( + __left_->size() + 9 + + __right_->size()); else const_cast<long&>(__cached_size_) = sizeof("operator<<=") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -1720,11 +1758,13 @@ public: if (__cached_size_ == -1) { if (__left_) - const_cast<long&>(__cached_size_) = __left_->size() + 7 + __right_->size(); + const_cast<long&>(__cached_size_) = static_cast<long>( + __left_->size() + 7 + + __right_->size()); else const_cast<long&>(__cached_size_) = sizeof("operator-") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -1771,11 +1811,13 @@ public: if (__cached_size_ == -1) { if (__left_) - const_cast<long&>(__cached_size_) = __left_->size() + 8 + __right_->size(); + const_cast<long&>(__cached_size_) = static_cast<long>( + __left_->size() + 8 + + __right_->size()); else const_cast<long&>(__cached_size_) = sizeof("operator-=") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -1822,11 +1864,13 @@ public: if (__cached_size_ == -1) { if (__left_) - const_cast<long&>(__cached_size_) = __left_->size() + 7 + __right_->size(); + const_cast<long&>(__cached_size_) = static_cast<long>( + __left_->size() + 7 + + __right_->size()); else const_cast<long&>(__cached_size_) = sizeof("operator*") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -1873,11 +1917,13 @@ public: if (__cached_size_ == -1) { if (__left_) - const_cast<long&>(__cached_size_) = __left_->size() + 8 + __right_->size(); + const_cast<long&>(__cached_size_) = static_cast<long>( + __left_->size() + 8 + + __right_->size()); else const_cast<long&>(__cached_size_) = sizeof("operator*=") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -1924,11 +1970,11 @@ public: if (__cached_size_ == -1) { if (__left_) - const_cast<long&>(__cached_size_) = 4+__left_->size(); + const_cast<long&>(__cached_size_) = static_cast<long>(4 + __left_->size()); else const_cast<long&>(__cached_size_) = sizeof("operator--") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -1983,11 +2029,13 @@ public: if (__cached_size_ == -1) { if (__left_) - const_cast<long&>(__cached_size_) = __left_->size() + 8 + __right_->size(); + const_cast<long&>(__cached_size_) = static_cast<long>( + __left_->size() + 8 + + __right_->size()); else const_cast<long&>(__cached_size_) = sizeof("operator!=") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -2033,11 +2081,11 @@ public: if (__cached_size_ == -1) { if (__left_) - const_cast<long&>(__cached_size_) = 3+__left_->size(); + const_cast<long&>(__cached_size_) = static_cast<long>(3 + __left_->size()); else const_cast<long&>(__cached_size_) = sizeof("operator-") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -2078,11 +2126,11 @@ public: if (__cached_size_ == -1) { if (__left_) - const_cast<long&>(__cached_size_) = 3+__left_->size(); + const_cast<long&>(__cached_size_) = static_cast<long>(3 + __left_->size()); else const_cast<long&>(__cached_size_) = sizeof("operator!") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -2124,11 +2172,13 @@ public: if (__cached_size_ == -1) { if (__left_) - const_cast<long&>(__cached_size_) = __left_->size() + 8 + __right_->size(); + const_cast<long&>(__cached_size_) = static_cast<long>( + __left_->size() + 8 + + __right_->size()); else const_cast<long&>(__cached_size_) = sizeof("operator||") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -2175,11 +2225,13 @@ public: if (__cached_size_ == -1) { if (__left_) - const_cast<long&>(__cached_size_) = __left_->size() + 7 + __right_->size(); + const_cast<long&>(__cached_size_) = static_cast<long>( + __left_->size() + 7 + + __right_->size()); else const_cast<long&>(__cached_size_) = sizeof("operator|") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -2226,11 +2278,13 @@ public: if (__cached_size_ == -1) { if (__left_) - const_cast<long&>(__cached_size_) = __left_->size() + 8 + __right_->size(); + const_cast<long&>(__cached_size_) = static_cast<long>( + __left_->size() + 8 + + __right_->size()); else const_cast<long&>(__cached_size_) = sizeof("operator|=") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -2277,11 +2331,13 @@ public: if (__cached_size_ == -1) { if (__left_) - const_cast<long&>(__cached_size_) = __left_->size() + 9 + __right_->size(); + const_cast<long&>(__cached_size_) = static_cast<long>( + __left_->size() + 9 + + __right_->size()); else const_cast<long&>(__cached_size_) = sizeof("operator->*") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -2328,11 +2384,13 @@ public: if (__cached_size_ == -1) { if (__left_) - const_cast<long&>(__cached_size_) = __left_->size() + 7 + __right_->size(); + const_cast<long&>(__cached_size_) = static_cast<long>( + __left_->size() + 7 + + __right_->size()); else const_cast<long&>(__cached_size_) = sizeof("operator+") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -2379,11 +2437,13 @@ public: if (__cached_size_ == -1) { if (__left_) - const_cast<long&>(__cached_size_) = __left_->size() + 8 + __right_->size(); + const_cast<long&>(__cached_size_) = static_cast<long>( + __left_->size() + 8 + + __right_->size()); else const_cast<long&>(__cached_size_) = sizeof("operator+=") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -2430,11 +2490,11 @@ public: if (__cached_size_ == -1) { if (__left_) - const_cast<long&>(__cached_size_) = 4+__left_->size(); + const_cast<long&>(__cached_size_) = static_cast<long>(4 + __left_->size()); else const_cast<long&>(__cached_size_) = sizeof("operator++") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -2488,11 +2548,11 @@ public: if (__cached_size_ == -1) { if (__left_) - const_cast<long&>(__cached_size_) = 3+__left_->size(); + const_cast<long&>(__cached_size_) = static_cast<long>(3 + __left_->size()); else const_cast<long&>(__cached_size_) = sizeof("operator+") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -2534,11 +2594,13 @@ public: if (__cached_size_ == -1) { if (__left_) - const_cast<long&>(__cached_size_) = __left_->size() + 8 + __right_->size(); + const_cast<long&>(__cached_size_) = static_cast<long>( + __left_->size() + 8 + + __right_->size()); else const_cast<long&>(__cached_size_) = sizeof("operator->") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -2588,12 +2650,15 @@ public: if (__left_) { __node* op1 = (__node*)__name_; - const_cast<long&>(__cached_size_) = op1->size() + __left_->size() + 12 + __right_->size(); + const_cast<long&>(__cached_size_) = static_cast<long>( + op1->size() + + __left_->size() + 12 + + __right_->size()); } else const_cast<long&>(__cached_size_) = sizeof("operator?") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -2646,11 +2711,13 @@ public: if (__cached_size_ == -1) { if (__left_) - const_cast<long&>(__cached_size_) = __left_->size() + 7 + __right_->size(); + const_cast<long&>(__cached_size_) = static_cast<long>( + __left_->size() + 7 + + __right_->size()); else const_cast<long&>(__cached_size_) = sizeof("operator%") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -2697,11 +2764,13 @@ public: if (__cached_size_ == -1) { if (__left_) - const_cast<long&>(__cached_size_) = __left_->size() + 8 + __right_->size(); + const_cast<long&>(__cached_size_) = static_cast<long>( + __left_->size() + 8 + + __right_->size()); else const_cast<long&>(__cached_size_) = sizeof("operator%=") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -2748,11 +2817,13 @@ public: if (__cached_size_ == -1) { if (__left_) - const_cast<long&>(__cached_size_) = __left_->size() + 8 + __right_->size(); + const_cast<long&>(__cached_size_) = static_cast<long>( + __left_->size() + 8 + + __right_->size()); else const_cast<long&>(__cached_size_) = sizeof("operator>>") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -2799,11 +2870,13 @@ public: if (__cached_size_ == -1) { if (__left_) - const_cast<long&>(__cached_size_) = __left_->size() + 9 + __right_->size(); + const_cast<long&>(__cached_size_) = static_cast<long>( + __left_->size() + 9 + + __right_->size()); else const_cast<long&>(__cached_size_) = sizeof("operator>>=") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -2849,11 +2922,11 @@ public: if (__cached_size_ == -1) { if (__right_) - const_cast<long&>(__cached_size_) = __right_->size() + 9; + const_cast<long&>(__cached_size_) = static_cast<long>(__right_->size() + 9); else const_cast<long&>(__cached_size_) = sizeof("operator sizeof") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -2894,11 +2967,11 @@ public: if (__cached_size_ == -1) { if (__right_) - const_cast<long&>(__cached_size_) = __right_->size() + 9; + const_cast<long&>(__cached_size_) = static_cast<long>(__right_->size() + 9); else const_cast<long&>(__cached_size_) = sizeof("operator sizeof") - 1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -2936,8 +3009,8 @@ public: virtual size_t first_size() const { if (__cached_size_ == -1) - const_cast<long&>(__cached_size_) = __right_->size() + 8; - return __cached_size_; + const_cast<long&>(__cached_size_) = static_cast<long>(__right_->size() + 8); + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -2965,8 +3038,8 @@ public: virtual size_t first_size() const { if (__cached_size_ == -1) - const_cast<long&>(__cached_size_) = __right_->size() + 6; - return __cached_size_; + const_cast<long&>(__cached_size_) = static_cast<long>(__right_->size() + 6); + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -3005,8 +3078,8 @@ public: virtual size_t first_size() const { if (__cached_size_ == -1) - const_cast<long&>(__cached_size_) = __right_->size() + 11; - return __cached_size_; + const_cast<long&>(__cached_size_) = static_cast<long>(__right_->size() + 11); + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -3035,8 +3108,9 @@ public: virtual size_t first_size() const { if (__cached_size_ == -1) - const_cast<long&>(__cached_size_) = __left_->size() + 14 + __right_->size(); - return __cached_size_; + const_cast<long&>(__cached_size_) = static_cast<long>(__left_->size() + + 14 + __right_->size()); + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -3069,8 +3143,9 @@ public: virtual size_t first_size() const { if (__cached_size_ == -1) - const_cast<long&>(__cached_size_) = __left_->size() + 16 + __right_->size(); - return __cached_size_; + const_cast<long&>(__cached_size_) = static_cast<long>(__left_->size() + + 16 + __right_->size()); + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -3103,8 +3178,9 @@ public: virtual size_t first_size() const { if (__cached_size_ == -1) - const_cast<long&>(__cached_size_) = __left_->size() + 20 + __right_->size(); - return __cached_size_; + const_cast<long&>(__cached_size_) = static_cast<long>(__left_->size() + + 20 + __right_->size()); + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -3137,8 +3213,9 @@ public: virtual size_t first_size() const { if (__cached_size_ == -1) - const_cast<long&>(__cached_size_) = __left_->size() + 15 + __right_->size(); - return __cached_size_; + const_cast<long&>(__cached_size_) = static_cast<long>(__left_->size() + + 15 + __right_->size()); + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -3175,9 +3252,9 @@ public: size_t off = __left_->size() + 2; if (__right_) off += __right_->size(); - const_cast<long&>(__cached_size_) = off; + const_cast<long&>(__cached_size_) = static_cast<long>(off); } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -3210,8 +3287,9 @@ public: virtual size_t first_size() const { if (__cached_size_ == -1) - const_cast<long&>(__cached_size_) = (__size_ ? 2 : 0) + 9 + __right_->size(); - return __cached_size_; + const_cast<long&>(__cached_size_) = static_cast<long>((__size_ ? 2 : 0) + + 9 + __right_->size()); + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -3242,8 +3320,9 @@ public: virtual size_t first_size() const { if (__cached_size_ == -1) - const_cast<long&>(__cached_size_) = (__size_ ? 2 : 0) + 7 + __right_->size(); - return __cached_size_; + const_cast<long&>(__cached_size_) = static_cast<long>((__size_ ? 2 : 0) + + 7 + __right_->size()); + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -3298,9 +3377,9 @@ public: if (__right_) off += __right_->size(); } - const_cast<long&>(__cached_size_) = off; + const_cast<long&>(__cached_size_) = static_cast<long>(off); } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -3360,8 +3439,9 @@ public: virtual size_t first_size() const { if (__cached_size_ == -1) - const_cast<long&>(__cached_size_) = __left_->size() + 2 + __right_->size(); - return __cached_size_; + const_cast<long&>(__cached_size_) = static_cast<long>(__left_->size() + + 2 + __right_->size()); + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -3390,8 +3470,9 @@ public: virtual size_t first_size() const { if (__cached_size_ == -1) - const_cast<long&>(__cached_size_) = __left_->size() + 1 + __right_->size(); - return __cached_size_; + const_cast<long&>(__cached_size_) = static_cast<long>(__left_->size() + + 1 + __right_->size()); + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -3419,8 +3500,9 @@ public: virtual size_t first_size() const { if (__cached_size_ == -1) - const_cast<long&>(__cached_size_) = __left_->size() + 2 + __right_->size(); - return __cached_size_; + const_cast<long&>(__cached_size_) = static_cast<long>(__left_->size() + + 2 + __right_->size()); + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -3623,6 +3705,8 @@ public: } virtual bool is_function() const { + if (__left_ == 0) + return false; return __left_->is_function(); } virtual bool is_cv_qualifer() const @@ -3641,7 +3725,7 @@ public: { if (__left_ == 0) { - if (__size_ < t_end - t_begin) + if (__size_ < static_cast<size_t>(t_end - t_begin)) { __left_ = t_begin[__size_]; __size_ = 0; @@ -3671,8 +3755,9 @@ public: virtual size_t first_size() const { if (__cached_size_ == -1) - const_cast<long&>(__cached_size_) = __left_->size() + __right_->size(); - return __cached_size_; + const_cast<long&>(__cached_size_) = static_cast<long>(__left_->size() + + __right_->size()); + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -3711,16 +3796,16 @@ public: if (__left_ == NULL) const_cast<long&>(__cached_size_) = 0; else if (__right_ == NULL) - const_cast<long&>(__cached_size_) = __left_->size(); + const_cast<long&>(__cached_size_) = static_cast<long>(__left_->size()); else { size_t off = __right_->size(); if (off > 0) off += 2; - const_cast<long&>(__cached_size_) = __left_->size() + off; + const_cast<long&>(__cached_size_) = static_cast<long>(__left_->size() + off); } } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -3742,10 +3827,14 @@ public: } virtual bool ends_with_template(bool parsing = false) const { - if (__right_ != NULL) + if (__right_ && __right_->size() > 0) + { return __right_->ends_with_template(parsing); - if (__left_ != NULL) + } + else if (__left_ && __left_->size() > 0) + { return __left_->ends_with_template(parsing); + } return false; } virtual bool fix_forward_references(__node** t_begin, __node** t_end) @@ -3788,9 +3877,9 @@ public: ++off; off += __right_->size(); } - const_cast<long&>(__cached_size_) = __left_->size() + off; + const_cast<long&>(__cached_size_) = static_cast<long>(__left_->size() + off); } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -3805,7 +3894,7 @@ public: *buf++ = '>'; return buf; } - virtual bool ends_with_template(bool parsing = false) const + virtual bool ends_with_template(bool /*parsing*/ = false) const { return true; } @@ -3836,8 +3925,8 @@ public: virtual size_t first_size() const { if (__cached_size_ == -1) - const_cast<long&>(__cached_size_) = 2 + __right_->size(); - return __cached_size_; + const_cast<long&>(__cached_size_) = static_cast<long>(2 + __right_->size()); + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -3852,6 +3941,91 @@ public: } }; +class ___lambda_node + : public __node +{ +public: + ___lambda_node(__node* params, const char *number, size_t number_size) + { + __right_ = params; + __name_ = number; + __size_ = number_size; + } + + virtual size_t first_size() const + { + if (__cached_size_ == -1) + { + size_t r = 2; + r += sizeof("'lambda'")-1; + if (__right_) + r += __right_->size(); + r += __size_; + const_cast<long&>(__cached_size_) = static_cast<long>(r); + } + return static_cast<size_t>(__cached_size_); + } + virtual char* first_demangled_name(char* buf) const + { + size_t n = sizeof("'lambda") - 1; + strncpy(buf, "'lambda", n); + buf += n; + if (__size_) + { + strncpy(buf, __name_, __size_); + buf += __size_; + } + *buf++ = '\''; + *buf++ = '('; + if (__right_) + buf = __right_->get_demangled_name(buf); + *buf++ = ')'; + return buf; + } + virtual bool fix_forward_references(__node** t_begin, __node** t_end) + { + if (__right_) + return __right_->fix_forward_references(t_begin, t_end); + return true; + } +}; + +class __unnamed + : public __node +{ +public: + __unnamed(const char *number, size_t number_size) + { + __name_ = number; + __size_ = number_size; + } + + virtual size_t first_size() const + { + if (__cached_size_ == -1) + { + size_t r = 0; + r += sizeof("'unnamed'")-1; + r += __size_; + const_cast<long&>(__cached_size_) = static_cast<long>(r); + } + return static_cast<size_t>(__cached_size_); + } + virtual char* first_demangled_name(char* buf) const + { + size_t n = sizeof("'unnamed") - 1; + strncpy(buf, "'unnamed", n); + buf += n; + if (__size_) + { + strncpy(buf, __name_, __size_); + buf += __size_; + } + *buf++ = '\''; + return buf; + } +}; + class __cv_qualifiers : public __node { @@ -4229,9 +4403,9 @@ public: off += 2; off += __right_->first_size(); } - const_cast<long&>(__cached_size_) = off; + const_cast<long&>(__cached_size_) = static_cast<long>(off); } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual bool is_function() const @@ -4478,8 +4652,8 @@ public: virtual size_t first_size() const { if (__cached_size_ == -1) - const_cast<long&>(__cached_size_) = n + __left_->size(); - return __cached_size_; + const_cast<long&>(__cached_size_) = static_cast<long>(n + __left_->size()); + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -4506,8 +4680,8 @@ public: virtual size_t first_size() const { if (__cached_size_ == -1) - const_cast<long&>(__cached_size_) = n + __left_->size(); - return __cached_size_; + const_cast<long&>(__cached_size_) = static_cast<long>(n + __left_->size()); + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -4563,9 +4737,9 @@ public: bottom->__left_ = sub; } } - const_cast<long&>(__cached_size_) = off; + const_cast<long&>(__cached_size_) = static_cast<long>(off); } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -4643,7 +4817,7 @@ public: explicit __wchar_t_literal(const char* __first, const char* __last) { __name_ = __first; - __size_ = __last - __first; + __size_ = static_cast<size_t>(__last - __first); } virtual size_t first_size() const @@ -4715,7 +4889,7 @@ public: explicit __char_literal(const char* __first, const char* __last) { __name_ = __first; - __size_ = __last - __first; + __size_ = static_cast<size_t>(__last - __first); } virtual size_t first_size() const @@ -4762,7 +4936,7 @@ public: explicit __signed_char_literal(const char* __first, const char* __last) { __name_ = __first; - __size_ = __last - __first; + __size_ = static_cast<size_t>(__last - __first); } virtual size_t first_size() const @@ -4809,7 +4983,7 @@ public: explicit __unsigned_char_literal(const char* __first, const char* __last) { __name_ = __first; - __size_ = __last - __first; + __size_ = static_cast<size_t>(__last - __first); } virtual size_t first_size() const @@ -4846,7 +5020,7 @@ public: explicit __short_literal(const char* __first, const char* __last) { __name_ = __first; - __size_ = __last - __first; + __size_ = static_cast<size_t>(__last - __first); } virtual size_t first_size() const @@ -4893,7 +5067,7 @@ public: explicit __unsigned_short_literal(const char* __first, const char* __last) { __name_ = __first; - __size_ = __last - __first; + __size_ = static_cast<size_t>(__last - __first); } virtual size_t first_size() const @@ -4932,7 +5106,7 @@ public: explicit __int_literal(const char* __first, const char* __last) { __name_ = __first; - __size_ = __last - __first; + __size_ = static_cast<size_t>(__last - __first); } virtual size_t first_size() const @@ -4977,7 +5151,7 @@ public: explicit __unsigned_int_literal(const char* __first, const char* __last) { __name_ = __first; - __size_ = __last - __first; + __size_ = static_cast<size_t>(__last - __first); } virtual size_t first_size() const @@ -5014,7 +5188,7 @@ public: explicit __long_literal(const char* __first, const char* __last) { __name_ = __first; - __size_ = __last - __first; + __size_ = static_cast<size_t>(__last - __first); } virtual size_t first_size() const @@ -5060,7 +5234,7 @@ public: explicit __unsigned_long_literal(const char* __first, const char* __last) { __name_ = __first; - __size_ = __last - __first; + __size_ = static_cast<size_t>(__last - __first); } virtual size_t first_size() const @@ -5098,7 +5272,7 @@ public: explicit __long_long_literal(const char* __first, const char* __last) { __name_ = __first; - __size_ = __last - __first; + __size_ = static_cast<size_t>(__last - __first); } virtual size_t first_size() const @@ -5145,7 +5319,7 @@ public: explicit __unsigned_long_long_literal(const char* __first, const char* __last) { __name_ = __first; - __size_ = __last - __first; + __size_ = static_cast<size_t>(__last - __first); } virtual size_t first_size() const @@ -5163,7 +5337,7 @@ public: } }; -class __int128 +class __signed_int128 : public __node { static const size_t n = sizeof("__int128") - 1; @@ -5184,7 +5358,7 @@ public: explicit __int128_literal(const char* __first, const char* __last) { __name_ = __first; - __size_ = __last - __first; + __size_ = static_cast<size_t>(__last - __first); } virtual size_t first_size() const @@ -5231,7 +5405,7 @@ public: explicit __unsigned_int128_literal(const char* __first, const char* __last) { __name_ = __first; - __size_ = __last - __first; + __size_ = static_cast<size_t>(__last - __first); } virtual size_t first_size() const @@ -5264,14 +5438,14 @@ public: float v = static_cast<float>(__value_); const_cast<long&>(__cached_size_) = sprintf(num, "%a", v)+1; } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { char num[20] = {0}; float v = static_cast<float>(__value_); int n = sprintf(num, "%a", v); - strncpy(buf, num, n); + strncpy(buf, num, static_cast<size_t>(n)); buf += n; *buf++ = 'f'; return buf; @@ -5309,14 +5483,14 @@ public: double v = static_cast<double>(__value_); const_cast<long&>(__cached_size_) = sprintf(num, "%a", v); } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { char num[30] = {0}; double v = static_cast<double>(__value_); int n = sprintf(num, "%a", v); - strncpy(buf, num, n); + strncpy(buf, num, static_cast<size_t>(n)); return buf + n; } }; @@ -5521,10 +5695,10 @@ public: if (__right_ != 0) r += __right_->size(); else if (__size_ != 0) - r += snprintf(0, 0, "%ld", __size_); - const_cast<long&>(__cached_size_) = r; + r += static_cast<size_t>(snprintf(0, 0, "%ld", __size_)); + const_cast<long&>(__cached_size_) = static_cast<long>(r); } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* get_demangled_name(char* buf) const @@ -5536,7 +5710,7 @@ public: buf = __right_->get_demangled_name(buf); else if (__size_ != 0) { - size_t rs = sprintf(buf, "%ld", __size_); + int rs = sprintf(buf, "%ld", __size_); buf += rs; } *buf++ = ']'; @@ -5561,7 +5735,7 @@ public: if (__right_ != 0) r += __right_->size(); else if (__size_ != 0) - r += snprintf(0, 0, "%ld", __size_); + r += static_cast<size_t>(snprintf(0, 0, "%ld", __size_)); return r; } @@ -5573,7 +5747,7 @@ public: buf = __right_->get_demangled_name(buf); else if (__size_ != 0) { - size_t off = sprintf(buf, "%ld", __size_); + int off = sprintf(buf, "%ld", __size_); buf += off; } char* t = buf; @@ -5610,10 +5784,10 @@ public: virtual size_t first_size() const { if (__cached_size_ == -1) - const_cast<long&>(__cached_size_) = __left_->size() + 3 - + __right_->first_size() - + __right_->second_size(); - return __cached_size_; + const_cast<long&>(__cached_size_) = static_cast<long>(__left_->size() + 3 + + __right_->first_size() + + __right_->second_size()); + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -5652,8 +5826,8 @@ public: virtual size_t first_size() const { if (__cached_size_ == -1) - const_cast<long&>(__cached_size_) = 10 + __right_->size(); - return __cached_size_; + const_cast<long&>(__cached_size_) = static_cast<long>(10 + __right_->size()); + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const @@ -5684,8 +5858,9 @@ public: virtual size_t first_size() const { if (__cached_size_ == -1) - const_cast<long&>(__cached_size_) = __left_->size() + __right_->size() + 2; - return __cached_size_; + const_cast<long&>(__cached_size_) = static_cast<long>(__left_->size() + + __right_->size() + 2); + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const @@ -5713,7 +5888,7 @@ public: return __left_->fix_forward_references(t_begin, t_end) && __right_->fix_forward_references(t_begin, t_end); } - virtual __node* extract_cv(__node*& rt) const + virtual __node* extract_cv(__node*&) const { return __right_->extract_cv(const_cast<__node*&>(__right_)); } @@ -5740,9 +5915,10 @@ public: virtual size_t first_size() const { if (__cached_size_ == -1) - const_cast<long&>(__cached_size_) = (__left_ ? __left_->size() + 2 : 0) + - __right_->size() + __size_ * 2; - return __cached_size_; + const_cast<long&>(__cached_size_) = static_cast<long>((__left_ ? + __left_->size() + 2 : 0) + + __right_->size() + __size_ * 2); + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const @@ -5780,7 +5956,7 @@ public: r = __left_->fix_forward_references(t_begin, t_end); return r && __right_->fix_forward_references(t_begin, t_end); } - virtual __node* extract_cv(__node*& rt) const + virtual __node* extract_cv(__node*&) const { return __right_->extract_cv(const_cast<__node*&>(__right_)); } @@ -5816,8 +5992,8 @@ public: virtual size_t first_size() const { if (__cached_size_ == -1) - const_cast<long&>(__cached_size_) = __right_->base_size(); - return __cached_size_; + const_cast<long&>(__cached_size_) = static_cast<long>(__right_->base_size()); + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const @@ -5855,8 +6031,8 @@ public: virtual size_t first_size() const { if (__cached_size_ == -1) - const_cast<long&>(__cached_size_) = __right_->base_size() + 1; - return __cached_size_; + const_cast<long&>(__cached_size_) = static_cast<long>(__right_->base_size() + 1); + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const @@ -5882,7 +6058,7 @@ class __dot_suffix : public __node { public: - __dot_suffix(__node* name, const char* suffix, unsigned sz) + __dot_suffix(__node* name, const char* suffix, size_t sz) { __left_ = name; __name_ = suffix; @@ -5895,9 +6071,9 @@ public: { size_t off = __left_->size(); off += __size_ + 3; - const_cast<long&>(__cached_size_) = off; + const_cast<long&>(__cached_size_) = static_cast<long>(off); } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -5948,9 +6124,9 @@ public: off += __right_->size(); else if (__size_ > 0) off += __size_; - const_cast<long&>(__cached_size_) = off; + const_cast<long&>(__cached_size_) = static_cast<long>(off); } - return __cached_size_; + return static_cast<size_t>(__cached_size_); } virtual char* first_demangled_name(char* buf) const { @@ -6364,7 +6540,7 @@ __demangle_tree::__parse_builtin_type(const char* first, const char* last) ++first; break; case 'n': - if (__make<__int128>()) + if (__make<__signed_int128>()) ++first; break; case 'o': @@ -6444,6 +6620,7 @@ __demangle_tree::__parse_bare_function_type(const char* first, const char* last) { if (first != last) { + bool prev_tag_templates = __tag_templates_; __tag_templates_ = false; const char* t = __parse_type(first, last); if (t != first && __make<__list>(__root_)) @@ -6474,7 +6651,7 @@ __demangle_tree::__parse_bare_function_type(const char* first, const char* last) } } } - __tag_templates_ = true; + __tag_templates_ = prev_tag_templates; } return first; } @@ -6527,11 +6704,11 @@ __demangle_tree::__parse_hex_number(const char* first, const char* last, unsigne if (t == first) n = 0; if (isdigit(*t)) - n = n * 16 + *t - '0'; + n = n * 16 + static_cast<unsigned long long>(*t - '0'); else if (isupper(*t)) - n = n * 16 + *t - 'A' + 10; + n = n * 16 + static_cast<unsigned long long>(*t - 'A') + 10; else - n = n * 16 + *t - 'a' + 10; + n = n * 16 + static_cast<unsigned long long>(*t - 'a') + 10; } first = t; return first; @@ -6567,11 +6744,11 @@ __demangle_tree::__parse_expr_primary(const char* first, const char* last) switch (first[2]) { case '0': - if (__make<__bool_literal>("false", 5)) + if (__make<__bool_literal>("false", 5u)) first += 4; break; case '1': - if (__make<__bool_literal>("true", 4)) + if (__make<__bool_literal>("true", 4u)) first += 4; break; } @@ -6746,6 +6923,10 @@ __demangle_tree::__parse_expr_primary(const char* first, const char* last) first = t+1; } break; + case 'T': + // Invalid mangled name per + // http://sourcerytools.com/pipermail/cxx-abi-dev/2011-August/002422.html + break; default: { // might be named type @@ -6792,12 +6973,67 @@ __demangle_tree::__parse_unnamed_type_name(const char* first, const char* last) { if (last - first > 2 && first[0] == 'U') { - switch (first[1]) + char type = first[1]; + switch (type) { case 't': case 'l': - first += 2; - __status_ = not_yet_implemented; + { + const char* t = first + 2; + __node* params = 0; + if (type == 'l') + { + if (*t == 'v') + { + // void lambda + ++t; + if (t != last && *t == 'E') + ++t; + else + return first; + } + else + { + const char* t1 = __parse_type(t, last); + if (t1 == t || !__make<__list>(__root_)) + return first; + params = __root_; + __node* prev = params; + t = t1; + while (true) + { + t1 = __parse_type(t, last); + if (t1 == t) + break; + if (!__make<__list>(__root_)) + return first; + t = t1; + prev->__right_ = __root_; + __root_->__size_ = prev->__size_ + 1; + prev = __root_; + } + if (t == last || *t != 'E') + return first; + ++t; + } + } + const char* number_start = t; + const char* number_end = __parse_number(t, last); + if (number_end == last || *number_end != '_') + return first; + t = number_end + 1; + if (type == 'l') + { + if (!__make<___lambda_node>(params, number_start, static_cast<size_t>(number_end - number_start))) + return first; + } + else + { + if (!__make<__unnamed>(number_start, static_cast<size_t>(number_end - number_start))) + return first; + } + first = t; + } break; } } @@ -6814,7 +7050,7 @@ __demangle_tree::__parse_unnamed_type_name(const char* first, const char* last) const char* __demangle_tree::__parse_ctor_dtor_name(const char* first, const char* last) { - if (last-first >= 2) + if (last-first >= 2 && __root_) { switch (first[0]) { @@ -6846,7 +7082,7 @@ __demangle_tree::__parse_ctor_dtor_name(const char* first, const char* last) } const char* -__demangle_tree::__parse_unscoped_template_name(const char* first, const char* last) +__demangle_tree::__parse_unscoped_template_name(const char* first, const char*) { // assert(!"__parse_unscoped_template_name not implemented"); __status_ = not_yet_implemented; @@ -7943,10 +8179,10 @@ __demangle_tree::__parse_array_type(const char* first, const char* last) } else if ('1' <= first[1] && first[1] <= '9') { - size_t dim = first[1] - '0'; + size_t dim = static_cast<size_t>(first[1] - '0'); const char* t = first+2; for (; t != last && isdigit(*t); ++t) - dim = dim * 10 + *t - '0'; + dim = dim * 10 + static_cast<size_t>(*t - '0'); if (t != last && *t == '_') { const char* t2 = __parse_type(t+1, last); @@ -8060,16 +8296,16 @@ __demangle_tree::__parse_template_param(const char* first, const char* last) else if (isdigit(first[1])) { const char* t = first+1; - size_t sub = *t - '0'; + size_t sub = static_cast<size_t>(*t - '0'); for (++t; t != last && isdigit(*t); ++t) { sub *= 10; - sub += *t - '0'; + sub += static_cast<size_t>(*t - '0'); } if (t == last || *t != '_') return first; ++sub; - if (sub < __t_end_ - __t_begin_) + if (sub < static_cast<size_t>(__t_end_ - __t_begin_)) { if (__make<__sub>(__t_begin_[sub])) first = t+1; @@ -8109,7 +8345,7 @@ __demangle_tree::__parse_vector_type(const char* first, const char* last) return first; } const char* num = first + 2; - size_t sz = t - num; + size_t sz = static_cast<size_t>(t - num); if (++t != last) { if (*t != 'p') @@ -8986,7 +9222,7 @@ __demangle_tree::__parse_operator_name(const char* first, const char* last, int* case 'v': // cast <type> { - const char* t = __parse_type(first+2, last, false); + const char* t = __parse_type(first+2, last, false, true); if (t != first+2) { __node* cast_type = __root_; @@ -9991,14 +10227,14 @@ __demangle_tree::__parse_source_name(const char* first, const char* last) if ('1' <= c && c <= '9' && first+1 != last) { const char* t = first+1; - size_t n = c - '0'; + size_t n = static_cast<size_t>(c - '0'); for (c = *t; '0' <= c && c <= '9'; c = *t) { - n = n * 10 + c - '0'; + n = n * 10 + static_cast<size_t>(c - '0'); if (++t == last) return first; } - if (last - t >= n && __make<__source_name>(t, n)) + if (static_cast<size_t>(last - t) >= n && __make<__source_name>(t, n)) first = t + n; } } @@ -10103,7 +10339,7 @@ __demangle_tree::__parse_nested_name(const char* first, const char* last) { bool can_sub = true; bool make_nested = true; - const char* t1; + const char* t1 = NULL; switch (*t0) { case '1': @@ -10179,8 +10415,9 @@ __demangle_tree::__parse_nested_name(const char* first, const char* last) } break; case 'U': - assert(!"__parse_nested_name U"); - // could have following <template-args> + t1 = __parse_unnamed_type_name(t0, last); + if (t1 == t0 || t1 == last) + return first; break; case 'T': t1 = __parse_template_param(t0, last); @@ -10482,21 +10719,21 @@ __demangle_tree::__parse_substitution(const char* first, const char* last) size_t sub = 0; const char* t = first+1; if (isdigit(*t)) - sub = *t - '0'; + sub = static_cast<size_t>(*t - '0'); else - sub = *t - 'A' + 10; + sub = static_cast<size_t>(*t - 'A') + 10; for (++t; t != last && (isdigit(*t) || isupper(*t)); ++t) { sub *= 36; if (isdigit(*t)) - sub += *t - '0'; + sub += static_cast<size_t>(*t - '0'); else - sub += *t - 'A' + 10; + sub += static_cast<size_t>(*t - 'A') + 10; } if (t == last || *t != '_') return first; ++sub; - if (sub < __sub_end_ - __sub_begin_) + if (sub < static_cast<size_t>(__sub_end_ - __sub_begin_)) { if (__make<__sub>(__sub_begin_[sub])) first = t+1; @@ -10593,7 +10830,7 @@ __demangle_tree::__parse_dot_suffix(const char* first, const char* last) { if (first != last && *first == '.') { - if (__make<__dot_suffix>(__root_, first, last-first)) + if (__make<__dot_suffix>(__root_, first, static_cast<size_t>(last-first))) first = last; } return first; @@ -10616,6 +10853,7 @@ __demangle_tree::__parse_encoding(const char* first, const char* last) !name->is_ctor_dtor_conv(); __node* ret = NULL; const char* t2; + bool prev_tag_templates = __tag_templates_; __tag_templates_ = false; if (has_return) { @@ -10648,7 +10886,7 @@ __demangle_tree::__parse_encoding(const char* first, const char* last) } } } - __tag_templates_ = true; + __tag_templates_ = prev_tag_templates; } else first = t; @@ -10729,23 +10967,23 @@ printf("\n"); const unsigned N = 4096; char tmp[N]; ptrdiff_t s; - if (est <= bs) + if (static_cast<size_t>(est) <= bs) { char* e = dmg_tree.__get_demangled_name(buf); *e++ = '\0'; s = e - buf; } - else if (est <= N) + else if (static_cast<size_t>(est) <= N) { char* e = dmg_tree.__get_demangled_name(tmp); *e++ = '\0'; s = e - tmp; } else - s = dmg_tree.size() + 1; - if (s > bs) + s = static_cast<ptrdiff_t>(dmg_tree.size() + 1); + if (static_cast<size_t>(s) > bs) { - buf = static_cast<char*>(realloc(buf, s)); + buf = static_cast<char*>(realloc(buf, static_cast<size_t>(s))); if (buf == NULL) { if (status) @@ -10753,12 +10991,12 @@ printf("\n"); return NULL; } if (n) - *n = s; + *n = static_cast<size_t>(s); } - if (est > bs) + if (static_cast<size_t>(est) > bs) { - if (est <= N) - strncpy(buf, tmp, s); + if (static_cast<size_t>(est) <= N) + strncpy(buf, tmp, static_cast<size_t>(s)); else *dmg_tree.__get_demangled_name(buf) = '\0'; } @@ -10784,7 +11022,7 @@ __cxa_demangle(const char* mangled_name, char* buf, size_t* n, int* status) *status = __libcxxabi::invalid_args; return NULL; } - const size_t bs = 64 * 1024; + const size_t bs = 4 * 1024; __attribute((aligned(16))) char static_buf[bs]; buf = __libcxxabi::__demangle(__libcxxabi::__demangle(mangled_name, diff --git a/system/lib/libcxxabi/src/cxa_exception.cpp b/system/lib/libcxxabi/src/cxa_exception.cpp index b866f9e4..1c362993 100644 --- a/system/lib/libcxxabi/src/cxa_exception.cpp +++ b/system/lib/libcxxabi/src/cxa_exception.cpp @@ -466,9 +466,9 @@ __cxa_rethrow() globals->caughtExceptions = 0; } #if __arm__ - (void) _Unwind_SjLj_Resume_or_Rethrow(&exception_header->unwindHeader); + _Unwind_SjLj_RaiseException(&exception_header->unwindHeader); #else - (void)_Unwind_RaiseException(&exception_header->unwindHeader); + _Unwind_RaiseException(&exception_header->unwindHeader); #endif // If we get here, some kind of unwinding error has occurred. diff --git a/system/lib/libcxxabi/src/cxa_exception.hpp b/system/lib/libcxxabi/src/cxa_exception.hpp index cf019d4c..66f05c45 100644 --- a/system/lib/libcxxabi/src/cxa_exception.hpp +++ b/system/lib/libcxxabi/src/cxa_exception.hpp @@ -11,6 +11,9 @@ // //===----------------------------------------------------------------------===// +#ifndef _CXA_EXCEPTION_H +#define _CXA_EXCEPTION_H + #include <exception> // for std::unexpected_handler and std::terminate_handler #include <cxxabi.h> #include "unwind.h" @@ -116,3 +119,5 @@ static const uint64_t get_vendor_and_language = 0xFFFFFFFFFFFFFF00; // mask #pragma GCC visibility pop } + +#endif // _CXA_EXCEPTION_H diff --git a/system/lib/libcxxabi/src/cxa_guard.cpp b/system/lib/libcxxabi/src/cxa_guard.cpp index 814aaeb1..e403b64a 100644 --- a/system/lib/libcxxabi/src/cxa_guard.cpp +++ b/system/lib/libcxxabi/src/cxa_guard.cpp @@ -28,7 +28,7 @@ namespace __cxxabiv1 namespace { -#if LIBCXXABI_ARMEABI +#if __arm__ // A 32-bit, 4-byte-aligned static data value. The least significant 2 bits must // be statically initialized to 0. @@ -62,7 +62,7 @@ void set_initialized(guard_type* guard_object) { pthread_mutex_t guard_mut = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t guard_cv = PTHREAD_COND_INITIALIZER; -#if __APPLE__ +#if defined(__APPLE__) && !defined(__arm__) typedef uint32_t lock_type; @@ -100,7 +100,7 @@ set_lock(uint64_t& x, lock_type y) #endif // __LITTLE_ENDIAN__ -#else // __APPLE__ +#else // !__APPLE__ || __arm__ typedef bool lock_type; @@ -169,7 +169,7 @@ int __cxa_guard_acquire(guard_type* guard_object) int result = *initialized == 0; if (result) { -#if __APPLE__ +#if defined(__APPLE__) && !defined(__arm__) const lock_type id = pthread_mach_thread_np(pthread_self()); lock_type lock = get_lock(*guard_object); if (lock) @@ -189,14 +189,14 @@ int __cxa_guard_acquire(guard_type* guard_object) } else set_lock(*guard_object, id); -#else // __APPLE__ +#else // !__APPLE__ || __arm__ while (get_lock(*guard_object)) if (pthread_cond_wait(&guard_cv, &guard_mut)) abort_message("__cxa_guard_acquire condition variable wait failed"); result = *initialized == 0; if (result) set_lock(*guard_object, true); -#endif // __APPLE__ +#endif // !__APPLE__ || __arm__ } if (pthread_mutex_unlock(&guard_mut)) abort_message("__cxa_guard_acquire failed to release mutex"); diff --git a/system/lib/libcxxabi/src/cxa_handlers.cpp b/system/lib/libcxxabi/src/cxa_handlers.cpp index be43181c..6c13fcd2 100644 --- a/system/lib/libcxxabi/src/cxa_handlers.cpp +++ b/system/lib/libcxxabi/src/cxa_handlers.cpp @@ -22,85 +22,13 @@ namespace std { -static const char* cause = "uncaught"; - -static void default_terminate_handler() -{ - // If there might be an uncaught exception - using namespace __cxxabiv1; - __cxa_eh_globals* globals = __cxa_get_globals_fast(); - if (globals) - { - __cxa_exception* exception_header = globals->caughtExceptions; - // If there is an uncaught exception - if (exception_header) - { - _Unwind_Exception* unwind_exception = - reinterpret_cast<_Unwind_Exception*>(exception_header + 1) - 1; - bool native_exception = - (unwind_exception->exception_class & get_vendor_and_language) == - (kOurExceptionClass & get_vendor_and_language); - if (native_exception) - { - void* thrown_object = - unwind_exception->exception_class == kOurDependentExceptionClass ? - ((__cxa_dependent_exception*)exception_header)->primaryException : - exception_header + 1; - const __shim_type_info* thrown_type = - static_cast<const __shim_type_info*>(exception_header->exceptionType); - // Try to get demangled name of thrown_type - int status; - char buf[1024]; - size_t len = sizeof(buf); - const char* name = __cxa_demangle(thrown_type->name(), buf, &len, &status); - if (status != 0) - name = thrown_type->name(); - // If the uncaught exception can be caught with std::exception& - const __shim_type_info* catch_type = - static_cast<const __shim_type_info*>(&typeid(exception)); - if (catch_type->can_catch(thrown_type, thrown_object)) - { - // Include the what() message from the exception - const exception* e = static_cast<const exception*>(thrown_object); - abort_message("terminating with %s exception of type %s: %s", - cause, name, e->what()); - } - else - // Else just note that we're terminating with an exception - abort_message("terminating with %s exception of type %s", - cause, name); - } - else - // Else we're terminating with a foreign exception - abort_message("terminating with %s foreign exception", cause); - } - } - // Else just note that we're terminating - abort_message("terminating"); -} - -static void default_unexpected_handler() -{ - cause = "unexpected"; - terminate(); -} - -static terminate_handler __terminate_handler = default_terminate_handler; -static unexpected_handler __unexpected_handler = default_unexpected_handler; -static new_handler __new_handler = 0; - -unexpected_handler -set_unexpected(unexpected_handler func) _NOEXCEPT -{ - if (func == 0) - func = default_unexpected_handler; - return __sync_lock_test_and_set(&__unexpected_handler, func); -} - unexpected_handler get_unexpected() _NOEXCEPT { - return __sync_fetch_and_add(&__unexpected_handler, (unexpected_handler)0); + return __sync_fetch_and_add(&__cxa_unexpected_handler, (unexpected_handler)0); +// The above is safe but overkill on x86 +// Using of C++11 atomics this should be rewritten +// return __cxa_unexpected_handler.load(memory_order_acq); } __attribute__((visibility("hidden"), noreturn)) @@ -120,17 +48,12 @@ unexpected() } terminate_handler -set_terminate(terminate_handler func) _NOEXCEPT -{ - if (func == 0) - func = default_terminate_handler; - return __sync_lock_test_and_set(&__terminate_handler, func); -} - -terminate_handler get_terminate() _NOEXCEPT { - return __sync_fetch_and_add(&__terminate_handler, (terminate_handler)0); + return __sync_fetch_and_add(&__cxa_terminate_handler, (terminate_handler)0); +// The above is safe but overkill on x86 +// Using of C++11 atomics this should be rewritten +// return __cxa_terminate_handler.load(memory_order_acq); } __attribute__((visibility("hidden"), noreturn)) @@ -172,25 +95,31 @@ terminate() _NOEXCEPT (unwind_exception->exception_class & get_vendor_and_language) == (kOurExceptionClass & get_vendor_and_language); if (native_exception) - { - __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1; __terminate(exception_header->terminateHandler); - } } } __terminate(get_terminate()); } +extern "C" new_handler __cxa_new_handler = 0; +// In the future these will become: +// std::atomic<std::new_handler> __cxa_new_handler(0); + new_handler set_new_handler(new_handler handler) _NOEXCEPT { - return __sync_lock_test_and_set(&__new_handler, handler); + return __sync_swap(&__cxa_new_handler, handler); +// Using of C++11 atomics this should be rewritten +// return __cxa_new_handler.exchange(handler, memory_order_acq_rel); } new_handler get_new_handler() _NOEXCEPT { - return __sync_fetch_and_add(&__new_handler, (new_handler)0); + return __sync_fetch_and_add(&__cxa_new_handler, (new_handler)0); +// The above is safe but overkill on x86 +// Using of C++11 atomics this should be rewritten +// return __cxa_new_handler.load(memory_order_acq); } } // std diff --git a/system/lib/libcxxabi/src/cxa_handlers.hpp b/system/lib/libcxxabi/src/cxa_handlers.hpp index a7f582c0..64994ac7 100644 --- a/system/lib/libcxxabi/src/cxa_handlers.hpp +++ b/system/lib/libcxxabi/src/cxa_handlers.hpp @@ -10,6 +10,9 @@ // unexpected_handler, and new_handler. //===----------------------------------------------------------------------===// +#ifndef _CXA_HANDLERS_H +#define _CXA_HANDLERS_H + #include <exception> namespace std @@ -24,3 +27,28 @@ void __terminate(terminate_handler func) _NOEXCEPT; } // std + +extern "C" +{ + +extern void (*__cxa_terminate_handler)(); +extern void (*__cxa_unexpected_handler)(); +extern void (*__cxa_new_handler)(); + +/* + + At some point in the future these three symbols will become + C++11 atomic variables: + + extern std::atomic<std::terminate_handler> __cxa_terminate_handler; + extern std::atomic<std::unexpected_handler> __cxa_unexpected_handler; + extern std::atomic<std::new_handler> __cxa_new_handler; + + This change will not impact their ABI. But it will allow for a + portible performance optimization. + +*/ + +} // extern "C" + +#endif // _CXA_HANDLERS_H diff --git a/system/lib/libcxxabi/src/cxa_personality.cpp b/system/lib/libcxxabi/src/cxa_personality.cpp index e49278c0..b2efe2aa 100644 --- a/system/lib/libcxxabi/src/cxa_personality.cpp +++ b/system/lib/libcxxabi/src/cxa_personality.cpp @@ -48,19 +48,36 @@ | callSiteEncoding | (char) | Encoding for Call Site Table | +------------------+--+-----+-----+------------------------+--------------------------+ | callSiteTableLength | (ULEB128) | Call Site Table length, used to find Action table | -+---------------------+-----------+------------------------------------------------+--+ -| Beginning of Call Site Table If the current ip lies within the | ++---------------------+-----------+---------------------------------------------------+ +#if !__arm__ ++---------------------+-----------+------------------------------------------------+ +| Beginning of Call Site Table The current ip lies within the | | ... (start, length) range of one of these | -| call sites, there may be action needed. | +| call sites. There may be action needed. | | +-------------+---------------------------------+------------------------------+ | | | start | (encoded with callSiteEncoding) | offset relative to funcStart | | -| | length | (encoded with callSiteEncoding) | lenght of code fragment | | +| | length | (encoded with callSiteEncoding) | length of code fragment | | | | landingPad | (encoded with callSiteEncoding) | offset relative to lpStart | | | | actionEntry | (ULEB128) | Action Table Index 1-based | | | | | | actionEntry == 0 -> cleanup | | | +-------------+---------------------------------+------------------------------+ | | ... | -+---------------------------------------------------------------------+------------+ ++----------------------------------------------------------------------------------+ +#else // __arm_ ++---------------------+-----------+------------------------------------------------+ +| Beginning of Call Site Table The current ip is a 1-based index into | +| ... this table. Or it is -1 meaning no | +| action is needed. Or it is 0 meaning | +| terminate. | +| +-------------+---------------------------------+------------------------------+ | +| | landingPad | (ULEB128) | offset relative to lpStart | | +| | actionEntry | (ULEB128) | Action Table Index 1-based | | +| | | | actionEntry == 0 -> cleanup | | +| +-------------+---------------------------------+------------------------------+ | +| ... | ++----------------------------------------------------------------------------------+ +#endif // __arm_ ++---------------------------------------------------------------------+ | Beginning of Action Table ttypeIndex == 0 : cleanup | | ... ttypeIndex > 0 : catch | | ttypeIndex < 0 : exception spec | @@ -175,7 +192,7 @@ readULEB128(const uint8_t** data) /// @param data reference variable holding memory pointer to decode from /// @returns decoded value static -uintptr_t +intptr_t readSLEB128(const uint8_t** data) { uintptr_t result = 0; @@ -191,7 +208,7 @@ readSLEB128(const uint8_t** data) *data = p; if ((byte & 0x40) && (shift < (sizeof(result) << 3))) result |= static_cast<uintptr_t>(~0) << shift; - return result; + return static_cast<intptr_t>(result); } /// Read a pointer encoded value and advance pointer @@ -219,7 +236,7 @@ readEncodedPointer(const uint8_t** data, uint8_t encoding) result = readULEB128(&p); break; case DW_EH_PE_sleb128: - result = readSLEB128(&p); + result = static_cast<uintptr_t>(readSLEB128(&p)); break; case DW_EH_PE_udata2: result = *((uint16_t*)p); @@ -230,19 +247,19 @@ readEncodedPointer(const uint8_t** data, uint8_t encoding) p += sizeof(uint32_t); break; case DW_EH_PE_udata8: - result = *((uint64_t*)p); + result = static_cast<uintptr_t>(*((uint64_t*)p)); p += sizeof(uint64_t); break; case DW_EH_PE_sdata2: - result = *((int16_t*)p); + result = static_cast<uintptr_t>(*((int16_t*)p)); p += sizeof(int16_t); break; case DW_EH_PE_sdata4: - result = *((int32_t*)p); + result = static_cast<uintptr_t>(*((int32_t*)p)); p += sizeof(int32_t); break; case DW_EH_PE_sdata8: - result = *((int64_t*)p); + result = static_cast<uintptr_t>(*((int64_t*)p)); p += sizeof(int64_t); break; default: @@ -292,7 +309,7 @@ call_terminate(bool native_exception, _Unwind_Exception* unwind_exception) static const __shim_type_info* -get_shim_type_info(int64_t ttypeIndex, const uint8_t* classInfo, +get_shim_type_info(uint64_t ttypeIndex, const uint8_t* classInfo, uint8_t ttypeEncoding, bool native_exception, _Unwind_Exception* unwind_exception) { @@ -381,6 +398,41 @@ get_thrown_object_ptr(_Unwind_Exception* unwind_exception) return adjustedPtr; } +namespace +{ + +struct scan_results +{ + int64_t ttypeIndex; // > 0 catch handler, < 0 exception spec handler, == 0 a cleanup + const uint8_t* actionRecord; // Currently unused. Retained to ease future maintenance. + const uint8_t* languageSpecificData; // Needed only for __cxa_call_unexpected + uintptr_t landingPad; // null -> nothing found, else something found + void* adjustedPtr; // Used in cxa_exception.cpp + _Unwind_Reason_Code reason; // One of _URC_FATAL_PHASE1_ERROR, + // _URC_FATAL_PHASE2_ERROR, + // _URC_CONTINUE_UNWIND, + // _URC_HANDLER_FOUND +}; + +} // unnamed namespace + +static +void +set_registers(_Unwind_Exception* unwind_exception, _Unwind_Context* context, + const scan_results& results) +{ +#if __arm__ + _Unwind_SetGR(context, 0, reinterpret_cast<uintptr_t>(unwind_exception)); + _Unwind_SetGR(context, 1, static_cast<uintptr_t>(results.ttypeIndex)); +#else + _Unwind_SetGR(context, __builtin_eh_return_data_regno(0), + reinterpret_cast<uintptr_t>(unwind_exception)); + _Unwind_SetGR(context, __builtin_eh_return_data_regno(1), + static_cast<uintptr_t>(results.ttypeIndex)); +#endif + _Unwind_SetIP(context, results.landingPad); +} + /* There are 3 types of scans needed: @@ -402,24 +454,6 @@ get_thrown_object_ptr(_Unwind_Exception* unwind_exception) _UA_CLEANUP_PHASE && !_UA_HANDLER_FRAME */ -namespace -{ - -struct scan_results -{ - int64_t ttypeIndex; // > 0 catch handler, < 0 exception spec handler, == 0 a cleanup - const uint8_t* actionRecord; // Currently unused. Retained to ease future maintenance. - const uint8_t* languageSpecificData; // Needed only for __cxa_call_unexpected - uintptr_t landingPad; // null -> nothing found, else something found - void* adjustedPtr; // Used in cxa_exception.cpp - _Unwind_Reason_Code reason; // One of _URC_FATAL_PHASE1_ERROR, - // _URC_FATAL_PHASE2_ERROR, - // _URC_CONTINUE_UNWIND, - // _URC_HANDLER_FOUND -}; - -} // unnamed namespace - static void scan_eh_tab(scan_results& results, _Unwind_Action actions, bool native_exception, @@ -477,7 +511,19 @@ scan_eh_tab(scan_results& results, _Unwind_Action actions, bool native_exception // Get beginning current frame's code (as defined by the // emitted dwarf code) uintptr_t funcStart = _Unwind_GetRegionStart(context); +#if __arm__ + if (ip == uintptr_t(-1)) + { + // no action + results.reason = _URC_CONTINUE_UNWIND; + return; + } + else if (ip == 0) + call_terminate(native_exception, unwind_exception); + // ip is 1-based index into call site table +#else // __arm__ uintptr_t ipOffset = ip - funcStart; +#endif // __arm__ const uint8_t* classInfo = NULL; // Note: See JITDwarfEmitter::EmitExceptionTable(...) for corresponding // dwarf emission @@ -498,14 +544,18 @@ scan_eh_tab(scan_results& results, _Unwind_Action actions, bool native_exception // Walk call-site table looking for range that // includes current PC. uint8_t callSiteEncoding = *lsda++; - uint32_t callSiteTableLength = readULEB128(&lsda); +#if __arm__ + (void)callSiteEncoding; // On arm callSiteEncoding is never used +#endif + uint32_t callSiteTableLength = static_cast<uint32_t>(readULEB128(&lsda)); const uint8_t* callSiteTableStart = lsda; const uint8_t* callSiteTableEnd = callSiteTableStart + callSiteTableLength; const uint8_t* actionTableStart = callSiteTableEnd; const uint8_t* callSitePtr = callSiteTableStart; - while (true) + while (callSitePtr < callSiteTableEnd) { // There is one entry per call site. +#if !__arm__ // The call sites are non-overlapping in [start, start+length) // The call sites are ordered in increasing value of start uintptr_t start = readEncodedPointer(&callSitePtr, callSiteEncoding); @@ -513,8 +563,15 @@ scan_eh_tab(scan_results& results, _Unwind_Action actions, bool native_exception uintptr_t landingPad = readEncodedPointer(&callSitePtr, callSiteEncoding); uintptr_t actionEntry = readULEB128(&callSitePtr); if ((start <= ipOffset) && (ipOffset < (start + length))) +#else // __arm__ + // ip is 1-based index into this table + uintptr_t landingPad = readULEB128(&callSitePtr); + uintptr_t actionEntry = readULEB128(&callSitePtr); + if (--ip == 0) +#endif // __arm__ { // Found the call site containing ip. +#if !__arm__ if (landingPad == 0) { // No handler here @@ -522,6 +579,9 @@ scan_eh_tab(scan_results& results, _Unwind_Action actions, bool native_exception return; } landingPad = (uintptr_t)lpStart + landingPad; +#else // __arm__ + ++landingPad; +#endif // __arm__ if (actionEntry == 0) { // Found a cleanup @@ -550,9 +610,9 @@ scan_eh_tab(scan_results& results, _Unwind_Action actions, bool native_exception // Found a catch, does it actually catch? // First check for catch (...) const __shim_type_info* catchType = - get_shim_type_info(ttypeIndex, classInfo, - ttypeEncoding, native_exception, - unwind_exception); + get_shim_type_info(static_cast<uint64_t>(ttypeIndex), + classInfo, ttypeEncoding, + native_exception, unwind_exception); if (catchType == 0) { // Found catch (...) catches everything, including foreign exceptions @@ -713,6 +773,7 @@ scan_eh_tab(scan_results& results, _Unwind_Action actions, bool native_exception action += actionOffset; } // there is no break out of this loop, only return } +#if !__arm__ else if (ipOffset < start) { // There is no call site for this ip @@ -720,7 +781,12 @@ scan_eh_tab(scan_results& results, _Unwind_Action actions, bool native_exception // Possible stack corruption. call_terminate(native_exception, unwind_exception); } - } // there is no break out of this loop, only return +#endif // !__arm__ + } // there might be some tricky cases which break out of this loop + + // It is possible that no eh table entry specify how to handle + // this exception. By spec, terminate it immediately. + call_terminate(native_exception, unwind_exception); } // public API @@ -772,7 +838,12 @@ _UA_CLEANUP_PHASE */ _Unwind_Reason_Code -__gxx_personality_v0(int version, _Unwind_Action actions, uint64_t exceptionClass, +#if __arm__ +__gxx_personality_sj0 +#else +__gxx_personality_v0 +#endif + (int version, _Unwind_Action actions, uint64_t exceptionClass, _Unwind_Exception* unwind_exception, _Unwind_Context* context) { if (version != 1 || unwind_exception == 0 || context == 0) @@ -832,9 +903,7 @@ __gxx_personality_v0(int version, _Unwind_Action actions, uint64_t exceptionClas call_terminate(native_exception, unwind_exception); } // Jump to the handler - _Unwind_SetGR(context, __builtin_eh_return_data_regno(0), (uintptr_t)unwind_exception); - _Unwind_SetGR(context, __builtin_eh_return_data_regno(1), results.ttypeIndex); - _Unwind_SetIP(context, results.landingPad); + set_registers(unwind_exception, context, results); return _URC_INSTALL_CONTEXT; } // Either we didn't do a phase 1 search (due to forced unwinding), or @@ -844,9 +913,7 @@ __gxx_personality_v0(int version, _Unwind_Action actions, uint64_t exceptionClas if (results.reason == _URC_HANDLER_FOUND) { // Found a non-catching handler. Jump to it: - _Unwind_SetGR(context, __builtin_eh_return_data_regno(0), (uintptr_t)unwind_exception); - _Unwind_SetGR(context, __builtin_eh_return_data_regno(1), results.ttypeIndex); - _Unwind_SetIP(context, results.landingPad); + set_registers(unwind_exception, context, results); return _URC_INSTALL_CONTEXT; } // Did not find a cleanup. Return the results of the scan @@ -910,6 +977,7 @@ __cxa_call_unexpected(void* arg) // uint8_t ttypeEncoding uint8_t lpStartEncoding = *lsda++; const uint8_t* lpStart = (const uint8_t*)readEncodedPointer(&lsda, lpStartEncoding); + (void)lpStart; // purposefully unused. Just needed to increment lsda. uint8_t ttypeEncoding = *lsda++; if (ttypeEncoding == DW_EH_PE_omit) std::__terminate(t_handler); diff --git a/system/lib/libcxxabi/src/fallback_malloc.ipp b/system/lib/libcxxabi/src/fallback_malloc.ipp index 979f0bbd..e04fb158 100644 --- a/system/lib/libcxxabi/src/fallback_malloc.ipp +++ b/system/lib/libcxxabi/src/fallback_malloc.ipp @@ -54,7 +54,7 @@ heap_node *node_from_offset ( const heap_offset offset ) { return (heap_node *) ( heap + ( offset * sizeof (heap_node))); } heap_offset offset_from_node ( const heap_node *ptr ) - { return (((char *) ptr ) - heap) / sizeof (heap_node); } + { return static_cast<heap_offset>(static_cast<size_t>(((char *) ptr ) - heap) / sizeof (heap_node)); } void init_heap () { freelist = (heap_node *) heap; @@ -87,7 +87,7 @@ void *fallback_malloc(size_t len) { p->len -= nelems; q = p + p->len; q->next_node = 0; - q->len = nelems; + q->len = static_cast<heap_size>(nelems); return (void *) (q + 1); } diff --git a/system/lib/libcxxabi/src/private_typeinfo.cpp b/system/lib/libcxxabi/src/private_typeinfo.cpp index 269116b6..44b084ae 100644 --- a/system/lib/libcxxabi/src/private_typeinfo.cpp +++ b/system/lib/libcxxabi/src/private_typeinfo.cpp @@ -9,17 +9,73 @@ #include "private_typeinfo.h" +// The flag _LIBCXX_DYNAMIC_FALLBACK is used to make dynamic_cast more +// forgiving when type_info's mistakenly have hidden visibility and thus +// multiple type_infos can exist for a single type. +// +// When _LIBCXX_DYNAMIC_FALLBACK is defined, and only in the case where +// there is a detected inconsistency in the type_info hierarchy during a +// dynamic_cast, then the equality operation will fall back to using strcmp +// on type_info names to determin type_info equality. +// +// This change happens *only* under dynamic_cast, and only when +// dynamic_cast is faced with the choice: abort, or possibly give back the +// wrong answer. If when the dynamic_cast is done with this fallback +// algorithm and an inconsistency is still detected, dynamic_cast will call +// abort with an approriate message. +// +// The current implementation of _LIBCXX_DYNAMIC_FALLBACK requires a +// printf-like function called syslog: +// +// void syslog(const char* format, ...); +// +// If you want this functionality but your platform doesn't have syslog, +// just implement it in terms of fprintf(stderr, ...). +// +// _LIBCXX_DYNAMIC_FALLBACK is currently off by default. + +#if _LIBCXX_DYNAMIC_FALLBACK +#include "abort_message.h" +#include <string.h> +#include <sys/syslog.h> +#endif + namespace __cxxabiv1 { #pragma GCC visibility push(hidden) +#if _LIBCXX_DYNAMIC_FALLBACK + +inline +bool +is_equal(const std::type_info* x, const std::type_info* y, bool use_strcmp) +{ + if (!use_strcmp) + return x == y; + return strcmp(x->name(), y->name()) == 0; +} + +#else // !_LIBCXX_DYNAMIC_FALLBACK + +inline +bool +is_equal(const std::type_info* x, const std::type_info* y, bool) +{ + return x == y; +} + +#endif // _LIBCXX_DYNAMIC_FALLBACK + // __shim_type_info __shim_type_info::~__shim_type_info() { } +void __shim_type_info::noop1() const {} +void __shim_type_info::noop2() const {} + // __fundamental_type_info // This miraculously (compiler magic) emits the type_info's for: @@ -116,12 +172,11 @@ bool __fundamental_type_info::can_catch(const __shim_type_info* thrown_type, void*&) const { - return this == thrown_type; + return is_equal(this, thrown_type, false); } bool -__array_type_info::can_catch(const __shim_type_info* thrown_type, - void*&) const +__array_type_info::can_catch(const __shim_type_info*, void*&) const { // We can get here if someone tries to catch an array by reference. // However if someone tries to throw an array, it immediately gets @@ -131,8 +186,7 @@ __array_type_info::can_catch(const __shim_type_info* thrown_type, } bool -__function_type_info::can_catch(const __shim_type_info* thrown_type, - void*&) const +__function_type_info::can_catch(const __shim_type_info*, void*&) const { // We can get here if someone tries to catch a function by reference. // However if someone tries to throw a function, it immediately gets @@ -146,16 +200,19 @@ bool __enum_type_info::can_catch(const __shim_type_info* thrown_type, void*&) const { - return this == thrown_type; + return is_equal(this, thrown_type, false); } +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wmissing-field-initializers" + // Handles bullets 1 and 2 bool __class_type_info::can_catch(const __shim_type_info* thrown_type, void*& adjustedPtr) const { // bullet 1 - if (this == thrown_type) + if (is_equal(this, thrown_type, false)) return true; const __class_type_info* thrown_class_type = dynamic_cast<const __class_type_info*>(thrown_type); @@ -173,6 +230,8 @@ __class_type_info::can_catch(const __shim_type_info* thrown_type, return false; } +#pragma clang diagnostic pop + void __class_type_info::process_found_base_class(__dynamic_cast_info* info, void* adjustedPtr, @@ -206,7 +265,7 @@ __class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info, void* adjustedPtr, int path_below) const { - if (this == info->static_type) + if (is_equal(this, info->static_type, false)) process_found_base_class(info, adjustedPtr, path_below); } @@ -215,7 +274,7 @@ __si_class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info, void* adjustedPtr, int path_below) const { - if (this == info->static_type) + if (is_equal(this, info->static_type, false)) process_found_base_class(info, adjustedPtr, path_below); else __base_type->has_unambiguous_public_base(info, adjustedPtr, path_below); @@ -244,7 +303,7 @@ __vmi_class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info, void* adjustedPtr, int path_below) const { - if (this == info->static_type) + if (is_equal(this, info->static_type, false)) process_found_base_class(info, adjustedPtr, path_below); else { @@ -269,11 +328,14 @@ bool __pbase_type_info::can_catch(const __shim_type_info* thrown_type, void*&) const { - if (this == thrown_type) + if (is_equal(this, thrown_type, false)) return true; - return thrown_type == &typeid(std::nullptr_t); + return is_equal(thrown_type, &typeid(std::nullptr_t), false); } +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wmissing-field-initializers" + // Handles bullets 1, 3 and 4 bool __pointer_type_info::can_catch(const __shim_type_info* thrown_type, @@ -292,10 +354,10 @@ __pointer_type_info::can_catch(const __shim_type_info* thrown_type, // bullet 3B if (thrown_pointer_type->__flags & ~__flags) return false; - if (__pointee == thrown_pointer_type->__pointee) + if (is_equal(__pointee, thrown_pointer_type->__pointee, false)) return true; // bullet 3A - if (__pointee == &typeid(void)) + if (is_equal(__pointee, &typeid(void), false)) return true; const __class_type_info* catch_class_type = dynamic_cast<const __class_type_info*>(__pointee); @@ -316,9 +378,14 @@ __pointer_type_info::can_catch(const __shim_type_info* thrown_type, return false; } +#pragma clang diagnostic pop + #pragma GCC visibility pop #pragma GCC visibility push(default) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wmissing-field-initializers" + // __dynamic_cast // static_ptr: pointer to an object of type static_type; nonnull, and since the @@ -417,12 +484,28 @@ __dynamic_cast(const void* static_ptr, __dynamic_cast_info info = {dst_type, static_ptr, static_type, src2dst_offset, 0}; // Find out if we can use a giant short cut in the search - if (dynamic_type == dst_type) + if (is_equal(dynamic_type, dst_type, false)) { // Using giant short cut. Add that information to info. info.number_of_dst_type = 1; // Do the search - dynamic_type->search_above_dst(&info, dynamic_ptr, dynamic_ptr, public_path); + dynamic_type->search_above_dst(&info, dynamic_ptr, dynamic_ptr, public_path, false); +#if _LIBCXX_DYNAMIC_FALLBACK + // The following if should always be false because we should definitely + // find (static_ptr, static_type), either on a public or private path + if (info.path_dst_ptr_to_static_ptr == unknown) + { + // We get here only if there is some kind of visibility problem + // in client code. + syslog(LOG_ERR, "dynamic_cast error 1: Both of the following type_info's " + "should have public visibility. At least of of them is hidden. %s" + ", %s.\n", static_type->name(), dynamic_type->name()); + // Redo the search comparing type_info's using strcmp + info = {dst_type, static_ptr, static_type, src2dst_offset, 0}; + info.number_of_dst_type = 1; + dynamic_type->search_above_dst(&info, dynamic_ptr, dynamic_ptr, public_path, true); + } +#endif // _LIBCXX_DYNAMIC_FALLBACK // Query the search. if (info.path_dst_ptr_to_static_ptr == public_path) dst_ptr = dynamic_ptr; @@ -430,7 +513,22 @@ __dynamic_cast(const void* static_ptr, else { // Not using giant short cut. Do the search - dynamic_type->search_below_dst(&info, dynamic_ptr, public_path); + dynamic_type->search_below_dst(&info, dynamic_ptr, public_path, false); + #if _LIBCXX_DYNAMIC_FALLBACK + // The following if should always be false because we should definitely + // find (static_ptr, static_type), either on a public or private path + if (info.path_dst_ptr_to_static_ptr == unknown && + info.path_dynamic_ptr_to_static_ptr == unknown) + { + syslog(LOG_ERR, "dynamic_cast error 2: One or more of the following type_info's " + " has hidden visibility. They should all have public visibility. " + " %s, %s, %s.\n", static_type->name(), dynamic_type->name(), + dst_type->name()); + // Redo the search comparing type_info's using strcmp + info = {dst_type, static_ptr, static_type, src2dst_offset, 0}; + dynamic_type->search_below_dst(&info, dynamic_ptr, public_path, true); + } +#endif // _LIBCXX_DYNAMIC_FALLBACK // Query the search. switch (info.number_to_static_ptr) { @@ -455,6 +553,8 @@ __dynamic_cast(const void* static_ptr, return const_cast<void*>(dst_ptr); } +#pragma clang diagnostic pop + #pragma GCC visibility pop #pragma GCC visibility push(hidden) @@ -584,12 +684,13 @@ __class_type_info::process_static_type_below_dst(__dynamic_cast_info* info, void __vmi_class_type_info::search_below_dst(__dynamic_cast_info* info, const void* current_ptr, - int path_below) const + int path_below, + bool use_strcmp) const { typedef const __base_class_type_info* Iter; - if (this == info->static_type) + if (is_equal(this, info->static_type, use_strcmp)) process_static_type_below_dst(info, current_ptr, path_below); - else if (this == info->dst_type) + else if (is_equal(this, info->dst_type, use_strcmp)) { // We've been here before if we've recorded current_ptr in one of these // two places: @@ -629,7 +730,7 @@ __vmi_class_type_info::search_below_dst(__dynamic_cast_info* info, // Zero out found flags info->found_our_static_ptr = false; info->found_any_static_type = false; - p->search_above_dst(info, current_ptr, current_ptr, public_path); + p->search_above_dst(info, current_ptr, current_ptr, public_path, use_strcmp); if (info->search_done) break; if (info->found_any_static_type) @@ -688,7 +789,7 @@ __vmi_class_type_info::search_below_dst(__dynamic_cast_info* info, // This is not a static_type and not a dst_type. const Iter e = __base_info + __base_count; Iter p = __base_info; - p->search_below_dst(info, current_ptr, path_below); + p->search_below_dst(info, current_ptr, path_below, use_strcmp); if (++p < e) { if ((__flags & __diamond_shaped_mask) || info->number_to_static_ptr == 1) @@ -701,7 +802,7 @@ __vmi_class_type_info::search_below_dst(__dynamic_cast_info* info, { if (info->search_done) break; - p->search_below_dst(info, current_ptr, path_below); + p->search_below_dst(info, current_ptr, path_below, use_strcmp); } while (++p < e); } else if (__flags & __non_diamond_repeat_mask) @@ -720,7 +821,7 @@ __vmi_class_type_info::search_below_dst(__dynamic_cast_info* info, if (info->number_to_static_ptr == 1 && info->path_dst_ptr_to_static_ptr == public_path) break; - p->search_below_dst(info, current_ptr, path_below); + p->search_below_dst(info, current_ptr, path_below, use_strcmp); } while (++p < e); } else @@ -743,7 +844,7 @@ __vmi_class_type_info::search_below_dst(__dynamic_cast_info* info, // and not a dst_type under here. if (info->number_to_static_ptr == 1) break; - p->search_below_dst(info, current_ptr, path_below); + p->search_below_dst(info, current_ptr, path_below, use_strcmp); } while (++p < e); } } @@ -755,11 +856,12 @@ __vmi_class_type_info::search_below_dst(__dynamic_cast_info* info, void __si_class_type_info::search_below_dst(__dynamic_cast_info* info, const void* current_ptr, - int path_below) const + int path_below, + bool use_strcmp) const { - if (this == info->static_type) + if (is_equal(this, info->static_type, use_strcmp)) process_static_type_below_dst(info, current_ptr, path_below); - else if (this == info->dst_type) + else if (is_equal(this, info->dst_type, use_strcmp)) { // We've been here before if we've recorded current_ptr in one of these // two places: @@ -787,7 +889,7 @@ __si_class_type_info::search_below_dst(__dynamic_cast_info* info, // Zero out found flags info->found_our_static_ptr = false; info->found_any_static_type = false; - __base_type->search_above_dst(info, current_ptr, current_ptr, public_path); + __base_type->search_above_dst(info, current_ptr, current_ptr, public_path, use_strcmp); if (info->found_any_static_type) { is_dst_type_derived_from_static_type = true; @@ -822,7 +924,7 @@ __si_class_type_info::search_below_dst(__dynamic_cast_info* info, else { // This is not a static_type and not a dst_type - __base_type->search_below_dst(info, current_ptr, path_below); + __base_type->search_below_dst(info, current_ptr, path_below, use_strcmp); } } @@ -831,12 +933,13 @@ __si_class_type_info::search_below_dst(__dynamic_cast_info* info, void __class_type_info::search_below_dst(__dynamic_cast_info* info, const void* current_ptr, - int path_below) const + int path_below, + bool use_strcmp) const { typedef const __base_class_type_info* Iter; - if (this == info->static_type) + if (is_equal(this, info->static_type, use_strcmp)) process_static_type_below_dst(info, current_ptr, path_below); - else if (this == info->dst_type) + else if (is_equal(this, info->dst_type, use_strcmp)) { // We've been here before if we've recorded current_ptr in one of these // two places: @@ -901,9 +1004,10 @@ void __vmi_class_type_info::search_above_dst(__dynamic_cast_info* info, const void* dst_ptr, const void* current_ptr, - int path_below) const + int path_below, + bool use_strcmp) const { - if (this == info->static_type) + if (is_equal(this, info->static_type, use_strcmp)) process_static_type_above_dst(info, dst_ptr, current_ptr, path_below); else { @@ -926,7 +1030,7 @@ __vmi_class_type_info::search_above_dst(__dynamic_cast_info* info, // Zero out found flags info->found_our_static_ptr = false; info->found_any_static_type = false; - p->search_above_dst(info, dst_ptr, current_ptr, path_below); + p->search_above_dst(info, dst_ptr, current_ptr, path_below, use_strcmp); if (++p < e) { do @@ -955,7 +1059,7 @@ __vmi_class_type_info::search_above_dst(__dynamic_cast_info* info, // Zero out found flags info->found_our_static_ptr = false; info->found_any_static_type = false; - p->search_above_dst(info, dst_ptr, current_ptr, path_below); + p->search_above_dst(info, dst_ptr, current_ptr, path_below, use_strcmp); } while (++p < e); } // Restore flags @@ -970,12 +1074,13 @@ void __si_class_type_info::search_above_dst(__dynamic_cast_info* info, const void* dst_ptr, const void* current_ptr, - int path_below) const + int path_below, + bool use_strcmp) const { - if (this == info->static_type) + if (is_equal(this, info->static_type, use_strcmp)) process_static_type_above_dst(info, dst_ptr, current_ptr, path_below); else - __base_type->search_above_dst(info, dst_ptr, current_ptr, path_below); + __base_type->search_above_dst(info, dst_ptr, current_ptr, path_below, use_strcmp); } // This is the same algorithm as __vmi_class_type_info::search_above_dst but @@ -984,9 +1089,10 @@ void __class_type_info::search_above_dst(__dynamic_cast_info* info, const void* dst_ptr, const void* current_ptr, - int path_below) const + int path_below, + bool use_strcmp) const { - if (this == info->static_type) + if (is_equal(this, info->static_type, use_strcmp)) process_static_type_above_dst(info, dst_ptr, current_ptr, path_below); } @@ -998,7 +1104,8 @@ void __base_class_type_info::search_above_dst(__dynamic_cast_info* info, const void* dst_ptr, const void* current_ptr, - int path_below) const + int path_below, + bool use_strcmp) const { ptrdiff_t offset_to_base = __offset_flags >> __offset_shift; if (__offset_flags & __virtual_mask) @@ -1010,13 +1117,15 @@ __base_class_type_info::search_above_dst(__dynamic_cast_info* info, static_cast<const char*>(current_ptr) + offset_to_base, (__offset_flags & __public_mask) ? path_below : - not_public_path); + not_public_path, + use_strcmp); } void __base_class_type_info::search_below_dst(__dynamic_cast_info* info, const void* current_ptr, - int path_below) const + int path_below, + bool use_strcmp) const { ptrdiff_t offset_to_base = __offset_flags >> __offset_shift; if (__offset_flags & __virtual_mask) @@ -1028,7 +1137,8 @@ __base_class_type_info::search_below_dst(__dynamic_cast_info* info, static_cast<const char*>(current_ptr) + offset_to_base, (__offset_flags & __public_mask) ? path_below : - not_public_path); + not_public_path, + use_strcmp); } #pragma GCC visibility pop diff --git a/system/lib/libcxxabi/src/private_typeinfo.h b/system/lib/libcxxabi/src/private_typeinfo.h index fec081ab..07e8ddea 100644 --- a/system/lib/libcxxabi/src/private_typeinfo.h +++ b/system/lib/libcxxabi/src/private_typeinfo.h @@ -18,13 +18,15 @@ namespace __cxxabiv1 #pragma GCC visibility push(hidden) -class __attribute__ ((__visibility__("hidden"))) __shim_type_info +class __attribute__ ((__visibility__("default"))) __shim_type_info : public std::type_info { public: - virtual ~__shim_type_info(); + __attribute__ ((__visibility__("hidden"))) virtual ~__shim_type_info(); - virtual bool can_catch(const __shim_type_info* thrown_type, void*& adjustedPtr) const = 0; + __attribute__ ((__visibility__("hidden"))) virtual void noop1() const; + __attribute__ ((__visibility__("hidden"))) virtual void noop2() const; + __attribute__ ((__visibility__("hidden"))) virtual bool can_catch(const __shim_type_info* thrown_type, void*& adjustedPtr) const = 0; }; class __attribute__ ((__visibility__("default"))) __fundamental_type_info @@ -68,16 +70,16 @@ enum no }; -class __class_type_info; +class __attribute__ ((__visibility__("default"))) __class_type_info; struct __dynamic_cast_info { // const data supplied to the search: - const __class_type_info* const dst_type; - const void* const static_ptr; - const __class_type_info* const static_type; - const std::ptrdiff_t src2dst_offset; + const __class_type_info* dst_type; + const void* static_ptr; + const __class_type_info* static_type; + std::ptrdiff_t src2dst_offset; // Data that represents the answer: @@ -131,9 +133,9 @@ public: __attribute__ ((__visibility__("hidden"))) void process_found_base_class(__dynamic_cast_info*, void*, int) const; __attribute__ ((__visibility__("hidden"))) - virtual void search_above_dst(__dynamic_cast_info*, const void*, const void*, int) const; + virtual void search_above_dst(__dynamic_cast_info*, const void*, const void*, int, bool) const; __attribute__ ((__visibility__("hidden"))) - virtual void search_below_dst(__dynamic_cast_info*, const void*, int) const; + virtual void search_below_dst(__dynamic_cast_info*, const void*, int, bool) const; __attribute__ ((__visibility__("hidden"))) virtual bool can_catch(const __shim_type_info*, void*&) const; __attribute__ ((__visibility__("hidden"))) @@ -150,9 +152,9 @@ public: __attribute__ ((__visibility__("hidden"))) virtual ~__si_class_type_info(); __attribute__ ((__visibility__("hidden"))) - virtual void search_above_dst(__dynamic_cast_info*, const void*, const void*, int) const; + virtual void search_above_dst(__dynamic_cast_info*, const void*, const void*, int, bool) const; __attribute__ ((__visibility__("hidden"))) - virtual void search_below_dst(__dynamic_cast_info*, const void*, int) const; + virtual void search_below_dst(__dynamic_cast_info*, const void*, int, bool) const; __attribute__ ((__visibility__("hidden"))) virtual void has_unambiguous_public_base(__dynamic_cast_info*, void*, int) const; }; @@ -170,8 +172,8 @@ public: __offset_shift = 8 }; - void search_above_dst(__dynamic_cast_info*, const void*, const void*, int) const; - void search_below_dst(__dynamic_cast_info*, const void*, int) const; + void search_above_dst(__dynamic_cast_info*, const void*, const void*, int, bool) const; + void search_below_dst(__dynamic_cast_info*, const void*, int, bool) const; void has_unambiguous_public_base(__dynamic_cast_info*, void*, int) const; }; @@ -195,9 +197,9 @@ public: __attribute__ ((__visibility__("hidden"))) virtual ~__vmi_class_type_info(); __attribute__ ((__visibility__("hidden"))) - virtual void search_above_dst(__dynamic_cast_info*, const void*, const void*, int) const; + virtual void search_above_dst(__dynamic_cast_info*, const void*, const void*, int, bool) const; __attribute__ ((__visibility__("hidden"))) - virtual void search_below_dst(__dynamic_cast_info*, const void*, int) const; + virtual void search_below_dst(__dynamic_cast_info*, const void*, int, bool) const; __attribute__ ((__visibility__("hidden"))) virtual void has_unambiguous_public_base(__dynamic_cast_info*, void*, int) const; }; diff --git a/system/lib/libcxxabi/src/stdexcept.cpp b/system/lib/libcxxabi/src/stdexcept.cpp index 4aa962d0..de859db4 100644 --- a/system/lib/libcxxabi/src/stdexcept.cpp +++ b/system/lib/libcxxabi/src/stdexcept.cpp @@ -14,6 +14,11 @@ #include <cstdint> #include <cstddef> +#if __APPLE__ +#include <dlfcn.h> +#include <mach-o/dyld.h> +#endif + // Note: optimize for size #pragma GCC visibility push(hidden) @@ -26,13 +31,39 @@ class __libcpp_nmstr private: const char* str_; - typedef std::size_t unused_t; - typedef std::int32_t count_t; - - static const std::ptrdiff_t offset = static_cast<std::ptrdiff_t>(2*sizeof(unused_t) + - sizeof(count_t)); + typedef int count_t; + + struct _Rep_base + { + std::size_t len; + std::size_t cap; + count_t count; + }; + + static const std::ptrdiff_t offset = static_cast<std::ptrdiff_t>(sizeof(_Rep_base)); + + count_t& count() const _NOEXCEPT {return ((_Rep_base*)(str_ - offset))->count;} + +#if __APPLE__ + static + const void* + compute_gcc_empty_string_storage() _LIBCPP_CANTTHROW + { + void* handle = dlopen("/usr/lib/libstdc++.6.dylib", RTLD_NOLOAD); + if (handle == 0) + return 0; + return (const char*)dlsym(handle, "_ZNSs4_Rep20_S_empty_rep_storageE") + offset; + } + + static + const void* + get_gcc_empty_string_storage() _LIBCPP_CANTTHROW + { + static const void* p = compute_gcc_empty_string_storage(); + return p; + } +#endif - count_t& count() const _NOEXCEPT {return (count_t&)(*(str_ - sizeof(count_t)));} public: explicit __libcpp_nmstr(const char* msg); __libcpp_nmstr(const __libcpp_nmstr& s) _LIBCPP_CANTTHROW; @@ -44,9 +75,9 @@ public: __libcpp_nmstr::__libcpp_nmstr(const char* msg) { std::size_t len = strlen(msg); - str_ = new char[len + 1 + offset]; - unused_t* c = (unused_t*)str_; - c[0] = c[1] = len; + str_ = static_cast<const char*>(::operator new(len + 1 + offset)); + _Rep_base* c = (_Rep_base*)str_; + c->len = c->cap = len; str_ += offset; count() = 0; std::strcpy(const_cast<char*>(c_str()), msg); @@ -56,7 +87,10 @@ inline __libcpp_nmstr::__libcpp_nmstr(const __libcpp_nmstr& s) : str_(s.str_) { - __sync_add_and_fetch(&count(), 1); +#if __APPLE__ + if (str_ != get_gcc_empty_string_storage()) +#endif + __sync_add_and_fetch(&count(), 1); } __libcpp_nmstr& @@ -64,17 +98,30 @@ __libcpp_nmstr::operator=(const __libcpp_nmstr& s) { const char* p = str_; str_ = s.str_; - __sync_add_and_fetch(&count(), 1); - if (__sync_add_and_fetch((count_t*)(p-sizeof(count_t)), -1) < 0) - delete [] (p-offset); +#if __APPLE__ + if (str_ != get_gcc_empty_string_storage()) +#endif + __sync_add_and_fetch(&count(), 1); +#if __APPLE__ + if (p != get_gcc_empty_string_storage()) +#endif + if (__sync_add_and_fetch((count_t*)(p-sizeof(count_t)), count_t(-1)) < 0) + { + ::operator delete(const_cast<char*>(p-offset)); + } return *this; } inline __libcpp_nmstr::~__libcpp_nmstr() { - if (__sync_add_and_fetch(&count(), -1) < 0) - delete [] (str_ - offset); +#if __APPLE__ + if (str_ != get_gcc_empty_string_storage()) +#endif + if (__sync_add_and_fetch(&count(), count_t(-1)) < 0) + { + ::operator delete(const_cast<char*>(str_ - offset)); + } } } diff --git a/system/lib/libcxxabi/src/temporary.cpp b/system/lib/libcxxabi/src/temporary.cpp deleted file mode 100644 index 5facf39d..00000000 --- a/system/lib/libcxxabi/src/temporary.cpp +++ /dev/null @@ -1,41 +0,0 @@ -//===---------------------------- temporary.cpp ---------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "abort_message.h" - -#pragma GCC visibility push(default) - -extern "C" -{ - -static -void f1() -{ - abort_message("__cxa_new_handler shouldn't be called"); -} - -static -void f2() -{ - abort_message("__cxa_terminate_handler shouldn't be called"); -} - -static -void f3() -{ - abort_message("__cxa_unexpected_handler shouldn't be called"); -} - -void (*__cxa_new_handler)() = f1; -void (*__cxa_terminate_handler)() = f2; -void (*__cxa_unexpected_handler)() = f3; - -} - -#pragma GCC visibility pop diff --git a/tests/freetype/src/tools/chktrcmp.py b/tests/freetype/src/tools/chktrcmp.py index d0f342e6..33213d2d 100755 --- a/tests/freetype/src/tools/chktrcmp.py +++ b/tests/freetype/src/tools/chktrcmp.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 # # Check trace components in FreeType 2 source. # Author: suzuki toshiya, 2009 diff --git a/tests/freetype/src/tools/docmaker/docbeauty.py b/tests/freetype/src/tools/docmaker/docbeauty.py index 3ddf4a94..8718a484 100644 --- a/tests/freetype/src/tools/docmaker/docbeauty.py +++ b/tests/freetype/src/tools/docmaker/docbeauty.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 # # DocBeauty (c) 2003, 2004, 2008 David Turner <david@freetype.org> # diff --git a/tests/freetype/src/tools/docmaker/docmaker.py b/tests/freetype/src/tools/docmaker/docmaker.py index 1d9de9fb..278742fa 100644 --- a/tests/freetype/src/tools/docmaker/docmaker.py +++ b/tests/freetype/src/tools/docmaker/docmaker.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 # # DocMaker (c) 2002, 2004, 2008 David Turner <david@freetype.org> # diff --git a/tests/freetype/src/tools/glnames.py b/tests/freetype/src/tools/glnames.py index 55573b22..173a8b42 100644 --- a/tests/freetype/src/tools/glnames.py +++ b/tests/freetype/src/tools/glnames.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 # # diff --git a/tests/python/ccproxy.py b/tests/python/ccproxy.py index 82750096..98cc8c41 100644 --- a/tests/python/ccproxy.py +++ b/tests/python/ccproxy.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 from __future__ import with_statement diff --git a/tests/runner.py b/tests/runner.py index 775225c6..1f154aee 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 # This Python file uses the following encoding: utf-8 ''' @@ -199,7 +199,7 @@ sys.path += [%r] process(sys.argv[1]) ''') transform.close() - transform_args = ['--js-transform', "python %s" % transform_filename] + transform_args = ['--js-transform', "%s %s" % (PYTHON, transform_filename)] Building.emcc(filename + '.o.ll', Settings.serialize() + self.emcc_args + transform_args + Building.COMPILER_TEST_OPTS, filename + '.o.js') run_post(post2) @@ -279,7 +279,7 @@ process(sys.argv[1]) return ret def build_native(self, filename): - process = Popen([CLANG, '-O2', filename, '-o', filename+'.native'], stdout=PIPE); + process = Popen([CLANG, '-O2', '-fno-math-errno', filename, '-o', filename+'.native'], stdout=PIPE); output = process.communicate() if process.returncode is not 0: print >> sys.stderr, "Building native executable with command '%s' failed with a return code %d!" % (' '.join([CLANG, '-O2', filename, '-o', filename+'.native']), process.returncode) @@ -1679,14 +1679,14 @@ c5,de,15,8a return 0; } ''' - for named, expected in [(0, 100), (1, 0)]: + for named, expected in [(0, range(100, 200)), (1, [0])]: print named Settings.NAMED_GLOBALS = named self.do_run(src, '4:10,177,543,def\n4\nwowie\ntoo\n76\n5\n(null)\n/* a comment */\n// another\ntest\n', ['wowie', 'too', '74']) if self.emcc_args == []: gen = open(self.in_dir('src.cpp.o.js')).read() count = gen.count('GLOBAL_BASE') - assert count == expected + assert count in expected, count print ' counted' def test_strcmp_uni(self): @@ -3499,7 +3499,7 @@ The current type of b is: 9 Building.link([supp_name + '.o', main_name + '.o'], all_name) # This will fail! See explanation near the warning we check for, in the compiler source code - output = Popen(['python', EMCC, all_name], stderr=PIPE).communicate() + output = Popen([PYTHON, EMCC, all_name], stderr=PIPE).communicate() # Check for warning in the generated code generated = open(os.path.join(self.get_dir(), 'src.cpp.o.js')).read() assert 'Casting a function pointer type to another with a different number of arguments' in output[1], 'Missing expected warning' @@ -3605,6 +3605,25 @@ The current type of b is: 9 extra_emscripten_args=['-H', 'libc/time.h']) #extra_emscripten_args=['-H', 'libc/fcntl.h,libc/sys/unistd.h,poll.h,libc/math.h,libc/langinfo.h,libc/time.h']) + def test_timeb(self): + # Confirms they are called in reverse order + src = r''' + #include <stdio.h> + #include <assert.h> + #include <sys/timeb.h> + + int main() { + timeb tb; + tb.timezone = 1; + printf("*%d\n", ftime(&tb)); + assert(tb.time > 10000); + assert(tb.timezone == 0); + assert(tb.dstflag == 0); + return 0; + } + ''' + self.do_run(src, '*0\n') + def test_intentional_fault(self): # Some programs intentionally segfault themselves, we should compile that into a throw src = r''' @@ -5306,6 +5325,8 @@ def process(filename): def test_utf(self): self.banned_js_engines = [SPIDERMONKEY_ENGINE] # only node handles utf well + Settings.EXPORTED_FUNCTIONS = ['_main', '_malloc'] + src = r''' #include <stdio.h> #include <emscripten.h> @@ -5954,7 +5975,7 @@ int main(int argc, char **argv) { # emcc should build in dlmalloc automatically, and do all the sign correction etc. for it try_delete(os.path.join(self.get_dir(), 'src.cpp.o.js')) - output = Popen(['python', EMCC, path_from_root('tests', 'dlmalloc_test.c'), '-s', 'TOTAL_MEMORY=100000000', + output = Popen([PYTHON, EMCC, path_from_root('tests', 'dlmalloc_test.c'), '-s', 'TOTAL_MEMORY=100000000', '-o', os.path.join(self.get_dir(), 'src.cpp.o.js')], stdout=PIPE, stderr=self.stderr_redirect).communicate() self.do_run('x', '*1,0*', ['200', '1'], no_build=True) @@ -6580,7 +6601,7 @@ def process(filename): # Autodebug the code def do_autodebug(self, filename): - output = Popen(['python', AUTODEBUGGER, filename+'.o.ll', filename+'.o.ll.ll'], stdout=PIPE, stderr=self.stderr_redirect).communicate()[0] + output = Popen([PYTHON, AUTODEBUGGER, filename+'.o.ll', filename+'.o.ll.ll'], stdout=PIPE, stderr=self.stderr_redirect).communicate()[0] assert 'Success.' in output, output self.prep_ll_run(filename, filename+'.o.ll.ll', force_recompile=True) # rebuild .bc # TODO: use code in do_autodebug_post for this @@ -6592,7 +6613,7 @@ def process(filename): return True print 'Autodebugging during post time' delattr(self, 'post') - output = Popen(['python', AUTODEBUGGER, filename+'.o.ll', filename+'.o.ll.ll'], stdout=PIPE, stderr=self.stderr_redirect).communicate()[0] + output = Popen([PYTHON, AUTODEBUGGER, filename+'.o.ll', filename+'.o.ll.ll'], stdout=PIPE, stderr=self.stderr_redirect).communicate()[0] assert 'Success.' in output, output shutil.copyfile(filename + '.o.ll.ll', filename + '.o.ll') Building.llvm_as(filename) @@ -6773,8 +6794,8 @@ def process(filename): ''' post = ''' def process(filename): - Popen(['python', DEMANGLER, filename], stdout=open(filename + '.tmp', 'w')).communicate() - Popen(['python', NAMESPACER, filename, filename + '.tmp'], stdout=open(filename + '.tmp2', 'w')).communicate() + Popen([PYTHON, DEMANGLER, filename], stdout=open(filename + '.tmp', 'w')).communicate() + Popen([PYTHON, NAMESPACER, filename, filename + '.tmp'], stdout=open(filename + '.tmp2', 'w')).communicate() src = open(filename, 'r').read().replace( '// {{MODULE_ADDITIONS}', 'Module["_"] = ' + open(filename + '.tmp2', 'r').read().replace('var ModuleNames = ', '').rstrip() + ';\n\n' + script_src + '\n\n' + @@ -6829,7 +6850,7 @@ def process(filename): open(header_filename, 'w').write(header) basename = os.path.join(self.get_dir(), 'bindingtest') - output = Popen(['python', BINDINGS_GENERATOR, basename, header_filename], stdout=PIPE, stderr=self.stderr_redirect).communicate()[0] + output = Popen([PYTHON, BINDINGS_GENERATOR, basename, header_filename], stdout=PIPE, stderr=self.stderr_redirect).communicate()[0] #print output assert 'Traceback' not in output, 'Failure in binding generation: ' + output @@ -7002,7 +7023,7 @@ Child2:9 open(header_filename, 'w').write(header) basename = os.path.join(self.get_dir(), 'bindingtest') - output = Popen(['python', BINDINGS_GENERATOR, basename, header_filename], stdout=PIPE, stderr=self.stderr_redirect).communicate()[0] + output = Popen([PYTHON, BINDINGS_GENERATOR, basename, header_filename], stdout=PIPE, stderr=self.stderr_redirect).communicate()[0] #print output assert 'Traceback' not in output, 'Failure in binding generation: ' + output @@ -7677,7 +7698,7 @@ TT = %s suffix = '.c' if compiler == EMCC else '.cpp' # --version - output = Popen(['python', compiler, '--version'], stdout=PIPE, stderr=PIPE).communicate() + output = Popen([PYTHON, compiler, '--version'], stdout=PIPE, stderr=PIPE).communicate() self.assertContained('''emcc (Emscripten GCC-like replacement) 2.0 Copyright (C) 2012 the Emscripten authors. This is free and open source software under the MIT license. @@ -7685,11 +7706,11 @@ There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR P ''', output[0].replace('\r', ''), output[1].replace('\r', '')) # -v, without input files - output = Popen(['python', compiler, '-v'], stdout=PIPE, stderr=PIPE).communicate() + output = Popen([PYTHON, compiler, '-v'], stdout=PIPE, stderr=PIPE).communicate() self.assertContained('''clang version''', output[1].replace('\r', ''), output[1].replace('\r', '')) # --help - output = Popen(['python', compiler, '--help'], stdout=PIPE, stderr=PIPE).communicate() + output = Popen([PYTHON, compiler, '--help'], stdout=PIPE, stderr=PIPE).communicate() self.assertContained('''%s [options] file... Most normal gcc/g++ options will work, for example: @@ -7702,7 +7723,7 @@ Options that are modified or new in %s include: # emcc src.cpp ==> writes a.out.js self.clear() - output = Popen(['python', compiler, path_from_root('tests', 'hello_world' + suffix)], stdout=PIPE, stderr=PIPE).communicate() + output = Popen([PYTHON, compiler, path_from_root('tests', 'hello_world' + suffix)], stdout=PIPE, stderr=PIPE).communicate() assert len(output[0]) == 0, output[0] assert os.path.exists('a.out.js'), '\n'.join(output) self.assertContained('hello, world!', run_js('a.out.js')) @@ -7710,7 +7731,7 @@ Options that are modified or new in %s include: # properly report source code errors, and stop there self.clear() assert not os.path.exists('a.out.js') - process = Popen(['python', compiler, path_from_root('tests', 'hello_world_error' + suffix)], stdout=PIPE, stderr=PIPE) + process = Popen([PYTHON, compiler, path_from_root('tests', 'hello_world_error' + suffix)], stdout=PIPE, stderr=PIPE) output = process.communicate() assert not os.path.exists('a.out.js'), 'compilation failed, so no output file is expected' assert len(output[0]) == 0, output[0] @@ -7718,38 +7739,38 @@ Options that are modified or new in %s include: self.assertNotContained('IOError', output[1]) # no python stack self.assertNotContained('Traceback', output[1]) # no python stack self.assertContained('error: invalid preprocessing directive', output[1]) - self.assertContained("error: use of undeclared identifier 'cheez", output[1]) - self.assertContained('2 errors generated', output[1]) - assert 'emcc: compiler frontend failed to generate LLVM bitcode, halting' in output[1].split('2 errors generated.')[1] + self.assertContained(["error: use of undeclared identifier 'cheez", "error: unknown type name 'cheez'"], output[1]) + self.assertContained('errors generated', output[1]) + assert 'emcc: compiler frontend failed to generate LLVM bitcode, halting' in output[1].split('errors generated.')[1] # emcc src.cpp -c and emcc src.cpp -o src.[o|bc] ==> should give a .bc file # regression check: -o js should create "js", with bitcode content for args in [['-c'], ['-o', 'src.o'], ['-o', 'src.bc'], ['-o', 'src.so'], ['-o', 'js']]: target = args[1] if len(args) == 2 else 'hello_world.o' self.clear() - Popen(['python', compiler, path_from_root('tests', 'hello_world' + suffix)] + args, stdout=PIPE, stderr=PIPE).communicate() + Popen([PYTHON, compiler, path_from_root('tests', 'hello_world' + suffix)] + args, stdout=PIPE, stderr=PIPE).communicate() syms = Building.llvm_nm(target) assert len(syms.defs) == 1 and 'main' in syms.defs, 'Failed to generate valid bitcode' if target == 'js': # make sure emcc can recognize the target as a bitcode file shutil.move(target, target + '.bc') target += '.bc' - output = Popen(['python', compiler, target, '-o', target + '.js'], stdout = PIPE, stderr = PIPE).communicate() + output = Popen([PYTHON, compiler, target, '-o', target + '.js'], stdout = PIPE, stderr = PIPE).communicate() assert len(output[0]) == 0, output[0] assert os.path.exists(target + '.js'), 'Expected %s to exist since args are %s : %s' % (target + '.js', str(args), '\n'.join(output)) self.assertContained('hello, world!', run_js(target + '.js')) # handle singleton archives self.clear() - Popen(['python', compiler, path_from_root('tests', 'hello_world' + suffix), '-o', 'a.bc'], stdout=PIPE, stderr=PIPE).communicate() + Popen([PYTHON, compiler, path_from_root('tests', 'hello_world' + suffix), '-o', 'a.bc'], stdout=PIPE, stderr=PIPE).communicate() Popen([LLVM_AR, 'r', 'a.a', 'a.bc'], stdout=PIPE, stderr=PIPE).communicate() assert os.path.exists('a.a') - output = Popen(['python', compiler, 'a.a']).communicate() + output = Popen([PYTHON, compiler, 'a.a']).communicate() assert os.path.exists('a.out.js'), output self.assertContained('hello, world!', run_js('a.out.js')) # emcc src.ll ==> generates .js self.clear() - output = Popen(['python', compiler, path_from_root('tests', 'hello_world.ll')], stdout=PIPE, stderr=PIPE).communicate() + output = Popen([PYTHON, compiler, path_from_root('tests', 'hello_world.ll')], stdout=PIPE, stderr=PIPE).communicate() assert len(output[0]) == 0, output[0] assert os.path.exists('a.out.js'), '\n'.join(output) self.assertContained('hello, world!', run_js('a.out.js')) @@ -7761,7 +7782,7 @@ Options that are modified or new in %s include: os.mkdir('b_dir') for path in [os.path.abspath(os.path.join('..', 'file1.js')), os.path.join('b_dir', 'file2.js')]: self.clear(in_curr=True) - output = Popen(['python', compiler, path_from_root('tests', 'hello_world.ll'), '-o', path], stdout=PIPE, stderr=PIPE).communicate() + output = Popen([PYTHON, compiler, path_from_root('tests', 'hello_world.ll'), '-o', path], stdout=PIPE, stderr=PIPE).communicate() assert os.path.exists(path), path + ' does not exist; ' + '\n'.join(output) self.assertContained('hello, world!', run_js(path)) finally: @@ -7775,7 +7796,7 @@ Options that are modified or new in %s include: # very speed-sensitive. So we do not implement it in JS in library.js, instead we compile it from source for source, has_malloc in [('hello_world' + suffix, False), ('hello_malloc.cpp', True)]: self.clear() - output = Popen(['python', compiler, path_from_root('tests', source)], stdout=PIPE, stderr=PIPE).communicate() + output = Popen([PYTHON, compiler, path_from_root('tests', source)], stdout=PIPE, stderr=PIPE).communicate() assert os.path.exists('a.out.js'), '\n'.join(output) self.assertContained('hello, world!', run_js('a.out.js')) generated = open('a.out.js').read() @@ -7801,14 +7822,14 @@ Options that are modified or new in %s include: ]: #print params, opt_level, bc_params, closure self.clear() - output = Popen(['python', compiler, path_from_root('tests', 'hello_world_loop' + ('_malloc' if has_malloc else '') + '.cpp')] + params, + output = Popen([PYTHON, compiler, path_from_root('tests', 'hello_world_loop' + ('_malloc' if has_malloc else '') + '.cpp')] + params, stdout=PIPE, stderr=PIPE).communicate() assert len(output[0]) == 0, output[0] if bc_params is not None: if '-O1' in params and 'something.bc' in params: assert 'warning: -Ox flags ignored, since not generating JavaScript' in output[1] assert os.path.exists('something.bc'), output[1] - output = Popen(['python', compiler, 'something.bc', '-o', 'something.js'] + bc_params, stdout=PIPE, stderr=PIPE).communicate() + output = Popen([PYTHON, compiler, 'something.bc', '-o', 'something.js'] + bc_params, stdout=PIPE, stderr=PIPE).communicate() assert os.path.exists('something.js'), output[1] assert ('Warning: Applying some potentially unsafe optimizations!' in output[1]) == (opt_level >= 3), 'unsafe warning should appear in opt >= 3' self.assertContained('hello, world!', run_js('something.js')) @@ -7827,9 +7848,9 @@ Options that are modified or new in %s include: # XXX find a way to test this: assert ('& 255' in generated or '&255' in generated) == (opt_level <= 2), 'corrections should be in opt <= 2' assert ('(label)' in generated) == (opt_level <= 1), 'relooping should be in opt >= 2' assert ('assert(STACKTOP < STACK_MAX' in generated) == (opt_level == 0), 'assertions should be in opt == 0' - assert 'var $i;' in generated or 'var $i_01;' in generated or 'var $storemerge3;' in generated or 'var $storemerge4;' in generated or 'var $i_04;' in generated, 'micro opts should always be on' + assert 'var $i;' in generated or 'var $i_0' in generated or 'var $storemerge3;' in generated or 'var $storemerge4;' in generated or 'var $i_04;' in generated, 'micro opts should always be on' if opt_level >= 2: - assert 'HEAP8[HEAP32[' in generated or 'HEAP8[$vla1 + (($storemerge4 | 0) / 2 & -1) | 0]' in generated or 'HEAP8[$vla1 + (($storemerge4 | 0) / 2 & -1) | 0]' in generated or 'HEAP8[$vla1 + (($i_04 | 0) / 2 & -1) | 0]' in generated or 'HEAP8[$vla1 + ($i_04 / 2 & -1)]' in generated or 'HEAP8[$1 + (($i_01 | 0) / 2 & -1) | 0]' in generated or 'HEAP8[$1 + (($i_01 | 0) / 2 & -1) | 0]' in generated or 'HEAP8[$1 + ($i_01 / 2 & -1)]' in generated, 'eliminator should create compound expressions, and fewer one-time vars' # also in -O1, but easier to test in -O2 + assert 'HEAP8[$0 + ($i_' in generated or 'HEAP8[$0 + (($i_0' in generated or 'HEAP8[HEAP32[' in generated or 'HEAP8[$vla1 + (($storemerge4 | 0) / 2 & -1) | 0]' in generated or 'HEAP8[$vla1 + (($storemerge4 | 0) / 2 & -1) | 0]' in generated or 'HEAP8[$vla1 + (($i_04 | 0) / 2 & -1) | 0]' in generated or 'HEAP8[$vla1 + ($i_04 / 2 & -1)]' in generated or 'HEAP8[$1 + (($i_01 | 0) / 2 & -1) | 0]' in generated or 'HEAP8[$1 + (($i_01 | 0) / 2 & -1) | 0]' in generated or 'HEAP8[$1 + ($i_01 / 2 & -1)]' in 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' assert ('function _malloc(bytes) {' in generated) == (not has_malloc), 'If malloc is needed, it should be there, if not not' assert 'function _main() {' in generated, 'Should be unminified, including whitespace' @@ -7849,7 +7870,7 @@ Options that are modified or new in %s include: (['--llvm-opts', '1'], lambda generated: '_puts(' in generated, 'llvm opts requested'), ]: self.clear() - output = Popen(['python', compiler, path_from_root('tests', 'hello_world_loop.cpp'), '-o', 'a.out.js'] + params, stdout=PIPE, stderr=PIPE).communicate() + output = Popen([PYTHON, compiler, path_from_root('tests', 'hello_world_loop.cpp'), '-o', 'a.out.js'] + params, stdout=PIPE, stderr=PIPE).communicate() assert len(output[0]) == 0, output[0] assert os.path.exists('a.out.js'), '\n'.join(output) self.assertContained('hello, world!', run_js('a.out.js')) @@ -7858,7 +7879,7 @@ Options that are modified or new in %s include: # Compiling two source files into a final JS. for args, target in [([], 'a.out.js'), (['-o', 'combined.js'], 'combined.js')]: self.clear() - output = Popen(['python', compiler, path_from_root('tests', 'twopart_main.cpp'), path_from_root('tests', 'twopart_side.cpp')] + args, + output = Popen([PYTHON, compiler, path_from_root('tests', 'twopart_main.cpp'), path_from_root('tests', 'twopart_side.cpp')] + args, stdout=PIPE, stderr=PIPE).communicate() assert len(output[0]) == 0, output[0] assert os.path.exists(target), '\n'.join(output) @@ -7866,7 +7887,7 @@ Options that are modified or new in %s include: # Compiling two files with -c will generate separate .bc files self.clear() - output = Popen(['python', compiler, path_from_root('tests', 'twopart_main.cpp'), path_from_root('tests', 'twopart_side.cpp'), '-c'] + args, + output = Popen([PYTHON, compiler, path_from_root('tests', 'twopart_main.cpp'), path_from_root('tests', 'twopart_side.cpp'), '-c'] + args, stdout=PIPE, stderr=PIPE).communicate() if '-o' in args: # specifying -o and -c is an error @@ -7878,24 +7899,24 @@ Options that are modified or new in %s include: assert not os.path.exists(target), 'We should only have created bitcode here: ' + '\n'.join(output) # Compiling one of them alone is expected to fail - output = Popen(['python', compiler, 'twopart_main.o'] + args, stdout=PIPE, stderr=PIPE).communicate() + output = Popen([PYTHON, compiler, 'twopart_main.o'] + args, stdout=PIPE, stderr=PIPE).communicate() assert os.path.exists(target), '\n'.join(output) #print '\n'.join(output) self.assertContained('is not a function', run_js(target, stderr=STDOUT)) try_delete(target) # Combining those bc files into js should work - output = Popen(['python', compiler, 'twopart_main.o', 'twopart_side.o'] + args, stdout=PIPE, stderr=PIPE).communicate() + output = Popen([PYTHON, compiler, 'twopart_main.o', 'twopart_side.o'] + args, stdout=PIPE, stderr=PIPE).communicate() assert os.path.exists(target), '\n'.join(output) self.assertContained('side got: hello from main, over', run_js(target)) # Combining bc files into another bc should also work try_delete(target) assert not os.path.exists(target) - output = Popen(['python', compiler, 'twopart_main.o', 'twopart_side.o', '-o', 'combined.bc'] + args, stdout=PIPE, stderr=PIPE).communicate() + output = Popen([PYTHON, compiler, 'twopart_main.o', 'twopart_side.o', '-o', 'combined.bc'] + args, stdout=PIPE, stderr=PIPE).communicate() syms = Building.llvm_nm('combined.bc') assert len(syms.defs) == 2 and 'main' in syms.defs, 'Failed to generate valid bitcode' - output = Popen(['python', compiler, 'combined.bc', '-o', 'combined.bc.js'], stdout = PIPE, stderr = PIPE).communicate() + output = Popen([PYTHON, compiler, 'combined.bc', '-o', 'combined.bc.js'], stdout = PIPE, stderr = PIPE).communicate() assert len(output[0]) == 0, output[0] assert os.path.exists('combined.bc.js'), 'Expected %s to exist' % ('combined.bc.js') self.assertContained('side got: hello from main, over', run_js('combined.bc.js')) @@ -7911,7 +7932,7 @@ f.write('transformed!') f.close() ''') trans_file.close() - output = Popen(['python', compiler, path_from_root('tests', 'hello_world' + suffix), '--js-transform', 'python t.py'], stdout=PIPE, stderr=PIPE).communicate() + output = Popen([PYTHON, compiler, path_from_root('tests', 'hello_world' + suffix), '--js-transform', '%s t.py' % (PYTHON)], stdout=PIPE, stderr=PIPE).communicate() assert open('a.out.js').read() == 'transformed!', 'Transformed output must be as expected' # TODO: Add in files test a clear example of using disablePermissions, and link to it from the wiki @@ -7977,14 +7998,14 @@ f.close() def test_failure_error_code(self): for compiler in [EMCC, EMXX]: # Test that if one file is missing from the build, then emcc shouldn't succeed, and shouldn't try to produce an output file. - process = Popen(['python', compiler, path_from_root('tests', 'hello_world.c'), 'this_file_is_missing.c', '-o', 'this_output_file_should_never_exist.js'], stdout=PIPE, stderr=PIPE) + process = Popen([PYTHON, compiler, path_from_root('tests', 'hello_world.c'), 'this_file_is_missing.c', '-o', 'this_output_file_should_never_exist.js'], stdout=PIPE, stderr=PIPE) process.communicate() assert process.returncode is not 0, 'Trying to compile a nonexisting file should return with a nonzero error code!' assert os.path.exists('this_output_file_should_never_exist.js') == False, 'Emcc should not produce an output file when build fails!' def test_Os(self): for opt in ['s', '0']: - output = Popen(['python', EMCC, path_from_root('tests', 'hello_world.c'), '-O' + opt], stdout=PIPE, stderr=PIPE).communicate() + output = Popen([PYTHON, EMCC, path_from_root('tests', 'hello_world.c'), '-O' + opt], stdout=PIPE, stderr=PIPE).communicate() assert len(output[0]) == 0, output[0] assert ('emcc: warning: -Os is ignored (use -O0, -O1, -O2)' in output[1]) == (opt == 's'), 'warn on -Os when necessary' assert os.path.exists('a.out.js'), '\n'.join(output) @@ -8007,7 +8028,7 @@ f.close() return 0; } ''') - Popen(['python', EMCC, os.path.join(self.get_dir(), 'test.cpp'), '-fcatch-undefined-behavior']).communicate() + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'test.cpp'), '-fcatch-undefined-behavior']).communicate() self.assertContained('hello, world!', run_js(os.path.join(self.get_dir(), 'a.out.js'))) def test_unaligned_memory(self): @@ -8027,7 +8048,7 @@ f.close() printf("data[1,2] 16bit: %x\n", *(Bit16u*)(data+1)); } ''') - Popen(['python', EMCC, os.path.join(self.get_dir(), 'test.cpp'), '-s', 'UNALIGNED_MEMORY=1']).communicate() + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'test.cpp'), '-s', 'UNALIGNED_MEMORY=1']).communicate() self.assertContained('data: 67452301\ndata[0,1] 16bit: 2301\ndata[1,2] 16bit: 4523', run_js(os.path.join(self.get_dir(), 'a.out.js'))) def test_unaligned_memory_2(self): @@ -8043,7 +8064,7 @@ f.close() return 0; } ''') - Popen(['python', EMCC, os.path.join(self.get_dir(), 'test.cpp'), '-s', 'UNALIGNED_MEMORY=1']).communicate() + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'test.cpp'), '-s', 'UNALIGNED_MEMORY=1']).communicate() self.assertContained('testString = Hello, World!', run_js(os.path.join(self.get_dir(), 'a.out.js'))) def test_l_link(self): @@ -8069,9 +8090,9 @@ f.close() } ''') - Popen(['python', EMCC, os.path.join(self.get_dir(), 'libdir', 'libfile.cpp'), '-c']).communicate() + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'libdir', 'libfile.cpp'), '-c']).communicate() shutil.move(os.path.join(self.get_dir(), 'libfile.o'), os.path.join(self.get_dir(), 'libdir', 'libfile.so')) - Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp'), '-L' + os.path.join(self.get_dir(), 'libdir'), '-lfile']).communicate() + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'main.cpp'), '-L' + os.path.join(self.get_dir(), 'libdir'), '-lfile']).communicate() self.assertContained('hello from lib', run_js(os.path.join(self.get_dir(), 'a.out.js'))) assert not os.path.exists('a.out') and not os.path.exists('a.exe'), 'Must not leave unneeded linker stubs' @@ -8139,6 +8160,27 @@ f.close() self.assertContained('result: 62', run_js(os.path.join(self.get_dir(), 'a.out.js'))) + def test_redundant_link(self): + lib = "int mult() { return 1; }" + lib_name = os.path.join(self.get_dir(), 'libA.c') + open(lib_name, 'w').write(lib) + main = r''' + #include <stdio.h> + int mult(); + int main() { + printf("result: %d\n", mult()); + return 0; + } + ''' + main_name = os.path.join(self.get_dir(), 'main.c') + open(main_name, 'w').write(main) + + Building.emcc(lib_name, output_filename='libA.so') + + Building.emcc(main_name, ['libA.so']*2, output_filename='a.out.js') + + self.assertContained('result: 1', run_js(os.path.join(self.get_dir(), 'a.out.js'))) + def test_abspaths(self): # Includes with absolute paths are generally dangerous, things like -I/usr/.. will get to system local headers, not our portable ones. @@ -8149,7 +8191,7 @@ f.close() (['-Isubdir/something'], False), (['-Lsubdir/something'], False), ([], False)]: - err = Popen(['python', EMCC, 'main.c'] + args, stderr=PIPE).communicate()[1] + err = Popen([PYTHON, EMCC, 'main.c'] + args, stderr=PIPE).communicate()[1] assert ('emcc: warning: -I or -L of an absolute path encountered. If this is to a local system header/library, it may cause problems (local system files make sense for compiling natively on your system, but not necessarily to JavaScript)' in err) == expected, err def test_local_link(self): @@ -8177,8 +8219,8 @@ f.close() } ''') - Popen(['python', EMCC, os.path.join(self.get_dir(), 'libfile.cpp'), '-o', 'libfile.so']).communicate() - Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp'), os.path.join(self.get_dir(), 'subdir', 'libfile.so'), '-L.'], stderr=PIPE).communicate() + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'libfile.cpp'), '-o', 'libfile.so']).communicate() + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'main.cpp'), os.path.join(self.get_dir(), 'subdir', 'libfile.so'), '-L.'], stderr=PIPE).communicate() self.assertContained('hello from lib', run_js(os.path.join(self.get_dir(), 'a.out.js'))) def test_runtimelink_multi(self): @@ -8239,11 +8281,11 @@ f.close() } ''') - Popen(['python', EMCC, 'testa.cpp', '-o', 'liba.js', '-s', 'BUILD_AS_SHARED_LIB=2', '-s', 'LINKABLE=1', '-I.']).communicate() - Popen(['python', EMCC, 'testb.cpp', '-o', 'libb.js', '-s', 'BUILD_AS_SHARED_LIB=2', '-s', 'LINKABLE=1', '-I.']).communicate() - Popen(['python', EMCC, 'main.cpp', '-o', 'main.js', '-s', 'RUNTIME_LINKED_LIBS=["liba.js", "libb.js"]', '-I.']).communicate() + Popen([PYTHON, EMCC, 'testa.cpp', '-o', 'liba.js', '-s', 'BUILD_AS_SHARED_LIB=2', '-s', 'LINKABLE=1', '-I.']).communicate() + Popen([PYTHON, EMCC, 'testb.cpp', '-o', 'libb.js', '-s', 'BUILD_AS_SHARED_LIB=2', '-s', 'LINKABLE=1', '-I.']).communicate() + Popen([PYTHON, EMCC, 'main.cpp', '-o', 'main.js', '-s', 'RUNTIME_LINKED_LIBS=["liba.js", "libb.js"]', '-I.']).communicate() - Popen(['python', EMCC, 'main.cpp', 'testa.cpp', 'testb.cpp', '-o', 'full.js', '-I.']).communicate() + Popen([PYTHON, EMCC, 'main.cpp', 'testa.cpp', 'testb.cpp', '-o', 'full.js', '-I.']).communicate() self.assertContained('TestA\nTestB\nTestA\n', run_js('main.js', engine=SPIDERMONKEY_ENGINE)) @@ -8275,7 +8317,7 @@ f.close() }); ''') - Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp'), '--js-library', os.path.join(self.get_dir(), 'mylib1.js'), + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'main.cpp'), '--js-library', os.path.join(self.get_dir(), 'mylib1.js'), '--js-library', os.path.join(self.get_dir(), 'mylib2.js')]).communicate() self.assertContained('hello from lib!\n*32*\n', run_js(os.path.join(self.get_dir(), 'a.out.js'))) @@ -8302,40 +8344,16 @@ f.close() void printey() { printf("hello there\\n"); } ''') - Popen(['python', EMCC, os.path.join(self.get_dir(), 'foo', 'main.cpp'), os.path.join(self.get_dir(), 'bar', 'main.cpp')]).communicate() + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'foo', 'main.cpp'), os.path.join(self.get_dir(), 'bar', 'main.cpp')]).communicate() self.assertContained('hello there', run_js(os.path.join(self.get_dir(), 'a.out.js'))) # ditto with first creating .o files try_delete(os.path.join(self.get_dir(), 'a.out.js')) - Popen(['python', EMCC, os.path.join(self.get_dir(), 'foo', 'main.cpp'), '-o', os.path.join(self.get_dir(), 'foo', 'main.o')]).communicate() - Popen(['python', EMCC, os.path.join(self.get_dir(), 'bar', 'main.cpp'), '-o', os.path.join(self.get_dir(), 'bar', 'main.o')]).communicate() - Popen(['python', EMCC, os.path.join(self.get_dir(), 'foo', 'main.o'), os.path.join(self.get_dir(), 'bar', 'main.o')]).communicate() + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'foo', 'main.cpp'), '-o', os.path.join(self.get_dir(), 'foo', 'main.o')]).communicate() + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'bar', 'main.cpp'), '-o', os.path.join(self.get_dir(), 'bar', 'main.o')]).communicate() + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'foo', 'main.o'), os.path.join(self.get_dir(), 'bar', 'main.o')]).communicate() self.assertContained('hello there', run_js(os.path.join(self.get_dir(), 'a.out.js'))) - def test_remove_duplicates(self): - # can happen with .a files. we do a best-effort, removing dupes - open(os.path.join(self.get_dir(), 'main.cpp'), 'w').write(''' - #include<stdio.h> - void printey() { printf("bye bye\\n"); } - int main() { - printey(); - return 0; - } - ''') - open(os.path.join(self.get_dir(), 'side.cpp'), 'w').write(''' - #include<stdio.h> - void printey() { printf("bye bye\\n"); } - ''') - - # without --remove-duplicates, we fail - err = Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp'), os.path.join(self.get_dir(), 'side.cpp')], stderr=PIPE).communicate()[1] - assert not os.path.exists('a.out.js') - assert 'multiply' in err - - # with it, we succeed - err = Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp'), os.path.join(self.get_dir(), 'side.cpp'), '--remove-duplicates'], stderr=PIPE).communicate()[1] - self.assertContained('bye bye', run_js(os.path.join(self.get_dir(), 'a.out.js'))) - def test_main_a(self): # if main() is in a .a, we need to pull in that .a @@ -8355,12 +8373,12 @@ f.close() int f() { return 12346; } ''') - Popen(['python', EMCC, main_name, '-c', '-o', main_name+'.bc']).communicate() - Popen(['python', EMCC, other_name, '-c', '-o', other_name+'.bc']).communicate() + Popen([PYTHON, EMCC, main_name, '-c', '-o', main_name+'.bc']).communicate() + Popen([PYTHON, EMCC, other_name, '-c', '-o', other_name+'.bc']).communicate() - Popen(['python', EMAR, 'cr', main_name+'.a', main_name+'.bc']).communicate() + Popen([PYTHON, EMAR, 'cr', main_name+'.a', main_name+'.bc']).communicate() - Popen(['python', EMCC, other_name+'.bc', main_name+'.a']).communicate() + Popen([PYTHON, EMCC, other_name+'.bc', main_name+'.a']).communicate() self.assertContained('result: 12346.', run_js(os.path.join(self.get_dir(), 'a.out.js'))) @@ -8371,8 +8389,8 @@ f.close() printf("a\n"); } ''') - Popen(['python', EMCC, 'common.c', '-c', '-o', 'common.o']).communicate() - Popen(['python', EMAR, 'rc', 'liba.a', 'common.o']).communicate() + Popen([PYTHON, EMCC, 'common.c', '-c', '-o', 'common.o']).communicate() + Popen([PYTHON, EMAR, 'rc', 'liba.a', 'common.o']).communicate() open('common.c', 'w').write(r''' #include <stdio.h> @@ -8380,8 +8398,8 @@ f.close() printf("b\n"); } ''') - Popen(['python', EMCC, 'common.c', '-c', '-o', 'common.o']).communicate() - Popen(['python', EMAR, 'rc', 'libb.a', 'common.o']).communicate() + Popen([PYTHON, EMCC, 'common.c', '-c', '-o', 'common.o']).communicate() + Popen([PYTHON, EMAR, 'rc', 'libb.a', 'common.o']).communicate() open('main.c', 'w').write(r''' void a(void); @@ -8391,7 +8409,7 @@ f.close() b(); } ''') - Popen(['python', EMCC, 'main.c', '-L.', '-la', '-lb']).communicate() + Popen([PYTHON, EMCC, 'main.c', '-L.', '-la', '-lb']).communicate() self.assertContained('a\nb\n', run_js(os.path.join(self.get_dir(), 'a.out.js'))) @@ -8410,11 +8428,11 @@ f.close() } ''') - Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp'), '--embed-file', 'somefile.txt']).communicate() + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'main.cpp'), '--embed-file', 'somefile.txt']).communicate() self.assertContained('|hello from a file wi|', run_js(os.path.join(self.get_dir(), 'a.out.js'))) # preload twice, should not err - Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp'), '--embed-file', 'somefile.txt', '--embed-file', 'somefile.txt']).communicate() + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'main.cpp'), '--embed-file', 'somefile.txt', '--embed-file', 'somefile.txt']).communicate() self.assertContained('|hello from a file wi|', run_js(os.path.join(self.get_dir(), 'a.out.js'))) def test_embed_file_dup(self): @@ -8446,7 +8464,7 @@ f.close() } ''') - Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp'), '--embed-file', 'tst']).communicate() + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'main.cpp'), '--embed-file', 'tst']).communicate() self.assertContained('|frist|\n|sacond|\n|thard|\n', run_js(os.path.join(self.get_dir(), 'a.out.js'))) def test_multidynamic_link(self): @@ -8491,7 +8509,7 @@ f.close() ''') # This lets us link the same dynamic lib twice. We will need to link it in manually at the end. - compiler = ['python', EMCC, '--ignore-dynamic-linking'] + compiler = [PYTHON, EMCC, '--ignore-dynamic-linking'] # Build libfile normally into an .so Popen(compiler + [os.path.join(self.get_dir(), 'libdir', 'libfile.cpp'), '-o', os.path.join(self.get_dir(), 'libdir', 'libfile.so')]).communicate() @@ -8501,7 +8519,7 @@ f.close() Popen(compiler + [os.path.join(self.get_dir(), 'main.cpp'), '-L' + os.path.join(self.get_dir(), 'libdir'), '-lfile', '-lother', '-c']).communicate() # The normal build system is over. We need to do an additional step to link in the dynamic libraries, since we ignored them before - Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.o'), '-L' + os.path.join(self.get_dir(), 'libdir'), '-lfile', '-lother']).communicate() + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'main.o'), '-L' + os.path.join(self.get_dir(), 'libdir'), '-lfile', '-lother']).communicate() self.assertContained('*hello from lib\n|hello from lib|\n*', run_js(os.path.join(self.get_dir(), 'a.out.js'))) @@ -8521,7 +8539,7 @@ f.close() Module.print(MESSAGE); ''') - Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp'), '--pre-js', 'before.js', '--post-js', 'after.js']).communicate() + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'main.cpp'), '--pre-js', 'before.js', '--post-js', 'after.js']).communicate() self.assertContained('hello from main\nhello from js\n', run_js(os.path.join(self.get_dir(), 'a.out.js'))) def test_sdl_endianness(self): @@ -8534,7 +8552,7 @@ f.close() return 0; } ''') - Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp')]).communicate() + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'main.cpp')]).communicate() self.assertContained('1234, 1234, 4321\n', run_js(os.path.join(self.get_dir(), 'a.out.js'))) def test_warn_undefined(self): @@ -8550,10 +8568,10 @@ f.close() return 0; } ''') - output = Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp'), '-s', 'WARN_ON_UNDEFINED_SYMBOLS=1'], stderr=PIPE).communicate() + output = Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'main.cpp'), '-s', 'WARN_ON_UNDEFINED_SYMBOLS=1'], stderr=PIPE).communicate() self.assertContained('Unresolved symbol: _something', output[1]) - output = Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp')], stderr=PIPE).communicate() + output = Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'main.cpp')], stderr=PIPE).communicate() self.assertNotContained('Unresolved symbol: _something\n', output[1]) def test_toobig(self): @@ -8579,7 +8597,7 @@ f.close() return 0; } ''') - output = Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp')], stderr=PIPE).communicate()[1] + output = Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'main.cpp')], stderr=PIPE).communicate()[1] assert 'Emscripten failed' in output, output assert 'warning: very large fixed-size structural type' in output, output @@ -8598,7 +8616,7 @@ f.close() }; ''') - Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp'), '--pre-js', 'pre.js']).communicate() + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'main.cpp'), '--pre-js', 'pre.js']).communicate() self.assertContained('pre-run\nhello from main\npost-run\n', run_js(os.path.join(self.get_dir(), 'a.out.js'))) # never run, so no preRun or postRun @@ -8608,7 +8626,7 @@ f.close() # noInitialRun prevents run for no_initial_run in [0, 1]: - Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp')]).communicate() + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'main.cpp')]).communicate() src = 'var Module = { noInitialRun: %d };\n' % no_initial_run + open(os.path.join(self.get_dir(), 'a.out.js')).read() open(os.path.join(self.get_dir(), 'a.out.js'), 'w').write(src) assert ('hello from main' in run_js(os.path.join(self.get_dir(), 'a.out.js'))) != no_initial_run, 'only run if no noInitialRun' @@ -8627,7 +8645,7 @@ f.close() preInit: function() { Module.print('pre-init') } }; ''') - Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp'), '--pre-js', 'pre.js']).communicate() + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'main.cpp'), '--pre-js', 'pre.js']).communicate() self.assertContained('pre-init\npre-run\nhello from main\npost-run\n', run_js(os.path.join(self.get_dir(), 'a.out.js'))) def test_prepost2(self): @@ -8646,7 +8664,7 @@ f.close() open(os.path.join(self.get_dir(), 'pre2.js'), 'w').write(''' Module.postRun = function() { Module.print('post-run') }; ''') - Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp'), '--pre-js', 'pre.js', '--pre-js', 'pre2.js']).communicate() + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'main.cpp'), '--pre-js', 'pre.js', '--pre-js', 'pre2.js']).communicate() self.assertContained('pre-run\nhello from main\npost-run\n', run_js(os.path.join(self.get_dir(), 'a.out.js'))) def test_prepre(self): @@ -8665,13 +8683,13 @@ f.close() open(os.path.join(self.get_dir(), 'pre2.js'), 'w').write(''' Module.preRun.push(function() { Module.print('prepre') }); ''') - Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp'), '--pre-js', 'pre.js', '--pre-js', 'pre2.js']).communicate() + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'main.cpp'), '--pre-js', 'pre.js', '--pre-js', 'pre2.js']).communicate() self.assertContained('prepre\npre-run\nhello from main\n', run_js(os.path.join(self.get_dir(), 'a.out.js'))) def test_fix_closure(self): input = path_from_root('tests', 'test-fix-closure.js') expected = path_from_root('tests', 'test-fix-closure.out.js') - Popen(['python', path_from_root('tools', 'fix_closure.py'), input, 'out.js']).communicate(input) + Popen([PYTHON, path_from_root('tools', 'fix_closure.py'), input, 'out.js']).communicate(input) output = open('out.js').read() assert '0,zzz_Q_39fa,0' in output assert 'function(a,c)' not in output # should be uninlined, so it gets a name @@ -8701,7 +8719,7 @@ f.close() def test_m_mm(self): open(os.path.join(self.get_dir(), 'foo.c'), 'w').write('''#include <emscripten.h>''') for opt in ['M', 'MM']: - output, err = Popen(['python', EMCC, os.path.join(self.get_dir(), 'foo.c'), '-' + opt], stdout=PIPE, stderr=PIPE).communicate() + output, err = Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'foo.c'), '-' + opt], stdout=PIPE, stderr=PIPE).communicate() assert 'foo.o: ' in output, '-%s failed to produce the right output: %s' % (opt, output) assert 'error' not in err, 'Unexpected stderr: ' + err @@ -8710,7 +8728,7 @@ f.close() if multiprocessing.cpu_count() < 2: return self.skip('need multiple cores') try: os.environ['EMCC_DEBUG'] = '1' - output, err = Popen(['python', EMCC, path_from_root('tests', 'hello_libcxx.cpp'), '-O1'], stdout=PIPE, stderr=PIPE).communicate() + output, err = Popen([PYTHON, EMCC, path_from_root('tests', 'hello_libcxx.cpp'), '-O1'], stdout=PIPE, stderr=PIPE).communicate() assert 'phase 2 working on 3 chunks' in err, err assert 'splitting up js optimization into 2 chunks' in err, err finally: @@ -8733,8 +8751,9 @@ f.close() # XXX TODO (['--bind', '-O2'], False) ]: print args, fail + self.clear() try_delete(self.in_dir('a.out.js')) - Popen(['python', EMCC, path_from_root('tests', 'embind', 'embind_test.cpp'), '--post-js', path_from_root('tests', 'embind', 'embind_test.js')] + args, stderr=PIPE if fail else None).communicate() + Popen([PYTHON, EMCC, path_from_root('tests', 'embind', 'embind_test.cpp'), '--post-js', path_from_root('tests', 'embind', 'embind_test.js')] + args, stderr=PIPE if fail else None).communicate() assert os.path.exists(self.in_dir('a.out.js')) == (not fail) if not fail: output = run_js(self.in_dir('a.out.js')) @@ -8798,8 +8817,8 @@ fixture: interfaces open(os.path.join(self.get_dir(), 'somefile.binary'), 'w').write('''waka waka############################''') open(os.path.join(self.get_dir(), 'test.file'), 'w').write('''ay file..............,,,,,,,,,,,,,,''') open(os.path.join(self.get_dir(), 'stdin'), 'w').write('''inter-active''') - Popen(['python', EMCC, os.path.join(self.get_dir(), 'files.cpp'), '-c']).communicate() - Popen(['python', path_from_root('tools', 'nativize_llvm.py'), os.path.join(self.get_dir(), 'files.o')]).communicate(input)[0] + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'files.cpp'), '-c']).communicate() + Popen([PYTHON, path_from_root('tools', 'nativize_llvm.py'), os.path.join(self.get_dir(), 'files.o')]).communicate(input)[0] output = Popen([os.path.join(self.get_dir(), 'files.o.run')], stdin=open(os.path.join(self.get_dir(), 'stdin')), stdout=PIPE, stderr=PIPE).communicate() self.assertIdentical('''size: 37 data: 119,97,107,97,32,119,97,107,97,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35 @@ -8817,7 +8836,7 @@ fscanfed: 10 - hello self.assertIdentical('texte\n', output[1]) def test_emconfig(self): - output = Popen(['python', EMCONFIG, 'LLVM_ROOT'], stdout=PIPE, stderr=PIPE).communicate()[0].strip() + output = Popen([PYTHON, EMCONFIG, 'LLVM_ROOT'], stdout=PIPE, stderr=PIPE).communicate()[0].strip() try: assert output == LLVM_ROOT except: @@ -8825,16 +8844,16 @@ fscanfed: 10 - hello raise invalid = 'Usage: em-config VAR_NAME' # Don't accept variables that do not exist - output = Popen(['python', EMCONFIG, 'VAR_WHICH_DOES_NOT_EXIST'], stdout=PIPE, stderr=PIPE).communicate()[0].strip() + output = Popen([PYTHON, EMCONFIG, 'VAR_WHICH_DOES_NOT_EXIST'], stdout=PIPE, stderr=PIPE).communicate()[0].strip() assert output == invalid # Don't accept no arguments - output = Popen(['python', EMCONFIG], stdout=PIPE, stderr=PIPE).communicate()[0].strip() + output = Popen([PYTHON, EMCONFIG], stdout=PIPE, stderr=PIPE).communicate()[0].strip() assert output == invalid # Don't accept more than one variable - output = Popen(['python', EMCONFIG, 'LLVM_ROOT', 'EMCC'], stdout=PIPE, stderr=PIPE).communicate()[0].strip() + output = Popen([PYTHON, EMCONFIG, 'LLVM_ROOT', 'EMCC'], stdout=PIPE, stderr=PIPE).communicate()[0].strip() assert output == invalid # Don't accept arbitrary python code - output = Popen(['python', EMCONFIG, 'sys.argv[1]'], stdout=PIPE, stderr=PIPE).communicate()[0].strip() + output = Popen([PYTHON, EMCONFIG, 'sys.argv[1]'], stdout=PIPE, stderr=PIPE).communicate()[0].strip() assert output == invalid def test_link_s(self): @@ -8858,10 +8877,10 @@ fscanfed: 10 - hello } } ''') - Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp'), '-o', 'main.o']).communicate() - Popen(['python', EMCC, os.path.join(self.get_dir(), 'supp.cpp'), '-o', 'supp.o']).communicate() + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'main.cpp'), '-o', 'main.o']).communicate() + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'supp.cpp'), '-o', 'supp.o']).communicate() - output = Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.o'), '-s', os.path.join(self.get_dir(), 'supp.o'), '-s', 'SAFE_HEAP=1'], stderr=PIPE).communicate() + output = Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'main.o'), '-s', os.path.join(self.get_dir(), 'supp.o'), '-s', 'SAFE_HEAP=1'], stderr=PIPE).communicate() self.assertContained('emcc: warning: treating -s as linker option', output[1]) output = run_js('a.out.js') assert 'yello' in output, 'code works' @@ -8875,7 +8894,7 @@ fscanfed: 10 - hello } ''') os.environ["EMMAKEN_JUST_CONFIGURE"] = "1" - cmd = ['python', EMCC, '-s', 'ASSERTIONS=1', os.path.join(self.get_dir(), 'conftest.c'), '-o', 'conftest'] + cmd = [PYTHON, EMCC, '-s', 'ASSERTIONS=1', os.path.join(self.get_dir(), 'conftest.c'), '-o', 'conftest'] output = Popen(cmd, stderr=PIPE).communicate() del os.environ["EMMAKEN_JUST_CONFIGURE"] self.assertNotContained('emcc: warning: treating -s as linker option', output[1]) @@ -8885,26 +8904,26 @@ fscanfed: 10 - hello # crunch should not be run if a .crn exists that is more recent than the .dds shutil.copyfile(path_from_root('tests', 'ship.dds'), 'ship.dds') time.sleep(0.1) - Popen(['python', FILE_PACKAGER, 'test.data', '--pre-run', '--crunch=32', '--preload', 'ship.dds'], stdout=open('pre.js', 'w')).communicate() + Popen([PYTHON, FILE_PACKAGER, 'test.data', '--pre-run', '--crunch=32', '--preload', 'ship.dds'], stdout=open('pre.js', 'w')).communicate() assert os.stat('test.data').st_size < 0.25*os.stat('ship.dds').st_size, 'Compressed should be much smaller than dds' crunch_time = os.stat('ship.crn').st_mtime dds_time = os.stat('ship.dds').st_mtime assert crunch_time > dds_time, 'Crunch is more recent' # run again, should not recrunch! time.sleep(0.1) - Popen(['python', FILE_PACKAGER, 'test.data', '--pre-run', '--crunch=32', '--preload', 'ship.dds'], stdout=open('pre.js', 'w')).communicate() + Popen([PYTHON, FILE_PACKAGER, 'test.data', '--pre-run', '--crunch=32', '--preload', 'ship.dds'], stdout=open('pre.js', 'w')).communicate() assert crunch_time == os.stat('ship.crn').st_mtime, 'Crunch is unchanged' # update dds, so should recrunch time.sleep(0.1) os.utime('ship.dds', None) - Popen(['python', FILE_PACKAGER, 'test.data', '--pre-run', '--crunch=32', '--preload', 'ship.dds'], stdout=open('pre.js', 'w')).communicate() + Popen([PYTHON, FILE_PACKAGER, 'test.data', '--pre-run', '--crunch=32', '--preload', 'ship.dds'], stdout=open('pre.js', 'w')).communicate() assert crunch_time < os.stat('ship.crn').st_mtime, 'Crunch was changed' def test_headless(self): if SPIDERMONKEY_ENGINE not in JS_ENGINES: return self.skip('cannot run without spidermonkey due to node limitations (Uint8ClampedArray etc.)') shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'example.png')) - Popen(['python', EMCC, path_from_root('tests', 'sdl_canvas.c'), '-s', 'HEADLESS=1']).communicate() + Popen([PYTHON, EMCC, path_from_root('tests', 'sdl_canvas.c'), '-s', 'HEADLESS=1']).communicate() output = run_js('a.out.js', engine=SPIDERMONKEY_ENGINE, stderr=PIPE) assert '''Init: 0 Font: 0x1 @@ -9092,7 +9111,7 @@ elif 'browser' in str(sys.argv): def test_html(self): # test HTML generation. self.reftest(path_from_root('tests', 'htmltest.png')) - output = Popen(['python', EMCC, path_from_root('tests', 'hello_world_sdl.cpp'), '-o', 'something.html', '--pre-js', 'reftest.js']).communicate() + output = Popen([PYTHON, EMCC, path_from_root('tests', 'hello_world_sdl.cpp'), '-o', 'something.html', '--pre-js', 'reftest.js']).communicate() self.run_browser('something.html', 'You should see "hello, world!" and a colored cube.', '/report_result?0') def build_native_lzma(self): @@ -9109,7 +9128,7 @@ elif 'browser' in str(sys.argv): def test_split(self): # test HTML generation. self.reftest(path_from_root('tests', 'htmltest.png')) - output = Popen(['python', EMCC, path_from_root('tests', 'hello_world_sdl.cpp'), '-o', 'something.js', '--split', '100', '--pre-js', 'reftest.js']).communicate() + output = Popen([PYTHON, EMCC, path_from_root('tests', 'hello_world_sdl.cpp'), '-o', 'something.js', '--split', '100', '--pre-js', 'reftest.js']).communicate() assert os.path.exists(os.path.join(self.get_dir(), 'something.js')), 'must be main js file' assert os.path.exists(os.path.join(self.get_dir(), 'something_functions.js')), 'must be functions js file' assert os.path.exists(os.path.join(self.get_dir(), 'something.include.html')), 'must be js include file' @@ -9200,7 +9219,7 @@ elif 'browser' in str(sys.argv): def test_split_in_source_filenames(self): self.reftest(path_from_root('tests', 'htmltest.png')) - output = Popen(['python', EMCC, path_from_root('tests', 'hello_world_sdl.cpp'), '-o', 'something.js', '-g', '--split', '100', '--pre-js', 'reftest.js']).communicate() + output = Popen([PYTHON, EMCC, path_from_root('tests', 'hello_world_sdl.cpp'), '-o', 'something.js', '-g', '--split', '100', '--pre-js', 'reftest.js']).communicate() assert os.path.exists(os.path.join(self.get_dir(), 'something.js')), 'must be main js file' assert os.path.exists(self.get_dir() + '/something/' + path_from_root('tests', 'hello_world_sdl.cpp.js')), 'must be functions js file' assert os.path.exists(os.path.join(self.get_dir(), 'something.include.html')), 'must be js include file' @@ -9302,7 +9321,7 @@ elif 'browser' in str(sys.argv): ''')) self.build_native_lzma() - Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp'), '-o', 'page.html', + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'main.cpp'), '-o', 'page.html', '--compression', '%s,%s,%s' % (path_from_root('third_party', 'lzma.js', 'lzma-native'), path_from_root('third_party', 'lzma.js', 'lzma-decoder.js'), 'LZMA.decompress')]).communicate() @@ -9335,13 +9354,13 @@ elif 'browser' in str(sys.argv): ''' % path)) make_main('somefile.txt') - Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp'), '--preload-file', 'somefile.txt', '-o', 'page.html']).communicate() + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'main.cpp'), '--preload-file', 'somefile.txt', '-o', 'page.html']).communicate() self.run_browser('page.html', 'You should see |load me right before|.', '/report_result?1') # By absolute path make_main(os.path.join(self.get_dir(), 'somefile.txt')) - Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp'), '--preload-file', os.path.join(self.get_dir(), 'somefile.txt'), '-o', 'page.html']).communicate() + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'main.cpp'), '--preload-file', os.path.join(self.get_dir(), 'somefile.txt'), '-o', 'page.html']).communicate() self.run_browser('page.html', 'You should see |load me right before|.', '/report_result?1') # Should still work with -o subdir/.. @@ -9351,7 +9370,7 @@ elif 'browser' in str(sys.argv): os.mkdir(os.path.join(self.get_dir(), 'dirrey')) except: pass - Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp'), '--preload-file', os.path.join(self.get_dir(), 'somefile.txt'), '-o', 'dirrey/page.html']).communicate() + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'main.cpp'), '--preload-file', os.path.join(self.get_dir(), 'somefile.txt'), '-o', 'dirrey/page.html']).communicate() self.run_browser('dirrey/page.html', 'You should see |load me right before|.', '/report_result?1') # With FS.preloadFile @@ -9362,7 +9381,7 @@ elif 'browser' in str(sys.argv): }; ''') make_main('someotherfile.txt') - Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp'), '--pre-js', 'pre.js', '-o', 'page.html']).communicate() + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'main.cpp'), '--pre-js', 'pre.js', '-o', 'page.html']).communicate() self.run_browser('page.html', 'You should see |load me right before|.', '/report_result?1') def test_multifile(self): @@ -9399,12 +9418,12 @@ elif 'browser' in str(sys.argv): ''')) # by individual files - Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp'), '--preload-file', 'subdirr/data1.txt', '--preload-file', 'subdirr/moar/data2.txt', '-o', 'page.html']).communicate() + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'main.cpp'), '--preload-file', 'subdirr/data1.txt', '--preload-file', 'subdirr/moar/data2.txt', '-o', 'page.html']).communicate() self.run_browser('page.html', 'You should see two cool numbers', '/report_result?1') os.remove('page.html') # by directory, and remove files to make sure - Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp'), '--preload-file', 'subdirr', '-o', 'page.html']).communicate() + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'main.cpp'), '--preload-file', 'subdirr', '-o', 'page.html']).communicate() shutil.rmtree(os.path.join(self.get_dir(), 'subdirr')) self.run_browser('page.html', 'You should see two cool numbers', '/report_result?1') @@ -9435,7 +9454,7 @@ elif 'browser' in str(sys.argv): ''')) self.build_native_lzma() - Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp'), '-o', 'page.html', '--preload-file', 'datafile.txt', '--preload-file', 'datafile2.txt', + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'main.cpp'), '-o', 'page.html', '--preload-file', 'datafile.txt', '--preload-file', 'datafile2.txt', '--compression', '%s,%s,%s' % (path_from_root('third_party', 'lzma.js', 'lzma-native'), path_from_root('third_party', 'lzma.js', 'lzma-decoder.js'), 'LZMA.decompress')]).communicate() @@ -9450,7 +9469,7 @@ elif 'browser' in str(sys.argv): shutil.copyfile(path_from_root('tests', 'screenshot.jpg'), os.path.join(self.get_dir(), 'screenshot.jpg')) open(os.path.join(self.get_dir(), 'sdl_image.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl_image.c')).read())) - Popen(['python', EMCC, os.path.join(self.get_dir(), 'sdl_image.c'), '-O2', '--preload-file', 'screenshot.jpg', '-o', 'page.html']).communicate() + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'sdl_image.c'), '-O2', '--preload-file', 'screenshot.jpg', '-o', 'page.html']).communicate() self.run_browser('page.html', '', '/report_result?600') def test_sdl_image_compressed(self): @@ -9464,7 +9483,7 @@ elif 'browser' in str(sys.argv): open(os.path.join(self.get_dir(), 'sdl_image.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl_image.c')).read()).replace('screenshot.jpg', basename)) self.build_native_lzma() - Popen(['python', EMCC, os.path.join(self.get_dir(), 'sdl_image.c'), '--preload-file', basename, '-o', 'page.html', + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'sdl_image.c'), '--preload-file', basename, '-o', 'page.html', '--compression', '%s,%s,%s' % (path_from_root('third_party', 'lzma.js', 'lzma-native'), path_from_root('third_party', 'lzma.js', 'lzma-decoder.js'), 'LZMA.decompress')]).communicate() @@ -9484,7 +9503,7 @@ elif 'browser' in str(sys.argv): def test_sdl_canvas(self): open(os.path.join(self.get_dir(), 'sdl_canvas.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl_canvas.c')).read())) - Popen(['python', EMCC, os.path.join(self.get_dir(), 'sdl_canvas.c'), '-o', 'page.html']).communicate() + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'sdl_canvas.c'), '-o', 'page.html']).communicate() self.run_browser('page.html', '', '/report_result?1') def test_sdl_key(self): @@ -9512,7 +9531,7 @@ elif 'browser' in str(sys.argv): ''') open(os.path.join(self.get_dir(), 'sdl_key.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl_key.c')).read())) - Popen(['python', EMCC, os.path.join(self.get_dir(), 'sdl_key.c'), '-o', 'page.html', '--pre-js', 'pre.js']).communicate() + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'sdl_key.c'), '-o', 'page.html', '--pre-js', 'pre.js']).communicate() self.run_browser('page.html', '', '/report_result?510510') def test_sdl_mouse(self): @@ -9545,7 +9564,7 @@ elif 'browser' in str(sys.argv): ''') open(os.path.join(self.get_dir(), 'sdl_mouse.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl_mouse.c')).read())) - Popen(['python', EMCC, os.path.join(self.get_dir(), 'sdl_mouse.c'), '-O2', '--minify', '0', '-o', 'page.html', '--pre-js', 'pre.js']).communicate() + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'sdl_mouse.c'), '-O2', '--minify', '0', '-o', 'page.html', '--pre-js', 'pre.js']).communicate() self.run_browser('page.html', '', '/report_result?740') def test_sdl_audio(self): @@ -9555,81 +9574,81 @@ elif 'browser' in str(sys.argv): open(os.path.join(self.get_dir(), 'sdl_audio.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl_audio.c')).read())) # use closure to check for a possible bug with closure minifying away newer Audio() attributes - Popen(['python', EMCC, '-O2', '--minify', '0', os.path.join(self.get_dir(), 'sdl_audio.c'), '--preload-file', 'sound.ogg', '--preload-file', 'sound2.wav', '--preload-file', 'bad.ogg', '-o', 'page.html', '-s', 'EXPORTED_FUNCTIONS=["_main", "_play", "_play2"]']).communicate() + Popen([PYTHON, EMCC, '-O2', '--minify', '0', os.path.join(self.get_dir(), 'sdl_audio.c'), '--preload-file', 'sound.ogg', '--preload-file', 'sound2.wav', '--preload-file', 'bad.ogg', '-o', 'page.html', '-s', 'EXPORTED_FUNCTIONS=["_main", "_play", "_play2"]']).communicate() self.run_browser('page.html', '', '/report_result?1') def test_sdl_audio_quickload(self): open(os.path.join(self.get_dir(), 'sdl_audio_quickload.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl_audio_quickload.c')).read())) # use closure to check for a possible bug with closure minifying away newer Audio() attributes - 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() + 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_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())) - Popen(['python', EMCC, os.path.join(self.get_dir(), 'sdl_gl_read.c'), '-o', 'something.html']).communicate() + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'sdl_gl_read.c'), '-o', 'something.html']).communicate() self.run_browser('something.html', '.', '/report_result?1') def test_sdl_ogl(self): # SDL, OpenGL, textures, immediate mode. Closure for more coverage shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png')) self.reftest(path_from_root('tests', 'screenshot-gray-purple.png')) - Popen(['python', EMCC, path_from_root('tests', 'sdl_ogl.c'), '-O2', '--minify', '0', '-o', 'something.html', '--pre-js', 'reftest.js', '--preload-file', 'screenshot.png']).communicate() + Popen([PYTHON, EMCC, path_from_root('tests', 'sdl_ogl.c'), '-O2', '--minify', '0', '-o', 'something.html', '--pre-js', 'reftest.js', '--preload-file', 'screenshot.png']).communicate() self.run_browser('something.html', 'You should see an image with gray at the top.', '/report_result?0') def test_sdl_ogl_defaultmatrixmode(self): # SDL, OpenGL, textures, immediate mode. Closure for more coverage shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png')) self.reftest(path_from_root('tests', 'screenshot-gray-purple.png')) - Popen(['python', EMCC, path_from_root('tests', 'sdl_ogl_defaultMatrixMode.c'), '--minify', '0', '-o', 'something.html', '--pre-js', 'reftest.js', '--preload-file', 'screenshot.png']).communicate() + Popen([PYTHON, EMCC, path_from_root('tests', 'sdl_ogl_defaultMatrixMode.c'), '--minify', '0', '-o', 'something.html', '--pre-js', 'reftest.js', '--preload-file', 'screenshot.png']).communicate() self.run_browser('something.html', 'You should see an image with gray at the top.', '/report_result?0') def test_sdl_ogl_p(self): # Immediate mode with pointers shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png')) self.reftest(path_from_root('tests', 'screenshot-gray.png')) - Popen(['python', EMCC, path_from_root('tests', 'sdl_ogl_p.c'), '-o', 'something.html', '--pre-js', 'reftest.js', '--preload-file', 'screenshot.png']).communicate() + Popen([PYTHON, EMCC, path_from_root('tests', 'sdl_ogl_p.c'), '-o', 'something.html', '--pre-js', 'reftest.js', '--preload-file', 'screenshot.png']).communicate() self.run_browser('something.html', 'You should see an image with gray at the top.', '/report_result?0') def test_sdl_fog_simple(self): # SDL, OpenGL, textures, fog, immediate mode. Closure for more coverage shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png')) self.reftest(path_from_root('tests', 'screenshot-fog-simple.png')) - Popen(['python', EMCC, path_from_root('tests', 'sdl_fog_simple.c'), '-O2', '--minify', '0', '-o', 'something.html', '--pre-js', 'reftest.js', '--preload-file', 'screenshot.png']).communicate() + Popen([PYTHON, EMCC, path_from_root('tests', 'sdl_fog_simple.c'), '-O2', '--minify', '0', '-o', 'something.html', '--pre-js', 'reftest.js', '--preload-file', 'screenshot.png']).communicate() self.run_browser('something.html', 'You should see an image with fog.', '/report_result?0') def test_sdl_fog_negative(self): # SDL, OpenGL, textures, fog, immediate mode. Closure for more coverage shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png')) self.reftest(path_from_root('tests', 'screenshot-fog-negative.png')) - Popen(['python', EMCC, path_from_root('tests', 'sdl_fog_negative.c'), '-o', 'something.html', '--pre-js', 'reftest.js', '--preload-file', 'screenshot.png']).communicate() + Popen([PYTHON, EMCC, path_from_root('tests', 'sdl_fog_negative.c'), '-o', 'something.html', '--pre-js', 'reftest.js', '--preload-file', 'screenshot.png']).communicate() self.run_browser('something.html', 'You should see an image with fog.', '/report_result?0') def test_sdl_fog_density(self): # SDL, OpenGL, textures, fog, immediate mode. Closure for more coverage shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png')) self.reftest(path_from_root('tests', 'screenshot-fog-density.png')) - Popen(['python', EMCC, path_from_root('tests', 'sdl_fog_density.c'), '-o', 'something.html', '--pre-js', 'reftest.js', '--preload-file', 'screenshot.png']).communicate() + Popen([PYTHON, EMCC, path_from_root('tests', 'sdl_fog_density.c'), '-o', 'something.html', '--pre-js', 'reftest.js', '--preload-file', 'screenshot.png']).communicate() self.run_browser('something.html', 'You should see an image with fog.', '/report_result?0') def test_sdl_fog_exp2(self): # SDL, OpenGL, textures, fog, immediate mode. Closure for more coverage shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png')) self.reftest(path_from_root('tests', 'screenshot-fog-exp2.png')) - Popen(['python', EMCC, path_from_root('tests', 'sdl_fog_exp2.c'), '-o', 'something.html', '--pre-js', 'reftest.js', '--preload-file', 'screenshot.png']).communicate() + Popen([PYTHON, EMCC, path_from_root('tests', 'sdl_fog_exp2.c'), '-o', 'something.html', '--pre-js', 'reftest.js', '--preload-file', 'screenshot.png']).communicate() self.run_browser('something.html', 'You should see an image with fog.', '/report_result?0') def test_sdl_fog_linear(self): # SDL, OpenGL, textures, fog, immediate mode. Closure for more coverage shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png')) self.reftest(path_from_root('tests', 'screenshot-fog-linear.png')) - Popen(['python', EMCC, path_from_root('tests', 'sdl_fog_linear.c'), '-o', 'something.html', '--pre-js', 'reftest.js', '--preload-file', 'screenshot.png']).communicate() + Popen([PYTHON, EMCC, path_from_root('tests', 'sdl_fog_linear.c'), '-o', 'something.html', '--pre-js', 'reftest.js', '--preload-file', 'screenshot.png']).communicate() self.run_browser('something.html', 'You should see an image with fog.', '/report_result?0') def test_worker(self): # Test running in a web worker - output = Popen(['python', EMCC, path_from_root('tests', 'hello_world_worker.cpp'), '-o', 'worker.js'], stdout=PIPE, stderr=PIPE).communicate() + output = Popen([PYTHON, EMCC, path_from_root('tests', 'hello_world_worker.cpp'), '-o', 'worker.js'], stdout=PIPE, stderr=PIPE).communicate() assert len(output[0]) == 0, output[0] assert os.path.exists('worker.js'), output self.assertContained('you should not see this text when in a worker!', run_js('worker.js')) # code should run standalone @@ -9712,7 +9731,7 @@ elif 'browser' in str(sys.argv): prejs_file.close() # vs. os.path.join(self.get_dir(), filename) # vs. path_from_root('tests', 'hello_world_gles.c') - Popen(['python', EMCC, path_from_root('tests', c_source_filename), '-g', '-s', 'SMALL_CHUNKS=1', '-o', worker_filename, + Popen([PYTHON, EMCC, path_from_root('tests', c_source_filename), '-g', '-s', 'SMALL_CHUNKS=1', '-o', worker_filename, '--pre-js', prejs_filename]).communicate() chunkSize = 1024 @@ -9763,19 +9782,19 @@ elif 'browser' in str(sys.argv): def test_glgears(self): self.reftest(path_from_root('tests', 'gears.png')) - Popen(['python', EMCC, path_from_root('tests', 'hello_world_gles.c'), '-o', 'something.html', + Popen([PYTHON, EMCC, path_from_root('tests', 'hello_world_gles.c'), '-o', 'something.html', '-DHAVE_BUILTIN_SINCOS', '--pre-js', 'reftest.js']).communicate() self.run_browser('something.html', 'You should see animating gears.', '/report_result?0') def test_glgears_animation(self): - Popen(['python', EMCC, path_from_root('tests', 'hello_world_gles.c'), '-o', 'something.html', + Popen([PYTHON, EMCC, path_from_root('tests', 'hello_world_gles.c'), '-o', 'something.html', '-DHAVE_BUILTIN_SINCOS', '--shell-file', path_from_root('tests', 'hello_world_gles_shell.html')]).communicate() self.run_browser('something.html', 'You should see animating gears.', '/report_gl_result?true') def test_glgears_bad(self): # Make sure that OpenGL ES is not available if typed arrays are not used - Popen(['python', EMCC, path_from_root('tests', 'hello_world_gles.c'), '-o', 'something.html', + Popen([PYTHON, EMCC, path_from_root('tests', 'hello_world_gles.c'), '-o', 'something.html', '-DHAVE_BUILTIN_SINCOS', '-s', 'USE_TYPED_ARRAYS=0', '--shell-file', path_from_root('tests', 'hello_world_gles_shell.html')]).communicate() @@ -9783,7 +9802,7 @@ elif 'browser' in str(sys.argv): def test_glgears_deriv(self): self.reftest(path_from_root('tests', 'gears.png')) - Popen(['python', EMCC, path_from_root('tests', 'hello_world_gles_deriv.c'), '-o', 'something.html', + Popen([PYTHON, EMCC, path_from_root('tests', 'hello_world_gles_deriv.c'), '-o', 'something.html', '-DHAVE_BUILTIN_SINCOS', '--pre-js', 'reftest.js']).communicate() self.run_browser('something.html', 'You should see animating gears.', '/report_result?0') src = open('something.html').read() @@ -9814,7 +9833,7 @@ elif 'browser' in str(sys.argv): args = ['--preload-file', 'smoke.tga', '-O2'] # test optimizations and closure here as well for more coverage self.reftest(book_path(basename.replace('.bc', '.png'))) - Popen(['python', EMCC, program, '-o', 'program.html', '--pre-js', 'reftest.js'] + args).communicate() + Popen([PYTHON, EMCC, program, '-o', 'program.html', '--pre-js', 'reftest.js'] + args).communicate() self.run_browser('program.html', '', '/report_result?0') def btest(self, filename, expected=None, reference=None, reference_slack=0, args=[]): # TODO: use in all other tests @@ -9830,7 +9849,7 @@ elif 'browser' in str(sys.argv): shutil.copyfile(path_from_root('tests', filename), os.path.join(self.get_dir(), filename)) self.reftest(path_from_root('tests', reference)) args = args + ['--pre-js', 'reftest.js'] - Popen(['python', EMCC, os.path.join(self.get_dir(), filename), '-o', 'test.html'] + args).communicate() + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), filename), '-o', 'test.html'] + args).communicate() if type(expected) is str: expected = [expected] self.run_browser('test.html', '.', ['/report_result?' + e for e in expected]) @@ -9932,7 +9951,7 @@ elif 'browser' in str(sys.argv): open(os.path.join(self.get_dir(), 'sdl_canvas_palette_2.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl_canvas_palette_2.c')).read())) open(os.path.join(self.get_dir(), 'pre.js'), 'w').write('Module[\'preRun\'] = function() { SDL.defaults.copyOnLock = false }') - Popen(['python', EMCC, os.path.join(self.get_dir(), 'sdl_canvas_palette_2.c'), '-o', 'page.html', '--pre-js', 'pre.js']).communicate() + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'sdl_canvas_palette_2.c'), '-o', 'page.html', '--pre-js', 'pre.js']).communicate() self.run_browser('page.html', '') def test_s3tc(self): @@ -9943,23 +9962,23 @@ elif 'browser' in str(sys.argv): shutil.copyfile(path_from_root('tests', 'ship.dds'), 'ship.dds') shutil.copyfile(path_from_root('tests', 'bloom.dds'), 'bloom.dds') shutil.copyfile(path_from_root('tests', 'water.dds'), 'water.dds') - Popen(['python', FILE_PACKAGER, 'test.data', '--pre-run', '--crunch', '--preload', 'ship.dds', 'bloom.dds', 'water.dds'], stdout=open('pre.js', 'w')).communicate() + Popen([PYTHON, FILE_PACKAGER, 'test.data', '--pre-run', '--crunch', '--preload', 'ship.dds', 'bloom.dds', 'water.dds'], stdout=open('pre.js', 'w')).communicate() assert os.stat('test.data').st_size < 0.5*(os.stat('ship.dds').st_size+os.stat('bloom.dds').st_size+os.stat('water.dds').st_size), 'Compressed should be smaller than dds' shutil.move('ship.dds', 'ship.donotfindme.dds') # make sure we load from the compressed shutil.move('bloom.dds', 'bloom.donotfindme.dds') # make sure we load from the compressed shutil.move('water.dds', 'water.donotfindme.dds') # make sure we load from the compressed - self.btest('s3tc_crunch.c', reference='s3tc_crunch.png', reference_slack=1, args=['--pre-js', 'pre.js']) + self.btest('s3tc_crunch.c', reference='s3tc_crunch.png', reference_slack=11, args=['--pre-js', 'pre.js']) def test_s3tc_crunch_split(self): # load several datafiles/outputs of file packager shutil.copyfile(path_from_root('tests', 'ship.dds'), 'ship.dds') shutil.copyfile(path_from_root('tests', 'bloom.dds'), 'bloom.dds') shutil.copyfile(path_from_root('tests', 'water.dds'), 'water.dds') - Popen(['python', FILE_PACKAGER, 'asset_a.data', '--pre-run', '--crunch', '--preload', 'ship.dds', 'bloom.dds'], stdout=open('asset_a.js', 'w')).communicate() - Popen(['python', FILE_PACKAGER, 'asset_b.data', '--pre-run', '--crunch', '--preload', 'water.dds'], stdout=open('asset_b.js', 'w')).communicate() + Popen([PYTHON, FILE_PACKAGER, 'asset_a.data', '--pre-run', '--crunch', '--preload', 'ship.dds', 'bloom.dds'], stdout=open('asset_a.js', 'w')).communicate() + Popen([PYTHON, FILE_PACKAGER, 'asset_b.data', '--pre-run', '--crunch', '--preload', 'water.dds'], stdout=open('asset_b.js', 'w')).communicate() shutil.move('ship.dds', 'ship.donotfindme.dds') # make sure we load from the compressed shutil.move('bloom.dds', 'bloom.donotfindme.dds') # make sure we load from the compressed shutil.move('water.dds', 'water.donotfindme.dds') # make sure we load from the compressed - self.btest('s3tc_crunch.c', reference='s3tc_crunch.png', reference_slack=1, args=['--pre-js', 'asset_a.js', '--pre-js', 'asset_b.js']) + self.btest('s3tc_crunch.c', reference='s3tc_crunch.png', reference_slack=11, args=['--pre-js', 'asset_a.js', '--pre-js', 'asset_b.js']) def test_aniso(self): shutil.copyfile(path_from_root('tests', 'water.dds'), 'water.dds') @@ -9978,7 +9997,7 @@ elif 'browser' in str(sys.argv): main, supp = self.setup_runtimelink_test() open(self.in_dir('supp.cpp'), 'w').write(supp) - Popen(['python', EMCC, self.in_dir('supp.cpp'), '-o', 'supp.js', '-s', 'LINKABLE=1', '-s', 'BUILD_AS_SHARED_LIB=2', '-O2', '--closure', '0']).communicate() + Popen([PYTHON, EMCC, self.in_dir('supp.cpp'), '-o', 'supp.js', '-s', 'LINKABLE=1', '-s', 'BUILD_AS_SHARED_LIB=2', '-O2', '--closure', '0']).communicate() shutil.move(self.in_dir('supp.js'), self.in_dir('supp.so')) self.btest(main, args=['-s', 'LINKABLE=1', '-s', 'RUNTIME_LINKED_LIBS=["supp.so"]', '-DBROWSER=1', '-O2', '--closure', '0'], expected='76') @@ -9998,11 +10017,11 @@ elif 'browser' in str(sys.argv): self.btest('pre_run_deps.cpp', expected='10', args=['--pre-js', 'pre.js']) def test_worker_api(self): - Popen(['python', EMCC, path_from_root('tests', 'worker_api_worker.cpp'), '-o', 'worker.js', '-s', 'BUILD_AS_WORKER=1', '-s', 'EXPORTED_FUNCTIONS=["_one"]']).communicate() + Popen([PYTHON, EMCC, path_from_root('tests', 'worker_api_worker.cpp'), '-o', 'worker.js', '-s', 'BUILD_AS_WORKER=1', '-s', 'EXPORTED_FUNCTIONS=["_one"]']).communicate() self.btest('worker_api_main.cpp', expected='566') def test_worker_api_2(self): - Popen(['python', EMCC, path_from_root('tests', 'worker_api_2_worker.cpp'), '-o', 'worker.js', '-s', 'BUILD_AS_WORKER=1', '-O2', '--minify', '0', '-s', 'EXPORTED_FUNCTIONS=["_one", "_two", "_three", "_four"]']).communicate() + Popen([PYTHON, EMCC, path_from_root('tests', 'worker_api_2_worker.cpp'), '-o', 'worker.js', '-s', 'BUILD_AS_WORKER=1', '-O2', '--minify', '0', '-s', 'EXPORTED_FUNCTIONS=["_one", "_two", "_three", "_four"]']).communicate() self.btest('worker_api_2_main.cpp', args=['-O2', '--minify', '0'], expected='11') pids_to_clean = [] @@ -10094,7 +10113,7 @@ elif 'browser' in str(sys.argv): def make_relay_server(self, port1, port2): def relay_server(q): print >> sys.stderr, 'creating relay server on ports %d,%d' % (port1, port2) - proc = Popen(['python', path_from_root('tests', 'socket_relay.py'), str(port1), str(port2)]) + proc = Popen([PYTHON, path_from_root('tests', 'socket_relay.py'), str(port1), str(port2)]) q.put(proc.pid) proc.communicate() return relay_server @@ -10103,7 +10122,7 @@ elif 'browser' in str(sys.argv): try: with self.WebsockHarness(8992, self.make_relay_server(8992, 8994)): with self.WebsockHarness(8994, no_server=True): - Popen(['python', EMCC, path_from_root('tests', 'websockets_bi_side.c'), '-o', 'side.html', '-DSOCKK=8995']).communicate() + Popen([PYTHON, EMCC, path_from_root('tests', 'websockets_bi_side.c'), '-o', 'side.html', '-DSOCKK=8995']).communicate() self.btest('websockets_bi.c', expected='2499') finally: self.clean_pids() @@ -10112,7 +10131,7 @@ elif 'browser' in str(sys.argv): try: with self.WebsockHarness(6992, self.make_relay_server(6992, 6994)): with self.WebsockHarness(6994, no_server=True): - Popen(['python', EMCC, path_from_root('tests', 'websockets_bi_side.c'), '-o', 'side.html', '-DSOCKK=6995']).communicate() + Popen([PYTHON, EMCC, path_from_root('tests', 'websockets_bi_side.c'), '-o', 'side.html', '-DSOCKK=6995']).communicate() self.btest('websockets_bi_listener.c', expected='2499') finally: self.clean_pids() @@ -10128,7 +10147,7 @@ elif 'browser' in str(sys.argv): try: with self.WebsockHarness(3992, self.make_relay_server(3992, 3994)): with self.WebsockHarness(3994, no_server=True): - Popen(['python', EMCC, path_from_root('tests', 'websockets_bi_side_bigdata.c'), '-o', 'side.html', '-DSOCKK=3995', '-s', 'SOCKET_DEBUG=0', '-I' + path_from_root('tests')]).communicate() + Popen([PYTHON, EMCC, path_from_root('tests', 'websockets_bi_side_bigdata.c'), '-o', 'side.html', '-DSOCKK=3995', '-s', 'SOCKET_DEBUG=0', '-I' + path_from_root('tests')]).communicate() self.btest('websockets_bi_bigdata.c', expected='0', args=['-s', 'SOCKET_DEBUG=0', '-I' + path_from_root('tests')]) finally: self.clean_pids() @@ -10138,11 +10157,11 @@ elif 'browser' in str(sys.argv): shutil.copytree(path_from_root('tests', 'enet'), self.in_dir('enet')) pwd = os.getcwd() os.chdir(self.in_dir('enet')) - Popen(['python', path_from_root('emconfigure'), './configure']).communicate() - Popen(['python', path_from_root('emmake'), 'make']).communicate() + Popen([PYTHON, path_from_root('emconfigure'), './configure']).communicate() + Popen([PYTHON, path_from_root('emmake'), 'make']).communicate() enet = [self.in_dir('enet', '.libs', 'libenet.a'), '-I'+path_from_root('tests', 'enet', 'include')] os.chdir(pwd) - Popen(['python', EMCC, path_from_root('tests', 'enet_server.c'), '-o', 'server.html'] + enet).communicate() + Popen([PYTHON, EMCC, path_from_root('tests', 'enet_server.c'), '-o', 'server.html'] + enet).communicate() try: with self.WebsockHarness(1234, self.make_relay_server(1234, 1236)): @@ -10245,7 +10264,7 @@ elif 'benchmark' in str(sys.argv): final_filename = os.path.join(dirname, name + '.js') try_delete(final_filename) - output = Popen(['python', EMCC, filename, #'-O3', + output = Popen([PYTHON, EMCC, filename, #'-O3', '-O2', '-s', 'INLINING_LIMIT=0', '-s', 'DOUBLE_MODE=0', '-s', 'PRECISE_I64_MATH=0', '-s', 'TOTAL_MEMORY=100*1024*1024', '-s', 'FAST_MEMORY=10*1024*1024', '-o', final_filename] + emcc_args, stdout=PIPE, stderr=self.stderr_redirect).communicate() @@ -10487,7 +10506,7 @@ elif 'sanity' in str(sys.argv): try_delete(CONFIG_FILE) try_delete(SANITY_FILE) - commands = [[EMCC], ['python', path_from_root('tests', 'runner.py'), 'blahblah']] + commands = [[EMCC], [PYTHON, path_from_root('tests', 'runner.py'), 'blahblah']] def mtime(filename): return os.stat(filename).st_mtime @@ -10503,7 +10522,7 @@ elif 'sanity' in str(sys.argv): if type(command) is not list: command = [command] if command[0] == EMCC: - command = ['python'] + command + command = [PYTHON] + command return Popen(command, stdout=PIPE, stderr=STDOUT).communicate()[0] @@ -10553,7 +10572,7 @@ elif 'sanity' in str(sys.argv): # The guessed config should be ok XXX This depends on your local system! it is possible `which` guesses wrong try_delete('a.out.js') - output = Popen(['python', EMCC, path_from_root('tests', 'hello_world.c')], stdout=PIPE, stderr=PIPE).communicate() + output = Popen([PYTHON, EMCC, path_from_root('tests', 'hello_world.c')], stdout=PIPE, stderr=PIPE).communicate() self.assertContained('hello, world!', run_js('a.out.js'), output) # Second run, with bad EM_CONFIG @@ -10750,7 +10769,7 @@ fi return 0; } ''') - Popen(['python', EMCC, os.path.join(dirname, 'main.cpp'), '-o', os.path.join(dirname, 'a.out.js')]).communicate() + Popen([PYTHON, EMCC, os.path.join(dirname, 'main.cpp'), '-o', os.path.join(dirname, 'a.out.js')]).communicate() del os.environ['EM_CONFIG'] self.assertContained('hello from emcc with no config file', run_js(os.path.join(dirname, 'a.out.js'))) shutil.rmtree(dirname) @@ -10810,9 +10829,9 @@ fi assert os.path.exists(os.path.join(EMCC_CACHE, libname + '.bc')) if libname == 'libcxx': print os.stat(os.path.join(EMCC_CACHE, libname + '.bc')).st_size, os.stat(basebc_name).st_size, os.stat(dcebc_name).st_size - assert os.stat(os.path.join(EMCC_CACHE, libname + '.bc')).st_size > 2000000, 'libc++ is big' - assert os.stat(basebc_name).st_size > 2000000, 'libc++ is indeed big' - assert os.stat(dcebc_name).st_size < 1500000, 'Dead code elimination must remove most of libc++' + assert os.stat(os.path.join(EMCC_CACHE, libname + '.bc')).st_size > 1800000, 'libc++ is big' + assert os.stat(basebc_name).st_size > 1800000, 'libc++ is indeed big' + assert os.stat(dcebc_name).st_size < 750000, 'Dead code elimination must remove most of libc++' # should only have metadata in -O0, not 1 and 2 ll = open(ll_name).read() if (ll.count('\n!') < 10) == (i == 0): # a few lines are left even in -O1 and -O2 @@ -10836,16 +10855,19 @@ fi try_delete(RELOOPER) for i in range(4): - print phase, i + print >> sys.stderr, phase, i opt = min(i, 2) try_delete('a.out.js') - output = Popen(['python', EMCC, path_from_root('tests', 'hello_world_loop.cpp'), '-O' + str(opt), '--closure', '0'], + output = Popen([PYTHON, EMCC, path_from_root('tests', 'hello_world_loop.cpp'), '-O' + str(opt), '--closure', '0'], stdout=PIPE, stderr=PIPE).communicate() self.assertContained('hello, world!', run_js('a.out.js')) output = '\n'.join(output) assert ('bootstrapping relooper succeeded' in output) == (i == 2), 'only bootstrap on first O2: ' + output assert os.path.exists(RELOOPER) == (i >= 2), 'have relooper on O2: ' + output - assert ('L2 : do {' in open('a.out.js').read()) == (i >= 2), 'reloop code on O2: ' + output + src = open('a.out.js').read() + main = src.split('function _main() {')[1].split('\n}\n')[0] + assert ('while (1) {' in main) == (i >= 2), 'reloop code on O2: ' + src + assert ('switch' not in main) == (i >= 2), 'reloop code on O2: ' + src def test_jcache(self): PRE_LOAD_MSG = 'loading pre from jcache' @@ -10891,12 +10913,12 @@ fi (['--jcache'], 'hello_libcxx.cpp', False, True, False, True, False, True, []), ([], 'hello_libcxx.cpp', False, False, False, False, False, False, []), # finally, build a file close to the previous, to see that some chunks are found in the cache and some not - (['--jcache'], 'hello_libcxx_mod1.cpp', False, True, True, True, True, False, []), # win on pre, mix on funcs, fail on jsfuncs + (['--jcache'], 'hello_libcxx_mod1.cpp', False, True, True, True, True, True, []), # win on pre, mix on funcs, mix on jsfuncs (['--jcache'], 'hello_libcxx_mod1.cpp', False, True, False, True, False, True, []), ]: print >> sys.stderr, args, input_file, expect_pre_save, expect_pre_load, expect_funcs_save, expect_funcs_load, expect_jsfuncs_save, expect_jsfuncs_load, expected self.clear() - out, err = Popen(['python', EMCC, '-O2', '--closure', '0', path_from_root('tests', input_file)] + args, stdout=PIPE, stderr=PIPE).communicate() + out, err = Popen([PYTHON, EMCC, '-O2', '--closure', '0', path_from_root('tests', input_file)] + args, stdout=PIPE, stderr=PIPE).communicate() errtail = err.split('emcc invocation')[-1] self.assertContained('hello, world!', run_js('a.out.js'), errtail) assert (PRE_SAVE_MSG in err) == expect_pre_save, errtail diff --git a/tests/s3tc_crunch.png b/tests/s3tc_crunch.png Binary files differindex 383d4c5b..3510b83b 100644 --- a/tests/s3tc_crunch.png +++ b/tests/s3tc_crunch.png diff --git a/third_party/CppHeaderParser/CppHeaderParser/CppHeaderParser.py b/third_party/CppHeaderParser/CppHeaderParser/CppHeaderParser.py index a16d32be..c9aacc56 100644 --- a/third_party/CppHeaderParser/CppHeaderParser/CppHeaderParser.py +++ b/third_party/CppHeaderParser/CppHeaderParser/CppHeaderParser.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python2 # # Author: Jashua R. Cloutier (contact via sourceforge username:senexcanis) # diff --git a/third_party/CppHeaderParser/setup.py b/third_party/CppHeaderParser/setup.py index 3c254a03..f81ff431 100644 --- a/third_party/CppHeaderParser/setup.py +++ b/third_party/CppHeaderParser/setup.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 # -*- coding: utf-8 -*- import sys, glob diff --git a/third_party/demangler.py b/third_party/demangler.py index 1066643b..66e8eaea 100644 --- a/third_party/demangler.py +++ b/third_party/demangler.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python2 ''' Simple tool to run the demangler. diff --git a/third_party/websockify/run b/third_party/websockify/run index 54db9b8d..2802254f 100755 --- a/third_party/websockify/run +++ b/third_party/websockify/run @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python2 import websockify diff --git a/third_party/websockify/websockify/websocket.py b/third_party/websockify/websockify/websocket.py index 3f539a1d..9ce13159 100644 --- a/third_party/websockify/websockify/websocket.py +++ b/third_party/websockify/websockify/websocket.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 ''' Python WebSocket library with support for "wss://" encryption. diff --git a/third_party/websockify/websockify/websocketproxy.py b/third_party/websockify/websockify/websocketproxy.py index 1154d925..18d0a284 100755 --- a/third_party/websockify/websockify/websocketproxy.py +++ b/third_party/websockify/websockify/websocketproxy.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 ''' A WebSocket to TCP socket proxy with support for "wss://" encryption. diff --git a/tools/bindings_generator.py b/tools/bindings_generator.py index 0c7c814f..d2c165a2 100755 --- a/tools/bindings_generator.py +++ b/tools/bindings_generator.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 ''' Use CppHeaderParser to parse some C++ headers, and generate binding code for them. diff --git a/tools/eliminator/eliminator-test-output.js b/tools/eliminator/eliminator-test-output.js index ede34103..01f092d5 100644 --- a/tools/eliminator/eliminator-test-output.js +++ b/tools/eliminator/eliminator-test-output.js @@ -6132,4 +6132,12 @@ function _mallocNoU($bytes) { return $mem_0; return null; } +function phi() { + if (wat()) { + var $10 = 1; + } else { + var $10 = (_init_mparams() | 0) != 0; + } + var $10; +} diff --git a/tools/eliminator/eliminator-test.js b/tools/eliminator/eliminator-test.js index e44f28ad..8b376305 100644 --- a/tools/eliminator/eliminator-test.js +++ b/tools/eliminator/eliminator-test.js @@ -8828,5 +8828,15 @@ function _mallocNoU($bytes) { return $mem_0; return null; } -// EMSCRIPTEN_GENERATED_FUNCTIONS: ["a", "b", "c", "f", "g", "h", "py", "r", "t", "f2", "f3", "llvm3_1", "_inflate", "_malloc", "_mallocNoU"] +function phi() { + if (wat()) { + var $10 = 1; + } else { + var $7=_init_mparams(); + var $8=(($7)|0)!=0; + var $10 = $8; + } + var $10; +} +// EMSCRIPTEN_GENERATED_FUNCTIONS: ["a", "b", "c", "f", "g", "h", "py", "r", "t", "f2", "f3", "llvm3_1", "_inflate", "_malloc", "_mallocNoU", "asm", "phi"] diff --git a/tools/emconfiguren.py b/tools/emconfiguren.py index fd7b7549..35d83b87 100755 --- a/tools/emconfiguren.py +++ b/tools/emconfiguren.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 import sys print >> sys.stderr, '\n\nemconfiguren.py is deprecated! use "emconfigure"\n\n' diff --git a/tools/emmaken.py b/tools/emmaken.py index ae4794f0..77405761 100755 --- a/tools/emmaken.py +++ b/tools/emmaken.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 import sys print >> sys.stderr, '\n\nemmaken.py is deprecated! use "emcc"\n\n' diff --git a/tools/emmakenxx.py b/tools/emmakenxx.py index 1c31f3c2..0af3f99e 100755 --- a/tools/emmakenxx.py +++ b/tools/emmakenxx.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 ''' see emmaken.py @@ -14,5 +14,5 @@ from tools.shared import * emmaken = path_from_root('tools', 'emmaken.py') os.environ['EMMAKEN_CXX'] = '1' -exit(subprocess.call(['python', emmaken] + sys.argv[1:])) +exit(subprocess.call([PYTHON, emmaken] + sys.argv[1:])) diff --git a/tools/exec_llvm.py b/tools/exec_llvm.py index 71c0f18d..2685f9e4 100755 --- a/tools/exec_llvm.py +++ b/tools/exec_llvm.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python2 ''' Small utility to execute some llvm bitcode. diff --git a/tools/fix_closure.py b/tools/fix_closure.py index ab2dacbc..91d2a866 100755 --- a/tools/fix_closure.py +++ b/tools/fix_closure.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 ''' With very very large projects, closure compiler can translate FUNCTION_TABLE into something like diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js index 29aecdcf..62161738 100644 --- a/tools/js-optimizer.js +++ b/tools/js-optimizer.js @@ -1464,7 +1464,7 @@ function eliminate(ast, memSafe) { for (var name in locals) { if (definitions[name] == 1 && uses[name] == 1) { potentials[name] = 1; - } else if (uses[name] == 0) { + } else if (uses[name] == 0 && (!definitions[name] || definitions[name] <= 1)) { // no uses, no def or 1 def (cannot operate on phis, and the llvm optimizer will remove unneeded phis anyhow) var hasSideEffects = false; if (values[name]) { traverse(values[name], function(node, type) { diff --git a/tools/ll-strip.py b/tools/ll-strip.py index b03e4f3a..a08da478 100755 --- a/tools/ll-strip.py +++ b/tools/ll-strip.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python2 import sys, re diff --git a/tools/make_minigzip.py b/tools/make_minigzip.py index 60177318..0c96457b 100644 --- a/tools/make_minigzip.py +++ b/tools/make_minigzip.py @@ -9,5 +9,5 @@ zlib = shared.Building.build_library('zlib', shared.EMSCRIPTEN_TEMP_DIR, shared. print 'Building minigzip' -Popen(['python', shared.EMCC, '-O2', shared.path_from_root('tests', 'zlib', 'minigzip.c'), zlib, '-o', shared.path_from_root('tools', 'minigzip.js')]).communicate() +Popen(['python2', shared.EMCC, '-O2', shared.path_from_root('tests', 'zlib', 'minigzip.c'), zlib, '-o', shared.path_from_root('tools', 'minigzip.js')]).communicate() diff --git a/tools/namespacer.py b/tools/namespacer.py index 810689eb..81b8d2d1 100644 --- a/tools/namespacer.py +++ b/tools/namespacer.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python2 ''' Tool that generates namespace boilerplate. Given diff --git a/tools/nativize_llvm.py b/tools/nativize_llvm.py index de78dce2..e76b9a4e 100755 --- a/tools/nativize_llvm.py +++ b/tools/nativize_llvm.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python2 ''' Small utility to build some llvm bitcode into native code. Useful when lli (called diff --git a/tools/reproduceriter.py b/tools/reproduceriter.py index 058eeecf..c820978b 100755 --- a/tools/reproduceriter.py +++ b/tools/reproduceriter.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 ''' Reproducer Rewriter diff --git a/tools/scons/site_scons/site_tools/emscripten/__init__.py b/tools/scons/site_scons/site_tools/emscripten/__init__.py index 8ae2288e..ebd2c21b 100644 --- a/tools/scons/site_scons/site_tools/emscripten/__init__.py +++ b/tools/scons/site_scons/site_tools/emscripten/__init__.py @@ -1,3 +1,3 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 from emscripten import exists, generate diff --git a/tools/scons/site_scons/site_tools/emscripten/emscripten.py b/tools/scons/site_scons/site_tools/emscripten/emscripten.py index ce704bf8..5abd4fee 100644 --- a/tools/scons/site_scons/site_tools/emscripten/emscripten.py +++ b/tools/scons/site_scons/site_tools/emscripten/emscripten.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 import os diff --git a/tools/settings_template_readonly.py b/tools/settings_template_readonly.py index 93ea2036..970a8f8c 100644 --- a/tools/settings_template_readonly.py +++ b/tools/settings_template_readonly.py @@ -7,6 +7,7 @@ import os # this helps projects using emscripten find it EMSCRIPTEN_ROOT = os.path.expanduser(os.getenv('EMSCRIPTEN') or '{{{ EMSCRIPTEN_ROOT }}}') LLVM_ROOT = os.path.expanduser(os.getenv('LLVM') or '{{{ LLVM_ROOT }}}') +PYTHON = os.path.expanduser(os.getenv('PYTHON') or '{{{ PYTHON }}}') # See below for notes on which JS engine(s) you need NODE_JS = os.path.expanduser(os.getenv('NODE') or '{{{ NODE }}}') diff --git a/tools/shared.py b/tools/shared.py index 1dec21cd..72629131 100644 --- a/tools/shared.py +++ b/tools/shared.py @@ -92,10 +92,16 @@ else: node = 'node' try: node = Popen(['which', 'node'], stdout=PIPE).communicate()[0].replace('\n', '') or \ - Popen(['which', 'nodejs'], stdout=PIPE).communicate()[0].replace('\n', '') + Popen(['which', 'nodejs'], stdout=PIPE).communicate()[0].replace('\n', '') or node except: pass config_file = config_file.replace('{{{ NODE }}}', node) + python = 'python' + try: + python = Popen(['which', 'python'], stdout=PIPE).communicate()[0].replace('\n', '') + except: + pass + config_file = config_file.replace('{{{ PYTHON }}}', python) # write open(CONFIG_FILE, 'w').write(config_file) @@ -110,6 +116,7 @@ A settings file has been copied to %s, at absolute path: %s It contains our best guesses for the important paths, which are: LLVM_ROOT = %s + PYTHON = %s NODE_JS = %s EMSCRIPTEN_ROOT = %s @@ -117,7 +124,7 @@ Please edit the file if any of those are incorrect. This command will now exit. When you are done editing those paths, re-run it. ============================================================================== -''' % (EM_CONFIG, CONFIG_FILE, llvm_root, node, __rootpath__) +''' % (EM_CONFIG, CONFIG_FILE, llvm_root, python, node, __rootpath__) sys.exit(0) try: config_text = open(CONFIG_FILE, 'r').read() if CONFIG_FILE else EM_CONFIG @@ -128,7 +135,7 @@ except Exception, e: # Expectations -EXPECTED_LLVM_VERSION = (3,1) +EXPECTED_LLVM_VERSION = (3,2) def check_clang_version(): expected = 'clang version ' + '.'.join(map(str, EXPECTED_LLVM_VERSION)) @@ -165,7 +172,7 @@ def check_node_version(): # 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.0.1a' +EMSCRIPTEN_VERSION = '1.1.0' def check_sanity(force=False): try: @@ -319,6 +326,12 @@ except: CLOSURE_COMPILER = path_from_root('third_party', 'closure-compiler', 'compiler.jar') try: + PYTHON +except: + print >> sys.stderr, 'PYTHON not defined in ~/.emscripten, using "python"' + PYTHON = 'python' + +try: JAVA except: print >> sys.stderr, 'JAVA not defined in ~/.emscripten, using "java"' @@ -333,7 +346,7 @@ except: # Force a simple, standard target as much as possible: target 32-bit linux, and disable various flags that hint at other platforms COMPILER_OPTS = COMPILER_OPTS + ['-m32', '-U__i386__', '-U__x86_64__', '-U__i386', '-U__x86_64', '-U__SSE__', '-U__SSE2__', '-U__MMX__', '-UX87_DOUBLE_ROUNDING', '-UHAVE_GCC_ASM_FOR_X87', '-DEMSCRIPTEN', '-U__STRICT_ANSI__', '-U__CYGWIN__', - '-D__STDC__', '-Xclang', '-triple=i386-pc-linux-gnu', '-D__IEEE_LITTLE_ENDIAN'] + '-D__STDC__', '-Xclang', '-triple=i386-pc-linux-gnu', '-D__IEEE_LITTLE_ENDIAN', '-fno-math-errno'] USE_EMSDK = not os.environ.get('EMMAKEN_NO_SDK') @@ -498,6 +511,14 @@ def read_pgo_data(filename): 'overflows_lines': overflows_lines } +def unique_ordered(values): # return a list of unique values in an input list, without changing order (list(set(.)) would change order randomly) + seen = set() + def check(value): + if value in seen: return False + seen.add(value) + return True + return filter(check, values) + # Settings. A global singleton. Not pretty, but nicer than passing |, settings| everywhere class Settings: @@ -712,7 +733,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e Popen([LLVM_EXTRACT, filename, '-delete', '-func=' + symbol, '-o', filename], stderr=PIPE).communicate() @staticmethod - def link(files, target, remove_duplicates=False): + def link(files, target): actual_files = [] unresolved_symbols = set(['main']) # tracking unresolveds is necessary for .a linking, see below. (and main is always a necessary symbol) resolved_symbols = set() @@ -773,26 +794,11 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e os.chdir(cwd) try_delete(target) - if remove_duplicates: - # Remove duplicate symbols. This is a workaround for how we compile .a files, we try to - # emulate ld behavior which is permissive TODO: cache llvm-nm results - seen_symbols = set() - print >> sys.stderr, actual_files - for actual in actual_files: - symbols = Building.llvm_nm(actual) - dupes = seen_symbols.intersection(symbols.defs) - if len(dupes) > 0: - print >> sys.stderr, 'emcc: warning: removing duplicates in', actual - for dupe in dupes: - print >> sys.stderr, 'emcc: warning: removing duplicate', dupe - Building.remove_symbol(actual, dupe) - Popen([LLVM_EXTRACT, actual, '-delete', '-glob=.str', '-o', actual], stderr=PIPE).communicate() # garbage that appears here - seen_symbols = seen_symbols.union(symbols.defs) - # Finish link + actual_files = unique_ordered(actual_files) # tolerate people trying to link a.so a.so etc. if DEBUG: print >>sys.stderr, 'emcc: llvm-linking:', actual_files output = Popen([LLVM_LINK] + actual_files + ['-o', target], stdout=PIPE).communicate()[0] - assert os.path.exists(target) and (output is None or 'Could not open input file' not in output), 'Linking error: ' + output + '\nemcc: If you get duplicate symbol errors, try --remove-duplicates' + assert os.path.exists(target) and (output is None or 'Could not open input file' not in output), 'Linking error: ' + output for temp_dir in temp_dirs: try_delete(temp_dir) @@ -877,13 +883,13 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e if output_filename is None: output_filename = filename + '.o' try_delete(output_filename) - Popen(ENV_PREFIX + ['python', EMCC, filename] + args + ['-o', output_filename], stdout=stdout, stderr=stderr, env=env).communicate() + Popen([PYTHON, EMCC, filename] + args + ['-o', output_filename], stdout=stdout, stderr=stderr, env=env).communicate() assert os.path.exists(output_filename), 'emcc could not create output file' @staticmethod def emar(action, output_filename, filenames, stdout=None, stderr=None, env=None): try_delete(output_filename) - Popen(ENV_PREFIX + ['python', EMAR, action, output_filename] + filenames, stdout=stdout, stderr=stderr, env=env).communicate() + Popen([PYTHON, EMAR, action, output_filename] + filenames, stdout=stdout, stderr=stderr, env=env).communicate() if 'c' in action: assert os.path.exists(output_filename), 'emar could not create output file' @@ -894,7 +900,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e # Run Emscripten settings = Settings.serialize() - compiler_output = timeout_run(Popen(ENV_PREFIX + ['python', EMSCRIPTEN, filename + ('.o.ll' if append_ext else ''), '-o', filename + '.o.js'] + settings + extra_args, stdout=PIPE), None, 'Compiling') + compiler_output = timeout_run(Popen([PYTHON, EMSCRIPTEN, filename + ('.o.ll' if append_ext else ''), '-o', filename + '.o.js'] + settings + extra_args, stdout=PIPE), None, 'Compiling') #print compiler_output # Detect compilation crashes and errors @@ -916,6 +922,12 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e return Settings.INLINING_LIMIT == 0 @staticmethod + def get_safe_internalize(): + exports = ','.join(map(lambda exp: exp[1:], Settings.EXPORTED_FUNCTIONS)) + # internalize carefully, llvm 3.2 will remove even main if not told not to + return ['-internalize', '-internalize-public-api-list=' + exports] + + @staticmethod def pick_llvm_opts(optimization_level): ''' It may be safe to use nonportable optimizations (like -OX) if we remove the platform info from the .ll @@ -950,7 +962,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e opts.append('-basicaa') # makes fannkuch slow but primes fast if Building.can_build_standalone(): - opts.append('-internalize') + opts += Building.get_safe_internalize() opts.append('-globalopt') opts.append('-ipsccp') @@ -1059,7 +1071,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e Building._is_ar_cache[filename] = sigcheck return sigcheck except Exception, e: - print 'shared.Building.is_ar failed to test whether file \'%s\' is a llvm archive file! Failed on exception: %s' % (filename, e) + print >> sys.stderr, 'shared.Building.is_ar failed to test whether file \'%s\' is a llvm archive file! Failed on exception: %s' % (filename, e) return False @staticmethod @@ -1079,7 +1091,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e assert os.path.exists(test_ll) try_delete(test_ll) except Exception, e: - print 'shared.Building.is_bitcode failed to test whether file \'%s\' is a llvm bitcode file! Failed on exception: %s' % (filename, e) + print >> sys.stderr, 'shared.Building.is_bitcode failed to test whether file \'%s\' is a llvm bitcode file! Failed on exception: %s' % (filename, e) return False # look for magic signature @@ -1110,7 +1122,12 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e def make(opt_level): raw = RELOOPER + '.raw.js' - Building.emcc(os.path.join('relooper', 'Relooper.cpp'), ['-I' + os.path.join('relooper'), '--post-js', os.path.join('relooper', 'emscripten', 'glue.js'), '-s', 'TOTAL_MEMORY=52428800', '-s', 'DEFAULT_LIBRARY_FUNCS_TO_INCLUDE=["memcpy", "memset", "malloc", "free", "puts"]', '-O' + str(opt_level), '--closure', '0'], raw) + Building.emcc(os.path.join('relooper', 'Relooper.cpp'), ['-I' + os.path.join('relooper'), '--post-js', + os.path.join('relooper', 'emscripten', 'glue.js'), + '-s', 'TOTAL_MEMORY=52428800', + '-s', 'EXPORTED_FUNCTIONS=["_rl_set_output_buffer","_rl_make_output_buffer","_rl_new_block","_rl_delete_block","_rl_block_add_branch_to","_rl_new_relooper","_rl_delete_relooper","_rl_relooper_add_block","_rl_relooper_calculate","_rl_relooper_render"]', + '-s', 'DEFAULT_LIBRARY_FUNCS_TO_INCLUDE=["memcpy", "memset", "malloc", "free", "puts"]', + '-O' + str(opt_level), '--closure', '0'], raw) f = open(RELOOPER, 'w') f.write("// Relooper, (C) 2012 Alon Zakai, MIT license, https://github.com/kripken/Relooper\n") f.write("var Relooper = (function() {\n"); |