Skip to main content

vm/
rt.rs

1use compiler::{Capture, Compiler, Symbol};
2use dynamic::{Dynamic, Type};
3use parser::{BinaryOp, Expr, ExprKind, PatternKind, Span, Stmt, StmtKind, UnaryOp};
4use std::collections::{BTreeMap, HashMap, VecDeque};
5
6use crate::context::LocalVar;
7
8use super::{FnInfo, FnVariant, PTR_TYPE, context::BuildContext, get_type, ptr_type};
9use cranelift::prelude::*;
10use cranelift_jit::{JITBuilder, JITModule};
11use cranelift_module::{FuncId, Module};
12
13use anyhow::{Result, anyhow};
14use parking_lot::RwLock;
15use smol_str::SmolStr;
16use std::sync::{Arc, Weak};
17
18pub struct JITRunTime {
19    pub compiler: Compiler,
20    pub fns: BTreeMap<u32, FnVariant>,
21    pub sigs: Vec<(Vec<Type>, Signature, Type)>,
22    pub native_symbols: Arc<RwLock<HashMap<String, usize>>>,
23    pub(crate) owner: Weak<RwLock<JITRunTime>>,
24    pub(crate) pending_fns: VecDeque<PendingFn>,
25    pub(crate) compile_depth: usize,
26    native_fn_cache: Vec<(SmolStr, Vec<Type>, FnInfo)>,
27    #[cfg(feature = "ir-disassembly")]
28    pub ir_disassembly: BTreeMap<SmolStr, String>,
29    pub module: JITModule,
30    pub consts: Vec<Option<usize>>,
31    pub(crate) scope_enter_fn: Option<FuncId>,
32    pub(crate) scope_exit_void_fn: Option<FuncId>,
33    pub(crate) scope_exit_dynamic_fn: Option<FuncId>,
34    pub(crate) scope_exit_bytes_fn: Option<FuncId>,
35    pub(crate) struct_alloc_fn: Option<FuncId>,
36    pub(crate) repeat_fill_fn: Option<FuncId>,
37    pub(crate) strcat_fn: Option<FuncId>,
38    pub(crate) strcat_i64_fn: Option<FuncId>,
39    pub(crate) strcat_assign_fn: Option<FuncId>,
40    pub(crate) callback_new_fn: Option<FuncId>,
41    pub(crate) spawn_ptr_fn: Option<FuncId>,
42    pub(crate) struct_from_ptr_fn: Option<FuncId>,
43    pub(crate) array_from_ptr_fn: Option<FuncId>,
44    pub(crate) array_to_ptr_fn: Option<FuncId>,
45    pub(crate) arith_fault_fn: Option<FuncId>,
46}
47
48// TODO(memory): 函数调用期间为 VM 内部临时 Any/struct 分配引入 arena。
49// 临时值进入 arena,返回值 promote 给 Rust 调用方;否则需要完整 drop 插桩,
50// 覆盖表达式丢弃、变量覆盖、函数出口、break/continue/return 等路径。
51pub(crate) struct PendingFn {
52    pub name: SmolStr,
53    pub symbol_id: u32,
54    pub fn_id: FuncId,
55    pub arg_tys: Vec<Type>,
56    pub ret_ty: Type,
57    pub local_type_hints: Vec<Option<Type>>,
58    pub body: Stmt,
59}
60
61impl JITRunTime {
62    fn expr(kind: ExprKind) -> Expr {
63        Expr::new(kind, Span::default())
64    }
65
66    fn stmt(kind: StmtKind) -> Stmt {
67        Stmt::new(kind, Span::default())
68    }
69
70    pub(crate) fn type_ptr_const(ctx: &mut BuildContext, ty: &Type) -> Value {
71        let ty_ptr = Box::into_raw(Box::new(ty.clone()));
72        ctx.builder.ins().iconst(ptr_type(), ty_ptr as i64)
73    }
74
75    pub fn load(&mut self, code: Vec<u8>, arg_name: SmolStr) -> Result<(i64, Type)> {
76        let stmts = Compiler::parse_code(code)?;
77        self.compiler.resolve_imports(&stmts, None)?;
78        self.compiler.clear();
79        self.compiler.symbols.add_module("__console".into());
80        let mut cap = Capture::default();
81        let body = Self::stmt(StmtKind::Block(self.compiler.compile_fn(&[arg_name], &mut vec![Type::Any], Self::stmt(StmtKind::Block(stmts)), &mut cap)?));
82        self.compiler.tys.push(Type::Any);
83        let ret_ty = self.compiler.infer_stmt(&body)?;
84        self.compiler.clear();
85        let fn_id = self.compile_fn(None, &[Type::Any], ret_ty.clone(), &body)?;
86        self.compiler.clear();
87        self.compiler.symbols.pop_module();
88        self.module.finalize_definitions()?;
89        Ok((self.module.get_finalized_function(fn_id) as i64, ret_ty))
90    }
91
92    pub fn import_code(&mut self, name: &str, code: Vec<u8>) -> Result<()> {
93        log::debug!("import {}", name);
94        let _ = self.compiler.import_code(name, code)?;
95        Ok(())
96    }
97
98    #[cfg(feature = "ir-disassembly")]
99    pub fn disassemble_ir(&mut self, name: &str) -> Result<String> {
100        if let Some(ir) = self.ir_disassembly.get(name) {
101            return Ok(ir.clone());
102        }
103        let id = self.get_id(name)?;
104        let (_, symbol) = self.compiler.symbols.get_symbol(id)?;
105        if let Symbol::Fn { ty, .. } = symbol
106            && let Type::Fn { tys, .. } = ty
107            && tys.is_empty()
108        {
109            let _ = self.gen_fn(None, id, &[])?;
110        }
111        self.ir_disassembly.get(name).cloned().ok_or_else(|| anyhow!("未找到函数 {} 的 Cranelift IR;如果它需要参数,请先触发对应实例化", name))
112    }
113
114    pub fn get_fn_ptr(&mut self, name: &str, arg_tys: &[Type]) -> Result<(*const u8, Type)> {
115        let main_id = self.get_id(name)?;
116        let fn_info = self.gen_fn(None, main_id, arg_tys)?;
117        Ok((self.module.get_finalized_function(fn_info.get_id()?), fn_info.get_type()?))
118    }
119
120    pub fn get_fn_ptr_with_params(&mut self, name: &str, arg_tys: &[Type], generic_args: &[Type]) -> Result<(*const u8, Type)> {
121        let main_id = self.get_id(name)?;
122        let fn_info = self.gen_fn_with_params(None, main_id, arg_tys, generic_args)?;
123        Ok((self.module.get_finalized_function(fn_info.get_id()?), fn_info.get_type()?))
124    }
125
126    pub fn get_const_value(&mut self, ctx: &mut BuildContext, idx: usize) -> Result<(Value, Type)> {
127        if self.consts.len() < idx + 1 {
128            self.consts.resize(idx + 1, None);
129        }
130        let ptr = if let Some(ptr) = self.consts.get(idx).cloned().unwrap_or(None) {
131            ptr
132        } else {
133            let c = Box::new(self.compiler.consts[idx].deep_clone()); //深度拷贝 避免常量被污染
134            let ptr = Box::into_raw(c) as usize;
135            self.consts[idx] = Some(ptr);
136            ptr
137        };
138        let value = ctx.builder.ins().iconst(ptr_type(), ptr as i64); //需要生成副本 避免被释放
139        let ty = if self.compiler.consts[idx].is_str() { Type::Str } else { Type::Any };
140        Ok((self.call(ctx, self.get_method(&Type::Any, "clone")?, vec![value])?.0, ty))
141    }
142
143    fn get_null_value(&mut self, ctx: &mut BuildContext) -> Result<(Value, Type)> {
144        let const_idx = self.compiler.get_const(Dynamic::Null);
145        self.get_const_value(ctx, const_idx)
146    }
147
148    pub fn get_dynamic(&self, expr: &Expr) -> Option<Dynamic> {
149        if let ExprKind::Const(idx) = &expr.kind { self.compiler.consts.get_index(*idx).map(|(_, v)| v.clone()) } else { None }
150    }
151
152    fn compile_error(&self, ctx: &BuildContext, span: Span, message: impl AsRef<str>) -> anyhow::Error {
153        if let Some(fn_name) = &ctx.fn_name { anyhow!("{}", self.compiler.format_source_span(fn_name.as_str(), span, message.as_ref())) } else { anyhow!("{}", message.as_ref()) }
154    }
155
156    pub fn get_method(&self, ty: &Type, name: &str) -> Result<FnInfo> {
157        self.compiler.get_field(ty, name).and_then(|(_, ty)| if let Type::Symbol { id, params: _ } = ty { self.get_fn(id, &[]) } else { Err(anyhow!("不是成员函数")) })
158    }
159
160    fn is_fn_field_type(&self, ty: &Type) -> bool {
161        match ty {
162            Type::Symbol { id, .. } => self.compiler.symbols.get_symbol(*id).map(|(_, symbol)| symbol.is_fn()).unwrap_or(false),
163            Type::Fn { .. } => true,
164            _ => false,
165        }
166    }
167
168    pub(crate) fn is_opaque_custom_ty(&self, ty: &Type) -> bool {
169        let ty = self.compiler.symbols.get_type(ty).unwrap_or_else(|_| ty.clone());
170        matches!(ty, Type::Struct { fields, .. } if !fields.is_empty() && fields.iter().all(|(_, field_ty)| self.is_fn_field_type(field_ty)))
171    }
172
173    pub(crate) fn is_aggregate_ty(&self, ty: &Type) -> bool {
174        (ty.is_struct() && !self.is_opaque_custom_ty(ty)) || ty.is_array()
175    }
176
177    pub fn get_id(&self, name: &str) -> Result<u32> {
178        self.compiler.symbols.get_id(name)
179    }
180
181    fn get_native_fn_cached(&mut self, name: &'static str, arg_tys: &[Type]) -> Result<FnInfo> {
182        if let Some((_, _, fn_info)) = self.native_fn_cache.iter().find(|(cached_name, cached_tys, _)| cached_name.as_str() == name && cached_tys.as_slice() == arg_tys) {
183            return Ok(fn_info.clone());
184        }
185        let fn_info = self.get_fn(self.get_id(name)?, arg_tys)?;
186        self.native_fn_cache.push((SmolStr::new(name), arg_tys.to_vec(), fn_info.clone()));
187        Ok(fn_info)
188    }
189
190    pub fn get_type(&mut self, name: &str, arg_tys: &[Type]) -> Result<Type> {
191        let id = self.get_id(name)?;
192        if self.compiler.symbols.symbols.get(name).map(|s| s.is_fn()).unwrap_or(false) {
193            return self.compiler.infer_fn(id, arg_tys);
194        }
195        self.compiler.symbols.get_type(&Type::Symbol { id, params: Vec::new() })
196    }
197
198    pub fn new<F: FnMut(&mut JITBuilder)>(mut f: F) -> Self {
199        let native_symbols = Arc::new(RwLock::new(HashMap::<String, usize>::new()));
200        let lookup_symbols = native_symbols.clone();
201        let mut builder = JITBuilder::new(cranelift_module::default_libcall_names()).unwrap();
202        builder.symbol_lookup_fn(Box::new(move |name| lookup_symbols.read().get(name).copied().map(|ptr| ptr as *const u8)));
203        f(&mut builder);
204        let module = JITModule::new(builder);
205        PTR_TYPE.get_or_init(|| module.isa().pointer_type());
206        let fns = BTreeMap::<u32, FnVariant>::new();
207        Self {
208            compiler: Compiler::new(),
209            fns,
210            sigs: Vec::new(),
211            native_symbols,
212            owner: Weak::new(),
213            pending_fns: VecDeque::new(),
214            compile_depth: 0,
215            native_fn_cache: Vec::new(),
216            #[cfg(feature = "ir-disassembly")]
217            ir_disassembly: BTreeMap::new(),
218            module,
219            consts: Vec::new(),
220            scope_enter_fn: None,
221            scope_exit_void_fn: None,
222            scope_exit_dynamic_fn: None,
223            scope_exit_bytes_fn: None,
224            struct_alloc_fn: None,
225            repeat_fill_fn: None,
226            strcat_fn: None,
227            strcat_i64_fn: None,
228            strcat_assign_fn: None,
229            callback_new_fn: None,
230            spawn_ptr_fn: None,
231            struct_from_ptr_fn: None,
232            array_from_ptr_fn: None,
233            array_to_ptr_fn: None,
234            arith_fault_fn: None,
235        }
236    }
237
238    pub(crate) fn set_owner(&mut self, owner: Weak<RwLock<JITRunTime>>) {
239        self.owner = owner;
240    }
241
242    pub(crate) fn owner_context_ptr(&self) -> usize {
243        &self.owner as *const Weak<RwLock<JITRunTime>> as usize
244    }
245
246    fn unary(ctx: &mut BuildContext, left: (Value, Type), op: UnaryOp) -> Result<(Value, Type)> {
247        match op {
248            UnaryOp::Neg => {
249                if left.1.is_int() || left.1.is_uint() {
250                    let (int_ty, result_ty) = match left.1.width() {
251                        8 => (types::I64, Type::I64),
252                        4 => (types::I32, Type::I32),
253                        2 => (types::I16, Type::I16),
254                        _ => (types::I8, Type::I8),
255                    };
256                    let zero = ctx.builder.ins().iconst(int_ty, 0);
257                    return Ok((ctx.builder.ins().isub(zero, left.0), result_ty));
258                } else if left.1.is_float() {
259                    return Ok((ctx.builder.ins().fneg(left.0), left.1));
260                }
261            }
262            UnaryOp::Not => {
263                if left.1.is_int() || left.1.is_uint() {
264                    let all_ones = ctx.builder.ins().iconst(get_type(&left.1)?, -1);
265                    return Ok((ctx.builder.ins().bxor(left.0, all_ones), left.1));
266                }
267                let zero = ctx.builder.ins().iconst(types::I8, 0);
268                let one = ctx.builder.ins().iconst(types::I8, 1);
269                let cond = if left.1.is_bool() {
270                    left.0
271                } else if left.1.is_f32() {
272                    let zero = ctx.builder.ins().f32const(0.0);
273                    ctx.builder.ins().fcmp(FloatCC::NotEqual, left.0, zero)
274                } else if left.1.is_f64() {
275                    let zero = ctx.builder.ins().f64const(0.0);
276                    ctx.builder.ins().fcmp(FloatCC::NotEqual, left.0, zero)
277                } else {
278                    return Err(anyhow!("未实现 {:?} {:?}", left, op));
279                };
280                let is_zero = ctx.builder.ins().icmp_imm(IntCC::Equal, cond, 0);
281                return Ok((ctx.builder.ins().select(is_zero, one, zero), Type::Bool));
282            }
283            _ => {}
284        }
285        Err(anyhow!("未实现 {:?} {:?}", left, op))
286    }
287
288    pub(crate) fn call(&mut self, ctx: &mut BuildContext, fn_info: FnInfo, args: Vec<Value>) -> Result<(Value, Type)> {
289        match fn_info {
290            FnInfo::Call { fn_id, arg_tys: _, caps: _, ret, context } => {
291                let fn_ref = self.get_fn_ref(ctx, fn_id);
292                let args = self.add_context_arg(ctx, context, args);
293                let call_inst = ctx.builder.ins().call(fn_ref, &args);
294                if !ret.is_void() { Ok((ctx.builder.inst_results(call_inst)[0], ret)) } else { Err(anyhow!("没有返回值")) }
295            }
296            FnInfo::Inline { fn_ptr, arg_tys: _ } => fn_ptr(Some(ctx), args).and_then(|(v, t)| v.map(|value| (value, t)).ok_or_else(|| anyhow!("inlined native callback returned no value"))),
297        }
298    }
299
300    pub(crate) fn scope_enter(&mut self, ctx: &mut BuildContext) -> Result<()> {
301        let fn_id = self.scope_enter_fn.ok_or_else(|| anyhow!("VM scope enter runtime is not registered"))?;
302        let fn_ref = self.get_fn_ref(ctx, fn_id);
303        ctx.builder.ins().call(fn_ref, &[]);
304        Ok(())
305    }
306
307    fn scope_exit_void(&mut self, ctx: &mut BuildContext) -> Result<()> {
308        let fn_id = self.scope_exit_void_fn.ok_or_else(|| anyhow!("VM scope exit runtime is not registered"))?;
309        let fn_ref = self.get_fn_ref(ctx, fn_id);
310        ctx.builder.ins().call(fn_ref, &[]);
311        Ok(())
312    }
313
314    fn return_value(&mut self, ctx: &mut BuildContext, value: Option<(Value, Type)>) -> Result<()> {
315        let ret_ty = ctx.ret_ty.clone();
316        if ret_ty.is_void() {
317            self.scope_exit_void(ctx)?;
318            ctx.builder.ins().return_(&[]);
319            return Ok(());
320        }
321
322        let Some((value, value_ty)) = value else {
323            self.scope_exit_void(ctx)?;
324            ctx.builder.ins().return_(&[]);
325            return Ok(());
326        };
327
328        if ret_ty.is_any() || ret_ty.is_str() || matches!(ret_ty, Type::Map | Type::List(_) | Type::Iter) {
329            let value = self.convert(ctx, (value, value_ty), Type::Any)?;
330            let fn_id = self.scope_exit_dynamic_fn.ok_or_else(|| anyhow!("VM dynamic return runtime is not registered"))?;
331            let fn_ref = self.get_fn_ref(ctx, fn_id);
332            let call_inst = ctx.builder.ins().call(fn_ref, &[value]);
333            let promoted = ctx.builder.inst_results(call_inst)[0];
334            ctx.builder.ins().return_(&[promoted]);
335        } else if self.is_aggregate_ty(&ret_ty) {
336            let value = self.convert(ctx, (value, value_ty), ret_ty.clone())?;
337            let size = ctx.builder.ins().iconst(types::I64, ret_ty.width() as i64);
338            let ty_ptr = Self::type_ptr_const(ctx, &ret_ty);
339            let fn_id = self.scope_exit_bytes_fn.ok_or_else(|| anyhow!("VM aggregate return runtime is not registered"))?;
340            let fn_ref = self.get_fn_ref(ctx, fn_id);
341            let call_inst = ctx.builder.ins().call(fn_ref, &[value, size, ty_ptr]);
342            let promoted = ctx.builder.inst_results(call_inst)[0];
343            ctx.builder.ins().return_(&[promoted]);
344        } else {
345            let value = self.convert(ctx, (value, value_ty), ret_ty)?;
346            self.scope_exit_void(ctx)?;
347            ctx.builder.ins().return_(&[value]);
348        }
349        Ok(())
350    }
351
352    fn call_for_side_effect(&mut self, ctx: &mut BuildContext, fn_info: FnInfo, args: Vec<Value>) -> Result<()> {
353        match fn_info {
354            FnInfo::Call { fn_id, arg_tys: _, caps: _, ret: _, context } => {
355                let fn_ref = self.get_fn_ref(ctx, fn_id);
356                let args = self.add_context_arg(ctx, context, args);
357                ctx.builder.ins().call(fn_ref, &args);
358                Ok(())
359            }
360            FnInfo::Inline { fn_ptr, arg_tys: _ } => fn_ptr(Some(ctx), args).map(|_| ()),
361        }
362    }
363
364    fn add_context_arg(&mut self, ctx: &mut BuildContext, context: Option<usize>, mut args: Vec<Value>) -> Vec<Value> {
365        if let Some(context) = context {
366            let context = ctx.builder.ins().iconst(ptr_type(), context as i64);
367            args.insert(0, context);
368        }
369        args
370    }
371
372    pub(crate) fn short_circuit_logic(&mut self, ctx: &mut BuildContext, left: (Value, Type), op: BinaryOp, right: &Expr) -> Result<(Value, Type)> {
373        let left = self.bool_value(ctx, left)?;
374        let rhs_block = ctx.builder.create_block();
375        let short_block = ctx.builder.create_block();
376        let end_block = ctx.builder.create_block();
377        ctx.builder.append_block_param(end_block, types::I8);
378
379        match op {
380            BinaryOp::And => {
381                ctx.builder.ins().brif(left, rhs_block, &[], short_block, &[]);
382            }
383            BinaryOp::Or => {
384                ctx.builder.ins().brif(left, short_block, &[], rhs_block, &[]);
385            }
386            _ => unreachable!(),
387        }
388
389        ctx.builder.switch_to_block(rhs_block);
390        let right = match self.eval(ctx, right)?.get(ctx) {
391            Some(right) => self.bool_value(ctx, right)?,
392            None => ctx.builder.ins().iconst(types::I8, 0),
393        };
394        ctx.builder.ins().jump(end_block, &[cranelift::codegen::ir::BlockArg::Value(right)]);
395        ctx.builder.seal_block(rhs_block);
396
397        ctx.builder.switch_to_block(short_block);
398        let short_value = match op {
399            BinaryOp::And => ctx.builder.ins().iconst(types::I8, 0),
400            BinaryOp::Or => ctx.builder.ins().iconst(types::I8, 1),
401            _ => unreachable!(),
402        };
403        ctx.builder.ins().jump(end_block, &[cranelift::codegen::ir::BlockArg::Value(short_value)]);
404        ctx.builder.seal_block(short_block);
405
406        ctx.builder.switch_to_block(end_block);
407        let result = ctx.builder.block_params(end_block)[0];
408        Ok((result, Type::Bool))
409    }
410
411    fn struct_alloc(&mut self, ctx: &mut BuildContext, ty: &Type) -> Result<Value> {
412        let size = ctx.builder.ins().iconst(types::I64, ty.width() as i64);
413        let fn_id = self.struct_alloc_fn.ok_or_else(|| anyhow!("VM struct allocator runtime is not registered"))?;
414        let fn_ref = self.get_fn_ref(ctx, fn_id);
415        let call_inst = ctx.builder.ins().call(fn_ref, &[size]);
416        Ok(ctx.builder.inst_results(call_inst)[0])
417    }
418
419    fn store_struct_field(&mut self, ctx: &mut BuildContext, base: Value, idx: usize, field_ty: &Type, value: (Value, Type), struct_ty: &Type) -> Result<()> {
420        let offset = struct_ty.field_offset(idx).ok_or_else(|| anyhow!("结构字段索引越界 {}", idx))?;
421        let value = self.convert(ctx, value, field_ty.clone())?;
422        if field_ty.is_struct() || field_ty.is_array() {
423            let field_addr = ctx.builder.ins().iadd_imm(base, offset as i64);
424            self.copy_vec_element(ctx, field_addr, value, field_ty);
425        } else {
426            ctx.builder.ins().store(MemFlags::trusted(), value, base, offset as i32);
427        }
428        Ok(())
429    }
430
431    fn load_struct_field(&mut self, ctx: &mut BuildContext, base: Value, idx: usize, struct_ty: &Type) -> Result<(Value, Type)> {
432        if let Type::Struct { params: _, fields } = struct_ty {
433            let field_ty = fields.get(idx).map(|(_, ty)| ty).ok_or_else(|| anyhow!("结构字段索引越界 {}", idx))?;
434            let offset = struct_ty.field_offset(idx).ok_or_else(|| anyhow!("结构字段索引越界 {}", idx))?;
435            if field_ty.is_struct() || field_ty.is_array() {
436                return Ok((ctx.builder.ins().iadd_imm(base, offset as i64), field_ty.clone()));
437            }
438            let val = ctx.builder.ins().load(crate::get_type(field_ty)?, MemFlags::trusted(), base, offset as i32);
439            Ok((val, field_ty.clone()))
440        } else {
441            Err(anyhow!("不是结构体 {:?}", struct_ty))
442        }
443    }
444
445    fn struct_field_index(&self, struct_ty: &Type, right: &Expr) -> Result<usize> {
446        let value = if let ExprKind::Const(idx) = right.kind { self.compiler.consts.get_index(idx).map(|(_, v)| v.clone()).ok_or_else(|| anyhow!("missing const {}", idx))? } else { right.clone().value()? };
447        if let Some(idx) = value.as_int() {
448            return usize::try_from(idx).map_err(|_| anyhow!("结构字段索引越界 {}", idx));
449        }
450        if value.is_str() {
451            return self.compiler.get_field(struct_ty, value.as_str()).map(|(idx, _)| idx);
452        }
453        Err(anyhow!("非立即数结构字段索引 {:?}", right))
454    }
455
456    fn vec_elem_ty(ty: &Type) -> Option<Type> {
457        if let Type::Vec(elem, 0) = ty { Some((**elem).clone()) } else { None }
458    }
459
460    fn array_elem_ty(ty: &Type) -> Option<Type> {
461        if let Type::Array(elem, _) = ty { Some((**elem).clone()) } else { None }
462    }
463
464    fn vec_index_addr(&mut self, ctx: &mut BuildContext, base: Value, idx: (Value, Type), elem_ty: &Type) -> Result<Value> {
465        let idx = self.convert(ctx, idx, Type::I64)?;
466        let width = ctx.builder.ins().iconst(types::I64, elem_ty.storage_width() as i64);
467        let offset = ctx.builder.ins().imul(idx, width);
468        Ok(ctx.builder.ins().iadd(base, offset))
469    }
470
471    fn array_index_addr(&mut self, ctx: &mut BuildContext, base: Value, idx: (Value, Type), elem_ty: &Type) -> Result<Value> {
472        self.vec_index_addr(ctx, base, idx, elem_ty)
473    }
474
475    fn load_array_index(&mut self, ctx: &mut BuildContext, base: Value, idx: (Value, Type), elem_ty: &Type) -> Result<(Value, Type)> {
476        let addr = self.array_index_addr(ctx, base, idx, elem_ty)?;
477        if elem_ty.is_struct() || elem_ty.is_array() {
478            Ok((addr, elem_ty.clone()))
479        } else {
480            let val = ctx.builder.ins().load(crate::get_type(elem_ty)?, MemFlags::trusted(), addr, 0);
481            Ok((val, elem_ty.clone()))
482        }
483    }
484
485    fn store_array_index(&mut self, ctx: &mut BuildContext, base: Value, idx: (Value, Type), elem_ty: &Type, value: (Value, Type)) -> Result<()> {
486        let addr = self.array_index_addr(ctx, base, idx, elem_ty)?;
487        let value = self.convert(ctx, value, elem_ty.clone())?;
488        if elem_ty.is_struct() || elem_ty.is_array() {
489            self.copy_vec_element(ctx, addr, value, elem_ty);
490        } else {
491            let value = LocalVar::normalize_for_var(ctx, value, elem_ty);
492            ctx.builder.ins().store(MemFlags::trusted(), value, addr, 0);
493        }
494        Ok(())
495    }
496
497    fn init_repeat_array(&mut self, ctx: &mut BuildContext, value: (Value, Type), len: u32) -> Result<(Value, Type)> {
498        let elem_ty = value.1.clone();
499        let array_ty = Type::Array(std::rc::Rc::new(elem_ty.clone()), len);
500        let base = self.struct_alloc(ctx, &array_ty)?;
501        if let Some(pattern) = self.repeat_fill_pattern(ctx, value.0, &elem_ty) {
502            let fn_id = self.repeat_fill_fn.ok_or_else(|| anyhow!("VM repeat fill runtime is not registered"))?;
503            let fn_ref = self.get_fn_ref(ctx, fn_id);
504            let width = ctx.builder.ins().iconst(types::I64, elem_ty.storage_width() as i64);
505            let len = ctx.builder.ins().iconst(types::I64, len as i64);
506            ctx.builder.ins().call(fn_ref, &[base, pattern, width, len]);
507            return Ok((base, array_ty));
508        }
509        for idx in 0..len {
510            let idx = (ctx.builder.ins().iconst(types::I64, idx as i64), Type::I64);
511            self.store_array_index(ctx, base, idx, &elem_ty, value.clone())?;
512        }
513        Ok((base, array_ty))
514    }
515
516    fn repeat_fill_pattern(&mut self, ctx: &mut BuildContext, value: Value, ty: &Type) -> Option<Value> {
517        if matches!(ty, Type::Bool) || ty.is_int() || ty.is_uint() {
518            return Some(if ty.storage_width() < 8 { ctx.builder.ins().uextend(types::I64, value) } else { value });
519        }
520        if ty.is_f32() {
521            let flags = MemFlags::new().with_endianness(cranelift::codegen::ir::Endianness::Little);
522            let bits = ctx.builder.ins().bitcast(types::I32, flags, value);
523            return Some(ctx.builder.ins().uextend(types::I64, bits));
524        }
525        if ty.is_f64() {
526            let flags = MemFlags::new().with_endianness(cranelift::codegen::ir::Endianness::Little);
527            return Some(ctx.builder.ins().bitcast(types::I64, flags, value));
528        }
529        None
530    }
531
532    fn init_array_from_items(&mut self, ctx: &mut BuildContext, items: &[Expr], ty: &Type) -> Result<Value> {
533        let Type::Array(elem_ty, len) = ty else {
534            return Err(anyhow!("not an array type: {:?}", ty));
535        };
536        if items.len() != *len as usize {
537            return Err(anyhow!("array literal length {} does not match {}", items.len(), len));
538        }
539        let base = self.struct_alloc(ctx, ty)?;
540        for (idx, item) in items.iter().enumerate() {
541            let value = self.eval(ctx, item)?.get(ctx).ok_or(anyhow!("array item has no value"))?;
542            let idx = (ctx.builder.ins().iconst(types::I64, idx as i64), Type::I64);
543            self.store_array_index(ctx, base, idx, elem_ty, value)?;
544        }
545        Ok(base)
546    }
547
548    pub(crate) fn any_to_array(&mut self, ctx: &mut BuildContext, value: Value, ty: &Type) -> Result<Value> {
549        let Type::Array(_, _) = ty else {
550            return Err(anyhow!("not an array type: {:?}", ty));
551        };
552        let base = self.struct_alloc(ctx, ty)?;
553        let ty_ptr = Self::type_ptr_const(ctx, ty);
554        let fn_id = self.array_to_ptr_fn.ok_or_else(|| anyhow!("VM array assignment runtime is not registered"))?;
555        let fn_ref = self.get_fn_ref(ctx, fn_id);
556        ctx.builder.ins().call(fn_ref, &[base, value, ty_ptr]);
557        Ok(base)
558    }
559
560    fn load_vec_index(&mut self, ctx: &mut BuildContext, base: Value, idx: (Value, Type), elem_ty: &Type) -> Result<(Value, Type)> {
561        let addr = self.vec_index_addr(ctx, base, idx, elem_ty)?;
562        if elem_ty.is_struct() {
563            Ok((addr, elem_ty.clone()))
564        } else {
565            let val = ctx.builder.ins().load(crate::get_type(elem_ty)?, MemFlags::trusted(), addr, 0);
566            Ok((val, elem_ty.clone()))
567        }
568    }
569
570    fn copy_vec_element(&mut self, ctx: &mut BuildContext, dst: Value, src: Value, elem_ty: &Type) {
571        let mut offset = 0u32;
572        let width = elem_ty.storage_width();
573        while offset < width {
574            let remaining = width - offset;
575            let (ty, size) = if remaining >= 8 {
576                (types::I64, 8)
577            } else if remaining >= 4 {
578                (types::I32, 4)
579            } else if remaining >= 2 {
580                (types::I16, 2)
581            } else {
582                (types::I8, 1)
583            };
584            let value = ctx.builder.ins().load(ty, MemFlags::trusted(), src, offset as i32);
585            ctx.builder.ins().store(MemFlags::trusted(), value, dst, offset as i32);
586            offset += size;
587        }
588    }
589
590    fn store_vec_index(&mut self, ctx: &mut BuildContext, base: Value, idx: (Value, Type), elem_ty: &Type, value: (Value, Type)) -> Result<()> {
591        let addr = self.vec_index_addr(ctx, base, idx, elem_ty)?;
592        let value = self.convert(ctx, value, elem_ty.clone())?;
593        if elem_ty.is_struct() {
594            self.copy_vec_element(ctx, addr, value, elem_ty);
595        } else {
596            let value = LocalVar::normalize_for_var(ctx, value, elem_ty);
597            ctx.builder.ins().store(MemFlags::trusted(), value, addr, 0);
598        }
599        Ok(())
600    }
601
602    fn swap_vec_index(&mut self, ctx: &mut BuildContext, base: Value, left: (Value, Type), right: (Value, Type), elem_ty: &Type) -> Result<()> {
603        let left_addr = self.vec_index_addr(ctx, base, left, elem_ty)?;
604        let right_addr = self.vec_index_addr(ctx, base, right, elem_ty)?;
605        let mut offset = 0u32;
606        let width = elem_ty.storage_width();
607        while offset < width {
608            let remaining = width - offset;
609            let (ty, size) = if remaining >= 8 {
610                (types::I64, 8)
611            } else if remaining >= 4 {
612                (types::I32, 4)
613            } else if remaining >= 2 {
614                (types::I16, 2)
615            } else {
616                (types::I8, 1)
617            };
618            let left_value = ctx.builder.ins().load(ty, MemFlags::trusted(), left_addr, offset as i32);
619            let right_value = ctx.builder.ins().load(ty, MemFlags::trusted(), right_addr, offset as i32);
620            ctx.builder.ins().store(MemFlags::trusted(), left_value, right_addr, offset as i32);
621            ctx.builder.ins().store(MemFlags::trusted(), right_value, left_addr, offset as i32);
622            offset += size;
623        }
624        Ok(())
625    }
626
627    fn init_struct_from_dynamic(&mut self, ctx: &mut BuildContext, value: (Value, Type), ty: &Type) -> Result<Value> {
628        let Type::Struct { params: _, fields } = ty else {
629            return Err(anyhow!("不是结构体 {:?}", ty));
630        };
631        let base = self.struct_alloc(ctx, ty)?;
632        for (idx, (_, field_ty)) in fields.iter().enumerate() {
633            let idx_val = ctx.builder.ins().iconst(types::I64, idx as i64);
634            let item = self.call(ctx, self.get_method(&Type::Any, "get_idx")?, vec![value.0, idx_val])?;
635            self.store_struct_field(ctx, base, idx, field_ty, item, ty)?;
636        }
637        Ok(base)
638    }
639
640    fn init_struct_from_items(&mut self, ctx: &mut BuildContext, items: &[Expr], ty: &Type) -> Result<Value> {
641        let Type::Struct { params: _, fields } = ty else {
642            return Err(anyhow!("not a struct type: {:?}", ty));
643        };
644        let base = self.struct_alloc(ctx, ty)?;
645        for (idx, item) in items.iter().enumerate() {
646            let Some((_, field_ty)) = fields.get(idx) else {
647                return Err(anyhow!("struct initializer has too many fields (field index {} out of bounds, type has {} fields)", idx, fields.len()));
648            };
649            let value = self.eval(ctx, item)?.get(ctx).ok_or(anyhow!("struct field has no value"))?;
650            self.store_struct_field(ctx, base, idx, field_ty, value, ty)?;
651        }
652        Ok(base)
653    }
654
655    fn expr_assigned_var(expr: &Expr) -> Option<(u32, Type)> {
656        if let ExprKind::Binary { left, op, right } = &expr.kind
657            && op.is_assign()
658            && let ExprKind::Var(idx) = left.kind
659        {
660            return Some((idx, right.get_type()));
661        }
662        None
663    }
664
665    fn declare_assigned_vars(&mut self, ctx: &mut BuildContext, stmt: &Stmt) -> Result<()> {
666        match &stmt.kind {
667            StmtKind::Expr(expr, _) => {
668                if let Some((idx, ty)) = Self::expr_assigned_var(expr) {
669                    match ctx.get_var(idx).ok() {
670                        Some(LocalVar::Variable { .. }) | Some(LocalVar::Closure { .. }) => {}
671                        Some(LocalVar::Value { val, ty }) => {
672                            ctx.set_var(idx, LocalVar::Value { val, ty })?;
673                        }
674                        Some(LocalVar::None) | None => {
675                            let init = self.zero_value(ctx, &ty)?;
676                            ctx.set_var(idx, init.into())?;
677                        }
678                    }
679                }
680            }
681            StmtKind::Block(stmts) => {
682                for stmt in stmts {
683                    self.declare_assigned_vars(ctx, stmt)?;
684                }
685            }
686            StmtKind::If { then_body, else_body, .. } => {
687                self.declare_assigned_vars(ctx, then_body)?;
688                if let Some(else_body) = else_body {
689                    self.declare_assigned_vars(ctx, else_body)?;
690                }
691            }
692            StmtKind::While { body, .. } | StmtKind::Loop(body) => {
693                self.declare_assigned_vars(ctx, body)?;
694            }
695            StmtKind::For { body, .. } => {
696                self.declare_assigned_vars(ctx, body)?;
697            }
698            _ => {}
699        }
700        Ok(())
701    }
702
703    fn zero_value(&mut self, ctx: &mut BuildContext, ty: &Type) -> Result<(Value, Type)> {
704        if self.is_aggregate_ty(ty) {
705            Ok((self.struct_alloc(ctx, ty)?, ty.clone()))
706        } else if ty.is_f32() {
707            Ok((ctx.builder.ins().f32const(0.0), ty.clone()))
708        } else if ty.is_f64() {
709            Ok((ctx.builder.ins().f64const(0.0), ty.clone()))
710        } else {
711            Ok((ctx.builder.ins().iconst(crate::get_type(ty)?, 0), ty.clone()))
712        }
713    }
714
715    fn assign(&mut self, ctx: &mut BuildContext, left: &Expr, value: LocalVar) -> Result<(Value, Type)> {
716        if let ExprKind::Var(idx) = &left.kind {
717            if value.is_closure() {
718                ctx.set_var(*idx, value)?;
719                return self.get_null_value(ctx);
720            }
721            let value_ty = value.get_ty();
722            if let Some(ty) = ctx.get_var_ty(*idx) {
723                if self.is_aggregate_ty(&ty) {
724                    let dst = ctx.get_var(*idx)?.get(ctx).ok_or(anyhow!("aggregate variable has no value"))?.0;
725                    let src = value.get(ctx).ok_or(anyhow!("aggregate assignment has no value"))?;
726                    let src = self.convert(ctx, src, ty.clone())?;
727                    self.copy_vec_element(ctx, dst, src, &ty);
728                } else if value_ty != ty {
729                    if let Some(vt) = value.get(ctx) {
730                        let val = self.convert(ctx, vt, ty.clone())?;
731                        ctx.set_var(*idx, LocalVar::Value { val, ty })?;
732                    } else if ty.is_any() {
733                        let const_idx = self.compiler.get_const(Dynamic::Null);
734                        let (val, ty) = self.get_const_value(ctx, const_idx)?;
735                        ctx.set_var(*idx, LocalVar::Value { val, ty })?;
736                    } else {
737                        ctx.set_var(*idx, LocalVar::None)?;
738                    }
739                } else {
740                    ctx.set_var(*idx, value)?;
741                }
742            } else if self.is_aggregate_ty(&value_ty) {
743                let src = value.get(ctx).ok_or(anyhow!("aggregate initializer has no value"))?;
744                let dst = self.struct_alloc(ctx, &value_ty)?;
745                let src = self.convert(ctx, src, value_ty.clone())?;
746                self.copy_vec_element(ctx, dst, src, &value_ty);
747                ctx.set_var(*idx, LocalVar::Value { val: dst, ty: value_ty })?;
748            } else {
749                ctx.set_var(*idx, value)?;
750            }
751            let assigned = ctx.get_var(*idx)?;
752            if assigned.is_closure() {
753                return self.get_null_value(ctx);
754            }
755            let val = assigned.get(ctx).ok_or(anyhow!("assigned variable has no value"))?;
756            return Ok(val);
757        } else if left.is_idx() {
758            let value = match value {
759                LocalVar::Closure { id, captures } => self.callback_value(ctx, id, captures)?,
760                value => value,
761            };
762            let value = value.get(ctx).ok_or_else(|| anyhow!("idx assignment rhs has no value: left={:?}", left))?;
763            let (left, _, right) = left.clone().binary().unwrap();
764            let left = self.eval(ctx, &left)?.get(ctx).ok_or(anyhow!("未知局部变量 {:?}", left))?;
765            if let Type::Struct { params: _, fields } = &left.1 {
766                let idx = self.struct_field_index(&left.1, &right)?;
767                let field_ty = fields.get(idx).map(|(_, ty)| ty.clone()).ok_or_else(|| anyhow!("结构字段索引越界 {}", idx))?;
768                self.store_struct_field(ctx, left.0, idx, &field_ty, value.clone(), &left.1)?;
769                return Ok(value);
770            }
771            if let Some(elem_ty) = Self::vec_elem_ty(&left.1) {
772                let idx = if right.is_value() {
773                    let idx = right.clone().value()?.as_int().ok_or(anyhow!("Vec 索引必须是整数"))?;
774                    (ctx.builder.ins().iconst(types::I64, idx), Type::I64)
775                } else {
776                    self.eval(ctx, &right)?.get(ctx).ok_or(anyhow!("Vec 索引没有值"))?
777                };
778                self.store_vec_index(ctx, left.0, idx, &elem_ty, value.clone())?;
779                return Ok(value);
780            }
781            if let Some(elem_ty) = Self::array_elem_ty(&left.1) {
782                let idx = if right.is_value() {
783                    let idx = right.clone().value()?.as_int().ok_or(anyhow!("array index must be integer"))?;
784                    (ctx.builder.ins().iconst(types::I64, idx), Type::I64)
785                } else {
786                    self.eval(ctx, &right)?.get(ctx).ok_or(anyhow!("array index has no value"))?
787                };
788                self.store_array_index(ctx, left.0, idx, &elem_ty, value.clone())?;
789                return Ok(value);
790            }
791            if right.is_value() {
792                let right_value = right.clone().value()?;
793                if let Some(idx) = right_value.as_int() {
794                    let idx = ctx.builder.ins().iconst(types::I64, idx);
795                    if let Type::List(elem_ty) = &left.1
796                        && let Some((fn_name, value_ty)) = Self::list_set_idx_shortcut(elem_ty)
797                    {
798                        let stored = self.convert(ctx, value.clone(), value_ty.clone())?;
799                        let set_idx_fn = self.get_native_fn_cached(fn_name, &[Type::Any, Type::I64, value_ty])?;
800                        self.call_for_side_effect(ctx, set_idx_fn, vec![left.0, idx, stored])?;
801                        return Ok(value);
802                    }
803                    let f = self.get_method(&left.1, "set_idx")?;
804                    let args = self.adjust_args(ctx, vec![left, (idx, Type::I64), value.clone()], f.arg_tys()?)?;
805                    self.call_for_side_effect(ctx, f, args)?;
806                } else {
807                    let key = ctx.get_const(&right_value)?;
808                    let f = self.get_method(&left.1, "set_key")?;
809                    let args = self.adjust_args(ctx, vec![left, key, value.clone()], f.arg_tys()?)?;
810                    self.call_for_side_effect(ctx, f, args)?;
811                }
812            } else {
813                let right = self.eval(ctx, &right)?.get(ctx).unwrap();
814                if right.1.is_any() || right.1.is_str() {
815                    let f = self.get_method(&left.1, "set_key")?;
816                    let args = self.adjust_args(ctx, vec![left, right, value.clone()], f.arg_tys()?)?;
817                    self.call_for_side_effect(ctx, f, args)?;
818                } else {
819                    if let Type::List(elem_ty) = &left.1
820                        && let Some((fn_name, value_ty)) = Self::list_set_idx_shortcut(elem_ty)
821                    {
822                        let idx = self.convert(ctx, right.clone(), Type::I64)?;
823                        let stored = self.convert(ctx, value.clone(), value_ty.clone())?;
824                        let set_idx_fn = self.get_native_fn_cached(fn_name, &[Type::Any, Type::I64, value_ty])?;
825                        self.call_for_side_effect(ctx, set_idx_fn, vec![left.0, idx, stored])?;
826                        return Ok(value);
827                    }
828                    let f = self.get_method(&left.1, "set_idx")?;
829                    let args = self.adjust_args(ctx, vec![left, right, value.clone()], f.arg_tys()?)?;
830                    self.call_for_side_effect(ctx, f, args)?;
831                }
832            }
833            return Ok(value);
834        } else {
835            anyhow::bail!("赋值给不支持的目标: {:?} {:?}", left, value)
836        }
837    }
838
839    fn assignment_target_ty(&mut self, ctx: &mut BuildContext, left: &Expr) -> Option<Type> {
840        if let ExprKind::Var(idx) = &left.kind {
841            return ctx.get_var_ty(*idx).filter(|ty| !ty.is_any()).or_else(|| ctx.local_type_hint(*idx));
842        }
843        None
844    }
845
846    fn empty_typed_list(ty: &Type) -> Option<Dynamic> {
847        let Type::List(elem_ty) = ty else {
848            return None;
849        };
850        match elem_ty.as_ref() {
851            Type::Bool | Type::U8 => Some(Dynamic::list(Vec::new())),
852            Type::I8 => Some(Dynamic::VecI8(Default::default())),
853            Type::U16 => Some(Dynamic::VecU16(Default::default())),
854            Type::I16 => Some(Dynamic::VecI16(Default::default())),
855            Type::U32 => Some(Dynamic::VecU32(Default::default())),
856            Type::I32 => Some(Dynamic::VecI32(Default::default())),
857            Type::F32 => Some(Dynamic::VecF32(Default::default())),
858            Type::U64 => Some(Dynamic::VecU64(Vec::new())),
859            Type::I64 => Some(Dynamic::VecI64(Vec::new())),
860            Type::F64 => Some(Dynamic::VecF64(Vec::new())),
861            Type::Str => Some(Dynamic::list(Vec::new())),
862            _ => None,
863        }
864    }
865
866    fn list_push_shortcut(elem_ty: &Type) -> Option<(&'static str, Type)> {
867        match elem_ty {
868            Type::Bool => Some(("Any::push_bool", Type::Bool)),
869            Type::U8 => Some(("Any::push_u8", Type::U8)),
870            Type::I8 => Some(("Any::push_i8", Type::I8)),
871            Type::U16 => Some(("Any::push_u16", Type::U16)),
872            Type::I16 => Some(("Any::push_i16", Type::I16)),
873            Type::U32 => Some(("Any::push_u32", Type::U32)),
874            Type::I32 => Some(("Any::push_i32", Type::I32)),
875            Type::F32 => Some(("Any::push_f32", Type::F32)),
876            Type::U64 => Some(("Any::push_u64", Type::U64)),
877            Type::I64 => Some(("Any::push_i64", Type::I64)),
878            Type::F64 => Some(("Any::push_f64", Type::F64)),
879            Type::Str => Some(("Any::push_str", Type::Str)),
880            _ => None,
881        }
882    }
883
884    fn list_get_idx_shortcut(elem_ty: &Type) -> Option<(&'static str, Type)> {
885        match elem_ty {
886            Type::Bool => Some(("Any::get_idx_bool", Type::Bool)),
887            Type::U8 => Some(("Any::get_idx_u8", Type::U8)),
888            Type::I8 => Some(("Any::get_idx_i8", Type::I8)),
889            Type::U16 => Some(("Any::get_idx_u16", Type::U16)),
890            Type::I16 => Some(("Any::get_idx_i16", Type::I16)),
891            Type::U32 => Some(("Any::get_idx_u32", Type::U32)),
892            Type::I32 => Some(("Any::get_idx_i32", Type::I32)),
893            Type::F32 => Some(("Any::get_idx_f32", Type::F32)),
894            Type::U64 => Some(("Any::get_idx_u64", Type::U64)),
895            Type::I64 => Some(("Any::get_idx_i64", Type::I64)),
896            Type::F64 => Some(("Any::get_idx_f64", Type::F64)),
897            Type::Str => Some(("Any::get_idx_str", Type::Str)),
898            _ => None,
899        }
900    }
901
902    fn list_set_idx_shortcut(elem_ty: &Type) -> Option<(&'static str, Type)> {
903        match elem_ty {
904            Type::Bool => Some(("Any::set_idx_bool", Type::Bool)),
905            Type::U8 => Some(("Any::set_idx_u8", Type::U8)),
906            Type::I8 => Some(("Any::set_idx_i8", Type::I8)),
907            Type::U16 => Some(("Any::set_idx_u16", Type::U16)),
908            Type::I16 => Some(("Any::set_idx_i16", Type::I16)),
909            Type::U32 => Some(("Any::set_idx_u32", Type::U32)),
910            Type::I32 => Some(("Any::set_idx_i32", Type::I32)),
911            Type::F32 => Some(("Any::set_idx_f32", Type::F32)),
912            Type::U64 => Some(("Any::set_idx_u64", Type::U64)),
913            Type::I64 => Some(("Any::set_idx_i64", Type::I64)),
914            Type::F64 => Some(("Any::set_idx_f64", Type::F64)),
915            Type::Str => Some(("Any::set_idx_str", Type::Str)),
916            _ => None,
917        }
918    }
919
920    fn expr_is_empty_list(&self, expr: &Expr) -> bool {
921        match &expr.kind {
922            ExprKind::Value(value) => value.is_list() && value.len() == 0,
923            ExprKind::Const(idx) => self.compiler.consts.get_index(*idx).is_some_and(|(_, value)| value.is_list() && value.len() == 0),
924            ExprKind::Typed { value, .. } => self.expr_is_empty_list(value),
925            _ => false,
926        }
927    }
928
929    fn closure_value(&self, ctx: &mut BuildContext, id: u32) -> Result<LocalVar> {
930        let (name, symbol) = self.compiler.symbols.get_symbol(id)?;
931        let captures = match symbol {
932            Symbol::Fn { cap, .. } => cap
933                .vars
934                .iter()
935                .map(|idx| {
936                    let var = ctx.get_var(*idx as u32).map_err(|err| anyhow!("闭包 {} 捕获变量失败: idx={}, cap.vars={:?}, {}", name, idx, cap.vars, err))?;
937                    var.get(ctx).ok_or_else(|| anyhow!("闭包 {} 捕获变量没有值: idx={}, cap.vars={:?}", name, idx, cap.vars))
938                })
939                .collect::<Result<Vec<_>>>()?,
940            _ => Vec::new(),
941        };
942        Ok(LocalVar::Closure { id, captures })
943    }
944
945    fn is_spawn_fn_name(name: &str) -> bool {
946        name == "spawn" || name == "std::spawn"
947    }
948
949    fn spawn_arg_pack_len(&self, expr: &Expr) -> Option<usize> {
950        match &expr.kind {
951            ExprKind::Tuple(items) | ExprKind::List(items) => Some(items.len()),
952            ExprKind::Value(value) => value.is_list().then(|| value.len()),
953            ExprKind::Const(idx) => self.compiler.consts.get_index(*idx).and_then(|(_, value)| value.is_list().then(|| value.len())),
954            ExprKind::Typed { value, .. } => self.spawn_arg_pack_len(value),
955            _ => None,
956        }
957    }
958
959    fn eval_spawn_arg_pack(&mut self, ctx: &mut BuildContext, expr: &Expr) -> Result<(Value, Type)> {
960        let (ExprKind::Tuple(items) | ExprKind::List(items)) = &expr.kind else {
961            return self.eval(ctx, expr)?.get(ctx).ok_or_else(|| anyhow!("spawn closure args expression has no value"));
962        };
963        if items.is_empty() {
964            let idx = self.compiler.get_const(Dynamic::Null);
965            return self.get_const_value(ctx, idx);
966        }
967        let values = items.iter().map(|item| self.eval(ctx, item)?.get(ctx).ok_or_else(|| anyhow!("spawn closure arg has no value: {:?}", item))).collect::<Result<Vec<_>>>()?;
968        self.dynamic_list_from_values(ctx, values)
969    }
970
971    fn dynamic_list_from_values(&mut self, ctx: &mut BuildContext, values: Vec<(Value, Type)>) -> Result<(Value, Type)> {
972        let idx = self.compiler.get_const(Dynamic::list(vec![Dynamic::Null; values.len()]));
973        let (list, _) = self.get_const_value(ctx, idx)?;
974        for (idx, value) in values.into_iter().enumerate() {
975            let value = self.convert(ctx, value, Type::Any)?;
976            let idx = ctx.builder.ins().iconst(types::I64, idx as i64);
977            let set_idx = self.get_fn(self.get_id("Any::set_idx")?, &[Type::Any, Type::I64, Type::Any])?;
978            self.call_for_side_effect(ctx, set_idx, vec![list, idx, value])?;
979        }
980        Ok((list, Type::Any))
981    }
982
983    fn callback_value(&mut self, ctx: &mut BuildContext, id: u32, captures: Vec<(Value, Type)>) -> Result<LocalVar> {
984        let explicit_arg_len = match self.compiler.symbols.get_symbol(id)?.1 {
985            Symbol::Fn { ty: Type::Fn { tys, .. }, .. } => tys.len(),
986            _ => 0,
987        };
988        if explicit_arg_len > 16 {
989            return Err(anyhow!("native callback closure supports at most 16 explicit args"));
990        }
991        if explicit_arg_len + captures.len() > 24 {
992            return Err(anyhow!("native callback closure supports at most 24 args including captures, got {}", explicit_arg_len + captures.len()));
993        }
994        let explicit_arg_tys = vec![Type::Any; explicit_arg_len];
995        let capture_tys = vec![Type::Any; captures.len()];
996        let fn_info = self.gen_fn_with_capture_tys(Some(ctx), id, &explicit_arg_tys, &[], Some(&capture_tys))?;
997        let FnInfo::Call { fn_id, ret, .. } = fn_info else {
998            return Err(anyhow!("callback target must be compiled function"));
999        };
1000        let captures = if captures.is_empty() {
1001            let idx = self.compiler.get_const(Dynamic::Null);
1002            self.get_const_value(ctx, idx)?
1003        } else {
1004            self.dynamic_list_from_values(ctx, captures)?
1005        };
1006        let fn_ref = self.get_fn_ref(ctx, fn_id);
1007        let fn_addr = ctx.builder.ins().func_addr(ptr_type(), fn_ref);
1008        let ret_ty = Self::type_ptr_const(ctx, &ret);
1009        let explicit_arg_len = ctx.builder.ins().iconst(types::I64, explicit_arg_len as i64);
1010        let callback_new = self.callback_new_fn.ok_or_else(|| anyhow!("VM callback runtime is not registered"))?;
1011        let callback_new_ref = self.get_fn_ref(ctx, callback_new);
1012        let call_inst = ctx.builder.ins().call(callback_new_ref, &[fn_addr, ret_ty, explicit_arg_len, captures.0]);
1013        Ok((ctx.builder.inst_results(call_inst)[0], Type::Any).into())
1014    }
1015
1016    fn spawn_closure(&mut self, ctx: &mut BuildContext, id: u32, captures: Vec<(Value, Type)>, args_expr: &Expr) -> Result<LocalVar> {
1017        if !captures.is_empty() {
1018            return Err(anyhow!("spawn closure does not support captures yet"));
1019        }
1020        let arg_len = self.spawn_arg_pack_len(args_expr).ok_or_else(|| anyhow!("spawn closure args must be a tuple argument pack"))?;
1021        if arg_len > 16 {
1022            return Err(anyhow!("spawn supports at most 16 args, got {}", arg_len));
1023        }
1024        let arg_tys = vec![Type::Any; arg_len];
1025        let fn_info = self.gen_fn_with_params(Some(ctx), id, &arg_tys, &[])?;
1026        let FnInfo::Call { fn_id, ret, .. } = fn_info else {
1027            return Err(anyhow!("spawn closure target must be compiled function"));
1028        };
1029        let args = self.eval_spawn_arg_pack(ctx, args_expr)?;
1030        let args = self.convert(ctx, args, Type::Any)?;
1031        let fn_ref = self.get_fn_ref(ctx, fn_id);
1032        let fn_addr = ctx.builder.ins().func_addr(ptr_type(), fn_ref);
1033        let ret_ty = Self::type_ptr_const(ctx, &ret);
1034        let spawn_ptr = self.spawn_ptr_fn.ok_or_else(|| anyhow!("VM spawn ptr runtime is not registered"))?;
1035        let spawn_ref = self.get_fn_ref(ctx, spawn_ptr);
1036        let call_inst = ctx.builder.ins().call(spawn_ref, &[fn_addr, ret_ty, args]);
1037        Ok((ctx.builder.inst_results(call_inst)[0], Type::Bool).into())
1038    }
1039
1040    pub(crate) fn call_fn(&mut self, ctx: &mut BuildContext, id: u32, obj: Option<Expr>, params: &Vec<Expr>) -> Result<LocalVar> {
1041        self.call_fn_with_params(ctx, id, &[], obj, params)
1042    }
1043
1044    pub(crate) fn call_fn_with_params(&mut self, ctx: &mut BuildContext, id: u32, generic_args: &[Type], obj: Option<Expr>, params: &Vec<Expr>) -> Result<LocalVar> {
1045        self.call_fn_with_capture_values(ctx, id, generic_args, obj, params, None)
1046    }
1047
1048    pub(crate) fn call_fn_with_capture_values(&mut self, ctx: &mut BuildContext, id: u32, generic_args: &[Type], obj: Option<Expr>, params: &Vec<Expr>, capture_values: Option<Vec<(Value, Type)>>) -> Result<LocalVar> {
1049        let fn_name = self.compiler.symbols.get_symbol(id).map(|(name, _)| name.clone())?;
1050        if capture_values.is_none()
1051            && generic_args.is_empty()
1052            && obj.is_none()
1053            && Self::is_spawn_fn_name(fn_name.as_str())
1054            && let [target, args] = params.as_slice()
1055            && let LocalVar::Closure { id, captures } = self.eval(ctx, target)?
1056        {
1057            return self.spawn_closure(ctx, id, captures, args);
1058        }
1059        let mut args: Vec<(Value, Type)> = if let Some(obj) = obj { vec![self.eval(ctx, &obj)?.get(ctx).ok_or_else(|| anyhow!("函数 {} 的接收者表达式没有值: {:?}", fn_name, obj))?] } else { Vec::new() };
1060        for p in params {
1061            let value = self.eval(ctx, p)?;
1062            let value = match value {
1063                LocalVar::Closure { id, captures } => self.callback_value(ctx, id, captures)?.get(ctx).ok_or_else(|| anyhow!("函数 {} 的 callback 参数没有值: {:?}", fn_name, p))?,
1064                value => value.get(ctx).ok_or_else(|| anyhow!("函数 {} 的参数表达式没有值: {:?}", fn_name, p))?,
1065            };
1066            args.push(value);
1067        }
1068        if let Some(captures) = &capture_values {
1069            args.extend(captures.iter().cloned());
1070        }
1071        if let [list, value] = args.as_slice()
1072            && fn_name.as_str() == "Any::push"
1073            && let Type::List(elem_ty) = &list.1
1074            && let Some((fn_name, value_ty)) = Self::list_push_shortcut(elem_ty)
1075        {
1076            let value = self.convert(ctx, (value.0, value.1.clone()), value_ty.clone())?;
1077            let push_fn = self.get_native_fn_cached(fn_name, &[Type::Any, value_ty])?;
1078            self.call_for_side_effect(ctx, push_fn, vec![list.0, value])?;
1079            return Ok(LocalVar::None);
1080        }
1081        if let [list, idx] = args.as_slice()
1082            && fn_name.as_str() == "Any::get_idx"
1083            && let Type::List(elem_ty) = &list.1
1084            && let Some((fn_name, _ret_ty)) = Self::list_get_idx_shortcut(elem_ty)
1085        {
1086            let idx = self.convert(ctx, (idx.0, idx.1.clone()), Type::I64)?;
1087            let get_idx_fn = self.get_native_fn_cached(fn_name, &[Type::Any, Type::I64])?;
1088            return self.call(ctx, get_idx_fn, vec![list.0, idx]).map(|value| value.into());
1089        }
1090        if fn_name.as_str().ends_with("Vec::swap")
1091            && let Some((base, vec_ty)) = args.first().cloned()
1092            && let Some(elem_ty) = Self::vec_elem_ty(&vec_ty)
1093        {
1094            let [_, left_idx, right_idx]: [(Value, Type); 3] = args.try_into().map_err(|_| anyhow!("Vec::swap 需要 self 和两个索引参数"))?;
1095            self.swap_vec_index(ctx, base, left_idx, right_idx, &elem_ty)?;
1096            return Ok(LocalVar::None);
1097        }
1098        let visible_arg_len = args.len() - capture_values.as_ref().map(|captures| captures.len()).unwrap_or(0);
1099        let arg_tys: Vec<Type> = args.iter().take(visible_arg_len).map(|(_, ty)| ty.clone()).collect();
1100        let fn_info = match if generic_args.is_empty() { self.get_fn(id, &arg_tys) } else { Err(anyhow!("generic function needs specialization")) } {
1101            Ok(info) => info,
1102            Err(_) => self.gen_fn_with_params(Some(ctx), id, &arg_tys, generic_args).map_err(|e| {
1103                log::error!("{:?}", self.compiler.symbols.get_symbol(id));
1104                e
1105            })?,
1106        };
1107        match &fn_info {
1108            FnInfo::Call { fn_id: _, arg_tys: want_tys, caps, ret, context: _ } => {
1109                let mut args = self.adjust_args(ctx, args, want_tys)?;
1110                if capture_values.is_none() {
1111                    for c in caps {
1112                        args.push(ctx.get_var(*c as u32)?.get(ctx).unwrap().0);
1113                    }
1114                }
1115                if ret.is_void() {
1116                    self.call_for_side_effect(ctx, fn_info, args)?;
1117                    Ok(LocalVar::None)
1118                } else {
1119                    self.call(ctx, fn_info, args).map(|r| r.into())
1120                }
1121            }
1122            _ => panic!("不可能编译出 inline 函数"),
1123        }
1124    }
1125
1126    pub(crate) fn eval(&mut self, ctx: &mut BuildContext, expr: &Expr) -> Result<LocalVar> {
1127        self.eval_with_expected(ctx, expr, None)
1128    }
1129
1130    fn eval_with_expected(&mut self, ctx: &mut BuildContext, expr: &Expr, expected: Option<&Type>) -> Result<LocalVar> {
1131        if let Some(ty) = expected
1132            && self.expr_is_empty_list(expr)
1133            && let Some(value) = Self::empty_typed_list(ty)
1134        {
1135            let idx = self.compiler.get_const(value);
1136            let (val, _) = self.get_const_value(ctx, idx)?;
1137            return Ok(LocalVar::Value { val, ty: ty.clone() });
1138        }
1139        match &expr.kind {
1140            ExprKind::Value(v) => Ok(ctx.get_const(v)?.into()),
1141            ExprKind::Var(idx) => {
1142                let v = ctx.get_var(*idx)?;
1143                Ok(v)
1144            }
1145            ExprKind::Unary { op, value } => {
1146                let v = self.eval(ctx, value)?.get(ctx).unwrap();
1147                if op == &UnaryOp::Not && v.1.is_any() {
1148                    let cond = self.bool_value(ctx, v)?;
1149                    let zero = ctx.builder.ins().iconst(types::I8, 0);
1150                    let one = ctx.builder.ins().iconst(types::I8, 1);
1151                    let is_zero = ctx.builder.ins().icmp_imm(IntCC::Equal, cond, 0);
1152                    Ok((ctx.builder.ins().select(is_zero, one, zero), Type::Bool).into())
1153                } else {
1154                    Ok(Self::unary(ctx, v, op.clone())?.into())
1155                }
1156            }
1157            ExprKind::Binary { left, op, right } => {
1158                if op == &BinaryOp::Assign {
1159                    let expected = self.assignment_target_ty(ctx, left);
1160                    match self.eval_with_expected(ctx, right, expected.as_ref()) {
1161                        Ok(value) => self.assign(ctx, left, value).map(|v| v.into()),
1162                        Err(e) => {
1163                            let err = self.compile_error(ctx, right.span, format!("赋值右侧编译失败: {e:#}"));
1164                            log::error!("{err:#}");
1165                            Err(err)
1166                        }
1167                    }
1168                } else {
1169                    if matches!(op, BinaryOp::And | BinaryOp::Or) {
1170                        let left = match self.eval(ctx, left)?.get(ctx) {
1171                            Some(left) => left,
1172                            None => {
1173                                let false_value = ctx.builder.ins().iconst(types::I8, 0);
1174                                (false_value, Type::Bool)
1175                            }
1176                        };
1177                        return self.short_circuit_logic(ctx, left, op.clone(), right).map(Into::into);
1178                    }
1179                    let assign_expr = if op.is_assign() { Some(left.clone()) } else { None };
1180                    let assign_expected = if op.is_assign() { self.assignment_target_ty(ctx, left) } else { None };
1181                    let left = match self.eval(ctx, left)?.get(ctx) {
1182                        Some(left) => left,
1183                        None => return Err(anyhow!("binary left has no value: {:?}", left)),
1184                    };
1185                    if op == &BinaryOp::Idx {
1186                        let left_ty = self.compiler.symbols.get_type(&left.1).unwrap_or_else(|_| left.1.clone());
1187                        let left = (left.0, left_ty);
1188                        if let Type::Struct { params: _, fields: _ } = &left.1 {
1189                            let idx = self.struct_field_index(&left.1, right)?;
1190                            return self.load_struct_field(ctx, left.0, idx, &left.1).map(|r| r.into());
1191                        }
1192                        if let Some(elem_ty) = Self::vec_elem_ty(&left.1) {
1193                            let idx = if right.is_value() {
1194                                let idx = right.clone().value()?.as_int().ok_or(anyhow!("Vec 索引必须是整数"))?;
1195                                (ctx.builder.ins().iconst(types::I64, idx), Type::I64)
1196                            } else {
1197                                self.eval(ctx, right)?.get(ctx).ok_or(anyhow!("Vec 索引没有值"))?
1198                            };
1199                            return self.load_vec_index(ctx, left.0, idx, &elem_ty).map(|r| r.into());
1200                        }
1201                        if let Some(elem_ty) = Self::array_elem_ty(&left.1) {
1202                            let idx = if right.is_value() {
1203                                let idx = right.clone().value()?.as_int().ok_or(anyhow!("array index must be integer"))?;
1204                                (ctx.builder.ins().iconst(types::I64, idx), Type::I64)
1205                            } else {
1206                                self.eval(ctx, right)?.get(ctx).ok_or(anyhow!("array index has no value"))?
1207                            };
1208                            return self.load_array_index(ctx, left.0, idx, &elem_ty).map(|r| r.into());
1209                        }
1210                        if right.is_value() {
1211                            let right_value = right.clone().value()?;
1212                            if let Some(idx) = right_value.as_int() {
1213                                let idx = ctx.builder.ins().iconst(types::I64, idx);
1214                                self.call(ctx, self.get_method(&left.1, "get_idx")?, vec![left.0, idx]).map(|r| r.into())
1215                            } else {
1216                                let key = ctx.get_const(&right_value)?;
1217                                self.call(ctx, self.get_method(&left.1, "get_key")?, vec![left.0, key.0]).map(|r| r.into())
1218                            }
1219                        } else if let ExprKind::Range { start, stop, inclusive } = &right.kind {
1220                            let start = self.eval(ctx, start)?.get(ctx).ok_or(anyhow!("range start has no value"))?;
1221                            let start = self.convert(ctx, start, Type::I64)?;
1222                            let stop = self.eval(ctx, stop)?.get(ctx).ok_or(anyhow!("range stop has no value"))?;
1223                            let stop = self.convert(ctx, stop, Type::Any)?;
1224                            let inclusive = ctx.builder.ins().iconst(types::I8, i64::from(*inclusive));
1225                            self.call(ctx, self.get_method(&left.1, "slice")?, vec![left.0, start, stop, inclusive]).map(|r| r.into())
1226                        } else {
1227                            let right = self.eval(ctx, right)?.get(ctx).ok_or(anyhow!("非Value {:?}", right))?;
1228                            if right.1.is_any() || right.1.is_str() {
1229                                let right = self.convert(ctx, right, Type::Any)?;
1230                                self.call(ctx, self.get_method(&left.1, "get_key")?, vec![left.0, right]).map(|r| r.into())
1231                            } else {
1232                                let right = self.convert(ctx, right, Type::I64)?;
1233                                if let Type::List(elem_ty) = &left.1
1234                                    && let Some((fn_name, _ret_ty)) = Self::list_get_idx_shortcut(elem_ty)
1235                                {
1236                                    let get_idx_fn = self.get_native_fn_cached(fn_name, &[Type::Any, Type::I64])?;
1237                                    return self.call(ctx, get_idx_fn, vec![left.0, right]).map(|r| r.into());
1238                                }
1239                                self.call(ctx, self.get_method(&left.1, "get_idx")?, vec![left.0, right]).map(|r| r.into())
1240                            }
1241                        }
1242                    } else {
1243                        let result = self.binary_with_expected(ctx, left, op.clone(), right, assign_expected.as_ref().or(expected))?.into();
1244                        if let Some(expr) = assign_expr { self.assign(ctx, &expr, result).map(|r| r.into()) } else { Ok(result.into()) }
1245                    }
1246                }
1247            }
1248            ExprKind::Call { obj, params } => {
1249                if let ExprKind::AssocId { id, params: generic_args } = &obj.kind {
1250                    self.call_fn_with_params(ctx, *id, generic_args, None, params)
1251                } else if let ExprKind::Id(id, obj) = &obj.kind {
1252                    self.call_fn(ctx, *id, obj.as_ref().map(|o| *o.clone()), params)
1253                } else if obj.is_value() {
1254                    //直接忽略掉的代码 编译期就可以忽略
1255                    return Ok(LocalVar::None);
1256                } else {
1257                    if obj.is_idx() {
1258                        let (left, _, right) = obj.clone().binary().unwrap();
1259                        let left = self.eval(ctx, &left)?.get(ctx).ok_or(anyhow!("obj {:?}", obj))?;
1260                        let ty = self.compiler.symbols.get_type(&left.1)?;
1261                        if let Some(name) = self.get_dynamic(&right) {
1262                            if name.as_str() == "swap"
1263                                && let Some(elem_ty) = Self::vec_elem_ty(&ty)
1264                            {
1265                                let [left_idx, right_idx]: [(Value, Type); 2] =
1266                                    params.iter().map(|p| self.eval(ctx, p)?.get(ctx).ok_or(anyhow!("Vec::swap 参数没有值"))).collect::<Result<Vec<_>>>()?.try_into().map_err(|_| anyhow!("Vec::swap 需要两个索引参数"))?;
1267                                self.swap_vec_index(ctx, left.0, left_idx, right_idx, &elem_ty)?;
1268                                return Ok(LocalVar::None);
1269                            }
1270                            let mut args = vec![left];
1271                            for p in params {
1272                                args.push(self.eval(ctx, p)?.get(ctx).ok_or_else(|| anyhow!("动态方法 {:?} 的参数表达式没有值: {:?}", name, p))?);
1273                            }
1274                            let (_, method_ty) = self.compiler.get_field(&ty, name.as_str()).map_err(|e| self.compile_error(ctx, obj.span, format!("类型 {:?} 没有成员方法 `{}`: {e:#}", ty, name.as_str())))?;
1275                            let Type::Symbol { id, .. } = method_ty else {
1276                                return Err(self.compile_error(ctx, obj.span, format!("`{:?}.{}` 不是成员函数", ty, name.as_str())));
1277                            };
1278                            let arg_tys: Vec<Type> = args.iter().map(|(_, ty)| ty.clone()).collect();
1279                            let method = self.get_fn(id, &arg_tys).or_else(|_| self.gen_fn_with_params(Some(ctx), id, &arg_tys, &[]))?;
1280                            let args = self.adjust_args(ctx, args, method.arg_tys()?)?;
1281                            self.call(ctx, method, args).map(|r| r.into())
1282                        } else {
1283                            self.eval(ctx, obj)
1284                        }
1285                    } else {
1286                        let val = self.eval(ctx, obj)?;
1287                        if let LocalVar::Closure { id, captures } = val {
1288                            return self.call_fn_with_capture_values(ctx, id, &[], None, params, Some(captures));
1289                        }
1290                        anyhow::bail!("暂未实现: {:?}", val)
1291                    }
1292                }
1293            }
1294            ExprKind::Typed { value, ty } => {
1295                if let Type::Struct { params: _, fields: _ } = ty
1296                    && let ExprKind::List(items) = &value.kind
1297                {
1298                    return Ok((self.init_struct_from_items(ctx, items, ty)?, ty.clone()).into());
1299                }
1300                if let Type::Array(_, _) = ty
1301                    && let ExprKind::List(items) = &value.kind
1302                {
1303                    return Ok((self.init_array_from_items(ctx, items, ty)?, ty.clone()).into());
1304                }
1305                let evaluated = self.eval(ctx, value)?;
1306                if evaluated.is_closure() {
1307                    return Ok(evaluated);
1308                }
1309                let vt = if let Some(vt) = evaluated.get(ctx) {
1310                    vt
1311                } else if ty.is_any() {
1312                    let idx = self.compiler.get_const(Dynamic::Null);
1313                    self.get_const_value(ctx, idx)?
1314                } else {
1315                    return Ok(LocalVar::None);
1316                };
1317                if let Type::Struct { params: _, fields: _ } = ty
1318                    && !self.is_opaque_custom_ty(ty)
1319                {
1320                    if &vt.1 == ty {
1321                        Ok(vt.into())
1322                    } else if vt.1.is_any() {
1323                        Ok((self.init_struct_from_dynamic(ctx, vt, ty)?, ty.clone()).into())
1324                    } else {
1325                        Err(anyhow!("cannot convert {:?} to {:?}", vt.1, ty))
1326                    }
1327                } else if &vt.1 != ty {
1328                    Ok((self.convert(ctx, vt, ty.clone())?, ty.clone()).into())
1329                } else {
1330                    Ok(vt.into())
1331                }
1332            }
1333            ExprKind::List(_) => anyhow::bail!("未实现: {:?}", expr),
1334            ExprKind::Repeat { value, len } => {
1335                let value = self.eval(ctx, value)?.get(ctx).ok_or(anyhow!("repeat value has no value"))?;
1336                let Type::ConstInt(len) = len else {
1337                    return Err(anyhow!("repeat length must be a compile-time integer"));
1338                };
1339                let len = u32::try_from(*len).map_err(|_| anyhow!("repeat length out of range"))?;
1340                self.init_repeat_array(ctx, value, len).map(|r| r.into())
1341            }
1342            ExprKind::Const(idx) => self.get_const_value(ctx, *idx).map(|v| v.into()),
1343            ExprKind::Id(id, _) => self.closure_value(ctx, *id),
1344            ExprKind::AssocId { id, .. } => self.closure_value(ctx, *id),
1345            expr => {
1346                //结构就是一块固定大小 的内存(或者是动态大小 最后一个数据成员可扩展 跟 C 结构一样)
1347                anyhow::bail!("未实现: {:?}", expr)
1348            }
1349        }
1350    }
1351
1352    fn gen_loop(&mut self, ctx: &mut BuildContext, cond: Option<&Expr>, body: &Stmt, f: Option<impl FnMut(&mut BuildContext)>) -> Result<()> {
1353        let loop_block = ctx.builder.create_block();
1354        let end_block = ctx.builder.create_block();
1355        if let Some(cond) = cond {
1356            let start_block = ctx.builder.create_block();
1357            ctx.builder.ins().jump(start_block, &[]);
1358            ctx.builder.switch_to_block(start_block);
1359            let cond = self.eval(ctx, cond)?.get(ctx).unwrap();
1360            let cond = self.bool_value(ctx, cond)?;
1361            let continue_block = if f.is_some() { ctx.builder.create_block() } else { start_block };
1362            ctx.builder.ins().brif(cond, loop_block, &[], end_block, &[]);
1363            ctx.builder.switch_to_block(loop_block);
1364            let body_terminated = self.gen_stmt(ctx, body, Some(end_block), Some(continue_block))?;
1365            if !body_terminated {
1366                ctx.builder.ins().jump(continue_block, &[]);
1367            }
1368            ctx.builder.seal_block(loop_block);
1369            f.map(|mut f| {
1370                ctx.builder.switch_to_block(continue_block);
1371                f(ctx);
1372                ctx.builder.ins().jump(start_block, &[]);
1373                ctx.builder.seal_block(continue_block);
1374            });
1375        } else {
1376            ctx.builder.ins().jump(loop_block, &[]);
1377            ctx.builder.switch_to_block(loop_block);
1378            let body_terminated = self.gen_stmt(ctx, body, Some(end_block), Some(loop_block))?;
1379            if !body_terminated {
1380                ctx.builder.ins().jump(loop_block, &[]);
1381            }
1382            ctx.builder.seal_block(loop_block);
1383        }
1384        ctx.builder.switch_to_block(end_block);
1385        Ok(())
1386    }
1387
1388    pub(crate) fn gen_stmt(&mut self, ctx: &mut BuildContext, stmt: &Stmt, break_block: Option<Block>, continue_block: Option<Block>) -> Result<bool> {
1389        match &stmt.kind {
1390            StmtKind::Expr(expr, _) => {
1391                let _ = self.eval(ctx, expr)?;
1392            }
1393            StmtKind::Break => {
1394                ctx.builder.ins().jump(break_block.unwrap(), &[]);
1395                return Ok(true);
1396            }
1397            StmtKind::Continue => {
1398                ctx.builder.ins().jump(continue_block.unwrap(), &[]);
1399                return Ok(true);
1400            }
1401            StmtKind::Return(expr) => {
1402                if let Some(expr) = expr {
1403                    let value = self.eval(ctx, expr)?;
1404                    let value = value.get(ctx);
1405                    self.return_value(ctx, value)?;
1406                } else {
1407                    self.return_value(ctx, None)?;
1408                }
1409                return Ok(true);
1410            }
1411            StmtKind::If { cond, then_body, else_body } => {
1412                self.declare_assigned_vars(ctx, then_body)?;
1413                if let Some(else_body) = else_body {
1414                    self.declare_assigned_vars(ctx, else_body)?;
1415                }
1416                let then_block = ctx.builder.create_block();
1417                let cond = self.eval(ctx, cond)?.get(ctx).ok_or(anyhow!("未知的条件 {:?}", cond))?;
1418                let cond = self.bool_value(ctx, cond)?;
1419                let mut end_block = None;
1420                if let Some(else_body) = else_body {
1421                    let else_block = ctx.builder.create_block();
1422                    ctx.builder.ins().brif(cond, then_block, &[], else_block, &[]);
1423                    ctx.builder.switch_to_block(then_block);
1424                    if !self.gen_stmt(ctx, then_body, break_block, continue_block)? {
1425                        let block = ctx.builder.create_block();
1426                        ctx.builder.ins().jump(block, &[]);
1427                        end_block = Some(block);
1428                    }
1429                    ctx.builder.switch_to_block(else_block);
1430                    if !self.gen_stmt(ctx, else_body, break_block, continue_block)? {
1431                        if end_block.is_none() {
1432                            end_block = Some(ctx.builder.create_block());
1433                        }
1434                        ctx.builder.ins().jump(end_block.unwrap(), &[]);
1435                    }
1436                    ctx.builder.seal_block(else_block);
1437                } else {
1438                    let block = ctx.builder.create_block();
1439                    ctx.builder.ins().brif(cond, then_block, &[], block, &[]);
1440                    end_block = Some(block);
1441                    ctx.builder.switch_to_block(then_block);
1442                    if !self.gen_stmt(ctx, then_body, break_block, continue_block)? {
1443                        ctx.builder.ins().jump(end_block.unwrap(), &[]); //如果不是返回指令 增加跳转到 end_block
1444                    }
1445                }
1446                if let Some(block) = end_block {
1447                    ctx.builder.switch_to_block(block);
1448                }
1449                ctx.builder.seal_block(then_block);
1450                return Ok(end_block.is_none());
1451            }
1452            StmtKind::Block(stmts) => {
1453                for (idx, stmt) in stmts.iter().enumerate() {
1454                    let r = self.gen_stmt(ctx, stmt, break_block, continue_block)?;
1455                    if idx == stmts.len() - 1 {
1456                        return Ok(r);
1457                    }
1458                }
1459            }
1460            StmtKind::While { cond, body } => {
1461                self.declare_assigned_vars(ctx, body)?;
1462                let no_loop: Option<fn(&mut BuildContext)> = None;
1463                self.gen_loop(ctx, Some(cond), body, no_loop)?;
1464            }
1465            StmtKind::Loop(body) => {
1466                self.declare_assigned_vars(ctx, body)?;
1467                let no_loop: Option<fn(&mut BuildContext)> = None;
1468                self.gen_loop(ctx, None, body, no_loop)?;
1469            }
1470            StmtKind::For { pat, range, body } => {
1471                if let ExprKind::Range { start, stop, inclusive } = &range.kind {
1472                    if let PatternKind::Var { idx, .. } = &pat.kind {
1473                        let start = self.eval(ctx, start)?.get(ctx).ok_or(anyhow!("range start has no value"))?;
1474                        let stop = self.eval(ctx, stop)?.get(ctx).ok_or(anyhow!("range stop has no value"))?;
1475                        let range_ty = if start.1.is_any() && stop.1.is_any() {
1476                            Type::I64
1477                        } else if start.1.is_any() {
1478                            stop.1.clone()
1479                        } else if stop.1.is_any() {
1480                            start.1.clone()
1481                        } else {
1482                            start.1.clone() + stop.1.clone()
1483                        };
1484                        if !range_ty.is_int() && !range_ty.is_uint() {
1485                            anyhow::bail!("for range bounds must be integer, got {:?}", range_ty);
1486                        }
1487                        let start = self.convert(ctx, start, range_ty.clone())?;
1488                        let stop = self.convert(ctx, stop, range_ty.clone())?;
1489                        ctx.set_var(*idx, (start, range_ty.clone()).into())?;
1490                        self.declare_assigned_vars(ctx, body)?;
1491
1492                        let start_block = ctx.builder.create_block();
1493                        let body_block = ctx.builder.create_block();
1494                        let continue_block = ctx.builder.create_block();
1495                        let end_block = ctx.builder.create_block();
1496                        ctx.builder.ins().jump(start_block, &[]);
1497
1498                        ctx.builder.switch_to_block(start_block);
1499                        let current = ctx.get_var(*idx)?.get(ctx).ok_or(anyhow!("range loop variable has no value"))?;
1500                        let cond = if range_ty.is_uint() {
1501                            let op = if *inclusive { IntCC::UnsignedLessThanOrEqual } else { IntCC::UnsignedLessThan };
1502                            ctx.builder.ins().icmp(op, current.0, stop)
1503                        } else {
1504                            let op = if *inclusive { IntCC::SignedLessThanOrEqual } else { IntCC::SignedLessThan };
1505                            ctx.builder.ins().icmp(op, current.0, stop)
1506                        };
1507                        ctx.builder.ins().brif(cond, body_block, &[], end_block, &[]);
1508
1509                        ctx.builder.switch_to_block(body_block);
1510                        let body_terminated = self.gen_stmt(ctx, body, Some(end_block), Some(continue_block))?;
1511                        if !body_terminated {
1512                            ctx.builder.ins().jump(continue_block, &[]);
1513                        }
1514                        ctx.builder.seal_block(body_block);
1515
1516                        ctx.builder.switch_to_block(continue_block);
1517                        let current = ctx.get_var(*idx)?.get(ctx).ok_or(anyhow!("range loop variable has no value"))?;
1518                        let step = match &range_ty {
1519                            Type::I64 | Type::U64 => ctx.builder.ins().iconst(types::I64, 1),
1520                            Type::I32 | Type::U32 => ctx.builder.ins().iconst(types::I32, 1),
1521                            Type::I16 | Type::U16 => ctx.builder.ins().iconst(types::I16, 1),
1522                            Type::I8 | Type::U8 => ctx.builder.ins().iconst(types::I8, 1),
1523                            _ => unreachable!(),
1524                        };
1525                        let next = ctx.builder.ins().iadd(current.0, step);
1526                        ctx.set_var(*idx, (next, range_ty).into())?;
1527                        ctx.builder.ins().jump(start_block, &[]);
1528                        ctx.builder.seal_block(continue_block);
1529                        ctx.builder.seal_block(start_block);
1530                        ctx.builder.switch_to_block(end_block);
1531                    }
1532                } else if let PatternKind::Var { idx, .. } = &pat.kind {
1533                    let vt = self.eval(ctx, range)?.get(ctx).unwrap();
1534                    if let Type::List(elem_ty) = &vt.1 {
1535                        let len_fn = self.get_native_fn_cached("Any::len", &[Type::Any])?;
1536                        let len = self.call(ctx, len_fn, vec![vt.0])?;
1537                        let len = self.convert(ctx, len.into(), Type::I64)?;
1538                        let zero = ctx.builder.ins().iconst(types::I64, 0);
1539                        let get_idx_fn = if let Some((fn_name, _)) = Self::list_get_idx_shortcut(elem_ty) {
1540                            self.get_native_fn_cached(fn_name, &[Type::Any, Type::I64])?
1541                        } else {
1542                            self.get_native_fn_cached("Any::get_idx", &[Type::Any, Type::I64])?
1543                        };
1544                        let get_idx_ret_ty = get_idx_fn.get_type()?;
1545                        let get_idx_id = get_idx_fn.get_id()?;
1546                        let get_idx_ref = self.get_fn_ref(ctx, get_idx_id);
1547                        let call_inst = ctx.builder.ins().call(get_idx_ref, &[vt.0, zero]);
1548                        let first = ctx.builder.inst_results(call_inst)[0];
1549                        ctx.set_var(*idx, (first, get_idx_ret_ty.clone()).into())?;
1550                        self.declare_assigned_vars(ctx, body)?;
1551
1552                        let index_var = ctx.builder.declare_var(types::I64);
1553                        ctx.builder.def_var(index_var, zero);
1554                        let start_block = ctx.builder.create_block();
1555                        let body_block = ctx.builder.create_block();
1556                        let continue_block = ctx.builder.create_block();
1557                        let end_block = ctx.builder.create_block();
1558                        ctx.builder.ins().jump(start_block, &[]);
1559                        ctx.builder.switch_to_block(start_block);
1560                        let index = ctx.builder.use_var(index_var);
1561                        let cond = ctx.builder.ins().icmp(IntCC::SignedLessThan, index, len);
1562                        ctx.builder.ins().brif(cond, body_block, &[], end_block, &[]);
1563
1564                        ctx.builder.switch_to_block(body_block);
1565                        let get_idx_ref = ctx.get_fn_ref(get_idx_id).unwrap();
1566                        let call_inst = ctx.builder.ins().call(get_idx_ref, &[vt.0, index]);
1567                        let item = ctx.builder.inst_results(call_inst)[0];
1568                        ctx.set_var(*idx, (item, get_idx_ret_ty).into())?;
1569                        let body_terminated = self.gen_stmt(ctx, body, Some(end_block), Some(continue_block))?;
1570                        if !body_terminated {
1571                            ctx.builder.ins().jump(continue_block, &[]);
1572                        }
1573                        ctx.builder.seal_block(body_block);
1574
1575                        ctx.builder.switch_to_block(continue_block);
1576                        let index = ctx.builder.use_var(index_var);
1577                        let one = ctx.builder.ins().iconst(types::I64, 1);
1578                        let next_index = ctx.builder.ins().iadd(index, one);
1579                        ctx.builder.def_var(index_var, next_index);
1580                        ctx.builder.ins().jump(start_block, &[]);
1581                        ctx.builder.seal_block(continue_block);
1582                        ctx.builder.seal_block(start_block);
1583                        ctx.builder.switch_to_block(end_block);
1584                    } else if vt.1.is_any() {
1585                        let iter = self.call(ctx, self.get_method(&vt.1, "iter")?, vec![vt.0])?;
1586                        let next = self.get_method(&vt.1, "next")?;
1587                        let next_id = next.get_id()?;
1588                        let start = self.call(ctx, next, vec![iter.0])?;
1589                        ctx.set_var(*idx, start.into())?;
1590                        let cond = Self::expr(ExprKind::Binary { left: Box::new(Self::expr(ExprKind::Var(*idx))), op: BinaryOp::Ne, right: Box::new(Self::expr(ExprKind::Value(Dynamic::Null))) });
1591                        self.gen_loop(
1592                            ctx,
1593                            Some(&cond),
1594                            body,
1595                            Some(|ctx: &mut BuildContext| {
1596                                let fn_ref = ctx.get_fn_ref(next_id).unwrap();
1597                                let call_inst = ctx.builder.ins().call(fn_ref, &[iter.0]);
1598                                let ret = ctx.builder.inst_results(call_inst)[0];
1599                                let _ = ctx.set_var(*idx, (ret, Type::Any).into());
1600                            }),
1601                        )?;
1602                    }
1603                } else if let PatternKind::Tuple(pats) = &pat.kind {
1604                    let vt = self.eval(ctx, range)?.get(ctx).unwrap();
1605                    if vt.1.is_any() && pats.len() == 2 {
1606                        //暂时只处理 kv
1607                        let iter = self.call(ctx, self.get_method(&vt.1, "iter")?, vec![vt.0])?;
1608                        let next_pair = self.get_method(&vt.1, "next_pair")?;
1609                        let next_id = next_pair.get_id()?;
1610                        let get_idx = self.get_method(&vt.1, "get_idx")?.get_id()?;
1611
1612                        let start = self.call(ctx, next_pair, vec![iter.0])?;
1613                        let key_idx = ctx.builder.ins().iconst(types::I64, 0);
1614                        let key = self.call(ctx, self.get_method(&start.1, "get_idx")?, vec![start.0, key_idx])?;
1615                        let value_idx = ctx.builder.ins().iconst(types::I64, 1);
1616                        let value = self.call(ctx, self.get_method(&start.1, "get_idx")?, vec![start.0, value_idx])?;
1617                        ctx.set_var(pats[0].var().unwrap(), key.into())?;
1618                        ctx.set_var(pats[1].var().unwrap(), value.into())?;
1619                        let cond = Self::expr(ExprKind::Binary { left: Box::new(Self::expr(ExprKind::Var(pats[0].var().unwrap()))), op: BinaryOp::Ne, right: Box::new(Self::expr(ExprKind::Value(Dynamic::Null))) });
1620                        self.gen_loop(
1621                            ctx,
1622                            Some(&cond),
1623                            body,
1624                            Some(|ctx: &mut BuildContext| {
1625                                let fn_ref = ctx.get_fn_ref(next_id).unwrap();
1626                                let call_inst = ctx.builder.ins().call(fn_ref, &[iter.0]);
1627                                let ret = ctx.builder.inst_results(call_inst)[0];
1628
1629                                let fn_ref = ctx.get_fn_ref(get_idx).unwrap();
1630                                let call_inst = ctx.builder.ins().call(fn_ref, &[ret, key_idx]);
1631                                let key_ret = ctx.builder.inst_results(call_inst)[0];
1632                                let call_inst = ctx.builder.ins().call(fn_ref, &[ret, value_idx]);
1633                                let value_ret = ctx.builder.inst_results(call_inst)[0];
1634
1635                                let _ = ctx.set_var(pats[0].var().unwrap(), (key_ret, Type::Any).into());
1636                                let _ = ctx.set_var(pats[1].var().unwrap(), (value_ret, Type::Any).into());
1637                            }),
1638                        )?;
1639                    }
1640                }
1641            }
1642            _ => {
1643                anyhow::bail!("未实现: {:?}", stmt)
1644            }
1645        }
1646        Ok(false)
1647    }
1648}