source: dev/BasicCompiler_Common/Class.cpp@ 94

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

New[]を禁止した。
一部の動的型情報が生成されないバグを修正。
As演算子によるダウンキャストを許可(プログラム的なチェックはまだ走っていない)

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