source: dev/trunk/abdev/BasicCompiler64/Compile_Func.cpp@ 325

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