diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/analyzer.js | 2 | ||||
-rw-r--r-- | src/intertyper.js | 2 | ||||
-rw-r--r-- | src/jsifier.js | 14 | ||||
-rw-r--r-- | src/library.js | 69 | ||||
-rw-r--r-- | src/library_gc.js | 13 | ||||
-rw-r--r-- | src/modules.js | 2 | ||||
-rw-r--r-- | src/settings.js | 1 | ||||
-rw-r--r-- | src/utility.js | 2 |
8 files changed, 67 insertions, 38 deletions
diff --git a/src/analyzer.js b/src/analyzer.js index c09739e9..014579f4 100644 --- a/src/analyzer.js +++ b/src/analyzer.js @@ -690,6 +690,8 @@ function analyzer(data, sidePass) { var subType = check[2]; addTypeInternal(subType, data); // needed for anonymous structure definitions (see below) + // Huge structural types are represented very inefficiently, both here and in generated JS. Best to avoid them - for example static char x[10*1024*1024]; is bad, while static char *x = malloc(10*1024*1024) is fine. + if (num >= 10*1024*1024) warnOnce('warning: very large fixed-size structural type: ' + type + ' - can you reduce it? (compilation may be slow)'); Types.types[nonPointing] = { name_: nonPointing, fields: range(num).map(function() { return subType }), diff --git a/src/intertyper.js b/src/intertyper.js index b1bd2ba8..8e7bb418 100644 --- a/src/intertyper.js +++ b/src/intertyper.js @@ -674,7 +674,7 @@ function intertyper(data, sidePass, baseLineNums) { // Inline assembly is just JavaScript that we paste into the code item.intertype = 'value'; if (tokensLeft[0].text == 'sideeffect') tokensLeft.splice(0, 1); - item.ident = tokensLeft[0].text.substr(1, tokensLeft[0].text.length-2); + item.ident = tokensLeft[0].text.substr(1, tokensLeft[0].text.length-2) || ';'; // use ; for empty inline assembly return { forward: null, ret: [item], item: item }; } if (item.ident.substr(-2) == '()') { diff --git a/src/jsifier.js b/src/jsifier.js index 6d3fe781..2791c65b 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -332,7 +332,7 @@ function JSify(data, functionsOnly, givenFunctions) { if (item.ident.substr(0, 5) == '__ZTV') { js += '\n' + makePointer('[0]', null, BUILD_AS_SHARED_LIB ? 'ALLOC_NORMAL' : 'ALLOC_STATIC', ['void*']) + ';'; } - if (item.ident in EXPORTED_GLOBALS) { + if (EXPORT_ALL || (item.ident in EXPORTED_GLOBALS)) { js += '\nModule["' + item.ident + '"] = ' + item.ident + ';'; } if (BUILD_AS_SHARED_LIB == 2 && !item.private_) { @@ -442,7 +442,7 @@ function JSify(data, functionsOnly, givenFunctions) { } var text = (deps ? '\n' + deps.map(addFromLibrary).filter(function(x) { return x != '' }).join('\n') : ''); text += isFunction ? snippet : 'var ' + ident + '=' + snippet + ';'; - if (ident in EXPORTED_FUNCTIONS) { + if (EXPORT_ALL || (ident in EXPORTED_FUNCTIONS)) { text += '\nModule["' + ident + '"] = ' + ident + ';'; } return text; @@ -702,7 +702,7 @@ function JSify(data, functionsOnly, givenFunctions) { func.JS += '\n//FUNCTION_END_MARKER_OF_SOURCE_FILE_' + associatedSourceFile + '\n'; } - if (func.ident in EXPORTED_FUNCTIONS) { + if (EXPORT_ALL || (func.ident in EXPORTED_FUNCTIONS)) { func.JS += 'Module["' + func.ident + '"] = ' + func.ident + ';'; } @@ -1069,12 +1069,12 @@ function JSify(data, functionsOnly, givenFunctions) { var param1 = finalizeLLVMParameter(item.params[0]); var param2 = finalizeLLVMParameter(item.params[1]); switch (item.op) { - case 'add': return '(tempValue=' + makeGetValue(param1, 0, type) + ',' + makeSetValue(param1, 0, 'tempValue+' + param2, type) + ',tempValue)'; - case 'sub': return '(tempValue=' + makeGetValue(param1, 0, type) + ',' + makeSetValue(param1, 0, 'tempValue-' + param2, type) + ',tempValue)'; - case 'xchg': return '(tempValue=' + makeGetValue(param1, 0, type) + ',' + makeSetValue(param1, 0, param2, type) + ',tempValue)'; + case 'add': return '(tempValue=' + makeGetValue(param1, 0, type) + ',' + makeSetValue(param1, 0, 'tempValue+' + param2, type, null, null, null, null, ',') + ',tempValue)'; + case 'sub': return '(tempValue=' + makeGetValue(param1, 0, type) + ',' + makeSetValue(param1, 0, 'tempValue-' + param2, type, null, null, null, null, ',') + ',tempValue)'; + case 'xchg': return '(tempValue=' + makeGetValue(param1, 0, type) + ',' + makeSetValue(param1, 0, param2, type, null, null, null, null, ',') + ',tempValue)'; case 'cmpxchg': { var param3 = finalizeLLVMParameter(item.params[2]); - return '(tempValue=' + makeGetValue(param1, 0, type) + ',(' + makeGetValue(param1, 0, type) + '==' + param2 + ' && (' + makeSetValue(param1, 0, param3, type) + ')),tempValue)'; + return '(tempValue=' + makeGetValue(param1, 0, type) + ',(' + makeGetValue(param1, 0, type) + '==' + param2 + ' && (' + makeSetValue(param1, 0, param3, type, null, null, null, null, ',') + ')),tempValue)'; } default: throw 'unhandled atomic op: ' + item.op; } diff --git a/src/library.js b/src/library.js index a281fc10..837ed71d 100644 --- a/src/library.js +++ b/src/library.js @@ -2457,20 +2457,22 @@ LibraryManager.library = { var argIndex = 0; var next; - next = 1; mainLoop: - for (var formatIndex = 0; formatIndex < format.length; formatIndex++) { + for (var formatIndex = 0; formatIndex < format.length;) { + if (format[formatIndex] === '%' && format[formatIndex+1] == 'n') { + var argPtr = {{{ makeGetValue('varargs', 'argIndex', 'void*') }}}; + {{{ makeSetValue('argPtr', 0, 'soFar', 'i32') }}}; + formatIndex += 2; + continue; + } + // remove whitespace while (1) { next = get(); if (next == 0) return fields; if (!(next in __scanString.whiteSpace)) break; - } - unget(next); - - if (next <= 0) return fields; - var next = get(); - if (next <= 0) return fields; // End of input. + } + unget(); if (format[formatIndex] === '%') { formatIndex++; @@ -2504,6 +2506,7 @@ LibraryManager.library = { // Read characters according to the format. floats are trickier, they may be in an unfloat state in the middle, then be a valid float later if (type == 'f') { var last = 0; + next = get(); while (next > 0) { buffer.push(String.fromCharCode(next)); if (__isFloat(buffer.join(''))) { @@ -2511,12 +2514,12 @@ LibraryManager.library = { } next = get(); } - unget(next); - while (buffer.length > last) { - unget(buffer.pop().charCodeAt(0)); + for (var i = 0; i < buffer.length - last + 1; i++) { + unget(); } + buffer.length = last; + } else { next = get(); - } else if (type != 'n') { var first = true; while ((curr < max_ || isNaN(max_)) && next > 0) { if (!(next in __scanString.whiteSpace) && // stop on whitespace @@ -2530,13 +2533,14 @@ LibraryManager.library = { buffer.push(String.fromCharCode(next)); next = get(); curr++; + first = false; } else { break; } - first = false; } + unget(); } - if (buffer.length === 0 && type != 'n') return 0; // Failure. + if (buffer.length === 0) return 0; // Failure. var text = buffer.join(''); var argPtr = {{{ makeGetValue('varargs', 'argIndex', 'void*') }}}; argIndex += Runtime.getNativeFieldSize('void*'); @@ -2566,31 +2570,26 @@ LibraryManager.library = { {{{ makeSetValue('argPtr', 'j', 'array[j]', 'i8') }}} } break; - case 'n': - {{{ makeSetValue('argPtr', 0, 'soFar-1', 'i32') }}} - break; } - if (type != 'n') fields++; - if (next <= 0) break mainLoop; // End of input. + fields++; } else if (format[formatIndex] in __scanString.whiteSpace) { + next = get(); while (next in __scanString.whiteSpace) { - next = get(); if (next <= 0) break mainLoop; // End of input. + next = get(); } unget(next); + formatIndex++; } else { // Not a specifier. + next = get(); if (format[formatIndex].charCodeAt(0) !== next) { unget(next); break mainLoop; } + formatIndex++; } } - // 'n' is special in that it needs no input. so it can be at the end, even with nothing left to read - if (format[formatIndex-1] == '%' && format[formatIndex] == 'n') { - var argPtr = {{{ makeGetValue('varargs', 'argIndex', 'void*') }}}; - {{{ makeSetValue('argPtr', 0, 'soFar-1', 'i32') }}} - } return fields; }, // Performs prtinf-style formatting. @@ -3455,8 +3454,9 @@ LibraryManager.library = { // int fscanf(FILE *restrict stream, const char *restrict format, ... ); // http://pubs.opengroup.org/onlinepubs/000095399/functions/scanf.html if (FS.streams[stream]) { - var get = function() { return _fgetc(stream); }; - var unget = function(c) { return _ungetc(c, stream); }; + var stack = []; + var get = function() { var ret = _fgetc(stream); stack.push(ret); return ret }; + var unget = function(c) { return _ungetc(stack.pop(), stream) }; return __scanString(format, get, unget, varargs); } else { return -1; @@ -4745,6 +4745,10 @@ LibraryManager.library = { return 32; }, + llvm_trap: function() { + throw 'trap! ' + new Error().stack; + }, + __assert_fail: function(condition, file, line) { ABORT = true; throw 'Assertion failed: ' + Pointer_stringify(condition);//JSON.stringify(arguments)//condition; @@ -6465,6 +6469,17 @@ LibraryManager.library = { _pthread_key_create.keys[key] = value; }, + pthread_cleanup_push: function(routine, arg) { + __ATEXIT__.push({ func: function() { FUNCTION_TABLE[routine](arg) } }) + _pthread_cleanup_push.level = __ATEXIT__.length; + }, + + pthread_cleanup_pop: function() { + assert(_pthread_cleanup_push.level == __ATEXIT__.length, 'cannot pop if something else added meanwhile!'); + __ATEXIT__.pop(); + _pthread_cleanup_push.level = __ATEXIT__.length; + }, + // ========================================================================== // malloc.h // ========================================================================== diff --git a/src/library_gc.js b/src/library_gc.js index bf0a6aff..a06e2f01 100644 --- a/src/library_gc.js +++ b/src/library_gc.js @@ -16,6 +16,11 @@ if (GC_SUPPORT) { init: function() { assert(!GC.initted); GC.initted = true; + + _GC_finalize_on_demand = _malloc(4); setValue(_GC_finalize_on_demand, 0, 'i32') + _GC_java_finalization = _malloc(4); setValue(_GC_java_finalization, 0, 'i32'); + _GC_finalizer_notifier = _malloc(4); setValue(_GC_finalizer_notifier, 0, 'i32'); + if (ENVIRONMENT_IS_WEB) { setInterval(function() { GC.maybeCollect(); @@ -159,7 +164,13 @@ if (GC_SUPPORT) { GC_FORCE_COLLECT__deps: ['$GC'], GC_FORCE_COLLECT: function() { GC.collect(); - } + }, + + GC_finalize_on_demand: 0, + GC_java_finalization: 0, + GC_finalizer_notifier: 0, + + GC_enable_incremental: function(){}, }; mergeInto(LibraryManager.library, LibraryGC); diff --git a/src/modules.js b/src/modules.js index 781bed45..06677936 100644 --- a/src/modules.js +++ b/src/modules.js @@ -5,7 +5,7 @@ var LLVM = { LINKAGES: set('private', 'linker_private', 'linker_private_weak', 'linker_private_weak_def_auto', 'internal', 'available_externally', 'linkonce', 'common', 'weak', 'appending', 'extern_weak', 'linkonce_odr', - 'weak_odr', 'externally_visible', 'dllimport', 'dllexport', 'unnamed_addr'), + 'weak_odr', 'externally_visible', 'dllimport', 'dllexport', 'unnamed_addr', 'thread_local'), VISIBILITIES: set('default', 'hidden', 'protected'), PARAM_ATTR: set('noalias', 'signext', 'zeroext', 'inreg', 'sret', 'nocapture', 'nest'), FUNC_ATTR: set('hidden', 'nounwind', 'define', 'inlinehint', '{'), diff --git a/src/settings.js b/src/settings.js index 9cdb496b..5dc1e2eb 100644 --- a/src/settings.js +++ b/src/settings.js @@ -196,6 +196,7 @@ var PGO = 0; // Profile-guided optimization. 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 "_". diff --git a/src/utility.js b/src/utility.js index 632ee08c..f3ece90b 100644 --- a/src/utility.js +++ b/src/utility.js @@ -184,7 +184,7 @@ function dprint() { text = text(); // Allows deferred calculation, so dprints don't slow us down when not needed } text = DPRINT_INDENT + '// ' + text; - print(text); + printErr(text); } var PROF_ORIGIN = Date.now(); |