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

Last change on this file since 290 was 290, checked in by dai_9181, 17 years ago

ジェネリクスのベースを実装

File size: 41.6 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
78bool CClass::IsClass() const
79{
80 return classType == CClass::Class;
81}
82bool CClass::IsInterface() const
83{
84 return classType == CClass::Interface;
85}
86bool CClass::IsEnum() const
87{
88 return classType == CClass::Enum;
89}
90bool CClass::IsDelegate() const
91{
92 return classType == CClass::Delegate;
93}
94bool CClass::IsStructure() const
95{
96 return classType == CClass::Structure;
97}
98
99
100// コンストラクタのコンパイルを開始
101void CClass::NotifyStartConstructorCompile() const
102{
103 isCompilingConstructor = true;
104}
105
106//コンストラクタのコンパイルを終了
107void CClass::NotifyFinishConstructorCompile() const
108{
109 isCompilingConstructor = false;
110}
111
112//コンストラクタをコンパイル中かどうかを判別
113bool CClass::IsCompilingConstructor() const
114{
115 return isCompilingConstructor;
116}
117
118//デストラクタのコンパイルを開始
119void CClass::NotifyStartDestructorCompile() const{
120 isCompilingDestructor = true;
121}
122
123//デストラクタのコンパイルを終了
124void CClass::NotifyFinishDestructorCompile() const{
125 isCompilingDestructor = false;
126}
127
128//デストラクタをコンパイル中かどうかを判別
129bool CClass::IsCompilingDestructor() const
130{
131 return isCompilingDestructor;
132}
133
134//自身の派生クラスかどうかを確認
135bool CClass::IsSubClass( const CClass *pClass ) const
136{
137 if( !pClass->HasSuperClass() )
138 {
139 return false;
140 }
141
142 const CClass *pTempClass = &pClass->GetSuperClass();
143 while( pTempClass ){
144 if( this == pTempClass ) return true;
145 pTempClass = &pTempClass->GetSuperClass();
146 }
147 return false;
148}
149
150//自身と等しいまたは派生クラスかどうかを確認
151bool CClass::IsEqualsOrSubClass( const CClass *pClass ) const
152{
153 if( IsEquals( pClass ) ) return true;
154 return IsSubClass( pClass );
155}
156
157// 自身と等しいまたは派生クラス、基底クラスかどうかを確認
158bool CClass::IsEqualsOrSubClassOrSuperClass( const CClass &objClass ) const
159{
160 if( IsEquals( &objClass ) ) return true;
161 if( IsSubClass( &objClass ) ) return true;
162 if( objClass.IsSubClass( this ) ) return true;
163 return false;
164}
165
166bool CClass::IsInheritsInterface( const CClass *pInterfaceClass ) const
167{
168 BOOST_FOREACH( const InheritedInterface &objInterface, interfaces ){
169 if( pInterfaceClass == &objInterface.GetInterfaceClass() ){
170 return true;
171 }
172 }
173 return false;
174}
175
176bool CClass::Inherits( const char *inheritNames, int nowLine ){
177 int i = 0;
178 bool isInheritsClass = false;
179 while( true ){
180
181 char temporary[VN_SIZE];
182 for( int i2=0;; i++, i2++ ){
183 if( inheritNames[i] == '\0' || inheritNames[i] == ',' ){
184 temporary[i2] = 0;
185 break;
186 }
187 temporary[i2] = inheritNames[i];
188 }
189
190 //継承元クラスを取得
191 const CClass *pInheritsClass = compiler.GetObjectModule().meta.GetClasses().Find(temporary);
192 if( !pInheritsClass ){
193 SmoothieException::Throw(106,temporary,nowLine);
194 return false;
195 }
196
197 if( pInheritsClass->IsInterface() ){
198 // インターフェイスはあとで継承する
199 }
200 else if( pInheritsClass->IsClass() ){
201 // クラスを継承する
202 isInheritsClass = true;
203
204 if( !InheritsClass( *pInheritsClass, nowLine ) ){
205 return false;
206 }
207 }
208 else{
209 SmoothieException::Throw(135,NULL,nowLine);
210 return false;
211 }
212
213 if( inheritNames[i] == '\0' ){
214 break;
215 }
216 i++;
217 }
218
219 if( !isInheritsClass ){
220 // クラスを一つも継承していないとき
221 if( !InheritsClass( *compiler.GetObjectModule().meta.GetClasses().GetObjectClassPtr(), nowLine ) ){
222 return false;
223 }
224 }
225
226 i=0;
227 while( true ){
228
229 char temporary[VN_SIZE];
230 for( int i2=0;; i++, i2++ ){
231 if( inheritNames[i] == '\0' || inheritNames[i] == ',' ){
232 temporary[i2] = 0;
233 break;
234 }
235 temporary[i2] = inheritNames[i];
236 }
237
238 //継承元クラスを取得
239 const CClass *pInheritsClass = compiler.GetObjectModule().meta.GetClasses().Find(temporary);
240 if( !pInheritsClass ){
241 SmoothieException::Throw(106,temporary,nowLine);
242 return false;
243 }
244
245 if( pInheritsClass->IsInterface() ){
246 // インターフェイスを継承する
247 if( !InheritsInterface( *pInheritsClass, nowLine ) ){
248 return false;
249 }
250 }
251 else if( pInheritsClass->IsClass() ){
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 return true;
266}
267bool CClass::InheritsClass( const CClass &inheritsClass, int nowLine ){
268
269 //ループ継承でないかをチェック
270 if(pobj_LoopRefCheck->check(inheritsClass)){
271 SmoothieException::Throw(123,inheritsClass.GetName(),nowLine);
272 return false;
273 }
274
275 if( !inheritsClass.IsReady() ){
276 //継承先が読み取られていないとき
277 pobj_LoopRefCheck->add(this->GetName().c_str());
278 compiler.GetObjectModule().meta.GetClasses().GetClass_recur(inheritsClass.GetName().c_str());
279 pobj_LoopRefCheck->del(this->GetName().c_str());
280 }
281
282 //メンバをコピー
283 BOOST_FOREACH( CMember *inheritsClassDynamicMember, inheritsClass.GetDynamicMembers() ){
284 CMember *pMember = new CMember( *inheritsClassDynamicMember );
285
286 // アクセシビリティ
287 if( inheritsClassDynamicMember->IsPrivate() ){
288 pMember->SetAccessibility( Prototype::None );
289 }
290 else{
291 pMember->SetAccessibility( inheritsClassDynamicMember->GetAccessibility() );
292 }
293
294 dynamicMembers.push_back( pMember );
295 }
296
297 //メソッドをコピー
298 BOOST_FOREACH( const CMethod *pBaseMethod, inheritsClass.GetMethods() ){
299 CMethod *pMethod = new DynamicMethod( *pBaseMethod );
300
301 // アクセシビリティ
302 if(pBaseMethod->GetAccessibility() == Prototype::Private){
303 pMethod->SetAccessibility( Prototype::None );
304 }
305 else{
306 pMethod->SetAccessibility( pBaseMethod->GetAccessibility() );
307 }
308
309 //pobj_Inherits
310 // ※継承元のClassIndexをセット(入れ子継承を考慮する)
311 if(pBaseMethod->GetInheritsClassPtr()==0){
312 pMethod->SetInheritsClassPtr( &inheritsClass );
313 }
314 else{
315 pMethod->SetInheritsClassPtr( pBaseMethod->GetInheritsClassPtr() );
316 }
317
318 methods.push_back( pMethod );
319 }
320
321 //仮想関数の数
322 AddVtblNum( inheritsClass.GetVtblNum() );
323
324 //継承先のクラスをメンバとして保持する
325 SetSuperClass( &inheritsClass );
326
327 return true;
328}
329bool CClass::InheritsInterface( const CClass &inheritsInterface, int nowLine ){
330
331 //ループ継承でないかをチェック
332 if(pobj_LoopRefCheck->check(inheritsInterface)){
333 SmoothieException::Throw(123,inheritsInterface.GetName(),nowLine);
334 return false;
335 }
336
337 if( !inheritsInterface.IsReady() ){
338 //継承先が読み取られていないとき
339 pobj_LoopRefCheck->add(this->GetName().c_str());
340 compiler.GetObjectModule().meta.GetClasses().GetClass_recur(inheritsInterface.GetName().c_str());
341 pobj_LoopRefCheck->del(this->GetName().c_str());
342 }
343
344 //メソッドをコピー
345 BOOST_FOREACH( const CMethod *pBaseMethod, inheritsInterface.GetMethods() ){
346 CMethod *pMethod = new DynamicMethod( *pBaseMethod );
347
348 // アクセシビリティ
349 if(pBaseMethod->GetAccessibility() == Prototype::Private){
350 pMethod->SetAccessibility( Prototype::None );
351 }
352 else{
353 pMethod->SetAccessibility( pBaseMethod->GetAccessibility() );
354 }
355
356 //pobj_Inherits
357 // ※継承元のClassIndexをセット(入れ子継承を考慮する)
358 if(pBaseMethod->GetInheritsClassPtr()==0){
359 pMethod->SetInheritsClassPtr( &inheritsInterface );
360 }
361 else{
362 pMethod->SetInheritsClassPtr( pBaseMethod->GetInheritsClassPtr() );
363 }
364
365 methods.push_back( pMethod );
366 }
367
368 interfaces.push_back( InheritedInterface( const_cast<CClass *>(&inheritsInterface), vtblNum ) );
369
370 //仮想関数の数
371 AddVtblNum( inheritsInterface.GetVtblNum() );
372
373 return true;
374}
375CMember *CClass::CreateMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine )
376{
377 extern int cp;
378
379 //構文を解析
380 char VarName[VN_SIZE];
381 char initBuffer[VN_SIZE];
382 char lpszConstructParameter[VN_SIZE];
383 Subscripts subscripts;
384 Type type;
385 GetDimentionFormat(buffer,VarName,subscripts,type,initBuffer,lpszConstructParameter);
386
387 //重複チェック
388 if(this->DupliCheckAll(VarName)){
389 SetError(15,VarName,cp);
390 }
391
392 CMember *pMember = new CMember( accessibility, VarName, type, isConst, subscripts, initBuffer, lpszConstructParameter );
393 pMember->source_code_address = nowLine;
394 return pMember;
395}
396void CClass::AddMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine ){
397 dynamicMembers.push_back(
398 CreateMember( accessibility, isConst, isRef, buffer, nowLine )
399 );
400}
401void CClass::AddStaticMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine ){
402 staticMembers.push_back(
403 CreateMember( accessibility, isConst, isRef, buffer, nowLine )
404 );
405}
406
407void CClass::AddMethod(CClass *pobj_c, Prototype::Accessibility accessibility, BOOL bStatic, bool isConst, bool isAbstract,
408 bool isVirtual, bool isOverride, char *buffer, int nowLine){
409 int i,i2;
410 char temporary[VN_SIZE];
411
412 i=2;
413 for(i2=0;;i++,i2++){
414 if(buffer[i]=='('||buffer[i]=='\0'){
415 temporary[i2]=0;
416 break;
417 }
418 temporary[i2]=buffer[i];
419 }
420
421
422 //関数ハッシュへ登録
423 UserProc *pUserProc = compiler.GetObjectModule().meta.GetUserProcs().Add( NamespaceScopes(), NamespaceScopesCollection(), buffer,nowLine,isVirtual,pobj_c, (bStatic!=0) );
424 if(!pUserProc) return;
425
426
427 ////////////////////////////////////////////////////////////
428 // コンストラクタ、デストラクタの場合の処理
429 ////////////////////////////////////////////////////////////
430 BOOL fConstructor=0,bDestructor=0;
431
432 if(lstrcmp(temporary,pobj_c->GetName().c_str())==0){
433 //コンストラクタの場合
434
435 //標準コンストラクタ(引数なし)
436 if(pUserProc->Params().size()==0) fConstructor=1;
437
438 //強制的にConst修飾子をつける
439 isConst = true;
440 }
441 else if(temporary[0]=='~'){
442 //デストラクタの場合はその名前が正しいかチェックを行う
443 if(lstrcmp(temporary+1,pobj_c->GetName().c_str())!=0)
444 SetError(117,NULL,nowLine);
445 else
446 bDestructor=1;
447 }
448 if(fConstructor||bDestructor){
449 // コンストラクタ、デストラクタのアクセシビリティをチェック
450
451 //強制的にConst修飾子をつける
452 isConst = true;
453 }
454
455 if( fConstructor == 1 )
456 pobj_c->SetConstructorMemberSubIndex( (int)pobj_c->GetMethods().size() );
457 else if( bDestructor )
458 pobj_c->SetDestructorMemberSubIndex( (int)pobj_c->GetMethods().size() );
459
460
461
462 //////////////////
463 // 重複チェック
464 //////////////////
465
466 if(pobj_c->DupliCheckMember(temporary)){
467 SetError(15,temporary,nowLine);
468 return;
469 }
470
471 //メソッド
472 BOOST_FOREACH( const CMethod *pMethod, pobj_c->GetMethods() ){
473 //基底クラスと重複する場合はオーバーライドを行う
474 if( pMethod->GetInheritsClassPtr() ) continue;
475
476 if( pMethod->GetUserProc().GetName() == temporary ){
477 if( pMethod->GetUserProc().Params().Equals( pUserProc->Params() ) ){
478 //関数名、パラメータ属性が合致したとき
479 SetError(15,pUserProc->GetName().c_str(),nowLine);
480 return;
481 }
482 }
483 }
484
485 //仮想関数の場合
486 if( isAbstract ) pUserProc->CompleteCompile();
487
488 //メソッドのオーバーライド
489 BOOST_FOREACH( CMethod *pMethod, pobj_c->GetMethods() ){
490 if( pMethod->GetUserProc().GetName() == temporary ){
491 if( pMethod->GetUserProc().Params().Equals( pUserProc->Params() ) ){
492
493 if(pMethod->IsVirtual()){
494 //メンバ関数を上書き
495 pMethod->SetUserProcPtr( pUserProc );
496 pMethod->Override();
497
498 if( !isOverride ){
499 SetError(127,NULL,nowLine);
500 }
501 if(pMethod->GetAccessibility() != accessibility ){
502 SetError(128,NULL,nowLine);
503 }
504
505 pUserProc->SetMethod( pMethod );
506 return;
507 }
508 }
509 }
510 }
511
512 if( isVirtual ){
513 pobj_c->AddVtblNum( 1 );
514 }
515
516 if( isOverride ){
517 SetError(12,"Override",nowLine);
518 }
519
520 if(bStatic){
521 pobj_c->GetStaticMethods().AddStatic( pUserProc, accessibility );
522 }
523 else{
524 pobj_c->GetMethods().Add(pUserProc, accessibility, isConst, isAbstract, isVirtual);
525 }
526}
527
528bool CClass::DupliCheckAll(const char *name){
529 //重複チェック
530
531 //メンバ
532 if(DupliCheckMember(name)) return 1;
533
534 //メソッド
535 BOOST_FOREACH( const CMethod *pMethod, methods ){
536 if( lstrcmp( name, pMethod->GetUserProc().GetName().c_str() ) == 0 ){
537 return 1;
538 }
539 }
540
541 return 0;
542}
543bool CClass::DupliCheckMember(const char *name){
544 //重複チェック
545
546 // 動的メンバ
547 BOOST_FOREACH( CMember *pMember, dynamicMembers ){
548 if( GetName() == pMember->GetName() ){
549 return 1;
550 }
551 }
552
553 // 静的メンバ
554 BOOST_FOREACH( CMember *pMember, staticMembers ){
555 if( GetName() == pMember->GetName() ){
556 return 1;
557 }
558 }
559
560 return 0;
561}
562
563//サイズを取得
564int CClass::GetSize() const
565{
566 return GetMemberOffset( NULL, NULL );
567}
568
569//メンバのオフセットを取得
570int CClass::GetMemberOffset( const char *memberName, int *pMemberNum ) const
571{
572 int i2;
573
574 //仮想関数が存在する場合は関数リストへのポインタのサイズを追加
575 int offset = IsExistVirtualFunctions() ? PTR_SIZE : 0;
576
577 int alignment = 1;
578 if( GetFixedAlignment() )
579 {
580 alignment = GetFixedAlignment();
581 }
582
583 int iMaxAlign=0;
584 int i = -1;
585 BOOST_FOREACH( CMember *pMember, dynamicMembers ){
586 i++;
587
588 i2 = pMember->GetType().GetSize();
589
590 //アラインメントを算出
591 int member_size;
592 if( pMember->GetType().IsStruct() ){
593 //メンバクラスのアラインメントを取得
594 member_size=pMember->GetType().GetClass().GetAlignment();
595 }
596 else{
597 //メンバサイズを取得
598 member_size=i2;
599 }
600 if(iMaxAlign<member_size) iMaxAlign=member_size;
601
602 //アラインメントを考慮
603 if(GetFixedAlignment()&&GetFixedAlignment()<member_size){
604 if(offset%alignment) offset+=alignment-(offset%alignment);
605 }
606 else{
607 if(alignment<member_size) alignment=member_size;
608
609 if(member_size==0){
610 //メンバを持たないクラス
611 //※何もしない(オフセットの計算をしない)
612 }
613 else{
614 if(offset%member_size) offset+=member_size-(offset%member_size);
615 }
616 }
617
618 if(memberName){
619 //メンバ指定がある場合は、オフセットを返す
620 if( pMember->GetName() == memberName ){
621 if(pMemberNum) *pMemberNum=i;
622 return offset;
623 }
624 }
625
626 //配列を考慮したメンバサイズを取得
627 member_size = i2 * Variable::GetSubScriptCounts( pMember->GetSubscripts() );
628
629 //メンバサイズを加算
630 offset+= member_size;
631 }
632
633 if(iMaxAlign<alignment) alignment=iMaxAlign;
634
635 //アラインメントを考慮
636 if(alignment){
637 if(offset%alignment) offset+=alignment-(offset%alignment);
638 }
639
640 if(pMemberNum) *pMemberNum=i;
641 return offset;
642}
643int CClass::GetAlignment() const
644{
645 //仮想関数が存在する場合は関数リストへのポインタのサイズを追加
646 int alignment = IsExistVirtualFunctions() ? PTR_SIZE : 0;
647
648 BOOST_FOREACH( CMember *pMember, dynamicMembers ){
649 int member_size;
650 if(pMember->GetType().IsStruct()){
651 //メンバクラスのアラインメントを取得
652 member_size=pMember->GetType().GetClass().GetAlignment();
653 }
654 else{
655 //メンバサイズを取得
656 member_size = pMember->GetType().GetSize();
657 }
658
659 //アラインメントをセット
660 if(alignment<member_size) alignment=member_size;
661 }
662
663 if(alignment==0) return 0;
664
665 if(GetFixedAlignment()) alignment=GetFixedAlignment();
666
667 return alignment;
668}
669int CClass::GetFuncNumInVtbl( const UserProc *pUserProc ) const
670{
671 int n = 0;
672 BOOST_FOREACH( const CMethod *pMethod, methods ){
673 if( &pMethod->GetUserProc() == pUserProc ) break;
674 if( pMethod->IsVirtual() ) n++;
675 }
676 return n;
677}
678LONG_PTR CClass::GetVtblGlobalOffset(void) const
679{
680
681 //既に存在する場合はそれを返す
682 if(vtbl_offset!=-1) return vtbl_offset;
683
684
685
686 //////////////////////////////////////
687 // 存在しないときは新たに生成する
688 //////////////////////////////////////
689
690 const UserProc **ppsi;
691 ppsi=(const UserProc **)malloc(GetVtblNum()*sizeof(UserProc *));
692
693 //関数テーブルに値をセット
694 int i2 = 0;
695 BOOST_FOREACH( const CMethod *pMethod, methods ){
696 if(pMethod->IsVirtual()){
697 pMethod->GetUserProc().Using();
698
699 if(pMethod->IsAbstract()){
700 extern int cp;
701 SmoothieException::Throw(300,NULL,cp);
702
703 ppsi[i2]=0;
704 }
705 else{
706 ppsi[i2]=&pMethod->GetUserProc();
707 }
708 i2++;
709 }
710 }
711
712 vtbl_offset=compiler.GetObjectModule().dataTable.AddBinary((void *)ppsi,GetVtblNum()*sizeof(LONG_PTR));
713
714 for( int i=0; i < GetVtblNum(); i++ ){
715 pobj_Reloc->AddSchedule_DataSection(vtbl_offset+i*sizeof(LONG_PTR));
716 }
717
718 free(ppsi);
719
720 return vtbl_offset;
721}
722void CClass::GenerateVTables()
723{
724 if( IsAbstract() )
725 {
726 // 抽象クラスは無視
727 return;
728 }
729 if( !IsUsing() )
730 {
731 // 使われていないクラスは無視
732 return;
733 }
734
735 const UserProc **ppsi;
736 ppsi=(const UserProc **)malloc(GetVtblNum()*sizeof(UserProc *));
737
738 //関数テーブルに値をセット
739 int i2 = 0;
740 BOOST_FOREACH( const CMethod *pMethod, methods ){
741 if(pMethod->IsVirtual()){
742 if( !pMethod->GetUserProc().IsUsing() )
743 {
744 ts((char *)pMethod->GetUserProc().GetFullName().c_str());
745 }
746 pMethod->GetUserProc().Using();
747
748 if(pMethod->IsAbstract()){
749 extern int cp;
750 SmoothieException::Throw(300,NULL,cp);
751
752 ppsi[i2]=0;
753 }
754 else{
755 ppsi[i2]=&pMethod->GetUserProc();
756 }
757 i2++;
758 }
759 }
760
761 vtbl_offset=compiler.GetObjectModule().dataTable.AddBinary((void *)ppsi,GetVtblNum()*sizeof(LONG_PTR));
762
763 for( int i=0; i < GetVtblNum(); i++ ){
764 pobj_Reloc->AddSchedule_DataSection(vtbl_offset+i*sizeof(LONG_PTR));
765 }
766
767 free(ppsi);
768}
769void CClass::ActionVtblSchedule(LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection){
770 if( IsAbstract() )
771 {
772 // 抽象クラスは無視
773 return;
774 }
775 if( !IsUsing() )
776 {
777 // 使われていないクラスは無視
778 return;
779 }
780 if(vtbl_offset==-1) return;
781
782 LONG_PTR *pVtbl;
783 pVtbl=(LONG_PTR *)((char *)compiler.GetObjectModule().dataTable.GetPtr()+vtbl_offset);
784
785 int i;
786 for(i=0;i<GetVtblNum();i++){
787 UserProc *pUserProc;
788 pUserProc=(UserProc *)pVtbl[i];
789 if(!pUserProc) continue;
790
791 if( pUserProc->GetBeginOpAddress() == 0
792 && pUserProc->GetEndOpAddress() == 0 )
793 {
794 Jenga::Throw( "未解決の仮想関数が存在する" );
795 }
796
797 pVtbl[i]=pUserProc->GetBeginOpAddress()+ImageBase+MemPos_CodeSection;
798 }
799}
800bool CClass::IsAbstract() const
801{
802 // 未実装(abstract)の仮想関数を持つ場合はtrueを返す
803
804 BOOST_FOREACH( const CMethod *pMethod, methods ){
805 if(pMethod->IsVirtual()){
806 if(pMethod->IsAbstract()){
807 return true;
808 }
809 }
810 }
811
812 return false;
813}
814
815CClass *Classes::Create( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, const char *name){
816 return new CClass(namespaceScopes, importedNamespaces, name);
817}
818bool Classes::Insert( CClass *pClass )
819{
820 /////////////////////////////////
821 // ハッシュデータに追加
822 /////////////////////////////////
823
824 if( !Put( pClass ) )
825 {
826 SetError(15,pClass->GetName(), cp);
827 return false;
828 }
829 return true;
830}
831CClass *Classes::Add( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, const char *name,int nowLine){
832 //////////////////////////////////////////////////////////////////////////
833 // クラスを追加
834 // ※名前のみを登録。その他の情報はSetClassメソッドで!
835 //////////////////////////////////////////////////////////////////////////
836
837 CClass *pClass = Create(namespaceScopes, importedNamespaces, name);
838
839 if( !Insert( pClass ) )
840 {
841 return NULL;
842 }
843
844 return pClass;
845}
846
847void Classes::CollectClassesForNameOnly( const BasicSource &source )
848{
849 int i, i2;
850 char temporary[VN_SIZE];
851
852 // 名前空間管理
853 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
854 namespaceScopes.clear();
855
856 // Importsされた名前空間の管理
857 NamespaceScopesCollection &importedNamespaces = compiler.GetNamespaceSupporter().GetImportedNamespaces();
858 importedNamespaces.clear();
859
860 for(i=0;;i++){
861 if(source[i]=='\0') break;
862
863 if( source[i] == 1 && source[i+1] == ESC_NAMESPACE ){
864 for(i+=2,i2=0;;i2++,i++){
865 if( IsCommandDelimitation( source[i] ) ){
866 temporary[i2]=0;
867 break;
868 }
869 temporary[i2]=source[i];
870 }
871 namespaceScopes.push_back( temporary );
872
873 continue;
874 }
875 else if( source[i] == 1 && source[i+1] == ESC_ENDNAMESPACE ){
876 if( namespaceScopes.size() <= 0 ){
877 SmoothieException::Throw(12, "End Namespace", i );
878 }
879 else{
880 namespaceScopes.pop_back();
881 }
882
883 i += 2;
884 continue;
885 }
886 else if( source[i] == 1 && source[i+1] == ESC_IMPORTS ){
887 for(i+=2,i2=0;;i2++,i++){
888 if( IsCommandDelimitation( source[i] ) ){
889 temporary[i2]=0;
890 break;
891 }
892 temporary[i2]=source[i];
893 }
894 if( !compiler.GetNamespaceSupporter().ImportsNamespace( temporary ) )
895 {
896 SmoothieException::Throw(64,temporary,i );
897 }
898
899 continue;
900 }
901 else if( source[i] == 1 && source[i+1] == ESC_CLEARNAMESPACEIMPORTED ){
902 importedNamespaces.clear();
903 continue;
904 }
905
906 if(source[i]==1&&(
907 source[i+1]==ESC_CLASS||
908 source[i+1]==ESC_TYPE||
909 source[i+1]==ESC_INTERFACE
910 ))
911 {
912 int nowLine = i;
913 i += 2;
914
915 Type blittableType;
916 if(memicmp(source.GetBuffer()+i,"Align(",6)==0){
917 //アラインメント修飾子
918 i+=6;
919 i=JumpStringInPare(source.GetBuffer(),i)+1;
920 }
921 else if( memicmp( source.GetBuffer() + i, "Blittable(", 10 ) == 0 ){
922 // Blittable修飾子
923 i+=10;
924 i+=GetStringInPare_RemovePare(temporary,source.GetBuffer()+i)+1;
925 compiler.StringToType( temporary, blittableType );
926 }
927
928 bool isEnum = false;
929 if( source[i] == 1 && source[i+1] == ESC_ENUM ){
930 // 列挙型の場合
931 isEnum = true;
932
933 i+=2;
934 }
935
936 for(i2=0;;i++,i2++){
937 if(!IsVariableChar(source[i])){
938 temporary[i2]=0;
939 break;
940 }
941 temporary[i2]=source[i];
942 }
943
944 //クラスを追加
945 CClass *pClass = this->Add(namespaceScopes, importedNamespaces, temporary,nowLine);
946 if( pClass ){
947 if( source[nowLine+1] == ESC_CLASS ){
948 if( isEnum ){
949 pClass->SetClassType( CClass::Enum );
950 }
951 else{
952 pClass->SetClassType( CClass::Class );
953 }
954 }
955 else if( source[nowLine+1] == ESC_INTERFACE ){
956 pClass->SetClassType( CClass::Interface );
957 }
958 else{
959 pClass->SetClassType( CClass::Structure );
960 }
961 }
962
963 // Blittable型の場合
964 if( !blittableType.IsNull() ){
965 pClass->SetBlittableType( blittableType );
966
967 // Blittable型として登録
968 compiler.GetObjectModule().meta.GetBlittableTypes().push_back( BlittableType( blittableType, pClass ) );
969 }
970 }
971 }
972}
973
974void Classes::GenerateVTables()
975{
976 Iterator_Reset();
977 while( Iterator_HasNext() )
978 {
979 CClass *pClass = Iterator_GetNext();
980 pClass->GenerateVTables();
981 }
982}
983
984void Classes::ActionVtblSchedule(LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection){
985 Iterator_Reset();
986 while( Iterator_HasNext() )
987 {
988 CClass *pClass = Iterator_GetNext();
989 pClass->ActionVtblSchedule(ImageBase,MemPos_CodeSection);
990 }
991}
992
993
994void Classes::InitStaticMember(){
995 //静的メンバをグローバル領域に作成
996
997 //イテレータをリセット
998
999 extern int cp;
1000 int back_cp=cp;
1001
1002 this->Iterator_Reset();
1003 while(this->Iterator_HasNext()){
1004 CClass &objClass = *this->Iterator_GetNext();
1005 if( objClass.isTargetObjectModule == false )
1006 {
1007 // 静的リンクライブラリの場合は飛ばす(既にインスタンスが定義済みであるため)
1008 continue;
1009 }
1010
1011 // 名前空間をセット
1012 compiler.GetNamespaceSupporter().GetLivingNamespaceScopes() = objClass.GetNamespaceScopes();
1013
1014 int i=0;
1015 BOOST_FOREACH( CMember *member, objClass.GetStaticMembers() ){
1016 char temporary[VN_SIZE];
1017 sprintf(temporary,"%s.%s",objClass.GetName().c_str(),member->GetName().c_str());
1018 dim(
1019 temporary,
1020 member->GetSubscripts(),
1021 member->GetType(),
1022 member->GetInitializeExpression().c_str(),
1023 member->GetConstructParameter().c_str(),
1024 0);
1025
1026 i++;
1027 }
1028 }
1029
1030 compiler.GetNamespaceSupporter().GetLivingNamespaceScopes().clear();
1031
1032 cp=back_cp;
1033}
1034bool Classes::MemberVar_LoopRefCheck(const CClass &objClass){
1035 bool result = true;
1036 BOOST_FOREACH( CMember *pMember, objClass.GetDynamicMembers() ){
1037 if(pMember->GetType().IsStruct()){
1038 //循環参照でないかをチェック
1039 if(pobj_LoopRefCheck->check(pMember->GetType().GetClass())){
1040 extern int cp;
1041 SetError(124,pMember->GetType().GetClass().GetName(),cp);
1042 return false;
1043 }
1044
1045 pobj_LoopRefCheck->add(objClass.GetName().c_str());
1046
1047 bool tempResult = MemberVar_LoopRefCheck(pMember->GetType().GetClass());
1048 if( result )
1049 {
1050 result = tempResult;
1051 }
1052
1053 pobj_LoopRefCheck->del(objClass.GetName().c_str());
1054 }
1055 }
1056
1057 return result;
1058}
1059void Classes::GetClass_recur(const char *lpszInheritsClass){
1060 extern char *basbuf;
1061 int i,i2,i3,sub_address,top_pos;
1062 char temporary[8192];
1063
1064 // 名前空間管理
1065 NamespaceScopes backupNamespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
1066 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
1067 namespaceScopes.clear();
1068
1069 for(i=0;;i++){
1070 if(basbuf[i]=='\0') break;
1071
1072
1073 // 名前空間
1074 if( basbuf[i] == 1 && basbuf[i+1] == ESC_NAMESPACE ){
1075 for(i+=2,i2=0;;i2++,i++){
1076 if( IsCommandDelimitation( basbuf[i] ) ){
1077 temporary[i2]=0;
1078 break;
1079 }
1080 temporary[i2]=basbuf[i];
1081 }
1082 namespaceScopes.push_back( temporary );
1083
1084 continue;
1085 }
1086 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_ENDNAMESPACE ){
1087 if( namespaceScopes.size() <= 0 ){
1088 SetError(12, "End Namespace", i );
1089 }
1090 else{
1091 namespaceScopes.pop_back();
1092 }
1093
1094 i += 2;
1095 continue;
1096 }
1097
1098
1099
1100 if(basbuf[i]==1&&basbuf[i+1]==ESC_INTERFACE){
1101 //////////////////////////
1102 // インターフェイス
1103 //////////////////////////
1104
1105 top_pos=i;
1106
1107 i+=2;
1108
1109 //インターフェイス名を取得
1110 GetIdentifierToken( temporary, basbuf, i );
1111
1112 CClass *pobj_c = const_cast<CClass *>( this->Find(namespaceScopes, temporary) );
1113 if(!pobj_c) continue;
1114
1115 if(lpszInheritsClass){
1116 if(lstrcmp(lpszInheritsClass,pobj_c->GetName().c_str())!=0){
1117 //継承先先読み用
1118 continue;
1119 }
1120 }
1121
1122 if(pobj_c->IsReady()){
1123 //既に先読みされているとき
1124 continue;
1125 }
1126
1127 pobj_c->Readed();
1128
1129 pobj_c->SetConstructorMemberSubIndex( -1 );
1130 pobj_c->SetDestructorMemberSubIndex( -1 );
1131
1132 if(basbuf[i+1]==1&&basbuf[i+2]==ESC_INHERITS){
1133 //継承を行う場合
1134 for(i+=3,i2=0;;i++,i2++){
1135 if(IsCommandDelimitation(basbuf[i])){
1136 temporary[i2]=0;
1137 break;
1138 }
1139 temporary[i2]=basbuf[i];
1140 }
1141
1142 if(lstrcmpi(temporary,pobj_c->GetName().c_str())==0){
1143 SetError(105,temporary,i);
1144 goto Interface_InheritsError;
1145 }
1146
1147 //継承元クラスを取得
1148 const Classes &classes = *this;
1149 const CClass *pInheritsClass = classes.Find(temporary);
1150 if( !pInheritsClass ){
1151 SetError(106,temporary,i);
1152 goto Interface_InheritsError;
1153 }
1154
1155 //継承させる
1156 if( !pobj_c->InheritsClass( *pInheritsClass, i ) ){
1157 goto Interface_InheritsError;
1158 }
1159 }
1160 else{
1161 //継承無し
1162 if( &pobj_c->GetSuperClass() || pobj_c->GetVtblNum() )
1163 {
1164 // TODO: ここに来ないことが実証できたらこの分岐は消す
1165 Jenga::Throw( "GetClass_recur内の例外" );
1166 }
1167 }
1168Interface_InheritsError:
1169
1170 //メンバ変数、関数を取得
1171 while(1){
1172 i++;
1173
1174 //エラー
1175 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE||basbuf[i+1]==ESC_INTERFACE)){
1176 SetError(22,"Interface",i);
1177 i--;
1178 break;
1179 }
1180
1181 if(basbuf[i]==1&&basbuf[i+1]==ESC_INHERITS){
1182 SetError(111,NULL,i);
1183 break;
1184 }
1185
1186 sub_address=i;
1187
1188 for(i2=0;;i++,i2++){
1189 if(IsCommandDelimitation(basbuf[i])){
1190 temporary[i2]=0;
1191 break;
1192 }
1193 temporary[i2]=basbuf[i];
1194 }
1195 if(temporary[0]=='\0'){
1196 if(basbuf[i]=='\0'){
1197 i--;
1198 SetError(22,"Interface",top_pos);
1199 break;
1200 }
1201 continue;
1202 }
1203
1204 //End Interface記述の場合
1205 if(temporary[0]==1&&temporary[1]==ESC_ENDINTERFACE) break;
1206
1207 if(!(temporary[0]==1&&(
1208 temporary[1]==ESC_SUB||temporary[1]==ESC_FUNCTION
1209 ))){
1210 SetError(1,NULL,i);
1211 break;
1212 }
1213
1214 //メンバ関数を追加
1215 pobj_c->AddMethod(pobj_c,
1216 Prototype::Public, //Publicアクセス権
1217 0, //Static指定なし
1218 false, //Constではない
1219 1, //Abstract
1220 1, //Virtual
1221 0,
1222 temporary,
1223 sub_address
1224 );
1225 }
1226 }
1227
1228 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE)){
1229 //////////////////////////
1230 // クラス
1231 //////////////////////////
1232
1233 top_pos=i;
1234
1235 const DWORD dwClassType=basbuf[i+1];
1236
1237 i+=2;
1238
1239 int iAlign=0;
1240 if(memicmp(basbuf+i,"Align(",6)==0){
1241 //アラインメント修飾子
1242 i+=6;
1243 i+=GetStringInPare_RemovePare(temporary,basbuf+i)+1;
1244 iAlign=atoi(temporary);
1245
1246 if(!(iAlign==1||iAlign==2||iAlign==4||iAlign==8||iAlign==16))
1247 SetError(51,NULL,i);
1248 }
1249 else if( memicmp( basbuf + i, "Blittable(", 10 ) == 0 ){
1250 // Blittable修飾子
1251 i+=10;
1252 i=JumpStringInPare(basbuf,i)+1;
1253 }
1254
1255 if( basbuf[i] == 1 && basbuf[i+1] == ESC_ENUM ){
1256 // 列挙型の場合
1257 i+=2;
1258 }
1259
1260 //クラス名を取得
1261 GetIdentifierToken( temporary, basbuf, i );
1262
1263 CClass *pobj_c = const_cast<CClass *>( this->Find(namespaceScopes, temporary) );
1264 if(!pobj_c) continue;
1265
1266 compiler.pCompilingClass = pobj_c;
1267
1268 if(lpszInheritsClass){
1269 if( pobj_c->GetName() != lpszInheritsClass ){
1270 //継承先先読み用
1271 continue;
1272 }
1273 }
1274
1275 if(pobj_c->IsReady()){
1276 //既に先読みされているとき
1277 continue;
1278 }
1279
1280
1281 /////////////////////////////////////////////////////////
1282 // ☆★☆ ジェネリクスサポート ☆★☆
1283 if( basbuf[i] == '<' )
1284 {
1285 // 型パラメータを取得
1286 i++;
1287 GetIdentifierToken( temporary, basbuf, i );
1288
1289 pobj_c->AddFormalGenericType( GenericType( temporary, Type(DEF_OBJECT,*GetObjectClassPtr()) ) );
1290
1291 if( basbuf[i] == '>' )
1292 {
1293 i++;
1294 }
1295 else
1296 {
1297 SetError();
1298 }
1299 }
1300 /////////////////////////////////////////////////////////
1301
1302
1303 pobj_c->SetFixedAlignment( iAlign );
1304
1305 pobj_c->Readed();
1306
1307 pobj_c->SetConstructorMemberSubIndex( -1 );
1308 pobj_c->SetDestructorMemberSubIndex( -1 );
1309
1310 //アクセス制限の初期値をセット
1311 Prototype::Accessibility accessibility;
1312 if(dwClassType==ESC_CLASS){
1313 accessibility = Prototype::Private;
1314 }
1315 else{
1316 accessibility = Prototype::Public;
1317 }
1318
1319 if( pobj_c->GetName() == "Object" || dwClassType == ESC_TYPE ){
1320 if( &pobj_c->GetSuperClass() || pobj_c->GetVtblNum() )
1321 {
1322 // TODO: ここに来ないことが実証できたらこの分岐は消す
1323 Jenga::Throw( "GetClass_recur内の例外" );
1324 }
1325 }
1326 else{
1327 bool isInherits = false;
1328 if(basbuf[i+1]==1&&basbuf[i+2]==ESC_INHERITS){
1329 //継承を行う場合
1330 isInherits = true;
1331
1332 for(i+=3,i2=0;;i++,i2++){
1333 if(IsCommandDelimitation(basbuf[i])){
1334 temporary[i2]=0;
1335 break;
1336 }
1337 temporary[i2]=basbuf[i];
1338 }
1339
1340 if(lstrcmpi(temporary,pobj_c->GetName().c_str())==0){
1341 SetError(105,temporary,i);
1342 goto InheritsError;
1343 }
1344 }
1345
1346 if( !isInherits ){
1347 //Objectを継承する
1348 lstrcpy( temporary, "Object" );
1349 }
1350
1351 pobj_c->Inherits( temporary, i );
1352 }
1353InheritsError:
1354
1355 //メンバとメソッドを取得
1356 while(1){
1357 i++;
1358
1359 //エラー
1360 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE)){
1361 SetError(22,"Class",i);
1362 i--;
1363 break;
1364 }
1365
1366 if(basbuf[i]==1&&basbuf[i+1]==ESC_INHERITS){
1367 SetError(111,NULL,i);
1368 break;
1369 }
1370
1371 //Static修飾子
1372 BOOL bStatic;
1373 if(basbuf[i]==1&&basbuf[i+1]==ESC_STATIC){
1374 bStatic=1;
1375 i+=2;
1376 }
1377 else bStatic=0;
1378
1379 //Const修飾子
1380 bool isConst = false;
1381 if( basbuf[i] == 1 && basbuf[i + 1] == ESC_CONST ){
1382 isConst = true;
1383 i += 2;
1384 }
1385
1386 if(basbuf[i]==1&&(
1387 basbuf[i+1]==ESC_ABSTRACT||basbuf[i+1]==ESC_VIRTUAL||basbuf[i+1]==ESC_OVERRIDE||
1388 basbuf[i+1]==ESC_SUB||basbuf[i+1]==ESC_FUNCTION
1389 )){
1390 i3=basbuf[i+1];
1391 sub_address=i;
1392 }
1393 else i3=0;
1394
1395 bool isVirtual = false, isAbstract = false, isOverride = false;
1396 if(i3==ESC_ABSTRACT){
1397 isAbstract=1;
1398 isVirtual=1;
1399 i+=2;
1400
1401 i3=basbuf[i+1];
1402 }
1403 else if(i3==ESC_VIRTUAL){
1404 isAbstract=0;
1405 isVirtual=1;
1406 i+=2;
1407
1408 i3=basbuf[i+1];
1409 }
1410 else if(i3==ESC_OVERRIDE){
1411 isOverride=1;
1412 isVirtual=1;
1413
1414 i+=2;
1415
1416 i3=basbuf[i+1];
1417 }
1418
1419 for(i2=0;;i++,i2++){
1420 if(IsCommandDelimitation(basbuf[i])){
1421 temporary[i2]=0;
1422 break;
1423 }
1424 temporary[i2]=basbuf[i];
1425 }
1426 if(temporary[0]=='\0'){
1427 if(basbuf[i]=='\0'){
1428
1429 if(dwClassType==ESC_CLASS)
1430 SetError(22,"Class",top_pos);
1431 else
1432 SetError(22,"Type",top_pos);
1433
1434 i--;
1435 break;
1436 }
1437 continue;
1438 }
1439
1440 //End Class記述の場合
1441 if(temporary[0]==1&&temporary[1]==ESC_ENDCLASS&&dwClassType==ESC_CLASS) break;
1442 if(temporary[0]==1&&temporary[1]==ESC_ENDTYPE&&dwClassType==ESC_TYPE) break;
1443
1444 //アクセスを変更
1445 if(lstrcmpi(temporary,"Private")==0){
1446 accessibility = Prototype::Private;
1447 continue;
1448 }
1449 if(lstrcmpi(temporary,"Public")==0){
1450 accessibility = Prototype::Public;
1451 continue;
1452 }
1453 if(lstrcmpi(temporary,"Protected")==0){
1454 accessibility = Prototype::Protected;
1455 continue;
1456 }
1457
1458 extern int cp;
1459 if(i3==0){
1460 if(bStatic){
1461 //静的メンバを追加
1462 cp=i; //エラー用
1463 pobj_c->AddStaticMember( accessibility, isConst, false, temporary, i);
1464 }
1465 else{
1466 //メンバを追加
1467 cp=i; //エラー用
1468 pobj_c->AddMember( accessibility, isConst, false, temporary, i );
1469
1470
1471 if(pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().IsStruct()){
1472 if( !pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().GetClass().IsReady() ){
1473 //参照先が読み取られていないとき
1474 GetClass_recur(pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().GetClass().GetName().c_str());
1475 }
1476 }
1477
1478
1479 if(pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().IsStruct()){
1480 //循環参照のチェック
1481 pobj_LoopRefCheck->add(pobj_c->GetName().c_str());
1482 if(!MemberVar_LoopRefCheck(pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().GetClass())){
1483 //エラー回避
1484 pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().SetBasicType( DEF_PTR_VOID );
1485 }
1486 pobj_LoopRefCheck->del(pobj_c->GetName().c_str());
1487 }
1488 }
1489 }
1490 else{
1491 //メソッドを追加
1492 cp=i; //エラー用
1493 pobj_c->AddMethod(pobj_c,
1494 accessibility,
1495 bStatic,
1496 isConst,
1497 isAbstract,
1498 isVirtual,
1499 isOverride,
1500 temporary,
1501 sub_address);
1502
1503 if( isAbstract ) continue;
1504
1505 for(;;i++){
1506 if(basbuf[i]=='\0'){
1507 i--;
1508 break;
1509 }
1510 if(basbuf[i-1]!='*'&&
1511 basbuf[i]==1&&(
1512 basbuf[i+1]==ESC_SUB||
1513 basbuf[i+1]==ESC_FUNCTION||
1514 basbuf[i+1]==ESC_MACRO||
1515 basbuf[i+1]==ESC_TYPE||
1516 basbuf[i+1]==ESC_CLASS||
1517 basbuf[i+1]==ESC_INTERFACE||
1518 basbuf[i+1]==ESC_ENUM)){
1519 GetDefaultNameFromES(i3,temporary);
1520 SetError(22,temporary,i);
1521 }
1522 if(basbuf[i]==1&&basbuf[i+1]==GetEndXXXCommand((char)i3)){
1523 i+=2;
1524 break;
1525 }
1526 }
1527 }
1528 }
1529 }
1530 }
1531
1532
1533 // 名前空間を元に戻す
1534 compiler.GetNamespaceSupporter().GetLivingNamespaceScopes() = backupNamespaceScopes;
1535}
1536void Classes::GetAllClassInfo(void){
1537 //ループ継承チェック用のクラス
1538 pobj_LoopRefCheck=new CLoopRefCheck();
1539
1540 //クラスを取得
1541 GetClass_recur(0);
1542
1543 delete pobj_LoopRefCheck;
1544 pobj_LoopRefCheck=0;
1545
1546 // イテレータの準備
1547 this->Iterator_Init();
1548}
1549void Classes::Compile_System_InitializeUserTypes(){
1550 char temporary[VN_SIZE];
1551
1552 ////////////////////////////////////////////////////////////////////
1553 // クラス登録
1554 ////////////////////////////////////////////////////////////////////
1555
1556 // イテレータをリセット
1557 Iterator_Reset();
1558
1559 while( Iterator_HasNext() ){
1560 const CClass &objClass = *Iterator_GetNext();
1561
1562 if( !objClass.IsUsing() ){
1563 // 未使用のクラスは無視する
1564 continue;
1565 }
1566
1567 char referenceOffsetsBuffer[1024] = "";
1568 int numOfReference = 0;
1569 BOOST_FOREACH( CMember *pMember, objClass.GetDynamicMembers() ){
1570 if( pMember->GetType().IsObject() || pMember->GetType().IsPointer() ){
1571 if( referenceOffsetsBuffer[0] ){
1572 lstrcat( referenceOffsetsBuffer, "," );
1573 }
1574
1575 sprintf( referenceOffsetsBuffer + lstrlen( referenceOffsetsBuffer ),
1576 "%d",
1577 objClass.GetMemberOffset( pMember->GetName().c_str() ) );
1578
1579 numOfReference++;
1580 }
1581 }
1582
1583 sprintf( temporary
1584 , "Add(%c%c_System_TypeForClass(\"%s\",\"%s\",[%s],%d))"
1585 , 1
1586 , ESC_NEW
1587 , "" // 名前空間 (TODO: 実装)
1588 , objClass.GetName().c_str() // クラス名
1589 , referenceOffsetsBuffer // 参照メンバオフセット配列
1590 , numOfReference // 参照メンバの個数
1591 );
1592
1593 // コンパイル
1594 ChangeOpcode( temporary );
1595 }
1596
1597
1598 ////////////////////////////////////////////////////////////////////
1599 // 基底クラスを登録
1600 ////////////////////////////////////////////////////////////////////
1601
1602 sprintf(temporary, "%c%ctempType=Nothing%c%cTypeBaseImpl"
1603 , HIBYTE( COM_DIM )
1604 , LOBYTE( COM_DIM )
1605 , 1
1606 , ESC_AS
1607 );
1608 ChangeOpcode( temporary );
1609
1610 // イテレータをリセット
1611 Iterator_Reset();
1612
1613 while( Iterator_HasNext() ){
1614 const CClass &objClass = *Iterator_GetNext();
1615
1616 if( !objClass.IsUsing() ){
1617 // 未使用のクラスは無視する
1618 continue;
1619 }
1620
1621 if( objClass.HasSuperClass() ){
1622 sprintf( temporary
1623 , "tempType=Search(\"%s\",\"%s\")"
1624 , "" // 名前空間 (TODO: 実装)
1625 , objClass.GetName().c_str() // クラス名
1626 );
1627
1628 // コンパイル
1629 ChangeOpcode( temporary );
1630
1631 sprintf( temporary
1632 , "tempType.SetBaseType(Search(\"%s\",\"%s\"))"
1633 , "" // 名前空間 (TODO: 実装)
1634 , objClass.GetSuperClass().GetName().c_str() // 基底クラス名
1635 );
1636
1637 // コンパイル
1638 ChangeOpcode( temporary );
1639 }
1640 }
1641
1642
1643
1644 ////////////////////////////////////////////////////////////////////
1645 // 継承関係登録
1646 ////////////////////////////////////////////////////////////////////
1647 // TODO: 未完成
1648 /*
1649
1650 // イテレータをリセット
1651 Iterator_Reset();
1652
1653 while( Iterator_HasNext() ){
1654 CClass *pClass = Iterator_GetNext();
1655
1656 sprintf( genBuffer + length
1657 , "obj.Search( \"%s\" ).SetBaseType( Search( \"%s\" ) ):"
1658 , "" // クラス名
1659 , pClass->name // クラス名
1660 );
1661 length += lstrlen( genBuffer + length );
1662
1663 while( length + 8192 > max ){
1664 max += 8192;
1665 genBuffer = (char *)realloc( genBuffer, max );
1666 }
1667 }*/
1668}
1669
1670const CClass *Classes::Find( const NamespaceScopes &namespaceScopes, const string &name ) const
1671{
1672 if( namespaceScopes.size() == 0 && name == "Object" ){
1673 return GetObjectClassPtr();
1674 }
1675 else if( namespaceScopes.size() == 0 && name == "String" ){
1676 return GetStringClassPtr();
1677 }
1678
1679 const CClass *pClass = GetHashArrayElement( name.c_str() );
1680 while( pClass )
1681 {
1682 if( pClass->IsEqualSymbol( namespaceScopes, name ) ){
1683 //名前空間とクラス名が一致した
1684 return pClass;
1685 }
1686 pClass = pClass->GetChainNext();
1687 }
1688
1689 // TypeDefも見る
1690 int index = compiler.GetObjectModule().meta.GetTypeDefs().GetIndex( namespaceScopes, name );
1691 if( index != -1 ){
1692 Type type = compiler.GetObjectModule().meta.GetTypeDefs()[index].GetBaseType();
1693 if( type.IsObject() ){
1694 return &type.GetClass();
1695 }
1696 }
1697
1698 return NULL;
1699}
1700const CClass *Classes::Find( const string &fullName ) const
1701{
1702 char AreaName[VN_SIZE] = ""; //オブジェクト変数
1703 char NestName[VN_SIZE] = ""; //入れ子メンバ
1704 bool isNest = SplitMemberName( fullName.c_str(), AreaName, NestName );
1705
1706 return Find( NamespaceScopes( AreaName ), NestName );
1707}
1708void Classes::StartCompile( const UserProc *pUserProc ){
1709 const CClass *pParentClass = pUserProc->GetParentClassPtr();
1710 if( pParentClass ){
1711 pParentClass->Using();
1712
1713 // 仮想関数になるメソッドに使用チェックをつける
1714 BOOST_FOREACH( const CMethod *pMethod, pParentClass->GetMethods() )
1715 {
1716 if( pMethod->IsVirtual() )
1717 {
1718 pMethod->GetUserProc().Using();
1719 }
1720 }
1721
1722 pCompilingMethod = pParentClass->GetMethods().GetMethodPtr( pUserProc );
1723 if( !pCompilingMethod ){
1724 pCompilingMethod = pParentClass->GetStaticMethods().GetMethodPtr( pUserProc );
1725 if( !pCompilingMethod ){
1726 SmoothieException::Throw(300);
1727 }
1728 }
1729 }
1730 else{
1731 pCompilingMethod = NULL;
1732 }
1733}
1734
1735const CClass *Classes::GetStringClassPtr() const
1736{
1737 if( !pStringClass ){
1738 // キャッシュしておく
1739 pStringClass = this->Find( NamespaceScopes( "System" ), "String" );
1740
1741 if( !pStringClass )
1742 {
1743 SmoothieException::Throw();
1744 }
1745 return pStringClass;
1746 }
1747 return pStringClass;
1748}
1749const CClass *Classes::GetObjectClassPtr() const
1750{
1751 if( !pObjectClass ){
1752 // キャッシュしておく
1753 pObjectClass = this->Find( NamespaceScopes( "System" ), "Object" );
1754
1755 if( !pObjectClass )
1756 {
1757 SmoothieException::Throw();
1758 }
1759 return pObjectClass;
1760 }
1761 return pObjectClass;
1762}
Note: See TracBrowser for help on using the repository browser.