Compare commits
No commits in common. "2078dd0d8e5a72f9539bdb6fcb7b81a5f0471169" and "bcb734846d77b388c1a26d97b6c349a0d032f114" have entirely different histories.
2078dd0d8e
...
bcb734846d
24
Cargo.lock
generated
24
Cargo.lock
generated
@ -534,12 +534,6 @@ dependencies = [
|
|||||||
"unicode-xid",
|
"unicode-xid",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "diff"
|
|
||||||
version = "0.1.13"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "displaydoc"
|
name = "displaydoc"
|
||||||
version = "0.2.5"
|
version = "0.2.5"
|
||||||
@ -1034,6 +1028,7 @@ dependencies = [
|
|||||||
"camino",
|
"camino",
|
||||||
"derive_more",
|
"derive_more",
|
||||||
"luaffi",
|
"luaffi",
|
||||||
|
"luaify",
|
||||||
"luajit",
|
"luajit",
|
||||||
"sysexits",
|
"sysexits",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
@ -1144,7 +1139,6 @@ dependencies = [
|
|||||||
name = "luaify"
|
name = "luaify"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"pretty_assertions",
|
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn",
|
||||||
@ -1417,16 +1411,6 @@ dependencies = [
|
|||||||
"zerocopy",
|
"zerocopy",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pretty_assertions"
|
|
||||||
version = "1.4.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d"
|
|
||||||
dependencies = [
|
|
||||||
"diff",
|
|
||||||
"yansi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "prettyplease"
|
name = "prettyplease"
|
||||||
version = "0.2.35"
|
version = "0.2.35"
|
||||||
@ -2363,12 +2347,6 @@ version = "0.6.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb"
|
checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "yansi"
|
|
||||||
version = "1.0.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "yoke"
|
name = "yoke"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
|
@ -16,3 +16,7 @@ sysexits = "0.9.0"
|
|||||||
thiserror = "2.0.12"
|
thiserror = "2.0.12"
|
||||||
tokio = { version = "1.45.1", features = ["rt", "time", "fs", "net", "process", "signal", "tracing"] }
|
tokio = { version = "1.45.1", features = ["rt", "time", "fs", "net", "process", "signal", "tracing"] }
|
||||||
tracing = "0.1.41"
|
tracing = "0.1.41"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
luaify = { path = "../luaify" }
|
||||||
|
tokio = { version = "1.45.1", features = ["full"] }
|
||||||
|
5
crates/lb/src/runtime.lua
Normal file
5
crates/lb/src/runtime.lua
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
local task = require("lb:task")
|
||||||
|
|
||||||
|
function spawn(f, ...)
|
||||||
|
return task:spawn(f, ...)
|
||||||
|
end
|
@ -1,3 +1,4 @@
|
|||||||
|
use crate::{chan::lb_chanlib, fs::lb_fslib, net::lb_netlib, task::lb_tasklib};
|
||||||
use derive_more::{Deref, DerefMut};
|
use derive_more::{Deref, DerefMut};
|
||||||
use luaffi::{Registry, Type};
|
use luaffi::{Registry, Type};
|
||||||
use luajit::{Chunk, State};
|
use luajit::{Chunk, State};
|
||||||
@ -14,13 +15,15 @@ pub struct Builder {
|
|||||||
|
|
||||||
impl Builder {
|
impl Builder {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
let mut registry = Registry::new();
|
||||||
registry: Registry::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn registry(&self) -> &Registry {
|
registry
|
||||||
&self.registry
|
.preload::<lb_tasklib>("lb:task")
|
||||||
|
.preload::<lb_chanlib>("lb:channel")
|
||||||
|
.preload::<lb_fslib>("lb:fs")
|
||||||
|
.preload::<lb_netlib>("lb:net");
|
||||||
|
|
||||||
|
Self { registry }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn module<T: Type>(&mut self, name: impl Display) -> &mut Self {
|
pub fn module<T: Type>(&mut self, name: impl Display) -> &mut Self {
|
||||||
@ -28,11 +31,18 @@ impl Builder {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn registry(&self) -> &Registry {
|
||||||
|
&self.registry
|
||||||
|
}
|
||||||
|
|
||||||
pub fn build(&self) -> luajit::Result<Runtime> {
|
pub fn build(&self) -> luajit::Result<Runtime> {
|
||||||
Ok(Runtime {
|
Ok(Runtime {
|
||||||
state: {
|
state: {
|
||||||
let mut s = State::new()?;
|
let mut s = State::new()?;
|
||||||
s.eval(Chunk::new(self.registry.build()).path("[luby]"), 0, 0)?;
|
let mut chunk = Chunk::new(self.registry.done());
|
||||||
|
chunk.extend(include_bytes!("./runtime.lua"));
|
||||||
|
// println!("{chunk}");
|
||||||
|
s.eval(chunk.path("[luby]"), 0, 0)?;
|
||||||
s
|
s
|
||||||
},
|
},
|
||||||
tasks: LocalSet::new(),
|
tasks: LocalSet::new(),
|
||||||
@ -63,9 +73,6 @@ impl Runtime {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn spawn<T: 'static>(f: impl AsyncFnOnce(&mut State) -> T + 'static) -> JoinHandle<T> {
|
pub fn spawn<T: 'static>(f: impl AsyncFnOnce(&mut State) -> T + 'static) -> JoinHandle<T> {
|
||||||
// SAFETY: `new_thread` must be called inside `spawn_local` because this free-standing spawn
|
|
||||||
// function may be called via ffi from lua, and it is not safe to access the lua state within
|
|
||||||
// ffi calls.
|
|
||||||
spawn_local(async move { f(&mut STATE.with(|s| s.new_thread())).await })
|
spawn_local(async move { f(&mut STATE.with(|s| s.new_thread())).await })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
32
crates/lb/tests/net.rs
Normal file
32
crates/lb/tests/net.rs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
use lb::runtime;
|
||||||
|
use luaify::luaify;
|
||||||
|
use luajit::{Chunk, LoadMode};
|
||||||
|
use tokio::test;
|
||||||
|
|
||||||
|
async fn run_lua(s: &'static str) {
|
||||||
|
let rt = runtime::Builder::new().build().unwrap();
|
||||||
|
let task = rt.spawn(async move |state| {
|
||||||
|
println!("executing test chunk: {s}");
|
||||||
|
|
||||||
|
state
|
||||||
|
.load(Chunk::new(s).mode(LoadMode::TEXT))
|
||||||
|
.unwrap_or_else(|err| panic!("{err}"));
|
||||||
|
|
||||||
|
state
|
||||||
|
.call_async(0, 0)
|
||||||
|
.await
|
||||||
|
.unwrap_or_else(|err| panic!("{err}"));
|
||||||
|
});
|
||||||
|
|
||||||
|
rt.await;
|
||||||
|
task.await.unwrap_or_else(|err| panic!("{err}"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
async fn ipaddr() {
|
||||||
|
run_lua(luaify!({
|
||||||
|
let net = require("lb:net");
|
||||||
|
print(net.ipaddr("127.0.0.1"));
|
||||||
|
}))
|
||||||
|
.await
|
||||||
|
}
|
35
crates/lb/tests/task.rs
Normal file
35
crates/lb/tests/task.rs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
use lb::runtime;
|
||||||
|
use luaify::luaify;
|
||||||
|
use luajit::{Chunk, LoadMode};
|
||||||
|
use tokio::test;
|
||||||
|
|
||||||
|
async fn run_lua(s: &'static str) {
|
||||||
|
let rt = runtime::Builder::new().build().unwrap();
|
||||||
|
let task = rt.spawn(async move |state| {
|
||||||
|
println!("executing test chunk: {s}");
|
||||||
|
|
||||||
|
state
|
||||||
|
.load(Chunk::new(s).mode(LoadMode::TEXT))
|
||||||
|
.unwrap_or_else(|err| panic!("{err}"));
|
||||||
|
|
||||||
|
state
|
||||||
|
.call_async(0, 0)
|
||||||
|
.await
|
||||||
|
.unwrap_or_else(|err| panic!("{err}"));
|
||||||
|
});
|
||||||
|
|
||||||
|
rt.await;
|
||||||
|
task.await.unwrap_or_else(|err| panic!("{err}"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
async fn task_test() {
|
||||||
|
run_lua(luaify!({
|
||||||
|
let thing = spawn(|| {
|
||||||
|
print("spawn callback!!!!!!!!!!!!!");
|
||||||
|
});
|
||||||
|
print("thing is", thing);
|
||||||
|
//
|
||||||
|
}))
|
||||||
|
.await
|
||||||
|
}
|
@ -171,7 +171,7 @@ impl Registry {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build(&self) -> String {
|
pub fn done(&self) -> String {
|
||||||
self.to_string()
|
self.to_string()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,3 @@ proc-macro = true
|
|||||||
proc-macro2 = "1.0.95"
|
proc-macro2 = "1.0.95"
|
||||||
quote = "1.0.40"
|
quote = "1.0.40"
|
||||||
syn = { version = "2.0.103", features = ["full", "visit-mut"] }
|
syn = { version = "2.0.103", features = ["full", "visit-mut"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
|
||||||
pretty_assertions = "1.4.1"
|
|
||||||
|
@ -14,12 +14,6 @@ pub fn generate(expr: &Expr) -> Result<TokenStream> {
|
|||||||
Ok(f.done())
|
Ok(f.done())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_chunk(block: &Block) -> Result<TokenStream> {
|
|
||||||
let mut f = Formatter::default();
|
|
||||||
generate_block(&mut f, &block, Context::stmt(false))?;
|
|
||||||
Ok(f.done())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct Formatter {
|
struct Formatter {
|
||||||
buf: String,
|
buf: String,
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
use crate::{
|
use crate::{generate::generate, transform::transform};
|
||||||
generate::{generate, generate_chunk},
|
|
||||||
transform::{transform, transform_chunk},
|
|
||||||
};
|
|
||||||
use proc_macro::TokenStream as TokenStream1;
|
use proc_macro::TokenStream as TokenStream1;
|
||||||
use quote::ToTokens;
|
use quote::ToTokens;
|
||||||
use syn::parse_macro_input;
|
use syn::parse_macro_input;
|
||||||
@ -19,13 +16,3 @@ pub fn luaify(input: TokenStream1) -> TokenStream1 {
|
|||||||
}
|
}
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[proc_macro]
|
|
||||||
pub fn luaify_chunk(input: TokenStream1) -> TokenStream1 {
|
|
||||||
let mut block = parse_macro_input!(input);
|
|
||||||
match transform_chunk(&mut block).and_then(|()| generate_chunk(&block)) {
|
|
||||||
Ok(s) => s,
|
|
||||||
Err(err) => err.into_compile_error().into_token_stream(),
|
|
||||||
}
|
|
||||||
.into()
|
|
||||||
}
|
|
||||||
|
@ -9,12 +9,6 @@ pub fn transform(expr: &mut Expr) -> Result<()> {
|
|||||||
visitor.result
|
visitor.result
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn transform_chunk(block: &mut Block) -> Result<()> {
|
|
||||||
let mut visitor = Visitor::new();
|
|
||||||
visitor.visit_block_mut(block);
|
|
||||||
visitor.result
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Visitor {
|
struct Visitor {
|
||||||
result: Result<()>,
|
result: Result<()>,
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
use luaify::{luaify, luaify_chunk};
|
use luaify::luaify;
|
||||||
use pretty_assertions::assert_eq;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn raw_ident() {
|
fn raw_ident() {
|
||||||
@ -403,19 +402,3 @@ fn length() {
|
|||||||
r#"local a,b,c=#a,#b,#c;"#
|
r#"local a,b,c=#a,#b,#c;"#
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn chunk() {
|
|
||||||
assert_eq!(
|
|
||||||
luaify_chunk!({
|
|
||||||
if a == b {
|
|
||||||
c()
|
|
||||||
} else if b == c {
|
|
||||||
a()
|
|
||||||
} else {
|
|
||||||
d()
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
"if a==b then c();elseif b==c then a();else d();end;"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
15
src/lib.rs
15
src/lib.rs
@ -1,14 +1 @@
|
|||||||
pub use lb::chan;
|
pub use lb::*;
|
||||||
pub use lb::fs;
|
|
||||||
pub use lb::net;
|
|
||||||
pub use lb::task;
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub fn load_modules(runtime: &mut lb::runtime::Builder) {
|
|
||||||
// core modules
|
|
||||||
runtime
|
|
||||||
.module::<task::lb_tasklib>("lb:task")
|
|
||||||
.module::<chan::lb_chanlib>("lb:channel")
|
|
||||||
.module::<fs::lb_fslib>("lb:fs")
|
|
||||||
.module::<net::lb_netlib>("lb:net");
|
|
||||||
}
|
|
||||||
|
31
src/main.rs
31
src/main.rs
@ -121,6 +121,13 @@ impl Args {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn exit_err<T, E: Display>(code: ExitCode) -> impl FnOnce(E) -> T {
|
||||||
|
move |err| {
|
||||||
|
eprintln!("{}", err.red().bold());
|
||||||
|
code.exit()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
panic::set_hook(Box::new(panic_cb));
|
panic::set_hook(Box::new(panic_cb));
|
||||||
|
|
||||||
@ -153,13 +160,6 @@ fn print_version() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unwrap_exit<T, E: Display>(code: ExitCode) -> impl FnOnce(E) -> T {
|
|
||||||
move |err| {
|
|
||||||
eprintln!("{}", err.red().bold());
|
|
||||||
code.exit()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn init_logger(args: &Args) {
|
fn init_logger(args: &Args) {
|
||||||
use tracing::level_filters::LevelFilter;
|
use tracing::level_filters::LevelFilter;
|
||||||
use tracing_subscriber::{Layer, util::*};
|
use tracing_subscriber::{Layer, util::*};
|
||||||
@ -202,18 +202,17 @@ fn init_tokio(args: &Args) -> tokio::runtime::Runtime {
|
|||||||
.thread_name("luby")
|
.thread_name("luby")
|
||||||
.max_blocking_threads(args.blocking_threads.get())
|
.max_blocking_threads(args.blocking_threads.get())
|
||||||
.build()
|
.build()
|
||||||
.unwrap_or_else(unwrap_exit(ExitCode::OsErr))
|
.unwrap_or_else(exit_err(ExitCode::OsErr))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init_lua(args: &Args) -> lb::runtime::Runtime {
|
fn init_lua(args: &Args) -> lb::runtime::Runtime {
|
||||||
let mut rt = lb::runtime::Builder::new();
|
let rt = lb::runtime::Builder::new();
|
||||||
luby::load_modules(&mut rt);
|
|
||||||
|
|
||||||
if args.dump.iter().find(|s| *s == "cdef").is_some() {
|
if args.dump.iter().find(|s| *s == "cdef").is_some() {
|
||||||
print!("{}", rt.registry());
|
print!("{}", rt.registry());
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut rt = rt.build().unwrap();
|
let mut rt = rt.build().unwrap_or_else(exit_err(ExitCode::Software));
|
||||||
|
|
||||||
for arg in args.jit.iter() {
|
for arg in args.jit.iter() {
|
||||||
let mut s = rt.guard();
|
let mut s = rt.guard();
|
||||||
@ -236,7 +235,7 @@ fn init_lua(args: &Args) -> lb::runtime::Runtime {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.unwrap_or_else(unwrap_exit(ExitCode::Usage));
|
.unwrap_or_else(exit_err(ExitCode::Usage));
|
||||||
}
|
}
|
||||||
|
|
||||||
rt
|
rt
|
||||||
@ -244,9 +243,9 @@ fn init_lua(args: &Args) -> lb::runtime::Runtime {
|
|||||||
|
|
||||||
fn parse_jitlib_cmd(s: &str) -> Option<(&str, &str)> {
|
fn parse_jitlib_cmd(s: &str) -> Option<(&str, &str)> {
|
||||||
match s {
|
match s {
|
||||||
"p" => Some(("p", "Flspv10")), // default -jp flags
|
"p" => Some(("p", "Flspv10")),
|
||||||
"v" => Some(("v", "-")), // default -jv flags
|
"v" => Some(("v", "-")),
|
||||||
"dump" => Some(("dump", "tirs")), // default -jdump flags
|
"dump" => Some(("dump", "tirs")),
|
||||||
_ => s.split_once('='),
|
_ => s.split_once('='),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -263,7 +262,7 @@ async fn main_async(args: Args, state: &mut luajit::State) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
s.load(&luajit::Chunk::new(chunk).path(path))
|
s.load(&luajit::Chunk::new(chunk).path(path))
|
||||||
.unwrap_or_else(unwrap_exit(ExitCode::NoInput));
|
.unwrap_or_else(exit_err(ExitCode::NoInput));
|
||||||
|
|
||||||
if let Err(err) = s.call_async(0, 0).await {
|
if let Err(err) = s.call_async(0, 0).await {
|
||||||
match err.trace() {
|
match err.trace() {
|
||||||
|
19
test.lua
Normal file
19
test.lua
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
local fs = require("lb:fs")
|
||||||
|
|
||||||
|
-- do
|
||||||
|
-- local start = os.clock()
|
||||||
|
-- for i = 1, 50000 do
|
||||||
|
-- fs:read("crates/luaffi_impl/src/metatype.rs")
|
||||||
|
-- end
|
||||||
|
-- local finish = os.clock()
|
||||||
|
-- print("finish in " .. (finish - start))
|
||||||
|
-- end
|
||||||
|
|
||||||
|
do
|
||||||
|
local start = os.clock()
|
||||||
|
for i = 1, 30000 do
|
||||||
|
fs:read_sync("bacon.toml")
|
||||||
|
end
|
||||||
|
local finish = os.clock()
|
||||||
|
print("finish in " .. (finish - start))
|
||||||
|
end
|
Loading…
x
Reference in New Issue
Block a user