| 1125 | |
| 1126 | |
| 1127 | def create_pointer_conversion_wrappers(metadata): |
| 1128 | # The signature format here is similar to the one used for JS libraries |
| 1129 | # but with the following as the only valid char: |
| 1130 | # '_' - non-pointer argument (pass through unchanged) |
| 1131 | # 'p' - pointer/int53 argument (convert to/from BigInt) |
| 1132 | # 'P' - same as above but allow `undefined` too (requires extra check) |
| 1133 | for function in settings.SIGNATURE_CONVERSIONS: |
| 1134 | sym, sig = function.split(':') |
| 1135 | native_sigs[sym] = sig |
| 1136 | |
| 1137 | for f in ASAN_C_HELPERS: |
| 1138 | native_sigs[f] = '_pp' |
| 1139 | |
| 1140 | wrappers = ''' |
| 1141 | // Argument name here must shadow the `wasmExports` global so |
| 1142 | // that it is recognised by metadce and minify-import-export-names |
| 1143 | // passes. |
| 1144 | function applySignatureConversions(wasmExports) { |
| 1145 | // First, make a copy of the incoming exports object |
| 1146 | wasmExports = Object.assign({}, wasmExports); |
| 1147 | ''' |
| 1148 | |
| 1149 | sigs_seen = set() |
| 1150 | wrap_functions = [] |
| 1151 | for symbol, functype in metadata.function_exports.items(): |
| 1152 | # dynCall_ functions are generated by binaryen. They all take a |
| 1153 | # function pointer as their first argument. |
| 1154 | # The second part of this check can be removed once the table64 |
| 1155 | # llvm changes land. |
| 1156 | if symbol.startswith('dynCall_') and functype.params[0] == webassembly.Type.I64: |
| 1157 | sig = symbol.split('_')[-1] |
| 1158 | sig = ['p' if t == 'p' else '_' for t in sig] |
| 1159 | sig.insert(1, 'p') |
| 1160 | sig = ''.join(sig) |
| 1161 | native_sigs[symbol] = sig |
| 1162 | sig = native_sigs.get(symbol) |
| 1163 | if sig: |
| 1164 | if settings.MEMORY64: |
| 1165 | if sig not in sigs_seen: |
| 1166 | wrappers += js_manipulation.make_wasm64_wrapper(sig) |
| 1167 | sigs_seen.add(sig) |
| 1168 | wrap_functions.append(symbol) |
| 1169 | elif sig[0] == 'p': |
| 1170 | if sig not in sigs_seen: |
| 1171 | wrappers += js_manipulation.make_unsign_pointer_wrapper(sig) |
| 1172 | sigs_seen.add(sig) |
| 1173 | wrap_functions.append(symbol) |
| 1174 | |
| 1175 | for f in wrap_functions: |
| 1176 | sig = native_sigs[f] |
| 1177 | wrappers += f"\n wasmExports['{f}'] = makeWrapper_{sig}(wasmExports['{f}']);" |
| 1178 | wrappers += '\n return wasmExports;\n}' |
| 1179 | |
| 1180 | return wrappers |