aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xemcc10
-rw-r--r--src/runtime.js3
-rw-r--r--tests/runner.py53
-rw-r--r--tools/shared.py10
4 files changed, 61 insertions, 15 deletions
diff --git a/emcc b/emcc
index 460f0b79..e29946cf 100755
--- a/emcc
+++ b/emcc
@@ -284,7 +284,7 @@ try:
if closure is None: closure = 1 if opt_level >= 2 else 0
if closure:
- assert os.path.exists(shared.CLOSURE_COMPILER), 'emcc: fatal: Closure compiler (%s) does not exist' % CLOSURE_COMPILER
+ assert os.path.exists(shared.CLOSURE_COMPILER), 'emcc: fatal: Closure compiler (%s) does not exist' % shared.CLOSURE_COMPILER
settings_changes = []
for i in range(len(newargs)):
@@ -363,9 +363,13 @@ try:
# First, generate LLVM bitcode. For each input file, we get base.o with bitcode
for input_file in input_files:
if input_file.endswith(SOURCE_SUFFIXES):
- args = newargs + ['-emit-llvm', '-c', input_file, '-o', in_temp(unsuffixed_basename(input_file) + '.o')]
+ output_file = in_temp(unsuffixed_basename(input_file) + '.o')
+ args = newargs + ['-emit-llvm', '-c', input_file, '-o', output_file]
if DEBUG: print >> sys.stderr, "emcc running:", call, ' '.join(args)
- Popen([call] + args).communicate()
+ Popen([call] + args).communicate() # let compiler frontend print directly, so colors are saved (PIPE kills that)
+ if not os.path.exists(output_file):
+ print >> sys.stderr, 'emcc: compiler frontend failed to generate LLVM bitcode, halting'
+ sys.exit(1)
else: # bitcode
if input_file.endswith(('.bc', '.o')):
shutil.copyfile(input_file, in_temp(unsuffixed_basename(input_file) + '.o'))
diff --git a/src/runtime.js b/src/runtime.js
index e1a6db39..39f522a7 100644
--- a/src/runtime.js
+++ b/src/runtime.js
@@ -9,9 +9,6 @@
var RuntimeGenerator = {
alloc: function(size, type, init) {
var ret = type + 'TOP';
- if (ASSERTIONS) {
- ret += '; assert(' + size + ' != 0, "Trying to allocate 0")';
- }
if (init) {
ret += '; _memset(' + type + 'TOP, 0, ' + size + ')';
}
diff --git a/tests/runner.py b/tests/runner.py
index f4cfe312..a2073af1 100644
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -4925,6 +4925,19 @@ Options that are modified or new in %s include:
assert os.path.exists('a.out.js'), '\n'.join(output)
self.assertContained('hello, world!', run_js('a.out.js'))
+ # properly report source code errors, and stop there
+ clear()
+ assert not os.path.exists('a.out.js')
+ output = Popen([compiler, path_from_root('tests', 'hello_world_error' + suffix)], stdout=PIPE, stderr=PIPE).communicate()
+ assert not os.path.exists('a.out.js'), 'compilation failed, so no output file is expected'
+ assert len(output[0]) == 0, output[0]
+ self.assertNotContained('IOError', output[1]) # no python stack
+ self.assertNotContained('Traceback', output[1]) # no python stack
+ self.assertContained('error: invalid preprocessing directive', output[1])
+ self.assertContained('''error: use of undeclared identifier 'cheez''', output[1])
+ self.assertContained('2 errors generated', output[1])
+ assert output[1].split('2 errors generated.')[1].replace('\n', '') == 'emcc: compiler frontend failed to generate LLVM bitcode, halting'
+
# emcc src.cpp -c and emcc src.cpp -o src.[o|bc] ==> should give a .bc file
for args in [['-c'], ['-o', 'src.o'], ['-o', 'src.bc']]:
target = args[1] if len(args) == 2 else 'hello_world.o'
@@ -5370,15 +5383,17 @@ elif 'sanity' in str(sys.argv):
return Popen(command, stdout=PIPE, stderr=STDOUT).communicate()[0]
- def check_working(self, command):
+ def check_working(self, command, expected=None):
if type(command) is not list:
command = [command]
+ if expected is None:
+ if command[0] == EMCC:
+ expected = 'no input files'
+ else:
+ expected = "has no attribute 'blahblah'"
output = self.do(command)
- if command[0] == EMCC:
- self.assertContained('no input files', output)
- else:
- self.assertContained("has no attribute 'blahblah'", output)
+ self.assertContained(expected, output)
return output
def test_aaa_normal(self): # this should be the very first thing that runs. if this fails, everything else is irrelevant!
@@ -5413,6 +5428,34 @@ elif 'sanity' in str(sys.argv):
else:
self.assertContained('FATAL', output) # sanity check should fail
+ def test_closure_compiler(self):
+ CLOSURE_FATAL = 'fatal: Closure compiler'
+ CLOSURE_WARNING = 'WARNING: Closure compiler'
+
+ # Sanity check should find closure
+ restore()
+ output = self.check_working(EMCC)
+ self.assertNotContained(CLOSURE_FATAL, output)
+ self.assertNotContained(CLOSURE_WARNING, output)
+
+ # Append a bad path for closure, will warn
+ f = open(CONFIG_FILE, 'a')
+ f.write('CLOSURE_COMPILER = "/tmp/nowhere/nothingtoseehere/kjadsfkjwelkjsdfkqgas/nonexistent.txt"\n')
+ f.close()
+ output = self.check_working(EMCC, CLOSURE_WARNING)
+
+ # And if you actually try to use the bad path, will be fatal
+ f = open(CONFIG_FILE, 'a')
+ f.write('CLOSURE_COMPILER = "/tmp/nowhere/nothingtoseehere/kjadsfkjwelkjsdfkqgas/nonexistent.txt"\n')
+ f.close()
+ output = self.check_working([EMCC, '-O2', 'tests/hello_world.cpp'], CLOSURE_FATAL)
+
+ # With a working path, all is well
+ restore()
+ try_delete('a.out.js')
+ output = self.check_working([EMCC, '-O2', 'tests/hello_world.cpp'], 'The relooper optimization can be very slow')
+ assert os.path.exists('a.out.js')
+
def test_emcc(self):
def mtime(filename):
return os.stat(filename).st_mtime
diff --git a/tools/shared.py b/tools/shared.py
index 1366f6fd..5b238aa4 100644
--- a/tools/shared.py
+++ b/tools/shared.py
@@ -563,7 +563,8 @@ class Building:
if type(passes) == str:
passes = [passes]
input = open(filename, 'r').read()
- output = Popen([NODE_JS, JS_OPTIMIZER] + passes, stdin=PIPE, stdout=PIPE).communicate(input)[0]
+ output, err = Popen([NODE_JS, JS_OPTIMIZER] + passes, stdin=PIPE, stdout=PIPE, stderr=PIPE).communicate(input)
+ assert len(output) > 0, 'Error in js optimizer: ' + err + '\n\n' + output
filename += '.jo.js'
f = open(filename, 'w')
f.write(output)
@@ -578,7 +579,8 @@ class Building:
coffee = path_from_root('tools', 'eliminator', 'node_modules', 'coffee-script', 'bin', 'coffee')
eliminator = path_from_root('tools', 'eliminator', 'eliminator.coffee')
input = open(filename, 'r').read()
- output = Popen([coffee, eliminator], stdin=PIPE, stdout=PIPE, stderr=PIPE).communicate(input)[0]
+ output, err = Popen([coffee, eliminator], stdin=PIPE, stdout=PIPE, stderr=PIPE).communicate(input)
+ assert len(output) > 0, 'Error in eliminator: ' + err + '\n\n' + output
filename += '.el.js'
f = open(filename, 'w')
f.write(output)
@@ -597,8 +599,8 @@ class Building:
#'--formatting', 'PRETTY_PRINT',
#'--variable_map_output_file', filename + '.vars',
'--js', filename, '--js_output_file', filename + '.cc.js'], stdout=PIPE, stderr=STDOUT).communicate()[0]
- if 'ERROR' in cc_output:
- raise Exception('Error in cc output: ' + cc_output)
+ if 'ERROR' in cc_output or not os.path.exists(filename + '.cc.js'):
+ raise Exception('closure compiler error: ' + cc_output)
return filename + '.cc.js'