Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: emscripten-core/emscripten
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 1.2.9
Choose a base ref
...
head repository: emscripten-core/emscripten
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 1.3.0
Choose a head ref
Loading
2 changes: 2 additions & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
@@ -52,4 +52,6 @@ a license to everyone to use it as detailed in LICENSE.)
* Roger Braun <roger@rogerbraun.net>
* Vladimir Vukicevic <vladimir@pobox.com> (copyright owned by Mozilla Foundation)
* Lorant Pinter <lorant.pinter@prezi.com>
* Tobias Doerffel <tobias.doerffel@gmail.com>
* Martin von Gagern <martin@von-gagern.net>

52 changes: 36 additions & 16 deletions emcc
Original file line number Diff line number Diff line change
@@ -129,8 +129,8 @@ while response_file:
for index in range(1, len(sys.argv)):
if sys.argv[index][0] == '@':
# found one, loop again next time
print >>sys.stderr, 'emcc: using response file: %s' % response_file
response_file = sys.argv[index][1:]
print >>sys.stderr, 'emcc: using response file: %s' % response_file
if not os.path.exists(response_file):
print >>sys.stderr, 'emcc: error: Response file not found: %s' % response_file
exit(1)
@@ -332,13 +332,11 @@ Options that are modified or new in %s include:
output HTML but with suffix .data.compress
--minify <on> 0: Do not minify the generated JavaScript's
whitespace (default if closure compiler
will not be run)
whitespace (default in -O0, -O1, or if
-g is used)
1: Minify the generated JavaScript's
whitespace (default if closure compiler
will be run). Note that this by itself
will not minify the code (closure does
that)
whitespace (default in -O2+, assuming
-g is not used)
--split <size> Splits the resulting javascript file into pieces
to ease debugging. This option only works if
@@ -451,6 +449,13 @@ Options that are modified or new in %s include:
the bootstrapped relooper. After the cache
is cleared, this process will exit.
--save-bc PATH When compiling to JavaScript or HTML, this
option will save a copy of the bitcode to
the specified path. The bitcode will include
all files being linked, including standard
libraries, and after any link-time optimizations
(if any).
The target file, if specified (-o <target>), defines what will
be generated:
@@ -696,6 +701,8 @@ try:
keep_js_debug = False
bind = False
jcache = False
save_bc = False

if use_cxx:
default_cxx_std = '-std=c++03' # Enforce a consistent C++ standard when compiling .cpp files, if user does not specify one on the cmdline.
else:
@@ -823,6 +830,11 @@ try:
print >> sys.stderr, 'emcc: clearing cache'
shared.Cache.erase()
sys.exit(0)
elif newargs[i] == '--save-bc':
check_bad_eq(newargs[i])
save_bc = newargs[i+1]
newargs[i] = ''
newargs[i+1] = ''
elif newargs[i].startswith(('-I/', '-L/')):
if not absolute_warning_shown:
print >> sys.stderr, 'emcc: warning: -I or -L of an absolute path encountered. If this is to a local system header/library, it may cause problems (local system files make sense for compiling natively on your system, but not necessarily to JavaScript)' # Of course an absolute path to a non-system-specific library or header is fine, and you can ignore this warning. The danger are system headers that are e.g. x86 specific and nonportable. The emscripten bundled headers are modified to be portable, local system ones are generally not
@@ -974,6 +986,7 @@ try:
if shared.Settings.CORRECT_OVERFLOWS != 1:
print >> sys.stderr, 'emcc: warning: setting CORRECT_OVERFLOWS to 1 for asm.js code generation'
shared.Settings.CORRECT_OVERFLOWS = 1
assert not shared.Settings.PGO, 'cannot run PGO in ASM_JS mode'

if shared.Settings.CORRECT_SIGNS >= 2 or shared.Settings.CORRECT_OVERFLOWS >= 2 or shared.Settings.CORRECT_ROUNDINGS >= 2:
keep_llvm_debug = True # must keep debug info to do line-by-line operations
@@ -983,7 +996,7 @@ try:
closure = False

if minify_whitespace is None:
minify_whitespace = closure # if closure is run, minify whitespace
minify_whitespace = opt_level >= 2 and not keep_js_debug

## Compile source code to bitcode

@@ -1084,10 +1097,14 @@ try:
os.path.join('libc', 'stdlib', 'strtod.c'),
];

prev_cxx = os.environ.get('EMMAKEN_CXX')
if prev_cxx: os.environ['EMMAKEN_CXX'] = ''
for src in libc_files:
o = in_temp(os.path.basename(src) + '.o')
execute([shared.PYTHON, shared.EMCC, shared.path_from_root('system', 'lib', src), '-o', o], stdout=stdout, stderr=stderr)
o_s.append(o)
if prev_cxx: os.environ['EMMAKEN_CXX'] = prev_cxx

shared.Building.link(o_s, in_temp('libc.bc'))
return in_temp('libc.bc')

@@ -1235,6 +1252,9 @@ try:
shared.Building.llvm_opt(in_temp(target_basename + '.bc'), link_opts)
if DEBUG: save_intermediate('linktime', 'bc')

if save_bc:
shutil.copyfile(final, save_bc)

# Prepare .ll for Emscripten
if not LEAVE_INPUTS_RAW:
final = shared.Building.llvm_dis(final, final + '.ll')
@@ -1347,26 +1367,26 @@ try:
if DEBUG: print >> sys.stderr, 'emcc: running closure'
final = shared.Building.closure_compiler(final)
if DEBUG: save_intermediate('closure')
elif shared.Settings.RELOOP and not closure and not keep_js_debug:
# do this if closure is not enabled (it gives similar speedups), and we do not need to keep debug info around
js_optimizer_queue += ['registerize']

if opt_level >= 1:
if DEBUG: print >> sys.stderr, 'emcc: running post-closure post-opts'
js_optimizer_queue += ['simplifyExpressionsPost']

if not closure and shared.Settings.RELOOP and not keep_js_debug:
# do this if closure is not enabled (it gives similar speedups), and we do not need to keep debug info around
js_optimizer_queue += ['registerize']

if minify_whitespace:
js_optimizer_queue += ['compress']

js_optimizer_queue += ['last']

flush_js_optimizer_queue()

if not minify_whitespace:
# Remove some trivial whitespace
src = open(final).read()
src = re.sub(r'\n+[ \n]*\n+', '\n', src)
open(final, 'w').write(src)
# Remove some trivial whitespace # TODO: do not run when compress has already been done on all parts of the code
src = open(final).read()
src = re.sub(r'\n+[ \n]*\n+', '\n', src)
open(final, 'w').write(src)

# If we were asked to also generate HTML, do that
if final_suffix == 'html':
22 changes: 16 additions & 6 deletions emscripten.py
Original file line number Diff line number Diff line change
@@ -33,7 +33,7 @@ def scan(ll, settings):
MIN_CHUNK_SIZE = 1024*1024
MAX_CHUNK_SIZE = float(os.environ.get('EMSCRIPT_MAX_CHUNK_SIZE') or 'inf') # configuring this is just for debugging purposes

def process_funcs((i, funcs, meta, settings_file, compiler, forwarded_file, libraries, compiler_engine, temp_files)):
def process_funcs((i, funcs, meta, settings_file, compiler, forwarded_file, libraries, compiler_engine, temp_files, DEBUG)):
ll = ''.join(funcs) + '\n' + meta
funcs_file = temp_files.get('.func_%d.ll' % i).name
open(funcs_file, 'w').write(ll)
@@ -44,6 +44,7 @@ def process_funcs((i, funcs, meta, settings_file, compiler, forwarded_file, libr
stdout=subprocess.PIPE,
cwd=path_from_root('src'))
tempfiles.try_delete(funcs_file)
if DEBUG: print >> sys.stderr, '.'
return out

def emscript(infile, settings, outfile, libraries=[], compiler_engine=None,
@@ -213,7 +214,7 @@ def load_from_cache(chunk):
if DEBUG: print >> sys.stderr, ' emscript: phase 2 working on %d chunks %s (intended chunk size: %.2f MB, meta: %.2f MB, forwarded: %.2f MB, total: %.2f MB)' % (len(chunks), ('using %d cores' % cores) if len(chunks) > 1 else '', chunk_size/(1024*1024.), len(meta)/(1024*1024.), len(forwarded_data)/(1024*1024.), total_ll_size/(1024*1024.))

commands = [
(i, chunk, meta, settings_file, compiler, forwarded_file, libraries, compiler_engine, temp_files)
(i, chunk, meta, settings_file, compiler, forwarded_file, libraries, compiler_engine, temp_files, DEBUG)
for i, chunk in enumerate(chunks)
]

@@ -332,9 +333,9 @@ def make_table(sig, raw):
params = ','.join(['p%d' % p for p in range(len(sig)-1)])
coercions = ';'.join(['p%d = %sp%d%s' % (p, '+' if sig[p+1] != 'i' else '', p, '' if sig[p+1] != 'i' else '|0') for p in range(len(sig)-1)]) + ';'
ret = '' if sig[0] == 'v' else ('return %s0' % ('+' if sig[0] != 'i' else ''))
return ('function %s(%s) { %s abort(%d); %s };' % (bad, params, coercions, i, ret), raw.replace('[0,', '[' + bad + ',').replace(',0,', ',' + bad + ',').replace(',0,', ',' + bad + ',').replace(',0]', ',' + bad + ']').replace(',0]', ',' + bad + ']').replace(',0\n', ',' + bad + '\n'))
return ('function %s(%s) { %s abort(%d); %s }' % (bad, params, coercions, i, ret), raw.replace('[0,', '[' + bad + ',').replace(',0,', ',' + bad + ',').replace(',0,', ',' + bad + ',').replace(',0]', ',' + bad + ']').replace(',0]', ',' + bad + ']').replace(',0\n', ',' + bad + '\n'))
infos = [make_table(sig, raw) for sig, raw in last_forwarded_json['Functions']['tables'].iteritems()]
function_tables_defs = '\n'.join([info[0] for info in infos] + [info[1] for info in infos])
function_tables_defs = '\n'.join([info[0] for info in infos]) + '\n// EMSCRIPTEN_END_FUNCS\n' + '\n'.join([info[1] for info in infos])

asm_setup = ''
maths = ['Math.' + func for func in ['floor', 'abs', 'sqrt', 'pow', 'cos', 'sin', 'tan', 'acos', 'asin', 'atan', 'atan2', 'exp', 'log', 'ceil', 'imul']]
@@ -416,6 +417,7 @@ def math_fix(g):
function asmPrintFloat(x, y) {
Module.print('float ' + x + ',' + y);// + ' ' + new Error().stack);
}
// EMSCRIPTEN_START_ASM
var asm = (function(global, env, buffer) {
'use asm';
var HEAP8 = new global.Int8Array(buffer);
@@ -432,6 +434,7 @@ def math_fix(g):
var tempInt = 0, tempBigInt = 0, tempBigIntP = 0, tempBigIntS = 0, tempBigIntR = 0.0, tempBigIntI = 0, tempBigIntD = 0, tempValue = 0, tempDouble = 0.0;
''' + ''.join(['''
var tempRet%d = 0;''' % i for i in range(10)]) + '\n' + asm_global_funcs + '''
// EMSCRIPTEN_START_FUNCS
function stackAlloc(size) {
size = size|0;
var ret = 0;
@@ -457,11 +460,12 @@ def math_fix(g):
tempRet%d = value;
}
''' % (i, i) for i in range(10)]) + funcs_js + '''
%s
return %s;
})(%s, %s, buffer);
})
// EMSCRIPTEN_END_ASM
(%s, %s, buffer);
%s;
Runtime.stackAlloc = function(size) { return asm.stackAlloc(size) };
Runtime.stackSave = function() { return asm.stackSave() };
@@ -483,6 +487,12 @@ def fix(m):
else:
function_tables_defs = '\n'.join([table for table in last_forwarded_json['Functions']['tables'].itervalues()])
outfile.write(function_tables_defs)
funcs_js = '''
// EMSCRIPTEN_START_FUNCS
''' + funcs_js + '''
// EMSCRIPTEN_END_FUNCS
'''

outfile.write(blockaddrsize(indexize(funcs_js)))
funcs_js = None

5 changes: 3 additions & 2 deletions src/analyzer.js
Original file line number Diff line number Diff line change
@@ -231,9 +231,10 @@ function analyzer(data, sidePass) {
}
if (isIllegalType(item.valueType) || isIllegalType(item.type)) {
isIllegal = true;
}
if ((item.intertype == 'load' || item.intertype == 'store') && isStructType(item.valueType)) {
} else if ((item.intertype == 'load' || item.intertype == 'store') && isStructType(item.valueType)) {
isIllegal = true; // storing an entire structure is illegal
} else if (item.intertype == 'mathop' && item.op == 'trunc' && isIllegalType(item.params[1].ident)) { // trunc stores target value in second ident
isIllegal = true;
}
});
if (!isIllegal) {
1 change: 1 addition & 0 deletions src/compiler.js
Original file line number Diff line number Diff line change
@@ -163,6 +163,7 @@ if (SAFE_HEAP >= 2) {
EXPORTED_FUNCTIONS = set(EXPORTED_FUNCTIONS);
EXPORTED_GLOBALS = set(EXPORTED_GLOBALS);
EXCEPTION_CATCHING_WHITELIST = set(EXCEPTION_CATCHING_WHITELIST);
DEAD_FUNCTIONS = set(DEAD_FUNCTIONS);

RUNTIME_DEBUG = LIBRARY_DEBUG || GL_DEBUG;

Loading