Skip to content

Commit ccc85ea

Browse files
committed
py: Combine native emitters to 1 glue function; distinguish viper.
This patch simplifies the glue between native emitter and runtime, and handles viper code like inline assember: return values are converted to Python objects. Fixes issue adafruit#531.
1 parent 04b7cc4 commit ccc85ea

5 files changed

Lines changed: 26 additions & 53 deletions

File tree

py/emitglue.c

Lines changed: 10 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ mp_raw_code_t *mp_emit_glue_new_raw_code(void) {
7474
}
7575

7676
void mp_emit_glue_assign_bytecode(mp_raw_code_t *rc, byte *code, uint len, uint n_pos_args, uint n_kwonly_args, qstr *arg_names, uint scope_flags) {
77-
rc->kind = MP_CODE_BYTE;
77+
rc->kind = MP_CODE_BYTECODE;
7878
rc->scope_flags = scope_flags;
7979
rc->n_pos_args = n_pos_args;
8080
rc->n_kwonly_args = n_kwonly_args;
@@ -104,40 +104,15 @@ void mp_emit_glue_assign_bytecode(mp_raw_code_t *rc, byte *code, uint len, uint
104104
#endif
105105
}
106106

107-
void mp_emit_glue_assign_native_code(mp_raw_code_t *rc, void *fun, uint len, int n_args) {
108-
rc->kind = MP_CODE_NATIVE;
107+
void mp_emit_glue_assign_native(mp_raw_code_t *rc, mp_raw_code_kind_t kind, void *fun, uint len, int n_args) {
108+
assert(kind == MP_CODE_NATIVE_PY || kind == MP_CODE_NATIVE_VIPER || kind == MP_CODE_NATIVE_ASM);
109+
rc->kind = kind;
109110
rc->scope_flags = 0;
110111
rc->n_pos_args = n_args;
111112
rc->u_native.fun = fun;
112113

113114
#ifdef DEBUG_PRINT
114-
DEBUG_printf("assign native code: fun=%p len=%u n_args=%d\n", fun, len, n_args);
115-
byte *fun_data = (byte*)(((machine_uint_t)fun) & (~1)); // need to clear lower bit in case it's thumb code
116-
for (int i = 0; i < 128 && i < len; i++) {
117-
if (i > 0 && i % 16 == 0) {
118-
DEBUG_printf("\n");
119-
}
120-
DEBUG_printf(" %02x", fun_data[i]);
121-
}
122-
DEBUG_printf("\n");
123-
124-
#ifdef WRITE_CODE
125-
if (fp_write_code != NULL) {
126-
fwrite(fun_data, len, 1, fp_write_code);
127-
fflush(fp_write_code);
128-
}
129-
#endif
130-
#endif
131-
}
132-
133-
void mp_emit_glue_assign_inline_asm_code(mp_raw_code_t *rc, void *fun, uint len, int n_args) {
134-
rc->kind = MP_CODE_INLINE_ASM;
135-
rc->scope_flags = 0;
136-
rc->n_pos_args = n_args;
137-
rc->u_inline_asm.fun = fun;
138-
139-
#ifdef DEBUG_PRINT
140-
DEBUG_printf("assign inline asm code: fun=%p len=%u n_args=%d\n", fun, len, n_args);
115+
DEBUG_printf("assign native: kind=%d fun=%p len=%u n_args=%d\n", kind, fun, len, n_args);
141116
byte *fun_data = (byte*)(((machine_uint_t)fun) & (~1)); // need to clear lower bit in case it's thumb code
142117
for (int i = 0; i < 128 && i < len; i++) {
143118
if (i > 0 && i % 16 == 0) {
@@ -169,14 +144,15 @@ mp_obj_t mp_make_function_from_raw_code(mp_raw_code_t *rc, mp_obj_t def_args, mp
169144
// make the function, depending on the raw code kind
170145
mp_obj_t fun;
171146
switch (rc->kind) {
172-
case MP_CODE_BYTE:
147+
case MP_CODE_BYTECODE:
173148
fun = mp_obj_new_fun_bc(rc->scope_flags, rc->arg_names, rc->n_pos_args, rc->n_kwonly_args, def_args, rc->u_byte.code);
174149
break;
175-
case MP_CODE_NATIVE:
150+
case MP_CODE_NATIVE_PY:
176151
fun = mp_make_function_n(rc->n_pos_args, rc->u_native.fun);
177152
break;
178-
case MP_CODE_INLINE_ASM:
179-
fun = mp_obj_new_fun_asm(rc->n_pos_args, rc->u_inline_asm.fun);
153+
case MP_CODE_NATIVE_VIPER:
154+
case MP_CODE_NATIVE_ASM:
155+
fun = mp_obj_new_fun_asm(rc->n_pos_args, rc->u_native.fun);
180156
break;
181157
default:
182158
// raw code was never set (this should not happen)

py/emitglue.h

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,10 @@
2929
typedef enum {
3030
MP_CODE_UNUSED,
3131
MP_CODE_RESERVED,
32-
MP_CODE_BYTE,
33-
MP_CODE_NATIVE,
34-
MP_CODE_INLINE_ASM,
32+
MP_CODE_BYTECODE,
33+
MP_CODE_NATIVE_PY,
34+
MP_CODE_NATIVE_VIPER,
35+
MP_CODE_NATIVE_ASM,
3536
} mp_raw_code_kind_t;
3637

3738
typedef struct _mp_code_t {
@@ -45,12 +46,9 @@ typedef struct _mp_code_t {
4546
byte *code;
4647
uint len;
4748
} u_byte;
48-
struct {
49-
mp_fun_t fun;
50-
} u_native;
5149
struct {
5250
void *fun;
53-
} u_inline_asm;
51+
} u_native;
5452
};
5553
} mp_raw_code_t;
5654

@@ -60,8 +58,7 @@ void mp_emit_glue_deinit(void);
6058
mp_raw_code_t *mp_emit_glue_new_raw_code(void);
6159

6260
void mp_emit_glue_assign_bytecode(mp_raw_code_t *rc, byte *code, uint len, uint n_pos_args, uint n_kwonly_args, qstr *arg_names, uint scope_flags);
63-
void mp_emit_glue_assign_native_code(mp_raw_code_t *rc, void *f, uint len, int n_args);
64-
void mp_emit_glue_assign_inline_asm_code(mp_raw_code_t *rc, void *f, uint len, int n_args);
61+
void mp_emit_glue_assign_native(mp_raw_code_t *rc, mp_raw_code_kind_t kind, void *f, uint len, int n_args);
6562

6663
mp_obj_t mp_make_function_from_raw_code(mp_raw_code_t *rc, mp_obj_t def_args, mp_obj_t def_kw_args);
6764
mp_obj_t mp_make_closure_from_raw_code(mp_raw_code_t *rc, uint n_closed_over, const mp_obj_t *args);

py/emitinlinethumb.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ STATIC bool emit_inline_thumb_end_pass(emit_inline_asm_t *emit) {
9999

100100
if (emit->pass == MP_PASS_EMIT) {
101101
void *f = asm_thumb_get_code(emit->as);
102-
mp_emit_glue_assign_inline_asm_code(emit->scope->raw_code, f, asm_thumb_get_code_size(emit->as), emit->scope->num_pos_args);
102+
mp_emit_glue_assign_native(emit->scope->raw_code, MP_CODE_NATIVE_ASM, f, asm_thumb_get_code_size(emit->as), emit->scope->num_pos_args);
103103
}
104104

105105
return emit->success;

py/emitnative.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -309,10 +309,10 @@ STATIC void emit_native_end_pass(emit_t *emit) {
309309
if (emit->pass == MP_PASS_EMIT) {
310310
#if N_X64
311311
void *f = asm_x64_get_code(emit->as);
312-
mp_emit_glue_assign_native_code(emit->scope->raw_code, f, asm_x64_get_code_size(emit->as), emit->scope->num_pos_args);
312+
mp_emit_glue_assign_native(emit->scope->raw_code, emit->do_viper_types ? MP_CODE_NATIVE_VIPER : MP_CODE_NATIVE_PY, f, asm_x64_get_code_size(emit->as), emit->scope->num_pos_args);
313313
#elif N_THUMB
314314
void *f = asm_thumb_get_code(emit->as);
315-
mp_emit_glue_assign_native_code(emit->scope->raw_code, f, asm_thumb_get_code_size(emit->as), emit->scope->num_pos_args);
315+
mp_emit_glue_assign_native(emit->scope->raw_code, emit->do_viper_types ? MP_CODE_NATIVE_VIPER : MP_CODE_NATIVE_PY, f, asm_thumb_get_code_size(emit->as), emit->scope->num_pos_args);
316316
#endif
317317
}
318318
}
@@ -438,6 +438,11 @@ STATIC void emit_access_stack(emit_t *emit, int pos, vtype_kind_t *vtype, int re
438438
}
439439
}
440440

441+
STATIC void emit_pre_pop_discard(emit_t *emit, vtype_kind_t *vtype) {
442+
emit->last_emit_was_return_value = false;
443+
adjust_stack(emit, -1);
444+
}
445+
441446
STATIC void emit_pre_pop_reg(emit_t *emit, vtype_kind_t *vtype, int reg_dest) {
442447
emit->last_emit_was_return_value = false;
443448
emit_access_stack(emit, 1, vtype, reg_dest);
@@ -938,7 +943,7 @@ STATIC void emit_native_dup_top_two(emit_t *emit) {
938943

939944
STATIC void emit_native_pop_top(emit_t *emit) {
940945
vtype_kind_t vtype;
941-
emit_pre_pop_reg(emit, &vtype, REG_TEMP0);
946+
emit_pre_pop_discard(emit, &vtype);
942947
emit_post(emit);
943948
}
944949

py/objfun.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -506,12 +506,7 @@ STATIC mp_obj_t convert_val_from_inline_asm(machine_uint_t val) {
506506
STATIC mp_obj_t fun_asm_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj_t *args) {
507507
mp_obj_fun_asm_t *self = self_in;
508508

509-
if (n_args != self->n_args) {
510-
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "function takes %d positional arguments but %d were given", self->n_args, n_args));
511-
}
512-
if (n_kw != 0) {
513-
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "function does not take keyword arguments"));
514-
}
509+
mp_arg_check_num(n_args, n_kw, self->n_args, self->n_args, false);
515510

516511
machine_uint_t ret;
517512
if (n_args == 0) {

0 commit comments

Comments
 (0)