diff options
-rw-r--r-- | src/jsifier.js | 32 | ||||
-rw-r--r-- | src/library.js | 87 | ||||
-rw-r--r-- | src/library_sdl.js | 20 | ||||
-rw-r--r-- | src/modules.js | 6 | ||||
-rw-r--r-- | src/parseTools.js | 36 | ||||
-rw-r--r-- | src/preamble.js | 27 | ||||
-rw-r--r-- | src/settings.js | 2 | ||||
-rw-r--r-- | system/include/SDL/SDL_stdinc.h | 2 | ||||
-rw-r--r-- | system/include/libc/ctype.h | 4 | ||||
-rw-r--r-- | system/include/libcxx/ostream | 2 | ||||
-rw-r--r-- | system/include/net/arpa/inet.h | 2 | ||||
-rw-r--r-- | system/include/net/netdb.h | 9 | ||||
-rw-r--r-- | system/include/net/netinet/in.h | 2 | ||||
-rw-r--r-- | system/include/sys/socket.h | 15 | ||||
-rw-r--r-- | tests/ctype/output.txt | 104 | ||||
-rw-r--r-- | tests/ctype/src.c | 187 | ||||
-rw-r--r-- | tests/printf/output.txt | 2 | ||||
-rw-r--r-- | tests/printf/test.c | 2 | ||||
-rw-r--r-- | tests/runner.py | 526 | ||||
-rwxr-xr-x | tools/emmaken.py | 14 | ||||
-rw-r--r-- | tools/file2json.py | 19 | ||||
-rw-r--r-- | tools/make_file.py | 2 | ||||
-rw-r--r-- | tools/shared.py | 20 |
23 files changed, 693 insertions, 429 deletions
diff --git a/src/jsifier.js b/src/jsifier.js index 9c34ddf1..91cfbe6a 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -42,6 +42,7 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) { substrate = new Substrate('JSifyer'); var GLOBAL_VARIABLES = !mainPass ? givenGlobalVariables : data.globalVariables; + Variables.globals = GLOBAL_VARIABLES; Functions.currFunctions = !mainPass ? givenFunctions.currFunctions : {}; Functions.currExternalFunctions = !mainPass ? givenFunctions.currExternalFunctions : {}; @@ -831,28 +832,13 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) { // We cannot compile assembly. See comment in intertyper.js:'Call' assert(ident != 'asm', 'Inline assembly cannot be compiled to JavaScript!'); - // Special cases - if (ident == '_llvm_va_start') { - // varargs - we received a pointer to the varargs as a final 'extra' parameter - var data = 'arguments[' + Framework.currItem.funcData.ident + '.length]'; - return makeSetValue(params[0].ident, 0, data, 'void*'); - } else if (ident == '_llvm_va_end') { - return ';'; - } else if (ident == '_EMSCRIPTEN_COMMENT') { - var param = finalizeParam(params[0]); - if (param.indexOf('CHECK_OVERFLOW') >= 0) { - param = param.split('(')[1].split(',')[0]; - } - return '// ' + GLOBAL_VARIABLES[param].value.text.replace('\\00', '') + ' '; - } - + var shortident = LibraryManager.getRootIdent(ident.slice(1)) || ident.slice(1); // ident may not be in library, if all there is is ident__inline var func = Functions.currFunctions[ident] || Functions.currExternalFunctions[ident]; - var args = []; var argsTypes = []; var varargs = []; var varargsTypes = []; - var useJSArgs = (ident.slice(1) + '__jsargs') in LibraryManager.library; + var useJSArgs = (shortident + '__jsargs') in LibraryManager.library; params.forEach(function(param, i) { var val = finalizeParam(param); @@ -878,11 +864,21 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) { varargs = makePointer('[' + varargs + ']', 0, 'ALLOC_STACK', varargsTypes); } + args = args.concat(varargs); + var argsText = args.join(', '); + + // Inline if either we inline whenever we can (and we can), or if there is no noninlined version + var inline = LibraryManager.library[shortident + '__inline']; + var nonInlined = shortident in LibraryManager.library; + if (inline && (INLINE_LIBRARY_FUNCS || !nonInlined)) { + return inline.apply(null, args); // Warning: inlining does not prevent recalculation of the arguments. They should be simple identifiers + } + if (getVarData(funcData, ident)) { ident = 'FUNCTION_TABLE[' + ident + ']'; } - return ident + '(' + args.concat(varargs).join(', ') + ')'; + return ident + '(' + args.join(', ') + ')'; } makeFuncLineActor('getelementptr', function(item) { return finalizeLLVMFunctionCall(item) }); makeFuncLineActor('call', function(item) { diff --git a/src/library.js b/src/library.js index c753422d..faa86c68 100644 --- a/src/library.js +++ b/src/library.js @@ -24,7 +24,7 @@ LibraryManager.library = { _impure_ptr: 0, $FS__deps: ['$ERRNO_CODES', '__setErrNo', 'stdin', 'stdout', 'stderr', '_impure_ptr'], - $FS__postset: 'FS.init();', + $FS__postset: 'FS.init(); __ATEXIT__.push({ func: function() { FS.quit() } });', $FS: { // The path to the current folder. currentPath: '/', @@ -246,8 +246,7 @@ LibraryManager.library = { // Makes sure a file's contents are loaded. Returns whether the file has // been loaded successfully. No-op for files that have been loaded already. forceLoadFile: function(obj) { - if (obj.isDevice || obj.isFolder || obj.link || - 'contents' in obj) return true; + if (obj.isDevice || obj.isFolder || obj.link || obj.contents) return true; var success = true; if (typeof XMLHttpRequest !== 'undefined') { // Browser. @@ -323,19 +322,6 @@ LibraryManager.library = { return input.cache.shift(); }; if (!output) output = function(val) { - if (!output.printer) { - if (typeof print == 'function') { - // Either console or custom print function defined. - output.printer = print; - } else if (console && typeof console.log == 'function') { - // Browser-like environment with a console. - output.printer = console.log; - } else { - // Fallback to a harmless no-op. - output.printer = function() {}; - } - } - if (!output.buffer) output.buffer = []; if (val === null || val === '\n'.charCodeAt(0)) { output.printer(output.buffer.join('')); output.buffer = []; @@ -343,6 +329,8 @@ LibraryManager.library = { output.buffer.push(String.fromCharCode(val)); } }; + if (!output.printer) output.printer = print; + if (!output.buffer) output.buffer = []; if (!error) error = output; // Create the temporary folder. @@ -403,6 +391,12 @@ LibraryManager.library = { // Once initialized, permissions start having effect. FS.ignorePermissions = false; + }, + + quit: function() { + // Flush any partially-printed lines in stdout and stderr + if (FS.streams[2].object.output.buffer.length > 0) FS.streams[2].object.output('\n'.charCodeAt(0)); + if (FS.streams[3].object.output.buffer.length > 0) FS.streams[3].object.output('\n'.charCodeAt(0)); } }, @@ -3353,6 +3347,7 @@ LibraryManager.library = { qsort__deps: ['memcpy'], qsort: function(base, num, size, comparator) { + if (num == 0 || size == 0) return; // forward calls to the JavaScript sort method // first, sort the items logically comparator = FUNCTION_TABLE[comparator]; @@ -3572,13 +3567,21 @@ LibraryManager.library = { // string.h // ========================================================================== + memcpy__inline: function (dest, src, num, idunno) { + var ret = ''; +#if ASSERTIONS + ret += "assert(" + num + " % 1 === 0, 'memcpy given ' + " + num + " + ' bytes to copy. Problem with QUANTUM_SIZE=1 corrections perhaps?');"; +#endif + ret += makeCopyValues(dest, src, num, 'null'); + return ret; + }, memcpy: function (dest, src, num, idunno) { #if ASSERTIONS assert(num % 1 === 0, 'memcpy given ' + num + ' bytes to copy. Problem with QUANTUM_SIZE=1 corrections perhaps?'); #endif - // || 0, since memcpy sometimes copies uninitialized areas XXX: Investigate why initializing alloc'ed memory does not fix that too - {{{ makeCopyValues('dest', 'src', 'num', 'null', ' || 0') }}}; + {{{ makeCopyValues('dest', 'src', 'num', 'null') }}}; }, + llvm_memcpy_i32: 'memcpy', llvm_memcpy_i64: 'memcpy', llvm_memcpy_p0i8_p0i8_i32: 'memcpy', @@ -3598,6 +3601,9 @@ LibraryManager.library = { llvm_memmove_p0i8_p0i8_i32: 'memmove', llvm_memmove_p0i8_p0i8_i64: 'memmove', + memset__inline: function(ptr, value, num) { + return makeSetValues(ptr, 0, value, 'null', num); + }, memset: function(ptr, value, num) { {{{ makeSetValues('ptr', '0', 'value', 'null', 'num') }}} }, @@ -3978,6 +3984,14 @@ LibraryManager.library = { // LLVM specifics // ========================================================================== + llvm_va_start__inline: function(ptr) { + // varargs - we received a pointer to the varargs as a final 'extra' parameter + var data = 'arguments[' + Framework.currItem.funcData.ident + '.length]'; + return makeSetValue(ptr, 0, data, 'void*'); + }, + + llvm_va_end: function() {}, + llvm_va_copy: function(ppdest, ppsrc) { {{{ makeCopyValues('ppdest', 'ppsrc', QUANTUM_SIZE, 'null') }}} /* Alternate implementation that copies the actual DATA; it assumes the va_list is prefixed by its size @@ -4003,6 +4017,15 @@ LibraryManager.library = { } return ret; }, + + llvm_ctlz_i32: function(x) { + for (var i=0; i<32; i++) { + if ( (x & (1 << (31-i))) != 0 ) { + return i; + } + } + return 32; + }, __assert_fail: function(condition, file, line) { ABORT = true; @@ -4158,8 +4181,8 @@ LibraryManager.library = { return ret; }, - llvm_expect_i32: function(x, y) { - return x == y; // TODO: inline this + llvm_expect_i32__inline: function(x, y) { + return '((' + x + ')==(' + y + '))'; }, llvm_lifetime_start: function() {}, @@ -4169,10 +4192,20 @@ LibraryManager.library = { // iostream.h // ========================================================================== - // TODO: Document; compile from real implementation. + // libc++ + + $libcxx__postset: 'try { __ZNSt3__14coutE = 1 } catch(e){}; try { __ZNSt3__14cerrE = 2 } catch(e){};', + $libcxx: {}, + + _ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEElsEPKv__deps: ['fputs', '$libcxx'], + _ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEElsEPKv: function(stream, str) { + _fputs(str, _stdout); // XXX stderr etc. + }, + + // glibc _ZNSt8ios_base4InitC1Ev: function() { - // need valid 'file descriptors' + // need valid 'file descriptors' for glibc //__ZSt4cout = 1; //__ZSt4cerr = 2; }, @@ -4245,6 +4278,11 @@ LibraryManager.library = { scalbnf: 'ldexp', scalbln: 'ldexp', scalblnf: 'ldexp', + cbrt: function(x) { + return Math.pow(x, 1/3); + }, + cbrtf: 'cbrt', + cbrtl: 'cbrt', modf: function(x, intpart) { {{{ makeSetValue('intpart', 0, 'Math.floor(x)', 'double') }}} @@ -5374,6 +5412,11 @@ LibraryManager.library = { _Z21emscripten_run_scriptPKc: function(ptr) { eval(Pointer_stringify(ptr)); + }, + + EMSCRIPTEN_COMMENT__inline: function(param) { + param = stripCorrections(param); + return '// ' + Variables.globals[param].value.text.replace('\\00', '') + ' '; } }; diff --git a/src/library_sdl.js b/src/library_sdl.js index af94301a..5ca049fe 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -255,6 +255,8 @@ mergeInto(LibraryManager.library, { }, SDL_SetVideoMode: function(width, height, depth, flags) { + Module['canvas'].width = width; + Module['canvas'].height = height; return SDL.screen = SDL.makeSurface(width, height, flags); }, @@ -268,7 +270,7 @@ mergeInto(LibraryManager.library, { } surfData.ctx.putImageData(surfData.image, 0, 0); } - _SDL_CloseAudio(); // make sure we don't leave our audio timer running + if (SDL.audio) _SDL_CloseAudio(); // make sure we don't leave our audio timer running __shutdownRuntime__(); throw 'SDL_Quit!'; }, @@ -304,11 +306,27 @@ mergeInto(LibraryManager.library, { if (!surfData.colors) { var data = surfData.image.data; var buffer = surfData.buffer; +#if USE_TYPED_ARRAYS == 2 + assert(buffer % 4 == 0, 'Invalid buffer offset: ' + buffer); + var src = buffer >> 2; + var dst = 0; + while (dst < num) { + var val = HEAP32[src]; // This is optimized. Instead, we could do {{{ makeGetValue('buffer', 'dst', 'i32') }}}; + data[dst] = val & 0xff; + data[dst+1] = (val >> 8) & 0xff; + data[dst+2] = (val >> 16) & 0xff; + data[dst+3] = 0xff; + src++; + dst += 4; + } +#else for (var i = 0; i < num; i++) { // We may need to correct signs here. Potentially you can hardcode a write of 255 to alpha, say, and // the compiler may decide to write -1 in the llvm bitcode... data[i] = {{{ makeGetValue('buffer', 'i', 'i8') + (CORRECT_SIGNS ? '&0xff' : '') }}}; + if (i % 4 == 3) data[i] = 0xff; } +#endif } else { var width = Module['canvas'].width; var height = Module['canvas'].height; diff --git a/src/modules.js b/src/modules.js index 2341b575..3b370878 100644 --- a/src/modules.js +++ b/src/modules.js @@ -186,6 +186,10 @@ var Debugging = { } }; +var Variables = { + globals: null +}; + var Types = { types: {}, fatTypes: {}, // With QUANTUM_SIZE=1, we store the full-size type data here @@ -255,7 +259,7 @@ var LibraryManager = { load: function() { assert(!this.library); - for (var suffix in set('', '_sdl', '_gl', '_browser')) { + for (var suffix in set('', '_sdl', '_browser')) { eval(processMacros(preprocess(read('library' + suffix + '.js'), CONSTANTS))); } }, diff --git a/src/parseTools.js b/src/parseTools.js index f9ef419a..2e7e1970 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -793,14 +793,23 @@ function makeSetValue(ptr, pos, value, type, noNeedFirst, ignore) { } } +var UNROLL_LOOP_LIMIT = 5; + function makeSetValues(ptr, pos, value, type, num) { function safety(where) { where = where || getFastValue(ptr, '+', pos) + '+$mspi$'; return ';' + (SAFE_HEAP ? 'SAFE_HEAP_ACCESS(' + where + ', ' + type + ', 1)' : ''); } if (USE_TYPED_ARRAYS in set(0, 1)) { + if (isNumber(num)) { + if (num < UNROLL_LOOP_LIMIT) { + return range(num).map(function(i) { + return makeSetValue(ptr, getFastValue(pos, '+', i), value, type); + }).join('; '); + } + } return 'for (var $mspi$ = 0; $mspi$ < ' + num + '; $mspi$++) {\n' + - makeSetValue(ptr, getFastValue(pos, '+', '$mspi$'), value, type) + ';\n}'; + makeSetValue(ptr, getFastValue(pos, '+', '$mspi$'), value, type) + '\n}'; } else { // USE_TYPED_ARRAYS == 2 /* return 'for (var $mspi$ = 0; $mspi$ < ' + num + '; $mspi$++) {\n' + @@ -837,6 +846,17 @@ function makeCopyValues(dest, src, num, type, modifier) { return (SAFE_HEAP ? 'SAFE_HEAP_COPY_HISTORY(' + to + ', ' + from + ')' : ''); } if (USE_TYPED_ARRAYS in set(0, 1)) { + if (isNumber(num)) { + if (num < UNROLL_LOOP_LIMIT) { + return range(num).map(function(i) { + return type !== 'null' ? makeSetValue(dest, i, makeGetValue(src, i, type) + (modifier || ''), type) + : // Null is special-cased: We copy over all heaps + makeGetSlabs(dest, 'null', true).map(function(slab) { + return slab + '[' + dest + '+' + i + ']=' + slab + '[' + src + '+' + i + ']'; + }).join('; ') + '; ' + safety(dest + '+' + i, src + '+' + i) + }).join('; '); + } + } return 'for (var $mcpi$ = 0; $mcpi$ < ' + num + '; $mcpi$++) {\n' + (type !== 'null' ? makeSetValue(dest, '$mcpi$', makeGetValue(src, '$mcpi$', type) + (modifier || ''), type) : // Null is special-cased: We copy over all heaps @@ -1362,3 +1382,17 @@ function finalizeBlockAddress(param) { return Functions.currFunctions[param.func].labelIds[param.label]; // XXX We rely on currFunctions here...? } +function stripCorrections(param) { + var m; + if (m = /^\((.*)\)$/.exec(param)) { + param = m[1]; + } + if (m = /^\((\w+)\)&\d+$/.exec(param)) { + param = m[1]; + } + if (m = /CHECK_OVERFLOW\(([^,)]*),.*/.exec(param)) { + param = m[1]; + } + return param; +} + diff --git a/src/preamble.js b/src/preamble.js index c8f93b56..8f8921f5 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -23,6 +23,9 @@ var ACCEPTABLE_SAFE_HEAP_ERRORS = 0; function SAFE_HEAP_ACCESS(dest, type, store, ignore) { //if (dest === A_NUMBER) print ([dest, type, store] + ' ' + new Error().stack); // Something like this may be useful, in debugging +#if USE_TYPED_ARRAYS == 2 + return; // It is legitimate to violate the load-store assumption in this case +#endif if (type && type[type.length-1] == '*') type = 'i32'; // pointers are ints, for our purposes here // Note that this will pass even with unions: You can store X, load X, then store Y and load Y. // You cannot, however, do the nonportable act of store X and load Y! @@ -30,7 +33,7 @@ function SAFE_HEAP_ACCESS(dest, type, store, ignore) { HEAP_HISTORY[dest] = ignore ? null : type; } else { #if USE_TYPED_ARRAYS == 0 - if (!HEAP[dest] && HEAP[dest] !== 0 && HEAP[dest] !== false) { // false can be the result of a mathop comparator + if (!HEAP[dest] && HEAP[dest] !== 0 && HEAP[dest] !== false && !ignore) { // false can be the result of a mathop comparator var error = true; try { if (HEAP[dest].toString() === 'NaN') error = false; // NaN is acceptable, as a double value @@ -98,11 +101,11 @@ function SAFE_HEAP_STORE(dest, value, type, ignore) { if (type[type.length-1] === '*') type = 'i32'; // hardcoded pointers as 32-bit switch(type) { case 'i1': case 'i8': HEAP8[dest] = value; break; - case 'i16': assert(dest % 2 === 0, type + ' stores must be aligned'); HEAP16[dest>>1] = value; break; - case 'i32': assert(dest % 4 === 0, type + ' stores must be aligned'); HEAP32[dest>>2] = value; break; - case 'i64': assert(dest % 4 === 0, type + ' stores must be aligned'); warn64(); HEAP32[dest>>2] = value; break; // XXX store int64 as int32 - case 'float': assert(dest % 4 === 0, type + ' stores must be aligned'); HEAPF32[dest>>2] = value; break; - case 'double': assert(dest % 4 === 0, type + ' stores must be aligned'); warn64(); HEAPF32[dest>>2] = value; break; // XXX store doubles as floats + case 'i16': assert(dest % 2 === 0, type + ' stores must be aligned: ' + dest); HEAP16[dest>>1] = value; break; + case 'i32': assert(dest % 4 === 0, type + ' stores must be aligned: ' + dest); HEAP32[dest>>2] = value; break; + case 'i64': assert(dest % 4 === 0, type + ' stores must be aligned: ' + dest); warn64(); HEAP32[dest>>2] = value; break; // XXX store int64 as int32 + case 'float': assert(dest % 4 === 0, type + ' stores must be aligned: ' + dest); HEAPF32[dest>>2] = value; break; + case 'double': assert(dest % 4 === 0, type + ' stores must be aligned: ' + dest); warn64(); HEAPF32[dest>>2] = value; break; // XXX store doubles as floats default: throw 'weird type for typed array II: ' + type + new Error().stack; } #else @@ -139,18 +142,18 @@ function SAFE_HEAP_LOAD(dest, type, unsigned, ignore) { break; } case 'i16': { - assert(dest % 2 === 0, type + ' loads must be aligned'); + assert(dest % 2 === 0, type + ' loads must be aligned: ' + dest); ret = (unsigned ? HEAPU16 : HEAP16)[dest>>1]; break; } case 'i32': case 'i64': { // XXX store int64 as int32 - assert(dest % 4 === 0, type + ' loads must be aligned'); + assert(dest % 4 === 0, type + ' loads must be aligned: ' + dest); if (type === 'i64') warn64(); ret = (unsigned ? HEAPU32 : HEAP32)[dest>>2]; break; } case 'float': case 'double': { // XXX store doubles as floats - assert(dest % 4 === 0, type + ' loads must be aligned'); + assert(dest % 4 === 0, type + ' loads must be aligned: ' + dest); if (type === 'double') warn64(); ret = HEAPF32[dest>>2]; break; @@ -655,8 +658,10 @@ Module['String_copy'] = String_copy; // Tools -if (typeof print === 'undefined') { - this['print'] = console.log; // we are on the web +if (typeof console === 'object' && typeof console.log === 'function') { + this['print'] = function(x) { console.log(x) }; // web console +} else if (typeof print === 'undefined') { + this['print'] = function(){}; // harmless no-op } // This processes a JS string into a C-line array of numbers, 0-terminated. diff --git a/src/settings.js b/src/settings.js index 0cbe989b..0fdc445d 100644 --- a/src/settings.js +++ b/src/settings.js @@ -53,6 +53,8 @@ SKIP_STACK_IN_SMALL = 1; // When enabled, does not push/pop the stack at all in // may allocate stack later, and in a loop, this can be // very bad. In particular, when debugging, printf()ing // a lot can exhaust the stack very fast, with this option. + // In particular, be careful with the autodebugger! +INLINE_LIBRARY_FUNCS = 1; // Will inline library functions that have __inline defined // Generated code debugging options SAFE_HEAP = 0; // Check each write to the heap against a list of blocked addresses diff --git a/system/include/SDL/SDL_stdinc.h b/system/include/SDL/SDL_stdinc.h index 89cbc3c5..c4ce7ccd 100644 --- a/system/include/SDL/SDL_stdinc.h +++ b/system/include/SDL/SDL_stdinc.h @@ -65,7 +65,7 @@ #endif #if defined(HAVE_INTTYPES_H) # include <inttypes.h> -#elif defined(HAVE_STDINT_H) +#elif defined(EMSCRIPTEN) || defined(HAVE_STDINT_H) # include <stdint.h> #endif #ifdef HAVE_CTYPE_H diff --git a/system/include/libc/ctype.h b/system/include/libc/ctype.h index 6df2e7c4..43d21f3f 100644 --- a/system/include/libc/ctype.h +++ b/system/include/libc/ctype.h @@ -33,9 +33,9 @@ int _EXFUN(toascii, (int __c)); #ifndef _MB_CAPABLE _CONST #endif -extern __IMPORT char *__ctype_ptr__; +/* XXX Emscripten extern __IMPORT char *__ctype_ptr__; */ -#ifndef __cplusplus +#if 0 /* ndef __cplusplus XXX Emscripten: Do not use the macros here. always use the simple functions */ /* XXX Emscripten - these confuse libc++. moved to inside ifndef __cplusplus, and added CTYPE_ */ #define CTYPE__U 01 diff --git a/system/include/libcxx/ostream b/system/include/libcxx/ostream index f1a3de9c..c70f3c15 100644 --- a/system/include/libcxx/ostream +++ b/system/include/libcxx/ostream @@ -204,6 +204,7 @@ protected: basic_ostream() {} // extension, intentially does not initialize }; +/* template <class _CharT, class _Traits> class _LIBCPP_VISIBLE basic_ostream<_CharT, _Traits>::sentry { @@ -1287,6 +1288,7 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const bitset<_Size>& __x) extern template class basic_ostream<char>; extern template class basic_ostream<wchar_t>; +*/ _LIBCPP_END_NAMESPACE_STD diff --git a/system/include/net/arpa/inet.h b/system/include/net/arpa/inet.h index 76ad8b5f..af7845fd 100644 --- a/system/include/net/arpa/inet.h +++ b/system/include/net/arpa/inet.h @@ -1,5 +1,7 @@ /* */ +#include <stdint.h> + uint32_t ntohl(uint32_t netlong); uint16_t ntohs(uint16_t netshort); diff --git a/system/include/net/netdb.h b/system/include/net/netdb.h index 3b6f3389..ee33be5f 100644 --- a/system/include/net/netdb.h +++ b/system/include/net/netdb.h @@ -16,3 +16,12 @@ extern void freeaddrinfo(struct addrinfo *ai); extern int getnameinfo (struct sockaddr *sa, socklen_t salen, char *host, socklen_t hostlen, char *serv, socklen_t servlen, unsigned int flags); const char *gai_strerror(int ecode); +struct hostent +{ + char *h_name; + char **h_aliases; + int h_addrtype; + int h_length; + char **h_addr_list; +}; + diff --git a/system/include/net/netinet/in.h b/system/include/net/netinet/in.h index 0def3127..7ac40c03 100644 --- a/system/include/net/netinet/in.h +++ b/system/include/net/netinet/in.h @@ -1,6 +1,8 @@ #define INET_ADDRSTRLEN 16 +#define INADDR_ANY 0 + struct in_addr { unsigned long s_addr; }; diff --git a/system/include/sys/socket.h b/system/include/sys/socket.h index 95a0635a..68e06509 100644 --- a/system/include/sys/socket.h +++ b/system/include/sys/socket.h @@ -1,5 +1,9 @@ /* */ +#define SOMAXCONN 128 +#define PF_INET 2 +#define SO_BROADCAST 6 + #define AF_UNSPEC 100 #define SOCK_STREAM 200 #define SOL_SOCKET 50 @@ -38,3 +42,14 @@ ssize_t send(int s, const void *buf, size_t len, int flags); int setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen); ssize_t sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen); +struct msghdr +{ + void *msg_name; + socklen_t msg_namelen; + struct iovec *msg_iov; + size_t msg_iovlen; + void * msg_control; + size_t msg_controllen; + int msg_flags; +}; + diff --git a/tests/ctype/output.txt b/tests/ctype/output.txt index 43775583..5212c40a 100644 --- a/tests/ctype/output.txt +++ b/tests/ctype/output.txt @@ -125,3 +125,107 @@ isascii('A'): 1 isascii('5'): 1 isascii('.'): 1 isascii(183): 0 + +islower(-45): 0 +islower( 10): 0 +islower('a'): 1 +islower('A'): 0 +islower('5'): 0 +islower('.'): 0 +islower(183): 0 + +isupper(-45): 0 +isupper( 10): 0 +isupper('a'): 0 +isupper('A'): 1 +isupper('5'): 0 +isupper('.'): 0 +isupper(183): 0 + +isupper(-45): 0 +isupper( 10): 0 +isupper('a'): 0 +isupper('A'): 1 +isupper('5'): 0 +isupper('.'): 0 +isupper(183): 0 + +isalpha(-45): 0 +isalpha( 10): 0 +isalpha('a'): 1 +isalpha('A'): 1 +isalpha('5'): 0 +isalpha('.'): 0 +isalpha(183): 0 + +isdigit(-45): 0 +isdigit( 10): 0 +isdigit('a'): 0 +isdigit('A'): 0 +isdigit('5'): 1 +isdigit('.'): 0 +isdigit(183): 0 + +isxdigit(-45): 0 +isxdigit( 10): 0 +isxdigit('a'): 1 +isxdigit('A'): 1 +isxdigit('5'): 1 +isxdigit('.'): 0 +isxdigit(183): 0 + +isalnum(-45): 0 +isalnum( 10): 0 +isalnum('a'): 1 +isalnum('A'): 1 +isalnum('5'): 1 +isalnum('.'): 0 +isalnum(183): 0 + +ispunct(-45): 0 +ispunct( 10): 0 +ispunct('a'): 0 +ispunct('A'): 0 +ispunct('5'): 0 +ispunct('.'): 1 +ispunct(183): 0 + +isspace(-45): 0 +isspace( 10): 1 +isspace('a'): 0 +isspace('A'): 0 +isspace('5'): 0 +isspace('.'): 0 +isspace(183): 0 + +isblank(-45): 0 +isblank( 10): 0 +isblank('a'): 0 +isblank('A'): 0 +isblank('5'): 0 +isblank('.'): 0 +isblank(183): 0 + +iscntrl(-45): 0 +iscntrl( 10): 1 +iscntrl('a'): 0 +iscntrl('A'): 0 +iscntrl('5'): 0 +iscntrl('.'): 0 +iscntrl(183): 0 + +isprint(-45): 0 +isprint( 10): 0 +isprint('a'): 1 +isprint('A'): 1 +isprint('5'): 1 +isprint('.'): 1 +isprint(183): 0 + +isgraph(-45): 0 +isgraph( 10): 0 +isgraph('a'): 1 +isgraph('A'): 1 +isgraph('5'): 1 +isgraph('.'): 1 +isgraph(183): 0 diff --git a/tests/ctype/src.c b/tests/ctype/src.c index 34436c3b..3fe99b25 100644 --- a/tests/ctype/src.c +++ b/tests/ctype/src.c @@ -73,127 +73,124 @@ int main() { printf("isascii('.'): %d\n", isascii('.') != 0); printf("isascii(183): %d\n", isascii(183) != 0); - /* These appear to require glibc headers and fail with newlib - // These are manually preprocessed to use __ctype_b_loc. The flags combination // that the test runner uses seems to cause the macro to be ignored. printf("\n"); - printf("islower(-45): %d\n", ((*__ctype_b_loc ())[(int) ((-45))] & (unsigned short int) _ISlower) != 0); - printf("islower( 10): %d\n", ((*__ctype_b_loc ())[(int) ((10))] & (unsigned short int) _ISlower) != 0); - printf("islower('a'): %d\n", ((*__ctype_b_loc ())[(int) (('a'))] & (unsigned short int) _ISlower) != 0); - printf("islower('A'): %d\n", ((*__ctype_b_loc ())[(int) (('A'))] & (unsigned short int) _ISlower) != 0); - printf("islower('5'): %d\n", ((*__ctype_b_loc ())[(int) (('5'))] & (unsigned short int) _ISlower) != 0); - printf("islower('.'): %d\n", ((*__ctype_b_loc ())[(int) (('.'))] & (unsigned short int) _ISlower) != 0); - printf("islower(183): %d\n", ((*__ctype_b_loc ())[(int) ((183))] & (unsigned short int) _ISlower) != 0); + printf("islower(-45): %d\n", islower(-45)); + printf("islower( 10): %d\n", islower(10)); + printf("islower('a'): %d\n", islower('a')); + printf("islower('A'): %d\n", islower('A')); + printf("islower('5'): %d\n", islower('5')); + printf("islower('.'): %d\n", islower('.')); + printf("islower(183): %d\n", islower(183)); printf("\n"); - printf("isupper(-45): %d\n", ((*__ctype_b_loc ())[(int) ((-45))] & (unsigned short int) _ISupper) != 0); - printf("isupper( 10): %d\n", ((*__ctype_b_loc ())[(int) ((10))] & (unsigned short int) _ISupper) != 0); - printf("isupper('a'): %d\n", ((*__ctype_b_loc ())[(int) (('a'))] & (unsigned short int) _ISupper) != 0); - printf("isupper('A'): %d\n", ((*__ctype_b_loc ())[(int) (('A'))] & (unsigned short int) _ISupper) != 0); - printf("isupper('5'): %d\n", ((*__ctype_b_loc ())[(int) (('5'))] & (unsigned short int) _ISupper) != 0); - printf("isupper('.'): %d\n", ((*__ctype_b_loc ())[(int) (('.'))] & (unsigned short int) _ISupper) != 0); - printf("isupper(183): %d\n", ((*__ctype_b_loc ())[(int) ((183))] & (unsigned short int) _ISupper) != 0); + printf("isupper(-45): %d\n", isupper(-45)); + printf("isupper( 10): %d\n", isupper(10)); + printf("isupper('a'): %d\n", isupper('a')); + printf("isupper('A'): %d\n", isupper('A')); + printf("isupper('5'): %d\n", isupper('5')); + printf("isupper('.'): %d\n", isupper('.')); + printf("isupper(183): %d\n", isupper(183)); printf("\n"); - printf("isupper(-45): %d\n", ((*__ctype_b_loc ())[(int) ((-45))] & (unsigned short int) _ISupper) != 0); - printf("isupper( 10): %d\n", ((*__ctype_b_loc ())[(int) ((10))] & (unsigned short int) _ISupper) != 0); - printf("isupper('a'): %d\n", ((*__ctype_b_loc ())[(int) (('a'))] & (unsigned short int) _ISupper) != 0); - printf("isupper('A'): %d\n", ((*__ctype_b_loc ())[(int) (('A'))] & (unsigned short int) _ISupper) != 0); - printf("isupper('5'): %d\n", ((*__ctype_b_loc ())[(int) (('5'))] & (unsigned short int) _ISupper) != 0); - printf("isupper('.'): %d\n", ((*__ctype_b_loc ())[(int) (('.'))] & (unsigned short int) _ISupper) != 0); - printf("isupper(183): %d\n", ((*__ctype_b_loc ())[(int) ((183))] & (unsigned short int) _ISupper) != 0); + printf("isupper(-45): %d\n", isupper(-45)); + printf("isupper( 10): %d\n", isupper(10)); + printf("isupper('a'): %d\n", isupper('a')); + printf("isupper('A'): %d\n", isupper('A')); + printf("isupper('5'): %d\n", isupper('5')); + printf("isupper('.'): %d\n", isupper('.')); + printf("isupper(183): %d\n", isupper(183)); printf("\n"); - printf("isalpha(-45): %d\n", ((*__ctype_b_loc ())[(int) ((-45))] & (unsigned short int) _ISalpha) != 0); - printf("isalpha( 10): %d\n", ((*__ctype_b_loc ())[(int) ((10))] & (unsigned short int) _ISalpha) != 0); - printf("isalpha('a'): %d\n", ((*__ctype_b_loc ())[(int) (('a'))] & (unsigned short int) _ISalpha) != 0); - printf("isalpha('A'): %d\n", ((*__ctype_b_loc ())[(int) (('A'))] & (unsigned short int) _ISalpha) != 0); - printf("isalpha('5'): %d\n", ((*__ctype_b_loc ())[(int) (('5'))] & (unsigned short int) _ISalpha) != 0); - printf("isalpha('.'): %d\n", ((*__ctype_b_loc ())[(int) (('.'))] & (unsigned short int) _ISalpha) != 0); - printf("isalpha(183): %d\n", ((*__ctype_b_loc ())[(int) ((183))] & (unsigned short int) _ISalpha) != 0); + printf("isalpha(-45): %d\n", isalpha(-45)); + printf("isalpha( 10): %d\n", isalpha(10)); + printf("isalpha('a'): %d\n", isalpha('a')); + printf("isalpha('A'): %d\n", isalpha('A')); + printf("isalpha('5'): %d\n", isalpha('5')); + printf("isalpha('.'): %d\n", isalpha('.')); + printf("isalpha(183): %d\n", isalpha(183)); printf("\n"); - printf("isdigit(-45): %d\n", ((*__ctype_b_loc ())[(int) ((-45))] & (unsigned short int) _ISdigit) != 0); - printf("isdigit( 10): %d\n", ((*__ctype_b_loc ())[(int) ((10))] & (unsigned short int) _ISdigit) != 0); - printf("isdigit('a'): %d\n", ((*__ctype_b_loc ())[(int) (('a'))] & (unsigned short int) _ISdigit) != 0); - printf("isdigit('A'): %d\n", ((*__ctype_b_loc ())[(int) (('A'))] & (unsigned short int) _ISdigit) != 0); - printf("isdigit('5'): %d\n", ((*__ctype_b_loc ())[(int) (('5'))] & (unsigned short int) _ISdigit) != 0); - printf("isdigit('.'): %d\n", ((*__ctype_b_loc ())[(int) (('.'))] & (unsigned short int) _ISdigit) != 0); - printf("isdigit(183): %d\n", ((*__ctype_b_loc ())[(int) ((183))] & (unsigned short int) _ISdigit) != 0); + printf("isdigit(-45): %d\n", isdigit(-45)); + printf("isdigit( 10): %d\n", isdigit(10)); + printf("isdigit('a'): %d\n", isdigit('a')); + printf("isdigit('A'): %d\n", isdigit('A')); + printf("isdigit('5'): %d\n", isdigit('5')); + printf("isdigit('.'): %d\n", isdigit('.')); + printf("isdigit(183): %d\n", isdigit(183)); printf("\n"); - printf("isxdigit(-45): %d\n", ((*__ctype_b_loc ())[(int) ((-45))] & (unsigned short int) _ISxdigit) != 0); - printf("isxdigit( 10): %d\n", ((*__ctype_b_loc ())[(int) ((10))] & (unsigned short int) _ISxdigit) != 0); - printf("isxdigit('a'): %d\n", ((*__ctype_b_loc ())[(int) (('a'))] & (unsigned short int) _ISxdigit) != 0); - printf("isxdigit('A'): %d\n", ((*__ctype_b_loc ())[(int) (('A'))] & (unsigned short int) _ISxdigit) != 0); - printf("isxdigit('5'): %d\n", ((*__ctype_b_loc ())[(int) (('5'))] & (unsigned short int) _ISxdigit) != 0); - printf("isxdigit('.'): %d\n", ((*__ctype_b_loc ())[(int) (('.'))] & (unsigned short int) _ISxdigit) != 0); - printf("isxdigit(183): %d\n", ((*__ctype_b_loc ())[(int) ((183))] & (unsigned short int) _ISxdigit) != 0); + printf("isxdigit(-45): %d\n", isxdigit(-45)); + printf("isxdigit( 10): %d\n", isxdigit(10)); + printf("isxdigit('a'): %d\n", isxdigit('a')); + printf("isxdigit('A'): %d\n", isxdigit('A')); + printf("isxdigit('5'): %d\n", isxdigit('5')); + printf("isxdigit('.'): %d\n", isxdigit('.')); + printf("isxdigit(183): %d\n", isxdigit(183)); printf("\n"); - printf("isalnum(-45): %d\n", ((*__ctype_b_loc ())[(int) ((-45))] & (unsigned short int) _ISalnum) != 0); - printf("isalnum( 10): %d\n", ((*__ctype_b_loc ())[(int) ((10))] & (unsigned short int) _ISalnum) != 0); - printf("isalnum('a'): %d\n", ((*__ctype_b_loc ())[(int) (('a'))] & (unsigned short int) _ISalnum) != 0); - printf("isalnum('A'): %d\n", ((*__ctype_b_loc ())[(int) (('A'))] & (unsigned short int) _ISalnum) != 0); - printf("isalnum('5'): %d\n", ((*__ctype_b_loc ())[(int) (('5'))] & (unsigned short int) _ISalnum) != 0); - printf("isalnum('.'): %d\n", ((*__ctype_b_loc ())[(int) (('.'))] & (unsigned short int) _ISalnum) != 0); - printf("isalnum(183): %d\n", ((*__ctype_b_loc ())[(int) ((183))] & (unsigned short int) _ISalnum) != 0); + printf("isalnum(-45): %d\n", isalnum(-45)); + printf("isalnum( 10): %d\n", isalnum(10)); + printf("isalnum('a'): %d\n", isalnum('a')); + printf("isalnum('A'): %d\n", isalnum('A')); + printf("isalnum('5'): %d\n", isalnum('5')); + printf("isalnum('.'): %d\n", isalnum('.')); + printf("isalnum(183): %d\n", isalnum(183)); printf("\n"); - printf("ispunct(-45): %d\n", ((*__ctype_b_loc ())[(int) ((-45))] & (unsigned short int) _ISpunct) != 0); - printf("ispunct( 10): %d\n", ((*__ctype_b_loc ())[(int) ((10))] & (unsigned short int) _ISpunct) != 0); - printf("ispunct('a'): %d\n", ((*__ctype_b_loc ())[(int) (('a'))] & (unsigned short int) _ISpunct) != 0); - printf("ispunct('A'): %d\n", ((*__ctype_b_loc ())[(int) (('A'))] & (unsigned short int) _ISpunct) != 0); - printf("ispunct('5'): %d\n", ((*__ctype_b_loc ())[(int) (('5'))] & (unsigned short int) _ISpunct) != 0); - printf("ispunct('.'): %d\n", ((*__ctype_b_loc ())[(int) (('.'))] & (unsigned short int) _ISpunct) != 0); - printf("ispunct(183): %d\n", ((*__ctype_b_loc ())[(int) ((183))] & (unsigned short int) _ISpunct) != 0); + printf("ispunct(-45): %d\n", ispunct(-45)); + printf("ispunct( 10): %d\n", ispunct(10)); + printf("ispunct('a'): %d\n", ispunct('a')); + printf("ispunct('A'): %d\n", ispunct('A')); + printf("ispunct('5'): %d\n", ispunct('5')); + printf("ispunct('.'): %d\n", ispunct('.')); + printf("ispunct(183): %d\n", ispunct(183)); printf("\n"); - printf("isspace(-45): %d\n", ((*__ctype_b_loc ())[(int) ((-45))] & (unsigned short int) _ISspace) != 0); - printf("isspace( 10): %d\n", ((*__ctype_b_loc ())[(int) ((10))] & (unsigned short int) _ISspace) != 0); - printf("isspace('a'): %d\n", ((*__ctype_b_loc ())[(int) (('a'))] & (unsigned short int) _ISspace) != 0); - printf("isspace('A'): %d\n", ((*__ctype_b_loc ())[(int) (('A'))] & (unsigned short int) _ISspace) != 0); - printf("isspace('5'): %d\n", ((*__ctype_b_loc ())[(int) (('5'))] & (unsigned short int) _ISspace) != 0); - printf("isspace('.'): %d\n", ((*__ctype_b_loc ())[(int) (('.'))] & (unsigned short int) _ISspace) != 0); - printf("isspace(183): %d\n", ((*__ctype_b_loc ())[(int) ((183))] & (unsigned short int) _ISspace) != 0); + printf("isspace(-45): %d\n", isspace(-45)); + printf("isspace( 10): %d\n", isspace(10)); + printf("isspace('a'): %d\n", isspace('a')); + printf("isspace('A'): %d\n", isspace('A')); + printf("isspace('5'): %d\n", isspace('5')); + printf("isspace('.'): %d\n", isspace('.')); + printf("isspace(183): %d\n", isspace(183)); printf("\n"); - printf("isblank(-45): %d\n", ((*__ctype_b_loc ())[(int) ((-45))] & (unsigned short int) _ISblank) != 0); - printf("isblank( 10): %d\n", ((*__ctype_b_loc ())[(int) ((10))] & (unsigned short int) _ISblank) != 0); - printf("isblank('a'): %d\n", ((*__ctype_b_loc ())[(int) (('a'))] & (unsigned short int) _ISblank) != 0); - printf("isblank('A'): %d\n", ((*__ctype_b_loc ())[(int) (('A'))] & (unsigned short int) _ISblank) != 0); - printf("isblank('5'): %d\n", ((*__ctype_b_loc ())[(int) (('5'))] & (unsigned short int) _ISblank) != 0); - printf("isblank('.'): %d\n", ((*__ctype_b_loc ())[(int) (('.'))] & (unsigned short int) _ISblank) != 0); - printf("isblank(183): %d\n", ((*__ctype_b_loc ())[(int) ((183))] & (unsigned short int) _ISblank) != 0); + printf("isblank(-45): %d\n", isblank(-45)); + printf("isblank( 10): %d\n", isblank(10)); + printf("isblank('a'): %d\n", isblank('a')); + printf("isblank('A'): %d\n", isblank('A')); + printf("isblank('5'): %d\n", isblank('5')); + printf("isblank('.'): %d\n", isblank('.')); + printf("isblank(183): %d\n", isblank(183)); printf("\n"); - printf("iscntrl(-45): %d\n", ((*__ctype_b_loc ())[(int) ((-45))] & (unsigned short int) _IScntrl) != 0); - printf("iscntrl( 10): %d\n", ((*__ctype_b_loc ())[(int) ((10))] & (unsigned short int) _IScntrl) != 0); - printf("iscntrl('a'): %d\n", ((*__ctype_b_loc ())[(int) (('a'))] & (unsigned short int) _IScntrl) != 0); - printf("iscntrl('A'): %d\n", ((*__ctype_b_loc ())[(int) (('A'))] & (unsigned short int) _IScntrl) != 0); - printf("iscntrl('5'): %d\n", ((*__ctype_b_loc ())[(int) (('5'))] & (unsigned short int) _IScntrl) != 0); - printf("iscntrl('.'): %d\n", ((*__ctype_b_loc ())[(int) (('.'))] & (unsigned short int) _IScntrl) != 0); - printf("iscntrl(183): %d\n", ((*__ctype_b_loc ())[(int) ((183))] & (unsigned short int) _IScntrl) != 0); + printf("iscntrl(-45): %d\n", iscntrl(-45)); + printf("iscntrl( 10): %d\n", iscntrl(10)); + printf("iscntrl('a'): %d\n", iscntrl('a')); + printf("iscntrl('A'): %d\n", iscntrl('A')); + printf("iscntrl('5'): %d\n", iscntrl('5')); + printf("iscntrl('.'): %d\n", iscntrl('.')); + printf("iscntrl(183): %d\n", iscntrl(183)); printf("\n"); - printf("isprint(-45): %d\n", ((*__ctype_b_loc ())[(int) ((-45))] & (unsigned short int) _ISprint) != 0); - printf("isprint( 10): %d\n", ((*__ctype_b_loc ())[(int) ((10))] & (unsigned short int) _ISprint) != 0); - printf("isprint('a'): %d\n", ((*__ctype_b_loc ())[(int) (('a'))] & (unsigned short int) _ISprint) != 0); - printf("isprint('A'): %d\n", ((*__ctype_b_loc ())[(int) (('A'))] & (unsigned short int) _ISprint) != 0); - printf("isprint('5'): %d\n", ((*__ctype_b_loc ())[(int) (('5'))] & (unsigned short int) _ISprint) != 0); - printf("isprint('.'): %d\n", ((*__ctype_b_loc ())[(int) (('.'))] & (unsigned short int) _ISprint) != 0); - printf("isprint(183): %d\n", ((*__ctype_b_loc ())[(int) ((183))] & (unsigned short int) _ISprint) != 0); + printf("isprint(-45): %d\n", isprint(-45)); + printf("isprint( 10): %d\n", isprint(10)); + printf("isprint('a'): %d\n", isprint('a')); + printf("isprint('A'): %d\n", isprint('A')); + printf("isprint('5'): %d\n", isprint('5')); + printf("isprint('.'): %d\n", isprint('.')); + printf("isprint(183): %d\n", isprint(183)); printf("\n"); - printf("isgraph(-45): %d\n", ((*__ctype_b_loc ())[(int) ((-45))] & (unsigned short int) _ISgraph) != 0); - printf("isgraph( 10): %d\n", ((*__ctype_b_loc ())[(int) ((10))] & (unsigned short int) _ISgraph) != 0); - printf("isgraph('a'): %d\n", ((*__ctype_b_loc ())[(int) (('a'))] & (unsigned short int) _ISgraph) != 0); - printf("isgraph('A'): %d\n", ((*__ctype_b_loc ())[(int) (('A'))] & (unsigned short int) _ISgraph) != 0); - printf("isgraph('5'): %d\n", ((*__ctype_b_loc ())[(int) (('5'))] & (unsigned short int) _ISgraph) != 0); - printf("isgraph('.'): %d\n", ((*__ctype_b_loc ())[(int) (('.'))] & (unsigned short int) _ISgraph) != 0); - printf("isgraph(183): %d\n", ((*__ctype_b_loc ())[(int) ((183))] & (unsigned short int) _ISgraph) != 0); - */ - + printf("isgraph(-45): %d\n", isgraph(-45)); + printf("isgraph( 10): %d\n", isgraph(10)); + printf("isgraph('a'): %d\n", isgraph('a')); + printf("isgraph('A'): %d\n", isgraph('A')); + printf("isgraph('5'): %d\n", isgraph('5')); + printf("isgraph('.'): %d\n", isgraph('.')); + printf("isgraph(183): %d\n", isgraph(183)); + return 0; } diff --git a/tests/printf/output.txt b/tests/printf/output.txt index 01822327..19a6c1c2 100644 --- a/tests/printf/output.txt +++ b/tests/printf/output.txt @@ -8274,3 +8274,5 @@ ffffff8000000000 1 1 1 + +no_new_line diff --git a/tests/printf/test.c b/tests/printf/test.c index efd9d087..d05ba096 100644 --- a/tests/printf/test.c +++ b/tests/printf/test.c @@ -8279,5 +8279,7 @@ int main() { printf("%hhx\n", -0xFF); printf("%hx\n", -0xFFFF); printf("%x\n", -0xFFFFFFFF); + printf("\n"); + printf("no_new_line"); return 0; } diff --git a/tests/runner.py b/tests/runner.py index 979b5978..6520b099 100644 --- a/tests/runner.py +++ b/tests/runner.py @@ -5,7 +5,7 @@ See settings.py file for options¶ms. Edit as needed. These tests can be run in parallel using nose, for example - nosetests --processes=4 -v -s tests/runner.py + nosetests --processes=4 -v -s tests/runner.py will use 4 processes. To install nose do something like |pip install nose| or |sudo apt-get install python-nose|. @@ -28,40 +28,34 @@ try: except: raise Exception('Cannot find "COMPILER_OPTS" definition. Is ~/.emscripten set up properly? You may need to copy the template from settings.py into it.') -# Paths - -EMSCRIPTEN = path_from_root('emscripten.py') -DEMANGLER = path_from_root('third_party', 'demangler.py') -NAMESPACER = path_from_root('tools', 'namespacer.py') -EMMAKEN = path_from_root('tools', 'emmaken.py') -AUTODEBUGGER = path_from_root('tools', 'autodebugger.py') -DFE = path_from_root('tools', 'dead_function_eliminator.py') - # Global cache for tests (we have multiple TestCase instances; this object lets them share data) GlobalCache = {} -class Dummy: pass -Settings = Dummy() -Settings.saveJS = 0 - # Core test runner class, shared between normal tests and benchmarks class RunnerCore(unittest.TestCase): + save_dir = 0 + save_JS = 0 + def setUp(self): - dirname = tempfile.mkdtemp(prefix="ems_" + self.__class__.__name__ + "_", dir=TEMP_DIR) + if not self.save_dir: + dirname = tempfile.mkdtemp(prefix="ems_" + self.__class__.__name__ + "_", dir=TEMP_DIR) + else: + dirname = os.path.join(TEMP_DIR, 'tmp') if not os.path.exists(dirname): os.makedirs(dirname) self.working_dir = dirname def tearDown(self): - if Settings.saveJS: + if self.save_JS: for name in os.listdir(self.get_dir()): if name.endswith(('.o.js', '.cc.js')): suff = '.'.join(name.split('.')[-2:]) shutil.copy(os.path.join(self.get_dir(), name), os.path.join(TEMP_DIR, self.id().replace('__main__.', '').replace('.test_', '.')+'.'+suff)) - shutil.rmtree(self.get_dir()) + if not self.save_dir: + shutil.rmtree(self.get_dir()) def skip(self, why): print >> sys.stderr, '<skipping: %s> ' % why, @@ -71,12 +65,12 @@ class RunnerCore(unittest.TestCase): # Similar to LLVM::createStandardModulePasses() def pick_llvm_opts(self, optimization_level, handpicked=None): - global LLVM_OPT_OPTS, QUANTUM_SIZE, USE_TYPED_ARRAYS + global LLVM_OPT_OPTS if handpicked is None: handpicked = True # Not even TA2 can withstand instruction combining - LLVM_OPT_OPTS = pick_llvm_opts(optimization_level, handpicked, quantum_size=QUANTUM_SIZE) + LLVM_OPT_OPTS = pick_llvm_opts(optimization_level, handpicked, quantum_size=Settings.QUANTUM_SIZE) # Emscripten optimizations that we run on the .ll file def do_ll_opts(self, filename): @@ -198,7 +192,7 @@ class RunnerCore(unittest.TestCase): exported_settings = {} for setting in ['QUANTUM_SIZE', 'RELOOP', 'OPTIMIZE', 'ASSERTIONS', 'USE_TYPED_ARRAYS', 'SAFE_HEAP', 'CHECK_OVERFLOWS', 'CORRECT_OVERFLOWS', 'CORRECT_SIGNS', 'CHECK_SIGNS', 'CORRECT_OVERFLOWS_LINES', 'CORRECT_SIGNS_LINES', 'CORRECT_ROUNDINGS', 'CORRECT_ROUNDINGS_LINES', 'INVOKE_RUN', 'SAFE_HEAP_LINES', 'INIT_STACK', 'AUTO_OPTIMIZE', 'EXPORTED_FUNCTIONS', 'EXPORTED_GLOBALS', 'BUILD_AS_SHARED_LIB', 'INCLUDE_FULL_LIBRARY', 'RUNTIME_TYPE_INFO', 'DISABLE_EXCEPTION_CATCHING', 'TOTAL_MEMORY', 'FAST_MEMORY', 'EXCEPTION_DEBUG', 'PROFILE']: try: - value = eval(setting) + value = eval('Settings.' + setting) if value is not None: exported_settings[setting] = value except: @@ -289,7 +283,7 @@ if 'benchmark' not in str(sys.argv): # Run in both JavaScript engines, if optimizing - significant differences there (typed arrays) if js_engines is None: js_engines = [SPIDERMONKEY_ENGINE, V8_ENGINE] - if USE_TYPED_ARRAYS == 2: + if Settings.USE_TYPED_ARRAYS == 2: js_engines = [SPIDERMONKEY_ENGINE] # when oh when will v8 support typed arrays in the console for engine in js_engines: js_output = self.run_generated_code(engine, filename + '.o.js', args) @@ -380,7 +374,7 @@ if 'benchmark' not in str(sys.argv): self.do_run(src, '*5,23,10,19,121,1,37,1,0*\n0:-1,1:134217727,2:4194303,3:131071,4:4095,5:127,6:3,7:0,8:0*\n*56,09*\nfixed:320434\n*21*') def test_sintvars(self): - global CORRECT_SIGNS; CORRECT_SIGNS = 1 # Relevant to this test + Settings.CORRECT_SIGNS = 1 # Relevant to this test src = ''' #include <stdio.h> struct S { @@ -407,11 +401,11 @@ if 'benchmark' not in str(sys.argv): } ''' output = '*32780,32522,258*\n*258,2*\n*32780,32999,-219*\n*65317,510*' - global CORRECT_OVERFLOWS; CORRECT_OVERFLOWS = 0 # We should not need overflow correction to get this right + Settings.CORRECT_OVERFLOWS = 0 # We should not need overflow correction to get this right self.do_run(src, output, force_c=True) def test_bigint(self): - if USE_TYPED_ARRAYS != 0: return self.skip('Typed arrays truncate i64') + if Settings.USE_TYPED_ARRAYS != 0: return self.skip('Typed arrays truncate i64') src = ''' #include <stdio.h> int main() @@ -435,8 +429,8 @@ if 'benchmark' not in str(sys.argv): self.do_run(src, '*245127260211081,579378795077769,808077213656969,16428841631881,791648372025088*\n*13.00,6.00,3.00,*3*') def test_unsigned(self): - global CORRECT_SIGNS; CORRECT_SIGNS = 1 # We test for exactly this sort of thing here - global CHECK_SIGNS; CHECK_SIGNS = 0 + Settings.CORRECT_SIGNS = 1 # We test for exactly this sort of thing here + Settings.CHECK_SIGNS = 0 src = ''' #include <stdio.h> const signed char cvals[2] = { -1, -2 }; // compiler can store this is a string, so -1 becomes \FF, and needs re-signing @@ -477,12 +471,12 @@ if 'benchmark' not in str(sys.argv): # Now let's see some code that should just work in USE_TYPED_ARRAYS == 2, but requires # corrections otherwise - if USE_TYPED_ARRAYS == 2: - CORRECT_SIGNS = 0 - CHECK_SIGNS = 1 + if Settings.USE_TYPED_ARRAYS == 2: + Settings.CORRECT_SIGNS = 0 + Settings.CHECK_SIGNS = 1 else: - CORRECT_SIGNS = 1 - CHECK_SIGNS = 0 + Settings.CORRECT_SIGNS = 1 + Settings.CHECK_SIGNS = 0 src = ''' #include <stdio.h> @@ -530,7 +524,7 @@ if 'benchmark' not in str(sys.argv): self.do_run(src, '*255*\n*65535*\n*-1*\n*-1*\n*-1*') def test_bitfields(self): - global SAFE_HEAP; SAFE_HEAP = 0 # bitfields do loads on invalid areas, by design + Settings.SAFE_HEAP = 0 # bitfields do loads on invalid areas, by design src = ''' #include <stdio.h> struct bitty { @@ -960,7 +954,7 @@ if 'benchmark' not in str(sys.argv): return 1; } ''' - if QUANTUM_SIZE == 1: + if Settings.QUANTUM_SIZE == 1: self.do_run(src, 'sizeofs:6,8\n*C___: 0,3,6,9<24*\n*Carr: 0,3,6,9<24*\n*C__w: 0,3,9,12<24*\n*Cp1_: 1,2,5,8<24*\n*Cp2_: 0,2,5,8<24*\n*Cint: 0,3,4,7<24*\n*C4__: 0,3,4,7<24*\n*C4_2: 0,3,5,8<20*\n*C__z: 0,3,5,8<28*') else: self.do_run(src, 'sizeofs:6,8\n*C___: 0,6,12,20<24*\n*Carr: 0,6,12,20<24*\n*C__w: 0,6,12,20<24*\n*Cp1_: 4,6,12,20<24*\n*Cp2_: 0,6,12,20<24*\n*Cint: 0,8,12,20<24*\n*C4__: 0,8,12,20<24*\n*C4_2: 0,6,10,16<20*\n*C__z: 0,8,16,24<28*') @@ -1003,15 +997,14 @@ if 'benchmark' not in str(sys.argv): ''' self.do_run(src, '*throw...caught!infunc...done!*') - global DISABLE_EXCEPTION_CATCHING - DISABLE_EXCEPTION_CATCHING = 1 + Settings.DISABLE_EXCEPTION_CATCHING = 1 self.do_run(src, 'Compiled code throwing an exception') def test_typed_exceptions(self): return self.skip('TODO: fix this for llvm 3.0') - global SAFE_HEAP; SAFE_HEAP = 0 # Throwing null will cause an ignorable null pointer access. - global EXCEPTION_DEBUG; EXCEPTION_DEBUG = 0 # Messes up expected output. + Settings.SAFE_HEAP = 0 # Throwing null will cause an ignorable null pointer access. + Settings.EXCEPTION_DEBUG = 0 # Messes up expected output. src = open(path_from_root('tests', 'exceptions', 'typed.cpp'), 'r').read() expected = open(path_from_root('tests', 'exceptions', 'output.txt'), 'r').read() self.do_run(src, expected) @@ -1372,7 +1365,7 @@ if 'benchmark' not in str(sys.argv): printf("*%d,%d,%d*\\n", sizeof(PyGC_Head), sizeof(gc_generation), int(GEN_HEAD(2)) - int(GEN_HEAD(1))); } ''' - if QUANTUM_SIZE == 1: + if Settings.QUANTUM_SIZE == 1: # Compressed memory. Note that sizeof() does give the fat sizes, however! self.do_run(src, '*0,0,0,1,2,3,4,5*\n*1,0,0*\n*0*\n0:1,1\n1:1,1\n2:1,1\n*12,20,5*') else: @@ -1402,7 +1395,7 @@ if 'benchmark' not in str(sys.argv): def test_sizeof(self): # Has invalid writes between printouts - global SAFE_HEAP; SAFE_HEAP = 0 + Settings.SAFE_HEAP = 0 src = ''' #include <stdio.h> @@ -1436,8 +1429,7 @@ if 'benchmark' not in str(sys.argv): self.do_run(src, '*2,2,5,8,8***8,8,5,8,8***7,2,6,990,7,2*', [], lambda x: x.replace('\n', '*')) def test_emscripten_api(self): - global OPTIMIZE, RELOOP, LLVM_OPTS - if OPTIMIZE or RELOOP or LLVM_OPTS: return self.skip('FIXME') + #if Settings.OPTIMIZE or Settings.RELOOP or LLVM_OPTS: return self.skip('FIXME') src = ''' #include <stdio.h> @@ -1481,7 +1473,7 @@ if 'benchmark' not in str(sys.argv): return 0; } ''' - if QUANTUM_SIZE == 1: + if Settings.QUANTUM_SIZE == 1: self.do_run(src, '''*4*\n0:22016,0,8,12\n1:22018,1,12,8\n''') else: self.do_run(src, '''*16*\n0:22016,0,32,48\n1:22018,1,48,32\n''') @@ -1580,13 +1572,13 @@ if 'benchmark' not in str(sys.argv): return 0; } ''' - if QUANTUM_SIZE == 1: + if Settings.QUANTUM_SIZE == 1: self.do_run(src, '*4,2,3*\n*6,2,3*') else: self.do_run(src, '*4,3,4*\n*6,4,6*') def test_varargs(self): - if QUANTUM_SIZE == 1: return self.skip('FIXME: Add support for this') + if Settings.QUANTUM_SIZE == 1: return self.skip('FIXME: Add support for this') src = ''' #include <stdio.h> @@ -1653,9 +1645,9 @@ if 'benchmark' not in str(sys.argv): self.do_run(src, '*cheez: 0+24*\n*cheez: 0+24*\n*albeit*\n*albeit*\nQ85*\nmaxxi:21*\nmaxxD:22.10*\n') def test_stdlibs(self): - if USE_TYPED_ARRAYS == 2: + if Settings.USE_TYPED_ARRAYS == 2: # Typed arrays = 2 + safe heap prints a warning that messes up our output. - global SAFE_HEAP; SAFE_HEAP = 0 + Settings.SAFE_HEAP = 0 src = ''' #include <stdio.h> #include <stdlib.h> @@ -1708,7 +1700,7 @@ if 'benchmark' not in str(sys.argv): self.do_run(src, '*1,2,3,5,5,6*\n*stdin==0:0*\n*%*\n*5*\n*66.0*\n*10*\n*0*\n*-10*\n*18*\n*10*\n*0*\n*4294967286*\n*cleaned*') def test_time(self): - if USE_TYPED_ARRAYS == 2: return self.skip('Typed arrays = 2 truncate i64s') + if Settings.USE_TYPED_ARRAYS == 2: return self.skip('Typed arrays = 2 truncate i64s') src = open(path_from_root('tests', 'time', 'src.c'), 'r').read() expected = open(path_from_root('tests', 'time', 'output.txt'), 'r').read() self.do_run(src, expected, @@ -1717,10 +1709,9 @@ if 'benchmark' not in str(sys.argv): def test_statics(self): # static initializers save i16 but load i8 for some reason - global SAFE_HEAP, SAFE_HEAP_LINES - if SAFE_HEAP: - SAFE_HEAP = 3 - SAFE_HEAP_LINES = ['src.cpp:19', 'src.cpp:26'] + if Settings.SAFE_HEAP: + Settings.SAFE_HEAP = 3 + Settings.SAFE_HEAP_LINES = ['src.cpp:19', 'src.cpp:26'] src = ''' #include <stdio.h> @@ -1906,7 +1897,7 @@ if 'benchmark' not in str(sys.argv): return 0; } ''' - if QUANTUM_SIZE == 1: + if Settings.QUANTUM_SIZE == 1: # Compressed memory. Note that sizeof() does give the fat sizes, however! self.do_run(src, '*16,0,1,2,2,3|20,0,1,1,2,3,3,4|24,0,5,0,1,1,2,3,3,4*\n*0,0,0,1,2,62,63,64,72*\n*2*') else: @@ -1914,7 +1905,6 @@ if 'benchmark' not in str(sys.argv): self.do_run(src, '*16,0,4,8,8,12|20,0,4,4,8,12,12,16|24,0,20,0,4,4,8,12,12,16*\n*0,0,0,1,2,64,68,69,72*\n*2*') def test_dlfcn_basic(self): - global BUILD_AS_SHARED_LIB lib_src = ''' #include <cstdio> @@ -1929,7 +1919,7 @@ if 'benchmark' not in str(sys.argv): ''' dirname = self.get_dir() filename = os.path.join(dirname, 'liblib.cpp') - BUILD_AS_SHARED_LIB = 1 + Settings.BUILD_AS_SHARED_LIB = 1 self.build(lib_src, dirname, filename) shutil.move(filename + '.o.js', os.path.join(dirname, 'liblib.so')) @@ -1951,7 +1941,7 @@ if 'benchmark' not in str(sys.argv): return 0; } ''' - BUILD_AS_SHARED_LIB = 0 + Settings.BUILD_AS_SHARED_LIB = 0 def add_pre_run_and_checks(filename): src = open(filename, 'r').read().replace( '// {{PRE_RUN_ADDITIONS}}', @@ -1962,7 +1952,6 @@ if 'benchmark' not in str(sys.argv): post_build=add_pre_run_and_checks) def test_dlfcn_qsort(self): - global BUILD_AS_SHARED_LIB, EXPORTED_FUNCTIONS lib_src = ''' int lib_cmp(const void* left, const void* right) { const int* a = (const int*) left; @@ -1980,8 +1969,8 @@ if 'benchmark' not in str(sys.argv): ''' dirname = self.get_dir() filename = os.path.join(dirname, 'liblib.cpp') - BUILD_AS_SHARED_LIB = 1 - EXPORTED_FUNCTIONS = ['_get_cmp'] + Settings.BUILD_AS_SHARED_LIB = 1 + Settings.EXPORTED_FUNCTIONS = ['_get_cmp'] self.build(lib_src, dirname, filename) shutil.move(filename + '.o.js', os.path.join(dirname, 'liblib.so')) @@ -2035,8 +2024,8 @@ if 'benchmark' not in str(sys.argv): return 0; } ''' - BUILD_AS_SHARED_LIB = 0 - EXPORTED_FUNCTIONS = ['_main'] + Settings.BUILD_AS_SHARED_LIB = 0 + Settings.EXPORTED_FUNCTIONS = ['_main'] def add_pre_run_and_checks(filename): src = open(filename, 'r').read().replace( '// {{PRE_RUN_ADDITIONS}}', @@ -2048,10 +2037,8 @@ if 'benchmark' not in str(sys.argv): post_build=add_pre_run_and_checks) def test_dlfcn_data_and_fptr(self): - global LLVM_OPTS if LLVM_OPTS: return self.skip('LLVM opts will optimize out parent_func') - global BUILD_AS_SHARED_LIB, EXPORTED_FUNCTIONS, EXPORTED_GLOBALS lib_src = ''' #include <stdio.h> @@ -2076,9 +2063,9 @@ if 'benchmark' not in str(sys.argv): ''' dirname = self.get_dir() filename = os.path.join(dirname, 'liblib.cpp') - BUILD_AS_SHARED_LIB = 1 - EXPORTED_FUNCTIONS = ['_func'] - EXPORTED_GLOBALS = ['_global'] + Settings.BUILD_AS_SHARED_LIB = 1 + Settings.EXPORTED_FUNCTIONS = ['_func'] + Settings.EXPORTED_GLOBALS = ['_global'] self.build(lib_src, dirname, filename) shutil.move(filename + '.o.js', os.path.join(dirname, 'liblib.so')) @@ -2134,9 +2121,9 @@ if 'benchmark' not in str(sys.argv): return 0; } ''' - BUILD_AS_SHARED_LIB = 0 - EXPORTED_FUNCTIONS = ['_main'] - EXPORTED_GLOBALS = [] + Settings.BUILD_AS_SHARED_LIB = 0 + Settings.EXPORTED_FUNCTIONS = ['_main'] + Settings.EXPORTED_GLOBALS = [] def add_pre_run_and_checks(filename): src = open(filename, 'r').read().replace( '// {{PRE_RUN_ADDITIONS}}', @@ -2148,7 +2135,6 @@ if 'benchmark' not in str(sys.argv): post_build=add_pre_run_and_checks) def test_dlfcn_alias(self): - global BUILD_AS_SHARED_LIB, EXPORTED_FUNCTIONS, INCLUDE_FULL_LIBRARY lib_src = r''' #include <stdio.h> extern int parent_global; @@ -2158,8 +2144,8 @@ if 'benchmark' not in str(sys.argv): ''' dirname = self.get_dir() filename = os.path.join(dirname, 'liblib.cpp') - BUILD_AS_SHARED_LIB = 1 - EXPORTED_FUNCTIONS = ['_func'] + Settings.BUILD_AS_SHARED_LIB = 1 + Settings.EXPORTED_FUNCTIONS = ['_func'] self.build(lib_src, dirname, filename) shutil.move(filename + '.o.js', os.path.join(dirname, 'liblib.so')) @@ -2181,9 +2167,9 @@ if 'benchmark' not in str(sys.argv): return 0; } ''' - BUILD_AS_SHARED_LIB = 0 - INCLUDE_FULL_LIBRARY = 1 - EXPORTED_FUNCTIONS = ['_main'] + Settings.BUILD_AS_SHARED_LIB = 0 + Settings.INCLUDE_FULL_LIBRARY = 1 + Settings.EXPORTED_FUNCTIONS = ['_main'] def add_pre_run_and_checks(filename): src = open(filename, 'r').read().replace( '// {{PRE_RUN_ADDITIONS}}', @@ -2194,11 +2180,10 @@ if 'benchmark' not in str(sys.argv): output_nicerizer=lambda x: x.replace('\n', '*'), post_build=add_pre_run_and_checks, extra_emscripten_args=['-H', 'libc/fcntl.h,libc/sys/unistd.h,poll.h,libc/math.h,libc/time.h,libc/langinfo.h']) - INCLUDE_FULL_LIBRARY = 0 + Settings.INCLUDE_FULL_LIBRARY = 0 def test_dlfcn_varargs(self): - if QUANTUM_SIZE == 1: return self.skip('FIXME: Add support for this') - global BUILD_AS_SHARED_LIB, EXPORTED_FUNCTIONS + if Settings.QUANTUM_SIZE == 1: return self.skip('FIXME: Add support for this') lib_src = r''' void print_ints(int n, ...); extern "C" void func() { @@ -2207,8 +2192,8 @@ if 'benchmark' not in str(sys.argv): ''' dirname = self.get_dir() filename = os.path.join(dirname, 'liblib.cpp') - BUILD_AS_SHARED_LIB = 1 - EXPORTED_FUNCTIONS = ['_func'] + Settings.BUILD_AS_SHARED_LIB = 1 + Settings.EXPORTED_FUNCTIONS = ['_func'] self.build(lib_src, dirname, filename) shutil.move(filename + '.o.js', os.path.join(dirname, 'liblib.so')) @@ -2239,8 +2224,8 @@ if 'benchmark' not in str(sys.argv): return 0; } ''' - BUILD_AS_SHARED_LIB = 0 - EXPORTED_FUNCTIONS = ['_main'] + Settings.BUILD_AS_SHARED_LIB = 0 + Settings.EXPORTED_FUNCTIONS = ['_main'] def add_pre_run_and_checks(filename): src = open(filename, 'r').read().replace( '// {{PRE_RUN_ADDITIONS}}', @@ -2294,7 +2279,7 @@ if 'benchmark' not in str(sys.argv): self.do_run(src, re.sub(r'(^|\n)\s+', r'\1', expected)) def test_strtod(self): - if USE_TYPED_ARRAYS == 2: return self.skip('Typed arrays = 2 truncate doubles') + if Settings.USE_TYPED_ARRAYS == 2: return self.skip('Typed arrays = 2 truncate doubles') src = r''' #include <stdio.h> #include <stdlib.h> @@ -2349,13 +2334,13 @@ if 'benchmark' not in str(sys.argv): self.do_run(src, re.sub(r'\n\s+', '\n', expected)) def test_parseInt(self): - if USE_TYPED_ARRAYS != 0: return self.skip('Typed arrays truncate i64') + if Settings.USE_TYPED_ARRAYS != 0: return self.skip('Typed arrays truncate i64') src = open(path_from_root('tests', 'parseInt', 'src.c'), 'r').read() expected = open(path_from_root('tests', 'parseInt', 'output.txt'), 'r').read() self.do_run(src, expected) def test_printf(self): - if USE_TYPED_ARRAYS != 0: return self.skip('Typed arrays truncate i64') + if Settings.USE_TYPED_ARRAYS != 0: return self.skip('Typed arrays truncate i64') src = open(path_from_root('tests', 'printf', 'test.c'), 'r').read() expected = open(path_from_root('tests', 'printf', 'output.txt'), 'r').read() self.do_run(src, expected) @@ -2410,7 +2395,7 @@ if 'benchmark' not in str(sys.argv): self.do_run(src, expected, extra_emscripten_args=['-H', 'libc/langinfo.h']) def test_files(self): - global CORRECT_SIGNS; CORRECT_SIGNS = 1 # Just so our output is what we expect. Can flip them both. + Settings.CORRECT_SIGNS = 1 # Just so our output is what we expect. Can flip them both. def post(filename): src = open(filename, 'r').read().replace( '// {{PRE_RUN_ADDITIONS}}', @@ -2762,7 +2747,7 @@ if 'benchmark' not in str(sys.argv): self.do_run(src, re.sub('(^|\n)\s+', '\\1', expected), post_build=add_pre_run_and_checks) def test_fs_base(self): - global INCLUDE_FULL_LIBRARY; INCLUDE_FULL_LIBRARY = 1 + Settings.INCLUDE_FULL_LIBRARY = 1 try: def addJS(filename): src = open(filename, 'r').read().replace( @@ -2773,7 +2758,7 @@ if 'benchmark' not in str(sys.argv): expected = open(path_from_root('tests', 'filesystem', 'output.txt'), 'r').read() self.do_run(src, expected, post_build=addJS, extra_emscripten_args=['-H', 'libc/fcntl.h,libc/sys/unistd.h,poll.h,libc/math.h,libc/langinfo.h,libc/time.h']) finally: - INCLUDE_FULL_LIBRARY = 0 + Settings.INCLUDE_FULL_LIBRARY = 0 def test_unistd_access(self): def add_pre_run(filename): @@ -2968,12 +2953,25 @@ if 'benchmark' not in str(sys.argv): def test_ctype(self): # The bit fiddling done by the macros using __ctype_b_loc requires this. - global CORRECT_SIGNS; CORRECT_SIGNS = 1 + Settings.CORRECT_SIGNS = 1 src = open(path_from_root('tests', 'ctype', 'src.c'), 'r').read() expected = open(path_from_root('tests', 'ctype', 'output.txt'), 'r').read() self.do_run(src, expected) CORRECT_SIGNS = 0 + def test_iostream(self): + src = ''' + #include <iostream> + + int main() + { + std::cout << "hello world"; + return 0; + } + ''' + + self.do_run(src, 'hello world') + ### 'Big' tests def test_fannkuch(self): @@ -2983,8 +2981,7 @@ if 'benchmark' not in str(sys.argv): self.do_run(src, 'Pfannkuchen(%d) = %d.' % (i,j), [str(i)], no_build=i>1) def test_raytrace(self): - global USE_TYPED_ARRAYS - if USE_TYPED_ARRAYS == 2: return self.skip('Relies on double values') + if Settings.USE_TYPED_ARRAYS == 2: return self.skip('Relies on double values') src = open(path_from_root('tests', 'raytrace.cpp'), 'r').read() output = open(path_from_root('tests', 'raytrace.ppm'), 'r').read() @@ -2998,9 +2995,9 @@ if 'benchmark' not in str(sys.argv): self.do_run(src, j, [str(i)], lambda x: x.replace('\n', '*'), no_build=i>1) def test_dlmalloc(self): - global CORRECT_SIGNS; CORRECT_SIGNS = 2 - global CORRECT_SIGNS_LINES; CORRECT_SIGNS_LINES = ['src.cpp:' + str(i+4) for i in [4816, 4191, 4246, 4199, 4205, 4235, 4227]] - global TOTAL_MEMORY; TOTAL_MEMORY = 100*1024*1024 # needed with typed arrays + Settings.CORRECT_SIGNS = 2 + Settings.CORRECT_SIGNS_LINES = ['src.cpp:' + str(i+4) for i in [4816, 4191, 4246, 4199, 4205, 4235, 4227]] + Settings.TOTAL_MEMORY = 100*1024*1024 # needed with typed arrays src = open(path_from_root('src', 'dlmalloc.c'), 'r').read() + '\n\n\n' + open(path_from_root('tests', 'dlmalloc_test.c'), 'r').read() self.do_run(src, '*1,0*', ['200', '1']) @@ -3048,11 +3045,11 @@ if 'benchmark' not in str(sys.argv): def test_cubescript(self): global COMPILER_TEST_OPTS; COMPILER_TEST_OPTS = [] # remove -g, so we have one test without it by default - global SAFE_HEAP; SAFE_HEAP = 0 # Has some actual loads of unwritten-to places, in the C++ code... + Settings.SAFE_HEAP = 0 # Has some actual loads of unwritten-to places, in the C++ code... # Overflows happen in hash loop - global CORRECT_OVERFLOWS; CORRECT_OVERFLOWS = 1 - global CHECK_OVERFLOWS; CHECK_OVERFLOWS = 0 + Settings.CORRECT_OVERFLOWS = 1 + Settings.CHECK_OVERFLOWS = 0 self.do_run(path_from_root('tests', 'cubescript'), '*\nTemp is 33\n9\n5\nhello, everyone\n*', main_file='command.cpp') #build_ll_hook=self.do_autodebug) @@ -3071,15 +3068,14 @@ if 'benchmark' not in str(sys.argv): # print opt, "FAIL" def test_lua(self): - global QUANTUM_SIZE - if QUANTUM_SIZE == 1: return self.skip('TODO: make this work') + if Settings.QUANTUM_SIZE == 1: return self.skip('TODO: make this work') # Overflows in luaS_newlstr hash loop - global SAFE_HEAP; SAFE_HEAP = 0 # Has various warnings, with copied HEAP_HISTORY values (fixed if we copy 'null' as the type) - global CORRECT_OVERFLOWS; CORRECT_OVERFLOWS = 1 - global CHECK_OVERFLOWS; CHECK_OVERFLOWS = 0 - global CORRECT_SIGNS; CORRECT_SIGNS = 1 # Not sure why, but needed - global INIT_STACK; INIT_STACK = 1 # TODO: Investigate why this is necessary + Settings.SAFE_HEAP = 0 # Has various warnings, with copied HEAP_HISTORY values (fixed if we copy 'null' as the type) + Settings.CORRECT_OVERFLOWS = 1 + Settings.CHECK_OVERFLOWS = 0 + Settings.CORRECT_SIGNS = 1 # Not sure why, but needed + Settings.INIT_STACK = 1 # TODO: Investigate why this is necessary self.do_ll_run(path_from_root('tests', 'lua', 'lua.ll'), 'hello lua world!\n17\n1\n2\n3\n4\n7', @@ -3138,17 +3134,16 @@ if 'benchmark' not in str(sys.argv): return bc_file def get_freetype(self): - global INIT_STACK; INIT_STACK = 1 # TODO: Investigate why this is necessary + Settings.INIT_STACK = 1 # TODO: Investigate why this is necessary return self.get_library('freetype', os.path.join('objs', '.libs', 'libfreetype.a.bc')) def test_freetype(self): - if QUANTUM_SIZE == 1: return self.skip('TODO: Figure out and try to fix') + if Settings.QUANTUM_SIZE == 1: return self.skip('TODO: Figure out and try to fix') - if LLVM_OPTS: global RELOOP; RELOOP = 0 # Too slow; we do care about typed arrays and OPTIMIZE though + if LLVM_OPTS: Settings.RELOOP = 0 # Too slow; we do care about typed arrays and OPTIMIZE though - global CORRECT_SIGNS - if CORRECT_SIGNS == 0: CORRECT_SIGNS = 1 # Not sure why, but needed + if Settings.CORRECT_SIGNS == 0: Settings.CORRECT_SIGNS = 1 # Not sure why, but needed def post(filename): # Embed the font into the document @@ -3171,22 +3166,21 @@ if 'benchmark' not in str(sys.argv): def test_sqlite(self): # gcc -O3 -I/home/alon/Dev/emscripten/tests/sqlite -ldl src.c - global QUANTUM_SIZE, OPTIMIZE, RELOOP, USE_TYPED_ARRAYS - if QUANTUM_SIZE == 1: return self.skip('TODO FIXME') - RELOOP = 0 # too slow + if Settings.QUANTUM_SIZE == 1: return self.skip('TODO FIXME') + Settings.RELOOP = 0 # too slow auto_optimize_data = read_auto_optimize_data(path_from_root('tests', 'sqlite', 'sqlite-autooptimize.fails.txt')) - global CORRECT_SIGNS; CORRECT_SIGNS = 2 - global CORRECT_SIGNS_LINES; CORRECT_SIGNS_LINES = auto_optimize_data['signs_lines'] - global CORRECT_OVERFLOWS; CORRECT_OVERFLOWS = 0 - global CORRECT_ROUNDINGS; CORRECT_ROUNDINGS = 0 - global SAFE_HEAP; SAFE_HEAP = 0 # uses time.h to set random bytes, other stuff - global DISABLE_EXCEPTION_CATCHING; DISABLE_EXCEPTION_CATCHING = 1 - global FAST_MEMORY; FAST_MEMORY = 4*1024*1024 - global EXPORTED_FUNCTIONS; EXPORTED_FUNCTIONS = ['_main', '_sqlite3_open', '_sqlite3_close', '_sqlite3_exec', '_sqlite3_free', '_callback']; + Settings.CORRECT_SIGNS = 2 + Settings.CORRECT_SIGNS_LINES = auto_optimize_data['signs_lines'] + Settings.CORRECT_OVERFLOWS = 0 + Settings.CORRECT_ROUNDINGS = 0 + Settings.SAFE_HEAP = 0 # uses time.h to set random bytes, other stuff + Settings.DISABLE_EXCEPTION_CATCHING = 1 + Settings.FAST_MEMORY = 4*1024*1024 + Settings.EXPORTED_FUNCTIONS = ['_main', '_sqlite3_open', '_sqlite3_close', '_sqlite3_exec', '_sqlite3_free', '_callback']; - global INVOKE_RUN; INVOKE_RUN = 0 # We append code that does run() ourselves + Settings.INVOKE_RUN = 0 # We append code that does run() ourselves def post(filename): src = open(filename, 'a') @@ -3216,7 +3210,7 @@ if 'benchmark' not in str(sys.argv): post_build=post)#,build_ll_hook=self.do_autodebug) def test_zlib(self): - global CORRECT_SIGNS; CORRECT_SIGNS = 1 + Settings.CORRECT_SIGNS = 1 self.do_run(open(path_from_root('tests', 'zlib', 'example.c'), 'r').read(), open(path_from_root('tests', 'zlib', 'ref.txt'), 'r').read(), @@ -3224,33 +3218,18 @@ if 'benchmark' not in str(sys.argv): includes=[path_from_root('tests', 'zlib')], force_c=True) - def zzztest_glibc(self): - global CORRECT_SIGNS; CORRECT_SIGNS = 1 - global CORRECT_OVERFLOWS; CORRECT_OVERFLOWS = 1 - global CORRECT_ROUNDINGS; CORRECT_ROUNDINGS = 1 - - self.do_run(r''' - #include <stdio.h> - int main() { printf("hai\n"); return 1; } - ''', - libraries=[self.get_library('glibc', [os.path.join('src', '.libs', 'libBulletCollision.a.bc'), - os.path.join('src', '.libs', 'libBulletDynamics.a.bc'), - os.path.join('src', '.libs', 'libLinearMath.a.bc')], - configure_args=['--disable-sanity-checks'])], - includes=[path_from_root('tests', 'glibc', 'include')]) - def test_the_bullet(self): # Called thus so it runs late in the alphabetical cycle... it is long - global SAFE_HEAP, SAFE_HEAP_LINES, USE_TYPED_ARRAYS, LLVM_OPTS + global LLVM_OPTS - if LLVM_OPTS: SAFE_HEAP = 0 # Optimizations make it so we do not have debug info on the line we need to ignore + if LLVM_OPTS: Settings.SAFE_HEAP = 0 # Optimizations make it so we do not have debug info on the line we need to ignore - if USE_TYPED_ARRAYS == 2: return self.skip('We have slightly different rounding here for some reason. TODO: activate this') + if Settings.USE_TYPED_ARRAYS == 2: return self.skip('We have slightly different rounding here for some reason. TODO: activate this') - if SAFE_HEAP: + if Settings.SAFE_HEAP: # Ignore bitfield warnings - SAFE_HEAP = 3 - SAFE_HEAP_LINES = ['btVoronoiSimplexSolver.h:40', 'btVoronoiSimplexSolver.h:41', - 'btVoronoiSimplexSolver.h:42', 'btVoronoiSimplexSolver.h:43'] + Settings.SAFE_HEAP = 3 + Settings.SAFE_HEAP_LINES = ['btVoronoiSimplexSolver.h:40', 'btVoronoiSimplexSolver.h:41', + 'btVoronoiSimplexSolver.h:42', 'btVoronoiSimplexSolver.h:43'] self.do_run(open(path_from_root('tests', 'bullet', 'Demos', 'HelloWorld', 'HelloWorld.cpp'), 'r').read(), open(path_from_root('tests', 'bullet', 'output.txt'), 'r').read(), @@ -3262,25 +3241,20 @@ if 'benchmark' not in str(sys.argv): js_engines=[SPIDERMONKEY_ENGINE]) # V8 issue 1407 def test_poppler(self): - global RELOOP, LLVM_OPTS, USE_TYPED_ARRAYS, QUANTUM_SIZE + global LLVM_OPTS # llvm-link failure when using clang, LLVM bug 9498, still relevant? - if RELOOP or LLVM_OPTS: return self.skip('TODO') - if USE_TYPED_ARRAYS == 2 or QUANTUM_SIZE == 1: return self.skip('TODO: Figure out and try to fix') - - USE_TYPED_ARRAYS = 0 # XXX bug - we fail with this FIXME + if Settings.RELOOP or LLVM_OPTS: return self.skip('TODO') + if Settings.USE_TYPED_ARRAYS == 2 or Settings.QUANTUM_SIZE == 1: return self.skip('TODO: Figure out and try to fix') - global SAFE_HEAP; SAFE_HEAP = 0 # Has variable object + Settings.USE_TYPED_ARRAYS = 0 # XXX bug - we fail with this FIXME - #global CORRECT_OVERFLOWS; CORRECT_OVERFLOWS = 1 - global CHECK_OVERFLOWS; CHECK_OVERFLOWS = 0 + Settings.SAFE_HEAP = 0 # Has variable object - #global CHECK_OVERFLOWS; CHECK_OVERFLOWS = 1 - #global CHECK_SIGNS; CHECK_SIGNS = 1 + Settings.CHECK_OVERFLOWS = 0 - global CORRECT_SIGNS; CORRECT_SIGNS = 1 - global CORRECT_SIGNS_LINES - CORRECT_SIGNS_LINES = ['parseargs.cc:171', 'BuiltinFont.cc:64', 'NameToCharCode.cc:115', 'GooHash.cc:368', + Settings.CORRECT_SIGNS = 1 + Settings.CORRECT_SIGNS_LINES = ['parseargs.cc:171', 'BuiltinFont.cc:64', 'NameToCharCode.cc:115', 'GooHash.cc:368', 'Stream.h:469', 'PDFDoc.cc:1064', 'Lexer.cc:201', 'Splash.cc:1130', 'XRef.cc:997', 'vector:714', 'Lexer.cc:259', 'Splash.cc:438', 'Splash.cc:532', 'GfxFont.cc:1152', 'Gfx.cc:3838', 'Splash.cc:3162', 'Splash.cc:3163', 'Splash.cc:3164', 'Splash.cc:3153', @@ -3300,7 +3274,7 @@ if 'benchmark' not in str(sys.argv): '-I' + path_from_root('tests', 'poppler', 'include'), ] - global INVOKE_RUN; INVOKE_RUN = 0 # We append code that does run() ourselves + Settings.INVOKE_RUN = 0 # We append code that does run() ourselves # See post(), below input_file = open(os.path.join(self.get_dir(), 'paper.pdf.js'), 'w') @@ -3345,14 +3319,11 @@ if 'benchmark' not in str(sys.argv): #, build_ll_hook=self.do_autodebug) def test_openjpeg(self): - global USE_TYPED_ARRAYS - global CORRECT_SIGNS - if USE_TYPED_ARRAYS == 2: - CORRECT_SIGNS = 1 + if Settings.USE_TYPED_ARRAYS == 2: + Settings.CORRECT_SIGNS = 1 else: - CORRECT_SIGNS = 2 - global CORRECT_SIGNS_LINES - CORRECT_SIGNS_LINES = ["mqc.c:566", "mqc.c:317"] + Settings.CORRECT_SIGNS = 2 + Settings.CORRECT_SIGNS_LINES = ["mqc.c:566", "mqc.c:317"] original_j2k = path_from_root('tests', 'openjpeg', 'syntensity_lobby_s.j2k') @@ -3428,16 +3399,15 @@ if 'benchmark' not in str(sys.argv): output_nicerizer=image_compare)# build_ll_hook=self.do_autodebug) def test_python(self): - global QUANTUM_SIZE, USE_TYPED_ARRAYS - if QUANTUM_SIZE == 1 or USE_TYPED_ARRAYS == 2: return self.skip('TODO: make this work') + if Settings.QUANTUM_SIZE == 1 or Settings.USE_TYPED_ARRAYS == 2: return self.skip('TODO: make this work') # Overflows in string_hash - global CORRECT_OVERFLOWS; CORRECT_OVERFLOWS = 1 - global CHECK_OVERFLOWS; CHECK_OVERFLOWS = 0 - global RELOOP; RELOOP = 0 # Too slow; we do care about typed arrays and OPTIMIZE though - global SAFE_HEAP; SAFE_HEAP = 0 # Has bitfields which are false positives. Also the PyFloat_Init tries to detect endianness. - global CORRECT_SIGNS; CORRECT_SIGNS = 1 # Not sure why, but needed - global EXPORTED_FUNCTIONS; EXPORTED_FUNCTIONS = ['_main', '_PyRun_SimpleStringFlags'] # for the demo + Settings.CORRECT_OVERFLOWS = 1 + Settings.CHECK_OVERFLOWS = 0 + Settings.RELOOP = 0 # Too slow; we do care about typed arrays and OPTIMIZE though + Settings.SAFE_HEAP = 0 # Has bitfields which are false positives. Also the PyFloat_Init tries to detect endianness. + Settings.CORRECT_SIGNS = 1 # Not sure why, but needed + Settings.EXPORTED_FUNCTIONS = ['_main', '_PyRun_SimpleStringFlags'] # for the demo self.do_ll_run(path_from_root('tests', 'python', 'python.ll'), 'hello python world!\n[0, 2, 4, 6]\n5\n22\n5.470000', @@ -3448,15 +3418,14 @@ if 'benchmark' not in str(sys.argv): # They are only valid enough for us to read for test purposes, not for llvm-as # to process. def test_cases(self): - global QUANTUM_SIZE - global CHECK_OVERFLOWS; CHECK_OVERFLOWS = 0 + Settings.CHECK_OVERFLOWS = 0 if LLVM_OPTS: return self.skip("Our code is not exactly 'normal' llvm assembly") for name in glob.glob(path_from_root('tests', 'cases', '*.ll')): shortname = name.replace('.ll', '') print "Testing case '%s'..." % shortname output_file = path_from_root('tests', 'cases', shortname + '.txt') - if QUANTUM_SIZE == 1: + if Settings.QUANTUM_SIZE == 1: q1_output_file = path_from_root('tests', 'cases', shortname + '_q1.txt') if os.path.exists(q1_output_file): output_file = q1_output_file @@ -3527,8 +3496,8 @@ if 'benchmark' not in str(sys.argv): self.do_run(src, '*hello slim world*', build_ll_hook=hook) def test_profiling(self): - global PROFILE; PROFILE = 1 - global INVOKE_RUN; INVOKE_RUN = 0 + Settings.PROFILE = 1 + Settings.INVOKE_RUN = 0 src = ''' #include <stdio.h> @@ -3624,7 +3593,7 @@ if 'benchmark' not in str(sys.argv): # Way 2: use CppHeaderParser - global RUNTIME_TYPE_INFO; RUNTIME_TYPE_INFO = 1 + Settings.RUNTIME_TYPE_INFO = 1 header = ''' #include <stdio.h> @@ -3810,9 +3779,8 @@ Child2:9 ''', post_build=post2) def test_typeinfo(self): - global RUNTIME_TYPE_INFO; RUNTIME_TYPE_INFO = 1 - global QUANTUM_SIZE - if QUANTUM_SIZE != 4: return self.skip('We assume normal sizes in the output here') + Settings.RUNTIME_TYPE_INFO = 1 + if Settings.QUANTUM_SIZE != 4: return self.skip('We assume normal sizes in the output here') src = ''' #include<stdio.h> @@ -3854,7 +3822,7 @@ Child2:9 post_build=post) # Make sure that without the setting, we don't spam the .js with the type info - RUNTIME_TYPE_INFO = 0 + Settings.RUNTIME_TYPE_INFO = 0 self.do_run(src, 'No type info.', post_build=post) ### Tests for tools @@ -3864,11 +3832,28 @@ Child2:9 #include<stdio.h> int main() { printf("*closured*\\n"); + + FILE *file = fopen("somefile.binary", "rb"); + char buffer[1024]; + size_t read = fread(buffer, 1, 4, file); + printf("data: %d", buffer[0]); + for (int i = 1; i < 4; i++) + printf(",%d", buffer[i]); + printf("\\n"); + return 0; } ''' - def add_cc(filename): + def post(filename): + src = open(filename, 'r').read().replace( + '// {{PRE_RUN_ADDITIONS}}', + ''' + FS.createDataFile('/', 'somefile.binary', [100, 1, 50, 25, 10, 77, 123], true, false); + ''' + ) + open(filename, 'w').write(src) + Popen(['java', '-jar', CLOSURE_COMPILER, '--compilation_level', 'ADVANCED_OPTIMIZATIONS', '--formatting', 'PRETTY_PRINT', @@ -3879,13 +3864,14 @@ Child2:9 assert re.search('function \w\(', src) # see before assert 'function _main()' not in src # closure should have wiped it out open(filename, 'w').write(src) - self.do_run(src, '*closured*', post_build=add_cc) - def test_safe_heap(self): - global SAFE_HEAP, SAFE_HEAP_LINES + self.do_run(src, '*closured*\ndata: 100,1,50,25\n', post_build=post) - if not SAFE_HEAP: return self.skip('We need SAFE_HEAP to test SAFE_HEAP') + def test_safe_heap(self): + if Settings.USE_TYPED_ARRAYS == 2: return self.skip('It is ok to violate the load-store assumption with TA2') + if not Settings.SAFE_HEAP: return self.skip('We need SAFE_HEAP to test SAFE_HEAP') if LLVM_OPTS: return self.skip('LLVM can optimize away the intermediate |x|') + src = ''' #include<stdio.h> int main() { @@ -3906,14 +3892,14 @@ Child2:9 # And we should not fail if we disable checking on that line - SAFE_HEAP = 3 - SAFE_HEAP_LINES = ["src.cpp:7"] + Settings.SAFE_HEAP = 3 + Settings.SAFE_HEAP_LINES = ["src.cpp:7"] self.do_run(src, '*ok*') # But if we disable the wrong lines, we still fail - SAFE_HEAP_LINES = ["src.cpp:99"] + Settings.SAFE_HEAP_LINES = ["src.cpp:99"] try: self.do_run(src, '*nothingatall*') @@ -3923,14 +3909,14 @@ Child2:9 # And reverse the checks with = 2 - SAFE_HEAP = 2 - SAFE_HEAP_LINES = ["src.cpp:99"] + Settings.SAFE_HEAP = 2 + Settings.SAFE_HEAP_LINES = ["src.cpp:99"] self.do_run(src, '*ok*') def test_check_overflow(self): - global CHECK_OVERFLOWS; CHECK_OVERFLOWS = 1 - global CORRECT_OVERFLOWS; CORRECT_OVERFLOWS = 0 + Settings.CHECK_OVERFLOWS = 1 + Settings.CORRECT_OVERFLOWS = 0 src = ''' #include<stdio.h> @@ -4000,9 +3986,8 @@ Child2:9 self.do_run(None, 'test\n', basename='new.cpp', no_build=True) def test_linespecific(self): - global CHECK_SIGNS; CHECK_SIGNS = 0 - global CHECK_OVERFLOWS; CHECK_OVERFLOWS = 0 - global CORRECT_SIGNS, CORRECT_OVERFLOWS, CORRECT_ROUNDINGS, CORRECT_SIGNS_LINES, CORRECT_OVERFLOWS_LINES, CORRECT_ROUNDINGS_LINES + Settings.CHECK_SIGNS = 0 + Settings.CHECK_OVERFLOWS = 0 # Signs @@ -4018,28 +4003,28 @@ Child2:9 } ''' - CORRECT_SIGNS = 0 + Settings.CORRECT_SIGNS = 0 self.do_run(src, '*1*') # This is a fail - we expect 0 - CORRECT_SIGNS = 1 + Settings.CORRECT_SIGNS = 1 self.do_run(src, '*0*') # Now it will work properly # And now let's fix just that one line - CORRECT_SIGNS = 2 - CORRECT_SIGNS_LINES = ["src.cpp:9"] + Settings.CORRECT_SIGNS = 2 + Settings.CORRECT_SIGNS_LINES = ["src.cpp:9"] self.do_run(src, '*0*') # Fixing the wrong line should not work - CORRECT_SIGNS = 2 - CORRECT_SIGNS_LINES = ["src.cpp:3"] + Settings.CORRECT_SIGNS = 2 + Settings.CORRECT_SIGNS_LINES = ["src.cpp:3"] self.do_run(src, '*1*') # And reverse the checks with = 2 - CORRECT_SIGNS = 3 - CORRECT_SIGNS_LINES = ["src.cpp:3"] + Settings.CORRECT_SIGNS = 3 + Settings.CORRECT_SIGNS_LINES = ["src.cpp:3"] self.do_run(src, '*0*') - CORRECT_SIGNS = 3 - CORRECT_SIGNS_LINES = ["src.cpp:9"] + Settings.CORRECT_SIGNS = 3 + Settings.CORRECT_SIGNS_LINES = ["src.cpp:9"] self.do_run(src, '*1*') # Overflows @@ -4057,7 +4042,7 @@ Child2:9 ''' correct = '*186854335,63*' - CORRECT_OVERFLOWS = 0 + Settings.CORRECT_OVERFLOWS = 0 try: self.do_run(src, correct) raise Exception('UNEXPECTED-PASS') @@ -4065,17 +4050,17 @@ Child2:9 assert 'UNEXPECTED' not in str(e), str(e) assert 'Expected to find' in str(e), str(e) - CORRECT_OVERFLOWS = 1 + Settings.CORRECT_OVERFLOWS = 1 self.do_run(src, correct) # Now it will work properly # And now let's fix just that one line - CORRECT_OVERFLOWS = 2 - CORRECT_OVERFLOWS_LINES = ["src.cpp:6"] + Settings.CORRECT_OVERFLOWS = 2 + Settings.CORRECT_OVERFLOWS_LINES = ["src.cpp:6"] self.do_run(src, correct) # Fixing the wrong line should not work - CORRECT_OVERFLOWS = 2 - CORRECT_OVERFLOWS_LINES = ["src.cpp:3"] + Settings.CORRECT_OVERFLOWS = 2 + Settings.CORRECT_OVERFLOWS_LINES = ["src.cpp:3"] try: self.do_run(src, correct) raise Exception('UNEXPECTED-PASS') @@ -4084,11 +4069,11 @@ Child2:9 assert 'Expected to find' in str(e), str(e) # And reverse the checks with = 2 - CORRECT_OVERFLOWS = 3 - CORRECT_OVERFLOWS_LINES = ["src.cpp:3"] + Settings.CORRECT_OVERFLOWS = 3 + Settings.CORRECT_OVERFLOWS_LINES = ["src.cpp:3"] self.do_run(src, correct) - CORRECT_OVERFLOWS = 3 - CORRECT_OVERFLOWS_LINES = ["src.cpp:6"] + Settings.CORRECT_OVERFLOWS = 3 + Settings.CORRECT_OVERFLOWS_LINES = ["src.cpp:6"] try: self.do_run(src, correct) raise Exception('UNEXPECTED-PASS') @@ -4120,29 +4105,27 @@ Child2:9 } ''' - CORRECT_ROUNDINGS = 0 + Settings.CORRECT_ROUNDINGS = 0 self.do_run(src.replace('TYPE', 'long long'), '*-3**2**-6**5*') # JS floor operations, always to the negative. This is an undetected error here! self.do_run(src.replace('TYPE', 'int'), '*-2**2**-5**5*') # We get these right, since they are 32-bit and we can shortcut using the |0 trick - CORRECT_ROUNDINGS = 1 + Settings.CORRECT_ROUNDINGS = 1 self.do_run(src.replace('TYPE', 'long long'), '*-2**2**-5**5*') # Correct self.do_run(src.replace('TYPE', 'int'), '*-2**2**-5**5*') # Correct - CORRECT_ROUNDINGS = 2 - CORRECT_ROUNDINGS_LINES = ["src.cpp:13"] # Fix just the last mistake + Settings.CORRECT_ROUNDINGS = 2 + Settings.CORRECT_ROUNDINGS_LINES = ["src.cpp:13"] # Fix just the last mistake self.do_run(src.replace('TYPE', 'long long'), '*-3**2**-5**5*') self.do_run(src.replace('TYPE', 'int'), '*-2**2**-5**5*') # Here we are lucky and also get the first one right # And reverse the check with = 2 - CORRECT_ROUNDINGS = 3 - CORRECT_ROUNDINGS_LINES = ["src.cpp:999"] + Settings.CORRECT_ROUNDINGS = 3 + Settings.CORRECT_ROUNDINGS_LINES = ["src.cpp:999"] self.do_run(src.replace('TYPE', 'long long'), '*-2**2**-5**5*') self.do_run(src.replace('TYPE', 'int'), '*-2**2**-5**5*') def test_autooptimize(self): - global CHECK_OVERFLOWS, CORRECT_OVERFLOWS, CHECK_SIGNS, CORRECT_SIGNS, AUTO_OPTIMIZE - - AUTO_OPTIMIZE = CHECK_OVERFLOWS = CORRECT_OVERFLOWS = CHECK_SIGNS = CORRECT_SIGNS = 1 + Settings.AUTO_OPTIMIZE = Settings.CHECK_OVERFLOWS = Settings.CORRECT_OVERFLOWS = Settings.CHECK_SIGNS = Settings.CORRECT_SIGNS = 1 src = ''' #include<stdio.h> @@ -4182,34 +4165,34 @@ class %s(T): def setUp(self): super(%s, self).setUp() - global COMPILER, QUANTUM_SIZE, RELOOP, OPTIMIZE, ASSERTIONS, USE_TYPED_ARRAYS, LLVM_OPTS, SAFE_HEAP, CHECK_OVERFLOWS, CORRECT_OVERFLOWS, CORRECT_OVERFLOWS_LINES, CORRECT_SIGNS, CORRECT_SIGNS_LINES, CHECK_SIGNS, COMPILER_TEST_OPTS, CORRECT_ROUNDINGS, CORRECT_ROUNDINGS_LINES, INVOKE_RUN, SAFE_HEAP_LINES, INIT_STACK, AUTO_OPTIMIZE, RUNTIME_TYPE_INFO, DISABLE_EXCEPTION_CATCHING, PROFILE, TOTAL_MEMORY, FAST_MEMORY + global COMPILER, LLVM_OPTS, COMPILER_TEST_OPTS COMPILER = %r llvm_opts = %d embetter = %d quantum_size = %d - USE_TYPED_ARRAYS = %d - INVOKE_RUN = 1 - RELOOP = OPTIMIZE = embetter - QUANTUM_SIZE = quantum_size - ASSERTIONS = 1-embetter - SAFE_HEAP = 1-(embetter and llvm_opts) + Settings.USE_TYPED_ARRAYS = %d + Settings.INVOKE_RUN = 1 + Settings.RELOOP = Settings.OPTIMIZE = embetter + Settings.QUANTUM_SIZE = quantum_size + Settings.ASSERTIONS = 1-embetter + Settings.SAFE_HEAP = 1-(embetter and llvm_opts) LLVM_OPTS = llvm_opts - AUTO_OPTIMIZE = 0 - CHECK_OVERFLOWS = 1-(embetter or llvm_opts) - CORRECT_OVERFLOWS = 1-(embetter and llvm_opts) - CORRECT_SIGNS = 0 - CORRECT_ROUNDINGS = 0 - CORRECT_OVERFLOWS_LINES = CORRECT_SIGNS_LINES = CORRECT_ROUNDINGS_LINES = SAFE_HEAP_LINES = [] - CHECK_SIGNS = 0 #1-(embetter or llvm_opts) - INIT_STACK = 0 - RUNTIME_TYPE_INFO = 0 - DISABLE_EXCEPTION_CATCHING = 0 - PROFILE = 0 - TOTAL_MEMORY = FAST_MEMORY = None - - if QUANTUM_SIZE == 1 or USE_TYPED_ARRAYS == 2: - RELOOP = 0 # XXX Would be better to use this, but it isn't really what we test in these cases, and is very slow + Settings.AUTO_OPTIMIZE = 0 + Settings.CHECK_OVERFLOWS = 1-(embetter or llvm_opts) + Settings.CORRECT_OVERFLOWS = 1-(embetter and llvm_opts) + Settings.CORRECT_SIGNS = 0 + Settings.CORRECT_ROUNDINGS = 0 + Settings.CORRECT_OVERFLOWS_LINES = CORRECT_SIGNS_LINES = CORRECT_ROUNDINGS_LINES = SAFE_HEAP_LINES = [] + Settings.CHECK_SIGNS = 0 #1-(embetter or llvm_opts) + Settings.INIT_STACK = 0 + Settings.RUNTIME_TYPE_INFO = 0 + Settings.DISABLE_EXCEPTION_CATCHING = 0 + Settings.PROFILE = 0 + Settings.TOTAL_MEMORY = Settings.FAST_MEMORY = None + + if Settings.QUANTUM_SIZE == 1 or Settings.USE_TYPED_ARRAYS == 2: + Settings.RELOOP = 0 # XXX Would be better to use this, but it isn't really what we test in these cases, and is very slow if LLVM_OPTS: self.pick_llvm_opts(3) @@ -4239,11 +4222,9 @@ TT = %s class OtherTests(RunnerCore): def test_eliminator(self): - coffee = path_from_root('tools', 'eliminator', 'node_modules', 'coffee-script', 'bin', 'coffee') - eliminator = path_from_root('tools', 'eliminator', 'eliminator.coffee') input = open(path_from_root('tools', 'eliminator', 'eliminator-test.js')).read() expected = open(path_from_root('tools', 'eliminator', 'eliminator-test-output.js')).read() - output = Popen([coffee, eliminator], stdin=PIPE, stdout=PIPE, stderr=PIPE).communicate(input)[0] + output = Popen([COFFEESCRIPT, VARIABLE_ELIMINATOR], stdin=PIPE, stdout=PIPE, stderr=PIPE).communicate(input)[0] self.assertEquals(output, expected) else: @@ -4268,18 +4249,18 @@ else: global COMPILER_TEST_OPTS; COMPILER_TEST_OPTS = [] - QUANTUM_SIZE = 1 - RELOOP = OPTIMIZE = 1 - USE_TYPED_ARRAYS = 1 - ASSERTIONS = SAFE_HEAP = CHECK_OVERFLOWS = CORRECT_OVERFLOWS = CHECK_SIGNS = INIT_STACK = AUTO_OPTIMIZE = RUNTIME_TYPE_INFO = 0 - INVOKE_RUN = 1 - CORRECT_SIGNS = 0 - CORRECT_ROUNDINGS = 0 - CORRECT_OVERFLOWS_LINES = CORRECT_SIGNS_LINES = CORRECT_ROUNDINGS_LINES = SAFE_HEAP_LINES = [] - DISABLE_EXCEPTION_CATCHING = 1 - if USE_TYPED_ARRAYS: - TOTAL_MEMORY = 100*1024*1024 # XXX Needed for dlmalloc. TODO: Test other values - FAST_MEMORY = 10*1024*1024 + Settings.QUANTUM_SIZE = 1 + Settings.RELOOP = Settings.OPTIMIZE = 1 + Settings.USE_TYPED_ARRAYS = 1 + Settings.ASSERTIONS = Settings.SAFE_HEAP = Settings.CHECK_OVERFLOWS = Settings.CORRECT_OVERFLOWS = Settings.CHECK_SIGNS = Settings.INIT_STACK = Settings.AUTO_OPTIMIZE = Settings.RUNTIME_TYPE_INFO = 0 + Settings.INVOKE_RUN = 1 + Settings.CORRECT_SIGNS = 0 + Settings.CORRECT_ROUNDINGS = 0 + Settings.CORRECT_OVERFLOWS_LINES = Settings.CORRECT_SIGNS_LINES = Settings.CORRECT_ROUNDINGS_LINES = Settings.SAFE_HEAP_LINES = [] + Settings.DISABLE_EXCEPTION_CATCHING = 1 + if Settings.USE_TYPED_ARRAYS: + Settings.TOTAL_MEMORY = 100*1024*1024 # XXX Needed for dlmalloc. TODO: Test other values + Settings.FAST_MEMORY = 10*1024*1024 TEST_REPS = 4 TOTAL_TESTS = 6 @@ -4313,7 +4294,7 @@ else: print ' Native (gcc): mean: %.3f (+-%.3f) seconds (max: %.3f, min: %.3f, noise/signal: %.3f) JS is %.2f X slower' % (mean_native, std_native, max(native_times), min(native_times), std_native/mean_native, final) def do_benchmark(self, src, args=[], expected_output='FAIL', main_file=None, llvm_opts=False, handpicked=False): - global USE_TYPED_ARRAYS, LLVM_OPTS + global LLVM_OPTS LLVM_OPTS = llvm_opts if LLVM_OPTS: @@ -4451,24 +4432,23 @@ else: def test_raytrace(self): global POST_OPTIMIZATIONS; POST_OPTIMIZATIONS = ['closure'] - global QUANTUM_SIZE, USE_TYPED_ARRAYS - old_quantum = QUANTUM_SIZE - old_use_typed_arrays = USE_TYPED_ARRAYS - QUANTUM_SIZE = 1 - USE_TYPED_ARRAYS = 0 # Rounding errors with TA2 are too big in this very rounding-sensitive code. However, TA2 is much faster (2X) + old_quantum = Settings.QUANTUM_SIZE + old_use_typed_arrays = Settings.USE_TYPED_ARRAYS + Settings.QUANTUM_SIZE = 1 + Settings.USE_TYPED_ARRAYS = 0 # Rounding errors with TA2 are too big in this very rounding-sensitive code. However, TA2 is much faster (2X) src = open(path_from_root('tests', 'raytrace.cpp'), 'r').read().replace('double', 'float') # benchmark with floats self.do_benchmark(src, ['7', '256'], '256 256', llvm_opts=True, handpicked=False) - QUANTUM_SIZE = old_quantum - USE_TYPED_ARRAYS = old_use_typed_arrays + Settings.QUANTUM_SIZE = old_quantum + Settings.USE_TYPED_ARRAYS = old_use_typed_arrays def test_dlmalloc(self): global POST_OPTIMIZATIONS; POST_OPTIMIZATIONS = ['eliminator'] global COMPILER_TEST_OPTS; COMPILER_TEST_OPTS = ['-g'] - global CORRECT_SIGNS; CORRECT_SIGNS = 2 - global CORRECT_SIGNS_LINES; CORRECT_SIGNS_LINES = ['src.cpp:' + str(i+4) for i in [4816, 4191, 4246, 4199, 4205, 4235, 4227]] + Settings.CORRECT_SIGNS = 2 + Settings.CORRECT_SIGNS_LINES = ['src.cpp:' + str(i+4) for i in [4816, 4191, 4246, 4199, 4205, 4235, 4227]] src = open(path_from_root('src', 'dlmalloc.c'), 'r').read() + '\n\n\n' + open(path_from_root('tests', 'dlmalloc_test.c'), 'r').read() self.do_benchmark(src, ['400', '400'], '*400,0*', llvm_opts=True, handpicked=True) diff --git a/tools/emmaken.py b/tools/emmaken.py index 4984435a..f97eaa4f 100755 --- a/tools/emmaken.py +++ b/tools/emmaken.py @@ -51,6 +51,14 @@ to run g++ on it despite the .c extension, see https://github.com/kripken/emscripten/issues/6 (If a similar situation occurs with ./configure, you can do the same there too.) + +emmaken can be influenced by a few environment variables: + + EMMAKEN_NO_SDK - Will tell emmaken *not* to use the emscripten headers. Instead + your system headers will be used. + + EMMAKEN_COMPILER - The compiler to be used, if you don't want the default clang. + ''' import sys @@ -76,7 +84,11 @@ try: #f.write('Args: ' + ' '.join(sys.argv) + '\nCMake? ' + str(CMAKE_CONFIG) + '\n') #f.close() - CXX = CLANG + if os.environ.get('EMMAKEN_COMPILER'): + CXX = os.environ['EMMAKEN_COMPILER'] + else: + CXX = CLANG + CC = to_cc(CXX) # If we got here from a redirection through emmakenxx.py, then force a C++ compiler here diff --git a/tools/file2json.py b/tools/file2json.py index a1c37244..f26f2864 100644 --- a/tools/file2json.py +++ b/tools/file2json.py @@ -28,3 +28,22 @@ if len(sys.argv) < 3: else: print 'var ' + sys.argv[2] + '=' + json + ';' +''' +or (but this fails, we get a string at runtime?) + +data = open(sys.argv[1], 'r').read() +counter = 0 +print '[', +for i in range(len(data)): + last = i == len(data)-1 + print ord(data[i]), + counter += 1 + if counter % 20 == 0: + print + if counter % 1005 == 0 and not last: + print '] + [', + elif not last: print ',', + +print ']' +''' + diff --git a/tools/make_file.py b/tools/make_file.py index 6885610d..720eb0e4 100644 --- a/tools/make_file.py +++ b/tools/make_file.py @@ -11,7 +11,7 @@ m = re.search('\[[\d, -]*\]', data) data = eval(m.group(0)) data = [x&0xff for x in data] string = ''.join([chr(item) for item in data]) -out = open(sys.argv[1]+'.raw', 'wb') +out = open(sys.argv[1]+'.' + (sys.argv[2] if len(sys.argv) >= 3 else 'raw'), 'wb') print data[0:80] print string[0:80] out.write(string) diff --git a/tools/shared.py b/tools/shared.py index 8f630ad6..e98436e4 100644 --- a/tools/shared.py +++ b/tools/shared.py @@ -10,7 +10,7 @@ if not os.path.exists(CONFIG_FILE): shutil.copy(path_from_root('settings.py'), CONFIG_FILE) exec(open(CONFIG_FILE, 'r').read()) -# Tools +# Tools/paths CLANG=os.path.expanduser(os.path.join(LLVM_ROOT, 'clang++')) LLVM_LINK=os.path.join(LLVM_ROOT, 'llvm-link') @@ -21,9 +21,17 @@ LLVM_DIS=os.path.expanduser(os.path.join(LLVM_ROOT, 'llvm-dis')) LLVM_DIS_OPTS = ['-show-annotations'] # For LLVM 2.8+. For 2.7, you may need to do just [] LLVM_INTERPRETER=os.path.expanduser(os.path.join(LLVM_ROOT, 'lli')) LLVM_COMPILER=os.path.expanduser(os.path.join(LLVM_ROOT, 'llc')) - +COFFEESCRIPT = path_from_root('tools', 'eliminator', 'node_modules', 'coffee-script', 'bin', 'coffee') + +EMSCRIPTEN = path_from_root('emscripten.py') +DEMANGLER = path_from_root('third_party', 'demangler.py') +NAMESPACER = path_from_root('tools', 'namespacer.py') +EMMAKEN = path_from_root('tools', 'emmaken.py') +AUTODEBUGGER = path_from_root('tools', 'autodebugger.py') +DFE = path_from_root('tools', 'dead_function_eliminator.py') BINDINGS_GENERATOR = path_from_root('tools', 'bindings_generator.py') EXEC_LLVM = path_from_root('tools', 'exec_llvm.py') +VARIABLE_ELIMINATOR = path_from_root('tools', 'eliminator', 'eliminator.coffee') # Additional compiler options @@ -41,6 +49,8 @@ if USE_EMSDK: '-I' + path_from_root('system', 'include', 'gfx'), '-I' + path_from_root('system', 'include', 'net'), '-I' + path_from_root('system', 'include', 'SDL'), +] + [ + '-U__APPLE__' ] # Engine tweaks @@ -196,3 +206,9 @@ def read_auto_optimize_data(filename): 'overflows_lines': overflows_lines } +# Settings + +class Dummy: pass + +Settings = Dummy() # A global singleton. Not pretty, but nicer than passing |, settings| everywhere + |