Skip to content

Commit 5f3e005

Browse files
committed
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.
1 parent 086d98c commit 5f3e005

File tree

4 files changed

+31
-28
lines changed

4 files changed

+31
-28
lines changed

py/emitnative.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -510,19 +510,19 @@ typedef enum {
510510
STACK_IMM,
511511
} stack_info_kind_t;
512512

513-
// these enums must be distinct and the bottom 2 bits
513+
// these enums must be distinct and the bottom 4 bits
514514
// must correspond to the correct MP_NATIVE_TYPE_xxx value
515515
typedef enum {
516516
VTYPE_PYOBJ = 0x00 | MP_NATIVE_TYPE_OBJ,
517517
VTYPE_BOOL = 0x00 | MP_NATIVE_TYPE_BOOL,
518518
VTYPE_INT = 0x00 | MP_NATIVE_TYPE_INT,
519519
VTYPE_UINT = 0x00 | MP_NATIVE_TYPE_UINT,
520+
VTYPE_PTR = 0x00 | MP_NATIVE_TYPE_PTR,
521+
VTYPE_PTR8 = 0x00 | MP_NATIVE_TYPE_PTR8,
522+
VTYPE_PTR16 = 0x00 | MP_NATIVE_TYPE_PTR16,
523+
VTYPE_PTR32 = 0x00 | MP_NATIVE_TYPE_PTR32,
520524

521-
VTYPE_PTR = 0x10 | MP_NATIVE_TYPE_UINT, // pointer to word sized entity
522-
VTYPE_PTR8 = 0x20 | MP_NATIVE_TYPE_UINT,
523-
VTYPE_PTR16 = 0x30 | MP_NATIVE_TYPE_UINT,
524-
VTYPE_PTR32 = 0x40 | MP_NATIVE_TYPE_UINT,
525-
VTYPE_PTR_NONE = 0x50 | MP_NATIVE_TYPE_UINT,
525+
VTYPE_PTR_NONE = 0x50 | MP_NATIVE_TYPE_PTR,
526526

527527
VTYPE_UNBOUND = 0x60 | MP_NATIVE_TYPE_OBJ,
528528
VTYPE_BUILTIN_CAST = 0x70 | MP_NATIVE_TYPE_OBJ,
@@ -882,10 +882,10 @@ STATIC void emit_native_end_pass(emit_t *emit) {
882882
mp_uint_t f_len = ASM_GET_CODE_SIZE(emit->as);
883883

884884
// compute type signature
885-
// note that the lower 2 bits of a vtype are tho correct MP_NATIVE_TYPE_xxx
886-
mp_uint_t type_sig = emit->return_vtype & 3;
885+
// note that the lower 4 bits of a vtype are tho correct MP_NATIVE_TYPE_xxx
886+
mp_uint_t type_sig = emit->return_vtype & 0xf;
887887
for (mp_uint_t i = 0; i < emit->scope->num_pos_args; i++) {
888-
type_sig |= (emit->local_vtype[i] & 3) << (i * 2 + 2);
888+
type_sig |= (emit->local_vtype[i] & 0xf) << (i * 4 + 4);
889889
}
890890

891891
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
23822382
vtype_kind_t vtype;
23832383
emit_pre_pop_reg(emit, &vtype, REG_ARG_1);
23842384
emit_pre_pop_discard(emit);
2385-
emit_call_with_imm_arg(emit, MP_F_CONVERT_OBJ_TO_NATIVE, MP_NATIVE_TYPE_UINT, REG_ARG_2); // arg2 = type
2385+
emit_call_with_imm_arg(emit, MP_F_CONVERT_OBJ_TO_NATIVE, vtype_cast, REG_ARG_2); // arg2 = type
23862386
emit_post_push_reg(emit, vtype_cast, REG_RET);
23872387
break;
23882388
}

py/nativeglue.c

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -45,19 +45,16 @@
4545
// convert a Micro Python object to a valid native value based on type
4646
mp_uint_t mp_convert_obj_to_native(mp_obj_t obj, mp_uint_t type) {
4747
DEBUG_printf("mp_convert_obj_to_native(%p, " UINT_FMT ")\n", obj, type);
48-
switch (type & 3) {
48+
switch (type & 0xf) {
4949
case MP_NATIVE_TYPE_OBJ: return (mp_uint_t)obj;
5050
case MP_NATIVE_TYPE_BOOL:
51-
case MP_NATIVE_TYPE_INT: return mp_obj_get_int_truncated(obj);
52-
case MP_NATIVE_TYPE_UINT: {
51+
case MP_NATIVE_TYPE_INT:
52+
case MP_NATIVE_TYPE_UINT: return mp_obj_get_int_truncated(obj);
53+
default: { // a pointer
5354
mp_buffer_info_t bufinfo;
54-
if (mp_get_buffer(obj, &bufinfo, MP_BUFFER_RW)) {
55-
return (mp_uint_t)bufinfo.buf;
56-
} else {
57-
return mp_obj_get_int_truncated(obj);
58-
}
55+
mp_get_buffer_raise(obj, &bufinfo, MP_BUFFER_RW);
56+
return (mp_uint_t)bufinfo.buf;
5957
}
60-
default: assert(0); return 0;
6158
}
6259
}
6360

@@ -68,12 +65,14 @@ mp_uint_t mp_convert_obj_to_native(mp_obj_t obj, mp_uint_t type) {
6865
// convert a native value to a Micro Python object based on type
6966
mp_obj_t mp_convert_native_to_obj(mp_uint_t val, mp_uint_t type) {
7067
DEBUG_printf("mp_convert_native_to_obj(" UINT_FMT ", " UINT_FMT ")\n", val, type);
71-
switch (type & 3) {
68+
switch (type & 0xf) {
7269
case MP_NATIVE_TYPE_OBJ: return (mp_obj_t)val;
7370
case MP_NATIVE_TYPE_BOOL: return mp_obj_new_bool(val);
7471
case MP_NATIVE_TYPE_INT: return mp_obj_new_int(val);
7572
case MP_NATIVE_TYPE_UINT: return mp_obj_new_int_from_uint(val);
76-
default: assert(0); return mp_const_none;
73+
default: // a pointer
74+
// we return just the value of the pointer as an integer
75+
return mp_obj_new_int_from_uint(val);
7776
}
7877
}
7978

py/objfun.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -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
404404
if (n_args == 0) {
405405
ret = ((viper_fun_0_t)fun)();
406406
} else if (n_args == 1) {
407-
ret = ((viper_fun_1_t)fun)(mp_convert_obj_to_native(args[0], self->type_sig >> 2));
407+
ret = ((viper_fun_1_t)fun)(mp_convert_obj_to_native(args[0], self->type_sig >> 4));
408408
} else if (n_args == 2) {
409-
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));
409+
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));
410410
} else if (n_args == 3) {
411-
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));
411+
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));
412412
} else if (n_args == 4) {
413413
ret = ((viper_fun_4_t)fun)(
414-
mp_convert_obj_to_native(args[0], self->type_sig >> 2),
415-
mp_convert_obj_to_native(args[1], self->type_sig >> 4),
416-
mp_convert_obj_to_native(args[2], self->type_sig >> 6),
417-
mp_convert_obj_to_native(args[3], self->type_sig >> 8)
414+
mp_convert_obj_to_native(args[0], self->type_sig >> 4),
415+
mp_convert_obj_to_native(args[1], self->type_sig >> 8),
416+
mp_convert_obj_to_native(args[2], self->type_sig >> 12),
417+
mp_convert_obj_to_native(args[3], self->type_sig >> 16)
418418
);
419419
} else {
420420
// TODO 5 or more arguments not supported for viper call

py/runtime0.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@
3737
#define MP_NATIVE_TYPE_BOOL (0x01)
3838
#define MP_NATIVE_TYPE_INT (0x02)
3939
#define MP_NATIVE_TYPE_UINT (0x03)
40+
#define MP_NATIVE_TYPE_PTR (0x04)
41+
#define MP_NATIVE_TYPE_PTR8 (0x05)
42+
#define MP_NATIVE_TYPE_PTR16 (0x06)
43+
#define MP_NATIVE_TYPE_PTR32 (0x07)
4044

4145
typedef enum {
4246
MP_UNARY_OP_BOOL, // __bool__

0 commit comments

Comments
 (0)