#include "stdafx.h" #ifdef _AMD64_ #include "../compiler_x64/opcode.h" #else #include "../compiler_x86/opcode.h" #endif int GetCallProcName(char *buffer,char *name){ int i2,i3,IsStr=0; for(i2=0;;i2++){ if(buffer[i2]=='\"') IsStr^=1; if(IsDBCSLeadByte(buffer[i2])){ name[i2]=buffer[i2]; i2++; name[i2]=buffer[i2]; continue; } if(buffer[i2]=='['&&IsStr==0){ i3=GetStringInBracket(name+i2,buffer+i2); i2+=i3-1; continue; } if(buffer[i2]=='('&&IsStr==0){ name[i2]=0; break; } if(buffer[i2]=='='&&IsStr==0){ name[i2]=0; break; } name[i2]=buffer[i2]; if(buffer[i2]=='\0') break; } return i2; } int GetProc(char *name,void **ppInfo){ //ユーザー定義関数 *ppInfo=(void *)GetSubHash(name); if(*ppInfo) return PROC_DEFAULT; //DLL関数 *ppInfo=(void *)GetDeclareHash(name); if(*ppInfo) return PROC_DLL; //コンパイラ埋め込み型 *ppInfo=(void *)(_int64)GetFunctionFromName(name); if(*ppInfo) return PROC_BUILTIN; ///////////////////////////////////////////////////////////////// //関数ポインタ、またはデリゲート ///////////////////////////////////////////////////////////////// Type type; if( !GetVarType( name, type, false ) ){ return 0; } if( type.IsProcPtr() ) { // 関数ポインタ return PROC_PTR; } if( type.IsDelegate() ) { // デリゲート return PROC_DELEGATE; } return 0; } void SplitObjectName(const char *name,char *ObjectName, ReferenceKind &referenceFind ) { referenceFind = RefNon; int i4; for(i4=lstrlen(name)-1;i4>=0;i4--){ if(name[i4]=='.'||(name[i4]==1&&name[i4+1]==ESC_PSMEM)) break; } if(i4==-1) ObjectName[0]=0; else{ //参照タイプを判別 if(name[i4]=='.') { referenceFind = RefDot; } else { referenceFind = RefPointer; } if(i4==0) GetWithName(ObjectName); else{ memcpy(ObjectName,name,i4); ObjectName[i4]=0; } } } bool CallProc( int kind, const void *pProc, const char *fullCallName, const char *lpszParms, const Type &baseType, Type &resultType, bool isCallOn ) { //GetSubHash内でエラー提示が行われた場合 if(pProc==(Procedure *)-1){ return false; } if(kind==PROC_DEFAULT){ ///////////////////// // ユーザー定義関数 ///////////////////// const UserProc *pUserProc = (const UserProc *)pProc; //オブジェクト名を取得 char ObjectName[VN_SIZE]; ReferenceKind referenceKind; SplitObjectName(fullCallName,ObjectName, referenceKind ); //////////////////////// // オーバーロードを解決 //////////////////////// std::vector subs; GetOverloadSubHash(fullCallName,subs); if(subs.size()){ //オーバーロードを解決 pUserProc=OverloadSolutionWithStrParam(fullCallName,subs,lpszParms,ObjectName); if(!pUserProc){ return false; } } resultType = pUserProc->ReturnType(); if( isCallOn ){ if( !Opcode_CallProc(lpszParms,pUserProc,0,ObjectName ) ){ return false; } } } else if(kind==PROC_DLL){ ///////////////////////// // DLL関数 ///////////////////////// DllProc *pDllProc = (DllProc *)pProc; resultType = pDllProc->ReturnType(); if( isCallOn ){ if( !Opcode_CallDllProc(lpszParms,pDllProc) ){ return false; } } } else if(kind==PROC_BUILTIN){ ///////////////////////// // 組み込み関数 ///////////////////////// int FuncId = (int)(_int64)pProc; if( !Opcode_CallFunc( lpszParms, FuncId, baseType, resultType, isCallOn ) ){ return false; } } else if(kind==PROC_PTR){ ///////////////// // 関数ポインタ ///////////////// Type type; GetVarType(fullCallName,type,false); ProcPointer *pProcPtr = compiler.GetObjectModule().meta.GetProcPointers()[type.GetIndex()]; resultType = pProcPtr->ReturnType(); if( isCallOn ){ if( !Opcode_CallProcPtr(fullCallName,lpszParms,pProcPtr) ){ return false; } } } else if( kind == PROC_DELEGATE ) { // デリゲート char tempName[VN_SIZE]; lstrcpy( tempName, fullCallName ); lstrcat( tempName, ".Call" ); void *pInfo=(void *)GetSubHash( tempName ); if( !pInfo ) { Jenga::Throw( "デリゲートの内部Callメソッドの取得に失敗" ); } return CallProc( PROC_DEFAULT, pInfo, tempName, lpszParms, baseType, resultType, isCallOn ); } else{ return false; } return true; } bool CallPropertyMethod( const char *variable, const char *rightSide, Type &resultType){ //プロパティ用のメソッドを呼び出す //配列要素を取得 char VarName[VN_SIZE],ArrayElements[VN_SIZE]; GetArrayElement(variable,VarName,ArrayElements); //オブジェクト名を取得 char ObjectName[VN_SIZE]; ReferenceKind referenceKind; SplitObjectName(VarName,ObjectName, referenceKind ); //オーバーロード用の関数リストを作成 std::vector subs; GetOverloadSubHash(VarName,subs); if(subs.size()==0){ return false; } //パラメータを整備 char *Parameter; Parameter=(char *)HeapAlloc(hHeap,0,lstrlen(ArrayElements)+lstrlen(rightSide)+32); lstrcpy(Parameter,ArrayElements); if(rightSide){ if(Parameter[0]&&rightSide[0]) lstrcat(Parameter,","); lstrcat(Parameter,rightSide); } //オーバーロードを解決 const UserProc *pUserProc = OverloadSolutionWithStrParam(VarName,subs,Parameter,ObjectName); if(pUserProc){ //呼び出し Opcode_CallProc(Parameter,pUserProc,0,ObjectName); resultType = pUserProc->ReturnType(); Type leftType; GetVarType( ObjectName, leftType, false ); // 型パラメータを解決 ResolveFormalGenericTypeParameter( resultType, leftType, pUserProc ); } HeapDefaultFree(Parameter); return true; } bool GetReturnTypeOfPropertyMethod( const char *variable, const char *rightSide, Type &resultType ){ //プロパティ用のメソッドを呼び出す //配列要素を取得 char VarName[VN_SIZE],ArrayElements[VN_SIZE]; GetArrayElement(variable,VarName,ArrayElements); //オブジェクト名を取得 char ObjectName[VN_SIZE]; ReferenceKind referenceKind; SplitObjectName(VarName,ObjectName, referenceKind ); //オーバーロード用の関数リストを作成 std::vector subs; GetOverloadSubHash(VarName,subs); if(subs.size()==0){ return 0; } //パラメータを整備 char *Parameter; Parameter=(char *)HeapAlloc(hHeap,0,lstrlen(ArrayElements)+lstrlen(rightSide)+32); lstrcpy(Parameter,ArrayElements); if(rightSide){ if(Parameter[0]&&rightSide[0]) lstrcat(Parameter,","); lstrcat(Parameter,rightSide); } //オーバーロードを解決 const UserProc *pUserProc = OverloadSolutionWithStrParam(VarName,subs,Parameter,ObjectName); if(pUserProc){ resultType = pUserProc->ReturnType(); } return 1; } //インデクサ(getter)の戻り値を取得 bool GetReturnTypeOfIndexerGetterProc( const Type &classType, Type &resultType ) { std::vector subs; classType.GetClass().GetDynamicMethods().Enum( CALC_ARRAY_GET, subs ); if( subs.size() == 0 ){ return false; } const UserProc *pUserProc = subs[0]; resultType = pUserProc->ReturnType(); // 型パラメータを解決 ResolveFormalGenericTypeParameter( resultType, classType, pUserProc ); return true; } bool IsNeedProcCompile(){ compiler.GetObjectModule().meta.GetUserProcs().Iterator_Reset(); while( compiler.GetObjectModule().meta.GetUserProcs().Iterator_HasNext() ) { UserProc *pUserProc = compiler.GetObjectModule().meta.GetUserProcs().Iterator_GetNext(); if( pUserProc->IsUsing() && pUserProc->IsCompiled() == false ){ return true; } } return false; } void CompileBufferInProcedure( const UserProc &userProc ){ if( userProc.IsCompiled() ) return; _compile_proc( &userProc ); /* // ログを履く char temporary[8192]; temporary[0]=0; lstrcat( temporary, "------------------------------------------------------------------\n" ); sprintf( temporary + lstrlen(temporary), "【 %s のコード情報】\n", userProc.GetFullName().c_str() ); sprintf( temporary + lstrlen(temporary), "code size: %d bytes\n", userProc.GetCodeSize() ); lstrcat( temporary, "------------------------------------------------------------------\n" ); lstrcat( temporary, "\n" ); Smoothie::Logger::Put( temporary );*/ } void CompileLocal(){ if( compiler.IsDll() ) { //DLLの場合はグローバル変数を初期化するための関数を一番初めにコンパイルする const UserProc *pUserProc=GetSubHash("_System_InitDllGlobalVariables"); if(pUserProc){ CompileBufferInProcedure( *pUserProc ); } else compiler.errorMessenger.Output(300,NULL,cp); } else { // グローバル領域を一番初めにコンパイルする extern const UserProc *pSub_System_GlobalArea; CompileBufferInProcedure( *pSub_System_GlobalArea ); } //_System_TypeBase_InitializeUserTypesは一番最後にコンパイル extern const UserProc *pSubStaticMethod_System_TypeBase_InitializeUserTypes; pSubStaticMethod_System_TypeBase_InitializeUserTypes->CompleteCompile(); //_System_TypeBase_InitializeUserTypesForBaseTypeは一番最後にコンパイル extern const UserProc *pSubStaticMethod_System_TypeBase_InitializeUserTypesForBaseType; pSubStaticMethod_System_TypeBase_InitializeUserTypesForBaseType->CompleteCompile(); //_System_InitStaticLocalVariablesは一番最後にコンパイル //※一般関数内の静的変数オブジェクトをすべて収集しなければならない extern const UserProc *pSub_System_InitStaticLocalVariables; pSub_System_InitStaticLocalVariables->CompleteCompile(); //_System_Call_Destructor_of_GlobalObjectは一番最後にコンパイル extern const UserProc *pSub_System_Call_Destructor_of_GlobalObject; pSub_System_Call_Destructor_of_GlobalObject->CompleteCompile(); // _System_CGarbageCollection.RegisterGlobalRootsは一番最後にコンパイル extern const UserProc *pUserProc_System_CGarbageCollection_RegisterGlobalRoots; pUserProc_System_CGarbageCollection_RegisterGlobalRoots->CompleteCompile(); repeat: compiler.GetObjectModule().meta.GetUserProcs().Iterator_Reset(); while( compiler.GetObjectModule().meta.GetUserProcs().Iterator_HasNext() ) { UserProc *pUserProc = compiler.GetObjectModule().meta.GetUserProcs().Iterator_GetNext(); CompileBufferInProcedure( *pUserProc ); } if( IsNeedProcCompile() ){ //プロシージャコンパイルによって、プロシージャコンパイルが必要になる場合 goto repeat; } if( !compiler.IsStaticLibrary() ) { //_System_TypeBase_InitializeUserTypesは最後のほうでコンパイル pSubStaticMethod_System_TypeBase_InitializeUserTypes->KillCompileStatus(); CompileBufferInProcedure( *pSubStaticMethod_System_TypeBase_InitializeUserTypes ); //_System_TypeBase_InitializeUserTypesForBaseTypeは最後のほうでコンパイル pSubStaticMethod_System_TypeBase_InitializeUserTypesForBaseType->KillCompileStatus(); CompileBufferInProcedure( *pSubStaticMethod_System_TypeBase_InitializeUserTypesForBaseType ); if( IsNeedProcCompile() ){ //プロシージャコンパイルによって、プロシージャコンパイルが必要になる場合 compiler.GetObjectModule().meta.GetUserProcs().Iterator_Reset(); while( compiler.GetObjectModule().meta.GetUserProcs().Iterator_HasNext() ) { UserProc *pUserProc = compiler.GetObjectModule().meta.GetUserProcs().Iterator_GetNext(); CompileBufferInProcedure( *pUserProc ); } } //_System_InitStaticLocalVariablesは一番最後にコンパイル pSub_System_InitStaticLocalVariables->KillCompileStatus(); CompileBufferInProcedure( *pSub_System_InitStaticLocalVariables ); //_System_Call_Destructor_of_GlobalObjectは一番最後にコンパイル pSub_System_Call_Destructor_of_GlobalObject->KillCompileStatus(); CompileBufferInProcedure( *pSub_System_Call_Destructor_of_GlobalObject ); // _System_CGarbageCollection.RegisterGlobalRootsは一番最後にコンパイル pUserProc_System_CGarbageCollection_RegisterGlobalRoots->KillCompileStatus(); CompileBufferInProcedure( *pUserProc_System_CGarbageCollection_RegisterGlobalRoots ); } }