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