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