aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2013-08-30 21:32:56 -0700
committerAlon Zakai <alonzakai@gmail.com>2013-09-03 14:41:30 -0700
commitbeb08e214984a234c82d3a2fd7e984dffdf2f5dc (patch)
tree560045c39234230ca0253f385da5c10e582fef90
parentd6e21d7851004b2853327d1de468e25ee97fe595 (diff)
clean up shared modules when dlclose()d
-rw-r--r--src/library.js1
-rw-r--r--src/runtime.js14
-rw-r--r--src/shell_sharedlib.js5
3 files changed, 20 insertions, 0 deletions
diff --git a/src/library.js b/src/library.js
index 25251299..ddcf926d 100644
--- a/src/library.js
+++ b/src/library.js
@@ -5102,6 +5102,7 @@ LibraryManager.library = {
} else {
var lib_record = DLFCN_DATA.loadedLibs[handle];
if (--lib_record.refcount == 0) {
+ lib_record.module.cleanups.forEach(function(cleanup) { cleanup() });
delete DLFCN_DATA.loadedLibNames[lib_record.name];
delete DLFCN_DATA.loadedLibs[handle];
}
diff --git a/src/runtime.js b/src/runtime.js
index e42f90e3..9104c55d 100644
--- a/src/runtime.js
+++ b/src/runtime.js
@@ -403,6 +403,20 @@ var Runtime = {
}
});
}
+
+ var newLength = table.length;
+ jsModule.cleanups.push(function() {
+ if (table.length === newLength) {
+ table.length = from; // nothing added since, just shrink
+ } else {
+ // something was added above us, clear and leak the span
+ for (var i = 0; i < num; i++) {
+ table[from + i] = null;
+ }
+ }
+ while (table.length > 0 && table[table.length-1] === null) table.pop();
+ });
+
// patch js module dynCall_* to use functionTable
sigs.forEach(function(sig) {
jsModule['dynCall_' + sig] = function() {
diff --git a/src/shell_sharedlib.js b/src/shell_sharedlib.js
index e57918ea..33fb521c 100644
--- a/src/shell_sharedlib.js
+++ b/src/shell_sharedlib.js
@@ -6,11 +6,16 @@
Module.print = parentModule.print;
Module.printErr = parentModule.printErr;
+ Module.cleanups = [];
+
#if ASM_JS
// Each module has its own stack
var STACKTOP = parentModule['_malloc'](TOTAL_STACK);
assert(STACKTOP % 8 == 0);
var STACK_MAX = STACKTOP + TOTAL_STACK;
+ Module.cleanups.push(function() {
+ parentModule['_free'](STACKTOP); // XXX ensure exported
+ });
#endif
{{BODY}}