Commit b4328c44 authored by Kunshan Wang's avatar Kunshan Wang

API-GEN: linker flags, test callbacks

Set linker flags properly according to the OS.

Tested trap handler callback. It looks like it is easy enough for Rust
to interact with C.
parent f9e3d65e
......@@ -2,6 +2,13 @@ RUSTC=rustc
MUAPI_H_DIR=..
INCLUDE_DIR=$(MUAPI_H_DIR)
UNAME := $(shell uname)
ifeq ($(UNAME),Darwin)
LDFLAGS = -lm
else
LDFLAGS = -ldl -pthread -lm -lrt -lutil
endif
.PHONY: all
all: cclient
......@@ -13,4 +20,4 @@ cpart.o: cpart.c cpart.h
$(CC) -c -I $(INCLUDE_DIR) -o $@ $<
cclient: cclient.c cpart.h rustpart.a cpart.o ../muapi.h
$(CC) -I $(INCLUDE_DIR) -ldl -pthread -lm -lrt -lutil -o $@ cclient.c cpart.o rustpart.a
$(CC) -I $(INCLUDE_DIR) $(LDFLAGS) -o $@ cclient.c cpart.o rustpart.a
......@@ -12,6 +12,8 @@
*/
use std::os::raw::*;
use std::ptr;
use std::slice;
use std::ffi::CStr;
use std::ffi::CString;
......@@ -152,7 +154,47 @@ impl MuVM {
println!("Set the trap handler to {:?} and the userdata to {:?}", trap_handler, userdata);
println!("Let's call the trap handler now.");
// TODO: Call the trap handler to test it.
let ctx: *mut CMuCtx = ptr::null_mut();
let thread: CMuValue = Box::into_raw(Box::new(APIMuValue{ty: 100, vb: ValueBox::BoxThread})) as CMuValue;
let stack: CMuValue = Box::into_raw(Box::new(APIMuValue{ty: 200, vb: ValueBox::BoxStack})) as CMuValue;
let wpid: u32 = 99;
let mut result: CMuTrapHandlerResult = 0;
let mut new_stack: CMuValue = ptr::null_mut();
let mut values: *mut CMuValue = ptr::null_mut();
let mut nvalues: usize = 0;
let mut freer: Option<CMuValuesFreer> = None;
let mut freerdata: CMuCPtr = ptr::null_mut();
let mut exception: CMuValue = ptr::null_mut();
trap_handler(ctx, thread, stack, wpid,
&mut result, &mut new_stack, &mut values, &mut nvalues,
&mut freer as *mut Option<CMuValuesFreer> as *mut CMuValuesFreer, &mut freerdata, &mut exception,
userdata);
println!("Back to Rust! result = {}", result);
let new_stack_proper = new_stack as *const APIMuValue;
let values_proper = values as *const *const APIMuValue;
let values_slice = unsafe { slice::from_raw_parts(values_proper, nvalues) };
unsafe {
println!(" new_stack = {}, {:?}", (*new_stack_proper).ty, (*new_stack_proper).vb);
println!(" nvalues = {}", nvalues);
for &v in values_slice {
println!(" {}, {:?}", (*v).ty, (*v).vb);
}
}
println!("freer = {:?}, freerdata = {:?}", freer, freerdata);
println!("Calling freer...");
let the_freer = freer.unwrap()(values, freerdata);
println!("Back to Rust from freer!");
// free memory
unsafe {
Box::from_raw(stack);
Box::from_raw(thread);
}
}
......
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <stdlib.h>
#include <muapi.h>
#include "cpart.h"
void my_mem_freer(MuValue *values, MuCPtr freerdata) {
printf("[C] in my_mem_freer, values=%p\n", values);
printf("[C] freerdata (as string) = %s\n", (char*)freerdata);
free(values);
}
void my_trap_handler(
// input parameters
MuCtx *ctx,
MuThreadRefValue thread,
MuStackRefValue stack,
MuWPID wpid,
// output parameters
MuTrapHandlerResult *result,
MuStackRefValue *new_stack,
MuValue **values,
MuArraySize *nvalues,
MuValuesFreer *freer,
MuCPtr *freerdata,
MuRefValue *exception,
// input parameter (userdata)
MuCPtr userdata) {
printf("[C] in my_trap_handler, ctx=%p, thread=%p, stak=%p, wpid=%u\n",
ctx, thread, stack, wpid);
printf("[C] userdata (as string) = %s\n", (char*)userdata);
*result = MU_REBIND_PASS_VALUES;
*new_stack = stack;
MuValue *values_array = (MuValue*)calloc(sizeof(MuValue), 2);
printf("[C] values_array = %p allocated.\n", values_array);
values_array[0] = stack;
values_array[1] = thread;
*values = values_array;
*nvalues = 2;
*freer = my_mem_freer;
*freerdata = (MuCPtr)"Free me!";
*exception = NULL;
return;
}
int main() {
printf("Hello world!\n");
......@@ -19,6 +66,9 @@ int main() {
MuName name_43_2 = mvm->name_of(mvm, 43);
printf("name_43_2 = '%s'\n", name_43_2);
printf("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.
free_mock_micro_vm(mvm);
......
......@@ -3,6 +3,7 @@ mod api_bridge;
pub mod api_impl;
mod deps {
use std::cell::*;
// should import from ast/src/ir.rs
pub type WPID = usize;
......@@ -10,8 +11,20 @@ mod deps {
pub type MuName = String;
pub type CName = MuName;
#[derive(Debug)]
pub enum ValueBox {
BoxInt(usize),
BoxF32(f32),
BoxF64(f64),
BoxRef(Cell<usize>), // so that GC can update the pointer
BoxSeq(Vec<ValueBox>),
BoxThread,
BoxStack,
}
pub struct APIMuValue {
// stub
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