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