Skip to content

Commit 5b63376

Browse files
authored
Move parts of wasm64 export wrapper generation to build time. NFC (#17057)
Specifically the metadata about which exports to wrap is now stored in the compiler rather than the runtime.
1 parent d51281a commit 5b63376

5 files changed

+85
-87
lines changed

emscripten.py

+58
Original file line numberDiff line numberDiff line change
@@ -875,6 +875,8 @@ def create_module(sending, receiving, invoke_funcs, metadata):
875875

876876
module.append(receiving)
877877
module.append(invoke_wrappers)
878+
if settings.MEMORY64:
879+
module.append(create_wasm64_wrappers(metadata))
878880
return module
879881

880882

@@ -929,6 +931,62 @@ def create_invoke_wrappers(invoke_funcs):
929931
return invoke_wrappers
930932

931933

934+
def create_wasm64_wrappers(metadata):
935+
# TODO(sbc): Move this into somewhere less static. Maybe it can become
936+
# part of library.js file, even though this metadata relates specifically
937+
# to native (non-JS) functions.
938+
#
939+
# The signature format here is similar to the one used for JS libraries
940+
# but with the following as the only valid char:
941+
# '_' - non-pointer argument (pass through unchanged)
942+
# 'p' - pointer/int53 argument (convert to/from BigInt)
943+
# 'P' - same as above but allow `undefined` too (requires extra check)
944+
mapping = {
945+
'sbrk': 'pP',
946+
'stackAlloc': 'pp',
947+
'emscripten_builtin_malloc': 'pp',
948+
'malloc': 'pp',
949+
'__getTypeName': 'pp',
950+
'setThrew': '_p',
951+
'free': '_p',
952+
'stackRestore': '_p',
953+
'__cxa_is_pointer_type': '_p',
954+
'stackSave': 'p',
955+
'fflush': '_p',
956+
'emscripten_stack_get_end': 'p',
957+
'emscripten_stack_get_base': 'p',
958+
'pthread_self': 'p',
959+
'emscripten_stack_get_current': 'p',
960+
'__errno_location': 'p',
961+
'emscripten_builtin_memalign': 'ppp',
962+
'main': '__PP',
963+
'emscripten_stack_set_limits': '_pp',
964+
'__set_stack_limits': '_pp',
965+
'__cxa_can_catch': '_ppp',
966+
}
967+
968+
wasm64_wrappers = '''
969+
function instrumentWasmExportsForMemory64(exports) {
970+
// First, make a copy of the incoming exports object
971+
exports = Object.assign({}, exports);'''
972+
973+
sigs_seen = set()
974+
wrap_functions = []
975+
for exp in metadata['exports']:
976+
sig = mapping.get(exp)
977+
if sig:
978+
if sig not in sigs_seen:
979+
sigs_seen.add(sig)
980+
wasm64_wrappers += js_manipulation.make_wasm64_wrapper(sig)
981+
wrap_functions.append(exp)
982+
983+
for f in wrap_functions:
984+
sig = mapping[f]
985+
wasm64_wrappers += f"\n exports['{f}'] = wasm64Wrapper_{sig}(exports['{f}']);"
986+
wasm64_wrappers += '\n return exports\n}'
987+
return wasm64_wrappers
988+
989+
932990
def normalize_line_endings(text):
933991
"""Normalize to UNIX line endings.
934992

src/preamble.js

-4
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,6 @@ if (typeof WebAssembly != 'object') {
5050
#include "runtime_asan.js"
5151
#endif
5252

53-
#if MEMORY64
54-
#include "runtime_wasm64.js"
55-
#endif
56-
5753
// Wasm globals
5854

5955
var wasmMemory;

src/preamble_minimal.js

-4
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,6 @@
1212
#include "runtime_asan.js"
1313
#endif
1414

15-
#if MEMORY64
16-
#include "runtime_wasm64.js"
17-
#endif
18-
1915
#if ASSERTIONS || SAFE_HEAP
2016
/** @type {function(*, string=)} */
2117
function assert(condition, text) {

src/runtime_wasm64.js

-79
This file was deleted.

tools/js_manipulation.py

+27
Original file line numberDiff line numberDiff line change
@@ -138,3 +138,30 @@ def make_invoke(sig):
138138
}''' % (sig, ','.join(args), body, exceptional_ret)
139139

140140
return ret
141+
142+
143+
def make_wasm64_wrapper(sig):
144+
assert 'p' in sig.lower()
145+
n_args = len(sig) - 1
146+
args = ['a%d' % i for i in range(n_args)]
147+
args_converted = args.copy()
148+
for i, arg_type in enumerate(sig[1:]):
149+
if arg_type == 'p':
150+
args_converted[i] = f'BigInt({args_converted[i]})'
151+
elif arg_type == 'P':
152+
args_converted[i] = f'BigInt({args_converted[i]} ? {args_converted[i]} : 0)'
153+
else:
154+
assert arg_type == '_'
155+
156+
args_in = ', '.join(args)
157+
args_out = ', '.join(args_converted)
158+
result = f'f({args_out})'
159+
if sig[0] == 'p':
160+
result = f'Number({result})'
161+
162+
return f'''
163+
function wasm64Wrapper_{sig}(f) {{
164+
return function({args_in}) {{
165+
return {result};
166+
}};
167+
}}'''

0 commit comments

Comments
 (0)