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

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