From f5d8c7818a182786b02491c9c52d5287682fac61 Mon Sep 17 00:00:00 2001 From: Alex Orlenko Date: Wed, 13 Dec 2023 12:21:26 +0000 Subject: [PATCH] Update wasm code Add exception test (useful for wasm) --- .github/workflows/main.yml | 2 +- src/lib.rs | 7 ++-- testcrate/src/lib.rs | 66 ++++++++++++++++++++++++++++++++++++-- 3 files changed, 68 insertions(+), 7 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index bd87d0b..662517a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -99,7 +99,7 @@ jobs: lua: [lua54, lua53, lua52, lua51] steps: - uses: actions/checkout@v3 - - uses: dtolnay/rust-toolchain@stable + - uses: dtolnay/rust-toolchain@nightly with: target: wasm32-unknown-emscripten - name: Install emscripten diff --git a/src/lib.rs b/src/lib.rs index 2850fc6..d9eadfb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -118,14 +118,13 @@ impl Build { for file in fs::read_dir(&source_dir).unwrap() { let file = file.unwrap(); - let filename = file.file_name().to_string_lossy().to_string(); + let filename = file.file_name(); + let filename = filename.to_str().unwrap(); let src_file = source_dir.join(file.file_name()); let dst_file = cpp_source_dir.join(file.file_name()); let mut content = fs::read(src_file).unwrap(); - // ljumptab.h only contains definitions and will cause errors when wrapping with - // 'extern "C"' - if filename.ends_with(".h") && !["ljumptab.h"].contains(&filename.as_str()) { + if ["lauxlib.h", "lua.h", "lualib.h"].contains(&filename) { content.splice(0..0, b"extern \"C\" {\n".to_vec()); content.extend(b"\n}".to_vec()) } diff --git a/testcrate/src/lib.rs b/testcrate/src/lib.rs index 744bc8b..0845ea8 100644 --- a/testcrate/src/lib.rs +++ b/testcrate/src/lib.rs @@ -6,6 +6,34 @@ extern "C" { pub fn lua_getfield(state: *mut c_void, index: c_int, k: *const c_char); pub fn lua_tolstring(state: *mut c_void, index: c_int, len: *mut c_long) -> *const c_char; pub fn luaL_loadstring(state: *mut c_void, s: *const c_char) -> c_int; + pub fn luaL_error(state: *mut c_void, fmt: *const c_char, ...) -> c_int; + + pub fn lua_pushcclosure( + state: *mut c_void, + f: unsafe extern "C-unwind" fn(state: *mut c_void) -> c_int, + n: c_int, + ); + + #[cfg(feature = "lua51")] + pub fn lua_pcall(state: *mut c_void, nargs: c_int, nresults: c_int, errfunc: c_int) -> c_int; + #[cfg(feature = "lua52")] + pub fn lua_pcallk( + state: *mut c_void, + nargs: c_int, + nresults: c_int, + errfunc: c_int, + ctx: c_int, + k: *const c_void, + ) -> c_int; + #[cfg(any(feature = "lua53", feature = "lua54"))] + pub fn lua_pcallk( + state: *mut c_void, + nargs: c_int, + nresults: c_int, + errfunc: c_int, + ctx: isize, + k: *const c_void, + ) -> c_int; #[cfg(feature = "lua52")] pub fn lua_getglobal(state: *mut c_void, k: *const c_char); @@ -18,8 +46,18 @@ pub unsafe fn lua_getglobal(state: *mut c_void, k: *const c_char) { lua_getfield(state, -10002 /* LUA_GLOBALSINDEX */, k); } +#[cfg(any(feature = "lua52", feature = "lua53", feature = "lua54"))] +pub unsafe fn lua_pcall( + state: *mut c_void, + nargs: c_int, + nresults: c_int, + errfunc: c_int, +) -> c_int { + lua_pcallk(state, nargs, nresults, errfunc, 0, std::ptr::null()) +} + #[test] -fn lua_works() { +fn test_lua() { use std::{ptr, slice}; unsafe { let state = luaL_newstate(); @@ -46,7 +84,7 @@ fn lua_works() { } #[test] -fn unicode_identifiers() { +fn test_unicode_identifiers() { unsafe { let state = luaL_newstate(); let code = "local 😀 = 0\0"; @@ -57,3 +95,27 @@ fn unicode_identifiers() { assert_ne!(0, ret); } } + +#[test] +fn test_exceptions() { + use std::{ptr, slice, str}; + unsafe { + let state = luaL_newstate(); + assert!(state != ptr::null_mut()); + + unsafe extern "C-unwind" fn it_panics(state: *mut c_void) -> c_int { + luaL_error(state, "exception!\0".as_ptr().cast()) + } + + lua_pushcclosure(state, it_panics, 0); + let result = lua_pcall(state, 0, 0, 0); + assert_eq!(result, 2); // LUA_ERRRUN + let s = { + let mut len: c_long = 0; + let version_ptr = lua_tolstring(state, -1, &mut len); + let s = slice::from_raw_parts(version_ptr as *const u8, len as usize); + str::from_utf8(s).unwrap() + }; + assert_eq!(s, "exception!"); + } +}