+// ------------------------- constructors --------------------------------
+
+#define AVERAGE_NUMBER_OF_MEMBERS 8
+classinfo_t* classinfo_register(int access, const char*package, const char*name, int num_interfaces)
+{
+ classinfo_t*c = rfx_calloc(sizeof(classinfo_t)+(sizeof(classinfo_t*)*(num_interfaces+1)));
+ c->interfaces[0] = 0;
+ c->kind = INFOTYPE_CLASS;
+ c->access = access;
+ c->package = package;
+ c->name = name;
+ dict_put(registry_classes, c, c);
+ dict_init2(&c->members, &slotinfo_type, AVERAGE_NUMBER_OF_MEMBERS);
+ return c;
+}
+methodinfo_t* methodinfo_register_onclass(classinfo_t*cls, U8 access, const char*ns, const char*name)
+{
+ NEW(methodinfo_t,m);
+ m->kind = INFOTYPE_METHOD;
+ m->access = access;
+ m->name = name;
+ m->package = ns;
+ m->parent = cls;
+ dict_put(&cls->members, m, m);
+ return m;
+}
+varinfo_t* varinfo_register_onclass(classinfo_t*cls, U8 access, const char*ns, const char*name)
+{
+ NEW(varinfo_t,m);
+ m->kind = INFOTYPE_SLOT;
+ m->access = access;
+ m->name = name;
+ m->package = ns;
+ m->parent = cls;
+ dict_put(&cls->members, m, m);
+ return m;
+}
+methodinfo_t* methodinfo_register_global(U8 access, const char*package, const char*name)
+{
+ NEW(methodinfo_t, m);
+ m->kind = INFOTYPE_METHOD;
+ m->flags = FLAG_STATIC;
+ m->access = access;
+ m->package = package;
+ m->name = name;
+ m->parent = 0;
+ dict_put(registry_classes, m, m);
+ return m;
+}
+varinfo_t* varinfo_register_global(U8 access, const char*package, const char*name)
+{
+ NEW(varinfo_t, m);
+ m->kind = INFOTYPE_SLOT;
+ m->flags = FLAG_STATIC;
+ m->access = access;
+ m->package = package;
+ m->name = name;
+ m->parent = 0;
+ dict_put(registry_classes, m, m);
+ return m;
+}
+
+// --------------- builtin classes (from builtin.c) ----------------------
+
+void registry_init()
+{
+ if(!registry_classes)
+ registry_classes = builtin_getclasses();
+}
+slotinfo_t* registry_find(const char*package, const char*name)
+{
+ assert(registry_classes);
+ slotinfo_t tmp;
+ tmp.package = package;
+ tmp.name = name;
+ slotinfo_t* c = (slotinfo_t*)dict_lookup(registry_classes, &tmp);
+ /*if(c)
+ printf("%s.%s->%08x (%s.%s)\n", package, name, c, c->package, c->name);*/
+ return c;
+}
+slotinfo_t* registry_safefind(const char*package, const char*name)
+{
+ slotinfo_t*c = registry_find(package, name);
+ if(!c) {
+ printf("%s.%s\n", package, name);
+ }
+ assert(c);
+ return c;
+}
+void registry_dump()
+{
+ int t;
+ for(t=0;t<registry_classes->hashsize;t++) {
+ dictentry_t*e = registry_classes->slots[t];
+ while(e) {
+ slotinfo_t*i = (slotinfo_t*)e->key;
+ printf("[%s] %s.%s\n", access2str(i->access), i->package, i->name);
+ e = e->next;
+ }
+ }
+}
+
+memberinfo_t* registry_findmember(classinfo_t*cls, const char*ns, const char*name, char recursive)
+{
+ memberinfo_t tmp;
+ tmp.name = name;
+ tmp.package = ns?ns:"";
+
+ if(!recursive) {
+ return (memberinfo_t*)dict_lookup(&cls->members, &tmp);
+ }
+ /* look at classes directly extended by this class */
+ slotinfo_t*m = 0;
+ classinfo_t*s = cls;