aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/library.js26
-rw-r--r--src/preamble.js8
-rw-r--r--src/runtime.js24
-rw-r--r--tests/runner.py69
-rwxr-xr-xtools/emmaken.py25
5 files changed, 86 insertions, 66 deletions
diff --git a/src/library.js b/src/library.js
index 8a77850f..b60bd07f 100644
--- a/src/library.js
+++ b/src/library.js
@@ -561,14 +561,9 @@ var Library = {
llvm_memmove_p0i8_p0i8_i32: 'memmove',
llvm_memmove_p0i8_p0i8_i64: 'memmove',
- memset: function(ptr, value, num) {
- for (var i = 0; i < num; i++) {
- {{{ makeSetValue('ptr', 'i', 'value', 'null') }}}
- }
- },
- llvm_memset_i32: 'memset',
- llvm_memset_p0i8_i32: 'memset',
- llvm_memset_p0i8_i64: 'memset',
+ llvm_memset_i32: 'Runtime.memset',
+ llvm_memset_p0i8_i32: 'Runtime.memset',
+ llvm_memset_p0i8_i64: 'Runtime.memset',
strlen: function(ptr) {
return String_len(ptr);
@@ -822,6 +817,21 @@ var Library = {
*/
},
+ llvm_bswap_i32: function(x) {
+ x = unSign(x, 32);
+ var bytes = [];
+ for (var i = 0; i < 4; i++) {
+ bytes[i] = x & 255;
+ x >>= 8;
+ }
+ var ret = 0;
+ for (i = 0; i < 4; i++) {
+ ret <<= 8;
+ ret += bytes[i];
+ }
+ return ret;
+ },
+
__assert_fail: function(condition, file, line) {
ABORT = true;
throw 'Assertion failed: ' + Pointer_stringify(condition);//JSON.stringify(arguments)//condition;
diff --git a/src/preamble.js b/src/preamble.js
index ade02496..38c18f35 100644
--- a/src/preamble.js
+++ b/src/preamble.js
@@ -221,7 +221,11 @@ var TOTAL_MEMORY = 50*1024*1024;
function __initializeRuntime__() {
// If we don't have malloc/free implemented, use a simple implementation.
Module['_malloc'] = _malloc = __Znwj = __Znaj = __Znam = __Znwm = Module['_malloc'] ? Module['_malloc'] : Runtime.staticAlloc;
- Module['_calloc'] = _calloc = Module['_calloc'] ? Module['_calloc'] : function(n, s) { return _malloc(n*s) };
+ Module['_calloc'] = _calloc = Module['_calloc'] ? Module['_calloc'] : function(n, s) {
+ var ret = _malloc(n*s);
+ Runtime.memset(ret, 0, n*s);
+ return ret;
+ };
Module['_free'] = _free = __ZdlPv = __ZdaPv = Module['_free'] ? Module['_free'] : function() { };
#if USE_TYPED_ARRAYS
@@ -252,7 +256,7 @@ function __initializeRuntime__() {
Module['FHEAP'] = FHEAP;
STACK_ROOT = STACKTOP = alignMemoryPage(10);
- if (!this['TOTAL_STACK']) TOTAL_STACK = 1024*1024; // Reserved room for stack
+ if (!this['TOTAL_STACK']) TOTAL_STACK = 1024*1024; // Reserved room for stack XXX: Changing this value can lead to bad perf on v8!
STACK_MAX = STACK_ROOT + TOTAL_STACK;
STATICTOP = alignMemoryPage(STACK_MAX);
diff --git a/src/runtime.js b/src/runtime.js
index 6b0d4be6..4de337f7 100644
--- a/src/runtime.js
+++ b/src/runtime.js
@@ -8,15 +8,10 @@ RuntimeGenerator = {
alloc: function(size, type, init) {
var ret = type + 'TOP';
if (GUARD_MEMORY) {
- ret += '; assert(' + size + ' > 0)';
+ ret += '; assert(' + size + ' > 0, "Trying to allocate 0")';
}
if (init) {
- var initMemory = 'for (var i = 0; i < ' + size + '; i++) ' + (
- USE_TYPED_ARRAYS ?
- 'IHEAP[' + type + 'TOP+i] = FHEAP[' + type + 'TOP+i] = 0' :
- 'HEAP[' + type + 'TOP+i] = 0'
- );
- ret += '; ' + initMemory;
+ ret += '; Runtime.memset(' + type + 'TOP, 0, ' + size + ')';
}
ret += '; ' + type + 'TOP += ' + size;
if (QUANTUM_SIZE > 1) {
@@ -29,7 +24,7 @@ RuntimeGenerator = {
stackAlloc: function(size) {
var ret = RuntimeGenerator.alloc(size, 'STACK', INIT_STACK);
if (GUARD_MEMORY) {
- ret += '; assert(STACKTOP < STACK_ROOT + STACK_MAX)';
+ ret += '; assert(STACKTOP < STACK_ROOT + STACK_MAX, "Ran out of stack")';
}
return ret;
},
@@ -44,13 +39,8 @@ RuntimeGenerator = {
ret += '; assert(STACKTOP < STACK_MAX)';
}
if (INIT_STACK) {
- var initMemory = 'for (var i = __stackBase__; i < STACKTOP; i++) {' + (
- USE_TYPED_ARRAYS ?
- 'IHEAP[i] = FHEAP[i] = 0' : // TODO: Benchmark this. Suboptimal due to type differences?
- 'HEAP[i] = 0'
- ) + (SAFE_HEAP ? '; SAFE_HEAP_ACCESS(i, null, true)' : '') + ' }';
+ ret += '; Runtime.memset(__stackBase__, 0, ' + initial + ')';
}
- ret += '; ' + initMemory;
return ret;
},
@@ -87,6 +77,12 @@ Runtime = {
staticAlloc: unInline('staticAlloc', ['size']),
alignMemory: unInline('alignMemory', ['size', 'quantum']),
+ memset: function(ptr, value, num) {
+ for (var i = 0; i < num; i++) {
+ {{{ makeSetValue('ptr', 'i', 'value', 'null') }}}
+ }
+ },
+
getFunctionIndex: function getFunctionIndex(func, ident) {
var key = FUNCTION_TABLE.length;
FUNCTION_TABLE[key] = func;
diff --git a/tests/runner.py b/tests/runner.py
index b006c0ef..00353adc 100644
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -195,9 +195,13 @@ if 'benchmark' not in sys.argv:
class T(RunnerCore): # Short name, to make it more fun to use manually on the commandline
## Does a complete test - builds, runs, checks output, etc.
- def do_test(self, src, expected_output, args=[], output_nicerizer=None, output_processor=None, no_build=False, main_file=None, additional_files=[], js_engines=None, post_build=None, basename='src.cpp', libraries=[], includes=[]):
+ def do_test(self, src, expected_output, args=[], output_nicerizer=None, output_processor=None, no_build=False, main_file=None, additional_files=[], js_engines=None, post_build=None, basename='src.cpp', libraries=[], includes=[], force_c=False):
#print 'Running test:', inspect.stack()[1][3].replace('test_', ''), '[%s,%s,%s]' % (COMPILER.split(os.sep)[-1], 'llvm-optimizations' if LLVM_OPTS else '', 'reloop&optimize' if RELOOP else '')
- if main_file is not None and main_file[-2:] == '.c': basename = 'src.c'
+ if force_c or (main_file is not None and main_file[-2:]) == '.c':
+ basename = 'src.c'
+ global COMPILER
+ COMPILER = COMPILER.replace('clang++', 'clang').replace('g++', 'gcc')
+
dirname = self.get_dir()
filename = os.path.join(dirname, basename)
if not no_build:
@@ -1475,35 +1479,34 @@ if 'benchmark' not in sys.argv:
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'))
+ # Build a library into a .bc file. We build the .bc file once and cache it for all our tests. (We cache in
+ # memory since the test directory is destroyed and recreated for each test.)
+ def get_library(self, name, generated_lib, make_args=[]):
+ if hasattr(GlobalCache, 'cached_lib' + name):
+ bc_file = os.path.join(self.get_dir(), 'lib' + name + '.bc')
+ f = open(bc_file, 'wb')
+ f.write(getattr(GlobalCache, 'cached_lib' + name))
+ f.close()
+ return bc_file
+
+ temp_dir = os.path.join(self.get_dir(), 'building')
+ ft_dir = os.path.join(temp_dir, name)
+ shutil.copytree(path_from_root('tests', name), ft_dir)
+ os.chdir(ft_dir)
+ env = os.environ.copy()
+ env['RANLIB'] = env['AR'] = env['CXX'] = env['CC'] = EMMAKEN
+ output = Popen(['./configure'], stdout=PIPE, stderr=STDOUT, env=env).communicate()[0]
+ Popen(['make', '-j', '2'] + make_args, stdout=PIPE, stderr=STDOUT).communicate()[0]
+ bc_file = os.path.join(ft_dir, generated_lib)
+ shutil.copyfile(bc_file, bc_file + '.bc')
+ bc_file += '.bc'
+ setattr(GlobalCache, 'cached_lib' + name, open(bc_file, 'rb').read())
+ return bc_file
+
def test_freetype(self):
if COMPILER != LLVM_GCC: return # TODO: Build in both clang and llvm-gcc. emmaken currently only does llvm-gcc
if LLVM_OPTS: global RELOOP; RELOOP = 0 # Too slow; we do care about typed arrays and OPTIMIZE though
- def get_bc():
- # We build the .bc file once and cache it for all our tests. (We cache in
- # memory since the test directory is destroyed and recreated for each test.)
- if hasattr(GlobalCache, 'cached_libfreetype'):
- bc_file = os.path.join(self.get_dir(), 'libfreetype.bc')
- f = open(bc_file, 'wb')
- f.write(GlobalCache.cached_libfreetype)
- f.close()
- return bc_file
-
- temp_dir = os.path.join(self.get_dir(), 'building')
- ft_dir = os.path.join(temp_dir, 'freetype')
- shutil.copytree(path_from_root('tests', 'freetype'), ft_dir)
- os.chdir(ft_dir)
- env = os.environ.copy()
- env['RANLIB'] = env['AR'] = env['CXX'] = env['CC'] = EMMAKEN
- output = Popen(['./configure'], stdout=PIPE, stderr=STDOUT, env=env).communicate()[0]
- self.assertContained('configure: creating ./config.status', output)
- Popen(['make', '-j', '2'], stdout=PIPE, stderr=STDOUT).communicate()[0]
- bc_file = os.path.join(ft_dir, 'objs', '.libs', 'libfreetype')
- shutil.copyfile(bc_file + '.so', bc_file + '.bc')
- bc_file += '.bc'
- GlobalCache.cached_libfreetype = open(bc_file, 'rb').read()
- return bc_file
-
def post(filename):
# Embed the font into the document
src = open(filename, 'r').read().replace(
@@ -1518,9 +1521,19 @@ if 'benchmark' not in sys.argv:
self.do_test(open(path_from_root('tests', 'freetype', 'main.c'), 'r').read(),
open(path_from_root('tests', 'freetype', 'ref.txt'), 'r').read(),
['font.ttf', 'test!'],
- libraries=[get_bc()], includes=[path_from_root('tests', 'freetype', 'include')],
+ libraries=[self.get_library('freetype', os.path.join('objs', '.libs', 'libfreetype.so'))],
+ includes=[path_from_root('tests', 'freetype', 'include')],
post_build=post)
+ def zzztest_zlib(self):
+ if COMPILER != LLVM_GCC: return # TODO: Build in both clang and llvm-gcc. emmaken currently only does llvm-gcc
+
+ self.do_test(open(path_from_root('tests', 'zlib', 'example.c'), 'r').read(),
+ open(path_from_root('tests', 'zlib', 'ref.txt'), 'r').read(),
+ libraries=[self.get_library('zlib', os.path.join('libz.a'), ['libz.a'])],
+ includes=[path_from_root('tests', 'zlib')],
+ force_c=True)
+
def zzztest_poppler(self):
# Has 'Object', which has a big union with a value that can be of any type (like a dynamic value)
global SAFE_HEAP; SAFE_HEAP = 0
diff --git a/tools/emmaken.py b/tools/emmaken.py
index 8ffbb963..ef392849 100755
--- a/tools/emmaken.py
+++ b/tools/emmaken.py
@@ -55,7 +55,8 @@ exec(open(CONFIG_FILE, 'r').read())
try:
print >> sys.stderr, 'emmaken.py: ', ' '.join(sys.argv)
- CC='/home/alon/Dev/llvm-gcc-4.2-2.8.source/cbuild/install/bin/llvm-g++'
+ CC='/home/alon/Dev/llvm-gcc-4.2-2.8.source/cbuild/install/bin/llvm-gcc'
+ CXX='/home/alon/Dev/llvm-gcc-4.2-2.8.source/cbuild/install/bin/llvm-g++'
CC_ARG_SKIP = ['-g', '-O1', '-O2', '-O3']
CC_ADDITIONAL_ARGS = ['-m32', '-U__i386__', '-U__x86_64__', '-UX87_DOUBLE_ROUNDING', '-UHAVE_GCC_ASM_FOR_X87']
@@ -67,6 +68,7 @@ try:
LLVM_DIS = '/home/alon/Dev/llvm-2.8/cbuild/Release/bin/llvm-dis'
ALLOWED_LINK_ARGS = ['-f', '-help', '-o', '-print-after', '-print-after-all', '-print-before',
'-print-before-all', '-time-passes', '-v', '-verify-dom-info', '-version' ]
+ DISALLOWED_LINK_ARGS = []#['rc']
#LINK_ARG_SKIP = ['-pthread', '-DNDEBUG', '-g', '-O3', '-Wall', '-Wstrict-prototypes',
# '-lpthread', '-ldl', '-lutil', '-Xlinker', '-export-dynamic', '-lm', '-shared']
@@ -80,8 +82,8 @@ try:
# noop ar
sys.exit(0)
+ use_cxx = True
use_linker = True
- #use_linker = False
opts = []
files = []
@@ -90,13 +92,15 @@ try:
opts.append(arg)
else:
files.append(arg)
+ if arg.endswith('.c'):
+ use_cxx = False
if arg.endswith(('.c', '.cc', '.cpp')):
use_linker = False
if '--version' in opts:
use_linker = False
- if sys.argv[1] == 'cru': # ar
+ if sys.argv[1] in ['cru', 'rc']: # ar
sys.argv = sys.argv[:1] + sys.argv[3:] + ['-o='+sys.argv[2]]
assert use_linker, 'Linker should be used in this case'
@@ -105,14 +109,6 @@ try:
newargs = []
found_o = False
for arg in sys.argv[1:]:
- if os.path.basename(sys.argv[0])=='arproxy.py':
- if arg.endswith('.a'):
- newargs.append('-o=%s' % arg)
- elif arg.endswith('.o'):
- newargs.append(arg)
- else:
- pass
- continue
if found_o:
newargs.append('-o=%s' % arg)
found_o = False
@@ -128,13 +124,14 @@ try:
continue # .so's do not exist yet, in many cases
else:
# not option, so just append
- newargs.append(arg)
+ if arg not in DISALLOWED_LINK_ARGS:
+ newargs.append(arg)
else:
- call = CC
+ call = CXX if use_cxx else CC
newargs = [ arg for arg in sys.argv[1:] if arg not in CC_ARG_SKIP ] + CC_ADDITIONAL_ARGS
if 'conftest.c' not in files:
newargs.append('-emit-llvm')
- if 'llvm-g' in CC:
+ if not use_linker:
newargs.append('-c')
print >> sys.stderr, "Running:", call, ' '.join(newargs)