diff options
Diffstat (limited to 'py/objinstance.c')
-rw-r--r-- | py/objinstance.c | 103 |
1 files changed, 0 insertions, 103 deletions
diff --git a/py/objinstance.c b/py/objinstance.c deleted file mode 100644 index 9bb9acbd72..0000000000 --- a/py/objinstance.c +++ /dev/null @@ -1,103 +0,0 @@ -#include <stdlib.h> -#include <stdint.h> -#include <string.h> -#include <assert.h> - -#include "nlr.h" -#include "misc.h" -#include "mpconfig.h" -#include "mpqstr.h" -#include "obj.h" -#include "runtime.h" -#include "map.h" - -typedef struct _mp_obj_instance_t { - mp_obj_base_t base; - mp_obj_base_t *class; // points to a "class" object - mp_map_t *members; -} mp_obj_instance_t; - -/* -type needs to be specified dynamically - case O_OBJ: - { - py_map_elem_t *qn = py_qstr_map_lookup(o->u_obj.class->u_class.locals, qstr_from_str_static("__qualname__"), false); assert(qn != NULL); - assert(IS_O(qn->value, O_STR)); - return qstr_str(((py_obj_base_t*)qn->value)->u_str); - } - */ - -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_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_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 - return mp_obj_new_bound_meth(self_in, elem->value); - } else { - // class member is a value, so just return that value - return elem->value; - } - } - nlr_jump(mp_obj_new_exception_msg_2_args(MP_QSTR_AttributeError, "'%s' object has no attribute '%s'", mp_obj_get_type_str(self_in), qstr_str(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_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_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 - dest[1] = elem->value; - dest[0] = self_in; - return; - } else { - // class member is a value, so just return that value - dest[1] = elem->value; - dest[0] = NULL; - return; - } - } - - // no such method, so fall back to load attr - dest[1] = rt_load_attr(self_in, attr); - dest[0] = NULL; -} - -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_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_map_lookup(self->members, MP_OBJ_NEW_QSTR(attr), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = value; - } -} - -const mp_obj_type_t instance_type = { - { &mp_const_type }, - "instance", -}; - -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(0); - return o; -} |