The JIT that runs makepad apps from source: lexer, front end, type checker, lazy borrow checker (Gandalf; `--check-first` opts in), codegen, session and warm/cold caches keyed by compiler stamp, provided crates bound late, startup images, live patching. User-facing name is `makepad run` (binary `makepad`, MAKEPAD_RUN_* env, ~/.makepad-run); libs/relax stays the internal library name. `makepad check` reports rustc-style diagnostics with rustc error codes and checks a whole workspace (`--workspace`). Runs on macOS, Linux, Windows and Android. makepad-remote: one tool schema for apps and the WM (app/1): grabs, captures, traces, frame profiles and tweaks. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
124 lines
3.8 KiB
Rust
124 lines
3.8 KiB
Rust
// Constant initializers evaluated to data (libs/relax/compiler/src/ctfe.rs): the shapes of lookup
|
|
// tables -- struct rows built by a const fn, (char, char, enum) ranges, niche-encoded Options,
|
|
// strings, nested references, repeats, arithmetic and casts. rustc prints the same hash:
|
|
// 3413466678543477432. MAKEPAD_RUN_CTFE=check also compiles and runs every initializer and
|
|
// compares the values.
|
|
|
|
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
|
pub struct Tag(pub u32);
|
|
impl Tag {
|
|
pub const fn from_bytes(bytes: &[u8; 4]) -> Self {
|
|
Tag(((bytes[0] as u32) << 24) | ((bytes[1] as u32) << 16) | ((bytes[2] as u32) << 8) | (bytes[3] as u32))
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Copy)]
|
|
pub struct LangTag {
|
|
pub language: &'static str,
|
|
pub tag: Tag,
|
|
}
|
|
|
|
pub const LANGS: &[LangTag] = &[
|
|
LangTag { language: "aa", tag: Tag::from_bytes(b"AFR ") },
|
|
LangTag { language: "aae", tag: Tag::from_bytes(b"SQI ") },
|
|
LangTag { language: "aba", tag: Tag(0) },
|
|
LangTag { language: "zh-Hant", tag: Tag::from_bytes(b"ZHT ") },
|
|
];
|
|
|
|
#[derive(Clone, Copy, PartialEq, Debug)]
|
|
pub enum Cat {
|
|
Cc,
|
|
Lu,
|
|
Ll,
|
|
Nd,
|
|
Zs,
|
|
}
|
|
|
|
pub const RANGES: &[(char, char, Cat)] = &[('\u{0}', '\u{1f}', Cat::Cc), ('0', '9', Cat::Nd), ('A', 'Z', Cat::Lu), ('a', 'z', Cat::Ll), ('\u{3000}', '\u{3000}', Cat::Zs)];
|
|
|
|
#[derive(Clone, Copy)]
|
|
pub enum Shape {
|
|
Unit,
|
|
Pair(i16, u8),
|
|
Named { w: u32, h: u32 },
|
|
}
|
|
|
|
pub static SHAPES: [Shape; 3] = [Shape::Unit, Shape::Pair(-7, 200), Shape::Named { w: 3, h: 4 }];
|
|
pub const OPTS: [Option<&str>; 3] = [None, Some("x"), Some("")];
|
|
pub const OPT_U8: [Option<u8>; 2] = [Some(5), None];
|
|
pub const NESTED: &[&[u16]] = &[&[1, 2, 3], &[], &[0xffff]];
|
|
pub const REPEAT: [u32; 6] = [0x1234_5678; 6];
|
|
pub const ARITH: (i64, u8, i32, u64, bool, char) = (-(3 * 7 - 100) << 2, (300u32 % 256) as u8, -5 / 2, !0u64 >> 4, 3 > 2 && 1 != 1 || true, 65u8 as char);
|
|
pub const FLOATS: [f64; 3] = [1.5, -0.25, 1e10];
|
|
pub const F32S: (f32, f32) = (0.1, -2.0);
|
|
pub const BASE: u32 = 40;
|
|
pub const DERIVED: u32 = BASE * 2 + 1;
|
|
pub const ARR_REF: &[i8; 4] = &[-1, 0, 1, 127];
|
|
pub const SLICE: &[i8] = ARR_REF;
|
|
pub const TUPLE_IDX: u8 = (1u8, 2u8).1 + [10u8, 20][1];
|
|
|
|
fn mix(h: &mut u64, x: u64) {
|
|
*h = (*h ^ x).wrapping_mul(0x100_0000_01b3);
|
|
}
|
|
|
|
#[test]
|
|
fn ctfe_data() {
|
|
let mut h = 0xcbf2_9ce4_8422_2325u64;
|
|
for l in LANGS {
|
|
mix(&mut h, l.tag.0 as u64);
|
|
for b in l.language.bytes() {
|
|
mix(&mut h, b as u64);
|
|
}
|
|
}
|
|
for (a, b, c) in RANGES {
|
|
mix(&mut h, *a as u64);
|
|
mix(&mut h, *b as u64);
|
|
mix(&mut h, *c as u64);
|
|
}
|
|
for s in SHAPES.iter() {
|
|
match s {
|
|
Shape::Unit => mix(&mut h, 1),
|
|
Shape::Pair(a, b) => {
|
|
mix(&mut h, *a as u64);
|
|
mix(&mut h, *b as u64)
|
|
}
|
|
Shape::Named { w, h: hh } => {
|
|
mix(&mut h, *w as u64);
|
|
mix(&mut h, *hh as u64)
|
|
}
|
|
}
|
|
}
|
|
for o in OPTS {
|
|
mix(&mut h, o.map_or(99, |s| s.len() as u64));
|
|
}
|
|
for o in OPT_U8 {
|
|
mix(&mut h, o.map_or(77, |x| x as u64));
|
|
}
|
|
for s in NESTED {
|
|
mix(&mut h, s.len() as u64);
|
|
for x in s.iter() {
|
|
mix(&mut h, *x as u64);
|
|
}
|
|
}
|
|
for x in REPEAT {
|
|
mix(&mut h, x as u64);
|
|
}
|
|
mix(&mut h, ARITH.0 as u64);
|
|
mix(&mut h, ARITH.1 as u64);
|
|
mix(&mut h, ARITH.2 as u64);
|
|
mix(&mut h, ARITH.3);
|
|
mix(&mut h, ARITH.4 as u64);
|
|
mix(&mut h, ARITH.5 as u64);
|
|
for f in FLOATS {
|
|
mix(&mut h, f.to_bits());
|
|
}
|
|
mix(&mut h, F32S.0.to_bits() as u64);
|
|
mix(&mut h, F32S.1.to_bits() as u64);
|
|
mix(&mut h, DERIVED as u64);
|
|
for x in SLICE {
|
|
mix(&mut h, *x as u64);
|
|
}
|
|
mix(&mut h, TUPLE_IDX as u64);
|
|
println!("hash {}", h);
|
|
assert_eq!(h, 3413466678543477432);
|
|
}
|