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
Show whitespace changes
Inline
Side-by-side
py/compile.c
View file @
6cdd3af6
...
...
@@ -27,6 +27,10 @@ typedef enum {
#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
{
qstr
qstr___class__
;
qstr
qstr___locals__
;
...
...
@@ -35,6 +39,8 @@ typedef struct _compiler_t {
qstr
qstr___qualname__
;
qstr
qstr___doc__
;
qstr
qstr_assertion_error
;
qstr
qstr_micropython
;
qstr
qstr_native
;
pass_kind_t
pass
;
...
...
@@ -56,8 +62,8 @@ typedef struct _compiler_t {
scope_t
*
scope_head
;
scope_t
*
scope_cur
;
emit_t
*
emit
;
const
emit_method_table_t
*
emit_method_table
;
emit_t
*
emit
;
// current emitter
const
emit_method_table_t
*
emit_method_table
;
// current emit method table
}
compiler_t
;
py_parse_node_t
fold_constants
(
py_parse_node_t
pn
)
{
...
...
@@ -165,8 +171,8 @@ static int comp_next_label(compiler_t *comp) {
return
comp
->
next_label
++
;
}
static
scope_t
*
scope_new_and_link
(
compiler_t
*
comp
,
scope_kind_t
kind
,
py_parse_node_t
pn
)
{
scope_t
*
scope
=
scope_new
(
kind
,
pn
,
rt_get_new_unique_code_id
());
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
()
,
emit_options
);
scope
->
parent
=
comp
->
scope_cur
;
scope
->
next
=
NULL
;
if
(
comp
->
scope_head
==
NULL
)
{
...
...
@@ -661,10 +667,10 @@ void compile_funcdef_param(compiler_t *comp, py_parse_node_t pn) {
// leaves function object on stack
// 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
)
{
// 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
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) {
// leaves class object on stack
// 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
)
{
// 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
pns
->
nodes
[
3
]
=
(
py_parse_node_t
)
s
;
}
...
...
@@ -739,41 +745,82 @@ qstr compile_classdef_helper(compiler_t *comp, py_parse_node_struct_t *pns) {
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
)
{
// get the list of decorators
py_parse_node_t
*
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
++
)
{
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_t
*
nodes2
;
int
n2
=
list_get
(
&
pns_decorator
->
nodes
[
0
],
PN_dotted_name
,
&
nodes2
);
compile_node
(
comp
,
nodes2
[
0
]);
for
(
int
i
=
1
;
i
<
n2
;
i
++
)
{
EMIT
(
load_attr
,
PY_PARSE_NODE_LEAF_ARG
(
nodes2
[
i
]));
// nodes[0] contains the decorator function, which is a dotted name
py_parse_node_t
*
name_nodes
;
int
name_len
=
list_get
(
&
pns_decorator
->
nodes
[
0
],
PN_dotted_name
,
&
name_nodes
);
// check for built-in decorators
if
(
compile_built_in_decorator
(
comp
,
name_len
,
name_nodes
,
&
emit_options
))
{
// this was a built-in
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
]))
{
// first call the
function with the
se
arguments
// call the decorator
function with the arguments
in nodes[1]
compile_node
(
comp
,
pns_decorator
->
nodes
[
1
]);
}
}
}
// compile the body (funcdef or classdef) and get its name
py_parse_node_struct_t
*
pns_body
=
(
py_parse_node_struct_t
*
)
pns
->
nodes
[
1
];
qstr
body_name
=
0
;
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
)
{
body_name
=
compile_classdef_helper
(
comp
,
pns_body
);
body_name
=
compile_classdef_helper
(
comp
,
pns_body
,
emit_options
);
}
else
{
// shouldn't happen
assert
(
0
);
}
// 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
);
}
...
...
@@ -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
)
{
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
EMIT
(
store_id
,
fname
);
}
...
...
@@ -1514,7 +1561,7 @@ void compile_lambdef(compiler_t *comp, py_parse_node_struct_t *pns) {
if
(
comp
->
pass
==
PASS_1
)
{
// 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
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_
if
(
comp
->
pass
==
PASS_1
)
{
// 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
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)
}
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
EMIT
(
store_id
,
cname
);
}
...
...
@@ -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
);
// 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
)
{
comp
->
have_bare_star
=
false
;
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) {
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
// must be done before compiling the body so that arguments are numbered first (for LOAD_FAST etc)
if
(
comp
->
pass
==
PASS_1
)
{
comp
->
have_bare_star
=
false
;
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) {
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
];
qstr
qstr_arg
=
qstr_from_str
n_copy
(
".0"
,
2
);
qstr
qstr_arg
=
qstr_from_str
_static
(
".0"
);
if
(
comp
->
pass
==
PASS_1
)
{
bool
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) {
void
py_compile
(
py_parse_node_t
pn
)
{
compiler_t
*
comp
=
m_new
(
compiler_t
,
1
);
comp
->
qstr___class__
=
qstr_from_strn_copy
(
"__class__"
,
9
);
comp
->
qstr___locals__
=
qstr_from_strn_copy
(
"__locals__"
,
10
);
comp
->
qstr___name__
=
qstr_from_strn_copy
(
"__name__"
,
8
);
comp
->
qstr___module__
=
qstr_from_strn_copy
(
"__module__"
,
10
);
comp
->
qstr___qualname__
=
qstr_from_strn_copy
(
"__qualname__"
,
12
);
comp
->
qstr___doc__
=
qstr_from_strn_copy
(
"__doc__"
,
7
);
comp
->
qstr_assertion_error
=
qstr_from_strn_copy
(
"AssertionError"
,
14
);
comp
->
qstr___class__
=
qstr_from_str_static
(
"__class__"
);
comp
->
qstr___locals__
=
qstr_from_str_static
(
"__locals__"
);
comp
->
qstr___name__
=
qstr_from_str_static
(
"__name__"
);
comp
->
qstr___module__
=
qstr_from_str_static
(
"__module__"
);
comp
->
qstr___qualname__
=
qstr_from_str_static
(
"__qualname__"
);
comp
->
qstr___doc__
=
qstr_from_str_static
(
"__doc__"
);
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
->
break_label
=
0
;
...
...
@@ -2508,10 +2559,11 @@ void py_compile(py_parse_node_t pn) {
comp
->
scope_head
=
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
);
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
)
{
compile_scope
(
comp
,
s
,
PASS_1
);
...
...
@@ -2521,11 +2573,29 @@ void py_compile(py_parse_node_t pn) {
compile_scope_compute_things
(
comp
,
s
);
}
emit_cpython_new
(
&
comp
->
emit
,
&
comp
->
emit_method_table
,
comp
->
max_num_labels
);
//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_pass1_free
(
comp
->
emit
);
emit_t
*
emit_bc
=
NULL
;
emit_t
*
emit_x64
=
NULL
;
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_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
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_pass1_new
(
emit_t
**
emit
,
const
emit_method_table_t
**
emit_method_table
,
qstr
qstr___class__
);
void
emit_cpython_new
(
emit_t
**
emit_out
,
const
emit_method_table_t
**
emit_method_table_out
,
uint
max_num_labels
);
void
emit_bc_new
(
emit_t
**
emit
,
const
emit_method_table_t
**
emit_method_table
,
uint
max_num_labels
);
void
emit_x64_new
(
emit_t
**
emit
,
const
emit_method_table_t
**
emit_method_table
,
uint
max_num_labels
);
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_pass1_method_table
;
extern
const
emit_method_table_t
emit_cpython_method_table
;
extern
const
emit_method_table_t
emit_bc_method_table
;
extern
const
emit_method_table_t
emit_x64_method_table
;
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 {
byte
dummy_data
[
8
];
};
// forward declaration
static
const
emit_method_table_t
emit_bc_method_table
;
emit_t
*
emit_bc_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
(
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
)
{
return
emit
->
code_size
;
...
...
@@ -672,7 +679,7 @@ static void emit_bc_yield_from(emit_t *emit) {
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_start_pass
,
emit_bc_end_pass
,
...
...
@@ -767,15 +774,3 @@ static const emit_method_table_t emit_bc_method_table = {
emit_bc_yield_value
,
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 {
int
*
label_offsets
;
};
// forward declarations
static
const
emit_method_table_t
emit_cpy_method_table
;
// forward declaration
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
)
{
}
...
...
@@ -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
)
{
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
)
{
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
)
{
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
)
{
...
...
@@ -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
);
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
);
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
);
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) {
}
}
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
);
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
);
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
);
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) {
}
}
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
);
if
(
emit
->
pass
==
PASS_3
)
{
printf
(
"DELETE_
NAME %s
\n
"
,
qstr_str
(
qstr
));
printf
(
"DELETE_
FAST %d %s
\n
"
,
local_num
,
qstr_str
(
qstr
));
}
}
static
void
emit_cpy_delete_
global
(
emit_t
*
emit
,
qstr
qstr
)
{
static
void
emit_cpy_delete_
name
(
emit_t
*
emit
,
qstr
qstr
)
{
emit_pre
(
emit
,
0
,
3
);
if
(
emit
->
pass
==
PASS_3
)
{
printf
(
"DELETE_
GLOBAL
%s
\n
"
,
qstr_str
(
qstr
));
printf
(
"DELETE_
NAME
%s
\n
"
,
qstr_str
(
qstr
));
}
}
static
void
emit_cpy_delete_
fast
(
emit_t
*
emit
,
qstr
qstr
,
int
local_num
)
{
static
void
emit_cpy_delete_
global
(
emit_t
*
emit
,
qstr
qstr
)
{
emit_pre
(
emit
,
0
,
3
);
if
(
emit
->
pass
==
PASS_3
)
{
printf
(
"DELETE_
FAST
%s
\n
"
,
qstr_str
(
qstr
));
printf
(
"DELETE_
GLOBAL
%s
\n
"
,
qstr_str
(
qstr
));
}
}
...
...
@@ -825,7 +831,7 @@ static void emit_cpy_yield_from(emit_t *emit) {
}
}
static
const
emit_method_table_t
emit_cpy_method_table
=
{
const
emit_method_table_t
emit_cpy
thon
_method_table
=
{
emit_cpy_set_native_types
,
emit_cpy_start_pass
,
emit_cpy_end_pass
,
...
...
@@ -921,13 +927,4 @@ static const emit_method_table_t emit_cpy_method_table = {
emit_cpy_yield_from
,
};
void
emit_cpython_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
(
int
,
max_num_labels
);
*
emit_out
=
emit
;
*
emit_method_table_out
=
&
emit_cpy_method_table
;
}
#endif // EMIT_ENABLE_CPY
py/emitx64.c
View file @
6cdd3af6
...
...
@@ -53,8 +53,12 @@ struct _emit_t {
bool
do_native_types
;
};
// forward declaration
static
const
emit_method_table_t
emit_x64_method_table
;
emit_t
*
emit_x64_new
(
uint
max_num_labels
)
{
emit_t
*
emit
=
m_new
(
emit_t
,
1
);
emit
->
as
=
asm_x64_new
(
max_num_labels
);
emit
->
do_native_types
=
false
;
return
emit
;
}
static
void
emit_x64_set_native_types
(
emit_t
*
emit
,
bool
do_native_types
)
{
emit
->
do_native_types
=
do_native_types
;
...
...
@@ -678,7 +682,7 @@ static void emit_x64_yield_from(emit_t *emit) {
assert
(
0
);
}
static
const
emit_method_table_t
emit_x64_method_table
=
{
const
emit_method_table_t
emit_x64_method_table
=
{
emit_x64_set_native_types
,
emit_x64_start_pass
,
emit_x64_end_pass
,
...
...
@@ -774,13 +778,4 @@ static const emit_method_table_t emit_x64_method_table = {
emit_x64_yield_from
,
};
void
emit_x64_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
->
as
=
asm_x64_new
(
max_num_labels
);
emit
->
do_native_types
=
false
;
*
emit_out
=
emit
;
*
emit_method_table_out
=
&
emit_x64_method_table
;
}
#endif // EMIT_ENABLE_X64
py/main.c
View file @
6cdd3af6
...
...
@@ -40,7 +40,7 @@ int main(int argc, char **argv) {
py_lexer_free
(
lex
);
if
(
0
)
{
if
(
1
)
{
// execute it
py_obj_t
module_fun
=
rt_make_function_from_id
(
1
);
if
(
module_fun
!=
py_const_none
)
{
...
...
py/runtime.c
View file @
6cdd3af6
...
...
@@ -9,8 +9,8 @@
#include
"runtime.h"
#include
"vm.h"
#define DEBUG_printf(args...) (void)0
//
#define DEBUG_printf(args...) printf(args)
//
#define DEBUG_printf(args...) (void)0
#define DEBUG_printf(args...) printf(args)
#define DEBUG_OP_printf(args...) (void)0
//#define DEBUG_OP_printf(args...) printf(args)
...
...
@@ -423,6 +423,12 @@ const char *py_obj_get_type_str(py_obj_t o_in) {
case
O_FLOAT
:
return
"float"
;
#endif
case
O_FUN_0
:
case
O_FUN_1
:
case
O_FUN_2
:
case
O_FUN_N
:
case
O_FUN_BC
:
return
"function"
;
case
O_LIST
:
return
"list"
;
case
O_SET
:
...
...
@@ -714,12 +720,12 @@ py_obj_t rt_call_function_0(py_obj_t fun) {
py_obj_t
rt_call_function_1
(
py_obj_t
fun
,
py_obj_t
arg
)
{
if
(
IS_O
(
fun
,
O_FUN_1
))
{
py_obj_base_t
*
o
=
fun
;
DEBUG_OP_printf
(
"calling native %p
...
\n
"
,
o
->
u_fun
.
fun
);
DEBUG_OP_printf
(
"calling native %p
with 1 arg
\n
"
,
o
->
u_fun
.
fun
);
return
((
py_fun_1_t
)
o
->
u_fun
.
fun
)(
arg
);
}
else
if
(
IS_O
(
fun
,
O_FUN_BC
))
{
py_obj_base_t
*
o
=
fun
;
assert
(
o
->
u_fun_bc
.
n_args
==
1
);
DEBUG_OP_printf
(
"calling byte code %p
...
\n
"
,
o
->
u_fun_bc
.
code
);
DEBUG_OP_printf
(
"calling byte code %p
with 1 arg
\n
"
,
o
->
u_fun_bc
.
code
);
return
py_execute_byte_code
(
o
->
u_fun_bc
.
code
,
o
->
u_fun_bc
.
len
,
&
arg
,
1
);
}
else
if
(
IS_O
(
fun
,
O_BOUND_METH
))
{
py_obj_base_t
*
o
=
fun
;
...
...
py/scope.c
View file @
6cdd3af6
...
...
@@ -8,7 +8,7 @@
#include
"parse.h"
#include
"scope.h"
scope_t
*
scope_new
(
scope_kind_t
kind
,
py_parse_node_t
pn
,
uint
unique_code_id
)
{
scope_t
*
scope_new
(
scope_kind_t
kind
,
py_parse_node_t
pn
,
uint
unique_code_id
,
uint
emit_options
)
{
scope_t
*
scope
=
m_new
(
scope_t
,
1
);
scope
->
kind
=
kind
;
scope
->
parent
=
NULL
;
...
...
@@ -53,6 +53,7 @@ scope_t *scope_new(scope_kind_t kind, py_parse_node_t pn, uint unique_code_id) {
*/
scope
->
num_locals
=
0
;
scope
->
unique_code_id
=
unique_code_id
;
scope
->
emit_options
=
emit_options
;
return
scope
;
}
...
...
@@ -80,8 +81,9 @@ id_info_t *scope_find_or_add_id(scope_t *scope, qstr qstr, bool *added) {
*/
}
{
if
(
0
)
{
// sort insert into id_info array, so we are equivalent to CPython (no other reason to do it)
// actually, seems that this is not what CPython does...
scope
->
id_info_len
+=
1
;
for
(
int
i
=
scope
->
id_info_len
-
1
;;
i
--
)
{
if
(
i
==
0
||
strcmp
(
qstr_str
(
scope
->
id_info
[
i
-
1
].
qstr
),
qstr_str
(
qstr
))
<
0
)
{
...
...
@@ -91,6 +93,11 @@ id_info_t *scope_find_or_add_id(scope_t *scope, qstr qstr, bool *added) {
scope
->
id_info
[
i
]
=
scope
->
id_info
[
i
-
1
];
}