| 10 | |
| 11 | /* Build the 6 `env.edge_*` imports for wasm-pdk plugins; bridges guest <-> compiler memory. */ |
| 12 | export function makeGuestEnv(compilerExports) { |
| 13 | const compMem = () => new Uint8Array(compilerExports.memory.buffer); |
| 14 | const compView = () => new DataView(compilerExports.memory.buffer); |
| 15 | |
| 16 | return (guestExports) => { |
| 17 | const gMem = () => new Uint8Array(guestExports.memory.buffer); |
| 18 | const gView = () => new DataView(guestExports.memory.buffer); |
| 19 | |
| 20 | const stage = (ptr, len) => { |
| 21 | const c = compilerExports.wasm_alloc(Math.max(1, len)); |
| 22 | if (len) compMem().set(gMem().subarray(ptr, ptr + len), c); |
| 23 | return c; |
| 24 | }; |
| 25 | |
| 26 | return { |
| 27 | edge_op: (op, recv, name_ptr, name_len, argv_ptr, argc, out) => { |
| 28 | const cName = stage(name_ptr, name_len); |
| 29 | const cArgv = compilerExports.wasm_alloc(Math.max(4, argc * 4)); |
| 30 | const cOut = compilerExports.wasm_alloc(4); |
| 31 | for (let i = 0; i < argc; i++) { |
| 32 | compView().setUint32(cArgv + i * 4, gView().getUint32(argv_ptr + i * 4, true), true); |
| 33 | } |
| 34 | const ret = compilerExports.host_edge_op(op, recv, cName, name_len, cArgv, argc, cOut); |
| 35 | if (ret === 0 && out) gView().setUint32(out, compView().getUint32(cOut, true), true); |
| 36 | return ret; |
| 37 | }, |
| 38 | |
| 39 | edge_encode: (tag, ptr, len) => |
| 40 | compilerExports.host_edge_encode(tag, stage(ptr, len), len), |
| 41 | |
| 42 | edge_decode: (h, out_tag, dst, dst_max) => { |
| 43 | const cTag = compilerExports.wasm_alloc(4); |
| 44 | const cBuf = compilerExports.wasm_alloc(Math.max(1, dst_max)); |
| 45 | const ret = compilerExports.host_edge_decode(h, cTag, cBuf, dst_max); |
| 46 | gView().setUint32(out_tag, compView().getUint32(cTag, true), true); |
| 47 | if (ret > 0) gMem().set(compMem().subarray(cBuf, cBuf + ret), dst); |
| 48 | return ret; |
| 49 | }, |
| 50 | |
| 51 | edge_release: (h) => compilerExports.host_edge_release(h), |
| 52 | |
| 53 | edge_throw: (kind, msg_ptr, msg_len) => { |
| 54 | compilerExports.host_edge_throw(kind, stage(msg_ptr, msg_len), msg_len); |
| 55 | }, |
| 56 | |
| 57 | edge_take_error: (out_kind, dst, dst_max) => { |
| 58 | const cKind = compilerExports.wasm_alloc(4); |
| 59 | const cBuf = compilerExports.wasm_alloc(Math.max(1, dst_max)); |
| 60 | const ret = compilerExports.host_edge_take_error(cKind, cBuf, dst_max); |
| 61 | if (ret >= 0) { |
| 62 | gView().setUint32(out_kind, compView().getUint32(cKind, true), true); |
| 63 | if (ret > 0) gMem().set(compMem().subarray(cBuf, cBuf + ret), dst); |
| 64 | } |
| 65 | return ret; |
| 66 | }, |
| 67 | }; |
| 68 | }; |
| 69 | } |