Compare commits
No commits in common. "5c257b0f7478b95f36a23b472399e80569993495" and "8c406a46b36f1a33cc2a5c19c111b887b26027f4" have entirely different histories.
5c257b0f74
...
8c406a46b3
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -1053,7 +1053,6 @@ dependencies = [
|
|||||||
"derive_more",
|
"derive_more",
|
||||||
"globset",
|
"globset",
|
||||||
"luaffi",
|
"luaffi",
|
||||||
"luaify",
|
|
||||||
"luajit",
|
"luajit",
|
||||||
"sysexits",
|
"sysexits",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
@ -1169,6 +1168,7 @@ dependencies = [
|
|||||||
"bstr",
|
"bstr",
|
||||||
"luaffi",
|
"luaffi",
|
||||||
"luajit-sys",
|
"luajit-sys",
|
||||||
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -35,9 +35,8 @@ name = "main"
|
|||||||
harness = false
|
harness = false
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["task", "time", "fs", "net"]
|
default = ["task", "fs", "net"]
|
||||||
task = ["lb/task"]
|
task = ["lb/task"]
|
||||||
time = ["lb/time"]
|
|
||||||
fs = ["lb/fs"]
|
fs = ["lb/fs"]
|
||||||
net = ["lb/net"]
|
net = ["lb/net"]
|
||||||
tokio-console = ["dep:console-subscriber"]
|
tokio-console = ["dep:console-subscriber"]
|
||||||
|
@ -1,11 +1,3 @@
|
|||||||
default_job = "test"
|
|
||||||
|
|
||||||
[jobs.test]
|
|
||||||
command = ["cargo", "test"]
|
|
||||||
watch = ["*.lua"]
|
|
||||||
need_stdout = true
|
|
||||||
background = false
|
|
||||||
|
|
||||||
[jobs.doc]
|
[jobs.doc]
|
||||||
command = ["cargo", "doc", "--workspace"]
|
command = ["cargo", "doc", "--workspace"]
|
||||||
|
|
||||||
|
@ -10,7 +10,6 @@ repository.workspace = true
|
|||||||
[features]
|
[features]
|
||||||
runtime = ["tokio/rt"]
|
runtime = ["tokio/rt"]
|
||||||
task = ["tokio/rt", "tokio/time"]
|
task = ["tokio/rt", "tokio/time"]
|
||||||
time = []
|
|
||||||
fs = ["tokio/fs", "dep:walkdir", "dep:globset", "dep:tempfile"]
|
fs = ["tokio/fs", "dep:walkdir", "dep:globset", "dep:tempfile"]
|
||||||
net = ["tokio/net", "tokio/io-util"]
|
net = ["tokio/net", "tokio/io-util"]
|
||||||
|
|
||||||
@ -18,7 +17,6 @@ net = ["tokio/net", "tokio/io-util"]
|
|||||||
derive_more = { version = "2.0.1", features = ["full"] }
|
derive_more = { version = "2.0.1", features = ["full"] }
|
||||||
globset = { version = "0.4.16", optional = true }
|
globset = { version = "0.4.16", optional = true }
|
||||||
luaffi = { path = "../luaffi" }
|
luaffi = { path = "../luaffi" }
|
||||||
luaify = { path = "../luaify" }
|
|
||||||
luajit = { path = "../luajit" }
|
luajit = { path = "../luajit" }
|
||||||
sysexits = "0.9.0"
|
sysexits = "0.9.0"
|
||||||
tempfile = { version = "3.20.0", optional = true }
|
tempfile = { version = "3.20.0", optional = true }
|
||||||
|
@ -11,7 +11,7 @@ use luaffi::{cdef, metatype};
|
|||||||
/// Items exported by the `lb:chan` library.
|
/// Items exported by the `lb:chan` library.
|
||||||
///
|
///
|
||||||
/// This library can be acquired by calling
|
/// This library can be acquired by calling
|
||||||
/// [`require("lb:chan")`](https://www.lua.org/manual/5.1/manual.html#pdf-require).
|
/// [`require("lb:chan")`](https://www.lua.org/manual/5.1/manual.html#pdf-require) in Lua.
|
||||||
///
|
///
|
||||||
/// ```lua
|
/// ```lua
|
||||||
/// local chan = require("lb:chan");
|
/// local chan = require("lb:chan");
|
||||||
|
@ -22,14 +22,14 @@ use thiserror::Error;
|
|||||||
|
|
||||||
/// Errors that can be thrown by this library.
|
/// Errors that can be thrown by this library.
|
||||||
///
|
///
|
||||||
/// Functions which return this error will **throw**. The error message can be caught by using
|
/// Functions which return this error will **throw** in Lua. The error message can be caught by
|
||||||
/// [`pcall(f, ...)`](https://www.lua.org/manual/5.1/manual.html#pdf-pcall).
|
/// using [`pcall(f, ...)`](https://www.lua.org/manual/5.1/manual.html#pdf-pcall).
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
/// Attempt to access an object while it is being modified.
|
/// Attempt to access an object while it is being modified.
|
||||||
#[error("cannot access object while it is being modified")]
|
#[error("cannot access object while it is being modified")]
|
||||||
Borrow(#[from] BorrowError),
|
Borrow(#[from] BorrowError),
|
||||||
/// Attempt to modify an object while it is in use.
|
/// Attempt to modify an object while it is in use
|
||||||
#[error("cannot modify object while it is in use")]
|
#[error("cannot modify object while it is in use")]
|
||||||
BorrowMut(#[from] BorrowMutError),
|
BorrowMut(#[from] BorrowMutError),
|
||||||
/// I/O error.
|
/// I/O error.
|
||||||
@ -48,7 +48,7 @@ type Result<T> = std::result::Result<T, Error>;
|
|||||||
/// Items exported by the `lb:fs` library.
|
/// Items exported by the `lb:fs` library.
|
||||||
///
|
///
|
||||||
/// This library can be acquired by calling
|
/// This library can be acquired by calling
|
||||||
/// [`require("lb:fs")`](https://www.lua.org/manual/5.1/manual.html#pdf-require).
|
/// [`require("lb:fs")`](https://www.lua.org/manual/5.1/manual.html#pdf-require) in Lua.
|
||||||
///
|
///
|
||||||
/// ```lua
|
/// ```lua
|
||||||
/// local fs = require("lb:fs");
|
/// local fs = require("lb:fs");
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
//! luby standard library
|
//! luby standard library
|
||||||
|
#![warn(missing_docs)]
|
||||||
#[cfg(feature = "task")]
|
#[cfg(feature = "task")]
|
||||||
pub mod chan;
|
pub mod chan;
|
||||||
#[cfg(feature = "fs")]
|
#[cfg(feature = "fs")]
|
||||||
@ -9,5 +10,3 @@ pub mod net;
|
|||||||
pub mod runtime;
|
pub mod runtime;
|
||||||
#[cfg(feature = "task")]
|
#[cfg(feature = "task")]
|
||||||
pub mod task;
|
pub mod task;
|
||||||
#[cfg(feature = "time")]
|
|
||||||
pub mod time;
|
|
||||||
|
@ -28,14 +28,14 @@ use tokio::{
|
|||||||
|
|
||||||
/// Errors that can be thrown by this library.
|
/// Errors that can be thrown by this library.
|
||||||
///
|
///
|
||||||
/// Functions which return this error will **throw**. The error message can be caught by using
|
/// Functions which return this error will **throw** in Lua. The error message can be caught by
|
||||||
/// [`pcall(f, ...)`](https://www.lua.org/manual/5.1/manual.html#pdf-pcall).
|
/// using [`pcall(f, ...)`](https://www.lua.org/manual/5.1/manual.html#pdf-pcall).
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
/// Attempt to access an object while it is being modified.
|
/// Attempt to access an object while it is being modified.
|
||||||
#[error("cannot access object while it is being modified")]
|
#[error("cannot access object while it is being modified")]
|
||||||
Borrow(#[from] BorrowError),
|
Borrow(#[from] BorrowError),
|
||||||
/// Attempt to modify an object while it is in use.
|
/// Attempt to modify an object while it is in use
|
||||||
#[error("cannot modify object while it is in use")]
|
#[error("cannot modify object while it is in use")]
|
||||||
BorrowMut(#[from] BorrowMutError),
|
BorrowMut(#[from] BorrowMutError),
|
||||||
/// I/O error.
|
/// I/O error.
|
||||||
@ -54,7 +54,7 @@ type Result<T> = std::result::Result<T, Error>;
|
|||||||
/// Items exported by the `lb:net` library.
|
/// Items exported by the `lb:net` library.
|
||||||
///
|
///
|
||||||
/// This library can be acquired by calling
|
/// This library can be acquired by calling
|
||||||
/// [`require("lb:net")`](https://www.lua.org/manual/5.1/manual.html#pdf-require).
|
/// [`require("lb:net")`](https://www.lua.org/manual/5.1/manual.html#pdf-require) in Lua.
|
||||||
///
|
///
|
||||||
/// ```lua
|
/// ```lua
|
||||||
/// local net = require("lb:net");
|
/// local net = require("lb:net");
|
||||||
@ -501,9 +501,9 @@ impl lb_ipaddr {
|
|||||||
|
|
||||||
/// Socket address, which is an IP address with a port number.
|
/// Socket address, which is an IP address with a port number.
|
||||||
///
|
///
|
||||||
/// This represents an IP address with a prescribed port, such as `127.0.0.1:8080` or `[::1]:443`.
|
/// This represents a combination of an IP address and a port, such as `127.0.0.1:8080` or
|
||||||
/// It is used to specify endpoints for network connections and listeners, and can be constructed by
|
/// `[::1]:443`. It is used to specify endpoints for network connections and listeners, and can be
|
||||||
/// [`socketaddr`](lb_netlib::socketaddr).
|
/// constructed by [`socketaddr`](lb_libnet::socketaddr).
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, From, FromStr)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, From, FromStr)]
|
||||||
#[cdef]
|
#[cdef]
|
||||||
pub struct lb_socketaddr(#[opaque] SocketAddr);
|
pub struct lb_socketaddr(#[opaque] SocketAddr);
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
#![doc(hidden)]
|
#![doc(hidden)]
|
||||||
use derive_more::{Deref, DerefMut};
|
use derive_more::{Deref, DerefMut};
|
||||||
use luaffi::{Module, Registry};
|
use luaffi::{Module, Registry};
|
||||||
use luaify::luaify_chunk;
|
use luajit::{Chunk, State};
|
||||||
use luajit::{Chunk, Index, NewTable, State};
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use tokio::{
|
use tokio::{
|
||||||
task::{JoinHandle, LocalSet, futures::TaskLocalFuture, spawn_local},
|
task::{JoinHandle, LocalSet, futures::TaskLocalFuture, spawn_local},
|
||||||
@ -14,7 +13,6 @@ pub type ErrorFn = dyn Fn(&luajit::Error);
|
|||||||
pub struct Builder {
|
pub struct Builder {
|
||||||
registry: Registry,
|
registry: Registry,
|
||||||
report_err: Rc<ErrorFn>,
|
report_err: Rc<ErrorFn>,
|
||||||
prohibit_globals: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Builder {
|
impl Builder {
|
||||||
@ -25,7 +23,6 @@ impl Builder {
|
|||||||
Some(trace) => eprintln!("unhandled lua error: {err}\n{trace}"),
|
Some(trace) => eprintln!("unhandled lua error: {err}\n{trace}"),
|
||||||
None => eprintln!("unhandled lua error: {err}"),
|
None => eprintln!("unhandled lua error: {err}"),
|
||||||
}),
|
}),
|
||||||
prohibit_globals: false,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,42 +35,19 @@ impl Builder {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prohibit_globals(&mut self, enabled: bool) -> &mut Self {
|
|
||||||
self.prohibit_globals = enabled;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn module<T: Module>(&mut self) -> &mut Self {
|
pub fn module<T: Module>(&mut self) -> &mut Self {
|
||||||
self.registry.preload::<T>();
|
self.registry.preload::<T>();
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build(&self) -> luajit::Result<Runtime> {
|
pub fn build(&self) -> luajit::Result<Runtime> {
|
||||||
let mut state = State::new()?;
|
|
||||||
let chunk = Chunk::new(self.registry.build()).with_path("[luby]");
|
|
||||||
state.eval(&chunk, 0, Some(0))?;
|
|
||||||
|
|
||||||
if self.prohibit_globals {
|
|
||||||
let mut s = state.guard();
|
|
||||||
s.eval(
|
|
||||||
&Chunk::new(luaify_chunk!({
|
|
||||||
return |self, key, value| {
|
|
||||||
error(("undeclared local variable '%s'").format(key), 2);
|
|
||||||
};
|
|
||||||
})),
|
|
||||||
0,
|
|
||||||
Some(1),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
s.push(NewTable::new());
|
|
||||||
(s.push("__index"), s.push_idx(-3), s.set(-3));
|
|
||||||
(s.push("__newindex"), s.push_idx(-3), s.set(-3));
|
|
||||||
s.set_metatable(Index::globals());
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(Runtime {
|
Ok(Runtime {
|
||||||
cx: Context {
|
cx: Context {
|
||||||
state,
|
state: {
|
||||||
|
let mut s = State::new()?;
|
||||||
|
s.eval(Chunk::new(self.registry.build()).path("[luby]"), 0, 0)?;
|
||||||
|
s
|
||||||
|
},
|
||||||
report_err: self.report_err.clone(),
|
report_err: self.report_err.clone(),
|
||||||
},
|
},
|
||||||
tasks: LocalSet::new(),
|
tasks: LocalSet::new(),
|
||||||
@ -123,7 +97,7 @@ pub struct Context {
|
|||||||
impl Context {
|
impl Context {
|
||||||
pub fn new_thread(&self) -> Self {
|
pub fn new_thread(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
state: State::new_thread(&self.state),
|
state: self.state.new_thread(),
|
||||||
report_err: self.report_err.clone(),
|
report_err: self.report_err.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,13 +12,14 @@ use luaffi::{
|
|||||||
marker::{function, many},
|
marker::{function, many},
|
||||||
metatype,
|
metatype,
|
||||||
};
|
};
|
||||||
|
use luajit::LUA_MULTRET;
|
||||||
use std::{cell::RefCell, ffi::c_int, time::Duration};
|
use std::{cell::RefCell, ffi::c_int, time::Duration};
|
||||||
use tokio::{task::JoinHandle, time::sleep};
|
use tokio::{task::JoinHandle, time::sleep};
|
||||||
|
|
||||||
/// Items exported by the `lb:task` library.
|
/// Items exported by the `lb:task` library.
|
||||||
///
|
///
|
||||||
/// This library can be acquired by calling
|
/// This library can be acquired by calling
|
||||||
/// [`require("lb:task")`](https://www.lua.org/manual/5.1/manual.html#pdf-require).
|
/// [`require("lb:task")`](https://www.lua.org/manual/5.1/manual.html#pdf-require) in Lua.
|
||||||
///
|
///
|
||||||
/// ```lua
|
/// ```lua
|
||||||
/// local task = require("lb:task");
|
/// local task = require("lb:task");
|
||||||
@ -58,12 +59,12 @@ impl lb_tasklib {
|
|||||||
extern "Lua-C" fn __spawn(spawn_ref: c_int, handle_ref: c_int) -> lb_task {
|
extern "Lua-C" fn __spawn(spawn_ref: c_int, handle_ref: c_int) -> lb_task {
|
||||||
let handle = spawn(async move |cx| {
|
let handle = spawn(async move |cx| {
|
||||||
// SAFETY: handle_ref is always unique, created in Self::spawn above.
|
// SAFETY: handle_ref is always unique, created in Self::spawn above.
|
||||||
let state = unsafe { luajit::Ref::from_raw(cx, spawn_ref) };
|
let state = unsafe { cx.new_ref_unchecked(spawn_ref) };
|
||||||
let mut s = cx.guard();
|
let mut s = cx.guard();
|
||||||
s.resize(0);
|
s.resize(0);
|
||||||
s.push(state); // this drops the state table ref, but the table is still on the stack
|
s.push(state); // this drops the state table ref, but the table is still on the stack
|
||||||
let narg = s.unpack(1, 1, None) - 1; // unpack the function and its args from the state table
|
let narg = s.unpack(1, 1, None) - 1; // unpack the function and its args from the state table
|
||||||
match s.call_async(narg, None).await {
|
match s.call_async(narg, LUA_MULTRET).await {
|
||||||
Ok(nret) => {
|
Ok(nret) => {
|
||||||
s.pack(1, nret); // pack the return values back into the state table
|
s.pack(1, nret); // pack the return values back into the state table
|
||||||
}
|
}
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
use luaffi::{cdef, metatype};
|
|
||||||
|
|
||||||
#[cdef(module = "lb:time")]
|
|
||||||
pub struct lb_timelib;
|
|
||||||
|
|
||||||
#[metatype]
|
|
||||||
impl lb_timelib {
|
|
||||||
#[new]
|
|
||||||
extern "Lua-C" fn new() -> Self {
|
|
||||||
Self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub extern "Lua-C" fn instant() -> lb_instant {
|
|
||||||
lb_instant::new(std::time::Instant::now())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cdef]
|
|
||||||
pub struct lb_instant(#[opaque] std::time::Instant);
|
|
||||||
|
|
||||||
#[metatype]
|
|
||||||
impl lb_instant {
|
|
||||||
fn new(instant: std::time::Instant) -> Self {
|
|
||||||
Self(instant)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub extern "Lua-C" fn elapsed(&self) -> f64 {
|
|
||||||
self.0.elapsed().as_secs_f64()
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,3 @@
|
|||||||
//! # luaify
|
|
||||||
//!
|
|
||||||
//! A Rust for generating Lua code from Rust syntax.
|
|
||||||
use crate::{
|
use crate::{
|
||||||
generate::{generate, generate_chunk},
|
generate::{generate, generate_chunk},
|
||||||
transform::{transform, transform_chunk},
|
transform::{transform, transform_chunk},
|
||||||
|
@ -16,3 +16,4 @@ bitflags = { version = "2.9.1", features = ["std"] }
|
|||||||
bstr = "1.12.0"
|
bstr = "1.12.0"
|
||||||
luaffi = { path = "../luaffi" }
|
luaffi = { path = "../luaffi" }
|
||||||
luajit-sys = { path = "../luajit-sys" }
|
luajit-sys = { path = "../luajit-sys" }
|
||||||
|
thiserror = "2.0.12"
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -6,8 +6,6 @@ pub use lb::fs;
|
|||||||
pub use lb::net;
|
pub use lb::net;
|
||||||
#[cfg(feature = "task")]
|
#[cfg(feature = "task")]
|
||||||
pub use lb::task;
|
pub use lb::task;
|
||||||
#[cfg(feature = "time")]
|
|
||||||
pub use lb::time;
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub fn open(#[allow(unused)] rt: &mut lb::runtime::Builder) {
|
pub fn open(#[allow(unused)] rt: &mut lb::runtime::Builder) {
|
||||||
@ -15,8 +13,6 @@ pub fn open(#[allow(unused)] rt: &mut lb::runtime::Builder) {
|
|||||||
rt.module::<task::lb_tasklib>();
|
rt.module::<task::lb_tasklib>();
|
||||||
#[cfg(feature = "task")]
|
#[cfg(feature = "task")]
|
||||||
rt.module::<chan::lb_chanlib>();
|
rt.module::<chan::lb_chanlib>();
|
||||||
#[cfg(feature = "time")]
|
|
||||||
rt.module::<time::lb_timelib>();
|
|
||||||
#[cfg(feature = "fs")]
|
#[cfg(feature = "fs")]
|
||||||
rt.module::<fs::lb_fslib>();
|
rt.module::<fs::lb_fslib>();
|
||||||
#[cfg(feature = "net")]
|
#[cfg(feature = "net")]
|
||||||
|
41
src/main.rs
41
src/main.rs
@ -1,5 +1,4 @@
|
|||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use luajit::Chunk;
|
|
||||||
use mimalloc::MiMalloc;
|
use mimalloc::MiMalloc;
|
||||||
use owo_colors::OwoColorize;
|
use owo_colors::OwoColorize;
|
||||||
use std::{backtrace::Backtrace, fmt::Display, num::NonZero, panic, process, thread};
|
use std::{backtrace::Backtrace, fmt::Display, num::NonZero, panic, process, thread};
|
||||||
@ -79,21 +78,12 @@ struct Args {
|
|||||||
#[clap(long, short = 'j', help_heading = "Runtime", value_name = "CMD=FLAGS")]
|
#[clap(long, short = 'j', help_heading = "Runtime", value_name = "CMD=FLAGS")]
|
||||||
jit: Vec<String>,
|
jit: Vec<String>,
|
||||||
|
|
||||||
/// Allow global variables.
|
|
||||||
#[clap(
|
|
||||||
long,
|
|
||||||
help_heading = "Runtime",
|
|
||||||
value_name = "ENABLED",
|
|
||||||
default_value_t = true
|
|
||||||
)]
|
|
||||||
allow_globals: bool,
|
|
||||||
|
|
||||||
/// Number of worker threads.
|
/// Number of worker threads.
|
||||||
#[clap(
|
#[clap(
|
||||||
long,
|
long,
|
||||||
short = 'T',
|
short = 'T',
|
||||||
help_heading = "Runtime",
|
help_heading = "Runtime",
|
||||||
value_name = "COUNT",
|
value_name = "THREADS",
|
||||||
default_value_t = Self::threads()
|
default_value_t = Self::threads()
|
||||||
)]
|
)]
|
||||||
threads: NonZero<usize>,
|
threads: NonZero<usize>,
|
||||||
@ -102,14 +92,14 @@ struct Args {
|
|||||||
#[clap(
|
#[clap(
|
||||||
long,
|
long,
|
||||||
help_heading = "Runtime",
|
help_heading = "Runtime",
|
||||||
value_name = "COUNT",
|
value_name = "THREADS",
|
||||||
default_value_t = Self::blocking_threads()
|
default_value_t = Self::blocking_threads()
|
||||||
)]
|
)]
|
||||||
blocking_threads: NonZero<usize>,
|
blocking_threads: NonZero<usize>,
|
||||||
|
|
||||||
/// Enable tokio-console integration.
|
/// Enable tokio-console integration.
|
||||||
#[cfg(feature = "tokio-console")]
|
#[cfg(feature = "tokio-console")]
|
||||||
#[clap(long, help_heading = "Debugging", value_name = "ENABLED")]
|
#[clap(long, help_heading = "Debugging")]
|
||||||
enable_console: bool,
|
enable_console: bool,
|
||||||
|
|
||||||
/// tokio-console publish address.
|
/// tokio-console publish address.
|
||||||
@ -239,32 +229,27 @@ fn init_lua(args: &Args) -> lb::runtime::Runtime {
|
|||||||
print!("{}", rt.registry()); // for cdef debugging
|
print!("{}", rt.registry()); // for cdef debugging
|
||||||
}
|
}
|
||||||
|
|
||||||
rt.unhandled_error(error_cb)
|
rt.unhandled_error(error_cb).build().unwrap()
|
||||||
.prohibit_globals(!args.allow_globals)
|
|
||||||
.build()
|
|
||||||
.unwrap()
|
|
||||||
};
|
};
|
||||||
|
|
||||||
for arg in args.jit.iter() {
|
for arg in args.jit.iter() {
|
||||||
let mut s = rt.guard();
|
let mut s = rt.guard();
|
||||||
let res = if let Some((cmd, flags)) = parse_jitlib_cmd(arg)
|
let res = if let Some((cmd, flags)) = parse_jitlib_cmd(arg)
|
||||||
&& let Ok(_) = s.require(format!("jit.{cmd}"), Some(1))
|
&& let Ok(_) = s.require(format!("jit.{cmd}"), 1)
|
||||||
{
|
{
|
||||||
(s.push("start"), s.get(-2));
|
(s.push("start"), s.get(-2), s.push(flags));
|
||||||
s.push(flags);
|
s.call(1, 0) // require("jit.{cmd}").start(flags)
|
||||||
s.call(1, Some(0)) // require("jit.{cmd}").start(flags)
|
|
||||||
} else {
|
} else {
|
||||||
s.require("jit", Some(1)).unwrap();
|
s.require("jit", 1).unwrap();
|
||||||
match arg.as_str() {
|
match arg.as_str() {
|
||||||
cmd @ ("on" | "off" | "flush") => {
|
cmd @ ("on" | "off" | "flush") => {
|
||||||
(s.push(cmd), s.get(-2));
|
(s.push(cmd), s.get(-2));
|
||||||
s.call(0, Some(0)) // require("jit").[on/off/flush]()
|
s.call(0, 0) // require("jit").[on/off/flush]()
|
||||||
}
|
}
|
||||||
flags => {
|
flags => {
|
||||||
(s.push("opt"), s.get(-2));
|
(s.push("opt"), s.get(-2));
|
||||||
(s.push("start"), s.get(-2));
|
(s.push("start"), s.get(-2), s.push(flags));
|
||||||
s.push(flags);
|
s.call(1, 0) // require("jit").opt.start(flags)
|
||||||
s.call(1, Some(0)) // require("jit").opt.start(flags)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -297,9 +282,9 @@ async fn main_async(args: Args, cx: &mut lb::runtime::Context) -> ExitCode {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Err(ref err) = cx.load(&Chunk::new(chunk).with_path(path)) {
|
if let Err(ref err) = cx.load(&luajit::Chunk::new(chunk).path(path)) {
|
||||||
cx.report_error(err);
|
cx.report_error(err);
|
||||||
} else if let Err(ref err) = cx.call_async(0, Some(0)).await {
|
} else if let Err(ref err) = cx.call_async(0, 0).await {
|
||||||
cx.report_error(err);
|
cx.report_error(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,32 +1,30 @@
|
|||||||
if (...) ~= nil and (...).type == "group" then return end -- prevent recursive harness call
|
if (...) ~= nil and (...).type == "group" then return end -- prevent recursive harness call
|
||||||
|
|
||||||
local ok = pcall(require, "lb:task")
|
local ok = pcall(require, "lb:task")
|
||||||
if not ok then error("lua test harness requires 'lb:task'") end
|
if not ok then error("lua test harness requires lb:task module") end
|
||||||
local ok, time = pcall(require, "lb:time")
|
|
||||||
if not ok then error("lua test harness requires 'lb:time'") end
|
|
||||||
local ok, fs = pcall(require, "lb:fs")
|
local ok, fs = pcall(require, "lb:fs")
|
||||||
if not ok then error("lua test harness requires 'lb:fs'") end
|
if not ok then error("lua test harness requires lb:fs module") end
|
||||||
|
|
||||||
local global = _G
|
local global = _G
|
||||||
local color = {
|
local colors = {
|
||||||
reset = "\x1b[0m",
|
reset = "\x1b[0m",
|
||||||
pass = "\x1b[32;1m", -- green
|
pass = "\x1b[32;1m",
|
||||||
fail = "\x1b[31;1m", -- red
|
fail = "\x1b[31;1m",
|
||||||
}
|
}
|
||||||
|
|
||||||
local icon = {
|
local icons = {
|
||||||
check = "\u{2713}",
|
check = "\u{2713}",
|
||||||
cross = "\u{00d7}",
|
cross = "\u{00d7}",
|
||||||
chevron = "\u{203a}",
|
chevron = "\u{203a}",
|
||||||
}
|
}
|
||||||
|
|
||||||
local function style(name, s)
|
local function color(name, s)
|
||||||
return ("%s%s%s"):format(color[name], s, color.reset)
|
return ("%s %s %s"):format(colors[name], s, colors.reset)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function create_test(name, f, group)
|
local function create_test(name, f, group)
|
||||||
local test = { type = "test", name = name or "", group = group, state = "pending", f = f }
|
local test = { type = "test", name = name or "", group = group, state = "pending", f = f }
|
||||||
local fenv = setmetatable({}, { __index = global, __newindex = global })
|
local fenv = setmetatable({}, { __index = global })
|
||||||
setfenv(f, fenv)
|
setfenv(f, fenv)
|
||||||
return test
|
return test
|
||||||
end
|
end
|
||||||
@ -45,7 +43,7 @@ local function create_group(name, f, parent)
|
|||||||
table.insert(group.items, item)
|
table.insert(group.items, item)
|
||||||
return item
|
return item
|
||||||
end,
|
end,
|
||||||
}, { __index = global, __newindex = global })
|
}, { __index = global })
|
||||||
|
|
||||||
setfenv(f, fenv)
|
setfenv(f, fenv)
|
||||||
f(group)
|
f(group)
|
||||||
@ -56,24 +54,24 @@ local function name_test(test)
|
|||||||
local name = test.name
|
local name = test.name
|
||||||
local group = test.group
|
local group = test.group
|
||||||
while group ~= nil do
|
while group ~= nil do
|
||||||
if group.name ~= "" then name = ("%s %s %s"):format(group.name, icon.chevron, name) end
|
if group.name ~= "" then name = ("%s %s %s"):format(group.name, icons.chevron, name) end
|
||||||
group = group.parent
|
group = group.parent
|
||||||
end
|
end
|
||||||
return name
|
return name
|
||||||
end
|
end
|
||||||
|
|
||||||
local function trace(msg)
|
local function trace(msg)
|
||||||
return style("fail", msg) .. debug.traceback("", 2):sub(("\nstack traceback:"):len() + 1)
|
return color("fail", msg) .. debug.traceback("", 2):sub(("\nstack traceback:"):len() + 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function run_test(test)
|
local function run_test(test)
|
||||||
local ok, res = xpcall(test.f, trace, test)
|
local ok, res = xpcall(test.f, trace, test)
|
||||||
if ok then
|
if ok then
|
||||||
test.state = "pass"
|
test.state = "pass"
|
||||||
print("", ("%s %s"):format(style("pass", "PASS"), name_test(test)))
|
print("", ("%s %s"):format(color("pass", "PASS"), name_test(test)))
|
||||||
else
|
else
|
||||||
test.state = "fail"
|
test.state = "fail"
|
||||||
print("", ("%s %s\n\n%s\n"):format(style("fail", "FAIL"), name_test(test), res))
|
print("", ("%s %s\n\n%s\n"):format(color("fail", "FAIL"), name_test(test), res))
|
||||||
end
|
end
|
||||||
collectgarbage() -- gc after each test to test destructors
|
collectgarbage() -- gc after each test to test destructors
|
||||||
return test
|
return test
|
||||||
@ -89,7 +87,7 @@ local function start(cx, item)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function check_refs()
|
local function check_unrefs()
|
||||||
-- ensure all refs were properly unref'ed
|
-- ensure all refs were properly unref'ed
|
||||||
local registry = debug.getregistry()
|
local registry = debug.getregistry()
|
||||||
local count = #registry
|
local count = #registry
|
||||||
@ -108,7 +106,7 @@ end
|
|||||||
|
|
||||||
local function main(item)
|
local function main(item)
|
||||||
local cx = { tasks = {} }
|
local cx = { tasks = {} }
|
||||||
local time, pass, fail = time.instant(), 0, 0
|
local pass, fail = 0, 0
|
||||||
start(cx, item)
|
start(cx, item)
|
||||||
for _, task in ipairs(cx.tasks) do
|
for _, task in ipairs(cx.tasks) do
|
||||||
if task:await().state == "pass" then
|
if task:await().state == "pass" then
|
||||||
@ -117,28 +115,22 @@ local function main(item)
|
|||||||
fail = fail + 1
|
fail = fail + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local elapsed = time:elapsed()
|
|
||||||
local code = 1
|
local code = 1
|
||||||
if fail == 0 then
|
if fail == 0 then
|
||||||
print("", style("pass", ("%s %d tests passed"):format(icon.check, pass)))
|
print("", color("pass", ("%s %d tests passed"):format(icons.check, pass)))
|
||||||
code = 0
|
code = 0
|
||||||
else
|
else
|
||||||
print(
|
print(
|
||||||
"",
|
"",
|
||||||
("%s, %s"):format(
|
("%s, %s"):format(
|
||||||
style("pass", ("%s %d tests passed"):format(icon.check, pass)),
|
color("pass", ("%s %d tests passed"):format(icons.check, pass)),
|
||||||
style("fail", ("%s %d tests failed"):format(icon.cross, fail))
|
color("fail", ("%s %d tests failed"):format(icons.cross, fail))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
if elapsed < 1000 then
|
|
||||||
print("", ("%s completed in %.2f ms"):format(icon.chevron, elapsed * 1000))
|
|
||||||
else
|
|
||||||
print("", ("%s completed in %.2f s"):format(icon.chevron, elapsed))
|
|
||||||
end
|
|
||||||
cx = nil
|
cx = nil
|
||||||
collectgarbage()
|
collectgarbage()
|
||||||
check_refs()
|
check_unrefs()
|
||||||
return code -- report error to cargo
|
return code -- report error to cargo
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -10,17 +10,14 @@ fn main() -> ExitCode {
|
|||||||
let lua = {
|
let lua = {
|
||||||
let mut rt = lb::runtime::Builder::new();
|
let mut rt = lb::runtime::Builder::new();
|
||||||
luby::open(&mut rt);
|
luby::open(&mut rt);
|
||||||
rt.unhandled_error(error_cb)
|
rt.unhandled_error(error_cb).build().unwrap()
|
||||||
.prohibit_globals(true)
|
|
||||||
.build()
|
|
||||||
.unwrap()
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let path = "tests/main.lua";
|
let path = "tests/main.lua";
|
||||||
let main = lua.spawn(async move |s| {
|
let main = lua.spawn(async move |s| {
|
||||||
if let Err(ref err) = s.load(&Chunk::new(fs::read(path).unwrap()).with_path(path)) {
|
if let Err(ref err) = s.load(Chunk::new(fs::read(path).unwrap()).path(path)) {
|
||||||
s.report_error(err);
|
s.report_error(err);
|
||||||
} else if let Err(ref err) = s.call_async(0, Some(1)).await {
|
} else if let Err(ref err) = s.call_async(0, 1).await {
|
||||||
s.report_error(err);
|
s.report_error(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user