#include "stdafx.h" #include void CodeGenerator::ResolveExitSubSchedule() { BOOST_FOREACH( long exitSubCodePosition, exitSubCodePositions ) { pNativeCode->Overwrite( exitSubCodePosition, (long)( pNativeCode->GetSize()-(exitSubCodePosition+sizeof(long)) ) ); } // TODO: 未完成 BOOST_FOREACH( long exitSubCodePositionOld, _exitSubCodePositions_ObpOld ) { extern int obp; pNativeCode->OverwriteOld( exitSubCodePositionOld, (long)( obp-(exitSubCodePositionOld+sizeof(long)) ) ); } } void CodeGenerator::CheckUnresolveSchedule() { if( pertialSchedules.size() > 0 ) { SetError(); } } void CodeGenerator::opfix( const PertialSchedule *pPertialSchedule, long newValue ) { bool isSuccessful = false; PertialSchedules::iterator it = pertialSchedules.begin(); while( it != pertialSchedules.end() ) { if( (*it) == pPertialSchedule ) { if( pPertialSchedule->GetTypeSize() == sizeof(char) ) { if( newValue < -128 || 127 < newValue ) { // 範囲外 SetError(); } pNativeCode->Overwrite( pPertialSchedule->GetCodePos(), (char)newValue ); // TODO: 未完成(用が無くなったら消す) pNativeCode->OverwriteOld( pPertialSchedule->GetObpOld(), (char)newValue ); } else if( pPertialSchedule->GetTypeSize() == sizeof(long) ) { pNativeCode->Overwrite( pPertialSchedule->GetCodePos(), newValue ); // TODO: 未完成(用が無くなったら消す) pNativeCode->OverwriteOld( pPertialSchedule->GetObpOld(), newValue ); } else { SetError(); } it = pertialSchedules.erase( it ); delete pPertialSchedule; isSuccessful = true; break; } else { it++; } } if( isSuccessful == false ) { SetError(); } } void CodeGenerator::opfix_offset( const PertialSchedule *pPertialSchedule, long offset ) { bool isSuccessful = false; PertialSchedules::iterator it = pertialSchedules.begin(); while( it != pertialSchedules.end() ) { if( (*it) == pPertialSchedule ) { if( pPertialSchedule->GetTypeSize() == sizeof(long) ) { pNativeCode->Overwrite( pPertialSchedule->GetCodePos(), pNativeCode->GetLong(pPertialSchedule->GetCodePos()) + offset ); // TODO: 未完成(用が無くなったら消す) pNativeCode->OverwriteOld( pPertialSchedule->GetObpOld(), pNativeCode->_GetLong_ObpOld(pPertialSchedule->GetObpOld()) + offset ); } else { SetError(); } it = pertialSchedules.erase( it ); delete pPertialSchedule; isSuccessful = true; break; } else { it++; } } if( isSuccessful == false ) { SetError(); } } // 分岐関連 void CodeGenerator::opfix_JmpPertialSchedule( const PertialSchedule *pPertialSchedule ) { bool isSuccessful = false; PertialSchedules::iterator it = pertialSchedules.begin(); while( it != pertialSchedules.end() ) { if( (*it) == pPertialSchedule ) { long newValue = pNativeCode->GetSize() - (pPertialSchedule->GetCodePos()+pPertialSchedule->GetTypeSize()); extern int obp; long newValueOld = obp - (pPertialSchedule->GetObpOld()+pPertialSchedule->GetTypeSize()); if( pPertialSchedule->GetTypeSize() == sizeof(char) ) { if( newValue < -128 || 127 < newValue ) { // 範囲外 SetError(); } pNativeCode->Overwrite( pPertialSchedule->GetCodePos(), (char)newValue ); // TODO: 未完成(用が無くなったら消す) pNativeCode->OverwriteOld( pPertialSchedule->GetObpOld(), (char)newValueOld ); } else if( pPertialSchedule->GetTypeSize() == sizeof(long) ) { pNativeCode->Overwrite( pPertialSchedule->GetCodePos(), newValue ); // TODO: 未完成(用が無くなったら消す) pNativeCode->OverwriteOld( pPertialSchedule->GetObpOld(), newValueOld ); } else { SetError(); } it = pertialSchedules.erase( it ); delete pPertialSchedule; isSuccessful = true; } else { it++; } } if( isSuccessful == false ) { SetError(); } } const PertialSchedule *CodeGenerator::__jmp_op_format( char opcode, long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset ) { long beginCodePos = pNativeCode->GetSize(); { // TODO: 未完成 extern int obp; beginCodePos = obp; } if( opcode == (char)0xEB ) { // jmp命令のとき if( op_size == sizeof(char) ) { pNativeCode->Put( (char)opcode ); } else if( op_size == sizeof(long) ) { pNativeCode->Put( (char)0xE9 ); } else { SetError(); } } else { if( op_size == sizeof(char) ) { pNativeCode->Put( (char)((char)0x70 | opcode) ); } else if( op_size == sizeof(long) ) { pNativeCode->Put( (char)0x0F ); pNativeCode->Put( (char)((char)0x80 | opcode) ); } else { SetError(); } } const PertialSchedule *pPertialSchedule = NULL; if( isPertialSchedule ) { pertialSchedules.push_back( new PertialSchedule( pNativeCode->GetSize(), op_size ) ); pPertialSchedule = pertialSchedules.back(); } if( isSelfOpcodeOffset ) { // 自分自身の命令サイズを考慮する場合 //offset += ( pNativeCode->GetSize() - beginCodePos ) + op_size; // TODO: 未完成 extern int obp; offset -= ( obp - beginCodePos ) + op_size; } if( op_size == sizeof(char) ) { pNativeCode->Put( (char)offset ); } else if( op_size == sizeof(long) ) { pNativeCode->Put( offset ); } else { SetError(); } return pPertialSchedule; } const PertialSchedule *CodeGenerator::op_jle( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset ) { return __jmp_op_format( (char)0x0E, offset, op_size, isPertialSchedule, isSelfOpcodeOffset ); } const PertialSchedule *CodeGenerator::op_jbe( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset ) { return __jmp_op_format( (char)0x06, offset, op_size, isPertialSchedule, isSelfOpcodeOffset ); } const PertialSchedule *CodeGenerator::op_jge( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset ) { return __jmp_op_format( (char)0x0D, offset, op_size, isPertialSchedule, isSelfOpcodeOffset ); } const PertialSchedule *CodeGenerator::op_jae( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset ) { return __jmp_op_format( (char)0x03, offset, op_size, isPertialSchedule, isSelfOpcodeOffset ); } const PertialSchedule *CodeGenerator::op_jl( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset ) { return __jmp_op_format( (char)0x0C, offset, op_size, isPertialSchedule, isSelfOpcodeOffset ); } const PertialSchedule *CodeGenerator::op_jb( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset ) { return __jmp_op_format( (char)0x02, offset, op_size, isPertialSchedule, isSelfOpcodeOffset ); } const PertialSchedule *CodeGenerator::op_jg( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset ) { return __jmp_op_format( (char)0x0F, offset, op_size, isPertialSchedule, isSelfOpcodeOffset ); } const PertialSchedule *CodeGenerator::op_ja( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset ) { return __jmp_op_format( (char)0x07, offset, op_size, isPertialSchedule, isSelfOpcodeOffset ); } const PertialSchedule *CodeGenerator::op_jne( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset ) { return __jmp_op_format( (char)0x05, offset, op_size, isPertialSchedule, isSelfOpcodeOffset ); } const PertialSchedule *CodeGenerator::op_je( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset ) { return __jmp_op_format( (char)0x04, offset, op_size, isPertialSchedule, isSelfOpcodeOffset ); } const PertialSchedule *CodeGenerator::op_jmp( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset ) { return __jmp_op_format( (char)0xEB, offset, op_size, isPertialSchedule, isSelfOpcodeOffset ); } void CodeGenerator::op_jmp_continue() { //op_jmp( GetContinueCodePos()-(pNativeCode->GetSize()+sizeof(long)), sizeof(long) ); // TODO: 未完成(OpBuffer/obp廃止が整ったら上記のコードを有効にすべし) if( GetContinueCodePosOld() == -1 ) { SetError(12,"Continue",cp); return; } extern int obp; op_jmp( GetContinueCodePosOld()-obp, sizeof(long), false, true ); } void CodeGenerator::op_jmp_exitsub() { // オペコード pNativeCode->Put( (char)0xE9 ); exitSubCodePositions.push_back( pNativeCode->GetSize() ); extern int obp; _exitSubCodePositions_ObpOld.push_back( obp ); pNativeCode->Put( (long)0 ); } void CodeGenerator::op_jmp_goto_schedule( const std::string &name, int lineNum, int sourceCodePos ) { // オペコード pNativeCode->Put( (char)0xE9 ); const GotoLabelSchedule *pGotoLabelSchedule = NULL; if( name.size() == 0 ) { pGotoLabelSchedule = new GotoLabelSchedule( name, pNativeCode->GetSize(), sourceCodePos ); } else { pGotoLabelSchedule = new GotoLabelSchedule( name, pNativeCode->GetSize(), sourceCodePos ); } gotoLabelSchedules.push_back( pGotoLabelSchedule ); pertialSchedules.push_back( pGotoLabelSchedule ); pNativeCode->Put( (long)0 ); }