ceifa / wasmoon

A real lua 5.4 VM with JS bindings made with webassembly
MIT License
462 stars 27 forks source link

Out of bounds memory access when trying to load a Lua bytecode file #56

Closed jaames closed 1 year ago

jaames commented 2 years ago

Hello! I'm trying to load a compiled Lua bytecode file (test.luac.zip) that was compiled for Panic's Playdate game console. As far as I understand, both the Playdate's Lua implementation and Wasmoon's Lua runtime is Lua 5.4 compiled with #define LUA_32BITS 1, so in theory they should be compatible?

To load bytecode, I'm calling factory.mountFile with the bytecode contents, and then loading that file with lua.doFile. If loaded correctly, the bytecode should print "hello world". Here's my code:

import { LuaFactory } from 'wasmoon';

const testFileUrl = '/luac/test.luac';

(async () => {
  const factory = new LuaFactory('/wasm/glue.wasm');

  const lua = await factory.createEngine();

  const resp = await fetch(testFileUrl);
  const testFile = await resp.arrayBuffer();
  await factory.mountFile('test.luac', new Uint8Array(testFile));

  try {
    await lua.doFile('test.luac');
  }
  finally {
    lua.global.close();
  }
})();

I seem to be getting a "memory access out of bounds" error here no matter what I try. I've tested it in various browsers on macOS 12.5 and get a similar error in different browsers:

Chrome 104.0.5112.79:

glue.wasm:0x11fa2 Uncaught (in promise) RuntimeError: memory access out of bounds
    at glue.wasm:0x11fa2
    at glue.wasm:0x37486
    at rb (index.js:1264:384)
    at glue.wasm:0xbde0
    at glue.wasm:0x2d617
    at c._lua_resume [as lua_resume] (index.js:1260:408)
    at Thread.resume (index.js:110:44)
    at Thread.run (index.js:140:41)
    at LuaEngine.callByteCode (index.js:1130:45)
    at LuaEngine.doFile (index.js:1113:25)

Firefox 103.0.2:

Uncaught (in promise) RuntimeError: index out of bounds
    rb index.js:1264
    _lua_resume index.js:1260
    resume index.js:110
    run index.js:140
    callByteCode index.js:1130
    doFile index.js:1113
    <anonymous> index.ts:16
    step emu.js:50
    verb emu.js:31

Safari 15.6:

Unhandled Promise Rejection: RuntimeError: Out of bounds memory access (evaluating 'ib(a)(b,d)')
step — emu.js:52
(anonymous function) — emu.js:31
rejected — emu.js:22
promiseReactionJob

Any pointers would be super appreciated, and would be happy to donate or contribute if that would help!

Thanks for your time, and congrats on the excellent library!

ceifa commented 2 years ago

I managed to reproduce it here: https://jsfiddle.net/3sgqw8Lx/6/

jaames commented 2 years ago

Any idea what's causing it? If I remember correctly, Lua is able to automatically determine whether a file is plaintext or bytecode so I figured it would "just work" :)

ceifa commented 2 years ago

Just tried it with another compiled file and it succeeds:

echo 'print("Hello, world!")' | ./luac - && wasmoon luac.out
Hello, world!

How are you compiling your file @jaames?