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
6cdd3af6
Commit
6cdd3af6
authored
Oct 05, 2013
by
Damien
Browse files
Implement built-in decorators to select emit type.
parent
4b03e77d
Changes
9
Hide whitespace changes
Inline
Side-by-side
py/compile.c
View file @
6cdd3af6
...
@@ -27,6 +27,10 @@ typedef enum {
...
@@ -27,6 +27,10 @@ typedef enum {
#define EMIT(fun, arg...) (comp->emit_method_table->fun(comp->emit, ##arg))
#define EMIT(fun, arg...) (comp->emit_method_table->fun(comp->emit, ##arg))
#define EMIT_OPT_NONE (0)
#define EMIT_OPT_BYTE_CODE (1)
#define EMIT_OPT_NATIVE_PYTHON (2)
typedef
struct
_compiler_t
{
typedef
struct
_compiler_t
{
qstr
qstr___class__
;
qstr
qstr___class__
;
qstr
qstr___locals__
;
qstr
qstr___locals__
;
...
@@ -35,6 +39,8 @@ typedef struct _compiler_t {
...
@@ -35,6 +39,8 @@ typedef struct _compiler_t {
qstr
qstr___qualname__
;
qstr
qstr___qualname__
;
qstr
qstr___doc__
;
qstr
qstr___doc__
;
qstr
qstr_assertion_error
;
qstr
qstr_assertion_error
;
qstr
qstr_micropython
;
qstr
qstr_native
;
pass_kind_t
pass
;
pass_kind_t
pass
;
...
@@ -56,8 +62,8 @@ typedef struct _compiler_t {
...
@@ -56,8 +62,8 @@ typedef struct _compiler_t {
scope_t
*
scope_head
;
scope_t
*
scope_head
;
scope_t
*
scope_cur
;
scope_t
*
scope_cur
;
emit_t
*
emit
;
emit_t
*
emit
;
// current emitter
const
emit_method_table_t
*
emit_method_table
;
const
emit_method_table_t
*
emit_method_table
;
// current emit method table
}
compiler_t
;
}
compiler_t
;
py_parse_node_t
fold_constants
(
py_parse_node_t
pn
)
{
py_parse_node_t
fold_constants
(
py_parse_node_t
pn
)
{
...
@@ -165,8 +171,8 @@ static int comp_next_label(compiler_t *comp) {
...
@@ -165,8 +171,8 @@ static int comp_next_label(compiler_t *comp) {
return
comp
->
next_label
++
;
return
comp
->
next_label
++
;
}
}
static
scope_t
*
scope_new_and_link
(
compiler_t
*
comp
,
scope_kind_t
kind
,
py_parse_node_t
pn
)
{
static
scope_t
*
scope_new_and_link
(
compiler_t
*
comp
,
scope_kind_t
kind
,
py_parse_node_t
pn
,
uint
emit_options
)
{
scope_t
*
scope
=
scope_new
(
kind
,
pn
,
rt_get_new_unique_code_id
());
scope_t
*
scope
=
scope_new
(
kind
,
pn
,
rt_get_new_unique_code_id
()
,
emit_options
);
scope
->
parent
=
comp
->
scope_cur
;
scope
->
parent
=
comp
->
scope_cur
;
scope
->
next
=
NULL
;
scope
->
next
=
NULL
;
if
(
comp
->
scope_head
==
NULL
)
{
if
(
comp
->
scope_head
==
NULL
)
{
...
@@ -661,10 +667,10 @@ void compile_funcdef_param(compiler_t *comp, py_parse_node_t pn) {
...
@@ -661,10 +667,10 @@ void compile_funcdef_param(compiler_t *comp, py_parse_node_t pn) {
// leaves function object on stack
// leaves function object on stack
// returns function name
// returns function name
qstr
compile_funcdef_helper
(
compiler_t
*
comp
,
py_parse_node_struct_t
*
pns
)
{
qstr
compile_funcdef_helper
(
compiler_t
*
comp
,
py_parse_node_struct_t
*
pns
,
uint
emit_options
)
{
if
(
comp
->
pass
==
PASS_1
)
{
if
(
comp
->
pass
==
PASS_1
)
{
// create a new scope for this function
// create a new scope for this function
scope_t
*
s
=
scope_new_and_link
(
comp
,
SCOPE_FUNCTION
,
(
py_parse_node_t
)
pns
);
scope_t
*
s
=
scope_new_and_link
(
comp
,
SCOPE_FUNCTION
,
(
py_parse_node_t
)
pns
,
emit_options
);
// store the function scope so the compiling function can use it at each pass
// store the function scope so the compiling function can use it at each pass
pns
->
nodes
[
4
]
=
(
py_parse_node_t
)
s
;
pns
->
nodes
[
4
]
=
(
py_parse_node_t
)
s
;
}
}
...
@@ -705,10 +711,10 @@ qstr compile_funcdef_helper(compiler_t *comp, py_parse_node_struct_t *pns) {
...
@@ -705,10 +711,10 @@ qstr compile_funcdef_helper(compiler_t *comp, py_parse_node_struct_t *pns) {
// leaves class object on stack
// leaves class object on stack
// returns class name
// returns class name
qstr
compile_classdef_helper
(
compiler_t
*
comp
,
py_parse_node_struct_t
*
pns
)
{
qstr
compile_classdef_helper
(
compiler_t
*
comp
,
py_parse_node_struct_t
*
pns
,
uint
emit_options
)
{
if
(
comp
->
pass
==
PASS_1
)
{
if
(
comp
->
pass
==
PASS_1
)
{
// create a new scope for this class
// create a new scope for this class
scope_t
*
s
=
scope_new_and_link
(
comp
,
SCOPE_CLASS
,
(
py_parse_node_t
)
pns
);
scope_t
*
s
=
scope_new_and_link
(
comp
,
SCOPE_CLASS
,
(
py_parse_node_t
)
pns
,
emit_options
);
// store the class scope so the compiling function can use it at each pass
// store the class scope so the compiling function can use it at each pass
pns
->
nodes
[
3
]
=
(
py_parse_node_t
)
s
;
pns
->
nodes
[
3
]
=
(
py_parse_node_t
)
s
;
}
}
...
@@ -739,24 +745,65 @@ qstr compile_classdef_helper(compiler_t *comp, py_parse_node_struct_t *pns) {
...
@@ -739,24 +745,65 @@ qstr compile_classdef_helper(compiler_t *comp, py_parse_node_struct_t *pns) {
return
cscope
->
simple_name
;
return
cscope
->
simple_name
;
}
}
// returns true if it was a built-in decorator (even if the built-in had an error)
static
bool
compile_built_in_decorator
(
compiler_t
*
comp
,
int
name_len
,
py_parse_node_t
*
name_nodes
,
uint
*
emit_options
)
{
if
(
PY_PARSE_NODE_LEAF_ARG
(
name_nodes
[
0
])
!=
comp
->
qstr_micropython
)
{
return
false
;
}
if
(
name_len
!=
2
)
{
printf
(
"SyntaxError: invalid micropython decorator
\n
"
);
return
true
;
}
qstr
attr
=
PY_PARSE_NODE_LEAF_ARG
(
name_nodes
[
1
]);
if
(
attr
==
comp
->
qstr_native
)
{
*
emit_options
=
EMIT_OPT_NATIVE_PYTHON
;
}
else
{
printf
(
"SyntaxError: invalid micropython decorator
\n
"
);
}
return
true
;
}
void
compile_decorated
(
compiler_t
*
comp
,
py_parse_node_struct_t
*
pns
)
{
void
compile_decorated
(
compiler_t
*
comp
,
py_parse_node_struct_t
*
pns
)
{
// get the list of decorators
// get the list of decorators
py_parse_node_t
*
nodes
;
py_parse_node_t
*
nodes
;
int
n
=
list_get
(
&
pns
->
nodes
[
0
],
PN_decorators
,
&
nodes
);
int
n
=
list_get
(
&
pns
->
nodes
[
0
],
PN_decorators
,
&
nodes
);
// load each decorator
// inherit emit options for this function/class definition
uint
emit_options
=
comp
->
scope_cur
->
emit_options
;
// compile each decorator
int
num_built_in_decorators
=
0
;
for
(
int
i
=
0
;
i
<
n
;
i
++
)
{
for
(
int
i
=
0
;
i
<
n
;
i
++
)
{
assert
(
PY_PARSE_NODE_IS_STRUCT_KIND
(
nodes
[
i
],
PN_decorator
));
// should be
assert
(
PY_PARSE_NODE_IS_STRUCT_KIND
(
nodes
[
i
],
PN_decorator
));
// should be
py_parse_node_struct_t
*
pns_decorator
=
(
py_parse_node_struct_t
*
)
nodes
[
i
];
py_parse_node_struct_t
*
pns_decorator
=
(
py_parse_node_struct_t
*
)
nodes
[
i
];
py_parse_node_t
*
nodes2
;
int
n2
=
list_get
(
&
pns_decorator
->
nodes
[
0
],
PN_dotted_name
,
&
nodes2
);
// nodes[0] contains the decorator function, which is a dotted name
compile_node
(
comp
,
nodes2
[
0
]);
py_parse_node_t
*
name_nodes
;
for
(
int
i
=
1
;
i
<
n2
;
i
++
)
{
int
name_len
=
list_get
(
&
pns_decorator
->
nodes
[
0
],
PN_dotted_name
,
&
name_nodes
);
EMIT
(
load_attr
,
PY_PARSE_NODE_LEAF_ARG
(
nodes2
[
i
]));
}
// check for built-in decorators
if
(
!
PY_PARSE_NODE_IS_NULL
(
pns_decorator
->
nodes
[
1
]))
{
if
(
compile_built_in_decorator
(
comp
,
name_len
,
name_nodes
,
&
emit_options
))
{
// first call the function with these arguments
// this was a built-in
compile_node
(
comp
,
pns_decorator
->
nodes
[
1
]);
num_built_in_decorators
+=
1
;
}
else
{
// not a built-in, compile normally
// compile the decorator function
compile_node
(
comp
,
name_nodes
[
0
]);
for
(
int
i
=
1
;
i
<
name_len
;
i
++
)
{
assert
(
PY_PARSE_NODE_IS_ID
(
name_nodes
[
i
]));
// should be
EMIT
(
load_attr
,
PY_PARSE_NODE_LEAF_ARG
(
name_nodes
[
i
]));
}
// nodes[1] contains arguments to the decorator function, if any
if
(
!
PY_PARSE_NODE_IS_NULL
(
pns_decorator
->
nodes
[
1
]))
{
// call the decorator function with the arguments in nodes[1]
compile_node
(
comp
,
pns_decorator
->
nodes
[
1
]);
}
}
}
}
}
...
@@ -764,16 +811,16 @@ void compile_decorated(compiler_t *comp, py_parse_node_struct_t *pns) {
...
@@ -764,16 +811,16 @@ void compile_decorated(compiler_t *comp, py_parse_node_struct_t *pns) {
py_parse_node_struct_t
*
pns_body
=
(
py_parse_node_struct_t
*
)
pns
->
nodes
[
1
];
py_parse_node_struct_t
*
pns_body
=
(
py_parse_node_struct_t
*
)
pns
->
nodes
[
1
];
qstr
body_name
=
0
;
qstr
body_name
=
0
;
if
(
PY_PARSE_NODE_STRUCT_KIND
(
pns_body
)
==
PN_funcdef
)
{
if
(
PY_PARSE_NODE_STRUCT_KIND
(
pns_body
)
==
PN_funcdef
)
{
body_name
=
compile_funcdef_helper
(
comp
,
pns_body
);
body_name
=
compile_funcdef_helper
(
comp
,
pns_body
,
emit_options
);
}
else
if
(
PY_PARSE_NODE_STRUCT_KIND
(
pns_body
)
==
PN_classdef
)
{
}
else
if
(
PY_PARSE_NODE_STRUCT_KIND
(
pns_body
)
==
PN_classdef
)
{
body_name
=
compile_classdef_helper
(
comp
,
pns_body
);
body_name
=
compile_classdef_helper
(
comp
,
pns_body
,
emit_options
);
}
else
{
}
else
{
// shouldn't happen
// shouldn't happen
assert
(
0
);
assert
(
0
);
}
}
// call each decorator
// call each decorator
for
(
int
i
=
0
;
i
<
n
;
i
++
)
{
for
(
int
i
=
0
;
i
<
n
-
num_built_in_decorators
;
i
++
)
{
EMIT
(
call_function
,
1
,
0
,
false
,
false
);
EMIT
(
call_function
,
1
,
0
,
false
,
false
);
}
}
...
@@ -782,7 +829,7 @@ void compile_decorated(compiler_t *comp, py_parse_node_struct_t *pns) {
...
@@ -782,7 +829,7 @@ void compile_decorated(compiler_t *comp, py_parse_node_struct_t *pns) {
}
}
void
compile_funcdef
(
compiler_t
*
comp
,
py_parse_node_struct_t
*
pns
)
{
void
compile_funcdef
(
compiler_t
*
comp
,
py_parse_node_struct_t
*
pns
)
{
qstr
fname
=
compile_funcdef_helper
(
comp
,
pns
);
qstr
fname
=
compile_funcdef_helper
(
comp
,
pns
,
comp
->
scope_cur
->
emit_options
);
// store function object into function name
// store function object into function name
EMIT
(
store_id
,
fname
);
EMIT
(
store_id
,
fname
);
}
}
...
@@ -1514,7 +1561,7 @@ void compile_lambdef(compiler_t *comp, py_parse_node_struct_t *pns) {
...
@@ -1514,7 +1561,7 @@ void compile_lambdef(compiler_t *comp, py_parse_node_struct_t *pns) {
if
(
comp
->
pass
==
PASS_1
)
{
if
(
comp
->
pass
==
PASS_1
)
{
// create a new scope for this lambda
// create a new scope for this lambda
scope_t
*
s
=
scope_new_and_link
(
comp
,
SCOPE_LAMBDA
,
(
py_parse_node_t
)
pns
);
scope_t
*
s
=
scope_new_and_link
(
comp
,
SCOPE_LAMBDA
,
(
py_parse_node_t
)
pns
,
comp
->
scope_cur
->
emit_options
);
// store the lambda scope so the compiling function (this one) can use it at each pass
// store the lambda scope so the compiling function (this one) can use it at each pass
pns
->
nodes
[
2
]
=
(
py_parse_node_t
)
s
;
pns
->
nodes
[
2
]
=
(
py_parse_node_t
)
s
;
}
}
...
@@ -1780,7 +1827,7 @@ void compile_comprehension(compiler_t *comp, py_parse_node_struct_t *pns, scope_
...
@@ -1780,7 +1827,7 @@ void compile_comprehension(compiler_t *comp, py_parse_node_struct_t *pns, scope_
if
(
comp
->
pass
==
PASS_1
)
{
if
(
comp
->
pass
==
PASS_1
)
{
// create a new scope for this comprehension
// create a new scope for this comprehension
scope_t
*
s
=
scope_new_and_link
(
comp
,
kind
,
(
py_parse_node_t
)
pns
);
scope_t
*
s
=
scope_new_and_link
(
comp
,
kind
,
(
py_parse_node_t
)
pns
,
comp
->
scope_cur
->
emit_options
);
// store the comprehension scope so the compiling function (this one) can use it at each pass
// store the comprehension scope so the compiling function (this one) can use it at each pass
pns_comp_for
->
nodes
[
3
]
=
(
py_parse_node_t
)
s
;
pns_comp_for
->
nodes
[
3
]
=
(
py_parse_node_t
)
s
;
}
}
...
@@ -2048,7 +2095,7 @@ void compile_dictorsetmaker_item(compiler_t *comp, py_parse_node_struct_t *pns)
...
@@ -2048,7 +2095,7 @@ void compile_dictorsetmaker_item(compiler_t *comp, py_parse_node_struct_t *pns)
}
}
void
compile_classdef
(
compiler_t
*
comp
,
py_parse_node_struct_t
*
pns
)
{
void
compile_classdef
(
compiler_t
*
comp
,
py_parse_node_struct_t
*
pns
)
{
qstr
cname
=
compile_classdef_helper
(
comp
,
pns
);
qstr
cname
=
compile_classdef_helper
(
comp
,
pns
,
comp
->
scope_cur
->
emit_options
);
// store class object into class name
// store class object into class name
EMIT
(
store_id
,
cname
);
EMIT
(
store_id
,
cname
);
}
}
...
@@ -2332,6 +2379,7 @@ void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
...
@@ -2332,6 +2379,7 @@ void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
assert
(
PY_PARSE_NODE_STRUCT_KIND
(
pns
)
==
PN_funcdef
);
assert
(
PY_PARSE_NODE_STRUCT_KIND
(
pns
)
==
PN_funcdef
);
// work out number of parameters, keywords and default parameters, and add them to the id_info array
// work out number of parameters, keywords and default parameters, and add them to the id_info array
// must be done before compiling the body so that arguments are numbered first (for LOAD_FAST etc)
if
(
comp
->
pass
==
PASS_1
)
{
if
(
comp
->
pass
==
PASS_1
)
{
comp
->
have_bare_star
=
false
;
comp
->
have_bare_star
=
false
;
apply_to_single_or_list
(
comp
,
pns
->
nodes
[
1
],
PN_typedargslist
,
compile_scope_func_param
);
apply_to_single_or_list
(
comp
,
pns
->
nodes
[
1
],
PN_typedargslist
,
compile_scope_func_param
);
...
@@ -2351,6 +2399,7 @@ void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
...
@@ -2351,6 +2399,7 @@ void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
assert
(
PY_PARSE_NODE_STRUCT_NUM_NODES
(
pns
)
==
3
);
assert
(
PY_PARSE_NODE_STRUCT_NUM_NODES
(
pns
)
==
3
);
// work out number of parameters, keywords and default parameters, and add them to the id_info array
// work out number of parameters, keywords and default parameters, and add them to the id_info array
// must be done before compiling the body so that arguments are numbered first (for LOAD_FAST etc)
if
(
comp
->
pass
==
PASS_1
)
{
if
(
comp
->
pass
==
PASS_1
)
{
comp
->
have_bare_star
=
false
;
comp
->
have_bare_star
=
false
;
apply_to_single_or_list
(
comp
,
pns
->
nodes
[
0
],
PN_varargslist
,
compile_scope_lambda_param
);
apply_to_single_or_list
(
comp
,
pns
->
nodes
[
0
],
PN_varargslist
,
compile_scope_lambda_param
);
...
@@ -2367,7 +2416,7 @@ void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
...
@@ -2367,7 +2416,7 @@ void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
assert
(
PY_PARSE_NODE_IS_STRUCT_KIND
(
pns
->
nodes
[
1
],
PN_comp_for
));
assert
(
PY_PARSE_NODE_IS_STRUCT_KIND
(
pns
->
nodes
[
1
],
PN_comp_for
));
py_parse_node_struct_t
*
pns_comp_for
=
(
py_parse_node_struct_t
*
)
pns
->
nodes
[
1
];
py_parse_node_struct_t
*
pns_comp_for
=
(
py_parse_node_struct_t
*
)
pns
->
nodes
[
1
];
qstr
qstr_arg
=
qstr_from_str
n_copy
(
".0"
,
2
);
qstr
qstr_arg
=
qstr_from_str
_static
(
".0"
);
if
(
comp
->
pass
==
PASS_1
)
{
if
(
comp
->
pass
==
PASS_1
)
{
bool
added
;
bool
added
;
id_info_t
*
id_info
=
scope_find_or_add_id
(
comp
->
scope_cur
,
qstr_arg
,
&
added
);
id_info_t
*
id_info
=
scope_find_or_add_id
(
comp
->
scope_cur
,
qstr_arg
,
&
added
);
...
@@ -2493,13 +2542,15 @@ void compile_scope_compute_things(compiler_t *comp, scope_t *scope) {
...
@@ -2493,13 +2542,15 @@ void compile_scope_compute_things(compiler_t *comp, scope_t *scope) {
void
py_compile
(
py_parse_node_t
pn
)
{
void
py_compile
(
py_parse_node_t
pn
)
{
compiler_t
*
comp
=
m_new
(
compiler_t
,
1
);
compiler_t
*
comp
=
m_new
(
compiler_t
,
1
);
comp
->
qstr___class__
=
qstr_from_strn_copy
(
"__class__"
,
9
);
comp
->
qstr___class__
=
qstr_from_str_static
(
"__class__"
);
comp
->
qstr___locals__
=
qstr_from_strn_copy
(
"__locals__"
,
10
);
comp
->
qstr___locals__
=
qstr_from_str_static
(
"__locals__"
);
comp
->
qstr___name__
=
qstr_from_strn_copy
(
"__name__"
,
8
);
comp
->
qstr___name__
=
qstr_from_str_static
(
"__name__"
);
comp
->
qstr___module__
=
qstr_from_strn_copy
(
"__module__"
,
10
);
comp
->
qstr___module__
=
qstr_from_str_static
(
"__module__"
);
comp
->
qstr___qualname__
=
qstr_from_strn_copy
(
"__qualname__"
,
12
);
comp
->
qstr___qualname__
=
qstr_from_str_static
(
"__qualname__"
);
comp
->
qstr___doc__
=
qstr_from_strn_copy
(
"__doc__"
,
7
);
comp
->
qstr___doc__
=
qstr_from_str_static
(
"__doc__"
);
comp
->
qstr_assertion_error
=
qstr_from_strn_copy
(
"AssertionError"
,
14
);
comp
->
qstr_assertion_error
=
qstr_from_str_static
(
"AssertionError"
);
comp
->
qstr_micropython
=
qstr_from_str_static
(
"micropython"
);
comp
->
qstr_native
=
qstr_from_str_static
(
"native"
);
comp
->
max_num_labels
=
0
;
comp
->
max_num_labels
=
0
;
comp
->
break_label
=
0
;
comp
->
break_label
=
0
;
...
@@ -2508,10 +2559,11 @@ void py_compile(py_parse_node_t pn) {
...
@@ -2508,10 +2559,11 @@ void py_compile(py_parse_node_t pn) {
comp
->
scope_head
=
NULL
;
comp
->
scope_head
=
NULL
;
comp
->
scope_cur
=
NULL
;
comp
->
scope_cur
=
NULL
;
emit_pass1_new
(
&
comp
->
emit
,
&
comp
->
emit_method_table
,
comp
->
qstr___class__
);
comp
->
emit
=
emit_pass1_new
(
comp
->
qstr___class__
);
comp
->
emit_method_table
=
&
emit_pass1_method_table
;
pn
=
fold_constants
(
pn
);
pn
=
fold_constants
(
pn
);
scope_new_and_link
(
comp
,
SCOPE_MODULE
,
pn
);
scope_new_and_link
(
comp
,
SCOPE_MODULE
,
pn
,
EMIT_OPT_NONE
);
for
(
scope_t
*
s
=
comp
->
scope_head
;
s
!=
NULL
;
s
=
s
->
next
)
{
for
(
scope_t
*
s
=
comp
->
scope_head
;
s
!=
NULL
;
s
=
s
->
next
)
{
compile_scope
(
comp
,
s
,
PASS_1
);
compile_scope
(
comp
,
s
,
PASS_1
);
...
@@ -2521,11 +2573,29 @@ void py_compile(py_parse_node_t pn) {
...
@@ -2521,11 +2573,29 @@ void py_compile(py_parse_node_t pn) {
compile_scope_compute_things
(
comp
,
s
);
compile_scope_compute_things
(
comp
,
s
);
}
}
emit_cpython_new
(
&
comp
->
emit
,
&
comp
->
emit_method_table
,
comp
->
max_num_labels
);
emit_pass1_free
(
comp
->
emit
);
//emit_bc_new(&comp->emit, &comp->emit_method_table, comp->max_num_labels);
//emit_x64_new(&comp->emit, &comp->emit_method_table, comp->max_num_labels);
emit_t
*
emit_bc
=
NULL
;
emit_t
*
emit_x64
=
NULL
;
for
(
scope_t
*
s
=
comp
->
scope_head
;
s
!=
NULL
;
s
=
s
->
next
)
{
for
(
scope_t
*
s
=
comp
->
scope_head
;
s
!=
NULL
;
s
=
s
->
next
)
{
switch
(
s
->
emit_options
)
{
case
EMIT_OPT_NATIVE_PYTHON
:
if
(
emit_x64
==
NULL
)
{
emit_x64
=
emit_x64_new
(
comp
->
max_num_labels
);
}
comp
->
emit
=
emit_x64
;
comp
->
emit_method_table
=
&
emit_x64_method_table
;
break
;
default:
if
(
emit_bc
==
NULL
)
{
emit_bc
=
emit_bc_new
(
comp
->
max_num_labels
);
}
comp
->
emit
=
emit_bc
;
comp
->
emit_method_table
=
&
emit_bc_method_table
;
break
;
}
compile_scope
(
comp
,
s
,
PASS_2
);
compile_scope
(
comp
,
s
,
PASS_2
);
compile_scope
(
comp
,
s
,
PASS_3
);
compile_scope
(
comp
,
s
,
PASS_3
);
}
}
...
...
py/emit.h
View file @
6cdd3af6
...
@@ -116,8 +116,15 @@ void emit_common_load_id(emit_t *emit, const emit_method_table_t *emit_method_ta
...
@@ -116,8 +116,15 @@ void emit_common_load_id(emit_t *emit, const emit_method_table_t *emit_method_ta
void
emit_common_store_id
(
emit_t
*
emit
,
const
emit_method_table_t
*
emit_method_table
,
scope_t
*
scope
,
qstr
qstr
);
void
emit_common_store_id
(
emit_t
*
emit
,
const
emit_method_table_t
*
emit_method_table
,
scope_t
*
scope
,
qstr
qstr
);
void
emit_common_delete_id
(
emit_t
*
emit
,
const
emit_method_table_t
*
emit_method_table
,
scope_t
*
scope
,
qstr
qstr
);
void
emit_common_delete_id
(
emit_t
*
emit
,
const
emit_method_table_t
*
emit_method_table
,
scope_t
*
scope
,
qstr
qstr
);
void
emit_pass1_new
(
emit_t
**
emit
,
const
emit_method_table_t
**
emit_method_table
,
qstr
qstr___class__
);
extern
const
emit_method_table_t
emit_pass1_method_table
;
void
emit_cpython_new
(
emit_t
**
emit_out
,
const
emit_method_table_t
**
emit_method_table_out
,
uint
max_num_labels
);
extern
const
emit_method_table_t
emit_cpython_method_table
;
void
emit_bc_new
(
emit_t
**
emit
,
const
emit_method_table_t
**
emit_method_table
,
uint
max_num_labels
);
extern
const
emit_method_table_t
emit_bc_method_table
;
void
emit_x64_new
(
emit_t
**
emit
,
const
emit_method_table_t
**
emit_method_table
,
uint
max_num_labels
);
extern
const
emit_method_table_t
emit_x64_method_table
;
void
emit_thumb_new
(
emit_t
**
emit
,
const
emit_method_table_t
**
emit_method_table
,
uint
max_num_labels
);
extern
const
emit_method_table_t
emit_thumb_method_table
;
emit_t
*
emit_pass1_new
(
qstr
qstr___class__
);
void
emit_pass1_free
(
emit_t
*
emit
);
emit_t
*
emit_cpython_new
(
uint
max_num_labels
);
emit_t
*
emit_bc_new
(
uint
max_num_labels
);
emit_t
*
emit_x64_new
(
uint
max_num_labels
);
emit_t
*
emit_thumb_new
(
uint
max_num_labels
);
py/emitbc.c
View file @
6cdd3af6
...
@@ -32,8 +32,15 @@ struct _emit_t {
...
@@ -32,8 +32,15 @@ struct _emit_t {
byte
dummy_data
[
8
];
byte
dummy_data
[
8
];
};
};
// forward declaration
emit_t
*
emit_bc_new
(
uint
max_num_labels
)
{
static
const
emit_method_table_t
emit_bc_method_table
;
emit_t
*
emit
=
m_new
(
emit_t
,
1
);
emit
->
max_num_labels
=
max_num_labels
;
emit
->
label_offsets
=
m_new
(
uint
,
emit
->
max_num_labels
);
emit
->
code_offset
=
0
;
emit
->
code_size
=
0
;
emit
->
code_base
=
NULL
;
return
emit
;
}
uint
emit_bc_get_code_size
(
emit_t
*
emit
)
{
uint
emit_bc_get_code_size
(
emit_t
*
emit
)
{
return
emit
->
code_size
;
return
emit
->
code_size
;
...
@@ -672,7 +679,7 @@ static void emit_bc_yield_from(emit_t *emit) {
...
@@ -672,7 +679,7 @@ static void emit_bc_yield_from(emit_t *emit) {
emit_write_byte_1
(
emit
,
PYBC_YIELD_FROM
);
emit_write_byte_1
(
emit
,
PYBC_YIELD_FROM
);
}
}
static
const
emit_method_table_t
emit_bc_method_table
=
{
const
emit_method_table_t
emit_bc_method_table
=
{
emit_bc_set_native_types
,
emit_bc_set_native_types
,
emit_bc_start_pass
,
emit_bc_start_pass
,
emit_bc_end_pass
,
emit_bc_end_pass
,
...
@@ -767,15 +774,3 @@ static const emit_method_table_t emit_bc_method_table = {
...
@@ -767,15 +774,3 @@ static const emit_method_table_t emit_bc_method_table = {
emit_bc_yield_value
,
emit_bc_yield_value
,
emit_bc_yield_from
,
emit_bc_yield_from
,
};
};
void
emit_bc_new
(
emit_t
**
emit_out
,
const
emit_method_table_t
**
emit_method_table_out
,
uint
max_num_labels
)
{
emit_t
*
emit
=
m_new
(
emit_t
,
1
);
emit
->
max_num_labels
=
max_num_labels
;
emit
->
label_offsets
=
m_new
(
uint
,
emit
->
max_num_labels
);
emit
->
code_offset
=
0
;
emit
->
code_size
=
0
;
emit
->
code_base
=
NULL
;
*
emit_out
=
emit
;
*
emit_method_table_out
=
&
emit_bc_method_table
;
}
py/emitcpy.c
View file @
6cdd3af6
...
@@ -29,10 +29,16 @@ struct _emit_t {
...
@@ -29,10 +29,16 @@ struct _emit_t {
int
*
label_offsets
;
int
*
label_offsets
;
};
};
// forward declarations
// forward declaration
static
const
emit_method_table_t
emit_cpy_method_table
;
static
void
emit_cpy_load_const_verbatim_quoted_str
(
emit_t
*
emit
,
qstr
qstr
,
bool
bytes
);
static
void
emit_cpy_load_const_verbatim_quoted_str
(
emit_t
*
emit
,
qstr
qstr
,
bool
bytes
);
emit_t
*
emit_cpython_new
(
uint
max_num_labels
)
{
emit_t
*
emit
=
m_new
(
emit_t
,
1
);
emit
->
max_num_labels
=
max_num_labels
;
emit
->
label_offsets
=
m_new
(
int
,
max_num_labels
);
return
emit
;
}
static
void
emit_cpy_set_native_types
(
emit_t
*
emit
,
bool
do_native_types
)
{
static
void
emit_cpy_set_native_types
(
emit_t
*
emit
,
bool
do_native_types
)
{
}
}
...
@@ -68,15 +74,15 @@ static void emit_cpy_set_stack_size(emit_t *emit, int size) {
...
@@ -68,15 +74,15 @@ static void emit_cpy_set_stack_size(emit_t *emit, int size) {
}
}
static
void
emit_cpy_load_id
(
emit_t
*
emit
,
qstr
qstr
)
{
static
void
emit_cpy_load_id
(
emit_t
*
emit
,
qstr
qstr
)
{
emit_common_load_id
(
emit
,
&
emit_cpy_method_table
,
emit
->
scope
,
qstr
);
emit_common_load_id
(
emit
,
&
emit_cpy
thon
_method_table
,
emit
->
scope
,
qstr
);
}
}
static
void
emit_cpy_store_id
(
emit_t
*
emit
,
qstr
qstr
)
{
static
void
emit_cpy_store_id
(
emit_t
*
emit
,
qstr
qstr
)
{
emit_common_store_id
(
emit
,
&
emit_cpy_method_table
,
emit
->
scope
,
qstr
);
emit_common_store_id
(
emit
,
&
emit_cpy
thon
_method_table
,
emit
->
scope
,
qstr
);
}
}
static
void
emit_cpy_delete_id
(
emit_t
*
emit
,
qstr
qstr
)
{
static
void
emit_cpy_delete_id
(
emit_t
*
emit
,
qstr
qstr
)
{
emit_common_delete_id
(
emit
,
&
emit_cpy_method_table
,
emit
->
scope
,
qstr
);
emit_common_delete_id
(
emit
,
&
emit_cpy
thon
_method_table
,
emit
->
scope
,
qstr
);
}
}
static
void
emit_pre
(
emit_t
*
emit
,
int
stack_size_delta
,
int
byte_code_size
)
{
static
void
emit_pre
(
emit_t
*
emit
,
int
stack_size_delta
,
int
byte_code_size
)
{
...
@@ -260,24 +266,24 @@ static void emit_cpy_load_const_verbatim_end(emit_t *emit) {
...
@@ -260,24 +266,24 @@ static void emit_cpy_load_const_verbatim_end(emit_t *emit) {
}
}
}
}
static
void
emit_cpy_load_
name
(
emit_t
*
emit
,
qstr
qstr
)
{
static
void
emit_cpy_load_
fast
(
emit_t
*
emit
,
qstr
qstr
,
int
local_num
)
{
emit_pre
(
emit
,
1
,
3
);
emit_pre
(
emit
,
1
,
3
);
if
(
emit
->
pass
==
PASS_3
)
{
if
(
emit
->
pass
==
PASS_3
)
{
printf
(
"LOAD_
NAME %s
\n
"
,
qstr_str
(
qstr
));
printf
(
"LOAD_
FAST %d %s
\n
"
,
local_num
,
qstr_str
(
qstr
));
}
}
}
}
static
void
emit_cpy_load_
global
(
emit_t
*
emit
,
qstr
qstr
)
{
static
void
emit_cpy_load_
name
(
emit_t
*
emit
,
qstr
qstr
)
{
emit_pre
(
emit
,
1
,
3
);
emit_pre
(
emit
,
1
,
3
);
if
(
emit
->
pass
==
PASS_3
)
{
if
(
emit
->
pass
==
PASS_3
)
{
printf
(
"LOAD_
GLOBAL
%s
\n
"
,
qstr_str
(
qstr
));
printf
(
"LOAD_
NAME
%s
\n
"
,
qstr_str
(
qstr
));
}
}
}
}
static
void
emit_cpy_load_
fast
(
emit_t
*
emit
,
qstr
qstr
,
int
local_num
)
{
static
void
emit_cpy_load_
global
(
emit_t
*
emit
,
qstr
qstr
)
{
emit_pre
(
emit
,
1
,
3
);
emit_pre
(
emit
,
1
,
3
);
if
(
emit
->
pass
==
PASS_3
)
{
if
(
emit
->
pass
==
PASS_3
)
{
printf
(
"LOAD_
FAST
%s
\n
"
,
qstr_str
(
qstr
));
printf
(
"LOAD_
GLOBAL
%s
\n
"
,
qstr_str
(
qstr
));
}
}
}
}
...
@@ -313,24 +319,24 @@ static void emit_cpy_load_build_class(emit_t *emit) {
...
@@ -313,24 +319,24 @@ static void emit_cpy_load_build_class(emit_t *emit) {
}
}
}
}
static
void
emit_cpy_store_
name
(
emit_t
*
emit
,
qstr
qstr
)
{
static
void
emit_cpy_store_
fast
(
emit_t
*
emit
,
qstr
qstr
,
int
local_num
)
{
emit_pre
(
emit
,
-
1
,
3
);
emit_pre
(
emit
,
-
1
,
3
);
if
(
emit
->
pass
==
PASS_3
)
{
if
(
emit
->
pass
==
PASS_3
)
{
printf
(
"STORE_
NAME %s
\n
"
,
qstr_str
(
qstr
));
printf
(
"STORE_
FAST %d %s
\n
"
,
local_num
,
qstr_str
(
qstr
));
}
}
}
}
static
void
emit_cpy_store_
global
(
emit_t
*
emit
,
qstr
qstr
)
{
static
void
emit_cpy_store_
name
(
emit_t
*
emit
,
qstr
qstr
)
{
emit_pre
(
emit
,
-
1
,
3
);
emit_pre
(
emit
,
-
1
,
3
);
if
(
emit
->
pass
==
PASS_3
)
{
if
(
emit
->
pass
==
PASS_3
)
{
printf
(
"STORE_
GLOBAL
%s
\n
"
,
qstr_str
(
qstr
));
printf
(
"STORE_
NAME
%s
\n
"
,
qstr_str
(
qstr
));
}
}
}
}
static
void
emit_cpy_store_
fast
(
emit_t
*
emit
,
qstr
qstr
,
int
local_num
)
{
static
void
emit_cpy_store_
global
(
emit_t
*
emit
,
qstr
qstr
)
{
emit_pre
(
emit
,
-
1
,
3
);
emit_pre
(
emit
,
-
1
,
3
);
if
(
emit
->
pass
==
PASS_3
)
{
if
(
emit
->
pass
==
PASS_3
)
{
printf
(
"STORE_
FAST
%s
\n
"
,
qstr_str
(
qstr
));
printf
(
"STORE_
GLOBAL
%s
\n
"
,
qstr_str
(
qstr
));
}
}
}
}
...
@@ -362,24 +368,24 @@ static void emit_cpy_store_subscr(emit_t *emit) {
...
@@ -362,24 +368,24 @@ static void emit_cpy_store_subscr(emit_t *emit) {
}
}
}
}
static
void
emit_cpy_delete_
name
(
emit_t
*
emit
,
qstr
qstr
)
{
static
void
emit_cpy_delete_
fast
(
emit_t
*
emit
,
qstr
qstr
,
int
local_num
)
{
emit_pre
(
emit
,
0
,
3
);