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