diff options
-rw-r--r-- | src/library.js | 26 | ||||
-rw-r--r-- | src/preamble.js | 8 | ||||
-rw-r--r-- | src/runtime.js | 24 | ||||
-rw-r--r-- | tests/runner.py | 69 | ||||
-rwxr-xr-x | tools/emmaken.py | 25 |
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) |