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

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

[416]のコミットによって発生した64bit版での不具合を修正。

File size: 39.1 KB
Line 
1#include "stdafx.h"
2
3#include <jenga/include/smoothie/Smoothie.h>
4#include <jenga/include/smoothie/SmoothieException.h>
5
6#include <Source.h>
7#include <Class.h>
8#include <Compiler.h>
9#include <NamespaceSupporter.h>
10
11#include "../common.h"
12#ifdef _AMD64_
13#include "../../BasicCompiler64/opcode.h"
14#else
15#include "../../BasicCompiler32/opcode.h"
16#endif
17
18
19Interface::Interface( const CClass *pInterfaceClass, const Types &actualTypeParameters )
20 : DynamicMethodsPrototype()
21 , pInterfaceClass( pInterfaceClass )
22 , vtblOffset( -1 )
23 , actualTypeParameters( actualTypeParameters )
24{
25 //メソッドをコピー
26 BOOST_FOREACH( const CMethod *pBaseMethod, pInterfaceClass->GetDynamicMethods() )
27 {
28 CMethod *pMethod = new DynamicMethod( *pBaseMethod );
29
30 // アクセシビリティ
31 if(pBaseMethod->GetAccessibility() == Prototype::Private){
32 pMethod->SetAccessibility( Prototype::None );
33 }
34 else{
35 pMethod->SetAccessibility( pBaseMethod->GetAccessibility() );
36 }
37
38 //pobj_Inherits
39 // ※継承元のClassIndexをセット(入れ子継承を考慮する)
40 if(pBaseMethod->GetInheritsClassPtr()==0){
41 pMethod->SetInheritsClassPtr( pInterfaceClass );
42 }
43 else{
44 pMethod->SetInheritsClassPtr( pBaseMethod->GetInheritsClassPtr() );
45 }
46
47 AddDynamicMethods( pMethod );
48 }
49}
50
51std::string Interface::GetFullNameWithActualGenericTypeParameters() const
52{
53 std::string interfaceName = this->GetClass().GetFullName();
54 if( actualTypeParameters.size() )
55 {
56 std::string actualGenericTypesName;
57 BOOST_FOREACH( const Type &typeParameter, actualTypeParameters )
58 {
59 if( actualGenericTypesName.size() )
60 {
61 actualGenericTypesName += ",";
62 }
63 actualGenericTypesName += typeParameter.ToString();
64 }
65
66 interfaceName += "<" + actualGenericTypesName + ">";
67 }
68 return interfaceName;
69}
70
71bool CClass::IsClass() const
72{
73 return classType == CClass::Class;
74}
75bool CClass::IsInterface() const
76{
77 return classType == CClass::Interface;
78}
79bool CClass::IsComInterface() const
80{
81 return classType == CClass::ComInterface;
82}
83bool CClass::IsEnum() const
84{
85 return classType == CClass::Enum;
86}
87bool CClass::IsDelegate() const
88{
89 return classType == CClass::Delegate;
90}
91bool CClass::IsStructure() const
92{
93 return classType == CClass::Structure;
94}
95
96
97// コンストラクタのコンパイルを開始
98void CClass::NotifyStartConstructorCompile() const
99{
100 isCompilingConstructor = true;
101}
102
103//コンストラクタのコンパイルを終了
104void CClass::NotifyFinishConstructorCompile() const
105{
106 isCompilingConstructor = false;
107}
108
109//コンストラクタをコンパイル中かどうかを判別
110bool CClass::IsCompilingConstructor() const
111{
112 return isCompilingConstructor;
113}
114
115//デストラクタのコンパイルを開始
116void CClass::NotifyStartDestructorCompile() const{
117 isCompilingDestructor = true;
118}
119
120//デストラクタのコンパイルを終了
121void CClass::NotifyFinishDestructorCompile() const{
122 isCompilingDestructor = false;
123}
124
125//デストラクタをコンパイル中かどうかを判別
126bool CClass::IsCompilingDestructor() const
127{
128 return isCompilingDestructor;
129}
130
131//自身の派生クラスかどうかを確認
132bool CClass::IsSubClass( const CClass *pClass ) const
133{
134 if( !pClass->HasSuperClass() )
135 {
136 return false;
137 }
138
139 const CClass *pTempClass = &pClass->GetSuperClass();
140 while( pTempClass ){
141 if( this == pTempClass ) return true;
142 pTempClass = &pTempClass->GetSuperClass();
143 }
144 return false;
145}
146
147//自身と等しいまたは派生クラスかどうかを確認
148bool CClass::IsEqualsOrSubClass( const CClass *pClass ) const
149{
150 if( IsEquals( pClass ) ) return true;
151 return IsSubClass( pClass );
152}
153
154// 自身と等しいまたは派生クラス、基底クラスかどうかを確認
155bool CClass::IsEqualsOrSubClassOrSuperClass( const CClass &objClass ) const
156{
157 if( IsEquals( &objClass ) ) return true;
158 if( IsSubClass( &objClass ) ) return true;
159 if( objClass.IsSubClass( this ) ) return true;
160 return false;
161}
162
163bool CClass::IsInheritsInterface( const CClass *pInterfaceClass ) const
164{
165 BOOST_FOREACH( const ::Interface *pInterface, interfaces ){
166 if( pInterfaceClass == &pInterface->GetClass() ){
167 return true;
168 }
169 }
170 return false;
171}
172
173bool CClass::Inherits( const char *inheritNames, int nowLine ){
174 int i = 0;
175 bool isInheritsClass = false;
176 while( true ){
177
178 char temporary[VN_SIZE];
179 for( int i2=0;; i++, i2++ ){
180 if( inheritNames[i] == '\0' || inheritNames[i] == ',' ){
181 temporary[i2] = 0;
182 break;
183 }
184 temporary[i2] = inheritNames[i];
185 }
186
187 // ジェネリクス構文を分解
188 char className[VN_SIZE];
189 Jenga::Common::Strings typeParameterStrings;
190 SplitGenericClassInstance( temporary, className, typeParameterStrings );
191
192 // 型パラメータ文字列から型データを取得
193 Types actualTypeParameters;
194 BOOST_FOREACH( const std::string &typeParameterStr, typeParameterStrings )
195 {
196 Type type;
197 compiler.StringToType( typeParameterStr, type );
198 actualTypeParameters.push_back( type );
199 }
200
201 //継承元クラスを取得
202 const CClass *pInheritsClass = compiler.GetObjectModule().meta.GetClasses().Find(className);
203 if( !pInheritsClass ){
204 SmoothieException::Throw(106,className,nowLine);
205 return false;
206 }
207
208 if( pInheritsClass->IsClass() ){
209 // クラスを継承する
210 isInheritsClass = true;
211
212 if( !InheritsClass( *pInheritsClass, actualTypeParameters, nowLine ) ){
213 return false;
214 }
215 }
216 else{
217 SetError(135,pInheritsClass->GetFullName().c_str(),nowLine);
218 return false;
219 }
220
221 if( inheritNames[i] == '\0' ){
222 break;
223 }
224 i++;
225 }
226
227 if( !isInheritsClass ){
228 // クラスを一つも継承していないとき
229 if( !InheritsClass( *compiler.GetObjectModule().meta.GetClasses().GetObjectClassPtr(), Types(), nowLine ) ){
230 return false;
231 }
232 }
233
234 return true;
235}
236bool CClass::InheritsClass( const CClass &inheritsClass, const Types &actualTypeParameters, int nowLine )
237{
238 //ループ継承でないかをチェック
239 if( !compiler.GetObjectModule().meta.GetClasses().LoopRefCheck(inheritsClass) )
240 {
241 SmoothieException::Throw(123,inheritsClass.GetName(),nowLine);
242 return false;
243 }
244
245 if( !inheritsClass.IsReady() ){
246 //継承先が読み取られていないとき
247 compiler.GetObjectModule().meta.GetClasses().LookaheadClass(inheritsClass.GetName().c_str());
248 }
249
250 //メソッドをコピー
251 BOOST_FOREACH( const CMethod *pBaseMethod, inheritsClass.GetDynamicMethods() ){
252 CMethod *pMethod = new DynamicMethod( *pBaseMethod );
253
254 // アクセシビリティ
255 if(pBaseMethod->GetAccessibility() == Prototype::Private){
256 pMethod->SetAccessibility( Prototype::None );
257 }
258 else{
259 pMethod->SetAccessibility( pBaseMethod->GetAccessibility() );
260 }
261
262 //pobj_Inherits
263 // ※継承元のClassIndexをセット(入れ子継承を考慮する)
264 if(pBaseMethod->GetInheritsClassPtr()==0){
265 pMethod->SetInheritsClassPtr( &inheritsClass );
266 }
267 else{
268 pMethod->SetInheritsClassPtr( pBaseMethod->GetInheritsClassPtr() );
269 }
270
271 GetDynamicMethods().push_back( pMethod );
272 }
273
274 //仮想関数の数
275 AddVtblNum( inheritsClass.GetVtblNum() );
276
277 //継承先のクラスをメンバとして保持する
278 SetSuperClass( &inheritsClass );
279 SetSuperClassActualTypeParameters( actualTypeParameters );
280
281 // インターフェイスを引き継ぐ
282 BOOST_FOREACH( ::Interface *pInterface, inheritsClass.GetInterfaces() )
283 {
284 interfaces.push_back( new ::Interface( *pInterface ) );
285 }
286
287 if( this->IsInterface() && inheritsClass.IsComInterface() )
288 {
289 // COMインターフェイスを継承した場合はCOMインターフェイスにする
290 this->SetClassType( CClass::ComInterface );
291 }
292
293 return true;
294}
295
296bool CClass::Implements( const CClass &interfaceClass, const Types &actualTypeParameters, int nowLine )
297{
298 if( !interfaceClass.IsInterface() && !interfaceClass.IsComInterface() )
299 {
300 // インターフェイスではないとき
301 SetError(138,interfaceClass.GetName().c_str(),nowLine );
302 return false;
303 }
304
305 if( !interfaceClass.IsReady() ){
306 // インターフェイスが未解析のとき
307 compiler.GetObjectModule().meta.GetClasses().LookaheadClass( interfaceClass.GetName().c_str() );
308 }
309
310 ::Interface *pDestInterface = new ::Interface( &interfaceClass, actualTypeParameters );
311
312 interfaces.push_back( pDestInterface );
313
314
315 /////////////////////////////////////////////////////////////////
316 // 基底クラスのメソッドからインターフェイスメソッドを再実装する
317 /////////////////////////////////////////////////////////////////
318 BOOST_FOREACH( CMethod *pMethod, GetDynamicMethods() )
319 {
320 CMethod *pMethodForOverride = pDestInterface->GetDynamicMethods().FindForOverride( pDestInterface->GetActualTypeParameters(), &pMethod->GetUserProc() );
321 if( pMethodForOverride )
322 {
323 pMethodForOverride->Override( &pMethod->GetUserProc(), pMethod->GetAccessibility(), false );
324
325 // 実装元になるメソッドは呼び出し不可にしておく(オーバーロードの解決から除外する)
326 pMethod->SetNotUseMark( true );
327 }
328 }
329
330
331 /////////////////////////////////////////////////////////////////
332 // キャストメソッドを追加(内部コードは自動生成すること)
333 /////////////////////////////////////////////////////////////////
334 if( interfaceClass.IsInterface() )
335 {
336 // Function Operator() As ITest
337
338 char temporary[1024];
339 sprintf(temporary,"%c%c%c%c()%c%c%s",
340 1, ESC_FUNCTION,
341 1, ESC_OPERATOR,
342 1, ESC_AS,
343 pDestInterface->GetFullNameWithActualGenericTypeParameters().c_str()
344 );
345
346 this->AddMethod(this,
347 Prototype::Public,
348 0,
349 false, // isConst
350 false, // isAbstract
351 false, // isVirtual
352 false, // isOverride
353 true, // isAutoGeneration
354 temporary,
355 -1
356 );
357 }
358
359
360 return true;
361}
362bool CClass::Implements( const char *interfaceNames, int nowLine )
363{
364 Jenga::Common::Strings paramStrs;
365 SplitParameter( interfaceNames, paramStrs );
366
367 BOOST_FOREACH( const std::string &paramStr, paramStrs )
368 {
369 char className[VN_SIZE];
370 Jenga::Common::Strings typeParameterStrings;
371 SplitGenericClassInstance( paramStr.c_str(), className, typeParameterStrings );
372
373 Types actualTypeParameters;
374 BOOST_FOREACH( const std::string &typeParameterStr, typeParameterStrings )
375 {
376 Type type;
377 compiler.StringToType( typeParameterStr, type );
378 actualTypeParameters.push_back( type );
379 }
380
381 //継承元クラスを取得
382 const CClass *pInterfaceClass = compiler.GetObjectModule().meta.GetClasses().Find( className );
383 if( !pInterfaceClass ){
384 SetError(106,paramStr.c_str(),nowLine);
385 continue;
386 }
387
388 // インターフェイスを継承する
389 Implements( *pInterfaceClass, actualTypeParameters, nowLine );
390 }
391
392 return true;
393}
394
395CMember *CClass::CreateMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine )
396{
397 extern int cp;
398
399 //構文を解析
400 char VarName[VN_SIZE];
401 char initBuffer[VN_SIZE];
402 char lpszConstructParameter[VN_SIZE];
403 Subscripts subscripts;
404 Type type;
405 GetDimentionFormat(buffer,VarName,subscripts,type,initBuffer,lpszConstructParameter);
406
407 //重複チェック
408 if(this->DupliCheckAll(VarName)){
409 SetError(15,VarName,cp);
410 }
411
412 CMember *pMember = new CMember( accessibility, VarName, type, isConst, subscripts, initBuffer, lpszConstructParameter );
413 pMember->source_code_address = nowLine;
414 return pMember;
415}
416void CClass::AddMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine ){
417 dynamicMembers.push_back(
418 CreateMember( accessibility, isConst, isRef, buffer, nowLine )
419 );
420}
421void CClass::AddStaticMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine ){
422 staticMembers.push_back(
423 CreateMember( accessibility, isConst, isRef, buffer, nowLine )
424 );
425}
426
427void CClass::AddMethod(CClass *pobj_c, Prototype::Accessibility accessibility, BOOL bStatic, bool isConst, bool isAbstract,
428 bool isVirtual, bool isOverride, bool isAutoGeneration, char *buffer, int nowLine){
429 int i,i2;
430 char temporary[VN_SIZE];
431
432 i=2;
433 for(i2=0;;i++,i2++){
434 if(buffer[i]=='('||buffer[i]=='\0'){
435 temporary[i2]=0;
436 break;
437 }
438 temporary[i2]=buffer[i];
439 }
440
441
442 //関数ハッシュへ登録
443 char interfaceName[VN_SIZE] = "";
444 UserProc *pUserProc = compiler.GetObjectModule().meta.GetUserProcs().AddUserProc( NamespaceScopes(), NamespaceScopesCollection(), buffer,nowLine,isVirtual,pobj_c, (bStatic!=0), interfaceName );
445 if(!pUserProc) return;
446
447 if( isAutoGeneration )
448 {
449 // コード自動生成
450 pUserProc->ThisIsAutoGenerationProc();
451 }
452
453
454 ////////////////////////////////////////////////////////////
455 // コンストラクタ、デストラクタの場合の処理
456 ////////////////////////////////////////////////////////////
457 BOOL fConstructor=0,bDestructor=0;
458
459 if(lstrcmp(temporary,pobj_c->GetName().c_str())==0){
460 //コンストラクタの場合
461
462 //標準コンストラクタ(引数なし)
463 if(pUserProc->Params().size()==0) fConstructor=1;
464
465 //強制的にConst修飾子をつける
466 isConst = true;
467 }
468 else if(temporary[0]=='~'){
469 //デストラクタの場合はその名前が正しいかチェックを行う
470 if(lstrcmp(temporary+1,pobj_c->GetName().c_str())!=0)
471 SetError(117,NULL,nowLine);
472 else
473 bDestructor=1;
474 }
475 if(fConstructor||bDestructor){
476 // コンストラクタ、デストラクタのアクセシビリティをチェック
477
478 //強制的にConst修飾子をつける
479 isConst = true;
480 }
481
482 if( fConstructor == 1 )
483 pobj_c->SetConstructorMemberSubIndex( (int)pobj_c->GetDynamicMethods().size() );
484 else if( bDestructor )
485 pobj_c->SetDestructorMemberSubIndex( (int)pobj_c->GetDynamicMethods().size() );
486
487
488
489 //////////////////
490 // 重複チェック
491 //////////////////
492
493 if(pobj_c->DupliCheckMember(temporary)){
494 SetError(15,temporary,nowLine);
495 return;
496 }
497
498 //メソッド
499 BOOST_FOREACH( const CMethod *pMethod, pobj_c->GetDynamicMethods() )
500 {
501 //基底クラスと重複する場合はオーバーライドを行う
502 if( pMethod->GetInheritsClassPtr() ) continue;
503
504 if( pMethod->GetUserProc().IsEqualForOverride( pobj_c->GetSuperClassActualTypeParameters(), pUserProc ) )
505 {
506 //関数名、パラメータ、戻り値が合致したとき
507 SetError(15,pUserProc->GetName().c_str(),nowLine);
508 return;
509 }
510 }
511
512 //仮想関数の場合
513 if( isAbstract ) pUserProc->CompleteCompile();
514
515 // メソッドのオーバーライド
516 CMethod *pMethodForOverride = pobj_c->GetDynamicMethods().FindForOverride( pobj_c->GetSuperClassActualTypeParameters(), pUserProc );
517 if( pMethodForOverride )
518 {
519 pMethodForOverride->Override( pUserProc, accessibility, isOverride );
520 pUserProc->SetMethod( pMethodForOverride );
521 return;
522 }
523 else
524 {
525 // インターフェイス メソッドのオーバーライド
526 BOOST_FOREACH( ::Interface *pInterface, pobj_c->GetInterfaces() )
527 {
528 if( interfaceName[0] )
529 {
530 if( pInterface->GetClass().GetName() != interfaceName )
531 {
532 // 指定されたインターフェイス名と整合しないとき
533 continue;
534 }
535 }
536
537 if( !pInterface->GetClass().IsReady() ){
538 // インターフェイスが未解析のとき
539 compiler.GetObjectModule().meta.GetClasses().LookaheadClass( pInterface->GetClass().GetName().c_str() );
540 }
541
542 CMethod *pMethodForOverride = pInterface->GetDynamicMethods().FindForOverride( pInterface->GetActualTypeParameters(), pUserProc );
543 if( pMethodForOverride )
544 {
545 pMethodForOverride->Override( pUserProc, accessibility, isOverride );
546 pUserProc->SetMethod( pMethodForOverride );
547 return;
548 }
549 }
550 }
551
552 if( interfaceName[0] )
553 {
554 SetError(139,interfaceName,nowLine);
555 }
556
557 if( isVirtual ){
558 pobj_c->AddVtblNum( 1 );
559 }
560
561 if( isOverride ){
562 SetError(12,"Override",nowLine);
563 }
564
565 if(bStatic){
566 pobj_c->GetStaticMethods().AddStatic( pUserProc, accessibility );
567 }
568 else{
569 pobj_c->GetDynamicMethods().Add(pUserProc, accessibility, isConst, isAbstract, isVirtual);
570 }
571}
572
573bool CClass::DupliCheckAll(const char *name) const
574{
575 //重複チェック
576
577 //メンバ
578 if(DupliCheckMember(name)) return 1;
579
580 //メソッド
581 BOOST_FOREACH( const CMethod *pMethod, GetDynamicMethods() ){
582 if( lstrcmp( name, pMethod->GetUserProc().GetName().c_str() ) == 0 ){
583 return 1;
584 }
585 }
586
587 return 0;
588}
589bool CClass::DupliCheckMember(const char *name) const
590{
591 //重複チェック
592
593 if( this->HasSuperClass() )
594 {
595 if( this->GetSuperClass().DupliCheckMember( name ) )
596 {
597 // 基底クラスで重複が発見された
598 return true;
599 }
600 }
601
602 // 動的メンバ
603 BOOST_FOREACH( CMember *pMember, dynamicMembers )
604 {
605 if( GetName() == pMember->GetName() )
606 {
607 return true;
608 }
609 }
610
611 // 静的メンバ
612 BOOST_FOREACH( CMember *pMember, staticMembers ){
613 if( GetName() == pMember->GetName() ){
614 return true;
615 }
616 }
617
618 return false;
619}
620
621const CMember *CClass::FindDynamicMember( const char *memberName ) const
622{
623 if( this->HasSuperClass() )
624 {
625 // 基底クラスで検索
626 const CMember *result = this->GetSuperClass().FindDynamicMember( memberName );
627 if( result )
628 {
629 return result;
630 }
631 }
632
633 BOOST_FOREACH( CMember *pMember, GetDynamicMembers() )
634 {
635 if( pMember->GetName() == memberName )
636 {
637 return pMember;
638 }
639 }
640 return NULL;
641}
642
643void CClass::EnumDynamicMethodsOrInterfaceMethods( const char *methodName, std::vector<const UserProc *> &subs ) const
644{
645 // 動的メソッド
646 GetDynamicMethods().Enum( methodName, subs );
647
648 // インターフェイス メソッド
649 BOOST_FOREACH( ::Interface *pInterface, GetInterfaces() )
650 {
651 pInterface->GetDynamicMethods().Enum( methodName, subs );
652 }
653}
654const CMethod *CClass::GetDynamicMethodOrInterfaceMethod( const UserProc *pUserProc ) const
655{
656 // 動的メソッド
657 const CMethod *result = GetDynamicMethods().GetMethodPtr( pUserProc );
658
659 if( !result )
660 {
661 // インターフェイス メソッド
662 BOOST_FOREACH( ::Interface *pInterface, GetInterfaces() )
663 {
664 result = pInterface->GetDynamicMethods().GetMethodPtr( pUserProc );
665 if( result )
666 {
667 return result;
668 }
669 }
670 }
671
672 return result;
673}
674
675const ::Delegate &CClass::GetDelegate() const
676{
677 const ::Delegate *dg = compiler.GetObjectModule().meta.GetDelegates().GetHashArrayElement( GetName().c_str() );
678 while( dg )
679 {
680 if( dg->IsEqualSymbol( GetNamespaceScopes(), GetName() ) ){
681 //名前空間とクラス名が一致した
682 return *dg;
683 }
684 dg = dg->GetChainNext();
685 }
686
687 Jenga::Throw( "CClass::GetDelegateメソッドに失敗" );
688 static ::Delegate dummy;
689 return dummy;
690}
691
692//サイズを取得
693int CClass::GetSize() const
694{
695 int resultSize = 0;
696
697 int alignment = 1;
698 if( this->IsStructure() )
699 {
700 // 構造体のとき
701
702 if( this->GetFixedAlignment() )
703 {
704 // アラインメントの固定値が指定されていた場合はそれを取得
705 alignment = this->GetFixedAlignment();
706 }
707 }
708 else
709 {
710 // それ以外
711
712 if( this->HasSuperClass() )
713 {
714 // 基底クラスのサイズを追加
715 resultSize += this->GetSuperClass().GetSize();
716
717 // 基底クラスのアラインメントを取得
718 alignment = this->GetSuperClass().GetAlignment();
719 }
720 else
721 {
722 // 基底クラスが存在しないとき
723
724 // 仮想関数が存在する場合はvtbl及びvtblMasterListへのポインタのサイズを追加
725 resultSize += IsExistVirtualFunctions() ? PTR_SIZE*2 : 0;
726 }
727 }
728
729 BOOST_FOREACH( CMember *pMember, dynamicMembers )
730 {
731 // メンバサイズ
732 int tempMemberSize = pMember->GetType().GetSize();
733
734 // 一時アラインメントを算出
735 int tempAlignment = tempMemberSize;
736 if( pMember->GetType().IsStruct() )
737 {
738 // メンバが構造体の場合は、メンバのアラインメントを取得
739 tempAlignment = pMember->GetType().GetClass().GetAlignment();
740 }
741
742 // アラインメントを考慮してパディングを追加
743 if( GetFixedAlignment() && alignment < tempAlignment )
744 {
745 if( resultSize % alignment )
746 {
747 resultSize += alignment - ( resultSize % alignment );
748 }
749 }
750 else
751 {
752 if( alignment < tempAlignment )
753 {
754 // 最大アラインメントを更新
755 alignment = tempAlignment;
756 }
757
758 if( tempMemberSize == 0 )
759 {
760 if( !pMember->GetType().IsStruct() )
761 {
762 SetError();
763 }
764
765 //メンバを持たない構造体
766 //※何もしない(オフセットの計算をしない)
767 }
768 else{
769 if( resultSize % tempAlignment )
770 {
771 resultSize += tempAlignment - ( resultSize % tempAlignment );
772 }
773 }
774 }
775
776 // メンバサイズを加算(配列を考慮)
777 resultSize += tempMemberSize * Variable::GetSubScriptCounts( pMember->GetSubscripts() );
778 }
779
780 if( alignment )
781 {
782 // 末尾アラインメントを考慮してパディングを追加
783 if( resultSize % alignment )
784 {
785 resultSize += alignment - ( resultSize % alignment );
786 }
787 }
788
789 return resultSize;
790}
791
792//メンバのオフセットを取得
793int CClass::GetMemberOffset( const char *memberName ) const
794{
795 int resultSize = 0;
796
797 int alignment = 1;
798 if( this->IsStructure() )
799 {
800 // 構造体のとき
801
802 if( this->GetFixedAlignment() )
803 {
804 // アラインメントの固定値が指定されていた場合はそれを取得
805 alignment = this->GetFixedAlignment();
806 }
807 }
808 else
809 {
810 // それ以外
811
812 if( this->HasSuperClass() )
813 {
814 if( this->GetSuperClass().HasDynamicMember( memberName ) )
815 {
816 // 基底クラスのメンバを取得
817 return this->GetSuperClass().GetMemberOffset( memberName );
818 }
819
820 // 基底クラスのサイズを追加
821 resultSize += this->GetSuperClass().GetSize();
822
823 // 基底クラスのアラインメントを取得
824 alignment = this->GetSuperClass().GetAlignment();
825 }
826 else
827 {
828 // 基底クラスが存在しないとき
829
830 // 仮想関数が存在する場合はvtbl及びvtblMasterListへのポインタのサイズを追加
831 resultSize += IsExistVirtualFunctions() ? PTR_SIZE*2 : 0;
832 }
833 }
834
835 BOOST_FOREACH( CMember *pMember, dynamicMembers )
836 {
837 // メンバサイズ
838 int tempMemberSize = pMember->GetType().GetSize();
839
840 // 一時アラインメントを算出
841 int tempAlignment = tempMemberSize;
842 if( pMember->GetType().IsStruct() )
843 {
844 // メンバが構造体の場合は、メンバのアラインメントを取得
845 tempAlignment = pMember->GetType().GetClass().GetAlignment();
846 }
847
848 // アラインメントを考慮してパディングを追加
849 if( GetFixedAlignment() && alignment < tempAlignment )
850 {
851 if( resultSize % alignment )
852 {
853 resultSize += alignment - ( resultSize % alignment );
854 }
855 }
856 else
857 {
858 if( alignment < tempAlignment )
859 {
860 // 最大アラインメントを更新
861 alignment = tempAlignment;
862 }
863
864 if( tempMemberSize == 0 )
865 {
866 if( !pMember->GetType().IsStruct() )
867 {
868 SetError();
869 }
870
871 //メンバを持たない構造体
872 //※何もしない(オフセットの計算をしない)
873 }
874 else{
875 if( resultSize % tempAlignment )
876 {
877 resultSize += tempAlignment - ( resultSize % tempAlignment );
878 }
879 }
880 }
881
882 if(memberName){
883 //メンバ指定がある場合は、オフセットを返す
884 if( pMember->GetName() == memberName )
885 {
886 return resultSize;
887 }
888 }
889
890 // メンバサイズを加算(配列を考慮)
891 resultSize += tempMemberSize * Variable::GetSubScriptCounts( pMember->GetSubscripts() );
892 }
893
894 if( alignment )
895 {
896 // 末尾アラインメントを考慮してパディングを追加
897 if( resultSize % alignment )
898 {
899 resultSize += alignment - ( resultSize % alignment );
900 }
901 }
902
903 return resultSize;
904}
905int CClass::GetAlignment() const
906{
907 int alignment = 1;
908 if( this->IsStructure() )
909 {
910 // 構造体のとき
911
912 if( this->GetFixedAlignment() )
913 {
914 // アラインメントの固定値が指定されていた場合はそれを取得
915 return this->GetFixedAlignment();
916 }
917 }
918 else
919 {
920 // それ以外
921
922 if( this->HasSuperClass() )
923 {
924 // 基底クラスのアラインメントを取得
925 alignment = this->GetSuperClass().GetAlignment();
926 }
927 else
928 {
929 // 基底クラスが存在しないとき
930
931 // 仮想関数が存在する場合はvtbl及びvtblMasterListへのポインタのサイズを追加
932 alignment = PTR_SIZE;
933 }
934 }
935
936 BOOST_FOREACH( CMember *pMember, dynamicMembers )
937 {
938 int tempAlignment = pMember->GetType().GetSize();
939 if( pMember->GetType().IsStruct() )
940 {
941 // メンバが構造体の場合は、メンバのアラインメントを取得
942 tempAlignment = pMember->GetType().GetClass().GetAlignment();
943 }
944
945 if( alignment < tempAlignment )
946 {
947 // 最大アラインメントを更新
948 alignment = tempAlignment;
949 }
950 }
951
952 return alignment;
953}
954
955void CClass::GetVtblMasterListIndexAndVtblIndex( const UserProc *pUserProc, int &vtblMasterListIndex, int &vtblIndex ) const
956{
957 vtblMasterListIndex = 0;
958
959 vtblIndex = 0;
960 BOOST_FOREACH( const CMethod *pMethod, GetDynamicMethods() ){
961 if( &pMethod->GetUserProc() == pUserProc )
962 {
963 return;
964 }
965
966 if( pMethod->IsVirtual() )
967 {
968 vtblIndex++;
969 }
970 }
971
972 BOOST_FOREACH( const ::Interface *pInterface, interfaces )
973 {
974 vtblMasterListIndex++;
975
976 vtblIndex = 0;
977 BOOST_FOREACH( const CMethod *pMethod, pInterface->GetDynamicMethods() ){
978 if( &pMethod->GetUserProc() == pUserProc )
979 {
980 return;
981 }
982
983 if( pMethod->IsVirtual() )
984 {
985 vtblIndex++;
986 }
987 }
988 }
989
990 SetError();
991 return;
992}
993int CClass::GetVtblMasterListIndex( const CClass *pClass ) const
994{
995 int result = 0;
996
997 BOOST_FOREACH( const ::Interface *pInterface, interfaces )
998 {
999 result++;
1000
1001 if( &pInterface->GetClass() == pClass )
1002 {
1003 return result;
1004 }
1005 }
1006
1007 SetError();
1008 return 0;
1009}
1010long CClass::GetComVtblOffset() const
1011{
1012 return comVtblOffset;
1013}
1014long CClass::GetVtblMasterListOffset() const
1015{
1016 //既に存在する場合はそれを返す
1017 if( vtblMasterListOffset == -1 )
1018 {
1019 SetError();
1020 }
1021
1022 return vtblMasterListOffset;
1023}
1024void CClass::GenerateVTableMasterList( const std::vector<long> &vtableMasterList, long &offset )
1025{
1026 offset = compiler.GetObjectModule().dataTable.AddBinary(
1027 (void *)&vtableMasterList[0],
1028 static_cast<int>(vtableMasterList.size()*sizeof(LONG_PTR))
1029 );
1030}
1031void CClass::GenerateFullVTables()
1032{
1033 if( IsAbstract() )
1034 {
1035 // 抽象クラスは無視
1036 return;
1037 }
1038 if( !IsUsing() )
1039 {
1040 // 使われていないクラスは無視
1041 return;
1042 }
1043
1044 // vtblマスターリストの元データに不要なデータが含まれていたらエラー
1045 if( vtblMasterList.size() )
1046 {
1047 SetError();
1048 }
1049
1050 // 自身のクラスのvtblを生成
1051 GetDynamicMethods().GenerateVTablePart( this->vtbl_offset );
1052 vtblMasterList.push_back( this->vtbl_offset );
1053
1054 // インターフェイスのvtblを生成
1055 BOOST_FOREACH( const ::Interface *pInterface, interfaces )
1056 {
1057 long tempVtblOffset;
1058 pInterface->GetDynamicMethods().GenerateVTablePart( tempVtblOffset );
1059 vtblMasterList.push_back( tempVtblOffset );
1060
1061 pInterface->SetVtblOffset( tempVtblOffset );
1062
1063 if( pInterface->GetClass().IsComInterface() )
1064 {
1065 if( this->comVtblOffset )
1066 {
1067 SetError();
1068 }
1069 this->comVtblOffset = tempVtblOffset;
1070 }
1071 }
1072
1073 // vtblマスターリストを生成
1074 GenerateVTableMasterList( vtblMasterList, this->vtblMasterListOffset );
1075}
1076void CClass::ActionVtblSchedule( LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection, LONG_PTR MemPos_DataSection )
1077{
1078 if( IsAbstract() )
1079 {
1080 // 抽象クラスは無視
1081 return;
1082 }
1083 if( !IsUsing() )
1084 {
1085 // 使われていないクラスは無視
1086 return;
1087 }
1088 if(vtbl_offset==-1) return;
1089
1090 // 自身のクラスのvtbl
1091 {
1092 LONG_PTR *pVtbl = (LONG_PTR *)((char *)compiler.GetObjectModule().dataTable.GetPtr() + vtbl_offset);
1093
1094 for( int i=0; i<GetVtblNum(); i++ ){
1095 const UserProc *pUserProc = (UserProc *)pVtbl[i];
1096 if(!pUserProc) continue;
1097
1098 if( pUserProc->GetBeginOpAddress() == 0
1099 && pUserProc->GetEndOpAddress() == 0 )
1100 {
1101 Jenga::Throw( "未解決の仮想関数が存在する" );
1102 }
1103
1104 pVtbl[i] = pUserProc->GetBeginOpAddress() + ImageBase + MemPos_CodeSection;
1105 }
1106 }
1107
1108 // インターフェイスのvtbl
1109 BOOST_FOREACH( const ::Interface *pInterface, interfaces )
1110 {
1111 LONG_PTR *pVtbl = (LONG_PTR *)((char *)compiler.GetObjectModule().dataTable.GetPtr() + pInterface->GetVtblOffset());
1112
1113 for( int i=0; i<pInterface->GetClass().GetVtblNum(); i++ ){
1114 const UserProc *pUserProc = (UserProc *)pVtbl[i];
1115 if(!pUserProc) continue;
1116
1117 if( pUserProc->GetBeginOpAddress() == 0
1118 && pUserProc->GetEndOpAddress() == 0 )
1119 {
1120 Jenga::Throw( "未解決の仮想関数が存在する" );
1121 }
1122
1123 pVtbl[i] = pUserProc->GetBeginOpAddress() + ImageBase + MemPos_CodeSection;
1124 }
1125 }
1126
1127 // vtblマスターリスト
1128 LONG_PTR *pVtblMasterList = (LONG_PTR *)((char *)compiler.GetObjectModule().dataTable.GetPtr() + vtblMasterListOffset );
1129 for( int i=0; i<static_cast<int>(vtblMasterList.size()); i++ )
1130 {
1131 pVtblMasterList[i] = vtblMasterList[i] + ImageBase + MemPos_DataSection;
1132 }
1133}
1134bool CClass::IsAbstract() const
1135{
1136 // 未実装(abstract)の仮想関数を持つ場合はtrueを返す
1137
1138 BOOST_FOREACH( const CMethod *pMethod, GetDynamicMethods() ){
1139 if(pMethod->IsVirtual()){
1140 if(pMethod->IsAbstract()){
1141 return true;
1142 }
1143 }
1144 }
1145
1146 // インターフェイスのvtbl
1147 BOOST_FOREACH( const ::Interface *pInterface, interfaces )
1148 {
1149 BOOST_FOREACH( const CMethod *pMethod, pInterface->GetDynamicMethods() ){
1150 if(pMethod->IsVirtual()){
1151 if(pMethod->IsAbstract()){
1152 return true;
1153 }
1154 }
1155 }
1156 }
1157
1158 return false;
1159}
1160
1161CClass *Classes::Create( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, const char *name){
1162 return new CClass(namespaceScopes, importedNamespaces, name);
1163}
1164bool Classes::Insert( CClass *pClass, int nowLine )
1165{
1166 /////////////////////////////////
1167 // ハッシュデータに追加
1168 /////////////////////////////////
1169
1170 if( !Put( pClass ) )
1171 {
1172 SetError(15,pClass->GetName(), nowLine);
1173 return false;
1174 }
1175 return true;
1176}
1177CClass *Classes::Add( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, const char *name,int nowLine){
1178 //////////////////////////////////////////////////////////////////////////
1179 // クラスを追加
1180 // ※名前のみを登録。その他の情報はSetClassメソッドで!
1181 //////////////////////////////////////////////////////////////////////////
1182
1183 CClass *pClass = Create(namespaceScopes, importedNamespaces, name);
1184
1185 if( !Insert( pClass, nowLine ) )
1186 {
1187 return NULL;
1188 }
1189
1190 return pClass;
1191}
1192
1193void Classes::GenerateVTables()
1194{
1195 Iterator_Reset();
1196 while( Iterator_HasNext() )
1197 {
1198 CClass *pClass = Iterator_GetNext();
1199 pClass->GenerateFullVTables();
1200 }
1201}
1202
1203void Classes::ActionVtblSchedule( LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection, LONG_PTR MemPos_DataSection ){
1204 Iterator_Reset();
1205 while( Iterator_HasNext() )
1206 {
1207 CClass *pClass = Iterator_GetNext();
1208 pClass->ActionVtblSchedule( ImageBase, MemPos_CodeSection, MemPos_DataSection);
1209 }
1210}
1211
1212
1213void Classes::InitStaticMember(){
1214 //静的メンバをグローバル領域に作成
1215
1216 //イテレータをリセット
1217
1218 extern int cp;
1219 int back_cp=cp;
1220
1221 this->Iterator_Reset();
1222 while(this->Iterator_HasNext()){
1223 CClass &objClass = *this->Iterator_GetNext();
1224 if( objClass.isTargetObjectModule == false )
1225 {
1226 // 静的リンクライブラリの場合は飛ばす(既にインスタンスが定義済みであるため)
1227 continue;
1228 }
1229
1230 // 名前空間をセット
1231 compiler.GetNamespaceSupporter().GetLivingNamespaceScopes() = objClass.GetNamespaceScopes();
1232
1233 DWORD dwFlags = 0;
1234 if( objClass.GetName() == "_System_TypeBase" )
1235 {
1236 // _System_TypeBaseクラスはグローバル、スタティック領域を初期化するためのクラスなのでここでの初期化は除外する
1237 dwFlags |= DIMFLAG_NONCALL_CONSTRACTOR;
1238 }
1239
1240 // コンパイル中クラスとしてセット
1241 compiler.pCompilingClass = &objClass;
1242
1243 const EnumInfo *pEnumInfo = NULL;
1244 if( objClass.IsEnum() )
1245 {
1246 pEnumInfo = compiler.enumInfoCollection.Find( objClass );
1247 }
1248
1249 int i=0;
1250 BOOST_FOREACH( CMember *member, objClass.GetStaticMembers() )
1251 {
1252 if( pEnumInfo )
1253 {
1254 cp = pEnumInfo->GetEnumMember( member->GetName() ).GetSourceIndex();
1255 }
1256
1257 char temporary[VN_SIZE];
1258 sprintf(temporary,"%s.%s",objClass.GetName().c_str(),member->GetName().c_str());
1259 dim(
1260 temporary,
1261 member->GetSubscripts(),
1262 member->GetType(),
1263 member->GetInitializeExpression().c_str(),
1264 member->GetConstructParameter().c_str(),
1265 dwFlags);
1266
1267 i++;
1268 }
1269
1270 compiler.pCompilingClass = NULL;
1271 }
1272
1273 compiler.GetNamespaceSupporter().GetLivingNamespaceScopes().clear();
1274
1275 cp=back_cp;
1276}
1277
1278void Classes::Compile_System_InitializeUserTypes(){
1279 char temporary[VN_SIZE];
1280
1281 ////////////////////////////////////////////////////////////////////
1282 // クラス登録
1283 ////////////////////////////////////////////////////////////////////
1284
1285 // イテレータをリセット
1286 Iterator_Reset();
1287
1288 while( Iterator_HasNext() ){
1289 const CClass &objClass = *Iterator_GetNext();
1290
1291 if( !objClass.IsUsing() ){
1292 // 未使用のクラスは無視する
1293 continue;
1294 }
1295
1296 std::string referenceOffsetsBuffer;
1297 int numOfReference = 0;
1298 objClass.GetReferenceOffsetsInitializeBuffer( referenceOffsetsBuffer, numOfReference );
1299
1300 sprintf( temporary
1301 , "Add(%c%c_System_TypeForClass[strNamespace=\"%s\",name=\"%s\",fullName=\"%s\",referenceOffsets=[%s],numOfReference=%d])"
1302 , 1
1303 , ESC_SYSTEM_STATIC_NEW
1304 , objClass.GetNamespaceScopes().ToString().c_str() // 名前空間
1305 , objClass.GetName().c_str() // クラス名
1306 , objClass.GetFullName().c_str() // フルネーム
1307 , referenceOffsetsBuffer.c_str() // 参照メンバオフセット配列
1308 , numOfReference // 参照メンバの個数
1309 );
1310
1311 // コンパイル
1312 ChangeOpcode( temporary );
1313
1314 objClass.SetTypeInfoDataTableOffset(
1315 compiler.GetObjectModule().dataTable.GetLastMadeConstObjectDataTableOffset()
1316 );
1317 }
1318}
1319void Classes::Compile_System_InitializeUserTypesForBaseType()
1320{
1321 extern int cp;
1322 cp = -1;
1323 ////////////////////////////////////////////////////////////////////
1324 // 基底クラスを登録
1325 ////////////////////////////////////////////////////////////////////
1326
1327 char temporary[8192];
1328 sprintf(temporary, "%c%ctempType=Nothing%c%cTypeBaseImpl"
1329 , HIBYTE( COM_DIM )
1330 , LOBYTE( COM_DIM )
1331 , 1
1332 , ESC_AS
1333 );
1334 ChangeOpcode( temporary );
1335
1336 // イテレータをリセット
1337 Iterator_Reset();
1338
1339 while( Iterator_HasNext() ){
1340 const CClass &objClass = *Iterator_GetNext();
1341
1342 if( !objClass.IsUsing() ){
1343 // 未使用のクラスは無視する
1344 continue;
1345 }
1346
1347 if( objClass.HasSuperClass() || objClass.GetDynamicMembers().size() ){
1348 sprintf( temporary
1349 , "tempType=Search(\"%s\")"
1350 , objClass.GetFullName().c_str()
1351 );
1352
1353 // コンパイル
1354 ChangeOpcode( temporary );
1355
1356 if( objClass.HasSuperClass() )
1357 {
1358 sprintf( temporary
1359 , "tempType.SetBaseType(Search(\"%s\"))"
1360 , objClass.GetSuperClass().GetFullName().c_str()
1361 );
1362
1363 // コンパイル
1364 ChangeOpcode( temporary );
1365 }
1366
1367 if( objClass.GetDynamicMembers().size() )
1368 {
1369 // メンバの型を示すTypeInfoオブジェクトへのDataOffset配列の静的データ定義文字列を取得
1370 sprintf(
1371 temporary,
1372 "tempType.SetMembers([%s],[%s],[%s],%d)",
1373 objClass.GetStaticDefiningStringAsMemberNames().c_str(),
1374 objClass.GetStaticDefiningStringAsMemberTypeInfoNames().c_str(),
1375 objClass.GetStaticDefiningStringAsMemberOffsets().c_str(),
1376 objClass.GetDynamicMembers().size()
1377 );
1378 ChangeOpcode( temporary );
1379 }
1380 }
1381 }
1382}
1383
1384const CClass *Classes::Find( const NamespaceScopes &namespaceScopes, const string &name ) const
1385{
1386 if( namespaceScopes.size() == 0 && name == "Object" ){
1387 return GetObjectClassPtr();
1388 }
1389 else if( namespaceScopes.size() == 0 && name == "String" ){
1390 return GetStringClassPtr();
1391 }
1392
1393 std::vector<const CClass *> classes;
1394 const CClass *pClass = GetHashArrayElement( name.c_str() );
1395 while( pClass )
1396 {
1397 if( pClass->IsEqualSymbol( namespaceScopes, name ) ){
1398 //名前空間とクラス名が一致した
1399 classes.push_back( pClass );
1400 }
1401 pClass = pClass->GetChainNext();
1402 }
1403 if( classes.size() > 0 )
1404 {
1405 // 複数の名前空間の中に同一のクラス名が存在する場合があるので、アクセス可能で尚且つ階層が一番深いものをチョイスする
1406 pClass = classes.front();
1407
1408 BOOST_FOREACH( const CClass *pTempClass, classes )
1409 {
1410 if( pClass->GetNamespaceScopes().size() < pTempClass->GetNamespaceScopes().size() )
1411 {
1412 pClass = pTempClass;
1413 }
1414 }
1415
1416 return pClass;
1417 }
1418
1419 // TypeDefも見る
1420 int index = compiler.GetObjectModule().meta.GetTypeDefs().GetIndex( namespaceScopes, name );
1421 if( index != -1 ){
1422 Type type = compiler.GetObjectModule().meta.GetTypeDefs()[index].GetBaseType();
1423 if( type.IsObject() ){
1424 return &type.GetClass();
1425 }
1426 }
1427
1428 return NULL;
1429}
1430const CClass *Classes::Find( const string &fullName ) const
1431{
1432 char AreaName[VN_SIZE] = ""; //オブジェクト変数
1433 char NestName[VN_SIZE] = ""; //入れ子メンバ
1434 bool isNest = SplitMemberName( fullName.c_str(), AreaName, NestName );
1435
1436 return Find( NamespaceScopes( AreaName ), NestName );
1437}
1438void Classes::StartCompile( const UserProc *pUserProc ){
1439 const CClass *pParentClass = pUserProc->GetParentClassPtr();
1440 if( pParentClass ){
1441 pParentClass->Using();
1442
1443 // 仮想関数になるメソッドに使用チェックをつける
1444 BOOST_FOREACH( const CMethod *pMethod, pParentClass->GetDynamicMethods() )
1445 {
1446 if( pMethod->IsVirtual() )
1447 {
1448 pMethod->GetUserProc().Using();
1449 }
1450 }
1451
1452 pCompilingMethod = pParentClass->GetDynamicMethodOrInterfaceMethod( pUserProc );
1453 if( !pCompilingMethod ){
1454 pCompilingMethod = pParentClass->GetStaticMethods().GetMethodPtr( pUserProc );
1455 if( !pCompilingMethod ){
1456 SmoothieException::Throw(300);
1457 }
1458 }
1459 }
1460 else{
1461 pCompilingMethod = NULL;
1462 }
1463}
1464
1465const CClass *Classes::GetStringClassPtr() const
1466{
1467 if( !pStringClass ){
1468 // キャッシュしておく
1469 pStringClass = this->Find( NamespaceScopes( "System" ), "String" );
1470
1471 if( !pStringClass )
1472 {
1473 SetError(400, "System.String", cp);
1474 static CClass dummy;
1475 return &dummy;
1476 }
1477 return pStringClass;
1478 }
1479 return pStringClass;
1480}
1481const CClass *Classes::GetObjectClassPtr() const
1482{
1483 if( !pObjectClass ){
1484 // キャッシュしておく
1485 pObjectClass = this->Find( NamespaceScopes( "System" ), "Object" );
1486
1487 if( !pObjectClass )
1488 {
1489 SetError(400, "System.Object", cp);
1490 static CClass dummy;
1491 return &dummy;
1492 }
1493 return pObjectClass;
1494 }
1495 return pObjectClass;
1496}
1497const CClass *Classes::GetInterfaceInfoClassPtr() const
1498{
1499 if( !pInterfaceInfo ){
1500 // キャッシュしておく
1501 pInterfaceInfo = this->Find( "ActiveBasic.Core.InterfaceInfo" );
1502
1503 if( !pInterfaceInfo )
1504 {
1505 SetError(400, "ActiveBasic.Core.InterfaceInfo", cp);
1506 static CClass dummy;
1507 return &dummy;
1508 }
1509 return pInterfaceInfo;
1510 }
1511 return pInterfaceInfo;
1512}
1513
1514std::string CClass::GetStaticDefiningStringAsMemberNames() const
1515{
1516 std::string result;
1517
1518 BOOST_FOREACH( const CMember *pMember, dynamicMembers )
1519 {
1520 if( result.size() )
1521 {
1522 result += ",";
1523 }
1524
1525 result += "\"" + pMember->GetName() + "\"";
1526 }
1527
1528 return result;
1529}
1530std::string CClass::GetStaticDefiningStringAsMemberTypeInfoNames() const
1531{
1532 std::string result;
1533
1534 BOOST_FOREACH( const CMember *pMember, dynamicMembers )
1535 {
1536 if( result.size() )
1537 {
1538 result += ",";
1539 }
1540
1541 result += "\"" + compiler.TypeToString( pMember->GetType() ) + "\"";
1542 }
1543
1544 return result;
1545}
1546std::string CClass::GetStaticDefiningStringAsMemberOffsets() const
1547{
1548 std::string result;
1549
1550 BOOST_FOREACH( const CMember *pMember, dynamicMembers )
1551 {
1552 if( result.size() )
1553 {
1554 result += ",";
1555 }
1556
1557 int offset = this->GetMemberOffset( pMember->GetName().c_str() );
1558
1559 char temporary[255];
1560 itoa( offset, temporary, 16 );
1561
1562 result += (std::string)"&H" + temporary;
1563 }
1564
1565 return result;
1566}
1567
1568void CClass::GetReferenceOffsetsInitializeBuffer( std::string &referenceOffsetsBuffer, int &numOfReference, int baseOffset ) const
1569{
1570 const CClass &thisClass = *this;
1571 BOOST_FOREACH( const CMember *pMember, thisClass.GetDynamicMembers() )
1572 {
1573 if( pMember->GetType().IsObject() || pMember->GetType().IsPointer() )
1574 {
1575 if( referenceOffsetsBuffer.size() )
1576 {
1577 referenceOffsetsBuffer += ",";
1578 }
1579
1580 char temp[255];
1581 sprintf( temp, "%d", baseOffset + thisClass.GetMemberOffset( pMember->GetName().c_str() ) );
1582 referenceOffsetsBuffer += temp;
1583
1584 numOfReference++;
1585 }
1586 if( pMember->GetType().IsStruct() && !pMember->GetType().IsPointer() )
1587 {
1588 // 構造体の実体をメンバに持つとき
1589 int baseOffset = thisClass.GetMemberOffset( pMember->GetName().c_str() );
1590
1591 // 構造体メンバでGCによるチェックが必要な参照位置を追加
1592 pMember->GetType().GetClass().GetReferenceOffsetsInitializeBuffer( referenceOffsetsBuffer, numOfReference, baseOffset );
1593 }
1594 }
1595}
Note: See TracBrowser for help on using the repository browser.