source: dev/trunk/jenga/src/smoothie/Class.cpp@ 172

Last change on this file since 172 was 172, checked in by dai_9181, 17 years ago
File size: 20.0 KB
Line 
1#include <stdlib.h>
2
3#include <jenga/include/smoothie/Smoothie.h>
4#include <jenga/include/smoothie/Class.h>
5#include <jenga/include/smoothie/SmoothieException.h>
6
7
8class CLoopRefCheck{
9 char **names;
10 int num;
11 void init(){
12 int i;
13 for(i=0;i<num;i++){
14 free(names[i]);
15 }
16 free(names);
17 }
18public:
19 CLoopRefCheck()
20 {
21 names=(char **)malloc(1);
22 num=0;
23 }
24 ~CLoopRefCheck()
25 {
26 init();
27 }
28 void add(const char *lpszInheritsClass)
29 {
30 names=(char **)realloc(names,(num+1)*sizeof(char *));
31 names[num]=(char *)malloc(lstrlen(lpszInheritsClass)+1);
32 lstrcpy(names[num],lpszInheritsClass);
33 num++;
34 }
35 void del(const char *lpszInheritsClass)
36 {
37 int i;
38 for(i=0;i<num;i++){
39 if(lstrcmp(names[i],lpszInheritsClass)==0){
40 free(names[i]);
41 break;
42 }
43 }
44 if(i!=num){
45 num--;
46 for(;i<num;i++){
47 names[i]=names[i+1];
48 }
49 }
50 }
51 BOOL check(const CClass &inheritsClass) const
52 {
53 //ループ継承チェック
54 int i;
55 for(i=0;i<num;i++){
56 if( inheritsClass.GetName() == names[i] ){
57 return 1;
58 }
59 }
60 return 0;
61 }
62};
63CLoopRefCheck *pobj_LoopRefCheck;
64
65
66
67
68CClass::CClass( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, const string &name )
69 : isReady( false )
70 , Prototype( namespaceScopes, name )
71 , importedNamespaces( importedNamespaces )
72 , ConstructorMemberSubIndex( 0 )
73 , DestructorMemberSubIndex( 0 )
74 , classType( Class )
75 , pobj_InheritsClass( NULL )
76 , vtblNum( 0 )
77 , iAlign( 0 )
78 , vtbl_offset( -1 )
79 , isCompilingConstructor( false )
80 , isCompilingDestructor( false )
81 , pobj_NextClass( NULL )
82{
83}
84CClass::~CClass(){
85 // 動的メンバ
86 BOOST_FOREACH( CMember *member, dynamicMembers ){
87 delete member;
88 }
89
90 // 静的メンバ
91 BOOST_FOREACH( CMember *member, staticMembers ){
92 delete member;
93 }
94}
95
96bool CClass::IsInheritsInterface( const CClass *pInterfaceClass ) const
97{
98 BOOST_FOREACH( const InheritedInterface &objInterface, interfaces ){
99 if( pInterfaceClass == &objInterface.GetInterfaceClass() ){
100 return true;
101 }
102 }
103 return false;
104}
105
106bool CClass::IsClass() const
107{
108 return classType == CClass::Class;
109}
110bool CClass::IsInterface() const
111{
112 return classType == CClass::Interface;
113}
114bool CClass::IsEnum() const
115{
116 return classType == CClass::Enum;
117}
118bool CClass::IsDelegate() const
119{
120 return classType == CClass::Delegate;
121}
122bool CClass::IsStructure() const
123{
124 return classType == CClass::Structure;
125}
126
127bool CClass::Inherits( const char *inheritNames, int nowLine ){
128 int i = 0;
129 bool isInheritsClass = false;
130 while( true ){
131
132 char temporary[VN_SIZE];
133 for( int i2=0;; i++, i2++ ){
134 if( inheritNames[i] == '\0' || inheritNames[i] == ',' ){
135 temporary[i2] = 0;
136 break;
137 }
138 temporary[i2] = inheritNames[i];
139 }
140
141 //継承元クラスを取得
142 const CClass *pInheritsClass = Smoothie::meta.classes.Find(temporary);
143 if( !pInheritsClass ){
144 throw SmoothieException(106,temporary,nowLine);
145 return false;
146 }
147
148 if( pInheritsClass->IsInterface() ){
149 // インターフェイスはあとで継承する
150 }
151 else if( pInheritsClass->IsClass() ){
152 // クラスを継承する
153 isInheritsClass = true;
154
155 if( !InheritsClass( *pInheritsClass, nowLine ) ){
156 return false;
157 }
158 }
159 else{
160 throw SmoothieException(135,NULL,nowLine);
161 return false;
162 }
163
164 if( inheritNames[i] == '\0' ){
165 break;
166 }
167 i++;
168 }
169
170 if( !isInheritsClass ){
171 // クラスを一つも継承していないとき
172 const CClass *pObjectClass = Smoothie::meta.classes.Find("Object");
173 if( !pObjectClass ){
174 throw SmoothieException(106,"Object",i);
175 return false;
176 }
177
178 if( !InheritsClass( *pObjectClass, nowLine ) ){
179 return false;
180 }
181 }
182
183 i=0;
184 while( true ){
185
186 char temporary[VN_SIZE];
187 for( int i2=0;; i++, i2++ ){
188 if( inheritNames[i] == '\0' || inheritNames[i] == ',' ){
189 temporary[i2] = 0;
190 break;
191 }
192 temporary[i2] = inheritNames[i];
193 }
194
195 //継承元クラスを取得
196 const CClass *pInheritsClass = Smoothie::meta.classes.Find(temporary);
197 if( !pInheritsClass ){
198 throw SmoothieException(106,temporary,nowLine);
199 return false;
200 }
201
202 if( pInheritsClass->IsInterface() ){
203 // インターフェイスを継承する
204 if( !InheritsInterface( *pInheritsClass, nowLine ) ){
205 return false;
206 }
207 }
208 else if( pInheritsClass->IsClass() ){
209 // クラスはさっき継承した
210 }
211 else{
212 throw SmoothieException(135,NULL,nowLine);
213 return false;
214 }
215
216 if( inheritNames[i] == '\0' ){
217 break;
218 }
219 i++;
220 }
221
222 return true;
223}
224/*
225bool CClass::InheritsClass( const CClass &inheritsClass, int nowLine ){
226
227 //ループ継承でないかをチェック
228 if(pobj_LoopRefCheck->check(inheritsClass)){
229 throw SmoothieException(123,inheritsClass.GetName(),nowLine);
230 return false;
231 }
232
233 if( !inheritsClass.IsReady() ){
234 //継承先が読み取られていないとき
235 pobj_LoopRefCheck->add(this->GetName().c_str());
236 Smoothie::meta.classes.GetClass_recur(inheritsClass.GetName().c_str());
237 pobj_LoopRefCheck->del(this->GetName().c_str());
238 }
239
240 //メンバをコピー
241 BOOST_FOREACH( CMember *inheritsClassDynamicMember, inheritsClass.dynamicMembers ){
242 CMember *pMember = new CMember( *inheritsClassDynamicMember );
243
244 // アクセシビリティ
245 if( inheritsClassDynamicMember->IsPrivate() ){
246 pMember->SetAccessibility( Prototype::None );
247 }
248 else{
249 pMember->SetAccessibility( inheritsClassDynamicMember->GetAccessibility() );
250 }
251
252 dynamicMembers.push_back( pMember );
253 }
254
255 //メソッドをコピー
256 BOOST_FOREACH( const CMethod *pBaseMethod, inheritsClass.methods ){
257 CMethod *pMethod = new DynamicMethod( *pBaseMethod );
258
259 // アクセシビリティ
260 if(pBaseMethod->GetAccessibility() == Prototype::Private){
261 pMethod->SetAccessibility( Prototype::None );
262 }
263 else{
264 pMethod->SetAccessibility( pBaseMethod->GetAccessibility() );
265 }
266
267 //pobj_Inherits
268 // ※継承元のClassIndexをセット(入れ子継承を考慮する)
269 if(pBaseMethod->GetInheritsClassPtr()==0){
270 pMethod->SetInheritsClassPtr( &inheritsClass );
271 }
272 else{
273 pMethod->SetInheritsClassPtr( pBaseMethod->GetInheritsClassPtr() );
274 }
275
276 methods.push_back( pMethod );
277 }
278
279 //仮想関数の数
280 AddVtblNum( inheritsClass.GetVtblNum() );
281
282 //継承先のクラスをメンバとして保持する
283 pobj_InheritsClass = &inheritsClass;
284
285 return true;
286}
287bool CClass::InheritsInterface( const CClass &inheritsInterface, int nowLine ){
288
289 //ループ継承でないかをチェック
290 if(pobj_LoopRefCheck->check(inheritsInterface)){
291 throw SmoothieException(123,inheritsInterface.GetName(),nowLine);
292 return false;
293 }
294
295 if( !inheritsInterface.IsReady() ){
296 //継承先が読み取られていないとき
297 pobj_LoopRefCheck->add(this->GetName().c_str());
298 Smoothie::meta.classes.GetClass_recur(inheritsInterface.GetName().c_str());
299 pobj_LoopRefCheck->del(this->GetName().c_str());
300 }
301
302 //メソッドをコピー
303 BOOST_FOREACH( const CMethod *pBaseMethod, inheritsInterface.methods ){
304 CMethod *pMethod = new DynamicMethod( *pBaseMethod );
305
306 // アクセシビリティ
307 if(pBaseMethod->GetAccessibility() == Prototype::Private){
308 pMethod->SetAccessibility( Prototype::None );
309 }
310 else{
311 pMethod->SetAccessibility( pBaseMethod->GetAccessibility() );
312 }
313
314 //pobj_Inherits
315 // ※継承元のClassIndexをセット(入れ子継承を考慮する)
316 if(pBaseMethod->GetInheritsClassPtr()==0){
317 pMethod->SetInheritsClassPtr( &inheritsInterface );
318 }
319 else{
320 pMethod->SetInheritsClassPtr( pBaseMethod->GetInheritsClassPtr() );
321 }
322
323 methods.push_back( pMethod );
324 }
325
326 interfaces.push_back( InheritedInterface( const_cast<CClass *>(&inheritsInterface), vtblNum ) );
327
328 //仮想関数の数
329 AddVtblNum( inheritsInterface.GetVtblNum() );
330
331 return true;
332}
333void CClass::AddMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer ){
334 CMember *pMember = new CMember( this, accessibility, isConst, isRef, buffer );
335 dynamicMembers.push_back( pMember );
336}
337void CClass::AddStaticMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine ){
338 CMember *pMember = new CMember( this, accessibility, isConst, isRef, buffer, nowLine );
339 staticMembers.push_back( pMember );
340}*/
341BOOL CClass::DupliCheckAll(const char *name){
342 //重複チェック
343
344 //メンバ
345 if(DupliCheckMember(name)) return 1;
346
347 //メソッド
348 BOOST_FOREACH( const CMethod *pMethod, methods ){
349 if( lstrcmp( name, pMethod->pUserProc->GetName().c_str() ) == 0 ){
350 return 1;
351 }
352 }
353
354 return 0;
355}
356BOOL CClass::DupliCheckMember(const char *name){
357 //重複チェック
358
359 // 動的メンバ
360 BOOST_FOREACH( CMember *pMember, dynamicMembers ){
361 if( GetName() == pMember->GetName() ){
362 return 1;
363 }
364 }
365
366 // 静的メンバ
367 BOOST_FOREACH( CMember *pMember, staticMembers ){
368 if( GetName() == pMember->GetName() ){
369 return 1;
370 }
371 }
372
373 return 0;
374}
375
376//デフォルト コンストラクタ メソッドを取得
377const CMethod *CClass::GetConstructorMethod() const
378{
379 if( ConstructorMemberSubIndex == -1 ) return NULL;
380 return methods[ConstructorMemberSubIndex];
381}
382
383//デストラクタ メソッドを取得
384const CMethod *CClass::GetDestructorMethod() const
385{
386 if( DestructorMemberSubIndex == -1 ) return NULL;
387 return methods[DestructorMemberSubIndex];
388}
389
390//サイズを取得
391int CClass::GetSize() const
392{
393 return GetMemberOffset( NULL, NULL );
394}
395
396//メンバのオフセットを取得
397int CClass::GetMemberOffset( const char *memberName, int *pMemberNum ) const
398{
399 int i2;
400
401 //仮想関数が存在する場合は関数リストへのポインタのサイズを追加
402 int offset = IsExistVirtualFunctions() ? PTR_SIZE : 0;
403
404 int alignment;
405 if(iAlign) alignment=iAlign;
406 else alignment=1;
407
408 int iMaxAlign=0;
409 int i = -1;
410 BOOST_FOREACH( CMember *pMember, dynamicMembers ){
411 i++;
412
413 i2 = pMember->GetType().GetSize();
414
415 //アラインメントを算出
416 int member_size;
417 if( pMember->GetType().IsStruct() ){
418 //メンバクラスのアラインメントを取得
419 member_size=pMember->GetType().GetClass().GetAlignment();
420 }
421 else{
422 //メンバサイズを取得
423 member_size=i2;
424 }
425 if(iMaxAlign<member_size) iMaxAlign=member_size;
426
427 //アラインメントを考慮
428 if(iAlign&&iAlign<member_size){
429 if(offset%alignment) offset+=alignment-(offset%alignment);
430 }
431 else{
432 if(alignment<member_size) alignment=member_size;
433
434 if(member_size==0){
435 //メンバを持たないクラス
436 //※何もしない(オフセットの計算をしない)
437 }
438 else{
439 if(offset%member_size) offset+=member_size-(offset%member_size);
440 }
441 }
442
443 if(memberName){
444 //メンバ指定がある場合は、オフセットを返す
445 if( pMember->GetName() == memberName ){
446 if(pMemberNum) *pMemberNum=i;
447 return offset;
448 }
449 }
450
451 //配列を考慮したメンバサイズを取得
452 member_size=i2 * Variable::GetSubScriptCounts(pMember->SubScripts);
453
454 //メンバサイズを加算
455 offset+= member_size;
456 }
457
458 if(iMaxAlign<alignment) alignment=iMaxAlign;
459
460 //アラインメントを考慮
461 if(alignment){
462 if(offset%alignment) offset+=alignment-(offset%alignment);
463 }
464
465 if(pMemberNum) *pMemberNum=i;
466 return offset;
467}
468
469int CClass::GetAlignment() const
470{
471 //仮想関数が存在する場合は関数リストへのポインタのサイズを追加
472 int alignment = IsExistVirtualFunctions() ? PTR_SIZE : 0;
473
474 BOOST_FOREACH( CMember *pMember, dynamicMembers ){
475 int member_size;
476 if(pMember->GetType().IsStruct()){
477 //メンバクラスのアラインメントを取得
478 member_size=pMember->GetType().GetClass().GetAlignment();
479 }
480 else{
481 //メンバサイズを取得
482 member_size = pMember->GetType().GetSize();
483 }
484
485 //アラインメントをセット
486 if(alignment<member_size) alignment=member_size;
487 }
488
489 if(alignment==0) return 0;
490
491 if(iAlign) alignment=iAlign;
492
493 return alignment;
494}
495
496
497
498int CClass::GetFuncNumInVtbl( const UserProc *pUserProc ) const
499{
500 int n = 0;
501 BOOST_FOREACH( const CMethod *pMethod, methods ){
502 if( pMethod->pUserProc == pUserProc ) break;
503 if( pMethod->IsVirtual() ) n++;
504 }
505 return n;
506}
507/*
508LONG_PTR CClass::GetVtblGlobalOffset(void) const
509{
510
511 //既に存在する場合はそれを返す
512 if(vtbl_offset!=-1) return vtbl_offset;
513
514
515
516 //////////////////////////////////////
517 // 存在しないときは新たに生成する
518 //////////////////////////////////////
519
520 UserProc **ppsi;
521 ppsi=(UserProc **)malloc(GetVtblNum()*sizeof(GlobalProc *));
522
523 //関数テーブルに値をセット
524 int i2 = 0;
525 BOOST_FOREACH( const CMethod *pMethod, methods ){
526 if(pMethod->IsVirtual()){
527 pMethod->pUserProc->Using();
528
529 if(pMethod->IsAbstract()){
530 extern int cp;
531 throw SmoothieException(300,NULL,cp);
532
533 ppsi[i2]=0;
534 }
535 else{
536 ppsi[i2]=pMethod->pUserProc;
537 }
538 i2++;
539 }
540 }
541
542 vtbl_offset=dataTable.AddBinary((void *)ppsi,GetVtblNum()*sizeof(LONG_PTR));
543
544 for( int i=0; i < GetVtblNum(); i++ ){
545 pobj_Reloc->AddSchedule_DataSection(vtbl_offset+i*sizeof(LONG_PTR));
546 }
547
548 free(ppsi);
549
550 return vtbl_offset;
551}
552void CClass::ActionVtblSchedule(LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection){
553 if(vtbl_offset==-1) return;
554
555 LONG_PTR *pVtbl;
556 pVtbl=(LONG_PTR *)((char *)dataTable.GetPtr()+vtbl_offset);
557
558 int i;
559 for(i=0;i<GetVtblNum();i++){
560 GlobalProc *pUserProc;
561 pUserProc=(GlobalProc *)pVtbl[i];
562 if(!pUserProc) continue;
563 pVtbl[i]=pUserProc->beginOpAddress+ImageBase+MemPos_CodeSection;
564 }
565}*/
566bool CClass::IsAbstract() const
567{
568 // 未実装(abstract)の仮想関数を持つ場合はtrueを返す
569
570 BOOST_FOREACH( const CMethod *pMethod, methods ){
571 if(pMethod->IsVirtual()){
572 if(pMethod->IsAbstract()){
573 return true;
574 }
575 }
576 }
577
578 return false;
579}
580
581// コンストラクタのコンパイルを開始
582void CClass::NotifyStartConstructorCompile() const
583{
584 isCompilingConstructor = true;
585}
586
587//コンストラクタのコンパイルを終了
588void CClass::NotifyFinishConstructorCompile() const
589{
590 isCompilingConstructor = false;
591}
592
593//コンストラクタをコンパイル中かどうかを判別
594bool CClass::IsCompilingConstructor() const
595{
596 return isCompilingConstructor;
597}
598
599//デストラクタのコンパイルを開始
600void CClass::NotifyStartDestructorCompile() const{
601 isCompilingDestructor = true;
602}
603
604//デストラクタのコンパイルを終了
605void CClass::NotifyFinishDestructorCompile() const{
606 isCompilingDestructor = false;
607}
608
609//デストラクタをコンパイル中かどうかを判別
610bool CClass::IsCompilingDestructor() const
611{
612 return isCompilingDestructor;
613}
614
615//自身の派生クラスかどうかを確認
616bool CClass::IsSubClass( const CClass *pClass ) const
617{
618 pClass = pClass->pobj_InheritsClass;
619 while( pClass ){
620 if( this == pClass ) return true;
621 pClass = pClass->pobj_InheritsClass;
622 }
623 return false;
624}
625
626//自身と等しいまたは派生クラスかどうかを確認
627bool CClass::IsEqualsOrSubClass( const CClass *pClass ) const
628{
629 if( IsEquals( pClass ) ) return true;
630 return IsSubClass( pClass );
631}
632
633// 自身と等しいまたは派生クラス、基底クラスかどうかを確認
634bool CClass::IsEqualsOrSubClassOrSuperClass( const CClass &objClass ) const
635{
636 if( IsEquals( &objClass ) ) return true;
637 if( IsSubClass( &objClass ) ) return true;
638 if( objClass.IsSubClass( this ) ) return true;
639 return false;
640}
641
642
643
644int Classes::hash(const char *name) const{
645 int key;
646
647 for(key=0;*name!='\0';name++){
648 key=((key<<8)+ *name )%MAX_CLASS_HASH;
649 }
650
651 return key;
652}
653
654void Classes::DestroyClass(CClass *pobj_c){
655 if(pobj_c->pobj_NextClass){
656 DestroyClass(pobj_c->pobj_NextClass);
657 }
658
659 delete pobj_c;
660}
661
662Classes::Classes():
663 pStringClass( NULL ),
664 pObjectClass( NULL ),
665 pCompilingClass( NULL ),
666 pCompilingMethod( NULL ),
667 ppobj_IteClass( NULL ),
668 iIteMaxNum( 0 ),
669 iIteNextNum( 0 )
670{
671 memset( pobj_ClassHash, 0, MAX_CLASS_HASH * sizeof(CClass *) );
672}
673Classes::~Classes(){
674 int i;
675 for(i=0;i<MAX_CLASS_HASH;i++){
676 if(pobj_ClassHash[i]) DestroyClass(pobj_ClassHash[i]);
677 }
678
679 if(ppobj_IteClass) free(ppobj_IteClass);
680}
681
682void Classes::ActionVtblSchedule(LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection){
683 int i;
684 for(i=0;i<MAX_CLASS_HASH;i++){
685 if(pobj_ClassHash[i]){
686 CClass *pobj_c;
687 pobj_c=pobj_ClassHash[i];
688 while(1){
689 pobj_c->ActionVtblSchedule(ImageBase,MemPos_CodeSection);
690
691 if(pobj_c->pobj_NextClass==0) break;
692 pobj_c=pobj_c->pobj_NextClass;
693 }
694 }
695 }
696}
697
698const CClass *Classes::Find( const NamespaceScopes &namespaceScopes, const string &name ) const
699{
700 int key;
701 key=hash(name.c_str());
702
703 if( namespaceScopes.size() == 0 && name == "Object" ){
704 return GetObjectClassPtr();
705 }
706 else if( namespaceScopes.size() == 0 && name == "String" ){
707 return GetStringClassPtr();
708 }
709
710 if(pobj_ClassHash[key]){
711 CClass *pobj_c;
712 pobj_c=pobj_ClassHash[key];
713 while(1){
714 if( pobj_c->IsEqualSymbol( namespaceScopes, name ) ){
715 //名前空間とクラス名が一致した
716 return pobj_c;
717 }
718
719 if(pobj_c->pobj_NextClass==0) break;
720 pobj_c=pobj_c->pobj_NextClass;
721 }
722 }
723
724 // TypeDefも見る
725 int index = Smoothie::meta.typeDefs.GetIndex( namespaceScopes, name );
726 if( index != -1 ){
727 Type type = Smoothie::meta.typeDefs[index].GetBaseType();
728 if( type.IsObject() ){
729 return &type.GetClass();
730 }
731 }
732
733 return NULL;
734}
735const CClass *Classes::Find( const string &fullName ) const
736{
737 char AreaName[VN_SIZE] = ""; //オブジェクト変数
738 char NestName[VN_SIZE] = ""; //入れ子メンバ
739 bool isNest = CClass::SplitName( fullName.c_str(), AreaName, NestName );
740
741 return Find( NamespaceScopes( AreaName ), NestName );
742}
743
744CClass *Classes::AddClass( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, const char *name,int nowLine){
745 //////////////////////////////////////////////////////////////////////////
746 // クラスを追加
747 // ※名前のみを登録。その他の情報はSetClassメソッドで!
748 //////////////////////////////////////////////////////////////////////////
749
750 CClass *pobj_c;
751 pobj_c=new CClass(namespaceScopes, importedNamespaces, name);
752
753 if(lstrcmp(name,"String")==0){
754 //Stringクラス
755 pStringClass=pobj_c;
756 }
757 if( lstrcmp( name, "Object" ) == 0 ){
758 pObjectClass = pobj_c;
759 }
760
761
762 /////////////////////////////////
763 // ハッシュデータに追加
764 /////////////////////////////////
765
766 int key;
767 key=hash(name);
768
769 if(pobj_ClassHash[key]){
770 CClass *pobj_c2;
771 pobj_c2=pobj_ClassHash[key];
772 while(1){
773 if( pobj_c2->IsEqualSymbol( namespaceScopes, name ) ){
774 //名前空間及びクラス名が重複した場合
775 throw SmoothieException(15,name,nowLine);
776 return 0;
777 }
778
779 if(pobj_c2->pobj_NextClass==0) break;
780 pobj_c2=pobj_c2->pobj_NextClass;
781 }
782 pobj_c2->pobj_NextClass=pobj_c;
783 }
784 else{
785 pobj_ClassHash[key]=pobj_c;
786 }
787
788 return pobj_c;
789}
790
791
792
793CClass *Classes::GetStringClassPtr() const
794{
795 if( !pStringClass ){
796 throw SmoothieException();
797 return NULL;
798 }
799 return pStringClass;
800}
801CClass *Classes::GetObjectClassPtr() const
802{
803 if( !pObjectClass ){
804 throw SmoothieException();
805 return NULL;
806 }
807 return pObjectClass;
808}
809
810void Classes::StartCompile( UserProc *pUserProc ){
811 pCompilingClass = pUserProc->GetParentClassPtr();
812 if( pCompilingClass ){
813 pCompilingClass->Using();
814
815 pCompilingMethod = pCompilingClass->GetMethods().GetMethodPtr( pUserProc );
816 if( !pCompilingMethod ){
817 pCompilingMethod = pCompilingClass->GetStaticMethods().GetMethodPtr( pUserProc );
818 if( !pCompilingMethod ){
819 throw SmoothieException(300);
820 }
821 }
822 }
823 else{
824 pCompilingMethod = NULL;
825 }
826}
827const CClass *Classes::GetNowCompilingClass() const
828{
829 return pCompilingClass;
830}
831const CMethod *Classes::GetNowCompilingMethodInfo(){
832 return pCompilingMethod;
833}
834
835
836
837
838//////////////////////
839// イテレータ
840//////////////////////
841
842void Classes::Iterator_Init(void){
843 if(ppobj_IteClass) free(ppobj_IteClass);
844
845 iIteMaxNum=0;
846 iIteNextNum=0;
847 ppobj_IteClass=(CClass **)malloc(1);
848
849 int i;
850 for(i=0;i<MAX_CLASS_HASH;i++){
851 if(pobj_ClassHash[i]){
852 CClass *pobj_c;
853 pobj_c=pobj_ClassHash[i];
854 while(1){
855 ppobj_IteClass=(CClass **)realloc(ppobj_IteClass,(iIteMaxNum+1)*sizeof(CClass *));
856 ppobj_IteClass[iIteMaxNum]=pobj_c;
857 iIteMaxNum++;
858
859 if(pobj_c->pobj_NextClass==0) break;
860 pobj_c=pobj_c->pobj_NextClass;
861 }
862 }
863 }
864}
865void Classes::Iterator_Reset(void){
866 iIteNextNum = 0;
867}
868BOOL Classes::Iterator_HasNext(void){
869 if(iIteNextNum<iIteMaxNum) return 1;
870 return 0;
871}
872CClass *Classes::Iterator_GetNext(void){
873 CClass *pobj_c;
874 pobj_c=ppobj_IteClass[iIteNextNum];
875 iIteNextNum++;
876 return pobj_c;
877}
878int Classes::Iterator_GetMaxCount(void){
879 return iIteMaxNum;
880}
Note: See TracBrowser for help on using the repository browser.