use xjbutil::boxed_slice;
use xjbutil::void::Void;
use crate::builtins::object::Object;
use crate::data::Value;
use crate::data::traits::StaticBase;
use crate::ffi::{FFIException, Signature};
use crate::ffi::sync_fn::{Function, FunctionBase, OwnershipGuard, VMContext, value_into_ref};
use crate::vm::al31f::Combustor;
use crate::vm::al31f::alloc::Alloc;
use crate::vm::al31f::compiled::{CompiledFunction, CompiledProgram, ExceptionHandlingBlock};
use crate::vm::al31f::insc::Insc;
pub fn basic_program<A: Alloc>() -> CompiledProgram<A> {
CompiledProgram {
code: boxed_slice![
Insc::AddInt(0, 1, 0),
Insc::Return(boxed_slice![0])
],
const_pool: boxed_slice![],
init_proc: 0,
functions: boxed_slice![
CompiledFunction::new(0, 2, 1, 2, boxed_slice![])
],
ffi_funcs: boxed_slice![],
#[cfg(feature = "async")]
async_ffi_funcs: boxed_slice![],
}
}
pub fn basic_fn_call_program<A: Alloc>() -> CompiledProgram<A> {
CompiledProgram {
code: boxed_slice![
Insc::MakeIntConst(1, 0), Insc::MakeIntConst(2, 1), Insc::Call(
1, boxed_slice![0, 1], boxed_slice![0] ),
Insc::Return(boxed_slice![0]),
Insc::AddInt(0, 1, 0), Insc::Return(boxed_slice![0]) ],
const_pool: boxed_slice![],
init_proc: 0,
functions: boxed_slice![
CompiledFunction::new(0, 0, 1, 2, boxed_slice![]), CompiledFunction::new(4, 2, 1, 2, boxed_slice![]), ],
ffi_funcs: boxed_slice![],
#[cfg(feature = "async")]
async_ffi_funcs: boxed_slice![],
}
}
pub fn fibonacci_program<A: Alloc>() -> CompiledProgram<A> {
CompiledProgram {
code: boxed_slice![
Insc::MakeIntConst(0, 1), Insc::LeInt(0, 1, 2), Insc::JumpIfTrue(2, 12), Insc::MakeIntConst(1, 1), Insc::EqValue(0, 1, 2), Insc::JumpIfTrue(2, 12), Insc::SubInt(0, 1, 2), Insc::MakeIntConst(2, 1), Insc::SubInt(0, 1, 3), Insc::Call(0, boxed_slice![2], boxed_slice![2]), Insc::Call(0, boxed_slice![3], boxed_slice![3]), Insc::AddInt(2, 3, 1), Insc::ReturnOne(1) ],
const_pool: boxed_slice![],
init_proc: 0,
functions: boxed_slice![
CompiledFunction::new(0, 1, 1, 4, boxed_slice![])
],
ffi_funcs: boxed_slice![],
#[cfg(feature = "async")]
async_ffi_funcs: boxed_slice![],
}
}
pub fn alloc_1m_program<A: Alloc>() -> CompiledProgram<A> {
CompiledProgram {
code: boxed_slice![
Insc::MakeIntConst(0, 0), Insc::MakeIntConst(1, 1), Insc::MakeIntConst(10_000_000, 2), Insc::EqValue(0, 2, 3), Insc::JumpIfTrue(3, 8), Insc::CreateObject(3), Insc::SubInt(2, 1, 2), Insc::Jump(3), Insc::ReturnNothing ],
const_pool: boxed_slice![],
init_proc: 0,
functions: boxed_slice![
CompiledFunction::new(0, 0, 0, 4, boxed_slice![])
],
ffi_funcs: boxed_slice![],
#[cfg(feature = "async")]
async_ffi_funcs: boxed_slice![],
}
}
pub fn exception_program<A: Alloc>() -> CompiledProgram<A> {
CompiledProgram {
code: boxed_slice![
Insc::MakeIntConst(12345, 0), Insc::Call(1, boxed_slice![], boxed_slice![]), Insc::ReturnOne(0),
Insc::MakeIntConst(114514, 0), Insc::ReturnOne(0),
Insc::Call(2, boxed_slice![], boxed_slice![]), Insc::ReturnNothing,
Insc::CreateObject(0), Insc::Raise(0) ],
const_pool: boxed_slice![],
init_proc: 0,
functions: boxed_slice![
CompiledFunction::new_with_exc(0, 0, 1, 1, boxed_slice![], boxed_slice![
ExceptionHandlingBlock::new(0, 2, <Void as StaticBase<Object>>::type_id(), 3)
]),
CompiledFunction::new(5, 0, 0, 0, boxed_slice![]),
CompiledFunction::new(7, 0, 0, 1, boxed_slice![])
],
ffi_funcs: boxed_slice![],
#[cfg(feature = "async")]
async_ffi_funcs: boxed_slice![]
}
}
pub fn exception_no_eh_program<A: Alloc>() -> CompiledProgram<A> {
CompiledProgram {
code: boxed_slice![
Insc::Call(1, boxed_slice![], boxed_slice![0]), Insc::ReturnOne(0),
Insc::CreateObject(0), Insc::Raise(0), ],
const_pool: boxed_slice![],
init_proc: 0,
functions: boxed_slice![
CompiledFunction::new(0, 0, 1, 1, boxed_slice![]),
CompiledFunction::new(2, 0, 1, 1, boxed_slice![])
],
ffi_funcs: boxed_slice![],
#[cfg(feature = "async")]
async_ffi_funcs: boxed_slice![]
}
}
#[inline(never)] fn ffi_function(x: &Object, y: &Object, z: &Object) {
assert_eq!(x as *const Object as usize, y as *const Object as usize);
assert_eq!(y as *const Object as usize, z as *const Object as usize);
}
#[allow(non_camel_case_types)]
struct Pr47Binder_ffi_function();
impl FunctionBase for Pr47Binder_ffi_function {
fn signature() -> Signature {
todo!()
}
fn call_tyck<CTX: VMContext>(
_context: &mut CTX,
_args: &[Value],
_rets: &[*mut Value]
) -> Result<(), FFIException> {
todo!()
}
unsafe fn call_rtlc<CTX: VMContext>(
_context: &mut CTX,
args: &[Value],
rets: &[*mut Value]
) -> Result<(), FFIException> {
debug_assert_eq!(args.len(), 3);
debug_assert_eq!(rets.len(), 0);
let (a1, g1): (&Object, Option<OwnershipGuard>) = value_into_ref(*args.get_unchecked(0))?;
let (a2, g2): (&Object, Option<OwnershipGuard>) = value_into_ref(*args.get_unchecked(1))?;
let (a3, g3): (&Object, Option<OwnershipGuard>) = value_into_ref(*args.get_unchecked(2))?;
ffi_function(a1, a2, a3);
std::mem::drop(g3);
std::mem::drop(g2);
std::mem::drop(g1);
Ok(())
}
unsafe fn call_unchecked<CTX: VMContext>(
_context: &mut CTX,
_args: &[Value],
_rets: &[*mut Value]
) -> Result<(), FFIException> {
todo!()
}
}
pub fn ffi_call_program<A: Alloc>() -> CompiledProgram<A> {
CompiledProgram {
code: boxed_slice![
Insc::CreateObject(0), Insc::FFICallRtlc(0, boxed_slice![0, 0, 0], boxed_slice![]),
Insc::ReturnNothing ],
const_pool: boxed_slice![],
init_proc: 0,
functions: boxed_slice![
CompiledFunction::new(0, 0, 0, 1, boxed_slice![])
],
ffi_funcs: boxed_slice![
Box::new(Pr47Binder_ffi_function()) as Box<dyn Function<Combustor<A>>>
],
#[cfg(feature="async")] async_ffi_funcs: boxed_slice![]
}
}
pub fn bench_raw_iter_program<A: Alloc>() -> CompiledProgram<A> {
CompiledProgram {
code: boxed_slice![
Insc::MakeIntConst(0, 0), Insc::MakeIntConst(100_000_000, 1), Insc::MakeIntConst(1, 2), Insc::EqValue(0, 1, 3), Insc::JumpIfTrue(3, 7), Insc::AddInt(0, 2, 0), Insc::Jump(3), Insc::ReturnNothing ],
const_pool: boxed_slice![],
init_proc: 0,
functions: boxed_slice![
CompiledFunction::new(0, 0, 0, 5, boxed_slice![])
],
ffi_funcs: boxed_slice![],
#[cfg(feature="async")] async_ffi_funcs: boxed_slice![]
}
}
pub fn bench_ffi_call_program<A: Alloc>() -> CompiledProgram<A> {
CompiledProgram {
code: boxed_slice![
Insc::MakeIntConst(0, 0), Insc::MakeIntConst(100_000_000, 1), Insc::MakeIntConst(1, 2), Insc::CreateObject(3), Insc::EqValue(0, 1, 4), Insc::JumpIfTrue(4, 9), Insc::FFICallRtlc(0, boxed_slice![3, 3, 3], boxed_slice![]),
Insc::AddInt(0, 2, 0), Insc::Jump(4), Insc::ReturnNothing ],
const_pool: boxed_slice![],
init_proc: 0,
functions: boxed_slice![
CompiledFunction::new(0, 0, 0, 5, boxed_slice![])
],
ffi_funcs: boxed_slice![
Box::new(Pr47Binder_ffi_function()) as Box<dyn Function<Combustor<A>>>
],
#[cfg(feature="async")] async_ffi_funcs: boxed_slice![]
}
}
#[inline(never)] fn ffi_function2(a: i64, b: i64) -> i64 {
a + b
}
#[allow(non_camel_case_types)]
struct Pr47Binder_ffi_function2();
impl FunctionBase for Pr47Binder_ffi_function2 {
fn signature() -> Signature {
todo!()
}
fn call_tyck<CTX: VMContext>(
_context: &mut CTX,
_args: &[Value],
_rets: &[*mut Value]
) -> Result<(), FFIException> {
todo!()
}
unsafe fn call_rtlc<CTX: VMContext>(
_context: &mut CTX,
args: &[Value],
rets: &[*mut Value]
) -> Result<(), FFIException> {
debug_assert_eq!(args.len(), 2);
debug_assert_eq!(rets.len(), 1);
let a1: i64 = args.get_unchecked(0).vt_data.inner.int_value;
let a2: i64 = args.get_unchecked(1).vt_data.inner.int_value;
let ret: i64 = ffi_function2(a1, a2);
*(*rets.get_unchecked(0)) = Value::new_int(ret);
Ok(())
}
unsafe fn call_unchecked<CTX: VMContext>(
_context: &mut CTX,
_args: &[Value],
_rets: &[*mut Value]
) -> Result<(), FFIException> {
todo!()
}
}
pub fn ffi_call_program2<A: Alloc>() -> CompiledProgram<A> {
CompiledProgram {
code: boxed_slice![
Insc::FFICallRtlc(0, boxed_slice![0, 1], boxed_slice![0]),
Insc::ReturnOne(0) ],
const_pool: boxed_slice![],
init_proc: 0,
functions: boxed_slice![
CompiledFunction::new(0, 2, 1, 2, boxed_slice![])
],
ffi_funcs: boxed_slice![
Box::new(Pr47Binder_ffi_function2()) as Box<dyn Function<Combustor<A>>>
],
#[cfg(feature="async")] async_ffi_funcs: boxed_slice![]
}
}
pub fn bench_ffi_call_program2<A: Alloc>() -> CompiledProgram<A> {
CompiledProgram {
code: boxed_slice![
Insc::MakeIntConst(0, 0), Insc::MakeIntConst(10_000, 1), Insc::EqValue(0, 1, 2), Insc::JumpIfTrue(2, 15), Insc::MakeIntConst(0, 3), Insc::EqValue(3, 1, 2), Insc::JumpIfTrue(2, 13), Insc::AddInt(0, 3, 4), Insc::FFICallRtlc(0, boxed_slice![0, 3], boxed_slice![5]),
Insc::EqValue(4, 5, 2), Insc::JumpIfFalse(2, 16), Insc::IncrInt(3), Insc::Jump(5), Insc::IncrInt(0), Insc::Jump(2), Insc::ReturnNothing, Insc::CreateObject(0), Insc::Raise(0) ],
const_pool: boxed_slice![],
init_proc: 0,
functions: boxed_slice![
CompiledFunction::new(0, 0, 0, 6, boxed_slice![])
],
ffi_funcs: boxed_slice![
Box::new(Pr47Binder_ffi_function2()) as Box<dyn Function<Combustor<A>>>
],
#[cfg(feature="async")] async_ffi_funcs: boxed_slice![]
}
}