source: dev/BasicCompiler64/Compile_Var.cpp@ 103

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

名前空間機能をグローバル変数、定数と列挙型に適用。
一部、クラスの静的メンバと名前空間の相性が悪いコードが潜んでいるため、要改修

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