(module, ctx)
| 70 | |
| 71 | /* Built-in Path A fallback: instantiate guest, walk exports, annotate each fn with its guest's `__edge_alloc` + `__edge_memory`. */ |
| 72 | async function builtinWasmPdkLoader(module, ctx) { |
| 73 | const envFactory = makeGuestEnv(ctx.compilerExports); |
| 74 | // Forward reference: the getter captures `instance` lazily. It's only read when env functions fire during VM execution, by which point `instance` is bound. |
| 75 | const env = envFactory({ get memory() { return instance.exports.memory; } }); |
| 76 | // WebAssembly.instantiate(Module, ...) returns the Instance directly, not {module, instance}. |
| 77 | const instance = await WebAssembly.instantiate(module, { env }); |
| 78 | |
| 79 | if (typeof instance.exports.__edge_alloc !== 'function') { |
| 80 | throw new Error( |
| 81 | `native module missing '__edge_alloc(size: u32) -> *mut u8';` + |
| 82 | ` see /reference/wasm-abi for the contract` |
| 83 | ); |
| 84 | } |
| 85 | |
| 86 | const names = []; |
| 87 | const fns = []; |
| 88 | for (const [k, v] of Object.entries(instance.exports)) { |
| 89 | if (k === 'memory' || typeof v !== 'function') continue; |
| 90 | // Keep convention exports (__fn_/__class_/__const_), drop ABI internals like __edge_alloc. |
| 91 | if (k.startsWith('__') && !k.startsWith('__class_') && !k.startsWith('__const_') && !k.startsWith('__fn_')) continue; |
| 92 | names.push(k); |
| 93 | v.__edge_alloc = instance.exports.__edge_alloc; |
| 94 | v.__edge_memory = instance.exports.memory; |
| 95 | v.__edge_kind = 'wasmpdk'; |
| 96 | fns.push(v); |
| 97 | } |
| 98 | return { kind: 'wasmpdk', names, fns }; |
| 99 | } |
| 100 | |
| 101 | /* Try custom loaders first; built-in Path A is the implicit fallback. */ |
| 102 | export async function loadNativeModule(_spec, bytes, ctx) { |
no test coverage detected