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

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

BasicSourceのシリアライズがうまくいっていない

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