smokes: add curated LLVM runner; archive legacy smokes; PHI-off unified across Bridge/Builder; LLVM resolver tracing; minimal Throw lowering; config env getters; dev profile and root cleaner; docs updated; CI workflow runs curated LLVM (PHI-on/off)

This commit is contained in:
Selfhosting Dev
2025-09-16 23:49:36 +09:00
parent 97a76c0571
commit 5c9213cd03
104 changed files with 8094 additions and 2930 deletions

View File

@ -3,7 +3,10 @@
//! TimeBox: now() -> i64 (unix seconds)
use std::collections::HashMap;
use std::sync::{Mutex, atomic::{AtomicU32, Ordering}};
use std::sync::{
atomic::{AtomicU32, Ordering},
Mutex,
};
// Error codes
const OK: i32 = 0;
@ -37,18 +40,56 @@ static ID: AtomicU32 = AtomicU32::new(1);
// TLV helpers
mod tlv {
pub fn header(argc: u16) -> Vec<u8> { let mut b=Vec::with_capacity(4); b.extend_from_slice(&1u16.to_le_bytes()); b.extend_from_slice(&argc.to_le_bytes()); b }
pub fn encode_handle(buf: &mut Vec<u8>, t: u32, i: u32) { buf.push(8); buf.push(0); buf.push(8); buf.push(0); buf.extend_from_slice(&t.to_le_bytes()); buf.extend_from_slice(&i.to_le_bytes()); }
pub fn encode_i64(buf: &mut Vec<u8>, v: i64) { buf.push(3); buf.push(0); buf.push(8); buf.push(0); buf.extend_from_slice(&v.to_le_bytes()); }
pub fn encode_void(buf: &mut Vec<u8>) { buf.push(9); buf.push(0); buf.push(0); buf.push(0); }
pub fn decode_first(args:&[u8]) -> Option<(u16,u16,usize)> { if args.len()<8 {return None;} let argc=u16::from_le_bytes([args[2],args[3]]); if argc==0{return None;} let tag=u16::from_le_bytes([args[4],args[5]]); let sz=u16::from_le_bytes([args[6],args[7]]); Some((tag,sz,8)) }
pub fn header(argc: u16) -> Vec<u8> {
let mut b = Vec::with_capacity(4);
b.extend_from_slice(&1u16.to_le_bytes());
b.extend_from_slice(&argc.to_le_bytes());
b
}
pub fn encode_handle(buf: &mut Vec<u8>, t: u32, i: u32) {
buf.push(8);
buf.push(0);
buf.push(8);
buf.push(0);
buf.extend_from_slice(&t.to_le_bytes());
buf.extend_from_slice(&i.to_le_bytes());
}
pub fn encode_i64(buf: &mut Vec<u8>, v: i64) {
buf.push(3);
buf.push(0);
buf.push(8);
buf.push(0);
buf.extend_from_slice(&v.to_le_bytes());
}
pub fn encode_void(buf: &mut Vec<u8>) {
buf.push(9);
buf.push(0);
buf.push(0);
buf.push(0);
}
pub fn decode_first(args: &[u8]) -> Option<(u16, u16, usize)> {
if args.len() < 8 {
return None;
}
let argc = u16::from_le_bytes([args[2], args[3]]);
if argc == 0 {
return None;
}
let tag = u16::from_le_bytes([args[4], args[5]]);
let sz = u16::from_le_bytes([args[6], args[7]]);
Some((tag, sz, 8))
}
}
#[no_mangle]
pub extern "C" fn nyash_plugin_abi() -> u32 { 1 }
pub extern "C" fn nyash_plugin_abi() -> u32 {
1
}
#[no_mangle]
pub extern "C" fn nyash_plugin_init() -> i32 { OK }
pub extern "C" fn nyash_plugin_init() -> i32 {
OK
}
#[no_mangle]
pub extern "C" fn nyash_plugin_invoke(
@ -77,31 +118,67 @@ pub extern "C" fn nyash_plugin_invoke(
}
}
unsafe fn birth<T>(tid: u32, map: &Lazy<Mutex<HashMap<u32,T>>>, out: *mut u8, out_len: *mut usize) -> i32 where T: Default {
let need = 4+4+8; if *out_len < need { *out_len = need; return E_SHORT; }
unsafe fn birth<T>(
tid: u32,
map: &Lazy<Mutex<HashMap<u32, T>>>,
out: *mut u8,
out_len: *mut usize,
) -> i32
where
T: Default,
{
let need = 4 + 4 + 8;
if *out_len < need {
*out_len = need;
return E_SHORT;
}
let id = ID.fetch_add(1, Ordering::Relaxed);
if let Ok(mut m) = map.lock() { m.insert(id, T::default()); } else { return E_FAIL; }
let mut buf = tlv::header(1); tlv::encode_handle(&mut buf, tid, id);
std::ptr::copy_nonoverlapping(buf.as_ptr(), out, buf.len()); *out_len = buf.len(); OK
if let Ok(mut m) = map.lock() {
m.insert(id, T::default());
} else {
return E_FAIL;
}
let mut buf = tlv::header(1);
tlv::encode_handle(&mut buf, tid, id);
std::ptr::copy_nonoverlapping(buf.as_ptr(), out, buf.len());
*out_len = buf.len();
OK
}
unsafe fn fini<T>(map: &Lazy<Mutex<HashMap<u32,T>>>, instance_id: u32) -> i32 {
if let Ok(mut m) = map.lock() { m.remove(&instance_id); OK } else { E_FAIL }
unsafe fn fini<T>(map: &Lazy<Mutex<HashMap<u32, T>>>, instance_id: u32) -> i32 {
if let Ok(mut m) = map.lock() {
m.remove(&instance_id);
OK
} else {
E_FAIL
}
}
unsafe fn sqrt_call(args: *const u8, args_len: usize, out: *mut u8, out_len: *mut usize) -> i32 {
if args_len < 8 { return E_ARGS; }
if args_len < 8 {
return E_ARGS;
}
let a = std::slice::from_raw_parts(args, args_len);
if let Some((tag, sz, p)) = tlv::decode_first(a) {
if tag == 3 && sz == 8 && a.len() >= p+8 {
let mut b=[0u8;8]; b.copy_from_slice(&a[p..p+8]);
if tag == 3 && sz == 8 && a.len() >= p + 8 {
let mut b = [0u8; 8];
b.copy_from_slice(&a[p..p + 8]);
let x = i64::from_le_bytes(b) as f64;
let r = x.sqrt();
let need = 4+4+8; if *out_len < need { *out_len = need; return E_SHORT; }
let need = 4 + 4 + 8;
if *out_len < need {
*out_len = need;
return E_SHORT;
}
let mut buf = tlv::header(1);
// encode f64 (tag=5)
buf.push(5); buf.push(0); buf.push(8); buf.push(0); buf.extend_from_slice(&r.to_le_bytes());
std::ptr::copy_nonoverlapping(buf.as_ptr(), out, buf.len()); *out_len = buf.len();
buf.push(5);
buf.push(0);
buf.push(8);
buf.push(0);
buf.extend_from_slice(&r.to_le_bytes());
std::ptr::copy_nonoverlapping(buf.as_ptr(), out, buf.len());
*out_len = buf.len();
return OK;
}
}
@ -109,26 +186,53 @@ unsafe fn sqrt_call(args: *const u8, args_len: usize, out: *mut u8, out_len: *mu
}
unsafe fn now_call(out: *mut u8, out_len: *mut usize) -> i32 {
let ts = std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).map(|d| d.as_secs() as i64).unwrap_or(0);
let need = 4+4+8; if *out_len < need { *out_len = need; return E_SHORT; }
let mut buf = tlv::header(1); tlv::encode_i64(&mut buf, ts);
std::ptr::copy_nonoverlapping(buf.as_ptr(), out, buf.len()); *out_len = buf.len();
let ts = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.map(|d| d.as_secs() as i64)
.unwrap_or(0);
let need = 4 + 4 + 8;
if *out_len < need {
*out_len = need;
return E_SHORT;
}
let mut buf = tlv::header(1);
tlv::encode_i64(&mut buf, ts);
std::ptr::copy_nonoverlapping(buf.as_ptr(), out, buf.len());
*out_len = buf.len();
OK
}
unsafe fn trig_call(args: *const u8, args_len: usize, out: *mut u8, out_len: *mut usize, is_sin: bool) -> i32 {
if args_len < 8 { return E_ARGS; }
unsafe fn trig_call(
args: *const u8,
args_len: usize,
out: *mut u8,
out_len: *mut usize,
is_sin: bool,
) -> i32 {
if args_len < 8 {
return E_ARGS;
}
let a = std::slice::from_raw_parts(args, args_len);
if let Some((tag, sz, p)) = tlv::decode_first(a) {
if tag == 3 && sz == 8 && a.len() >= p+8 {
let mut b=[0u8;8]; b.copy_from_slice(&a[p..p+8]);
if tag == 3 && sz == 8 && a.len() >= p + 8 {
let mut b = [0u8; 8];
b.copy_from_slice(&a[p..p + 8]);
let x = i64::from_le_bytes(b) as f64;
let r = if is_sin { x.sin() } else { x.cos() };
let need = 4+4+8; if *out_len < need { *out_len = need; return E_SHORT; }
let need = 4 + 4 + 8;
if *out_len < need {
*out_len = need;
return E_SHORT;
}
let mut buf = tlv::header(1);
// encode f64 (tag=5)
buf.push(5); buf.push(0); buf.push(8); buf.push(0); buf.extend_from_slice(&r.to_le_bytes());
std::ptr::copy_nonoverlapping(buf.as_ptr(), out, buf.len()); *out_len = buf.len();
buf.push(5);
buf.push(0);
buf.push(8);
buf.push(0);
buf.extend_from_slice(&r.to_le_bytes());
std::ptr::copy_nonoverlapping(buf.as_ptr(), out, buf.len());
*out_len = buf.len();
return OK;
}
}
@ -136,18 +240,30 @@ unsafe fn trig_call(args: *const u8, args_len: usize, out: *mut u8, out_len: *mu
}
unsafe fn round_call(args: *const u8, args_len: usize, out: *mut u8, out_len: *mut usize) -> i32 {
if args_len < 8 { return E_ARGS; }
if args_len < 8 {
return E_ARGS;
}
let a = std::slice::from_raw_parts(args, args_len);
if let Some((tag, sz, p)) = tlv::decode_first(a) {
if tag == 3 && sz == 8 && a.len() >= p+8 {
let mut b=[0u8;8]; b.copy_from_slice(&a[p..p+8]);
if tag == 3 && sz == 8 && a.len() >= p + 8 {
let mut b = [0u8; 8];
b.copy_from_slice(&a[p..p + 8]);
let x = i64::from_le_bytes(b) as f64;
let r = x.round();
let need = 4+4+8; if *out_len < need { *out_len = need; return E_SHORT; }
let need = 4 + 4 + 8;
if *out_len < need {
*out_len = need;
return E_SHORT;
}
let mut buf = tlv::header(1);
// encode f64 (tag=5)
buf.push(5); buf.push(0); buf.push(8); buf.push(0); buf.extend_from_slice(&r.to_le_bytes());
std::ptr::copy_nonoverlapping(buf.as_ptr(), out, buf.len()); *out_len = buf.len();
buf.push(5);
buf.push(0);
buf.push(8);
buf.push(0);
buf.extend_from_slice(&r.to_le_bytes());
std::ptr::copy_nonoverlapping(buf.as_ptr(), out, buf.len());
*out_len = buf.len();
return OK;
}
}