aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/analyzer.js2
-rw-r--r--src/intertyper.js2
-rw-r--r--src/jsifier.js14
-rw-r--r--src/library.js69
-rw-r--r--src/library_gc.js13
-rw-r--r--src/modules.js2
-rw-r--r--src/settings.js1
-rw-r--r--src/utility.js2
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();