summaryrefslogtreecommitdiffstatshomepage
path: root/py/objfun.c
diff options
context:
space:
mode:
authorPaul Sokolovsky <pfalcon@users.sourceforge.net>2015-03-28 01:14:44 +0200
committerPaul Sokolovsky <pfalcon@users.sourceforge.net>2015-04-03 00:03:07 +0300
commit2039757b854b656a41c9e041776ccd5dad8ec5fe (patch)
tree2450c1e129651c27cb5579bb26a288a841c70c70 /py/objfun.c
parentf88eec0de24277e8713ebdfe34e1e7b852a25731 (diff)
downloadmicropython-2039757b854b656a41c9e041776ccd5dad8ec5fe.tar.gz
micropython-2039757b854b656a41c9e041776ccd5dad8ec5fe.zip
vm: Initial support for calling bytecode functions w/o C stack ("stackless").
Diffstat (limited to 'py/objfun.c')
-rw-r--r--py/objfun.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/py/objfun.c b/py/objfun.c
index d8ea22f394..187bb5a59e 100644
--- a/py/objfun.c
+++ b/py/objfun.c
@@ -142,6 +142,38 @@ STATIC void dump_args(const mp_obj_t *a, mp_uint_t sz) {
// Set this to enable a simple stack overflow check.
#define VM_DETECT_STACK_OVERFLOW (0)
+mp_code_state *mp_obj_fun_bc_prepare_codestate(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
+ MP_STACK_CHECK();
+ mp_obj_fun_bc_t *self = self_in;
+
+ // skip code-info block
+ const byte *code_info = self->bytecode;
+ mp_uint_t code_info_size = mp_decode_uint(&code_info);
+ const byte *ip = self->bytecode + code_info_size;
+
+ // bytecode prelude: skip arg names
+ ip += (self->n_pos_args + self->n_kwonly_args) * sizeof(mp_obj_t);
+
+ // bytecode prelude: state size and exception stack size
+ mp_uint_t n_state = mp_decode_uint(&ip);
+ mp_uint_t n_exc_stack = mp_decode_uint(&ip);
+
+ // allocate state for locals and stack
+ mp_uint_t state_size = n_state * sizeof(mp_obj_t) + n_exc_stack * sizeof(mp_exc_stack_t);
+ mp_code_state *code_state;
+ code_state = m_new_obj_var(mp_code_state, byte, state_size);
+
+ code_state->n_state = n_state;
+ code_state->ip = ip;
+ mp_setup_code_state(code_state, self_in, n_args, n_kw, args);
+
+ // execute the byte code with the correct globals context
+ code_state->old_globals = mp_globals_get();
+ mp_globals_set(self->globals);
+
+ return code_state;
+}
+
STATIC mp_obj_t fun_bc_call(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
MP_STACK_CHECK();