Skip to content

Commit

Permalink
partial support for runtime linking of separately-compiled modules (o…
Browse files Browse the repository at this point in the history
…nly functions)
  • Loading branch information
kripken committed Dec 5, 2011
1 parent 60a4cbd commit d2f91ef
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 2 deletions.
15 changes: 15 additions & 0 deletions src/jsifier.js
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,10 @@ function JSify(data, functionsOnly, givenFunctions) {
if (item.ident in EXPORTED_GLOBALS) {
js += '\nModule["' + item.ident + '"] = ' + item.ident + ';';
}
// TODO: Support exporting BUILD_AS_SHARED_LIB == 2 globals. The problem now is that they override the main file's globals.
//if (BUILD_AS_SHARED_LIB == 2) {
// js += 'if (globalScope) globalScope["' + item.ident + '"] = ' + item.ident + ';'; // XXX: assert not overriding
//}
return ret.concat({
intertype: 'GlobalVariable',
JS: js,
Expand Down Expand Up @@ -603,6 +607,10 @@ function JSify(data, functionsOnly, givenFunctions) {
func.JS += func.ident + '["X"]=1;';
}

if (BUILD_AS_SHARED_LIB == 2) {
func.JS += 'if (globalScope) { assert(!globalScope["' + func.ident + '"]); globalScope["' + func.ident + '"] = ' + func.ident + ' }';
}

return func;
}
});
Expand Down Expand Up @@ -1116,7 +1124,14 @@ function JSify(data, functionsOnly, givenFunctions) {
data.unparsedGlobalss = null;

print(Functions.generateIndexing()); // done last, as it may rely on aliases set in postsets

// Load runtime-linked libraries
RUNTIME_LINKED_LIBS.forEach(function(lib) {
print('eval(read("' + lib + '"))(FUNCTION_TABLE.length, this);');
});

print(postParts[1]);

print(shellParts[1]);
// Print out some useful metadata (for additional optimizations later, like the eliminator)
print('// EMSCRIPTEN_GENERATED_FUNCTIONS: ' + JSON.stringify(Functions.allIdents) + '\n');
Expand Down
11 changes: 11 additions & 0 deletions src/settings.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/shell_sharedlib.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Capture the output of this into a variable, if you want
(function(FUNCTION_TABLE_OFFSET) {
(function(FUNCTION_TABLE_OFFSET, globalScope) {
var Module = {};
var args = [];
Module.arguments = [];
Expand Down
58 changes: 58 additions & 0 deletions tests/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -2168,6 +2168,63 @@ def test_nestedstructs(self):
# Bloated memory; same layout as C/C++
self.do_run(src, '*16,0,4,8,8,12|20,0,4,4,8,12,12,16|24,0,20,0,4,4,8,12,12,16*\n*0,0,0,1,2,64,68,69,72*\n*2*')

def test_runtimelink(self):
header = r'''
struct point
{
int x, y;
};
'''
open(os.path.join(self.get_dir(), 'header.h'), 'w').write(header)

supp = r'''
#include <stdio.h>
#include "header.h"
extern void mainFunc(int x);
extern int mainInt;
void suppFunc(struct point &p) {
printf("supp: %d,%d\n", p.x, p.y);
mainFunc(p.x+p.y);
printf("supp see: %d\n", mainInt);
}
//int suppInt = 76; // TODO: Support this. Right now, _str1 will override the main _str1
'''
supp_name = os.path.join(self.get_dir(), 'supp.c')
open(supp_name, 'w').write(supp)

main = r'''
#include <stdio.h>
#include "header.h"
extern void suppFunc(struct point &p);
extern int suppInt;
void mainFunc(int x) {
printf("main: %d\n", x);
}
int mainInt = 543;
int main( int argc, const char *argv[] ) {
struct point p = { 54, 2 };
suppFunc(p);
return 0;
}
'''

Settings.BUILD_AS_SHARED_LIB = 2
dirname = self.get_dir()
self.build(supp, dirname, supp_name)
shutil.move(supp_name + '.o.js', os.path.join(dirname, 'liblib.so'))
Settings.BUILD_AS_SHARED_LIB = 0

Settings.RUNTIME_LINKED_LIBS = ['liblib.so'];
self.do_run(main, 'supp: 54,2\nmain: 56\nsupp see: 543\n')

def test_dlfcn_basic(self):
lib_src = '''
#include <cstdio>
Expand Down Expand Up @@ -4647,6 +4704,7 @@ def setUp(self):
Settings.PROFILE = 0
Settings.INCLUDE_FULL_LIBRARY = 0
Settings.BUILD_AS_SHARED_LIB = 0
Settings.LIBS_TO_LOAD = []
Settings.CATCH_EXIT_CODE = 0
Settings.TOTAL_MEMORY = Settings.FAST_MEMORY = None
Settings.EMULATE_UNALIGNED_ACCESSES = Settings.USE_TYPED_ARRAYS == 2 and Building.LLVM_OPTS == 2
Expand Down
2 changes: 1 addition & 1 deletion tools/shared.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ def emscripten(filename, output_processor=None, append_ext=True, extra_args=[]):

# Run Emscripten
exported_settings = {}
for setting in ['QUANTUM_SIZE', 'RELOOP', 'MICRO_OPTS', 'ASSERTIONS', 'USE_TYPED_ARRAYS', 'SAFE_HEAP', 'CHECK_OVERFLOWS', 'CORRECT_OVERFLOWS', 'CORRECT_SIGNS', 'CHECK_SIGNS', 'CORRECT_OVERFLOWS_LINES', 'CORRECT_SIGNS_LINES', 'CORRECT_ROUNDINGS', 'CORRECT_ROUNDINGS_LINES', 'INVOKE_RUN', 'SAFE_HEAP_LINES', 'INIT_STACK', 'PGO', 'EXPORTED_FUNCTIONS', 'EXPORTED_GLOBALS', 'BUILD_AS_SHARED_LIB', 'INCLUDE_FULL_LIBRARY', 'RUNTIME_TYPE_INFO', 'DISABLE_EXCEPTION_CATCHING', 'TOTAL_MEMORY', 'FAST_MEMORY', 'EXCEPTION_DEBUG', 'PROFILE', 'I64_MODE', 'EMULATE_UNALIGNED_ACCESSES', 'CATCH_EXIT_CODE']:
for setting in ['QUANTUM_SIZE', 'RELOOP', 'MICRO_OPTS', 'ASSERTIONS', 'USE_TYPED_ARRAYS', 'SAFE_HEAP', 'CHECK_OVERFLOWS', 'CORRECT_OVERFLOWS', 'CORRECT_SIGNS', 'CHECK_SIGNS', 'CORRECT_OVERFLOWS_LINES', 'CORRECT_SIGNS_LINES', 'CORRECT_ROUNDINGS', 'CORRECT_ROUNDINGS_LINES', 'INVOKE_RUN', 'SAFE_HEAP_LINES', 'INIT_STACK', 'PGO', 'EXPORTED_FUNCTIONS', 'EXPORTED_GLOBALS', 'BUILD_AS_SHARED_LIB', 'RUNTIME_LINKED_LIBS', 'INCLUDE_FULL_LIBRARY', 'RUNTIME_TYPE_INFO', 'DISABLE_EXCEPTION_CATCHING', 'TOTAL_MEMORY', 'FAST_MEMORY', 'EXCEPTION_DEBUG', 'PROFILE', 'I64_MODE', 'EMULATE_UNALIGNED_ACCESSES', 'CATCH_EXIT_CODE']:
try:
value = eval('Settings.' + setting)
if value is not None:
Expand Down

0 comments on commit d2f91ef

Please sign in to comment.