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