indexize external functions (for shared libraries, primarily), +some code cleanup around that. fixed issues 38
This commit is contained in:
Родитель
8fc2acdc4e
Коммит
0e9344a428
|
@ -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 = 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) {
|
||||
Functions.currFunctions = !mainPass ? givenFunctions : {};
|
||||
if (mainPass) {
|
||||
Functions.currExternalFunctions = set(data.functionStubs.map(function(item) { return item.ident }));
|
||||
}
|
||||
|
||||
// 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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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):
|
||||
|
|
Загрузка…
Ссылка в новой задаче