aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xemcc9
-rw-r--r--src/postamble.js7
-rw-r--r--tools/file_packager.py77
3 files changed, 53 insertions, 40 deletions
diff --git a/emcc b/emcc
index 2aa223db..4222caa3 100755
--- a/emcc
+++ b/emcc
@@ -1654,7 +1654,7 @@ try:
# Embed and preload files
if len(preload_files) + len(embed_files) > 0:
logging.debug('setting up files')
- file_args = []
+ file_args = ['--pre-run']
if len(preload_files) > 0:
file_args.append('--preload')
file_args += preload_files
@@ -1665,11 +1665,8 @@ try:
file_args += ['--compress', Compression.encoder, Compression.decoder, Compression.js_name]
if use_preload_cache:
file_args.append('--use-preload-cache')
- code = execute([shared.PYTHON, shared.FILE_PACKAGER, unsuffixed(target) + '.data'] + file_args, stdout=PIPE)[0]
- src = open(final).read().replace('// {{PRE_RUN_ADDITIONS}}', '// {{PRE_RUN_ADDITIONS}}\n' + code)
- final += '.files.js'
- open(final, 'w').write(src)
- if DEBUG: save_intermediate('files')
+ file_code = execute([shared.PYTHON, shared.FILE_PACKAGER, unsuffixed(target) + '.data'] + file_args, stdout=PIPE)[0]
+ pre_js = file_code + pre_js
# Apply pre and postjs files
if pre_js or post_js:
diff --git a/src/postamble.js b/src/postamble.js
index d64fb220..63495914 100644
--- a/src/postamble.js
+++ b/src/postamble.js
@@ -33,12 +33,11 @@ ExitStatus.prototype.constructor = ExitStatus;
var initialStackTop;
var preloadStartTime = null;
var calledMain = false;
-var calledRun = false;
dependenciesFulfilled = function runCaller() {
// If run has never been called, and we should call run (INVOKE_RUN is true, and Module.noInitialRun is not false)
- if (!calledRun && shouldRunNow) run();
- if (!calledRun) dependenciesFulfilled = runCaller; // try this again later, after new deps are fulfilled
+ if (!Module['calledRun'] && shouldRunNow) run();
+ if (!Module['calledRun']) dependenciesFulfilled = runCaller; // try this again later, after new deps are fulfilled
}
Module['callMain'] = Module.callMain = function callMain(args) {
@@ -128,7 +127,7 @@ function run(args) {
preMain();
- calledRun = true;
+ Module['calledRun'] = true;
if (Module['_main'] && shouldRunNow) {
Module['callMain'](args);
}
diff --git a/tools/file_packager.py b/tools/file_packager.py
index 8f0f8be8..8efa85f4 100644
--- a/tools/file_packager.py
+++ b/tools/file_packager.py
@@ -11,10 +11,7 @@ data downloads.
Usage:
- file_packager.py TARGET [--preload A [B..]] [--embed C [D..]] [--compress COMPRESSION_DATA] [--pre-run] [--crunch[=X]] [--js-output=OUTPUT.js] [--no-force]
-
- --pre-run Will generate wrapper code that does preloading in Module.preRun. This is necessary if you add this
- code before the main file has been loading, which includes necessary components like addRunDependency.
+ file_packager.py TARGET [--preload A [B..]] [--embed C [D..]] [--compress COMPRESSION_DATA] [--crunch[=X]] [--js-output=OUTPUT.js] [--no-force]
--crunch=X Will compress dxt files to crn with quality level X. The crunch commandline tool must be present
and CRUNCH should be defined in ~/.emscripten that points to it. JS crunch decompressing code will
@@ -46,7 +43,7 @@ from shared import Compression, execute, suffix, unsuffixed
from subprocess import Popen, PIPE, STDOUT
if len(sys.argv) == 1:
- print '''Usage: file_packager.py TARGET [--preload A...] [--embed B...] [--compress COMPRESSION_DATA] [--pre-run] [--crunch[=X]] [--js-output=OUTPUT.js] [--no-force] [--use-preload-cache]
+ print '''Usage: file_packager.py TARGET [--preload A...] [--embed B...] [--compress COMPRESSION_DATA] [--crunch[=X]] [--js-output=OUTPUT.js] [--no-force] [--use-preload-cache]
See the source for more details.'''
sys.exit(0)
@@ -69,7 +66,6 @@ in_preload = False
in_embed = False
has_preloaded = False
in_compress = 0
-pre_run = False
crunch = 0
plugins = []
jsoutput = None
@@ -91,11 +87,6 @@ for arg in sys.argv[1:]:
in_compress = 1
in_preload = False
in_embed = False
- elif arg == '--pre-run':
- pre_run = True
- in_preload = False
- in_embed = False
- in_compress = 0
elif arg == '--no-force':
force = False
elif arg == '--use-preload-cache':
@@ -141,6 +132,8 @@ if (not force) and len(data_files) == 0:
has_preloaded = False
ret = '''
+var Module;
+if (typeof Module === 'undefined') Module = eval('(function() { try { return Module || {} } catch(e) { return {} } })()');
(function() {
'''
@@ -432,6 +425,7 @@ if has_preloaded:
''' % use_data
package_uuid = uuid.uuid4();
+ remote_package_name = os.path.basename(Compression.compressed_name(data_target) if Compression.on else data_target)
code += r'''
if (!Module.expectedDataFileDownloads) {
Module.expectedDataFileDownloads = 0;
@@ -443,7 +437,7 @@ if has_preloaded:
var PACKAGE_NAME = '%s';
var REMOTE_PACKAGE_NAME = '%s';
var PACKAGE_UUID = '%s';
- ''' % (data_target, os.path.basename(Compression.compressed_name(data_target) if Compression.on else data_target), package_uuid)
+ ''' % (data_target, remote_package_name, package_uuid)
if use_preload_cache:
code += r'''
@@ -536,7 +530,7 @@ if has_preloaded:
};
'''
- code += r'''
+ ret += r'''
function fetchRemotePackage(packageName, callback, errback) {
var xhr = new XMLHttpRequest();
xhr.open('GET', packageName, true);
@@ -564,9 +558,9 @@ if has_preloaded:
num++;
}
total = Math.ceil(total * Module.expectedDataFileDownloads/num);
- Module['setStatus']('Downloading data... (' + loaded + '/' + total + ')');
+ if (Module['setStatus']) Module['setStatus']('Downloading data... (' + loaded + '/' + total + ')');
} else if (!Module.dataFileDownloads) {
- Module['setStatus']('Downloading data...');
+ if (Module['setStatus']) Module['setStatus']('Downloading data...');
}
};
xhr.onload = function(event) {
@@ -576,6 +570,12 @@ if has_preloaded:
xhr.send(null);
};
+ function handleError(error) {
+ console.error('package error:', error);
+ };
+ '''
+
+ code += r'''
function processPackageData(arrayBuffer) {
Module.finishedDataFileDownloads++;
assert(arrayBuffer, 'Loading data file failed.');
@@ -584,15 +584,10 @@ if has_preloaded:
%s
};
Module['addRunDependency']('datafile_%s');
-
- function handleError(error) {
- console.error('package error:', error);
- };
''' % (use_data, data_target) # use basename because from the browser's point of view, we need to find the datafile in the same dir as the html file
code += r'''
- if (!Module.preloadResults)
- Module.preloadResults = {};
+ if (!Module.preloadResults) Module.preloadResults = {};
'''
if use_preload_cache:
@@ -631,21 +626,43 @@ if has_preloaded:
if (Module['setStatus']) Module['setStatus']('Downloading...');
'''
else:
+ # Not using preload cache, so we might as well start the xhr ASAP, potentially before JS parsing of the main codebase if it's after us.
+ # Only tricky bit is the fetch is async, but also when runWithFS is called is async, so we handle both orderings.
+ ret += r'''
+ var fetched = null, fetchedCallback = null;
+ fetchRemotePackage('%s', function(data) {
+ if (fetchedCallback) {
+ fetchedCallback(data);
+ fetchedCallback = null;
+ } else {
+ fetched = data;
+ }
+ }, handleError);
+ ''' % os.path.basename(Compression.compressed_name(data_target) if Compression.on else data_target)
+
code += r'''
Module.preloadResults[PACKAGE_NAME] = {fromCache: false};
- fetchRemotePackage(REMOTE_PACKAGE_NAME, processPackageData, handleError);
+ if (fetched) {
+ processPackageData(fetched);
+ fetched = null;
+ } else {
+ fetchedCallback = processPackageData;
+ }
'''
-if pre_run:
- ret += '''
- if (typeof Module == 'undefined') Module = {};
- if (!Module['preRun']) Module['preRun'] = [];
- Module["preRun"].push(function() {
+ret += '''
+ function runWithFS() {
'''
ret += code
-
-if pre_run:
- ret += ' });\n'
+ret += '''
+ }
+ if (Module['calledRun']) {
+ runWithFS();
+ } else {
+ if (!Module['preRun']) Module['preRun'] = [];
+ Module["preRun"].push(runWithFS); // FS is not initialized yet, wait for it
+ }
+'''
if crunch:
ret += '''