summaryrefslogtreecommitdiffstatshomepage
path: root/py
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2018-06-29 16:32:58 +1000
committerDamien George <damien.p.george@gmail.com>2018-07-02 15:30:57 +1000
commitb488a4a8480533a6a3c9468c2f8bd359c94d4d02 (patch)
tree709b6ca9495c832856f54e03bc4db3055c861cb0 /py
parent8f86fbfd6c34a4d03f2bd62e9dc1ff59c236b037 (diff)
downloadmicropython-b488a4a8480533a6a3c9468c2f8bd359c94d4d02.tar.gz
micropython-b488a4a8480533a6a3c9468c2f8bd359c94d4d02.zip
py/objgenerator: Eliminate need for mp_obj_gen_wrap wrapper instances.
For generating functions there is no need to wrap the bytecode function in a generator wrapper instance. Instead the type of the bytecode function can be changed to mp_type_gen_wrap. This reduces code size and saves a block of GC heap RAM for each generator.
Diffstat (limited to 'py')
-rw-r--r--py/emitglue.c9
-rw-r--r--py/obj.h1
-rw-r--r--py/objgenerator.c17
3 files changed, 7 insertions, 20 deletions
diff --git a/py/emitglue.c b/py/emitglue.c
index 74bf8ddca2..a7fff0e0eb 100644
--- a/py/emitglue.c
+++ b/py/emitglue.c
@@ -146,14 +146,13 @@ mp_obj_t mp_make_function_from_raw_code(const mp_raw_code_t *rc, mp_obj_t def_ar
// rc->kind should always be set and BYTECODE is the only remaining case
assert(rc->kind == MP_CODE_BYTECODE);
fun = mp_obj_new_fun_bc(def_args, def_kw_args, rc->data.u_byte.bytecode, rc->data.u_byte.const_table);
+ // check for generator functions and if so change the type of the object
+ if ((rc->scope_flags & MP_SCOPE_FLAG_GENERATOR) != 0) {
+ ((mp_obj_base_t*)MP_OBJ_TO_PTR(fun))->type = &mp_type_gen_wrap;
+ }
break;
}
- // check for generator functions and if so wrap in generator object
- if ((rc->scope_flags & MP_SCOPE_FLAG_GENERATOR) != 0) {
- fun = mp_obj_new_gen_wrap(fun);
- }
-
return fun;
}
diff --git a/py/obj.h b/py/obj.h
index a64cd0f694..54bc980055 100644
--- a/py/obj.h
+++ b/py/obj.h
@@ -547,6 +547,7 @@ extern const mp_obj_type_t mp_type_slice;
extern const mp_obj_type_t mp_type_zip;
extern const mp_obj_type_t mp_type_array;
extern const mp_obj_type_t mp_type_super;
+extern const mp_obj_type_t mp_type_gen_wrap;
extern const mp_obj_type_t mp_type_gen_instance;
extern const mp_obj_type_t mp_type_fun_builtin_0;
extern const mp_obj_type_t mp_type_fun_builtin_1;
diff --git a/py/objgenerator.c b/py/objgenerator.c
index a2ad490d63..8b898c9374 100644
--- a/py/objgenerator.c
+++ b/py/objgenerator.c
@@ -37,11 +37,6 @@
/******************************************************************************/
/* generator wrapper */
-typedef struct _mp_obj_gen_wrap_t {
- mp_obj_base_t base;
- mp_obj_t *fun;
-} mp_obj_gen_wrap_t;
-
typedef struct _mp_obj_gen_instance_t {
mp_obj_base_t base;
mp_obj_dict_t *globals;
@@ -49,9 +44,8 @@ typedef struct _mp_obj_gen_instance_t {
} mp_obj_gen_instance_t;
STATIC mp_obj_t gen_wrap_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
- mp_obj_gen_wrap_t *self = MP_OBJ_TO_PTR(self_in);
- mp_obj_fun_bc_t *self_fun = (mp_obj_fun_bc_t*)self->fun;
- assert(self_fun->base.type == &mp_type_fun_bc);
+ // A generating function is just a bytecode function with type mp_type_gen_wrap
+ mp_obj_fun_bc_t *self_fun = MP_OBJ_TO_PTR(self_in);
// bytecode prelude: get state size and exception stack size
size_t n_state = mp_decode_uint_value(self_fun->bytecode);
@@ -76,13 +70,6 @@ const mp_obj_type_t mp_type_gen_wrap = {
.unary_op = mp_generic_unary_op,
};
-mp_obj_t mp_obj_new_gen_wrap(mp_obj_t fun) {
- mp_obj_gen_wrap_t *o = m_new_obj(mp_obj_gen_wrap_t);
- o->base.type = &mp_type_gen_wrap;
- o->fun = MP_OBJ_TO_PTR(fun);
- return MP_OBJ_FROM_PTR(o);
-}
-
/******************************************************************************/
/* generator instance */