| 1 | #include "stdafx.h"
 | 
|---|
| 2 | 
 | 
|---|
| 3 | #include <Source.h>
 | 
|---|
| 4 | #include <Class.h>
 | 
|---|
| 5 | #include <Compiler.h>
 | 
|---|
| 6 | 
 | 
|---|
| 7 | #include "../common.h"
 | 
|---|
| 8 | #ifdef _AMD64_
 | 
|---|
| 9 | #include "../../compiler_x64/opcode.h"
 | 
|---|
| 10 | #else
 | 
|---|
| 11 | #include "../../compiler_x86/opcode.h"
 | 
|---|
| 12 | #endif
 | 
|---|
| 13 | 
 | 
|---|
| 14 | using namespace ActiveBasic::Compiler;
 | 
|---|
| 15 | 
 | 
|---|
| 16 | 
 | 
|---|
| 17 | bool CClass::IsClass() const
 | 
|---|
| 18 | {
 | 
|---|
| 19 |     return classType == CClass::Class;
 | 
|---|
| 20 | }
 | 
|---|
| 21 | bool CClass::IsInterface() const
 | 
|---|
| 22 | {
 | 
|---|
| 23 |     return classType == CClass::Interface;
 | 
|---|
| 24 | }
 | 
|---|
| 25 | bool CClass::IsComInterface() const
 | 
|---|
| 26 | {
 | 
|---|
| 27 |     return classType == CClass::ComInterface;
 | 
|---|
| 28 | }
 | 
|---|
| 29 | bool CClass::IsEnum() const
 | 
|---|
| 30 | {
 | 
|---|
| 31 |     return classType == CClass::Enum;
 | 
|---|
| 32 | }
 | 
|---|
| 33 | bool CClass::IsDelegate() const
 | 
|---|
| 34 | {
 | 
|---|
| 35 |     return classType == CClass::Delegate;
 | 
|---|
| 36 | }
 | 
|---|
| 37 | bool CClass::IsStructure() const
 | 
|---|
| 38 | {
 | 
|---|
| 39 |     return classType == CClass::Structure;
 | 
|---|
| 40 | }
 | 
|---|
| 41 | 
 | 
|---|
| 42 | 
 | 
|---|
| 43 | // コンストラクタのコンパイルを開始
 | 
|---|
| 44 | void CClass::NotifyStartConstructorCompile() const
 | 
|---|
| 45 | {
 | 
|---|
| 46 |     isCompilingConstructor = true;
 | 
|---|
| 47 | }
 | 
|---|
| 48 | 
 | 
|---|
| 49 | //コンストラクタのコンパイルを終了
 | 
|---|
| 50 | void CClass::NotifyFinishConstructorCompile() const
 | 
|---|
| 51 | {
 | 
|---|
| 52 |     isCompilingConstructor = false;
 | 
|---|
| 53 | }
 | 
|---|
| 54 | 
 | 
|---|
| 55 | //コンストラクタをコンパイル中かどうかを判別
 | 
|---|
| 56 | bool CClass::IsCompilingConstructor() const
 | 
|---|
| 57 | {
 | 
|---|
| 58 |     return isCompilingConstructor;
 | 
|---|
| 59 | }
 | 
|---|
| 60 | 
 | 
|---|
| 61 | //デストラクタのコンパイルを開始
 | 
|---|
| 62 | void CClass::NotifyStartDestructorCompile() const{
 | 
|---|
| 63 |     isCompilingDestructor = true;
 | 
|---|
| 64 | }
 | 
|---|
| 65 | 
 | 
|---|
| 66 | //デストラクタのコンパイルを終了
 | 
|---|
| 67 | void CClass::NotifyFinishDestructorCompile() const{
 | 
|---|
| 68 |     isCompilingDestructor = false;
 | 
|---|
| 69 | }
 | 
|---|
| 70 | 
 | 
|---|
| 71 | //デストラクタをコンパイル中かどうかを判別
 | 
|---|
| 72 | bool CClass::IsCompilingDestructor() const
 | 
|---|
| 73 | {
 | 
|---|
| 74 |     return isCompilingDestructor;
 | 
|---|
| 75 | }
 | 
|---|
| 76 | 
 | 
|---|
| 77 | //自身の派生クラスかどうかを確認
 | 
|---|
| 78 | bool CClass::IsSubClass( const CClass *pSubClass ) const
 | 
|---|
| 79 | {
 | 
|---|
| 80 |     if( !pSubClass->HasSuperClass() )
 | 
|---|
| 81 |     {
 | 
|---|
| 82 |         return false;
 | 
|---|
| 83 |     }
 | 
|---|
| 84 | 
 | 
|---|
| 85 |     const CClass *pTempClass = &pSubClass->GetSuperClass();
 | 
|---|
| 86 |     while( pTempClass ){
 | 
|---|
| 87 |         if( this == pTempClass ) return true;
 | 
|---|
| 88 |         pTempClass = &pTempClass->GetSuperClass();
 | 
|---|
| 89 |     }
 | 
|---|
| 90 |     return false;
 | 
|---|
| 91 | }
 | 
|---|
| 92 | 
 | 
|---|
| 93 | //自身と等しいまたは派生クラスかどうかを確認
 | 
|---|
| 94 | bool CClass::IsEqualsOrSubClass( const CClass *pSubClass ) const
 | 
|---|
| 95 | {
 | 
|---|
| 96 |     if( IsEquals( pSubClass ) ) return true;
 | 
|---|
| 97 |     return IsSubClass( pSubClass );
 | 
|---|
| 98 | }
 | 
|---|
| 99 | 
 | 
|---|
| 100 | // 自身と等しいまたは派生クラス、基底クラスかどうかを確認
 | 
|---|
| 101 | bool CClass::IsEqualsOrSubClassOrSuperClass( const CClass &objClass ) const
 | 
|---|
| 102 | {
 | 
|---|
| 103 |     if( IsEquals( &objClass ) ) return true;
 | 
|---|
| 104 |     if( IsSubClass( &objClass ) ) return true;
 | 
|---|
| 105 |     if( objClass.IsSubClass( this ) ) return true;
 | 
|---|
| 106 |     return false;
 | 
|---|
| 107 | }
 | 
|---|
| 108 | 
 | 
|---|
| 109 | bool CClass::IsInheritsInterface( const CClass *pInterfaceClass ) const
 | 
|---|
| 110 | {
 | 
|---|
| 111 |     BOOST_FOREACH( const ::Interface *pInterface, interfaces ){
 | 
|---|
| 112 |         if( pInterfaceClass == &pInterface->GetClass() ){
 | 
|---|
| 113 |             return true;
 | 
|---|
| 114 |         }
 | 
|---|
| 115 |     }
 | 
|---|
| 116 |     return false;
 | 
|---|
| 117 | }
 | 
|---|
| 118 | 
 | 
|---|
| 119 | bool CClass::InheritsClass( const CClass &inheritsClass, const Types &actualTypeParameters, int nowLine )
 | 
|---|
| 120 | {
 | 
|---|
| 121 |     //メソッドをコピー
 | 
|---|
| 122 |     BOOST_FOREACH( const CMethod *pBaseMethod, inheritsClass.GetDynamicMethods() ){
 | 
|---|
| 123 |         CMethod *pMethod = new DynamicMethod( *pBaseMethod );
 | 
|---|
| 124 | 
 | 
|---|
| 125 |         // アクセシビリティ
 | 
|---|
| 126 |         if(pBaseMethod->GetAccessibility() == Prototype::Private){
 | 
|---|
| 127 |             pMethod->SetAccessibility( Prototype::None );
 | 
|---|
| 128 |         }
 | 
|---|
| 129 |         else{
 | 
|---|
| 130 |             pMethod->SetAccessibility( pBaseMethod->GetAccessibility() );
 | 
|---|
| 131 |         }
 | 
|---|
| 132 | 
 | 
|---|
| 133 |         //pobj_Inherits
 | 
|---|
| 134 |         // ※継承元のClassIndexをセット(入れ子継承を考慮する)
 | 
|---|
| 135 |         if(pBaseMethod->GetInheritsClassPtr()==0){
 | 
|---|
| 136 |             pMethod->SetInheritsClassPtr( &inheritsClass );
 | 
|---|
| 137 |         }
 | 
|---|
| 138 |         else{
 | 
|---|
| 139 |             pMethod->SetInheritsClassPtr( pBaseMethod->GetInheritsClassPtr() );
 | 
|---|
| 140 |         }
 | 
|---|
| 141 | 
 | 
|---|
| 142 |         GetDynamicMethods().push_back( pMethod );
 | 
|---|
| 143 |     }
 | 
|---|
| 144 | 
 | 
|---|
| 145 |     //仮想関数の数
 | 
|---|
| 146 |     AddVtblNum( inheritsClass.GetVtblNum() );
 | 
|---|
| 147 | 
 | 
|---|
| 148 |     //継承先のクラスをメンバとして保持する
 | 
|---|
| 149 |     SetSuperClass( &inheritsClass );
 | 
|---|
| 150 |     SetSuperClassActualTypeParameters( actualTypeParameters );
 | 
|---|
| 151 | 
 | 
|---|
| 152 |     // インターフェイスを引き継ぐ
 | 
|---|
| 153 |     BOOST_FOREACH( ::Interface *pInterface, inheritsClass.GetInterfaces() )
 | 
|---|
| 154 |     {
 | 
|---|
| 155 |         interfaces.push_back( new ::Interface( *pInterface ) );
 | 
|---|
| 156 |     }
 | 
|---|
| 157 | 
 | 
|---|
| 158 |     if( this->IsInterface() && inheritsClass.IsComInterface() )
 | 
|---|
| 159 |     {
 | 
|---|
| 160 |         // COMインターフェイスを継承した場合はCOMインターフェイスにする
 | 
|---|
| 161 |         this->SetClassType( CClass::ComInterface );
 | 
|---|
| 162 |     }
 | 
|---|
| 163 | 
 | 
|---|
| 164 |     return true;
 | 
|---|
| 165 | }
 | 
|---|
| 166 | 
 | 
|---|
| 167 | bool CClass::Implements( const CClass &interfaceClass, const Types &actualTypeParameters, int nowLine )
 | 
|---|
| 168 | {
 | 
|---|
| 169 |     if( !interfaceClass.IsInterface() && !interfaceClass.IsComInterface() )
 | 
|---|
| 170 |     {
 | 
|---|
| 171 |         // インターフェイスではないとき
 | 
|---|
| 172 |         compiler.errorMessenger.Output(138,interfaceClass.GetName().c_str(),nowLine );
 | 
|---|
| 173 |         return false;
 | 
|---|
| 174 |     }
 | 
|---|
| 175 | 
 | 
|---|
| 176 |     ::Interface *pDestInterface = new ::Interface( &interfaceClass, actualTypeParameters );
 | 
|---|
| 177 | 
 | 
|---|
| 178 |     interfaces.push_back( pDestInterface );
 | 
|---|
| 179 | 
 | 
|---|
| 180 | 
 | 
|---|
| 181 |     /////////////////////////////////////////////////////////////////
 | 
|---|
| 182 |     // 基底クラスのメソッドからインターフェイスメソッドを再実装する
 | 
|---|
| 183 |     /////////////////////////////////////////////////////////////////
 | 
|---|
| 184 |     BOOST_FOREACH( CMethod *pMethod, GetDynamicMethods() )
 | 
|---|
| 185 |     {
 | 
|---|
| 186 |         CMethod *pMethodForOverride = pDestInterface->GetDynamicMethods().FindForOverride( pDestInterface->GetActualTypeParameters(), &pMethod->GetUserProc() );
 | 
|---|
| 187 |         if( pMethodForOverride )
 | 
|---|
| 188 |         {
 | 
|---|
| 189 |             pMethodForOverride->Override( &pMethod->GetUserProc(), pMethod->GetAccessibility(), false );
 | 
|---|
| 190 | 
 | 
|---|
| 191 |             // 実装元になるメソッドは呼び出し不可にしておく(オーバーロードの解決から除外する)
 | 
|---|
| 192 |             pMethod->SetNotUseMark( true );
 | 
|---|
| 193 |         }
 | 
|---|
| 194 |     }
 | 
|---|
| 195 | 
 | 
|---|
| 196 | 
 | 
|---|
| 197 |     /////////////////////////////////////////////////////////////////
 | 
|---|
| 198 |     // キャストメソッドを追加(内部コードは自動生成すること)
 | 
|---|
| 199 |     /////////////////////////////////////////////////////////////////
 | 
|---|
| 200 |     if( interfaceClass.IsInterface() )
 | 
|---|
| 201 |     {
 | 
|---|
| 202 |         // Function Operator() As ITest
 | 
|---|
| 203 | 
 | 
|---|
| 204 |         char methodName[255] = { 1, ESC_OPERATOR, CALC_AS, '\0' };
 | 
|---|
| 205 | 
 | 
|---|
| 206 |         //関数ハッシュへ登録
 | 
|---|
| 207 |         UserProc *pUserProc = new UserProc(
 | 
|---|
| 208 |             NamespaceScopes(),
 | 
|---|
| 209 |             NamespaceScopesCollection(),
 | 
|---|
| 210 |             methodName,
 | 
|---|
| 211 |             Procedure::Function,
 | 
|---|
| 212 |             false,
 | 
|---|
| 213 |             false,
 | 
|---|
| 214 |             false );
 | 
|---|
| 215 |         pUserProc->SetParentClass( this );
 | 
|---|
| 216 | 
 | 
|---|
| 217 |         Parameters params;
 | 
|---|
| 218 |         params.push_back( new Parameter( "_System_LocalThis", Type( DEF_PTR_VOID ) ) );
 | 
|---|
| 219 |         pUserProc->SetRealParams( params );
 | 
|---|
| 220 | 
 | 
|---|
| 221 |         pUserProc->SetReturnType( Type( DEF_OBJECT, interfaceClass ) );
 | 
|---|
| 222 |         pUserProc->_paramStr = "";
 | 
|---|
| 223 |         pUserProc->Using();
 | 
|---|
| 224 |         compiler.GetObjectModule().meta.GetUserProcs().Insert( pUserProc, -1 );
 | 
|---|
| 225 | 
 | 
|---|
| 226 |         LexicalAnalyzer::AddMethod(this,
 | 
|---|
| 227 |             pUserProc,
 | 
|---|
| 228 |             Prototype::Public,
 | 
|---|
| 229 |             0,
 | 
|---|
| 230 |             false,          // isConst
 | 
|---|
| 231 |             false,          // isAbstract
 | 
|---|
| 232 |             false,          // isVirtual
 | 
|---|
| 233 |             false,          // isOverride
 | 
|---|
| 234 |             "",
 | 
|---|
| 235 |             true,           // isAutoGeneration
 | 
|---|
| 236 |             -1
 | 
|---|
| 237 |         );
 | 
|---|
| 238 |     }
 | 
|---|
| 239 | 
 | 
|---|
| 240 | 
 | 
|---|
| 241 |     return true;
 | 
|---|
| 242 | }
 | 
|---|
| 243 | 
 | 
|---|
| 244 | CMember *CClass::CreateMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine )
 | 
|---|
| 245 | {
 | 
|---|
| 246 |     extern int cp;
 | 
|---|
| 247 | 
 | 
|---|
| 248 |     //構文を解析
 | 
|---|
| 249 |     char VarName[VN_SIZE];
 | 
|---|
| 250 |     char initBuffer[VN_SIZE];
 | 
|---|
| 251 |     char lpszConstructParameter[VN_SIZE];
 | 
|---|
| 252 |     Subscripts subscripts;
 | 
|---|
| 253 |     Type type;
 | 
|---|
| 254 |     GetDimentionFormat(buffer,VarName,subscripts,type,initBuffer,lpszConstructParameter);
 | 
|---|
| 255 | 
 | 
|---|
| 256 |     //重複チェック
 | 
|---|
| 257 |     if(this->DupliCheckAll(VarName)){
 | 
|---|
| 258 |         compiler.errorMessenger.Output(15,VarName,cp);
 | 
|---|
| 259 |     }
 | 
|---|
| 260 | 
 | 
|---|
| 261 |     CMember *pMember = new CMember( accessibility, VarName, type, isConst, subscripts, initBuffer, lpszConstructParameter );
 | 
|---|
| 262 |     pMember->source_code_address = nowLine;
 | 
|---|
| 263 |     return pMember;
 | 
|---|
| 264 | }
 | 
|---|
| 265 | void CClass::AddMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine ){
 | 
|---|
| 266 |     dynamicMembers.push_back(
 | 
|---|
| 267 |         CreateMember( accessibility, isConst, isRef, buffer, nowLine )
 | 
|---|
| 268 |     );
 | 
|---|
| 269 | }
 | 
|---|
| 270 | void CClass::AddStaticMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine ){
 | 
|---|
| 271 |     staticMembers.push_back(
 | 
|---|
| 272 |         CreateMember( accessibility, isConst, isRef, buffer, nowLine )
 | 
|---|
| 273 |     );
 | 
|---|
| 274 | }
 | 
|---|
| 275 | 
 | 
|---|
| 276 | bool CClass::DupliCheckAll(const char *name) const
 | 
|---|
| 277 | {
 | 
|---|
| 278 |     //重複チェック
 | 
|---|
| 279 | 
 | 
|---|
| 280 |     //メンバ
 | 
|---|
| 281 |     if(DupliCheckMember(name)) return 1;
 | 
|---|
| 282 | 
 | 
|---|
| 283 |     //メソッド
 | 
|---|
| 284 |     BOOST_FOREACH( const CMethod *pMethod, GetDynamicMethods() ){
 | 
|---|
| 285 |         if( lstrcmp( name, pMethod->GetUserProc().GetName().c_str() ) == 0 ){
 | 
|---|
| 286 |             return 1;
 | 
|---|
| 287 |         }
 | 
|---|
| 288 |     }
 | 
|---|
| 289 | 
 | 
|---|
| 290 |     return 0;
 | 
|---|
| 291 | }
 | 
|---|
| 292 | bool CClass::DupliCheckMember(const char *name) const
 | 
|---|
| 293 | {
 | 
|---|
| 294 |     //重複チェック
 | 
|---|
| 295 | 
 | 
|---|
| 296 |     if( this->HasSuperClass() )
 | 
|---|
| 297 |     {
 | 
|---|
| 298 |         if( this->GetSuperClass().DupliCheckMember( name ) )
 | 
|---|
| 299 |         {
 | 
|---|
| 300 |             // 基底クラスで重複が発見された
 | 
|---|
| 301 |             return true;
 | 
|---|
| 302 |         }
 | 
|---|
| 303 |     }
 | 
|---|
| 304 | 
 | 
|---|
| 305 |     // 動的メンバ
 | 
|---|
| 306 |     BOOST_FOREACH( CMember *pMember, dynamicMembers )
 | 
|---|
| 307 |     {
 | 
|---|
| 308 |         if( GetName() == pMember->GetName() )
 | 
|---|
| 309 |         {
 | 
|---|
| 310 |             return true;
 | 
|---|
| 311 |         }
 | 
|---|
| 312 |     }
 | 
|---|
| 313 | 
 | 
|---|
| 314 |     // 静的メンバ
 | 
|---|
| 315 |     BOOST_FOREACH( CMember *pMember, staticMembers ){
 | 
|---|
| 316 |         if( GetName() == pMember->GetName() ){
 | 
|---|
| 317 |             return true;
 | 
|---|
| 318 |         }
 | 
|---|
| 319 |     }
 | 
|---|
| 320 | 
 | 
|---|
| 321 |     return false;
 | 
|---|
| 322 | }
 | 
|---|
| 323 | 
 | 
|---|
| 324 | const CMember *CClass::FindDynamicMember( const char *memberName ) const
 | 
|---|
| 325 | {
 | 
|---|
| 326 |     if( this->HasSuperClass() )
 | 
|---|
| 327 |     {
 | 
|---|
| 328 |         // 基底クラスで検索
 | 
|---|
| 329 |         const CMember *result = this->GetSuperClass().FindDynamicMember( memberName );
 | 
|---|
| 330 |         if( result )
 | 
|---|
| 331 |         {
 | 
|---|
| 332 |             return result;
 | 
|---|
| 333 |         }
 | 
|---|
| 334 |     }
 | 
|---|
| 335 | 
 | 
|---|
| 336 |     BOOST_FOREACH( CMember *pMember, GetDynamicMembers() )
 | 
|---|
| 337 |     {
 | 
|---|
| 338 |         if( pMember->GetName() == memberName )
 | 
|---|
| 339 |         {
 | 
|---|
| 340 |             return pMember;
 | 
|---|
| 341 |         }
 | 
|---|
| 342 |     }
 | 
|---|
| 343 |     return NULL;
 | 
|---|
| 344 | }
 | 
|---|
| 345 | 
 | 
|---|
| 346 | void CClass::EnumDynamicMethodsOrInterfaceMethods( const char *methodName, std::vector<const UserProc *> &subs ) const
 | 
|---|
| 347 | {
 | 
|---|
| 348 |     // 動的メソッド
 | 
|---|
| 349 |     GetDynamicMethods().Enum( methodName, subs );
 | 
|---|
| 350 | 
 | 
|---|
| 351 |     // インターフェイス メソッド
 | 
|---|
| 352 |     BOOST_FOREACH( ::Interface *pInterface, GetInterfaces() )
 | 
|---|
| 353 |     {
 | 
|---|
| 354 |         pInterface->GetDynamicMethods().Enum( methodName, subs );
 | 
|---|
| 355 |     }
 | 
|---|
| 356 | }
 | 
|---|
| 357 | const CMethod *CClass::GetDynamicMethodOrInterfaceMethod( const UserProc *pUserProc ) const
 | 
|---|
| 358 | {
 | 
|---|
| 359 |     // 動的メソッド
 | 
|---|
| 360 |     const CMethod *result = GetDynamicMethods().GetMethodPtr( pUserProc );
 | 
|---|
| 361 | 
 | 
|---|
| 362 |     if( !result )
 | 
|---|
| 363 |     {
 | 
|---|
| 364 |         // インターフェイス メソッド
 | 
|---|
| 365 |         BOOST_FOREACH( ::Interface *pInterface, GetInterfaces() )
 | 
|---|
| 366 |         {
 | 
|---|
| 367 |             result = pInterface->GetDynamicMethods().GetMethodPtr( pUserProc );
 | 
|---|
| 368 |             if( result )
 | 
|---|
| 369 |             {
 | 
|---|
| 370 |                 return result;
 | 
|---|
| 371 |             }
 | 
|---|
| 372 |         }
 | 
|---|
| 373 |     }
 | 
|---|
| 374 | 
 | 
|---|
| 375 |     return result;
 | 
|---|
| 376 | }
 | 
|---|
| 377 | 
 | 
|---|
| 378 | const ::Delegate &CClass::GetDelegate() const
 | 
|---|
| 379 | {
 | 
|---|
| 380 |     const ::Delegate *dg = compiler.GetObjectModule().meta.GetDelegates().GetHashArrayElement( GetName().c_str() );
 | 
|---|
| 381 |     while( dg )
 | 
|---|
| 382 |     {
 | 
|---|
| 383 |         if( dg->IsEqualSymbol( GetNamespaceScopes(), GetName() ) ){
 | 
|---|
| 384 |             //名前空間とクラス名が一致した
 | 
|---|
| 385 |             return *dg;
 | 
|---|
| 386 |         }
 | 
|---|
| 387 |         dg = dg->GetChainNext();
 | 
|---|
| 388 |     }
 | 
|---|
| 389 | 
 | 
|---|
| 390 |     Jenga::Throw( "CClass::GetDelegateメソッドに失敗" );
 | 
|---|
| 391 |     static ::Delegate dummy;
 | 
|---|
| 392 |     return dummy;
 | 
|---|
| 393 | }
 | 
|---|
| 394 | 
 | 
|---|
| 395 | //サイズを取得
 | 
|---|
| 396 | int CClass::GetSize() const
 | 
|---|
| 397 | {
 | 
|---|
| 398 |     int resultSize = 0;
 | 
|---|
| 399 | 
 | 
|---|
| 400 |     int alignment = 1;
 | 
|---|
| 401 |     if( this->IsStructure() )
 | 
|---|
| 402 |     {
 | 
|---|
| 403 |         // 構造体のとき
 | 
|---|
| 404 | 
 | 
|---|
| 405 |         if( this->GetFixedAlignment() )
 | 
|---|
| 406 |         {
 | 
|---|
| 407 |             // アラインメントの固定値が指定されていた場合はそれを取得
 | 
|---|
| 408 |             alignment = this->GetFixedAlignment();
 | 
|---|
| 409 |         }
 | 
|---|
| 410 |     }
 | 
|---|
| 411 |     else
 | 
|---|
| 412 |     {
 | 
|---|
| 413 |         // それ以外
 | 
|---|
| 414 | 
 | 
|---|
| 415 |         if( this->HasSuperClass() )
 | 
|---|
| 416 |         {
 | 
|---|
| 417 |             // 基底クラスのサイズを追加
 | 
|---|
| 418 |             resultSize += this->GetSuperClass().GetSize();
 | 
|---|
| 419 | 
 | 
|---|
| 420 |             // 基底クラスのアラインメントを取得
 | 
|---|
| 421 |             alignment = this->GetSuperClass().GetAlignment();
 | 
|---|
| 422 |         }
 | 
|---|
| 423 |         else
 | 
|---|
| 424 |         {
 | 
|---|
| 425 |             // 基底クラスが存在しないとき
 | 
|---|
| 426 | 
 | 
|---|
| 427 |             // 仮想関数が存在する場合はvtbl及びvtblMasterListへのポインタのサイズを追加
 | 
|---|
| 428 |             resultSize += IsExistVirtualFunctions() ? PTR_SIZE*2 : 0;
 | 
|---|
| 429 |         }
 | 
|---|
| 430 |     }
 | 
|---|
| 431 | 
 | 
|---|
| 432 |     BOOST_FOREACH( CMember *pMember, dynamicMembers )
 | 
|---|
| 433 |     {
 | 
|---|
| 434 |         // メンバサイズ
 | 
|---|
| 435 |         int tempMemberSize = pMember->GetType().GetSize();
 | 
|---|
| 436 | 
 | 
|---|
| 437 |         // 一時アラインメントを算出
 | 
|---|
| 438 |         int tempAlignment = tempMemberSize;
 | 
|---|
| 439 |         if( pMember->GetType().IsStruct() )
 | 
|---|
| 440 |         {
 | 
|---|
| 441 |             // メンバが構造体の場合は、メンバのアラインメントを取得
 | 
|---|
| 442 |             tempAlignment = pMember->GetType().GetClass().GetAlignment();
 | 
|---|
| 443 |         }
 | 
|---|
| 444 | 
 | 
|---|
| 445 |         // アラインメントを考慮してパディングを追加
 | 
|---|
| 446 |         if( GetFixedAlignment() && alignment < tempAlignment )
 | 
|---|
| 447 |         {
 | 
|---|
| 448 |             if( resultSize % alignment )
 | 
|---|
| 449 |             {
 | 
|---|
| 450 |                 resultSize += alignment - ( resultSize % alignment );
 | 
|---|
| 451 |             }
 | 
|---|
| 452 |         }
 | 
|---|
| 453 |         else
 | 
|---|
| 454 |         {
 | 
|---|
| 455 |             if( alignment < tempAlignment )
 | 
|---|
| 456 |             {
 | 
|---|
| 457 |                 // 最大アラインメントを更新
 | 
|---|
| 458 |                 alignment = tempAlignment;
 | 
|---|
| 459 |             }
 | 
|---|
| 460 | 
 | 
|---|
| 461 |             if( tempMemberSize == 0 )
 | 
|---|
| 462 |             {
 | 
|---|
| 463 |                 if( !pMember->GetType().IsStruct() )
 | 
|---|
| 464 |                 {
 | 
|---|
| 465 |                     compiler.errorMessenger.OutputFatalError();
 | 
|---|
| 466 |                 }
 | 
|---|
| 467 | 
 | 
|---|
| 468 |                 //メンバを持たない構造体
 | 
|---|
| 469 |                 //※何もしない(オフセットの計算をしない)
 | 
|---|
| 470 |             }
 | 
|---|
| 471 |             else{
 | 
|---|
| 472 |                 if( resultSize % tempAlignment )
 | 
|---|
| 473 |                 {
 | 
|---|
| 474 |                     resultSize += tempAlignment - ( resultSize % tempAlignment );
 | 
|---|
| 475 |                 }
 | 
|---|
| 476 |             }
 | 
|---|
| 477 |         }
 | 
|---|
| 478 | 
 | 
|---|
| 479 |         // メンバサイズを加算(配列を考慮)
 | 
|---|
| 480 |         resultSize += tempMemberSize * Variable::GetSubScriptCounts( pMember->GetSubscripts() );
 | 
|---|
| 481 |     }
 | 
|---|
| 482 | 
 | 
|---|
| 483 |     if( alignment )
 | 
|---|
| 484 |     {
 | 
|---|
| 485 |         // 末尾アラインメントを考慮してパディングを追加
 | 
|---|
| 486 |         if( resultSize % alignment )
 | 
|---|
| 487 |         {
 | 
|---|
| 488 |             resultSize += alignment - ( resultSize % alignment );
 | 
|---|
| 489 |         }
 | 
|---|
| 490 |     }
 | 
|---|
| 491 | 
 | 
|---|
| 492 |     return resultSize;
 | 
|---|
| 493 | }
 | 
|---|
| 494 | 
 | 
|---|
| 495 | //メンバのオフセットを取得
 | 
|---|
| 496 | int CClass::GetMemberOffset( const char *memberName ) const
 | 
|---|
| 497 | {
 | 
|---|
| 498 |     int resultSize = 0;
 | 
|---|
| 499 | 
 | 
|---|
| 500 |     int alignment = 1;
 | 
|---|
| 501 |     if( this->IsStructure() )
 | 
|---|
| 502 |     {
 | 
|---|
| 503 |         // 構造体のとき
 | 
|---|
| 504 | 
 | 
|---|
| 505 |         if( this->GetFixedAlignment() )
 | 
|---|
| 506 |         {
 | 
|---|
| 507 |             // アラインメントの固定値が指定されていた場合はそれを取得
 | 
|---|
| 508 |             alignment = this->GetFixedAlignment();
 | 
|---|
| 509 |         }
 | 
|---|
| 510 |     }
 | 
|---|
| 511 |     else
 | 
|---|
| 512 |     {
 | 
|---|
| 513 |         // それ以外
 | 
|---|
| 514 | 
 | 
|---|
| 515 |         if( this->HasSuperClass() )
 | 
|---|
| 516 |         {
 | 
|---|
| 517 |             if( this->GetSuperClass().HasDynamicMember( memberName ) )
 | 
|---|
| 518 |             {
 | 
|---|
| 519 |                 // 基底クラスのメンバを取得
 | 
|---|
| 520 |                 return this->GetSuperClass().GetMemberOffset( memberName );
 | 
|---|
| 521 |             }
 | 
|---|
| 522 | 
 | 
|---|
| 523 |             // 基底クラスのサイズを追加
 | 
|---|
| 524 |             resultSize += this->GetSuperClass().GetSize();
 | 
|---|
| 525 | 
 | 
|---|
| 526 |             // 基底クラスのアラインメントを取得
 | 
|---|
| 527 |             alignment = this->GetSuperClass().GetAlignment();
 | 
|---|
| 528 |         }
 | 
|---|
| 529 |         else
 | 
|---|
| 530 |         {
 | 
|---|
| 531 |             // 基底クラスが存在しないとき
 | 
|---|
| 532 | 
 | 
|---|
| 533 |             // 仮想関数が存在する場合はvtbl及びvtblMasterListへのポインタのサイズを追加
 | 
|---|
| 534 |             resultSize += IsExistVirtualFunctions() ? PTR_SIZE*2 : 0;
 | 
|---|
| 535 |         }
 | 
|---|
| 536 |     }
 | 
|---|
| 537 | 
 | 
|---|
| 538 |     BOOST_FOREACH( CMember *pMember, dynamicMembers )
 | 
|---|
| 539 |     {
 | 
|---|
| 540 |         // メンバサイズ
 | 
|---|
| 541 |         int tempMemberSize = pMember->GetType().GetSize();
 | 
|---|
| 542 | 
 | 
|---|
| 543 |         // 一時アラインメントを算出
 | 
|---|
| 544 |         int tempAlignment = tempMemberSize;
 | 
|---|
| 545 |         if( pMember->GetType().IsStruct() )
 | 
|---|
| 546 |         {
 | 
|---|
| 547 |             // メンバが構造体の場合は、メンバのアラインメントを取得
 | 
|---|
| 548 |             tempAlignment = pMember->GetType().GetClass().GetAlignment();
 | 
|---|
| 549 |         }
 | 
|---|
| 550 | 
 | 
|---|
| 551 |         // アラインメントを考慮してパディングを追加
 | 
|---|
| 552 |         if( GetFixedAlignment() && alignment < tempAlignment )
 | 
|---|
| 553 |         {
 | 
|---|
| 554 |             if( resultSize % alignment )
 | 
|---|
| 555 |             {
 | 
|---|
| 556 |                 resultSize += alignment - ( resultSize % alignment );
 | 
|---|
| 557 |             }
 | 
|---|
| 558 |         }
 | 
|---|
| 559 |         else
 | 
|---|
| 560 |         {
 | 
|---|
| 561 |             if( alignment < tempAlignment )
 | 
|---|
| 562 |             {
 | 
|---|
| 563 |                 // 最大アラインメントを更新
 | 
|---|
| 564 |                 alignment = tempAlignment;
 | 
|---|
| 565 |             }
 | 
|---|
| 566 | 
 | 
|---|
| 567 |             if( tempMemberSize == 0 )
 | 
|---|
| 568 |             {
 | 
|---|
| 569 |                 if( !pMember->GetType().IsStruct() )
 | 
|---|
| 570 |                 {
 | 
|---|
| 571 |                     compiler.errorMessenger.OutputFatalError();
 | 
|---|
| 572 |                 }
 | 
|---|
| 573 | 
 | 
|---|
| 574 |                 //メンバを持たない構造体
 | 
|---|
| 575 |                 //※何もしない(オフセットの計算をしない)
 | 
|---|
| 576 |             }
 | 
|---|
| 577 |             else{
 | 
|---|
| 578 |                 if( resultSize % tempAlignment )
 | 
|---|
| 579 |                 {
 | 
|---|
| 580 |                     resultSize += tempAlignment - ( resultSize % tempAlignment );
 | 
|---|
| 581 |                 }
 | 
|---|
| 582 |             }
 | 
|---|
| 583 |         }
 | 
|---|
| 584 | 
 | 
|---|
| 585 |         if(memberName){
 | 
|---|
| 586 |             //メンバ指定がある場合は、オフセットを返す
 | 
|---|
| 587 |             if( pMember->GetName() == memberName )
 | 
|---|
| 588 |             {
 | 
|---|
| 589 |                 return resultSize;
 | 
|---|
| 590 |             }
 | 
|---|
| 591 |         }
 | 
|---|
| 592 | 
 | 
|---|
| 593 |         // メンバサイズを加算(配列を考慮)
 | 
|---|
| 594 |         resultSize += tempMemberSize * Variable::GetSubScriptCounts( pMember->GetSubscripts() );
 | 
|---|
| 595 |     }
 | 
|---|
| 596 | 
 | 
|---|
| 597 |     if( alignment )
 | 
|---|
| 598 |     {
 | 
|---|
| 599 |         // 末尾アラインメントを考慮してパディングを追加
 | 
|---|
| 600 |         if( resultSize % alignment )
 | 
|---|
| 601 |         {
 | 
|---|
| 602 |             resultSize += alignment - ( resultSize % alignment );
 | 
|---|
| 603 |         }
 | 
|---|
| 604 |     }
 | 
|---|
| 605 | 
 | 
|---|
| 606 |     return resultSize;
 | 
|---|
| 607 | }
 | 
|---|
| 608 | int CClass::GetAlignment() const
 | 
|---|
| 609 | {
 | 
|---|
| 610 |     int alignment = 1;
 | 
|---|
| 611 |     if( this->IsStructure() )
 | 
|---|
| 612 |     {
 | 
|---|
| 613 |         // 構造体のとき
 | 
|---|
| 614 | 
 | 
|---|
| 615 |         if( this->GetFixedAlignment() )
 | 
|---|
| 616 |         {
 | 
|---|
| 617 |             // アラインメントの固定値が指定されていた場合はそれを取得
 | 
|---|
| 618 |             return this->GetFixedAlignment();
 | 
|---|
| 619 |         }
 | 
|---|
| 620 |     }
 | 
|---|
| 621 |     else
 | 
|---|
| 622 |     {
 | 
|---|
| 623 |         // それ以外
 | 
|---|
| 624 | 
 | 
|---|
| 625 |         if( this->HasSuperClass() )
 | 
|---|
| 626 |         {
 | 
|---|
| 627 |             // 基底クラスのアラインメントを取得
 | 
|---|
| 628 |             alignment = this->GetSuperClass().GetAlignment();
 | 
|---|
| 629 |         }
 | 
|---|
| 630 |         else
 | 
|---|
| 631 |         {
 | 
|---|
| 632 |             // 基底クラスが存在しないとき
 | 
|---|
| 633 | 
 | 
|---|
| 634 |             // 仮想関数が存在する場合はvtbl及びvtblMasterListへのポインタのサイズを追加
 | 
|---|
| 635 |             alignment = PTR_SIZE;
 | 
|---|
| 636 |         }
 | 
|---|
| 637 |     }
 | 
|---|
| 638 | 
 | 
|---|
| 639 |     BOOST_FOREACH( CMember *pMember, dynamicMembers )
 | 
|---|
| 640 |     {
 | 
|---|
| 641 |         int tempAlignment = pMember->GetType().GetSize();
 | 
|---|
| 642 |         if( pMember->GetType().IsStruct() )
 | 
|---|
| 643 |         {
 | 
|---|
| 644 |             // メンバが構造体の場合は、メンバのアラインメントを取得
 | 
|---|
| 645 |             tempAlignment = pMember->GetType().GetClass().GetAlignment();
 | 
|---|
| 646 |         }
 | 
|---|
| 647 | 
 | 
|---|
| 648 |         if( alignment < tempAlignment )
 | 
|---|
| 649 |         {
 | 
|---|
| 650 |             // 最大アラインメントを更新
 | 
|---|
| 651 |             alignment = tempAlignment;
 | 
|---|
| 652 |         }
 | 
|---|
| 653 |     }
 | 
|---|
| 654 | 
 | 
|---|
| 655 |     return alignment;
 | 
|---|
| 656 | }
 | 
|---|
| 657 | 
 | 
|---|
| 658 | void CClass::GetVtblMasterListIndexAndVtblIndex( const UserProc *pUserProc, int &vtblMasterListIndex, int &vtblIndex ) const
 | 
|---|
| 659 | {
 | 
|---|
| 660 |     vtblMasterListIndex = 0;
 | 
|---|
| 661 | 
 | 
|---|
| 662 |     vtblIndex = 0;
 | 
|---|
| 663 |     BOOST_FOREACH( const CMethod *pMethod, GetDynamicMethods() ){
 | 
|---|
| 664 |         if( &pMethod->GetUserProc() == pUserProc )
 | 
|---|
| 665 |         {
 | 
|---|
| 666 |             return;
 | 
|---|
| 667 |         }
 | 
|---|
| 668 | 
 | 
|---|
| 669 |         if( pMethod->IsVirtual() )
 | 
|---|
| 670 |         {
 | 
|---|
| 671 |             vtblIndex++;
 | 
|---|
| 672 |         }
 | 
|---|
| 673 |     }
 | 
|---|
| 674 | 
 | 
|---|
| 675 |     BOOST_FOREACH( const ::Interface *pInterface, interfaces )
 | 
|---|
| 676 |     {
 | 
|---|
| 677 |         vtblMasterListIndex++;
 | 
|---|
| 678 | 
 | 
|---|
| 679 |         vtblIndex = 0;
 | 
|---|
| 680 |         BOOST_FOREACH( const CMethod *pMethod, pInterface->GetDynamicMethods() ){
 | 
|---|
| 681 |             if( &pMethod->GetUserProc() == pUserProc )
 | 
|---|
| 682 |             {
 | 
|---|
| 683 |                 return;
 | 
|---|
| 684 |             }
 | 
|---|
| 685 | 
 | 
|---|
| 686 |             if( pMethod->IsVirtual() )
 | 
|---|
| 687 |             {
 | 
|---|
| 688 |                 vtblIndex++;
 | 
|---|
| 689 |             }
 | 
|---|
| 690 |         }
 | 
|---|
| 691 |     }
 | 
|---|
| 692 | 
 | 
|---|
| 693 |     compiler.errorMessenger.OutputFatalError();
 | 
|---|
| 694 |     return;
 | 
|---|
| 695 | }
 | 
|---|
| 696 | int CClass::GetVtblMasterListIndex( const CClass *pClass ) const
 | 
|---|
| 697 | {
 | 
|---|
| 698 |     int result = 0;
 | 
|---|
| 699 | 
 | 
|---|
| 700 |     BOOST_FOREACH( const ::Interface *pInterface, interfaces )
 | 
|---|
| 701 |     {
 | 
|---|
| 702 |         result++;
 | 
|---|
| 703 |         
 | 
|---|
| 704 |         if( &pInterface->GetClass() == pClass )
 | 
|---|
| 705 |         {
 | 
|---|
| 706 |             return result;
 | 
|---|
| 707 |         }
 | 
|---|
| 708 |     }
 | 
|---|
| 709 | 
 | 
|---|
| 710 |     compiler.errorMessenger.OutputFatalError();
 | 
|---|
| 711 |     return 0;
 | 
|---|
| 712 | }
 | 
|---|
| 713 | long CClass::GetComVtblOffset() const
 | 
|---|
| 714 | {
 | 
|---|
| 715 |     return comVtblOffset;
 | 
|---|
| 716 | }
 | 
|---|
| 717 | long CClass::GetVtblMasterListOffset() const
 | 
|---|
| 718 | {
 | 
|---|
| 719 |     //既に存在する場合はそれを返す
 | 
|---|
| 720 |     if( vtblMasterListOffset == -1 )
 | 
|---|
| 721 |     {
 | 
|---|
| 722 |         compiler.errorMessenger.OutputFatalError();
 | 
|---|
| 723 |     }
 | 
|---|
| 724 | 
 | 
|---|
| 725 |     return vtblMasterListOffset;
 | 
|---|
| 726 | }
 | 
|---|
| 727 | void CClass::GenerateVTableMasterList( const std::vector<long> &vtableMasterList, long &offset )
 | 
|---|
| 728 | {
 | 
|---|
| 729 |     offset = compiler.GetObjectModule().dataTable.AddBinary(
 | 
|---|
| 730 |         (void *)&vtableMasterList[0],
 | 
|---|
| 731 |         static_cast<int>(vtableMasterList.size()*sizeof(LONG_PTR))
 | 
|---|
| 732 |     );
 | 
|---|
| 733 | }
 | 
|---|
| 734 | void CClass::GenerateFullVTables()
 | 
|---|
| 735 | {
 | 
|---|
| 736 |     if( IsAbstract() )
 | 
|---|
| 737 |     {
 | 
|---|
| 738 |         // 抽象クラスは無視
 | 
|---|
| 739 |         return;
 | 
|---|
| 740 |     }
 | 
|---|
| 741 |     if( !IsUsing() )
 | 
|---|
| 742 |     {
 | 
|---|
| 743 |         // 使われていないクラスは無視
 | 
|---|
| 744 |         return;
 | 
|---|
| 745 |     }
 | 
|---|
| 746 | 
 | 
|---|
| 747 |     // vtblマスターリストの元データに不要なデータが含まれていたらエラー
 | 
|---|
| 748 |     if( vtblMasterList.size() )
 | 
|---|
| 749 |     {
 | 
|---|
| 750 |         compiler.errorMessenger.OutputFatalError();
 | 
|---|
| 751 |     }
 | 
|---|
| 752 | 
 | 
|---|
| 753 |     // 自身のクラスのvtblを生成
 | 
|---|
| 754 |     GetDynamicMethods().GenerateVTablePart( this->vtbl_offset );
 | 
|---|
| 755 |     vtblMasterList.push_back( this->vtbl_offset );
 | 
|---|
| 756 | 
 | 
|---|
| 757 |     // インターフェイスのvtblを生成
 | 
|---|
| 758 |     BOOST_FOREACH( const ::Interface *pInterface, interfaces )
 | 
|---|
| 759 |     {
 | 
|---|
| 760 |         long tempVtblOffset;
 | 
|---|
| 761 |         pInterface->GetDynamicMethods().GenerateVTablePart( tempVtblOffset );
 | 
|---|
| 762 |         vtblMasterList.push_back( tempVtblOffset );
 | 
|---|
| 763 | 
 | 
|---|
| 764 |         pInterface->SetVtblOffset( tempVtblOffset );
 | 
|---|
| 765 | 
 | 
|---|
| 766 |         if( pInterface->GetClass().IsComInterface() )
 | 
|---|
| 767 |         {
 | 
|---|
| 768 |             if( this->comVtblOffset )
 | 
|---|
| 769 |             {
 | 
|---|
| 770 |                 compiler.errorMessenger.OutputFatalError();
 | 
|---|
| 771 |             }
 | 
|---|
| 772 |             this->comVtblOffset = tempVtblOffset;
 | 
|---|
| 773 |         }
 | 
|---|
| 774 |     }
 | 
|---|
| 775 | 
 | 
|---|
| 776 |     // vtblマスターリストを生成
 | 
|---|
| 777 |     GenerateVTableMasterList( vtblMasterList, this->vtblMasterListOffset );
 | 
|---|
| 778 | }
 | 
|---|
| 779 | void CClass::ActionVtblSchedule( LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection, LONG_PTR MemPos_DataSection )
 | 
|---|
| 780 | {
 | 
|---|
| 781 |     if( IsAbstract() )
 | 
|---|
| 782 |     {
 | 
|---|
| 783 |         // 抽象クラスは無視
 | 
|---|
| 784 |         return;
 | 
|---|
| 785 |     }
 | 
|---|
| 786 |     if( !IsUsing() )
 | 
|---|
| 787 |     {
 | 
|---|
| 788 |         // 使われていないクラスは無視
 | 
|---|
| 789 |         return;
 | 
|---|
| 790 |     }
 | 
|---|
| 791 |     if(vtbl_offset==-1) return;
 | 
|---|
| 792 | 
 | 
|---|
| 793 |     // 自身のクラスのvtbl
 | 
|---|
| 794 |     {
 | 
|---|
| 795 |         LONG_PTR *pVtbl = (LONG_PTR *)((char *)compiler.GetObjectModule().dataTable.GetPtr() + vtbl_offset);
 | 
|---|
| 796 | 
 | 
|---|
| 797 |         for( int i=0; i<GetVtblNum(); i++ ){
 | 
|---|
| 798 |             const UserProc *pUserProc = (UserProc *)pVtbl[i];
 | 
|---|
| 799 |             if(!pUserProc) continue;
 | 
|---|
| 800 | 
 | 
|---|
| 801 |             if( pUserProc->GetBeginOpAddress() == 0
 | 
|---|
| 802 |                 && pUserProc->GetEndOpAddress() == 0 )
 | 
|---|
| 803 |             {
 | 
|---|
| 804 |                 Jenga::Throw( "未解決の仮想関数が存在する" );
 | 
|---|
| 805 |             }
 | 
|---|
| 806 | 
 | 
|---|
| 807 |             pVtbl[i] = pUserProc->GetBeginOpAddress() + ImageBase + MemPos_CodeSection;
 | 
|---|
| 808 |         }
 | 
|---|
| 809 |     }
 | 
|---|
| 810 | 
 | 
|---|
| 811 |     // インターフェイスのvtbl
 | 
|---|
| 812 |     BOOST_FOREACH( const ::Interface *pInterface, interfaces )
 | 
|---|
| 813 |     {
 | 
|---|
| 814 |         LONG_PTR *pVtbl = (LONG_PTR *)((char *)compiler.GetObjectModule().dataTable.GetPtr() + pInterface->GetVtblOffset());
 | 
|---|
| 815 | 
 | 
|---|
| 816 |         for( int i=0; i<pInterface->GetClass().GetVtblNum(); i++ ){
 | 
|---|
| 817 |             const UserProc *pUserProc = (UserProc *)pVtbl[i];
 | 
|---|
| 818 |             if(!pUserProc) continue;
 | 
|---|
| 819 | 
 | 
|---|
| 820 |             if( pUserProc->GetBeginOpAddress() == 0
 | 
|---|
| 821 |                 && pUserProc->GetEndOpAddress() == 0 )
 | 
|---|
| 822 |             {
 | 
|---|
| 823 |                 Jenga::Throw( "未解決の仮想関数が存在する" );
 | 
|---|
| 824 |             }
 | 
|---|
| 825 | 
 | 
|---|
| 826 |             pVtbl[i] = pUserProc->GetBeginOpAddress() + ImageBase + MemPos_CodeSection;
 | 
|---|
| 827 |         }
 | 
|---|
| 828 |     }
 | 
|---|
| 829 | 
 | 
|---|
| 830 |     // vtblマスターリスト
 | 
|---|
| 831 |     LONG_PTR *pVtblMasterList = (LONG_PTR *)((char *)compiler.GetObjectModule().dataTable.GetPtr() + vtblMasterListOffset );
 | 
|---|
| 832 |     for( int i=0; i<static_cast<int>(vtblMasterList.size()); i++ )
 | 
|---|
| 833 |     {
 | 
|---|
| 834 |         pVtblMasterList[i] = vtblMasterList[i] + ImageBase + MemPos_DataSection;
 | 
|---|
| 835 |     }
 | 
|---|
| 836 | }
 | 
|---|
| 837 | bool CClass::IsAbstract() const
 | 
|---|
| 838 | {
 | 
|---|
| 839 |     // 未実装(abstract)の仮想関数を持つ場合はtrueを返す
 | 
|---|
| 840 | 
 | 
|---|
| 841 |     BOOST_FOREACH( const CMethod *pMethod, GetDynamicMethods() ){
 | 
|---|
| 842 |         if(pMethod->IsVirtual()){
 | 
|---|
| 843 |             if(pMethod->IsAbstract()){
 | 
|---|
| 844 |                 return true;
 | 
|---|
| 845 |             }
 | 
|---|
| 846 |         }
 | 
|---|
| 847 |     }
 | 
|---|
| 848 | 
 | 
|---|
| 849 |     // インターフェイスのvtbl
 | 
|---|
| 850 |     BOOST_FOREACH( const ::Interface *pInterface, interfaces )
 | 
|---|
| 851 |     {
 | 
|---|
| 852 |         BOOST_FOREACH( const CMethod *pMethod, pInterface->GetDynamicMethods() ){
 | 
|---|
| 853 |             if(pMethod->IsVirtual()){
 | 
|---|
| 854 |                 if(pMethod->IsAbstract()){
 | 
|---|
| 855 |                     return true;
 | 
|---|
| 856 |                 }
 | 
|---|
| 857 |             }
 | 
|---|
| 858 |         }
 | 
|---|
| 859 |     }
 | 
|---|
| 860 | 
 | 
|---|
| 861 |     return false;
 | 
|---|
| 862 | }
 | 
|---|
| 863 | 
 | 
|---|
| 864 | CClass *Classes::Create( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, const char *name){
 | 
|---|
| 865 |     return new CClass(namespaceScopes, importedNamespaces, name);
 | 
|---|
| 866 | }
 | 
|---|
| 867 | bool Classes::Insert( CClass *pClass, int nowLine )
 | 
|---|
| 868 | {
 | 
|---|
| 869 |     /////////////////////////////////
 | 
|---|
| 870 |     // ハッシュデータに追加
 | 
|---|
| 871 |     /////////////////////////////////
 | 
|---|
| 872 | 
 | 
|---|
| 873 |     if( !Put( pClass ) )
 | 
|---|
| 874 |     {
 | 
|---|
| 875 |         compiler.errorMessenger.Output(15,pClass->GetName(), nowLine);
 | 
|---|
| 876 |         return false;
 | 
|---|
| 877 |     }
 | 
|---|
| 878 |     return true;
 | 
|---|
| 879 | }
 | 
|---|
| 880 | CClass *Classes::Add( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, const char *name,int nowLine){
 | 
|---|
| 881 |     //////////////////////////////////////////////////////////////////////////
 | 
|---|
| 882 |     // クラスを追加
 | 
|---|
| 883 |     // ※名前のみを登録。その他の情報はSetClassメソッドで!
 | 
|---|
| 884 |     //////////////////////////////////////////////////////////////////////////
 | 
|---|
| 885 | 
 | 
|---|
| 886 |     CClass *pClass = Create(namespaceScopes, importedNamespaces, name);
 | 
|---|
| 887 | 
 | 
|---|
| 888 |     if( !Insert( pClass, nowLine ) )
 | 
|---|
| 889 |     {
 | 
|---|
| 890 |         return NULL;
 | 
|---|
| 891 |     }
 | 
|---|
| 892 | 
 | 
|---|
| 893 |     return pClass;  
 | 
|---|
| 894 | }
 | 
|---|
| 895 | 
 | 
|---|
| 896 | void Classes::GenerateVTables()
 | 
|---|
| 897 | {
 | 
|---|
| 898 |     Iterator_Reset();
 | 
|---|
| 899 |     while( Iterator_HasNext() )
 | 
|---|
| 900 |     {
 | 
|---|
| 901 |         CClass *pClass = Iterator_GetNext();
 | 
|---|
| 902 |         pClass->GenerateFullVTables();
 | 
|---|
| 903 |     }
 | 
|---|
| 904 | }
 | 
|---|
| 905 | 
 | 
|---|
| 906 | void Classes::ActionVtblSchedule( LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection, LONG_PTR MemPos_DataSection ){
 | 
|---|
| 907 |     Iterator_Reset();
 | 
|---|
| 908 |     while( Iterator_HasNext() )
 | 
|---|
| 909 |     {
 | 
|---|
| 910 |         CClass *pClass = Iterator_GetNext();
 | 
|---|
| 911 |         pClass->ActionVtblSchedule( ImageBase, MemPos_CodeSection, MemPos_DataSection);
 | 
|---|
| 912 |     }
 | 
|---|
| 913 | }
 | 
|---|
| 914 | 
 | 
|---|
| 915 | 
 | 
|---|
| 916 | void Classes::InitStaticMember(){
 | 
|---|
| 917 |     //静的メンバをグローバル領域に作成
 | 
|---|
| 918 | 
 | 
|---|
| 919 |     //イテレータをリセット
 | 
|---|
| 920 | 
 | 
|---|
| 921 |     extern int cp;
 | 
|---|
| 922 |     int back_cp=cp;
 | 
|---|
| 923 | 
 | 
|---|
| 924 |     this->Iterator_Reset();
 | 
|---|
| 925 |     while(this->Iterator_HasNext()){
 | 
|---|
| 926 |         CClass &objClass = *this->Iterator_GetNext();
 | 
|---|
| 927 |         if( objClass.isTargetObjectModule == false )
 | 
|---|
| 928 |         {
 | 
|---|
| 929 |             // 静的リンクライブラリの場合は飛ばす(既にインスタンスが定義済みであるため)
 | 
|---|
| 930 |             continue;
 | 
|---|
| 931 |         }
 | 
|---|
| 932 | 
 | 
|---|
| 933 |         // 名前空間をセット
 | 
|---|
| 934 |         compiler.GetNamespaceSupporter().GetLivingNamespaceScopes() = objClass.GetNamespaceScopes();
 | 
|---|
| 935 | 
 | 
|---|
| 936 |         DWORD dwFlags = 0;
 | 
|---|
| 937 |         if( objClass.GetName() == "_System_TypeBase" )
 | 
|---|
| 938 |         {
 | 
|---|
| 939 |             // _System_TypeBaseクラスはグローバル、スタティック領域を初期化するためのクラスなのでここでの初期化は除外する
 | 
|---|
| 940 |             dwFlags |= DIMFLAG_NONCALL_CONSTRACTOR;
 | 
|---|
| 941 |         }
 | 
|---|
| 942 | 
 | 
|---|
| 943 |         // コンパイル中クラスとしてセット
 | 
|---|
| 944 |         compiler.SetCompilingClass( &objClass );
 | 
|---|
| 945 | 
 | 
|---|
| 946 |         const EnumInfo *pEnumInfo = NULL;
 | 
|---|
| 947 |         if( objClass.IsEnum() )
 | 
|---|
| 948 |         {
 | 
|---|
| 949 |             pEnumInfo = compiler.enumInfoCollection.Find( objClass );
 | 
|---|
| 950 |         }
 | 
|---|
| 951 | 
 | 
|---|
| 952 |         int i=0;
 | 
|---|
| 953 |         BOOST_FOREACH( CMember *member, objClass.GetStaticMembers() )
 | 
|---|
| 954 |         {
 | 
|---|
| 955 |             if( pEnumInfo )
 | 
|---|
| 956 |             {
 | 
|---|
| 957 |                 cp = pEnumInfo->GetEnumMember( member->GetName() ).GetSourceIndex();
 | 
|---|
| 958 |             }
 | 
|---|
| 959 | 
 | 
|---|
| 960 |             char temporary[VN_SIZE];
 | 
|---|
| 961 |             sprintf(temporary,"%s.%s",objClass.GetName().c_str(),member->GetName().c_str());
 | 
|---|
| 962 |             dim(
 | 
|---|
| 963 |                 temporary,
 | 
|---|
| 964 |                 member->GetSubscripts(),
 | 
|---|
| 965 |                 member->GetType(),
 | 
|---|
| 966 |                 member->GetInitializeExpression().c_str(),
 | 
|---|
| 967 |                 member->GetConstructParameter().c_str(),
 | 
|---|
| 968 |                 dwFlags);
 | 
|---|
| 969 | 
 | 
|---|
| 970 |             i++;
 | 
|---|
| 971 |         }
 | 
|---|
| 972 | 
 | 
|---|
| 973 |         compiler.SetCompilingClass( NULL );
 | 
|---|
| 974 |     }
 | 
|---|
| 975 | 
 | 
|---|
| 976 |     compiler.GetNamespaceSupporter().GetLivingNamespaceScopes().clear();
 | 
|---|
| 977 | 
 | 
|---|
| 978 |     cp=back_cp;
 | 
|---|
| 979 | }
 | 
|---|
| 980 | 
 | 
|---|
| 981 | void Classes::Compile_System_InitializeUserTypes(){
 | 
|---|
| 982 |     char temporary[VN_SIZE];
 | 
|---|
| 983 | 
 | 
|---|
| 984 |     ////////////////////////////////////////////////////////////////////
 | 
|---|
| 985 |     // クラス登録
 | 
|---|
| 986 |     ////////////////////////////////////////////////////////////////////
 | 
|---|
| 987 | 
 | 
|---|
| 988 |     // イテレータをリセット
 | 
|---|
| 989 |     Iterator_Reset();
 | 
|---|
| 990 | 
 | 
|---|
| 991 |     while( Iterator_HasNext() ){
 | 
|---|
| 992 |         const CClass &objClass = *Iterator_GetNext();
 | 
|---|
| 993 | 
 | 
|---|
| 994 |         if( !objClass.IsUsing() ){
 | 
|---|
| 995 |             // 未使用のクラスは無視する
 | 
|---|
| 996 |             continue;
 | 
|---|
| 997 |         }
 | 
|---|
| 998 | 
 | 
|---|
| 999 |         std::string referenceOffsetsBuffer;
 | 
|---|
| 1000 |         int numOfReference = 0;
 | 
|---|
| 1001 |         objClass.GetReferenceOffsetsInitializeBuffer( referenceOffsetsBuffer, numOfReference );
 | 
|---|
| 1002 | 
 | 
|---|
| 1003 |         sprintf( temporary
 | 
|---|
| 1004 |             , "Add(%c%c_System_TypeForClass[strNamespace=\"%s\",name=\"%s\",fullName=\"%s\",referenceOffsets=[%s],numOfReference=%d])"
 | 
|---|
| 1005 |             , 1
 | 
|---|
| 1006 |             , ESC_SYSTEM_STATIC_NEW
 | 
|---|
| 1007 |             , objClass.GetNamespaceScopes().ToString().c_str()      // 名前空間
 | 
|---|
| 1008 |             , objClass.GetName().c_str()                            // クラス名
 | 
|---|
| 1009 |             , objClass.GetFullName().c_str()                        // フルネーム
 | 
|---|
| 1010 |             , referenceOffsetsBuffer.c_str()                        // 参照メンバオフセット配列
 | 
|---|
| 1011 |             , numOfReference                                        // 参照メンバの個数
 | 
|---|
| 1012 |             );
 | 
|---|
| 1013 | 
 | 
|---|
| 1014 |         // コンパイル
 | 
|---|
| 1015 |         ChangeOpcode( temporary );
 | 
|---|
| 1016 | 
 | 
|---|
| 1017 |         objClass.SetTypeInfoDataTableOffset(
 | 
|---|
| 1018 |             compiler.GetObjectModule().dataTable.GetLastMadeConstObjectDataTableOffset()
 | 
|---|
| 1019 |         );
 | 
|---|
| 1020 |     }
 | 
|---|
| 1021 | }
 | 
|---|
| 1022 | void Classes::Compile_System_InitializeUserTypesForBaseType()
 | 
|---|
| 1023 | {
 | 
|---|
| 1024 |     extern int cp;
 | 
|---|
| 1025 |     cp = -1;
 | 
|---|
| 1026 |     ////////////////////////////////////////////////////////////////////
 | 
|---|
| 1027 |     // 基底クラスを登録
 | 
|---|
| 1028 |     ////////////////////////////////////////////////////////////////////
 | 
|---|
| 1029 | 
 | 
|---|
| 1030 |     char temporary[8192];
 | 
|---|
| 1031 |     sprintf(temporary, "%c%ctempType=Nothing%c%c_System_TypeForClass"
 | 
|---|
| 1032 |         , HIBYTE( COM_DIM )
 | 
|---|
| 1033 |         , LOBYTE( COM_DIM )
 | 
|---|
| 1034 |         , 1
 | 
|---|
| 1035 |         , ESC_AS
 | 
|---|
| 1036 |         );
 | 
|---|
| 1037 |     ChangeOpcode( temporary );
 | 
|---|
| 1038 | 
 | 
|---|
| 1039 |     // イテレータをリセット
 | 
|---|
| 1040 |     Iterator_Reset();
 | 
|---|
| 1041 | 
 | 
|---|
| 1042 |     while( Iterator_HasNext() ){
 | 
|---|
| 1043 |         const CClass &objClass = *Iterator_GetNext();
 | 
|---|
| 1044 | 
 | 
|---|
| 1045 |         if( !objClass.IsUsing() ){
 | 
|---|
| 1046 |             // 未使用のクラスは無視する
 | 
|---|
| 1047 |             continue;
 | 
|---|
| 1048 |         }
 | 
|---|
| 1049 | 
 | 
|---|
| 1050 |         if( objClass.HasSuperClass() || objClass.GetDynamicMembers().size() ){
 | 
|---|
| 1051 |             sprintf( temporary
 | 
|---|
| 1052 |                 , "tempType=Search(\"%s\") As ActiveBasic.Core._System_TypeForClass"
 | 
|---|
| 1053 |                 , objClass.GetFullName().c_str()
 | 
|---|
| 1054 |             );
 | 
|---|
| 1055 | 
 | 
|---|
| 1056 |             // コンパイル
 | 
|---|
| 1057 |             MakeMiddleCode( temporary );
 | 
|---|
| 1058 |             ChangeOpcode( temporary );
 | 
|---|
| 1059 | 
 | 
|---|
| 1060 |             sprintf( temporary
 | 
|---|
| 1061 |                 , "tempType.SetClassInfo(%d,_System_GetComVtbl(%s),_System_GetVtblList(%s),_System_GetDefaultConstructor(%s),_System_GetDestructor(%s))"
 | 
|---|
| 1062 |                 , objClass.GetSize()
 | 
|---|
| 1063 |                 , objClass.GetFullName().c_str()
 | 
|---|
| 1064 |                 , objClass.GetFullName().c_str()
 | 
|---|
| 1065 |                 , objClass.GetFullName().c_str()
 | 
|---|
| 1066 |                 , objClass.GetFullName().c_str()
 | 
|---|
| 1067 |                 , objClass.GetName().c_str()
 | 
|---|
| 1068 |             );
 | 
|---|
| 1069 | 
 | 
|---|
| 1070 |             // コンパイル
 | 
|---|
| 1071 |             ChangeOpcode( temporary );
 | 
|---|
| 1072 | 
 | 
|---|
| 1073 |             if( objClass.HasSuperClass() )
 | 
|---|
| 1074 |             {
 | 
|---|
| 1075 |                 sprintf( temporary
 | 
|---|
| 1076 |                     , "tempType.SetBaseType(Search(\"%s\"))"
 | 
|---|
| 1077 |                     , objClass.GetSuperClass().GetFullName().c_str()
 | 
|---|
| 1078 |                 );
 | 
|---|
| 1079 | 
 | 
|---|
| 1080 |                 // コンパイル
 | 
|---|
| 1081 |                 ChangeOpcode( temporary );
 | 
|---|
| 1082 |             }
 | 
|---|
| 1083 | 
 | 
|---|
| 1084 |             if( objClass.GetDynamicMembers().size() )
 | 
|---|
| 1085 |             {
 | 
|---|
| 1086 |                 // メンバの型を示すTypeInfoオブジェクトへのDataOffset配列の静的データ定義文字列を取得
 | 
|---|
| 1087 |                 sprintf(
 | 
|---|
| 1088 |                     temporary,
 | 
|---|
| 1089 |                     "tempType.SetMembers([%s],[%s],[%s],%d)",
 | 
|---|
| 1090 |                     objClass.GetStaticDefiningStringAsMemberNames().c_str(),
 | 
|---|
| 1091 |                     objClass.GetStaticDefiningStringAsMemberTypeInfoNames().c_str(),
 | 
|---|
| 1092 |                     objClass.GetStaticDefiningStringAsMemberOffsets().c_str(),
 | 
|---|
| 1093 |                     objClass.GetDynamicMembers().size()
 | 
|---|
| 1094 |                 );
 | 
|---|
| 1095 |                 ChangeOpcode( temporary );
 | 
|---|
| 1096 |             }
 | 
|---|
| 1097 |         }
 | 
|---|
| 1098 |     }
 | 
|---|
| 1099 | }
 | 
|---|
| 1100 | 
 | 
|---|
| 1101 | const CClass *Classes::Find( const NamespaceScopes &namespaceScopes, const std::string &name ) const
 | 
|---|
| 1102 | {
 | 
|---|
| 1103 |     if( namespaceScopes.size() == 0 && name == "Object" ){
 | 
|---|
| 1104 |         return GetObjectClassPtr();
 | 
|---|
| 1105 |     }
 | 
|---|
| 1106 |     else if( namespaceScopes.size() == 0 && name == "String" ){
 | 
|---|
| 1107 |         return GetStringClassPtr();
 | 
|---|
| 1108 |     }
 | 
|---|
| 1109 | 
 | 
|---|
| 1110 |     std::vector<const CClass *> classes;
 | 
|---|
| 1111 |     const CClass *pClass = GetHashArrayElement( name.c_str() );
 | 
|---|
| 1112 |     while( pClass )
 | 
|---|
| 1113 |     {
 | 
|---|
| 1114 |         if( pClass->IsEqualSymbol( namespaceScopes, name ) ){
 | 
|---|
| 1115 |             //名前空間とクラス名が一致した
 | 
|---|
| 1116 |             classes.push_back( pClass );
 | 
|---|
| 1117 |         }
 | 
|---|
| 1118 |         pClass = pClass->GetChainNext();
 | 
|---|
| 1119 |     }
 | 
|---|
| 1120 |     if( classes.size() > 0 )
 | 
|---|
| 1121 |     {
 | 
|---|
| 1122 |         // 複数の名前空間の中に同一のクラス名が存在する場合があるので、アクセス可能で尚且つ階層が一番深いものをチョイスする
 | 
|---|
| 1123 |         pClass = classes.front();
 | 
|---|
| 1124 | 
 | 
|---|
| 1125 |         BOOST_FOREACH( const CClass *pTempClass, classes )
 | 
|---|
| 1126 |         {
 | 
|---|
| 1127 |             if( pClass->GetNamespaceScopes().size() < pTempClass->GetNamespaceScopes().size() )
 | 
|---|
| 1128 |             {
 | 
|---|
| 1129 |                 pClass = pTempClass;
 | 
|---|
| 1130 |             }
 | 
|---|
| 1131 |         }
 | 
|---|
| 1132 | 
 | 
|---|
| 1133 |         return pClass;
 | 
|---|
| 1134 |     }
 | 
|---|
| 1135 | 
 | 
|---|
| 1136 |     // TypeDefも見る
 | 
|---|
| 1137 |     int index = compiler.GetObjectModule().meta.GetTypeDefs().GetIndex( namespaceScopes, name );
 | 
|---|
| 1138 |     if( index != -1 ){
 | 
|---|
| 1139 |         Type type = compiler.GetObjectModule().meta.GetTypeDefs()[index].GetBaseType();
 | 
|---|
| 1140 |         if( type.IsObject() ){
 | 
|---|
| 1141 |             return &type.GetClass();
 | 
|---|
| 1142 |         }
 | 
|---|
| 1143 |     }
 | 
|---|
| 1144 | 
 | 
|---|
| 1145 |     return NULL;
 | 
|---|
| 1146 | }
 | 
|---|
| 1147 | const CClass *Classes::Find( const std::string &fullName ) const
 | 
|---|
| 1148 | {
 | 
|---|
| 1149 |     char AreaName[VN_SIZE] = "";        //オブジェクト変数
 | 
|---|
| 1150 |     char NestName[VN_SIZE] = "";        //入れ子メンバ
 | 
|---|
| 1151 |     bool isNest = SplitMemberName( fullName.c_str(), AreaName, NestName );
 | 
|---|
| 1152 | 
 | 
|---|
| 1153 |     return Find( NamespaceScopes( AreaName ), NestName );
 | 
|---|
| 1154 | }
 | 
|---|
| 1155 | void Classes::StartCompile( const UserProc *pUserProc ){
 | 
|---|
| 1156 |     const CClass *pParentClass = pUserProc->GetParentClassPtr();
 | 
|---|
| 1157 |     if( pParentClass ){
 | 
|---|
| 1158 |         pParentClass->Using();
 | 
|---|
| 1159 | 
 | 
|---|
| 1160 |         // 仮想関数になるメソッドに使用チェックをつける
 | 
|---|
| 1161 |         BOOST_FOREACH( const CMethod *pMethod, pParentClass->GetDynamicMethods() )
 | 
|---|
| 1162 |         {
 | 
|---|
| 1163 |             if( pMethod->IsVirtual() )
 | 
|---|
| 1164 |             {
 | 
|---|
| 1165 |                 pMethod->GetUserProc().Using();
 | 
|---|
| 1166 |             }
 | 
|---|
| 1167 |         }
 | 
|---|
| 1168 | 
 | 
|---|
| 1169 |         pCompilingMethod = pParentClass->GetDynamicMethodOrInterfaceMethod( pUserProc );
 | 
|---|
| 1170 |         if( !pCompilingMethod ){
 | 
|---|
| 1171 |             pCompilingMethod = pParentClass->GetStaticMethods().GetMethodPtr( pUserProc );
 | 
|---|
| 1172 |             if( !pCompilingMethod ){
 | 
|---|
| 1173 |                 compiler.errorMessenger.OutputFatalError();
 | 
|---|
| 1174 |             }
 | 
|---|
| 1175 |         }
 | 
|---|
| 1176 |     }
 | 
|---|
| 1177 |     else{
 | 
|---|
| 1178 |         pCompilingMethod = NULL;
 | 
|---|
| 1179 |     }
 | 
|---|
| 1180 | }
 | 
|---|
| 1181 | 
 | 
|---|
| 1182 | const CClass *Classes::GetStringClassPtr() const
 | 
|---|
| 1183 | {
 | 
|---|
| 1184 |     if( !pStringClass ){
 | 
|---|
| 1185 |         // キャッシュしておく
 | 
|---|
| 1186 |         pStringClass = this->Find( NamespaceScopes( "System" ), "String" );
 | 
|---|
| 1187 | 
 | 
|---|
| 1188 |         if( !pStringClass )
 | 
|---|
| 1189 |         {
 | 
|---|
| 1190 |             compiler.errorMessenger.Output(400, "System.String", cp);
 | 
|---|
| 1191 |             static CClass dummy;
 | 
|---|
| 1192 |             return &dummy;
 | 
|---|
| 1193 |         }
 | 
|---|
| 1194 |         return pStringClass;
 | 
|---|
| 1195 |     }
 | 
|---|
| 1196 |     return pStringClass;
 | 
|---|
| 1197 | }
 | 
|---|
| 1198 | const CClass *Classes::GetObjectClassPtr() const
 | 
|---|
| 1199 | {
 | 
|---|
| 1200 |     if( !pObjectClass ){
 | 
|---|
| 1201 |         // キャッシュしておく
 | 
|---|
| 1202 |         pObjectClass = this->Find( NamespaceScopes( "System" ), "Object" );
 | 
|---|
| 1203 | 
 | 
|---|
| 1204 |         if( !pObjectClass )
 | 
|---|
| 1205 |         {
 | 
|---|
| 1206 |             compiler.errorMessenger.Output(400, "System.Object", cp);
 | 
|---|
| 1207 |             static CClass dummy;
 | 
|---|
| 1208 |             return &dummy;
 | 
|---|
| 1209 |         }
 | 
|---|
| 1210 |         return pObjectClass;
 | 
|---|
| 1211 |     }
 | 
|---|
| 1212 |     return pObjectClass;
 | 
|---|
| 1213 | }
 | 
|---|
| 1214 | const CClass *Classes::GetInterfaceInfoClassPtr() const
 | 
|---|
| 1215 | {
 | 
|---|
| 1216 |     if( !pInterfaceInfo ){
 | 
|---|
| 1217 |         // キャッシュしておく
 | 
|---|
| 1218 |         pInterfaceInfo = this->Find( "ActiveBasic.Core.InterfaceInfo" );
 | 
|---|
| 1219 | 
 | 
|---|
| 1220 |         if( !pInterfaceInfo )
 | 
|---|
| 1221 |         {
 | 
|---|
| 1222 |             compiler.errorMessenger.Output(400, "ActiveBasic.Core.InterfaceInfo", cp);
 | 
|---|
| 1223 |             static CClass dummy;
 | 
|---|
| 1224 |             return &dummy;
 | 
|---|
| 1225 |         }
 | 
|---|
| 1226 |         return pInterfaceInfo;
 | 
|---|
| 1227 |     }
 | 
|---|
| 1228 |     return pInterfaceInfo;
 | 
|---|
| 1229 | }
 | 
|---|
| 1230 | 
 | 
|---|
| 1231 | std::string CClass::GetStaticDefiningStringAsMemberNames() const
 | 
|---|
| 1232 | {
 | 
|---|
| 1233 |     std::string result;
 | 
|---|
| 1234 | 
 | 
|---|
| 1235 |     BOOST_FOREACH( const CMember *pMember, dynamicMembers )
 | 
|---|
| 1236 |     {
 | 
|---|
| 1237 |         if( result.size() )
 | 
|---|
| 1238 |         {
 | 
|---|
| 1239 |             result += ",";
 | 
|---|
| 1240 |         }
 | 
|---|
| 1241 | 
 | 
|---|
| 1242 |         result += "\"" + pMember->GetName() + "\"";
 | 
|---|
| 1243 |     }
 | 
|---|
| 1244 | 
 | 
|---|
| 1245 |     return result;
 | 
|---|
| 1246 | }
 | 
|---|
| 1247 | std::string CClass::GetStaticDefiningStringAsMemberTypeInfoNames() const
 | 
|---|
| 1248 | {
 | 
|---|
| 1249 |     std::string result;
 | 
|---|
| 1250 | 
 | 
|---|
| 1251 |     BOOST_FOREACH( const CMember *pMember, dynamicMembers )
 | 
|---|
| 1252 |     {
 | 
|---|
| 1253 |         if( result.size() )
 | 
|---|
| 1254 |         {
 | 
|---|
| 1255 |             result += ",";
 | 
|---|
| 1256 |         }
 | 
|---|
| 1257 | 
 | 
|---|
| 1258 |         result += "\"" + compiler.TypeToString( pMember->GetType() ) + "\"";
 | 
|---|
| 1259 |     }
 | 
|---|
| 1260 | 
 | 
|---|
| 1261 |     return result;
 | 
|---|
| 1262 | }
 | 
|---|
| 1263 | std::string CClass::GetStaticDefiningStringAsMemberOffsets() const
 | 
|---|
| 1264 | {
 | 
|---|
| 1265 |     std::string result;
 | 
|---|
| 1266 | 
 | 
|---|
| 1267 |     BOOST_FOREACH( const CMember *pMember, dynamicMembers )
 | 
|---|
| 1268 |     {
 | 
|---|
| 1269 |         if( result.size() )
 | 
|---|
| 1270 |         {
 | 
|---|
| 1271 |             result += ",";
 | 
|---|
| 1272 |         }
 | 
|---|
| 1273 | 
 | 
|---|
| 1274 |         int offset = this->GetMemberOffset( pMember->GetName().c_str() );
 | 
|---|
| 1275 | 
 | 
|---|
| 1276 |         char temporary[255];
 | 
|---|
| 1277 |         itoa( offset, temporary, 16 );
 | 
|---|
| 1278 | 
 | 
|---|
| 1279 |         result += (std::string)"&H" + temporary;
 | 
|---|
| 1280 |     }
 | 
|---|
| 1281 | 
 | 
|---|
| 1282 |     return result;
 | 
|---|
| 1283 | }
 | 
|---|
| 1284 | 
 | 
|---|
| 1285 | void CClass::GetReferenceOffsetsInitializeBuffer( std::string &referenceOffsetsBuffer, int &numOfReference, int baseOffset ) const
 | 
|---|
| 1286 | {
 | 
|---|
| 1287 |     const CClass &thisClass = *this;
 | 
|---|
| 1288 |     BOOST_FOREACH( const CMember *pMember, thisClass.GetDynamicMembers() )
 | 
|---|
| 1289 |     {
 | 
|---|
| 1290 |         if( pMember->GetType().IsObject() || pMember->GetType().IsPointer() )
 | 
|---|
| 1291 |         {
 | 
|---|
| 1292 |             if( referenceOffsetsBuffer.size() )
 | 
|---|
| 1293 |             {
 | 
|---|
| 1294 |                 referenceOffsetsBuffer += ",";
 | 
|---|
| 1295 |             }
 | 
|---|
| 1296 | 
 | 
|---|
| 1297 |             char temp[255];
 | 
|---|
| 1298 |             sprintf( temp, "%d", baseOffset + thisClass.GetMemberOffset( pMember->GetName().c_str() ) );
 | 
|---|
| 1299 |             referenceOffsetsBuffer += temp;
 | 
|---|
| 1300 | 
 | 
|---|
| 1301 |             numOfReference++;
 | 
|---|
| 1302 |         }
 | 
|---|
| 1303 |         if( pMember->GetType().IsStruct() && !pMember->GetType().IsPointer() )
 | 
|---|
| 1304 |         {
 | 
|---|
| 1305 |             // 構造体の実体をメンバに持つとき
 | 
|---|
| 1306 |             int baseOffset = thisClass.GetMemberOffset( pMember->GetName().c_str() );
 | 
|---|
| 1307 | 
 | 
|---|
| 1308 |             // 構造体メンバでGCによるチェックが必要な参照位置を追加
 | 
|---|
| 1309 |             pMember->GetType().GetClass().GetReferenceOffsetsInitializeBuffer( referenceOffsetsBuffer, numOfReference, baseOffset );
 | 
|---|
| 1310 |         }
 | 
|---|
| 1311 |     }
 | 
|---|
| 1312 | }
 | 
|---|