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

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

静的領域に初期オブジェクトを配置可能にした

File size: 52.1 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
20class CLoopRefCheck{
21 char **names;
22 int num;
23 void init(){
24 int i;
25 for(i=0;i<num;i++){
26 free(names[i]);
27 }
28 free(names);
29 }
30public:
31 CLoopRefCheck()
32 {
33 names=(char **)malloc(1);
34 num=0;
35 }
36 ~CLoopRefCheck()
37 {
38 init();
39 }
40 void add(const char *lpszInheritsClass)
41 {
42 names=(char **)realloc(names,(num+1)*sizeof(char *));
43 names[num]=(char *)malloc(lstrlen(lpszInheritsClass)+1);
44 lstrcpy(names[num],lpszInheritsClass);
45 num++;
46 }
47 void del(const char *lpszInheritsClass)
48 {
49 int i;
50 for(i=0;i<num;i++){
51 if(lstrcmp(names[i],lpszInheritsClass)==0){
52 free(names[i]);
53 break;
54 }
55 }
56 if(i!=num){
57 num--;
58 for(;i<num;i++){
59 names[i]=names[i+1];
60 }
61 }
62 }
63 BOOL check(const CClass &inheritsClass) const
64 {
65 //ループ継承チェック
66 int i;
67 for(i=0;i<num;i++){
68 if( inheritsClass.GetName() == names[i] ){
69 return 1;
70 }
71 }
72 return 0;
73 }
74};
75CLoopRefCheck *pobj_LoopRefCheck;
76
77
78Interface::Interface( const CClass *pInterfaceClass )
79 : DynamicMethodsPrototype()
80 , pInterfaceClass( pInterfaceClass )
81 , vtblOffset( -1 )
82{
83 //メソッドをコピー
84 BOOST_FOREACH( const CMethod *pBaseMethod, pInterfaceClass->GetDynamicMethods() )
85 {
86 CMethod *pMethod = new DynamicMethod( *pBaseMethod );
87
88 // アクセシビリティ
89 if(pBaseMethod->GetAccessibility() == Prototype::Private){
90 pMethod->SetAccessibility( Prototype::None );
91 }
92 else{
93 pMethod->SetAccessibility( pBaseMethod->GetAccessibility() );
94 }
95
96 //pobj_Inherits
97 // ※継承元のClassIndexをセット(入れ子継承を考慮する)
98 if(pBaseMethod->GetInheritsClassPtr()==0){
99 pMethod->SetInheritsClassPtr( pInterfaceClass );
100 }
101 else{
102 pMethod->SetInheritsClassPtr( pBaseMethod->GetInheritsClassPtr() );
103 }
104
105 AddDynamicMethods( pMethod );
106 }
107}
108
109
110bool CClass::IsClass() const
111{
112 return classType == CClass::Class;
113}
114bool CClass::IsInterface() const
115{
116 return classType == CClass::Interface;
117}
118bool CClass::IsEnum() const
119{
120 return classType == CClass::Enum;
121}
122bool CClass::IsDelegate() const
123{
124 return classType == CClass::Delegate;
125}
126bool CClass::IsStructure() const
127{
128 return classType == CClass::Structure;
129}
130
131
132// コンストラクタのコンパイルを開始
133void CClass::NotifyStartConstructorCompile() const
134{
135 isCompilingConstructor = true;
136}
137
138//コンストラクタのコンパイルを終了
139void CClass::NotifyFinishConstructorCompile() const
140{
141 isCompilingConstructor = false;
142}
143
144//コンストラクタをコンパイル中かどうかを判別
145bool CClass::IsCompilingConstructor() const
146{
147 return isCompilingConstructor;
148}
149
150//デストラクタのコンパイルを開始
151void CClass::NotifyStartDestructorCompile() const{
152 isCompilingDestructor = true;
153}
154
155//デストラクタのコンパイルを終了
156void CClass::NotifyFinishDestructorCompile() const{
157 isCompilingDestructor = false;
158}
159
160//デストラクタをコンパイル中かどうかを判別
161bool CClass::IsCompilingDestructor() const
162{
163 return isCompilingDestructor;
164}
165
166//自身の派生クラスかどうかを確認
167bool CClass::IsSubClass( const CClass *pClass ) const
168{
169 if( !pClass->HasSuperClass() )
170 {
171 return false;
172 }
173
174 const CClass *pTempClass = &pClass->GetSuperClass();
175 while( pTempClass ){
176 if( this == pTempClass ) return true;
177 pTempClass = &pTempClass->GetSuperClass();
178 }
179 return false;
180}
181
182//自身と等しいまたは派生クラスかどうかを確認
183bool CClass::IsEqualsOrSubClass( const CClass *pClass ) const
184{
185 if( IsEquals( pClass ) ) return true;
186 return IsSubClass( pClass );
187}
188
189// 自身と等しいまたは派生クラス、基底クラスかどうかを確認
190bool CClass::IsEqualsOrSubClassOrSuperClass( const CClass &objClass ) const
191{
192 if( IsEquals( &objClass ) ) return true;
193 if( IsSubClass( &objClass ) ) return true;
194 if( objClass.IsSubClass( this ) ) return true;
195 return false;
196}
197
198bool CClass::IsInheritsInterface( const CClass *pInterfaceClass ) const
199{
200 BOOST_FOREACH( const ::Interface *pInterface, interfaces ){
201 if( pInterfaceClass == &pInterface->GetClass() ){
202 return true;
203 }
204 }
205 return false;
206}
207
208bool CClass::Inherits( const char *inheritNames, int nowLine ){
209 int i = 0;
210 bool isInheritsClass = false;
211 while( true ){
212
213 char temporary[VN_SIZE];
214 for( int i2=0;; i++, i2++ ){
215 if( inheritNames[i] == '\0' || inheritNames[i] == ',' ){
216 temporary[i2] = 0;
217 break;
218 }
219 temporary[i2] = inheritNames[i];
220 }
221
222 // ジェネリクス構文を分解
223 char className[VN_SIZE];
224 Jenga::Common::Strings typeParameterStrings;
225 SplitGenericClassInstance( temporary, className, typeParameterStrings );
226
227 // 型パラメータ文字列から型データを取得
228 std::vector<Type> actualTypeParameters;
229 BOOST_FOREACH( const std::string &typeParameterStr, typeParameterStrings )
230 {
231 Type type;
232 compiler.StringToType( typeParameterStr, type );
233 actualTypeParameters.push_back( type );
234 }
235
236 //継承元クラスを取得
237 const CClass *pInheritsClass = compiler.GetObjectModule().meta.GetClasses().Find(className);
238 if( !pInheritsClass ){
239 SmoothieException::Throw(106,className,nowLine);
240 return false;
241 }
242
243 if( pInheritsClass->IsInterface() ){
244 // インターフェイスはあとで継承する
245 }
246 else if( pInheritsClass->IsClass() ){
247 // クラスを継承する
248 isInheritsClass = true;
249
250 if( !InheritsClass( *pInheritsClass, actualTypeParameters, nowLine ) ){
251 return false;
252 }
253 }
254 else{
255 SmoothieException::Throw(135,NULL,nowLine);
256 return false;
257 }
258
259 if( inheritNames[i] == '\0' ){
260 break;
261 }
262 i++;
263 }
264
265 if( !isInheritsClass ){
266 // クラスを一つも継承していないとき
267 if( !InheritsClass( *compiler.GetObjectModule().meta.GetClasses().GetObjectClassPtr(), Types(), nowLine ) ){
268 return false;
269 }
270 }
271
272 i=0;
273 while( true ){
274
275 char temporary[VN_SIZE];
276 for( int i2=0;; i++, i2++ ){
277 if( inheritNames[i] == '\0' || inheritNames[i] == ',' ){
278 temporary[i2] = 0;
279 break;
280 }
281 temporary[i2] = inheritNames[i];
282 }
283
284 char className[VN_SIZE];
285 Jenga::Common::Strings typeParameters;
286 SplitGenericClassInstance( temporary, className, typeParameters );
287
288 //継承元クラスを取得
289 const CClass *pInheritsClass = compiler.GetObjectModule().meta.GetClasses().Find(className);
290 if( !pInheritsClass ){
291 SmoothieException::Throw(106,className,nowLine);
292 return false;
293 }
294
295 if( pInheritsClass->IsInterface() ){
296 // インターフェイスを継承する
297 if( !InheritsInterface( *pInheritsClass, nowLine ) ){
298 return false;
299 }
300 }
301 else if( pInheritsClass->IsClass() ){
302 // クラスはさっき継承した
303 }
304 else{
305 SmoothieException::Throw(135,NULL,nowLine);
306 return false;
307 }
308
309 if( inheritNames[i] == '\0' ){
310 break;
311 }
312 i++;
313 }
314
315 return true;
316}
317bool CClass::InheritsClass( const CClass &inheritsClass, const Types &actualTypeParameters, int nowLine ){
318
319 //ループ継承でないかをチェック
320 if(pobj_LoopRefCheck->check(inheritsClass)){
321 SmoothieException::Throw(123,inheritsClass.GetName(),nowLine);
322 return false;
323 }
324
325 if( !inheritsClass.IsReady() ){
326 //継承先が読み取られていないとき
327 pobj_LoopRefCheck->add(this->GetName().c_str());
328 compiler.GetObjectModule().meta.GetClasses().GetClass_recur(inheritsClass.GetName().c_str());
329 pobj_LoopRefCheck->del(this->GetName().c_str());
330 }
331
332 //メンバをコピー
333 BOOST_FOREACH( CMember *inheritsClassDynamicMember, inheritsClass.GetDynamicMembers() ){
334 CMember *pMember = new CMember( *inheritsClassDynamicMember );
335
336 // アクセシビリティ
337 if( inheritsClassDynamicMember->IsPrivate() ){
338 pMember->SetAccessibility( Prototype::None );
339 }
340 else{
341 pMember->SetAccessibility( inheritsClassDynamicMember->GetAccessibility() );
342 }
343
344 // メンバのみ、型パラメータを解決する(メソッドのほうは呼び出し時に解決する)
345 if( pMember->GetType().IsTypeParameter() )
346 {
347 pMember->ResetType( actualTypeParameters[pMember->GetType().GetFormalTypeIndex()] );
348 }
349
350 dynamicMembers.push_back( pMember );
351 }
352
353 //メソッドをコピー
354 BOOST_FOREACH( const CMethod *pBaseMethod, inheritsClass.GetDynamicMethods() ){
355 CMethod *pMethod = new DynamicMethod( *pBaseMethod );
356
357 // アクセシビリティ
358 if(pBaseMethod->GetAccessibility() == Prototype::Private){
359 pMethod->SetAccessibility( Prototype::None );
360 }
361 else{
362 pMethod->SetAccessibility( pBaseMethod->GetAccessibility() );
363 }
364
365 //pobj_Inherits
366 // ※継承元のClassIndexをセット(入れ子継承を考慮する)
367 if(pBaseMethod->GetInheritsClassPtr()==0){
368 pMethod->SetInheritsClassPtr( &inheritsClass );
369 }
370 else{
371 pMethod->SetInheritsClassPtr( pBaseMethod->GetInheritsClassPtr() );
372 }
373
374 GetDynamicMethods().push_back( pMethod );
375 }
376
377 //仮想関数の数
378 AddVtblNum( inheritsClass.GetVtblNum() );
379
380 //継承先のクラスをメンバとして保持する
381 SetSuperClass( &inheritsClass );
382 SetSuperClassActualTypeParameters( actualTypeParameters );
383
384 // インターフェイスを引き継ぐ
385 BOOST_FOREACH( ::Interface *pInterface, inheritsClass.GetInterfaces() )
386 {
387 interfaces.push_back( new ::Interface( *pInterface ) );
388 }
389
390 return true;
391}
392bool CClass::InheritsInterface( const CClass &inheritsInterface, int nowLine ){
393
394 //ループ継承でないかをチェック
395 if(pobj_LoopRefCheck->check(inheritsInterface)){
396 SmoothieException::Throw(123,inheritsInterface.GetName(),nowLine);
397 return false;
398 }
399
400 if( !inheritsInterface.IsReady() ){
401 //継承先が読み取られていないとき
402 pobj_LoopRefCheck->add(this->GetName().c_str());
403 compiler.GetObjectModule().meta.GetClasses().GetClass_recur(inheritsInterface.GetName().c_str());
404 pobj_LoopRefCheck->del(this->GetName().c_str());
405 }
406
407 //メソッドをコピー
408 BOOST_FOREACH( const CMethod *pBaseMethod, inheritsInterface.GetDynamicMethods() ){
409 CMethod *pMethod = new DynamicMethod( *pBaseMethod );
410
411 // アクセシビリティ
412 if(pBaseMethod->GetAccessibility() == Prototype::Private){
413 pMethod->SetAccessibility( Prototype::None );
414 }
415 else{
416 pMethod->SetAccessibility( pBaseMethod->GetAccessibility() );
417 }
418
419 //pobj_Inherits
420 // ※継承元のClassIndexをセット(入れ子継承を考慮する)
421 if(pBaseMethod->GetInheritsClassPtr()==0){
422 pMethod->SetInheritsClassPtr( &inheritsInterface );
423 }
424 else{
425 pMethod->SetInheritsClassPtr( pBaseMethod->GetInheritsClassPtr() );
426 }
427
428 GetDynamicMethods().push_back( pMethod );
429 }
430
431 //interfaces.push_back( Interface( &inheritsInterface, vtblNum ) );
432
433 //仮想関数の数
434 AddVtblNum( inheritsInterface.GetVtblNum() );
435
436 return true;
437}
438
439bool CClass::Implements( const CClass &interfaceClass, int nowLine )
440{
441 if( !interfaceClass.IsInterface() )
442 {
443 // インターフェイスではないとき
444 SetError(138,interfaceClass.GetName().c_str(),nowLine );
445 return false;
446 }
447
448 if( !interfaceClass.IsReady() ){
449 // インターフェイスが未解析のとき
450 pobj_LoopRefCheck->add(this->GetName().c_str());
451 compiler.GetObjectModule().meta.GetClasses().GetClass_recur(interfaceClass.GetName().c_str());
452 pobj_LoopRefCheck->del(this->GetName().c_str());
453 }
454
455 ::Interface *pDestInterface = new ::Interface( &interfaceClass );
456
457 interfaces.push_back( pDestInterface );
458
459
460 /////////////////////////////////////////////////////////////////
461 // 基底クラスのメソッドからインターフェイスメソッドを再実装する
462 /////////////////////////////////////////////////////////////////
463 BOOST_FOREACH( CMethod *pMethod, GetDynamicMethods() )
464 {
465 CMethod *pMethodForOverride = pDestInterface->GetDynamicMethods().FindForOverride( &pMethod->GetUserProc() );
466 if( pMethodForOverride )
467 {
468 pMethodForOverride->Override( &pMethod->GetUserProc(), pMethod->GetAccessibility(), false );
469
470 // 実装元になるメソッドは呼び出し不可にしておく(オーバーロードの解決から除外する)
471 pMethod->SetNotUseMark( true );
472 }
473 }
474
475
476 /////////////////////////////////////////////////////////////////
477 // キャストメソッドを追加(内部コードは自動生成すること)
478 /////////////////////////////////////////////////////////////////
479 {
480 // Function Operator() As ITest
481
482 char temporary[1024];
483 sprintf(temporary,"%c%c%c%c()%c%c%s",
484 1, ESC_FUNCTION,
485 1, ESC_OPERATOR,
486 1, ESC_AS,
487 interfaceClass.GetName().c_str()
488 );
489
490 this->AddMethod(this,
491 Prototype::Public,
492 0,
493 false, // isConst
494 false, // isAbstract
495 false, // isVirtual
496 false, // isOverride
497 true, // isAutoGeneration
498 temporary,
499 -1
500 );
501 }
502
503
504 return true;
505}
506bool CClass::Implements( const char *interfaceNames, int nowLine )
507{
508 Jenga::Common::Strings paramStrs;
509 SplitParameter( interfaceNames, paramStrs );
510
511 BOOST_FOREACH( const std::string &paramStr, paramStrs )
512 {
513 //継承元クラスを取得
514 const CClass *pInterfaceClass = compiler.GetObjectModule().meta.GetClasses().Find( paramStr.c_str() );
515 if( !pInterfaceClass ){
516 SetError(106,paramStr.c_str(),nowLine);
517 continue;
518 }
519
520 // インターフェイスを継承する
521 Implements( *pInterfaceClass, nowLine );
522 }
523
524 return true;
525}
526
527CMember *CClass::CreateMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine )
528{
529 extern int cp;
530
531 //構文を解析
532 char VarName[VN_SIZE];
533 char initBuffer[VN_SIZE];
534 char lpszConstructParameter[VN_SIZE];
535 Subscripts subscripts;
536 Type type;
537 GetDimentionFormat(buffer,VarName,subscripts,type,initBuffer,lpszConstructParameter);
538
539 //重複チェック
540 if(this->DupliCheckAll(VarName)){
541 SetError(15,VarName,cp);
542 }
543
544 CMember *pMember = new CMember( accessibility, VarName, type, isConst, subscripts, initBuffer, lpszConstructParameter );
545 pMember->source_code_address = nowLine;
546 return pMember;
547}
548void CClass::AddMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine ){
549 dynamicMembers.push_back(
550 CreateMember( accessibility, isConst, isRef, buffer, nowLine )
551 );
552}
553void CClass::AddStaticMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine ){
554 staticMembers.push_back(
555 CreateMember( accessibility, isConst, isRef, buffer, nowLine )
556 );
557}
558
559void CClass::AddMethod(CClass *pobj_c, Prototype::Accessibility accessibility, BOOL bStatic, bool isConst, bool isAbstract,
560 bool isVirtual, bool isOverride, bool isAutoGeneration, char *buffer, int nowLine){
561 int i,i2;
562 char temporary[VN_SIZE];
563
564 i=2;
565 for(i2=0;;i++,i2++){
566 if(buffer[i]=='('||buffer[i]=='\0'){
567 temporary[i2]=0;
568 break;
569 }
570 temporary[i2]=buffer[i];
571 }
572
573
574 //関数ハッシュへ登録
575 char interfaceName[VN_SIZE] = "";
576 UserProc *pUserProc = compiler.GetObjectModule().meta.GetUserProcs().AddUserProc( NamespaceScopes(), NamespaceScopesCollection(), buffer,nowLine,isVirtual,pobj_c, (bStatic!=0), interfaceName );
577 if(!pUserProc) return;
578
579 if( isAutoGeneration )
580 {
581 // コード自動生成
582 pUserProc->ThisIsAutoGenerationProc();
583 }
584
585
586 ////////////////////////////////////////////////////////////
587 // コンストラクタ、デストラクタの場合の処理
588 ////////////////////////////////////////////////////////////
589 BOOL fConstructor=0,bDestructor=0;
590
591 if(lstrcmp(temporary,pobj_c->GetName().c_str())==0){
592 //コンストラクタの場合
593
594 //標準コンストラクタ(引数なし)
595 if(pUserProc->Params().size()==0) fConstructor=1;
596
597 //強制的にConst修飾子をつける
598 isConst = true;
599 }
600 else if(temporary[0]=='~'){
601 //デストラクタの場合はその名前が正しいかチェックを行う
602 if(lstrcmp(temporary+1,pobj_c->GetName().c_str())!=0)
603 SetError(117,NULL,nowLine);
604 else
605 bDestructor=1;
606 }
607 if(fConstructor||bDestructor){
608 // コンストラクタ、デストラクタのアクセシビリティをチェック
609
610 //強制的にConst修飾子をつける
611 isConst = true;
612 }
613
614 if( fConstructor == 1 )
615 pobj_c->SetConstructorMemberSubIndex( (int)pobj_c->GetDynamicMethods().size() );
616 else if( bDestructor )
617 pobj_c->SetDestructorMemberSubIndex( (int)pobj_c->GetDynamicMethods().size() );
618
619
620
621 //////////////////
622 // 重複チェック
623 //////////////////
624
625 if(pobj_c->DupliCheckMember(temporary)){
626 SetError(15,temporary,nowLine);
627 return;
628 }
629
630 //メソッド
631 BOOST_FOREACH( const CMethod *pMethod, pobj_c->GetDynamicMethods() )
632 {
633 //基底クラスと重複する場合はオーバーライドを行う
634 if( pMethod->GetInheritsClassPtr() ) continue;
635
636 if( pMethod->GetUserProc().IsEqualForOverride( pUserProc ) )
637 {
638 //関数名、パラメータ、戻り値が合致したとき
639 SetError(15,pUserProc->GetName().c_str(),nowLine);
640 return;
641 }
642 }
643
644 //仮想関数の場合
645 if( isAbstract ) pUserProc->CompleteCompile();
646
647 // メソッドのオーバーライド
648 CMethod *pMethodForOverride = pobj_c->GetDynamicMethods().FindForOverride( pUserProc );
649 if( pMethodForOverride )
650 {
651 pMethodForOverride->Override( pUserProc, accessibility, isOverride );
652 pUserProc->SetMethod( pMethodForOverride );
653 return;
654 }
655 else
656 {
657 // インターフェイス メソッドのオーバーライド
658 BOOST_FOREACH( ::Interface *pInterface, pobj_c->GetInterfaces() )
659 {
660 if( interfaceName[0] )
661 {
662 if( pInterface->GetClass().GetName() != interfaceName )
663 {
664 // 指定されたインターフェイス名と整合しないとき
665 continue;
666 }
667 }
668
669 CMethod *pMethodForOverride = pInterface->GetDynamicMethods().FindForOverride( pUserProc );
670 if( pMethodForOverride )
671 {
672 pMethodForOverride->Override( pUserProc, accessibility, isOverride );
673 pUserProc->SetMethod( pMethodForOverride );
674 return;
675 }
676 }
677 }
678
679 if( interfaceName[0] )
680 {
681 SetError(139,interfaceName,nowLine);
682 }
683
684 if( isVirtual ){
685 pobj_c->AddVtblNum( 1 );
686 }
687
688 if( isOverride ){
689 SetError(12,"Override",nowLine);
690 }
691
692 if(bStatic){
693 pobj_c->GetStaticMethods().AddStatic( pUserProc, accessibility );
694 }
695 else{
696 pobj_c->GetDynamicMethods().Add(pUserProc, accessibility, isConst, isAbstract, isVirtual);
697 }
698}
699
700bool CClass::DupliCheckAll(const char *name){
701 //重複チェック
702
703 //メンバ
704 if(DupliCheckMember(name)) return 1;
705
706 //メソッド
707 BOOST_FOREACH( const CMethod *pMethod, GetDynamicMethods() ){
708 if( lstrcmp( name, pMethod->GetUserProc().GetName().c_str() ) == 0 ){
709 return 1;
710 }
711 }
712
713 return 0;
714}
715bool CClass::DupliCheckMember(const char *name){
716 //重複チェック
717
718 // 動的メンバ
719 BOOST_FOREACH( CMember *pMember, dynamicMembers ){
720 if( GetName() == pMember->GetName() ){
721 return 1;
722 }
723 }
724
725 // 静的メンバ
726 BOOST_FOREACH( CMember *pMember, staticMembers ){
727 if( GetName() == pMember->GetName() ){
728 return 1;
729 }
730 }
731
732 return 0;
733}
734
735void CClass::EnumDynamicMethodsOrInterfaceMethods( const char *methodName, std::vector<const UserProc *> &subs ) const
736{
737 // 動的メソッド
738 GetDynamicMethods().Enum( methodName, subs );
739
740 // インターフェイス メソッド
741 BOOST_FOREACH( ::Interface *pInterface, GetInterfaces() )
742 {
743 pInterface->GetDynamicMethods().Enum( methodName, subs );
744 }
745}
746const CMethod *CClass::GetDynamicMethodOrInterfaceMethod( const UserProc *pUserProc ) const
747{
748 // 動的メソッド
749 const CMethod *result = GetDynamicMethods().GetMethodPtr( pUserProc );
750
751 if( !result )
752 {
753 // インターフェイス メソッド
754 BOOST_FOREACH( ::Interface *pInterface, GetInterfaces() )
755 {
756 result = pInterface->GetDynamicMethods().GetMethodPtr( pUserProc );
757 if( result )
758 {
759 return result;
760 }
761 }
762 }
763
764 return result;
765}
766
767const ::Delegate &CClass::GetDelegate() const
768{
769 const ::Delegate *dg = compiler.GetObjectModule().meta.GetDelegates().GetHashArrayElement( GetName().c_str() );
770 while( dg )
771 {
772 if( dg->IsEqualSymbol( GetNamespaceScopes(), GetName() ) ){
773 //名前空間とクラス名が一致した
774 return *dg;
775 }
776 dg = dg->GetChainNext();
777 }
778
779 Jenga::Throw( "CClass::GetDelegateメソッドに失敗" );
780 static ::Delegate dummy;
781 return dummy;
782}
783
784//サイズを取得
785int CClass::GetSize() const
786{
787 return GetMemberOffset( NULL, NULL );
788}
789
790//メンバのオフセットを取得
791int CClass::GetMemberOffset( const char *memberName, int *pMemberNum ) const
792{
793 int i2;
794
795 //仮想関数が存在する場合は関数リストへのポインタのサイズを追加
796 int offset = IsExistVirtualFunctions() ? PTR_SIZE : 0;
797
798 int alignment = 1;
799 if( GetFixedAlignment() )
800 {
801 alignment = GetFixedAlignment();
802 }
803
804 int iMaxAlign=0;
805 int i = -1;
806 BOOST_FOREACH( CMember *pMember, dynamicMembers ){
807 i++;
808
809 i2 = pMember->GetType().GetSize();
810
811 //アラインメントを算出
812 int member_size;
813 if( pMember->GetType().IsStruct() ){
814 //メンバクラスのアラインメントを取得
815 member_size=pMember->GetType().GetClass().GetAlignment();
816 }
817 else{
818 //メンバサイズを取得
819 member_size=i2;
820 }
821 if(iMaxAlign<member_size) iMaxAlign=member_size;
822
823 //アラインメントを考慮
824 if(GetFixedAlignment()&&GetFixedAlignment()<member_size){
825 if(offset%alignment) offset+=alignment-(offset%alignment);
826 }
827 else{
828 if(alignment<member_size) alignment=member_size;
829
830 if(member_size==0){
831 //メンバを持たないクラス
832 //※何もしない(オフセットの計算をしない)
833 }
834 else{
835 if(offset%member_size) offset+=member_size-(offset%member_size);
836 }
837 }
838
839 if(memberName){
840 //メンバ指定がある場合は、オフセットを返す
841 if( pMember->GetName() == memberName ){
842 if(pMemberNum) *pMemberNum=i;
843 return offset;
844 }
845 }
846
847 //配列を考慮したメンバサイズを取得
848 member_size = i2 * Variable::GetSubScriptCounts( pMember->GetSubscripts() );
849
850 //メンバサイズを加算
851 offset+= member_size;
852 }
853
854 if(iMaxAlign<alignment) alignment=iMaxAlign;
855
856 //アラインメントを考慮
857 if(alignment){
858 if(offset%alignment) offset+=alignment-(offset%alignment);
859 }
860
861 if(pMemberNum) *pMemberNum=i;
862 return offset;
863}
864int CClass::GetAlignment() const
865{
866 //仮想関数が存在する場合は関数リストへのポインタのサイズを追加
867 int alignment = IsExistVirtualFunctions() ? PTR_SIZE : 0;
868
869 BOOST_FOREACH( CMember *pMember, dynamicMembers ){
870 int member_size;
871 if(pMember->GetType().IsStruct()){
872 //メンバクラスのアラインメントを取得
873 member_size=pMember->GetType().GetClass().GetAlignment();
874 }
875 else{
876 //メンバサイズを取得
877 member_size = pMember->GetType().GetSize();
878 }
879
880 //アラインメントをセット
881 if(alignment<member_size) alignment=member_size;
882 }
883
884 if(alignment==0) return 0;
885
886 if(GetFixedAlignment()) alignment=GetFixedAlignment();
887
888 return alignment;
889}
890
891void CClass::GetVtblMasterListIndexAndVtblIndex( const UserProc *pUserProc, int &vtblMasterListIndex, int &vtblIndex ) const
892{
893 vtblMasterListIndex = 0;
894
895 vtblIndex = 0;
896 BOOST_FOREACH( const CMethod *pMethod, GetDynamicMethods() ){
897 if( &pMethod->GetUserProc() == pUserProc )
898 {
899 return;
900 }
901
902 if( pMethod->IsVirtual() )
903 {
904 vtblIndex++;
905 }
906 }
907
908 BOOST_FOREACH( const ::Interface *pInterface, interfaces )
909 {
910 vtblMasterListIndex++;
911
912 vtblIndex = 0;
913 BOOST_FOREACH( const CMethod *pMethod, pInterface->GetDynamicMethods() ){
914 if( &pMethod->GetUserProc() == pUserProc )
915 {
916 return;
917 }
918
919 if( pMethod->IsVirtual() )
920 {
921 vtblIndex++;
922 }
923 }
924 }
925
926 SetError();
927 return;
928}
929int CClass::GetVtblMasterListIndex( const CClass *pClass ) const
930{
931 int result = 0;
932
933 BOOST_FOREACH( const ::Interface *pInterface, interfaces )
934 {
935 result++;
936
937 if( &pInterface->GetClass() == pClass )
938 {
939 return result;
940 }
941 }
942
943 SetError();
944 return 0;
945}
946long CClass::GetVtblMasterListOffset() const
947{
948 //既に存在する場合はそれを返す
949 if( vtblMasterListOffset == -1 )
950 {
951 SetError();
952 }
953
954 return vtblMasterListOffset;
955}
956void CClass::GenerateVTableMasterList( const std::vector<long> &vtableMasterList, long &offset )
957{
958 offset = compiler.GetObjectModule().dataTable.AddBinary(
959 (void *)&vtableMasterList[0],
960 static_cast<int>(vtableMasterList.size()*sizeof(LONG_PTR))
961 );
962}
963void CClass::GenerateFullVTables()
964{
965 if( IsAbstract() )
966 {
967 // 抽象クラスは無視
968 return;
969 }
970 if( !IsUsing() )
971 {
972 // 使われていないクラスは無視
973 return;
974 }
975
976 // vtblマスターリストの元データに不要なデータが含まれていたらエラー
977 if( vtblMasterList.size() )
978 {
979 SetError();
980 }
981
982 // 自身のクラスのvtblを生成
983 GetDynamicMethods().GenerateVTablePart( this->vtbl_offset );
984 vtblMasterList.push_back( this->vtbl_offset );
985
986 // インターフェイスのvtblを生成
987 BOOST_FOREACH( const ::Interface *pInterface, interfaces )
988 {
989 long tempVtblOffset;
990 pInterface->GetDynamicMethods().GenerateVTablePart( tempVtblOffset );
991 vtblMasterList.push_back( tempVtblOffset );
992
993 pInterface->SetVtblOffset( tempVtblOffset );
994 }
995
996 // vtblマスターリストを生成
997 GenerateVTableMasterList( vtblMasterList, this->vtblMasterListOffset );
998}
999void CClass::ActionVtblSchedule( LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection, LONG_PTR MemPos_DataSection )
1000{
1001 if( IsAbstract() )
1002 {
1003 // 抽象クラスは無視
1004 return;
1005 }
1006 if( !IsUsing() )
1007 {
1008 // 使われていないクラスは無視
1009 return;
1010 }
1011 if(vtbl_offset==-1) return;
1012
1013 // 自身のクラスのvtbl
1014 {
1015 LONG_PTR *pVtbl = (LONG_PTR *)((char *)compiler.GetObjectModule().dataTable.GetPtr() + vtbl_offset);
1016
1017 for( int i=0; i<GetVtblNum(); i++ ){
1018 const UserProc *pUserProc = (UserProc *)pVtbl[i];
1019 if(!pUserProc) continue;
1020
1021 if( pUserProc->GetBeginOpAddress() == 0
1022 && pUserProc->GetEndOpAddress() == 0 )
1023 {
1024 Jenga::Throw( "未解決の仮想関数が存在する" );
1025 }
1026
1027 pVtbl[i] = pUserProc->GetBeginOpAddress() + ImageBase + MemPos_CodeSection;
1028 }
1029 }
1030
1031 // インターフェイスのvtbl
1032 BOOST_FOREACH( const ::Interface *pInterface, interfaces )
1033 {
1034 LONG_PTR *pVtbl = (LONG_PTR *)((char *)compiler.GetObjectModule().dataTable.GetPtr() + pInterface->GetVtblOffset());
1035
1036 for( int i=0; i<pInterface->GetClass().GetVtblNum(); i++ ){
1037 const UserProc *pUserProc = (UserProc *)pVtbl[i];
1038 if(!pUserProc) continue;
1039
1040 if( pUserProc->GetBeginOpAddress() == 0
1041 && pUserProc->GetEndOpAddress() == 0 )
1042 {
1043 Jenga::Throw( "未解決の仮想関数が存在する" );
1044 }
1045
1046 pVtbl[i] = pUserProc->GetBeginOpAddress() + ImageBase + MemPos_CodeSection;
1047 }
1048 }
1049
1050 // vtblマスターリスト
1051 LONG_PTR *pVtblMasterList = (LONG_PTR *)((char *)compiler.GetObjectModule().dataTable.GetPtr() + vtblMasterListOffset );
1052 for( int i=0; i<static_cast<int>(vtblMasterList.size()); i++ )
1053 {
1054 pVtblMasterList[i] = vtblMasterList[i] + ImageBase + MemPos_DataSection;
1055 }
1056}
1057bool CClass::IsAbstract() const
1058{
1059 // 未実装(abstract)の仮想関数を持つ場合はtrueを返す
1060
1061 BOOST_FOREACH( const CMethod *pMethod, GetDynamicMethods() ){
1062 if(pMethod->IsVirtual()){
1063 if(pMethod->IsAbstract()){
1064 return true;
1065 }
1066 }
1067 }
1068
1069 // インターフェイスのvtbl
1070 BOOST_FOREACH( const ::Interface *pInterface, interfaces )
1071 {
1072 BOOST_FOREACH( const CMethod *pMethod, pInterface->GetDynamicMethods() ){
1073 if(pMethod->IsVirtual()){
1074 if(pMethod->IsAbstract()){
1075 return true;
1076 }
1077 }
1078 }
1079 }
1080
1081 return false;
1082}
1083
1084CClass *Classes::Create( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, const char *name){
1085 return new CClass(namespaceScopes, importedNamespaces, name);
1086}
1087bool Classes::Insert( CClass *pClass )
1088{
1089 /////////////////////////////////
1090 // ハッシュデータに追加
1091 /////////////////////////////////
1092
1093 if( !Put( pClass ) )
1094 {
1095 SetError(15,pClass->GetName(), cp);
1096 return false;
1097 }
1098 return true;
1099}
1100CClass *Classes::Add( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, const char *name,int nowLine){
1101 //////////////////////////////////////////////////////////////////////////
1102 // クラスを追加
1103 // ※名前のみを登録。その他の情報はSetClassメソッドで!
1104 //////////////////////////////////////////////////////////////////////////
1105
1106 CClass *pClass = Create(namespaceScopes, importedNamespaces, name);
1107
1108 if( !Insert( pClass ) )
1109 {
1110 return NULL;
1111 }
1112
1113 return pClass;
1114}
1115
1116void Classes::CollectClassesForNameOnly( const BasicSource &source )
1117{
1118 int i, i2;
1119 char temporary[VN_SIZE];
1120
1121 // 名前空間管理
1122 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
1123 namespaceScopes.clear();
1124
1125 // Importsされた名前空間の管理
1126 NamespaceScopesCollection &importedNamespaces = compiler.GetNamespaceSupporter().GetImportedNamespaces();
1127 importedNamespaces.clear();
1128
1129 for(i=0;;i++){
1130 if(source[i]=='\0') break;
1131
1132 if( source[i] == 1 && source[i+1] == ESC_NAMESPACE ){
1133 for(i+=2,i2=0;;i2++,i++){
1134 if( IsCommandDelimitation( source[i] ) ){
1135 temporary[i2]=0;
1136 break;
1137 }
1138 temporary[i2]=source[i];
1139 }
1140 namespaceScopes.push_back( temporary );
1141
1142 continue;
1143 }
1144 else if( source[i] == 1 && source[i+1] == ESC_ENDNAMESPACE ){
1145 if( namespaceScopes.size() <= 0 ){
1146 SmoothieException::Throw(12, "End Namespace", i );
1147 }
1148 else{
1149 namespaceScopes.pop_back();
1150 }
1151
1152 i += 2;
1153 continue;
1154 }
1155 else if( source[i] == 1 && source[i+1] == ESC_IMPORTS ){
1156 for(i+=2,i2=0;;i2++,i++){
1157 if( IsCommandDelimitation( source[i] ) ){
1158 temporary[i2]=0;
1159 break;
1160 }
1161 temporary[i2]=source[i];
1162 }
1163 if( !compiler.GetNamespaceSupporter().ImportsNamespace( temporary ) )
1164 {
1165 SmoothieException::Throw(64,temporary,i );
1166 }
1167
1168 continue;
1169 }
1170 else if( source[i] == 1 && source[i+1] == ESC_CLEARNAMESPACEIMPORTED ){
1171 importedNamespaces.clear();
1172 continue;
1173 }
1174
1175 if(source[i]==1&&(
1176 source[i+1]==ESC_CLASS||
1177 source[i+1]==ESC_TYPE||
1178 source[i+1]==ESC_INTERFACE
1179 ))
1180 {
1181 int nowLine = i;
1182 i += 2;
1183
1184 Type blittableType;
1185 if(memicmp(source.GetBuffer()+i,"Align(",6)==0){
1186 //アラインメント修飾子
1187 i+=6;
1188 i=JumpStringInPare(source.GetBuffer(),i)+1;
1189 }
1190 else if( memicmp( source.GetBuffer() + i, "Blittable(", 10 ) == 0 ){
1191 // Blittable修飾子
1192 i+=10;
1193 i+=GetStringInPare_RemovePare(temporary,source.GetBuffer()+i)+1;
1194 compiler.StringToType( temporary, blittableType );
1195 }
1196
1197 bool isEnum = false;
1198 bool isDelegate = false;
1199 if( source[i] == 1 && source[i+1] == ESC_ENUM ){
1200 // 列挙型の場合
1201 isEnum = true;
1202
1203 i += 2;
1204 }
1205 else if( source[i] == 1 && source[i+1] == ESC_DELEGATE )
1206 {
1207 // デリゲートの場合
1208 isDelegate = true;
1209
1210 i += 2;
1211 }
1212
1213 for(i2=0;;i++,i2++){
1214 if(!IsVariableChar(source[i])){
1215 temporary[i2]=0;
1216 break;
1217 }
1218 temporary[i2]=source[i];
1219 }
1220
1221 //クラスを追加
1222 CClass *pClass = this->Add(namespaceScopes, importedNamespaces, temporary,nowLine);
1223 if( pClass ){
1224 if( source[nowLine+1] == ESC_CLASS ){
1225 if( isEnum )
1226 {
1227 pClass->SetClassType( CClass::Enum );
1228 }
1229 else if( isDelegate )
1230 {
1231 pClass->SetClassType( CClass::Delegate );
1232 }
1233 else{
1234 pClass->SetClassType( CClass::Class );
1235 }
1236 }
1237 else if( source[nowLine+1] == ESC_INTERFACE ){
1238 pClass->SetClassType( CClass::Interface );
1239 }
1240 else{
1241 pClass->SetClassType( CClass::Structure );
1242 }
1243 }
1244
1245 // Blittable型の場合
1246 if( !blittableType.IsNull() ){
1247 pClass->SetBlittableType( blittableType );
1248
1249 // Blittable型として登録
1250 compiler.GetObjectModule().meta.GetBlittableTypes().push_back( BlittableType( blittableType, pClass ) );
1251 }
1252 }
1253 }
1254}
1255
1256void Classes::GenerateVTables()
1257{
1258 Iterator_Reset();
1259 while( Iterator_HasNext() )
1260 {
1261 CClass *pClass = Iterator_GetNext();
1262 pClass->GenerateFullVTables();
1263 }
1264}
1265
1266void Classes::ActionVtblSchedule( LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection, LONG_PTR MemPos_DataSection ){
1267 Iterator_Reset();
1268 while( Iterator_HasNext() )
1269 {
1270 CClass *pClass = Iterator_GetNext();
1271 pClass->ActionVtblSchedule( ImageBase, MemPos_CodeSection, MemPos_DataSection);
1272 }
1273}
1274
1275
1276void Classes::InitStaticMember(){
1277 //静的メンバをグローバル領域に作成
1278
1279 //イテレータをリセット
1280
1281 extern int cp;
1282 int back_cp=cp;
1283
1284 this->Iterator_Reset();
1285 while(this->Iterator_HasNext()){
1286 CClass &objClass = *this->Iterator_GetNext();
1287 if( objClass.isTargetObjectModule == false )
1288 {
1289 // 静的リンクライブラリの場合は飛ばす(既にインスタンスが定義済みであるため)
1290 continue;
1291 }
1292
1293 // 名前空間をセット
1294 compiler.GetNamespaceSupporter().GetLivingNamespaceScopes() = objClass.GetNamespaceScopes();
1295
1296 DWORD dwFlags = 0;
1297 if( objClass.GetName() == "_System_TypeBase" )
1298 {
1299 // _System_TypeBaseクラスはグローバル、スタティック領域を初期化するためのクラスなのでここでの初期化は除外する
1300 dwFlags |= DIMFLAG_NONCALL_CONSTRACTOR;
1301 }
1302
1303 int i=0;
1304 BOOST_FOREACH( CMember *member, objClass.GetStaticMembers() ){
1305 char temporary[VN_SIZE];
1306 sprintf(temporary,"%s.%s",objClass.GetName().c_str(),member->GetName().c_str());
1307 dim(
1308 temporary,
1309 member->GetSubscripts(),
1310 member->GetType(),
1311 member->GetInitializeExpression().c_str(),
1312 member->GetConstructParameter().c_str(),
1313 dwFlags);
1314
1315 i++;
1316 }
1317 }
1318
1319 compiler.GetNamespaceSupporter().GetLivingNamespaceScopes().clear();
1320
1321 cp=back_cp;
1322}
1323bool Classes::MemberVar_LoopRefCheck(const CClass &objClass){
1324 bool result = true;
1325 BOOST_FOREACH( CMember *pMember, objClass.GetDynamicMembers() ){
1326 if(pMember->GetType().IsStruct()){
1327 //循環参照でないかをチェック
1328 if(pobj_LoopRefCheck->check(pMember->GetType().GetClass())){
1329 extern int cp;
1330 SetError(124,pMember->GetType().GetClass().GetName(),cp);
1331 return false;
1332 }
1333
1334 pobj_LoopRefCheck->add(objClass.GetName().c_str());
1335
1336 bool tempResult = MemberVar_LoopRefCheck(pMember->GetType().GetClass());
1337 if( result )
1338 {
1339 result = tempResult;
1340 }
1341
1342 pobj_LoopRefCheck->del(objClass.GetName().c_str());
1343 }
1344 }
1345
1346 return result;
1347}
1348void Classes::GetClass_recur(const char *lpszInheritsClass){
1349 extern char *basbuf;
1350 int i,i2,i3,sub_address,top_pos;
1351 char temporary[8192];
1352
1353 // 名前空間管理
1354 NamespaceScopes backupNamespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
1355 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
1356 namespaceScopes.clear();
1357
1358 // Importsされた名前空間の管理
1359 NamespaceScopesCollection backupImportedNamespaces = compiler.GetNamespaceSupporter().GetImportedNamespaces();
1360 compiler.GetNamespaceSupporter().GetImportedNamespaces().clear();
1361
1362 // 呼び出し元でコンパイル中のクラスポインタをバックアップ
1363 const CClass *pBackCompilingClass = compiler.pCompilingClass;
1364
1365 for(i=0;;i++){
1366 if(basbuf[i]=='\0') break;
1367
1368
1369 // 名前空間
1370 if( basbuf[i] == 1 && basbuf[i+1] == ESC_NAMESPACE ){
1371 for(i+=2,i2=0;;i2++,i++){
1372 if( IsCommandDelimitation( basbuf[i] ) ){
1373 temporary[i2]=0;
1374 break;
1375 }
1376 temporary[i2]=basbuf[i];
1377 }
1378 namespaceScopes.push_back( temporary );
1379
1380 continue;
1381 }
1382 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_ENDNAMESPACE ){
1383 if( namespaceScopes.size() <= 0 ){
1384 SetError(12, "End Namespace", i );
1385 }
1386 else{
1387 namespaceScopes.pop_back();
1388 }
1389
1390 i += 2;
1391 continue;
1392 }
1393
1394 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_IMPORTS ){
1395 for(i+=2,i2=0;;i2++,i++){
1396 if( IsCommandDelimitation( basbuf[i] ) ){
1397 temporary[i2]=0;
1398 break;
1399 }
1400 temporary[i2]=basbuf[i];
1401 }
1402 if( !compiler.GetNamespaceSupporter().ImportsNamespace( temporary ) )
1403 {
1404 SmoothieException::Throw(64,temporary,i );
1405 }
1406
1407 continue;
1408 }
1409 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_CLEARNAMESPACEIMPORTED ){
1410 compiler.GetNamespaceSupporter().GetImportedNamespaces().clear();
1411 continue;
1412 }
1413
1414
1415
1416 if(basbuf[i]==1&&basbuf[i+1]==ESC_INTERFACE){
1417 //////////////////////////
1418 // インターフェイス
1419 //////////////////////////
1420
1421 top_pos=i;
1422
1423 i+=2;
1424
1425 //インターフェイス名を取得
1426 GetIdentifierToken( temporary, basbuf, i );
1427
1428 CClass *pobj_c = const_cast<CClass *>( this->Find(namespaceScopes, temporary) );
1429 if(!pobj_c) continue;
1430
1431 if(lpszInheritsClass){
1432 if(lstrcmp(lpszInheritsClass,pobj_c->GetName().c_str())!=0){
1433 //継承先先読み用
1434 continue;
1435 }
1436 }
1437
1438 if(pobj_c->IsReady()){
1439 //既に先読みされているとき
1440 continue;
1441 }
1442
1443 pobj_c->Readed();
1444
1445 pobj_c->SetConstructorMemberSubIndex( -1 );
1446 pobj_c->SetDestructorMemberSubIndex( -1 );
1447
1448 if(basbuf[i+1]==1&&basbuf[i+2]==ESC_INHERITS){
1449 //継承を行う場合
1450 for(i+=3,i2=0;;i++,i2++){
1451 if(IsCommandDelimitation(basbuf[i])){
1452 temporary[i2]=0;
1453 break;
1454 }
1455 temporary[i2]=basbuf[i];
1456 }
1457
1458 if(lstrcmpi(temporary,pobj_c->GetName().c_str())==0){
1459 SetError(105,temporary,i);
1460 goto Interface_InheritsError;
1461 }
1462
1463 //継承元クラスを取得
1464 const Classes &classes = *this;
1465 const CClass *pInheritsClass = classes.Find(temporary);
1466 if( !pInheritsClass ){
1467 SetError(106,temporary,i);
1468 goto Interface_InheritsError;
1469 }
1470
1471 //継承させる
1472 if( !pobj_c->InheritsClass( *pInheritsClass, Types(), i ) ){
1473 goto Interface_InheritsError;
1474 }
1475 }
1476 else{
1477 //継承無し
1478 if( &pobj_c->GetSuperClass() || pobj_c->GetVtblNum() )
1479 {
1480 // TODO: ここに来ないことが実証できたらこの分岐は消す
1481 Jenga::Throw( "GetClass_recur内の例外" );
1482 }
1483 }
1484Interface_InheritsError:
1485
1486 //メンバ変数、関数を取得
1487 while(1){
1488 i++;
1489
1490 //エラー
1491 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE||basbuf[i+1]==ESC_INTERFACE)){
1492 SetError(22,"Interface",i);
1493 i--;
1494 break;
1495 }
1496
1497 if(basbuf[i]==1&&basbuf[i+1]==ESC_INHERITS){
1498 SetError(111,NULL,i);
1499 break;
1500 }
1501 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_IMPLEMENTS )
1502 {
1503 SetError(137, NULL, i );
1504 break;
1505 }
1506
1507 sub_address=i;
1508
1509 for(i2=0;;i++,i2++){
1510 if(IsCommandDelimitation(basbuf[i])){
1511 temporary[i2]=0;
1512 break;
1513 }
1514 temporary[i2]=basbuf[i];
1515 }
1516 if(temporary[0]=='\0'){
1517 if(basbuf[i]=='\0'){
1518 i--;
1519 SetError(22,"Interface",top_pos);
1520 break;
1521 }
1522 continue;
1523 }
1524
1525 //End Interface記述の場合
1526 if(temporary[0]==1&&temporary[1]==ESC_ENDINTERFACE) break;
1527
1528 if(!(temporary[0]==1&&(
1529 temporary[1]==ESC_SUB||temporary[1]==ESC_FUNCTION
1530 ))){
1531 SetError(1,NULL,i);
1532 break;
1533 }
1534
1535 //メンバ関数を追加
1536 pobj_c->AddMethod(pobj_c,
1537 Prototype::Public, //Publicアクセス権
1538 0, // bStatic
1539 false, // isConst
1540 true, // isAbstract
1541 true, // isVirtual
1542 false, // isOverride
1543 false, // isAutoGeneration
1544 temporary,
1545 sub_address
1546 );
1547 }
1548 }
1549
1550 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE)){
1551 //////////////////////////
1552 // クラス
1553 //////////////////////////
1554
1555 top_pos=i;
1556
1557 const DWORD dwClassType=basbuf[i+1];
1558
1559 i+=2;
1560
1561 int iAlign=0;
1562 if(memicmp(basbuf+i,"Align(",6)==0){
1563 //アラインメント修飾子
1564 i+=6;
1565 i+=GetStringInPare_RemovePare(temporary,basbuf+i)+1;
1566 iAlign=atoi(temporary);
1567
1568 if(!(iAlign==1||iAlign==2||iAlign==4||iAlign==8||iAlign==16))
1569 SetError(51,NULL,i);
1570 }
1571 else if( memicmp( basbuf + i, "Blittable(", 10 ) == 0 ){
1572 // Blittable修飾子
1573 i+=10;
1574 i=JumpStringInPare(basbuf,i)+1;
1575 }
1576
1577 if( basbuf[i] == 1 && basbuf[i+1] == ESC_ENUM )
1578 {
1579 // 列挙型の場合
1580 i += 2;
1581 }
1582 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_DELEGATE )
1583 {
1584 // デリゲートの場合
1585 i += 2;
1586 }
1587
1588 //クラス名を取得
1589 GetCommandToken( temporary, basbuf, i );
1590
1591 char className[VN_SIZE];
1592 Jenga::Common::Strings typeParameters;
1593 SplitGenericClassInstance( temporary, className, typeParameters );
1594
1595 CClass *pobj_c = const_cast<CClass *>( this->Find(namespaceScopes, className) );
1596 if(!pobj_c) continue;
1597
1598 compiler.pCompilingClass = pobj_c;
1599
1600 if(lpszInheritsClass){
1601 if( pobj_c->GetName() != lpszInheritsClass ){
1602 //継承先先読み用
1603 continue;
1604 }
1605 }
1606
1607 if(pobj_c->IsReady()){
1608 //既に先読みされているとき
1609 continue;
1610 }
1611
1612
1613 /////////////////////////////////////////////////////////
1614 // ☆★☆ ジェネリクスサポート ☆★☆
1615 BOOST_FOREACH( const std::string &typeParameter, typeParameters )
1616 {
1617 pobj_c->AddFormalGenericType( GenericType( typeParameter, Type(DEF_OBJECT,*GetObjectClassPtr()) ) );
1618 }
1619 /////////////////////////////////////////////////////////
1620
1621
1622 pobj_c->SetFixedAlignment( iAlign );
1623
1624 pobj_c->Readed();
1625
1626 pobj_c->SetConstructorMemberSubIndex( -1 );
1627 pobj_c->SetDestructorMemberSubIndex( -1 );
1628
1629 //アクセス制限の初期値をセット
1630 Prototype::Accessibility accessibility;
1631 if(dwClassType==ESC_CLASS){
1632 accessibility = Prototype::Private;
1633 }
1634 else{
1635 accessibility = Prototype::Public;
1636 }
1637
1638 if( pobj_c->GetName() == "Object"
1639 || dwClassType == ESC_TYPE )
1640 {
1641 // 何も継承しない
1642
1643 if( &pobj_c->GetSuperClass() || pobj_c->GetVtblNum() )
1644 {
1645 // TODO: ここに来ないことが実証できたらこの分岐は消す
1646 Jenga::Throw( "GetClass_recur内の例外" );
1647 }
1648 }
1649 else{
1650 if(basbuf[i+1]==1&&basbuf[i+2]==ESC_INHERITS)
1651 {
1652 // クラス継承先が指定されているとき
1653 i += 3;
1654 GetCommandToken( temporary, basbuf, i );
1655
1656 if(lstrcmpi(temporary,pobj_c->GetName().c_str())==0){
1657 SetError(105,temporary,i);
1658 goto InheritsError;
1659 }
1660 }
1661 else
1662 {
1663 // 何の指定もないときはObjectクラスを継承する
1664 lstrcpy( temporary, "Object" );
1665 }
1666 pobj_c->Inherits( temporary, i );
1667
1668 if( basbuf[i+1] == 1 && basbuf[i+2] == ESC_IMPLEMENTS )
1669 {
1670 // インターフェイス実装を行う場合
1671 i += 3;
1672 GetCommandToken( temporary, basbuf, i );
1673
1674 pobj_c->Implements( temporary, i );
1675 }
1676 }
1677InheritsError:
1678
1679 //メンバとメソッドを取得
1680 while(1){
1681 i++;
1682
1683 //エラー
1684 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE)){
1685 SetError(22,"Class",i);
1686 i--;
1687 break;
1688 }
1689
1690 if(basbuf[i]==1&&basbuf[i+1]==ESC_INHERITS){
1691 SetError(111,NULL,i);
1692 break;
1693 }
1694 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_IMPLEMENTS )
1695 {
1696 SetError(137, NULL, i );
1697 break;
1698 }
1699
1700 //Static修飾子
1701 BOOL bStatic;
1702 if(basbuf[i]==1&&basbuf[i+1]==ESC_STATIC){
1703 bStatic=1;
1704 i+=2;
1705 }
1706 else bStatic=0;
1707
1708 //Const修飾子
1709 bool isConst = false;
1710 if( basbuf[i] == 1 && basbuf[i + 1] == ESC_CONST ){
1711 isConst = true;
1712 i += 2;
1713 }
1714
1715 if(basbuf[i]==1&&(
1716 basbuf[i+1]==ESC_ABSTRACT||basbuf[i+1]==ESC_VIRTUAL||basbuf[i+1]==ESC_OVERRIDE||
1717 basbuf[i+1]==ESC_SUB||basbuf[i+1]==ESC_FUNCTION
1718 )){
1719 i3=basbuf[i+1];
1720 sub_address=i;
1721 }
1722 else i3=0;
1723
1724 bool isVirtual = false, isAbstract = false, isOverride = false;
1725 if(i3==ESC_ABSTRACT){
1726 isAbstract=1;
1727 isVirtual=1;
1728 i+=2;
1729
1730 i3=basbuf[i+1];
1731 }
1732 else if(i3==ESC_VIRTUAL){
1733 isAbstract=0;
1734 isVirtual=1;
1735 i+=2;
1736
1737 i3=basbuf[i+1];
1738 }
1739 else if(i3==ESC_OVERRIDE){
1740 isOverride=1;
1741 isVirtual=1;
1742
1743 i+=2;
1744
1745 i3=basbuf[i+1];
1746 }
1747
1748 for(i2=0;;i++,i2++){
1749 if(IsCommandDelimitation(basbuf[i])){
1750 temporary[i2]=0;
1751 break;
1752 }
1753 temporary[i2]=basbuf[i];
1754 }
1755 if(temporary[0]=='\0'){
1756 if(basbuf[i]=='\0'){
1757
1758 if(dwClassType==ESC_CLASS)
1759 SetError(22,"Class",top_pos);
1760 else
1761 SetError(22,"Type",top_pos);
1762
1763 i--;
1764 break;
1765 }
1766 continue;
1767 }
1768
1769 //End Class記述の場合
1770 if(temporary[0]==1&&temporary[1]==ESC_ENDCLASS&&dwClassType==ESC_CLASS) break;
1771 if(temporary[0]==1&&temporary[1]==ESC_ENDTYPE&&dwClassType==ESC_TYPE) break;
1772
1773 //アクセスを変更
1774 if(lstrcmpi(temporary,"Private")==0){
1775 accessibility = Prototype::Private;
1776 continue;
1777 }
1778 if(lstrcmpi(temporary,"Public")==0){
1779 accessibility = Prototype::Public;
1780 continue;
1781 }
1782 if(lstrcmpi(temporary,"Protected")==0){
1783 accessibility = Prototype::Protected;
1784 continue;
1785 }
1786
1787 extern int cp;
1788 if(i3==0){
1789 if(bStatic){
1790 //静的メンバを追加
1791 cp=i; //エラー用
1792 pobj_c->AddStaticMember( accessibility, isConst, false, temporary, i);
1793 }
1794 else{
1795 //メンバを追加
1796 cp=i; //エラー用
1797 pobj_c->AddMember( accessibility, isConst, false, temporary, i );
1798
1799
1800 if(pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().IsStruct()){
1801 if( !pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().GetClass().IsReady() ){
1802 //参照先が読み取られていないとき
1803 GetClass_recur(pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().GetClass().GetName().c_str());
1804 }
1805 }
1806
1807
1808 if(pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().IsStruct()){
1809 //循環参照のチェック
1810 pobj_LoopRefCheck->add(pobj_c->GetName().c_str());
1811 if(!MemberVar_LoopRefCheck(pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().GetClass())){
1812 //エラー回避
1813 Type &type = const_cast<Type &>(pobj_c->GetDynamicMembers().back()->GetType());
1814 type.SetBasicType( DEF_PTR_VOID );
1815 }
1816 pobj_LoopRefCheck->del(pobj_c->GetName().c_str());
1817 }
1818 }
1819 }
1820 else{
1821 //メソッドを追加
1822 cp=i; //エラー用
1823 pobj_c->AddMethod(pobj_c,
1824 accessibility,
1825 bStatic,
1826 isConst,
1827 isAbstract,
1828 isVirtual,
1829 isOverride,
1830 false,
1831 temporary,
1832 sub_address);
1833
1834 if( isAbstract ) continue;
1835
1836 for(;;i++){
1837 if(basbuf[i]=='\0'){
1838 i--;
1839 break;
1840 }
1841 if(basbuf[i-1]!='*'&&
1842 basbuf[i]==1&&(
1843 basbuf[i+1]==ESC_SUB||
1844 basbuf[i+1]==ESC_FUNCTION||
1845 basbuf[i+1]==ESC_MACRO||
1846 basbuf[i+1]==ESC_TYPE||
1847 basbuf[i+1]==ESC_CLASS||
1848 basbuf[i+1]==ESC_INTERFACE||
1849 basbuf[i+1]==ESC_ENUM)){
1850 GetDefaultNameFromES(i3,temporary);
1851 SetError(22,temporary,i);
1852 }
1853 if(basbuf[i]==1&&basbuf[i+1]==GetEndXXXCommand((char)i3)){
1854 i+=2;
1855 break;
1856 }
1857 }
1858 }
1859 }
1860 }
1861 }
1862
1863 // 呼び出し元でコンパイル中のクラスポインタを元に戻す
1864 compiler.pCompilingClass = pBackCompilingClass;
1865
1866 // 名前空間を元に戻す
1867 compiler.GetNamespaceSupporter().GetLivingNamespaceScopes() = backupNamespaceScopes;
1868
1869 // インポートされた名前空間を元に戻す
1870 compiler.GetNamespaceSupporter().GetImportedNamespaces() = backupImportedNamespaces;
1871}
1872void Classes::GetAllClassInfo(void){
1873 //ループ継承チェック用のクラス
1874 pobj_LoopRefCheck=new CLoopRefCheck();
1875
1876 //クラスを取得
1877 GetClass_recur(0);
1878
1879 delete pobj_LoopRefCheck;
1880 pobj_LoopRefCheck=0;
1881
1882 // イテレータの準備
1883 this->Iterator_Init();
1884}
1885void Classes::Compile_System_InitializeUserTypes(){
1886 char temporary[VN_SIZE];
1887
1888 ////////////////////////////////////////////////////////////////////
1889 // クラス登録
1890 ////////////////////////////////////////////////////////////////////
1891
1892 // イテレータをリセット
1893 Iterator_Reset();
1894
1895 while( Iterator_HasNext() ){
1896 const CClass &objClass = *Iterator_GetNext();
1897
1898 if( !objClass.IsUsing() ){
1899 // 未使用のクラスは無視する
1900 continue;
1901 }
1902
1903 char referenceOffsetsBuffer[1024] = "";
1904 int numOfReference = 0;
1905 BOOST_FOREACH( CMember *pMember, objClass.GetDynamicMembers() ){
1906 if( pMember->GetType().IsObject() || pMember->GetType().IsPointer() ){
1907 if( referenceOffsetsBuffer[0] ){
1908 lstrcat( referenceOffsetsBuffer, "," );
1909 }
1910
1911 sprintf( referenceOffsetsBuffer + lstrlen( referenceOffsetsBuffer ),
1912 "%d",
1913 objClass.GetMemberOffset( pMember->GetName().c_str() ) );
1914
1915 numOfReference++;
1916 }
1917 }
1918
1919 sprintf( temporary
1920 , "Add(%c%c_System_TypeForClass[strNamespace=\"%s\",name=\"%s\",fullName=\"%s\",referenceOffsets=[%s],numOfReference=%d])"
1921 , 1
1922 , ESC_SYSTEM_STATIC_NEW
1923 , objClass.GetNamespaceScopes().ToString().c_str() // 名前空間
1924 , objClass.GetName().c_str() // クラス名
1925 , objClass.GetFullName().c_str() // フルネーム
1926 , referenceOffsetsBuffer // 参照メンバオフセット配列
1927 , numOfReference // 参照メンバの個数
1928 );
1929
1930 // コンパイル
1931 ChangeOpcode( temporary );
1932
1933 objClass.SetTypeInfoDataTableOffset(
1934 compiler.GetObjectModule().dataTable.GetLastMadeConstObjectDataTableOffset()
1935 );
1936 }
1937}
1938void Classes::Compile_System_InitializeUserTypesForBaseType()
1939{
1940 extern int cp;
1941 cp = -1;
1942 ////////////////////////////////////////////////////////////////////
1943 // 基底クラスを登録
1944 ////////////////////////////////////////////////////////////////////
1945
1946 char temporary[VN_SIZE];
1947 sprintf(temporary, "%c%ctempType=Nothing%c%cTypeBaseImpl"
1948 , HIBYTE( COM_DIM )
1949 , LOBYTE( COM_DIM )
1950 , 1
1951 , ESC_AS
1952 );
1953 ChangeOpcode( temporary );
1954
1955 // イテレータをリセット
1956 Iterator_Reset();
1957
1958 while( Iterator_HasNext() ){
1959 const CClass &objClass = *Iterator_GetNext();
1960
1961 if( !objClass.IsUsing() ){
1962 // 未使用のクラスは無視する
1963 continue;
1964 }
1965
1966 if( objClass.HasSuperClass() ){
1967 sprintf( temporary
1968 , "tempType=Search(\"%s\")"
1969 , objClass.GetFullName().c_str()
1970 );
1971
1972 // コンパイル
1973 ChangeOpcode( temporary );
1974
1975 sprintf( temporary
1976 , "tempType.SetBaseType(Search(\"%s\"))"
1977 , objClass.GetSuperClass().GetFullName().c_str()
1978 );
1979
1980 // コンパイル
1981 ChangeOpcode( temporary );
1982 }
1983 }
1984
1985
1986
1987 ////////////////////////////////////////////////////////////////////
1988 // 継承関係登録
1989 ////////////////////////////////////////////////////////////////////
1990 // TODO: 未完成
1991 /*
1992
1993 // イテレータをリセット
1994 Iterator_Reset();
1995
1996 while( Iterator_HasNext() ){
1997 CClass *pClass = Iterator_GetNext();
1998
1999 sprintf( genBuffer + length
2000 , "obj.Search( \"%s\" ).SetBaseType( Search( \"%s\" ) ):"
2001 , "" // クラス名
2002 , pClass->name // クラス名
2003 );
2004 length += lstrlen( genBuffer + length );
2005
2006 while( length + 8192 > max ){
2007 max += 8192;
2008 genBuffer = (char *)realloc( genBuffer, max );
2009 }
2010 }*/
2011}
2012
2013const CClass *Classes::Find( const NamespaceScopes &namespaceScopes, const string &name ) const
2014{
2015 if( namespaceScopes.size() == 0 && name == "Object" ){
2016 return GetObjectClassPtr();
2017 }
2018 else if( namespaceScopes.size() == 0 && name == "String" ){
2019 return GetStringClassPtr();
2020 }
2021
2022 const CClass *pClass = GetHashArrayElement( name.c_str() );
2023 while( pClass )
2024 {
2025 if( pClass->IsEqualSymbol( namespaceScopes, name ) ){
2026 //名前空間とクラス名が一致した
2027 return pClass;
2028 }
2029 pClass = pClass->GetChainNext();
2030 }
2031
2032 // TypeDefも見る
2033 int index = compiler.GetObjectModule().meta.GetTypeDefs().GetIndex( namespaceScopes, name );
2034 if( index != -1 ){
2035 Type type = compiler.GetObjectModule().meta.GetTypeDefs()[index].GetBaseType();
2036 if( type.IsObject() ){
2037 return &type.GetClass();
2038 }
2039 }
2040
2041 return NULL;
2042}
2043const CClass *Classes::Find( const string &fullName ) const
2044{
2045 char AreaName[VN_SIZE] = ""; //オブジェクト変数
2046 char NestName[VN_SIZE] = ""; //入れ子メンバ
2047 bool isNest = SplitMemberName( fullName.c_str(), AreaName, NestName );
2048
2049 return Find( NamespaceScopes( AreaName ), NestName );
2050}
2051void Classes::StartCompile( const UserProc *pUserProc ){
2052 const CClass *pParentClass = pUserProc->GetParentClassPtr();
2053 if( pParentClass ){
2054 pParentClass->Using();
2055
2056 // 仮想関数になるメソッドに使用チェックをつける
2057 BOOST_FOREACH( const CMethod *pMethod, pParentClass->GetDynamicMethods() )
2058 {
2059 if( pMethod->IsVirtual() )
2060 {
2061 pMethod->GetUserProc().Using();
2062 }
2063 }
2064
2065 pCompilingMethod = pParentClass->GetDynamicMethodOrInterfaceMethod( pUserProc );
2066 if( !pCompilingMethod ){
2067 pCompilingMethod = pParentClass->GetStaticMethods().GetMethodPtr( pUserProc );
2068 if( !pCompilingMethod ){
2069 SmoothieException::Throw(300);
2070 }
2071 }
2072 }
2073 else{
2074 pCompilingMethod = NULL;
2075 }
2076}
2077
2078const CClass *Classes::GetStringClassPtr() const
2079{
2080 if( !pStringClass ){
2081 // キャッシュしておく
2082 pStringClass = this->Find( NamespaceScopes( "System" ), "String" );
2083
2084 if( !pStringClass )
2085 {
2086 SetError(400, "System.String", cp);
2087 static CClass dummy;
2088 return &dummy;
2089 }
2090 return pStringClass;
2091 }
2092 return pStringClass;
2093}
2094const CClass *Classes::GetObjectClassPtr() const
2095{
2096 if( !pObjectClass ){
2097 // キャッシュしておく
2098 pObjectClass = this->Find( NamespaceScopes( "System" ), "Object" );
2099
2100 if( !pObjectClass )
2101 {
2102 SetError(400, "System.Object", cp);
2103 static CClass dummy;
2104 return &dummy;
2105 }
2106 return pObjectClass;
2107 }
2108 return pObjectClass;
2109}
2110const CClass *Classes::GetInterfaceInfoClassPtr() const
2111{
2112 if( !pInterfaceInfo ){
2113 // キャッシュしておく
2114 pInterfaceInfo = this->Find( "ActiveBasic.Core.InterfaceInfo" );
2115
2116 if( !pInterfaceInfo )
2117 {
2118 SetError(400, "ActiveBasic.Core.InterfaceInfo", cp);
2119 static CClass dummy;
2120 return &dummy;
2121 }
2122 return pInterfaceInfo;
2123 }
2124 return pInterfaceInfo;
2125}
Note: See TracBrowser for help on using the repository browser.