Skip to content
Snippets Groups Projects
Commit 5f3e005b authored by Damien George's avatar Damien George
Browse files

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.
parent 086d98cb
Branches
No related tags found
No related merge requests found
...@@ -510,19 +510,19 @@ typedef enum { ...@@ -510,19 +510,19 @@ typedef enum {
STACK_IMM, STACK_IMM,
} stack_info_kind_t; } 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 // must correspond to the correct MP_NATIVE_TYPE_xxx value
typedef enum { typedef enum {
VTYPE_PYOBJ = 0x00 | MP_NATIVE_TYPE_OBJ, VTYPE_PYOBJ = 0x00 | MP_NATIVE_TYPE_OBJ,
VTYPE_BOOL = 0x00 | MP_NATIVE_TYPE_BOOL, VTYPE_BOOL = 0x00 | MP_NATIVE_TYPE_BOOL,
VTYPE_INT = 0x00 | MP_NATIVE_TYPE_INT, VTYPE_INT = 0x00 | MP_NATIVE_TYPE_INT,
VTYPE_UINT = 0x00 | MP_NATIVE_TYPE_UINT, 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_PTR_NONE = 0x50 | MP_NATIVE_TYPE_PTR,
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_UNBOUND = 0x60 | MP_NATIVE_TYPE_OBJ, VTYPE_UNBOUND = 0x60 | MP_NATIVE_TYPE_OBJ,
VTYPE_BUILTIN_CAST = 0x70 | 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) { ...@@ -882,10 +882,10 @@ STATIC void emit_native_end_pass(emit_t *emit) {
mp_uint_t f_len = ASM_GET_CODE_SIZE(emit->as); mp_uint_t f_len = ASM_GET_CODE_SIZE(emit->as);
// compute type signature // compute type signature
// note that the lower 2 bits of a vtype are tho correct MP_NATIVE_TYPE_xxx // note that the lower 4 bits of a vtype are tho correct MP_NATIVE_TYPE_xxx
mp_uint_t type_sig = emit->return_vtype & 3; mp_uint_t type_sig = emit->return_vtype & 0xf;
for (mp_uint_t i = 0; i < emit->scope->num_pos_args; i++) { 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, 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 ...@@ -2382,7 +2382,7 @@ STATIC void emit_native_call_function(emit_t *emit, mp_uint_t n_positional, mp_u
vtype_kind_t vtype; vtype_kind_t vtype;
emit_pre_pop_reg(emit, &vtype, REG_ARG_1); emit_pre_pop_reg(emit, &vtype, REG_ARG_1);
emit_pre_pop_discard(emit); 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); emit_post_push_reg(emit, vtype_cast, REG_RET);
break; break;
} }
......
...@@ -45,20 +45,17 @@ ...@@ -45,20 +45,17 @@
// convert a Micro Python object to a valid native value based on type // 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) { 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); 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_OBJ: return (mp_uint_t)obj;
case MP_NATIVE_TYPE_BOOL: case MP_NATIVE_TYPE_BOOL:
case MP_NATIVE_TYPE_INT: return mp_obj_get_int_truncated(obj); case MP_NATIVE_TYPE_INT:
case MP_NATIVE_TYPE_UINT: { case MP_NATIVE_TYPE_UINT: return mp_obj_get_int_truncated(obj);
default: { // a pointer
mp_buffer_info_t bufinfo; mp_buffer_info_t bufinfo;
if (mp_get_buffer(obj, &bufinfo, MP_BUFFER_RW)) { mp_get_buffer_raise(obj, &bufinfo, MP_BUFFER_RW);
return (mp_uint_t)bufinfo.buf; return (mp_uint_t)bufinfo.buf;
} else {
return mp_obj_get_int_truncated(obj);
} }
} }
default: assert(0); return 0;
}
} }
#endif #endif
...@@ -68,12 +65,14 @@ mp_uint_t mp_convert_obj_to_native(mp_obj_t obj, mp_uint_t type) { ...@@ -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 // 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) { 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); 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_OBJ: return (mp_obj_t)val;
case MP_NATIVE_TYPE_BOOL: return mp_obj_new_bool(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_INT: return mp_obj_new_int(val);
case MP_NATIVE_TYPE_UINT: return mp_obj_new_int_from_uint(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);
} }
} }
......
...@@ -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 ...@@ -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) { if (n_args == 0) {
ret = ((viper_fun_0_t)fun)(); ret = ((viper_fun_0_t)fun)();
} else if (n_args == 1) { } 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) { } 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) { } 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) { } else if (n_args == 4) {
ret = ((viper_fun_4_t)fun)( ret = ((viper_fun_4_t)fun)(
mp_convert_obj_to_native(args[0], self->type_sig >> 2), mp_convert_obj_to_native(args[0], self->type_sig >> 4),
mp_convert_obj_to_native(args[1], 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 >> 6), mp_convert_obj_to_native(args[2], self->type_sig >> 12),
mp_convert_obj_to_native(args[3], self->type_sig >> 8) mp_convert_obj_to_native(args[3], self->type_sig >> 16)
); );
} else { } else {
// TODO 5 or more arguments not supported for viper call // TODO 5 or more arguments not supported for viper call
......
...@@ -37,6 +37,10 @@ ...@@ -37,6 +37,10 @@
#define MP_NATIVE_TYPE_BOOL (0x01) #define MP_NATIVE_TYPE_BOOL (0x01)
#define MP_NATIVE_TYPE_INT (0x02) #define MP_NATIVE_TYPE_INT (0x02)
#define MP_NATIVE_TYPE_UINT (0x03) #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 { typedef enum {
MP_UNARY_OP_BOOL, // __bool__ MP_UNARY_OP_BOOL, // __bool__
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment