source: dev/trunk/ab5.0/abdev/BasicCompiler_Common/src/Class.cpp@ 445

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

_System_Newに対応(32bit版のみ)。

File size: 39.6 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%c_System_TypeForClass"
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\") As ActiveBasic.Core._System_TypeForClass"
1350 , objClass.GetFullName().c_str()
1351 );
1352
1353 // コンパイル
1354 MakeMiddleCode( temporary );
1355 ChangeOpcode( temporary );
1356
1357 sprintf( temporary
1358 , "tempType.SetClassInfo(%d,_System_GetComVtbl(%s),_System_GetVtblList(%s),_System_GetDefaultConstructor(%s),_System_GetDestructor(%s))"
1359 , objClass.GetSize()
1360 , objClass.GetFullName().c_str()
1361 , objClass.GetFullName().c_str()
1362 , objClass.GetFullName().c_str()
1363 , objClass.GetFullName().c_str()
1364 , objClass.GetName().c_str()
1365 );
1366
1367 // コンパイル
1368 ChangeOpcode( temporary );
1369
1370 if( objClass.HasSuperClass() )
1371 {
1372 sprintf( temporary
1373 , "tempType.SetBaseType(Search(\"%s\"))"
1374 , objClass.GetSuperClass().GetFullName().c_str()
1375 );
1376
1377 // コンパイル
1378 ChangeOpcode( temporary );
1379 }
1380
1381 if( objClass.GetDynamicMembers().size() )
1382 {
1383 // メンバの型を示すTypeInfoオブジェクトへのDataOffset配列の静的データ定義文字列を取得
1384 sprintf(
1385 temporary,
1386 "tempType.SetMembers([%s],[%s],[%s],%d)",
1387 objClass.GetStaticDefiningStringAsMemberNames().c_str(),
1388 objClass.GetStaticDefiningStringAsMemberTypeInfoNames().c_str(),
1389 objClass.GetStaticDefiningStringAsMemberOffsets().c_str(),
1390 objClass.GetDynamicMembers().size()
1391 );
1392 ChangeOpcode( temporary );
1393 }
1394 }
1395 }
1396}
1397
1398const CClass *Classes::Find( const NamespaceScopes &namespaceScopes, const string &name ) const
1399{
1400 if( namespaceScopes.size() == 0 && name == "Object" ){
1401 return GetObjectClassPtr();
1402 }
1403 else if( namespaceScopes.size() == 0 && name == "String" ){
1404 return GetStringClassPtr();
1405 }
1406
1407 std::vector<const CClass *> classes;
1408 const CClass *pClass = GetHashArrayElement( name.c_str() );
1409 while( pClass )
1410 {
1411 if( pClass->IsEqualSymbol( namespaceScopes, name ) ){
1412 //名前空間とクラス名が一致した
1413 classes.push_back( pClass );
1414 }
1415 pClass = pClass->GetChainNext();
1416 }
1417 if( classes.size() > 0 )
1418 {
1419 // 複数の名前空間の中に同一のクラス名が存在する場合があるので、アクセス可能で尚且つ階層が一番深いものをチョイスする
1420 pClass = classes.front();
1421
1422 BOOST_FOREACH( const CClass *pTempClass, classes )
1423 {
1424 if( pClass->GetNamespaceScopes().size() < pTempClass->GetNamespaceScopes().size() )
1425 {
1426 pClass = pTempClass;
1427 }
1428 }
1429
1430 return pClass;
1431 }
1432
1433 // TypeDefも見る
1434 int index = compiler.GetObjectModule().meta.GetTypeDefs().GetIndex( namespaceScopes, name );
1435 if( index != -1 ){
1436 Type type = compiler.GetObjectModule().meta.GetTypeDefs()[index].GetBaseType();
1437 if( type.IsObject() ){
1438 return &type.GetClass();
1439 }
1440 }
1441
1442 return NULL;
1443}
1444const CClass *Classes::Find( const string &fullName ) const
1445{
1446 char AreaName[VN_SIZE] = ""; //オブジェクト変数
1447 char NestName[VN_SIZE] = ""; //入れ子メンバ
1448 bool isNest = SplitMemberName( fullName.c_str(), AreaName, NestName );
1449
1450 return Find( NamespaceScopes( AreaName ), NestName );
1451}
1452void Classes::StartCompile( const UserProc *pUserProc ){
1453 const CClass *pParentClass = pUserProc->GetParentClassPtr();
1454 if( pParentClass ){
1455 pParentClass->Using();
1456
1457 // 仮想関数になるメソッドに使用チェックをつける
1458 BOOST_FOREACH( const CMethod *pMethod, pParentClass->GetDynamicMethods() )
1459 {
1460 if( pMethod->IsVirtual() )
1461 {
1462 pMethod->GetUserProc().Using();
1463 }
1464 }
1465
1466 pCompilingMethod = pParentClass->GetDynamicMethodOrInterfaceMethod( pUserProc );
1467 if( !pCompilingMethod ){
1468 pCompilingMethod = pParentClass->GetStaticMethods().GetMethodPtr( pUserProc );
1469 if( !pCompilingMethod ){
1470 SmoothieException::Throw(300);
1471 }
1472 }
1473 }
1474 else{
1475 pCompilingMethod = NULL;
1476 }
1477}
1478
1479const CClass *Classes::GetStringClassPtr() const
1480{
1481 if( !pStringClass ){
1482 // キャッシュしておく
1483 pStringClass = this->Find( NamespaceScopes( "System" ), "String" );
1484
1485 if( !pStringClass )
1486 {
1487 SetError(400, "System.String", cp);
1488 static CClass dummy;
1489 return &dummy;
1490 }
1491 return pStringClass;
1492 }
1493 return pStringClass;
1494}
1495const CClass *Classes::GetObjectClassPtr() const
1496{
1497 if( !pObjectClass ){
1498 // キャッシュしておく
1499 pObjectClass = this->Find( NamespaceScopes( "System" ), "Object" );
1500
1501 if( !pObjectClass )
1502 {
1503 SetError(400, "System.Object", cp);
1504 static CClass dummy;
1505 return &dummy;
1506 }
1507 return pObjectClass;
1508 }
1509 return pObjectClass;
1510}
1511const CClass *Classes::GetInterfaceInfoClassPtr() const
1512{
1513 if( !pInterfaceInfo ){
1514 // キャッシュしておく
1515 pInterfaceInfo = this->Find( "ActiveBasic.Core.InterfaceInfo" );
1516
1517 if( !pInterfaceInfo )
1518 {
1519 SetError(400, "ActiveBasic.Core.InterfaceInfo", cp);
1520 static CClass dummy;
1521 return &dummy;
1522 }
1523 return pInterfaceInfo;
1524 }
1525 return pInterfaceInfo;
1526}
1527
1528std::string CClass::GetStaticDefiningStringAsMemberNames() const
1529{
1530 std::string result;
1531
1532 BOOST_FOREACH( const CMember *pMember, dynamicMembers )
1533 {
1534 if( result.size() )
1535 {
1536 result += ",";
1537 }
1538
1539 result += "\"" + pMember->GetName() + "\"";
1540 }
1541
1542 return result;
1543}
1544std::string CClass::GetStaticDefiningStringAsMemberTypeInfoNames() const
1545{
1546 std::string result;
1547
1548 BOOST_FOREACH( const CMember *pMember, dynamicMembers )
1549 {
1550 if( result.size() )
1551 {
1552 result += ",";
1553 }
1554
1555 result += "\"" + compiler.TypeToString( pMember->GetType() ) + "\"";
1556 }
1557
1558 return result;
1559}
1560std::string CClass::GetStaticDefiningStringAsMemberOffsets() const
1561{
1562 std::string result;
1563
1564 BOOST_FOREACH( const CMember *pMember, dynamicMembers )
1565 {
1566 if( result.size() )
1567 {
1568 result += ",";
1569 }
1570
1571 int offset = this->GetMemberOffset( pMember->GetName().c_str() );
1572
1573 char temporary[255];
1574 itoa( offset, temporary, 16 );
1575
1576 result += (std::string)"&H" + temporary;
1577 }
1578
1579 return result;
1580}
1581
1582void CClass::GetReferenceOffsetsInitializeBuffer( std::string &referenceOffsetsBuffer, int &numOfReference, int baseOffset ) const
1583{
1584 const CClass &thisClass = *this;
1585 BOOST_FOREACH( const CMember *pMember, thisClass.GetDynamicMembers() )
1586 {
1587 if( pMember->GetType().IsObject() || pMember->GetType().IsPointer() )
1588 {
1589 if( referenceOffsetsBuffer.size() )
1590 {
1591 referenceOffsetsBuffer += ",";
1592 }
1593
1594 char temp[255];
1595 sprintf( temp, "%d", baseOffset + thisClass.GetMemberOffset( pMember->GetName().c_str() ) );
1596 referenceOffsetsBuffer += temp;
1597
1598 numOfReference++;
1599 }
1600 if( pMember->GetType().IsStruct() && !pMember->GetType().IsPointer() )
1601 {
1602 // 構造体の実体をメンバに持つとき
1603 int baseOffset = thisClass.GetMemberOffset( pMember->GetName().c_str() );
1604
1605 // 構造体メンバでGCによるチェックが必要な参照位置を追加
1606 pMember->GetType().GetClass().GetReferenceOffsetsInitializeBuffer( referenceOffsetsBuffer, numOfReference, baseOffset );
1607 }
1608 }
1609}
Note: See TracBrowser for help on using the repository browser.