source: dev/trunk/ab5.0/abdev/BasicCompiler_Common/Subroutine.cpp@ 648

Last change on this file since 648 was 608, checked in by dai_9181, 16 years ago

静的リンクライブラリプロジェクトの作成(IDE側)に対応。

File size: 11.7 KB
Line 
1#include "stdafx.h"
2
3#ifdef _AMD64_
4#include "../compiler_x64/opcode.h"
5#else
6#include "../compiler_x86/opcode.h"
7#endif
8
9int GetCallProcName(char *buffer,char *name){
10 int i2,i3,IsStr=0;
11
12 for(i2=0;;i2++){
13 if(buffer[i2]=='\"') IsStr^=1;
14 if(IsDBCSLeadByte(buffer[i2])){
15 name[i2]=buffer[i2];
16 i2++;
17 name[i2]=buffer[i2];
18 continue;
19 }
20 if(buffer[i2]=='['&&IsStr==0){
21 i3=GetStringInBracket(name+i2,buffer+i2);
22 i2+=i3-1;
23 continue;
24 }
25 if(buffer[i2]=='('&&IsStr==0){
26 name[i2]=0;
27 break;
28 }
29 if(buffer[i2]=='='&&IsStr==0){
30 name[i2]=0;
31 break;
32 }
33
34 name[i2]=buffer[i2];
35 if(buffer[i2]=='\0') break;
36 }
37 return i2;
38}
39
40int GetProc(char *name,void **ppInfo){
41
42 //ユーザー定義関数
43 *ppInfo=(void *)GetSubHash(name);
44 if(*ppInfo) return PROC_DEFAULT;
45
46 //DLL関数
47 *ppInfo=(void *)GetDeclareHash(name);
48 if(*ppInfo) return PROC_DLL;
49
50 //コンパイラ埋め込み型
51 *ppInfo=(void *)(_int64)GetFunctionFromName(name);
52 if(*ppInfo) return PROC_BUILTIN;
53
54
55 /////////////////////////////////////////////////////////////////
56 //関数ポインタ、またはデリゲート
57 /////////////////////////////////////////////////////////////////
58
59 Type type;
60 if( !GetVarType( name, type, false ) ){
61 return 0;
62 }
63
64 if( type.IsProcPtr() )
65 {
66 // 関数ポインタ
67 return PROC_PTR;
68 }
69
70 if( type.IsDelegate() )
71 {
72 // デリゲート
73 return PROC_DELEGATE;
74 }
75
76 return 0;
77}
78
79void SplitObjectName(const char *name,char *ObjectName, ReferenceKind &referenceFind )
80{
81 referenceFind = RefNon;
82
83 int i4;
84 for(i4=lstrlen(name)-1;i4>=0;i4--){
85 if(name[i4]=='.'||(name[i4]==1&&name[i4+1]==ESC_PSMEM))
86 break;
87 }
88 if(i4==-1) ObjectName[0]=0;
89 else{
90 //参照タイプを判別
91 if(name[i4]=='.')
92 {
93 referenceFind = RefDot;
94 }
95 else
96 {
97 referenceFind = RefPointer;
98 }
99
100 if(i4==0) GetWithName(ObjectName);
101 else{
102 memcpy(ObjectName,name,i4);
103 ObjectName[i4]=0;
104 }
105 }
106}
107
108bool CallProc( int kind, const void *pProc, const char *fullCallName, const char *lpszParms, const Type &baseType, Type &resultType, bool isCallOn )
109{
110 //GetSubHash内でエラー提示が行われた場合
111 if(pProc==(Procedure *)-1){
112 return false;
113 }
114
115 if(kind==PROC_DEFAULT){
116 /////////////////////
117 // ユーザー定義関数
118 /////////////////////
119
120 const UserProc *pUserProc = (const UserProc *)pProc;
121
122 //オブジェクト名を取得
123 char ObjectName[VN_SIZE];
124 ReferenceKind referenceKind;
125 SplitObjectName(fullCallName,ObjectName, referenceKind );
126
127
128 ////////////////////////
129 // オーバーロードを解決
130 ////////////////////////
131
132 std::vector<const UserProc *> subs;
133 GetOverloadSubHash(fullCallName,subs);
134 if(subs.size()){
135 //オーバーロードを解決
136 pUserProc=OverloadSolutionWithStrParam(fullCallName,subs,lpszParms,ObjectName);
137
138 if(!pUserProc){
139 return false;
140 }
141 }
142
143 resultType = pUserProc->ReturnType();
144
145 if( isCallOn ){
146 if( !Opcode_CallProc(lpszParms,pUserProc,0,ObjectName ) ){
147 return false;
148 }
149 }
150 }
151 else if(kind==PROC_DLL){
152 /////////////////////////
153 // DLL関数
154 /////////////////////////
155 DllProc *pDllProc = (DllProc *)pProc;
156
157 resultType = pDllProc->ReturnType();
158
159 if( isCallOn ){
160 if( !Opcode_CallDllProc(lpszParms,pDllProc) ){
161 return false;
162 }
163 }
164 }
165 else if(kind==PROC_BUILTIN){
166 /////////////////////////
167 // 組み込み関数
168 /////////////////////////
169 int FuncId = (int)(_int64)pProc;
170
171 if( !Opcode_CallFunc( lpszParms, FuncId, baseType, resultType, isCallOn ) ){
172 return false;
173 }
174 }
175 else if(kind==PROC_PTR){
176 /////////////////
177 // 関数ポインタ
178 /////////////////
179
180 Type type;
181 GetVarType(fullCallName,type,false);
182
183 ProcPointer *pProcPtr = compiler.GetObjectModule().meta.GetProcPointers()[type.GetIndex()];
184 resultType = pProcPtr->ReturnType();
185
186 if( isCallOn ){
187 if( !Opcode_CallProcPtr(fullCallName,lpszParms,pProcPtr) ){
188 return false;
189 }
190 }
191 }
192 else if( kind == PROC_DELEGATE )
193 {
194 // デリゲート
195 char tempName[VN_SIZE];
196 lstrcpy( tempName, fullCallName );
197 lstrcat( tempName, ".Call" );
198
199 void *pInfo=(void *)GetSubHash( tempName );
200 if( !pInfo )
201 {
202 Jenga::Throw( "デリゲートの内部Callメソッドの取得に失敗" );
203 }
204
205 return CallProc( PROC_DEFAULT, pInfo, tempName, lpszParms, baseType, resultType, isCallOn );
206 }
207 else{
208 return false;
209 }
210
211 return true;
212}
213bool CallPropertyMethod( const char *variable, const char *rightSide, Type &resultType){
214 //プロパティ用のメソッドを呼び出す
215
216 //配列要素を取得
217 char VarName[VN_SIZE],ArrayElements[VN_SIZE];
218 GetArrayElement(variable,VarName,ArrayElements);
219
220 //オブジェクト名を取得
221 char ObjectName[VN_SIZE];
222 ReferenceKind referenceKind;
223 SplitObjectName(VarName,ObjectName, referenceKind );
224
225 //オーバーロード用の関数リストを作成
226 std::vector<const UserProc *> subs;
227 GetOverloadSubHash(VarName,subs);
228 if(subs.size()==0){
229 return false;
230 }
231
232 //パラメータを整備
233 char *Parameter;
234 Parameter=(char *)HeapAlloc(hHeap,0,lstrlen(ArrayElements)+lstrlen(rightSide)+32);
235 lstrcpy(Parameter,ArrayElements);
236 if(rightSide){
237 if(Parameter[0]&&rightSide[0]) lstrcat(Parameter,",");
238 lstrcat(Parameter,rightSide);
239 }
240
241 //オーバーロードを解決
242 const UserProc *pUserProc = OverloadSolutionWithStrParam(VarName,subs,Parameter,ObjectName);
243
244 if(pUserProc){
245 //呼び出し
246 Opcode_CallProc(Parameter,pUserProc,0,ObjectName);
247
248 resultType = pUserProc->ReturnType();
249
250 Type leftType;
251 GetVarType( ObjectName, leftType, false );
252
253 // 型パラメータを解決
254 ResolveFormalGenericTypeParameter( resultType, leftType, pUserProc );
255 }
256
257 HeapDefaultFree(Parameter);
258
259 return true;
260}
261
262bool GetReturnTypeOfPropertyMethod( const char *variable, const char *rightSide, Type &resultType ){
263 //プロパティ用のメソッドを呼び出す
264
265 //配列要素を取得
266 char VarName[VN_SIZE],ArrayElements[VN_SIZE];
267 GetArrayElement(variable,VarName,ArrayElements);
268
269 //オブジェクト名を取得
270 char ObjectName[VN_SIZE];
271 ReferenceKind referenceKind;
272 SplitObjectName(VarName,ObjectName, referenceKind );
273
274 //オーバーロード用の関数リストを作成
275 std::vector<const UserProc *> subs;
276 GetOverloadSubHash(VarName,subs);
277 if(subs.size()==0){
278 return 0;
279 }
280
281 //パラメータを整備
282 char *Parameter;
283 Parameter=(char *)HeapAlloc(hHeap,0,lstrlen(ArrayElements)+lstrlen(rightSide)+32);
284 lstrcpy(Parameter,ArrayElements);
285 if(rightSide){
286 if(Parameter[0]&&rightSide[0]) lstrcat(Parameter,",");
287 lstrcat(Parameter,rightSide);
288 }
289
290 //オーバーロードを解決
291 const UserProc *pUserProc = OverloadSolutionWithStrParam(VarName,subs,Parameter,ObjectName);
292
293 if(pUserProc){
294 resultType = pUserProc->ReturnType();
295 }
296
297 return 1;
298}
299
300//インデクサ(getter)の戻り値を取得
301bool GetReturnTypeOfIndexerGetterProc( const Type &classType, Type &resultType )
302{
303 std::vector<const UserProc *> subs;
304 classType.GetClass().GetDynamicMethods().Enum( CALC_ARRAY_GET, subs );
305 if( subs.size() == 0 ){
306 return false;
307 }
308
309 const UserProc *pUserProc = subs[0];
310
311 resultType = pUserProc->ReturnType();
312
313
314 // 型パラメータを解決
315 ResolveFormalGenericTypeParameter( resultType, classType, pUserProc );
316
317 return true;
318}
319
320bool IsNeedProcCompile(){
321 compiler.GetObjectModule().meta.GetUserProcs().Iterator_Reset();
322 while( compiler.GetObjectModule().meta.GetUserProcs().Iterator_HasNext() )
323 {
324 UserProc *pUserProc = compiler.GetObjectModule().meta.GetUserProcs().Iterator_GetNext();
325 if( pUserProc->IsUsing() && pUserProc->IsCompiled() == false ){
326 return true;
327 }
328 }
329 return false;
330}
331
332void CompileBufferInProcedure( const UserProc &userProc ){
333 if( userProc.IsCompiled() ) return;
334
335 _compile_proc( &userProc );
336
337/*
338 // ログを履く
339 char temporary[8192];
340 temporary[0]=0;
341 lstrcat( temporary, "------------------------------------------------------------------\n" );
342 sprintf( temporary + lstrlen(temporary), "【 %s のコード情報】\n", userProc.GetFullName().c_str() );
343 sprintf( temporary + lstrlen(temporary), "code size: %d bytes\n", userProc.GetCodeSize() );
344 lstrcat( temporary, "------------------------------------------------------------------\n" );
345 lstrcat( temporary, "\n" );
346 Smoothie::Logger::Put( temporary );*/
347}
348void CompileLocal(){
349 if( compiler.IsDll() )
350 {
351 //DLLの場合はグローバル変数を初期化するための関数を一番初めにコンパイルする
352 const UserProc *pUserProc=GetSubHash("_System_InitDllGlobalVariables");
353 if(pUserProc){
354 CompileBufferInProcedure( *pUserProc );
355 }
356 else compiler.errorMessenger.Output(300,NULL,cp);
357 }
358 else
359 {
360 // グローバル領域を一番初めにコンパイルする
361 extern const UserProc *pSub_System_GlobalArea;
362 CompileBufferInProcedure( *pSub_System_GlobalArea );
363 }
364
365 //_System_TypeBase_InitializeUserTypesは一番最後にコンパイル
366 extern const UserProc *pSubStaticMethod_System_TypeBase_InitializeUserTypes;
367 pSubStaticMethod_System_TypeBase_InitializeUserTypes->CompleteCompile();
368
369 //_System_TypeBase_InitializeUserTypesForBaseTypeは一番最後にコンパイル
370 extern const UserProc *pSubStaticMethod_System_TypeBase_InitializeUserTypesForBaseType;
371 pSubStaticMethod_System_TypeBase_InitializeUserTypesForBaseType->CompleteCompile();
372
373 //_System_InitStaticLocalVariablesは一番最後にコンパイル
374 //※一般関数内の静的変数オブジェクトをすべて収集しなければならない
375 extern const UserProc *pSub_System_InitStaticLocalVariables;
376 pSub_System_InitStaticLocalVariables->CompleteCompile();
377
378 //_System_Call_Destructor_of_GlobalObjectは一番最後にコンパイル
379 extern const UserProc *pSub_System_Call_Destructor_of_GlobalObject;
380 pSub_System_Call_Destructor_of_GlobalObject->CompleteCompile();
381
382 // _System_CGarbageCollection.RegisterGlobalRootsは一番最後にコンパイル
383 extern const UserProc *pUserProc_System_CGarbageCollection_RegisterGlobalRoots;
384 pUserProc_System_CGarbageCollection_RegisterGlobalRoots->CompleteCompile();
385
386repeat:
387 compiler.GetObjectModule().meta.GetUserProcs().Iterator_Reset();
388 while( compiler.GetObjectModule().meta.GetUserProcs().Iterator_HasNext() )
389 {
390 UserProc *pUserProc = compiler.GetObjectModule().meta.GetUserProcs().Iterator_GetNext();
391 CompileBufferInProcedure( *pUserProc );
392 }
393
394 if( IsNeedProcCompile() ){
395 //プロシージャコンパイルによって、プロシージャコンパイルが必要になる場合
396 goto repeat;
397 }
398
399 if( !compiler.IsSll() )
400 {
401 //_System_TypeBase_InitializeUserTypesは最後のほうでコンパイル
402 pSubStaticMethod_System_TypeBase_InitializeUserTypes->KillCompileStatus();
403 CompileBufferInProcedure( *pSubStaticMethod_System_TypeBase_InitializeUserTypes );
404
405 //_System_TypeBase_InitializeUserTypesForBaseTypeは最後のほうでコンパイル
406 pSubStaticMethod_System_TypeBase_InitializeUserTypesForBaseType->KillCompileStatus();
407 CompileBufferInProcedure( *pSubStaticMethod_System_TypeBase_InitializeUserTypesForBaseType );
408
409 if( IsNeedProcCompile() ){
410 //プロシージャコンパイルによって、プロシージャコンパイルが必要になる場合
411
412 compiler.GetObjectModule().meta.GetUserProcs().Iterator_Reset();
413 while( compiler.GetObjectModule().meta.GetUserProcs().Iterator_HasNext() )
414 {
415 UserProc *pUserProc = compiler.GetObjectModule().meta.GetUserProcs().Iterator_GetNext();
416 CompileBufferInProcedure( *pUserProc );
417 }
418 }
419
420 //_System_InitStaticLocalVariablesは一番最後にコンパイル
421 pSub_System_InitStaticLocalVariables->KillCompileStatus();
422 CompileBufferInProcedure( *pSub_System_InitStaticLocalVariables );
423
424 //_System_Call_Destructor_of_GlobalObjectは一番最後にコンパイル
425 pSub_System_Call_Destructor_of_GlobalObject->KillCompileStatus();
426 CompileBufferInProcedure( *pSub_System_Call_Destructor_of_GlobalObject );
427
428 // _System_CGarbageCollection.RegisterGlobalRootsは一番最後にコンパイル
429 pUserProc_System_CGarbageCollection_RegisterGlobalRoots->KillCompileStatus();
430 CompileBufferInProcedure( *pUserProc_System_CGarbageCollection_RegisterGlobalRoots );
431 }
432}
Note: See TracBrowser for help on using the repository browser.