py: Extend native type-sig to use 4 bits, so uint is separate to ptr.
Before this patch, the native types for uint and ptr/ptr8/ptr16/ptr32 all overlapped and it was possible to make a mistake in casting. Now, these types are all separate and any coding mistakes will be raised as runtime errors.
This commit is contained in:
parent
086d98cbde
commit
5f3e005b67
|
@ -510,19 +510,19 @@ typedef enum {
|
|||
STACK_IMM,
|
||||
} stack_info_kind_t;
|
||||
|
||||
// these enums must be distinct and the bottom 2 bits
|
||||
// these enums must be distinct and the bottom 4 bits
|
||||
// must correspond to the correct MP_NATIVE_TYPE_xxx value
|
||||
typedef enum {
|
||||
VTYPE_PYOBJ = 0x00 | MP_NATIVE_TYPE_OBJ,
|
||||
VTYPE_BOOL = 0x00 | MP_NATIVE_TYPE_BOOL,
|
||||
VTYPE_INT = 0x00 | MP_NATIVE_TYPE_INT,
|
||||
VTYPE_UINT = 0x00 | MP_NATIVE_TYPE_UINT,
|
||||
VTYPE_PTR = 0x00 | MP_NATIVE_TYPE_PTR,
|
||||
VTYPE_PTR8 = 0x00 | MP_NATIVE_TYPE_PTR8,
|
||||
VTYPE_PTR16 = 0x00 | MP_NATIVE_TYPE_PTR16,
|
||||
VTYPE_PTR32 = 0x00 | MP_NATIVE_TYPE_PTR32,
|
||||
|
||||
VTYPE_PTR = 0x10 | MP_NATIVE_TYPE_UINT, // pointer to word sized entity
|
||||
VTYPE_PTR8 = 0x20 | MP_NATIVE_TYPE_UINT,
|
||||
VTYPE_PTR16 = 0x30 | MP_NATIVE_TYPE_UINT,
|
||||
VTYPE_PTR32 = 0x40 | MP_NATIVE_TYPE_UINT,
|
||||
VTYPE_PTR_NONE = 0x50 | MP_NATIVE_TYPE_UINT,
|
||||
VTYPE_PTR_NONE = 0x50 | MP_NATIVE_TYPE_PTR,
|
||||
|
||||
VTYPE_UNBOUND = 0x60 | MP_NATIVE_TYPE_OBJ,
|
||||
VTYPE_BUILTIN_CAST = 0x70 | MP_NATIVE_TYPE_OBJ,
|
||||
|
@ -882,10 +882,10 @@ STATIC void emit_native_end_pass(emit_t *emit) {
|
|||
mp_uint_t f_len = ASM_GET_CODE_SIZE(emit->as);
|
||||
|
||||
// compute type signature
|
||||
// note that the lower 2 bits of a vtype are tho correct MP_NATIVE_TYPE_xxx
|
||||
mp_uint_t type_sig = emit->return_vtype & 3;
|
||||
// note that the lower 4 bits of a vtype are tho correct MP_NATIVE_TYPE_xxx
|
||||
mp_uint_t type_sig = emit->return_vtype & 0xf;
|
||||
for (mp_uint_t i = 0; i < emit->scope->num_pos_args; i++) {
|
||||
type_sig |= (emit->local_vtype[i] & 3) << (i * 2 + 2);
|
||||
type_sig |= (emit->local_vtype[i] & 0xf) << (i * 4 + 4);
|
||||
}
|
||||
|
||||
mp_emit_glue_assign_native(emit->scope->raw_code,
|
||||
|
@ -2382,7 +2382,7 @@ STATIC void emit_native_call_function(emit_t *emit, mp_uint_t n_positional, mp_u
|
|||
vtype_kind_t vtype;
|
||||
emit_pre_pop_reg(emit, &vtype, REG_ARG_1);
|
||||
emit_pre_pop_discard(emit);
|
||||
emit_call_with_imm_arg(emit, MP_F_CONVERT_OBJ_TO_NATIVE, MP_NATIVE_TYPE_UINT, REG_ARG_2); // arg2 = type
|
||||
emit_call_with_imm_arg(emit, MP_F_CONVERT_OBJ_TO_NATIVE, vtype_cast, REG_ARG_2); // arg2 = type
|
||||
emit_post_push_reg(emit, vtype_cast, REG_RET);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -45,19 +45,16 @@
|
|||
// convert a Micro Python object to a valid native value based on type
|
||||
mp_uint_t mp_convert_obj_to_native(mp_obj_t obj, mp_uint_t type) {
|
||||
DEBUG_printf("mp_convert_obj_to_native(%p, " UINT_FMT ")\n", obj, type);
|
||||
switch (type & 3) {
|
||||
switch (type & 0xf) {
|
||||
case MP_NATIVE_TYPE_OBJ: return (mp_uint_t)obj;
|
||||
case MP_NATIVE_TYPE_BOOL:
|
||||
case MP_NATIVE_TYPE_INT: return mp_obj_get_int_truncated(obj);
|
||||
case MP_NATIVE_TYPE_UINT: {
|
||||
case MP_NATIVE_TYPE_INT:
|
||||
case MP_NATIVE_TYPE_UINT: return mp_obj_get_int_truncated(obj);
|
||||
default: { // a pointer
|
||||
mp_buffer_info_t bufinfo;
|
||||
if (mp_get_buffer(obj, &bufinfo, MP_BUFFER_RW)) {
|
||||
return (mp_uint_t)bufinfo.buf;
|
||||
} else {
|
||||
return mp_obj_get_int_truncated(obj);
|
||||
}
|
||||
mp_get_buffer_raise(obj, &bufinfo, MP_BUFFER_RW);
|
||||
return (mp_uint_t)bufinfo.buf;
|
||||
}
|
||||
default: assert(0); return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,12 +65,14 @@ mp_uint_t mp_convert_obj_to_native(mp_obj_t obj, mp_uint_t type) {
|
|||
// convert a native value to a Micro Python object based on type
|
||||
mp_obj_t mp_convert_native_to_obj(mp_uint_t val, mp_uint_t type) {
|
||||
DEBUG_printf("mp_convert_native_to_obj(" UINT_FMT ", " UINT_FMT ")\n", val, type);
|
||||
switch (type & 3) {
|
||||
switch (type & 0xf) {
|
||||
case MP_NATIVE_TYPE_OBJ: return (mp_obj_t)val;
|
||||
case MP_NATIVE_TYPE_BOOL: return mp_obj_new_bool(val);
|
||||
case MP_NATIVE_TYPE_INT: return mp_obj_new_int(val);
|
||||
case MP_NATIVE_TYPE_UINT: return mp_obj_new_int_from_uint(val);
|
||||
default: assert(0); return mp_const_none;
|
||||
default: // a pointer
|
||||
// we return just the value of the pointer as an integer
|
||||
return mp_obj_new_int_from_uint(val);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
14
py/objfun.c
14
py/objfun.c
|
@ -404,17 +404,17 @@ STATIC mp_obj_t fun_viper_call(mp_obj_t self_in, size_t n_args, size_t n_kw, con
|
|||
if (n_args == 0) {
|
||||
ret = ((viper_fun_0_t)fun)();
|
||||
} else if (n_args == 1) {
|
||||
ret = ((viper_fun_1_t)fun)(mp_convert_obj_to_native(args[0], self->type_sig >> 2));
|
||||
ret = ((viper_fun_1_t)fun)(mp_convert_obj_to_native(args[0], self->type_sig >> 4));
|
||||
} else if (n_args == 2) {
|
||||
ret = ((viper_fun_2_t)fun)(mp_convert_obj_to_native(args[0], self->type_sig >> 2), mp_convert_obj_to_native(args[1], self->type_sig >> 4));
|
||||
ret = ((viper_fun_2_t)fun)(mp_convert_obj_to_native(args[0], self->type_sig >> 4), mp_convert_obj_to_native(args[1], self->type_sig >> 8));
|
||||
} else if (n_args == 3) {
|
||||
ret = ((viper_fun_3_t)fun)(mp_convert_obj_to_native(args[0], self->type_sig >> 2), mp_convert_obj_to_native(args[1], self->type_sig >> 4), mp_convert_obj_to_native(args[2], self->type_sig >> 6));
|
||||
ret = ((viper_fun_3_t)fun)(mp_convert_obj_to_native(args[0], self->type_sig >> 4), mp_convert_obj_to_native(args[1], self->type_sig >> 8), mp_convert_obj_to_native(args[2], self->type_sig >> 12));
|
||||
} else if (n_args == 4) {
|
||||
ret = ((viper_fun_4_t)fun)(
|
||||
mp_convert_obj_to_native(args[0], self->type_sig >> 2),
|
||||
mp_convert_obj_to_native(args[1], self->type_sig >> 4),
|
||||
mp_convert_obj_to_native(args[2], self->type_sig >> 6),
|
||||
mp_convert_obj_to_native(args[3], self->type_sig >> 8)
|
||||
mp_convert_obj_to_native(args[0], self->type_sig >> 4),
|
||||
mp_convert_obj_to_native(args[1], self->type_sig >> 8),
|
||||
mp_convert_obj_to_native(args[2], self->type_sig >> 12),
|
||||
mp_convert_obj_to_native(args[3], self->type_sig >> 16)
|
||||
);
|
||||
} else {
|
||||
// TODO 5 or more arguments not supported for viper call
|
||||
|
|
|
@ -37,6 +37,10 @@
|
|||
#define MP_NATIVE_TYPE_BOOL (0x01)
|
||||
#define MP_NATIVE_TYPE_INT (0x02)
|
||||
#define MP_NATIVE_TYPE_UINT (0x03)
|
||||
#define MP_NATIVE_TYPE_PTR (0x04)
|
||||
#define MP_NATIVE_TYPE_PTR8 (0x05)
|
||||
#define MP_NATIVE_TYPE_PTR16 (0x06)
|
||||
#define MP_NATIVE_TYPE_PTR32 (0x07)
|
||||
|
||||
typedef enum {
|
||||
MP_UNARY_OP_BOOL, // __bool__
|
||||
|
|
Loading…
Reference in New Issue