Skip to main content

vm/
rt.rs

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