#include "stdafx.h" #include #include "../BasicCompiler_Common/common.h" #include "opcode.h" int ParamImpl::NewTempParameters( const string &procName, const Parameters ¶ms, int SecondParmNum ){ if( SecondParmNum == -1 ) SecondParmNum = (int)params.size(); /////////////////////////////////////////////////////// // 一時オブジェクトをあらかじめスタックに積んでおく /////////////////////////////////////////////////////// useTempObject = false; //一時参照の数 nCountOfTempObjects = 0; BOOL bEllipse; if(params.size()){ if(params[params.size()-1]->GetBasicType()==DEF_ELLIPSE) bEllipse=1; else bEllipse=0; } else bEllipse=0; for(int i2=ParmsNum-1;i2>=0;i2--){ useTempParameters[i2] = false; if(bEllipse&&i2<=(int)params.size()-2) bEllipse=0; if(i2==0){ if( params[i2]->GetVarName() == "_System_LocalThis" ){ //オブジェクトメンバの第一パラメータのThisポインタ continue; } } if( i2==0||i2==1 ){ if( params[i2]->GetVarName() == procName ){ //オブジェクトメンバの第一または第二パラメータの戻り値用オブジェクト continue; } } Type dummyType; BOOL bByVal; if(bEllipse){ NumOpe_GetType( Parms[i2], Type(), dummyType ); bByVal=1; } else{ dummyType = *params[i2]; bByVal = ( params[i2]->IsRef() == false ) ? TRUE:FALSE; } if( !bByVal ){ //ポインタ参照 if(Parms[i2][0]==1&&Parms[i2][1]==ESC_BYVAL){ //ポインタ指定 continue; } if( !GetVarType( Parms[i2], Type(), FALSE ) ){ //変数ではないとき Type calcType; NumOpe( Parms[i2], dummyType, calcType ); //↑ここでスタックに積む nCountOfTempObjects++; if( !calcType.IsStruct() ){ //一時参照を作成 //push esp compiler.codeGenerator.op_push( REG_ESP ); nCountOfTempObjects++; } bool result = CheckDifferentType( dummyType, calcType, procName.c_str(), i2); if( result ){ useTempParameters[i2] = true; useTempObject = true; types[i2] = calcType; } } } } return nCountOfTempObjects * PTR_SIZE; } void ParamImpl::DeleteTempParameters(){ /////////////////////////////////////////////////////// // 一時オブジェクトを破棄 /////////////////////////////////////////////////////// if( !useTempObject ) return; for(int i2=ParmsNum-1;i2>=0;i2--){ if( useTempParameters[i2] ){ if( types[i2].IsStruct() ){ // 構造体の一時メモリ //メモリを解放する //call free extern const UserProc *pSub_free; compiler.codeGenerator.op_call(pSub_free); } else{ if( types[i2].Is64() ){ //pop ... 参照を消す //pop ... 上位32ビット //pop ... 下位32ビット compiler.codeGenerator.op_add_esp( PTR_SIZE * 3 ); } else{ //pop ... 参照を消す //pop ... 値を消す compiler.codeGenerator.op_add_esp( PTR_SIZE * 2 ); } } } } } void ParamImpl::SetStructParameter( const Type &baseType, const char *expression ){ int object_size = baseType.GetClass().GetSize(); //push object_size compiler.codeGenerator.op_push_V(object_size); //call calloc extern const UserProc *pSub_calloc; compiler.codeGenerator.op_call(pSub_calloc); //push eax(ここでプッシュされた値が実際にパラメータとして引き渡される) compiler.codeGenerator.op_push(REG_EAX); //push eax compiler.codeGenerator.op_push(REG_EAX); Type calcType; BOOL bUseHeap; NumOpe( expression, baseType, calcType, &bUseHeap ); // ※スタックにある二つのデータ(コピー先、コピー元)の値を必要とする SetStructVariable( baseType, calcType, bUseHeap ); } int ParamImpl::SetParameter( const string &procName, const Parameters ¶ms, int SecondParmNum ){ if( SecondParmNum == -1 ) SecondParmNum = (int)params.size(); /////////////////////////////////////////////////////////// // パラメータをレジスタ及びスタックフレームにセット /////////////////////////////////////////////////////////// int i2,i3; BOOL bEllipse; if( params.size() ){ if(params[params.size()-1]->GetBasicType()==DEF_ELLIPSE) bEllipse=1; else bEllipse=0; } else bEllipse=0; BOOL bHas_System_LocalThis=0; if(ParmsNum>=1){ if( params[0]->GetVarName() == "_System_LocalThis" ){ bHas_System_LocalThis=1; } } //戻り値用の変数名を取得 const char *lpszVarNameToReturn = (procName[0]==1&&procName[1]==ESC_OPERATOR)?"_System_ReturnValue":procName.c_str(); //パラメータをレジスタとスタックに格納 int ParmSize=0; RELATIVE_VAR RelativeVar; int nCountOfNowTempObjects = 0; for(i2=ParmsNum-1;i2>=0;i2--){ if(bEllipse&&i2<=(int)params.size()-2) bEllipse=0; if(i2==0){ if( params[i2]->GetVarName() == "_System_LocalThis" ){ //オブジェクトメンバの第一パラメータのThisポインタ continue; } } if(i2==0||i2==1){ if( params[i2]->GetVarName() == lpszVarNameToReturn ){ //オブジェクトメンバの第一または第二パラメータの戻り値用オブジェクト continue; } } Type dummyType; BOOL bByVal; if(bEllipse){ NumOpe_GetType( Parms[i2], Type(), dummyType ); bByVal=1; } else{ dummyType = *params[i2]; bByVal = ( params[i2]->IsRef() == false ) ? TRUE:FALSE; ///////////////////////////////////////////////////////// // ☆★☆ ジェネリクスサポート ☆★☆ if( dummyType.IsTypeParameter() ) { // 型パラメータだったとき int ptrLevel = PTR_LEVEL( dummyType.GetBasicType() ); if( leftType.HasActualGenericType() ) { // TODO: GetDummyActualGenericTypeを適切な形に実装し直す dummyType = leftType.GetDummyActualGenericType(); } else { // TODO: ベースオブジェクト(指定されていないときはObjectクラス)にセットする dummyType.SetBasicType( DEF_OBJECT ); } for( int i=0; i