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

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

jengaライブラリに一通りserializeメソッドを仕込んだ

File size: 11.2 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
8CClass::~CClass(){
9 // 動的メンバ
10 BOOST_FOREACH( CMember *member, dynamicMembers ){
11 delete member;
12 }
13
14 // 静的メンバ
15 BOOST_FOREACH( CMember *member, staticMembers ){
16 delete member;
17 }
18}
19
20bool CClass::IsInheritsInterface( const CClass *pInterfaceClass ) const
21{
22 BOOST_FOREACH( const InheritedInterface &objInterface, interfaces ){
23 if( pInterfaceClass == &objInterface.GetInterfaceClass() ){
24 return true;
25 }
26 }
27 return false;
28}
29
30bool CClass::IsClass() const
31{
32 return classType == CClass::Class;
33}
34bool CClass::IsInterface() const
35{
36 return classType == CClass::Interface;
37}
38bool CClass::IsEnum() const
39{
40 return classType == CClass::Enum;
41}
42bool CClass::IsDelegate() const
43{
44 return classType == CClass::Delegate;
45}
46bool CClass::IsStructure() const
47{
48 return classType == CClass::Structure;
49}
50
51BOOL CClass::DupliCheckAll(const char *name){
52 //重複チェック
53
54 //メンバ
55 if(DupliCheckMember(name)) return 1;
56
57 //メソッド
58 BOOST_FOREACH( const CMethod *pMethod, methods ){
59 if( lstrcmp( name, pMethod->pUserProc->GetName().c_str() ) == 0 ){
60 return 1;
61 }
62 }
63
64 return 0;
65}
66BOOL CClass::DupliCheckMember(const char *name){
67 //重複チェック
68
69 // 動的メンバ
70 BOOST_FOREACH( CMember *pMember, dynamicMembers ){
71 if( GetName() == pMember->GetName() ){
72 return 1;
73 }
74 }
75
76 // 静的メンバ
77 BOOST_FOREACH( CMember *pMember, staticMembers ){
78 if( GetName() == pMember->GetName() ){
79 return 1;
80 }
81 }
82
83 return 0;
84}
85
86//デフォルト コンストラクタ メソッドを取得
87const CMethod *CClass::GetConstructorMethod() const
88{
89 if( ConstructorMemberSubIndex == -1 ) return NULL;
90 return methods[ConstructorMemberSubIndex];
91}
92
93//デストラクタ メソッドを取得
94const CMethod *CClass::GetDestructorMethod() const
95{
96 if( DestructorMemberSubIndex == -1 ) return NULL;
97 return methods[DestructorMemberSubIndex];
98}
99
100//サイズを取得
101int CClass::GetSize() const
102{
103 return GetMemberOffset( NULL, NULL );
104}
105
106//メンバのオフセットを取得
107int CClass::GetMemberOffset( const char *memberName, int *pMemberNum ) const
108{
109 int i2;
110
111 //仮想関数が存在する場合は関数リストへのポインタのサイズを追加
112 int offset = IsExistVirtualFunctions() ? PTR_SIZE : 0;
113
114 int alignment;
115 if(iAlign) alignment=iAlign;
116 else alignment=1;
117
118 int iMaxAlign=0;
119 int i = -1;
120 BOOST_FOREACH( CMember *pMember, dynamicMembers ){
121 i++;
122
123 i2 = pMember->GetType().GetSize();
124
125 //アラインメントを算出
126 int member_size;
127 if( pMember->GetType().IsStruct() ){
128 //メンバクラスのアラインメントを取得
129 member_size=pMember->GetType().GetClass().GetAlignment();
130 }
131 else{
132 //メンバサイズを取得
133 member_size=i2;
134 }
135 if(iMaxAlign<member_size) iMaxAlign=member_size;
136
137 //アラインメントを考慮
138 if(iAlign&&iAlign<member_size){
139 if(offset%alignment) offset+=alignment-(offset%alignment);
140 }
141 else{
142 if(alignment<member_size) alignment=member_size;
143
144 if(member_size==0){
145 //メンバを持たないクラス
146 //※何もしない(オフセットの計算をしない)
147 }
148 else{
149 if(offset%member_size) offset+=member_size-(offset%member_size);
150 }
151 }
152
153 if(memberName){
154 //メンバ指定がある場合は、オフセットを返す
155 if( pMember->GetName() == memberName ){
156 if(pMemberNum) *pMemberNum=i;
157 return offset;
158 }
159 }
160
161 //配列を考慮したメンバサイズを取得
162 member_size=i2 * Variable::GetSubScriptCounts(pMember->SubScripts);
163
164 //メンバサイズを加算
165 offset+= member_size;
166 }
167
168 if(iMaxAlign<alignment) alignment=iMaxAlign;
169
170 //アラインメントを考慮
171 if(alignment){
172 if(offset%alignment) offset+=alignment-(offset%alignment);
173 }
174
175 if(pMemberNum) *pMemberNum=i;
176 return offset;
177}
178
179int CClass::GetAlignment() const
180{
181 //仮想関数が存在する場合は関数リストへのポインタのサイズを追加
182 int alignment = IsExistVirtualFunctions() ? PTR_SIZE : 0;
183
184 BOOST_FOREACH( CMember *pMember, dynamicMembers ){
185 int member_size;
186 if(pMember->GetType().IsStruct()){
187 //メンバクラスのアラインメントを取得
188 member_size=pMember->GetType().GetClass().GetAlignment();
189 }
190 else{
191 //メンバサイズを取得
192 member_size = pMember->GetType().GetSize();
193 }
194
195 //アラインメントをセット
196 if(alignment<member_size) alignment=member_size;
197 }
198
199 if(alignment==0) return 0;
200
201 if(iAlign) alignment=iAlign;
202
203 return alignment;
204}
205
206
207
208int CClass::GetFuncNumInVtbl( const UserProc *pUserProc ) const
209{
210 int n = 0;
211 BOOST_FOREACH( const CMethod *pMethod, methods ){
212 if( pMethod->pUserProc == pUserProc ) break;
213 if( pMethod->IsVirtual() ) n++;
214 }
215 return n;
216}
217
218bool CClass::IsAbstract() const
219{
220 // 未実装(abstract)の仮想関数を持つ場合はtrueを返す
221
222 BOOST_FOREACH( const CMethod *pMethod, methods ){
223 if(pMethod->IsVirtual()){
224 if(pMethod->IsAbstract()){
225 return true;
226 }
227 }
228 }
229
230 return false;
231}
232
233// コンストラクタのコンパイルを開始
234void CClass::NotifyStartConstructorCompile() const
235{
236 isCompilingConstructor = true;
237}
238
239//コンストラクタのコンパイルを終了
240void CClass::NotifyFinishConstructorCompile() const
241{
242 isCompilingConstructor = false;
243}
244
245//コンストラクタをコンパイル中かどうかを判別
246bool CClass::IsCompilingConstructor() const
247{
248 return isCompilingConstructor;
249}
250
251//デストラクタのコンパイルを開始
252void CClass::NotifyStartDestructorCompile() const{
253 isCompilingDestructor = true;
254}
255
256//デストラクタのコンパイルを終了
257void CClass::NotifyFinishDestructorCompile() const{
258 isCompilingDestructor = false;
259}
260
261//デストラクタをコンパイル中かどうかを判別
262bool CClass::IsCompilingDestructor() const
263{
264 return isCompilingDestructor;
265}
266
267//自身の派生クラスかどうかを確認
268bool CClass::IsSubClass( const CClass *pClass ) const
269{
270 if( !pClass->HasSuperClass() )
271 {
272 return false;
273 }
274
275 const CClass *pTempClass = &pClass->GetSuperClass();
276 while( pTempClass ){
277 if( this == pTempClass ) return true;
278 pTempClass = &pTempClass->GetSuperClass();
279 }
280 return false;
281}
282
283//自身と等しいまたは派生クラスかどうかを確認
284bool CClass::IsEqualsOrSubClass( const CClass *pClass ) const
285{
286 if( IsEquals( pClass ) ) return true;
287 return IsSubClass( pClass );
288}
289
290// 自身と等しいまたは派生クラス、基底クラスかどうかを確認
291bool CClass::IsEqualsOrSubClassOrSuperClass( const CClass &objClass ) const
292{
293 if( IsEquals( &objClass ) ) return true;
294 if( IsSubClass( &objClass ) ) return true;
295 if( objClass.IsSubClass( this ) ) return true;
296 return false;
297}
298
299
300
301int Classes::GetHashCode(const char *name) const{
302 int key;
303
304 for(key=0;*name!='\0';name++){
305 key=((key<<8)+ *name )%MAX_CLASS_HASH;
306 }
307
308 return key;
309}
310
311void Classes::DestroyClass(CClass *pobj_c){
312 if(pobj_c->pobj_NextClass){
313 DestroyClass(pobj_c->pobj_NextClass);
314 }
315
316 delete pobj_c;
317}
318
319Classes::Classes():
320 pStringClass( NULL ),
321 pObjectClass( NULL ),
322 pCompilingClass( NULL ),
323 pCompilingMethod( NULL ),
324 ppobj_IteClass( NULL ),
325 iIteMaxNum( 0 ),
326 iIteNextNum( 0 )
327{
328 memset( pobj_ClassHash, 0, MAX_CLASS_HASH * sizeof(CClass *) );
329 Clear();
330}
331Classes::~Classes(){
332 Clear();
333}
334void Classes::Clear()
335{
336 int i;
337 for(i=0;i<MAX_CLASS_HASH;i++){
338 if(pobj_ClassHash[i]) DestroyClass(pobj_ClassHash[i]);
339 }
340
341 if(ppobj_IteClass)
342 {
343 free(ppobj_IteClass);
344 ppobj_IteClass = NULL;
345 }
346 memset( pobj_ClassHash, 0, MAX_CLASS_HASH * sizeof(CClass *) );
347}
348
349void Classes::ActionVtblSchedule(LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection){
350 int i;
351 for(i=0;i<MAX_CLASS_HASH;i++){
352 if(pobj_ClassHash[i]){
353 CClass *pobj_c;
354 pobj_c=pobj_ClassHash[i];
355 while(1){
356 pobj_c->ActionVtblSchedule(ImageBase,MemPos_CodeSection);
357
358 if(pobj_c->pobj_NextClass==0) break;
359 pobj_c=pobj_c->pobj_NextClass;
360 }
361 }
362 }
363}
364
365const CClass *Classes::Find( const string &fullName ) const
366{
367 char AreaName[VN_SIZE] = ""; //オブジェクト変数
368 char NestName[VN_SIZE] = ""; //入れ子メンバ
369 bool isNest = CClass::SplitName( fullName.c_str(), AreaName, NestName );
370
371 return Find( NamespaceScopes( AreaName ), NestName );
372}
373
374bool Classes::Insert( CClass *pClass )
375{
376 /////////////////////////////////
377 // ハッシュデータに追加
378 /////////////////////////////////
379
380 int key;
381 key=GetHashCode( pClass->GetName().c_str() );
382
383 if(pobj_ClassHash[key]){
384 CClass *pobj_c2;
385 pobj_c2=pobj_ClassHash[key];
386 while(1){
387 if( pobj_c2->IsEqualSymbol( *pClass ) ){
388 //名前空間及びクラス名が重複した場合
389 SmoothieException::Throw(15,pClass->GetName());
390 return false;
391 }
392
393 if(pobj_c2->pobj_NextClass==0) break;
394 pobj_c2=pobj_c2->pobj_NextClass;
395 }
396 pobj_c2->pobj_NextClass=pClass;
397 }
398 else{
399 pobj_ClassHash[key]=pClass;
400 }
401 return true;
402}
403CClass *Classes::Add( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, const char *name,int nowLine){
404 //////////////////////////////////////////////////////////////////////////
405 // クラスを追加
406 // ※名前のみを登録。その他の情報はSetClassメソッドで!
407 //////////////////////////////////////////////////////////////////////////
408
409 CClass *pClass = Create(namespaceScopes, importedNamespaces, name);
410
411 if(lstrcmp(name,"String")==0){
412 //Stringクラス
413 pStringClass=pClass;
414 }
415 if( lstrcmp( name, "Object" ) == 0 ){
416 pObjectClass = pClass;
417 }
418
419 if( !Insert( pClass ) )
420 {
421 return NULL;
422 }
423
424 return pClass;
425}
426
427
428
429CClass *Classes::GetStringClassPtr() const
430{
431 if( !pStringClass ){
432 SmoothieException::Throw();
433 return NULL;
434 }
435 return pStringClass;
436}
437CClass *Classes::GetObjectClassPtr() const
438{
439 if( !pObjectClass ){
440 SmoothieException::Throw();
441 return NULL;
442 }
443 return pObjectClass;
444}
445
446void Classes::StartCompile( UserProc *pUserProc ){
447 pCompilingClass = pUserProc->GetParentClassPtr();
448 if( pCompilingClass ){
449 pCompilingClass->Using();
450
451 pCompilingMethod = pCompilingClass->GetMethods().GetMethodPtr( pUserProc );
452 if( !pCompilingMethod ){
453 pCompilingMethod = pCompilingClass->GetStaticMethods().GetMethodPtr( pUserProc );
454 if( !pCompilingMethod ){
455 SmoothieException::Throw(300);
456 }
457 }
458 }
459 else{
460 pCompilingMethod = NULL;
461 }
462}
463const CClass *Classes::GetNowCompilingClass() const
464{
465 return pCompilingClass;
466}
467const CMethod *Classes::GetNowCompilingMethodInfo(){
468 return pCompilingMethod;
469}
470
471
472
473
474//////////////////////
475// イテレータ
476//////////////////////
477
478void Classes::Iterator_Init() const
479{
480 if(ppobj_IteClass) free(ppobj_IteClass);
481
482 iIteMaxNum=0;
483 iIteNextNum=0;
484 ppobj_IteClass=(CClass **)malloc(1);
485
486 int i;
487 for(i=0;i<MAX_CLASS_HASH;i++){
488 if(pobj_ClassHash[i]){
489 CClass *pobj_c;
490 pobj_c=pobj_ClassHash[i];
491 while(1){
492 ppobj_IteClass=(CClass **)realloc(ppobj_IteClass,(iIteMaxNum+1)*sizeof(CClass *));
493 ppobj_IteClass[iIteMaxNum]=pobj_c;
494 iIteMaxNum++;
495
496 if(pobj_c->pobj_NextClass==0) break;
497 pobj_c=pobj_c->pobj_NextClass;
498 }
499 }
500 }
501}
502void Classes::Iterator_Reset() const
503{
504 iIteNextNum = 0;
505}
506BOOL Classes::Iterator_HasNext() const
507{
508 if(iIteNextNum<iIteMaxNum) return 1;
509 return 0;
510}
511CClass *Classes::Iterator_GetNext() const
512{
513 CClass *pobj_c;
514 pobj_c=ppobj_IteClass[iIteNextNum];
515 iIteNextNum++;
516 return pobj_c;
517}
518int Classes::Iterator_GetMaxCount() const
519{
520 return iIteMaxNum;
521}
Note: See TracBrowser for help on using the repository browser.