diff options
-rw-r--r-- | src/jsifier.js | 26 | ||||
-rw-r--r-- | src/library.js | 15 | ||||
-rw-r--r-- | src/modules.js | 2 | ||||
-rw-r--r-- | src/parseTools.js | 2 | ||||
-rw-r--r-- | tests/runner.py | 16 |
5 files changed, 50 insertions, 11 deletions
diff --git a/src/jsifier.js b/src/jsifier.js index 62acf8d7..5a92ba52 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -3,8 +3,10 @@ // Main function function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) { + var mainPass = !functionsOnly; + // Add additional necessary items for the main pass - if (!functionsOnly) { + if (mainPass) { var libFuncsToInclude; if (INCLUDE_FULL_LIBRARY) { assert(!BUILD_AS_SHARED_LIB, 'Cannot have both INCLUDE_FULL_LIBRARY and BUILD_AS_SHARED_LIB set.') @@ -31,11 +33,15 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) { substrate = new Substrate('JSifyer'); - var GLOBAL_VARIABLES = functionsOnly ? givenGlobalVariables : data.globalVariables; + var GLOBAL_VARIABLES = !mainPass ? givenGlobalVariables : data.globalVariables; + + Functions.currFunctions = !mainPass ? givenFunctions : {}; + if (mainPass) { + Functions.currExternalFunctions = set(data.functionStubs.map(function(item) { return item.ident })); + } - Functions.currFunctions = functionsOnly ? givenFunctions : {}; - // Now that analysis has completed, we can get around to handling unparsedFunctions - (functionsOnly ? data.functions : data.unparsedFunctions.concat(data.functions)).forEach(function(func) { + // Now that first-pass analysis has completed (so we have basic types, etc.), we can get around to handling unparsedFunctions + (!mainPass ? data.functions : data.unparsedFunctions.concat(data.functions)).forEach(function(func) { // Save just what we need, to save memory Functions.currFunctions[func.ident] = { hasVarArgs: func.hasVarArgs, @@ -57,7 +63,11 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) { if (data.unparsedFunctions.length > 0) { // We are now doing the final JS generation dprint('unparsedFunctions', '== Completed unparsedFunctions ==\n'); - //Debugging.clear(); // Save some memory, before the final heavy lifting + + // Save some memory, before the final heavy lifting + //Functions.currFunctions = null; + //Functions.currExternalFunctions = null; + //Debugging.clear(); } // Actors @@ -771,12 +781,12 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) { items = null; var generated = []; - if (!functionsOnly) { + if (mainPass) { generated = generated.concat(itemsDict.type).concat(itemsDict.GlobalVariableStub).concat(itemsDict.functionStub); } generated = generated.concat(itemsDict.function).concat(data.unparsedFunctions); - if (functionsOnly) return generated.map(function(item) { return item.JS }).join('\n'); + if (!mainPass) return generated.map(function(item) { return item.JS }).join('\n'); // We are ready to print out the data, but must do so carefully - we are // dealing with potentially *huge* strings. Convenient replacements and diff --git a/src/library.js b/src/library.js index 284f093d..685f839a 100644 --- a/src/library.js +++ b/src/library.js @@ -1476,7 +1476,17 @@ var Library = { // ========================================================================== - // dlfcn.h + // dlfcn.h - Dynamic library loading + // + // Some limitations: + // + // * Minification on each file separately may not work, as they will + // have different shortened names. You can in theory combine them, then + // minify, then split... perhaps. + // + // * LLVM optimizations may fail. If the child wants to access a function + // in the parent, LLVM opts may remove it from the parent when it is + // being compiled. Not sure how to tell LLVM to not do so. // ========================================================================== // Data for dlfcn.h. @@ -1510,6 +1520,9 @@ var Library = { try { var lib_module = eval(lib_data)(FUNCTION_TABLE.length); } catch (e) { +#if ASSERTIONS + print('Error in loading dynamic library: ' + e); +#endif DLFCN_DATA.isError = true; return 0; } diff --git a/src/modules.js b/src/modules.js index 91758609..f9185725 100644 --- a/src/modules.js +++ b/src/modules.js @@ -124,6 +124,8 @@ var Types = { var Functions = { // The list of function datas which are being processed in the jsifier, currently currFunctions: [], + // The list of functions that are external'ly defined + currExternalFunctions: [], indexedFunctions: [0, 0], // Start at a non-0 (even, see below) value diff --git a/src/parseTools.js b/src/parseTools.js index 4f0cda35..fe71ff3b 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -695,7 +695,7 @@ function makeGetValue(ptr, pos, type, noNeedFirst, unsigned) { } function indexizeFunctions(value) { - if (value in Functions.currFunctions) { + if (value in Functions.currFunctions || value in Functions.currExternalFunctions) { if (BUILD_AS_SHARED_LIB) { return '(FUNCTION_TABLE_OFFSET + ' + Functions.getIndex(value) + ')'; } else { diff --git a/tests/runner.py b/tests/runner.py index 4b433b13..fdf15d44 100644 --- a/tests/runner.py +++ b/tests/runner.py @@ -1924,14 +1924,24 @@ if 'benchmark' not in sys.argv: output_nicerizer=lambda x: x.replace('\n', '*')) def test_dlfcn_data_and_fptr(self): + global LLVM_OPTS + if LLVM_OPTS: return self.skip() # LLVM opts will optimize out parent_func + global BUILD_AS_SHARED_LIB, EXPORTED_FUNCTIONS, EXPORTED_GLOBALS lib_src = ''' #include <stdio.h> int global = 42; + extern void parent_func(); // a function that is defined in the parent + void lib_fptr() { printf("Second calling lib_fptr from main.\\n"); + parent_func(); + // call it also through a pointer, to check indexizing + void (*p_f)(); + p_f = parent_func; + p_f(); } void (*func(int x, void(*fptr)()))() { @@ -1956,6 +1966,10 @@ if 'benchmark' not in sys.argv: FUNCTYPE func; + void parent_func() { + printf("parent_func called from child\\n"); + } + void main_fptr() { printf("First calling main_fptr from lib.\\n"); } @@ -1997,7 +2011,7 @@ if 'benchmark' not in sys.argv: BUILD_AS_SHARED_LIB = 0 EXPORTED_FUNCTIONS = ['_main'] EXPORTED_GLOBALS = [] - self.do_test(src, 'In func: 13*First calling main_fptr from lib.*Second calling lib_fptr from main.*Var: 42*', + self.do_test(src, 'In func: 13*First calling main_fptr from lib.*Second calling lib_fptr from main.*parent_func called from child*parent_func called from child*Var: 42*', output_nicerizer=lambda x: x.replace('\n', '*')) def test_strtod(self): |