source: dev/trunk/abdev/BasicCompiler32/Compile_CallProc.cpp@ 224

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

コード全体のリファクタリングを実施

File size: 10.5 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
10//ローカル変数アドレススケジュール
11DWORD *pLocalVarAddrSchedule;
12int LocalVarAddrScheduleNum;
13
14void Call_DebugSys_SaveContext(){
15 //call _System_GetEip
16 extern const UserProc *pSub_System_GetEip;
17 op_call(pSub_System_GetEip);
18
19 //push eax
20 op_push(REG_EAX);
21
22 //push ebp
23 op_push(REG_EBP);
24
25 //call _DebugSys_SaveContext
26 extern const UserProc *pSub_DebugSys_SaveContext;
27 op_call(pSub_DebugSys_SaveContext);
28}
29
30void AddLocalVarAddrSchedule(){
31 extern HANDLE hHeap;
32
33 //ローカル変数アドレススケジュールに追加する
34 pLocalVarAddrSchedule=(DWORD *)HeapReAlloc(hHeap,0,pLocalVarAddrSchedule,(LocalVarAddrScheduleNum+1)*sizeof(DWORD));
35 pLocalVarAddrSchedule[LocalVarAddrScheduleNum]=obp;
36 LocalVarAddrScheduleNum++;
37}
38
39
40bool Opcode_CallProcPtr( const char *variable, const char *lpszParms,ProcPointer *pProcPointer){
41
42 extern BOOL bDebugCompile;
43 extern BOOL bDebugSupportProc;
44 if(bDebugCompile&&bDebugSupportProc==0)
45 Call_DebugSys_SaveContext();
46
47
48 ////////////////////////
49 // パラメータのセット
50 ////////////////////////
51
52 //パラメータオブジェクトを生成
53 ParamImpl *pobj_parameter=0;
54 pobj_parameter=new ParamImpl(lpszParms);
55
56 // デフォルト引数を適用
57 pobj_parameter->ApplyDefaultParameters( pProcPointer->Params() );
58
59 //エラーチェック
60 if( !pobj_parameter->ErrorCheck(variable,pProcPointer->Params() ) ){
61 //パラメータにエラーがあるときは処理を終える
62 return false;
63 }
64
65 //一時オブジェクトを生成
66 pobj_parameter->NewTempParameters( variable,pProcPointer->Params() );
67
68 //レジスタ、スタックフレームにセット
69 pobj_parameter->SetParameter(variable,pProcPointer->Params() );
70
71
72
73 ////////////////////////
74 // call
75 ////////////////////////
76 RELATIVE_VAR RelativeVar;
77 GetVarOffsetReadOnly(variable,&RelativeVar,Type());
78 SetVarPtrToEax(&RelativeVar);
79
80 //mov eax,dword ptr[eax]
81 OpBuffer[obp++]=(char)0x8B;
82 OpBuffer[obp++]=(char)0x00;
83
84 //call eax
85 OpBuffer[obp++]=(char)0xFF;
86 OpBuffer[obp++]=(char)0xD0;
87
88
89
90 //一時オブジェクトを破棄
91 pobj_parameter->DeleteTempParameters();
92
93 //パラメータオブジェクトを破棄
94 delete pobj_parameter;
95
96 return true;
97}
98
99bool Opcode_CallProc(const char *Parameter,const UserProc *pUserProc,DWORD dwFlags,const char *ObjectName,int RefType){
100 int i2;
101
102 if( pUserProc->IsMacro() ){
103 if( lstrcmpi( pUserProc->GetName().c_str(), "Print" ) == 0 ){
104 Opcode_Print(Parameter,0);
105 return true;
106 }
107 if( lstrcmpi( pUserProc->GetName().c_str(), "Input" ) == 0 ){
108 Opcode_Input(Parameter);
109 return true;
110 }
111 if( lstrcmpi( pUserProc->GetName().c_str(), "Write" ) == 0 ){
112 Opcode_Print(Parameter,1);
113 return true;
114 }
115 }
116
117 pUserProc->Using();
118
119 bool isStatic = false;
120 const CClass *pobj_c = NULL;
121 const CMethod *pMethod = NULL;
122 if( pUserProc->GetParentClassPtr() ){
123 //クラスのメンバ関数を呼び出す場合はアクセスチェックを行う
124 if(ObjectName[0] && (dwFlags&PROCFLAG_NEW)==0){
125 if(lstrcmpi(ObjectName,"Super")==0){
126 //クラスメンバ関数内から基底クラスの呼び出し
127 pobj_c=compiler.pCompilingClass;
128 }
129 else{
130 //"->"によってオブジェクトを指定する通常のメンバ関数呼び出し
131 Type varType;
132 GetVarType( ObjectName, varType, false );
133 pobj_c = &varType.GetClass();
134 if( NATURAL_TYPE( varType.GetBasicType() ) != DEF_OBJECT ){
135 pobj_c=compiler.GetMeta().GetClasses().Find(ObjectName);
136 if( pobj_c ){
137 isStatic = true;
138 }
139 else{
140 SetError(300,NULL,cp);
141 }
142 }
143 }
144 }
145 else{
146 if(dwFlags&PROCFLAG_NEW){
147 //New演算子によるコンストラクタ呼び出し
148 pobj_c=pUserProc->GetParentClassPtr();
149 }
150 else{
151 //クラスメンバ関数内から同一クラスのメンバ関数の呼び出し
152 pobj_c=compiler.pCompilingClass;
153 }
154 }
155
156
157 /////////////////////////////////
158 // メソッド情報を取得
159 /////////////////////////////////
160 pMethod = NULL;
161 if( ! isStatic ) pMethod = pobj_c->GetMethods().GetMethodPtr( pUserProc );
162 if( ! pMethod ){
163 //動的メソッドが取得できなかったときは静的メソッドを当たる
164 pMethod = pobj_c->GetStaticMethods().GetMethodPtr( pUserProc );
165 if( !pMethod ){
166 SetError(300,NULL,cp);
167 return false;
168 }
169
170 //静的メンバ
171 isStatic = true;
172 }
173
174
175 //////////////////////////////
176 // アクセスエラーチェック
177 //////////////////////////////
178
179 if(ObjectName[0]){
180 //外部からの呼び出し
181 if(pobj_c==compiler.pCompilingClass){
182 //同一クラスオブジェクトの場合はプライベートアクセスを容認する
183 if( pMethod->IsNoneAccess() ){
184 SetError(109,pUserProc->GetName(),cp);
185 return false;
186 }
187 }
188 else{
189 if( pMethod->IsPrivate()
190 || pMethod->IsNoneAccess() ){
191 SetError(109,pUserProc->GetName(),cp);
192 return false;
193 }
194 if( pMethod->IsProtected() ){
195 SetError(110,pUserProc->GetName(),cp);
196 return false;
197 }
198 }
199 }
200 else{
201 //クラス内部からの呼び出し(継承によるACCESS_NONのみをエラーとする)
202 if( pMethod->IsNoneAccess() ){
203 SetError(109,pUserProc->GetName(),cp);
204 return false;
205 }
206 }
207 }
208
209
210 ///////////////////////////////////////////////////////////////
211 // _System_LocalThisのダミーをセット
212 ///////////////////////////////////////////////////////////////
213
214 char temporary[VN_SIZE]={0};
215 if( pUserProc->GetParentClassPtr() && isStatic == false ){
216 //_System_LocalThis(第一パラメータ)のダミーを作成
217 lstrcpy(temporary,"0,");
218 }
219
220 if(Parameter[0]=='\0'&&temporary[0])
221 temporary[lstrlen(temporary)-1]=0;
222 else lstrcat(temporary,Parameter);
223
224
225 ////////////////////////
226 // パラメータをセット
227 ////////////////////////
228
229 //パラメータオブジェクトを生成
230 ParamImpl *pobj_parameter=0;
231 pobj_parameter=new ParamImpl(temporary);
232
233 // デフォルト引数を適用
234 pobj_parameter->ApplyDefaultParameters( pUserProc->RealParams() );
235
236 //エラーチェック
237 if( !pobj_parameter->ErrorCheck(pUserProc->GetName(),pUserProc->RealParams(),pUserProc->GetSecondParmNum() ) ){
238 //パラメータにエラーがあるときは処理を終える
239 return false;
240 }
241
242 if(pUserProc->IsMacro()){
243 //マクロ関数の場合は、パラメータ省略を考慮する
244 pobj_parameter->MacroParameterSupport( pUserProc->RealParams() );
245 }
246
247 //一時オブジェクトを生成
248 int tempSize = pobj_parameter->NewTempParameters( pUserProc->GetName(),pUserProc->RealParams(),pUserProc->GetRealSecondParmNum() );
249
250 //レジスタ、スタックフレームにセット
251 int ParmSize = pobj_parameter->SetParameter(pUserProc->GetName(),pUserProc->RealParams(),pUserProc->GetRealSecondParmNum() );
252
253 if(pUserProc->ReturnType().IsStruct() ){
254 //////////////////////////////////////////////////////
255 // 戻り値に構造体インスタンスを持つ場合
256 // ※ByRef _System_ReturnValue パラメータをセット
257 //////////////////////////////////////////////////////
258
259 int object_size = pUserProc->ReturnType().GetClass().GetSize();
260
261 //push object_size
262 op_push_V(object_size);
263
264 //call calloc
265 extern const UserProc *pSub_calloc;
266 op_call(pSub_calloc);
267
268 //push eax
269 op_push(REG_EAX);
270 }
271
272
273 if( pUserProc->GetParentClassPtr() && isStatic == false ){
274 //////////////////////////////////////////////////////
275 // メンバ関数の場合
276 // ※_System_LocalThis パラメータをセット
277 //////////////////////////////////////////////////////
278
279 if(ObjectName[0] && (dwFlags&PROCFLAG_NEW)==0){
280 if(lstrcmpi(ObjectName,"Super")==0) goto InClassMember;
281 else{
282 RELATIVE_VAR RelativeVar;
283 if( pMethod->IsConst() ){
284 //Constアクセスが可能なメソッドの場合
285 if( !GetVarOffsetReadOnly( ObjectName, &RelativeVar, Type() ) ){
286 return false;
287 }
288 }
289 else{
290 //Constアクセスが不可能なメソッドの場合
291 if( !GetVarOffsetReadWrite( ObjectName, &RelativeVar, Type() ) ){
292 return false;
293 }
294 }
295
296 SetVarPtrToEax(&RelativeVar);
297
298 // 参照を実体ポインタにする
299 op_mov_RM( sizeof(long), REG_ECX, REG_EAX, 0, MOD_BASE );
300 }
301 }
302 else{
303InClassMember:
304 if(dwFlags&PROCFLAG_NEW){
305 //New演算子によるコンストラクタ呼び出しの場合
306
307 //mov ecx,dword ptr[esp+ParmSize]
308 op_mov_RM( sizeof(long), REG_ECX, REG_ESP, ParmSize + tempSize, MOD_BASE_DISP32 );
309 }
310 else{
311 //Thisポインタをecxにコピー
312 SetThisPtrToReg(REG_ECX);
313 }
314 }
315
316 //push ecx
317 op_push(REG_ECX);
318 }
319
320 if( pUserProc->IsVirtual() ){
321 //仮想関数(オブジェクトメソッド)呼び出し
322 //pObj->func_table->func1
323 // ->func2
324 // ->func3
325
326 //mov edx,dword ptr[ecx]
327 OpBuffer[obp++]=(char)0x8B;
328 OpBuffer[obp++]=(char)0x11;
329
330 i2 = pobj_c->GetFuncNumInVtbl( pUserProc );
331
332 //call dword ptr[edx+func_index]
333 if(i2*PTR_SIZE<=0x7F){
334 OpBuffer[obp++]=(char)0xFF;
335 OpBuffer[obp++]=(char)0x52;
336 OpBuffer[obp++]=(char)(i2*PTR_SIZE);
337 }
338 else{
339 OpBuffer[obp++]=(char)0xFF;
340 OpBuffer[obp++]=(char)0x92;
341 *((long *)(OpBuffer+obp))=i2*PTR_SIZE;
342 obp+=sizeof(long);
343 }
344 }
345 else{
346 //通常呼び出し
347
348 //call ProcAddr
349 op_call(pUserProc);
350 }
351
352 if(pUserProc->IsCdecl()){
353 //add esp,ParmSize
354 op_add_esp(ParmSize);
355 }
356
357 //一時オブジェクトを破棄
358 pobj_parameter->DeleteTempParameters();
359
360 //パラメータオブジェクトを破棄
361 delete pobj_parameter;
362
363 return true;
364}
365
366bool Opcode_CallDllProc( const char *lpszParms, DllProc *pDllProc ){
367
368 extern BOOL bDebugCompile;
369 extern BOOL bDebugSupportProc;
370 if(bDebugCompile&&bDebugSupportProc==0&& pDllProc->IsEqualSymbol( "DebugBreak" ) ){
371 Call_DebugSys_SaveContext();
372 }
373
374
375 ////////////////////////
376 // パラメータのセット
377 ////////////////////////
378
379 //パラメータオブジェクトを生成
380 ParamImpl *pobj_parameter=0;
381 pobj_parameter=new ParamImpl(lpszParms);
382
383 // デフォルト引数を適用
384 pobj_parameter->ApplyDefaultParameters( pDllProc->Params() );
385
386 //エラーチェック
387 if( !pobj_parameter->ErrorCheck( pDllProc->GetName(), pDllProc->Params() ) ){
388 //パラメータにエラーがあるときは処理を終える
389 return false;
390 }
391
392 //一時オブジェクトを生成
393 pobj_parameter->NewTempParameters( pDllProc->GetName(), pDllProc->Params() );
394
395 //レジスタ、スタックフレームにセット
396 int ParmSize = pobj_parameter->SetParameter(pDllProc->GetName(), pDllProc->Params() );
397
398
399 //動的リンクされたプロシージャの呼び出し
400
401 //call dword ptr[LookupTable]
402 pDllProc->Using();
403 OpBuffer[obp++]=(char)0xFF;
404 OpBuffer[obp++]=(char)0x15;
405 pobj_ImportAddrSchedule->add(pDllProc);
406 obp+=sizeof(long);
407
408 if(pDllProc->IsCdecl()){
409 //add esp,ParmSize
410 op_add_esp(ParmSize);
411 }
412
413 //一時オブジェクトを破棄
414 pobj_parameter->DeleteTempParameters();
415
416 //パラメータオブジェクトを破棄
417 delete pobj_parameter;
418
419 return true;
420}
Note: See TracBrowser for help on using the repository browser.