Piccolo-用纯Rust实现的无栈Lua虚拟机

piccolo - 用纯rust实现的无栈lua虚拟机
piccolo,原名luster,在经过数年的中断后,于2023年4月悄然恢复了开发。曾经开发过 rlua 的 kyren,在底层 gc-arena crate 取得突破后,回到了 piccolo 项目。这两个项目现在已经(小心地)在生产中使用,比如 fish folk 用在了游戏脚本中,ruffle 用于其 actionscript 虚拟机。 如今两个重要版本的发布了:piccolo v0.3.0 和 gc-arena v0.5。 piccolo项目的目标,按大致优先级降序排列:
成为一个可以工作、有用的 lua 解释器。
成为一种简单而可靠的方式,用于安全地隔离不受信任的lua脚本。
抵御来自不受信任脚本的 dos 攻击(脚本不能够导致解释器崩溃或使用无限量的内存,并应保证在有限时间内返回控制权给调用者)。
提供一种安全地将 rust api 绑定到 lua 的简便方法,具有对异常情况和边缘情况具有处理的绑定系统,并且用户类型可以安全地参与运行时垃圾回收。
与某些版本的 puc-rio lua 兼容。
不要过于缓慢(例如,避免不必要的抽象化)。
使用 rust 生成 ip 地址的 png 图片
看起来像是这样:
原文是一个详尽的教程,告诉读者如何一步一步的实现这个例子,感兴趣的可以查看原文。最终实现其实代码很简洁:
use std::{io::cursor, net::socketaddr, sync::oncelock};
use axum::{
extract::connectinfo,
http::{header, statuscode},
response::intoresponse,
routing::get,
router,
};
use image::{imagebuffer, imageoutputformat, rgb};
use imageproc::drawing::draw_text_mut;
use rusttype::{font, scale};
const x: i32 = 8;
const y: i32 = 96;
const width: u32 = 256;
const height: u32 = width;
const text_color: rgb = rgb([235, 219, 178]);
const background_color: rgb = rgb([177, 98, 134]);
const scale: scale = scale { x: 32.0, y: 32.0 };
const font_data: &[u8] = include_bytes!(concat!(
env!(cargo_manifest_dir),
/fonts/ubuntumono-r.ttf
));
#[derive(debug, thiserror::error)]
#[error(failed to generate image: {0})]
struct avatarerror(#[from] image::imageerror);
impl intoresponse for avatarerror {
fn into_response(self) -> axum::response::response {
(statuscode::internal_server_error, self.to_string()).into_response()
}
}
fn font() -> &'static font {
static font: oncelock = oncelock::new();
font.get_or_init(|| font::try_from_bytes(font_data).expect(built-in font data was invalid))
}
async fn avatar(
connectinfo(addr): connectinfo,
) -> result {
// wow, ipv6 causes a lot of headache.
let ip = addr.ip().to_canonical();
letmut img = imagebuffer::from_pixel(width, height, background_color);
draw_text_mut(&mut img, text_color, x, y, scale, font(), hello,);
let y = y + scale.y asi32;
draw_text_mut(&mut img, text_color, x, y, scale, font(), &format!({ip}!));
letmut cursor = cursor::new(vec![]);
img.write_to(&mut cursor, imageoutputformat::png)?;
ok(([(header::content_type, image/png)], cursor.into_inner()))
}
#[tokio::main]
async fn main() -> anyhow::result {
let app = router::new().route(/avatar.png, get(avatar));
let listener = tokio::net::tcplistener::bind([::]:3000).await?;
let make_service = app.into_make_service_with_connect_info::();
axum::serve(listener, make_service).await?;
ok(())
}


分析nfc天线集总参数的几种方法推荐
基于内部区域压实(IZC)的垃圾回收
tdr测试的原理及方法介绍
进入电视领域,荣耀凭什么?
B450主板与B350主板有什么区别 哪个更值得买
Piccolo-用纯Rust实现的无栈Lua虚拟机
这家医疗AI公司要全面“变身”开展区块链业务了?
PCB板子的LOGO添加步骤
长征火箭245飞!成功发射通信技术试验卫星2号
挑选示波器时要注意的几个重要参数
可充电触屏遥控模块电路设计
LDR6020Type-C一拖二同时快充超低成本方案
全球首位3D版AI合成主播“新小微”正式亮相
有线网络通信实验4之TCP服务器
关于KUKA机器人的内部结构介绍
压敏电阻五种过热保护技术分析
中国移动多维度推进5G应用创新发展,推动产业成熟和生态构建
直线模组有哪些配件组成的?
高智能测土配方施肥仪的简单介绍
宁德时代考虑赴港上市,宣布与Stellantis签署战略谅解备忘录