source: dev/trunk/abdev/BasicCompiler32/Compile_Calc.cpp@ 179

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

キャスト演算子が変数オフセットが格納されたレジスタ(ecx)を上書きしてしまうバグを修正

File size: 13.3 KB
Line 
1#include "../BasicCompiler_Common/common.h"
2#include "Opcode.h"
3
4void ChangeTypeToDouble_ToFpuReg(int OldType){
5 //現在のスタックの内容を実数レジスタに保存する
6 //NumOpeの直後専用
7 if(OldType==DEF_DOUBLE){
8 //fld qword ptr[esp]
9 op_fld_ptr_esp(DEF_DOUBLE);
10
11 //add esp,8
12 op_add_esp(8);
13 }
14 else if(OldType==DEF_SINGLE){
15 //fld dword ptr[esp]
16 op_fld_ptr_esp(DEF_SINGLE);
17
18 //add esp,4
19 op_add_esp(4);
20 }
21 else if(OldType==DEF_LONG){
22 //fild dword ptr[esp]
23 op_fld_ptr_esp(DEF_LONG);
24
25 //add esp,4
26 op_add_esp(4);
27 }
28 else if(OldType==DEF_DWORD){
29 //pop eax
30 op_pop(REG_EAX);
31
32 //push 0
33 op_push_V(0);
34
35 //push eax
36 op_push(REG_EAX);
37
38 //fild qword ptr[esp]
39 OpBuffer[obp++]=(char)0xDF;
40 OpBuffer[obp++]=(char)0x2C;
41 OpBuffer[obp++]=(char)0x24;
42
43 //add esp,8
44 op_add_esp(8);
45 }
46}
47void ChangeTypeToDouble(int OldType){
48 //現在のスタックの内容をdouble型に変換する
49 //NumOpeの直後専用
50 if(OldType==DEF_DOUBLE) return;
51 else if(OldType==DEF_SINGLE){
52 //fld dword ptr[esp]
53 op_fld_ptr_esp(DEF_SINGLE);
54
55 //sub esp,4
56 op_sub_esp(4);
57
58 //fstp qword ptr[esp]
59 OpBuffer[obp++]=(char)0xDD;
60 OpBuffer[obp++]=(char)0x1C;
61 OpBuffer[obp++]=(char)0x24;
62 }
63 else if(OldType==DEF_INT64||OldType==DEF_QWORD){
64 //64ビット整数型
65
66 //fild qword ptr[esp]
67 op_fld_ptr_esp(DEF_INT64);
68
69 //fstp qword ptr[esp]
70 OpBuffer[obp++]=(char)0xDD;
71 OpBuffer[obp++]=(char)0x1C;
72 OpBuffer[obp++]=(char)0x24;
73 }
74 else if(IsWholeNumberType(OldType)){
75 //その他整数型
76
77 if(IsSignedType(OldType)){
78 //符号あり
79
80 if(OldType==DEF_INTEGER || (isUnicode&&OldType==DEF_CHAR)){
81 //pop eax
82 op_pop(REG_EAX);
83
84 //movsx eax,ax
85 OpBuffer[obp++]=(char)0x0F;
86 OpBuffer[obp++]=(char)0xBF;
87 OpBuffer[obp++]=(char)0xC0;
88
89 //push eax
90 op_push(REG_EAX);
91 }
92 else if(OldType==DEF_SBYTE || (isUnicode==false&&OldType==DEF_CHAR)){
93 //pop eax
94 op_pop(REG_EAX);
95
96 //movsx eax,al
97 OpBuffer[obp++]=(char)0x0F;
98 OpBuffer[obp++]=(char)0xBE;
99 OpBuffer[obp++]=(char)0xC0;
100
101 //push eax
102 op_push(REG_EAX);
103 }
104
105 //fild dword ptr[esp]
106 op_fld_ptr_esp(DEF_LONG);
107
108 //sub esp,4
109 op_sub_esp(4);
110 }
111 else{
112 //符号なし
113
114 //pop eax
115 op_pop(REG_EAX);
116
117 //push 0
118 op_push_V(0);
119
120 //push eax
121 op_push(REG_EAX);
122
123 //fild qword ptr[esp]
124 OpBuffer[obp++]=(char)0xDF;
125 OpBuffer[obp++]=(char)0x2C;
126 OpBuffer[obp++]=(char)0x24;
127 }
128
129 //fstp qword ptr[esp]
130 OpBuffer[obp++]=(char)0xDD;
131 OpBuffer[obp++]=(char)0x1C;
132 OpBuffer[obp++]=(char)0x24;
133 }
134 else SetError(9,NULL,cp);
135}
136void ChangeTypeToSingle(int OldType){
137 //現在のスタックの内容をfloat型に変換する
138 //NumOpeの直後専用
139 if(OldType==DEF_SINGLE) return;
140 else if(OldType==DEF_DOUBLE){
141 //fld qword ptr[esp]
142 op_fld_ptr_esp(DEF_DOUBLE);
143
144 //add esp,4
145 op_add_esp(4);
146
147 //fstp dword ptr[esp]
148 OpBuffer[obp++]=(char)0xD9;
149 OpBuffer[obp++]=(char)0x1C;
150 OpBuffer[obp++]=(char)0x24;
151 }
152 else if(OldType==DEF_INT64||OldType==DEF_QWORD){
153 //64ビット整数型
154
155 //fild qword ptr[esp]
156 op_fld_ptr_esp(DEF_INT64);
157
158 //add esp,4
159 op_add_esp(4);
160
161 //fstp dword ptr[esp]
162 OpBuffer[obp++]=(char)0xD9;
163 OpBuffer[obp++]=(char)0x1C;
164 OpBuffer[obp++]=(char)0x24;
165 }
166 else if(IsWholeNumberType(OldType)){
167 //その他整数型
168
169 if(IsSignedType(OldType)){
170 //符号あり
171
172 if(OldType==DEF_INTEGER || (isUnicode&&OldType==DEF_CHAR)){
173 //pop eax
174 op_pop(REG_EAX);
175
176 //movsx eax,ax
177 OpBuffer[obp++]=(char)0x0F;
178 OpBuffer[obp++]=(char)0xBF;
179 OpBuffer[obp++]=(char)0xC0;
180
181 //push eax
182 op_push(REG_EAX);
183 }
184 else if(OldType==DEF_SBYTE || (isUnicode==false&&OldType==DEF_CHAR)){
185 //pop eax
186 op_pop(REG_EAX);
187
188 //movsx eax,al
189 OpBuffer[obp++]=(char)0x0F;
190 OpBuffer[obp++]=(char)0xBE;
191 OpBuffer[obp++]=(char)0xC0;
192
193 //push eax
194 op_push(REG_EAX);
195 }
196
197 //fild dword ptr[esp]
198 op_fld_ptr_esp(DEF_LONG);
199 }
200 else{
201 //符号なし
202
203 //fild dword ptr[esp]
204 op_fld_ptr_esp(DEF_LONG);
205 }
206
207 //fstp dword ptr[esp]
208 OpBuffer[obp++]=(char)0xD9;
209 OpBuffer[obp++]=(char)0x1C;
210 OpBuffer[obp++]=(char)0x24;
211 }
212 else SetError(9,NULL,cp);
213}
214
215void ChangeTypeToInt64(int OldType){
216 //現在のスタックの内容をInt64型に変換する
217 //NumOpeの直後専用
218 if(Is64Type(OldType)) return;
219
220 else if(OldType==DEF_DOUBLE){
221 //fld qword ptr[esp]
222 op_fld_ptr_esp(DEF_DOUBLE);
223
224 //fistp qword ptr[esp]
225 op_fistp_ptr_esp( sizeof(_int64) );
226 }
227 else if(OldType==DEF_SINGLE){
228 //fld dword ptr[esp]
229 op_fld_ptr_esp(DEF_SINGLE);
230
231 //sub esp,4
232 op_sub_esp(4);
233
234 //fistp qword ptr[esp]
235 op_fistp_ptr_esp( sizeof(_int64) );
236 }
237 else if(IsWholeNumberType(OldType)){
238 //その他整数
239
240 if(IsSignedType(OldType)){
241 //符号あり
242
243 //pop eax
244 op_pop(REG_EAX);
245
246 //cdq
247 op_cdq();
248
249 //push edx
250 op_push(REG_EDX);
251
252 //push eax
253 op_push(REG_EAX);
254 }
255 else{
256 //符号なし
257
258 //pop eax
259 op_pop(REG_EAX);
260
261 //push 0
262 op_push_V(0);
263
264 //push eax
265 op_push(REG_EAX);
266 }
267 }
268 else SetError(9,NULL,cp);
269}
270void ChangeTypeToLong(int OldType){
271 //現在のスタックの内容をLong型に変換する
272 //NumOpeの直後専用
273 if(OldType==DEF_DOUBLE){
274
275 //fld qword ptr[esp]
276 op_fld_ptr_esp(DEF_DOUBLE);
277
278 //add esp,4
279 op_add_esp(4);
280
281 //fistp dword ptr[esp]
282 op_fistp_ptr_esp( sizeof(long) );
283 }
284 else if(OldType==DEF_SINGLE){
285 //fld dword ptr[esp]
286 op_fld_ptr_esp(DEF_SINGLE);
287
288 //fistp dword ptr[esp]
289 op_fistp_ptr_esp( sizeof(long) );
290 }
291 else if(OldType==DEF_INT64||OldType==DEF_QWORD){
292 //pop eax
293 op_pop(REG_EAX);
294
295 //add esp,4
296 op_add_esp(4);
297
298 //push eax
299 op_push(REG_EAX);
300 }
301}
302void ChangeTypeToInteger(int OldType){
303 //現在のスタックの内容をInteger型に変換する
304 if(OldType==DEF_BOOLEAN||
305 OldType==DEF_BYTE||
306 OldType==DEF_WORD||OldType==DEF_INTEGER || (isUnicode&&OldType==DEF_CHAR)) return;
307 else if(OldType==DEF_SBYTE || (isUnicode==false&&OldType==DEF_CHAR)){
308 //pop eax
309 op_pop(REG_EAX);
310
311 //movsx eax,al
312 OpBuffer[obp++]=(char)0x0F;
313 OpBuffer[obp++]=(char)0xBE;
314 OpBuffer[obp++]=(char)0xC0;
315
316 //push eax
317 op_push(REG_EAX);
318 }
319 else{
320 ChangeTypeToLong(OldType);
321
322 //pop eax
323 op_pop(REG_EAX);
324
325 //and eax,0000FFFFh
326 OpBuffer[obp++]=(char)0x25;
327 *((long *)(OpBuffer+obp))=0x0000FFFF;
328 obp+=sizeof(long);
329
330 //push eax
331 op_push(REG_EAX);
332 }
333}
334void ChangeTypeToByte(int OldType){
335 //現在のスタックの内容をbyte型に変換する
336 if(OldType==DEF_BYTE||OldType==DEF_SBYTE || (isUnicode==false&&OldType==DEF_CHAR)) return;
337
338 ChangeTypeToLong(OldType);
339
340 //pop eax
341 op_pop(REG_EAX);
342
343 //and eax,000000FFh
344 OpBuffer[obp++]=(char)0x25;
345 *((long *)(OpBuffer+obp))=0x000000FF;
346 obp+=sizeof(long);
347
348 //push eax
349 op_push(REG_EAX);
350}
351
352
353
354
355
356
357
358
359
360void RestoreDefaultRegisterFromStackMemory( int type ){
361 //現在のスタックの内容を実数レジスタに保存する
362 //NumOpeの直後専用
363 if(type==DEF_DOUBLE){
364 //fld qword ptr[esp]
365 op_fld_ptr_esp(DEF_DOUBLE);
366
367 //add esp,8
368 op_add_esp(8);
369 }
370 else if(type==DEF_SINGLE){
371 //fld dword ptr[esp]
372 op_fld_ptr_esp(DEF_SINGLE);
373
374 //add esp,4
375 op_add_esp(4);
376 }
377 else if( Is64Type( type ) ){
378 //pop eax
379 op_pop(REG_EAX);
380
381 //pop edx
382 op_pop(REG_EDX);
383 }
384 else{
385 //pop eax
386 op_pop(REG_EAX);
387 }
388}
389
390void SetVariableFromEax(int VarType,int CalcType,RELATIVE_VAR *pRelativeVar){
391 /////////////////////////////////////////////////
392 // eaxの内容を変数にコピーするコードを抽出
393 /////////////////////////////////////////////////
394
395 if(VarType==DEF_BOOLEAN){
396 //bool
397 SetBooleanVariable(CalcType,pRelativeVar);
398 }
399 else if( IsRealNumberType( VarType ) ){
400 // Double/Single型変数へレジスタの値を代入
401 SetRealVariable(VarType, CalcType, pRelativeVar);
402 }
403 else if( IsWholeNumberType( VarType ) || VarType == DEF_OBJECT ){
404 int typeSize = GetTypeSize( VarType, -1 );
405
406 //整数変数へraxの値を格納する
407 SetWholeVariable( typeSize, CalcType, pRelativeVar );
408 }
409 else{
410 SetError(300,NULL,cp);
411 }
412}
413
414void OpcodeCalc( const char *Command ){
415 int i,i2,i3;
416 char variable[VN_SIZE];
417
418
419
420 //////////////////////////////////////
421 // インクリメント・デクリメント
422 //////////////////////////////////////
423
424 for(i=0;;i++){
425 if(Command[i]=='\"'){
426 //ダブルクォートは不正なのでエラー扱い
427 variable[i]=0;
428 SetError(3,variable,cp);
429 return;
430 }
431
432 if(Command[i]=='('){
433 i2=GetStringInPare(variable+i,Command+i);
434 i+=i2-1;
435 continue;
436 }
437 if(Command[i]=='['){
438 i2=GetStringInBracket(variable+i,Command+i);
439 i+=i2-1;
440 continue;
441 }
442 if(Command[i]=='\0'){
443
444 ///////////////////////////////////
445 // インクリメント・デクリメント
446 ///////////////////////////////////
447
448 if(i>2){
449 if(Command[i-2]=='+'&&Command[i-1]=='+'){
450 //インクリメント
451 variable[i-2]=0;
452 IncDec(CALC_ADDITION,variable,"1");
453 return;
454 }
455 else if(Command[i-2]=='-'&&Command[i-1]=='-'){
456 //デクリメント
457 variable[i-2]=0;
458 IncDec(CALC_SUBTRACTION,variable,"1");
459 return;
460 }
461 }
462
463
464 //先端部分の識別子をエラーキーワードにする
465 for(i=0;;i++){
466 if(!IsVariableChar(Command[i])){
467 variable[i]=0;
468 break;
469 }
470 variable[i]=Command[i];
471 }
472
473 if(GetVarType(variable,Type(),0)){
474 //変数リストに該当したとき
475 SetError(1,NULL,cp);
476 }
477 else{
478 if(GetConstHash(variable)){
479 //定数リストに該当したとき
480 SetError(1,NULL,cp);
481 }
482 else{
483 //変数リスト、定数リストに該当しないとき
484 SetError(3,variable,cp);
485 }
486 }
487 return;
488 }
489
490 i2=GetCalcId(Command+i,&i3);
491 if(i2){
492 variable[i]=0;
493
494 if(Command[i]=='=') break;
495
496 if(Command[i+1+i3]=='='){
497 IncDec(i2,variable,Command+i+1+i3+1);
498 return;
499 }
500 }
501
502 variable[i]=Command[i];
503 }
504
505 if(Command[i+1]=='\0'){
506 SetError(1,NULL,cp);
507 return;
508 }
509
510
511
512 ///////////////////////////////////////////////////////////////
513 // インデクサのsetアクセサ([]=演算子のオーバーロードに対応)
514 ///////////////////////////////////////////////////////////////
515
516 char ObjName[VN_SIZE],array_element[VN_SIZE];
517 GetArrayElement(variable,ObjName,array_element);
518 if(array_element[0]){
519 Type varType;
520 if( GetVarType(ObjName,varType,0) && varType.IsObject() ){
521 char temporary[VN_SIZE];
522 sprintf(temporary,"%s.%c%c%c",ObjName,1,ESC_OPERATOR,CALC_ARRAY_SET);
523
524 char temp2[VN_SIZE];
525 sprintf(temp2,"%s,%s",array_element,Command+i+1);
526
527 int idProc;
528 void *pProc;
529 idProc=GetProc(temporary,(void **)&pProc);
530 if(idProc){
531 CallProc(idProc,pProc,temporary,temp2,Type());
532 return;
533 }
534 }
535 }
536
537
538 if( lstrcmpi( variable, "This" ) == 0 ){
539 SetError(133,NULL,cp);
540 return;
541 }
542
543
544 ////////////////////////////////////////
545 // 変数のタイプ型を識別して、演算を行う
546 ////////////////////////////////////////
547
548 Type varType;
549
550 //型を識別
551 if( !GetVarType(variable,varType,false) ){
552
553 // プロパティ用のメソッドを呼び出す
554 if(!CallPropertyMethod( variable, Command+i+1, Type() )){
555 //エラーを表示
556 GetVarType(variable,varType,true);
557 }
558
559 return;
560 }
561
562 extern LONG_PTR ProcPtr_BaseIndex;
563 if(varType.IsProcPtr()) ProcPtr_BaseIndex=varType.GetIndex();
564 else ProcPtr_BaseIndex=-1;
565
566 RELATIVE_VAR VarRelativeVar;
567 if( varType.IsStruct() ){
568 //代入コピーに備える
569
570 //変数アドレスを取得
571 if(!GetVarOffsetReadWrite(
572 variable,
573 &VarRelativeVar,
574 varType)) return;
575
576 SetVarPtrToEax(&VarRelativeVar);
577
578 //push eax
579 op_push(REG_EAX);
580 }
581
582
583 //NumOpe...(スタックに答えが格納される)
584 BOOL bCalcUseHeap;
585 Type calcType;
586 if( !NumOpe(Command+i+1,varType,calcType,&bCalcUseHeap) ){
587 return;
588 }
589
590 if( calcType.IsObject() && !calcType.Equals( varType ) ){
591 bool isUpCast = false;
592 if( varType.IsObject() ){
593 if( varType.GetClass().IsEqualsOrSubClass( &calcType.GetClass() ) ){
594 isUpCast = true;
595 }
596 }
597 if( !isUpCast ){
598 //キャスト演算子のオーバーロードに対応する
599 CallCastOperatorProc(calcType,bCalcUseHeap,varType);
600 }
601 }
602
603 //変数アドレスを取得
604 if(!GetVarOffsetReadWrite(
605 variable,
606 &VarRelativeVar,
607 varType)) return;
608
609 if(varType.GetBasicType()&FLAG_PTR){
610 SetError(14,variable,cp);
611 return;
612 }
613
614 if( varType.IsStruct() ){
615 //構造体インスタンスへの代入
616 SetStructVariable(varType,calcType,bCalcUseHeap);
617 return;
618 }
619
620
621 if( varType.IsObject() && Smoothie::meta.blittableTypes.IsExist( calcType ) ){
622 // Blittable型をオブジェクトとして扱う
623 vector<UserProc *> userProcs;
624 Smoothie::meta.blittableTypes.GetClass( calcType ).GetStaticMethods().Enum( "_Create", userProcs );
625 if( userProcs.size() != 1 ){
626 SetError();
627 return;
628 }
629 UserProc *pUserProc = userProcs[0];
630
631 // call System.[TypeClass]._Create
632 op_call( pUserProc );
633
634 // push eax
635 op_push( REG_EAX );
636
637 calcType = pUserProc->ReturnType();
638 }
639
640
641 /////////////////////////////////
642 // 右辺、左辺の型チェックを行う
643 /////////////////////////////////
644
645 CheckDifferentType(varType,calcType,0,0);
646
647
648 /////////////////////////////////////////////////
649 // スタックの内容を変数にコピーするコードを抽出
650 /////////////////////////////////////////////////
651
652 //eax、edx:eax、またはst(0)にスタック上のデータを取り出す
653 RestoreDefaultRegisterFromStackMemory( calcType.GetBasicType() );
654
655 SetVariableFromEax(varType.GetBasicType(),calcType.GetBasicType(),&VarRelativeVar);
656}
Note: See TracBrowser for help on using the repository browser.