mirror of
https://github.com/fluencelabs/musl
synced 2025-04-25 15:22:15 +00:00
[WebAssembly] Use hardcoded list expected undefined symbols (#21)
Rather than generate wasm.syms from wasm.js (which includes a huge superset of the number of symbols actaully expected to be undefined at link time) simply hardcode that list as a test file, which lld can read.
This commit is contained in:
parent
8116ebcd0c
commit
c185c68dd0
@ -951,88 +951,83 @@ var ffi = (function() {
|
|||||||
if (arguments.length < 1)
|
if (arguments.length < 1)
|
||||||
throw new Error('Expected at least one wasm module to load.');
|
throw new Error('Expected at least one wasm module to load.');
|
||||||
|
|
||||||
if (arguments[0] == '--dump-ffi-symbols') {
|
function load_wasm(file_path) {
|
||||||
for (var name in ffi["env"])
|
// TODO this should be split up in load, check dependencies, and then resolve
|
||||||
print(name)
|
// dependencies. That would make it easier to do lazy loading. We could do
|
||||||
} else {
|
// this by catching load exceptions + adding to ffi and trying again, but
|
||||||
function load_wasm(file_path) {
|
// we're talking silly there: modules should just tell us what they want.
|
||||||
// TODO this should be split up in load, check dependencies, and then resolve
|
const buf = (typeof readbuffer === 'function')
|
||||||
// dependencies. That would make it easier to do lazy loading. We could do
|
? new Uint8Array(readbuffer(file_path))
|
||||||
// this by catching load exceptions + adding to ffi and trying again, but
|
: read(file_path, 'binary');
|
||||||
// we're talking silly there: modules should just tell us what they want.
|
instance = new WebAssembly.Instance(new WebAssembly.Module(buf), ffi)
|
||||||
const buf = (typeof readbuffer === 'function')
|
// For the application exports its memory, we use that rather than
|
||||||
? new Uint8Array(readbuffer(file_path))
|
// the one we created. In this way this code works with modules that
|
||||||
: read(file_path, 'binary');
|
// import or export their memory.
|
||||||
instance = new WebAssembly.Instance(new WebAssembly.Module(buf), ffi)
|
if (instance.exports.memory) {
|
||||||
// For the application exports its memory, we use that rather than
|
heap = instance.exports.memory.buffer;
|
||||||
// the one we created. In this way this code works with modules that
|
heap_uint8 = new Uint8Array(heap);
|
||||||
// import or export their memory.
|
heap_size_bytes = heap.byteLength;
|
||||||
if (instance.exports.memory) {
|
|
||||||
heap = instance.exports.memory.buffer;
|
|
||||||
heap_uint8 = new Uint8Array(heap);
|
|
||||||
heap_size_bytes = heap.byteLength;
|
|
||||||
}
|
|
||||||
return instance;
|
|
||||||
}
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
// Load modules in reverse, adding their exports to the ffi object.
|
// Load modules in reverse, adding their exports to the ffi object.
|
||||||
// This is analogous to how the linker resolves symbols: the later modules
|
// This is analogous to how the linker resolves symbols: the later modules
|
||||||
// export symbols used by the earlier modules, and allow shadowing.
|
// export symbols used by the earlier modules, and allow shadowing.
|
||||||
// Note that all modules, as well as the main module, share a heap.
|
// Note that all modules, as well as the main module, share a heap.
|
||||||
var modules = {};
|
var modules = {};
|
||||||
for (var i = arguments.length - 1; i > 0; --i) {
|
for (var i = arguments.length - 1; i > 0; --i) {
|
||||||
var path = arguments[i];
|
var path = arguments[i];
|
||||||
modules[i] = load_wasm(path);
|
modules[i] = load_wasm(path);
|
||||||
for (var f in modules[i].exports) {
|
for (var f in modules[i].exports) {
|
||||||
// TODO wasm modules don't have hasOwnProperty. They probably should.
|
// TODO wasm modules don't have hasOwnProperty. They probably should.
|
||||||
// The code should look like:
|
// The code should look like:
|
||||||
// if (modules[i].hasOwnProperty(f) &&
|
// if (modules[i].hasOwnProperty(f) &&
|
||||||
// modules[i][f] instanceof Function)
|
// modules[i][f] instanceof Function)
|
||||||
if (modules[i].exports[f] instanceof Function)
|
if (modules[i].exports[f] instanceof Function)
|
||||||
ffi['env'][f] = modules[i].exports[f];
|
ffi['env'][f] = modules[i].exports[f];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load the main module once the ffi object has been fully populated.
|
// Load the main module once the ffi object has been fully populated.
|
||||||
var main_module = arguments[0];
|
var main_module = arguments[0];
|
||||||
modules[0] = load_wasm(main_module);
|
modules[0] = load_wasm(main_module);
|
||||||
|
|
||||||
// TODO check that `main` exists in modules[0].exports and error out if not.
|
// TODO check that `main` exists in modules[0].exports and error out if not.
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var ret = modules[0].exports.main();
|
var ret = modules[0].exports.main();
|
||||||
stdio.__flush_stdout();
|
stdio.__flush_stdout();
|
||||||
print(main_module + '::main() returned ' + ret);
|
print(main_module + '::main() returned ' + ret);
|
||||||
if (ret != stdlib.EXIT_SUCCESS)
|
if (ret != stdlib.EXIT_SUCCESS)
|
||||||
throw new Error('main reported failure');
|
throw new Error('main reported failure');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
stdio.__flush_stdout();
|
stdio.__flush_stdout();
|
||||||
if (e instanceof TerminateWasmException) {
|
if (e instanceof TerminateWasmException) {
|
||||||
print('Program terminated with: ' + e);
|
print('Program terminated with: ' + e);
|
||||||
if (stdlib.__get_exit_code() != stdlib.EXIT_SUCCESS) {
|
if (stdlib.__get_exit_code() != stdlib.EXIT_SUCCESS) {
|
||||||
throw stdlib.__get_exit_code();
|
throw stdlib.__get_exit_code();
|
||||||
}
|
}
|
||||||
} else if (e instanceof NotYetImplementedException) {
|
} else if (e instanceof NotYetImplementedException) {
|
||||||
print(e);
|
print(e);
|
||||||
throw e;
|
throw e;
|
||||||
} else {
|
} else {
|
||||||
function is_runtime_trap(e) {
|
function is_runtime_trap(e) {
|
||||||
if ('string' != typeof e) return false;
|
if ('string' != typeof e) return false;
|
||||||
var traps = ['unreachable',
|
var traps = ['unreachable',
|
||||||
'memory access out of bounds',
|
'memory access out of bounds',
|
||||||
'divide by zero',
|
'divide by zero',
|
||||||
'divide result unrepresentable',
|
'divide result unrepresentable',
|
||||||
'remainder by zero',
|
'remainder by zero',
|
||||||
'integer result unrepresentable',
|
'integer result unrepresentable',
|
||||||
'invalid function',
|
'invalid function',
|
||||||
'function signature mismatch'];
|
'function signature mismatch'];
|
||||||
for (var msg in traps) if (e == traps[msg]) return true;
|
for (var msg in traps) if (e == traps[msg]) return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
print(is_runtime_trap(e) ?
|
print(is_runtime_trap(e) ?
|
||||||
('Runtime trap: ' + e) :
|
('Runtime trap: ' + e) :
|
||||||
('Unknown exception of type `' + typeof(e) + '`: ' + e));
|
('Unknown exception of type `' + typeof(e) + '`: ' + e));
|
||||||
throw e;
|
throw e;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
34
arch/wasm32/wasm.syms
Normal file
34
arch/wasm32/wasm.syms
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
# Symbols we want wasm.js to define at runtime
|
||||||
|
_Exit
|
||||||
|
abort
|
||||||
|
puts
|
||||||
|
|
||||||
|
# Musl syscall interface, provided by wasm.js
|
||||||
|
__syscall
|
||||||
|
__syscall0
|
||||||
|
__syscall1
|
||||||
|
__syscall2
|
||||||
|
__syscall3
|
||||||
|
__syscall4
|
||||||
|
__syscall5
|
||||||
|
__syscall6
|
||||||
|
__syscall_cp
|
||||||
|
|
||||||
|
# Symbols not supported by clang but currently expected to work on the
|
||||||
|
# wasm waterfall
|
||||||
|
# TODO(sbc): remove these
|
||||||
|
__builtin_isinff
|
||||||
|
__builtin_isinfl
|
||||||
|
__builtin_clrsb
|
||||||
|
__builtin_clrsbl
|
||||||
|
__builtin_clrsbll
|
||||||
|
__builtin_apply
|
||||||
|
__builtin_apply_args
|
||||||
|
__builtin_malloc
|
||||||
|
|
||||||
|
# Part of musl we still don't compile for wasm
|
||||||
|
__lock
|
||||||
|
__unlock
|
||||||
|
__set_thread_area
|
||||||
|
setjmp
|
||||||
|
longjmp
|
Loading…
x
Reference in New Issue
Block a user