680
693
symbol_table[value] = str(i)
681
694
outfile.write("var SYMBOL_TABLE = %s;" % json.dumps(symbol_table).replace('"', ''))
683
for funcs_js_item in funcs_js: # do this loop carefully to save memory
696
for i in range(len(funcs_js)): # do this loop carefully to save memory
697
funcs_js_item = funcs_js[i]
684
699
funcs_js_item = indexize(funcs_js_item)
685
700
funcs_js_item = blockaddrsize(funcs_js_item)
686
701
outfile.write(funcs_js_item)
689
704
outfile.write(indexize(post))
690
if DEBUG: print >> sys.stderr, ' emscript: phase 3 took %s seconds' % (time.time() - t)
705
if DEBUG: logging.debug(' emscript: phase 3 took %s seconds' % (time.time() - t))
709
# emscript_fast: emscript'en code using the 'fast' compilation path, using
711
# FIXME: this is just a copy-paste of normal emscript(), and we trample it
712
# if the proper env var is set (see below). we should refactor to
713
# share code between the two, once emscript_fast stabilizes (or,
714
# leaving it separate like it is will make it trivial to rip out
715
# if the experiment fails)
717
def emscript_fast(infile, settings, outfile, libraries=[], compiler_engine=None,
718
jcache=None, temp_files=None, DEBUG=None, DEBUG_CACHE=None):
719
"""Runs the emscripten LLVM-to-JS compiler. We parallelize as much as possible
722
infile: The path to the input LLVM assembly file.
723
settings: JSON-formatted settings that override the values
724
defined in src/settings.js.
725
outfile: The file where the output is written.
728
assert(settings['ASM_JS']) # TODO: apply ASM_JS even in -O0 for fastcomp
731
# * Run LLVM backend to emit JS. JS includes function bodies, memory initializer,
732
# and various metadata
733
# * Run compiler.js on the metadata to emit the shell js code, pre/post-ambles,
734
# JS library dependencies, etc.
737
logging.debug('emscript: llvm backend')
740
temp_js = temp_files.get('.4.js').name
741
backend_compiler = os.path.join(shared.LLVM_ROOT, 'llc')
742
shared.jsrun.timeout_run(subprocess.Popen([backend_compiler, infile, '-march=js', '-filetype=asm', '-o', temp_js], stdout=subprocess.PIPE))
745
logging.debug(' emscript: llvm backend took %s seconds' % (time.time() - t))
749
backend_output = open(temp_js).read()
750
#if DEBUG: print >> sys.stderr, backend_output
752
start_funcs_marker = '// EMSCRIPTEN_START_FUNCTIONS'
753
end_funcs_marker = '// EMSCRIPTEN_END_FUNCTIONS'
754
metadata_split_marker = '// EMSCRIPTEN_METADATA'
756
start_funcs = backend_output.index(start_funcs_marker)
757
end_funcs = backend_output.rindex(end_funcs_marker)
758
metadata_split = backend_output.rindex(metadata_split_marker)
760
funcs = backend_output[start_funcs+len(start_funcs_marker):end_funcs]
761
metadata_raw = backend_output[metadata_split+len(metadata_split_marker):]
762
#if DEBUG: print >> sys.stderr, "METAraw", metadata_raw
763
metadata = json.loads(metadata_raw)
764
mem_init = backend_output[end_funcs+len(end_funcs_marker):metadata_split]
765
#if DEBUG: print >> sys.stderr, "FUNCS", funcs
766
#if DEBUG: print >> sys.stderr, "META", metadata
767
#if DEBUG: print >> sys.stderr, "meminit", mem_init
769
# function table masks
772
for k, v in metadata['tables'].iteritems():
773
table_sizes[k] = str(v.count(',')) # undercounts by one, but that is what we want
774
funcs = re.sub(r"#FM_(\w+)#", lambda m: table_sizes[m.groups(0)[0]], funcs)
776
# fix +float into float.0, if not running js opts
777
if not settings['RUNNING_JS_OPTS']:
780
# TODO: handle 0x floats?
781
if num.find('.') < 0:
786
num = num[:e] + '.0' + num[e:]
787
return m.group(1) + m.group(2) + num
788
funcs = re.sub(r'([(=,+\-*/%<>:?] *)\+(-?)((0x)?[0-9a-f]*\.?[0-9]+([eE][-+]?[0-9]+)?)', lambda m: fix_dot_zero(m), funcs)
792
if DEBUG: logging.debug('emscript: js compiler glue')
795
assert settings['TARGET_LE32'] == 1
796
settings['TARGET_LE32'] = 2
797
if 'i64Add' in metadata['declares']: # TODO: others, once we split them up
798
settings['PRECISE_I64_MATH'] = 2
799
metadata['declares'] = filter(lambda i64_func: i64_func not in ['getHigh32', 'setHigh32', '__muldi3', '__divdi3', '__remdi3', '__udivdi3', '__uremdi3'], metadata['declares']) # FIXME: do these one by one as normal js lib funcs
801
# Integrate info from backend
802
settings['DEFAULT_LIBRARY_FUNCS_TO_INCLUDE'] = list(
803
set(settings['DEFAULT_LIBRARY_FUNCS_TO_INCLUDE'] + map(shared.JS.to_nice_ident, metadata['declares'])).difference(
804
map(lambda x: x[1:], metadata['implementedFunctions'])
806
) + map(lambda x: x[1:], metadata['externs'])
809
settings['ASM_JS'] = 2
811
# Save settings to a file to work around v8 issue 1579
812
settings_file = temp_files.get('.txt').name
815
settings_text = json.dumps(settings, sort_keys=True)
816
s = open(settings_file, 'w')
817
s.write(settings_text)
822
if DEBUG: t = time.time()
823
out = jsrun.run_js(path_from_root('src', 'compiler.js'), compiler_engine, [settings_file, ';', 'glue'] + libraries, stdout=subprocess.PIPE, stderr=STDERR_FILE,
824
cwd=path_from_root('src'))
825
assert '//FORWARDED_DATA:' in out, 'Did not receive forwarded data in pre output - process failed?'
826
glue, forwarded_data = out.split('//FORWARDED_DATA:')
829
logging.debug(' emscript: glue took %s seconds' % (time.time() - t))
832
last_forwarded_json = forwarded_json = json.loads(forwarded_data)
834
# merge in information from llvm backend
836
last_forwarded_json['Functions']['tables'] = metadata['tables']
838
'''indexed_functions = set()
839
for key in forwarded_json['Functions']['indexedFunctions'].iterkeys():
840
indexed_functions.add(key)'''
842
pre, post = glue.split('// EMSCRIPTEN_END_FUNCS')
844
#print >> sys.stderr, 'glue:', pre, '\n\n||||||||||||||||\n\n', post, '...............'
846
# memory and global initializers
848
global_initializers = ', '.join(map(lambda i: '{ func: function() { %s() } }' % i, metadata['initializers']))
850
pre = pre.replace('STATICTOP = STATIC_BASE + 0;', '''STATICTOP = STATIC_BASE + Runtime.alignMemory(%d);
851
/* global initializers */ __ATINIT__.push(%s);
852
%s''' % (mem_init.count(',')+1, global_initializers, mem_init)) # XXX wrong size calculation!
855
if settings.get('ASM_JS'):
856
parts = pre.split('// ASM_LIBRARY FUNCTIONS\n')
859
funcs_js.append(parts[1])
861
# calculations on merged forwarded data TODO
863
# merge forwarded data
864
assert settings.get('ASM_JS'), 'fastcomp is asm.js only'
865
settings['EXPORTED_FUNCTIONS'] = forwarded_json['EXPORTED_FUNCTIONS']
866
all_exported_functions = set(settings['EXPORTED_FUNCTIONS']) # both asm.js and otherwise
867
for additional_export in settings['DEFAULT_LIBRARY_FUNCS_TO_INCLUDE']: # additional functions to export from asm, if they are implemented
868
all_exported_functions.add('_' + additional_export)
869
exported_implemented_functions = set()
870
export_bindings = settings['EXPORT_BINDINGS']
871
export_all = settings['EXPORT_ALL']
872
for key in metadata['implementedFunctions'] + forwarded_json['Functions']['implementedFunctions'].keys(): # XXX perf
873
if key in all_exported_functions or export_all or (export_bindings and key.startswith('_emscripten_bind')):
874
exported_implemented_functions.add(key)
875
implemented_functions = set(metadata['implementedFunctions'])
878
named_globals = '\n'.join(['var %s = %s;' % (k, v) for k, v in metadata['namedGlobals'].iteritems()])
879
pre = pre.replace('// === Body ===', '// === Body ===\n' + named_globals + '\n')
881
#if DEBUG: outfile.write('// pre\n')
885
#if DEBUG: outfile.write('// funcs\n')
887
if settings.get('ASM_JS'):
888
# Move preAsms to their right place
890
contents = m.groups(0)[0]
891
outfile.write(contents + '\n')
893
funcs_js[1] = re.sub(r'/\* PRE_ASM \*/(.*)\n', lambda m: move_preasm(m), funcs_js[1])
895
funcs_js += ['\n// EMSCRIPTEN_END_FUNCS\n']
897
simple = os.environ.get('EMCC_SIMPLE_ASM')
901
if 'pre' in last_forwarded_json['Functions']['tables']:
902
pre_tables = last_forwarded_json['Functions']['tables']['pre']
903
del last_forwarded_json['Functions']['tables']['pre']
907
def make_table(sig, raw):
911
params = ','.join(['p%d' % p for p in range(len(sig)-1)])
912
coerced_params = ','.join([shared.JS.make_coercion('p%d', sig[p+1], settings) % p for p in range(len(sig)-1)])
913
coercions = ';'.join(['p%d = %s' % (p, shared.JS.make_coercion('p%d' % p, sig[p+1], settings)) for p in range(len(sig)-1)]) + ';'
914
def make_func(name, code):
915
return 'function %s(%s) { %s %s }' % (name, params, coercions, code)
916
Counter.pre = [make_func(bad, ('abort' if not settings['ASSERTIONS'] else 'nullFunc') + '(' + str(i) + ');' + (
917
'' if sig[0] == 'v' else ('return %s' % shared.JS.make_initializer(sig[0], settings))
919
start = raw.index('[')
920
end = raw.rindex(']')
921
body = raw[start+1:end].split(',')
922
for j in range(settings['RESERVED_FUNCTION_POINTERS']):
923
body[settings['FUNCTION_POINTER_ALIGNMENT'] * (1 + j)] = 'jsCall_%s_%s' % (sig, j)
927
newline = Counter.j % 30 == 29
928
if item == '0': return bad if not newline else (bad + '\n')
929
if item not in implemented_functions:
930
# this is imported into asm, we must wrap it
932
if call_ident in metadata['redirects']: call_ident = metadata['redirects'][call_ident]
933
if not call_ident.startswith('_') and not call_ident.startswith('Math_'): call_ident = '_' + call_ident
934
code = call_ident + '(' + coerced_params + ')'
936
code = 'return ' + shared.JS.make_coercion(code, sig[0], settings)
938
Counter.pre.append(make_func(item + '__wrapper', code))
939
return item + '__wrapper'
940
return item if not newline else (item + '\n')
941
body = ','.join(map(fix_item, body))
942
return ('\n'.join(Counter.pre), ''.join([raw[:start+1], body, raw[end:]]))
944
infos = [make_table(sig, raw) for sig, raw in last_forwarded_json['Functions']['tables'].iteritems()]
947
function_tables_defs = '\n'.join([info[0] for info in infos]) + '\n// EMSCRIPTEN_END_FUNCS\n' + '\n'.join([info[1] for info in infos])
950
maths = ['Math.' + func for func in ['floor', 'abs', 'sqrt', 'pow', 'cos', 'sin', 'tan', 'acos', 'asin', 'atan', 'atan2', 'exp', 'log', 'ceil', 'imul']]
951
fundamentals = ['Math', 'Int8Array', 'Int16Array', 'Int32Array', 'Uint8Array', 'Uint16Array', 'Uint32Array', 'Float32Array', 'Float64Array']
952
math_envs = ['Math.min'] # TODO: move min to maths
953
asm_setup += '\n'.join(['var %s = %s;' % (f.replace('.', '_'), f) for f in math_envs])
955
if settings['PRECISE_F32']: maths += ['Math.fround']
957
basic_funcs = ['abort', 'assert', 'asmPrintInt', 'asmPrintFloat'] + [m.replace('.', '_') for m in math_envs]
958
if settings['RESERVED_FUNCTION_POINTERS'] > 0: basic_funcs.append('jsCall')
959
if settings['SAFE_HEAP']: basic_funcs += ['SAFE_HEAP_LOAD', 'SAFE_HEAP_STORE', 'SAFE_HEAP_CLEAR']
960
if settings['CHECK_HEAP_ALIGN']: basic_funcs += ['CHECK_ALIGN_2', 'CHECK_ALIGN_4', 'CHECK_ALIGN_8']
961
if settings['ASSERTIONS']:
962
basic_funcs += ['nullFunc']
963
asm_setup += 'function nullFunc(x) { Module["printErr"]("Invalid function pointer called. Perhaps a miscast function pointer (check compilation warnings) or bad vtable lookup (maybe due to derefing a bad pointer, like NULL)?"); abort(x) }\n'
965
basic_vars = ['STACKTOP', 'STACK_MAX', 'tempDoublePtr', 'ABORT']
966
basic_float_vars = ['NaN', 'Infinity']
968
if metadata.get('preciseI64MathUsed') or \
969
forwarded_json['Functions']['libraryFunctions'].get('llvm_cttz_i32') or \
970
forwarded_json['Functions']['libraryFunctions'].get('llvm_ctlz_i32'):
971
basic_vars += ['cttz_i8', 'ctlz_i8']
973
if settings.get('DLOPEN_SUPPORT'):
974
for sig in last_forwarded_json['Functions']['tables'].iterkeys():
975
basic_vars.append('F_BASE_%s' % sig)
976
asm_setup += ' var F_BASE_%s = %s;\n' % (sig, 'FUNCTION_TABLE_OFFSET' if settings.get('SIDE_MODULE') else '0') + '\n'
978
asm_runtime_funcs = ['stackAlloc', 'stackSave', 'stackRestore', 'setThrew'] + ['setTempRet%d' % i for i in range(10)]
980
function_tables = ['dynCall_' + table for table in last_forwarded_json['Functions']['tables']]
981
function_tables_impls = []
983
for sig in last_forwarded_json['Functions']['tables'].iterkeys():
984
args = ','.join(['a' + str(i) for i in range(1, len(sig))])
985
arg_coercions = ' '.join(['a' + str(i) + '=' + shared.JS.make_coercion('a' + str(i), sig[i], settings) + ';' for i in range(1, len(sig))])
986
coerced_args = ','.join([shared.JS.make_coercion('a' + str(i), sig[i], settings) for i in range(1, len(sig))])
987
ret = ('return ' if sig[0] != 'v' else '') + shared.JS.make_coercion('FUNCTION_TABLE_%s[index&{{{ FTM_%s }}}](%s)' % (sig, sig, coerced_args), sig[0], settings)
988
function_tables_impls.append('''
989
function dynCall_%s(index%s%s) {
994
''' % (sig, ',' if len(sig) > 1 else '', args, arg_coercions, ret))
996
for i in range(settings['RESERVED_FUNCTION_POINTERS']):
997
jsret = ('return ' if sig[0] != 'v' else '') + shared.JS.make_coercion('jsCall(%d%s%s)' % (i, ',' if coerced_args else '', coerced_args), sig[0], settings)
998
function_tables_impls.append('''
999
function jsCall_%s_%s(%s) {
1004
''' % (sig, i, args, arg_coercions, jsret))
1005
shared.Settings.copy(settings)
1006
asm_setup += '\n' + shared.JS.make_invoke(sig) + '\n'
1007
basic_funcs.append('invoke_%s' % sig)
1008
if settings.get('DLOPEN_SUPPORT'):
1009
asm_setup += '\n' + shared.JS.make_extcall(sig) + '\n'
1010
basic_funcs.append('extCall_%s' % sig)
1013
exported_implemented_functions = list(exported_implemented_functions) + metadata['initializers']
1014
exported_implemented_functions.append('runPostSets')
1017
for export in exported_implemented_functions + asm_runtime_funcs + function_tables:
1018
exports.append("%s: %s" % (export, export))
1019
exports = '{ ' + ', '.join(exports) + ' }'
1024
del forwarded_json['Variables']['globals']['_llvm_global_ctors'] # not a true variable
1027
# If no named globals, only need externals
1028
global_vars = metadata['externs'] #+ forwarded_json['Variables']['globals']
1029
global_funcs = list(set(['_' + key for key, value in forwarded_json['Functions']['libraryFunctions'].iteritems() if value != 2]).difference(set(global_vars)).difference(implemented_functions))
1031
return g if not g.startswith('Math_') else g.split('_')[1]
1032
asm_global_funcs = ''.join([' var ' + g.replace('.', '_') + '=global.' + g + ';\n' for g in maths]) + \
1033
''.join([' var ' + g + '=env.' + math_fix(g) + ';\n' for g in basic_funcs + global_funcs])
1034
asm_global_vars = ''.join([' var ' + g + '=env.' + g + '|0;\n' for g in basic_vars + global_vars])
1035
# In linkable modules, we need to add some explicit globals for global variables that can be linked and used across modules
1036
if settings.get('MAIN_MODULE') or settings.get('SIDE_MODULE'):
1037
assert settings.get('TARGET_LE32'), 'TODO: support x86 target when linking modules (needs offset of 4 and not 8 here)'
1038
for key, value in forwarded_json['Variables']['globals'].iteritems():
1039
if value.get('linkable'):
1040
init = forwarded_json['Variables']['indexedGlobals'][key] + 8 # 8 is Runtime.GLOBAL_BASE / STATIC_BASE
1041
if settings.get('SIDE_MODULE'): init = '(H_BASE+' + str(init) + ')|0'
1042
asm_global_vars += ' var %s=%s;\n' % (key, str(init))
1045
the_global = '{ ' + ', '.join(['"' + math_fix(s) + '": ' + s for s in fundamentals]) + ' }'
1046
sending = '{ ' + ', '.join(['"' + math_fix(s) + '": ' + s for s in basic_funcs + global_funcs + basic_vars + basic_float_vars + global_vars]) + ' }'
1049
receiving = ';\n'.join(['var ' + s + ' = Module["' + s + '"] = asm["' + s + '"]' for s in exported_implemented_functions + function_tables])
1051
receiving = 'var _main = Module["_main"] = asm;'
1055
if DEBUG: logging.debug('asm text sizes' + str([map(len, funcs_js), len(asm_setup), len(asm_global_vars), len(asm_global_funcs), len(pre_tables), len('\n'.join(function_tables_impls)), len(function_tables_defs.replace('\n', '\n ')), len(exports), len(the_global), len(sending), len(receiving)]))
1059
function asmPrintInt(x, y) {
1060
Module.print('int ' + x + ',' + y);// + ' ' + new Error().stack);
1062
function asmPrintFloat(x, y) {
1063
Module.print('float ' + x + ',' + y);// + ' ' + new Error().stack);
1065
// EMSCRIPTEN_START_ASM
1066
var asm = (function(global, env, buffer) {
1068
var HEAP8 = new global.Int8Array(buffer);
1069
var HEAP16 = new global.Int16Array(buffer);
1070
var HEAP32 = new global.Int32Array(buffer);
1071
var HEAPU8 = new global.Uint8Array(buffer);
1072
var HEAPU16 = new global.Uint16Array(buffer);
1073
var HEAPU32 = new global.Uint32Array(buffer);
1074
var HEAPF32 = new global.Float32Array(buffer);
1075
var HEAPF64 = new global.Float64Array(buffer);
1076
''' % (asm_setup, "'use asm';" if not metadata.get('hasInlineJS') and not settings['SIDE_MODULE'] and settings['ASM_JS'] == 1 else "'almost asm';") + '\n' + asm_global_vars + '''
1081
var nan = +env.NaN, inf = +env.Infinity;
1082
var tempInt = 0, tempBigInt = 0, tempBigIntP = 0, tempBigIntS = 0, tempBigIntR = 0.0, tempBigIntI = 0, tempBigIntD = 0, tempValue = 0, tempDouble = 0.0;
1084
var tempRet%d = 0;''' % i for i in range(10)]) + '\n' + asm_global_funcs] + [' var tempFloat = %s;\n' % ('Math_fround(0)' if settings.get('PRECISE_F32') else '0.0')] + ['''
1085
// EMSCRIPTEN_START_FUNCS
1086
function stackAlloc(size) {
1090
STACKTOP = (STACKTOP + size)|0;
1091
''' + ('STACKTOP = (STACKTOP + 3)&-4;' if settings['TARGET_X86'] else 'STACKTOP = (STACKTOP + 7)&-8;') + '''
1094
function stackSave() {
1097
function stackRestore(top) {
1101
function setThrew(threw, value) {
1104
if ((__THREW__|0) == 0) {
1109
function copyTempFloat(ptr) {
1111
HEAP8[tempDoublePtr] = HEAP8[ptr];
1112
HEAP8[tempDoublePtr+1|0] = HEAP8[ptr+1|0];
1113
HEAP8[tempDoublePtr+2|0] = HEAP8[ptr+2|0];
1114
HEAP8[tempDoublePtr+3|0] = HEAP8[ptr+3|0];
1116
function copyTempDouble(ptr) {
1118
HEAP8[tempDoublePtr] = HEAP8[ptr];
1119
HEAP8[tempDoublePtr+1|0] = HEAP8[ptr+1|0];
1120
HEAP8[tempDoublePtr+2|0] = HEAP8[ptr+2|0];
1121
HEAP8[tempDoublePtr+3|0] = HEAP8[ptr+3|0];
1122
HEAP8[tempDoublePtr+4|0] = HEAP8[ptr+4|0];
1123
HEAP8[tempDoublePtr+5|0] = HEAP8[ptr+5|0];
1124
HEAP8[tempDoublePtr+6|0] = HEAP8[ptr+6|0];
1125
HEAP8[tempDoublePtr+7|0] = HEAP8[ptr+7|0];
1128
function setTempRet%d(value) {
1132
''' % (i, i) for i in range(10)])] + funcs_js + ['''
1137
// EMSCRIPTEN_END_ASM
1140
''' % (pre_tables + '\n'.join(function_tables_impls) + '\n' + function_tables_defs.replace('\n', '\n '), exports, the_global, sending, receiving)]
1142
if not settings.get('SIDE_MODULE'):
1144
Runtime.stackAlloc = function(size) { return asm['stackAlloc'](size) };
1145
Runtime.stackSave = function() { return asm['stackSave']() };
1146
Runtime.stackRestore = function(top) { asm['stackRestore'](top) };
1149
# Set function table masks
1152
for sig, table in last_forwarded_json['Functions']['tables'].iteritems():
1153
mask = table.count(',')
1154
masks[sig] = str(mask)
1155
max_mask = max(mask, max_mask)
1156
def function_table_maskize(js, masks):
1158
sig = m.groups(0)[0]
1160
return re.sub(r'{{{ FTM_([\w\d_$]+) }}}', lambda m: fix(m), js) # masks[m.groups(0)[0]]
1161
funcs_js = map(lambda js: function_table_maskize(js, masks), funcs_js)
1163
if settings.get('DLOPEN_SUPPORT'):
1165
asm.maxFunctionIndex = %(max_mask)d;
1166
DLFCN.registerFunctions(asm, %(max_mask)d+1, %(sigs)s, Module);
1167
Module.SYMBOL_TABLE = SYMBOL_TABLE;
1168
''' % { 'max_mask': max_mask, 'sigs': str(map(str, last_forwarded_json['Functions']['tables'].keys())) })
1171
function_tables_defs = '\n'.join([table for table in last_forwarded_json['Functions']['tables'].itervalues()])
1172
outfile.write(function_tables_defs)
1174
// EMSCRIPTEN_START_FUNCS
1175
'''] + funcs_js + ['''
1176
// EMSCRIPTEN_END_FUNCS
1179
# Create symbol table for self-dlopen
1180
if settings.get('DLOPEN_SUPPORT'):
1182
for k, v in forwarded_json['Variables']['indexedGlobals'].iteritems():
1183
if forwarded_json['Variables']['globals'][k]['named']:
1184
symbol_table[k] = str(v + forwarded_json['Runtime']['GLOBAL_BASE'])
1185
for raw in last_forwarded_json['Functions']['tables'].itervalues():
1186
if raw == '': continue
1187
table = map(string.strip, raw[raw.find('[')+1:raw.find(']')].split(","))
1188
for i in range(len(table)):
1191
if settings.get('SIDE_MODULE'):
1192
symbol_table[value] = 'FUNCTION_TABLE_OFFSET+' + str(i)
1194
symbol_table[value] = str(i)
1195
outfile.write("var SYMBOL_TABLE = %s;" % json.dumps(symbol_table).replace('"', ''))
1197
for i in range(len(funcs_js)): # do this loop carefully to save memory
1198
outfile.write(funcs_js[i])
1205
if DEBUG: logging.debug(' emscript: final python processing took %s seconds' % (time.time() - t))
1207
if os.environ.get('EMCC_FAST_COMPILER'):
1208
emscript = emscript_fast
694
1210
def main(args, compiler_engine, cache, jcache, relooper, temp_files, DEBUG, DEBUG_CACHE):
695
1211
# Prepare settings for serialization to JSON.