source: dev/branches/egtra/ab5.0/abdev/BasicCompiler_Common/Subroutine.cpp

Last change on this file was 803, checked in by イグトランス (egtra), 14 years ago

Hashmapの実装にunorderedを用いるよう変更

File size: 11.3 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(const 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, int dwCallProcFlags )
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,dwCallProcFlags,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 *)malloc(lstrlen(ArrayElements)+(rightSide ? lstrlen(rightSide) : 0)+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 free(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)+(rightSide ? lstrlen(rightSide) : 0)+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 foreach (auto pUserProc, compiler.GetObjectModule().meta.GetUserProcs())
322 {
323 if( pUserProc->IsUsing() && pUserProc->IsCompiled() == false ){
324 return true;
325 }
326 }
327 return false;
328}
329
330void CompileBufferInProcedure( const UserProc &userProc ){
331 if( userProc.IsCompiled() ) return;
332
333 _compile_proc( &userProc );
334
335/*
336 // ログを履く
337 char temporary[8192];
338 temporary[0]=0;
339 lstrcat( temporary, "------------------------------------------------------------------\n" );
340 sprintf( temporary + lstrlen(temporary), "【 %s のコード情報】\n", userProc.GetFullName().c_str() );
341 sprintf( temporary + lstrlen(temporary), "code size: %d bytes\n", userProc.GetCodeSize() );
342 lstrcat( temporary, "------------------------------------------------------------------\n" );
343 lstrcat( temporary, "\n" );
344 Smoothie::Logger::Put( temporary );*/
345}
346void CompileLocal(){
347 if( compiler.IsDll() )
348 {
349 //DLLの場合はグローバル変数を初期化するための関数を一番初めにコンパイルする
350 const UserProc *pUserProc=GetSubHash("_System_InitDllGlobalVariables");
351 if(pUserProc){
352 CompileBufferInProcedure( *pUserProc );
353 }
354 else compiler.errorMessenger.Output(300,NULL,cp);
355 }
356 else
357 {
358 // グローバル領域を一番初めにコンパイルする
359 extern const UserProc *pSub_System_GlobalArea;
360 CompileBufferInProcedure( *pSub_System_GlobalArea );
361 }
362
363 //_System_TypeBase_InitializeUserTypesは一番最後にコンパイル
364 extern const UserProc *pSubStaticMethod_System_TypeBase_InitializeUserTypes;
365 pSubStaticMethod_System_TypeBase_InitializeUserTypes->CompleteCompile();
366
367 //_System_TypeBase_InitializeUserTypesForBaseTypeは一番最後にコンパイル
368 extern const UserProc *pSubStaticMethod_System_TypeBase_InitializeUserTypesForBaseType;
369 pSubStaticMethod_System_TypeBase_InitializeUserTypesForBaseType->CompleteCompile();
370
371 //_System_InitStaticLocalVariablesは一番最後にコンパイル
372 //※一般関数内の静的変数オブジェクトをすべて収集しなければならない
373 extern const UserProc *pSub_System_InitStaticLocalVariables;
374 pSub_System_InitStaticLocalVariables->CompleteCompile();
375
376 //_System_Call_Destructor_of_GlobalObjectは一番最後にコンパイル
377 extern const UserProc *pSub_System_Call_Destructor_of_GlobalObject;
378 pSub_System_Call_Destructor_of_GlobalObject->CompleteCompile();
379
380 // _System_CGarbageCollection.RegisterGlobalRootsは一番最後にコンパイル
381 extern const UserProc *pUserProc_System_CGarbageCollection_RegisterGlobalRoots;
382 pUserProc_System_CGarbageCollection_RegisterGlobalRoots->CompleteCompile();
383
384repeat:
385 foreach (auto pUserProc, compiler.GetObjectModule().meta.GetUserProcs())
386 {
387 CompileBufferInProcedure( *pUserProc );
388 }
389
390 if( IsNeedProcCompile() ){
391 //プロシージャコンパイルによって、プロシージャコンパイルが必要になる場合
392 goto repeat;
393 }
394
395 if( !compiler.IsSll() )
396 {
397 //_System_TypeBase_InitializeUserTypesは最後のほうでコンパイル
398 pSubStaticMethod_System_TypeBase_InitializeUserTypes->KillCompileStatus();
399 CompileBufferInProcedure( *pSubStaticMethod_System_TypeBase_InitializeUserTypes );
400
401 //_System_TypeBase_InitializeUserTypesForBaseTypeは最後のほうでコンパイル
402 pSubStaticMethod_System_TypeBase_InitializeUserTypesForBaseType->KillCompileStatus();
403 CompileBufferInProcedure( *pSubStaticMethod_System_TypeBase_InitializeUserTypesForBaseType );
404
405 if( IsNeedProcCompile() ){
406 //プロシージャコンパイルによって、プロシージャコンパイルが必要になる場合
407
408 foreach(auto pUserProc, compiler.GetObjectModule().meta.GetUserProcs())
409 {
410 CompileBufferInProcedure( *pUserProc );
411 }
412 }
413
414 //_System_InitStaticLocalVariablesは一番最後にコンパイル
415 pSub_System_InitStaticLocalVariables->KillCompileStatus();
416 CompileBufferInProcedure( *pSub_System_InitStaticLocalVariables );
417
418 //_System_Call_Destructor_of_GlobalObjectは一番最後にコンパイル
419 pSub_System_Call_Destructor_of_GlobalObject->KillCompileStatus();
420 CompileBufferInProcedure( *pSub_System_Call_Destructor_of_GlobalObject );
421
422 // _System_CGarbageCollection.RegisterGlobalRootsは一番最後にコンパイル
423 pUserProc_System_CGarbageCollection_RegisterGlobalRoots->KillCompileStatus();
424 CompileBufferInProcedure( *pUserProc_System_CGarbageCollection_RegisterGlobalRoots );
425 }
426}
Note: See TracBrowser for help on using the repository browser.