Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
M
micropython
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
This is an archived project. Repository and other project resources are read-only.
Show more breadcrumbs
card10
micropython
Commits
2039757b
Commit
2039757b
authored
10 years ago
by
Paul Sokolovsky
Browse files
Options
Downloads
Patches
Plain Diff
vm: Initial support for calling bytecode functions w/o C stack ("stackless").
parent
f88eec0d
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
py/bc.c
+3
-0
3 additions, 0 deletions
py/bc.c
py/bc.h
+4
-0
4 additions, 0 deletions
py/bc.h
py/mpconfig.h
+5
-0
5 additions, 0 deletions
py/mpconfig.h
py/objfun.c
+32
-0
32 additions, 0 deletions
py/objfun.c
py/vm.c
+41
-2
41 additions, 2 deletions
py/vm.c
with
85 additions
and
2 deletions
py/bc.c
+
3
−
0
View file @
2039757b
...
...
@@ -86,6 +86,9 @@ void mp_setup_code_state(mp_code_state *code_state, mp_obj_t self_in, mp_uint_t
mp_obj_fun_bc_t
*
self
=
self_in
;
mp_uint_t
n_state
=
code_state
->
n_state
;
#if MICROPY_STACKLESS
code_state
->
prev
=
NULL
;
#endif
code_state
->
code_info
=
self
->
bytecode
;
code_state
->
sp
=
&
code_state
->
state
[
0
]
-
1
;
code_state
->
exc_sp
=
(
mp_exc_stack_t
*
)(
code_state
->
state
+
n_state
)
-
1
;
...
...
This diff is collapsed.
Click to expand it.
py/bc.h
+
4
−
0
View file @
2039757b
...
...
@@ -46,6 +46,9 @@ typedef struct _mp_code_state {
// bit 0 is saved currently_in_except_block value
mp_exc_stack_t
*
exc_sp
;
mp_obj_dict_t
*
old_globals
;
#if MICROPY_STACKLESS
struct
_mp_code_state
*
prev
;
#endif
mp_uint_t
n_state
;
// Variable-length
mp_obj_t
state
[
0
];
...
...
@@ -56,6 +59,7 @@ typedef struct _mp_code_state {
mp_uint_t
mp_decode_uint
(
const
byte
**
ptr
);
mp_vm_return_kind_t
mp_execute_bytecode
(
mp_code_state
*
code_state
,
volatile
mp_obj_t
inject_exc
);
mp_code_state
*
mp_obj_fun_bc_prepare_codestate
(
mp_obj_t
func
,
mp_uint_t
n_args
,
mp_uint_t
n_kw
,
const
mp_obj_t
*
args
);
void
mp_setup_code_state
(
mp_code_state
*
code_state
,
mp_obj_t
self_in
,
mp_uint_t
n_args
,
mp_uint_t
n_kw
,
const
mp_obj_t
*
args
);
void
mp_bytecode_print
(
const
void
*
descr
,
mp_uint_t
n_total_args
,
const
byte
*
code
,
mp_uint_t
len
);
void
mp_bytecode_print2
(
const
byte
*
code
,
mp_uint_t
len
);
...
...
This diff is collapsed.
Click to expand it.
py/mpconfig.h
+
5
−
0
View file @
2039757b
...
...
@@ -125,6 +125,11 @@
#define MICROPY_QSTR_BYTES_IN_LEN (1)
#endif
// Avoid using C stack when making Python function calls.
#ifndef MICROPY_STACKLESS
#define MICROPY_STACKLESS (0)
#endif
/*****************************************************************************/
/* Micro Python emitters */
...
...
This diff is collapsed.
Click to expand it.
py/objfun.c
+
32
−
0
View file @
2039757b
...
...
@@ -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
();
...
...
This diff is collapsed.
Click to expand it.
py/vm.c
+
41
−
2
View file @
2039757b
...
...
@@ -129,9 +129,12 @@ mp_vm_return_kind_t mp_execute_bytecode(mp_code_state *code_state, volatile mp_o
// loop and the exception handler, leading to very obscure bugs.
#define RAISE(o) do { nlr_pop(); nlr.ret_val = o; goto exception_handler; } while(0)
#if MICROPY_STACKLESS
run_code_state:
;
#endif
// Pointers which are constant for particular invocation of mp_execute_bytecode()
mp_obj_t
*
const
fastn
=
&
code_state
->
state
[
code_state
->
n_state
-
1
];
mp_exc_stack_t
*
const
exc_stack
=
(
mp_exc_stack_t
*
)(
code_state
->
state
+
code_state
->
n_state
);
mp_obj_t
*/
*
const
*/
fastn
=
&
code_state
->
state
[
code_state
->
n_state
-
1
];
mp_exc_stack_t
*/
*
const
*/
exc_stack
=
(
mp_exc_stack_t
*
)(
code_state
->
state
+
code_state
->
n_state
);
// variables that are visible to the exception handler (declared volatile)
volatile
bool
currently_in_except_block
=
MP_TAGPTR_TAG0
(
code_state
->
exc_sp
);
// 0 or 1, to detect nested exceptions
...
...
@@ -865,6 +868,18 @@ unwind_jump:;
// unum & 0xff == n_positional
// (unum >> 8) & 0xff == n_keyword
sp
-=
(
unum
&
0xff
)
+
((
unum
>>
7
)
&
0x1fe
);
#if MICROPY_STACKLESS
if
(
mp_obj_get_type
(
*
sp
)
==
&
mp_type_fun_bc
)
{
code_state
->
ip
=
ip
;
code_state
->
sp
=
sp
;
code_state
->
exc_sp
=
MP_TAGPTR_MAKE
(
exc_sp
,
currently_in_except_block
);
mp_code_state
*
new_state
=
mp_obj_fun_bc_prepare_codestate
(
*
sp
,
unum
&
0xff
,
(
unum
>>
8
)
&
0xff
,
sp
+
1
);
new_state
->
prev
=
code_state
;
code_state
=
new_state
;
nlr_pop
();
goto
run_code_state
;
}
#endif
SET_TOP
(
mp_call_function_n_kw
(
*
sp
,
unum
&
0xff
,
(
unum
>>
8
)
&
0xff
,
sp
+
1
));
DISPATCH
();
}
...
...
@@ -925,6 +940,15 @@ unwind_return:
nlr_pop
();
code_state
->
sp
=
sp
;
assert
(
exc_sp
==
exc_stack
-
1
);
#if MICROPY_STACKLESS
if
(
code_state
->
prev
!=
NULL
)
{
mp_obj_t
res
=
*
sp
;
mp_globals_set
(
code_state
->
old_globals
);
code_state
=
code_state
->
prev
;
*
code_state
->
sp
=
res
;
goto
run_code_state
;
}
#endif
return
MP_VM_RETURN_NORMAL
;
ENTRY
(
MP_BC_RAISE_VARARGS
)
:
{
...
...
@@ -1122,6 +1146,9 @@ exception_handler:
goto
outer_dispatch_loop
;
// continue with dispatch loop
}
#if MICROPY_STACKLESS
unwind_loop:
#endif
// set file and line number that the exception occurred at
// TODO: don't set traceback for exceptions re-raised by END_FINALLY.
// But consider how to handle nested exceptions.
...
...
@@ -1185,6 +1212,18 @@ exception_handler:
PUSH
(
mp_obj_get_type
(
nlr
.
ret_val
));
code_state
->
sp
=
sp
;
#if MICROPY_STACKLESS
}
else
if
(
code_state
->
prev
!=
NULL
)
{
mp_globals_set
(
code_state
->
old_globals
);
code_state
=
code_state
->
prev
;
fastn
=
&
code_state
->
state
[
code_state
->
n_state
-
1
];
exc_stack
=
(
mp_exc_stack_t
*
)(
code_state
->
state
+
code_state
->
n_state
);
// variables that are visible to the exception handler (declared volatile)
currently_in_except_block
=
MP_TAGPTR_TAG0
(
code_state
->
exc_sp
);
// 0 or 1, to detect nested exceptions
exc_sp
=
MP_TAGPTR_PTR
(
code_state
->
exc_sp
);
// stack grows up, exc_sp points to top of stack
goto
unwind_loop
;
#endif
}
else
{
// propagate exception to higher level
// TODO what to do about ip and sp? they don't really make sense at this point
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment