chore: comment

This commit is contained in:
2025-08-07 21:00:32 +08:00
parent f946cb2fd1
commit 67cdcfea33
24 changed files with 734 additions and 105 deletions

View File

@@ -1,13 +1,29 @@
//! This module defines the `JITCompile` trait and its implementations for
//! various IR types. It provides the translation from LIR to Cranelift IR.
use cranelift::codegen::ir::{self, StackSlot};
use cranelift::prelude::*;
use nixjit_eval::{EvalContext, Value};
use nixjit_eval::Value;
use nixjit_ir::*;
use nixjit_lir::Lir;
use super::{Context, JITContext};
/// A trait for compiling IR nodes to Cranelift IR.
///
/// This trait defines how different IR nodes should be compiled to
/// Cranelift IR instructions that can be executed by the JIT compiler.
pub trait JITCompile<Ctx: JITContext> {
/// Compiles the IR node to Cranelift IR.
///
/// # Arguments
/// * `ctx` - The compilation context
/// * `engine` - The evaluation context value
/// * `env` - The environment value
///
/// # Returns
/// A stack slot containing the compiled result
fn compile(&self, ctx: &mut Context<Ctx>, engine: ir::Value, env: ir::Value) -> StackSlot;
}
@@ -24,6 +40,9 @@ impl<Ctx: JITContext> JITCompile<Ctx> for Lir {
}
impl<Ctx: JITContext> JITCompile<Ctx> for AttrSet {
/// Compiles an attribute set to Cranelift IR.
///
/// This creates a new attribute set and compiles all static attributes into it.
fn compile(&self, ctx: &mut Context<Ctx>, engine: ir::Value, env: ir::Value) -> StackSlot {
let attrs = ctx.create_attrs();
for (k, v) in self.stcs.iter() {
@@ -35,6 +54,9 @@ impl<Ctx: JITContext> JITCompile<Ctx> for AttrSet {
}
impl<Ctx: JITContext> JITCompile<Ctx> for List {
/// Compiles a list to Cranelift IR.
///
/// This creates a new list by compiling all items and storing them in an array.
fn compile(&self, ctx: &mut Context<Ctx>, engine: ir::Value, env: ir::Value) -> StackSlot {
let array = ctx.alloc_array(self.items.len());
for (i, item) in self.items.iter().enumerate() {
@@ -67,6 +89,11 @@ impl<Ctx: JITContext> JITCompile<Ctx> for HasAttr {
}
impl<Ctx: JITContext> JITCompile<Ctx> for BinOp {
/// Compiles a binary operation to Cranelift IR.
///
/// This implementation handles various binary operations like addition, subtraction,
/// division, logical AND/OR, and equality checks. It generates code that checks
/// the types of operands and performs the appropriate operation.
fn compile(&self, ctx: &mut Context<Ctx>, engine: ir::Value, env: ir::Value) -> StackSlot {
use BinOpKind::*;
let lhs = self.lhs.compile(ctx, engine, env);
@@ -328,6 +355,9 @@ impl<Ctx: JITContext> JITCompile<Ctx> for UnOp {
}
impl<Ctx: JITContext> JITCompile<Ctx> for Attr {
/// Compiles an attribute key to Cranelift IR.
///
/// An attribute can be either a static string or a dynamic expression.
fn compile(&self, ctx: &mut Context<Ctx>, engine: ir::Value, env: ir::Value) -> StackSlot {
use Attr::*;
match self {
@@ -338,6 +368,10 @@ impl<Ctx: JITContext> JITCompile<Ctx> for Attr {
}
impl<Ctx: JITContext> JITCompile<Ctx> for Select {
/// Compiles an attribute selection to Cranelift IR.
///
/// This compiles the expression to select from, builds the attribute path,
/// and calls the select helper function.
fn compile(&self, ctx: &mut Context<Ctx>, engine: ir::Value, env: ir::Value) -> StackSlot {
let val = self.expr.compile(ctx, engine, env);
let attrpath = ctx.alloc_array(self.attrpath.len());
@@ -366,6 +400,10 @@ impl<Ctx: JITContext> JITCompile<Ctx> for Select {
}
impl<Ctx: JITContext> JITCompile<Ctx> for If {
/// Compiles an if-expression to Cranelift IR.
///
/// This generates code that evaluates the condition, checks that it's a boolean,
/// and then jumps to the appropriate branch (true or false).
fn compile(&self, ctx: &mut Context<Ctx>, engine: ir::Value, env: ir::Value) -> StackSlot {
let cond = self.cond.compile(ctx, engine, env);
let cond_type = ctx.builder.ins().stack_load(types::I64, cond, 0);
@@ -424,6 +462,10 @@ impl<Ctx: JITContext> JITCompile<Ctx> for If {
}
impl<Ctx: JITContext> JITCompile<Ctx> for Call {
/// Compiles a function call to Cranelift IR.
///
/// This compiles the function expression and all arguments, builds an argument array,
/// and calls the call helper function.
fn compile(&self, ctx: &mut Context<Ctx>, engine: ir::Value, env: ir::Value) -> StackSlot {
let func = self.func.compile(ctx, engine, env);
let args = ctx.alloc_array(self.args.len());
@@ -452,6 +494,10 @@ impl<Ctx: JITContext> JITCompile<Ctx> for Call {
}
impl<Ctx: JITContext> JITCompile<Ctx> for With {
/// Compiles a `with` expression to Cranelift IR.
///
/// This enters a new `with` scope with the compiled namespace, compiles the body expression,
/// and then exits the `with` scope.
fn compile(&self, ctx: &mut Context<Ctx>, engine: ir::Value, env: ir::Value) -> StackSlot {
let namespace = self.namespace.compile(ctx, engine, env);
ctx.enter_with(env, namespace);
@@ -475,6 +521,10 @@ impl<Ctx: JITContext> JITCompile<Ctx> for ConcatStrings {
}
impl<Ctx: JITContext> JITCompile<Ctx> for Const {
/// Compiles a constant value to Cranelift IR.
///
/// This handles boolean, integer, float, and null constants by storing
/// their values and type tags in a stack slot.
fn compile(&self, ctx: &mut Context<Ctx>, engine: ir::Value, env: ir::Value) -> StackSlot {
use nixjit_value::Const::*;
let slot = ctx.alloca();
@@ -507,12 +557,18 @@ impl<Ctx: JITContext> JITCompile<Ctx> for Const {
}
impl<Ctx: JITContext> JITCompile<Ctx> for Str {
/// Compiles a string literal to Cranelift IR.
///
/// This creates a string value from the string literal.
fn compile(&self, ctx: &mut Context<Ctx>, engine: ir::Value, env: ir::Value) -> StackSlot {
ctx.create_string(&self.val)
}
}
impl<Ctx: JITContext> JITCompile<Ctx> for Var {
/// Compiles a variable lookup to Cranelift IR.
///
/// This looks up a variable by its symbol in the current environment.
fn compile(&self, ctx: &mut Context<Ctx>, engine: ir::Value, env: ir::Value) -> StackSlot {
ctx.lookup(env, &self.sym)
}