source: dev/BasicCompiler64/Compile_Func.cpp@ 109

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

ObjPtr関数を実装。

File size: 8.5 KB
RevLine 
[3]1#include "../BasicCompiler_Common/common.h"
2#include "Opcode.h"
3
4int GetFunctionType(int FuncNum){
5 switch(FuncNum){
6 case FUNC_LEN:
7 return DEF_LONG;
8 case FUNC_SIZEOF:
9 return DEF_LONG;
10 case FUNC_ADDRESSOF:
11 case FUNC_VARPTR:
[109]12 case FUNC_OBJPTR:
[3]13 return DEF_PTR_VOID;
14 case FUNC_GETDOUBLE:
15 return DEF_DOUBLE;
16 case FUNC_GETSINGLE:
17 return DEF_SINGLE;
18 case FUNC_GETQWORD:
19 return DEF_QWORD;
20 case FUNC_GETDWORD:
21 return DEF_DWORD;
22 case FUNC_GETWORD:
23 return DEF_WORD;
24 case FUNC_GETBYTE:
25 return DEF_BYTE;
26 }
27 return 0;
28}
29int GetFunctionFromName(char *FuncName){
30 if(lstrcmpi(FuncName,"Len")==0) return FUNC_LEN;
31 if(lstrcmpi(FuncName,"AddressOf")==0) return FUNC_ADDRESSOF;
32 if(lstrcmpi(FuncName,"SizeOf")==0) return FUNC_SIZEOF;
33 if(lstrcmpi(FuncName,"VarPtr")==0) return FUNC_VARPTR;
[109]34 if(lstrcmpi(FuncName,"ObjPtr")==0) return FUNC_OBJPTR;
[3]35 if(lstrcmpi(FuncName,"GetDouble")==0) return FUNC_GETDOUBLE;
36 if(lstrcmpi(FuncName,"GetSingle")==0) return FUNC_GETSINGLE;
37 if(lstrcmpi(FuncName,"GetQWord")==0) return FUNC_GETQWORD;
38 if(lstrcmpi(FuncName,"GetDWord")==0) return FUNC_GETDWORD;
39 if(lstrcmpi(FuncName,"GetWord")==0) return FUNC_GETWORD;
40 if(lstrcmpi(FuncName,"GetByte")==0) return FUNC_GETBYTE;
41 return 0;
42}
[46]43void Opcode_Func_Len( const char *Parameter ){
[3]44 BOOL bArrayHead;
45
[46]46 const char *tempParm=Parameter;
[3]47 char temporary[VN_SIZE];
48 char temp2[32];
[75]49 Type type;
50 if( !GetVarType(Parameter,type,0) ){
[3]51 sprintf(temporary,"_System_DummyStr2=%s",Parameter);
52 OpcodeCalc(temporary);
53
54 lstrcpy(temp2,"_System_DummyStr2");
55 tempParm=temp2;
56
57 extern CClass *pobj_StringClass;
[75]58 type.SetType( DEF_OBJECT, pobj_StringClass );
[3]59 }
60
[97]61 if( type.IsStringClass() ){
[3]62 //Stringオブジェクトの場合
63 sprintf(temporary,"%s.Length",tempParm);
64
65 int reg=REG_RAX;
[76]66 NumOpe(&reg,temporary,Type(),Type());
[3]67 return;
68 }
69
70 int SubScripts[MAX_ARRAYDIM];
71 RELATIVE_VAR RelativeVar;
[75]72 if(!GetVarOffsetReadOnly(tempParm,&RelativeVar,type,SubScripts)) return;
[3]73
[75]74 if(type.GetBasicType()&FLAG_PTR){
75 type.SetBasicType( type.GetBasicType() & ( ~FLAG_PTR ) );
[3]76
77 bArrayHead=1;
78 }
79 else bArrayHead=0;
80
[75]81 int typeSize = type.GetSize();
[3]82
[75]83 if(bArrayHead) typeSize*=JumpSubScripts(SubScripts);
[3]84
85 //mov rax,TypeSize
[75]86 op_mov_RV(sizeof(_int64),REG_RAX,typeSize);
[3]87
88 return;
89}
[46]90void Opcode_Func_AddressOf( const char *name ){
[3]91 extern int cp;
[75]92 UserProc *pUserProc;
[3]93
94 extern LONG_PTR ProcPtr_BaseIndex;
95 if(ProcPtr_BaseIndex!=-1){
96 //左辺の型にのっとり、オーバーロードを解決
97
[75]98 std::vector<UserProc *> subs;
[50]99 GetOverloadSubHash( name, subs );
100 if( subs.size() == 0 ){
[3]101 SetError(27,name,cp);
102 return;
103 }
104
105 //オーバーロードを解決
[88]106 pUserProc=OverloadSolution(name,subs,Smoothie::Meta::procPointers[ProcPtr_BaseIndex]->Params(), Type() );
[3]107
[75]108 if(!pUserProc){
[3]109 SetError(27,name,cp);
110 return;
111 }
112 }
113 else{
[75]114 pUserProc=GetSubHash(name);
115 if(!pUserProc){
[3]116 SetError(27,name,cp);
117 return;
118 }
119 }
120
[75]121 if( pUserProc->IsVirtual() ){
[3]122 ///////////////////////////////
123 // 仮想関数の場合
124 // thisポインタをrcxにコピー
125 ///////////////////////////////
126
127 CClass *pobj_c;
128
129 char ObjectName[VN_SIZE];
130 int RefType;
[28]131 SplitObjectName(name,ObjectName,&RefType);
[3]132
133 if(ObjectName[0]){
134 if(lstrcmpi(ObjectName,"Super")==0) goto InClassMember;
135 else{
136 RELATIVE_VAR RelativeVar;
[75]137 Type type;
138 if(!GetVarOffsetReadOnly(ObjectName,&RelativeVar,type)) return;
[3]139 SetVarPtrToReg(REG_RCX,&RelativeVar);
140
141 //参照タイプが整合しているかをチェック
[75]142 if(type.GetBasicType()!=RefType) SetError(104,ObjectName,cp);
[3]143
[75]144 if(type.IsObjectPtr()){
[3]145 //mov rcx,qword ptr[rcx]
146 op_mov_RM(sizeof(_int64),REG_RCX,REG_RCX,0,MOD_BASE);
147 }
148 }
149 }
150 else{
151InClassMember:
152 //自身のオブジェクトのThisポインタをrcxにコピー
153 SetThisPtrToReg(REG_RCX);
154
155 pobj_c=pobj_CompilingClass;
156 }
157
158
159 //仮想関数(オブジェクトメソッド)
160 //pObj->func_table->func1
161 // ->func2
162 // ->func3
163
164 //mov r11,qword ptr[rcx]
165 op_mov_RM(sizeof(_int64),REG_R11,REG_RCX,0,MOD_BASE);
166
[75]167 int i2 = pobj_c->GetFuncNumInVtbl( pUserProc );
[3]168
169 //mov rax,qword ptr[r11+func_index]
170 if(i2*PTR_SIZE<=0x7F){
171 op_mov_RM(sizeof(_int64),REG_RAX,REG_R11,i2*PTR_SIZE,MOD_BASE_DISP8);
172 }
173 else{
174 op_mov_RM(sizeof(_int64),REG_RAX,REG_R11,i2*PTR_SIZE,MOD_BASE_DISP32);
175 }
176 }
177 else{
178 //一般の関数
179
180 //mov rax,ProcAddr
181 op_mov_RV(sizeof(_int64),REG_RAX,0);
182 obp-=sizeof(long);
[75]183 pobj_SubAddrSchedule->add(pUserProc,0);
[3]184 obp+=sizeof(long);
185 }
186
[75]187 pUserProc->Using();
[3]188}
[79]189void Opcode_Func_SizeOf( const string &typeName ){
190 Type tempType;
191 if( !Type::StringToType( typeName, tempType ) ){
192 SetError(3,typeName,cp);
193 return;
[64]194 }
[3]195
[79]196 int typeSize = ( tempType.IsObject() ) ?
197 tempType.GetClass().GetSize() : tempType.GetSize();
198
[3]199 //mov rax,size
[79]200 op_mov_RV(sizeof(_int64),REG_RAX,typeSize);
[3]201}
[75]202void Opcode_Func_VarPtr( const char *Parameter, Type &resultType, bool isCallOn ){
203 if( isCallOn == false ){
204 // 戻り値の型を取得するだけ
205
206 //変数のアドレスを取得
207 if(!GetVarType( Parameter, resultType, true )) return;
208
209 resultType.PtrLevelUp();
210
211 return;
212 }
213
[3]214 RELATIVE_VAR RelativeVar;
215
216 //変数のアドレスを取得
[75]217 if(!GetVarOffsetReadOnly( Parameter, &RelativeVar, resultType )) return;
[3]218
[75]219 int beforeType = resultType.GetBasicType();
[64]220
[75]221 resultType.PtrLevelUp();
[46]222
[3]223 SetVarPtrToReg(REG_RAX,&RelativeVar);
[64]224
[109]225 // TODO: 取り除く(この動きはObjPtrに託す)
[64]226 if( beforeType == DEF_OBJECT && lstrcmpi( Parameter, "This" ) != 0 ){
227 //参照をオブジェクトポインタに変更
228
229 //mov rax,qword ptr[rax]
230 op_mov_RM( sizeof(_int64), REG_RAX, REG_RAX, 0, MOD_BASE );
231 }
[3]232}
[109]233void Opcode_Func_ObjPtr( const char *Parameter, Type &resultType, bool isCallOn ){
234 if( isCallOn == false ){
235 // 戻り値の型を取得するだけ
236
237 //変数のアドレスを取得
238 if(!GetVarType( Parameter, resultType, true )) return;
239
240 resultType.PtrLevelUp();
241
242 return;
243 }
244
245 RELATIVE_VAR RelativeVar;
246
247 //変数のアドレスを取得
248 if(!GetVarOffsetReadOnly( Parameter, &RelativeVar, resultType )) return;
249
250 int beforeType = resultType.GetBasicType();
251
252 resultType.PtrLevelUp();
253
254 SetVarPtrToReg(REG_RAX,&RelativeVar);
255
256 if( beforeType == DEF_OBJECT && lstrcmpi( Parameter, "This" ) != 0 ){
257 //参照をオブジェクトポインタに変更
258
259 //mov rax,qword ptr[rax]
260 op_mov_RM( sizeof(_int64), REG_RAX, REG_RAX, 0, MOD_BASE );
261 }
262 else{
263 SetError(134,NULL,cp );
264 }
265}
[46]266void Opcode_Func_GetPtrData( const char *Parameter, const int type ){
[3]267 int reg=REG_RAX;
[75]268 Type tempType;
269 if( !NumOpe(&reg,Parameter,Type(),tempType) ){
270 return;
271 }
272 if(!tempType.IsWhole()){
[3]273 SetError(11,Parameter,cp);
274 return;
275 }
276
277 if(type==DEF_DOUBLE){
278 //movlpd xmm0,qword ptr[rax]
279 op_movlpd_RM(REG_XMM0,REG_RAX,0,MOD_BASE);
280 }
281 else if(type==DEF_SINGLE){
282 //movss xmm0,dword ptr[rax]
283 op_movss_RM(REG_XMM0,REG_RAX,0,MOD_BASE);
284 }
285 else{
286 //mov rax,ptr[rax]
287 op_mov_RM(GetTypeSize(type,-1),REG_RAX,REG_RAX,0,MOD_BASE);
288 }
289}
290
[75]291bool Opcode_CallFunc( const char *Parameter, const int FuncNum, Type &resultType, bool isCallOn ){
[3]292 switch(FuncNum){
293 case FUNC_LEN:
[75]294 if( isCallOn ) Opcode_Func_Len(Parameter);
295 resultType.SetBasicType( DEF_LONG );
[46]296 break;
[3]297 case FUNC_ADDRESSOF:
[75]298 if( isCallOn ) Opcode_Func_AddressOf(Parameter);
299 resultType.SetBasicType( DEF_PTR_VOID );
[46]300 break;
[3]301 case FUNC_SIZEOF:
[75]302 if( isCallOn ) Opcode_Func_SizeOf(Parameter);
303 resultType.SetBasicType( DEF_LONG );
[46]304 break;
[3]305 case FUNC_VARPTR:
[75]306 Opcode_Func_VarPtr( Parameter, resultType, isCallOn );
[46]307 break;
[109]308 case FUNC_OBJPTR:
309 Opcode_Func_ObjPtr( Parameter, resultType, isCallOn );
310 break;
[3]311
312 case FUNC_GETDOUBLE:
[75]313 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_DOUBLE);
314 resultType.SetBasicType( DEF_DOUBLE );
[46]315 break;
[3]316 case FUNC_GETSINGLE:
[75]317 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_SINGLE);
318 resultType.SetBasicType( DEF_SINGLE );
[46]319 break;
[3]320 case FUNC_GETQWORD:
[75]321 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_QWORD);
322 resultType.SetBasicType( DEF_QWORD );
[46]323 break;
[3]324 case FUNC_GETDWORD:
[75]325 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_DWORD);
326 resultType.SetBasicType( DEF_DWORD );
[46]327 break;
[3]328 case FUNC_GETWORD:
[75]329 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_WORD);
330 resultType.SetBasicType( DEF_WORD );
[46]331 break;
[3]332 case FUNC_GETBYTE:
[75]333 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_BYTE);
334 resultType.SetBasicType( DEF_BYTE );
[46]335 break;
[75]336 default:
337 return false;
[3]338 }
[75]339 return true;
[3]340}
Note: See TracBrowser for help on using the repository browser.