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