aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/analyzer.js36
-rw-r--r--src/compiler.js3
-rw-r--r--src/intertyper.js9
-rw-r--r--src/jsifier.js9
-rw-r--r--src/library.js12
-rw-r--r--src/parseTools.js16
-rw-r--r--src/preamble.js12
-rw-r--r--src/settings.js10
8 files changed, 74 insertions, 33 deletions
diff --git a/src/analyzer.js b/src/analyzer.js
index 96e6297b..824e7903 100644
--- a/src/analyzer.js
+++ b/src/analyzer.js
@@ -275,25 +275,27 @@ function analyzer(data) {
}
});
- // Second pass over variables - notice when types are crossed by bitcast
-
- func.lines.forEach(function(item) {
- if (item.intertype === 'assign' && item.value.intertype === 'bitcast') {
- // bitcasts are unique in that they convert one pointer to another. We
- // sometimes need to know the original type of a pointer, so we save that.
- //
- // originalType is the type this variable is created from
- // derivedTypes are the types that this variable is cast into
- func.variables[item.ident].originalType = item.value.type2;
-
- if (!isNumber(item.value.ident)) {
- if (!func.variables[item.value.ident].derivedTypes) {
- func.variables[item.value.ident].derivedTypes = [];
+ if (QUANTUM_SIZE === 1) {
+ // Second pass over variables - notice when types are crossed by bitcast
+
+ func.lines.forEach(function(item) {
+ if (item.intertype === 'assign' && item.value.intertype === 'bitcast') {
+ // bitcasts are unique in that they convert one pointer to another. We
+ // sometimes need to know the original type of a pointer, so we save that.
+ //
+ // originalType is the type this variable is created from
+ // derivedTypes are the types that this variable is cast into
+ func.variables[item.ident].originalType = item.value.type2;
+
+ if (!isNumber(item.value.ident)) {
+ if (!func.variables[item.value.ident].derivedTypes) {
+ func.variables[item.value.ident].derivedTypes = [];
+ }
+ func.variables[item.value.ident].derivedTypes.push(item.value.type);
}
- func.variables[item.value.ident].derivedTypes.push(item.value.type);
}
- }
- });
+ });
+ }
for (vname in func.variables) {
var variable = func.variables[vname];
diff --git a/src/compiler.js b/src/compiler.js
index 8980da93..9bf81ba4 100644
--- a/src/compiler.js
+++ b/src/compiler.js
@@ -71,6 +71,9 @@ eval(processMacros(preprocess(read('runtime.js'))));
// Read llvm
var raw = read(ll_file);
+if (FAKE_X86_FP80) {
+ raw = raw.replace(/x86_fp80/g, 'double');
+}
var lines = raw.split('\n');
raw = null;
diff --git a/src/intertyper.js b/src/intertyper.js
index 7649203a..7d74dfd2 100644
--- a/src/intertyper.js
+++ b/src/intertyper.js
@@ -543,7 +543,9 @@ function intertyper(data, parseFunctions, baseLineNum) {
item.intertype = 'bitcast';
item.type = item.tokens[4].text; // The final type
Types.needAnalysis[item.type] = 0;
- item.ident = toNiceIdent(item.tokens[2].text);
+ var to = getTokenIndexByText(item.tokens, 'to');
+ item.params = [parseLLVMSegment(item.tokens.slice(2, to))];
+ item.ident = item.params[0].ident;
item.type2 = item.tokens[1].text; // The original type
Types.needAnalysis[item.type2] = 0;
this.forwardItem(item, 'Reintegrator');
@@ -791,13 +793,10 @@ function intertyper(data, parseFunctions, baseLineNum) {
// external function stub
substrate.addActor('External', {
processItem: function(item) {
- if (item.tokens[1].text in LLVM.LINKAGES || item.tokens[1].text in LLVM.PARAM_ATTR) {
+ if (item.tokens[1].text in LLVM.LINKAGES || item.tokens[1].text in LLVM.PARAM_ATTR || item.tokens[1].text in LLVM.VISIBILITIES) {
item.tokens.splice(1, 1);
}
- if (item.tokens[1].text == 'hidden') {
- item.tokens = [item.tokens[0]].concat(item.tokens.slice(2));
- }
var params = parseParamTokens(item.tokens[3].item.tokens);
return [{
intertype: 'functionStub',
diff --git a/src/jsifier.js b/src/jsifier.js
index 1124b008..1fd4a790 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -253,6 +253,10 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) {
constant = makePointer(constant, null, BUILD_AS_SHARED_LIB ? 'ALLOC_NORMAL' : 'ALLOC_STATIC', item.type);
var js = item.ident + '=' + constant + ';';
+ // Special case: class vtables. We make sure they are null-terminated, to allow easy runtime operations
+ 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) {
js += '\nModule["' + item.ident + '"] = ' + item.ident + ';';
}
@@ -603,7 +607,7 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) {
makeFuncLineActor('store', function(item) {
var value = finalizeLLVMParameter(item.value);
if (pointingLevels(item.pointerType) == 1) {
- value = parseNumerical(value, removePointing(item.pointerType));
+ value = parseNumerical(value, item.valueType);
}
var impl = VAR_EMULATED;
if (item.pointer.intertype == 'value') {
@@ -776,7 +780,7 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) {
makeFuncLineActor('mathop', processMathop);
makeFuncLineActor('bitcast', function(item) {
- return item.ident;
+ return finalizeLLVMParameter(item.params[0]);
});
function makeFunctionCall(ident, params, funcData) {
@@ -876,6 +880,7 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) {
var preFile = BUILD_AS_SHARED_LIB ? 'preamble_sharedlib.js' : 'preamble.js';
var pre = processMacros(preprocess(read(preFile).replace('{{RUNTIME}}', getRuntime()), CONSTANTS));
print(pre);
+ print('Runtime.QUANTUM_SIZE = ' + QUANTUM_SIZE);
if (RUNTIME_TYPE_INFO) {
Types.cleanForRuntime();
print('Runtime.typeInfo = ' + JSON.stringify(Types.types));
diff --git a/src/library.js b/src/library.js
index 88feb66c..156c1c25 100644
--- a/src/library.js
+++ b/src/library.js
@@ -3758,7 +3758,8 @@ LibraryManager.library = {
strdup: function(ptr) {
var len = String_len(ptr);
var newStr = _malloc(len + 1);
- {{{ makeCopyValues('newStr', 'ptr', 'len + 1', 'null', ' || 0') }}};
+ {{{ makeCopyValues('newStr', 'ptr', 'len', 'null') }}};
+ {{{ makeSetValue('newStr', 'len', '0', 'i8') }}};
return newStr;
},
@@ -4120,6 +4121,14 @@ LibraryManager.library = {
return -1; // 'indeterminable' for FLT_ROUNDS
},
+ llvm_memory_barrier: function(){},
+
+ llvm_atomic_load_add_i32_p0i32: function(ptr, delta) {
+ var ret = {{{ makeGetValue('ptr', '0', 'i32') }}};
+ {{{ makeSetValue('ptr', '0', 'ret+delta', 'i32') }}};
+ return ret;
+ },
+
// ==========================================================================
// iostream.h
// ==========================================================================
@@ -5285,6 +5294,7 @@ LibraryManager.library = {
pthread_mutex_destroy: function() {},
pthread_mutex_lock: function() {},
pthread_mutex_unlock: function() {},
+ pthread_cond_broadcast: function() {},
// ==========================================================================
// malloc.h
diff --git a/src/parseTools.js b/src/parseTools.js
index 88758454..955353b2 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -74,7 +74,7 @@ function toNiceIdent(ident) {
assert(ident);
if (parseFloat(ident) == ident) return ident;
if (ident == 'null') return '0'; // see parseNumerical
- return ident.replace('%', '$').replace(/["&\\ \.@:<>,\*\[\]-]/g, '_');
+ return ident.replace('%', '$').replace(/["&\\ \.@:<>,\*\[\]\(\)-]/g, '_');
}
// Kind of a hack. In some cases we have strings that we do not want
@@ -143,6 +143,7 @@ function isFunctionDef(token) {
}
function isFunctionType(type) {
+ type = type.replace(/"[^"]+"/g, '".."');
var parts = type.split(' ');
if (pointingLevels(type) !== 1) return false;
var text = removeAllPointing(parts.slice(1).join(' '));
@@ -430,6 +431,9 @@ function parseLLVMFunctionCall(segment) {
if (type === '?') {
if (intertype === 'getelementptr') {
type = '*'; // a pointer, we can easily say, this is
+ } else if (intertype === 'bitcast') {
+ assert(segment[2].item.tokens.slice(-2)[0].text === 'to');
+ type = segment[2].item.tokens.slice(-1)[0].text;
}
}
var ret = {
@@ -486,7 +490,15 @@ function IEEEUnHex(stringy) {
stringy = stringy.substr(2); // leading '0x';
if (stringy.replace(/0/g, '') === '') return 0;
while (stringy.length < 16) stringy = '0' + stringy;
- assert(stringy.length === 16, 'Can only unhex 16-digit double numbers, nothing platform-specific');
+ if (FAKE_X86_FP80 && stringy.length > 16) {
+ stringy = stringy.substr(stringy.length-16, 16);
+ if (!Debugging.shownIEEEUnHexWarning) {
+ dprint('WARNING: .ll contains floating-point values with more than 64 bits. Faking values for them.');
+ dprint(' If they are used, this will almost certainly fail!');
+ Debugging.shownIEEEUnHexWarning = true;
+ }
+ }
+ assert(stringy.length === 16, 'Can only unhex 16-digit double numbers, nothing platform-specific'); // |long double| can cause x86_fp80 which causes this
var top = eval('0x' + stringy[0]);
var neg = !!(top & 8); // sign
if (neg) {
diff --git a/src/preamble.js b/src/preamble.js
index 9e0f5ce3..35bb75d7 100644
--- a/src/preamble.js
+++ b/src/preamble.js
@@ -320,7 +320,7 @@ function setValue(ptr, value, type) {
default: abort('invalid type for setValue: ' + type);
}
}
-this['setValue'] = setValue;
+Module['setValue'] = setValue;
// Parallel to setValue.
@@ -338,7 +338,7 @@ function getValue(ptr, type) {
}
return null;
}
-this['getValue'] = getValue;
+Module['getValue'] = getValue;
// Allocates memory for some data and initializes it properly.
@@ -428,7 +428,8 @@ var STACK_ROOT, STACKTOP, STACK_MAX;
var STATICTOP;
var HAS_TYPED_ARRAYS = false;
-var TOTAL_MEMORY = 50*1024*1024;
+var TOTAL_MEMORY = Module['TOTAL_MEMORY'] || {{{ TOTAL_MEMORY }}};
+var FAST_MEMORY = Module['FAST_MEMORY'] || {{{ FAST_MEMORY }}};
// Initialize the runtime's memory
#if USE_TYPED_ARRAYS
@@ -459,9 +460,8 @@ if (HAS_TYPED_ARRAYS) {
} else
#endif
{
- // Without this optimization, Chrome is slow. Sadly, the constant here needs to be tweaked depending on the code being run...
- var FAST_MEMORY = TOTAL_MEMORY/32;
- HEAP = new Array(FAST_MEMORY);
+ // Make sure that our HEAP is implemented as a flat array.
+ HEAP = new Array(TOTAL_MEMORY);
for (var i = 0; i < FAST_MEMORY; i++) {
HEAP[i] = 0; // XXX We do *not* use {{| makeSetValue(0, 'i', 0, 'null') |}} here, since this is done just to optimize runtime speed
}
diff --git a/src/settings.js b/src/settings.js
index ed3437b1..ab532e67 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -34,6 +34,12 @@ INVOKE_RUN = 1; // Whether we will call run(). Disable if you embed the generate
// code in your own, and will call run() yourself at the right time
INIT_STACK = 1; // Whether to initialize memory on the stack to 0.
INIT_HEAP = 0; // Whether to initialize memory anywhere other than the stack to 0.
+FAST_MEMORY = 2*1024*1024; // The amount of memory to initialize to 0. This ensures it will be
+ // in a flat array. This only matters in non-typed array builds.
+TOTAL_MEMORY = 50*1024*1024; // The total amount of memory to use. This mainly matters in
+ // typed array builds - accessing memory about this value will
+ // return undefined values and lead to serious problems, and there
+ // is currently no warning about that!
// Code embetterments
OPTIMIZE = 0; // Optimize llvm operations into js commands
@@ -129,6 +135,10 @@ RUNTIME_TYPE_INFO = 0; // Whether to expose type info to the script at run time.
// to more easily perform operations from handwritten JS on
// objects with structures etc.
+FAKE_X86_FP80 = 0; // Replaces x86_fp80 with double. This loses precision. It is better,
+ // if you can, to get the original source code to build without x86_fp80
+ // (which is nonportable anyhow).
+
// Compiler debugging options
DEBUG_TAGS_SHOWING = [];
// Some useful items: