MemberInfo *Type::findMember(const char *name, bool includeBases) { if (cached) { MemberInfo **minfo = memberCache.get(name); if (minfo) { return *minfo; } return NULL; } for (UTsize i = 0; i < members.size(); i++) { MemberInfo *m = members.at(i); if (!strcmp(m->getName(), name)) { return m; } } if (includeBases && baseType) { MemberInfo *m = baseType->findMember(name, true); return m; } return NULL; }
void Type::cache() { if (baseType) { baseType->cache(); } if (cached) { return; } cached = true; MemberTypes types; types.constructor = true; types.field = true; types.method = true; types.property = true; utArray<MemberInfo *> allMembers; findMembers(types, allMembers, true, true); maxMemberOrdinal = 0; for (UTsize i = 0; i < allMembers.size(); i++) { MemberInfo *mi = allMembers.at(i); if (mi->ordinal > maxMemberOrdinal) { maxMemberOrdinal = mi->ordinal; } } maxMemberOrdinal++; memberInfoOrdinalLookup = (MemberInfo **)lmAlloc(NULL, sizeof(MemberInfo *) * maxMemberOrdinal); memset(memberInfoOrdinalLookup, 0, sizeof(MemberInfo *) * maxMemberOrdinal); for (int i = (int)(allMembers.size() - 1); i >= 0; i--) { MemberInfo *mi = allMembers.at(i); memberCache.insert(mi->getName(), mi); memberInfoOrdinalLookup[mi->getOrdinal()] = mi; } }
void Type::assignOrdinals() { if (baseType) { baseType->assignOrdinals(); } // already assigned? if (members.size() && members.at(0)->ordinal) { return; } MemberTypes types; types.constructor = true; types.field = true; types.method = true; types.property = true; utArray<MemberInfo *> allMembers; findMembers(types, allMembers, true, true); int maxOrdinal = 0; for (UTsize i = 0; i < allMembers.size(); i++) { MemberInfo *mi = allMembers.at(i); if (mi->getOrdinal() > maxOrdinal) { maxOrdinal = mi->getOrdinal(); } } // and assign int start = maxOrdinal + 1; for (UTsize i = 0; i < allMembers.size(); i++) { MemberInfo *mi = allMembers.at(i); if (!mi->ordinal) { lmAssert(mi->getDeclaringType() == this, "ordinal being assigned to non-declared member"); UTsize j; for (j = 0; j < allMembers.size(); j++) { MemberInfo *other = allMembers.at(j); if (other->getDeclaringType() == this) { continue; } if (strcmp(other->getName(), mi->getName())) { continue; } break; } if (j == allMembers.size()) { mi->setOrdinal(start++); } else { mi->setOrdinal(allMembers.at(j)->getOrdinal()); } } } }
void LSLuaState::cacheAssemblyTypes(Assembly *assembly, utArray<Type *>& types) { // setup assembly type lookup field lua_rawgeti(L, LUA_GLOBALSINDEX, LSASSEMBLYLOOKUP); lua_pushlightuserdata(L, assembly); lua_setfield(L, -2, assembly->getName().c_str()); lua_pop(L, 1); assembly->ordinalTypes = new Type *[types.size() + 1]; for (UTsize j = 0; j < types.size(); j++) { Type *type = types.at(j); assembly->types.insert(type->getName(), type); lmAssert(type->getTypeID() > 0 && type->getTypeID() <= (LSTYPEID)types.size(), "LSLuaState::cacheAssemblyTypes TypeID out of range"); assembly->ordinalTypes[type->getTypeID()] = type; const char *typeName = type->getFullName().c_str(); // fast access cache if (!strcmp(typeName, "system.Object")) { objectType = type; } else if (!strcmp(typeName, "system.Null")) { nullType = type; } else if (!strcmp(typeName, "system.Boolean")) { booleanType = type; } else if (!strcmp(typeName, "system.Number")) { numberType = type; } else if (!strcmp(typeName, "system.String")) { stringType = type; } else if (!strcmp(typeName, "system.Function")) { functionType = type; } else if (!strcmp(typeName, "system.Vector")) { vectorType = type; } lua_rawgeti(L, LUA_GLOBALSINDEX, LSINDEXMEMBERINFONAME); lua_pushlightuserdata(L, type); lua_gettable(L, -2); // cache all members for fast lookup of memberinfo -> pre-interned // lua string (interning strings is the devil's work) if (lua_isnil(L, -1)) { lua_pop(L, 1); utArray<MemberInfo *> members; MemberTypes types; types.method = true; types.field = true; types.property = true; type->findMembers(types, members, false); // cache the type to member info table lua_pushlightuserdata(L, type); lua_pushstring(L, type->getName()); lua_settable(L, -3); for (UTsize i = 0; i < members.size(); i++) { MemberInfo *mi = members.at(i); lua_pushlightuserdata(L, mi); lua_pushstring(L, mi->getName()); lua_settable(L, -3); } } else { lua_pop(L, 1); } lua_pop(L, 1); // if we weren't cached during assembly load, cache now if (!typeCache.get(type->getFullName())) { typeCache.insert(type->getFullName(), type); } } lmAssert(nullType, "LSLuaState::cacheAssemblyTypes - system.Null not found"); lmAssert(booleanType, "LSLuaState::cacheAssemblyTypes - system.Boolean not found"); lmAssert(numberType, "LSLuaState::cacheAssemblyTypes - system.Number not found"); lmAssert(stringType, "LSLuaState::cacheAssemblyTypes - system.String not found"); lmAssert(functionType, "LSLuaState::cacheAssemblyTypes - system.Function not found"); lmAssert(vectorType, "LSLuaState::cacheAssemblyTypes - system.Vector not found"); }