Skip to main content

vm/
rt.rs

1#[cfg(feature = "ir-disassembly")]
2use compiler::Symbol;
3use compiler::{Capture, Compiler};
4use dynamic::{Dynamic, Type};
5use parser::{BinaryOp, Expr, ExprKind, PatternKind, Span, Stmt, StmtKind, UnaryOp};
6use std::collections::{BTreeMap, HashMap, VecDeque};
7
8use crate::context::LocalVar;
9
10use super::{FnInfo, FnVariant, PTR_TYPE, context::BuildContext, ptr_type};
11use cranelift::prelude::*;
12use cranelift_jit::{JITBuilder, JITModule};
13use cranelift_module::{DataDescription, DataId, FuncId, Module};
14
15use anyhow::{Result, anyhow};
16use smol_str::SmolStr;
17use std::sync::{Arc, RwLock};
18
19pub struct JITRunTime {
20    pub compiler: Compiler,
21    pub fns: BTreeMap<u32, FnVariant>,
22    pub sigs: Vec<(Vec<Type>, Signature, Type)>,
23    pub native_symbols: Arc<RwLock<HashMap<String, usize>>>,
24    pub(crate) pending_fns: VecDeque<PendingFn>,
25    pub(crate) compile_depth: usize,
26    #[cfg(feature = "ir-disassembly")]
27    pub ir_disassembly: BTreeMap<SmolStr, String>,
28    pub module: JITModule,
29    pub consts: Vec<Option<DataId>>,
30}
31
32pub(crate) struct PendingFn {
33    pub name: SmolStr,
34    pub symbol_id: u32,
35    pub fn_id: FuncId,
36    pub arg_tys: Vec<Type>,
37    pub ret_ty: Type,
38    pub body: Stmt,
39}
40
41impl JITRunTime {
42    fn expr(kind: ExprKind) -> Expr {
43        Expr::new(kind, Span::default())
44    }
45
46    fn stmt(kind: StmtKind) -> Stmt {
47        Stmt::new(kind, Span::default())
48    }
49
50    pub fn load(&mut self, code: Vec<u8>, arg_name: SmolStr) -> Result<(i64, Type)> {
51        let stmts = Compiler::parse_code(code)?;
52        self.compiler.clear();
53        self.compiler.symbols.add_module("__console".into());
54        let mut cap = Capture::default();
55        let body = Self::stmt(StmtKind::Block(self.compiler.compile_fn(&[arg_name], &mut vec![Type::Any], Self::stmt(StmtKind::Block(stmts)), &mut cap)?));
56        self.compiler.tys.push(Type::Any);
57        let ret_ty = self.compiler.infer_stmt(&body)?;
58        self.compiler.clear();
59        let fn_id = self.compile_fn(None, &[Type::Any], ret_ty.clone(), &body)?;
60        self.compiler.clear();
61        self.compiler.symbols.pop_module();
62        self.module.finalize_definitions()?;
63        Ok((self.module.get_finalized_function(fn_id) as i64, ret_ty))
64    }
65
66    pub fn import_code(&mut self, name: &str, code: Vec<u8>) -> Result<()> {
67        log::info!("import {}", name);
68        let _ = self.compiler.import_code(name, code)?;
69        Ok(())
70    }
71
72    #[cfg(feature = "ir-disassembly")]
73    pub fn disassemble_ir(&mut self, name: &str) -> Result<String> {
74        if let Some(ir) = self.ir_disassembly.get(name) {
75            return Ok(ir.clone());
76        }
77        let id = self.get_id(name)?;
78        let (_, symbol) = self.compiler.symbols.get_symbol(id)?;
79        if let Symbol::Fn { ty, .. } = symbol
80            && let Type::Fn { tys, .. } = ty
81            && tys.is_empty()
82        {
83            let _ = self.gen_fn(None, id, &[])?;
84        }
85        self.ir_disassembly.get(name).cloned().ok_or_else(|| anyhow!("未找到函数 {} 的 Cranelift IR;如果它需要参数,请先触发对应实例化", name))
86    }
87
88    pub fn get_fn_ptr(&mut self, name: &str, arg_tys: &[Type]) -> Result<(*const u8, Type)> {
89        let main_id = self.get_id(name)?;
90        let fn_info = self.gen_fn(None, main_id, arg_tys)?;
91        Ok((self.module.get_finalized_function(fn_info.get_id()?), fn_info.get_type()?))
92    }
93
94    pub fn get_const_value(&mut self, ctx: &mut BuildContext, idx: usize) -> Result<(Value, Type)> {
95        if self.consts.len() < idx + 1 {
96            self.consts.resize(idx + 1, None);
97        }
98        let id = if let Some(id) = self.consts.get(idx).cloned().unwrap_or(None) {
99            id
100        } else {
101            let id = self.module.declare_anonymous_data(true, false)?;
102            let mut desc = DataDescription::new();
103            let c = Box::new(self.compiler.consts[idx].deep_clone()); //深度拷贝 避免常量被污染
104            let ptr = Box::into_raw(c);
105            desc.define((ptr as i64).to_le_bytes().into());
106            self.module.define_data(id, &desc)?;
107            self.consts[idx] = Some(id);
108            id
109        };
110        let c = self.module.declare_data_in_func(id, &mut ctx.builder.func);
111        let addr = ctx.builder.ins().global_value(ptr_type(), c);
112        let value = ctx.builder.ins().load(ptr_type(), MemFlags::new(), addr, 0); //需要生成副本 避免被释放
113        Ok((self.call(ctx, self.get_method(&Type::Any, "clone")?, vec![value])?.0, Type::Any))
114    }
115
116    fn get_null_value(&mut self, ctx: &mut BuildContext) -> Result<(Value, Type)> {
117        let const_idx = self.compiler.get_const(Dynamic::Null);
118        self.get_const_value(ctx, const_idx)
119    }
120
121    pub fn get_dynamic(&self, expr: &Expr) -> Option<Dynamic> {
122        if let ExprKind::Const(idx) = &expr.kind { self.compiler.consts.get(*idx).cloned() } else { None }
123    }
124
125    pub fn get_method(&self, ty: &Type, name: &str) -> Result<FnInfo> {
126        self.compiler.get_field(ty, name).and_then(|(_, ty)| if let Type::Symbol { id, params: _ } = ty { self.get_fn(id, &[]) } else { Err(anyhow!("不是成员函数")) })
127    }
128
129    pub fn get_id(&self, name: &str) -> Result<u32> {
130        self.compiler.symbols.get_id(name)
131    }
132
133    pub fn get_type(&mut self, name: &str, arg_tys: &[Type]) -> Result<Type> {
134        let id = self.get_id(name)?;
135        if self.compiler.symbols.symbols.get(name).map(|s| s.is_fn()).unwrap_or(false) {
136            return self.compiler.infer_fn(id, arg_tys);
137        }
138        self.compiler.symbols.get_type(&Type::Symbol { id, params: Vec::new() })
139    }
140
141    pub fn new<F: FnMut(&mut JITBuilder)>(mut f: F) -> Self {
142        let native_symbols = Arc::new(RwLock::new(HashMap::<String, usize>::new()));
143        let lookup_symbols = native_symbols.clone();
144        let mut builder = JITBuilder::new(cranelift_module::default_libcall_names()).unwrap();
145        builder.symbol_lookup_fn(Box::new(move |name| lookup_symbols.read().unwrap().get(name).copied().map(|ptr| ptr as *const u8)));
146        f(&mut builder);
147        let module = JITModule::new(builder);
148        PTR_TYPE.get_or_init(|| module.isa().pointer_type());
149        let fns = BTreeMap::<u32, FnVariant>::new();
150        Self {
151            compiler: Compiler::new(),
152            fns,
153            sigs: Vec::new(),
154            native_symbols,
155            pending_fns: VecDeque::new(),
156            compile_depth: 0,
157            #[cfg(feature = "ir-disassembly")]
158            ir_disassembly: BTreeMap::new(),
159            module,
160            consts: Vec::new(),
161        }
162    }
163
164    fn unary(ctx: &mut BuildContext, left: (Value, Type), op: UnaryOp) -> Result<(Value, Type)> {
165        match op {
166            UnaryOp::Neg => {
167                if left.1.is_int() || left.1.is_uint() {
168                    if left.1.width() == 8 {
169                        let zero = ctx.builder.ins().iconst(types::I64, 0);
170                        return Ok((ctx.builder.ins().isub(zero, left.0), Type::I64));
171                    } else if left.1.width() == 4 {
172                        let zero = ctx.builder.ins().iconst(types::I32, 0);
173                        return Ok((ctx.builder.ins().isub(zero, left.0), Type::I32));
174                    }
175                } else if left.1.is_float() {
176                    return Ok((ctx.builder.ins().fneg(left.0), left.1));
177                }
178            }
179            UnaryOp::Not => {
180                if left.1.is_any() {
181                    return Err(anyhow!("defer any-bool not handling"));
182                }
183                let zero = ctx.builder.ins().iconst(types::I8, 0);
184                let one = ctx.builder.ins().iconst(types::I8, 1);
185                let is_zero = ctx.builder.ins().icmp_imm(IntCC::Equal, left.0, 0);
186                return Ok((ctx.builder.ins().select(is_zero, one, zero), Type::Bool));
187            }
188            _ => {}
189        }
190        Err(anyhow!("未实现 {:?} {:?}", left, op))
191    }
192
193    pub(crate) fn call(&mut self, ctx: &mut BuildContext, fn_info: FnInfo, args: Vec<Value>) -> Result<(Value, Type)> {
194        match fn_info {
195            FnInfo::Call { fn_id, arg_tys: _, caps: _, ret } => {
196                let fn_ref = self.get_fn_ref(ctx, fn_id);
197                let call_inst = ctx.builder.ins().call(fn_ref, &args);
198                if !ret.is_void() { Ok((ctx.builder.inst_results(call_inst)[0], ret)) } else { Err(anyhow!("没有返回值")) }
199            }
200            FnInfo::Inline { fn_ptr, arg_tys: _ } => fn_ptr(Some(ctx), args).map(|(v, t)| (v.unwrap(), t)),
201        }
202    }
203
204    fn call_for_side_effect(&mut self, ctx: &mut BuildContext, fn_info: FnInfo, args: Vec<Value>) -> Result<()> {
205        match fn_info {
206            FnInfo::Call { fn_id, arg_tys: _, caps: _, ret: _ } => {
207                let fn_ref = self.get_fn_ref(ctx, fn_id);
208                ctx.builder.ins().call(fn_ref, &args);
209                Ok(())
210            }
211            FnInfo::Inline { fn_ptr, arg_tys: _ } => fn_ptr(Some(ctx), args).map(|_| ()),
212        }
213    }
214
215    pub(crate) fn short_circuit_logic(&mut self, ctx: &mut BuildContext, left: (Value, Type), op: BinaryOp, right: &Expr) -> Result<(Value, Type)> {
216        let is_any = left.1.is_any();
217        if is_any {
218            let left_cond = self.bool_value(ctx, left.clone())?;
219            let rhs_block = ctx.builder.create_block();
220            let short_block = ctx.builder.create_block();
221            let end_block = ctx.builder.create_block();
222            ctx.builder.append_block_param(end_block, ptr_type());
223
224            match op {
225                BinaryOp::And => {
226                    ctx.builder.ins().brif(left_cond, rhs_block, &[], short_block, &[]);
227                }
228                BinaryOp::Or => {
229                    ctx.builder.ins().brif(left_cond, short_block, &[], rhs_block, &[]);
230                }
231                _ => unreachable!(),
232            }
233
234            ctx.builder.switch_to_block(rhs_block);
235            let right = self.eval(ctx, right)?.get(ctx).unwrap();
236            let right_any = self.convert(ctx, right, Type::Any)?;
237            ctx.builder.ins().jump(end_block, &[cranelift::codegen::ir::BlockArg::Value(right_any)]);
238            ctx.builder.seal_block(rhs_block);
239
240            ctx.builder.switch_to_block(short_block);
241            ctx.builder.ins().jump(end_block, &[cranelift::codegen::ir::BlockArg::Value(left.0)]);
242            ctx.builder.seal_block(short_block);
243
244            ctx.builder.switch_to_block(end_block);
245            let result = ctx.builder.block_params(end_block)[0];
246            Ok((result, Type::Any))
247        } else {
248            let left = self.bool_value(ctx, left)?;
249            let rhs_block = ctx.builder.create_block();
250            let short_block = ctx.builder.create_block();
251            let end_block = ctx.builder.create_block();
252            ctx.builder.append_block_param(end_block, types::I8);
253
254            match op {
255                BinaryOp::And => {
256                    ctx.builder.ins().brif(left, rhs_block, &[], short_block, &[]);
257                }
258                BinaryOp::Or => {
259                    ctx.builder.ins().brif(left, short_block, &[], rhs_block, &[]);
260                }
261                _ => unreachable!(),
262            }
263
264            ctx.builder.switch_to_block(rhs_block);
265            let right = self.eval(ctx, right)?.get(ctx).unwrap();
266            let right = self.bool_value(ctx, right)?;
267            ctx.builder.ins().jump(end_block, &[cranelift::codegen::ir::BlockArg::Value(right)]);
268            ctx.builder.seal_block(rhs_block);
269
270            ctx.builder.switch_to_block(short_block);
271            let short_value = match op {
272                BinaryOp::And => ctx.builder.ins().iconst(types::I8, 0),
273                BinaryOp::Or => ctx.builder.ins().iconst(types::I8, 1),
274                _ => unreachable!(),
275            };
276            ctx.builder.ins().jump(end_block, &[cranelift::codegen::ir::BlockArg::Value(short_value)]);
277            ctx.builder.seal_block(short_block);
278
279            ctx.builder.switch_to_block(end_block);
280            let result = ctx.builder.block_params(end_block)[0];
281            Ok((result, Type::Bool))
282        }
283    }
284
285    fn struct_alloc(&mut self, ctx: &mut BuildContext, ty: &Type) -> Result<Value> {
286        let size = ctx.builder.ins().iconst(types::I64, ty.width() as i64);
287        let alloc_id = self.get_id("__struct_alloc")?;
288        let alloc = self.get_fn(alloc_id, &[Type::I64])?;
289        self.call(ctx, alloc, vec![size]).map(|(v, _)| v)
290    }
291
292    fn store_struct_field(&mut self, ctx: &mut BuildContext, base: Value, idx: usize, field_ty: &Type, value: (Value, Type), struct_ty: &Type) -> Result<()> {
293        let offset = struct_ty.field_offset(idx).ok_or_else(|| anyhow!("结构字段索引越界 {}", idx))?;
294        let value = self.convert(ctx, value, field_ty.clone())?;
295        if field_ty.is_struct() || field_ty.is_array() {
296            let field_addr = ctx.builder.ins().iadd_imm(base, offset as i64);
297            self.copy_vec_element(ctx, field_addr, value, field_ty);
298        } else {
299            ctx.builder.ins().store(MemFlags::trusted(), value, base, offset as i32);
300        }
301        Ok(())
302    }
303
304    fn load_struct_field(&mut self, ctx: &mut BuildContext, base: Value, idx: usize, struct_ty: &Type) -> Result<(Value, Type)> {
305        if let Type::Struct { params: _, fields } = struct_ty {
306            let field_ty = fields.get(idx).map(|(_, ty)| ty).ok_or_else(|| anyhow!("结构字段索引越界 {}", idx))?;
307            let offset = struct_ty.field_offset(idx).ok_or_else(|| anyhow!("结构字段索引越界 {}", idx))?;
308            if field_ty.is_struct() || field_ty.is_array() {
309                return Ok((ctx.builder.ins().iadd_imm(base, offset as i64), field_ty.clone()));
310            }
311            let val = ctx.builder.ins().load(crate::get_type(field_ty)?, MemFlags::trusted(), base, offset as i32);
312            Ok((val, field_ty.clone()))
313        } else {
314            Err(anyhow!("不是结构体 {:?}", struct_ty))
315        }
316    }
317
318    fn struct_field_index(&self, struct_ty: &Type, right: &Expr) -> Result<usize> {
319        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()? };
320        if let Some(idx) = value.as_int() {
321            return usize::try_from(idx).map_err(|_| anyhow!("结构字段索引越界 {}", idx));
322        }
323        if value.is_str() {
324            return self.compiler.get_field(struct_ty, value.as_str()).map(|(idx, _)| idx);
325        }
326        Err(anyhow!("非立即数结构字段索引 {:?}", right))
327    }
328
329    fn vec_elem_ty(ty: &Type) -> Option<Type> {
330        if let Type::Vec(elem, 0) = ty { Some((**elem).clone()) } else { None }
331    }
332
333    fn array_elem_ty(ty: &Type) -> Option<Type> {
334        if let Type::Array(elem, _) = ty { Some((**elem).clone()) } else { None }
335    }
336
337    fn vec_index_addr(&mut self, ctx: &mut BuildContext, base: Value, idx: (Value, Type), elem_ty: &Type) -> Result<Value> {
338        let idx = self.convert(ctx, idx, Type::I64)?;
339        let width = ctx.builder.ins().iconst(types::I64, elem_ty.storage_width() as i64);
340        let offset = ctx.builder.ins().imul(idx, width);
341        Ok(ctx.builder.ins().iadd(base, offset))
342    }
343
344    fn array_index_addr(&mut self, ctx: &mut BuildContext, base: Value, idx: (Value, Type), elem_ty: &Type) -> Result<Value> {
345        self.vec_index_addr(ctx, base, idx, elem_ty)
346    }
347
348    fn load_array_index(&mut self, ctx: &mut BuildContext, base: Value, idx: (Value, Type), elem_ty: &Type) -> Result<(Value, Type)> {
349        let addr = self.array_index_addr(ctx, base, idx, elem_ty)?;
350        if elem_ty.is_struct() || elem_ty.is_array() {
351            Ok((addr, elem_ty.clone()))
352        } else {
353            let val = ctx.builder.ins().load(crate::get_type(elem_ty)?, MemFlags::trusted(), addr, 0);
354            Ok((val, elem_ty.clone()))
355        }
356    }
357
358    fn store_array_index(&mut self, ctx: &mut BuildContext, base: Value, idx: (Value, Type), elem_ty: &Type, value: (Value, Type)) -> Result<()> {
359        let addr = self.array_index_addr(ctx, base, idx, elem_ty)?;
360        let value = self.convert(ctx, value, elem_ty.clone())?;
361        if elem_ty.is_struct() || elem_ty.is_array() {
362            self.copy_vec_element(ctx, addr, value, elem_ty);
363        } else {
364            ctx.builder.ins().store(MemFlags::trusted(), value, addr, 0);
365        }
366        Ok(())
367    }
368
369    fn init_repeat_array(&mut self, ctx: &mut BuildContext, value: (Value, Type), len: u32) -> Result<(Value, Type)> {
370        let elem_ty = value.1.clone();
371        let array_ty = Type::Array(std::rc::Rc::new(elem_ty.clone()), len);
372        let base = self.struct_alloc(ctx, &array_ty)?;
373        for idx in 0..len {
374            let idx = (ctx.builder.ins().iconst(types::I64, idx as i64), Type::I64);
375            self.store_array_index(ctx, base, idx, &elem_ty, value.clone())?;
376        }
377        Ok((base, array_ty))
378    }
379
380    fn init_array_from_items(&mut self, ctx: &mut BuildContext, items: &[Expr], ty: &Type) -> Result<Value> {
381        let Type::Array(elem_ty, len) = ty else {
382            return Err(anyhow!("not an array type: {:?}", ty));
383        };
384        if items.len() != *len as usize {
385            return Err(anyhow!("array literal length {} does not match {}", items.len(), len));
386        }
387        let base = self.struct_alloc(ctx, ty)?;
388        for (idx, item) in items.iter().enumerate() {
389            let value = self.eval(ctx, item)?.get(ctx).ok_or(anyhow!("array item has no value"))?;
390            let idx = (ctx.builder.ins().iconst(types::I64, idx as i64), Type::I64);
391            self.store_array_index(ctx, base, idx, elem_ty, value)?;
392        }
393        Ok(base)
394    }
395
396    fn load_vec_index(&mut self, ctx: &mut BuildContext, base: Value, idx: (Value, Type), elem_ty: &Type) -> Result<(Value, Type)> {
397        let addr = self.vec_index_addr(ctx, base, idx, elem_ty)?;
398        if elem_ty.is_struct() {
399            Ok((addr, elem_ty.clone()))
400        } else {
401            let val = ctx.builder.ins().load(crate::get_type(elem_ty)?, MemFlags::trusted(), addr, 0);
402            Ok((val, elem_ty.clone()))
403        }
404    }
405
406    fn copy_vec_element(&mut self, ctx: &mut BuildContext, dst: Value, src: Value, elem_ty: &Type) {
407        let mut offset = 0u32;
408        let width = elem_ty.storage_width();
409        while offset < width {
410            let remaining = width - offset;
411            let (ty, size) = if remaining >= 8 {
412                (types::I64, 8)
413            } else if remaining >= 4 {
414                (types::I32, 4)
415            } else if remaining >= 2 {
416                (types::I16, 2)
417            } else {
418                (types::I8, 1)
419            };
420            let value = ctx.builder.ins().load(ty, MemFlags::trusted(), src, offset as i32);
421            ctx.builder.ins().store(MemFlags::trusted(), value, dst, offset as i32);
422            offset += size;
423        }
424    }
425
426    fn store_vec_index(&mut self, ctx: &mut BuildContext, base: Value, idx: (Value, Type), elem_ty: &Type, value: (Value, Type)) -> Result<()> {
427        let addr = self.vec_index_addr(ctx, base, idx, elem_ty)?;
428        let value = self.convert(ctx, value, elem_ty.clone())?;
429        if elem_ty.is_struct() {
430            self.copy_vec_element(ctx, addr, value, elem_ty);
431        } else {
432            ctx.builder.ins().store(MemFlags::trusted(), value, addr, 0);
433        }
434        Ok(())
435    }
436
437    fn swap_vec_index(&mut self, ctx: &mut BuildContext, base: Value, left: (Value, Type), right: (Value, Type), elem_ty: &Type) -> Result<()> {
438        let left_addr = self.vec_index_addr(ctx, base, left, elem_ty)?;
439        let right_addr = self.vec_index_addr(ctx, base, right, elem_ty)?;
440        let mut offset = 0u32;
441        let width = elem_ty.storage_width();
442        while offset < width {
443            let remaining = width - offset;
444            let (ty, size) = if remaining >= 8 {
445                (types::I64, 8)
446            } else if remaining >= 4 {
447                (types::I32, 4)
448            } else if remaining >= 2 {
449                (types::I16, 2)
450            } else {
451                (types::I8, 1)
452            };
453            let left_value = ctx.builder.ins().load(ty, MemFlags::trusted(), left_addr, offset as i32);
454            let right_value = ctx.builder.ins().load(ty, MemFlags::trusted(), right_addr, offset as i32);
455            ctx.builder.ins().store(MemFlags::trusted(), left_value, right_addr, offset as i32);
456            ctx.builder.ins().store(MemFlags::trusted(), right_value, left_addr, offset as i32);
457            offset += size;
458        }
459        Ok(())
460    }
461
462    fn init_struct_from_dynamic(&mut self, ctx: &mut BuildContext, value: (Value, Type), ty: &Type) -> Result<Value> {
463        let Type::Struct { params: _, fields } = ty else {
464            return Err(anyhow!("不是结构体 {:?}", ty));
465        };
466        let base = self.struct_alloc(ctx, ty)?;
467        for (idx, (_, field_ty)) in fields.iter().enumerate() {
468            let idx_val = ctx.builder.ins().iconst(types::I64, idx as i64);
469            let item = self.call(ctx, self.get_method(&Type::Any, "get_idx")?, vec![value.0, idx_val])?;
470            self.store_struct_field(ctx, base, idx, field_ty, item, ty)?;
471        }
472        Ok(base)
473    }
474
475    fn init_struct_from_items(&mut self, ctx: &mut BuildContext, items: &[Expr], ty: &Type) -> Result<Value> {
476        let Type::Struct { params: _, fields } = ty else {
477            return Err(anyhow!("not a struct type: {:?}", ty));
478        };
479        let base = self.struct_alloc(ctx, ty)?;
480        for (idx, item) in items.iter().enumerate() {
481            let Some((_, field_ty)) = fields.get(idx) else {
482                break;
483            };
484            let value = self.eval(ctx, item)?.get(ctx).ok_or(anyhow!("struct field has no value"))?;
485            self.store_struct_field(ctx, base, idx, field_ty, value, ty)?;
486        }
487        Ok(base)
488    }
489
490    fn expr_assigned_var(expr: &Expr) -> Option<(u32, Type)> {
491        if let ExprKind::Binary { left, op, right } = &expr.kind
492            && op.is_assign()
493            && let ExprKind::Var(idx) = left.kind
494        {
495            return Some((idx, right.get_type()));
496        }
497        None
498    }
499
500    fn declare_assigned_vars(&mut self, ctx: &mut BuildContext, stmt: &Stmt) -> Result<()> {
501        match &stmt.kind {
502            StmtKind::Expr(expr, _) => {
503                if let Some((idx, ty)) = Self::expr_assigned_var(expr) {
504                    match ctx.get_var(idx).ok() {
505                        Some(LocalVar::Variable { .. }) | Some(LocalVar::Closure(_)) => {}
506                        Some(LocalVar::Value { val, ty }) => {
507                            ctx.set_var(idx, LocalVar::Value { val, ty })?;
508                        }
509                        Some(LocalVar::None) | None => {
510                            let init = self.zero_value(ctx, &ty)?;
511                            ctx.set_var(idx, init.into())?;
512                        }
513                    }
514                }
515            }
516            StmtKind::Block(stmts) => {
517                for stmt in stmts {
518                    self.declare_assigned_vars(ctx, stmt)?;
519                }
520            }
521            StmtKind::If { then_body, else_body, .. } => {
522                self.declare_assigned_vars(ctx, then_body)?;
523                if let Some(else_body) = else_body {
524                    self.declare_assigned_vars(ctx, else_body)?;
525                }
526            }
527            StmtKind::While { body, .. } | StmtKind::Loop(body) => {
528                self.declare_assigned_vars(ctx, body)?;
529            }
530            StmtKind::For { body, .. } => {
531                self.declare_assigned_vars(ctx, body)?;
532            }
533            _ => {}
534        }
535        Ok(())
536    }
537
538    fn zero_value(&mut self, ctx: &mut BuildContext, ty: &Type) -> Result<(Value, Type)> {
539        if ty.is_struct() || ty.is_array() {
540            Ok((self.struct_alloc(ctx, ty)?, ty.clone()))
541        } else if ty.is_f32() {
542            Ok((ctx.builder.ins().f32const(0.0), ty.clone()))
543        } else if ty.is_f64() {
544            Ok((ctx.builder.ins().f64const(0.0), ty.clone()))
545        } else {
546            Ok((ctx.builder.ins().iconst(crate::get_type(ty)?, 0), ty.clone()))
547        }
548    }
549
550    fn assign(&mut self, ctx: &mut BuildContext, left: &Expr, value: LocalVar) -> Result<(Value, Type)> {
551        if let ExprKind::Var(idx) = &left.kind {
552            let value_ty = value.get_ty();
553            if let Some(ty) = ctx.get_var_ty(*idx) {
554                if ty.is_struct() || ty.is_array() {
555                    let dst = ctx.get_var(*idx)?.get(ctx).ok_or(anyhow!("aggregate variable has no value"))?.0;
556                    let src = value.get(ctx).ok_or(anyhow!("aggregate assignment has no value"))?;
557                    let src = self.convert(ctx, src, ty.clone())?;
558                    self.copy_vec_element(ctx, dst, src, &ty);
559                } else if value_ty != ty {
560                    if let Some(vt) = value.get(ctx) {
561                        let val = self.convert(ctx, vt, ty.clone())?;
562                        ctx.set_var(*idx, LocalVar::Value { val, ty })?;
563                    } else if ty.is_any() {
564                        let const_idx = self.compiler.get_const(Dynamic::Null);
565                        let (val, ty) = self.get_const_value(ctx, const_idx)?;
566                        ctx.set_var(*idx, LocalVar::Value { val, ty })?;
567                    } else {
568                        ctx.set_var(*idx, LocalVar::None)?;
569                    }
570                } else {
571                    ctx.set_var(*idx, value)?;
572                }
573            } else if value_ty.is_struct() || value_ty.is_array() {
574                let src = value.get(ctx).ok_or(anyhow!("aggregate initializer has no value"))?;
575                let dst = self.struct_alloc(ctx, &value_ty)?;
576                let src = self.convert(ctx, src, value_ty.clone())?;
577                self.copy_vec_element(ctx, dst, src, &value_ty);
578                ctx.set_var(*idx, LocalVar::Value { val: dst, ty: value_ty })?;
579            } else {
580                ctx.set_var(*idx, value)?;
581            }
582            let val = ctx.get_var(*idx)?.get(ctx).ok_or(anyhow!("assigned variable has no value"))?;
583            return Ok(val);
584        } else if left.is_idx() {
585            let value = value.get(ctx).unwrap();
586            let (left, _, right) = left.clone().binary().unwrap();
587            let left = self.eval(ctx, &left)?.get(ctx).ok_or(anyhow!("未知局部变量 {:?}", left))?;
588            if let Type::Struct { params: _, fields } = &left.1 {
589                let idx = self.struct_field_index(&left.1, &right)?;
590                let field_ty = fields.get(idx).map(|(_, ty)| ty.clone()).ok_or_else(|| anyhow!("结构字段索引越界 {}", idx))?;
591                self.store_struct_field(ctx, left.0, idx, &field_ty, value.clone(), &left.1)?;
592                return Ok(value);
593            }
594            if let Some(elem_ty) = Self::vec_elem_ty(&left.1) {
595                let idx = if right.is_value() {
596                    let idx = right.clone().value()?.as_int().ok_or(anyhow!("Vec 索引必须是整数"))?;
597                    (ctx.builder.ins().iconst(types::I64, idx), Type::I64)
598                } else {
599                    self.eval(ctx, &right)?.get(ctx).ok_or(anyhow!("Vec 索引没有值"))?
600                };
601                self.store_vec_index(ctx, left.0, idx, &elem_ty, value.clone())?;
602                return Ok(value);
603            }
604            if let Some(elem_ty) = Self::array_elem_ty(&left.1) {
605                let idx = if right.is_value() {
606                    let idx = right.clone().value()?.as_int().ok_or(anyhow!("array index must be integer"))?;
607                    (ctx.builder.ins().iconst(types::I64, idx), Type::I64)
608                } else {
609                    self.eval(ctx, &right)?.get(ctx).ok_or(anyhow!("array index has no value"))?
610                };
611                self.store_array_index(ctx, left.0, idx, &elem_ty, value.clone())?;
612                return Ok(value);
613            }
614            if right.is_value() {
615                let right_value = right.clone().value()?;
616                if let Some(idx) = right_value.as_int() {
617                    let idx = ctx.builder.ins().iconst(types::I64, idx);
618                    let f = self.get_method(&left.1, "set_idx")?;
619                    let args = self.adjust_args(ctx, vec![left, (idx, Type::I64), value.clone()], f.arg_tys()?)?;
620                    self.call_for_side_effect(ctx, f, args)?;
621                } else {
622                    let key = ctx.get_const(&right_value)?;
623                    let f = self.get_method(&left.1, "set_key")?;
624                    let args = self.adjust_args(ctx, vec![left, key, value.clone()], f.arg_tys()?)?;
625                    self.call_for_side_effect(ctx, f, args)?;
626                }
627            } else {
628                let right = self.eval(ctx, &right)?.get(ctx).unwrap();
629                if right.1.is_any() {
630                    let f = self.get_method(&left.1, "set_key")?;
631                    let args = self.adjust_args(ctx, vec![left, right, value.clone()], f.arg_tys()?)?;
632                    self.call_for_side_effect(ctx, f, args)?;
633                } else {
634                    let f = self.get_method(&left.1, "set_idx")?;
635                    let args = self.adjust_args(ctx, vec![left, right, value.clone()], f.arg_tys()?)?;
636                    self.call_for_side_effect(ctx, f, args)?;
637                }
638            }
639            return Ok(value);
640        } else {
641            panic!("赋值给 {:?} {:?}", left, value)
642        }
643    }
644
645    pub(crate) fn call_fn(&mut self, ctx: &mut BuildContext, id: u32, obj: Option<Expr>, params: &Vec<Expr>) -> Result<LocalVar> {
646        self.call_fn_with_params(ctx, id, &[], obj, params)
647    }
648
649    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> {
650        let mut args: Vec<(Value, Type)> = if let Some(obj) = obj { vec![self.eval(ctx, &obj)?.get(ctx).unwrap()] } else { Vec::new() };
651        for p in params {
652            args.push(self.eval(ctx, p)?.get(ctx).unwrap());
653        }
654        let fn_name = self.compiler.symbols.get_symbol(id).map(|(name, _)| name.clone())?;
655        if fn_name.as_str().ends_with("Vec::swap")
656            && let Some((base, vec_ty)) = args.first().cloned()
657            && let Some(elem_ty) = Self::vec_elem_ty(&vec_ty)
658        {
659            let [_, left_idx, right_idx]: [(Value, Type); 3] = args.try_into().map_err(|_| anyhow!("Vec::swap 需要 self 和两个索引参数"))?;
660            self.swap_vec_index(ctx, base, left_idx, right_idx, &elem_ty)?;
661            return Ok(LocalVar::None);
662        }
663        let arg_tys: Vec<Type> = args.iter().map(|(_, ty)| ty.clone()).collect();
664        let fn_info = match if generic_args.is_empty() { self.get_fn(id, &arg_tys) } else { Err(anyhow!("generic function needs specialization")) } {
665            Ok(info) => info,
666            Err(_) => self.gen_fn_with_params(Some(ctx), id, &arg_tys, generic_args).map_err(|e| {
667                log::error!("{:?}", self.compiler.symbols.get_symbol(id));
668                e
669            })?,
670        };
671        match &fn_info {
672            FnInfo::Call { fn_id: _, arg_tys: want_tys, caps, ret } => {
673                let mut args = self.adjust_args(ctx, args, want_tys)?;
674                for c in caps {
675                    args.push(ctx.get_var(*c as u32)?.get(ctx).unwrap().0);
676                }
677                if ret.is_void() {
678                    self.call_for_side_effect(ctx, fn_info, args)?;
679                    Ok(LocalVar::None)
680                } else {
681                    self.call(ctx, fn_info, args).map(|r| r.into())
682                }
683            }
684            _ => panic!("不可能编译出 inline 函数"),
685        }
686    }
687
688    pub(crate) fn eval(&mut self, ctx: &mut BuildContext, expr: &Expr) -> Result<LocalVar> {
689        match &expr.kind {
690            ExprKind::Value(v) => Ok(ctx.get_const(v)?.into()),
691            ExprKind::Var(idx) => {
692                let v = ctx.get_var(*idx)?;
693                Ok(v)
694            }
695            ExprKind::Unary { op, value } => {
696                let v = self.eval(ctx, value)?.get(ctx).unwrap();
697                if op == &UnaryOp::Not {
698                    let cond = self.bool_value(ctx, v)?;
699                    let zero = ctx.builder.ins().iconst(types::I8, 0);
700                    let one = ctx.builder.ins().iconst(types::I8, 1);
701                    let is_zero = ctx.builder.ins().icmp_imm(IntCC::Equal, cond, 0);
702                    Ok((ctx.builder.ins().select(is_zero, one, zero), Type::Bool).into())
703                } else {
704                    Ok(Self::unary(ctx, v, op.clone())?.into())
705                }
706            }
707            ExprKind::Binary { left, op, right } => {
708                if op == &BinaryOp::Assign {
709                    match self.eval(ctx, right) {
710                        Ok(value) => self.assign(ctx, left, value).map(|v| v.into()),
711                        Err(e) => {
712                            log::error!("assign error {:?}", e);
713                            Err(e)
714                        }
715                    }
716                } else {
717                    let assign_expr = if op.is_assign() { Some(left.clone()) } else { None };
718                    let left = match self.eval(ctx, left)?.get(ctx) {
719                        Some(left) => left,
720                        None if matches!(op, BinaryOp::And | BinaryOp::Or) => self.get_null_value(ctx)?,
721                        None => return Err(anyhow!("binary left has no value: {:?}", left)),
722                    };
723                    if op == &BinaryOp::Idx {
724                        if let Type::Struct { params: _, fields: _ } = &left.1 {
725                            let idx = self.struct_field_index(&left.1, right)?;
726                            return self.load_struct_field(ctx, left.0, idx, &left.1).map(|r| r.into());
727                        }
728                        if let Some(elem_ty) = Self::vec_elem_ty(&left.1) {
729                            let idx = if right.is_value() {
730                                let idx = right.clone().value()?.as_int().ok_or(anyhow!("Vec 索引必须是整数"))?;
731                                (ctx.builder.ins().iconst(types::I64, idx), Type::I64)
732                            } else {
733                                self.eval(ctx, right)?.get(ctx).ok_or(anyhow!("Vec 索引没有值"))?
734                            };
735                            return self.load_vec_index(ctx, left.0, idx, &elem_ty).map(|r| r.into());
736                        }
737                        if let Some(elem_ty) = Self::array_elem_ty(&left.1) {
738                            let idx = if right.is_value() {
739                                let idx = right.clone().value()?.as_int().ok_or(anyhow!("array index must be integer"))?;
740                                (ctx.builder.ins().iconst(types::I64, idx), Type::I64)
741                            } else {
742                                self.eval(ctx, right)?.get(ctx).ok_or(anyhow!("array index has no value"))?
743                            };
744                            return self.load_array_index(ctx, left.0, idx, &elem_ty).map(|r| r.into());
745                        }
746                        if right.is_value() {
747                            let right_value = right.clone().value()?;
748                            if let Some(idx) = right_value.as_int() {
749                                let idx = ctx.builder.ins().iconst(types::I64, idx);
750                                self.call(ctx, self.get_method(&left.1, "get_idx")?, vec![left.0, idx]).map(|r| r.into())
751                            } else {
752                                let key = ctx.get_const(&right_value)?;
753                                self.call(ctx, self.get_method(&left.1, "get_key")?, vec![left.0, key.0]).map(|r| r.into())
754                            }
755                        } else if let ExprKind::Range { start, stop, inclusive } = &right.kind {
756                            let start = self.eval(ctx, start)?.get(ctx).ok_or(anyhow!("range start has no value"))?;
757                            let start = self.convert(ctx, start, Type::I64)?;
758                            let stop = self.eval(ctx, stop)?.get(ctx).ok_or(anyhow!("range stop has no value"))?;
759                            let stop = self.convert(ctx, stop, Type::Any)?;
760                            let inclusive = ctx.builder.ins().iconst(types::I8, i64::from(*inclusive));
761                            self.call(ctx, self.get_method(&left.1, "slice")?, vec![left.0, start, stop, inclusive]).map(|r| r.into())
762                        } else {
763                            let right = self.eval(ctx, right)?.get(ctx).ok_or(anyhow!("非Value {:?}", right))?;
764                            if right.1.is_any() {
765                                self.call(ctx, self.get_method(&left.1, "get_key")?, vec![left.0, right.0]).map(|r| r.into())
766                            } else {
767                                let right = self.convert(ctx, right, Type::I64)?;
768                                self.call(ctx, self.get_method(&left.1, "get_idx")?, vec![left.0, right]).map(|r| r.into())
769                            }
770                        }
771                    } else {
772                        let result = self.binary(ctx, left, op.clone(), right)?.into();
773                        if let Some(expr) = assign_expr { self.assign(ctx, &expr, result).map(|r| r.into()) } else { Ok(result.into()) }
774                    }
775                }
776            }
777            ExprKind::Call { obj, params } => {
778                if let ExprKind::AssocId { id, params: generic_args } = &obj.kind {
779                    self.call_fn_with_params(ctx, *id, generic_args, None, params)
780                } else if let ExprKind::Id(id, obj) = &obj.kind {
781                    self.call_fn(ctx, *id, obj.as_ref().map(|o| *o.clone()), params)
782                } else if obj.is_value() {
783                    //直接忽略掉的代码 编译期就可以忽略
784                    return Ok(LocalVar::None);
785                } else {
786                    if obj.is_idx() {
787                        let (left, _, right) = obj.clone().binary().unwrap();
788                        let left = self.eval(ctx, &left)?.get(ctx).ok_or(anyhow!("obj {:?}", obj))?;
789                        let ty = self.compiler.symbols.get_type(&left.1)?;
790                        if let Some(name) = self.get_dynamic(&right) {
791                            if name.as_str() == "swap"
792                                && let Some(elem_ty) = Self::vec_elem_ty(&ty)
793                            {
794                                let [left_idx, right_idx]: [(Value, Type); 2] =
795                                    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 需要两个索引参数"))?;
796                                self.swap_vec_index(ctx, left.0, left_idx, right_idx, &elem_ty)?;
797                                return Ok(LocalVar::None);
798                            }
799                            let mut args = vec![left];
800                            for p in params {
801                                args.push(self.eval(ctx, p)?.get(ctx).unwrap());
802                            }
803                            let (_, method_ty) = self.compiler.get_field(&ty, name.as_str())?;
804                            let Type::Symbol { id, .. } = method_ty else {
805                                return Err(anyhow!("不是成员函数"));
806                            };
807                            let arg_tys: Vec<Type> = args.iter().map(|(_, ty)| ty.clone()).collect();
808                            let method = self.get_fn(id, &arg_tys).or_else(|_| self.gen_fn_with_params(Some(ctx), id, &arg_tys, &[]))?;
809                            let args = self.adjust_args(ctx, args, method.arg_tys()?)?;
810                            self.call(ctx, method, args).map(|r| r.into())
811                        } else {
812                            self.eval(ctx, obj)
813                        }
814                    } else {
815                        let val = self.eval(ctx, obj)?;
816                        if let LocalVar::Closure(id) = val {
817                            return self.call_fn(ctx, id, None, params);
818                        }
819                        panic!("暂未实现 {:?}", val)
820                    }
821                }
822            }
823            ExprKind::Typed { value, ty } => {
824                if let Type::Struct { params: _, fields: _ } = ty
825                    && let ExprKind::List(items) = &value.kind
826                {
827                    return Ok((self.init_struct_from_items(ctx, items, ty)?, ty.clone()).into());
828                }
829                if let Type::Array(_, _) = ty
830                    && let ExprKind::List(items) = &value.kind
831                {
832                    return Ok((self.init_array_from_items(ctx, items, ty)?, ty.clone()).into());
833                }
834                let vt = if let Some(vt) = self.eval(ctx, value)?.get(ctx) {
835                    vt
836                } else if ty.is_any() {
837                    let idx = self.compiler.get_const(Dynamic::Null);
838                    self.get_const_value(ctx, idx)?
839                } else {
840                    return Ok(LocalVar::None);
841                };
842                if let Type::Struct { params: _, fields: _ } = ty {
843                    if &vt.1 == ty {
844                        Ok(vt.into())
845                    } else if vt.1.is_any() {
846                        Ok((self.init_struct_from_dynamic(ctx, vt, ty)?, ty.clone()).into())
847                    } else {
848                        Err(anyhow!("cannot convert {:?} to {:?}", vt.1, ty))
849                    }
850                } else if &vt.1 != ty {
851                    Ok((self.convert(ctx, vt, ty.clone())?, ty.clone()).into())
852                } else {
853                    Ok(vt.into())
854                }
855            }
856            ExprKind::List(_) => Err(anyhow!("未实现 {:?}", expr)),
857            ExprKind::Repeat { value, len } => {
858                let value = self.eval(ctx, value)?.get(ctx).ok_or(anyhow!("repeat value has no value"))?;
859                let Type::ConstInt(len) = len else {
860                    return Err(anyhow!("repeat length must be a compile-time integer"));
861                };
862                let len = u32::try_from(*len).map_err(|_| anyhow!("repeat length out of range"))?;
863                self.init_repeat_array(ctx, value, len).map(|r| r.into())
864            }
865            ExprKind::Const(idx) => self.get_const_value(ctx, *idx).map(|v| v.into()),
866            ExprKind::Id(id, _) => Ok(LocalVar::Closure(*id)),
867            ExprKind::AssocId { id, .. } => Ok(LocalVar::Closure(*id)),
868            expr => {
869                //结构就是一块固定大小 的内存(或者是动态大小 最后一个数据成员可扩展 跟 C 结构一样)
870                panic!("未实现 {:?}", expr)
871            }
872        }
873    }
874
875    fn gen_loop(&mut self, ctx: &mut BuildContext, cond: Option<&Expr>, body: &Stmt, f: Option<impl FnMut(&mut BuildContext)>) -> Result<()> {
876        let loop_block = ctx.builder.create_block();
877        let end_block = ctx.builder.create_block();
878        if let Some(cond) = cond {
879            let start_block = ctx.builder.create_block();
880            ctx.builder.ins().jump(start_block, &[]);
881            ctx.builder.switch_to_block(start_block);
882            let cond = self.eval(ctx, cond)?.get(ctx).unwrap();
883            let cond = self.bool_value(ctx, cond)?;
884            let continue_block = if f.is_some() { ctx.builder.create_block() } else { start_block };
885            ctx.builder.ins().brif(cond, loop_block, &[], end_block, &[]);
886            ctx.builder.switch_to_block(loop_block);
887            let body_terminated = self.gen_stmt(ctx, body, Some(end_block), Some(continue_block))?;
888            if !body_terminated {
889                ctx.builder.ins().jump(continue_block, &[]);
890            }
891            ctx.builder.seal_block(loop_block);
892            f.map(|mut f| {
893                ctx.builder.switch_to_block(continue_block);
894                f(ctx);
895                ctx.builder.ins().jump(start_block, &[]);
896                ctx.builder.seal_block(continue_block);
897            });
898        } else {
899            ctx.builder.ins().jump(loop_block, &[]);
900            ctx.builder.switch_to_block(loop_block);
901            let body_terminated = self.gen_stmt(ctx, body, Some(end_block), Some(loop_block))?;
902            if !body_terminated {
903                ctx.builder.ins().jump(loop_block, &[]);
904            }
905            ctx.builder.seal_block(loop_block);
906        }
907        ctx.builder.switch_to_block(end_block);
908        Ok(())
909    }
910
911    pub(crate) fn gen_stmt(&mut self, ctx: &mut BuildContext, stmt: &Stmt, break_block: Option<Block>, continue_block: Option<Block>) -> Result<bool> {
912        match &stmt.kind {
913            StmtKind::Expr(expr, _) => {
914                let _ = self.eval(ctx, expr)?;
915            }
916            StmtKind::Break => {
917                ctx.builder.ins().jump(break_block.unwrap(), &[]);
918                return Ok(true);
919            }
920            StmtKind::Continue => {
921                ctx.builder.ins().jump(continue_block.unwrap(), &[]);
922                return Ok(true);
923            }
924            StmtKind::Return(expr) => {
925                if let Some(expr) = expr {
926                    let value = self.eval(ctx, expr)?;
927                    if let Some((r, _)) = value.get(ctx) {
928                        ctx.builder.ins().return_(&[r]);
929                    } else {
930                        ctx.builder.ins().return_(&[]);
931                    }
932                } else {
933                    ctx.builder.ins().return_(&[]);
934                }
935                return Ok(true);
936            }
937            StmtKind::If { cond, then_body, else_body } => {
938                self.declare_assigned_vars(ctx, then_body)?;
939                if let Some(else_body) = else_body {
940                    self.declare_assigned_vars(ctx, else_body)?;
941                }
942                let then_block = ctx.builder.create_block();
943                let cond = self.eval(ctx, cond)?.get(ctx).ok_or(anyhow!("未知的条件 {:?}", cond))?;
944                let cond = self.bool_value(ctx, cond)?;
945                let mut end_block = None;
946                if let Some(else_body) = else_body {
947                    let else_block = ctx.builder.create_block();
948                    ctx.builder.ins().brif(cond, then_block, &[], else_block, &[]);
949                    ctx.builder.switch_to_block(then_block);
950                    if !self.gen_stmt(ctx, then_body, break_block, continue_block)? {
951                        let block = ctx.builder.create_block();
952                        ctx.builder.ins().jump(block, &[]);
953                        end_block = Some(block);
954                    }
955                    ctx.builder.switch_to_block(else_block);
956                    if !self.gen_stmt(ctx, else_body, break_block, continue_block)? {
957                        if end_block.is_none() {
958                            end_block = Some(ctx.builder.create_block());
959                        }
960                        ctx.builder.ins().jump(end_block.unwrap(), &[]);
961                    }
962                    ctx.builder.seal_block(else_block);
963                } else {
964                    let block = ctx.builder.create_block();
965                    ctx.builder.ins().brif(cond, then_block, &[], block, &[]);
966                    end_block = Some(block);
967                    ctx.builder.switch_to_block(then_block);
968                    if !self.gen_stmt(ctx, then_body, break_block, continue_block)? {
969                        ctx.builder.ins().jump(end_block.unwrap(), &[]); //如果不是返回指令 增加跳转到 end_block
970                    }
971                }
972                if let Some(block) = end_block {
973                    ctx.builder.switch_to_block(block);
974                }
975                ctx.builder.seal_block(then_block);
976                return Ok(end_block.is_none());
977            }
978            StmtKind::Block(stmts) => {
979                for (idx, stmt) in stmts.iter().enumerate() {
980                    let r = self.gen_stmt(ctx, stmt, break_block, continue_block)?;
981                    if idx == stmts.len() - 1 {
982                        return Ok(r);
983                    }
984                }
985            }
986            StmtKind::While { cond, body } => {
987                self.declare_assigned_vars(ctx, body)?;
988                let no_loop: Option<fn(&mut BuildContext)> = None;
989                self.gen_loop(ctx, Some(cond), body, no_loop)?;
990            }
991            StmtKind::Loop(body) => {
992                self.declare_assigned_vars(ctx, body)?;
993                let no_loop: Option<fn(&mut BuildContext)> = None;
994                self.gen_loop(ctx, None, body, no_loop)?;
995            }
996            StmtKind::For { pat, range, body } => {
997                if let ExprKind::Range { start, stop, inclusive } = &range.kind {
998                    if let PatternKind::Var { idx, .. } = &pat.kind {
999                        let start = self.eval(ctx, start)?;
1000                        ctx.set_var(*idx, start)?;
1001                        self.declare_assigned_vars(ctx, body)?;
1002                        let op = if *inclusive { BinaryOp::Le } else { BinaryOp::Lt };
1003                        let cond = Self::expr(ExprKind::Binary { left: Box::new(Self::expr(ExprKind::Var(*idx))), op, right: Box::new(stop.as_ref().clone()) });
1004                        self.gen_loop(
1005                            ctx,
1006                            Some(&cond),
1007                            body,
1008                            Some(|ctx: &mut BuildContext| {
1009                                let v = ctx.get_var(*idx).unwrap().get(ctx).unwrap();
1010                                let step = if v.1 == Type::I64 {
1011                                    ctx.builder.ins().iconst(types::I64, 1)
1012                                } else if v.1 == Type::I32 {
1013                                    ctx.builder.ins().iconst(types::I32, 1)
1014                                } else {
1015                                    panic!("{:?} 不能作为增量", v.1)
1016                                };
1017                                let vt = (ctx.builder.ins().iadd(v.0, step), v.1).into();
1018                                let _ = ctx.set_var(*idx, vt);
1019                            }),
1020                        )?;
1021                    }
1022                } else if let PatternKind::Var { idx, .. } = &pat.kind {
1023                    let vt = self.eval(ctx, range)?.get(ctx).unwrap();
1024                    if vt.1.is_any() {
1025                        let iter = self.call(ctx, self.get_method(&vt.1, "iter")?, vec![vt.0])?;
1026                        let next = self.get_method(&vt.1, "next")?;
1027                        let next_id = next.get_id()?;
1028                        let start = self.call(ctx, next, vec![iter.0])?;
1029                        ctx.set_var(*idx, start.into())?;
1030                        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))) });
1031                        self.gen_loop(
1032                            ctx,
1033                            Some(&cond),
1034                            body,
1035                            Some(|ctx: &mut BuildContext| {
1036                                let fn_ref = ctx.get_fn_ref(next_id).unwrap();
1037                                let call_inst = ctx.builder.ins().call(fn_ref, &[iter.0]);
1038                                let ret = ctx.builder.inst_results(call_inst)[0];
1039                                let _ = ctx.set_var(*idx, (ret, Type::Any).into());
1040                            }),
1041                        )?;
1042                    }
1043                } else if let PatternKind::Tuple(pats) = &pat.kind {
1044                    let vt = self.eval(ctx, range)?.get(ctx).unwrap();
1045                    if vt.1.is_any() && pats.len() == 2 {
1046                        //暂时只处理 kv
1047                        let iter = self.call(ctx, self.get_method(&vt.1, "iter")?, vec![vt.0])?;
1048                        let next = self.get_method(&vt.1, "next")?;
1049                        let next_id = next.get_id()?;
1050                        let get_idx = self.get_method(&vt.1, "get_idx")?.get_id()?;
1051
1052                        let start = self.call(ctx, next, vec![iter.0])?;
1053                        let key_idx = ctx.builder.ins().iconst(types::I64, 0);
1054                        let key = self.call(ctx, self.get_method(&start.1, "get_idx")?, vec![start.0, key_idx])?;
1055                        let value_idx = ctx.builder.ins().iconst(types::I64, 1);
1056                        let value = self.call(ctx, self.get_method(&start.1, "get_idx")?, vec![start.0, value_idx])?;
1057                        ctx.set_var(pats[0].var().unwrap(), key.into())?;
1058                        ctx.set_var(pats[1].var().unwrap(), value.into())?;
1059                        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))) });
1060                        self.gen_loop(
1061                            ctx,
1062                            Some(&cond),
1063                            body,
1064                            Some(|ctx: &mut BuildContext| {
1065                                let fn_ref = ctx.get_fn_ref(next_id).unwrap();
1066                                let call_inst = ctx.builder.ins().call(fn_ref, &[iter.0]);
1067                                let ret = ctx.builder.inst_results(call_inst)[0];
1068
1069                                let fn_ref = ctx.get_fn_ref(get_idx).unwrap();
1070                                let call_inst = ctx.builder.ins().call(fn_ref, &[ret, key_idx]);
1071                                let key_ret = ctx.builder.inst_results(call_inst)[0];
1072                                let call_inst = ctx.builder.ins().call(fn_ref, &[ret, value_idx]);
1073                                let value_ret = ctx.builder.inst_results(call_inst)[0];
1074
1075                                let _ = ctx.set_var(pats[0].var().unwrap(), (key_ret, Type::Any).into());
1076                                let _ = ctx.set_var(pats[1].var().unwrap(), (value_ret, Type::Any).into());
1077                            }),
1078                        )?;
1079                    }
1080                }
1081            }
1082            _ => {
1083                panic!("未实现 {:?}", stmt)
1084            }
1085        }
1086        Ok(false)
1087    }
1088}