#include #include #include #include CClass::CClass( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, const string &name ) : isReady( false ) , Prototype( namespaceScopes, name ) , importedNamespaces( importedNamespaces ) , ConstructorMemberSubIndex( -1 ) , DestructorMemberSubIndex( -1 ) , classType( Class ) , pobj_InheritsClass( NULL ) , vtblNum( 0 ) , iAlign( 0 ) , vtbl_offset( -1 ) , isCompilingConstructor( false ) , isCompilingDestructor( false ) , pobj_NextClass( NULL ) { } CClass::~CClass(){ // 動的メンバ BOOST_FOREACH( CMember *member, dynamicMembers ){ delete member; } // 静的メンバ BOOST_FOREACH( CMember *member, staticMembers ){ delete member; } } bool CClass::IsInheritsInterface( const CClass *pInterfaceClass ) const { BOOST_FOREACH( const InheritedInterface &objInterface, interfaces ){ if( pInterfaceClass == &objInterface.GetInterfaceClass() ){ return true; } } return false; } bool CClass::IsClass() const { return classType == CClass::Class; } bool CClass::IsInterface() const { return classType == CClass::Interface; } bool CClass::IsEnum() const { return classType == CClass::Enum; } bool CClass::IsDelegate() const { return classType == CClass::Delegate; } bool CClass::IsStructure() const { return classType == CClass::Structure; } BOOL CClass::DupliCheckAll(const char *name){ //重複チェック //メンバ if(DupliCheckMember(name)) return 1; //メソッド BOOST_FOREACH( const CMethod *pMethod, methods ){ if( lstrcmp( name, pMethod->pUserProc->GetName().c_str() ) == 0 ){ return 1; } } return 0; } BOOL CClass::DupliCheckMember(const char *name){ //重複チェック // 動的メンバ BOOST_FOREACH( CMember *pMember, dynamicMembers ){ if( GetName() == pMember->GetName() ){ return 1; } } // 静的メンバ BOOST_FOREACH( CMember *pMember, staticMembers ){ if( GetName() == pMember->GetName() ){ return 1; } } return 0; } //デフォルト コンストラクタ メソッドを取得 const CMethod *CClass::GetConstructorMethod() const { if( ConstructorMemberSubIndex == -1 ) return NULL; return methods[ConstructorMemberSubIndex]; } //デストラクタ メソッドを取得 const CMethod *CClass::GetDestructorMethod() const { if( DestructorMemberSubIndex == -1 ) return NULL; return methods[DestructorMemberSubIndex]; } //サイズを取得 int CClass::GetSize() const { return GetMemberOffset( NULL, NULL ); } //メンバのオフセットを取得 int CClass::GetMemberOffset( const char *memberName, int *pMemberNum ) const { int i2; //仮想関数が存在する場合は関数リストへのポインタのサイズを追加 int offset = IsExistVirtualFunctions() ? PTR_SIZE : 0; int alignment; if(iAlign) alignment=iAlign; else alignment=1; int iMaxAlign=0; int i = -1; BOOST_FOREACH( CMember *pMember, dynamicMembers ){ i++; i2 = pMember->GetType().GetSize(); //アラインメントを算出 int member_size; if( pMember->GetType().IsStruct() ){ //メンバクラスのアラインメントを取得 member_size=pMember->GetType().GetClass().GetAlignment(); } else{ //メンバサイズを取得 member_size=i2; } if(iMaxAlignGetName() == memberName ){ if(pMemberNum) *pMemberNum=i; return offset; } } //配列を考慮したメンバサイズを取得 member_size=i2 * Variable::GetSubScriptCounts(pMember->SubScripts); //メンバサイズを加算 offset+= member_size; } if(iMaxAlignGetType().IsStruct()){ //メンバクラスのアラインメントを取得 member_size=pMember->GetType().GetClass().GetAlignment(); } else{ //メンバサイズを取得 member_size = pMember->GetType().GetSize(); } //アラインメントをセット if(alignmentpUserProc == pUserProc ) break; if( pMethod->IsVirtual() ) n++; } return n; } bool CClass::IsAbstract() const { // 未実装(abstract)の仮想関数を持つ場合はtrueを返す BOOST_FOREACH( const CMethod *pMethod, methods ){ if(pMethod->IsVirtual()){ if(pMethod->IsAbstract()){ return true; } } } return false; } // コンストラクタのコンパイルを開始 void CClass::NotifyStartConstructorCompile() const { isCompilingConstructor = true; } //コンストラクタのコンパイルを終了 void CClass::NotifyFinishConstructorCompile() const { isCompilingConstructor = false; } //コンストラクタをコンパイル中かどうかを判別 bool CClass::IsCompilingConstructor() const { return isCompilingConstructor; } //デストラクタのコンパイルを開始 void CClass::NotifyStartDestructorCompile() const{ isCompilingDestructor = true; } //デストラクタのコンパイルを終了 void CClass::NotifyFinishDestructorCompile() const{ isCompilingDestructor = false; } //デストラクタをコンパイル中かどうかを判別 bool CClass::IsCompilingDestructor() const { return isCompilingDestructor; } //自身の派生クラスかどうかを確認 bool CClass::IsSubClass( const CClass *pClass ) const { pClass = pClass->pobj_InheritsClass; while( pClass ){ if( this == pClass ) return true; pClass = pClass->pobj_InheritsClass; } return false; } //自身と等しいまたは派生クラスかどうかを確認 bool CClass::IsEqualsOrSubClass( const CClass *pClass ) const { if( IsEquals( pClass ) ) return true; return IsSubClass( pClass ); } // 自身と等しいまたは派生クラス、基底クラスかどうかを確認 bool CClass::IsEqualsOrSubClassOrSuperClass( const CClass &objClass ) const { if( IsEquals( &objClass ) ) return true; if( IsSubClass( &objClass ) ) return true; if( objClass.IsSubClass( this ) ) return true; return false; } int Classes::hash(const char *name) const{ int key; for(key=0;*name!='\0';name++){ key=((key<<8)+ *name )%MAX_CLASS_HASH; } return key; } void Classes::DestroyClass(CClass *pobj_c){ if(pobj_c->pobj_NextClass){ DestroyClass(pobj_c->pobj_NextClass); } delete pobj_c; } Classes::Classes(): pStringClass( NULL ), pObjectClass( NULL ), pCompilingClass( NULL ), pCompilingMethod( NULL ), ppobj_IteClass( NULL ), iIteMaxNum( 0 ), iIteNextNum( 0 ) { memset( pobj_ClassHash, 0, MAX_CLASS_HASH * sizeof(CClass *) ); Clear(); } Classes::~Classes(){ Clear(); } void Classes::Clear() { int i; for(i=0;iActionVtblSchedule(ImageBase,MemPos_CodeSection); if(pobj_c->pobj_NextClass==0) break; pobj_c=pobj_c->pobj_NextClass; } } } } const CClass *Classes::Find( const NamespaceScopes &namespaceScopes, const string &name ) const { int key; key=hash(name.c_str()); if( namespaceScopes.size() == 0 && name == "Object" ){ return GetObjectClassPtr(); } else if( namespaceScopes.size() == 0 && name == "String" ){ return GetStringClassPtr(); } if(pobj_ClassHash[key]){ CClass *pobj_c; pobj_c=pobj_ClassHash[key]; while(1){ if( pobj_c->IsEqualSymbol( namespaceScopes, name ) ){ //名前空間とクラス名が一致した return pobj_c; } if(pobj_c->pobj_NextClass==0) break; pobj_c=pobj_c->pobj_NextClass; } } // TypeDefも見る int index = Smoothie::GetMeta().typeDefs.GetIndex( namespaceScopes, name ); if( index != -1 ){ Type type = Smoothie::GetMeta().typeDefs[index].GetBaseType(); if( type.IsObject() ){ return &type.GetClass(); } } return NULL; } const CClass *Classes::Find( const string &fullName ) const { char AreaName[VN_SIZE] = ""; //オブジェクト変数 char NestName[VN_SIZE] = ""; //入れ子メンバ bool isNest = CClass::SplitName( fullName.c_str(), AreaName, NestName ); return Find( NamespaceScopes( AreaName ), NestName ); } CClass *Classes::Add( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, const char *name,int nowLine){ ////////////////////////////////////////////////////////////////////////// // クラスを追加 // ※名前のみを登録。その他の情報はSetClassメソッドで! ////////////////////////////////////////////////////////////////////////// CClass *pobj_c = Create(namespaceScopes, importedNamespaces, name); if(lstrcmp(name,"String")==0){ //Stringクラス pStringClass=pobj_c; } if( lstrcmp( name, "Object" ) == 0 ){ pObjectClass = pobj_c; } ///////////////////////////////// // ハッシュデータに追加 ///////////////////////////////// int key; key=hash(name); if(pobj_ClassHash[key]){ CClass *pobj_c2; pobj_c2=pobj_ClassHash[key]; while(1){ if( pobj_c2->IsEqualSymbol( namespaceScopes, name ) ){ //名前空間及びクラス名が重複した場合 SmoothieException::Throw(15,name,nowLine); return 0; } if(pobj_c2->pobj_NextClass==0) break; pobj_c2=pobj_c2->pobj_NextClass; } pobj_c2->pobj_NextClass=pobj_c; } else{ pobj_ClassHash[key]=pobj_c; } return pobj_c; } CClass *Classes::GetStringClassPtr() const { if( !pStringClass ){ SmoothieException::Throw(); return NULL; } return pStringClass; } CClass *Classes::GetObjectClassPtr() const { if( !pObjectClass ){ SmoothieException::Throw(); return NULL; } return pObjectClass; } void Classes::StartCompile( UserProc *pUserProc ){ pCompilingClass = pUserProc->GetParentClassPtr(); if( pCompilingClass ){ pCompilingClass->Using(); pCompilingMethod = pCompilingClass->GetMethods().GetMethodPtr( pUserProc ); if( !pCompilingMethod ){ pCompilingMethod = pCompilingClass->GetStaticMethods().GetMethodPtr( pUserProc ); if( !pCompilingMethod ){ SmoothieException::Throw(300); } } } else{ pCompilingMethod = NULL; } } const CClass *Classes::GetNowCompilingClass() const { return pCompilingClass; } const CMethod *Classes::GetNowCompilingMethodInfo(){ return pCompilingMethod; } ////////////////////// // イテレータ ////////////////////// void Classes::Iterator_Init(void){ if(ppobj_IteClass) free(ppobj_IteClass); iIteMaxNum=0; iIteNextNum=0; ppobj_IteClass=(CClass **)malloc(1); int i; for(i=0;ipobj_NextClass==0) break; pobj_c=pobj_c->pobj_NextClass; } } } } void Classes::Iterator_Reset(void){ iIteNextNum = 0; } BOOL Classes::Iterator_HasNext(void){ if(iIteNextNum