Improve error messages when compiling Lua #59
4 changed files with 37 additions and 35 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
)
|
)
|
||||||
|
|
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 => {
|
||||||
|
|
Loading…
Add table
Reference in a new issue