Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
TASTE
uPython-mirror
Commits
7f5dacf3
Commit
7f5dacf3
authored
Oct 10, 2013
by
Damien
Browse files
Implement basic class/object in native code.
parent
a397776d
Changes
4
Hide whitespace changes
Inline
Side-by-side
py/emitbc.c
View file @
7f5dacf3
...
...
@@ -354,8 +354,9 @@ static void emit_bc_store_subscr(emit_t *emit) {
}
static
void
emit_bc_store_locals
(
emit_t
*
emit
)
{
// not needed
for byte code
// not needed
emit_pre
(
emit
,
-
1
);
emit_write_byte_1
(
emit
,
PYBC_POP_TOP
);
}
static
void
emit_bc_delete_fast
(
emit_t
*
emit
,
qstr
qstr
,
int
local_num
)
{
...
...
py/emitnative.c
View file @
7f5dacf3
...
...
@@ -344,7 +344,7 @@ static void need_reg_single(emit_t *emit, int reg_needed) {
}
}
static
void
need_reg_all
(
emit_t
*
emit
)
{
static
void
need_reg_all
(
emit_t
*
emit
,
int
num_stack_top_that_must_be_value
)
{
for
(
int
i
=
0
;
i
<
emit
->
stack_size
;
i
++
)
{
stack_info_t
*
si
=
&
emit
->
stack_info
[
i
];
if
(
si
->
kind
==
STACK_REG
)
{
...
...
@@ -352,6 +352,14 @@ static void need_reg_all(emit_t *emit) {
ASM_MOV_REG_TO_LOCAL
(
si
->
u_reg
,
emit
->
stack_start
+
i
);
}
}
// must do this after making all registers available because ASM_MOV_IMM_TO_LOCAL uses a temporary register
for
(
int
i
=
0
;
i
<
num_stack_top_that_must_be_value
;
i
++
)
{
stack_info_t
*
si
=
&
emit
->
stack_info
[
emit
->
stack_size
-
1
-
i
];
if
(
si
->
kind
==
STACK_IMM
)
{
si
->
kind
=
STACK_VALUE
;
ASM_MOV_IMM_TO_LOCAL
(
si
->
u_imm
,
emit
->
stack_start
+
emit
->
stack_size
-
1
-
i
);
}
}
}
static
void
emit_pre_pop_reg
(
emit_t
*
emit
,
vtype_kind_t
*
vtype
,
int
reg_dest
)
{
...
...
@@ -427,9 +435,10 @@ static void emit_post_push_reg_reg_reg_reg(emit_t *emit, vtype_kind_t vtypea, in
// vtype of all n_pop objects is VTYPE_PYOBJ
static
void
emit_get_stack_pointer_to_reg_for_pop
(
emit_t
*
emit
,
int
reg_dest
,
int
n_pop
)
{
need_reg_all
(
emit
);
need_reg_all
(
emit
,
n_pop
);
for
(
int
i
=
0
;
i
<
n_pop
;
i
++
)
{
assert
(
emit
->
stack_info
[
emit
->
stack_size
+
i
].
vtype
==
VTYPE_PYOBJ
);
assert
(
emit
->
stack_info
[
emit
->
stack_size
-
1
-
i
].
kind
==
STACK_VALUE
);
assert
(
emit
->
stack_info
[
emit
->
stack_size
-
1
-
i
].
vtype
==
VTYPE_PYOBJ
);
}
ASM_MOV_LOCAL_ADDR_TO_REG
(
emit
->
stack_start
+
emit
->
stack_size
-
1
,
reg_dest
);
adjust_stack
(
emit
,
-
n_pop
);
...
...
@@ -437,8 +446,9 @@ static void emit_get_stack_pointer_to_reg_for_pop(emit_t *emit, int reg_dest, in
// vtype of all n_push objects is VTYPE_PYOBJ
static
void
emit_get_stack_pointer_to_reg_for_push
(
emit_t
*
emit
,
int
reg_dest
,
int
n_push
)
{
need_reg_all
(
emit
);
need_reg_all
(
emit
,
0
);
for
(
int
i
=
0
;
i
<
n_push
;
i
++
)
{
emit
->
stack_info
[
emit
->
stack_size
+
i
].
kind
=
STACK_VALUE
;
emit
->
stack_info
[
emit
->
stack_size
+
i
].
vtype
=
VTYPE_PYOBJ
;
}
ASM_MOV_LOCAL_ADDR_TO_REG
(
emit
->
stack_start
+
emit
->
stack_size
+
n_push
-
1
,
reg_dest
);
...
...
@@ -454,7 +464,7 @@ static void emit_call(emit_t *emit, rt_fun_kind_t fun_kind, void *fun) {
}
static
void
emit_call_with_imm_arg
(
emit_t
*
emit
,
rt_fun_kind_t
fun_kind
,
void
*
fun
,
machine_int_t
arg_val
,
int
arg_reg
)
{
need_reg_all
(
emit
);
need_reg_all
(
emit
,
0
);
ASM_MOV_IMM_TO_REG
(
arg_val
,
arg_reg
);
emit_call
(
emit
,
fun_kind
,
fun
);
}
...
...
@@ -549,8 +559,13 @@ static void emit_native_load_const_dec(emit_t *emit, qstr qstr) {
}
static
void
emit_native_load_const_id
(
emit_t
*
emit
,
qstr
qstr
)
{
// not supported for viper?
assert
(
0
);
emit_pre
(
emit
);
if
(
emit
->
do_viper_types
)
{
assert
(
0
);
}
else
{
emit_call_with_imm_arg
(
emit
,
RT_F_LOAD_CONST_STR
,
rt_load_const_str
,
qstr
,
REG_ARG_1
);
// TODO
emit_post_push_reg
(
emit
,
VTYPE_PYOBJ
,
REG_RET
);
}
}
static
void
emit_native_load_const_str
(
emit_t
*
emit
,
qstr
qstr
,
bool
bytes
)
{
...
...
@@ -669,8 +684,9 @@ static void emit_native_load_method(emit_t *emit, qstr qstr) {
}
static
void
emit_native_load_build_class
(
emit_t
*
emit
)
{
// not supported
assert
(
0
);
emit_pre
(
emit
);
emit_call
(
emit
,
RT_F_LOAD_BUILD_CLASS
,
rt_load_build_class
);
emit_post_push_reg
(
emit
,
VTYPE_PYOBJ
,
REG_RET
);
}
static
void
emit_native_store_fast
(
emit_t
*
emit
,
qstr
qstr
,
int
local_num
)
{
...
...
@@ -727,8 +743,12 @@ static void emit_native_store_deref(emit_t *emit, qstr qstr) {
}
static
void
emit_native_store_attr
(
emit_t
*
emit
,
qstr
qstr
)
{
// not implemented
assert
(
0
);
vtype_kind_t
vtype_base
,
vtype_val
;
emit_pre_pop_reg_reg
(
emit
,
&
vtype_base
,
REG_ARG_1
,
&
vtype_val
,
REG_ARG_3
);
// arg1 = base, arg3 = value
assert
(
vtype_base
==
VTYPE_PYOBJ
);
assert
(
vtype_val
==
VTYPE_PYOBJ
);
emit_call_with_imm_arg
(
emit
,
RT_F_STORE_ATTR
,
rt_store_attr
,
qstr
,
REG_ARG_2
);
// arg2 = attribute name
emit_post
(
emit
);
}
static
void
emit_native_store_subscr
(
emit_t
*
emit
)
{
...
...
@@ -1069,7 +1089,9 @@ static void emit_native_call_method(emit_t *emit, int n_positional, int n_keywor
assert
(
vtype_arg1
==
VTYPE_PYOBJ
);
emit_call
(
emit
,
RT_F_CALL_METHOD_2
,
rt_call_method_2
);
}
else
{
assert
(
0
);
emit_pre
(
emit
);
emit_get_stack_pointer_to_reg_for_pop
(
emit
,
REG_ARG_2
,
n_positional
+
2
);
// pointer to items in reverse order, including meth and self
emit_call_with_imm_arg
(
emit
,
RT_F_CALL_METHOD_N
,
rt_call_method_n
,
n_positional
,
REG_ARG_1
);
}
emit_post_push_reg
(
emit
,
VTYPE_PYOBJ
,
REG_RET
);
}
...
...
py/runtime.c
View file @
7f5dacf3
...
...
@@ -9,11 +9,13 @@
#include
"runtime.h"
#include
"vm.h"
#if 0 // print debugging info
#define DEBUG_printf(args...) printf(args)
#define DEBUG_OP_printf(args...) printf(args)
#else
// don't print debugging info
#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)
#endif
// enable/disable float support with this definition
#define PY_FLOAT (1)
...
...
@@ -914,7 +916,7 @@ py_obj_t rt_call_function_1(py_obj_t fun, py_obj_t arg) {
py_obj_t
rt_call_function_2
(
py_obj_t
fun
,
py_obj_t
arg1
,
py_obj_t
arg2
)
{
if
(
IS_O
(
fun
,
O_FUN_2
))
{
py_obj_base_t
*
o
=
fun
;
DEBUG_OP_printf
(
"calling native %p
with 2 args
\n
"
,
o
->
u_fun
.
fun
);
DEBUG_OP_printf
(
"calling native %p
(%p, %p)
\n
"
,
o
->
u_fun
.
fun
,
arg1
,
arg2
);
return
((
py_fun_2_t
)
o
->
u_fun
.
fun
)(
arg1
,
arg2
);
}
else
if
(
IS_O
(
fun
,
O_FUN_BC
))
{
py_obj_base_t
*
o
=
fun
;
...
...
@@ -937,7 +939,12 @@ py_obj_t rt_call_function_2(py_obj_t fun, py_obj_t arg1, py_obj_t arg2) {
// args are in reverse order in the array
py_obj_t
rt_call_function_n
(
py_obj_t
fun
,
int
n_args
,
const
py_obj_t
*
args
)
{
if
(
IS_O
(
fun
,
O_FUN_BC
))
{
if
(
IS_O
(
fun
,
O_FUN_2
))
{
assert
(
n_args
==
2
);
py_obj_base_t
*
o
=
fun
;
DEBUG_OP_printf
(
"calling native %p(%p, %p)
\n
"
,
o
->
u_fun
.
fun
,
args
[
1
],
args
[
0
]);
return
((
py_fun_2_t
)
o
->
u_fun
.
fun
)(
args
[
1
],
args
[
0
]);
}
else
if
(
IS_O
(
fun
,
O_FUN_BC
))
{
py_obj_base_t
*
o
=
fun
;
assert
(
o
->
u_fun_bc
.
n_args
==
n_args
);
DEBUG_OP_printf
(
"calling byte code %p with %d args
\n
"
,
o
->
u_fun_bc
.
code
,
n_args
);
...
...
@@ -949,7 +956,7 @@ py_obj_t rt_call_function_n(py_obj_t fun, int n_args, const py_obj_t *args) {
}
py_obj_t
rt_call_method_1
(
py_obj_t
fun
,
py_obj_t
self
)
{
DEBUG_OP_printf
(
"call method %p
%p
\n
"
,
fun
,
self
);
DEBUG_OP_printf
(
"call method %p
(self=
%p
)
\n
"
,
fun
,
self
);
if
(
self
==
NULL
)
{
return
rt_call_function_0
(
fun
);
}
else
{
...
...
@@ -958,7 +965,7 @@ py_obj_t rt_call_method_1(py_obj_t fun, py_obj_t self) {
}
py_obj_t
rt_call_method_2
(
py_obj_t
fun
,
py_obj_t
self
,
py_obj_t
arg
)
{
DEBUG_OP_printf
(
"call method %p
%p %p
\n
"
,
fun
,
self
,
arg
);
DEBUG_OP_printf
(
"call method %p
(self=
%p
,
%p
)
\n
"
,
fun
,
self
,
arg
);
if
(
self
==
NULL
)
{
return
rt_call_function_1
(
fun
,
arg
);
}
else
{
...
...
@@ -969,7 +976,7 @@ py_obj_t rt_call_method_2(py_obj_t fun, py_obj_t self, py_obj_t arg) {
// args contains: arg(n_args-1) arg(n_args-2) ... arg(0) self/NULL fun
// if n_args==0 then there are only self/NULL and fun
py_obj_t
rt_call_method_n
(
int
n_args
,
const
py_obj_t
*
args
)
{
DEBUG_OP_printf
(
"call method %p
%p %d args
\n
"
,
args
[
n_args
+
1
],
args
[
n_args
]
,
n_args
);
DEBUG_OP_printf
(
"call method %p
(self=%p, n_args=%d)
\n
"
,
args
[
n_args
+
1
],
args
[
n_args
],
n_args
);
return
rt_call_function_n
(
args
[
n_args
+
1
],
n_args
+
((
args
[
n_args
]
==
NULL
)
?
0
:
1
),
args
);
}
...
...
@@ -1186,9 +1193,11 @@ void *rt_fun_table[RT_F_NUMBER_OF] = {
rt_load_const_str
,
rt_load_name
,
rt_load_global
,
rt_load_build_class
,
rt_load_attr
,
rt_load_method
,
rt_store_name
,
rt_store_attr
,
rt_store_subscr
,
rt_is_true
,
rt_unary_op
,
...
...
@@ -1202,6 +1211,7 @@ void *rt_fun_table[RT_F_NUMBER_OF] = {
rt_call_function_2
,
rt_call_method_1
,
rt_call_method_2
,
rt_call_method_n
,
rt_binary_op
,
rt_compare_op
,
};
...
...
py/runtime.h
View file @
7f5dacf3
...
...
@@ -51,9 +51,11 @@ typedef enum {
RT_F_LOAD_CONST_STR
=
0
,
RT_F_LOAD_NAME
,
RT_F_LOAD_GLOBAL
,
RT_F_LOAD_BUILD_CLASS
,
RT_F_LOAD_ATTR
,
RT_F_LOAD_METHOD
,
RT_F_STORE_NAME
,
RT_F_STORE_ATTR
,
RT_F_STORE_SUBSCR
,
RT_F_IS_TRUE
,
RT_F_UNARY_OP
,
...
...
@@ -67,6 +69,7 @@ typedef enum {
RT_F_CALL_FUNCTION_2
,
RT_F_CALL_METHOD_1
,
RT_F_CALL_METHOD_2
,
RT_F_CALL_METHOD_N
,
RT_F_BINARY_OP
,
RT_F_COMPARE_OP
,
RT_F_NUMBER_OF
,
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a 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