summaryrefslogtreecommitdiffstatshomepage
path: root/py/emitglue.c
diff options
context:
space:
mode:
Diffstat (limited to 'py/emitglue.c')
-rw-r--r--py/emitglue.c159
1 files changed, 37 insertions, 122 deletions
diff --git a/py/emitglue.c b/py/emitglue.c
index bcc9b2cca1..ce296f4321 100644
--- a/py/emitglue.c
+++ b/py/emitglue.c
@@ -23,46 +23,11 @@
#define DEBUG_OP_printf(...) (void)0
#endif
-typedef enum {
- MP_CODE_UNUSED,
- MP_CODE_RESERVED,
- MP_CODE_BYTE,
- MP_CODE_NATIVE,
- MP_CODE_INLINE_ASM,
-} mp_code_kind_t;
-
-typedef struct _mp_code_t {
- mp_code_kind_t kind : 8;
- uint scope_flags : 8;
- uint n_args : 16;
- union {
- struct {
- byte *code;
- uint len;
- } u_byte;
- struct {
- mp_fun_t fun;
- } u_native;
- struct {
- void *fun;
- } u_inline_asm;
- };
- qstr *arg_names;
-} mp_code_t;
-
-STATIC machine_uint_t unique_codes_alloc = 0;
-STATIC machine_uint_t unique_codes_total = 0; // always >= unique_codes_alloc
-STATIC mp_code_t *unique_codes = NULL;
-
#ifdef WRITE_CODE
FILE *fp_write_code = NULL;
#endif
void mp_emit_glue_init(void) {
- unique_codes_alloc = 0;
- unique_codes_total = 0;
- unique_codes = NULL;
-
#ifdef WRITE_CODE
fp_write_code = fopen("out-code", "wb");
#endif
@@ -74,50 +39,24 @@ void mp_emit_glue_deinit(void) {
fclose(fp_write_code);
}
#endif
-
- m_del(mp_code_t, unique_codes, unique_codes_alloc);
-}
-
-uint mp_emit_glue_get_unique_code_id(void) {
- // look for an existing unused slot
- for (uint i = 0; i < unique_codes_alloc; i++) {
- if (unique_codes[i].kind == MP_CODE_UNUSED) {
- unique_codes[i].kind = MP_CODE_RESERVED;
- return i;
- }
- }
- // no existing slot
- // return next available id, memory will be allocated later
- return unique_codes_total++;
}
-STATIC void mp_emit_glue_alloc_unique_codes(void) {
- if (unique_codes_total > unique_codes_alloc) {
- DEBUG_printf("allocate more unique codes: " UINT_FMT " -> %u\n", unique_codes_alloc, unique_codes_total);
- // increase size of unique_codes table (all new entries are already reserved)
- unique_codes = m_renew(mp_code_t, unique_codes, unique_codes_alloc, unique_codes_total);
- for (uint i = unique_codes_alloc; i < unique_codes_total; i++) {
- unique_codes[i].kind = MP_CODE_RESERVED;
- }
- unique_codes_alloc = unique_codes_total;
- }
+mp_raw_code_t *mp_emit_glue_new_raw_code(void) {
+ mp_raw_code_t *rc = m_new0(mp_raw_code_t, 1);
+ rc->kind = MP_CODE_RESERVED;
+ return rc;
}
-void mp_emit_glue_assign_byte_code(uint unique_code_id, byte *code, uint len, int n_args, int n_locals, uint scope_flags, qstr *arg_names) {
- mp_emit_glue_alloc_unique_codes();
-
- assert(unique_code_id < unique_codes_alloc && unique_codes[unique_code_id].kind == MP_CODE_RESERVED);
- unique_codes[unique_code_id].kind = MP_CODE_BYTE;
- unique_codes[unique_code_id].scope_flags = scope_flags;
- unique_codes[unique_code_id].n_args = n_args;
- unique_codes[unique_code_id].u_byte.code = code;
- unique_codes[unique_code_id].u_byte.len = len;
- unique_codes[unique_code_id].arg_names = arg_names;
-
- //printf("byte code: %d bytes\n", len);
+void mp_emit_glue_assign_byte_code(mp_raw_code_t *rc, byte *code, uint len, int n_args, int n_locals, uint scope_flags, qstr *arg_names) {
+ rc->kind = MP_CODE_BYTE;
+ rc->scope_flags = scope_flags;
+ rc->n_args = n_args;
+ rc->u_byte.code = code;
+ rc->u_byte.len = len;
+ rc->arg_names = arg_names;
#ifdef DEBUG_PRINT
- DEBUG_printf("assign byte code: id=%d code=%p len=%u n_args=%d n_locals=%d\n", unique_code_id, code, len, n_args, n_locals);
+ DEBUG_printf("assign byte code: code=%p len=%u n_args=%d n_locals=%d\n", code, len, n_args, n_locals);
for (int i = 0; i < 128 && i < len; i++) {
if (i > 0 && i % 16 == 0) {
DEBUG_printf("\n");
@@ -131,19 +70,14 @@ void mp_emit_glue_assign_byte_code(uint unique_code_id, byte *code, uint len, in
#endif
}
-void mp_emit_glue_assign_native_code(uint unique_code_id, void *fun, uint len, int n_args) {
- mp_emit_glue_alloc_unique_codes();
-
- assert(unique_code_id < unique_codes_alloc && unique_codes[unique_code_id].kind == MP_CODE_RESERVED);
- unique_codes[unique_code_id].kind = MP_CODE_NATIVE;
- unique_codes[unique_code_id].scope_flags = 0;
- unique_codes[unique_code_id].n_args = n_args;
- unique_codes[unique_code_id].u_native.fun = fun;
-
- //printf("native code: %d bytes\n", len);
+void mp_emit_glue_assign_native_code(mp_raw_code_t *rc, void *fun, uint len, int n_args) {
+ rc->kind = MP_CODE_NATIVE;
+ rc->scope_flags = 0;
+ rc->n_args = n_args;
+ rc->u_native.fun = fun;
#ifdef DEBUG_PRINT
- DEBUG_printf("assign native code: id=%d fun=%p len=%u n_args=%d\n", unique_code_id, fun, len, n_args);
+ DEBUG_printf("assign native code: fun=%p len=%u n_args=%d\n", fun, len, n_args);
byte *fun_data = (byte*)(((machine_uint_t)fun) & (~1)); // need to clear lower bit in case it's thumb code
for (int i = 0; i < 128 && i < len; i++) {
if (i > 0 && i % 16 == 0) {
@@ -162,17 +96,14 @@ void mp_emit_glue_assign_native_code(uint unique_code_id, void *fun, uint len, i
#endif
}
-void mp_emit_glue_assign_inline_asm_code(uint unique_code_id, void *fun, uint len, int n_args) {
- mp_emit_glue_alloc_unique_codes();
-
- assert(unique_code_id < unique_codes_alloc && unique_codes[unique_code_id].kind == MP_CODE_RESERVED);
- unique_codes[unique_code_id].kind = MP_CODE_INLINE_ASM;
- unique_codes[unique_code_id].scope_flags = 0;
- unique_codes[unique_code_id].n_args = n_args;
- unique_codes[unique_code_id].u_inline_asm.fun = fun;
+void mp_emit_glue_assign_inline_asm_code(mp_raw_code_t *rc, void *fun, uint len, int n_args) {
+ rc->kind = MP_CODE_INLINE_ASM;
+ rc->scope_flags = 0;
+ rc->n_args = n_args;
+ rc->u_inline_asm.fun = fun;
#ifdef DEBUG_PRINT
- DEBUG_printf("assign inline asm code: id=%d fun=%p len=%u n_args=%d\n", unique_code_id, fun, len, n_args);
+ DEBUG_printf("assign inline asm code: fun=%p len=%u n_args=%d\n", fun, len, n_args);
byte *fun_data = (byte*)(((machine_uint_t)fun) & (~1)); // need to clear lower bit in case it's thumb code
for (int i = 0; i < 128 && i < len; i++) {
if (i > 0 && i % 16 == 0) {
@@ -191,12 +122,9 @@ void mp_emit_glue_assign_inline_asm_code(uint unique_code_id, void *fun, uint le
#endif
}
-mp_obj_t mp_make_function_from_id(uint unique_code_id, mp_obj_t def_args, mp_obj_t def_kw_args) {
- DEBUG_OP_printf("make_function_from_id %d\n", unique_code_id);
- if (unique_code_id >= unique_codes_total) {
- // illegal code id
- return mp_const_none;
- }
+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) {
+ DEBUG_OP_printf("make_function_from_raw_code %p\n", rc);
+ assert(rc != NULL);
// def_args must be MP_OBJ_NULL or a tuple
assert(def_args == MP_OBJ_NULL || MP_OBJ_IS_TYPE(def_args, &mp_type_tuple));
@@ -204,49 +132,36 @@ mp_obj_t mp_make_function_from_id(uint unique_code_id, mp_obj_t def_args, mp_obj
// TODO implement default kw args
assert(def_kw_args == MP_OBJ_NULL);
- // make the function, depending on the code kind
- mp_code_t *c = &unique_codes[unique_code_id];
+ // make the function, depending on the raw code kind
mp_obj_t fun;
- switch (c->kind) {
+ switch (rc->kind) {
case MP_CODE_BYTE:
- fun = mp_obj_new_fun_bc(c->scope_flags, c->arg_names, c->n_args, def_args, c->u_byte.code);
+ fun = mp_obj_new_fun_bc(rc->scope_flags, rc->arg_names, rc->n_args, def_args, rc->u_byte.code);
break;
case MP_CODE_NATIVE:
- fun = mp_make_function_n(c->n_args, c->u_native.fun);
+ fun = mp_make_function_n(rc->n_args, rc->u_native.fun);
break;
case MP_CODE_INLINE_ASM:
- fun = mp_obj_new_fun_asm(c->n_args, c->u_inline_asm.fun);
+ fun = mp_obj_new_fun_asm(rc->n_args, rc->u_inline_asm.fun);
break;
default:
- // code id was never assigned (this should not happen)
+ // raw code was never set (this should not happen)
assert(0);
return mp_const_none;
}
// check for generator functions and if so wrap in generator object
- if ((c->scope_flags & MP_SCOPE_FLAG_GENERATOR) != 0) {
+ if ((rc->scope_flags & MP_SCOPE_FLAG_GENERATOR) != 0) {
fun = mp_obj_new_gen_wrap(fun);
}
return fun;
}
-mp_obj_t mp_make_function_from_id_and_free(uint unique_code_id, mp_obj_t def_args, mp_obj_t def_kw_args) {
- mp_obj_t f = mp_make_function_from_id(unique_code_id, def_args, def_kw_args);
-
- // in some cases we can free the unique_code slot
- // any dynamically allocated memory is now owned by the fun object
- mp_code_t *c = &unique_codes[unique_code_id];
- memset(c, 0, sizeof *c); // make sure all pointers are zeroed
- c->kind = MP_CODE_UNUSED;
-
- return f;
-}
-
-mp_obj_t mp_make_closure_from_id(uint unique_code_id, mp_obj_t closure_tuple, mp_obj_t def_args, mp_obj_t def_kw_args) {
- DEBUG_OP_printf("make_closure_from_id %d\n", unique_code_id);
+mp_obj_t mp_make_closure_from_raw_code(mp_raw_code_t *rc, mp_obj_t closure_tuple, mp_obj_t def_args, mp_obj_t def_kw_args) {
+ DEBUG_OP_printf("make_closure_from_raw_code %p\n", rc);
// make function object
- mp_obj_t ffun = mp_make_function_from_id(unique_code_id, def_args, def_kw_args);
+ mp_obj_t ffun = mp_make_function_from_raw_code(rc, def_args, def_kw_args);
// wrap function in closure object
return mp_obj_new_closure(ffun, closure_tuple);
}