aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2012-10-15 16:40:29 -0700
committerAlon Zakai <alonzakai@gmail.com>2012-10-17 12:43:59 -0700
commiteb466e688fb95efe4bdf32facb99c1b668e6cb4e (patch)
tree1d95d9f6c63971a92c567b3b1d80cdf25398a163
parent844faf36ebb89698bb6db042f366ec851b89ddbe (diff)
improve runtimelink handling of function aliases
-rw-r--r--src/jsifier.js12
-rw-r--r--src/settings.js4
-rwxr-xr-xtests/runner.py64
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>