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
78772ada
Commit
78772ada
authored
Apr 06, 2015
by
Damien George
Browse files
py: Implement calling functions with *args in native emitter.
parent
282ca09f
Changes
4
Hide whitespace changes
Inline
Side-by-side
py/emitnative.c
View file @
78772ada
...
...
@@ -184,6 +184,7 @@ STATIC byte mp_f_n_args[MP_F_NUMBER_OF] = {
[
MP_F_MAKE_FUNCTION_FROM_RAW_CODE
]
=
3
,
[
MP_F_NATIVE_CALL_FUNCTION_N_KW
]
=
3
,
[
MP_F_CALL_METHOD_N_KW
]
=
3
,
[
MP_F_CALL_METHOD_N_KW_VAR
]
=
3
,
[
MP_F_GETITER
]
=
1
,
[
MP_F_ITERNEXT
]
=
1
,
[
MP_F_NLR_PUSH
]
=
1
,
...
...
@@ -2189,13 +2190,12 @@ STATIC void emit_native_call_function(emit_t *emit, mp_uint_t n_positional, mp_u
// TODO: in viper mode, call special runtime routine with type info for args,
// and wanted type info for return, to remove need for boxing/unboxing
assert
(
!
star_flags
);
emit_native_pre
(
emit
);
vtype_kind_t
vtype_fun
=
peek_vtype
(
emit
,
n_positional
+
2
*
n_keyword
);
if
(
vtype_fun
==
VTYPE_BUILTIN_CAST
)
{
// casting operator
assert
(
n_positional
==
1
&&
n_keyword
==
0
);
assert
(
!
star_flags
);
DEBUG_printf
(
" cast to %d
\n
"
,
vtype_fun
);
vtype_kind_t
vtype_cast
=
peek_stack
(
emit
,
1
)
->
data
.
u_imm
;
switch
(
peek_vtype
(
emit
,
0
))
{
...
...
@@ -2221,22 +2221,49 @@ STATIC void emit_native_call_function(emit_t *emit, mp_uint_t n_positional, mp_u
assert
(
!
"TODO: convert obj to int"
);
}
}
else
{
if
(
n_positional
!=
0
||
n_keyword
!=
0
)
{
emit_get_stack_pointer_to_reg_for_pop
(
emit
,
REG_ARG_3
,
n_positional
+
2
*
n_keyword
);
// pointer to args
}
emit_pre_pop_reg
(
emit
,
&
vtype_fun
,
REG_ARG_1
);
// the function
assert
(
vtype_fun
==
VTYPE_PYOBJ
);
emit_call_with_imm_arg
(
emit
,
MP_F_NATIVE_CALL_FUNCTION_N_KW
,
n_positional
|
(
n_keyword
<<
8
),
REG_ARG_2
);
emit_post_push_reg
(
emit
,
VTYPE_PYOBJ
,
REG_RET
);
if
(
star_flags
)
{
if
(
!
(
star_flags
&
MP_EMIT_STAR_FLAG_SINGLE
))
{
// load dummy entry for non-existent pos_seq
emit_native_load_null
(
emit
);
emit_native_rot_two
(
emit
);
}
else
if
(
!
(
star_flags
&
MP_EMIT_STAR_FLAG_DOUBLE
))
{
// load dummy entry for non-existent kw_dict
emit_native_load_null
(
emit
);
}
emit_get_stack_pointer_to_reg_for_pop
(
emit
,
REG_ARG_3
,
n_positional
+
2
*
n_keyword
+
3
);
// pointer to args
emit_call_with_2_imm_args
(
emit
,
MP_F_CALL_METHOD_N_KW_VAR
,
0
,
REG_ARG_1
,
n_positional
|
(
n_keyword
<<
8
),
REG_ARG_2
);
emit_post_push_reg
(
emit
,
VTYPE_PYOBJ
,
REG_RET
);
}
else
{
if
(
n_positional
!=
0
||
n_keyword
!=
0
)
{
emit_get_stack_pointer_to_reg_for_pop
(
emit
,
REG_ARG_3
,
n_positional
+
2
*
n_keyword
);
// pointer to args
}
emit_pre_pop_reg
(
emit
,
&
vtype_fun
,
REG_ARG_1
);
// the function
emit_call_with_imm_arg
(
emit
,
MP_F_NATIVE_CALL_FUNCTION_N_KW
,
n_positional
|
(
n_keyword
<<
8
),
REG_ARG_2
);
emit_post_push_reg
(
emit
,
VTYPE_PYOBJ
,
REG_RET
);
}
}
}
STATIC
void
emit_native_call_method
(
emit_t
*
emit
,
mp_uint_t
n_positional
,
mp_uint_t
n_keyword
,
mp_uint_t
star_flags
)
{
assert
(
!
star_flags
);
emit_native_pre
(
emit
);
emit_get_stack_pointer_to_reg_for_pop
(
emit
,
REG_ARG_3
,
2
+
n_positional
+
2
*
n_keyword
);
// pointer to items, including meth and self
emit_call_with_2_imm_args
(
emit
,
MP_F_CALL_METHOD_N_KW
,
n_positional
,
REG_ARG_1
,
n_keyword
,
REG_ARG_2
);
emit_post_push_reg
(
emit
,
VTYPE_PYOBJ
,
REG_RET
);
if
(
star_flags
)
{
if
(
!
(
star_flags
&
MP_EMIT_STAR_FLAG_SINGLE
))
{
// load dummy entry for non-existent pos_seq
emit_native_load_null
(
emit
);
emit_native_rot_two
(
emit
);
}
else
if
(
!
(
star_flags
&
MP_EMIT_STAR_FLAG_DOUBLE
))
{
// load dummy entry for non-existent kw_dict
emit_native_load_null
(
emit
);
}
emit_get_stack_pointer_to_reg_for_pop
(
emit
,
REG_ARG_3
,
n_positional
+
2
*
n_keyword
+
4
);
// pointer to args
emit_call_with_2_imm_args
(
emit
,
MP_F_CALL_METHOD_N_KW_VAR
,
1
,
REG_ARG_1
,
n_positional
|
(
n_keyword
<<
8
),
REG_ARG_2
);
emit_post_push_reg
(
emit
,
VTYPE_PYOBJ
,
REG_RET
);
}
else
{
emit_native_pre
(
emit
);
emit_get_stack_pointer_to_reg_for_pop
(
emit
,
REG_ARG_3
,
2
+
n_positional
+
2
*
n_keyword
);
// pointer to items, including meth and self
emit_call_with_2_imm_args
(
emit
,
MP_F_CALL_METHOD_N_KW
,
n_positional
,
REG_ARG_1
,
n_keyword
,
REG_ARG_2
);
emit_post_push_reg
(
emit
,
VTYPE_PYOBJ
,
REG_RET
);
}
}
STATIC
void
emit_native_return_value
(
emit_t
*
emit
)
{
...
...
py/nativeglue.c
View file @
78772ada
...
...
@@ -117,6 +117,7 @@ void *const mp_fun_table[MP_F_NUMBER_OF] = {
mp_make_function_from_raw_code
,
mp_native_call_function_n_kw
,
mp_call_method_n_kw
,
mp_call_method_n_kw_var
,
mp_getiter
,
mp_iternext
,
nlr_push
,
...
...
py/runtime0.h
View file @
78772ada
...
...
@@ -133,6 +133,7 @@ typedef enum {
MP_F_MAKE_FUNCTION_FROM_RAW_CODE
,
MP_F_NATIVE_CALL_FUNCTION_N_KW
,
MP_F_CALL_METHOD_N_KW
,
MP_F_CALL_METHOD_N_KW_VAR
,
MP_F_GETITER
,
MP_F_ITERNEXT
,
MP_F_NLR_PUSH
,
...
...
tests/run-tests
View file @
78772ada
...
...
@@ -160,7 +160,6 @@ def run_tests(pyb, tests, args):
skip_tests
.
add
(
'basics/boundmeth1.py'
)
# requires support for many args
skip_tests
.
add
(
'basics/closure_manyvars.py'
)
# requires closures
skip_tests
.
add
(
'float/string_format.py'
)
skip_tests
.
add
(
'float/cmath_fun.py'
)
# requires f(*args) support
skip_tests
.
add
(
'import/gen_context.py'
)
skip_tests
.
add
(
'io/file_with.py'
)
skip_tests
.
add
(
'io/stringio_with.py'
)
...
...
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