Updated some terminology and added comments.
diff --git a/python/map.c b/python/map.c
index aed6ab5..8e5ac24 100644
--- a/python/map.c
+++ b/python/map.c
@@ -38,11 +38,15 @@
typedef struct {
PyObject_HEAD
PyObject* arena;
- uintptr_t field; // upb_fielddef*, low bit 1 == unset
+ // The field descriptor (upb_fielddef*).
+ // The low bit indicates whether the container is reified (see ptr below).
+ // - low bit set: repeated field is a stub (no underlying data).
+ // - low bit clear: repeated field is reified (points to upb_array).
+ uintptr_t field;
union {
- upb_map* map; // when set, the data for this array.
- PyObject* parent; // when unset owning pointer to parent message.
- };
+ PyObject* parent; // stub: owning pointer to parent message.
+ upb_map* map; // reified: the data for this array.
+ } ptr;
int version;
} PyUpb_MapContainer;
@@ -53,7 +57,7 @@
}
static upb_map* PyUpb_MapContainer_GetIfWritable(PyUpb_MapContainer* self) {
- return PyUpb_MapContainer_IsUnset(self) ? NULL : self->map;
+ return PyUpb_MapContainer_IsUnset(self) ? NULL : self->ptr.map;
}
static const upb_fielddef* PyUpb_MapContainer_GetField(
@@ -65,10 +69,11 @@
PyUpb_MapContainer* self = _self;
Py_DECREF(self->arena);
if (PyUpb_MapContainer_IsUnset(self)) {
- PyUpb_CMessage_CacheDelete(self->parent, PyUpb_MapContainer_GetField(self));
- Py_DECREF(self->parent);
+ PyUpb_CMessage_CacheDelete(self->ptr.parent,
+ PyUpb_MapContainer_GetField(self));
+ Py_DECREF(self->ptr.parent);
} else {
- PyUpb_ObjCache_Delete(self->map);
+ PyUpb_ObjCache_Delete(self->ptr.map);
}
PyUpb_Dealloc(_self);
}
@@ -80,26 +85,24 @@
: state->scalar_map_container_type;
}
-PyObject* PyUpb_MapContainer_NewUnset(PyObject* parent, const upb_fielddef* f,
- PyObject* arena) {
+PyObject* PyUpb_MapContainer_NewStub(PyObject* parent, const upb_fielddef* f,
+ PyObject* arena) {
PyTypeObject* cls = PyUpb_MapContainer_GetClass(f);
- // We are GC because of the MutableMapping base class. Ideally we could
- // implement them ourselves so we don't need a base so we don't need to be GC.
PyUpb_MapContainer* map = (void*)PyType_GenericAlloc(cls, 0);
map->arena = arena;
map->field = (uintptr_t)f | 1;
- map->parent = parent;
+ map->ptr.parent = parent;
map->version = 0;
Py_INCREF(arena);
Py_INCREF(parent);
return &map->ob_base;
}
-void PyUpb_MapContainer_SwitchToSet(PyObject* _self, upb_map* map) {
+void PyUpb_MapContainer_Reify(PyObject* _self, upb_map* map) {
PyUpb_MapContainer* self = (PyUpb_MapContainer*)_self;
PyUpb_ObjCache_Add(map, &self->ob_base);
- Py_DECREF(self->parent);
- self->map = map; // Overwrites self->parent.
+ Py_DECREF(self->ptr.parent);
+ self->ptr.map = map; // Overwrites self->ptr.parent.
self->field = self->field & ~(uintptr_t)1;
assert(!PyUpb_MapContainer_IsUnset(self));
}
@@ -121,8 +124,8 @@
const upb_fielddef* val_f = upb_msgdef_field(entry_m, 1);
map = upb_map_new(arena, upb_fielddef_type(key_f), upb_fielddef_type(val_f));
upb_msgval msgval = {.map_val = map};
- PyUpb_CMessage_SetConcreteSubobj(self->parent, f, msgval);
- PyUpb_MapContainer_SwitchToSet((PyObject*)self, map);
+ PyUpb_CMessage_SetConcreteSubobj(self->ptr.parent, f, msgval);
+ PyUpb_MapContainer_Reify((PyObject*)self, map);
return map;
}
@@ -294,21 +297,21 @@
return PyUpb_UpbToPy(u_val, val_f, self->arena);
}
-PyObject* PyUpb_MapContainer_GetOrCreateWrapper(upb_map* u_map,
+PyObject* PyUpb_MapContainer_GetOrCreateWrapper(upb_map* map,
const upb_fielddef* f,
PyObject* arena) {
- PyObject* ret = PyUpb_ObjCache_Get(u_map);
+ PyObject* ret = PyUpb_ObjCache_Get(map);
if (!ret) {
PyTypeObject* cls = PyUpb_MapContainer_GetClass(f);
PyUpb_MapContainer* map = (void*)PyType_GenericAlloc(cls, 0);
map->arena = arena;
map->field = (uintptr_t)f;
- map->map = u_map;
+ map->ptr.map = map;
map->version = 0;
ret = &map->ob_base;
Py_INCREF(arena);
- PyUpb_ObjCache_Add(u_map, ret);
+ PyUpb_ObjCache_Add(map, ret);
}
return ret;