Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion src/proxyClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,23 @@
#if ENVIRONMENT_MAY_BE_NODE
var ENVIRONMENT_IS_NODE = typeof process == 'object' && typeof process.versions == 'object' && typeof process.versions.node == 'string';
if (ENVIRONMENT_IS_NODE) {
global.Worker = require('worker_threads').Worker;
var NodeWorker = require('worker_threads').Worker;
global.Worker = function(url, options) {
// Special handling for `data:` URL argument, to match the behaviour
// of the Web API.
if (typeof url == 'string' && url.startsWith('data:')) {
#if EXPORT_ES6
// worker_threads always assume data URLs are ES6 modules
url = new URL(url);
#else
// For class modules we decode the data URL and use `eval: true`.
url = Buffer.from(url.split(",")[1], 'base64').toString();
options ||= {}
options.eval = true;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not know this was possible...

#endif
}
return new NodeWorker(url, options);
}
var Module = Module || {}
} else
#endif
Expand Down
10 changes: 8 additions & 2 deletions src/shell.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,12 @@ if (ENVIRONMENT_IS_NODE) {
// TODO: Swap all `require()`'s with `import()`'s?
#if EXPORT_ES6 && ENVIRONMENT_MAY_BE_WEB
const { createRequire } = await import('module');
let dirname = import.meta.url;
if (dirname.startsWith("data:")) {
dirname = '/';
}
/** @suppress{duplicate} */
var require = createRequire(import.meta.url);
var require = createRequire(dirname);
#endif

#if PTHREADS || WASM_WORKERS
Expand Down Expand Up @@ -235,7 +239,9 @@ if (ENVIRONMENT_IS_NODE) {
// EXPORT_ES6 + ENVIRONMENT_IS_NODE always requires use of import.meta.url,
// since there's no way getting the current absolute path of the module when
// support for that is not available.
scriptDirectory = nodePath.dirname(require('url').fileURLToPath(import.meta.url)) + '/';
if (!import.meta.url.startsWith('data:')) {
scriptDirectory = nodePath.dirname(require('url').fileURLToPath(import.meta.url)) + '/';
}
#else
scriptDirectory = __dirname + '/';
#endif
Expand Down
9 changes: 7 additions & 2 deletions test/test_other.py
Original file line number Diff line number Diff line change
Expand Up @@ -14722,8 +14722,13 @@ def test_standalone_whole_archive(self):
self.emcc_args += ['-sSTANDALONE_WASM', '-pthread', '-Wl,--whole-archive', '-lbulkmemory', '-lstandalonewasm', '-Wl,--no-whole-archive']
self.do_runf('hello_world.c')

def test_proxy_to_worker(self):
self.do_runf('hello_world.c', emcc_args=['--proxy-to-worker'])
@parameterized({
'': ([],),
'_single_file': (['-sSINGLE_FILE'],),
'_single_file_es6': (['-sSINGLE_FILE', '-sEXPORT_ES6', '--extern-post-js', test_file('modularize_post_js.js')],),
})
def test_proxy_to_worker(self, args):
self.do_runf('hello_world.c', emcc_args=['--proxy-to-worker'] + args)

@also_with_standalone_wasm()
def test_console_out(self):
Expand Down
14 changes: 9 additions & 5 deletions tools/link.py
Original file line number Diff line number Diff line change
Expand Up @@ -2501,7 +2501,7 @@ def generate_traditional_runtime_html(target, options, js_target, target_basenam
var filename = '%s';
if ((',' + window.location.search.substr(1) + ',').indexOf(',noProxy,') < 0) {
console.log('running code in a web worker');
''' % get_subresource_location(proxy_worker_filename)) + worker_js + '''
''' % get_subresource_location_js(proxy_worker_filename)) + worker_js + '''
} else {
console.log('running code on the main thread');
var fileBytes = tryParseAsDataURI(filename);
Expand Down Expand Up @@ -2569,7 +2569,7 @@ def generate_traditional_runtime_html(target, options, js_target, target_basenam
// Current browser supports Wasm, proceed with loading the main JS runtime.
loadMainJs();
}
''' % (script.inline, get_subresource_location(wasm_target) + '.js')
''' % (script.inline, get_subresource_location_js(wasm_target + '.js'))

shell = do_replace(shell, '{{{ SCRIPT }}}', script.replacement())
shell = shell.replace('{{{ SHELL_CSS }}}', utils.read_file(utils.path_from_root('src/shell.css')))
Expand Down Expand Up @@ -2645,7 +2645,7 @@ def generate_html(target, options, js_target, target_basename, wasm_target):
def generate_worker_js(target, js_target, target_basename):
if settings.SINGLE_FILE:
# compiler output is embedded as base64 data URL
proxy_worker_filename = get_subresource_location(js_target)
proxy_worker_filename = get_subresource_location_js(js_target)
else:
# compiler output goes in .worker.js file
move_file(js_target, shared.replace_suffix(js_target, get_worker_js_suffix()))
Expand Down Expand Up @@ -2958,13 +2958,17 @@ def move_file(src, dst):


# Returns the subresource location for run-time access
def get_subresource_location(path):
def get_subresource_location(path, mimetype='application/octet-stream'):
if settings.SINGLE_FILE:
return 'data:application/octet-stream;base64,' + base64_encode(path)
return f'data:{mimetype};base64,{base64_encode(path)}'
else:
return os.path.basename(path)


def get_subresource_location_js(path):
return get_subresource_location(path, 'text/javascript')


@ToolchainProfiler.profile()
def package_files(options, target):
rtn = []
Expand Down
Loading