aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2013-07-15 15:24:54 -0700
committerAlon Zakai <alonzakai@gmail.com>2013-07-15 15:24:54 -0700
commit6e7a7aa3e8c2096463fed1f24d561557f49787f8 (patch)
treef81ea4377db6d4fd1b002cb55875d2291b71b62e /src
parent9bf755607fc7a0e7f446a5e2d6c82738d77d876f (diff)
parent61c31f69359132e7630a9c4c2c3d25a6ed742247 (diff)
Merge branch 'self-dlopen' of github.com:int3/emscripten into incoming
Diffstat (limited to 'src')
-rw-r--r--src/intertyper.js2
-rw-r--r--src/jsifier.js4
-rw-r--r--src/library.js81
-rw-r--r--src/modules.js3
-rw-r--r--src/settings.js4
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