Improve error messages when compiling Lua #59

Merged
lucas merged 1 commit from issue/58 into master 2023-03-08 21:28:22 +01:00
4 changed files with 37 additions and 35 deletions
Showing only changes of commit 308613d5fc - Show all commits

View file

@ -1,4 +1,3 @@
use std::ffi::CString;
use std::io::{Cursor, ErrorKind}; use std::io::{Cursor, ErrorKind};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::str::FromStr; use std::str::FromStr;
@ -216,7 +215,6 @@ async fn build_bundles(state: Arc<ActionState>) -> Result<Vec<Bundle>> {
let _enter = span.enter(); let _enter = span.enter();
let lua = build_mod_data_lua(state.clone()); let lua = build_mod_data_lua(state.clone());
let lua = CString::new(lua).wrap_err("Failed to build CString from mod data Lua string")?;
let file = let file =
lua::compile(MOD_DATA_SCRIPT, &lua).wrap_err("Failed to compile mod data Lua file")?; lua::compile(MOD_DATA_SCRIPT, &lua).wrap_err("Failed to compile mod data Lua file")?;
@ -437,9 +435,8 @@ async fn patch_boot_bundle(state: Arc<ActionState>) -> Result<Vec<Bundle>> {
let _enter = span.enter(); let _enter = span.enter();
let lua = include_str!("../../assets/mod_main.lua"); let lua = include_str!("../../assets/mod_main.lua");
let lua = CString::new(lua).wrap_err("Failed to build CString from mod main Lua string")?;
let file = let file =
lua::compile(MOD_BOOT_SCRIPT, &lua).wrap_err("Failed to compile mod main Lua file")?; lua::compile(MOD_BOOT_SCRIPT, lua).wrap_err("Failed to compile mod main Lua file")?;
boot_bundle.add_file(file); boot_bundle.add_file(file);
} }

View file

@ -151,17 +151,6 @@ where
results.into_iter().collect() results.into_iter().collect()
} }
#[tracing::instrument(skip_all, fields(files = files.len()))]
fn compile_bundle(name: String, files: Vec<BundleFile>) -> Result<Bundle> {
let mut bundle = Bundle::new(name);
for file in files {
bundle.add_file(file);
}
Ok(bundle)
}
#[tracing::instrument] #[tracing::instrument]
async fn build_package<P1, P2>(package: P1, root: P2) -> Result<Bundle> async fn build_package<P1, P2>(package: P1, root: P2) -> Result<Bundle>
where where
@ -182,18 +171,20 @@ where
.await .await
.wrap_err_with(|| format!("Invalid package file {}", &pkg_name))?; .wrap_err_with(|| format!("Invalid package file {}", &pkg_name))?;
compile_package_files(&pkg, root) let files = compile_package_files(&pkg, root).await?;
.await let mut bundle = Bundle::new(pkg_name);
.wrap_err("Failed to compile package") for file in files {
.and_then(|files| compile_bundle(pkg_name, files)) bundle.add_file(file);
.wrap_err("Failed to build bundle") }
Ok(bundle)
} }
fn normalize_file_path<P: AsRef<Path>>(path: P) -> Result<PathBuf> { fn normalize_file_path<P: AsRef<Path>>(path: P) -> Result<PathBuf> {
let path = path.as_ref(); let path = path.as_ref();
if path.is_absolute() || path.has_root() { if path.is_absolute() || path.has_root() {
let err = eyre::eyre!("path is absolute: {}", path.display()); let err = eyre::eyre!("Path is absolute: {}", path.display());
return Err(err).with_suggestion(|| "Specify a relative file path.".to_string()); return Err(err).with_suggestion(|| "Specify a relative file path.".to_string());
} }
@ -302,7 +293,7 @@ pub(crate) async fn run(_ctx: sdk::Context, matches: &ArgMatches) -> Result<()>
let bundle = build_package(path, &cfg.dir).await.wrap_err_with(|| { let bundle = build_package(path, &cfg.dir).await.wrap_err_with(|| {
format!( format!(
"failed to build package {} in {}", "Failed to build package '{}' at '{}'",
path.display(), path.display(),
cfg.dir.display() cfg.dir.display()
) )

View file

@ -1,4 +1,3 @@
use std::ffi::CString;
use std::io::{Cursor, Read, Seek, Write}; use std::io::{Cursor, Read, Seek, Write};
use std::path::Path; use std::path::Path;
@ -660,11 +659,8 @@ impl BundleFile {
S: AsRef<str>, S: AsRef<str>,
{ {
match file_type { match file_type {
BundleFileType::Lua => { BundleFileType::Lua => lua::compile(name.clone(), sjson)
let sjson = .wrap_err_with(|| format!("Failed to compile Lua file '{}'", name)),
CString::new(sjson.as_ref()).wrap_err("Failed to build CString from SJSON")?;
lua::compile(name, sjson)
}
BundleFileType::Unknown(_) => { BundleFileType::Unknown(_) => {
eyre::bail!("Unknown file type. Cannot compile from SJSON"); eyre::bail!("Unknown file type. Cannot compile from SJSON");
} }

View file

@ -25,7 +25,7 @@ where
pub fn compile<S, C>(name: S, code: C) -> Result<BundleFile> pub fn compile<S, C>(name: S, code: C) -> Result<BundleFile>
where where
S: Into<String>, S: Into<String>,
C: AsRef<CStr>, C: AsRef<str>,
{ {
let name = name.into(); let name = name.into();
let code = code.as_ref(); let code = code.as_ref();
@ -34,15 +34,33 @@ where
let state = lua::luaL_newstate(); let state = lua::luaL_newstate();
lua::luaL_openlibs(state); lua::luaL_openlibs(state);
lua::lua_pushstring(state, code.as_ptr() as _);
lua::lua_setglobal(state, b"code\0".as_ptr() as _);
let name = CString::new(name.as_bytes()) let name = CString::new(name.as_bytes())
.wrap_err_with(|| format!("Cannot convert name into CString: {}", name))?; .wrap_err_with(|| format!("Cannot convert name into CString: {}", name))?;
lua::lua_pushstring(state, name.as_ptr() as _); match lua::luaL_loadbuffer(
lua::lua_setglobal(state, b"name\0".as_ptr() as _); state,
code.as_ptr() as _,
code.len() as _,
name.as_ptr() as _,
) as u32
{
lua::LUA_OK => {}
lua::LUA_ERRSYNTAX => {
let err = lua::lua_tostring(state, -1);
let err = CStr::from_ptr(err).to_string_lossy().to_string();
let run = b"return string.dump(loadstring(code, \"@\" .. name), false)\0"; lua::lua_close(state);
eyre::bail!("Invalid syntax: {}", err);
}
lua::LUA_ERRMEM => {
lua::lua_close(state);
eyre::bail!("Failed to allocate sufficient memory to compile LuaJIT bytecode")
}
_ => unreachable!(),
}
lua::lua_setglobal(state, b"fn\0".as_ptr() as _);
let run = b"return string.dump(fn, false)\0";
match lua::luaL_loadstring(state, run.as_ptr() as _) as u32 { match lua::luaL_loadstring(state, run.as_ptr() as _) as u32 {
lua::LUA_OK => {} lua::LUA_OK => {}
lua::LUA_ERRSYNTAX => { lua::LUA_ERRSYNTAX => {