diff options
author | Alon Zakai <alonzakai@gmail.com> | 2012-10-15 16:40:29 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2012-10-17 12:43:59 -0700 |
commit | eb466e688fb95efe4bdf32facb99c1b668e6cb4e (patch) | |
tree | 1d95d9f6c63971a92c567b3b1d80cdf25398a163 | |
parent | 844faf36ebb89698bb6db042f366ec851b89ddbe (diff) |
improve runtimelink handling of function aliases
-rw-r--r-- | src/jsifier.js | 12 | ||||
-rw-r--r-- | src/settings.js | 4 | ||||
-rwxr-xr-x | tests/runner.py | 64 |
3 files changed, 79 insertions, 1 deletions
diff --git a/src/jsifier.js b/src/jsifier.js index b76579cc..02459193 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -358,11 +358,21 @@ function JSify(data, functionsOnly, givenFunctions) { item.JS = 'var ' + item.ident + ';'; // Set the actual value in a postset, since it may be a global variable. We also order by dependencies there var value = Variables.globals[item.ident].resolvedAlias = finalizeLLVMParameter(item.value); + var fix = ''; + if (BUILD_AS_SHARED_LIB == 2 && !item.private_) { + var target = item.ident; + if (isFunctionType(item.type)) { + target = item.value.ident; // the other side does not know this is an alias/function table index. So make it the alias target. + var varData = Variables.globals[target]; + assert(!varData, 'multi-level aliasing does not work yet in shared lib 2 exports'); + } + fix = '\nif (globalScope) { assert(!globalScope["' + item.ident + '"]); globalScope["' + item.ident + '"] = ' + target + ' }' + } ret.push({ intertype: 'GlobalVariablePostSet', ident: item.ident, dependencies: set([value]), - JS: item.ident + ' = ' + value + ';' + JS: item.ident + ' = ' + value + ';' + fix }); return ret; } diff --git a/src/settings.js b/src/settings.js index 9e6f257a..0b58a26f 100644 --- a/src/settings.js +++ b/src/settings.js @@ -198,6 +198,10 @@ var INCLUDE_FULL_LIBRARY = 0; // Whether to include the whole library rather tha // functions used by the generated code. This is needed when // dynamically loading modules that make use of runtime // library functions that are not used in the main module. + // Note that this includes js libraries but *not* C. You will + // need the main file to include all needed C libraries. For + // example, if a library uses malloc or new, you will need + // to use those in the main file too to link in dlmalloc. var SHELL_FILE = 0; // set this to a string to override the shell file used diff --git a/tests/runner.py b/tests/runner.py index a8af375c..c61fee3a 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -7343,6 +7343,70 @@ f.close() Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp'), os.path.join(self.get_dir(), 'subdir', 'libfile.so'), '-L.']).communicate() self.assertContained('hello from lib', run_js(os.path.join(self.get_dir(), 'a.out.js'))) + def test_runtimelink_multi(self): + open('testa.h', 'w').write(r''' + #ifndef _TESTA_H_ + #define _TESTA_H_ + + class TestA { + public: + TestA(); + }; + + #endif + ''') + open('testb.h', 'w').write(r''' + #ifndef _TESTB_H_ + #define _TESTB_H_ + + class TestB { + public: + TestB(); + }; + + #endif + ''') + open('testa.cpp', 'w').write(r''' + #include <stdio.h> + #include <testa.h> + + TestA::TestA() { + printf("TestA\n"); + } + ''') + open('testb.cpp', 'w').write(r''' + #include <stdio.h> + #include <testb.h> + #include <testa.h> + /* + */ + TestB::TestB() { + printf("TestB\n"); + TestA* testa = new TestA(); + } + ''') + open('main.cpp', 'w').write(r''' + #include <stdio.h> + #include <testa.h> + #include <testb.h> + + /* + */ + int main(int argc, char** argv) { + printf("Main\n"); + TestA* testa = new TestA(); + TestB* testb = new TestB(); + } + ''') + + Popen(['python', EMCC, 'testa.cpp', '-o', 'liba.js', '-s', 'BUILD_AS_SHARED_LIB=2', '-s', 'LINKABLE=1', '-I.']).communicate() + Popen(['python', EMCC, 'testb.cpp', '-o', 'libb.js', '-s', 'BUILD_AS_SHARED_LIB=2', '-s', 'LINKABLE=1', '-I.']).communicate() + Popen(['python', EMCC, 'main.cpp', '-o', 'main.js', '-s', 'RUNTIME_LINKED_LIBS=["liba.js", "libb.js"]', '-I.']).communicate() + + Popen(['python', EMCC, 'main.cpp', 'testa.cpp', 'testb.cpp', '-o', 'full.js', '-I.']).communicate() + + self.assertContained('TestA\nTestB\nTestA\n', run_js('main.js', engine=SPIDERMONKEY_ENGINE)) + def test_js_libraries(self): open(os.path.join(self.get_dir(), 'main.cpp'), 'w').write(''' #include <stdio.h> |