source: dev/trunk/abdev/BasicCompiler_Common/src/Class.cpp@ 402

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

UserProc::SetParamsAndReturnTypeメソッドをリファクタリング
LexicalAnalysis.hのインクルードを除去した

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