Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
TASTE
uPython-mirror
Commits
8dcc0c79
Commit
8dcc0c79
authored
Mar 27, 2014
by
Damien George
Browse files
py: Calculate maximum exception stack size in compiler.
parent
945a01c4
Changes
5
Hide whitespace changes
Inline
Side-by-side
py/compile.c
View file @
8dcc0c79
...
...
@@ -144,11 +144,7 @@ mp_parse_node_t fold_constants(mp_parse_node_t pn) {
}
else
if
(
MP_PARSE_NODE_IS_TOKEN_KIND
(
pns
->
nodes
[
1
],
MP_TOKEN_OP_PERCENT
))
{
pn
=
mp_parse_node_new_leaf
(
MP_PARSE_NODE_SMALL_INT
,
python_modulo
(
arg0
,
arg1
));
}
else
if
(
MP_PARSE_NODE_IS_TOKEN_KIND
(
pns
->
nodes
[
1
],
MP_TOKEN_OP_DBL_SLASH
))
{
//pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT,
// floor((mp_float_t)arg0 / arg1));
pn
=
mp_parse_node_new_leaf
(
MP_PARSE_NODE_SMALL_INT
,
python_floor_divide
(
arg0
,
arg1
));
pn
=
mp_parse_node_new_leaf
(
MP_PARSE_NODE_SMALL_INT
,
python_floor_divide
(
arg0
,
arg1
));
}
else
{
// shouldn't happen
assert
(
0
);
...
...
@@ -198,12 +194,24 @@ mp_parse_node_t fold_constants(mp_parse_node_t pn) {
}
STATIC
void
compile_trailer_paren_helper
(
compiler_t
*
comp
,
mp_parse_node_t
pn_arglist
,
bool
is_method_call
,
int
n_positional_extra
);
void
compile_node
(
compiler_t
*
comp
,
mp_parse_node_t
pn
);
STATIC
void
compile_node
(
compiler_t
*
comp
,
mp_parse_node_t
pn
);
STATIC
int
comp_next_label
(
compiler_t
*
comp
)
{
return
comp
->
next_label
++
;
}
STATIC
void
compile_increase_except_level
(
compiler_t
*
comp
)
{
comp
->
cur_except_level
+=
1
;
if
(
comp
->
cur_except_level
>
comp
->
scope_cur
->
exc_stack_size
)
{
comp
->
scope_cur
->
exc_stack_size
=
comp
->
cur_except_level
;
}
}
STATIC
void
compile_decrease_except_level
(
compiler_t
*
comp
)
{
assert
(
comp
->
cur_except_level
>
0
);
comp
->
cur_except_level
-=
1
;
}
STATIC
scope_t
*
scope_new_and_link
(
compiler_t
*
comp
,
scope_kind_t
kind
,
mp_parse_node_t
pn
,
uint
emit_options
)
{
scope_t
*
scope
=
scope_new
(
kind
,
pn
,
comp
->
source_file
,
rt_get_unique_code_id
(),
emit_options
);
scope
->
parent
=
comp
->
scope_cur
;
...
...
@@ -1635,7 +1643,7 @@ void compile_try_except(compiler_t *comp, mp_parse_node_t pn_body, int n_except,
int
success_label
=
comp_next_label
(
comp
);
EMIT_ARG
(
setup_except
,
l1
);
comp
->
cur
_except_level
+=
1
;
comp
ile_increase
_except_level
(
comp
)
;
compile_node
(
comp
,
pn_body
);
// body
EMIT
(
pop_block
);
...
...
@@ -1687,7 +1695,7 @@ void compile_try_except(compiler_t *comp, mp_parse_node_t pn_body, int n_except,
if
(
qstr_exception_local
!=
0
)
{
l3
=
comp_next_label
(
comp
);
EMIT_ARG
(
setup_finally
,
l3
);
comp
->
cur
_except_level
+=
1
;
comp
ile_increase
_except_level
(
comp
)
;
}
compile_node
(
comp
,
pns_except
->
nodes
[
1
]);
if
(
qstr_exception_local
!=
0
)
{
...
...
@@ -1701,14 +1709,14 @@ void compile_try_except(compiler_t *comp, mp_parse_node_t pn_body, int n_except,
EMIT_ARG
(
store_id
,
qstr_exception_local
);
EMIT_ARG
(
delete_id
,
qstr_exception_local
);
comp
->
cur
_except_level
-=
1
;
comp
ile_decrease
_except_level
(
comp
)
;
EMIT
(
end_finally
);
}
EMIT_ARG
(
jump
,
l2
);
EMIT_ARG
(
label_assign
,
end_finally_label
);
}
comp
->
cur
_except_level
-=
1
;
comp
ile_decrease
_except_level
(
comp
)
;
EMIT
(
end_finally
);
EMIT_ARG
(
label_assign
,
success_label
);
...
...
@@ -1723,7 +1731,7 @@ void compile_try_finally(compiler_t *comp, mp_parse_node_t pn_body, int n_except
int
l_finally_block
=
comp_next_label
(
comp
);
EMIT_ARG
(
setup_finally
,
l_finally_block
);
comp
->
cur
_except_level
+=
1
;
comp
ile_increase
_except_level
(
comp
)
;
if
(
n_except
==
0
)
{
assert
(
MP_PARSE_NODE_IS_NULL
(
pn_else
));
...
...
@@ -1736,7 +1744,7 @@ void compile_try_finally(compiler_t *comp, mp_parse_node_t pn_body, int n_except
EMIT_ARG
(
label_assign
,
l_finally_block
);
compile_node
(
comp
,
pn_finally
);
comp
->
cur
_except_level
-=
1
;
comp
ile_decrease
_except_level
(
comp
)
;
EMIT
(
end_finally
);
EMIT_ARG
(
set_stack_size
,
stack_size
);
...
...
@@ -2799,7 +2807,10 @@ void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
EMIT_ARG
(
start_pass
,
pass
,
scope
);
if
(
comp
->
pass
==
PASS_1
)
{
// reset maximum stack sizes in scope
// they will be computed in this first pass
scope
->
stack_size
=
0
;
scope
->
exc_stack_size
=
0
;
}
#if MICROPY_EMIT_CPYTHON
...
...
@@ -2939,6 +2950,9 @@ void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
}
EMIT
(
end_pass
);
// make sure we match all the exception levels
assert
(
comp
->
cur_except_level
==
0
);
}
void
compile_scope_inline_asm
(
compiler_t
*
comp
,
scope_t
*
scope
,
pass_kind_t
pass
)
{
...
...
py/emitbc.c
View file @
8dcc0c79
...
...
@@ -224,7 +224,14 @@ STATIC void emit_bc_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope) {
emit_write_code_info_qstr
(
emit
,
scope
->
source_file
);
emit_write_code_info_qstr
(
emit
,
scope
->
simple_name
);
// prelude for initialising closed over variables
// bytecode prelude: exception stack size; 16 bit uint for now
{
byte
*
c
=
emit_get_cur_to_write_byte_code
(
emit
,
2
);
c
[
0
]
=
scope
->
exc_stack_size
&
0xff
;
c
[
1
]
=
(
scope
->
exc_stack_size
>>
8
)
&
0xff
;
}
// bytecode prelude: initialise closed over variables
int
num_cell
=
0
;
for
(
int
i
=
0
;
i
<
scope
->
id_info_len
;
i
++
)
{
id_info_t
*
id
=
&
scope
->
id_info
[
i
];
...
...
py/objgenerator.c
View file @
8dcc0c79
...
...
@@ -211,8 +211,22 @@ const mp_obj_type_t gen_instance_type = {
};
mp_obj_t
mp_obj_new_gen_instance
(
const
byte
*
bytecode
,
uint
n_state
,
int
n_args
,
const
mp_obj_t
*
args
)
{
// TODO: 4 is hardcoded number from vm.c, calc exc stack size instead.
mp_obj_gen_instance_t
*
o
=
m_new_obj_var
(
mp_obj_gen_instance_t
,
byte
,
n_state
*
sizeof
(
mp_obj_t
)
+
4
*
sizeof
(
mp_exc_stack
));
// get code info size, and skip the line number table
machine_uint_t
code_info_size
=
bytecode
[
0
]
|
(
bytecode
[
1
]
<<
8
)
|
(
bytecode
[
2
]
<<
16
)
|
(
bytecode
[
3
]
<<
24
);
bytecode
+=
code_info_size
;
// bytecode prelude: get exception stack size
machine_uint_t
n_exc_stack
=
bytecode
[
0
]
|
(
bytecode
[
1
]
<<
8
);
bytecode
+=
2
;
// bytecode prelude: initialise closed over variables
// TODO
// for now we just make sure there are no cells variables
// need to work out how to implement closed over variables in generators
assert
(
bytecode
[
0
]
==
0
);
bytecode
+=
1
;
mp_obj_gen_instance_t
*
o
=
m_new_obj_var
(
mp_obj_gen_instance_t
,
byte
,
n_state
*
sizeof
(
mp_obj_t
)
+
n_exc_stack
*
sizeof
(
mp_exc_stack
));
o
->
base
.
type
=
&
gen_instance_type
;
o
->
code_info
=
bytecode
;
o
->
ip
=
bytecode
;
...
...
@@ -225,16 +239,5 @@ mp_obj_t mp_obj_new_gen_instance(const byte *bytecode, uint n_state, int n_args,
o
->
state
[
n_state
-
1
-
i
]
=
args
[
i
];
}
// TODO
// prelude for making cells (closed over variables)
// for now we just make sure there are no cells variables
// need to work out how to implement closed over variables in generators
// get code info size
machine_uint_t
code_info_size
=
bytecode
[
0
]
|
(
bytecode
[
1
]
<<
8
)
|
(
bytecode
[
2
]
<<
16
)
|
(
bytecode
[
3
]
<<
24
);
o
->
ip
+=
code_info_size
;
assert
(
o
->
ip
[
0
]
==
0
);
o
->
ip
+=
1
;
return
o
;
}
py/scope.h
View file @
8dcc0c79
...
...
@@ -36,7 +36,8 @@ typedef struct _scope_t {
int num_dict_params;
*/
int
num_locals
;
int
stack_size
;
int
stack_size
;
// maximum size of the locals stack
int
exc_stack_size
;
// maximum size of the exception stack
uint
unique_code_id
;
uint
emit_options
;
}
scope_t
;
...
...
py/vm.c
View file @
8dcc0c79
...
...
@@ -45,6 +45,16 @@ typedef enum {
#define SET_TOP(val) *sp = (val)
mp_vm_return_kind_t
mp_execute_byte_code
(
const
byte
*
code
,
const
mp_obj_t
*
args
,
uint
n_args
,
const
mp_obj_t
*
args2
,
uint
n_args2
,
uint
n_state
,
mp_obj_t
*
ret
)
{
const
byte
*
ip
=
code
;
// get code info size, and skip line number table
machine_uint_t
code_info_size
=
ip
[
0
]
|
(
ip
[
1
]
<<
8
)
|
(
ip
[
2
]
<<
16
)
|
(
ip
[
3
]
<<
24
);
ip
+=
code_info_size
;
// bytecode prelude: exception stack size; 16 bit uint for now
machine_uint_t
n_exc_stack
=
ip
[
0
]
|
(
ip
[
1
]
<<
8
);
ip
+=
2
;
// allocate state for locals and stack
mp_obj_t
temp_state
[
10
];
mp_obj_t
*
state
=
&
temp_state
[
0
];
...
...
@@ -53,6 +63,14 @@ mp_vm_return_kind_t mp_execute_byte_code(const byte *code, const mp_obj_t *args,
}
mp_obj_t
*
sp
=
&
state
[
0
]
-
1
;
// allocate state for exceptions
mp_exc_stack
exc_state
[
4
];
mp_exc_stack
*
exc_stack
=
&
exc_state
[
0
];
if
(
n_exc_stack
>
4
)
{
exc_stack
=
m_new
(
mp_exc_stack
,
n_exc_stack
);
}
mp_exc_stack
*
exc_sp
=
&
exc_stack
[
0
]
-
1
;
// init args
for
(
uint
i
=
0
;
i
<
n_args
;
i
++
)
{
state
[
n_state
-
1
-
i
]
=
args
[
i
];
...
...
@@ -61,26 +79,16 @@ mp_vm_return_kind_t mp_execute_byte_code(const byte *code, const mp_obj_t *args,
state
[
n_state
-
1
-
n_args
-
i
]
=
args2
[
i
];
}
const
byte
*
ip
=
code
;
// get code info size
machine_uint_t
code_info_size
=
ip
[
0
]
|
(
ip
[
1
]
<<
8
)
|
(
ip
[
2
]
<<
16
)
|
(
ip
[
3
]
<<
24
);
ip
+=
code_info_size
;
// execute prelude to make any cells (closed over variables)
{
for
(
uint
n_local
=
*
ip
++
;
n_local
>
0
;
n_local
--
)
{
uint
local_num
=
*
ip
++
;
if
(
local_num
<
n_args
+
n_args2
)
{
state
[
n_state
-
1
-
local_num
]
=
mp_obj_new_cell
(
state
[
n_state
-
1
-
local_num
]);
}
else
{
state
[
n_state
-
1
-
local_num
]
=
mp_obj_new_cell
(
MP_OBJ_NULL
);
}
// bytecode prelude: initialise closed over variables
for
(
uint
n_local
=
*
ip
++
;
n_local
>
0
;
n_local
--
)
{
uint
local_num
=
*
ip
++
;
if
(
local_num
<
n_args
+
n_args2
)
{
state
[
n_state
-
1
-
local_num
]
=
mp_obj_new_cell
(
state
[
n_state
-
1
-
local_num
]);
}
else
{
state
[
n_state
-
1
-
local_num
]
=
mp_obj_new_cell
(
MP_OBJ_NULL
);
}
}
mp_exc_stack
exc_stack
[
4
];
mp_exc_stack
*
exc_sp
=
&
exc_stack
[
0
]
-
1
;
// execute the byte code
mp_vm_return_kind_t
vm_return_kind
=
mp_execute_byte_code_2
(
code
,
&
ip
,
&
state
[
n_state
-
1
],
&
sp
,
exc_stack
,
&
exc_sp
,
MP_OBJ_NULL
);
...
...
Write
Preview
Supports
Markdown
0%
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!
Cancel
Please
register
or
sign in
to comment