source: dev/trunk/ab5.0/abdev/BasicCompiler_Common/src/Class.cpp@ 563

Last change on this file since 563 was 563, checked in by dai_9181, 16 years ago

OutputFatalErrorをthrowに変更。

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