summaryrefslogtreecommitdiffstatshomepage
path: root/py/emitglue.c
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2014-08-24 16:28:17 +0100
committerDamien George <damien.p.george@gmail.com>2014-08-24 16:28:17 +0100
commit3c658a4e755a75e495303957208486e583ddb270 (patch)
tree6418fea9bf3dcf4aed2145db94fda4c0de1d0321 /py/emitglue.c
parent25fc41dd316c38df3e2a6cfe4b53322d76dc92fc (diff)
downloadmicropython-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.c27
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) {