diff options
author | Alon Zakai <alonzakai@gmail.com> | 2013-07-15 15:24:54 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2013-07-15 15:24:54 -0700 |
commit | 6e7a7aa3e8c2096463fed1f24d561557f49787f8 (patch) | |
tree | f81ea4377db6d4fd1b002cb55875d2291b71b62e /src | |
parent | 9bf755607fc7a0e7f446a5e2d6c82738d77d876f (diff) | |
parent | 61c31f69359132e7630a9c4c2c3d25a6ed742247 (diff) |
Merge branch 'self-dlopen' of github.com:int3/emscripten into incoming
Diffstat (limited to 'src')
-rw-r--r-- | src/intertyper.js | 2 | ||||
-rw-r--r-- | src/jsifier.js | 4 | ||||
-rw-r--r-- | src/library.js | 81 | ||||
-rw-r--r-- | src/modules.js | 3 | ||||
-rw-r--r-- | src/settings.js | 4 |
5 files changed, 57 insertions, 37 deletions
diff --git a/src/intertyper.js b/src/intertyper.js index 94d937e1..abfbdacb 100644 --- a/src/intertyper.js +++ b/src/intertyper.js @@ -503,6 +503,7 @@ function intertyper(data, sidePass, baseLineNums) { // variable var ident = item.tokens[0].text; var private_ = findTokenText(item, 'private') >= 0 || findTokenText(item, 'internal') >= 0; + var named = findTokenText(item, 'unnamed_addr') < 0; cleanOutTokens(LLVM.GLOBAL_MODIFIERS, item.tokens, [2, 3]); var external = false; if (item.tokens[2].text === 'external') { @@ -516,6 +517,7 @@ function intertyper(data, sidePass, baseLineNums) { type: item.tokens[2].text, external: external, private_: private_, + named: named, lineNum: item.lineNum }; if (!NAMED_GLOBALS) { diff --git a/src/jsifier.js b/src/jsifier.js index 82b78d0a..38581ce4 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -286,6 +286,8 @@ function JSify(data, functionsOnly, givenFunctions) { allocator = 'ALLOC_NONE'; } + Variables.globals[item.ident].named = item.named; + if (ASM_JS && (MAIN_MODULE || SIDE_MODULE) && !item.private_ && !NAMED_GLOBALS && isIndexableGlobal(item.ident)) { // We need this to be named (and it normally would not be), so that it can be linked to and used from other modules Variables.globals[item.ident].linkable = 1; @@ -602,6 +604,8 @@ function JSify(data, functionsOnly, givenFunctions) { var associatedSourceFile = "NO_SOURCE"; } + if (DLOPEN_SUPPORT) Functions.getIndex(func.ident); + func.JS += 'function ' + func.ident + '(' + paramIdents.join(', ') + ') {\n'; if (PGO) { diff --git a/src/library.js b/src/library.js index c5618b53..fd883e82 100644 --- a/src/library.js +++ b/src/library.js @@ -5881,7 +5881,7 @@ LibraryManager.library = { dlopen: function(filename, flag) { // void *dlopen(const char *file, int mode); // http://pubs.opengroup.org/onlinepubs/009695399/functions/dlopen.html - filename = (ENV['LD_LIBRARY_PATH'] || '/') + Pointer_stringify(filename); + filename = filename === 0 ? '__self__' : (ENV['LD_LIBRARY_PATH'] || '/') + Pointer_stringify(filename); if (DLFCN_DATA.loadedLibNames[filename]) { // Already loaded; increment ref count and return. @@ -5890,48 +5890,55 @@ LibraryManager.library = { return handle; } - var target = FS.findObject(filename); - if (!target || target.isFolder || target.isDevice) { - DLFCN_DATA.errorMsg = 'Could not find dynamic lib: ' + filename; - return 0; + if (filename === '__self__') { + var handle = -1; + var lib_module = Module; + var cached_functions = SYMBOL_TABLE; } else { - FS.forceLoadFile(target); - var lib_data = intArrayToString(target.contents); - } + var target = FS.findObject(filename); + if (!target || target.isFolder || target.isDevice) { + DLFCN_DATA.errorMsg = 'Could not find dynamic lib: ' + filename; + return 0; + } else { + FS.forceLoadFile(target); + var lib_data = intArrayToString(target.contents); + } - try { - var lib_module = eval(lib_data)({{{ Functions.getTable('x') }}}.length); - } catch (e) { + try { + var lib_module = eval(lib_data)({{{ Functions.getTable('x') }}}.length); + } catch (e) { #if ASSERTIONS - Module.printErr('Error in loading dynamic library: ' + e); + Module.printErr('Error in loading dynamic library: ' + e); #endif - DLFCN_DATA.errorMsg = 'Could not evaluate dynamic lib: ' + filename; - return 0; - } + DLFCN_DATA.errorMsg = 'Could not evaluate dynamic lib: ' + filename; + return 0; + } - // Not all browsers support Object.keys(). - var handle = 1; - for (var key in DLFCN_DATA.loadedLibs) { - if (DLFCN_DATA.loadedLibs.hasOwnProperty(key)) handle++; - } + // Not all browsers support Object.keys(). + var handle = 1; + for (var key in DLFCN_DATA.loadedLibs) { + if (DLFCN_DATA.loadedLibs.hasOwnProperty(key)) handle++; + } + + // We don't care about RTLD_NOW and RTLD_LAZY. + if (flag & 256) { // RTLD_GLOBAL + for (var ident in lib_module) { + if (lib_module.hasOwnProperty(ident)) { + Module[ident] = lib_module[ident]; + } + } + } + var cached_functions = {}; + } DLFCN_DATA.loadedLibs[handle] = { refcount: 1, name: filename, module: lib_module, - cached_functions: {} + cached_functions: cached_functions }; DLFCN_DATA.loadedLibNames[filename] = handle; - // We don't care about RTLD_NOW and RTLD_LAZY. - if (flag & 256) { // RTLD_GLOBAL - for (var ident in lib_module) { - if (lib_module.hasOwnProperty(ident)) { - Module[ident] = lib_module[ident]; - } - } - } - return handle; }, // int dlclose(void* handle); @@ -5963,13 +5970,15 @@ LibraryManager.library = { return 0; } else { var lib = DLFCN_DATA.loadedLibs[handle]; - if (!lib.module.hasOwnProperty(symbol)) { - DLFCN_DATA.errorMsg = ('Tried to lookup unknown symbol "' + symbol + - '" in dynamic lib: ' + lib.name); - return 0; + // self-dlopen means that lib.module is not a superset of + // cached_functions, so check the latter first + if (lib.cached_functions.hasOwnProperty(symbol)) { + return lib.cached_functions[symbol]; } else { - if (lib.cached_functions.hasOwnProperty(symbol)) { - return lib.cached_functions[symbol]; + if (!lib.module.hasOwnProperty(symbol)) { + DLFCN_DATA.errorMsg = ('Tried to lookup unknown symbol "' + symbol + + '" in dynamic lib: ' + lib.name); + return 0; } else { var result = lib.module[symbol]; if (typeof result == 'function') { diff --git a/src/modules.js b/src/modules.js index a6aa2644..53d97817 100644 --- a/src/modules.js +++ b/src/modules.js @@ -449,7 +449,8 @@ var PassManager = { Types: Types, Variables: Variables, Functions: Functions, - EXPORTED_FUNCTIONS: EXPORTED_FUNCTIONS // needed for asm.js global constructors (ctors) + EXPORTED_FUNCTIONS: EXPORTED_FUNCTIONS, // needed for asm.js global constructors (ctors) + Runtime: { GLOBAL_BASE: Runtime.GLOBAL_BASE } })); } else if (phase == 'funcs') { print('\n//FORWARDED_DATA:' + JSON.stringify({ diff --git a/src/settings.js b/src/settings.js index 7f9dca3b..10e93975 100644 --- a/src/settings.js +++ b/src/settings.js @@ -327,6 +327,10 @@ var LINKABLE = 0; // If set to 1, this file can be linked with others, either as // LINKABLE of 0 is very useful in that we can reduce the size of the // generated code very significantly, by removing everything not actually used. +var DLOPEN_SUPPORT = 0; // Whether to support dlopen(NULL, ...) which enables dynamic access to the + // module's functions and globals. Implies LINKABLE=1, because we do not want + // dead code elimination. + var RUNTIME_TYPE_INFO = 0; // Whether to expose type info to the script at run time. This // increases the size of the generated script, but allows you // to more easily perform operations from handwritten JS on |