Skip to content

Commit 81e657c

Browse files
committed
Merge remote-tracking branch 'origin/incoming' into strMemInit
2 parents 9d3c8d5 + ba249f5 commit 81e657c

15 files changed

+307
-58
lines changed

emcc

+2-1
Original file line numberDiff line numberDiff line change
@@ -893,7 +893,6 @@ try:
893893
assert shared.Settings.PGO == 0, 'pgo not supported in fastcomp'
894894
assert shared.Settings.USE_TYPED_ARRAYS == 2, 'altering USE_TYPED_ARRAYS is not supported'
895895
assert shared.Settings.QUANTUM_SIZE == 4, 'altering the QUANTUM_SIZE is not supported'
896-
assert shared.Settings.INIT_HEAP == 0, 'HEAP_INIT is not supported in fastcomp (and should never be needed except for debugging)'
897896
except Exception, e:
898897
logging.error('Compiler settings are incompatible with fastcomp. You can fall back to the older compiler core, although that is not recommended, see http://kripken.github.io/emscripten-site/docs/building_from_source/LLVM-Backend.html')
899898
raise e
@@ -1284,6 +1283,8 @@ try:
12841283
file_args.append('--use-preload-cache')
12851284
if no_heap_copy:
12861285
file_args.append('--no-heap-copy')
1286+
if not closure:
1287+
file_args.append('--no-closure')
12871288
file_code = execute([shared.PYTHON, shared.FILE_PACKAGER, unsuffixed(target) + '.data'] + file_args, stdout=PIPE)[0]
12881289
pre_js = file_code + pre_js
12891290

emscripten.py

+16-7
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,8 @@ def fix_dot_zero(m):
165165
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
166166

167167
# Integrate info from backend
168+
if settings['SIDE_MODULE']:
169+
settings['DEFAULT_LIBRARY_FUNCS_TO_INCLUDE'] = [] # we don't need any JS library contents in side modules
168170
settings['DEFAULT_LIBRARY_FUNCS_TO_INCLUDE'] = list(
169171
set(settings['DEFAULT_LIBRARY_FUNCS_TO_INCLUDE'] + map(shared.JS.to_nice_ident, metadata['declares'])).difference(
170172
map(lambda x: x[1:], metadata['implementedFunctions'])
@@ -306,7 +308,7 @@ def move_preasm(m):
306308
contents = m.groups(0)[0]
307309
outfile.write(contents + '\n')
308310
return ''
309-
if not settings['BOOTSTRAPPING_STRUCT_INFO']:
311+
if not settings['BOOTSTRAPPING_STRUCT_INFO'] and not settings['SIDE_MODULE']:
310312
funcs_js[1] = re.sub(r'/\* PRE_ASM \*/(.*)\n', lambda m: move_preasm(m), funcs_js[1])
311313

312314
class Counter:
@@ -579,13 +581,16 @@ def keyfunc(other):
579581
if settings.get('EMULATED_FUNCTION_POINTERS'):
580582
args = ['a%d' % i for i in range(len(sig)-1)]
581583
full_args = ['x'] + args
584+
table_access = 'FUNCTION_TABLE_' + sig
585+
if settings['SIDE_MODULE']:
586+
table_access = 'parentModule["' + table_access + '"]' # side module tables were merged into the parent, we need to access the global one
582587
prelude = '''
583-
if (x < 0 || x >= FUNCTION_TABLE_%s.length) { Module.printErr("Function table mask error (out of range)"); %s ; abort(x) }''' % (sig, get_function_pointer_error(sig))
588+
if (x < 0 || x >= %s.length) { Module.printErr("Function table mask error (out of range)"); %s ; abort(x) }''' % (table_access, get_function_pointer_error(sig))
584589
asm_setup += '''
585590
function ftCall_%s(%s) {%s
586-
return FUNCTION_TABLE_%s[x](%s);
591+
return %s[x](%s);
587592
}
588-
''' % (sig, ', '.join(full_args), prelude, sig, ', '.join(args))
593+
''' % (sig, ', '.join(full_args), prelude, table_access, ', '.join(args))
589594
basic_funcs.append('ftCall_%s' % sig)
590595

591596
def quote(prop):
@@ -675,10 +680,14 @@ def math_fix(g):
675680

676681
if settings['RELOCATABLE']:
677682
receiving += '''
678-
var NAMED_GLOBALS = %s;
679-
for (var named in NAMED_GLOBALS) NAMED_GLOBALS[named] += gb;
683+
var NAMED_GLOBALS = { %s };
684+
for (var named in NAMED_GLOBALS) {
685+
Module['_' + named] = gb + NAMED_GLOBALS[named];
686+
}
680687
Module['NAMED_GLOBALS'] = NAMED_GLOBALS;
681-
''' % json.dumps(metadata['namedGlobals'])
688+
''' % ', '.join('"' + k + '": ' + str(v) for k, v in metadata['namedGlobals'].iteritems())
689+
690+
receiving += ''.join(["Module['%s'] = Module['%s']\n" % (k, v) for k, v in metadata['aliases'].iteritems()])
682691

683692
funcs_js = ['''
684693
%s

src/jsifier.js

+12-5
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ function JSify(data, functionsOnly) {
6262
var libFuncsToInclude;
6363
if (INCLUDE_FULL_LIBRARY) {
6464
assert(!(BUILD_AS_SHARED_LIB || SIDE_MODULE), 'Cannot have both INCLUDE_FULL_LIBRARY and BUILD_AS_SHARED_LIB/SIDE_MODULE set.')
65-
libFuncsToInclude = MAIN_MODULE ? DEFAULT_LIBRARY_FUNCS_TO_INCLUDE.slice(0) : [];
65+
libFuncsToInclude = (MAIN_MODULE || SIDE_MODULE) ? DEFAULT_LIBRARY_FUNCS_TO_INCLUDE.slice(0) : [];
6666
for (var key in LibraryManager.library) {
6767
if (!key.match(/__(deps|postset|inline|asm|sig)$/)) {
6868
libFuncsToInclude.push(key);
@@ -123,7 +123,9 @@ function JSify(data, functionsOnly) {
123123
// Note: We don't return the dependencies here. Be careful not to end up where this matters
124124
if (finalName in Functions.implementedFunctions) return '';
125125

126-
if (!LibraryManager.library.hasOwnProperty(ident) && !LibraryManager.library.hasOwnProperty(ident + '__inline')) {
126+
var noExport = false;
127+
128+
if ((!LibraryManager.library.hasOwnProperty(ident) && !LibraryManager.library.hasOwnProperty(ident + '__inline')) || SIDE_MODULE) {
127129
if (notDep) {
128130
if (VERBOSE || ident.substr(0, 11) !== 'emscripten_') { // avoid warning on emscripten_* functions which are for internal usage anyhow
129131
if (ERROR_ON_UNDEFINED_SYMBOLS) error('unresolved symbol: ' + ident);
@@ -134,7 +136,13 @@ function JSify(data, functionsOnly) {
134136
// emit a stub that will fail at runtime
135137
LibraryManager.library[shortident] = new Function("Module['printErr']('missing function: " + shortident + "'); abort(-1);");
136138
} else {
137-
LibraryManager.library[shortident] = function() { return Module['_' + shortident].apply(null, arguments); };
139+
LibraryManager.library[shortident] = new Function("return " + (MAIN_MODULE ? '' : 'parent') + "Module['_" + shortident + "'].apply(null, arguments);");
140+
if (SIDE_MODULE) {
141+
// no dependencies, just emit the thunk
142+
Functions.libraryFunctions[finalName] = 1;
143+
return processLibraryFunction(LibraryManager.library[shortident], ident, finalName);
144+
}
145+
noExport = true;
138146
}
139147
}
140148

@@ -203,8 +211,7 @@ function JSify(data, functionsOnly) {
203211
EXPORTED_FUNCTIONS[finalName] = 1;
204212
Functions.libraryFunctions[finalName] = 2;
205213
}
206-
if (SIDE_MODULE) return ';'; // we import into the side module js library stuff from the outside parent
207-
if (EXPORT_ALL || (finalName in EXPORTED_FUNCTIONS)) {
214+
if ((EXPORT_ALL || (finalName in EXPORTED_FUNCTIONS)) && !noExport) {
208215
contentText += '\nModule["' + finalName + '"] = ' + finalName + ';';
209216
}
210217
return depsText + contentText;

src/library.js

-5
Original file line numberDiff line numberDiff line change
@@ -4054,7 +4054,6 @@ LibraryManager.library = {
40544054
if (filename === '__self__') {
40554055
var handle = -1;
40564056
var lib_module = Module;
4057-
Module.NAMED_GLOBALS = NAMED_GLOBALS;
40584057
var cached_functions = {};
40594058
} else {
40604059
var target = FS.findObject(filename);
@@ -4138,10 +4137,6 @@ LibraryManager.library = {
41384137
return 0;
41394138
} else {
41404139
var lib = DLFCN.loadedLibs[handle];
4141-
if (lib.module.NAMED_GLOBALS.hasOwnProperty(symbol)) {
4142-
return lib.module.NAMED_GLOBALS[symbol];
4143-
}
4144-
// not a global var, must be a function
41454140
symbol = '_' + symbol;
41464141
if (lib.cached_functions.hasOwnProperty(symbol)) {
41474142
return lib.cached_functions[symbol];

src/postamble_sharedlib.js

+6-8
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,12 @@
33

44
{{GLOBAL_VARS}}
55

6-
function run(args) {
6+
runPostSets();
7+
8+
if (runtimeInitialized) {
79
initRuntime();
10+
Module['initLibraryRuntime'] = function(){};
11+
} else {
12+
Module['initLibraryRuntime'] = initRuntime; // rely on the system to call it later, at the right time
813
}
9-
Module['run'] = run;
10-
11-
// {{PRE_RUN_ADDITIONS}}
12-
13-
run();
14-
15-
// {{POST_RUN_ADDITIONS}}
1614

src/preamble.js

+16
Original file line numberDiff line numberDiff line change
@@ -1190,6 +1190,12 @@ function ensureInitRuntime() {
11901190
if (runtimeInitialized) return;
11911191
runtimeInitialized = true;
11921192
callRuntimeCallbacks(__ATINIT__);
1193+
1194+
#if RELOCATABLE
1195+
Runtime.loadedDynamicLibraries.forEach(function(lib) {
1196+
lib['initLibraryRuntime']();
1197+
});
1198+
#endif
11931199
}
11941200

11951201
function preMain() {
@@ -1449,6 +1455,16 @@ __ATEXIT__.push({ func: function() { PGOMonitor.dump() } });
14491455
addOnPreRun(function() { addRunDependency('pgo') });
14501456
#endif
14511457

1458+
#if RELOCATABLE
1459+
if (Module['dynamicLibraries']) {
1460+
Module['dynamicLibraries'].forEach(function(lib) {
1461+
addOnPreRun(function() {
1462+
Runtime.loadDynamicLibrary(lib);
1463+
});
1464+
});
1465+
}
1466+
#endif
1467+
14521468
#if MEM_INIT_METHOD == 1
14531469
var memoryInitializer = null;
14541470
#else

src/runtime.js

+32-7
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,9 @@
77
// itself is as optimized as possible - no unneeded runtime checks).
88

99
var RuntimeGenerator = {
10-
alloc: function(size, type, init, sep, ignoreAlign) {
10+
alloc: function(size, type, sep, ignoreAlign) {
1111
sep = sep || ';';
1212
var ret = type + 'TOP';
13-
if (init) {
14-
ret += sep + '_memset(' + type + 'TOP, 0, ' + size + ')';
15-
}
1613
ret += sep + type + 'TOP = (' + type + 'TOP + ' + size + ')|0';
1714
if ({{{ STACK_ALIGN }}} > 1 && !ignoreAlign) {
1815
ret += sep + RuntimeGenerator.alignMemory(type + 'TOP', {{{ STACK_ALIGN }}});
@@ -23,7 +20,7 @@ var RuntimeGenerator = {
2320
// An allocation that lives as long as the current function call
2421
stackAlloc: function(size, sep) {
2522
sep = sep || ';';
26-
var ret = RuntimeGenerator.alloc(size, 'STACK', false, sep, (isNumber(size) && parseInt(size) % {{{ STACK_ALIGN }}} == 0));
23+
var ret = RuntimeGenerator.alloc(size, 'STACK', sep, (isNumber(size) && parseInt(size) % {{{ STACK_ALIGN }}} == 0));
2724
if (ASSERTIONS) {
2825
ret += sep + '(assert(' + asmCoercion('(STACKTOP|0) < (STACK_MAX|0)', 'i32') + ')|0)';
2926
}
@@ -53,14 +50,14 @@ var RuntimeGenerator = {
5350
// called, takes control of STATICTOP)
5451
staticAlloc: function(size) {
5552
if (ASSERTIONS) size = '(assert(!staticSealed),' + size + ')'; // static area must not be sealed
56-
var ret = RuntimeGenerator.alloc(size, 'STATIC', INIT_HEAP);
53+
var ret = RuntimeGenerator.alloc(size, 'STATIC');
5754
return ret;
5855
},
5956

6057
// allocation on the top of memory, adjusted dynamically by sbrk
6158
dynamicAlloc: function(size) {
6259
if (ASSERTIONS) size = '(assert(DYNAMICTOP > 0),' + size + ')'; // dynamic area must be ready
63-
var ret = RuntimeGenerator.alloc(size, 'DYNAMIC', INIT_HEAP);
60+
var ret = RuntimeGenerator.alloc(size, 'DYNAMIC');
6461
ret += '; if (DYNAMICTOP >= TOTAL_MEMORY) { var success = enlargeMemory(); if (!success) { DYNAMICTOP = ret; return 0; } }'
6562
return ret;
6663
},
@@ -283,8 +280,36 @@ var Runtime = {
283280
},
284281

285282
removeFunction: function(index) {
283+
#if EMULATED_FUNCTION_POINTERS == 0
286284
Runtime.functionPointers[(index-{{{ FUNCTION_POINTER_ALIGNMENT }}})/{{{ FUNCTION_POINTER_ALIGNMENT }}}] = null;
285+
#else
286+
Runtime.alignFunctionTables(); // XXX we should rely on this being an invariant
287+
var tables = Runtime.getFunctionTables();
288+
for (var sig in tables) {
289+
tables[sig][index] = null;
290+
}
291+
#endif
292+
},
293+
294+
#if RELOCATABLE
295+
loadedDynamicLibraries: [],
296+
297+
loadDynamicLibrary: function(lib) {
298+
// TODO: addRunDep etc., do asynchronously when in the browser. for now we assume we can do a sync xhr, no mem init files in libs, and we ignore the sync xhr lag
299+
var src = Module['read'](lib);
300+
var libModule = eval(src)(
301+
Runtime.alignFunctionTables(),
302+
Module
303+
);
304+
// add symbols into global namespace TODO: weak linking etc.
305+
for (var sym in libModule) {
306+
if (!Module.hasOwnProperty(sym)) {
307+
Module[sym] = libModule[sym];
308+
}
309+
}
310+
Runtime.loadedDynamicLibraries.push(libModule);
287311
},
312+
#endif
288313

289314
warnOnce: function(text) {
290315
if (!Runtime.warnOnce.shown) Runtime.warnOnce.shown = {};

src/settings.js

-10
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ var INVOKE_RUN = 1; // Whether we will run the main() function. Disable if you e
3535
// can do with Module.callMain(), with an optional parameter of commandline args).
3636
var NO_EXIT_RUNTIME = 0; // If set, the runtime is not quit when main() completes (allowing code to
3737
// run afterwards, for example from the browser main event loop).
38-
var INIT_HEAP = 0; // Whether to initialize memory anywhere other than the stack to 0.
3938
var MEM_INIT_METHOD = 2; // Set using the --memory-init-file command line switch.
4039
// 0: keep array literal representing the initial memory data
4140
// 1: create a *.mem file containing the binary data of the initial memory
@@ -60,7 +59,6 @@ var GLOBAL_BASE = -1; // where global data begins; the start of static memory. -
6059
// default, any other value will be used as an override
6160

6261
// Code embetterments
63-
var MICRO_OPTS = 1; // Various micro-optimizations, like nativizing variables
6462
var USE_TYPED_ARRAYS = 2; // Use typed arrays for the heap. See https://github.com/kripken/emscripten/wiki/Code-Generation-Modes/
6563
// 2 is a single heap, accessible through views as int8, int32, etc. This is
6664
// the only supported mode.
@@ -121,8 +119,6 @@ var SIMD = 0; // Whether to allow autovectorized SIMD code ( https://github.com/
121119
// any SIMD output at all.)
122120

123121
var CLOSURE_COMPILER = 0; // Whether closure compiling is being run on this output
124-
var CLOSURE_ANNOTATIONS = 0; // If set, the generated code will be annotated for the closure
125-
// compiler. This potentially lets closure optimize the code better.
126122

127123
var SKIP_STACK_IN_SMALL = 1; // When enabled, does not push/pop the stack at all in
128124
// functions that have no basic stack usage. But, they
@@ -131,7 +127,6 @@ var SKIP_STACK_IN_SMALL = 1; // When enabled, does not push/pop the stack at all
131127
// a lot can exhaust the stack very fast, with this option.
132128
// In particular, be careful with the autodebugger! (We do turn
133129
// this off automatically in that case, though.)
134-
var INLINE_LIBRARY_FUNCS = 1; // Will inline library functions that have __inline defined
135130
var INLINING_LIMIT = 0; // A limit on inlining. If 0, we will inline normally in LLVM and
136131
// closure. If greater than 0, we will *not* inline in LLVM, and
137132
// we will prevent inlining of functions of this size or larger
@@ -353,8 +348,6 @@ var INCLUDE_FULL_LIBRARY = 0; // Whether to include the whole library rather tha
353348

354349
var SHELL_FILE = 0; // set this to a string to override the shell file used
355350

356-
var SHOW_LABELS = 0; // Show labels in the generated code
357-
358351
var RELOCATABLE = 0; // If set to 1, we emit relocatable code from the LLVM backend; both
359352
// globals and function pointers are all offset (by gb and fp, respectively)
360353

@@ -507,9 +500,6 @@ var EMTERPRETIFY_ADVISE = 0; // Performs a static analysis to suggest which func
507500
var RUNNING_JS_OPTS = 0; // whether js opts will be run, after the main compiler
508501
var BOOTSTRAPPING_STRUCT_INFO = 0; // whether we are in the generate struct_info bootstrap phase
509502

510-
var COMPILER_ASSERTIONS = 0; // costly (slow) compile-time assertions
511-
var COMPILER_FASTPATHS = 1; // use fast-paths to speed up compilation
512-
513503
var EMSCRIPTEN_TRACING = 0; // Add some calls to emscripten tracing APIs
514504

515505
var USE_GLFW = 2; // Specify the GLFW version that is being linked against.

tests/cases/longjmp_tiny_keepem_cond.ll

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ target triple = "asmjs-unknown-emscripten"
66
@.str1 = private unnamed_addr constant [6 x i8] c"more\0A\00", align 1
77

88
define i32 @main() {
9+
%wimpy = trunc i32 100 to i8
910
%call0 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([6 x i8]* @.str1, i32 0, i32 0))
1011
%chak = icmp ne i32 %call0, 12345678
1112
br i1 %chak, label %middle, label %if.then
1213

1314
middle:
1415
%retval = alloca i32, align 4
1516
store i32 0, i32* %retval
16-
%wimpy = trunc i32 100 to i8
1717
%buffy = inttoptr i8 %wimpy to i16*
1818
%call = call i32 @setjmp(i16* %buffy) returns_twice ; 20
1919
%tobool = icmp ne i32 %call, 0 ; 20

tests/cases/phiself.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1 @@
1-
if Settings.MICRO_OPTS:
2-
assert '$phi' not in generated, 'we should optimize out self-phis'
3-
1+
assert '$phi' not in generated, 'we should optimize out self-phis'

tests/runner.py

+16-8
Original file line numberDiff line numberDiff line change
@@ -108,16 +108,16 @@ def hardcode_arguments(self, filename, args):
108108
open(filename, 'w').write(js.replace('run();', 'run(%s + Module["arguments"]);' % str(args)))
109109

110110
def prep_ll_run(self, filename, ll_file, force_recompile=False, build_ll_hook=None):
111-
if ll_file.endswith(('.bc', '.o')):
112-
if ll_file != filename + '.o':
113-
shutil.copy(ll_file, filename + '.o')
114-
Building.llvm_dis(filename)
115-
else:
116-
shutil.copy(ll_file, filename + '.o.ll')
117-
118111
#force_recompile = force_recompile or os.stat(filename + '.o.ll').st_size > 50000 # if the file is big, recompile just to get ll_opts # Recompiling just for dfe in ll_opts is too costly
119112

120113
if Building.LLVM_OPTS or force_recompile or build_ll_hook:
114+
if ll_file.endswith(('.bc', '.o')):
115+
if ll_file != filename + '.o':
116+
shutil.copy(ll_file, filename + '.o')
117+
Building.llvm_dis(filename)
118+
else:
119+
shutil.copy(ll_file, filename + '.o.ll')
120+
121121
Building.ll_opts(filename)
122122
if build_ll_hook:
123123
need_post = build_ll_hook(filename)
@@ -132,6 +132,14 @@ def prep_ll_run(self, filename, ll_file, force_recompile=False, build_ll_hook=No
132132
shutil.move(filename + '.o.ll', filename + '.o.ll.post') # for comparisons later
133133
Building.llvm_dis(filename)
134134

135+
Building.llvm_as(filename)
136+
else:
137+
if ll_file.endswith('.ll'):
138+
safe_copy(ll_file, filename + '.o.ll')
139+
Building.llvm_as(filename)
140+
else:
141+
safe_copy(ll_file, filename + '.o')
142+
135143
# Generate JS from ll, and optionally modify the generated JS with a post_build function. Note
136144
# that post_build is called on unoptimized JS, so we send it to emcc (otherwise, if run after
137145
# emcc, it would not apply on the optimized/minified JS)
@@ -155,7 +163,7 @@ def ll_to_js(self, filename, extra_emscripten_args, post_build):
155163
transform.write('\nprocess(sys.argv[1])\n')
156164
transform.close()
157165
transform_args = ['--js-transform', "%s %s" % (PYTHON, transform_filename)]
158-
Building.emcc(filename + '.o.ll', Settings.serialize() + emcc_args + transform_args + Building.COMPILER_TEST_OPTS, filename + '.o.js')
166+
Building.emcc(filename + '.o', Settings.serialize() + emcc_args + transform_args + Building.COMPILER_TEST_OPTS, filename + '.o.js')
159167
if post2: post2(filename + '.o.js')
160168

161169
# Build JavaScript code from source code

0 commit comments

Comments
 (0)