source: dev/BasicCompiler32/Compile_Func.cpp@ 75

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

TYPEINFO→Typeへのリファクタリングを実施。64bitはほぼ完了。32bitが全般的に未完成。

File size: 11.1 KB
Line 
1#include "../BasicCompiler_Common/common.h"
2#include "Opcode.h"
3
4int GetFunctionType(int FuncNum){
5 switch(FuncNum){
6 case FUNC_CUDBL:
7 return DEF_DOUBLE;
8 case FUNC_FIX:
9 case FUNC_LEN:
10 return DEF_LONG;
11 case FUNC_ADDRESSOF:
12 case FUNC_SIZEOF:
13 case FUNC_VARPTR:
14 return DEF_DWORD;
15 case FUNC_GETDOUBLE:
16 return DEF_DOUBLE;
17 case FUNC_GETSINGLE:
18 return DEF_SINGLE;
19 case FUNC_GETQWORD:
20 return DEF_QWORD;
21 case FUNC_GETDWORD:
22 return DEF_DWORD;
23 case FUNC_GETWORD:
24 return DEF_WORD;
25 case FUNC_GETBYTE:
26 return DEF_BYTE;
27 }
28 return 0;
29}
30int GetFunctionFromName(char *FuncName){
31 if(lstrcmpi(FuncName,"CUDbl")==0) return FUNC_CUDBL;
32 if(lstrcmpi(FuncName,"Fix")==0) return FUNC_FIX;
33 if(lstrcmpi(FuncName,"Len")==0) return FUNC_LEN;
34 if(lstrcmpi(FuncName,"AddressOf")==0) return FUNC_ADDRESSOF;
35 if(lstrcmpi(FuncName,"SizeOf")==0) return FUNC_SIZEOF;
36 if(lstrcmpi(FuncName,"VarPtr")==0) return FUNC_VARPTR;
37 if(lstrcmpi(FuncName,"GetDouble")==0) return FUNC_GETDOUBLE;
38 if(lstrcmpi(FuncName,"GetSingle")==0) return FUNC_GETSINGLE;
39 if(lstrcmpi(FuncName,"GetQWord")==0) return FUNC_GETQWORD;
40 if(lstrcmpi(FuncName,"GetDWord")==0) return FUNC_GETDWORD;
41 if(lstrcmpi(FuncName,"GetWord")==0) return FUNC_GETWORD;
42 if(lstrcmpi(FuncName,"GetByte")==0) return FUNC_GETBYTE;
43 return 0;
44}
45
46void Opcode_Func_Fix(const char *Parameter){
47 int i;
48
49 i=NumOpe(Parameter,0,0,0);
50
51 if(i==DEF_DOUBLE){
52 //fld qword ptr[esp]
53 op_fld_ptr_esp(DEF_DOUBLE);
54
55 //fnstcw word ptr[esp]
56 OpBuffer[obp++]=(char)0xD9;
57 OpBuffer[obp++]=(char)0x3C;
58 OpBuffer[obp++]=(char)0x24;
59
60 //mov ax,word ptr[esp]
61 OpBuffer[obp++]=(char)0x66;
62 OpBuffer[obp++]=(char)0x8B;
63 OpBuffer[obp++]=(char)0x04;
64 OpBuffer[obp++]=(char)0x24;
65
66 //or ah,0Ch
67 OpBuffer[obp++]=(char)0x80;
68 OpBuffer[obp++]=(char)0xCC;
69 OpBuffer[obp++]=(char)0x0C;
70
71 //mov word ptr[esp-2],ax
72 OpBuffer[obp++]=(char)0x66;
73 OpBuffer[obp++]=(char)0x89;
74 OpBuffer[obp++]=(char)0x44;
75 OpBuffer[obp++]=(char)0x24;
76 OpBuffer[obp++]=(char)0xFE;
77
78 //fldcw word ptr[esp-2]
79 OpBuffer[obp++]=(char)0xD9;
80 OpBuffer[obp++]=(char)0x6C;
81 OpBuffer[obp++]=(char)0x24;
82 OpBuffer[obp++]=(char)0xFE;
83
84 //fistp dword ptr[esp+4]
85 OpBuffer[obp++]=(char)0xDB;
86 OpBuffer[obp++]=(char)0x5C;
87 OpBuffer[obp++]=(char)0x24;
88 OpBuffer[obp++]=(char)0x04;
89
90 //fldcw word ptr[esp]
91 OpBuffer[obp++]=(char)0xD9;
92 OpBuffer[obp++]=(char)0x2C;
93 OpBuffer[obp++]=(char)0x24;
94
95 //add esp,4
96 op_add_esp(4);
97 }
98 else if(i==DEF_SINGLE){
99 //fld dword ptr[esp]
100 op_fld_ptr_esp(DEF_SINGLE);
101
102 //sub esp,4
103 op_sub_esp(4);
104
105 //fnstcw word ptr[esp]
106 OpBuffer[obp++]=(char)0xD9;
107 OpBuffer[obp++]=(char)0x3C;
108 OpBuffer[obp++]=(char)0x24;
109
110 //mov ax,word ptr[esp]
111 OpBuffer[obp++]=(char)0x66;
112 OpBuffer[obp++]=(char)0x8B;
113 OpBuffer[obp++]=(char)0x04;
114 OpBuffer[obp++]=(char)0x24;
115
116 //or ah,0Ch
117 OpBuffer[obp++]=(char)0x80;
118 OpBuffer[obp++]=(char)0xCC;
119 OpBuffer[obp++]=(char)0x0C;
120
121 //mov word ptr[esp-2],ax
122 OpBuffer[obp++]=(char)0x66;
123 OpBuffer[obp++]=(char)0x89;
124 OpBuffer[obp++]=(char)0x44;
125 OpBuffer[obp++]=(char)0x24;
126 OpBuffer[obp++]=(char)0xFE;
127
128 //fldcw word ptr[esp-2]
129 OpBuffer[obp++]=(char)0xD9;
130 OpBuffer[obp++]=(char)0x6C;
131 OpBuffer[obp++]=(char)0x24;
132 OpBuffer[obp++]=(char)0xFE;
133
134 //fistp dword ptr[esp+4]
135 OpBuffer[obp++]=(char)0xDB;
136 OpBuffer[obp++]=(char)0x5C;
137 OpBuffer[obp++]=(char)0x24;
138 OpBuffer[obp++]=(char)0x04;
139
140 //fldcw word ptr[esp]
141 OpBuffer[obp++]=(char)0xD9;
142 OpBuffer[obp++]=(char)0x2C;
143 OpBuffer[obp++]=(char)0x24;
144
145 //add esp,4
146 op_add_esp(4);
147 }
148 else if(Is64Type(i)){
149 //pop eax
150 op_pop(REG_EAX);
151
152 //add esp,4
153 op_add_esp(4);
154
155 //push eax
156 op_push(REG_EAX);
157 }
158
159 //pop eax
160 op_pop(REG_EAX);
161}
162
163void Opcode_Func_CUDbl(const char *Parameter){
164 int i;
165
166 i=NumOpe(Parameter,0,0,0);
167 ChangeTypeToLong(i);
168
169 //pop eax
170 op_pop(REG_EAX);
171
172 //push 0
173 OpBuffer[obp++]=(char)0x6A;
174 OpBuffer[obp++]=(char)0x00;
175
176 //push eax
177 op_push(REG_EAX);
178
179 //fild qword ptr[esp]
180 OpBuffer[obp++]=(char)0xDF;
181 OpBuffer[obp++]=(char)0x2C;
182 OpBuffer[obp++]=(char)0x24;
183
184 //add esp,8
185 op_add_esp(8);
186}
187void Opcode_Func_Len(const char *Parameter){
188 int type,TypeSize;
189 LONG_PTR lpIndex;
190 BOOL bArrayHead;
191
192 type=GetVarType(Parameter,&lpIndex,0);
193
194 const char *tempParm=Parameter;
195 char temporary[VN_SIZE];
196 char temp2[32];
197 if(type==-1){
198 sprintf(temporary,"_System_DummyStr2=%s",Parameter);
199 OpcodeCalc(temporary);
200
201 lstrcpy(temp2,"_System_DummyStr2");
202 tempParm=temp2;
203
204 extern CClass *pobj_StringClass;
205 type=DEF_OBJECT;
206 lpIndex=(LONG_PTR)pobj_StringClass;
207 }
208
209 Type TypeInfo={type,lpIndex};
210 if(IsStringObjectType(TypeInfo)){
211 //Stringオブジェクトの場合
212 char temporary[VN_SIZE];
213 sprintf(temporary,"%s.Length",tempParm);
214
215 NumOpe(temporary,0,0,NULL,NULL);
216
217 //pop eax
218 op_pop(REG_EAX);
219
220 return;
221 }
222
223 int SubScripts[MAX_ARRAYDIM];
224 RELATIVE_VAR RelativeVar;
225 if(!GetVarOffsetReadOnly(tempParm,&type,&RelativeVar,&lpIndex,SubScripts)) return;
226
227 if(type&FLAG_PTR){
228 type&=~FLAG_PTR;
229
230 bArrayHead=1;
231 }
232 else bArrayHead=0;
233
234 TypeSize=GetTypeSize(type,lpIndex);
235
236 if(bArrayHead) TypeSize*=JumpSubScripts(SubScripts);
237
238 //mov eax,TypeSize
239 OpBuffer[obp++]=(char)0xB8;
240 *((long *)(OpBuffer+obp))=TypeSize;
241 obp+=sizeof(long);
242}
243void Opcode_Func_AddressOf(const char *name){
244 extern int cp;
245 UserProc *pUserProc;
246
247 extern LONG_PTR ProcPtr_BaseIndex;
248 if(ProcPtr_BaseIndex!=-1){
249 //左辺の型にのっとり、オーバーロードを解決
250
251 std::vector<UserProc *> subs;
252 GetOverloadSubHash( name, subs );
253 if( subs.size() == 0 ){
254 SetError(27,name,cp);
255 return;
256 }
257
258 //オーバーロードを解決
259 extern ProcPointer **ppProcPtrInfo;
260 pUserProc=OverloadSolution(name,subs,ppProcPtrInfo[ProcPtr_BaseIndex]->Params(), Type() );
261
262 if(!pUserProc){
263 SetError(27,name,cp);
264 return;
265 }
266 }
267 else{
268 pUserProc=GetSubHash(name);
269 if(!pUserProc){
270 SetError(27,name,cp);
271 return;
272 }
273 }
274
275 if( pUserProc->IsVirtual() ){
276 ///////////////////////////////
277 // 仮想関数の場合
278 // thisポインタをrcxにコピー
279 ///////////////////////////////
280
281 CClass *pobj_c;
282
283 char ObjectName[VN_SIZE];
284 int RefType;
285 SplitObjectName(name,ObjectName,&RefType);
286
287 if(ObjectName[0]){
288 if(lstrcmpi(ObjectName,"Super")==0) goto InClassMember;
289 else{
290 RELATIVE_VAR RelativeVar;
291 int type;
292 if(!GetVarOffsetReadOnly(ObjectName,&type,&RelativeVar,(LONG_PTR *)&pobj_c)) return;
293 SetVarPtrToEax(&RelativeVar);
294
295 //mov ecx,eax
296 op_mov_RR(REG_ECX,REG_EAX);
297
298 //参照タイプが整合しているかをチェック
299 if(type!=RefType) SetError(104,ObjectName,cp);
300
301 if(type==DEF_PTR_OBJECT){
302 //mov ecx,dword ptr[ecx]
303 op_mov_RM(sizeof(long),REG_ECX,REG_ECX,0,MOD_BASE);
304 }
305 }
306 }
307 else{
308InClassMember:
309 //自身のオブジェクトのThisポインタをrcxにコピー
310 SetThisPtrToReg(REG_RCX);
311
312 pobj_c=pobj_CompilingClass;
313 }
314
315
316 //仮想関数(オブジェクトメソッド)
317 //pObj->func_table->func1
318 // ->func2
319 // ->func3
320
321 //mov edx,dword ptr[ecx]
322 OpBuffer[obp++]=(char)0x8B;
323 OpBuffer[obp++]=(char)0x11;
324
325 int i2 = pobj_c->GetFuncNumInVtbl( pUserProc );
326
327 //mov eax,dword ptr[edx+func_index]
328 if(i2*PTR_SIZE<=0x7F){
329 op_mov_RM(sizeof(long),REG_EAX,REG_EDX,i2*PTR_SIZE,MOD_BASE_DISP8);
330 }
331 else{
332 op_mov_RM(sizeof(long),REG_EAX,REG_EDX,i2*PTR_SIZE,MOD_BASE_DISP32);
333 }
334 }
335 else{
336 //一般の関数
337
338 //mov eax,ProcAddr
339 OpBuffer[obp++]=(char)0xB8;
340 pobj_SubAddrSchedule->add(pUserProc,0);
341 obp+=sizeof(long);
342 }
343
344 pUserProc->Using();
345}
346void Opcode_Func_SizeOf(const char *Parameter){
347 LONG_PTR lpIndex;
348 int type = GetTypeFixed(Parameter,&lpIndex);
349
350 int size;
351 if( type == DEF_OBJECT ){
352 CClass *pClass = (CClass *)lpIndex;
353 size = pClass->GetSize();
354 }
355 else{
356 size=GetTypeSize(type,lpIndex);
357 }
358
359 //mov eax,size
360 op_mov_RV( REG_EAX, size );
361}
362void Opcode_Func_VarPtr( const char *Parameter, Type &ReturnTypeInfo ){
363 RELATIVE_VAR RelativeVar;
364
365 //変数のアドレスを取得
366 if(!GetVarOffsetReadOnly( Parameter, &ReturnTypeInfo.type, &RelativeVar, &ReturnTypeInfo.u.lpIndex )) return;
367
368 int beforeType = ReturnTypeInfo.type;
369
370 PTR_LEVEL_UP( ReturnTypeInfo.type );
371
372 SetVarPtrToEax(&RelativeVar);
373
374 if( beforeType == DEF_OBJECT && lstrcmpi( Parameter, "This" ) != 0 ){
375 //参照をオブジェクトポインタに変更
376
377 //mov eax,dword ptr[eax]
378 op_mov_RM( sizeof(long), REG_EAX, REG_EAX, 0, MOD_BASE );
379 }
380}
381void Opcode_Func_GetPtrData(const char *Parameter,const int type){
382 int i2;
383
384 i2=NumOpe(Parameter,0,0,0);
385 ChangeTypeToLong(i2);
386
387 if(type==DEF_DOUBLE){
388 //pop eax
389 op_pop(REG_EAX);
390
391 //fld qword ptr[eax]
392 OpBuffer[obp++]=(char)0xDD;
393 OpBuffer[obp++]=(char)0x00;
394 }
395 else if(type==DEF_SINGLE||type==DEF_DWORD){
396 //pop eax
397 op_pop(REG_EAX);
398
399 //mov eax,dword ptr[eax]
400 OpBuffer[obp++]=(char)0x8B;
401 OpBuffer[obp++]=(char)0x00;
402 }
403 else if(type==DEF_QWORD){
404 //pop ecx
405 op_pop(REG_ECX);
406
407 //mov eax,dword ptr[ecx]
408 op_mov_RM(sizeof(long),REG_EAX,REG_ECX,0,MOD_BASE);
409
410 //mov edx,dword ptr[ecx+sizeof(long)]
411 op_mov_RM(sizeof(long),REG_EDX,REG_ECX,sizeof(long),MOD_BASE_DISP8);
412 }
413 else if(type==DEF_WORD){
414 //pop ebx
415 op_pop(REG_EBX);
416
417 //xor eax,eax
418 OpBuffer[obp++]=(char)0x33;
419 OpBuffer[obp++]=(char)0xC0;
420
421 //mov ax,word ptr[ebx]
422 OpBuffer[obp++]=(char)0x66;
423 OpBuffer[obp++]=(char)0x8B;
424 OpBuffer[obp++]=(char)0x03;
425 }
426 else if(type==DEF_BYTE){
427 //pop ebx
428 op_pop(REG_EBX);
429
430 //xor eax,eax
431 OpBuffer[obp++]=(char)0x33;
432 OpBuffer[obp++]=(char)0xC0;
433
434 //mov al,byte ptr[ebx]
435 OpBuffer[obp++]=(char)0x8A;
436 OpBuffer[obp++]=(char)0x03;
437 }
438}
439
440void Opcode_CallFunc( const char *Parameter, const int FuncNum, Type &ReturnTypeInfo ){
441 switch(FuncNum){
442 case FUNC_FIX:
443 Opcode_Func_Fix(Parameter);
444 ReturnTypeInfo.type = DEF_LONG;
445 break;
446 case FUNC_CUDBL:
447 Opcode_Func_CUDbl(Parameter);
448 ReturnTypeInfo.type = DEF_DOUBLE;
449 break;
450 case FUNC_LEN:
451 Opcode_Func_Len(Parameter);
452 ReturnTypeInfo.type = DEF_LONG;
453 break;
454 case FUNC_ADDRESSOF:
455 Opcode_Func_AddressOf(Parameter);
456 ReturnTypeInfo.type = DEF_PTR_VOID;
457 break;
458 case FUNC_SIZEOF:
459 Opcode_Func_SizeOf(Parameter);
460 ReturnTypeInfo.type = DEF_LONG;
461 break;
462 case FUNC_VARPTR:
463 Opcode_Func_VarPtr( Parameter, ReturnTypeInfo );
464 break;
465
466 case FUNC_GETDOUBLE:
467 Opcode_Func_GetPtrData(Parameter,DEF_DOUBLE);
468 ReturnTypeInfo.type = DEF_DOUBLE;
469 break;
470 case FUNC_GETSINGLE:
471 Opcode_Func_GetPtrData(Parameter,DEF_SINGLE);
472 ReturnTypeInfo.type = DEF_SINGLE;
473 break;
474 case FUNC_GETQWORD:
475 Opcode_Func_GetPtrData(Parameter,DEF_QWORD);
476 ReturnTypeInfo.type = DEF_QWORD;
477 break;
478 case FUNC_GETDWORD:
479 Opcode_Func_GetPtrData(Parameter,DEF_DWORD);
480 ReturnTypeInfo.type = DEF_DWORD;
481 break;
482 case FUNC_GETWORD:
483 Opcode_Func_GetPtrData(Parameter,DEF_WORD);
484 ReturnTypeInfo.type = DEF_WORD;
485 break;
486 case FUNC_GETBYTE:
487 Opcode_Func_GetPtrData(Parameter,DEF_BYTE);
488 ReturnTypeInfo.type = DEF_BYTE;
489 break;
490 }
491}
Note: See TracBrowser for help on using the repository browser.