use crate::Error::InternalError;
use crate::Result;
use ahash::AHashMap;
use cranelift::codegen::ir::{Block, Inst, Value};
use cranelift::frontend::FunctionBuilder;
use ristretto_classfile::attributes::ExceptionTableEntry;
#[derive(Copy, Clone)]
pub(crate) struct ThrowContext<'a> {
pub exception_block: Block,
pub blocks: &'a AHashMap<usize, Block>,
pub exception_table: &'a [ExceptionTableEntry],
pub program_counter: usize,
}
fn single_inst_result(function_builder: &FunctionBuilder<'_>, instruction: Inst) -> Result<Value> {
function_builder
.inst_results(instruction)
.first()
.copied()
.ok_or_else(|| InternalError("Cranelift instruction did not produce a result".to_string()))
}
mod array;
mod branch;
mod byte;
mod char;
mod convert;
mod debug;
mod double;
mod exception;
mod field;
mod float;
mod integer;
mod invoke;
mod invokedynamic;
mod invokeinterface;
mod invokespecial;
mod invokestatic;
mod invokevirtual;
mod ldc;
mod long;
mod monitor;
mod nop;
mod object;
mod push;
mod reference;
mod short;
mod stack;
mod r#static;
mod wide;
pub(crate) use array::*;
pub(crate) use branch::*;
pub(crate) use byte::*;
pub(crate) use char::*;
pub(crate) use convert::*;
pub(crate) use debug::*;
pub(crate) use double::*;
pub(crate) use exception::*;
pub(crate) use field::*;
pub(crate) use float::*;
pub(crate) use integer::*;
pub(crate) use ldc::*;
pub(crate) use long::*;
pub(crate) use monitor::*;
pub(crate) use nop::*;
pub(crate) use object::*;
pub(crate) use push::*;
pub(crate) use reference::*;
pub(crate) use short::*;
pub(crate) use stack::*;
pub(crate) use r#static::*;
pub(crate) use wide::*;
pub(crate) const TRAP_INTERNAL_ERROR: u8 = 127;
pub(crate) fn emit_bci(
function_builder: &mut FunctionBuilder<'_>,
throw_context: &ThrowContext<'_>,
) -> Value {
use cranelift::prelude::InstBuilder;
function_builder.ins().iconst(
cranelift::prelude::types::I32,
i64::try_from(throw_context.program_counter).unwrap_or(i64::from(i32::MAX)),
)
}