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
37pub(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()); 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); 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 assignment_target_ty(&mut self, ctx: &mut BuildContext, left: &Expr) -> Option<Type> {
736 if let ExprKind::Var(idx) = &left.kind {
737 return ctx.get_var_ty(*idx).filter(|ty| !ty.is_any());
738 }
739 None
740 }
741
742 fn closure_value(&self, ctx: &mut BuildContext, id: u32) -> Result<LocalVar> {
743 let captures = match self.compiler.symbols.get_symbol(id)?.1 {
744 Symbol::Fn { cap, .. } => cap.vars.iter().map(|idx| ctx.get_var(*idx as u32)?.get(ctx).ok_or_else(|| anyhow!("捕获变量 {} 没有值", idx))).collect::<Result<Vec<_>>>()?,
745 _ => Vec::new(),
746 };
747 Ok(LocalVar::Closure { id, captures })
748 }
749
750 pub(crate) fn call_fn(&mut self, ctx: &mut BuildContext, id: u32, obj: Option<Expr>, params: &Vec<Expr>) -> Result<LocalVar> {
751 self.call_fn_with_params(ctx, id, &[], obj, params)
752 }
753
754 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> {
755 self.call_fn_with_capture_values(ctx, id, generic_args, obj, params, None)
756 }
757
758 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> {
759 let fn_name = self.compiler.symbols.get_symbol(id).map(|(name, _)| name.clone())?;
760 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() };
761 for p in params {
762 args.push(self.eval(ctx, p)?.get(ctx).ok_or_else(|| anyhow!("函数 {} 的参数表达式没有值: {:?}", fn_name, p))?);
763 }
764 if let Some(captures) = &capture_values {
765 args.extend(captures.iter().cloned());
766 }
767 if fn_name.as_str().ends_with("Vec::swap")
768 && let Some((base, vec_ty)) = args.first().cloned()
769 && let Some(elem_ty) = Self::vec_elem_ty(&vec_ty)
770 {
771 let [_, left_idx, right_idx]: [(Value, Type); 3] = args.try_into().map_err(|_| anyhow!("Vec::swap 需要 self 和两个索引参数"))?;
772 self.swap_vec_index(ctx, base, left_idx, right_idx, &elem_ty)?;
773 return Ok(LocalVar::None);
774 }
775 let visible_arg_len = args.len() - capture_values.as_ref().map(|captures| captures.len()).unwrap_or(0);
776 let arg_tys: Vec<Type> = args.iter().take(visible_arg_len).map(|(_, ty)| ty.clone()).collect();
777 let fn_info = match if generic_args.is_empty() { self.get_fn(id, &arg_tys) } else { Err(anyhow!("generic function needs specialization")) } {
778 Ok(info) => info,
779 Err(_) => self.gen_fn_with_params(Some(ctx), id, &arg_tys, generic_args).map_err(|e| {
780 log::error!("{:?}", self.compiler.symbols.get_symbol(id));
781 e
782 })?,
783 };
784 match &fn_info {
785 FnInfo::Call { fn_id: _, arg_tys: want_tys, caps, ret, context: _ } => {
786 let mut args = self.adjust_args(ctx, args, want_tys)?;
787 if capture_values.is_none() {
788 for c in caps {
789 args.push(ctx.get_var(*c as u32)?.get(ctx).unwrap().0);
790 }
791 }
792 if ret.is_void() {
793 self.call_for_side_effect(ctx, fn_info, args)?;
794 Ok(LocalVar::None)
795 } else {
796 self.call(ctx, fn_info, args).map(|r| r.into())
797 }
798 }
799 _ => panic!("不可能编译出 inline 函数"),
800 }
801 }
802
803 pub(crate) fn eval(&mut self, ctx: &mut BuildContext, expr: &Expr) -> Result<LocalVar> {
804 self.eval_with_expected(ctx, expr, None)
805 }
806
807 fn eval_with_expected(&mut self, ctx: &mut BuildContext, expr: &Expr, expected: Option<&Type>) -> Result<LocalVar> {
808 match &expr.kind {
809 ExprKind::Value(v) => Ok(ctx.get_const(v)?.into()),
810 ExprKind::Var(idx) => {
811 let v = ctx.get_var(*idx)?;
812 Ok(v)
813 }
814 ExprKind::Unary { op, value } => {
815 let v = self.eval(ctx, value)?.get(ctx).unwrap();
816 if op == &UnaryOp::Not && v.1.is_any() {
817 let cond = self.bool_value(ctx, v)?;
818 let zero = ctx.builder.ins().iconst(types::I8, 0);
819 let one = ctx.builder.ins().iconst(types::I8, 1);
820 let is_zero = ctx.builder.ins().icmp_imm(IntCC::Equal, cond, 0);
821 Ok((ctx.builder.ins().select(is_zero, one, zero), Type::Bool).into())
822 } else {
823 Ok(Self::unary(ctx, v, op.clone())?.into())
824 }
825 }
826 ExprKind::Binary { left, op, right } => {
827 if op == &BinaryOp::Assign {
828 let expected = self.assignment_target_ty(ctx, left);
829 match self.eval_with_expected(ctx, right, expected.as_ref()) {
830 Ok(value) => self.assign(ctx, left, value).map(|v| v.into()),
831 Err(e) => {
832 log::error!("assign error {:?}", e);
833 Err(e)
834 }
835 }
836 } else {
837 let assign_expr = if op.is_assign() { Some(left.clone()) } else { None };
838 let assign_expected = if op.is_assign() { self.assignment_target_ty(ctx, left) } else { None };
839 let left = match self.eval(ctx, left)?.get(ctx) {
840 Some(left) => left,
841 None => return Err(anyhow!("binary left has no value: {:?}", left)),
842 };
843 if op == &BinaryOp::Idx {
844 let left_ty = self.compiler.symbols.get_type(&left.1).unwrap_or_else(|_| left.1.clone());
845 let left = (left.0, left_ty);
846 if let Type::Struct { params: _, fields: _ } = &left.1 {
847 let idx = self.struct_field_index(&left.1, right)?;
848 return self.load_struct_field(ctx, left.0, idx, &left.1).map(|r| r.into());
849 }
850 if let Some(elem_ty) = Self::vec_elem_ty(&left.1) {
851 let idx = if right.is_value() {
852 let idx = right.clone().value()?.as_int().ok_or(anyhow!("Vec 索引必须是整数"))?;
853 (ctx.builder.ins().iconst(types::I64, idx), Type::I64)
854 } else {
855 self.eval(ctx, right)?.get(ctx).ok_or(anyhow!("Vec 索引没有值"))?
856 };
857 return self.load_vec_index(ctx, left.0, idx, &elem_ty).map(|r| r.into());
858 }
859 if let Some(elem_ty) = Self::array_elem_ty(&left.1) {
860 let idx = if right.is_value() {
861 let idx = right.clone().value()?.as_int().ok_or(anyhow!("array index must be integer"))?;
862 (ctx.builder.ins().iconst(types::I64, idx), Type::I64)
863 } else {
864 self.eval(ctx, right)?.get(ctx).ok_or(anyhow!("array index has no value"))?
865 };
866 return self.load_array_index(ctx, left.0, idx, &elem_ty).map(|r| r.into());
867 }
868 if right.is_value() {
869 let right_value = right.clone().value()?;
870 if let Some(idx) = right_value.as_int() {
871 let idx = ctx.builder.ins().iconst(types::I64, idx);
872 self.call(ctx, self.get_method(&left.1, "get_idx")?, vec![left.0, idx]).map(|r| r.into())
873 } else {
874 let key = ctx.get_const(&right_value)?;
875 self.call(ctx, self.get_method(&left.1, "get_key")?, vec![left.0, key.0]).map(|r| r.into())
876 }
877 } else if let ExprKind::Range { start, stop, inclusive } = &right.kind {
878 let start = self.eval(ctx, start)?.get(ctx).ok_or(anyhow!("range start has no value"))?;
879 let start = self.convert(ctx, start, Type::I64)?;
880 let stop = self.eval(ctx, stop)?.get(ctx).ok_or(anyhow!("range stop has no value"))?;
881 let stop = self.convert(ctx, stop, Type::Any)?;
882 let inclusive = ctx.builder.ins().iconst(types::I8, i64::from(*inclusive));
883 self.call(ctx, self.get_method(&left.1, "slice")?, vec![left.0, start, stop, inclusive]).map(|r| r.into())
884 } else {
885 let right = self.eval(ctx, right)?.get(ctx).ok_or(anyhow!("非Value {:?}", right))?;
886 if right.1.is_any() || right.1.is_str() {
887 let right = self.convert(ctx, right, Type::Any)?;
888 self.call(ctx, self.get_method(&left.1, "get_key")?, vec![left.0, right]).map(|r| r.into())
889 } else {
890 let right = self.convert(ctx, right, Type::I64)?;
891 self.call(ctx, self.get_method(&left.1, "get_idx")?, vec![left.0, right]).map(|r| r.into())
892 }
893 }
894 } else {
895 let result = self.binary_with_expected(ctx, left, op.clone(), right, assign_expected.as_ref().or(expected))?.into();
896 if let Some(expr) = assign_expr { self.assign(ctx, &expr, result).map(|r| r.into()) } else { Ok(result.into()) }
897 }
898 }
899 }
900 ExprKind::Call { obj, params } => {
901 if let ExprKind::AssocId { id, params: generic_args } = &obj.kind {
902 self.call_fn_with_params(ctx, *id, generic_args, None, params)
903 } else if let ExprKind::Id(id, obj) = &obj.kind {
904 self.call_fn(ctx, *id, obj.as_ref().map(|o| *o.clone()), params)
905 } else if obj.is_value() {
906 return Ok(LocalVar::None);
908 } else {
909 if obj.is_idx() {
910 let (left, _, right) = obj.clone().binary().unwrap();
911 let left = self.eval(ctx, &left)?.get(ctx).ok_or(anyhow!("obj {:?}", obj))?;
912 let ty = self.compiler.symbols.get_type(&left.1)?;
913 if let Some(name) = self.get_dynamic(&right) {
914 if name.as_str() == "swap"
915 && let Some(elem_ty) = Self::vec_elem_ty(&ty)
916 {
917 let [left_idx, right_idx]: [(Value, Type); 2] =
918 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 需要两个索引参数"))?;
919 self.swap_vec_index(ctx, left.0, left_idx, right_idx, &elem_ty)?;
920 return Ok(LocalVar::None);
921 }
922 let mut args = vec![left];
923 for p in params {
924 args.push(self.eval(ctx, p)?.get(ctx).ok_or_else(|| anyhow!("动态方法 {:?} 的参数表达式没有值: {:?}", name, p))?);
925 }
926 let (_, method_ty) = self.compiler.get_field(&ty, name.as_str())?;
927 let Type::Symbol { id, .. } = method_ty else {
928 return Err(anyhow!("不是成员函数"));
929 };
930 let arg_tys: Vec<Type> = args.iter().map(|(_, ty)| ty.clone()).collect();
931 let method = self.get_fn(id, &arg_tys).or_else(|_| self.gen_fn_with_params(Some(ctx), id, &arg_tys, &[]))?;
932 let args = self.adjust_args(ctx, args, method.arg_tys()?)?;
933 self.call(ctx, method, args).map(|r| r.into())
934 } else {
935 self.eval(ctx, obj)
936 }
937 } else {
938 let val = self.eval(ctx, obj)?;
939 if let LocalVar::Closure { id, captures } = val {
940 return self.call_fn_with_capture_values(ctx, id, &[], None, params, Some(captures));
941 }
942 panic!("暂未实现 {:?}", val)
943 }
944 }
945 }
946 ExprKind::Typed { value, ty } => {
947 if let Type::Struct { params: _, fields: _ } = ty
948 && let ExprKind::List(items) = &value.kind
949 {
950 return Ok((self.init_struct_from_items(ctx, items, ty)?, ty.clone()).into());
951 }
952 if let Type::Array(_, _) = ty
953 && let ExprKind::List(items) = &value.kind
954 {
955 return Ok((self.init_array_from_items(ctx, items, ty)?, ty.clone()).into());
956 }
957 let evaluated = self.eval(ctx, value)?;
958 if evaluated.is_closure() {
959 return Ok(evaluated);
960 }
961 let vt = if let Some(vt) = evaluated.get(ctx) {
962 vt
963 } else if ty.is_any() {
964 let idx = self.compiler.get_const(Dynamic::Null);
965 self.get_const_value(ctx, idx)?
966 } else {
967 return Ok(LocalVar::None);
968 };
969 if let Type::Struct { params: _, fields: _ } = ty
970 && !self.is_opaque_custom_ty(ty)
971 {
972 if &vt.1 == ty {
973 Ok(vt.into())
974 } else if vt.1.is_any() {
975 Ok((self.init_struct_from_dynamic(ctx, vt, ty)?, ty.clone()).into())
976 } else {
977 Err(anyhow!("cannot convert {:?} to {:?}", vt.1, ty))
978 }
979 } else if &vt.1 != ty {
980 Ok((self.convert(ctx, vt, ty.clone())?, ty.clone()).into())
981 } else {
982 Ok(vt.into())
983 }
984 }
985 ExprKind::List(_) => Err(anyhow!("未实现 {:?}", expr)),
986 ExprKind::Repeat { value, len } => {
987 let value = self.eval(ctx, value)?.get(ctx).ok_or(anyhow!("repeat value has no value"))?;
988 let Type::ConstInt(len) = len else {
989 return Err(anyhow!("repeat length must be a compile-time integer"));
990 };
991 let len = u32::try_from(*len).map_err(|_| anyhow!("repeat length out of range"))?;
992 self.init_repeat_array(ctx, value, len).map(|r| r.into())
993 }
994 ExprKind::Const(idx) => self.get_const_value(ctx, *idx).map(|v| v.into()),
995 ExprKind::Id(id, _) => self.closure_value(ctx, *id),
996 ExprKind::AssocId { id, .. } => self.closure_value(ctx, *id),
997 expr => {
998 panic!("未实现 {:?}", expr)
1000 }
1001 }
1002 }
1003
1004 fn gen_loop(&mut self, ctx: &mut BuildContext, cond: Option<&Expr>, body: &Stmt, f: Option<impl FnMut(&mut BuildContext)>) -> Result<()> {
1005 let loop_block = ctx.builder.create_block();
1006 let end_block = ctx.builder.create_block();
1007 if let Some(cond) = cond {
1008 let start_block = ctx.builder.create_block();
1009 ctx.builder.ins().jump(start_block, &[]);
1010 ctx.builder.switch_to_block(start_block);
1011 let cond = self.eval(ctx, cond)?.get(ctx).unwrap();
1012 let cond = self.bool_value(ctx, cond)?;
1013 let continue_block = if f.is_some() { ctx.builder.create_block() } else { start_block };
1014 ctx.builder.ins().brif(cond, loop_block, &[], end_block, &[]);
1015 ctx.builder.switch_to_block(loop_block);
1016 let body_terminated = self.gen_stmt(ctx, body, Some(end_block), Some(continue_block))?;
1017 if !body_terminated {
1018 ctx.builder.ins().jump(continue_block, &[]);
1019 }
1020 ctx.builder.seal_block(loop_block);
1021 f.map(|mut f| {
1022 ctx.builder.switch_to_block(continue_block);
1023 f(ctx);
1024 ctx.builder.ins().jump(start_block, &[]);
1025 ctx.builder.seal_block(continue_block);
1026 });
1027 } else {
1028 ctx.builder.ins().jump(loop_block, &[]);
1029 ctx.builder.switch_to_block(loop_block);
1030 let body_terminated = self.gen_stmt(ctx, body, Some(end_block), Some(loop_block))?;
1031 if !body_terminated {
1032 ctx.builder.ins().jump(loop_block, &[]);
1033 }
1034 ctx.builder.seal_block(loop_block);
1035 }
1036 ctx.builder.switch_to_block(end_block);
1037 Ok(())
1038 }
1039
1040 pub(crate) fn gen_stmt(&mut self, ctx: &mut BuildContext, stmt: &Stmt, break_block: Option<Block>, continue_block: Option<Block>) -> Result<bool> {
1041 match &stmt.kind {
1042 StmtKind::Expr(expr, _) => {
1043 let _ = self.eval(ctx, expr)?;
1044 }
1045 StmtKind::Break => {
1046 ctx.builder.ins().jump(break_block.unwrap(), &[]);
1047 return Ok(true);
1048 }
1049 StmtKind::Continue => {
1050 ctx.builder.ins().jump(continue_block.unwrap(), &[]);
1051 return Ok(true);
1052 }
1053 StmtKind::Return(expr) => {
1054 if let Some(expr) = expr {
1055 let value = self.eval(ctx, expr)?;
1056 let value = value.get(ctx);
1057 self.return_value(ctx, value)?;
1058 } else {
1059 self.return_value(ctx, None)?;
1060 }
1061 return Ok(true);
1062 }
1063 StmtKind::If { cond, then_body, else_body } => {
1064 self.declare_assigned_vars(ctx, then_body)?;
1065 if let Some(else_body) = else_body {
1066 self.declare_assigned_vars(ctx, else_body)?;
1067 }
1068 let then_block = ctx.builder.create_block();
1069 let cond = self.eval(ctx, cond)?.get(ctx).ok_or(anyhow!("未知的条件 {:?}", cond))?;
1070 let cond = self.bool_value(ctx, cond)?;
1071 let mut end_block = None;
1072 if let Some(else_body) = else_body {
1073 let else_block = ctx.builder.create_block();
1074 ctx.builder.ins().brif(cond, then_block, &[], else_block, &[]);
1075 ctx.builder.switch_to_block(then_block);
1076 if !self.gen_stmt(ctx, then_body, break_block, continue_block)? {
1077 let block = ctx.builder.create_block();
1078 ctx.builder.ins().jump(block, &[]);
1079 end_block = Some(block);
1080 }
1081 ctx.builder.switch_to_block(else_block);
1082 if !self.gen_stmt(ctx, else_body, break_block, continue_block)? {
1083 if end_block.is_none() {
1084 end_block = Some(ctx.builder.create_block());
1085 }
1086 ctx.builder.ins().jump(end_block.unwrap(), &[]);
1087 }
1088 ctx.builder.seal_block(else_block);
1089 } else {
1090 let block = ctx.builder.create_block();
1091 ctx.builder.ins().brif(cond, then_block, &[], block, &[]);
1092 end_block = Some(block);
1093 ctx.builder.switch_to_block(then_block);
1094 if !self.gen_stmt(ctx, then_body, break_block, continue_block)? {
1095 ctx.builder.ins().jump(end_block.unwrap(), &[]); }
1097 }
1098 if let Some(block) = end_block {
1099 ctx.builder.switch_to_block(block);
1100 }
1101 ctx.builder.seal_block(then_block);
1102 return Ok(end_block.is_none());
1103 }
1104 StmtKind::Block(stmts) => {
1105 for (idx, stmt) in stmts.iter().enumerate() {
1106 let r = self.gen_stmt(ctx, stmt, break_block, continue_block)?;
1107 if idx == stmts.len() - 1 {
1108 return Ok(r);
1109 }
1110 }
1111 }
1112 StmtKind::While { cond, body } => {
1113 self.declare_assigned_vars(ctx, body)?;
1114 let no_loop: Option<fn(&mut BuildContext)> = None;
1115 self.gen_loop(ctx, Some(cond), body, no_loop)?;
1116 }
1117 StmtKind::Loop(body) => {
1118 self.declare_assigned_vars(ctx, body)?;
1119 let no_loop: Option<fn(&mut BuildContext)> = None;
1120 self.gen_loop(ctx, None, body, no_loop)?;
1121 }
1122 StmtKind::For { pat, range, body } => {
1123 if let ExprKind::Range { start, stop, inclusive } = &range.kind {
1124 if let PatternKind::Var { idx, .. } = &pat.kind {
1125 let start = self.eval(ctx, start)?;
1126 ctx.set_var(*idx, start)?;
1127 self.declare_assigned_vars(ctx, body)?;
1128 let op = if *inclusive { BinaryOp::Le } else { BinaryOp::Lt };
1129 let cond = Self::expr(ExprKind::Binary { left: Box::new(Self::expr(ExprKind::Var(*idx))), op, right: Box::new(stop.as_ref().clone()) });
1130 self.gen_loop(
1131 ctx,
1132 Some(&cond),
1133 body,
1134 Some(|ctx: &mut BuildContext| {
1135 let v = ctx.get_var(*idx).unwrap().get(ctx).unwrap();
1136 let step = if v.1 == Type::I64 {
1137 ctx.builder.ins().iconst(types::I64, 1)
1138 } else if v.1 == Type::I32 {
1139 ctx.builder.ins().iconst(types::I32, 1)
1140 } else {
1141 panic!("{:?} 不能作为增量", v.1)
1142 };
1143 let vt = (ctx.builder.ins().iadd(v.0, step), v.1).into();
1144 let _ = ctx.set_var(*idx, vt);
1145 }),
1146 )?;
1147 }
1148 } else if let PatternKind::Var { idx, .. } = &pat.kind {
1149 let vt = self.eval(ctx, range)?.get(ctx).unwrap();
1150 if vt.1.is_any() {
1151 let iter = self.call(ctx, self.get_method(&vt.1, "iter")?, vec![vt.0])?;
1152 let next = self.get_method(&vt.1, "next")?;
1153 let next_id = next.get_id()?;
1154 let start = self.call(ctx, next, vec![iter.0])?;
1155 ctx.set_var(*idx, start.into())?;
1156 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))) });
1157 self.gen_loop(
1158 ctx,
1159 Some(&cond),
1160 body,
1161 Some(|ctx: &mut BuildContext| {
1162 let fn_ref = ctx.get_fn_ref(next_id).unwrap();
1163 let call_inst = ctx.builder.ins().call(fn_ref, &[iter.0]);
1164 let ret = ctx.builder.inst_results(call_inst)[0];
1165 let _ = ctx.set_var(*idx, (ret, Type::Any).into());
1166 }),
1167 )?;
1168 }
1169 } else if let PatternKind::Tuple(pats) = &pat.kind {
1170 let vt = self.eval(ctx, range)?.get(ctx).unwrap();
1171 if vt.1.is_any() && pats.len() == 2 {
1172 let iter = self.call(ctx, self.get_method(&vt.1, "iter")?, vec![vt.0])?;
1174 let next = self.get_method(&vt.1, "next")?;
1175 let next_id = next.get_id()?;
1176 let get_idx = self.get_method(&vt.1, "get_idx")?.get_id()?;
1177
1178 let start = self.call(ctx, next, vec![iter.0])?;
1179 let key_idx = ctx.builder.ins().iconst(types::I64, 0);
1180 let key = self.call(ctx, self.get_method(&start.1, "get_idx")?, vec![start.0, key_idx])?;
1181 let value_idx = ctx.builder.ins().iconst(types::I64, 1);
1182 let value = self.call(ctx, self.get_method(&start.1, "get_idx")?, vec![start.0, value_idx])?;
1183 ctx.set_var(pats[0].var().unwrap(), key.into())?;
1184 ctx.set_var(pats[1].var().unwrap(), value.into())?;
1185 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))) });
1186 self.gen_loop(
1187 ctx,
1188 Some(&cond),
1189 body,
1190 Some(|ctx: &mut BuildContext| {
1191 let fn_ref = ctx.get_fn_ref(next_id).unwrap();
1192 let call_inst = ctx.builder.ins().call(fn_ref, &[iter.0]);
1193 let ret = ctx.builder.inst_results(call_inst)[0];
1194
1195 let fn_ref = ctx.get_fn_ref(get_idx).unwrap();
1196 let call_inst = ctx.builder.ins().call(fn_ref, &[ret, key_idx]);
1197 let key_ret = ctx.builder.inst_results(call_inst)[0];
1198 let call_inst = ctx.builder.ins().call(fn_ref, &[ret, value_idx]);
1199 let value_ret = ctx.builder.inst_results(call_inst)[0];
1200
1201 let _ = ctx.set_var(pats[0].var().unwrap(), (key_ret, Type::Any).into());
1202 let _ = ctx.set_var(pats[1].var().unwrap(), (value_ret, Type::Any).into());
1203 }),
1204 )?;
1205 }
1206 }
1207 }
1208 _ => {
1209 panic!("未实现 {:?}", stmt)
1210 }
1211 }
1212 Ok(false)
1213 }
1214}