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
53 changes: 32 additions & 21 deletions src/jsifier.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ import {
warningOccured,
localFile,
} from './utility.mjs';
import {LibraryManager, librarySymbols} from './modules.mjs';
import {LibraryManager, librarySymbols, nativeAliases} from './modules.mjs';

const addedLibraryItems = {};

Expand Down Expand Up @@ -128,9 +128,13 @@ function isDefined(symName) {
}

function resolveAlias(symbol) {
var value = LibraryManager.library[symbol];
if (typeof value == 'string' && value[0] != '=' && LibraryManager.library.hasOwnProperty(value)) {
return value;
while (true) {
var value = LibraryManager.library[symbol];
if (typeof value == 'string' && value[0] != '=' && (LibraryManager.library.hasOwnProperty(value) || WASM_EXPORTS.has(value))) {
symbol = value;
} else {
break;
}
}
return symbol;
}
Expand Down Expand Up @@ -639,6 +643,7 @@ function(${args}) {
});

let isFunction = false;
let isNativeAlias = false;

const postsetId = symbol + '__postset';
const postset = LibraryManager.library[postsetId];
Expand All @@ -654,13 +659,22 @@ function(${args}) {

if (typeof snippet == 'string') {
if (snippet[0] != '=') {
if (LibraryManager.library[snippet]) {
if (LibraryManager.library[snippet] || WASM_EXPORTS.has(snippet)) {
// Redirection for aliases. We include the parent, and at runtime
// make ourselves equal to it. This avoid having duplicate
// functions with identical content.
const aliasTarget = snippet;
snippet = mangleCSymbolName(aliasTarget);
deps.push(aliasTarget);
const aliasTarget = resolveAlias(snippet);
if (WASM_EXPORTS.has(aliasTarget)) {
//printErr(`native alias: ${mangled} -> ${snippet}`);
//console.error(WASM_EXPORTS);
nativeAliases[mangled] = aliasTarget;
snippet = undefined;
isNativeAlias = true;
} else {
//printErr(`js alias: ${mangled} -> ${snippet}`);
deps.push(aliasTarget);
snippet = mangleCSymbolName(aliasTarget);
}
}
}
} else if (typeof snippet == 'object') {
Expand Down Expand Up @@ -728,15 +742,11 @@ function(${args}) {
contentText += ';';
}
} else if (typeof snippet == 'undefined') {
// wasmTable is kind of special. In the normal configuration we export
// it from the wasm module under the name `__indirect_function_table`
// but we declare it as an 'undefined' in `libcore.js`.
// Since the normal export mechanism will declare this variable we don't
// want the JS library version of this symbol be declared (otherwise
// it would be a duplicate decl).
// TODO(sbc): This is kind of hacky, we should come up with a better solution.
var isDirectWasmExport = mangled == 'wasmTable';
if (isDirectWasmExport) {
// For JS library functions that are simply aliases of native symbols,
// we don't need to generate anything here. Instead these get included
// and exported alongside native symbols.
// See `create_receiving` in `tools/emscripten.py`.
if (isNativeAlias) {
contentText = '';
} else {
contentText = `var ${mangled};`;
Expand All @@ -752,7 +762,7 @@ function(${args}) {
contentText = `var ${mangled} = ${snippet};`;
}

if (MODULARIZE == 'instance' && (EXPORT_ALL || EXPORTED_FUNCTIONS.has(mangled)) && !isStub) {
if (contentText && MODULARIZE == 'instance' && (EXPORT_ALL || EXPORTED_FUNCTIONS.has(mangled)) && !isStub) {
// In MODULARIZE=instance mode mark JS library symbols are exported at
// the point of declaration.
contentText = 'export ' + contentText;
Expand All @@ -775,11 +785,11 @@ function(${args}) {
}
}

let commentText = '';
let docs = LibraryManager.library[symbol + '__docs'];
// Add the docs if they exist and if we are actually emitting a declaration.
// See the TODO about wasmTable above.
if (docs && contentText != '') {
let docs = LibraryManager.library[symbol + '__docs'];
let commentText = '';
if (contentText != '' && docs) {
commentText += docs + '\n';
}

Expand Down Expand Up @@ -886,6 +896,7 @@ var proxiedFunctionTable = [
'//FORWARDED_DATA:' +
JSON.stringify({
librarySymbols,
nativeAliases,
warnings: warningOccured(),
asyncFuncs,
libraryDefinitions: LibraryManager.libraryDefinitions,
Expand Down
2 changes: 2 additions & 0 deletions src/lib/libbootstrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ assert(Object.keys(LibraryManager.library).length === 0);
addToLibrary({
$callRuntimeCallbacks: () => {},

$wasmMemory: 'memory',

$ExitStatus: class {
name = 'ExitStatus';
constructor(status) {
Expand Down
13 changes: 9 additions & 4 deletions src/lib/libcore.js
Original file line number Diff line number Diff line change
Expand Up @@ -1641,7 +1641,7 @@ addToLibrary({
#endif
}
}

exportAliases(wasmExports);
},
#endif

Expand Down Expand Up @@ -2150,8 +2150,6 @@ addToLibrary({
#endif // MINIMAL_RUNTIME

$asmjsMangle: (x) => {
if (x == 'memory') return 'wasmMemory';
if (x == '__indirect_function_table') return 'wasmTable';
if (x == '__main_argc_argv') {
x = 'main';
}
Expand Down Expand Up @@ -2287,7 +2285,14 @@ addToLibrary({
});
`,
#else
$wasmTable: undefined,
$wasmTable: '__indirect_function_table',
#endif

#if IMPORTED_MEMORY
// This gets defined in src/runtime_init_memory.js
$wasmMemory: undefined,
#else
$wasmMemory: 'memory',
#endif

$getUniqueRunDependency: (id) => {
Expand Down
4 changes: 2 additions & 2 deletions src/lib/liblegacy.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ legacyFuncs = {
},

// Legacy names for runtime `out`/`err` symbols.
$print: 'out',
$printErr: 'err',
$print: '=out',
$printErr: '=err',

// Converts a JS string to an integer base-10. Despite _s, which
// suggests signaling error handling, this returns NaN on error.
Expand Down
12 changes: 4 additions & 8 deletions src/modules.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ import {preprocess, processMacros} from './parseTools.mjs';

// List of symbols that were added from the library.
export const librarySymbols = [];
// Map of library symbols which are aliases for native symbols
// e.g. `wasmTable` -> `__indirect_function_table`
export const nativeAliases = {};

const srcDir = fileURLToPath(new URL('.', import.meta.url));
const systemLibdir = path.join(srcDir, 'lib');
Expand Down Expand Up @@ -448,7 +451,6 @@ function exportRuntimeSymbols() {
'err',
'callMain',
'abort',
'wasmMemory',
'wasmExports',
'HEAPF32',
'HEAPF64',
Expand Down Expand Up @@ -562,13 +564,7 @@ function exportLibrarySymbols() {
assert(MODULARIZE != 'instance');
const results = ['// Begin JS library exports'];
for (const ident of librarySymbols) {
if (EXPORT_ALL || EXPORTED_FUNCTIONS.has(ident)) {
// Special case for wasmTable which can be both a JS library symbol but
// also a wasm export. See isDirectWasmExport in jsifier.mjs.
// FIXME: Remove this hack
if (ident == 'wasmTable' && WASM_EXPORTS.has('__indirect_function_table')) {
continue;
}
if ((EXPORT_ALL || EXPORTED_FUNCTIONS.has(ident)) && !nativeAliases[ident]) {
results.push(exportSymbol(ident));
}
}
Expand Down
14 changes: 14 additions & 0 deletions src/parseTools.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import {
srcDir,
} from './utility.mjs';

import { nativeAliases } from './modules.mjs';

const FOUR_GB = 4 * 1024 * 1024 * 1024;
const WASM_PAGE_SIZE = 64 * 1024;
const FLOAT_TYPES = new Set(['float', 'double']);
Expand Down Expand Up @@ -1155,6 +1157,17 @@ function nodeWWDetection() {
}
}

function makeExportAliases() {
var res = ''
for (var [alias, ex] of Object.entries(nativeAliases)) {
if (ASSERTIONS) {
res += ` assert(wasmExports['${ex}'], 'alias target "${ex}" not found in wasmExports');\n`;
}
res += ` globalThis['${alias}'] = wasmExports['${ex}'];\n`;
}
return res;
}

addToCompileTimeContext({
ATEXITS,
ATPRERUNS,
Expand Down Expand Up @@ -1204,6 +1217,7 @@ addToCompileTimeContext({
isSymbolNeeded,
makeDynCall,
makeEval,
makeExportAliases,
makeGetValue,
makeHEAPView,
makeModuleReceive,
Expand Down
6 changes: 6 additions & 0 deletions src/runtime_common.js
Original file line number Diff line number Diff line change
Expand Up @@ -174,3 +174,9 @@ if (ENVIRONMENT_IS_NODE) {
#endif // !IMPORTED_MEMORY && ASSERTIONS

#include "memoryprofiler.js"

#if !DECLARE_ASM_MODULE_EXPORTS
function exportAliases(wasmExports) {
{{{ makeExportAliases() }}}
}
#endif
2 changes: 0 additions & 2 deletions src/runtime_init_memory.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
#error "this file should not be be included when IMPORTED_MEMORY is set"
#endif

var wasmMemory;

// check for full engine support (use string 'subarray' to avoid closure compiler confusion)

function initMemory() {
Expand Down
2 changes: 2 additions & 0 deletions src/settings_internal.js
Original file line number Diff line number Diff line change
Expand Up @@ -275,3 +275,5 @@ var OUTPUT_FORMAT = '';
// Whether we should load the WASM source map at runtime.
// This is enabled automatically when using -gsource-map with sanitizers.
var LOAD_SOURCE_MAP = false;

var ALIASES = [];
6 changes: 3 additions & 3 deletions test/codesize/test_codesize_file_preload.expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -3154,12 +3154,12 @@ Module["FS_createLazyFile"] = FS_createLazyFile;
// End JS library exports
// end include: postlibrary.js
// Imports from the Wasm binary.
var _main, wasmMemory, wasmTable;
var _main, memory, __indirect_function_table, wasmMemory;

function assignWasmExports(wasmExports) {
_main = Module["_main"] = wasmExports["d"];
wasmMemory = wasmExports["b"];
wasmTable = wasmExports["__indirect_function_table"];
memory = wasmMemory = wasmExports["b"];
__indirect_function_table = wasmExports["__indirect_function_table"];
}

var wasmImports = {
Expand Down
4 changes: 2 additions & 2 deletions test/codesize/test_codesize_hello_dylink.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"a.out.js": 26931,
"a.out.js.gz": 11473,
"a.out.js.gz": 11472,
"a.out.nodebug.wasm": 18567,
"a.out.nodebug.wasm.gz": 9199,
"total": 45498,
"total_gz": 20672,
"total_gz": 20671,
"sent": [
"__heap_base",
"__indirect_function_table",
Expand Down
11 changes: 7 additions & 4 deletions test/codesize/test_codesize_minimal_O0.expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -850,6 +850,8 @@ async function createWasm() {
err(text);
}
};


// End JS library code

// include: postlibrary.js
Expand Down Expand Up @@ -1056,7 +1058,6 @@ missingLibrarySymbols.forEach(missingLibrarySymbol)
'err',
'callMain',
'abort',
'wasmMemory',
'wasmExports',
'HEAPF32',
'HEAPF64',
Expand Down Expand Up @@ -1084,6 +1085,7 @@ missingLibrarySymbols.forEach(missingLibrarySymbol)
'warnOnce',
'readEmAsmArgsArray',
'wasmTable',
'wasmMemory',
'noExitRuntime',
'addRunDependency',
'removeRunDependency',
Expand Down Expand Up @@ -1315,8 +1317,9 @@ var _emscripten_stack_get_end = makeInvalidEarlyAccess('_emscripten_stack_get_en
var __emscripten_stack_restore = makeInvalidEarlyAccess('__emscripten_stack_restore');
var __emscripten_stack_alloc = makeInvalidEarlyAccess('__emscripten_stack_alloc');
var _emscripten_stack_get_current = makeInvalidEarlyAccess('_emscripten_stack_get_current');
var memory = makeInvalidEarlyAccess('memory');
var __indirect_function_table = makeInvalidEarlyAccess('__indirect_function_table');
var wasmMemory = makeInvalidEarlyAccess('wasmMemory');
var wasmTable = makeInvalidEarlyAccess('wasmTable');

function assignWasmExports(wasmExports) {
_add = Module['_add'] = createExportWrapper('add', 2);
Expand All @@ -1328,8 +1331,8 @@ function assignWasmExports(wasmExports) {
__emscripten_stack_restore = wasmExports['_emscripten_stack_restore'];
__emscripten_stack_alloc = wasmExports['_emscripten_stack_alloc'];
_emscripten_stack_get_current = wasmExports['emscripten_stack_get_current'];
wasmMemory = wasmExports['memory'];
wasmTable = wasmExports['__indirect_function_table'];
memory = wasmMemory = wasmExports['memory'];
__indirect_function_table = wasmExports['__indirect_function_table'];
}

var _global_val = Module['_global_val'] = 65536;
Expand Down
8 changes: 4 additions & 4 deletions test/codesize/test_codesize_minimal_pthreads.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"a.out.js": 7613,
"a.out.js.gz": 3764,
"a.out.js": 7609,
"a.out.js.gz": 3762,
"a.out.nodebug.wasm": 19599,
"a.out.nodebug.wasm.gz": 9063,
"total": 27212,
"total_gz": 12827,
"total": 27208,
"total_gz": 12825,
"sent": [
"a (memory)",
"b (emscripten_get_now)",
Expand Down
4 changes: 2 additions & 2 deletions test/codesize/test_codesize_minimal_pthreads_memgrowth.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"a.out.js": 8040,
"a.out.js": 8036,
"a.out.js.gz": 3962,
"a.out.nodebug.wasm": 19600,
"a.out.nodebug.wasm.gz": 9064,
"total": 27640,
"total": 27636,
"total_gz": 13026,
"sent": [
"a (memory)",
Expand Down
16 changes: 8 additions & 8 deletions test/codesize/test_unoptimized_code_size.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
{
"hello_world.js": 55400,
"hello_world.js.gz": 17483,
"hello_world.js": 55508,
"hello_world.js.gz": 17498,
"hello_world.wasm": 15127,
"hello_world.wasm.gz": 7450,
"no_asserts.js": 26559,
"no_asserts.js.gz": 8867,
"no_asserts.js": 26614,
"no_asserts.js.gz": 8877,
"no_asserts.wasm": 12227,
"no_asserts.wasm.gz": 6010,
"strict.js": 53438,
"strict.js.gz": 16822,
"strict.js": 53546,
"strict.js.gz": 16835,
"strict.wasm": 15127,
"strict.wasm.gz": 7447,
"total": 177878,
"total_gz": 64079
"total": 178149,
"total_gz": 64117
}
4 changes: 3 additions & 1 deletion test/other/test_symbol_map.O3.symbols
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@
2:middle
3:main
4:foo::cpp_func(int)
5:__wasm_call_ctors
5:emscripten_stack_get_current
6:_emscripten_stack_restore
7:__wasm_call_ctors
Loading