source: dev/trunk/ab5.0/abdev/compiler_x86/Compile_Var.cpp@ 544

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

pCompilingMethodを排除。

File size: 35.4 KB
Line 
1#include "stdafx.h"
2
3#include <LexicalScope.h>
4#include <CodeGenerator.h>
5#include <Compiler.h>
6#include <Variable.h>
7
8#include "../BasicCompiler_Common/common.h"
9#include "Opcode.h"
10
11//変数
12// TODO: xml未完成
13int AllLocalVarSize;
14
15using namespace ActiveBasic::Compiler;
16
17void SetRelativeOffset( Type &resultType, RELATIVE_VAR *pRelativeVar,const char *lpPtrOffset){
18 PushLongVariable(pRelativeVar);
19
20 Type type;
21 NumOpe( lpPtrOffset, Type(), type );
22 ChangeTypeToLong( type.GetBasicType() );
23
24 //pop ebx
25 compiler.codeGenerator.op_pop(REG_EBX);
26
27 if( resultType.PtrLevel() ){
28 resultType.PtrLevelDown();
29
30 int typeSize = resultType.GetSize();
31 if(typeSize>=2){
32 //imul ebx,i2
33 compiler.codeGenerator.op_imul_RV( REG_EBX, typeSize );
34 }
35 }
36 else{
37 //エラー
38 compiler.errorMessenger.Output(1,NULL,cp);
39 return;
40 }
41
42 //pop ecx
43 compiler.codeGenerator.op_pop(REG_ECX);
44
45 //add ecx,ebx
46 compiler.codeGenerator.op_add_RR( REG_ECX, REG_EBX );
47}
48void SetRelativeOffset( RELATIVE_VAR &relativeVar ){
49 if(relativeVar.dwKind==VAR_DIRECTMEM){
50 //mov ecx,dword ptr[ecx]
51 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_ECX, REG_ECX, 0, MOD_BASE );
52 }
53 else{
54 //直接参照に切り替え
55 SetVarPtrToEax(&relativeVar);
56 relativeVar.dwKind=VAR_DIRECTMEM;
57
58 //mov ecx,dword ptr[eax]
59 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_ECX, REG_EAX, 0, MOD_BASE );
60 }
61}
62bool GetArrayOffset(const Subscripts &subscripts,char *array, const Type &type){
63 extern HANDLE hHeap;
64 int i,i2,i3,i4;
65 char temporary[VN_SIZE],*pParm[MAX_PARMS];
66
67 for(i=0,i2=0,i3=0;;i++,i2++){
68 if(array[i]=='('){
69 i4=GetStringInPare(temporary+i2,array+i);
70 i+=i4-1;
71 i2+=i4-1;
72 continue;
73 }
74 if(array[i]=='['){
75 i4=GetStringInBracket(temporary+i2,array+i);
76 i+=i4-1;
77 i2+=i4-1;
78 continue;
79 }
80 if(array[i]==','||array[i]=='\0'){
81 if( i3 >= (int)subscripts.size() )
82 {
83 for(i3--;i3>=0;i3--) HeapDefaultFree(pParm[i3]);
84 return 0;
85 }
86
87 temporary[i2]=0;
88
89 pParm[i3]=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1);
90 lstrcpy(pParm[i3],temporary);
91
92 i3++;
93
94 if(array[i]=='\0'){
95 if( i3 < (int)subscripts.size() )
96 {
97 for(i3--;i3>=0;i3--) HeapDefaultFree(pParm[i3]);
98 return 0;
99 }
100 break;
101 }
102
103 i2=-1;
104 continue;
105 }
106 temporary[i2]=array[i];
107 }
108
109 //push ecx
110 compiler.codeGenerator.op_push(REG_ECX);
111
112 //push 0
113 compiler.codeGenerator.op_push_V(0);
114
115 for(i=i3-1;i>=0;i--){
116 Type tempType;
117 bool isNeedHeapFreeStructure;
118 NumOpe( pParm[i], Type( DEF_LONG ), tempType, &isNeedHeapFreeStructure );
119 if( tempType.IsObject() )
120 {
121 //キャスト演算子のオーバーロードに対応する
122 CallCastOperatorProc(
123 tempType,
124 isNeedHeapFreeStructure, Type(DEF_LONG) );
125 tempType.SetBasicType( DEF_LONG );
126 }
127 ChangeTypeToLong( tempType.GetBasicType() );
128
129 //pop eax
130 compiler.codeGenerator.op_pop(REG_EAX);
131
132 for( i2=i+1, i4=1; i2<i3; i2++ )
133 {
134 i4*=subscripts[i2]+1;
135 }
136
137 //imul eax,i4
138 compiler.codeGenerator.op_imul_RV( REG_EAX, i4 );
139
140 //add dword ptr[esp],eax
141 compiler.codeGenerator.PutOld(
142 (char)0x01,
143 (char)0x04,
144 (char)0x24
145 );
146
147 HeapDefaultFree(pParm[i]);
148 }
149
150 //pop eax
151 compiler.codeGenerator.op_pop(REG_EAX);
152
153 //imul eax,TypeSize
154 compiler.codeGenerator.op_imul_RV( REG_EAX, type.GetSize() );
155
156 //pop ecx
157 compiler.codeGenerator.op_pop(REG_ECX);
158
159 //add ecx,eax
160 compiler.codeGenerator.op_add_RR( REG_ECX, REG_EAX );
161
162 return 1;
163}
164bool _member_offset(bool isErrorEnabled, bool isWriteAccess, const Type &classType, const char *member, RELATIVE_VAR *pRelativeVar, Type &resultType, BOOL bPrivateAccess)
165{
166 const CClass &objClass = classType.GetClass();
167
168 //////////////////////////////////////
169 // クラス、配列の構成要素を解析する
170 //////////////////////////////////////
171
172 char VarName[VN_SIZE]; //変数名
173 char array[VN_SIZE]; //第1次配列
174 char lpPtrOffset[VN_SIZE]; //第2次配列
175 char NestMember[VN_SIZE]; //入れ子メンバ
176 ReferenceKind refType;
177 lstrcpy(VarName,member);
178 if(!GetVarFormatString(VarName,array,lpPtrOffset,NestMember,refType)) return false;
179
180
181 ////////////////////////////
182 // メンバオフセットを取得
183 ////////////////////////////
184
185 const CMember *pMember = objClass.FindDynamicMember( VarName );
186 if( !pMember )
187 {
188 if(isErrorEnabled) compiler.errorMessenger.Output(103,VarName,cp);
189 return false;
190 }
191
192 int offset = objClass.GetMemberOffset( VarName );
193
194
195 //アクセシビリティをチェック
196 if( compiler.IsCompilingClass() && &objClass == &compiler.GetCompilingClass() ){
197 //同一クラスオブジェクトの場合はプライベートアクセスを容認する
198 if(pMember->IsNoneAccess()){
199 if(isErrorEnabled) compiler.errorMessenger.Output(107,VarName,cp);
200 return false;
201 }
202 }
203 else{
204 if((bPrivateAccess==0&&pMember->IsPrivate())||
205 pMember->IsNoneAccess()){
206 if(isErrorEnabled) compiler.errorMessenger.Output(107,VarName,cp);
207 return false;
208 }
209 else if(bPrivateAccess==0&&pMember->IsProtected()){
210 if(isErrorEnabled) compiler.errorMessenger.Output(108,VarName,cp);
211 return false;
212 }
213 }
214
215 //Const定義の場合は書き込みアクセスを制限する
216 //※コンストラクタをコンパイル中の場合は例外的に許可する
217 if( pMember->IsConst() && //定数メンバである
218 isWriteAccess && //書き込みアクセスを要求されている
219 objClass.IsCompilingConstructor() == false //コンストラクタ コンパイル中を除く
220 ){
221 //Const定義の変数に書き込みアクセスをしようとした場合
222 compiler.errorMessenger.Output(61,VarName,cp);
223 }
224
225 resultType = pMember->GetType();
226
227 // 型パラメータを解決
228 ResolveFormalGenericTypeParameter( resultType, classType );
229
230
231 //ポインタ変数の場合
232 if( resultType.IsPointer() ){
233 if( pMember->GetSubscripts().size() == 0 ){
234 lstrcpy(lpPtrOffset,array);
235 array[0]=0;
236 }
237 }
238 else{
239 if(lpPtrOffset[0]){
240 if(isErrorEnabled) compiler.errorMessenger.Output(16,member,cp);
241 return false;
242 }
243 }
244
245 if(offset){
246 //add ecx,offset
247 compiler.codeGenerator.op_add_RV( REG_ECX, offset );
248 }
249
250 if(array[0]){
251 //配列オフセット
252 if(!GetArrayOffset(pMember->GetSubscripts(),array,pMember->GetType())){
253 if(isErrorEnabled) compiler.errorMessenger.Output(14,member,cp);
254 return false;
255 }
256 }
257 else if( pMember->GetSubscripts().size() > 0 ){
258 resultType.SetBasicType( resultType.GetBasicType() | FLAG_PTR );
259 }
260
261 if(NestMember[0]){
262 //入れ子構造の場合
263
264 if( resultType.IsObject() || resultType.IsStruct() ){
265 if( refType != RefDot ){
266 if(isErrorEnabled) compiler.errorMessenger.Output(104,member,cp);
267 return false;
268 }
269
270 if( resultType.IsObject() ){
271 // 参照内容へのポインタを抽出
272 SetRelativeOffset( *pRelativeVar );
273 }
274 }
275 else if( resultType.IsObjectPtr() || resultType.IsStructPtr() ){
276 //構造体ポインタ型メンバ変数
277
278 if(lpPtrOffset[0]){
279 //pObj[n].member
280 if( ( resultType.IsObjectPtr() || resultType.IsStructPtr() )
281 && refType != RefDot ){
282 if(isErrorEnabled) compiler.errorMessenger.Output(104,member,cp);
283 return false;
284 }
285
286 //直接参照に切り替え
287 SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset);
288 pRelativeVar->dwKind=VAR_DIRECTMEM;
289
290 lpPtrOffset[0]=0;
291 }
292 else{
293 //pObj->member
294 if( ( resultType.IsObjectPtr() || resultType.IsStructPtr() )
295 && refType != RefPointer ){
296 if(isErrorEnabled) compiler.errorMessenger.Output(104,member,cp);
297 return false;
298 }
299
300 SetRelativeOffset( *pRelativeVar );
301 }
302 }
303 else if( resultType.GetBasicType() == MAKE_PTR_TYPE(DEF_OBJECT,2)
304 || resultType.GetBasicType() == MAKE_PTR_TYPE(DEF_STRUCT,2)){
305 //構造体ポインタのポインタ型メンバ変数
306
307 if(lpPtrOffset[0]){
308 //ppObj[n]->member
309 if( refType != RefPointer ){
310 if(isErrorEnabled) compiler.errorMessenger.Output(104,member,cp);
311 return false;
312 }
313
314 //直接参照に切り替え
315 SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset);
316 pRelativeVar->dwKind=VAR_DIRECTMEM;
317
318 lpPtrOffset[0]=0;
319
320 //mov ecx,dword ptr[ecx]
321 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_ECX, REG_ECX, 0, MOD_BASE );
322 }
323 else{
324 if(isErrorEnabled) compiler.errorMessenger.Output(104,member,cp);
325 return false;
326 }
327 }
328
329 if(!_member_offset(
330 isErrorEnabled,
331 isWriteAccess,
332 pMember->GetType(),
333 NestMember,
334 pRelativeVar,
335 resultType,
336 0)) return false;
337 }
338
339 if(lpPtrOffset[0]){
340 SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset);
341 pRelativeVar->dwKind=VAR_DIRECTMEM;
342 }
343
344 return true;
345}
346
347int LocalVar_ThisPtrOffset;
348void SetThisPtrToReg(int reg){
349 //自身のオブジェクトのThisポインタをregにコピー
350
351 RELATIVE_VAR RelativeVar;
352 RelativeVar.dwKind=VAR_LOCAL;
353 RelativeVar.bOffsetOffset=0;
354 RelativeVar.offset=-LocalVar_ThisPtrOffset;
355
356 SetReg_WholeVariable(Type(DEF_PTR_VOID),&RelativeVar,reg);
357}
358
359bool GetVarOffset(bool isErrorEnabled,bool isWriteAccess,const char *NameBuffer,RELATIVE_VAR *pRelativeVar,Type &resultType, Subscripts *pResultSubscripts ){
360 char variable[VN_SIZE];
361
362 if(NameBuffer[0]=='.'){
363 GetWithName(variable);
364 lstrcat(variable,NameBuffer);
365 }
366 else lstrcpy(variable,NameBuffer);
367
368 // 名前空間を分離
369 char namespaceStr[VN_SIZE]="", simpleName[VN_SIZE];
370 compiler.GetObjectModule().meta.GetNamespaces().SplitNamespace( variable, namespaceStr, simpleName );
371
372 // 先頭オブジェクトまたはクラス名と入れ子メンバに分割
373 ReferenceKind refType;
374 char member[VN_SIZE],array[VN_SIZE],lpPtrOffset[VN_SIZE];
375 GetVarFormatString(simpleName,array,lpPtrOffset,member,refType);
376
377 // 名前空間を分離していた場合は結合
378 char VarName[VN_SIZE];
379 if( namespaceStr[0] ){
380 sprintf( VarName, "%s.%s", namespaceStr, simpleName );
381 }
382 else{
383 lstrcpy( VarName, simpleName );
384 }
385
386 const Subscripts *pSubscripts;
387 bool bConst = false;
388
389
390 if( compiler.IsLocalAreaCompiling() ){
391 //////////////////
392 // ローカル変数
393 //////////////////
394
395 const Variable *pVar = compiler.GetCompilingUserProc().GetLocalVars().BackSearch( LexicalAnalyzer::FullNameToSymbol( VarName ) );
396 if( pVar ){
397 //ポインタ変数の場合
398 if( pVar->GetType().IsPointer() ){
399 if( !pVar->IsArray() ){
400 lstrcpy(lpPtrOffset,array);
401 array[0]=0;
402 }
403 }
404 else{
405 if(lpPtrOffset[0]){
406 compiler.errorMessenger.Output(16,variable,cp);
407 pRelativeVar->dwKind=NON_VAR;
408 return false;
409 }
410 }
411
412 pRelativeVar->offset=-pVar->GetOffsetAddress();
413 pRelativeVar->bOffsetOffset=0;
414 if( pVar->IsRef() ){
415 // 参照型
416 pRelativeVar->dwKind = VAR_REFLOCAL;
417 }
418 else pRelativeVar->dwKind=VAR_LOCAL;
419 resultType = pVar->GetType();
420 pSubscripts = &pVar->GetSubscripts();
421 bConst = pVar->IsConst();
422
423
424 /////////////////////////////////////////////////////////
425 // ☆★☆ ジェネリクスサポート ☆★☆
426
427 if( resultType.IsTypeParameter() )
428 {
429 // 型パラメータだったとき
430
431 int ptrLevel = PTR_LEVEL( resultType.GetBasicType() );
432
433 // 制約クラス(指定されていないときはObjectクラス)にセットする
434 resultType.SetBasicType( DEF_OBJECT );
435
436 for( int i=0; i<ptrLevel; i++ )
437 {
438 resultType.PtrLevelUp();
439 }
440 }
441
442 //
443 /////////////////////////////////////////////////////////
444
445 goto ok;
446 }
447 }
448
449 if( compiler.IsCompilingClass() ){
450 //////////////////////
451 // クラスメンバの参照
452 //////////////////////
453
454 if(lstrcmpi(variable,"This")==0){
455 //Thisオブジェクト
456
457 //Thisポインタをecxにコピー
458 SetThisPtrToReg(REG_ECX);
459
460 pRelativeVar->dwKind=VAR_DIRECTMEM;
461
462 resultType.SetType( DEF_OBJECT, &compiler.GetCompilingClass() );
463 return true;
464 }
465
466 if(memicmp(variable,"This.",5)==0){
467 //Thisオブジェクトのメンバを参照するとき
468 SlideString(variable+5,-5);
469 lstrcpy(VarName,variable);
470 }
471 else{
472 //クラス内の動的メンバを参照するとき(通常)
473
474 if( !compiler.GetCompilingClass().HasDynamicMember( VarName ) )
475 {
476 goto NonClassMember;
477 }
478 }
479
480 //Const修飾子のメソッド内でメンバ書き込みアクセスが発生したとき
481 //(コンストラクタ、デストラクタ内を除く)
482 const CMethod *pMethod = &compiler.GetCompilingUserProc().GetMethod();
483 if( isWriteAccess &&
484 pMethod->IsConst() &&
485 compiler.GetCompilingClass().IsCompilingConstructor() == false &&
486 compiler.GetCompilingClass().IsCompilingDestructor() == false
487 ){
488 compiler.errorMessenger.Output(131, NULL, cp );
489 }
490
491 /////////////////////////////
492 // thisポインタをecxにセット
493
494 //Thisポインタをecxにコピー
495 SetThisPtrToReg(REG_ECX);
496
497 pRelativeVar->dwKind=VAR_DIRECTMEM;
498 if(!_member_offset(
499 isErrorEnabled,
500 isWriteAccess,
501 Type( DEF_OBJECT, compiler.GetCompilingClass() ),
502 variable,
503 pRelativeVar,
504 resultType,1)) return false;
505 return true;
506 }
507
508NonClassMember:
509
510 {
511 const Variable *pVar;
512
513 //////////////////////////
514 // 静的ローカル変数
515 // ※"Static.Object.Method.Variable"
516 //////////////////////////
517
518 char temporary[VN_SIZE];
519 if( compiler.IsLocalAreaCompiling() ){
520 GetNowStaticVarFullName(VarName,temporary);
521
522 pVar = compiler.GetObjectModule().meta.GetGlobalVars().Find( LexicalAnalyzer::FullNameToSymbol( temporary ) );
523 if( pVar ){
524 goto GlobalOk;
525 }
526 }
527
528
529 //////////////////////////
530 // クラスの静的メンバ
531 //////////////////////////
532
533 if(member[0]){
534 lstrcpy(temporary,member);
535
536 // TODO: 名前空間を考慮したコードになっていない
537
538 char tempMember[VN_SIZE];
539 char tempArray[VN_SIZE];
540 {
541 ReferenceKind refType;
542 GetVarFormatString(temporary,tempArray,lpPtrOffset,tempMember, refType );
543 }
544
545 int typeDefIndex = compiler.GetObjectModule().meta.GetTypeDefs().GetIndex( VarName );
546 if( typeDefIndex != -1 ){
547 // TypeDef後の型名だったとき
548 lstrcpy( VarName, compiler.GetObjectModule().meta.GetTypeDefs()[typeDefIndex].GetBaseName().c_str() );
549 }
550
551 char temp2[VN_SIZE];
552 sprintf(temp2,"%s.%s",VarName,temporary);
553 pVar = compiler.GetObjectModule().meta.GetGlobalVars().Find( LexicalAnalyzer::FullNameToSymbol( temp2 ) );
554 if( pVar ){
555 lstrcpy(member,tempMember);
556 lstrcpy(array,tempArray);
557 goto GlobalOk;
558 }
559 }
560
561 if( compiler.IsCompilingClass() ){
562 //自身のクラスから静的メンバを参照する場合
563 char temp2[VN_SIZE];
564 sprintf(temp2,"%s.%s",compiler.GetCompilingClass().GetName().c_str(),VarName);
565 pVar = compiler.GetObjectModule().meta.GetGlobalVars().Find( LexicalAnalyzer::FullNameToSymbol( temp2 ) );
566 if( pVar ){
567 goto GlobalOk;
568 }
569 }
570
571 /////////////////////
572 // グローバル変数
573 /////////////////////
574
575 pVar = compiler.GetObjectModule().meta.GetGlobalVars().BackSearch( LexicalAnalyzer::FullNameToSymbol( VarName ) );
576 if( pVar ){
577 goto GlobalOk;
578 }
579
580 if(isErrorEnabled) compiler.errorMessenger.Output(3,variable,cp);
581 pRelativeVar->dwKind=NON_VAR;
582 return false;
583
584
585
586GlobalOk:
587 //ポインタ変数の場合
588 if( pVar->GetType().IsPointer() ){
589 if( !pVar->IsArray() ){
590 lstrcpy(lpPtrOffset,array);
591 array[0]=0;
592 }
593 }
594 else{
595 if(lpPtrOffset[0]){
596 compiler.errorMessenger.Output(16,variable,cp);
597 pRelativeVar->dwKind=NON_VAR;
598 return false;
599 }
600 }
601
602 pRelativeVar->offset=pVar->GetOffsetAddress();
603 pRelativeVar->bOffsetOffset=0;
604 if( pVar->IsRef() ){
605 // 参照型
606 pRelativeVar->dwKind = VAR_REFGLOBAL;
607 }
608 else pRelativeVar->dwKind=VAR_GLOBAL;
609 resultType = pVar->GetType();
610 pSubscripts=&pVar->GetSubscripts();
611 bConst = pVar->IsConst();
612 }
613
614
615
616ok:
617
618 if( bConst && isWriteAccess ){
619 //Const定義の変数に書き込みアクセスをしようとした場合
620 if( resultType.IsObject() ){
621 //オブジェクト定数
622 compiler.errorMessenger.Output(130, VarName, cp );
623 }
624 else{
625 //一般のConst変数
626 compiler.errorMessenger.Output(61,VarName,cp);
627 }
628 }
629
630 if( array[0] == 0 && pSubscripts->size() > 0 ){
631 //配列の先頭ポインタを示す場合
632 resultType.SetBasicType( resultType.GetBasicType() | FLAG_PTR );
633
634 if( pResultSubscripts )
635 {
636 (*pResultSubscripts) = *pSubscripts;
637 }
638 return true;
639 }
640
641 if(array[0]||member[0]){
642 //xor ecx,ecx(ecxを0に初期化する)
643 //※ecxは変数ベースアドレスからの相対オフセットを示す
644 compiler.codeGenerator.op_zero_reg(REG_ECX);
645
646 pRelativeVar->bOffsetOffset=1;
647 }
648 if(array[0]){
649 if(!GetArrayOffset(*pSubscripts,array,resultType)){
650 compiler.errorMessenger.Output(14,variable,cp);
651 pRelativeVar->dwKind=NON_VAR;
652 return false;
653 }
654 }
655 if(member[0]){
656 if( resultType.IsObject() || resultType.IsStruct() ){
657 //実態オブジェクトのメンバを参照(obj.member)
658 if( refType != RefDot ){
659 compiler.errorMessenger.Output(104,VarName,cp);
660 pRelativeVar->dwKind=NON_VAR;
661 return false;
662 }
663
664 if( resultType.IsObject() ){
665 // 参照内容へのポインタを抽出
666 SetRelativeOffset( *pRelativeVar );
667 }
668 }
669 else if( resultType.IsObjectPtr() || resultType.IsStructPtr() ){
670 //ポインタオブジェクトが示すメンバを参照
671 if(lpPtrOffset[0]){
672 //pObj[n].member
673 if( refType != RefDot ){
674 compiler.errorMessenger.Output(104,VarName,cp);
675 pRelativeVar->dwKind=NON_VAR;
676 return false;
677 }
678 SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset);
679 pRelativeVar->dwKind=VAR_DIRECTMEM;
680 }
681 else{
682 //pObj->member
683 if( refType != RefPointer ){
684 compiler.errorMessenger.Output(104,VarName,cp);
685 pRelativeVar->dwKind=NON_VAR;
686 return false;
687 }
688
689 SetVarPtrToEax(pRelativeVar);
690 pRelativeVar->dwKind=VAR_DIRECTMEM;
691
692 //mov ecx,dword ptr[eax]
693 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_ECX, REG_EAX, 0, MOD_BASE );
694 }
695 }
696 else if( resultType.GetBasicType()==MAKE_PTR_TYPE(DEF_OBJECT,2) || resultType.GetBasicType()==MAKE_PTR_TYPE(DEF_STRUCT,2)){
697 //ポインタオブジェクトが示すメンバを参照
698 if(lpPtrOffset[0]){
699 //ppObj[n]->member
700 if( refType != RefPointer ){
701 compiler.errorMessenger.Output(104,VarName,cp);
702 pRelativeVar->dwKind=NON_VAR;
703 return false;
704 }
705
706 SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset);
707 pRelativeVar->dwKind=VAR_DIRECTMEM;
708
709
710 SetVarPtrToEax(pRelativeVar);
711
712 //mov ecx,dword ptr[eax]
713 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_ECX, REG_EAX, 0, MOD_BASE );
714 }
715 else{
716 compiler.errorMessenger.Output(104,VarName,cp);
717 pRelativeVar->dwKind=NON_VAR;
718 return false;
719 }
720 }
721 else{
722 compiler.errorMessenger.Output(102,VarName,cp);
723 pRelativeVar->dwKind=NON_VAR;
724 return false;
725 }
726
727 Type classType( resultType );
728
729 if(!_member_offset(
730 isErrorEnabled,
731 isWriteAccess,
732 classType,
733 member,pRelativeVar,resultType,0)) return false;
734
735 return true;
736 }
737
738 if(lpPtrOffset[0]){
739 SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset);
740 pRelativeVar->dwKind=VAR_DIRECTMEM;
741 }
742
743 return true;
744}
745
746bool SetInitGlobalData(int offset,const Type &type,const Subscripts &subscripts,const char *lpszInitBuf){
747 int i2,i3;
748 char temporary[VN_SIZE];
749 char InitBuf[VN_SIZE];
750 lstrcpy( InitBuf, lpszInitBuf );
751
752 if(InitBuf[0]=='['){
753 SlideString(InitBuf+1,-1);
754 InitBuf[lstrlen(InitBuf)-1]=0;
755
756 int typeSize = type.GetSize();
757
758 if( subscripts.size() > 0 ){
759 Subscripts nestSubscripts;
760 for( int i=1; i<(int)subscripts.size(); i++ )
761 {
762 nestSubscripts.push_back( subscripts[i] );
763 }
764
765 typeSize*=JumpSubScripts( nestSubscripts );
766 {
767 int i=0;
768 i2=0;
769 while(1){
770 if( subscripts[0] < i2 ){
771 compiler.errorMessenger.Output(41,0,cp);
772 return 0;
773 }
774 i=GetOneParameter(InitBuf,i,temporary);
775 if(!SetInitGlobalData(
776 offset+i2*typeSize,
777 type,
778 nestSubscripts,
779 temporary)) return false;
780 i2++;
781 if(InitBuf[i]=='\0') break;
782 }
783 }
784 return true;
785 }
786
787 if(type.IsStruct()){
788 const CClass &objClass = type.GetClass();
789
790 int i = 0;
791 BOOST_FOREACH( CMember *pMember, objClass.GetDynamicMembers() ){
792 if(InitBuf[i]=='\0'){
793 compiler.errorMessenger.Output(41,0,cp);
794 return false;
795 }
796
797 i=GetOneParameter(InitBuf,i,temporary);
798
799 i3=objClass.GetMemberOffset( pMember->GetName().c_str() );
800
801 if(!SetInitGlobalData(offset+i3,
802 pMember->GetType(),
803 pMember->GetSubscripts(),
804 temporary)) return false;
805 }
806 return true;
807 }
808
809 compiler.errorMessenger.Output(41,0,cp);
810 return false;
811 }
812
813
814 ///////////////////////////////////////
815 // 単発式([]で囲まれていない)
816 ///////////////////////////////////////
817
818 if( subscripts.size() > 0 ){
819 compiler.errorMessenger.Output(41,0,cp);
820 return false;
821 }
822
823 double dbl;
824 _int64 i64data;
825 Type calcType;
826
827 if( !StaticCalculation(false, InitBuf,type.GetBasicType(),&i64data,calcType) ){
828 //動的データだった場合
829 return false;
830 }
831 if( calcType.IsReal() ){
832 memcpy(&dbl,&i64data,sizeof(double));
833 i64data=(_int64)dbl;
834 }
835 else dbl=(double)i64data;
836
837 //型チェック
838 CheckDifferentType(
839 type,
840 calcType,
841 0,0);
842
843 if( type.IsDouble() ){
844 compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.Overwrite(
845 offset,
846 (const char *)&dbl,
847 sizeof(double)
848 );
849 }
850 else if( type.IsSingle() ){
851 float flt = (float)dbl;
852 compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.Overwrite(
853 offset,
854 (const char *)&flt,
855 sizeof(float)
856 );
857 }
858 else if( type.Is64() ){
859 compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.Overwrite(
860 offset,
861 (const char *)&i64data,
862 sizeof(_int64)
863 );
864 }
865 else if( type.IsLong() || type.IsDWord() || type.IsPointer() ){
866 if( type.GetBasicType() == typeOfPtrChar && calcType.GetIndex() == LITERAL_STRING )
867 {
868 //文字列定数のとき
869
870 char *temp;
871 temp=(char *)i64data;
872 i2=compiler.GetObjectModule().dataTable.AddString(temp,lstrlen(temp));
873 HeapDefaultFree(temp);
874
875 //mov eax,DataPos
876 compiler.codeGenerator.op_mov_RV( REG_EAX, i2, Schedule::DataTable );
877
878 //mov dword ptr[offset],eax
879 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, 0, offset, MOD_DISP32, Schedule::GlobalVar );
880 }
881 else{
882 long l = (long)i64data;
883 compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.Overwrite(
884 offset,
885 (const char *)&l,
886 sizeof(long)
887 );
888 }
889 }
890 else if( type.IsWord() || type.IsInteger() ){
891 short s = (short)i64data;
892 compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.Overwrite(
893 offset,
894 (const char *)&s,
895 sizeof(short)
896 );
897 }
898 else if( type.IsSByte() || type.IsByte() || type.IsBoolean() ){
899 char c = (char)i64data;
900 compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.Overwrite(
901 offset,
902 (const char *)&c,
903 sizeof(char)
904 );
905 }
906
907 return true;
908}
909bool InitLocalVar(int offset,const Type &type,const Subscripts &subscripts,const char *lpszInitBuf){
910 int i2,i3;
911 char temporary[VN_SIZE];
912 char InitBuf[VN_SIZE];
913 lstrcpy( InitBuf, lpszInitBuf );
914
915 if(InitBuf[0]=='['){
916 SlideString(InitBuf+1,-1);
917 InitBuf[lstrlen(InitBuf)-1]=0;
918
919 int typeSize = type.GetSize();
920
921 if( subscripts.size() > 0 ){
922 Subscripts nestSubscripts;
923 for( int i=1; i<(int)subscripts.size(); i++ )
924 {
925 nestSubscripts.push_back( subscripts[i] );
926 }
927
928 typeSize*=JumpSubScripts( nestSubscripts );
929 {
930 int i=0;
931 i2=0;
932 while(1){
933 if( subscripts[0] < i2 ){
934 compiler.errorMessenger.Output(41,0,cp);
935 return 0;
936 }
937 i=GetOneParameter(InitBuf,i,temporary);
938 if(!InitLocalVar(
939 offset+i2*typeSize,
940 type,
941 nestSubscripts,
942 temporary)) return false;
943 i2++;
944 if(InitBuf[i]=='\0') break;
945 }
946 }
947 return true;
948 }
949
950 if(type.IsStruct()){
951 const CClass &objClass = type.GetClass();
952
953 int i = 0;
954 BOOST_FOREACH( CMember *pMember, objClass.GetDynamicMembers() ){
955 if(InitBuf[i]=='\0'){
956 compiler.errorMessenger.Output(41,0,cp);
957 return false;
958 }
959
960 i=GetOneParameter(InitBuf,i,temporary);
961
962 i3=objClass.GetMemberOffset( pMember->GetName().c_str() );
963
964 if(!InitLocalVar(offset+i3,
965 pMember->GetType(),
966 pMember->GetSubscripts(),
967 temporary)) return false;
968
969 if(InitBuf[i]=='\0') break;
970 }
971 return true;
972 }
973
974 compiler.errorMessenger.Output(41,0,cp);
975 return false;
976 }
977
978
979 ///////////////////////////////////////
980 // 単発式([]で囲まれていない)
981 ///////////////////////////////////////
982
983 if( subscripts.size() > 0 ){
984 compiler.errorMessenger.Output(41,0,cp);
985 return false;
986 }
987
988 double dbl;
989 _int64 i64data;
990 Type calcType;
991
992 if( !StaticCalculation(false, InitBuf,type.GetBasicType(),&i64data,calcType) ){
993 //動的データだった場合
994 return false;
995 }
996 if( calcType.IsReal() ){
997 memcpy(&dbl,&i64data,sizeof(double));
998 i64data=(_int64)dbl;
999 }
1000 else dbl=(double)i64data;
1001
1002 //型チェック
1003 CheckDifferentType(
1004 type,
1005 calcType,
1006 0,0);
1007
1008 if( type.IsDouble() ){
1009 //mov eax,HILONG(dbl)
1010 compiler.codeGenerator.op_mov_RV( REG_EAX, *(long *)(((char *)(&dbl))+4) );
1011
1012 //mov dword ptr[ebp+offset+sizeof(long)],eax
1013 compiler.codeGenerator.localVarPertialSchedules.push_back(
1014 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset+sizeof(long), MOD_BASE_DISP32, Schedule::None, true )
1015 );
1016
1017 //mov eax,LOLONG(dbl)
1018 compiler.codeGenerator.op_mov_RV( REG_EAX, *(long *)(&dbl) );
1019
1020 //mov dword ptr[ebp+offset],eax
1021 compiler.codeGenerator.localVarPertialSchedules.push_back(
1022 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset, MOD_BASE_DISP32, Schedule::None, true )
1023 );
1024 }
1025 else if( type.IsSingle() ){
1026 float flt;
1027 flt=(float)dbl;
1028
1029 //mov eax,InitValue
1030 compiler.codeGenerator.op_mov_RV( REG_EAX, *(long *)&flt );
1031
1032 //mov dword ptr[ebp+offset],eax
1033 compiler.codeGenerator.localVarPertialSchedules.push_back(
1034 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset, MOD_BASE_DISP32, Schedule::None, true )
1035 );
1036 }
1037 else if( type.Is64() ){
1038 //mov eax,HILONG(i64data)
1039 compiler.codeGenerator.op_mov_RV( REG_EAX, *(long *)(((char *)(&i64data))+4) );
1040
1041 //mov dword ptr[ebp+offset+sizeof(long)],eax
1042 compiler.codeGenerator.localVarPertialSchedules.push_back(
1043 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset+sizeof(long), MOD_BASE_DISP32, Schedule::None, true )
1044 );
1045
1046 //mov eax,LOLONG(i64data)
1047 compiler.codeGenerator.op_mov_RV( REG_EAX, *(long *)(&i64data) );
1048
1049 //mov dword ptr[ebp+offset],eax
1050 compiler.codeGenerator.localVarPertialSchedules.push_back(
1051 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset, MOD_BASE_DISP32, Schedule::None, true )
1052 );
1053 }
1054 else if( type.IsDWord() || type.IsLong() || type.IsPointer() ){
1055 if( type.GetBasicType() == typeOfPtrChar && calcType.GetIndex() == LITERAL_STRING )
1056 {
1057 //文字列定数のとき
1058
1059 char *temp;
1060 temp=(char *)i64data;
1061 i2=compiler.GetObjectModule().dataTable.AddString(temp,lstrlen(temp));
1062 HeapDefaultFree(temp);
1063
1064 //mov eax,DataPos
1065 compiler.codeGenerator.op_mov_RV( REG_EAX, i2, Schedule::DataTable );
1066 }
1067 else{
1068 //mov eax,InitValue
1069 compiler.codeGenerator.op_mov_RV( REG_EAX, (long)i64data );
1070 }
1071
1072 //mov dword ptr[ebp+offset],eax
1073 compiler.codeGenerator.localVarPertialSchedules.push_back(
1074 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset, MOD_BASE_DISP32, Schedule::None, true )
1075 );
1076 }
1077 else if( type.IsWord() || type.IsInteger() ){
1078 //mov word ptr[ebp+offset],InitValue
1079 compiler.codeGenerator.localVarPertialSchedules.push_back(
1080 compiler.codeGenerator.op_mov_MV( sizeof(short), REG_EBP, offset, Schedule::None, true, (long)i64data )
1081 );
1082 }
1083 else if( type.IsSByte() || type.IsByte() || type.IsBoolean() ){
1084 //mov byte ptr[ebp+offset],InitValue
1085 compiler.codeGenerator.localVarPertialSchedules.push_back(
1086 compiler.codeGenerator.op_mov_MV( sizeof(char), REG_EBP, offset, Schedule::None, true, (long)i64data )
1087 );
1088 }
1089
1090 return true;
1091}
1092
1093void dim( char *VarName, const Subscripts &subscripts, const Type &type,const char *InitBuf,const char *ConstractParameter,DWORD dwFlags){
1094 if( compiler.IsGlobalAreaCompiling() ){
1095 /////////////////////////
1096 // グローバル変数
1097 /////////////////////////
1098
1099 AddGlobalVariable(VarName,subscripts,type,InitBuf,ConstractParameter,dwFlags);
1100 }
1101 else{
1102 /////////////////
1103 // ローカル変数
1104 /////////////////
1105
1106 if( compiler.GetCompilingUserProc().GetLocalVars().DuplicateCheck( LexicalAnalyzer::FullNameToSymbol( VarName ) ) ){
1107 //2重定義のエラー
1108 compiler.errorMessenger.Output(15,VarName,cp);
1109 return;
1110 }
1111
1112 bool isConst = ( dwFlags & DIMFLAG_CONST ) ? true:false;
1113
1114 Variable *pVar = new Variable( VarName, type, isConst, false, ConstractParameter, false );
1115
1116 if( subscripts.size() > 0 ){
1117 //配列あり
1118 pVar->SetArray( subscripts );
1119 }
1120
1121 //レキシカルスコープ
1122 pVar->SetScopeLevel( compiler.codeGenerator.lexicalScopes.GetNowLevel() );
1123 pVar->SetScopeStartAddress( compiler.codeGenerator.lexicalScopes.GetStartAddress() );
1124 pVar->isLiving = true;
1125
1126 //エラー用
1127 pVar->source_code_address=cp;
1128
1129 // 変数を追加
1130 compiler.GetCompilingUserProc().GetLocalVars().push_back( pVar );
1131
1132 //アラインメントを考慮
1133 if( pVar->GetType().IsStruct() ){
1134 int alignment = pVar->GetType().GetClass().GetFixedAlignment();
1135
1136 if( alignment ){
1137 if( AllLocalVarSize % alignment ){
1138 AllLocalVarSize += alignment - (AllLocalVarSize % alignment);
1139 }
1140 }
1141
1142 if( alignment == PTR_SIZE*2 ){
1143 // ポインタに要するサイズよりも一回り大きなアラインメントが指定されているとき
1144 // (例:CONTEXT構造体など)
1145 // 呼び出し側のオフセットズレを考慮する
1146
1147 if( 0 == ( compiler.GetCompilingUserProc().RealParams().GetMemorySize() + PTR_SIZE /* ret分 */ ) % alignment ){
1148 AllLocalVarSize += PTR_SIZE;
1149 }
1150 }
1151 }
1152
1153 AllLocalVarSize += pVar->GetMemorySize();
1154 pVar->SetOffsetAddress( AllLocalVarSize );
1155
1156 //レキシカルスコープ
1157 pVar->SetScopeLevel( compiler.codeGenerator.lexicalScopes.GetNowLevel() );
1158 pVar->SetScopeStartAddress( compiler.codeGenerator.lexicalScopes.GetStartAddress() );
1159 pVar->isLiving = true;
1160
1161 if(InitBuf[0]){
1162 //初期代入時のみ、書き込みアクセスを許可する
1163 if( isConst ){
1164 pVar->ConstOff();
1165 }
1166
1167 int result = 0;
1168 if( !pVar->GetType().IsObject() ){
1169 result = InitLocalVar(-pVar->GetOffsetAddress(),
1170 pVar->GetType(),
1171 pVar->GetSubscripts(),
1172 InitBuf);
1173 }
1174
1175 if(!result){
1176 //動的な式だった場合は代入演算を行う
1177 char temporary[8192];
1178 sprintf(temporary,"%s=%s",VarName,InitBuf);
1179 OpcodeCalc(temporary);
1180 }
1181
1182 if( isConst ){
1183 pVar->ConstOn();
1184 }
1185 }
1186 else{
1187 //push 0
1188 compiler.codeGenerator.op_push_V(0);
1189
1190 //push VarSize
1191 compiler.codeGenerator.op_push_V( pVar->GetMemorySize() );
1192
1193 //mov eax,ebp
1194 compiler.codeGenerator.op_mov_RR( REG_EAX, REG_EBP );
1195
1196 //add eax,offset
1197 compiler.codeGenerator.localVarPertialSchedules.push_back(
1198 compiler.codeGenerator.op_add_RV( REG_EAX, -pVar->GetOffsetAddress(), Schedule::None, true )
1199 );
1200
1201 //push eax
1202 compiler.codeGenerator.op_push(REG_EAX);
1203
1204 //call FillMemory
1205 compiler.codeGenerator.op_call( GetDeclareHash("FillMemory") );
1206 }
1207 }
1208
1209 //New呼び出し
1210 if( type.IsObject()
1211 && !type.IsInterface() && !type.IsComInterface()
1212 &&(dwFlags&DIMFLAG_NONCALL_CONSTRACTOR)==0
1213 &&InitBuf[0]=='\0')
1214 {
1215 char objectSize[255];
1216 if( subscripts.size() == 0 ){
1217 objectSize[0] = 0;
1218 }
1219 else{
1220 if( subscripts.size() > 1 ){
1221 compiler.errorMessenger.Output(300,NULL,cp);
1222 }
1223 sprintf( objectSize, "%d", subscripts[0] );
1224 }
1225 Operator_New( type.GetClass(), objectSize, ConstractParameter, type );
1226
1227 //pop eax
1228 compiler.codeGenerator.op_pop( REG_EAX );
1229
1230 RELATIVE_VAR RelativeVar;
1231 GetVarOffset( true, false, VarName, &RelativeVar, Type() );
1232 if( RelativeVar.dwKind == VAR_DIRECTMEM ){
1233 compiler.errorMessenger.OutputFatalError();
1234 }
1235 SetVariableFromEax( Type( DEF_OBJECT, *compiler.GetObjectModule().meta.GetClasses().GetObjectClassPtr() ), DEF_OBJECT, &RelativeVar );
1236 }
1237}
1238
1239void SetVarPtrToEax(RELATIVE_VAR *pRelativeVar){
1240 if(pRelativeVar->dwKind==VAR_GLOBAL){
1241 if(pRelativeVar->bOffsetOffset){
1242 //lea eax,dword ptr[ecx+offset]
1243 compiler.codeGenerator.op_lea_RM( REG_EAX, REG_ECX, pRelativeVar->offset, MOD_BASE_DISP32, Schedule::GlobalVar );
1244 }
1245 else{
1246 //mov eax,offset
1247 compiler.codeGenerator.op_mov_RV( REG_EAX, pRelativeVar->offset, Schedule::GlobalVar );
1248 }
1249 }
1250 else if(pRelativeVar->dwKind==VAR_REFGLOBAL){
1251 if(pRelativeVar->bOffsetOffset){
1252 //mov eax,ecx
1253 compiler.codeGenerator.op_mov_RR( REG_EAX, REG_ECX );
1254
1255 //add eax,dword ptr[offset]
1256 compiler.codeGenerator.op_add_RM( sizeof(long), REG_EAX, REG_NON, (int)pRelativeVar->offset, MOD_DISP32, Schedule::GlobalVar );
1257 }
1258 else{
1259 //mov eax,dword ptr[offset]
1260 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EAX, REG_NON, (int)pRelativeVar->offset, MOD_DISP32, Schedule::GlobalVar );
1261 }
1262 }
1263 else if(pRelativeVar->dwKind==VAR_LOCAL){
1264 if(pRelativeVar->bOffsetOffset){
1265 //add ecx,offset
1266 compiler.codeGenerator.localVarPertialSchedules.push_back(
1267 compiler.codeGenerator.op_add_RV( REG_ECX, pRelativeVar->offset, Schedule::None, true )
1268 );
1269
1270 //lea eax,dword ptr[ebp+ecx]
1271 compiler.codeGenerator.PutOld(
1272 (char)0x8D,
1273 (char)0x44,
1274 (char)0x0D,
1275 (char)0x00
1276 );
1277 }
1278 else{
1279 //lea eax,dword ptr[ecx+offset]
1280 compiler.codeGenerator.localVarPertialSchedules.push_back(
1281 compiler.codeGenerator.op_lea_RM( REG_EAX, REG_EBP, pRelativeVar->offset, MOD_BASE_DISP32, Schedule::None, true )
1282 );
1283 }
1284 }
1285 else if(pRelativeVar->dwKind==VAR_REFLOCAL){
1286 if(pRelativeVar->bOffsetOffset){
1287 //mov eax,ecx
1288 compiler.codeGenerator.op_mov_RR( REG_EAX, REG_ECX );
1289
1290 //add eax,dword ptr[ebp+offset]
1291 compiler.codeGenerator.localVarPertialSchedules.push_back(
1292 compiler.codeGenerator.op_add_RM( sizeof(long), REG_EAX, REG_EBP, pRelativeVar->offset, MOD_BASE_DISP32, Schedule::None, true )
1293 );
1294 }
1295 else{
1296 //mov eax,dword ptr[ebp+offset]
1297 compiler.codeGenerator.localVarPertialSchedules.push_back(
1298 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EAX, REG_EBP, pRelativeVar->offset, MOD_BASE_DISP32, Schedule::None, true )
1299 );
1300 }
1301 }
1302 else if(pRelativeVar->dwKind==VAR_DIRECTMEM){
1303 //mov eax,ecx
1304 compiler.codeGenerator.op_mov_RR( REG_EAX, REG_ECX );
1305 }
1306}
1307void SetVarPtrToReg(int reg,RELATIVE_VAR *pRelativeVar){
1308 if( reg != REG_EAX ){
1309 compiler.errorMessenger.OutputFatalError();
1310 //TODO: 未完成
1311 }
1312 SetVarPtrToEax( pRelativeVar );
1313}
1314
1315bool Compile_AddGlobalRootsForGc(){
1316 const UserProc *pUserProc_AddGlobalRootPtr = GetClassMethod( "_System_CGarbageCollection", "AddGlobalRootPtr" );
1317 if( !pUserProc_AddGlobalRootPtr ){
1318 compiler.errorMessenger.Output(3, "_System_CGarbageCollection.AddGlobalRootPtr", -1 );
1319 return false;
1320 }
1321
1322 BOOST_FOREACH( const Variable *pVar, compiler.GetObjectModule().meta.GetGlobalVars() ){
1323 if( pVar->GetType().IsObject() || pVar->GetType().IsPointer() || pVar->GetType().IsStruct() ){
1324 // オブジェクトまたはポインタだったとき
1325 // ※構造体も含む(暫定対応)
1326
1327 // 変数領域に要するLONG_PTR単位の個数を引き渡す
1328 compiler.codeGenerator.op_push_V( pVar->GetMemorySize()/PTR_SIZE );
1329
1330
1331 /////////////////////////////
1332 // ルートポインタを引き渡す
1333
1334 //mov eax,offset
1335 compiler.codeGenerator.op_mov_RV(REG_EAX,(int)pVar->GetOffsetAddress(), Schedule::GlobalVar );
1336
1337 //push eax
1338 compiler.codeGenerator.op_push( REG_EAX );
1339
1340 //
1341 /////////////////////////////
1342
1343
1344 /////////////////////////////
1345 // Thisポインタを引き渡す
1346
1347 SetThisPtrToReg(REG_EAX);
1348
1349 //push eax
1350 compiler.codeGenerator.op_push( REG_EAX );
1351
1352 //
1353 /////////////////////////////
1354
1355
1356 // call AddGlobalRootPtr
1357 compiler.codeGenerator.op_call( pUserProc_AddGlobalRootPtr );
1358 }
1359 }
1360
1361 return true;
1362}
Note: See TracBrowser for help on using the repository browser.