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