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
38a2da68
Commit
38a2da68
authored
Jan 08, 2014
by
Damien George
Browse files
py: Stuff qstr in object pointer; keys for mp_map_t are now always mp_obj_t.
parent
ea9e441a
Changes
13
Show whitespace changes
Inline
Side-by-side
py/builtin.c
View file @
38a2da68
...
...
@@ -23,7 +23,7 @@ mp_obj_t mp_builtin___build_class__(int n_args, const mp_obj_t *args) {
// we differ from CPython: we set the new __locals__ object here
mp_map_t
*
old_locals
=
rt_locals_get
();
mp_map_t
*
class_locals
=
mp_map_new
(
MP_MAP_QSTR
,
0
);
mp_map_t
*
class_locals
=
mp_map_new
(
0
);
rt_locals_set
(
class_locals
);
// call the class code
...
...
py/map.c
View file @
38a2da68
...
...
@@ -26,21 +26,22 @@ int get_doubling_prime_greater_or_equal_to(int x) {
/******************************************************************************/
/* map */
void
mp_map_init
(
mp_map_t
*
map
,
mp_map_kind_t
kind
,
int
n
)
{
map
->
kind
=
kind
;
map
->
used
=
0
;
void
mp_map_init
(
mp_map_t
*
map
,
int
n
)
{
map
->
alloc
=
get_doubling_prime_greater_or_equal_to
(
n
+
1
);
map
->
used
=
0
;
map
->
all_keys_are_qstrs
=
1
;
map
->
table
=
m_new0
(
mp_map_elem_t
,
map
->
alloc
);
}
mp_map_t
*
mp_map_new
(
mp_map_kind_t
kind
,
int
n
)
{
mp_map_t
*
mp_map_new
(
int
n
)
{
mp_map_t
*
map
=
m_new
(
mp_map_t
,
1
);
mp_map_init
(
map
,
kind
,
n
);
mp_map_init
(
map
,
n
);
return
map
;
}
void
mp_map_clear
(
mp_map_t
*
map
)
{
map
->
used
=
0
;
map
->
all_keys_are_qstrs
=
1
;
machine_uint_t
a
=
map
->
alloc
;
map
->
alloc
=
0
;
map
->
table
=
m_renew
(
mp_map_elem_t
,
map
->
table
,
a
,
map
->
alloc
);
...
...
@@ -50,30 +51,26 @@ void mp_map_clear(mp_map_t *map) {
}
}
static
void
mp_map_rehash
(
mp_map_t
*
map
)
{
static
void
mp_map_rehash
(
mp_map_t
*
map
)
{
int
old_alloc
=
map
->
alloc
;
mp_map_elem_t
*
old_table
=
map
->
table
;
map
->
alloc
=
get_doubling_prime_greater_or_equal_to
(
map
->
alloc
+
1
);
map
->
used
=
0
;
map
->
all_keys_are_qstrs
=
1
;
map
->
table
=
m_new0
(
mp_map_elem_t
,
map
->
alloc
);
for
(
int
i
=
0
;
i
<
old_alloc
;
i
++
)
{
if
(
old_table
[
i
].
key
!=
NULL
)
{
mp_map_lookup
_helper
(
map
,
old_table
[
i
].
key
,
true
,
false
)
->
value
=
old_table
[
i
].
value
;
mp_map_lookup
(
map
,
old_table
[
i
].
key
,
MP_MAP_LOOKUP_ADD_IF_NOT_FOUND
)
->
value
=
old_table
[
i
].
value
;
}
}
m_del
(
mp_map_elem_t
,
old_table
,
old_alloc
);
}
mp_map_elem_t
*
mp_map_lookup_helper
(
mp_map_t
*
map
,
mp_obj_t
index
,
bool
add_if_not_found
,
bool
remove_if_found
)
{
bool
is_map_mp_obj
=
(
map
->
kind
==
MP_MAP_OBJ
);
mp_map_elem_t
*
mp_map_lookup
(
mp_map_t
*
map
,
mp_obj_t
index
,
mp_map_lookup_kind_t
lookup_kind
)
{
machine_uint_t
hash
;
if
(
is_map_mp_obj
)
{
hash
=
mp_obj_hash
(
index
);
}
else
{
hash
=
(
machine_uint_t
)
index
;
}
if
(
map
->
alloc
==
0
)
{
if
(
add_if_not_found
)
{
if
(
lookup_kind
==
MP_MAP_LOOKUP_ADD_IF_NOT_FOUND
)
{
mp_map_rehash
(
map
);
}
else
{
return
NULL
;
...
...
@@ -84,7 +81,7 @@ mp_map_elem_t* mp_map_lookup_helper(mp_map_t *map, mp_obj_t index, bool add_if_n
mp_map_elem_t
*
elem
=
&
map
->
table
[
pos
];
if
(
elem
->
key
==
NULL
)
{
// not in table
if
(
add_if_not_found
)
{
if
(
lookup_kind
==
MP_MAP_LOOKUP_ADD_IF_NOT_FOUND
)
{
if
(
map
->
used
+
1
>=
map
->
alloc
)
{
// not enough room in table, rehash it
mp_map_rehash
(
map
);
...
...
@@ -93,21 +90,24 @@ mp_map_elem_t* mp_map_lookup_helper(mp_map_t *map, mp_obj_t index, bool add_if_n
}
else
{
map
->
used
+=
1
;
elem
->
key
=
index
;
if
(
!
MP_OBJ_IS_QSTR
(
index
))
{
map
->
all_keys_are_qstrs
=
0
;
}
return
elem
;
}
}
else
{
return
NULL
;
}
}
else
if
(
elem
->
key
==
index
||
(
is_map_mp_obj
&&
mp_obj_equal
(
elem
->
key
,
index
)))
{
}
else
if
(
elem
->
key
==
index
||
(
!
map
->
all_keys_are_qstrs
&&
mp_obj_equal
(
elem
->
key
,
index
)))
{
// found it
/* it seems CPython does not replace the index; try x={True:'true'};x[1]='one';x
if (add_if_not_found) {
elem->key = index;
}
*/
if
(
remove_if_found
)
{
if
(
lookup_kind
==
MP_MAP_LOOKUP_REMOVE_IF_FOUND
)
{
map
->
used
--
;
/
*
this leaks this memory (but see dict_get_helper)
*/
/
/
this leaks this memory (but see dict_get_helper)
mp_map_elem_t
*
retval
=
m_new
(
mp_map_elem_t
,
1
);
retval
->
key
=
elem
->
key
;
retval
->
value
=
elem
->
value
;
...
...
@@ -123,11 +123,6 @@ mp_map_elem_t* mp_map_lookup_helper(mp_map_t *map, mp_obj_t index, bool add_if_n
}
}
mp_map_elem_t
*
mp_qstr_map_lookup
(
mp_map_t
*
map
,
qstr
index
,
bool
add_if_not_found
)
{
mp_obj_t
o
=
(
mp_obj_t
)(
machine_uint_t
)
index
;
return
mp_map_lookup_helper
(
map
,
o
,
add_if_not_found
,
false
);
}
/******************************************************************************/
/* set */
...
...
py/map.h
View file @
38a2da68
typedef
enum
{
MP_MAP_QSTR
,
MP_MAP_OBJ
,
}
mp_map_kind_t
;
typedef
struct
_mp_map_elem_t
{
mp_obj_t
key
;
mp_obj_t
value
;
...
...
@@ -10,8 +5,8 @@ typedef struct _mp_map_elem_t {
typedef
struct
_mp_map_t
{
struct
{
m
p_map_k
in
d
_t
kind
:
1
;
machine_uint_t
used
:
(
8
*
BYTES_PER_WORD
-
1
);
m
achine_u
in
t
_t
all_keys_are_qstrs
:
1
;
machine_uint_t
used
:
(
8
*
sizeof
(
machine_uint_t
)
-
1
);
};
machine_uint_t
alloc
;
mp_map_elem_t
*
table
;
...
...
@@ -23,11 +18,16 @@ typedef struct _mp_set_t {
mp_obj_t
*
table
;
}
mp_set_t
;
typedef
enum
{
MP_MAP_LOOKUP
,
MP_MAP_LOOKUP_ADD_IF_NOT_FOUND
,
MP_MAP_LOOKUP_REMOVE_IF_FOUND
,
}
mp_map_lookup_kind_t
;
int
get_doubling_prime_greater_or_equal_to
(
int
x
);
void
mp_map_init
(
mp_map_t
*
map
,
mp_map_kind_t
kind
,
int
n
);
mp_map_t
*
mp_map_new
(
mp_map_kind_t
kind
,
int
n
);
mp_map_elem_t
*
mp_map_lookup_helper
(
mp_map_t
*
map
,
mp_obj_t
index
,
bool
add_if_not_found
,
bool
remove_if_found
);
mp_map_elem_t
*
mp_qstr_map_lookup
(
mp_map_t
*
map
,
qstr
index
,
bool
add_if_not_found
);
void
mp_map_init
(
mp_map_t
*
map
,
int
n
);
mp_map_t
*
mp_map_new
(
int
n
);
mp_map_elem_t
*
mp_map_lookup
(
mp_map_t
*
map
,
mp_obj_t
index
,
mp_map_lookup_kind_t
lookup_kind
);
void
mp_map_clear
(
mp_map_t
*
map
);
void
mp_set_init
(
mp_set_t
*
set
,
int
n
);
...
...
py/obj.c
View file @
38a2da68
...
...
@@ -16,6 +16,8 @@
mp_obj_t
mp_obj_get_type
(
mp_obj_t
o_in
)
{
if
(
MP_OBJ_IS_SMALL_INT
(
o_in
))
{
return
(
mp_obj_t
)
&
int_type
;
}
else
if
(
MP_OBJ_IS_QSTR
(
o_in
))
{
return
(
mp_obj_t
)
&
str_type
;
}
else
{
mp_obj_base_t
*
o
=
o_in
;
return
(
mp_obj_t
)
o
->
type
;
...
...
@@ -71,6 +73,8 @@ machine_int_t mp_obj_hash(mp_obj_t o_in) {
return
1
;
// needs to hash to same as the integer 1, since True==1
}
else
if
(
MP_OBJ_IS_SMALL_INT
(
o_in
))
{
return
MP_OBJ_SMALL_INT_VALUE
(
o_in
);
}
else
if
(
MP_OBJ_IS_QSTR
(
o_in
))
{
return
MP_OBJ_QSTR_VALUE
(
o_in
);
}
else
if
(
MP_OBJ_IS_TYPE
(
o_in
,
&
none_type
))
{
return
(
machine_int_t
)
o_in
;
}
else
if
(
MP_OBJ_IS_TYPE
(
o_in
,
&
str_type
))
{
...
...
@@ -107,6 +111,8 @@ bool mp_obj_equal(mp_obj_t o1, mp_obj_t o2) {
return
false
;
}
}
}
else
if
(
MP_OBJ_IS_QSTR
(
o1
)
||
MP_OBJ_IS_QSTR
(
o2
))
{
return
false
;
}
else
if
(
MP_OBJ_IS_TYPE
(
o1
,
&
str_type
)
&&
MP_OBJ_IS_TYPE
(
o2
,
&
str_type
))
{
return
mp_obj_str_get
(
o1
)
==
mp_obj_str_get
(
o2
);
}
else
{
...
...
py/obj.h
View file @
38a2da68
...
...
@@ -29,13 +29,21 @@ typedef struct _mp_obj_base_t mp_obj_base_t;
#define MP_OBJ_NULL ((mp_obj_t)NULL)
// These macros check for small int or object, and access small int values
// These macros check for small int, qstr or object, and access small int and qstr values
// - xxxx...xxx1: a small int, bits 1 and above are the value
// - xxxx...xx10: a qstr, bits 2 and above are the value
// - xxxx...xx00: a pointer to an mp_obj_base_t
#define MP_OBJ_IS_OBJ(o) ((((mp_small_int_t)(o)) & 1) == 0)
#define MP_OBJ_IS_SMALL_INT(o) ((((mp_small_int_t)(o)) & 1) != 0)
#define MP_OBJ_IS_TYPE(o, t) (((((mp_small_int_t)(o)) & 1) == 0) && (((mp_obj_base_t*)(o))->type == (t)))
#define MP_OBJ_IS_QSTR(o) ((((mp_small_int_t)(o)) & 3) == 2)
#define MP_OBJ_IS_OBJ(o) ((((mp_small_int_t)(o)) & 3) == 0)
#define MP_OBJ_IS_TYPE(o, t) (MP_OBJ_IS_OBJ(o) && (((mp_obj_base_t*)(o))->type == (t)))
#define MP_OBJ_SMALL_INT_VALUE(o) (((mp_small_int_t)(o)) >> 1)
#define MP_OBJ_NEW_SMALL_INT(o) ((mp_obj_t)(((o) << 1) | 1))
#define MP_OBJ_NEW_SMALL_INT(small_int) ((mp_obj_t)(((small_int) << 1) | 1))
#define MP_OBJ_QSTR_VALUE(o) (((mp_small_int_t)(o)) >> 2)
#define MP_OBJ_NEW_QSTR(qstr) ((mp_obj_t)((((machine_uint_t)qstr) << 2) | 2))
// These macros are used to declare and define constant function objects
// You can put "static" in front of the definitions to make them local
...
...
py/objclass.c
View file @
38a2da68
...
...
@@ -26,7 +26,7 @@ mp_obj_t class_call_n(mp_obj_t self_in, int n_args, const mp_obj_t *args) {
mp_obj_t
o
=
mp_obj_new_instance
(
self_in
);
// look for __init__ function
mp_map_elem_t
*
init_fn
=
mp_
qstr_
map_lookup
(
self
->
locals
,
MP_QSTR
_
__init__
,
false
);
mp_map_elem_t
*
init_fn
=
mp_map_lookup
(
self
->
locals
,
MP_
OBJ_NEW_QSTR
(
MP_
QSTR__
_
init__
)
,
MP_MAP_LOOKUP
);
if
(
init_fn
!=
NULL
)
{
// call __init__ function
...
...
py/objdict.c
View file @
38a2da68
...
...
@@ -50,7 +50,7 @@ static mp_obj_t dict_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
case
RT_BINARY_OP_SUBSCR
:
{
// dict load
mp_map_elem_t
*
elem
=
mp_map_lookup
_helper
(
&
o
->
map
,
rhs_in
,
false
,
false
);
mp_map_elem_t
*
elem
=
mp_map_lookup
(
&
o
->
map
,
rhs_in
,
MP_MAP_LOOKUP
);
if
(
elem
==
NULL
)
{
nlr_jump
(
mp_obj_new_exception_msg
(
MP_QSTR_KeyError
,
"<value>"
));
}
else
{
...
...
@@ -139,12 +139,12 @@ static mp_obj_t dict_copy(mp_obj_t self_in) {
}
static
MP_DEFINE_CONST_FUN_OBJ_1
(
dict_copy_obj
,
dict_copy
);
static
mp_obj_t
dict_get_helper
(
mp_map_t
*
self
,
mp_obj_t
key
,
mp_obj_t
deflt
,
bool
pop
,
bool
set
)
{
mp_map_elem_t
*
elem
=
mp_map_lookup
_helper
(
self
,
key
,
set
,
pop
);
static
mp_obj_t
dict_get_helper
(
mp_map_t
*
self
,
mp_obj_t
key
,
mp_obj_t
deflt
,
mp_map_lookup_kind_t
lookup_kind
)
{
mp_map_elem_t
*
elem
=
mp_map_lookup
(
self
,
key
,
lookup_kind
);
mp_obj_t
value
;
if
(
elem
==
NULL
||
elem
->
value
==
NULL
)
{
if
(
deflt
==
NULL
)
{
if
(
pop
)
{
if
(
lookup_kind
==
MP_MAP_LOOKUP_REMOVE_IF_FOUND
)
{
nlr_jump
(
mp_obj_new_exception_msg
(
MP_QSTR_KeyError
,
"<value>"
));
}
else
{
value
=
mp_const_none
;
...
...
@@ -154,12 +154,12 @@ static mp_obj_t dict_get_helper(mp_map_t *self, mp_obj_t key, mp_obj_t deflt, bo
}
}
else
{
value
=
elem
->
value
;
if
(
pop
)
{
/
*
catch the leak (from mp_map_lookup
_helper) */
if
(
lookup_kind
==
MP_MAP_LOOKUP_REMOVE_IF_FOUND
)
{
/
/
catch the leak (from mp_map_lookup
)
m_free
(
elem
,
sizeof
(
mp_map_elem_t
));
}
}
if
(
set
)
{
if
(
lookup_kind
==
MP_MAP_LOOKUP_ADD_IF_NOT_FOUND
)
{
elem
->
value
=
value
;
}
return
value
;
...
...
@@ -172,7 +172,7 @@ static mp_obj_t dict_get(int n_args, const mp_obj_t *args) {
return
dict_get_helper
(
&
((
mp_obj_dict_t
*
)
args
[
0
])
->
map
,
args
[
1
],
n_args
==
3
?
args
[
2
]
:
NULL
,
false
,
false
);
MP_MAP_LOOKUP
);
}
static
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN
(
dict_get_obj
,
2
,
3
,
dict_get
);
...
...
@@ -183,7 +183,7 @@ static mp_obj_t dict_pop(int n_args, const mp_obj_t *args) {
return
dict_get_helper
(
&
((
mp_obj_dict_t
*
)
args
[
0
])
->
map
,
args
[
1
],
n_args
==
3
?
args
[
2
]
:
NULL
,
true
,
false
);
MP_MAP_LOOKUP_REMOVE_IF_FOUND
);
}
static
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN
(
dict_pop_obj
,
2
,
3
,
dict_pop
);
...
...
@@ -195,7 +195,7 @@ static mp_obj_t dict_setdefault(int n_args, const mp_obj_t *args) {
return
dict_get_helper
(
&
((
mp_obj_dict_t
*
)
args
[
0
])
->
map
,
args
[
1
],
n_args
==
3
?
args
[
2
]
:
NULL
,
false
,
true
);
MP_MAP_LOOKUP_ADD_IF_NOT_FOUND
);
}
static
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN
(
dict_setdefault_obj
,
2
,
3
,
dict_setdefault
);
...
...
@@ -237,7 +237,7 @@ static mp_obj_t dict_update(mp_obj_t self_in, mp_obj_t iterable) {
MP_QSTR_ValueError
,
"dictionary update sequence has the wrong length"
));
}
else
{
mp_map_lookup
_helper
(
&
self
->
map
,
key
,
true
,
false
)
->
value
=
value
;
mp_map_lookup
(
&
self
->
map
,
key
,
MP_MAP_LOOKUP_ADD_IF_NOT_FOUND
)
->
value
=
value
;
}
}
...
...
@@ -273,7 +273,7 @@ const mp_obj_type_t dict_type = {
mp_obj_t
mp_obj_new_dict
(
int
n_args
)
{
mp_obj_dict_t
*
o
=
m_new_obj
(
mp_obj_dict_t
);
o
->
base
.
type
=
&
dict_type
;
mp_map_init
(
&
o
->
map
,
MP_MAP_OBJ
,
n_args
);
mp_map_init
(
&
o
->
map
,
n_args
);
return
o
;
}
...
...
@@ -284,6 +284,6 @@ uint mp_obj_dict_len(mp_obj_t self_in) {
mp_obj_t
mp_obj_dict_store
(
mp_obj_t
self_in
,
mp_obj_t
key
,
mp_obj_t
value
)
{
assert
(
MP_OBJ_IS_TYPE
(
self_in
,
&
dict_type
));
mp_obj_dict_t
*
self
=
self_in
;
mp_map_lookup
_helper
(
&
self
->
map
,
key
,
true
,
false
)
->
value
=
value
;
mp_map_lookup
(
&
self
->
map
,
key
,
MP_MAP_LOOKUP_ADD_IF_NOT_FOUND
)
->
value
=
value
;
return
self_in
;
}
py/objfun.c
View file @
38a2da68
...
...
@@ -81,13 +81,13 @@ mp_obj_t fun_native_call_n_kw(mp_obj_t self_in, int n_args, int n_kw, const mp_o
}
mp_obj_t
*
vargs
=
mp_obj_new_tuple_reverse
(
n_args
,
args
+
2
*
n_kw
);
mp_map_t
*
kw_args
=
mp_map_new
(
MP_MAP_QSTR
,
n_kw
);
mp_map_t
*
kw_args
=
mp_map_new
(
n_kw
);
for
(
int
i
=
0
;
i
<
2
*
n_kw
;
i
+=
2
)
{
qstr
name
=
mp_obj_str_get
(
args
[
i
+
1
]);
mp_
qstr_
map_lookup
(
kw_args
,
name
,
true
)
->
value
=
args
[
i
];
mp_map_lookup
(
kw_args
,
MP_OBJ_NEW_QSTR
(
name
)
,
MP_MAP_LOOKUP_ADD_IF_NOT_FOUND
)
->
value
=
args
[
i
];
}
mp_obj_t
res
=
((
mp_fun_kw_t
)
self
->
fun
)(
vargs
,
kw_args
);
/
*
TODO clean up vargs and kw_args
*/
/
/
TODO clean up vargs and kw_args
return
res
;
}
...
...
py/objinstance.c
View file @
38a2da68
...
...
@@ -30,12 +30,12 @@ type needs to be specified dynamically
mp_obj_t
mp_obj_instance_load_attr
(
mp_obj_t
self_in
,
qstr
attr
)
{
// logic: look in obj members then class locals (TODO check this against CPython)
mp_obj_instance_t
*
self
=
self_in
;
mp_map_elem_t
*
elem
=
mp_
qstr_
map_lookup
(
self
->
members
,
attr
,
false
);
mp_map_elem_t
*
elem
=
mp_map_lookup
(
self
->
members
,
MP_OBJ_NEW_QSTR
(
attr
)
,
MP_MAP_LOOKUP
);
if
(
elem
!=
NULL
)
{
// object member, always treated as a value
return
elem
->
value
;
}
elem
=
mp_
qstr_
map_lookup
(
mp_obj_class_get_locals
(
self
->
class
),
attr
,
false
);
elem
=
mp_map_lookup
(
mp_obj_class_get_locals
(
self
->
class
),
MP_OBJ_NEW_QSTR
(
attr
)
,
MP_MAP_LOOKUP
);
if
(
elem
!=
NULL
)
{
if
(
mp_obj_is_callable
(
elem
->
value
))
{
// class member is callable so build a bound method
...
...
@@ -51,14 +51,14 @@ mp_obj_t mp_obj_instance_load_attr(mp_obj_t self_in, qstr attr) {
void
mp_obj_instance_load_method
(
mp_obj_t
self_in
,
qstr
attr
,
mp_obj_t
*
dest
)
{
// logic: look in obj members then class locals (TODO check this against CPython)
mp_obj_instance_t
*
self
=
self_in
;
mp_map_elem_t
*
elem
=
mp_
qstr_
map_lookup
(
self
->
members
,
attr
,
false
);
mp_map_elem_t
*
elem
=
mp_map_lookup
(
self
->
members
,
MP_OBJ_NEW_QSTR
(
attr
)
,
MP_MAP_LOOKUP
);
if
(
elem
!=
NULL
)
{
// object member, always treated as a value
dest
[
1
]
=
elem
->
value
;
dest
[
0
]
=
NULL
;
return
;
}
elem
=
mp_
qstr_
map_lookup
(
mp_obj_class_get_locals
(
self
->
class
),
attr
,
false
);
elem
=
mp_map_lookup
(
mp_obj_class_get_locals
(
self
->
class
),
MP_OBJ_NEW_QSTR
(
attr
)
,
MP_MAP_LOOKUP
);
if
(
elem
!=
NULL
)
{
if
(
mp_obj_is_callable
(
elem
->
value
))
{
// class member is callable so build a bound method
...
...
@@ -81,11 +81,11 @@ void mp_obj_instance_load_method(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
void
mp_obj_instance_store_attr
(
mp_obj_t
self_in
,
qstr
attr
,
mp_obj_t
value
)
{
// logic: look in class locals (no add) then obj members (add) (TODO check this against CPython)
mp_obj_instance_t
*
self
=
self_in
;
mp_map_elem_t
*
elem
=
mp_
qstr_
map_lookup
(
mp_obj_class_get_locals
(
self
->
class
),
attr
,
false
);
mp_map_elem_t
*
elem
=
mp_map_lookup
(
mp_obj_class_get_locals
(
self
->
class
),
MP_OBJ_NEW_QSTR
(
attr
)
,
MP_MAP_LOOKUP
);
if
(
elem
!=
NULL
)
{
elem
->
value
=
value
;
}
else
{
mp_
qstr_
map_lookup
(
self
->
members
,
attr
,
true
)
->
value
=
value
;
mp_map_lookup
(
self
->
members
,
MP_OBJ_NEW_QSTR
(
attr
)
,
MP_MAP_LOOKUP_ADD_IF_NOT_FOUND
)
->
value
=
value
;
}
}
...
...
@@ -98,6 +98,6 @@ mp_obj_t mp_obj_new_instance(mp_obj_t class) {
mp_obj_instance_t
*
o
=
m_new_obj
(
mp_obj_instance_t
);
o
->
base
.
type
=
&
instance_type
;
o
->
class
=
class
;
o
->
members
=
mp_map_new
(
MP_MAP_QSTR
,
0
);
o
->
members
=
mp_map_new
(
0
);
return
o
;
}
py/objlist.c
View file @
38a2da68
...
...
@@ -146,8 +146,6 @@ static void mp_quicksort(mp_obj_t *head, mp_obj_t *tail, mp_obj_t key_fn, bool r
static
mp_obj_t
list_sort
(
mp_obj_t
args
,
mp_map_t
*
kwargs
)
{
mp_obj_t
*
args_items
=
NULL
;
uint
args_len
=
0
;
qstr
key_idx
=
qstr_from_str_static
(
"key"
);
qstr
reverse_idx
=
qstr_from_str_static
(
"reverse"
);
assert
(
MP_OBJ_IS_TYPE
(
args
,
&
tuple_type
));
mp_obj_tuple_get
(
args
,
&
args_len
,
&
args_items
);
...
...
@@ -158,8 +156,8 @@ static mp_obj_t list_sort(mp_obj_t args, mp_map_t *kwargs) {
}
mp_obj_list_t
*
self
=
args_items
[
0
];
if
(
self
->
len
>
1
)
{
mp_map_elem_t
*
keyfun
=
mp_
qstr_
map_lookup
(
kwargs
,
key_idx
,
false
);
mp_map_elem_t
*
reverse
=
mp_
qstr_
map_lookup
(
kwargs
,
reverse_idx
,
false
);
mp_map_elem_t
*
keyfun
=
mp_map_lookup
(
kwargs
,
MP_OBJ_NEW_QSTR
(
qstr_from_str_static
(
"key"
)),
MP_MAP_LOOKUP
);
mp_map_elem_t
*
reverse
=
mp_map_lookup
(
kwargs
,
MP_OBJ_NEW_QSTR
(
qstr_from_str_static
(
"reverse"
)),
MP_MAP_LOOKUP
);
mp_quicksort
(
self
->
items
,
self
->
items
+
self
->
len
-
1
,
keyfun
?
keyfun
->
value
:
NULL
,
reverse
&&
reverse
->
value
?
rt_is_true
(
reverse
->
value
)
:
false
);
...
...
py/objmodule.c
View file @
38a2da68
...
...
@@ -32,8 +32,8 @@ mp_obj_t mp_obj_new_module(qstr module_name) {
mp_obj_module_t
*
o
=
m_new_obj
(
mp_obj_module_t
);
o
->
base
.
type
=
&
module_type
;
o
->
name
=
module_name
;
o
->
globals
=
mp_map_new
(
MP_MAP_QSTR
,
1
);
mp_
qstr_
map_lookup
(
o
->
globals
,
MP_QSTR___name__
,
true
)
->
value
=
mp_obj_new_str
(
module_name
);
o
->
globals
=
mp_map_new
(
1
);
mp_map_lookup
(
o
->
globals
,
MP_OBJ_NEW_QSTR
(
MP_QSTR___name__
)
,
MP_MAP_LOOKUP_ADD_IF_NOT_FOUND
)
->
value
=
mp_obj_new_str
(
module_name
);
return
o
;
}
...
...
py/runtime.c
View file @
38a2da68
...
...
@@ -68,64 +68,69 @@ static mp_code_t *unique_codes = NULL;
FILE
*
fp_write_code
=
NULL
;
#endif
// a good optimising compiler will inline this if necessary
static
void
mp_map_add_qstr
(
mp_map_t
*
map
,
qstr
qstr
,
mp_obj_t
value
)
{
mp_map_lookup
(
map
,
MP_OBJ_NEW_QSTR
(
qstr
),
MP_MAP_LOOKUP_ADD_IF_NOT_FOUND
)
->
value
=
value
;
}
void
rt_init
(
void
)
{
// locals = globals for outer module (see Objects/frameobject.c/PyFrame_New())
map_locals
=
map_globals
=
mp_map_new
(
MP_MAP_QSTR
,
1
);
mp_
qstr_map_lookup
(
map_globals
,
MP_QSTR___name__
,
true
)
->
value
=
mp_obj_new_str
(
MP_QSTR___main__
);
map_locals
=
map_globals
=
mp_map_new
(
1
);
mp_
map_add_qstr
(
map_globals
,
MP_QSTR___name__
,
mp_obj_new_str
(
MP_QSTR___main__
)
)
;
// init built-in hash table
mp_map_init
(
&
map_builtins
,
MP_MAP_QSTR
,
3
);
mp_map_init
(
&
map_builtins
,
3
);
// built-in exceptions (TODO, make these proper classes)
mp_
qstr_map_lookup
(
&
map_builtins
,
MP_QSTR_AttributeError
,
true
)
->
value
=
mp_obj_new_exception
(
MP_QSTR_AttributeError
);
mp_
qstr_map_lookup
(
&
map_builtins
,
MP_QSTR_IndexError
,
true
)
->
value
=
mp_obj_new_exception
(
MP_QSTR_IndexError
);
mp_
qstr_map_lookup
(
&
map_builtins
,
MP_QSTR_KeyError
,
true
)
->
value
=
mp_obj_new_exception
(
MP_QSTR_KeyError
);
mp_
qstr_map_lookup
(
&
map_builtins
,
MP_QSTR_NameError
,
true
)
->
value
=
mp_obj_new_exception
(
MP_QSTR_NameError
);
mp_
qstr_map_lookup
(
&
map_builtins
,
MP_QSTR_TypeError
,
true
)
->
value
=
mp_obj_new_exception
(
MP_QSTR_TypeError
);
mp_
qstr_map_lookup
(
&
map_builtins
,
MP_QSTR_SyntaxError
,
true
)
->
value
=
mp_obj_new_exception
(
MP_QSTR_SyntaxError
);
mp_
qstr_map_lookup
(
&
map_builtins
,
MP_QSTR_ValueError
,
true
)
->
value
=
mp_obj_new_exception
(
MP_QSTR_ValueError
);
mp_
qstr_map_lookup
(
&
map_builtins
,
MP_QSTR_OSError
,
true
)
->
value
=
mp_obj_new_exception
(
MP_QSTR_OSError
);
mp_
map_add_qstr
(
&
map_builtins
,
MP_QSTR_AttributeError
,
mp_obj_new_exception
(
MP_QSTR_AttributeError
)
)
;
mp_
map_add_qstr
(
&
map_builtins
,
MP_QSTR_IndexError
,
mp_obj_new_exception
(
MP_QSTR_IndexError
)
)
;
mp_
map_add_qstr
(
&
map_builtins
,
MP_QSTR_KeyError
,
mp_obj_new_exception
(
MP_QSTR_KeyError
)
)
;
mp_
map_add_qstr
(
&
map_builtins
,
MP_QSTR_NameError
,
mp_obj_new_exception
(
MP_QSTR_NameError
)
)
;
mp_
map_add_qstr
(
&
map_builtins
,
MP_QSTR_TypeError
,
mp_obj_new_exception
(
MP_QSTR_TypeError
)
)
;
mp_
map_add_qstr
(
&
map_builtins
,
MP_QSTR_SyntaxError
,
mp_obj_new_exception
(
MP_QSTR_SyntaxError
)
)
;
mp_
map_add_qstr
(
&
map_builtins
,
MP_QSTR_ValueError
,
mp_obj_new_exception
(
MP_QSTR_ValueError
)
)
;
mp_
map_add_qstr
(
&
map_builtins
,
MP_QSTR_OSError
,
mp_obj_new_exception
(
MP_QSTR_OSError
)
)
;
// built-in objects
mp_
qstr_map_lookup
(
&
map_builtins
,
MP_QSTR_Ellipsis
,
true
)
->
value
=
mp_const_ellipsis
;
mp_
map_add_qstr
(
&
map_builtins
,
MP_QSTR_Ellipsis
,
mp_const_ellipsis
)
;
// built-in core functions
mp_
qstr_map_lookup
(
&
map_builtins
,
MP_QSTR___build_class__
,
true
)
->
value
=
(
mp_obj_t
)
&
mp_builtin___build_class___obj
;
mp_
qstr_map_lookup
(
&
map_builtins
,
MP_QSTR___repl_print__
,
true
)
->
value
=
rt_make_function_1
(
mp_builtin___repl_print__
);
mp_
map_add_qstr
(
&
map_builtins
,
MP_QSTR___build_class__
,
(
mp_obj_t
)
&
mp_builtin___build_class___obj
)
;
mp_
map_add_qstr
(
&
map_builtins
,
MP_QSTR___repl_print__
,
rt_make_function_1
(
mp_builtin___repl_print__
)
)
;
// built-in types
mp_
qstr_map_lookup
(
&
map_builtins
,
MP_QSTR_bool
,
true
)
->
value
=
(
mp_obj_t
)
&
bool_type
;
mp_
map_add_qstr
(
&
map_builtins
,
MP_QSTR_bool
,
(
mp_obj_t
)
&
bool_type
)
;
#if MICROPY_ENABLE_FLOAT
mp_
qstr_map_lookup
(
&
map_builtins
,
MP_QSTR_complex
,
true
)
->
value
=
(
mp_obj_t
)
&
complex_type
;
mp_
map_add_qstr
(
&
map_builtins
,
MP_QSTR_complex
,
(
mp_obj_t
)
&
complex_type
)
;
#endif
mp_
qstr_map_lookup
(
&
map_builtins
,
MP_QSTR_dict
,
true
)
->
value
=
(
mp_obj_t
)
&
dict_type
;
mp_
map_add_qstr
(
&
map_builtins
,
MP_QSTR_dict
,
(
mp_obj_t
)
&
dict_type
)
;
#if MICROPY_ENABLE_FLOAT
mp_
qstr_map_lookup
(
&
map_builtins
,
MP_QSTR_float
,
true
)
->
value
=
(
mp_obj_t
)
&
float_type
;
mp_
map_add_qstr
(
&
map_builtins
,
MP_QSTR_float
,
(
mp_obj_t
)
&
float_type
)
;
#endif
mp_
qstr_map_lookup
(
&
map_builtins
,
MP_QSTR_int
,
true
)
->
value
=
(
mp_obj_t
)
&
int_type
;
mp_
qstr_map_lookup
(
&
map_builtins
,
MP_QSTR_list
,
true
)
->
value
=
(
mp_obj_t
)
&
list_type
;
mp_
qstr_map_lookup
(
&
map_builtins
,
MP_QSTR_set
,
true
)
->
value
=
(
mp_obj_t
)
&
set_type
;
mp_
qstr_map_lookup
(
&
map_builtins
,
MP_QSTR_tuple
,
true
)
->
value
=
(
mp_obj_t
)
&
tuple_type
;
mp_
qstr_map_lookup
(
&
map_builtins
,
MP_QSTR_type
,
true
)
->
value
=
(
mp_obj_t
)
&
mp_builtin_type_obj
;
// TODO
mp_
map_add_qstr
(
&
map_builtins
,
MP_QSTR_int
,
(
mp_obj_t
)
&
int_type
)
;
mp_
map_add_qstr
(
&
map_builtins
,
MP_QSTR_list
,
(
mp_obj_t
)
&
list_type
)
;
mp_
map_add_qstr
(
&
map_builtins
,
MP_QSTR_set
,
(
mp_obj_t
)
&
set_type
)
;
mp_
map_add_qstr
(
&
map_builtins
,
MP_QSTR_tuple
,
(
mp_obj_t
)
&
tuple_type
)
;
mp_
map_add_qstr
(
&
map_builtins
,
MP_QSTR_type
,
(
mp_obj_t
)
&
mp_builtin_type_obj
)
;
// TODO
// built-in user functions; TODO covert all to &mp_builtin_xxx's
mp_
qstr_map_lookup
(
&
map_builtins
,
MP_QSTR_abs
,
true
)
->
value
=
rt_make_function_1
(
mp_builtin_abs
);
mp_
qstr_map_lookup
(
&
map_builtins
,
MP_QSTR_all
,
true
)
->
value
=
rt_make_function_1
(
mp_builtin_all
);
mp_
qstr_map_lookup
(
&
map_builtins
,
MP_QSTR_any
,
true
)
->
value
=
rt_make_function_1
(
mp_builtin_any
);
mp_
qstr_map_lookup
(
&
map_builtins
,
MP_QSTR_callable
,
true
)
->
value
=
rt_make_function_1
(
mp_builtin_callable
);
mp_
qstr_map_lookup
(
&
map_builtins
,
MP_QSTR_chr
,
true
)
->
value
=
rt_make_function_1
(
mp_builtin_chr
);
mp_
qstr_map_lookup
(
&
map_builtins
,
MP_QSTR_divmod
,
true
)
->
value
=
rt_make_function_2
(
mp_builtin_divmod
);
mp_
qstr_map_lookup
(
&
map_builtins
,
MP_QSTR_hash
,
true
)
->
value
=
(
mp_obj_t
)
&
mp_builtin_hash_obj
;
mp_
qstr_map_lookup
(
&
map_builtins
,
MP_QSTR_iter
,
true
)
->
value
=
(
mp_obj_t
)
&
mp_builtin_iter_obj
;
mp_
qstr_map_lookup
(
&
map_builtins
,
MP_QSTR_len
,
true
)
->
value
=
rt_make_function_1
(
mp_builtin_len
);
mp_
qstr_map_lookup
(
&
map_builtins
,
MP_QSTR_max
,
true
)
->
value
=
rt_make_function_var
(
1
,
mp_builtin_max
);
mp_
qstr_map_lookup
(
&
map_builtins
,
MP_QSTR_min
,
true
)
->
value
=
rt_make_function_var
(
1
,
mp_builtin_min
);
mp_
qstr_map_lookup
(
&
map_builtins
,
MP_QSTR_next
,
true
)
->
value
=
(
mp_obj_t
)
&
mp_builtin_next_obj
;
mp_
qstr_map_lookup
(
&
map_builtins
,
MP_QSTR_ord
,
true
)
->
value
=
rt_make_function_1
(
mp_builtin_ord
);
mp_
qstr_map_lookup
(
&
map_builtins
,
MP_QSTR_pow
,
true
)
->
value
=
rt_make_function_var
(
2
,
mp_builtin_pow
);
mp_
qstr_map_lookup
(
&
map_builtins
,
MP_QSTR_print
,
true
)
->
value
=
rt_make_function_var
(
0
,
mp_builtin_print
);
mp_
qstr_map_lookup
(
&
map_builtins
,
MP_QSTR_range
,
true
)
->
value
=
rt_make_function_var
(
1
,
mp_builtin_range
);
mp_
qstr_map_lookup
(
&
map_builtins
,
MP_QSTR_sum
,
true
)
->
value
=
rt_make_function_var
(
1
,
mp_builtin_sum
);
mp_
map_add_qstr
(
&
map_builtins
,
MP_QSTR_abs
,
rt_make_function_1
(
mp_builtin_abs
)
)
;
mp_
map_add_qstr
(
&
map_builtins
,
MP_QSTR_all
,
rt_make_function_1
(
mp_builtin_all
)
)
;
mp_
map_add_qstr
(
&
map_builtins
,
MP_QSTR_any
,
rt_make_function_1
(
mp_builtin_any
)
)
;
mp_
map_add_qstr
(
&
map_builtins
,
MP_QSTR_callable
,
rt_make_function_1
(
mp_builtin_callable
)
)
;
mp_
map_add_qstr
(
&
map_builtins
,
MP_QSTR_chr
,
rt_make_function_1
(
mp_builtin_chr
)
)
;
mp_
map_add_qstr
(
&
map_builtins
,
MP_QSTR_divmod
,
rt_make_function_2
(
mp_builtin_divmod
)
)
;
mp_
map_add_qstr
(
&
map_builtins
,
MP_QSTR_hash
,
(
mp_obj_t
)
&
mp_builtin_hash_obj
)
;
mp_
map_add_qstr
(
&
map_builtins
,
MP_QSTR_iter
,
(
mp_obj_t
)
&
mp_builtin_iter_obj
)
;
mp_
map_add_qstr
(
&
map_builtins
,
MP_QSTR_len
,
rt_make_function_1
(
mp_builtin_len
)
)
;
mp_
map_add_qstr
(
&
map_builtins
,
MP_QSTR_max
,
rt_make_function_var
(
1
,
mp_builtin_max
)
)
;
mp_
map_add_qstr
(
&
map_builtins
,
MP_QSTR_min
,
rt_make_function_var
(
1
,
mp_builtin_min
)
)
;
mp_
map_add_qstr
(
&
map_builtins
,
MP_QSTR_next
,
(
mp_obj_t
)
&
mp_builtin_next_obj
)
;
mp_
map_add_qstr
(
&
map_builtins
,
MP_QSTR_ord
,
rt_make_function_1
(
mp_builtin_ord
)
)
;
mp_
map_add_qstr
(
&
map_builtins
,
MP_QSTR_pow
,
rt_make_function_var
(
2
,
mp_builtin_pow
)
)
;
mp_
map_add_qstr
(
&
map_builtins
,
MP_QSTR_print
,
rt_make_function_var
(
0
,
mp_builtin_print
)
)
;
mp_
map_add_qstr
(
&
map_builtins
,
MP_QSTR_range
,
rt_make_function_var
(
1
,
mp_builtin_range
)
)
;
mp_
map_add_qstr
(
&
map_builtins
,
MP_QSTR_sum
,
rt_make_function_var
(
1
,
mp_builtin_sum
)
)
;
next_unique_code_id
=
1
;
// 0 indicates "no code"
unique_codes_alloc
=
0
;
...
...
@@ -362,11 +367,11 @@ mp_obj_t rt_load_const_str(qstr qstr) {
mp_obj_t
rt_load_name
(
qstr
qstr
)
{
// logic: search locals, globals, builtins
DEBUG_OP_printf
(
"load name %s
\n
"
,
qstr_str
(
qstr
));
mp_map_elem_t
*
elem
=
mp_
qstr_
map_lookup
(
map_locals
,
qstr
,
false
);
mp_map_elem_t
*
elem
=
mp_map_lookup
(
map_locals
,
MP_OBJ_NEW_QSTR
(
qstr
)
,
MP_MAP_LOOKUP
);
if
(
elem
==
NULL
)
{
elem
=
mp_
qstr_
map_lookup
(
map_globals
,
qstr
,
false
);
elem
=
mp_map_lookup
(
map_globals
,
MP_OBJ_NEW_QSTR
(
qstr
)
,
MP_MAP_LOOKUP
);
if
(
elem
==
NULL
)
{
elem
=
mp_
qstr_
map_lookup
(
&
map_builtins
,
qstr
,
false
);
elem
=
mp_map_lookup
(
&
map_builtins
,
MP_OBJ_NEW_QSTR
(
qstr
)
,
MP_MAP_LOOKUP
);
if
(
elem
==
NULL
)
{
nlr_jump
(
mp_obj_new_exception_msg_1_arg
(
MP_QSTR_NameError
,
"name '%s' is not defined"
,
qstr_str
(
qstr
)));
}
...
...
@@ -378,9 +383,9 @@ mp_obj_t rt_load_name(qstr qstr) {
mp_obj_t
rt_load_global
(
qstr
qstr
)
{
// logic: search globals, builtins
DEBUG_OP_printf
(
"load global %s
\n
"
,
qstr_str
(
qstr
));
mp_map_elem_t
*
elem
=
mp_
qstr_
map_lookup
(
map_globals
,
qstr
,
false
);
mp_map_elem_t
*
elem
=
mp_map_lookup
(
map_globals
,
MP_OBJ_NEW_QSTR
(
qstr
)
,
MP_MAP_LOOKUP
);
if
(
elem
==
NULL
)
{
elem
=
mp_
qstr_
map_lookup
(
&
map_builtins
,
qstr
,
false
);
elem
=
mp_map_lookup
(
&
map_builtins
,
MP_OBJ_NEW_QSTR
(
qstr
)
,
MP_MAP_LOOKUP
);
if
(
elem
==
NULL
)
{
nlr_jump
(
mp_obj_new_exception_msg_1_arg
(
MP_QSTR_NameError
,
"name '%s' is not defined"
,
qstr_str
(
qstr
)));
}
...
...
@@ -390,7 +395,7 @@ mp_obj_t rt_load_global(qstr qstr) {
mp_obj_t
rt_load_build_class
(
void
)
{
DEBUG_OP_printf
(
"load_build_class
\n
"
);
mp_map_elem_t
*
elem
=
mp_
qstr_
map_lookup
(
&
map_builtins
,
MP_QSTR
_
__build_class__
,
false
);
mp_map_elem_t
*
elem
=
mp_map_lookup
(
&
map_builtins
,
MP_
OBJ_NEW_QSTR
(
MP_
QSTR__
_
build_class__
)
,
MP_MAP_LOOKUP
);
if
(
elem
==
NULL
)
{
nlr_jump
(
mp_obj_new_exception_msg
(
MP_QSTR_NameError
,
"name '__build_class__' is not defined"
));
}
...
...
@@ -407,12 +412,12 @@ void rt_set_cell(mp_obj_t cell, mp_obj_t val) {
void
rt_store_name
(
qstr
qstr
,
mp_obj_t
obj
)
{
DEBUG_OP_printf
(
"store name %s <- %p
\n
"
,
qstr_str
(
qstr
),
obj
);
mp_
qstr_
map_lookup
(
map_locals
,
qstr
,
true
)
->
value
=
obj
;
mp_map_lookup
(
map_locals
,
MP_OBJ_NEW_QSTR
(
qstr
)
,
MP_MAP_LOOKUP_ADD_IF_NOT_FOUND
)
->
value
=
obj
;
}
void
rt_store_global
(
qstr
qstr
,
mp_obj_t
obj
)
{
DEBUG_OP_printf
(
"store global %s <- %p
\n
"
,
qstr_str
(
qstr
),
obj
);
mp_
qstr_
map_lookup
(
map_globals
,
qstr
,
true
)
->
value
=
obj
;
mp_map_lookup
(
map_globals
,
MP_OBJ_NEW_QSTR
(
qstr
)
,
MP_MAP_LOOKUP_ADD_IF_NOT_FOUND
)
->
value
=
obj
;
}
mp_obj_t
rt_unary_op
(
int
op
,
mp_obj_t
arg
)
{
...
...
@@ -772,7 +777,7 @@ mp_obj_t rt_store_map(mp_obj_t map, mp_obj_t key, mp_obj_t value) {
mp_obj_t
rt_load_attr
(
mp_obj_t
base
,
qstr
attr
)
{
DEBUG_OP_printf
(
"load attr %s
\n
"
,
qstr_str
(
attr
));
if
(
MP_OBJ_IS_TYPE
(
base
,
&
class_type
))
{
mp_map_elem_t
*
elem
=
mp_
qstr_
map_lookup
(
mp_obj_class_get_locals
(
base
),
attr
,
false
);
mp_map_elem_t
*
elem
=
mp_map_lookup
(
mp_obj_class_get_locals
(
base
),
MP_OBJ_NEW_QSTR
(
attr
)
,
MP_MAP_LOOKUP
);
if
(
elem
==
NULL
)
{
// TODO what about generic method lookup?