Skip to content

Commit

Permalink
Add Module['scriptDirectory'] to fix loading files that should be rel…
Browse files Browse the repository at this point in the history
…ative to main .js file on Node.js.
  • Loading branch information
juj committed Jul 21, 2018
1 parent b2c9a15 commit 9f3441b
Show file tree
Hide file tree
Showing 9 changed files with 78 additions and 0 deletions.
2 changes: 2 additions & 0 deletions emcc.py
Original file line number Diff line number Diff line change
Expand Up @@ -2713,6 +2713,8 @@ def generate_html(target, options, js_target, target_basename,
} else if (Module['memoryInitializerPrefixURL']) {
memoryInitializer = Module['memoryInitializerPrefixURL'] + memoryInitializer;
}
// If URL to memory initializer is relative, treat it relative with respect to Module['scriptDirectory'], if that is present.
if (Module['scriptDirectory'] && !/^(?:[a-z]+:)?[\/\\\\]\/?/i.test(memoryInitializer)) memoryInitializer = Module['scriptDirectory'] + memoryInitializer;
Module['memoryInitializerRequestURL'] = memoryInitializer;
var meminitXHR = Module['memoryInitializerRequest'] = new XMLHttpRequest();
meminitXHR.open('GET', memoryInitializer, true);
Expand Down
1 change: 1 addition & 0 deletions src/Fetch.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ var Fetch = {
// of these are passed, then the default URL 'pthread-main.js' relative to the main html file is loaded.
if (typeof Module['locateFile'] === 'function') fetchJs = Module['locateFile'](fetchJs);
else if (Module['pthreadMainPrefixURL']) fetchJs = Module['pthreadMainPrefixURL'] + fetchJs;
fetchJs = joinUrl(Module['scriptDirectory'], fetchJs);
Fetch.worker = new Worker(fetchJs);
Fetch.worker.onmessage = function(e) {
out('fetch-worker sent a message: ' + e.filename + ':' + e.lineno + ': ' + e.message);
Expand Down
1 change: 1 addition & 0 deletions src/library_debugger_toolkit.js
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,7 @@ var CyberDWARFHeapPrinter = function(cdFileLocation) {
} else if (Module['cdInitializerPrefixURL']) {
cdFileLocation = Module['cdInitializerPrefixURL'] + cdFileLocation;
}
cdFileLocation = joinUrl(Module['scriptDirectory'], cdFileLocation);
if (ENVIRONMENT_IS_NODE || ENVIRONMENT_IS_SHELL) {
var data = Module['read'](cdFileLocation);
install_cyberdwarf(data);
Expand Down
1 change: 1 addition & 0 deletions src/library_pthread.js
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ var LibraryPThread = {
else if (Module['pthreadMainPrefixURL']) pthreadMainJs = Module['pthreadMainPrefixURL'] + pthreadMainJs;

for (var i = 0; i < numWorkers; ++i) {
pthreadMainJs = joinUrl(Module['scriptDirectory'], pthreadMainJs);
var worker = new Worker(pthreadMainJs);

(function(worker) {
Expand Down
2 changes: 2 additions & 0 deletions src/postamble.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ if (memoryInitializer) {
} else if (Module['memoryInitializerPrefixURL']) {
memoryInitializer = Module['memoryInitializerPrefixURL'] + memoryInitializer;
}
memoryInitializer = joinUrl(Module['scriptDirectory'], memoryInitializer);
}

if (ENVIRONMENT_IS_NODE || ENVIRONMENT_IS_SHELL) {
var data = Module['readBinary'](memoryInitializer);
HEAPU8.set(data, GLOBAL_BASE);
Expand Down
15 changes: 15 additions & 0 deletions src/preamble.js
Original file line number Diff line number Diff line change
Expand Up @@ -844,6 +844,18 @@ function stackTrace() {
return demangleAll(js);
}

function isAbsolutePath(path) {
return isDataURI(path) || /^(?:[a-z]+:)?[\/\\]\/?/i.test(path);
}

// Joins relative URL 'b' to URL 'a'. 'a' may be empty, in which case 'b' is returned.
// If 'b' is an absolute URL, then 'a' is ignored and 'b' is returned as-is as well.
function joinUrl(a, b) {
#if ASSERTIONS
if (a && !a.endsWith('/')) throw 'First parameter to joinUrl() should end in /!';
#endif
return (a && !isAbsolutePath(b)) ? a + b : b;
}
// Memory management

var PAGE_SIZE = 16384;
Expand Down Expand Up @@ -2031,6 +2043,9 @@ function integrateWasmJS() {
asmjsCodeFile = Module['locateFile'](asmjsCodeFile);
}
}
wasmTextFile = joinUrl(Module['scriptDirectory'], wasmTextFile);
wasmBinaryFile = joinUrl(Module['scriptDirectory'], wasmBinaryFile);
asmjsCodeFile = joinUrl(Module['scriptDirectory'], asmjsCodeFile);
// utilities
Expand Down
2 changes: 2 additions & 0 deletions src/shell.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ if (ENVIRONMENT_IS_NODE) {

// Expose functionality in the same simple way that the shells work
// Note that we pollute the global namespace here, otherwise we break in node
if (!Module['scriptDirectory']) Module['scriptDirectory'] = __dirname + '/';

var nodeFS;
var nodePath;

Expand Down
53 changes: 53 additions & 0 deletions tests/test_other.py
Original file line number Diff line number Diff line change
Expand Up @@ -8539,3 +8539,56 @@ def test_html_preprocess(self):
T4:NO_EXIT_RUNTIME > 1
T5:NO_EXIT_RUNTIME
T6:(else) !NO_EXIT_RUNTIME""", output)

# Tests that Emscripten-compiled applications can be run from a relative path with node command line that is different than the current working directory.
def test_node_js_run_from_different_directory(self):
args = ['-O3', '-s', 'WASM=1', '--memory-init-file', '1', '-s', 'BINARYEN_METHOD="asmjs,native-wasm"']
# Test that .mem.js is loaded up properly even if running the build output from a separate directory.
os.mkdir('subdir')
Popen([PYTHON, EMCC, path_from_root('tests', 'hello_world.c'), '-o', os.path.join('subdir', 'a.js')] + args).communicate()
ret = Popen(NODE_JS + [os.path.join('subdir', 'a.js')], stdout=PIPE).communicate()[0]
try_delete('subdir')
assert 'hello, world!' in ret

# Test that the build is loaded properly when Module.locateFile is being used, where Module.locateFile() specifies an absolute path already.
os.mkdir('subdir')
open(os.path.join('subdir', 'pre.js'), 'w').write('''
var Module = {};
Module.memoryInitializerPrefixURL = 'this_should_be_getting_ignored_since_locateFile_is_specified/';
Module.locateFile = function(f) { return __dirname + '/' + f; }
''')

Popen([PYTHON, EMCC, path_from_root('tests', 'hello_world.c'), '-o', os.path.join('subdir', 'a.js'), '--pre-js', os.path.join('subdir', 'pre.js')] + args).communicate()
ret = Popen(NODE_JS + [os.path.join('subdir', 'a.js')], stdout=PIPE).communicate()[0]
try_delete('subdir')
assert 'hello, world!' in ret

# Test that the build is loaded properly when Module.locateFile is being used, and it returns a relative path.
os.mkdir('subdir')
open(os.path.join('subdir', 'pre.js'), 'w').write('''
var Module = {};
Module.memoryInitializerPrefixURL = 'this_should_be_getting_ignored_since_locateFile_is_specified/';
Module.locateFile = function(f) { return 'data/' + f; }
''')

Popen([PYTHON, EMCC, path_from_root('tests', 'hello_world.c'), '-o', os.path.join('subdir', 'a.js'), '--pre-js', os.path.join('subdir', 'pre.js')] + args).communicate()
os.mkdir(os.path.join('subdir', 'data'))
os.rename(os.path.join('subdir', 'a.js.mem'), os.path.join('subdir', 'data', 'a.js.mem'))
os.rename(os.path.join('subdir', 'a.asm.js'), os.path.join('subdir', 'data', 'a.asm.js'))
ret = Popen(NODE_JS + [os.path.join('subdir', 'a.js')], stdout=PIPE).communicate()[0]
try_delete('subdir')
assert 'hello, world!' in ret

# Test that the build is loaded properly when memoryInitializerPrefixURL is being used, and it returns a relative path.
os.mkdir('subdir')
open(os.path.join('subdir', 'pre.js'), 'w').write('''
var Module = {};
Module.memoryInitializerPrefixURL = 'data/';
''')

Popen([PYTHON, EMCC, path_from_root('tests', 'hello_world.c'), '-o', os.path.join('subdir', 'a.js'), '--pre-js', os.path.join('subdir', 'pre.js')] + args).communicate()
os.mkdir(os.path.join('subdir', 'data'))
os.rename(os.path.join('subdir', 'a.js.mem'), os.path.join('subdir', 'data', 'a.js.mem'))
ret = Popen(NODE_JS + [os.path.join('subdir', 'a.js')], stdout=PIPE).communicate()[0]
try_delete('subdir')
assert 'hello, world!' in ret
1 change: 1 addition & 0 deletions tools/file_packager.py
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,7 @@ def was_seen(name):
var REMOTE_METADATA_NAME = typeof Module['locateFile'] === 'function' ?
Module['locateFile']('%(metadata_file)s') :
((Module['filePackagePrefixURL'] || '') + '%(metadata_file)s');
REMOTE_METADATA_NAME = joinUrl(Module['scriptDirectory'], REMOTE_METADATA_NAME);
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
Expand Down

0 comments on commit 9f3441b

Please sign in to comment.