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

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

MakeLiteralArrayBufferにてStringクラスの静的領域用配列を生成できるようにした

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