summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Leech <andrew.leech@planetinnovation.com.au>2020-06-10 10:46:38 +1000
committerDamien George <damien.p.george@gmail.com>2020-06-10 22:03:39 +1000
commit95cbe6b65ec84793f0f5ac2fd89c1375969a3bea (patch)
treed204f4f326596d904cdb30efab5ead7695f1a012
parent28370c04509a6255cd3d6b9424443a5b57bb7467 (diff)
py/objtype: Use mp_obj_dict_copy() for creating obj.__dict__ attribute.
The resulting dict is now marked as read-only (is_fixed=1) to enforce the fact that changes to this dict will not be reflected in the class instance. This commit reduces code size by about 20 bytes, and should be more efficient because it creates a direct copy of the dict rather than reinserting all elements.
-rw-r--r--py/objtype.c17
1 files changed, 7 insertions, 10 deletions
diff --git a/py/objtype.c b/py/objtype.c
index cb0fb267c..a539fcab2 100644
--- a/py/objtype.c
+++ b/py/objtype.c
@@ -588,16 +588,13 @@ STATIC void mp_obj_instance_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *des
#if MICROPY_CPYTHON_COMPAT
if (attr == MP_QSTR___dict__) {
// Create a new dict with a copy of the instance's map items.
- // This creates, unlike CPython, a 'read-only' __dict__: modifying
- // it will not result in modifications to the actual instance members.
- mp_map_t *map = &self->members;
- mp_obj_t attr_dict = mp_obj_new_dict(map->used);
- for (size_t i = 0; i < map->alloc; ++i) {
- if (mp_map_slot_is_filled(map, i)) {
- mp_obj_dict_store(attr_dict, map->table[i].key, map->table[i].value);
- }
- }
- dest[0] = attr_dict;
+ // This creates, unlike CPython, a read-only __dict__ that can't be modified.
+ mp_obj_dict_t dict;
+ dict.base.type = &mp_type_dict;
+ dict.map = self->members;
+ dest[0] = mp_obj_dict_copy(MP_OBJ_FROM_PTR(&dict));
+ mp_obj_dict_t *dest_dict = MP_OBJ_TO_PTR(dest[0]);
+ dest_dict->map.is_fixed = 1;
return;
}
#endif