Functions to convert values to/from inline asm.

pull/3/head
Damien 2013-10-06 12:04:13 +01:00
rodzic dc83382903
commit e4af64f307
1 zmienionych plików z 61 dodań i 15 usunięć

Wyświetl plik

@ -71,7 +71,7 @@ typedef struct _py_obj_base_t {
const char *id;
qstr u_str;
#ifdef PY_FLOAT
float_t flt;
float_t u_flt;
#endif
struct { // for O_FUN_[012N]
int n_args;
@ -258,7 +258,7 @@ py_obj_t py_obj_new_str(qstr qstr) {
py_obj_t py_obj_new_float(float_t val) {
py_obj_base_t *o = m_new(py_obj_base_t, 1);
o->kind = O_FLOAT;
o->flt = val;
o->u_flt = val;
return (py_obj_t)o;
}
#endif
@ -298,7 +298,7 @@ typedef struct _py_code_t {
py_fun_t fun;
} u_native;
struct {
py_fun_t fun;
void *fun;
} u_inline_asm;
};
} py_code_t;
@ -497,7 +497,7 @@ void py_obj_print(py_obj_t o_in) {
break;
#ifdef PY_FLOAT
case O_FLOAT:
printf("%f", o->flt);
printf("%f", o->u_flt);
break;
#endif
case O_LIST:
@ -745,16 +745,63 @@ py_obj_t rt_make_function(int n_args, py_fun_t code) {
return o;
}
// convert a Python object to a sensible value for inline asm
machine_uint_t rt_convert_obj_for_inline_asm(py_obj_t obj) {
// TODO for byte_array, pass pointer to the array
if (IS_SMALL_INT(obj)) {
return FROM_SMALL_INT(obj);
} else if (obj == py_const_none) {
return 0;
} else if (obj == py_const_false) {
return 0;
} else if (obj == py_const_true) {
return 1;
} else {
py_obj_base_t *o = obj;
switch (o->kind) {
case O_STR:
// pointer to the string (it's probably constant though!)
return (machine_uint_t)qstr_str(o->u_str);
case O_FLOAT:
// convert float to int (could also pass in float registers)
return (machine_int_t)o->u_flt;
case O_LIST:
// pointer to start of list (could pass length, but then could use len(x) for that)
return (machine_uint_t)o->u_list.items;
default:
// just pass along a pointer to the object
return (machine_uint_t)obj;
}
}
}
// convert a return value from inline asm to a sensible Python object
py_obj_t rt_convert_val_from_inline_asm(machine_uint_t val) {
return TO_SMALL_INT(val);
}
typedef machine_uint_t (*inline_asm_fun_0_t)();
typedef machine_uint_t (*inline_asm_fun_1_t)(machine_uint_t);
typedef machine_uint_t (*inline_asm_fun_2_t)(machine_uint_t, machine_uint_t);
py_obj_t rt_call_function_0(py_obj_t fun) {
if (IS_O(fun, O_FUN_0)) {
py_obj_base_t *o = fun;
DEBUG_OP_printf("calling native %p...\n", o->u_fun.fun);
DEBUG_OP_printf("calling native %p with no args\n", o->u_fun.fun);
return ((py_fun_0_t)o->u_fun.fun)();
} else if (IS_O(fun, O_FUN_BC)) {
py_obj_base_t *o = fun;
assert(o->u_fun_bc.n_args == 0);
DEBUG_OP_printf("calling byte code %p...\n", o->u_fun_bc.code);
DEBUG_OP_printf("calling byte code %p with no args\n", o->u_fun_bc.code);
return py_execute_byte_code(o->u_fun_bc.code, o->u_fun_bc.len, NULL, 0);
} else if (IS_O(fun, O_FUN_ASM)) {
py_obj_base_t *o = fun;
assert(o->u_fun_asm.n_args == 0);
DEBUG_OP_printf("calling inline asm %p with no args\n", o->u_fun_asm.fun);
return rt_convert_val_from_inline_asm(((inline_asm_fun_0_t)o->u_fun_asm.fun)());
} else {
printf("fun0:%p\n", fun);
assert(0);
@ -776,13 +823,7 @@ py_obj_t rt_call_function_1(py_obj_t fun, py_obj_t arg) {
py_obj_base_t *o = fun;
assert(o->u_fun_asm.n_args == 1);
DEBUG_OP_printf("calling inline asm %p with 1 arg\n", o->u_fun_asm.fun);
machine_int_t arg_val;
if (IS_SMALL_INT(arg)) {
arg_val = FROM_SMALL_INT(arg);
} else {
arg_val = arg;
}
return ((py_fun_1_t)o->u_fun_asm.fun)(arg_val);
return rt_convert_val_from_inline_asm(((inline_asm_fun_1_t)o->u_fun_asm.fun)(rt_convert_obj_for_inline_asm(arg)));
} else if (IS_O(fun, O_BOUND_METH)) {
py_obj_base_t *o = fun;
return rt_call_function_2(o->u_bound_meth.meth, o->u_bound_meth.self, arg);
@ -796,16 +837,21 @@ py_obj_t rt_call_function_1(py_obj_t fun, py_obj_t arg) {
py_obj_t rt_call_function_2(py_obj_t fun, py_obj_t arg1, py_obj_t arg2) {
if (IS_O(fun, O_FUN_2)) {
py_obj_base_t *o = fun;
DEBUG_OP_printf("calling native %p...\n", o->u_fun.fun);
DEBUG_OP_printf("calling native %p with 2 args\n", o->u_fun.fun);
return ((py_fun_2_t)o->u_fun.fun)(arg1, arg2);
} else if (IS_O(fun, O_FUN_BC)) {
py_obj_base_t *o = fun;
assert(o->u_fun_bc.n_args == 2);
DEBUG_OP_printf("calling byte code %p...\n", o->u_fun_bc.code);
DEBUG_OP_printf("calling byte code %p with 2 args\n", o->u_fun_bc.code);
py_obj_t args[2];
args[0] = arg1;
args[1] = arg2;
return py_execute_byte_code(o->u_fun_bc.code, o->u_fun_bc.len, &args[0], 2);
} else if (IS_O(fun, O_FUN_ASM)) {
py_obj_base_t *o = fun;
assert(o->u_fun_asm.n_args == 2);
DEBUG_OP_printf("calling inline asm %p with 2 args\n", o->u_fun_asm.fun);
return rt_convert_val_from_inline_asm(((inline_asm_fun_2_t)o->u_fun_asm.fun)(rt_convert_obj_for_inline_asm(arg1), rt_convert_obj_for_inline_asm(arg2)));
} else {
assert(0);
return py_const_none;