aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--settings.py2
-rw-r--r--src/analyzer.js36
-rw-r--r--src/compiler.js3
-rw-r--r--src/intertyper.js7
-rw-r--r--src/jsifier.js4
-rw-r--r--src/library.js12
-rw-r--r--src/parseTools.js16
-rw-r--r--src/preamble.js8
-rw-r--r--src/settings.js10
-rw-r--r--tests/runner.py19
10 files changed, 76 insertions, 41 deletions
diff --git a/settings.py b/settings.py
index cf4fd28c..c6d63341 100644
--- a/settings.py
+++ b/settings.py
@@ -13,7 +13,7 @@ COMPILER_OPTS = ['-m32'] # Need to build as 32bit arch, for now -
# various errors on 64bit compilation
# WARNING: '-g' here will generate llvm bitcode that lli will crash on!
-SPIDERMONKEY_ENGINE = [os.path.expanduser('~/Dev/mozilla-central/js/src/js'), '-m', '-j', '-p']
+SPIDERMONKEY_ENGINE = [os.path.expanduser('~/Dev/mozilla-central/js/src/js'), '-m', '-n']
V8_ENGINE = [os.path.expanduser('~/Dev/v8/d8')]
#COMPILER_ENGINE=SPIDERMONKEY_ENGINE # XXX Warning: currently appears to be broken on trunk, some file reading issue
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 ed8d5099..83a49645 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,10 +793,9 @@ 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);
}
-
var params = parseParamTokens(item.tokens[3].item.tokens);
return [{
intertype: 'functionStub',
diff --git a/src/jsifier.js b/src/jsifier.js
index ab381a03..330597bf 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -585,7 +585,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') {
@@ -758,7 +758,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) {
diff --git a/src/library.js b/src/library.js
index 9cb1967a..62e4de55 100644
--- a/src/library.js
+++ b/src/library.js
@@ -3743,7 +3743,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;
},
@@ -4037,6 +4038,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
// ==========================================================================
@@ -5145,6 +5154,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 edf8384d..a3347139 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..8ab9bce8 100644
--- a/src/preamble.js
+++ b/src/preamble.js
@@ -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:
diff --git a/tests/runner.py b/tests/runner.py
index 09ea6745..54898ac0 100644
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -178,7 +178,7 @@ class RunnerCore(unittest.TestCase):
def do_emscripten(self, filename, output_processor=None, append_ext=True, extra_args=[]):
# Run Emscripten
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_EXCEPTIONS']:
+ 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_EXCEPTIONS', 'FAST_MEMORY']:
try:
value = eval(setting)
exported_settings[setting] = value
@@ -233,7 +233,7 @@ class RunnerCore(unittest.TestCase):
###################################################################################################
-if 'benchmark' not in sys.argv:
+if 'benchmark' not in str(sys.argv):
# Tests
print "Running Emscripten tests..."
@@ -2980,7 +2980,6 @@ if 'benchmark' not in sys.argv:
self.do_ll_test(path_from_root('tests', 'lua', 'lua.ll'),
'hello lua world!\n17\n1\n2\n3\n4\n7',
- js_engines=[V8_ENGINE], # XXX Moz bug 675269
args=['-e', '''print("hello lua world!");print(17);for x = 1,4 do print(x) end;print(10-3)'''],
output_nicerizer=lambda string: string.replace('\n\n', '\n').replace('\n\n', '\n'))
@@ -3161,15 +3160,13 @@ if 'benchmark' not in sys.argv:
self.do_ll_test(combined,
lambda: map(ord, open(path_from_root('tests', 'poppler', 'ref.ppm'), 'r').read()).__str__().replace(' ', ''),
args='-scale-to 512 paper.pdf filename'.split(' '),
- post_build=post,
- js_engines=[V8_ENGINE]) # XXX Moz bug 675269
+ post_build=post)
#, build_ll_hook=self.do_autodebug)
def test_openjpeg(self):
global USE_TYPED_ARRAYS
global CORRECT_SIGNS
if USE_TYPED_ARRAYS == 2:
- return self.skip() # XXX Moz bug 675269
CORRECT_SIGNS = 1
else:
CORRECT_SIGNS = 2
@@ -3250,7 +3247,6 @@ if 'benchmark' not in sys.argv:
os.path.join(self.get_building_dir(), 'openjpeg')],
force_c=True,
post_build=post,
- js_engines=[V8_ENGINE], # XXX Moz bug 675269
output_nicerizer=image_compare)# build_ll_hook=self.do_autodebug)
def test_python(self):
@@ -3264,7 +3260,6 @@ if 'benchmark' not in sys.argv:
self.do_ll_test(path_from_root('tests', 'python', 'python.ll'),
'hello python world!\n[0, 2, 4, 6]\n5\n22\n5.470000',
- js_engines=[V8_ENGINE], # XXX Moz bug 675269
args=['-S', '-c' '''print "hello python world!"; print [x*2 for x in range(4)]; t=2; print 10-3-t; print (lambda x: x*2)(11); print '%f' % 5.47'''],
extra_emscripten_args=['-m'])
@@ -3968,7 +3963,8 @@ TT = %s
self.assertEquals(output, expected)
else:
- # Benchmarks
+ # Benchmarks. Run them with argument |benchmark|. To run a specific test, do
+ # |benchmark.test_X|.
print "Running Emscripten benchmarks..."
@@ -4001,6 +3997,7 @@ else:
CORRECT_OVERFLOWS_LINES = CORRECT_SIGNS_LINES = CORRECT_ROUNDINGS_LINES = SAFE_HEAP_LINES = []
LLVM_OPTS = 1
DISABLE_EXCEPTIONS = 1
+ FAST_MEMORY = 10*1024*1024
TEST_REPS = 4
TOTAL_TESTS = 6
@@ -4009,7 +4006,7 @@ else:
total_times = map(lambda x: 0., range(TEST_REPS))
total_native_times = map(lambda x: 0., range(TEST_REPS))
- class Benchmark(RunnerCore):
+ class benchmark(RunnerCore):
def print_stats(self, times, native_times):
mean = sum(times)/len(times)
squared_times = map(lambda x: x*x, times)
@@ -4149,7 +4146,7 @@ else:
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
+ 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')