source: dev/BasicCompiler32/NumOpe.cpp@ 68

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

#84の対応(64bitでの動作確認はまだ)。
Stringクラスのコンストラクタにリテラル文字列が渡せないバグを修正。
STRING_IS_NOT_ALWAYS_UNICODEを暗黙的に定義するようにした(暫定対応)。

File size: 17.8 KB
Line 
1#include "../BasicCompiler_Common/common.h"
2#include "Opcode.h"
3
4void PushReturnValue(int type){
5 //関数の戻り値をスタックへプッシュする
6 //※この処理内では、esi、ediは使用不可
7
8 if(type==DEF_OBJECT || type==DEF_STRUCT){
9 //push eax
10 op_push(REG_EAX);
11 }
12 else if(type==DEF_DOUBLE){
13 //sub esp,8
14 op_sub_esp(8);
15
16 //fstp qword ptr[esp]
17 OpBuffer[obp++]=(char)0xDD;
18 OpBuffer[obp++]=(char)0x1C;
19 OpBuffer[obp++]=(char)0x24;
20 }
21 else if(type==DEF_SINGLE){
22 //sub esp,4
23 op_sub_esp(4);
24
25 //fstp dword ptr[esp]
26 OpBuffer[obp++]=(char)0xD9;
27 OpBuffer[obp++]=(char)0x1C;
28 OpBuffer[obp++]=(char)0x24;
29 }
30 else if(type==DEF_INT64||type==DEF_QWORD){
31 //push edx
32 op_push(REG_EDX);
33
34 //push eax
35 op_push(REG_EAX);
36 }
37 else if(type==DEF_LONG){
38 //push eax
39 op_push(REG_EAX);
40 }
41 else if(type==DEF_INTEGER || (isUnicode&&type==DEF_CHAR)){
42 //movsx ebx,ax
43 OpBuffer[obp++]=(char)0x0F;
44 OpBuffer[obp++]=(char)0xBF;
45 OpBuffer[obp++]=(char)0xD8;
46
47 //push ebx
48 op_push(REG_EBX);
49 }
50 else if(type==DEF_SBYTE || (isUnicode==false&&type==DEF_CHAR)){
51 //movsx ebx,al
52 OpBuffer[obp++]=(char)0x0F;
53 OpBuffer[obp++]=(char)0xBE;
54 OpBuffer[obp++]=(char)0xD8;
55
56 //push ebx
57 op_push(REG_EBX);
58 }
59 else if(type==DEF_DWORD||type==DEF_WORD||type==DEF_BYTE||type==DEF_BOOLEAN||
60 IsPtrType(type)){
61 //push eax
62 op_push(REG_EAX);
63 }
64 else{
65 SetError();
66 }
67}
68
69void NewStringObject(LPSTR lpszText){
70 ///////////////////////////////////////////////////////
71 // lpszTextを元にStringオブジェクトを生成し、
72 // オブジェクトポインタをregに格納する
73 ///////////////////////////////////////////////////////
74
75 char *parameter = (char *)malloc( lstrlen( lpszText ) + 32 );
76 sprintf( parameter, "\"%s\"%c%c*Char", lpszText, 1, ESC_AS );
77 SetStringQuotes( parameter );
78
79 extern CClass *pobj_StringClass;
80 TYPEINFO baseTypeInfo = { DEF_OBJECT, (LONG_PTR)pobj_StringClass };
81 Operator_New( *pobj_StringClass, "", parameter, baseTypeInfo );
82
83 free( parameter );
84}
85
86
87int NumOpe(const char *Command,int BaseType,LONG_PTR lpBaseIndex,LONG_PTR *plpIndex,BOOL *pbUseHeap){
88 extern HANDLE hHeap;
89 int i,i2,i3,i4;
90 char temporary[8192],temp2[1024],temp3[1024];
91
92 if(Command[0]=='\0'){
93 SetError(1,NULL,cp);
94 return -1;
95 }
96
97 if(Command[0]==1&& Command[1]==ESC_NEW ){
98 //New演算子(オブジェクト生成)
99 TYPEINFO baseTypeInfo = { BaseType, lpBaseIndex };
100 int resultType = Operator_New(Command+2,plpIndex, baseTypeInfo );
101
102 return resultType;
103 }
104
105
106 /////////////////////////////////
107 // 式要素を逆ポーランド式で取得
108 /////////////////////////////////
109
110 char *values[255];
111 long calc[255];
112 long stack[255];
113 int pnum;
114 if(!GetNumOpeElements(Command,&pnum,values,calc,stack)){
115 for(i=0;i<pnum;i++){
116 if(values[i]) HeapDefaultFree(values[i]);
117 }
118 return 0;
119 }
120
121
122 BOOL bError;
123 bError=0;
124
125 //リテラル値のみの計算かどうかを判別するためのフラグ
126 BOOL bLiteralCalculation=1;
127
128 //リテラル演算の場合を考慮した演算前のバッファ位置
129 int BeforeObp;
130 BeforeObp=obp;
131
132 //リテラル演算の場合を考慮した演算前のプロシージャスケジュール位置
133 //※64ビットの掛け算、除算などで特殊関数が呼ばれるため
134 int Before_ProcAddrScheduleNum;
135 Before_ProcAddrScheduleNum=pobj_SubAddrSchedule->num;
136
137 //リテラル演算の場合を考慮した演算前のデータテーブルスケジュール位置
138 int Before_DataTableScheduleNum;
139 Before_DataTableScheduleNum=pobj_DataTableSchedule->num;
140
141 //リテラル演算の場合を考慮した演算前の再配置スケジュール
142 CReloc *pobj_BackReloc;
143 pobj_BackReloc=new CReloc();
144 pobj_BackReloc->copy(pobj_Reloc);
145
146 double dbl;
147 int sp;
148 int type[255];
149 LONG_PTR index_stack[255];
150 BOOL bUseHeap[255];
151 _int64 i64data;
152 for(i=0,sp=0;i<pnum;i++){
153 int idCalc;
154 idCalc=calc[i]%100;
155
156 if(idCalc){
157 if(type[sp-2]==DEF_OBJECT){
158 //オーバーロードされたオペレータを呼び出す
159 TYPEINFO BaseTypeInfo={BaseType,lpBaseIndex};
160 i2=CallOperatorProc(idCalc,&BaseTypeInfo,type,index_stack,bUseHeap,sp);
161 if(i2==0){
162 if(idCalc==CALC_EQUAL) lstrcpy(temp2,"==");
163 else GetCalcName(idCalc,temp2);
164 sprintf(temporary,"Operator %s",temp2);
165 SetError(27,temporary,cp);
166 goto error;
167 }
168 else if(i2==-1) goto error;
169
170 continue;
171 }
172
173 if(!CheckCalcType(idCalc,type,sp)) goto error;
174 }
175
176 switch(idCalc){
177 //数値
178 case 0:
179 index_stack[sp]=-1;
180 bUseHeap[sp]=0;
181
182 char *term;
183 term=values[i];
184
185 if(term[0]=='\"'){
186 //リテラル文字列
187 if(!RemoveStringQuotes(term)){
188 SetError(43,NULL,cp);
189 goto error;
190 }
191 i3=lstrlen(term);
192StrLiteral:
193
194 if(BaseType==DEF_OBJECT){
195 CClass *pobj_Class;
196 pobj_Class=(CClass *)lpBaseIndex;
197 TYPEINFO BaseTypeInfo = {BaseType,lpBaseIndex};
198 if(IsStringObjectType(BaseTypeInfo)){
199 //要求タイプがオブジェクトであり、Stringの受け入れが可能な場合
200
201 //String型オブジェクトを生成
202 NewStringObject(term);
203
204 extern CClass *pobj_StringClass;
205 type[sp]=DEF_OBJECT;
206 index_stack[sp]=(LONG_PTR)pobj_StringClass;
207 bUseHeap[sp]=1;
208 bLiteralCalculation=0;
209
210 sp++;
211 break;
212 }
213 }
214
215
216 type[sp]=DEF_PTR_CHAR;
217 index_stack[sp]=LITERAL_STRING;
218 bLiteralCalculation=0;
219
220 i2=dataTable.AddString(term,i3);
221
222 //push DataSize
223 OpBuffer[obp++]=(char)0x68;
224 *((long *)(OpBuffer+obp))=i2;
225 pobj_DataTableSchedule->add();
226 obp+=sizeof(long);
227 }
228 else if((term[0]=='e'||term[0]=='E')&&
229 (term[1]=='x'||term[1]=='X')&&
230 term[2]=='\"'){
231 //拡張版リテラル文字列(エスケープシーケンス可能)
232 if(!RemoveStringQuotes(term+2)){
233 SetError(43,NULL,cp);
234 goto error;
235 }
236 i3=FormatString_EscapeSequence(term+2);
237 term+=2;
238
239 goto StrLiteral;
240 }
241 else if(IsVariableTopChar(term[0])||
242 term[0]=='*'||
243 (term[0]=='.'&&IsVariableTopChar(term[1]))){
244 //////////////////
245 // 何らかの識別子
246
247 //////////////////////////////////////
248 // 関数(DLL、ユーザー定義、組み込み)
249 //////////////////////////////////////
250
251 i2=GetCallProcName(term,temporary);
252 if(term[i2]=='('){
253 i4=GetStringInPare_RemovePare(temp2,term+i2+1);
254
255 int idProc;
256 void *pInfo;
257 idProc=GetProc(temporary,&pInfo);
258
259 if(idProc){
260 //閉じカッコ")"に続く文字がNULLでないとき
261 if(term[i2+1+i4+1]!='\0'){
262 if( term[i2+1+i4+1] == '.'
263 || term[i2+1+i4+1] == 1 && term[i2+1+i4+2] == ESC_PSMEM ){
264 goto NonProc;
265 }
266 else{
267 SetError(42,NULL,cp);
268 }
269 }
270
271 ////////////////
272 // 呼び出し
273 ////////////////
274
275 i2=CallProc(idProc,pInfo,temporary,temp2,&index_stack[sp]);
276 if(i2==-1){
277 //戻り値が存在しないとき
278 for(i2=2;;i2++){
279 if(term[i2]=='('||term[i2]=='\0'){
280 term[i2]=0;
281 break;
282 }
283 }
284 SetError(38,term,cp);
285
286 goto error;
287 }
288
289
290 /////////////////////
291 // 戻り値の処理
292 /////////////////////
293
294 //大きな型への暗黙の変換
295 type[sp]=AutoBigCast(BaseType,i2);
296 bLiteralCalculation=0;
297
298 //スタックへプッシュ
299 PushReturnValue(i2);
300
301 if(Is64Type(type[sp])&&IsWholeNumberType(i2)&&GetTypeSize(i2,-1)<=sizeof(long)){
302 //必要に応じて64ビット拡張
303 ExtendStackTo64(i2);
304 }
305
306 if(i2==DEF_STRUCT){
307 //構造体が戻ったときはヒープ領域にインスタンスが格納されている
308 //※後にfreeする必要あり
309 bUseHeap[sp]=1;
310 }
311
312 sp++;
313 break;
314 }
315 else if(GetConstCalcBuffer(temporary,temp2,temp3)){
316 /////////////////////////
317 // マクロ関数
318 /////////////////////////
319
320 //閉じカッコ")"に続く文字がNULLでないときはエラーにする
321 if(term[i2+1+i4+1]!='\0') SetError(42,NULL,cp);
322
323 //マクロ関数の場合
324 type[sp]=NumOpe(temp3,0,0,&index_stack[sp]);
325
326 if(!IS_LITERAL(index_stack[sp])){
327 //リテラル値ではなかったとき
328 bLiteralCalculation=0;
329 }
330
331 sp++;
332 break;
333 }
334 }
335NonProc:
336
337
338
339 char variable[VN_SIZE],array_element[VN_SIZE];
340 CClass *pobj_c;
341 GetArrayElement(term,variable,array_element);
342 if(array_element[0]){
343 i2=GetVarType(variable,(LONG_PTR *)&pobj_c,0);
344 if(i2==DEF_OBJECT){
345 TYPEINFO RetTypeInfo;
346 CallIndexerGetterProc(pobj_c,variable,array_element,RetTypeInfo);
347 type[sp]=RetTypeInfo.type;
348 index_stack[sp]=RetTypeInfo.u.lpIndex;
349 bLiteralCalculation=0;
350
351 //push eax
352 op_push(REG_EAX);
353
354 sp++;
355 break;
356 }
357 }
358
359
360 // Nothing
361 if( lstrcmp( term, "Nothing" ) == 0 ){
362 type[sp] = DEF_OBJECT;
363 if( BaseType == DEF_OBJECT ){
364 index_stack[sp] = lpBaseIndex;
365 }
366 else{
367 index_stack[sp] = (LONG_PTR)pobj_DBClass->GetObjectClass();
368 }
369
370 bLiteralCalculation = 0;
371
372 //push 0
373 op_push_V( 0 );
374
375 sp++;
376 break;
377 }
378
379
380
381 RELATIVE_VAR RelativeVar;
382 if(GetVarOffset(
383 false, //エラー表示あり
384 false, //読み込み専用
385 term,&i2,&RelativeVar,&index_stack[sp])){
386 //////////
387 // 変数
388 //////////
389
390 //大きな型への暗黙の変換
391 type[sp]=AutoBigCast(BaseType,i2);
392 bLiteralCalculation=0;
393
394 if(i2&FLAG_PTR){
395 //配列ポインタ
396 type[sp]=GetPtrType(i2^FLAG_PTR,index_stack[sp]);
397
398 SetVarPtrToEax(&RelativeVar);
399
400 //push eax
401 op_push(REG_EAX);
402 }
403 else if(i2==DEF_DOUBLE||
404 i2==DEF_INT64||
405 i2==DEF_QWORD){
406 //64ビット型
407 PushDoubleVariable(&RelativeVar);
408 }
409 else if(i2==DEF_LONG||i2==DEF_DWORD||i2==DEF_SINGLE||
410 IsPtrType(i2) || i2==DEF_OBJECT){
411 //32ビット型
412 PushLongVariable(&RelativeVar);
413 }
414 else if(i2==DEF_INTEGER || (isUnicode&&i2==DEF_CHAR)){
415 PushIntegerVariable(&RelativeVar);
416 }
417 else if(i2==DEF_WORD){
418 PushWordVariable(&RelativeVar);
419 }
420 else if(i2==DEF_SBYTE || (isUnicode==false&&i2==DEF_CHAR)){
421 PushCharVariable(&RelativeVar);
422 }
423 else if(i2==DEF_BYTE||i2==DEF_BOOLEAN){
424 PushByteVariable(&RelativeVar);
425 }
426 else if(i2==DEF_STRUCT){
427 //構造体ポインタをeaxへ格納(構造体は値型)
428 SetVarPtrToEax(&RelativeVar);
429
430 //push eax
431 op_push(REG_EAX);
432 }
433 else SetError(11,term,cp);
434
435 if(Is64Type(type[sp])&&IsWholeNumberType(i2)&&GetTypeSize(i2,-1)<=sizeof(long)){
436 //必要に応じて64ビット拡張
437 ExtendStackTo64(i2);
438 }
439
440 sp++;
441 break;
442 }
443
444
445 //////////////
446 // 定数の場合
447 //////////////
448
449 i3 = CDBConst::obj.GetType(term);
450 if(i3){
451 type[sp]=i3;
452 if(IsRealNumberType(i3)){
453 //実数
454 double dbl = CDBConst::obj.GetDoubleData(term);
455 memcpy(&i64data,&dbl,sizeof(double));
456 goto Literal;
457 }
458 else if(IsWholeNumberType(i3)){
459 //整数
460 i64data = CDBConst::obj.GetWholeData(term);
461 goto Literal;
462 }
463 /*else if(i3==DEF_STRING){
464 //リテラル文字列
465
466 //バイト数
467 i3=(int)dbl;
468
469 memcpy(term,temporary,i3);
470 goto StrLiteral;
471 }*/
472 else{
473 SetError(300,NULL,cp);
474 goto error;
475 }
476 }
477
478
479 //////////////
480 // 型名の場合
481 //////////////
482
483 LONG_PTR lp;
484 i3=GetTypeFixed(term,&lp);
485 if(i3!=-1){
486 type[sp]=i3|FLAG_CAST;
487 index_stack[sp]=lp;
488 sp++;
489 break;
490 }
491
492
493
494 /////////////////////////////////
495 // プロパティ用のメソッド
496 /////////////////////////////////
497
498 //配列要素を排除
499 char VarName[VN_SIZE],ArrayElements[VN_SIZE];
500 GetArrayElement(term,VarName,ArrayElements);
501
502 if(GetSubHash(VarName,0)){
503 TYPEINFO RetTypeInfo;
504 CallPropertyMethod(term,NULL,&RetTypeInfo);
505
506 //大きな型への暗黙の変換
507 type[sp]=AutoBigCast(BaseType,RetTypeInfo.type);
508
509 index_stack[sp]=RetTypeInfo.u.lpIndex;
510 bLiteralCalculation=0;
511
512 //スタックへプッシュ
513 PushReturnValue(RetTypeInfo.type);
514
515 if(type[sp]==DEF_STRUCT){
516 //構造体が戻ったときはヒープ領域にインスタンスが格納されている
517 //※後にfreeする必要あり
518 bUseHeap[sp]=1;
519 }
520
521 sp++;
522 break;
523 }
524
525
526
527 //該当する識別子が見当たらないときはエラー扱いにする
528 bError=1;
529 SetError(3,term,cp);
530 type[sp]=DEF_DOUBLE;
531 }
532 else{
533 //リテラル値
534 type[sp]=GetLiteralValue(term,&i64data,BaseType);
535Literal:
536 if(type[sp]==DEF_INT64||
537 type[sp]==DEF_QWORD||
538 type[sp]==DEF_DOUBLE){
539 //64ビット(符号有り整数/実数)
540
541 //push HILONG(dbl)
542 op_push_V((long)*(long *)(((char *)(&i64data))+4));
543
544 //push LOLONG(dbl)
545 op_push_V(*(long *)(&i64data));
546 }
547 else if(type[sp]==DEF_SINGLE){
548 //single実数
549
550 float flt;
551 memcpy(&dbl,&i64data,sizeof(double));
552 flt=(float)dbl;
553 memcpy(&i3,&flt,sizeof(long));
554
555 //push term
556 op_push_V(i3);
557 }
558 else{
559 //その他
560
561 //push term
562 op_push_V((long)i64data);
563
564 if((long)i64data==0) index_stack[sp]=LITERAL_NULL;
565 }
566
567
568 //リテラル値の種類
569 if(Is64Type(type[sp])==0&&IsRealNumberType(type[sp])==0){
570 //整数(符号有り/無し)
571
572 index_stack[sp]=GetLiteralIndex(i64data);
573 }
574 }
575 sp++;
576 break;
577
578 //論理演算子
579 case CALC_XOR:
580 //value[sp-2] xor= value[sp-1]
581 //xor演算
582 if(!Calc_Xor(type,index_stack,&sp)) goto error;
583 break;
584 case CALC_OR:
585 //value[sp-2] or= value[sp-1]
586 //or演算
587 if(!Calc_Or(type,index_stack,&sp)) goto error;
588 break;
589 case CALC_AND:
590 //value[sp-2] and= value[sp-1]
591 //and演算
592 if(!Calc_And(type,index_stack,&sp)) goto error;
593 break;
594 case CALC_NOT:
595 //value[sp-1]=Not value[sp-1]
596 //NOT演算子
597 if(!Calc_Not(type,sp)) goto error;
598 break;
599
600 //比較演算子
601 case CALC_PE:
602 //value[sp-2]<=value[sp-1]
603 if(!Calc_Relation_PE(type,index_stack,&sp)) goto error;
604 break;
605 case CALC_QE:
606 //value[sp-2]>=value[sp-1]
607 if(!Calc_Relation_QE(type,index_stack,&sp)) goto error;
608 break;
609 case CALC_P:
610 //value[sp-2]<value[sp-1]
611 if(!Calc_Relation_P(type,index_stack,&sp)) goto error;
612 break;
613 case CALC_Q:
614 //value[sp-2]>value[sp-1]
615 if(!Calc_Relation_Q(type,index_stack,&sp)) goto error;
616 break;
617 case CALC_NOTEQUAL:
618 //value[sp-2]<>value[sp-1]
619 if(!Calc_Relation_NotEqual(type,&sp)) goto error;
620 break;
621 case CALC_EQUAL:
622 //value[sp-2]=value[sp-1]
623 if(!Calc_Relation_Equal(type,&sp)) goto error;
624 break;
625
626 //ビットシフト
627 case CALC_SHL:
628 //value[sp-2]=value[sp-2]<<value[sp-1]
629 if(!Calc_SHL(type,&sp)) goto error;
630 break;
631 case CALC_SHR:
632 //value[sp-2]=value[sp-2]>>value[sp-1]
633 if(!Calc_SHR(type,&sp)) goto error;
634 break;
635
636 //算術演算
637 case CALC_ADDITION:
638 case CALC_SUBTRACTION:
639 case CALC_PRODUCT:
640 if(!CalcTwoTerm_Arithmetic(idCalc,type,index_stack,&sp)) goto error;
641 break;
642
643 case CALC_MOD:
644 //value[sp-2]%=value[sp-1]
645 //剰余演算
646 if(!Calc_Mod(type,&sp)) goto error;
647 break;
648 case CALC_QUOTIENT:
649 //value[sp-2]/=value[sp-1];
650 //除算
651 if(!Calc_Divide(type,&sp,BaseType)) goto error;
652 break;
653 case CALC_INTQUOTIENT:
654 //value[sp-2]/=value[sp-1]
655 //整数除算
656 if(!Calc_IntDivide(type,index_stack,&sp)) goto error;
657 break;
658 case CALC_MINUSMARK:
659 //value[sp-1]=-value[sp-1]
660 //符号反転
661 if(!Calc_MinusMark(type,sp)) goto error;
662 index_stack[sp-1]=-1;
663 break;
664 case CALC_POWER:
665 //べき乗演算(浮動小数点演算のみ)
666 if(!Calc_Power(type,&sp)) goto error;
667 break;
668 case CALC_AS:
669 //キャスト
670 if(!Calc_Cast(type,index_stack,&sp)) goto error;
671 break;
672
673 case CALC_BYVAL:
674 //ポインタ型→参照型
675 if( PTR_LEVEL( type[sp-1] ) <= 0 ){
676 //ポインタ型ではないとき
677 SetError( 3, NULL, cp );
678 goto error;
679 }
680
681 type[sp-1] = PTR_LEVEL_DOWN( type[sp-1] );
682
683 break;
684
685 default:
686 SetError(300,NULL,cp);
687 goto error;
688 }
689 }
690
691 if(bError) goto error;
692
693 if(sp!=1){
694 SetError(1,NULL,cp);
695 goto error;
696 }
697
698 if(bLiteralCalculation){
699 //右辺値が数値の定数式の場合
700 LONG_PTR lpClassIndex;
701 i2=StaticCalculation(true, Command,BaseType,&i64data,&lpClassIndex);
702
703 obp=BeforeObp;
704 pobj_SubAddrSchedule->num=Before_ProcAddrScheduleNum;
705 pobj_DataTableSchedule->num=Before_DataTableScheduleNum;
706 pobj_Reloc->copy(pobj_BackReloc);
707
708 if(i2==DEF_INT64||
709 i2==DEF_QWORD||
710 i2==DEF_DOUBLE){
711 //64ビット(符号有り整数/実数)
712
713 //push HILONG(i64data)
714 op_push_V((long)*(long *)(((char *)(&i64data))+4));
715
716 //push LOLONG(i64data)
717 op_push_V(*(long *)(&i64data));
718 }
719 else if(i2==DEF_SINGLE){
720 //single実数
721
722 memcpy(&dbl,&i64data,sizeof(_int64));
723
724 float flt;
725 flt=(float)dbl;
726 memcpy(&i3,&flt,sizeof(long));
727
728 //push flt
729 op_push_V(i3);
730 }
731 else{
732 //整数(符号有り/無し)
733
734 i3=(long)i64data;
735
736 if(i2==DEF_SBYTE||i2==DEF_BYTE||i2==DEF_BOOLEAN || (isUnicode==false&&i2==DEF_CHAR)) i3=i3&0x000000FF;
737 if(i2==DEF_INTEGER||i2==DEF_WORD || (isUnicode&&i2==DEF_CHAR)) i3=i3&0x0000FFFF;
738
739 //push term
740 op_push_V(i3);
741 }
742
743 type[0]=i2;
744 index_stack[0]=lpClassIndex;
745 }
746 else{
747 //右辺値が数値の定数式ではないとき
748 if(IS_LITERAL(index_stack[0])) index_stack[0]=-1;
749 }
750
751 if(plpIndex) *plpIndex=index_stack[0];
752 if(pbUseHeap) *pbUseHeap=bUseHeap[0];
753
754 int RetType;
755 RetType=type[0];
756 goto finish;
757
758
759error:
760 RetType=-1;
761 goto finish;
762
763
764finish:
765
766 for(i=0;i<pnum;i++){
767 if(values[i]) HeapDefaultFree(values[i]);
768 }
769
770 //再配置スケジュールバックアップ情報を解放
771 delete pobj_BackReloc;
772
773 return RetType;
774}
Note: See TracBrowser for help on using the repository browser.