import fs from 'node:fs' import path from 'node:path' const source = process.argv[2] ?? 'node_modules/@mlightcad/libredwg-web/wasm/libredwg-web.wasm' const target = process.argv[3] ?? 'public/vendor/libredwg/wasm/libredwg-web.wasm' const INITIAL_PAGES = 4096 // 256 MiB; the module can still grow up to its 4 GiB maximum. const MAX_PAGES = 65536 const buf = fs.readFileSync(source) if (buf.readUInt32LE(0) !== 0x6d736100 || buf.readUInt32LE(4) !== 1) { throw new Error('Not a WebAssembly module') } function readU32(data, offset) { let value = 0 let shift = 0 let pos = offset while (true) { const byte = data[pos++] value += (byte & 0x7f) * 2 ** shift if (!(byte & 0x80)) break shift += 7 if (shift > 35) throw new Error('Invalid LEB128 value') } return [value >>> 0, pos] } function encodeU32(value) { const bytes = [] let v = value >>> 0 do { let byte = v & 0x7f v >>>= 7 if (v) byte |= 0x80 bytes.push(byte) } while (v) return Buffer.from(bytes) } function encodeSection(id, payload) { return Buffer.concat([Buffer.from([id]), encodeU32(payload.length), payload]) } const sections = [] let pos = 8 while (pos < buf.length) { const id = buf[pos++] const [size, afterSize] = readU32(buf, pos) const payload = buf.subarray(afterSize, afterSize + size) sections.push({ id, payload }) pos = afterSize + size } let patched = false const output = [] output.push(buf.subarray(0, 8)) for (const section of sections) { if (section.id === 5 && !patched) { const [count, afterCount] = readU32(section.payload, 0) if (count < 1) throw new Error('Memory section has no memory') const flags = section.payload[afterCount] if ((flags & 0x01) === 0) throw new Error('Memory has no maximum; refusing to patch') const [oldMin, afterMin] = readU32(section.payload, afterCount + 1) const [oldMax] = readU32(section.payload, afterMin) if (oldMin !== 16384) throw new Error(`Unexpected initial memory: ${oldMin}`) const payload = Buffer.concat([ encodeU32(count), Buffer.from([flags]), encodeU32(INITIAL_PAGES), encodeU32(MAX_PAGES), section.payload.subarray(afterMin + encodeU32(oldMax).length) ]) output.push(encodeSection(5, payload)) patched = true console.log( `patched memory: ${oldMin} -> ${INITIAL_PAGES} pages (${Math.round((INITIAL_PAGES * 64) / 1024)} MiB)` ) } else { output.push(encodeSection(section.id, section.payload)) } } if (!patched) throw new Error('Memory section not found') fs.mkdirSync(path.dirname(target), { recursive: true }) fs.writeFileSync(target, Buffer.concat(output)) console.log('wrote', target, fs.statSync(target).size, 'bytes')