#include #include #include #include class CLoopRefCheck{ char **names; int num; void init(){ int i; for(i=0;iIsInterface() ){ // インターフェイスはあとで継承する } else if( pInheritsClass->IsClass() ){ // クラスを継承する isInheritsClass = true; if( !InheritsClass( *pInheritsClass, nowLine ) ){ return false; } } else{ throw SmoothieException(135,NULL,nowLine); return false; } if( inheritNames[i] == '\0' ){ break; } i++; } if( !isInheritsClass ){ // クラスを一つも継承していないとき const CClass *pObjectClass = Smoothie::meta.classes.Find("Object"); if( !pObjectClass ){ throw SmoothieException(106,"Object",i); return false; } if( !InheritsClass( *pObjectClass, nowLine ) ){ return false; } } i=0; while( true ){ char temporary[VN_SIZE]; for( int i2=0;; i++, i2++ ){ if( inheritNames[i] == '\0' || inheritNames[i] == ',' ){ temporary[i2] = 0; break; } temporary[i2] = inheritNames[i]; } //継承元クラスを取得 const CClass *pInheritsClass = Smoothie::meta.classes.Find(temporary); if( !pInheritsClass ){ throw SmoothieException(106,temporary,nowLine); return false; } if( pInheritsClass->IsInterface() ){ // インターフェイスを継承する if( !InheritsInterface( *pInheritsClass, nowLine ) ){ return false; } } else if( pInheritsClass->IsClass() ){ // クラスはさっき継承した } else{ throw SmoothieException(135,NULL,nowLine); return false; } if( inheritNames[i] == '\0' ){ break; } i++; } return true; } /* bool CClass::InheritsClass( const CClass &inheritsClass, int nowLine ){ //ループ継承でないかをチェック if(pobj_LoopRefCheck->check(inheritsClass)){ throw SmoothieException(123,inheritsClass.GetName(),nowLine); return false; } if( !inheritsClass.IsReady() ){ //継承先が読み取られていないとき pobj_LoopRefCheck->add(this->GetName().c_str()); Smoothie::meta.classes.GetClass_recur(inheritsClass.GetName().c_str()); pobj_LoopRefCheck->del(this->GetName().c_str()); } //メンバをコピー BOOST_FOREACH( CMember *inheritsClassDynamicMember, inheritsClass.dynamicMembers ){ CMember *pMember = new CMember( *inheritsClassDynamicMember ); // アクセシビリティ if( inheritsClassDynamicMember->IsPrivate() ){ pMember->SetAccessibility( Prototype::None ); } else{ pMember->SetAccessibility( inheritsClassDynamicMember->GetAccessibility() ); } dynamicMembers.push_back( pMember ); } //メソッドをコピー BOOST_FOREACH( const CMethod *pBaseMethod, inheritsClass.methods ){ CMethod *pMethod = new DynamicMethod( *pBaseMethod ); // アクセシビリティ if(pBaseMethod->GetAccessibility() == Prototype::Private){ pMethod->SetAccessibility( Prototype::None ); } else{ pMethod->SetAccessibility( pBaseMethod->GetAccessibility() ); } //pobj_Inherits // ※継承元のClassIndexをセット(入れ子継承を考慮する) if(pBaseMethod->GetInheritsClassPtr()==0){ pMethod->SetInheritsClassPtr( &inheritsClass ); } else{ pMethod->SetInheritsClassPtr( pBaseMethod->GetInheritsClassPtr() ); } methods.push_back( pMethod ); } //仮想関数の数 AddVtblNum( inheritsClass.GetVtblNum() ); //継承先のクラスをメンバとして保持する pobj_InheritsClass = &inheritsClass; return true; } bool CClass::InheritsInterface( const CClass &inheritsInterface, int nowLine ){ //ループ継承でないかをチェック if(pobj_LoopRefCheck->check(inheritsInterface)){ throw SmoothieException(123,inheritsInterface.GetName(),nowLine); return false; } if( !inheritsInterface.IsReady() ){ //継承先が読み取られていないとき pobj_LoopRefCheck->add(this->GetName().c_str()); Smoothie::meta.classes.GetClass_recur(inheritsInterface.GetName().c_str()); pobj_LoopRefCheck->del(this->GetName().c_str()); } //メソッドをコピー BOOST_FOREACH( const CMethod *pBaseMethod, inheritsInterface.methods ){ CMethod *pMethod = new DynamicMethod( *pBaseMethod ); // アクセシビリティ if(pBaseMethod->GetAccessibility() == Prototype::Private){ pMethod->SetAccessibility( Prototype::None ); } else{ pMethod->SetAccessibility( pBaseMethod->GetAccessibility() ); } //pobj_Inherits // ※継承元のClassIndexをセット(入れ子継承を考慮する) if(pBaseMethod->GetInheritsClassPtr()==0){ pMethod->SetInheritsClassPtr( &inheritsInterface ); } else{ pMethod->SetInheritsClassPtr( pBaseMethod->GetInheritsClassPtr() ); } methods.push_back( pMethod ); } interfaces.push_back( InheritedInterface( const_cast(&inheritsInterface), vtblNum ) ); //仮想関数の数 AddVtblNum( inheritsInterface.GetVtblNum() ); return true; } void CClass::AddMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer ){ CMember *pMember = new CMember( this, accessibility, isConst, isRef, buffer ); dynamicMembers.push_back( pMember ); } void CClass::AddStaticMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine ){ CMember *pMember = new CMember( this, accessibility, isConst, isRef, buffer, nowLine ); staticMembers.push_back( pMember ); }*/ 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; } /* LONG_PTR CClass::GetVtblGlobalOffset(void) const { //既に存在する場合はそれを返す if(vtbl_offset!=-1) return vtbl_offset; ////////////////////////////////////// // 存在しないときは新たに生成する ////////////////////////////////////// UserProc **ppsi; ppsi=(UserProc **)malloc(GetVtblNum()*sizeof(GlobalProc *)); //関数テーブルに値をセット int i2 = 0; BOOST_FOREACH( const CMethod *pMethod, methods ){ if(pMethod->IsVirtual()){ pMethod->pUserProc->Using(); if(pMethod->IsAbstract()){ extern int cp; throw SmoothieException(300,NULL,cp); ppsi[i2]=0; } else{ ppsi[i2]=pMethod->pUserProc; } i2++; } } vtbl_offset=dataTable.AddBinary((void *)ppsi,GetVtblNum()*sizeof(LONG_PTR)); for( int i=0; i < GetVtblNum(); i++ ){ pobj_Reloc->AddSchedule_DataSection(vtbl_offset+i*sizeof(LONG_PTR)); } free(ppsi); return vtbl_offset; } void CClass::ActionVtblSchedule(LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection){ if(vtbl_offset==-1) return; LONG_PTR *pVtbl; pVtbl=(LONG_PTR *)((char *)dataTable.GetPtr()+vtbl_offset); int i; for(i=0;ibeginOpAddress+ImageBase+MemPos_CodeSection; } }*/ 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 ) { 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::meta.typeDefs.GetIndex( namespaceScopes, name ); if( index != -1 ){ Type type = Smoothie::meta.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::AddClass( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, const char *name,int nowLine){ ////////////////////////////////////////////////////////////////////////// // クラスを追加 // ※名前のみを登録。その他の情報はSetClassメソッドで! ////////////////////////////////////////////////////////////////////////// CClass *pobj_c; pobj_c=new CClass(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 ) ){ //名前空間及びクラス名が重複した場合 throw SmoothieException(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 ){ throw SmoothieException(); return NULL; } return pStringClass; } CClass *Classes::GetObjectClassPtr() const { if( !pObjectClass ){ throw SmoothieException(); 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 ){ throw SmoothieException(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