diff options
author | Damien George <damien.p.george@gmail.com> | 2014-08-24 16:28:17 +0100 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2014-08-24 16:28:17 +0100 |
commit | 3c658a4e755a75e495303957208486e583ddb270 (patch) | |
tree | 6418fea9bf3dcf4aed2145db94fda4c0de1d0321 /py/emitglue.c | |
parent | 25fc41dd316c38df3e2a6cfe4b53322d76dc92fc (diff) | |
download | micropython-3c658a4e755a75e495303957208486e583ddb270.tar.gz micropython-3c658a4e755a75e495303957208486e583ddb270.zip |
py: Fix bug where GC collected native/viper/asm function data.
Because (for Thumb) a function pointer has the LSB set, pointers to
dynamic functions in RAM (eg native, viper or asm functions) were not
being traced by the GC. This patch is a comprehensive fix for this.
Addresses issue #820.
Diffstat (limited to 'py/emitglue.c')
-rw-r--r-- | py/emitglue.c | 27 |
1 files changed, 13 insertions, 14 deletions
diff --git a/py/emitglue.c b/py/emitglue.c index 5be54a6fc5..5916586aea 100644 --- a/py/emitglue.c +++ b/py/emitglue.c @@ -55,7 +55,7 @@ mp_raw_code_t *mp_emit_glue_new_raw_code(void) { return rc; } -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) { +void mp_emit_glue_assign_bytecode(mp_raw_code_t *rc, byte *code, mp_uint_t len, mp_uint_t n_pos_args, mp_uint_t n_kwonly_args, qstr *arg_names, mp_uint_t scope_flags) { rc->kind = MP_CODE_BYTECODE; rc->scope_flags = scope_flags; rc->n_pos_args = n_pos_args; @@ -65,7 +65,7 @@ void mp_emit_glue_assign_bytecode(mp_raw_code_t *rc, byte *code, uint len, uint rc->u_byte.len = len; #ifdef DEBUG_PRINT - DEBUG_printf("assign byte code: code=%p len=%u n_pos_args=%d n_kwonly_args=%d flags=%x\n", code, len, n_pos_args, n_kwonly_args, scope_flags); + DEBUG_printf("assign byte code: code=%p len=" UINT_FMT " n_pos_args=" UINT_FMT " n_kwonly_args=" UINT_FMT " flags=%x\n", code, len, n_pos_args, n_kwonly_args, (uint)scope_flags); DEBUG_printf(" arg names:"); for (int i = 0; i < n_pos_args + n_kwonly_args; i++) { DEBUG_printf(" %s", qstr_str(arg_names[i])); @@ -74,7 +74,7 @@ void mp_emit_glue_assign_bytecode(mp_raw_code_t *rc, byte *code, uint len, uint #endif #if MICROPY_DEBUG_PRINTERS if (mp_verbose_flag > 0) { - for (int i = 0; i < 128 && i < len; i++) { + for (mp_uint_t i = 0; i < len; i++) { if (i > 0 && i % 16 == 0) { printf("\n"); } @@ -87,22 +87,21 @@ void mp_emit_glue_assign_bytecode(mp_raw_code_t *rc, byte *code, uint len, uint } #if MICROPY_EMIT_NATIVE || MICROPY_EMIT_INLINE_THUMB -void mp_emit_glue_assign_native(mp_raw_code_t *rc, mp_raw_code_kind_t kind, void *fun, uint len, int n_args, mp_uint_t type_sig) { +void mp_emit_glue_assign_native(mp_raw_code_t *rc, mp_raw_code_kind_t kind, void *fun_data, mp_uint_t fun_len, mp_uint_t n_args, mp_uint_t type_sig) { assert(kind == MP_CODE_NATIVE_PY || kind == MP_CODE_NATIVE_VIPER || kind == MP_CODE_NATIVE_ASM); rc->kind = kind; rc->scope_flags = 0; rc->n_pos_args = n_args; - rc->u_native.fun = fun; + rc->u_native.fun_data = fun_data; rc->u_native.type_sig = type_sig; #ifdef DEBUG_PRINT - DEBUG_printf("assign native: kind=%d fun=%p len=%u n_args=%d\n", kind, fun, len, n_args); - byte *fun_data = (byte*)(((mp_uint_t)fun) & (~1)); // need to clear lower bit in case it's thumb code - for (int i = 0; i < 128 && i < len; i++) { + DEBUG_printf("assign native: kind=%d fun=%p len=" UINT_FMT " n_args=" UINT_FMT "\n", kind, fun_data, fun_len, n_args); + for (mp_uint_t i = 0; i < fun_len; i++) { if (i > 0 && i % 16 == 0) { DEBUG_printf("\n"); } - DEBUG_printf(" %02x", fun_data[i]); + DEBUG_printf(" %02x", ((byte*)fun_data)[i]); } DEBUG_printf("\n"); @@ -133,15 +132,15 @@ mp_obj_t mp_make_function_from_raw_code(mp_raw_code_t *rc, mp_obj_t def_args, mp break; #if MICROPY_EMIT_NATIVE case MP_CODE_NATIVE_PY: - fun = mp_make_function_n(rc->n_pos_args, rc->u_native.fun); + fun = mp_obj_new_fun_native(rc->n_pos_args, rc->u_native.fun_data); break; case MP_CODE_NATIVE_VIPER: - fun = mp_obj_new_fun_viper(rc->n_pos_args, rc->u_native.fun, rc->u_native.type_sig); + fun = mp_obj_new_fun_viper(rc->n_pos_args, rc->u_native.fun_data, rc->u_native.type_sig); break; #endif #if MICROPY_EMIT_INLINE_THUMB case MP_CODE_NATIVE_ASM: - fun = mp_obj_new_fun_asm(rc->n_pos_args, rc->u_native.fun); + fun = mp_obj_new_fun_asm(rc->n_pos_args, rc->u_native.fun_data); break; #endif default: @@ -158,8 +157,8 @@ mp_obj_t mp_make_function_from_raw_code(mp_raw_code_t *rc, mp_obj_t def_args, mp return fun; } -mp_obj_t mp_make_closure_from_raw_code(mp_raw_code_t *rc, uint n_closed_over, const mp_obj_t *args) { - DEBUG_OP_printf("make_closure_from_raw_code %p %u %p\n", rc, n_closed_over, args); +mp_obj_t mp_make_closure_from_raw_code(mp_raw_code_t *rc, mp_uint_t n_closed_over, const mp_obj_t *args) { + DEBUG_OP_printf("make_closure_from_raw_code %p " UINT_FMT " %p\n", rc, n_closed_over, args); // make function object mp_obj_t ffun; if (n_closed_over & 0x100) { |