Skip to content

Commit e6c0dff

Browse files
committed
py: Viper can now store to global.
1 parent a5190a7 commit e6c0dff

7 files changed

Lines changed: 62 additions & 32 deletions

File tree

py/emitnative.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -903,8 +903,16 @@ STATIC void emit_native_store_name(emit_t *emit, qstr qstr) {
903903
}
904904

905905
STATIC void emit_native_store_global(emit_t *emit, qstr qstr) {
906-
// not implemented
907-
assert(0);
906+
vtype_kind_t vtype = peek_vtype(emit);
907+
if (vtype == VTYPE_PYOBJ) {
908+
emit_pre_pop_reg(emit, &vtype, REG_ARG_2);
909+
} else {
910+
emit_pre_pop_reg(emit, &vtype, REG_ARG_1);
911+
emit_call_with_imm_arg(emit, MP_F_CONVERT_NATIVE_TO_OBJ, mp_convert_native_to_obj, vtype, REG_ARG_2); // arg2 = type
912+
ASM_MOV_REG_TO_REG(REG_RET, REG_ARG_2);
913+
}
914+
emit_call_with_imm_arg(emit, MP_F_STORE_GLOBAL, mp_store_global, qstr, REG_ARG_1); // arg1 = name
915+
emit_post(emit);
908916
}
909917

910918
STATIC void emit_native_store_attr(emit_t *emit, qstr qstr) {
@@ -1420,12 +1428,14 @@ STATIC void emit_native_call_method(emit_t *emit, int n_positional, int n_keywor
14201428

14211429
STATIC void emit_native_return_value(emit_t *emit) {
14221430
DEBUG_printf("return_value\n");
1423-
// easy. since we don't know who we return to, just return the raw value.
1424-
// runtime needs then to know our type signature, but I think that's possible.
14251431
vtype_kind_t vtype;
14261432
emit_pre_pop_reg(emit, &vtype, REG_RET);
14271433
if (emit->do_viper_types) {
1428-
if (vtype != emit->return_vtype) {
1434+
if (vtype == VTYPE_PTR_NONE) {
1435+
if (emit->return_vtype == VTYPE_PYOBJ) {
1436+
ASM_MOV_IMM_TO_REG((mp_uint_t)mp_const_none, REG_RET);
1437+
}
1438+
} else if (vtype != emit->return_vtype) {
14291439
printf("ViperTypeError: incompatible return type\n");
14301440
}
14311441
} else {

py/objfun.c

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -517,28 +517,6 @@ typedef mp_uint_t (*viper_fun_1_t)(mp_uint_t);
517517
typedef mp_uint_t (*viper_fun_2_t)(mp_uint_t, mp_uint_t);
518518
typedef mp_uint_t (*viper_fun_3_t)(mp_uint_t, mp_uint_t, mp_uint_t);
519519

520-
// convert a Micro Python object to a valid value for viper, based on wanted type
521-
STATIC mp_uint_t convert_obj_for_viper(mp_obj_t obj, mp_uint_t type) {
522-
switch (type & 3) {
523-
case MP_NATIVE_TYPE_OBJ: return (mp_uint_t)obj;
524-
case MP_NATIVE_TYPE_BOOL:
525-
case MP_NATIVE_TYPE_INT:
526-
case MP_NATIVE_TYPE_UINT: return mp_obj_get_int(obj);
527-
default: assert(0); return 0;
528-
}
529-
}
530-
531-
// convert a return value from viper to a Micro Python object based on viper return type
532-
STATIC mp_obj_t convert_val_from_viper(mp_uint_t val, mp_uint_t type) {
533-
switch (type & 3) {
534-
case MP_NATIVE_TYPE_OBJ: return (mp_obj_t)val;
535-
case MP_NATIVE_TYPE_BOOL: return MP_BOOL(val);
536-
case MP_NATIVE_TYPE_INT: return mp_obj_new_int(val);
537-
case MP_NATIVE_TYPE_UINT: return mp_obj_new_int_from_uint(val);
538-
default: assert(0); return mp_const_none;
539-
}
540-
}
541-
542520
STATIC mp_obj_t fun_viper_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj_t *args) {
543521
mp_obj_fun_viper_t *self = self_in;
544522

@@ -548,17 +526,17 @@ STATIC mp_obj_t fun_viper_call(mp_obj_t self_in, uint n_args, uint n_kw, const m
548526
if (n_args == 0) {
549527
ret = ((viper_fun_0_t)self->fun)();
550528
} else if (n_args == 1) {
551-
ret = ((viper_fun_1_t)self->fun)(convert_obj_for_viper(args[0], self->type_sig >> 2));
529+
ret = ((viper_fun_1_t)self->fun)(mp_convert_obj_to_native(args[0], self->type_sig >> 2));
552530
} else if (n_args == 2) {
553-
ret = ((viper_fun_2_t)self->fun)(convert_obj_for_viper(args[0], self->type_sig >> 2), convert_obj_for_viper(args[1], self->type_sig >> 4));
531+
ret = ((viper_fun_2_t)self->fun)(mp_convert_obj_to_native(args[0], self->type_sig >> 2), mp_convert_obj_to_native(args[1], self->type_sig >> 4));
554532
} else if (n_args == 3) {
555-
ret = ((viper_fun_3_t)self->fun)(convert_obj_for_viper(args[0], self->type_sig >> 2), convert_obj_for_viper(args[1], self->type_sig >> 4), convert_obj_for_viper(args[2], self->type_sig >> 6));
533+
ret = ((viper_fun_3_t)self->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));
556534
} else {
557535
assert(0);
558536
ret = 0;
559537
}
560538

561-
return convert_val_from_viper(ret, self->type_sig);
539+
return mp_convert_native_to_obj(ret, self->type_sig);
562540
}
563541

564542
STATIC const mp_obj_type_t mp_type_fun_viper = {

py/runtime.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1163,8 +1163,34 @@ NORETURN void mp_not_implemented(const char *msg) {
11631163
nlr_raise(mp_obj_new_exception_msg(&mp_type_NotImplementedError, msg));
11641164
}
11651165

1166+
// convert a Micro Python object to a valid native value based on type
1167+
mp_uint_t mp_convert_obj_to_native(mp_obj_t obj, mp_uint_t type) {
1168+
DEBUG_printf("mp_convert_obj_to_native(%p, " UINT_FMT ")\n", obj, type);
1169+
switch (type & 3) {
1170+
case MP_NATIVE_TYPE_OBJ: return (mp_uint_t)obj;
1171+
case MP_NATIVE_TYPE_BOOL:
1172+
case MP_NATIVE_TYPE_INT:
1173+
case MP_NATIVE_TYPE_UINT: return mp_obj_get_int(obj);
1174+
default: assert(0); return 0;
1175+
}
1176+
}
1177+
1178+
// convert a native value to a Micro Python object based on type
1179+
mp_obj_t mp_convert_native_to_obj(mp_uint_t val, mp_uint_t type) {
1180+
DEBUG_printf("mp_convert_native_to_obj(" UINT_FMT ", " UINT_FMT ")\n", val, type);
1181+
switch (type & 3) {
1182+
case MP_NATIVE_TYPE_OBJ: return (mp_obj_t)val;
1183+
case MP_NATIVE_TYPE_BOOL: return MP_BOOL(val);
1184+
case MP_NATIVE_TYPE_INT: return mp_obj_new_int(val);
1185+
case MP_NATIVE_TYPE_UINT: return mp_obj_new_int_from_uint(val);
1186+
default: assert(0); return mp_const_none;
1187+
}
1188+
}
1189+
11661190
// these must correspond to the respective enum
11671191
void *const mp_fun_table[MP_F_NUMBER_OF] = {
1192+
mp_convert_obj_to_native,
1193+
mp_convert_native_to_obj,
11681194
mp_load_const_int,
11691195
mp_load_const_dec,
11701196
mp_load_const_str,
@@ -1174,6 +1200,7 @@ void *const mp_fun_table[MP_F_NUMBER_OF] = {
11741200
mp_load_attr,
11751201
mp_load_method,
11761202
mp_store_name,
1203+
mp_store_global,
11771204
mp_store_attr,
11781205
mp_obj_subscr,
11791206
mp_obj_is_true,

py/runtime.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,9 @@ void mp_import_all(mp_obj_t module);
115115
// Raise NotImplementedError with given message
116116
NORETURN void mp_not_implemented(const char *msg);
117117

118+
mp_uint_t mp_convert_obj_to_native(mp_obj_t obj, mp_uint_t type);
119+
mp_obj_t mp_convert_native_to_obj(mp_uint_t val, mp_uint_t type);
120+
118121
extern struct _mp_obj_list_t mp_sys_path_obj;
119122
extern struct _mp_obj_list_t mp_sys_argv_obj;
120123
#define mp_sys_path ((mp_obj_t)&mp_sys_path_obj)

py/runtime0.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,9 @@ typedef enum {
102102
} mp_binary_op_t;
103103

104104
typedef enum {
105-
MP_F_LOAD_CONST_INT = 0,
105+
MP_F_CONVERT_OBJ_TO_NATIVE = 0,
106+
MP_F_CONVERT_NATIVE_TO_OBJ,
107+
MP_F_LOAD_CONST_INT,
106108
MP_F_LOAD_CONST_DEC,
107109
MP_F_LOAD_CONST_STR,
108110
MP_F_LOAD_NAME,
@@ -111,6 +113,7 @@ typedef enum {
111113
MP_F_LOAD_ATTR,
112114
MP_F_LOAD_METHOD,
113115
MP_F_STORE_NAME,
116+
MP_F_STORE_GLOBAL,
114117
MP_F_STORE_ATTR,
115118
MP_F_OBJ_SUBSCR,
116119
MP_F_OBJ_IS_TRUE,

tests/micropython/viper.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,13 @@ def viper_sum(a:int, b:int) -> int:
2929
total += x
3030
return total
3131

32+
# accessing a global
33+
@micropython.viper
34+
def access_global():
35+
global gl
36+
gl = 1
37+
return gl
38+
3239
# this doesn't work at the moment
3340
#@micropython.viper
3441
#def g() -> uint:
@@ -39,3 +46,4 @@ def viper_sum(a:int, b:int) -> int:
3946
print(h(3))
4047
print(i(4, 5))
4148
print(viper_sum(10, 10000))
49+
print(access_global(), gl)

tests/micropython/viper.py.exp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
7
44
20
55
49994955
6+
1 1

0 commit comments

Comments
 (0)