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

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

AddMemberAddDynamicMethod
・CMember→Member
・CreateMemberメソッドをCClassクラスからLexicalAnalyzerクラスへ移動した。

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