source: dev/BasicCompiler32/Compile_Var.cpp@ 116

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

暗黙的なアップキャストを可能にした

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