Commit e39e0e4d authored by Kunshan Wang's avatar Kunshan Wang

API-GEN: More tests against other funcs.

Found a way to implement handle allocation and dealllocation, and a way
to access MuVM from MuCtx using pointers.
parent cb708ec4
......@@ -18,6 +18,7 @@ use std::ffi::CStr;
use std::ffi::CString;
use std::collections::HashMap;
use std::collections::HashSet;
use api_c::*;
use api_bridge::*;
......@@ -102,14 +103,15 @@ pub extern fn free_mock_micro_vm(cmvm: *mut CMuVM) {
#[derive(Default)]
pub struct MuVM {
my_name: String,
contexts: Vec<MuCtx>,
cname_dict: HashMap<MuID, CString>,
trap_handler: Option<CMuTrapHandler>,
trap_handler_user_data: Option<CMuCPtr>,
}
pub struct MuCtx {
// Stub
mvm: *mut MuVM,
c_struct: *mut CMuCtx,
handles: HashSet<*const APIMuValue>,
}
pub struct MuIRBuilder {
......@@ -118,7 +120,35 @@ pub struct MuIRBuilder {
impl MuVM {
pub fn new_context(&mut self) -> *mut CMuCtx {
panic!("Not implemented")
println!("Creating Mu context...");
let ctx = Box::new(MuCtx {
mvm: self,
c_struct: ptr::null_mut(),
handles: Default::default(),
});
let ctx_ptr = Box::into_raw(ctx);
println!("The header address: {:?}", ctx_ptr);
let cctx = make_new_MuCtx(ctx_ptr as *mut c_void);
println!("The C-visible CMuCtx struct address: {:?}", cctx);
unsafe{ (*ctx_ptr).c_struct = cctx; }
cctx
}
fn dealloc_context(&mut self, ctx: &mut MuCtx) {
let c_struct = ctx.c_struct;
let ctx_ptr = ctx as *mut MuCtx;
println!("Deallocating MuCtx {:?} and CMuCtx {:?}...", ctx_ptr, c_struct);
unsafe {
Box::from_raw(c_struct);
Box::from_raw(ctx_ptr);
}
}
pub fn id_of(&mut self, name: MuName) -> MuID {
......@@ -198,16 +228,25 @@ impl MuVM {
}
impl MuCtx {
fn get_mvm<'a>(&mut self) -> &'a mut MuVM {
unsafe { &mut * self.mvm }
}
pub fn id_of(&mut self, name: MuName) -> MuID {
panic!("Not implemented")
println!("MuCtx is looking up the ID for the client..");
self.get_mvm().id_of(name)
}
pub fn name_of(&mut self, id: MuID) -> CMuCString {
panic!("Not implemented")
println!("MuCtx is looking up the name for the client..");
self.get_mvm().name_of(id)
}
pub fn close_context(&mut self) {
panic!("Not implemented")
for &ptr in self.handles.iter() {
MuCtx::dealloc_handle(ptr);
}
self.get_mvm().dealloc_context(self)
}
pub fn load_bundle(&mut self, buf: &[c_char]) {
......@@ -218,6 +257,15 @@ impl MuCtx {
panic!("Not implemented")
}
#[inline(always)]
fn expose_handle(&mut self, handle: APIMuValue) -> *const APIMuValue {
let box_ptr = Box::into_raw(Box::new(handle));
self.handles.insert(box_ptr);
box_ptr
}
pub fn handle_from_sint8(&mut self, num: i8, len: c_int) -> *const APIMuValue {
panic!("Not implemented")
}
......@@ -235,7 +283,10 @@ impl MuCtx {
}
pub fn handle_from_sint32(&mut self, num: i32, len: c_int) -> *const APIMuValue {
panic!("Not implemented")
self.expose_handle(APIMuValue {
ty: 300,
vb: ValueBox::BoxInt(num as u64, len),
})
}
pub fn handle_from_uint32(&mut self, num: u32, len: c_int) -> *const APIMuValue {
......@@ -334,8 +385,18 @@ impl MuCtx {
panic!("Not implemented")
}
#[inline(always)]
fn dealloc_handle(ptr: *const APIMuValue) {
unsafe {
println!("Deallocating handle {:?}", *ptr);
Box::from_raw(ptr as *mut APIMuValue);
}
}
pub fn delete_value(&mut self, opnd: &APIMuValue) {
panic!("Not implemented")
let ptr = opnd as *const APIMuValue;
self.handles.remove(&ptr);
MuCtx::dealloc_handle(opnd);
}
pub fn ref_eq(&mut self, lhs: &APIMuValue, rhs: &APIMuValue) -> bool {
......
......@@ -52,24 +52,35 @@ void my_trap_handler(
}
int main() {
printf("Hello world!\n");
printf("[C] Hello world!\n");
MuVM *mvm = new_mock_micro_vm("cclientt");
MuID forty_two = mvm->id_of(mvm, "@forty_two");
printf("forty_two = %d\n", forty_two);
printf("[C] forty_two = %d\n", forty_two);
MuName name_43 = mvm->name_of(mvm, 43);
printf("name_43 = '%s'\n", name_43);
printf("[C] name_43 = '%s'\n", name_43);
MuName name_43_2 = mvm->name_of(mvm, 43);
printf("name_43_2 = '%s'\n", name_43_2);
printf("[C] name_43_2 = '%s'\n", name_43_2);
printf("Setting trap handler...\n");
printf("[C] Setting trap handler...\n");
mvm->set_trap_handler(mvm, my_trap_handler, "I am the trap handler!");
// TODO: Register a trap handler to see if Rust can really call back.
printf("[C] Asking for a context...\n");
MuCtx *ctx = mvm->new_context(mvm);
printf("[C] Context created. ctx=%p\n", ctx);
MuName name_43_3 = ctx->name_of(ctx, 43);
printf("[C] name_43_3 = '%s'\n", name_43_3);
MuIntValue *v1 = ctx->handle_from_sint32(ctx, 345, 32);
MuIntValue *v2 = ctx->handle_from_sint32(ctx, 678, 32);
ctx->delete_value(ctx, v1);
ctx->close_context(ctx);
free_mock_micro_vm(mvm);
......
......@@ -13,7 +13,7 @@ mod deps {
#[derive(Debug)]
pub enum ValueBox {
BoxInt(usize),
BoxInt(u64, i32),
BoxF32(f32),
BoxF64(f64),
BoxRef(Cell<usize>), // so that GC can update the pointer
......@@ -22,6 +22,7 @@ mod deps {
BoxStack,
}
#[derive(Debug)]
pub struct APIMuValue {
pub ty: MuID,
pub vb: ValueBox,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment