aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2011-12-18 07:59:06 -0800
committerAlon Zakai <alonzakai@gmail.com>2011-12-18 07:59:06 -0800
commit56b65a54cb92d2d4a34535f71dbae08d758d3fc3 (patch)
tree0220d27388eab38587a8fd12140552e0ce513435
parente77d99dac0b1ba58c773b4b8c7d8a223ad008624 (diff)
parent47bc8ba2c47c67d8824c2b7bf35195a079cbed7c (diff)
Merge branch 'incoming'
-rwxr-xr-xemar3
-rwxr-xr-xemcc81
-rw-r--r--src/compiler.js2
-rw-r--r--src/intertyper.js2
-rw-r--r--src/library.js23
-rw-r--r--src/preamble.js19
-rw-r--r--src/runtime.js9
-rw-r--r--system/include/SDL/SDL_surface.h4
-rw-r--r--system/include/libcxx/ostream2
-rw-r--r--tests/cases/inttoptr.ll20
-rw-r--r--tests/hello_world.ll17
-rw-r--r--tests/hello_world_sdl.cpp4
-rw-r--r--tests/poppler/fontconfig/fontconfig.h (renamed from tests/poppler/include/fontconfig/fontconfig.h)0
-rw-r--r--tests/runner.py45
-rwxr-xr-xtools/emconfiguren.py2
-rwxr-xr-xtools/emmaken.py2
-rw-r--r--tools/shared.py55
17 files changed, 197 insertions, 93 deletions
diff --git a/emar b/emar
index 5a627993..312bd4a4 100755
--- a/emar
+++ b/emar
@@ -17,5 +17,6 @@ newargs = [shared.EMLD] + sys.argv[3:] + ['-o='+sys.argv[2]]
if DEBUG:
print >> sys.stderr, 'emar:', sys.argv, ' ==> ', newargs
-os.execvp(shared.EMLD, newargs)
+if len(newargs) > 2:
+ os.execvp(shared.EMLD, newargs)
diff --git a/emcc b/emcc
index 88730539..a0f59f0b 100755
--- a/emcc
+++ b/emcc
@@ -11,12 +11,12 @@ use emar, emld and emranlib instead of the same command without 'em'.
Example uses:
- * For configure, instead of ./configure, cmake, etc., run emconfiguren.py
+ * For configure, instead of ./configure, cmake, etc., run emconfigure.py
with that command as an argument, for example
- emconfiguren.py ./configure [options]
+ emconfigure.py ./configure [options]
- emconfiguren.py is a tiny script that just sets some environment vars
+ emconfigure.py is a tiny script that just sets some environment vars
as a convenience. The command just shown is equivalent to
EMMAKEN_JUST_CONFIGURE=1 RANLIB=PATH/emranlib AR=PATH/emar CXX=PATH/em++ CC=PATH/emcc ./configure [options]
@@ -80,10 +80,6 @@ from tools import shared
DEBUG = os.environ.get('EMCC_DEBUG')
TEMP_DIR = os.environ.get('EMCC_TEMP_DIR')
-################### XXX
-print >> sys.stderr, '\n***This is a WORK IN PROGRESS***'
-################### XXX
-
if DEBUG: print >> sys.stderr, 'emcc: ', ' '.join(sys.argv)
# Handle some global flags
@@ -148,16 +144,23 @@ The -c option (which tells gcc not to run the linker) will
cause LLVM bitcode to be generated, as %s only generates
JavaScript in the final linking stage of building.
+The input file(s) can be either source code files that
+Clang can handle (C or C++), LLVM bitcode in binary form,
+or LLVM assembly files in human-readable form.
+
''' % (this, this, this)
exit(0)
-# If this is a configure-type thing, just do that
+# If this is a configure-type thing, do not compile to JavaScript, instead use clang
+# to compile to a native binary (using our headers, so things make sense later)
CONFIGURE_CONFIG = os.environ.get('EMMAKEN_JUST_CONFIGURE')
CMAKE_CONFIG = 'CMakeFiles/cmTryCompileExec.dir' in ' '.join(sys.argv)# or 'CMakeCCompilerId' in ' '.join(sys.argv)
if CONFIGURE_CONFIG or CMAKE_CONFIG:
- compiler = 'g++' if 'CXXCompiler' in ' '.join(sys.argv) or os.environ.get('EMMAKEN_CXX') else 'gcc'
+ compiler = shared.CLANG
+ if not ('CXXCompiler' in ' '.join(sys.argv) or os.environ.get('EMMAKEN_CXX')):
+ compiler = shared.to_cc(compiler)
cmd = [compiler] + shared.EMSDK_OPTS + sys.argv[1:]
- if DEBUG: print >> sys.stderr, 'emcc, just configuring: ', cmd
+ if DEBUG: print >> sys.stderr, 'emcc, just configuring: ', compiler, cmd
exit(os.execvp(compiler, cmd))
if os.environ.get('EMMAKEN_COMPILER'):
@@ -179,6 +182,7 @@ if EMMAKEN_CFLAGS: CC_ADDITIONAL_ARGS += EMMAKEN_CFLAGS.split(' ')
# ---------------- Utilities ---------------
SOURCE_SUFFIXES = ('.c', '.cpp', '.cxx', '.cc')
+BITCODE_SUFFIXES = ('.bc', '.o', '.ll')
def unsuffixed(name):
return '.'.join(name.split('.')[:-1])
@@ -266,6 +270,12 @@ try:
closure = int(newargs[i+1])
newargs[i] = ''
newargs[i+1] = ''
+ elif newargs[i] == '-MF': # clang cannot handle this, so we fake it
+ f = open(newargs[i+1], 'w')
+ f.write('\n')
+ f.close()
+ newargs[i] = ''
+ newargs[i+1] = ''
newargs = [ arg for arg in newargs if arg is not '' ]
if llvm_opt_level is None: llvm_opt_level = 1 if opt_level >= 1 else 0
@@ -289,14 +299,23 @@ try:
for i in range(len(newargs)): # find input files XXX this a simple heuristic. we should really analyze based on a full understanding of gcc params,
# right now we just assume that what is left contains no more |-x OPT| things
arg = newargs[i]
- if arg.endswith(SOURCE_SUFFIXES + ('.bc', '.o')): # we already removed -o <target>, so all these should be inputs
- input_files.append(arg)
+ if arg.endswith(SOURCE_SUFFIXES + BITCODE_SUFFIXES): # we already removed -o <target>, so all these should be inputs
newargs[i] = ''
- if arg.endswith(SOURCE_SUFFIXES):
- has_source_inputs = True
+ if os.path.exists(arg):
+ if arg.endswith(SOURCE_SUFFIXES):
+ input_files.append(arg)
+ has_source_inputs = True
+ else:
+ # this should be bitcode, make sure it is valid
+ if arg.endswith('.ll') or shared.Building.is_bitcode(arg):
+ input_files.append(arg)
+ else:
+ print >> sys.stderr, 'emcc: %s: Not valid LLVM bitcode' % arg
+ else:
+ print >> sys.stderr, 'emcc: %s: No such file or directory' % arg
newargs = [ arg for arg in newargs if arg is not '' ]
- assert len(input_files) > 0, 'emcc: no input files specified'
+ assert len(input_files) > 0, 'emcc: no input files'
newargs += CC_ADDITIONAL_ARGS
@@ -334,24 +353,29 @@ try:
## Compile source code to bitcode
- if DEBUG: print >> sys.stderr, 'emcc: compiling to bitcode'
+ if DEBUG: print >> sys.stderr, 'emcc: compiling to bitcode (%s)' % str(sys.argv)
# First, generate LLVM bitcode. For each input file, we get base.o with bitcode
- newargs = newargs + ['-emit-llvm', '-c']
-
for input_file in input_files:
if input_file.endswith(SOURCE_SUFFIXES):
- args = newargs + [input_file, '-o', in_temp(unsuffixed_basename(input_file) + '.o')]
+ args = newargs + ['-emit-llvm', '-c', input_file, '-o', in_temp(unsuffixed_basename(input_file) + '.o')]
if DEBUG: print >> sys.stderr, "emcc running:", call, ' '.join(args)
Popen([call] + args).communicate()
- else:
- shutil.copyfile(input_file, in_temp(unsuffixed_basename(input_file) + '.o'))
+ else: # bitcode
+ if input_file.endswith(('.bc', '.o')):
+ shutil.copyfile(input_file, in_temp(unsuffixed_basename(input_file) + '.o'))
+ else: #.ll
+ shared.Building.llvm_as(input_file, in_temp(unsuffixed_basename(input_file) + '.o'))
# Optimize, if asked to
if llvm_opt_level > 0:
if DEBUG: print >> sys.stderr, 'emcc: LLVM opts'
for input_file in input_files:
- shared.Building.llvm_opt(in_temp(unsuffixed_basename(input_file) + '.o'), LLVM_INTERNAL_OPT_LEVEL, safe=llvm_opt_level < 2)
+ try:
+ shared.Building.llvm_opt(in_temp(unsuffixed_basename(input_file) + '.o'), LLVM_INTERNAL_OPT_LEVEL, safe=llvm_opt_level < 2)
+ except:
+ # This might be an invalid input, which will get ignored during linking later anyhow
+ print >> sys.stderr, 'emcc: warning: LLVM opt failed to run on %s, continuing without optimization' % input_file
# If we were just asked to generate bitcode, stop there
if final_suffix not in ['js', 'html']:
@@ -364,9 +388,12 @@ try:
else:
assert not has_dash_c, 'fatal error: cannot specify -o with -c with multiple files' + str(sys.argv)
# We have a specified target (-o <target>), which is not JavaScript or HTML, and
- # we have multiple files: Link them. TODO: Pass complex linker args along
- shared.Building.link(map(lambda input_file: in_temp(unsuffixed_basename(input_file) + '.o'), input_files), specified_target)
-
+ # we have multiple files: Link them TODO: llvm link-time opts?
+ ld_args = map(lambda input_file: in_temp(unsuffixed_basename(input_file) + '.o'), input_files) + \
+ ['-o', specified_target]
+ #[arg.split('-Wl,')[1] for arg in filter(lambda arg: arg.startswith('-Wl,'), sys.argv)]
+ if DEBUG: print >> sys.stderr, 'emcc: link: ' + str(ld_args)
+ Popen([shared.LLVM_LINK] + ld_args).communicate()
exit(0)
## Continue on to create JavaScript
@@ -389,7 +416,7 @@ try:
if need_dlmalloc and not has_dlmalloc:
# We need to build and link dlmalloc in
if DEBUG: print >> sys.stderr, 'emcc: including dlmalloc'
- Popen([shared.EMCC, shared.path_from_root('src', 'dlmalloc.c'), '-g', '-o', in_temp('dlmalloc.o')]).communicate()
+ Popen([shared.EMCC, shared.path_from_root('src', 'dlmalloc.c'), '-g', '-o', in_temp('dlmalloc.o')], stdout=PIPE, stderr=PIPE).communicate()
if llvm_opt_level > 0:
shared.Building.llvm_opt(in_temp('dlmalloc.o'), LLVM_INTERNAL_OPT_LEVEL, safe=llvm_opt_level < 2)
extra_files_to_link.append(in_temp('dlmalloc.o'))
@@ -408,7 +435,7 @@ try:
if len(input_files) + len(extra_files_to_link) > 1:
shared.Building.link(map(lambda input_file: in_temp(unsuffixed_basename(input_file) + '.o'), input_files) + extra_files_to_link,
in_temp(target_basename + '.bc'))
- # TODO: LLVM link-time opts?
+ # TODO: LLVM link-time opts? here and/or elsewhere?
else:
shutil.move(in_temp(unsuffixed_basename(input_files[0]) + '.o'), in_temp(target_basename + '.bc'))
diff --git a/src/compiler.js b/src/compiler.js
index 2dea5797..33f0e1fb 100644
--- a/src/compiler.js
+++ b/src/compiler.js
@@ -152,7 +152,7 @@ if (!MICRO_OPTS || !RELOOP || ASSERTIONS || CHECK_SIGNS || CHECK_OVERFLOWS || IN
print('// Note: For maximum-speed code, see "Optimizing Code" on the Emscripten wiki, https://github.com/kripken/emscripten/wiki/Optimizing-Code');
}
-if (CORRECT_SIGNS || CORRECT_OVERFLOWS || CORRECT_ROUNDINGS) {
+if (DOUBLE_MODE || I64_MODE || CORRECT_SIGNS || CORRECT_OVERFLOWS || CORRECT_ROUNDINGS) {
print('// Note: Some Emscripten settings may limit the speed of the generated code.');
}
diff --git a/src/intertyper.js b/src/intertyper.js
index ba9e3f0d..4b4544ae 100644
--- a/src/intertyper.js
+++ b/src/intertyper.js
@@ -801,7 +801,7 @@ function intertyper(data, sidePass, baseLineNums) {
var segments = splitTokenList(item.tokens.slice(1));
for (var i = 1; i <= 4; i++) {
if (segments[i-1]) {
- if (i > 1 && segments[i-1].length == 1 && segments[0].length > 1) {
+ if (i > 1 && segments[i-1].length == 1 && segments[0].length > 1 && !isType(segments[i-1][0].text)) {
segments[i-1].unshift(segments[0][0]); // Add the type from the first segment, they are all alike
}
item['param'+i] = parseLLVMSegment(segments[i-1]);
diff --git a/src/library.js b/src/library.js
index 2a4a5e7d..1747155f 100644
--- a/src/library.js
+++ b/src/library.js
@@ -2111,15 +2111,12 @@ LibraryManager.library = {
// TODO: We could in theory slice off the top of the HEAP when
// sbrk gets a negative increment in |bytes|...
var self = _sbrk;
- if (!self.STATICTOP) {
- STATICTOP = alignMemoryPage(STATICTOP);
- self.STATICTOP = STATICTOP;
- self.DATASIZE = 0;
- } else {
- assert(self.STATICTOP == STATICTOP, "No one should touch the heap!");
+ if (!self.called) {
+ STATICTOP = alignMemoryPage(STATICTOP); // make sure we start out aligned
+ self.called = true;
}
- var ret = STATICTOP + self.DATASIZE;
- self.DATASIZE += alignMemoryPage(bytes);
+ var ret = STATICTOP;
+ if (bytes != 0) Runtime.staticAlloc(bytes);
return ret; // Previous break location.
},
open64: 'open',
@@ -4323,6 +4320,16 @@ LibraryManager.library = {
_fputs(str, _stdout); // XXX stderr etc.
},
+ _ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEElsEi__deps: ['fputs', '$libcxx'],
+ _ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEElsEi: function(stream, num) {
+ _fputs(allocate(intArrayFromString(num.toString()), 'i8', ALLOC_STACK), _stdout);
+ },
+
+ _ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEElsEPFRS3_S4_E__deps: ['fputc', '$libcxx'],
+ _ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEElsEPFRS3_S4_E: function(stream, x) {
+ _fputc('\n'.charCodeAt(0), _stdout);
+ },
+
// glibc
_ZNSt8ios_base4InitC1Ev: function() {
diff --git a/src/preamble.js b/src/preamble.js
index cd9138d4..51e22390 100644
--- a/src/preamble.js
+++ b/src/preamble.js
@@ -23,6 +23,15 @@ var ACCEPTABLE_SAFE_HEAP_ERRORS = 0;
function SAFE_HEAP_ACCESS(dest, type, store, ignore) {
//if (dest === A_NUMBER) print ([dest, type, store] + ' ' + new Error().stack); // Something like this may be useful, in debugging
+
+#if USE_TYPED_ARRAYS
+ // When using typed arrays, reads over the top of TOTAL_MEMORY will fail silently, so we must
+ // correct that by growing TOTAL_MEMORY as needed. Without typed arrays, memory is a normal
+ // JS array so it will work (potentially slowly, depending on the engine).
+ assert(dest < STATICTOP);
+ assert(STATICTOP <= TOTAL_MEMORY);
+#endif
+
#if USE_TYPED_ARRAYS == 2
return; // It is legitimate to violate the load-store assumption in this case
#endif
@@ -452,10 +461,10 @@ function allocate(slab, types, allocator) {
size = slab.length;
}
- var ret = [_malloc, Runtime.stackAlloc, Runtime.staticAlloc][allocator === undefined ? ALLOC_STATIC : allocator](Math.max(size, 1));
-
var singleType = typeof types === 'string' ? types : null;
+ var ret = [_malloc, Runtime.stackAlloc, Runtime.staticAlloc][allocator === undefined ? ALLOC_STATIC : allocator](Math.max(size, singleType ? 1 : types.length));
+
var i = 0, type;
while (i < size) {
var curr = zeroinit ? 0 : slab[i];
@@ -533,12 +542,11 @@ var HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32;
var STACK_ROOT, STACKTOP, STACK_MAX;
var STATICTOP;
#if USE_TYPED_ARRAYS
-var LAST_STATICTOP;
function enlargeMemory() {
- // LAST_STATICTOP is the previous top, TOTAL_MEMORY is the current size of the actual array, and STATICTOP is the new top.
+ // TOTAL_MEMORY is the current size of the actual array, and STATICTOP is the new top.
#if ASSERTIONS
printErr('Warning: Enlarging memory arrays, this is not fast! ' + [STATICTOP, TOTAL_MEMORY]);
- assert(STATICTOP >= TOTAL_MEMORY && LAST_STATICTOP < TOTAL_MEMORY);
+ assert(STATICTOP >= TOTAL_MEMORY);
assert(TOTAL_MEMORY > 4); // So the loop below will not be infinite
#endif
while (TOTAL_MEMORY <= STATICTOP) { // Simple heuristic. Override enlargeMemory() if your program has something more optimal for it
@@ -610,6 +618,7 @@ var FAST_MEMORY = Module['FAST_MEMORY'] || {{{ FAST_MEMORY }}};
var base = intArrayFromString('(null)'); // So printing %s of NULL gives '(null)'
// Also this ensures we leave 0 as an invalid address, 'NULL'
+STATICTOP = base.length;
for (var i = 0; i < base.length; i++) {
{{{ makeSetValue(0, 'i', 'base[i]', 'i8') }}}
}
diff --git a/src/runtime.js b/src/runtime.js
index 0b36f967..e1a6db39 100644
--- a/src/runtime.js
+++ b/src/runtime.js
@@ -10,7 +10,7 @@ var RuntimeGenerator = {
alloc: function(size, type, init) {
var ret = type + 'TOP';
if (ASSERTIONS) {
- ret += '; assert(' + size + ' > 0, "Trying to allocate 0")';
+ ret += '; assert(' + size + ' != 0, "Trying to allocate 0")';
}
if (init) {
ret += '; _memset(' + type + 'TOP, 0, ' + size + ')';
@@ -54,11 +54,10 @@ var RuntimeGenerator = {
return ret += 'STACKTOP = __stackBase__';
},
- // An allocation that cannot be free'd
+ // An allocation that cannot normally be free'd (except through sbrk, which once
+ // called, takes control of STATICTOP)
staticAlloc: function(size) {
- var ret = '';
- if (USE_TYPED_ARRAYS) ret += 'LAST_STATICTOP = STATICTOP;'
- ret += RuntimeGenerator.alloc(size, 'STATIC', INIT_HEAP);
+ var ret = RuntimeGenerator.alloc(size, 'STATIC', INIT_HEAP);
if (USE_TYPED_ARRAYS) ret += '; if (STATICTOP >= TOTAL_MEMORY) enlargeMemory();'
return ret;
},
diff --git a/system/include/SDL/SDL_surface.h b/system/include/SDL/SDL_surface.h
index 77b58258..ecf89606 100644
--- a/system/include/SDL/SDL_surface.h
+++ b/system/include/SDL/SDL_surface.h
@@ -59,7 +59,9 @@ extern "C" {
/**
* Evaluates to true if the surface needs to be locked before access.
*/
-#define SDL_MUSTLOCK(S) (((S)->flags & SDL_RLEACCEL) != 0)
+#define SDL_MUSTLOCK(S) 1
+ /* XXX Emscripten: we always need to lock.
+ (((S)->flags & SDL_RLEACCEL) != 0) */
/**
* \brief A collection of pixels used in software blitting.
diff --git a/system/include/libcxx/ostream b/system/include/libcxx/ostream
index dd28e686..f7cbb8a2 100644
--- a/system/include/libcxx/ostream
+++ b/system/include/libcxx/ostream
@@ -1181,6 +1181,7 @@ basic_ostream<_CharT, _Traits>::seekp(off_type __off, ios_base::seekdir __dir)
return *this;
}
+*/
template <class _CharT, class _Traits>
inline _LIBCPP_INLINE_VISIBILITY
basic_ostream<_CharT, _Traits>&
@@ -1209,6 +1210,7 @@ flush(basic_ostream<_CharT, _Traits>& __os)
return __os;
}
+/*
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
template <class _Stream, class _Tp>
diff --git a/tests/cases/inttoptr.ll b/tests/cases/inttoptr.ll
new file mode 100644
index 00000000..c70904c8
--- /dev/null
+++ b/tests/cases/inttoptr.ll
@@ -0,0 +1,20 @@
+; ModuleID = '/tmp/emscripten/tmp/src.cpp.o'
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"
+target triple = "i386-pc-linux-gnu"
+
+@.str = private constant [14 x i8] c"hello, world!\00", align 1 ; [#uses=1]
+
+; [#uses=1]
+declare i32 @puts(i8*)
+
+; [#uses=0]
+define i32 @main() {
+entry:
+ %retval = alloca i32 ; [#uses=2]
+ %0 = alloca i32 ; [#uses=2]
+ %"alloca point" = bitcast i32 0 to i32 ; [#uses=0]
+ %sz.i7 = inttoptr i32 64 to i32* ; [#uses=1 type=i32*]
+ store i32 184, i32* %sz.i7, align 8, !tbaa !1610
+ %0 = call i32 bitcast (i32 (i8*)* @puts to i32 (i32*)*)(i8* getelementptr inbounds ([14 x i8]* @.str, i32 0, i32 0)) ; [#uses=0]
+ ret i32 0
+}
diff --git a/tests/hello_world.ll b/tests/hello_world.ll
new file mode 100644
index 00000000..adeac7eb
--- /dev/null
+++ b/tests/hello_world.ll
@@ -0,0 +1,17 @@
+; ModuleID = 'tests/hello_world.bc'
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S128"
+target triple = "i386-pc-linux-gnu"
+
+@.str = private unnamed_addr constant [15 x i8] c"hello, world!\0A\00", align 1 ; [#uses=1 type=[15 x i8]*]
+
+; [#uses=0]
+define i32 @main() {
+entry:
+ %retval = alloca i32, align 4 ; [#uses=1 type=i32*]
+ store i32 0, i32* %retval
+ %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([15 x i8]* @.str, i32 0, i32 0)) ; [#uses=0 type=i32]
+ ret i32 1
+}
+
+; [#uses=1]
+declare i32 @printf(i8*, ...)
diff --git a/tests/hello_world_sdl.cpp b/tests/hello_world_sdl.cpp
index f3fb8ae7..df69b055 100644
--- a/tests/hello_world_sdl.cpp
+++ b/tests/hello_world_sdl.cpp
@@ -8,7 +8,7 @@ int main() {
SDL_Init(SDL_INIT_VIDEO);
SDL_Surface *screen = SDL_SetVideoMode(256, 256, 32, SDL_SWSURFACE);
- SDL_LockSurface(screen);
+ if (SDL_MUSTLOCK(screen)) SDL_LockSurface(screen);
for (int i = 0; i < 256; i++) {
for (int j = 0; j < 256; j++) {
*((char*)screen->pixels + i*256*4 + j*4 + 0) = i;
@@ -17,7 +17,7 @@ int main() {
*((char*)screen->pixels + i*256*4 + j*4 + 3) = 255;
}
}
- SDL_UnlockSurface(screen);
+ if (SDL_MUSTLOCK(screen)) SDL_UnlockSurface(screen);
SDL_Flip(screen);
printf("you should see a colored cube.");
diff --git a/tests/poppler/include/fontconfig/fontconfig.h b/tests/poppler/fontconfig/fontconfig.h
index 4efa4507..4efa4507 100644
--- a/tests/poppler/include/fontconfig/fontconfig.h
+++ b/tests/poppler/fontconfig/fontconfig.h
diff --git a/tests/runner.py b/tests/runner.py
index 9224cb4b..e62e7681 100644
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -1964,8 +1964,8 @@ if 'benchmark' not in str(sys.argv):
main_name = os.path.join(self.get_dir(), 'main.cpp')
open(main_name, 'w').write(main)
- Building.emmaken(supp_name)
- Building.emmaken(main_name)
+ Building.emcc(supp_name)
+ Building.emcc(main_name)
all_name = os.path.join(self.get_dir(), 'all.bc')
Building.link([supp_name + '.o', main_name + '.o'], all_name)
@@ -3482,12 +3482,12 @@ at function.:blag
int main()
{
- std::cout << "hello world";
+ std::cout << "hello world" << std::endl << 77 << "." << std::endl;
return 0;
}
'''
- self.do_run(src, 'hello world')
+ self.do_run(src, 'hello world\n77.\n')
def test_stdvec(self):
src = '''
@@ -3564,9 +3564,9 @@ at function.:blag
# emcc should build in dlmalloc automatically, and do all the sign correction etc. for it
try_delete(os.path.join(self.get_dir(), 'src.cpp.o.js'))
- # XXX find out why we fail without TOTAL_MEMORY here. that should not happen!
- output = Popen([EMCC, '-g', '-s', 'TOTAL_MEMORY=104857600', path_from_root('tests', 'dlmalloc_test.c'),
+ output = Popen([EMCC, path_from_root('tests', 'dlmalloc_test.c'),
'-o', os.path.join(self.get_dir(), 'src.cpp.o.js')], stdout=PIPE, stderr=PIPE).communicate()
+ #print output
self.do_run('x', '*1,0*', ['200', '1'], no_build=True)
self.do_run('x', '*400,0*', ['400', '400'], no_build=True)
@@ -3782,7 +3782,7 @@ at function.:blag
freetype = self.get_freetype()
poppler = self.get_library('poppler',
- [os.path.join('poppler', '.libs', 'libpoppler.so.13.0.0.bc'),
+ [os.path.join('poppler', '.libs', 'libpoppler.so.13.0.0'),
os.path.join('goo', '.libs', 'libgoo.a.bc'),
os.path.join('fofi', '.libs', 'libfofi.a.bc'),
os.path.join('splash', '.libs', 'libsplash.a.bc'),
@@ -3825,7 +3825,7 @@ at function.:blag
shutil.copy(path_from_root('tests', 'openjpeg', 'opj_config.h'), self.get_dir())
lib = self.get_library('openjpeg',
- [os.path.join('bin', 'libopenjpeg.so.1.4.0.bc'),
+ [os.path.join('bin', 'libopenjpeg.so.1.4.0'),
os.path.sep.join('codec/CMakeFiles/j2k_to_image.dir/index.c.o'.split('/')),
os.path.sep.join('codec/CMakeFiles/j2k_to_image.dir/convert.c.o'.split('/')),
os.path.sep.join('codec/CMakeFiles/j2k_to_image.dir/__/common/color.c.o'.split('/')),
@@ -4484,8 +4484,8 @@ Child2:9
main_name = os.path.join(self.get_dir(), 'main.cpp')
open(main_name, 'w').write(main)
- Building.emmaken(module_name, ['-g'])
- Building.emmaken(main_name, ['-g'])
+ Building.emcc(module_name, ['-g'])
+ Building.emcc(main_name, ['-g'])
all_name = os.path.join(self.get_dir(), 'all.bc')
Building.link([module_name + '.o', main_name + '.o'], all_name)
@@ -4889,11 +4889,6 @@ TT = %s
del T # T is just a shape for the specific subclasses, we don't test it itself
class other(RunnerCore):
- def test_reminder(self):
- raise Exception('''Fix emmaken.py and emconfiguren.py, they should work but mention they are deprecated
- Test emconfigure
- configure in test_zlib looks broken''')
-
def test_emcc(self):
def clear():
for name in os.listdir(self.get_dir()):
@@ -4939,6 +4934,13 @@ Options that are modified or new in %s include:
assert os.path.exists(target), 'Expected %s to exist since args are %s : %s' % (target, str(args), '\n'.join(output))
self.assertContained('hello, world!', self.run_llvm_interpreter([target]))
+ # emcc src.ll ==> generates .js
+ clear()
+ output = Popen([compiler, path_from_root('tests', 'hello_world.ll')], stdout=PIPE, stderr=PIPE).communicate()
+ assert len(output[0]) == 0, output[0]
+ assert os.path.exists('a.out.js'), '\n'.join(output)
+ self.assertContained('hello, world!', run_js('a.out.js'))
+
# dlmalloc. dlmalloc is special in that it is the only part of libc that is (1) hard to write well, and
# very speed-sensitive. So we do not implement it in JS in library.js, instead we compile it from source
for source, has_malloc in [('hello_world' + suffix, False), ('hello_malloc.cpp', True)]:
@@ -5057,12 +5059,11 @@ Options that are modified or new in %s include:
assert os.path.exists('combined.bc'), '\n'.join(output)
self.assertContained('side got: hello from main, over', self.run_llvm_interpreter(['combined.bc']))
- # TODO: compile .ll inputs to emcc into .bc
# TODO: test normal project linking, static and dynamic: get_library should not need to be told what to link!
# TODO: when ready, switch tools/shared building to use emcc over emmaken
# TODO: when this is done, more test runner to test these (i.e., test all -Ox thoroughly)
# TODO: emscripten tutorial with emcc
- # TODO: deprecate llvm optimizations etc. in emscripten.py.
+ # TODO: deprecate llvm optimizations, dlmalloc, etc. in emscripten.py.
# Finally, do some web browser tests
def run_browser(html_file, message):
@@ -5147,8 +5148,14 @@ else:
Building.COMPILER = CLANG
- # Pick the JS engine to benchmark
- JS_ENGINE = JS_ENGINES[1]
+ # Pick the JS engine to benchmark. If you specify one, it will be picked. For example, python tests/runner.py benchmark SPIDERMONKEY_ENGINE
+ JS_ENGINE = JS_ENGINES[0]
+ for i in range(1, len(sys.argv)):
+ arg = sys.argv[i]
+ if not arg.startswith('test_'):
+ JS_ENGINE = eval(arg)
+ sys.argv[i] = None
+ sys.argv = filter(lambda arg: arg is not None, sys.argv)
print 'Benchmarking JS engine:', JS_ENGINE
Building.COMPILER_TEST_OPTS = []
diff --git a/tools/emconfiguren.py b/tools/emconfiguren.py
index 28cb6366..4987fbbd 100755
--- a/tools/emconfiguren.py
+++ b/tools/emconfiguren.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
-#raise Exception('emconfiguren is deprecated!')
+raise Exception('emconfiguren is deprecated! use "emconfigure" (no "n")')
'''
This is a helper script for emmaken.py. See docs in that file for more info.
diff --git a/tools/emmaken.py b/tools/emmaken.py
index 1192eb85..a3a9a721 100755
--- a/tools/emmaken.py
+++ b/tools/emmaken.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
-#raise Exception('emmaken is deprecated!')
+raise Exception('emmaken is deprecated! use "emcc"')
'''
emmaken - the emscripten make proxy tool
diff --git a/tools/shared.py b/tools/shared.py
index 1b5f5d09..f109d9d2 100644
--- a/tools/shared.py
+++ b/tools/shared.py
@@ -77,6 +77,8 @@ if USE_EMSDK:
'-U__APPLE__'
]
COMPILER_OPTS += EMSDK_OPTS
+else:
+ EMSDK_OPTS = []
# Engine tweaks
@@ -222,11 +224,11 @@ class Building:
@staticmethod
def get_building_env():
env = os.environ.copy()
- env['CC'] = EMMAKEN #EMCC
- env['CXX'] = EMMAKEN #EMXX
- env['AR'] = EMMAKEN #EMAR
- env['RANLIB'] = EMMAKEN #EMRANLIB
- env['LIBTOOL'] = EMMAKEN #EMLIBTOOL
+ env['CC'] = EMCC
+ env['CXX'] = EMXX
+ env['AR'] = EMAR
+ env['RANLIB'] = EMRANLIB
+ env['LIBTOOL'] = EMLIBTOOL
env['EMMAKEN_COMPILER'] = Building.COMPILER
env['EMSCRIPTEN_TOOLS'] = path_from_root('tools')
env['CFLAGS'] = env['EMMAKEN_CFLAGS'] = ' '.join(COMPILER_OPTS + Building.COMPILER_TEST_OPTS) # Normal CFLAGS is ignored by some configure's.
@@ -334,19 +336,20 @@ class Building:
assert os.path.exists(filename + '.o.ll'), 'Could not create .ll file: ' + output
@staticmethod
- def llvm_as(filename):
+ def llvm_as(input_filename, output_filename=None):
# LLVM assembly ==> LLVM binary
- try:
- os.remove(target)
- except:
- pass
- output = Popen([LLVM_AS, filename + '.o.ll', '-o=' + filename + '.o'], stdout=PIPE).communicate()[0]
- assert os.path.exists(filename + '.o'), 'Could not create bc file: ' + output
+ if output_filename is None:
+ # use test runner conventions
+ output_filename = input_filename + '.o'
+ input_filename = input_filename + '.o.ll'
+ try_delete(output_filename)
+ output = Popen([LLVM_AS, input_filename, '-o=' + output_filename], stdout=PIPE).communicate()[0]
+ assert os.path.exists(output_filename), 'Could not create bc file: ' + output
@staticmethod
- def llvm_nm(filename):
+ def llvm_nm(filename, stdout=PIPE, stderr=None):
# LLVM binary ==> list of symbols
- output = Popen([LLVM_NM, filename], stdout=PIPE).communicate()[0]
+ output = Popen([LLVM_NM, filename], stdout=stdout, stderr=stderr).communicate()[0]
class ret:
defs = []
undefs = []
@@ -359,13 +362,10 @@ class Building:
ret.defs.append(symbol)
return ret
- @staticmethod # TODO: make this use emcc instead of emmaken
- def emmaken(filename, args=[], stdout=None, stderr=None, env=None):
- try:
- os.remove(filename + '.o')
- except:
- pass
- Popen([EMMAKEN, filename] + args + ['-o', filename + '.o'], stdout=stdout, stderr=stderr, env=env).communicate()[0]
+ @staticmethod
+ def emcc(filename, args=[], stdout=None, stderr=None, env=None):
+ try_delete(filename + '.o')
+ Popen([EMCC, filename] + args + ['-o', filename + '.o'], stdout=stdout, stderr=stderr, env=env).communicate()[0]
assert os.path.exists(filename + '.o'), 'Could not create bc file'
@staticmethod
@@ -533,3 +533,16 @@ class Building:
return filename + '.cc.js'
+ @staticmethod
+ def is_bitcode(filename):
+ # checks if a file contains LLVM bitcode
+ # if the file doesn't exist or doesn't have valid symbols, it isn't bitcode
+ try:
+ defs = Building.llvm_nm(filename, stderr=PIPE)
+ assert len(defs.defs + defs.undefs) > 0
+ except:
+ return False
+ # look for magic signature
+ b = open(filename, 'r').read(4)
+ return b[0] == 'B' and b[1] == 'C'
+