예제 #1
0
파일: lsType.cpp 프로젝트: Ivory27/LoomSDK
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;
}
예제 #2
0
void Assembly::bootstrap()
{
    utArray<Type *> types;
    getTypes(types);

    Type *btype = vm->getType("system.Bootstrap");

    for (UTsize i = 0; i < types.size(); i++)
    {
        Type *type = types[i];

        if (type->getFullName() == "system.Null")
        {
            continue;
        }

        if (type->castToType(btype))
        {
            MemberInfo *mi = type->findMember("initialize");
            assert(mi);
            assert(mi->isMethod());

            MethodInfo *method = (MethodInfo *)mi;

            method->invoke(NULL, 0);
        }
    }
}
예제 #3
0
void NativeTypeBase::validate(Type *type)
{
    utArray<MemberInfo *> members;
    MemberTypes           mtypes;
    mtypes.property    = true;
    mtypes.field       = true;
    mtypes.constructor = true;
    mtypes.method      = true;
    type->findMembers(mtypes, members);

    lua_State *L = type->getAssembly()->getLuaState()->VM();

    for (UTsize i = 0; i < members.size(); i++)
    {
        MemberInfo *info = members.at(i);

        // if we don't have an ordinal we aren't native
        if (!info->isNative())
        {
            continue;
        }

        checkBridge(info);
    }
}
예제 #4
0
파일: health.cpp 프로젝트: jayridge/mongo
 void ReplSet::startHealthThreads() {
     MemberInfo* m = _members.head();
     while( m ) {
         FeedbackThread *f = new FeedbackThread();
         f->m = m;
         m = m->next();
     }
 }
예제 #5
0
파일: lsType.cpp 프로젝트: Ivory27/LoomSDK
FieldInfo *Type::findFieldInfoByName(const char *name)
{
    MemberInfo *mi = findMember(name);

    if (mi && mi->isField())
    {
        return (FieldInfo *)mi;
    }

    return NULL;
}
예제 #6
0
파일: lsType.cpp 프로젝트: Ivory27/LoomSDK
MethodInfo *Type::getMethodInfo(const utString& name)
{
    MemberInfo *minfo = findMember(name.c_str());

    if (minfo && minfo->isMethod())
    {
        return (MethodInfo *)minfo;
    }

    return NULL;
}
예제 #7
0
파일: lsType.cpp 프로젝트: Ivory27/LoomSDK
PropertyInfo *Type::findPropertyInfoByName(const char *name)
{
    MemberInfo *mi = findMember(name);

    if (mi && mi->isProperty())
    {
        return (PropertyInfo *)mi;
    }

    return NULL;
}
예제 #8
0
파일: lsType.cpp 프로젝트: Ivory27/LoomSDK
void Type::findMembers(const MemberTypes& memberTypes,
                       utArray<MemberInfo *>& membersOut, bool includeBases, bool includePropertyGetterSetters)
{
    if (!includeBases)
    {
        membersOut.clear();
    }

    for (size_t i = 0; i < members.size(); i++)
    {
        MemberInfo *m = members.at((int)i);

        if (m->isConstructor() && memberTypes.constructor)
        {
            membersOut.push_back(m);
        }

        if (m->isMethod() && memberTypes.method)
        {
            membersOut.push_back(m);
        }

        if (m->isField() && memberTypes.field)
        {
            membersOut.push_back(m);
        }

        if (m->isProperty() && memberTypes.property)
        {
            membersOut.push_back(m);

            if (includePropertyGetterSetters)
            {
                PropertyInfo *p = (PropertyInfo *)m;

                if (p->getter && (p->getter->getDeclaringType() == p->getDeclaringType()))
                {
                    membersOut.push_back(p->getter);
                }

                if (p->setter && (p->setter->getDeclaringType() == p->getDeclaringType()))
                {
                    membersOut.push_back(p->setter);
                }
            }
        }
    }

    if (baseType && includeBases)
    {
        baseType->findMembers(memberTypes, membersOut, true, includePropertyGetterSetters);
    }
}
예제 #9
0
파일: lsType.cpp 프로젝트: Ivory27/LoomSDK
ConstructorInfo *Type::getConstructor()
{
    for (UTsize i = 0; i < members.size(); i++)
    {
        MemberInfo *m = members.at(i);
        if (m->isConstructor())
        {
            return (ConstructorInfo *)m;
        }
    }

    return NULL;
}
예제 #10
0
파일: lsType.cpp 프로젝트: Ivory27/LoomSDK
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;
    }
}
예제 #11
0
파일: lsType.cpp 프로젝트: Ivory27/LoomSDK
bool Type::isNativeMemberPure(bool ignoreStaticMembers)
{
    //if (!attr.isNative)
    //	return false;

    for (UTsize i = 0; i < members.size(); i++)
    {
        MemberInfo *memberInfo = members.at(i);

        if (ignoreStaticMembers && memberInfo->isStatic())
        {
            continue;
        }

        if (memberInfo->isConstructor())
        {
            ConstructorInfo *cinfo = (ConstructorInfo *)memberInfo;
            if (cinfo->defaultConstructor)
            {
                continue;
            }
        }

        if (memberInfo->isConstructor() || memberInfo->isMethod())
        {
            if (!((MethodBase *)memberInfo)->isNative())
            {
                return false;
            }
        }

        if (memberInfo->isProperty())
        {
            PropertyInfo *pinfo = (PropertyInfo *)memberInfo;
            if (pinfo->getGetMethod() && !pinfo->getGetMethod()->isNative())
            {
                return false;
            }
            if (pinfo->getSetMethod() && !pinfo->getSetMethod()->isNative())
            {
                return false;
            }
        }

        if (memberInfo->isField())
        {
            if (!memberInfo->getOrdinal())
            {
                return false;
            }
        }
    }

    if (baseType)
    {
        return baseType->isNativeMemberPure();
    }

    return true;
}
예제 #12
0
파일: lsType.cpp 프로젝트: Ivory27/LoomSDK
MethodInfo *Type::findOperatorMethod(const utString& methodName)
{
    MemberInfo *mi = findMember(methodName.c_str());

    if (!mi)
    {
        return NULL;
    }
    if (!mi->isMethod())
    {
        return NULL;
    }
    if (!((MethodInfo *)mi)->isOperator())
    {
        return NULL;
    }

    return (MethodInfo *)mi;
}
예제 #13
0
void LSLuaState::invokeStaticMethod(const utString& typePath,
                                    const char *methodName, int numParameters)
{
    Type *type = getType(typePath.c_str());

    lmAssert(type, "LSLuaState::invokeStaticMethod unknown type: %s", typePath.c_str());

    MemberInfo *member = type->findMember(methodName);
    lmAssert(member, "LSLuaState::invokeStaticMethod unknown member: %s:%s", typePath.c_str(), methodName);
    if (!member->isMethod())
    {
        lmAssert(0, "LSLuaState::invokeStaticMethod member: %s:%s is not a method", typePath.c_str(), methodName);
    }

    MethodInfo *method = (MethodInfo *)member;

    lmAssert(method->isStatic(), "LSLuaState::invokeStaticMethod member: %s:%s is not a static method", typePath.c_str(), methodName);

    method->invoke(NULL, numParameters);
}
예제 #14
0
void cGuild::save()
{
	QStringList fields;
	fields.append( QString::number( serial_ ) );
	fields.append( QString( "'%1'" ).arg( PersistentBroker::instance()->quoteString( name_ ) ) );
	fields.append( QString( "'%1'" ).arg( PersistentBroker::instance()->quoteString( abbreviation_ ) ) );
	fields.append( QString( "'%1'" ).arg( PersistentBroker::instance()->quoteString( charta_ ) ) );
	fields.append( QString( "'%1'" ).arg( PersistentBroker::instance()->quoteString( website_ ) ) );
	fields.append( QString::number( alignment_ ) );
	if ( leader_ )
	{
		fields.append( QString::number( leader_->serial() ) );
	}
	else
	{
		fields.append( "-1" );
	}
	fields.append( QString::number( founded_.toTime_t() ) );
	if ( guildstone_ )
	{
		fields.append( QString::number( guildstone_->serial() ) );
	}
	else
	{
		fields.append( "-1" );
	}

	PersistentBroker::instance()->executeQuery( QString( "INSERT INTO guilds VALUES(%1);" ).arg( fields.join( "," ) ) );

	// Save Members/Canidates
	P_PLAYER player;

	foreach ( player, members_ )
	{
		MemberInfo* info = getMemberInfo( player );
		PersistentBroker::instance()->executeQuery( QString( "INSERT INTO guilds_members VALUES(%1,%2,%3,'%4',%5);" )
			.arg( serial_ ).arg( player->serial() ).arg( info->showSign() ? 1 : 0 )
			.arg( PersistentBroker::instance()->quoteString( info->guildTitle() ) )
			.arg( info->joined() ) );
	}
예제 #15
0
// TODO: Unify this with the JIT bc generator binary expressions
// https://theengineco.atlassian.net/browse/LOOM-640
// https://theengineco.atlassian.net/browse/LOOM-641
Expression *TypeCompiler::visit(BinaryOperatorExpression *expression)
{
    Tokens *tok = Tokens::getSingletonPtr();

    Expression *eleft  = expression->leftExpression;
    Expression *eright = expression->rightExpression;

    // operator overloads
    lmAssert(eleft->type && eright->type, "Untyped binary expression");

    const char *opmethod = tok->getOperatorMethodName(expression->op);
    if (opmethod)
    {
        MemberInfo *mi = eleft->type->findMember(opmethod);
        if (mi)
        {
            lmAssert(mi->isMethod(), "Non-method operator");
            MethodInfo *method = (MethodInfo *)mi;
            lmAssert(method->isOperator(), "Non-operator method");

            utArray<Expression *> args;
            args.push_back(eleft);
            args.push_back(eright);

            ExpDesc opcall;
            ExpDesc emethod;

            BC::singleVar(cs, &opcall, eleft->type->getName());
            BC::expString(cs, &emethod, method->getName());

            BC::expToNextReg(cs->fs, &opcall);
            BC::expToNextReg(cs->fs, &emethod);
            BC::expToVal(cs->fs, &emethod);
            BC::indexed(cs->fs, &opcall, &emethod);

            generateCall(&opcall, &args, method);

            expression->e = opcall;
            return expression;
        }
    }

    // dynamic cast
    if ((expression->op == &tok->KEYWORD_IS) ||
        (expression->op == &tok->KEYWORD_INSTANCEOF) ||
        (expression->op == &tok->KEYWORD_AS))
    {
        lmAssert(eleft->type && eright->type, "Untype expression");

        FuncState *fs = cs->fs;

        ExpDesc object;
        BC::singleVar(cs, &object, "Object");

        ExpDesc method;

        if (expression->op == &tok->KEYWORD_IS)
        {
            BC::expString(cs, &method, "_is");
        }
        else if (expression->op == &tok->KEYWORD_AS)
        {
            BC::expString(cs, &method, "_as");
        }
        else
        {
            BC::expString(cs, &method, "_instanceof");
        }

        BC::expToNextReg(fs, &object);
        BC::expToNextReg(fs, &method);
        BC::expToVal(fs, &method);
        BC::indexed(fs, &object, &method);

        utArray<Expression *> args;
        args.push_back(eleft);
        args.push_back(new StringLiteral(eright->type->getAssembly()->getName().c_str()));
        args.push_back(new NumberLiteral(eright->type->getTypeID()));

        generateCall(&object, &args);

        expression->e = object;

        return expression;
    }

    BinOpr op = getbinopr(expression->op);

    if (op == OPR_LOOM_ADD)
    {
        lmAssert(eleft->type && eright->type, "Untyped add operaton %i",
                 lineNumber);

        int ncheck = 0;
        if (eleft->type->isEnum() || (eleft->type->getFullName() == "system.Number"))
        {
            ncheck++;
        }

        if (eright->type->isEnum() || (eright->type->getFullName() == "system.Number"))
        {
            ncheck++;
        }

        if (ncheck != 2)
        {
            op = OPR_CONCAT;
        }
    }


    // If we're concat'ing arbitrary types with a string, we need to coerce them
    // to strings with Object._toString otherwise the Lua VM will error when
    // it can't concat (which has strict rules, for instance cannot concat nil)
    if ((op == OPR_CONCAT) && ((eleft->type->getFullName() == "system.String") || (eright->type->getFullName() == "system.String")))
    {
        // coerce left to string, must be done even for string types as they may be null
        coerceToString(eleft);

        BC::infix(cs->fs, op, &eleft->e);

        // coerce right to string, must be done even for string types as they may be null
        coerceToString(eright);

        // and the binary op
        BC::posFix(cs->fs, op, &eleft->e, &eright->e);
        // save off expression and return
        expression->e = eleft->e;

        return expression;
    }

    eleft->visitExpression(this);

    BC::infix(cs->fs, op, &eleft->e);

    eright->visitExpression(this);

    BC::posFix(cs->fs, op, &eleft->e, &eright->e);

    expression->e = eleft->e;

    // promote to register
    BC::expToNextReg(cs->fs, &expression->e);

    return expression;
}
예제 #16
0
파일: lsType.cpp 프로젝트: Ivory27/LoomSDK
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());
            }
        }
    }
}
예제 #17
0
Expression *TypeCompiler::visit(SuperExpression *expression)
{
    lmAssert(currentMethod, "super outside of method");

    Type *type     = currentMethod->getDeclaringType();
    Type *baseType = type->getBaseType();

    //FIXME:  issue a warning
    if (!baseType)
    {
        return expression;
    }

    FuncState *fs = cs->fs;

    if (currentMethod->isConstructor())
    {
        ConstructorInfo *base = baseType->getConstructor();

        //FIXME: warn if no base constructor
        if (!base)
        {
            return expression;
        }

        // load up base class
        ExpDesc eclass;
        BC::singleVar(cs, &eclass, baseType->getFullName().c_str());

        // index with the __ls_constructor
        BC::expToNextReg(fs, &eclass);

        ExpDesc fname;
        BC::expString(cs, &fname, "__ls_constructor");

        BC::expToNextReg(fs, &fname);
        BC::expToVal(fs, &fname);
        BC::indexed(fs, &eclass, &fname);

        // call the LSMethod
        generateCall(&eclass, &expression->arguments);
    }
    else
    {
        utString name = currentMethod->getName();

        if (expression->method)
        {
            name = expression->method->string;
        }

        MemberInfo *mi = baseType->findMember(name.c_str());
        //FIXME: warn
        if (!mi)
        {
            return expression;
        }

        lmAssert(mi->isMethod(), "Non-method in super call");

        MethodInfo *methodInfo = (MethodInfo *)mi;

        // load up declaring class
        ExpDesc eclass;
        BC::singleVar(cs, &eclass,
                      methodInfo->getDeclaringType()->getFullName().c_str());

        BC::expToNextReg(fs, &eclass);

        ExpDesc fname;
        BC::expString(cs, &fname, name.c_str());

        BC::expToNextReg(fs, &fname);
        BC::expToVal(fs, &fname);
        BC::indexed(fs, &eclass, &fname);

        // call the LSMethod
        generateCall(&eclass, &expression->arguments);

        expression->e = eclass;
    }

    return expression;
}
예제 #18
0
Expression *TypeCompiler::visit(AssignmentOperatorExpression *expression)
{
    Tokens *tok = Tokens::getSingletonPtr();
    BinOpr op   = getassignmentopr(expression->type);

    lmAssert(op != OPR_NOBINOPR, "Unknown bin op on AssignentOperatorExpression");

    Expression *eleft  = expression->leftExpression;
    Expression *eright = expression->rightExpression;

    lmAssert(eleft->type, "Untyped error on left expression");

    const char *opmethod = tok->getOperatorMethodName(expression->type);
    if (opmethod)
    {
        MemberInfo *mi = eleft->type->findMember(opmethod);
        if (mi)
        {
            lmAssert(mi->isMethod(), "Non-method operator");

            MethodInfo *method = (MethodInfo *)mi;

            lmAssert(method->isOperator(), "Non-operator method");

            utArray<Expression *> args;
            args.push_back(eright);

            ExpDesc opcall;
            ExpDesc emethod;

            eleft->visitExpression(this);
            opcall = eleft->e;

            BC::initExpDesc(&emethod, VKNUM, 0);
            emethod.u.nval = method->getOrdinal();
            BC::expToNextReg(cs->fs, &opcall);
            BC::expToNextReg(cs->fs, &emethod);
            BC::expToVal(cs->fs, &emethod);
            BC::indexed(cs->fs, &opcall, &emethod);

            generateCall(&opcall, &args, method);

            expression->e = opcall;
            return expression;
        }
    }

    eleft->assignment = false;
    eleft->visitExpression(this);

    BC::infix(cs->fs, op, &eleft->e);

    eright->visitExpression(this);
    BC::expToNextReg(cs->fs, &eright->e);

    BC::posFix(cs->fs, op, &eleft->e, &eright->e);

    ExpDesc right = eleft->e;

    BC::expToNextReg(cs->fs, &right);

    memset(&eleft->e, 0, sizeof(ExpDesc));
    eleft->assignment = true;
    eleft->visitExpression(this);
    ExpDesc left = eleft->e;

    if (eleft->memberInfo && eleft->memberInfo->isProperty())
    {
        eright->e = right;
        generatePropertySet(&eleft->e, eright, false);
    }
    else
    {
        BC::storeVar(cs->fs, &left, &right);
    }

    return expression;
}
예제 #19
0
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");
}
예제 #20
0
static int lsr_instanceindex(lua_State *L)
{
    // we hit the instance index metamethod when we can't find a value
    // in the instance's table, this is a native or a bound method

    lua_rawgeti(L, 1, LSINDEXTYPE);
    Type *type = (Type *)lua_topointer(L, -1);
    lua_pop(L, 1);

    lmAssert(type, "Missing type on instance index");

    if (lua_isnumber(L, 2))
    {
        int ordinal = (int)lua_tonumber(L, 2);

        MemberInfo *mi = type->getMemberInfoByOrdinal(ordinal);

        lmAssert(mi, "Unable to find ordinal %s %i", type->getFullName().c_str(), ordinal);

        if (mi->isStatic())
        {
            lua_rawgeti(L, 1, LSINDEXCLASS);
            lua_replace(L, 1);
            lua_gettable(L, 1);
            return 1;
        }

        // we need to look in the class, the result will be cached to instance

        MethodBase *method = NULL;

        if (mi->isMethod())
        {
            method = (MethodBase *)mi;
        }

        if (method)
        {
            lua_rawgeti(L, 1, LSINDEXCLASS);
            assert(!lua_isnil(L, -1));

            int clsIdx = lua_gettop(L);

            if (!method->isStatic())
            {
                if (method->isFastCall())
                {
                    // get the fast call structure pointer
                    lua_pushlightuserdata(L, method->getFastCall());

                    // get the the "this"
                    if (lua_type(L, 1) == LUA_TTABLE)
                    {
                        lua_rawgeti(L, 1, LSINDEXNATIVE);
                    }
                    else
                    {
                        lua_pushvalue(L, 1);
                    }

                    // unwrap this
                    Detail::UserdataPtr *p1 = (Detail::UserdataPtr *)lua_topointer(L, -1);
                    lua_pushlightuserdata(L, p1->getPointer());
                    lua_replace(L, -2);

                    lua_pushnumber(L, ordinal);
                    lua_gettable(L, clsIdx);
                }
                else
                {
                    lua_pushlightuserdata(L, method);
                    lua_pushvalue(L, 1);
                    lua_pushnumber(L, ordinal);
                    lua_gettable(L, clsIdx);
                }

                assert(!lua_isnil(L, -1));

                int nup = 3;

                int fd = method->getFirstDefaultParm();
                if (fd != -1)
                {
                    utString dname;
                    if (method->isConstructor())
                    {
                        dname = "__ls_constructor";
                    }
                    else
                    {
                        dname = method->getName();
                    }

                    dname += "__default_args";

                    lua_getfield(L, clsIdx, dname.c_str());

                    int dargs = lua_gettop(L);

                    for (int i = fd; i < method->getNumParameters(); i++)
                    {
                        lua_pushnumber(L, i);
                        lua_gettable(L, dargs);
                        nup++;
                    }

                    lua_remove(L, dargs);
                }

                // check for fast path
                if (method->isFastCall())
                {
                    if (method->getNumParameters())
                    {
                        // setter
                        lua_pushcclosure(L, lsr_method_fastcall_set, nup);
                    }
                    else
                    {
                        // getter
                        lua_pushcclosure(L, lsr_method_fastcall_get, nup);
                    }
                }
                else
                {
                    // bind the instance method
                    lua_pushcclosure(L, lsr_method, nup);
                }

                // store to method lookup, this is worth it
                // as only happens once per instance method bind
                // and can now lookup MethodBase on any function
                // in one table lookup
                lua_rawgeti(L, LUA_GLOBALSINDEX, LSINDEXMETHODLOOKUP);
                lua_pushvalue(L, -2);
                lua_pushlightuserdata(L, method);
                lua_rawset(L, -3);
                lua_pop(L, 1);

                // cache to instance
                lua_pushvalue(L, -1);
                lua_rawseti(L, 1, ordinal);


                return 1;
            }
            else
            {
                assert(0);
            }
        }

        FieldInfo *field = NULL;

        if (mi->isField())
        {
            field = (FieldInfo *)mi;
        }

        if (field && field->isNative())
        {
            // for primitive fields, we could generate
            // a direct lookup in the LSINDEXNATIVE table
            // in bytecode gen, however this only saves for
            // native vars and not properties
            // (which should be using fast path anyway and complicates bytecode)

            // get the native userdata
            lua_rawgeti(L, 1, LSINDEXNATIVE);
            lua_pushnumber(L, field->getOrdinal());
            lua_gettable(L, -2);

            // if we are native we need to wrap
            if (lua_isuserdata(L, -1))
            {
                lualoom_pushnative_userdata(L, field->getType(), -1);
            }

            return 1;
        }

        // if we get here the value actually is null
        lua_pushnil(L);
        return 1;
    }

    // if we hit here, this should be an interface access where we have to
    // look up by string (and cache as these are only ever instance methods)

    const char *name  = lua_tostring(L, 2);
    const char *pname = name;
    MemberInfo *mi    = NULL;

    if (!strncmp(name, "__pget_", 7))
    {
        pname = &name[7];
        mi    = type->findMember(pname, true);
        lmAssert(mi && mi->isProperty(), "Could not find property getter for '%s' on type '%s'", pname, type->getFullName().c_str());
        mi = ((PropertyInfo *)mi)->getGetMethod();
        lmAssert(mi, "Found NULL property getter for '%s' on type '%s'", pname, type->getFullName().c_str());
    }
    else if (!strncmp(name, "__pset_", 7))
    {
        pname = &name[7];
        mi    = type->findMember(pname, true);
        lmAssert(mi && mi->isProperty(), "Could not find property setter for '%s' on type '%s'", pname, type->getFullName().c_str());
        mi = ((PropertyInfo *)mi)->getSetMethod();
        lmAssert(mi, "Found NULL property setter for '%s' on type '%s'", pname, type->getFullName().c_str());
    }
    else
    {
        mi = type->findMember(name, true);
        lmAssert(mi, "Unable to find member '%s' via string on instance of type %s", name, type->getFullName().c_str());
        assert(mi);
        assert(mi->isMethod());
        assert(mi->getOrdinal());
    }

    lua_pushnumber(L, mi->getOrdinal());
    lua_gettable(L, 1);
    lua_pushstring(L, name);
    lua_pushvalue(L, -2);
    lua_rawset(L, 1);

    return 1;
}
예제 #21
0
void cGuild::load( const QSqlQuery& result )
{
	serial_ = result.value( 0 ).toInt();
	name_ = result.value( 1 ).toString();
	abbreviation_ = result.value( 2 ).toString();
	charta_ = result.value( 3 ).toString();
	website_ = result.value( 4 ).toString();
	alignment_ = ( eAlignment ) result.value( 5 ).toInt();
	leader_ = dynamic_cast<P_PLAYER>( World::instance()->findChar( result.value( 6 ).toInt() ) );
	founded_.setTime_t( result.value( 7 ).toInt() );
	guildstone_ = World::instance()->findItem( result.value( 8 ).toInt() );

	// Load members and canidates
	QSqlQuery members( QString( "SELECT player,showsign,guildtitle,joined FROM guilds_members WHERE guild = %1" ).arg( serial_ ) );

	while ( members.next() )
	{
		P_PLAYER player = dynamic_cast<P_PLAYER>( World::instance()->findChar( members.value( 0 ).toInt() ) );

		if ( player )
		{
			player->setGuild( this );
			members_.append( player );

			MemberInfo* info = new MemberInfo;
			info->setShowSign( members.value( 1 ).toInt() != 0 );
			info->setGuildTitle( members.value( 2 ).toString() );
			info->setJoined( members.value( 3 ).toInt() );
			memberinfo_.insert( player, info );
		}
	}

	QSqlQuery canidates( QString( "SELECT player FROM guilds_canidates WHERE guild = %1" ).arg( serial_ ) );

	while ( canidates.next() )
	{
		P_PLAYER player = dynamic_cast<P_PLAYER>( World::instance()->findChar( canidates.value( 0 ).toInt() ) );

		if ( player )
		{
			player->setGuild( this );
			canidates_.append( player );
		}
	}

	// Clear the leader if he's not a member of the guild
	if ( !members_.contains( leader_ ) )
	{
		leader_ = 0;
	}

	Guilds::instance()->registerGuild( this );

	QSqlQuery allies( QString( "SELECT ally FROM guilds_allies WHERE guild = %1" ).arg( serial_ ) );

	while ( allies.next() )
	{
		allies_.append( allies.value( 0 ).toInt() );
	}

	QSqlQuery enemies( QString( "SELECT enemy FROM guilds_enemies WHERE guild = %1" ).arg( serial_ ) );

	while ( enemies.next() )
	{
		enemies_.append( enemies.value( 0 ).toInt() );
	}
}