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