//----------------------------------------------------------------// int MOAILuaObject::_tostring ( lua_State* L ) { MOAILuaState state ( L ); MOAILuaObject* data = ( MOAILuaObject* )state.GetPtrUserData ( 1 ); if ( data ) { STLString str; lua_getfield ( state, 1, "getClassName" ); if ( state.IsType ( -1, LUA_TFUNCTION )) { lua_pushvalue ( state, 1 ); state.DebugCall ( 1, 1 ); cc8* classname = state.GetValue < cc8* >( -1, "" ); str.write ( "%p <%s>", data, classname ); state.Push ( str ); return 1; } str.write ( "%p <%s>", data, data->TypeName ()); state.Push ( str ); return 1; } return 0; }
//----------------------------------------------------------------// int MOAILuaObject::_gc ( lua_State* L ) { MOAILuaState state ( L ); MOAILuaObject* self = ( MOAILuaObject* )state.GetPtrUserData ( 1 ); self->mCollected = true; if ( MOAILuaRuntime::IsValid ()) { if ( self->mFinalizer ) { self->mFinalizer.PushRef ( state ); if ( state.IsType ( -1, LUA_TFUNCTION )) { state.DebugCall ( 0, 0 ); } else if ( state.IsType ( -1, LUA_TSTRING )) { printf ( "%s\n", state.GetValue < cc8* >( -1, "" )); } else { state.Pop ( 1 ); } self->mFinalizer.Clear (); } if ( MOAILuaRuntime::Get ().mReportGC ) { printf ( "GC %s <%p>\n", self->TypeName (), self ); } } if ( self->GetRefCount () == 0 ) { delete ( self ); } return 0; }
//----------------------------------------------------------------// void MOAILuaClass::InitLuaSingletonClass ( MOAILuaObject& data, MOAILuaState& state ) { // push class table lua_newtable ( state ); this->RegisterLuaClass ( state ); data.MOAILuaObject::RegisterLuaClass ( state ); data.RegisterLuaClass ( state ); // init the extend method lua_pushvalue ( state, -1 ); // copy of userdata //used to be 1 lua_pushvalue ( state, -2 ); // copy of class table lua_pushcclosure ( state, _extendSingleton, 2 ); lua_setfield ( state, -2, "extend" ); // ref class table this->mClassTable.SetRef ( state, -1 ); lua_pushvalue ( state, -1 ); lua_setfield ( state, -2, "__index" ); lua_pushvalue ( state, -1 ); lua_setfield ( state, -2, "__newindex" ); lua_setglobal ( state, data.TypeName ()); }
//----------------------------------------------------------------// void MOAISerializer::WriteObjectInits ( USStream& stream ) { if ( !this->mPending.size ()) return; while ( this->mPending.size ()) { MOAILuaObject* object = this->mPending.front (); assert ( object ); this->mPending.pop_front (); u32 id = this->GetID ( object ); stream.Print ( "\t--%s\n", object->TypeName ()); stream.Print ( "\tserializer:initObject (\n" ); MOAILuaClass* type = object->GetLuaClass (); if ( type->IsSingleton ()) { stream.Print ( "\t\t%s.get (),\n", object->TypeName ()); } else { stream.Print ( "\t\tobjects [ 0x%08X ],\n", id ); } MOAILuaStateHandle state = MOAILuaRuntime::Get ().State (); object->PushMemberTable ( state ); stream.Print ( "\t\tobjects [ 0x%08X ],\n", this->AffirmMemberID ( state, -1 )); state.Pop ( 1 ); // this should fill the table for the class lua_newtable ( state ); object->SerializeOut ( state, *this ); stream.Print ( "\t\t{" ); if ( this->WriteTable ( stream, state, -1, 3 )) { stream.Print ( "\t\t}\n" ); } else { stream.Print ( "}\n" ); } state.Pop ( 1 ); stream.Print ( "\t)\n\n" ); } }
//----------------------------------------------------------------// int MOAILuaObject::_getClassName ( lua_State* L ) { MOAILuaState state ( L ); MOAILuaObject* object = ( MOAILuaObject* )state.GetPtrUserData ( 1 ); if ( object ) { lua_pushstring ( L, object->TypeName ()); return 1; } return 0; }
//----------------------------------------------------------------// int MOAILuaObject::_tostring ( lua_State* L ) { MOAILuaState state ( L ); MOAILuaObject* data = ( MOAILuaObject* )state.GetPtrUserData ( 1 ); if ( data ) { STLString str; str.write ( "0x%p <%s>", data, data->TypeName ()); // TODO: 64-bit state.Push ( str ); return 1; } return 0; }
//----------------------------------------------------------------// void MOAILuaRuntime::BuildHistogram ( HistMap& histogram ) { HistSet::iterator histSetIt = this->mHistSet.begin (); for ( ; histSetIt != this->mHistSet.end (); ++histSetIt ) { MOAILuaObject* obj = *histSetIt; cc8* name = obj->TypeName (); if ( !histogram.contains ( name )) { histogram [ name ] = 1; } else { histogram [ name ]++; } } }
//----------------------------------------------------------------// void MOAILuaClass::InitLuaFactoryClass ( MOAILuaObject& data, MOAILuaState& state ) { int top = lua_gettop ( state ); // push interface table lua_newtable ( state ); // interface table is its own __index lua_pushvalue ( state, -1 ); lua_setfield ( state, -2, "__index" ); data.MOAILuaObject::RegisterLuaFuncs ( state ); data.RegisterLuaFuncs ( state ); this->mInterfaceTable.SetRef ( state, -1 ); // reset top lua_settop ( state, top ); // push class table lua_newtable ( state ); this->RegisterLuaClass ( state ); data.MOAILuaObject::RegisterLuaClass ( state ); data.RegisterLuaClass ( state ); // init the extend method lua_pushvalue ( state, -1 ); // class table this->mInterfaceTable.PushRef ( state ); // interface table lua_pushcclosure ( state, _extendFactory, 2 ); lua_setfield ( state, -2, "extend" ); // init the getInterfaceTable method this->mInterfaceTable.PushRef ( state ); // interface table lua_pushcclosure ( state, _getInterfaceTable, 1 ); lua_setfield ( state, -2, "getInterfaceTable" ); // ref class table and expose as global this->mClassTable.SetRef ( state, -1 ); lua_setglobal ( state, data.TypeName ()); // reset top lua_settop ( state, top ); }
//----------------------------------------------------------------// void MOAILuaRuntime::ReportLeaksFormatted ( FILE *f ) { this->ForceGarbageCollection (); lua_State* L = this->mMainState; // First, correlate leaks by identical stack traces. LeakStackMap stacks; for ( LeakMap::const_iterator i = this->mLeaks.begin (); i != this->mLeaks.end (); ++i ) { stacks [ i->second ].push_back ( i->first ); } fprintf ( f, "-- BEGIN LUA OBJECT LEAKS --\n" ); // Then, print out each unique allocation spot along with all references // (including multiple references) followed by the alloction stack int top = lua_gettop ( L ); UNUSED ( top ); for ( LeakStackMap::const_iterator i = stacks.begin (); i != stacks.end (); ++i ) { const LeakPtrList& list = i->second; MOAILuaObject *o = list.front (); fprintf ( f, "Allocation: %lu x %s\n", list.size (), o->TypeName ()); for( LeakPtrList::const_iterator j = list.begin (); j != list.end (); ++j ) { fprintf ( f, "\t(%6d) %p\n", ( *j )->GetRefCount (), *j ); } // A table to use as a traversal set. lua_newtable ( L ); // And the table to use as seed lua_pushglobaltable ( L ); this->FindAndPrintLuaRefs ( -2, "_G", f, list ); lua_pop ( L, 2 ); // Pop the 'done' set and our globals table fputs ( i->first.c_str (), f ); fputs ( "\n", f ); fflush ( f ); } assert ( top == lua_gettop ( L )); fprintf ( f, "-- END LUA LEAKS --\n" ); }
//----------------------------------------------------------------// void MOAISerializer::WriteObjectDecls ( USStream& stream ) { if ( !this->mObjectMap.size ()) return; stream.Print ( "\t--Declaring Instances\n" ); ObjectMapIt objectIt; objectIt = this->mObjectMap.begin (); for ( ; objectIt != this->mObjectMap.end (); ++objectIt ) { MOAILuaObject* object = objectIt->second; if ( !object ) continue; uintptr id = this->GetID ( object ); MOAILuaClass* type = object->GetLuaClass (); if ( !type->IsSingleton ()) { stream.Print ( "\t[ 0x%08X ] = serializer:registerObjectID ( %s.new (), 0x%08X ),\n", id, object->TypeName (), id ); } } stream.Print ( "\n" ); }