void CWin32EmbedServer::WriteInterfaceToConsole() { Framework::CMemStream marshalStream; { auto comStream = Framework::Win32::CComPtr<Framework::Win32::CComStreamAdapter>( new Framework::Win32::CComStreamAdapter(marshalStream)); DWORD dstContext = 0; HRESULT result = S_OK; result = CoMarshalInterface(comStream, IID_IEmbedApplication, this, MSHCTX_LOCAL, NULL, 0); assert(SUCCEEDED(result)); } { BOOL result = FALSE; DWORD numberWritten = 0; HANDLE stdoutHandle = GetStdHandle(STD_OUTPUT_HANDLE); assert(stdoutHandle != 0); DWORD marshalSize = marshalStream.GetLength(); result = WriteFile(stdoutHandle, &marshalSize, sizeof(DWORD), &numberWritten, nullptr); assert(result); assert(numberWritten == sizeof(DWORD)); result = WriteFile(stdoutHandle, marshalStream.GetBuffer(), marshalSize, &numberWritten, nullptr); assert(result); assert(numberWritten == marshalSize); } }
void CMemAccessRefTest::Compile(Jitter::CJitter& jitter) { Framework::CMemStream codeStream; jitter.SetStream(&codeStream); jitter.Begin(); { //Read ref test { jitter.PushRelRef(offsetof(CONTEXT, memory)); jitter.PushCst(LOAD_IDX * sizeof(void*)); jitter.AddRef(); jitter.LoadRefFromRef(); jitter.LoadFromRef(); jitter.PullRel(offsetof(CONTEXT, readValueResult)); } EmitNullTest(jitter, NULLCHECK_IDX, offsetof(CONTEXT, nullCheck0)); EmitNullTest(jitter, LOAD_IDX, offsetof(CONTEXT, nullCheck1)); EmitNullComparison(jitter, NULLCHECK_IDX, offsetof(CONTEXT, nullCheck2)); EmitNullComparison(jitter, LOAD_IDX, offsetof(CONTEXT, nullCheck3)); } jitter.End(); m_function = CMemoryFunction(codeStream.GetBuffer(), codeStream.GetSize()); }
void CFpIntMixTest::Compile(Jitter::CJitter& jitter) { Framework::CMemStream codeStream; jitter.SetStream(&codeStream); jitter.Begin(); { //number1 = 100.f jitter.PushCst(0x42C80000); jitter.PullRel(offsetof(CONTEXT, number1)); //number2 = toFloat(multiplier) jitter.FP_PushWord(offsetof(CONTEXT, multiplier)); jitter.FP_PullSingle(offsetof(CONTEXT, number2)); //number1 = number1 * number2 jitter.FP_PushSingle(offsetof(CONTEXT, number1)); jitter.FP_PushSingle(offsetof(CONTEXT, number2)); jitter.FP_Mul(); jitter.FP_PullSingle(offsetof(CONTEXT, number1)); //number1 = toInt(number1) jitter.FP_PushSingle(offsetof(CONTEXT, number1)); jitter.FP_PullWordTruncate(offsetof(CONTEXT, number1)); //result = number1 jitter.PushRel(offsetof(CONTEXT, number1)); jitter.PullRel(offsetof(CONTEXT, result)); } jitter.End(); m_function = CMemoryFunction(codeStream.GetBuffer(), codeStream.GetSize()); }
CDialog::CDialog(const TCHAR* resourceName, HWND parentWnd) : m_isModal(false) { DIALOGTEMPLATE dialogTemplate; { HRSRC resourceSrc = FindResource(GetModuleHandle(NULL), resourceName, RT_DIALOG); DWORD resourceSize = SizeofResource(GetModuleHandle(NULL), resourceSrc); HGLOBAL resourceHandle = LoadResource(GetModuleHandle(NULL), resourceSrc); DLGTEMPLATE* dialogTemplateSrc = reinterpret_cast<DLGTEMPLATE*>(LockResource(resourceHandle)); Framework::CPtrStream dialogTemplateStream(dialogTemplateSrc, resourceSize); dialogTemplate = ReadDialogTemplate(dialogTemplateStream); UnlockResource(resourceHandle); } NONCLIENTMETRICS metrics; CDefaultFonts::GetNonClientMetrics(metrics); dialogTemplate.pointsize = -MulDiv(metrics.lfMessageFont.lfHeight, 72, GetDeviceCaps(GetDC(NULL), LOGPIXELSY)); dialogTemplate.weight = static_cast<WORD>(metrics.lfMessageFont.lfWeight); dialogTemplate.italic = metrics.lfMessageFont.lfItalic; dialogTemplate.charset = metrics.lfMessageFont.lfCharSet; dialogTemplate.typeface = metrics.lfMessageFont.lfFaceName; { Framework::CMemStream dialogTemplateStream; WriteDialogTemplate(dialogTemplate, dialogTemplateStream); m_hWnd = CreateDialogIndirect(GetModuleHandle(NULL), reinterpret_cast<LPDLGTEMPLATE>(dialogTemplateStream.GetBuffer()), parentWnd, &CDialog::DialogProc); } }
void CAliasTest2::Compile(Jitter::CJitter& jitter) { Framework::CMemStream codeStream; jitter.SetStream(&codeStream); jitter.Begin(); { jitter.PushCst(CONSTANT_1); jitter.PullRel(offsetof(CONTEXT, value1[0])); jitter.PushCst(CONSTANT_2); jitter.PullRel(offsetof(CONTEXT, value1[1])); jitter.PushCst(CONSTANT_3); jitter.PullRel(offsetof(CONTEXT, value1[2])); jitter.PushCst(CONSTANT_4); jitter.PullRel(offsetof(CONTEXT, value1[3])); jitter.MD_PushRel(offsetof(CONTEXT, value2)); jitter.MD_PushRelExpand(offsetof(CONTEXT, value1[2])); jitter.MD_AddS(); jitter.MD_PullRel(offsetof(CONTEXT, value1), true, true, true, false); //Here value1 should be (3, 3, 3, 4) jitter.MD_PushRel(offsetof(CONTEXT, value2)); jitter.MD_PushRelExpand(offsetof(CONTEXT, value1[2])); jitter.MD_AddS(); jitter.MD_PullRel(offsetof(CONTEXT, value3)); //Here value3 should be (4, 4, 4, 4) } jitter.End(); m_function = CMemoryFunction(codeStream.GetBuffer(), codeStream.GetSize()); }
void CMdTest::Compile(Jitter::CJitter& jitter) { Framework::CMemStream codeStream; jitter.SetStream(&codeStream); jitter.Begin(); { jitter.MD_PushRel(offsetof(CONTEXT, src1)); jitter.MD_PullRel(offsetof(CONTEXT, dstMov)); //Shifts jitter.MD_PushRel(offsetof(CONTEXT, src0)); jitter.MD_PushRel(offsetof(CONTEXT, src1)); jitter.PushCst(48); jitter.MD_Srl256(); jitter.MD_PullRel(offsetof(CONTEXT, dstSrl256_1)); jitter.MD_PushRel(offsetof(CONTEXT, src0)); jitter.MD_PushRel(offsetof(CONTEXT, src1)); jitter.PushRel(offsetof(CONTEXT, shiftAmount)); jitter.MD_Srl256(); jitter.MD_PullRel(offsetof(CONTEXT, dstSrl256_2)); //Packs jitter.MD_PushRel(offsetof(CONTEXT, src0)); jitter.MD_PushRel(offsetof(CONTEXT, src1)); jitter.MD_PackHB(); jitter.MD_PullRel(offsetof(CONTEXT, dstPackHB)); jitter.MD_PushRel(offsetof(CONTEXT, src0)); jitter.MD_PushRel(offsetof(CONTEXT, src1)); jitter.MD_PackWH(); jitter.MD_PullRel(offsetof(CONTEXT, dstPackWH)); //Aliased packs jitter.MD_PushRel(offsetof(CONTEXT, dstPackHBAlias)); jitter.MD_PushRel(offsetof(CONTEXT, src1)); jitter.MD_PackHB(); jitter.MD_PullRel(offsetof(CONTEXT, dstPackHBAlias)); jitter.MD_PushRel(offsetof(CONTEXT, dstPackWHAlias)); jitter.MD_PushRel(offsetof(CONTEXT, src1)); jitter.MD_PackWH(); jitter.MD_PullRel(offsetof(CONTEXT, dstPackWHAlias)); } jitter.End(); m_function = CMemoryFunction(codeStream.GetBuffer(), codeStream.GetSize()); }
void CSimpleMdTest::Compile(Jitter::CJitter& jitter) { Framework::CMemStream codeStream; jitter.SetStream(&codeStream); jitter.Begin(); { jitter.MD_PushRel(offsetof(CONTEXT, op1)); jitter.MD_PushRel(offsetof(CONTEXT, op2)); jitter.MD_AddW(); jitter.MD_PullRel(offsetof(CONTEXT, result)); } jitter.End(); m_function = CMemoryFunction(codeStream.GetBuffer(), codeStream.GetSize()); }
unsigned int CompileFunction(CPsfVm& virtualMachine, CMipsJitter* jitter, const std::vector<uint32>& blockCode, Jitter::CObjectFile& objectFile, const std::string& functionName, uint32 begin, uint32 end) { auto& context = virtualMachine.GetCpu(); uint8* ram = virtualMachine.GetRam(); for(uint32 address = begin; address <= end; address += 4) { *reinterpret_cast<uint32*>(&ram[address]) = blockCode[(address - begin) / 4]; } { Framework::CMemStream outputStream; Jitter::CObjectFile::INTERNAL_SYMBOL func; jitter->GetCodeGen()->SetExternalSymbolReferencedHandler( [&] (void* symbol, uint32 offset) { Jitter::CObjectFile::SYMBOL_REFERENCE ref; ref.offset = offset; ref.type = Jitter::CObjectFile::SYMBOL_TYPE_EXTERNAL; ref.symbolIndex = objectFile.GetExternalSymbolIndexByValue(symbol); func.symbolReferences.push_back(ref); } ); jitter->SetStream(&outputStream); jitter->Begin(); for(uint32 address = begin; address <= end; address += 4) { context.m_pArch->CompileInstruction(address, jitter, &context); //Sanity check assert(jitter->IsStackEmpty()); } jitter->End(); func.name = functionName; func.data = std::vector<uint8>(outputStream.GetBuffer(), outputStream.GetBuffer() + outputStream.GetSize()); func.location = Jitter::CObjectFile::INTERNAL_SYMBOL_LOCATION_TEXT; return objectFile.AddInternalSymbol(func); } }
bool CPacketUtils::HasPacket(Framework::CMemStream& stream) { if (stream.GetSize() < sizeof(PACKETHEADER)) { return false; } stream.Seek(0, Framework::STREAM_SEEK_SET); PACKETHEADER header; stream.Read(&header, sizeof(PACKETHEADER)); stream.Seek(0, Framework::STREAM_SEEK_END); if (stream.GetSize() < header.packetSize) { return false; } return true; }
void CMemAccessTest::Compile(Jitter::CJitter& jitter) { Framework::CMemStream codeStream; jitter.SetStream(&codeStream); jitter.Begin(); { //Store test jitter.PushRelRef(offsetof(CONTEXT, memory)); jitter.PushRel(offsetof(CONTEXT, offset)); jitter.AddRef(); jitter.PushCst(CONSTANT_1); jitter.StoreAtRef(); //Read test jitter.PushRelRef(offsetof(CONTEXT, memory)); jitter.PushCst(0x08); jitter.AddRef(); jitter.LoadFromRef(); jitter.PullRel(offsetof(CONTEXT, result0)); //Write array test jitter.PushRelAddrRef(offsetof(CONTEXT, array0)); jitter.PushCst(ARRAY_IDX_0 * 4); jitter.AddRef(); jitter.PushCst(CONSTANT_2); jitter.StoreAtRef(); //Read array test jitter.PushRelAddrRef(offsetof(CONTEXT, array0)); jitter.PushCst(ARRAY_IDX_1 * 4); jitter.AddRef(); jitter.LoadFromRef(); jitter.PullRel(offsetof(CONTEXT, result1)); } jitter.End(); m_function = CMemoryFunction(codeStream.GetBuffer(), codeStream.GetSize()); }
std::string CEmbedRemoteCall::ToString() const { auto rpcParamsNode = new Framework::Xml::CNode("Params", true); for(const auto& param : m_params) { auto rpcParamNode = new Framework::Xml::CNode("Param", true); rpcParamNode->InsertAttribute(Framework::Xml::CreateAttributeStringValue("Name", param.first.c_str())); rpcParamNode->InsertAttribute(Framework::Xml::CreateAttributeStringValue("Value", param.second.c_str())); rpcParamsNode->InsertNode(rpcParamNode); } auto rpcNode = std::make_unique<Framework::Xml::CNode>("Call", true); rpcNode->InsertAttribute(Framework::Xml::CreateAttributeStringValue("Method", m_method.c_str())); rpcNode->InsertNode(rpcParamsNode); Framework::CMemStream rpcNodeStream; Framework::Xml::CWriter::WriteDocument(rpcNodeStream, rpcNode.get()); return std::string(rpcNodeStream.GetBuffer(), rpcNodeStream.GetBuffer() + rpcNodeStream.GetSize()); }
void CAlu64Test::Compile(Jitter::CJitter& jitter) { Framework::CMemStream codeStream; jitter.SetStream(&codeStream); jitter.Begin(); { jitter.PushRel64(offsetof(CONTEXT, value0)); jitter.PushRel64(offsetof(CONTEXT, value1)); jitter.Add64(); jitter.PullRel64(offsetof(CONTEXT, resultAdd0)); jitter.PushRel64(offsetof(CONTEXT, value2)); jitter.PushRel64(offsetof(CONTEXT, value3)); jitter.Add64(); jitter.PullRel64(offsetof(CONTEXT, resultAdd1)); jitter.PushRel64(offsetof(CONTEXT, value0)); jitter.PushCst64(CONSTANT_5); jitter.Add64(); jitter.PullRel64(offsetof(CONTEXT, resultAddCst)); jitter.PushRel64(offsetof(CONTEXT, value0)); jitter.PushRel64(offsetof(CONTEXT, value1)); jitter.Sub64(); jitter.PullRel64(offsetof(CONTEXT, resultSub0)); jitter.PushRel64(offsetof(CONTEXT, value2)); jitter.PushRel64(offsetof(CONTEXT, value3)); jitter.Sub64(); jitter.PullRel64(offsetof(CONTEXT, resultSub1)); jitter.PushCst64(CONSTANT_5); jitter.PushRel64(offsetof(CONTEXT, value0)); jitter.Sub64(); jitter.PullRel64(offsetof(CONTEXT, resultSubCst)); } jitter.End(); m_function = CMemoryFunction(codeStream.GetBuffer(), codeStream.GetSize()); }
void CMdMemAccessTest::Compile(Jitter::CJitter& jitter) { Framework::CMemStream codeStream; jitter.SetStream(&codeStream); jitter.Begin(); { jitter.PushRelRef(offsetof(CONTEXT, array)); jitter.MD_LoadFromRef(); jitter.MD_PullRel(offsetof(CONTEXT, result)); jitter.PushRelRef(offsetof(CONTEXT, array)); jitter.PushCst(0x10); jitter.AddRef(); jitter.MD_PushRel(offsetof(CONTEXT, op)); jitter.MD_StoreAtRef(); } jitter.End(); m_function = CMemoryFunction(codeStream.GetBuffer(), codeStream.GetSize()); }
std::vector<uint8> CPacketUtils::ReadPacket(Framework::CMemStream& stream) { std::vector<uint8> result; if(!CPacketUtils::HasPacket(stream)) { assert(0); return result; } stream.Seek(0, Framework::STREAM_SEEK_SET); PACKETHEADER header; stream.Read(&header, sizeof(PACKETHEADER)); if(header.packetSize < sizeof(PACKETHEADER)) { //Invalid packet CLog::GetInstance().LogError(LOG_NAME, "Packet size in header is invalid.\r\n"); return result; } stream.Seek(0, Framework::STREAM_SEEK_SET); result.resize(header.packetSize); stream.Read(&result[0], header.packetSize); stream.Truncate(); stream.Seek(0, Framework::STREAM_SEEK_END); return result; }
void CRandomAluTest3::Compile(Jitter::CJitter& jitter) { Framework::CMemStream codeStream; jitter.SetStream(&codeStream); jitter.Begin(); { //a = b ^ a if(m_useConstant) { jitter.PushCst(TEST_NUMBER1); } else { jitter.PushRel(offsetof(CONTEXT, number1)); } if(m_useConstant) { jitter.PushCst(TEST_NUMBER2); } else { jitter.PushRel(offsetof(CONTEXT, number2)); } jitter.Xor(); //b = a jitter.PullRel(offsetof(CONTEXT, number1)); jitter.PushRel(offsetof(CONTEXT, number1)); jitter.PullRel(offsetof(CONTEXT, number2)); } jitter.End(); m_function = CMemoryFunction(codeStream.GetBuffer(), codeStream.GetSize()); }
void CMdFpFlagTest::Compile(Jitter::CJitter& jitter) { Framework::CMemStream codeStream; jitter.SetStream(&codeStream); jitter.Begin(); { //0 jitter.MD_PushRel(offsetof(CONTEXT, src0)); jitter.MD_IsNegative(); jitter.PullRel(offsetof(CONTEXT, dstIsNegative0)); jitter.MD_PushRel(offsetof(CONTEXT, src0)); jitter.MD_IsZero(); jitter.PullRel(offsetof(CONTEXT, dstIsZero0)); //1 jitter.MD_PushRel(offsetof(CONTEXT, src1)); jitter.MD_IsNegative(); jitter.PullRel(offsetof(CONTEXT, dstIsNegative1)); jitter.MD_PushRel(offsetof(CONTEXT, src1)); jitter.MD_IsZero(); jitter.PullRel(offsetof(CONTEXT, dstIsZero1)); //2 jitter.MD_PushRel(offsetof(CONTEXT, src2)); jitter.MD_IsNegative(); jitter.PullRel(offsetof(CONTEXT, dstIsNegative2)); jitter.MD_PushRel(offsetof(CONTEXT, src2)); jitter.MD_IsZero(); jitter.PullRel(offsetof(CONTEXT, dstIsZero2)); } jitter.End(); m_function = CMemoryFunction(codeStream.GetBuffer(), codeStream.GetSize()); }
extern "C" JNIEXPORT jstring JNICALL Java_com_virtualapplications_play_InputManager_getVirtualPadItems(JNIEnv* env, jobject obj, jfloat screenWidth, jfloat screenHeight) { auto items = CVirtualPad::GetItems(screenWidth, screenHeight); auto documentNode = std::make_unique<Framework::Xml::CNode>("Document", true); for(const auto& item : items) { auto itemNode = new Framework::Xml::CNode("Item", true); itemNode->InsertAttribute("isAnalog", item.isAnalog ? "true" : "false"); itemNode->InsertAttribute("x1", std::to_string(item.x1).c_str()); itemNode->InsertAttribute("y1", std::to_string(item.y1).c_str()); itemNode->InsertAttribute("x2", std::to_string(item.x2).c_str()); itemNode->InsertAttribute("y2", std::to_string(item.y2).c_str()); itemNode->InsertAttribute("code0", std::to_string(item.code0).c_str()); itemNode->InsertAttribute("code1", std::to_string(item.code1).c_str()); itemNode->InsertAttribute("caption", item.caption.c_str()); itemNode->InsertAttribute("imageName", item.imageName.c_str()); documentNode->InsertNode(itemNode); } Framework::CMemStream outputStream; Framework::Xml::CWriter::WriteDocument(outputStream, documentNode.get()); auto resultString = std::string(outputStream.GetBuffer(), outputStream.GetBuffer() + outputStream.GetSize()); jstring result = env->NewStringUTF(resultString.c_str()); return result; }
void CAliasTest::Compile(Jitter::CJitter& jitter) { Framework::CMemStream codeStream; jitter.SetStream(&codeStream); jitter.Begin(); { jitter.PushCst64(0); jitter.PullRel64(offsetof(CONTEXT, value0)); jitter.PushCst(CONSTANT_1); jitter.PullRel(offsetof(CONTEXT, value0[0])); jitter.PushCst(CONSTANT_2); jitter.PullRel(offsetof(CONTEXT, value0[1])); jitter.PushRel64(offsetof(CONTEXT, value0)); jitter.PushRel64(offsetof(CONTEXT, value1)); jitter.Cmp64(Jitter::CONDITION_EQ); jitter.PullRel(offsetof(CONTEXT, result)); for(unsigned int i = 0; i < 4; i++) { jitter.PushCst(0); jitter.PullRel(offsetof(CONTEXT, value4[i])); } jitter.MD_PushRel(offsetof(CONTEXT, value2)); jitter.MD_PushRel(offsetof(CONTEXT, value3)); jitter.MD_AddWSS(); jitter.MD_PullRel(offsetof(CONTEXT, value4), true, false, false, true); } jitter.End(); m_function = CMemoryFunction(codeStream.GetBuffer(), codeStream.GetSize()); }
void CCmp64Test::Compile(Jitter::CJitter& jitter) { Framework::CMemStream codeStream; jitter.SetStream(&codeStream); jitter.Begin(); { //Equal //--------------------------------- jitter.PushRel64(offsetof(CONTEXT, value0)); if(m_useConstant) { jitter.PushCst64(m_value1); } else { jitter.PushRel64(offsetof(CONTEXT, value1)); } jitter.Cmp64(Jitter::CONDITION_EQ); jitter.PullRel(offsetof(CONTEXT, resultEq)); //Not Equal //--------------------------------- jitter.PushRel64(offsetof(CONTEXT, value0)); if(m_useConstant) { jitter.PushCst64(m_value1); } else { jitter.PushRel64(offsetof(CONTEXT, value1)); } jitter.Cmp64(Jitter::CONDITION_NE); jitter.PullRel(offsetof(CONTEXT, resultNe)); //Less Than (unsigned) //--------------------------------- jitter.PushRel64(offsetof(CONTEXT, value0)); if(m_useConstant) { jitter.PushCst64(m_value1); } else { jitter.PushRel64(offsetof(CONTEXT, value1)); } jitter.Cmp64(Jitter::CONDITION_BL); jitter.PullRel(offsetof(CONTEXT, resultBl)); //Less Than (signed) //--------------------------------- jitter.PushRel64(offsetof(CONTEXT, value0)); if(m_useConstant) { jitter.PushCst64(m_value1); } else { jitter.PushRel64(offsetof(CONTEXT, value1)); } jitter.Cmp64(Jitter::CONDITION_LT); jitter.PullRel(offsetof(CONTEXT, resultLt)); //Less Equal (signed) //--------------------------------- jitter.PushRel64(offsetof(CONTEXT, value0)); if(m_useConstant) { jitter.PushCst64(m_value1); } else { jitter.PushRel64(offsetof(CONTEXT, value1)); } jitter.Cmp64(Jitter::CONDITION_LE); jitter.PullRel(offsetof(CONTEXT, resultLe)); //Greater Than (unsigned) //--------------------------------- jitter.PushRel64(offsetof(CONTEXT, value0)); if(m_useConstant) { jitter.PushCst64(m_value1); } else { jitter.PushRel64(offsetof(CONTEXT, value1)); } jitter.Cmp64(Jitter::CONDITION_AB); jitter.PullRel(offsetof(CONTEXT, resultAb)); //Greater Than (signed) //--------------------------------- jitter.PushRel64(offsetof(CONTEXT, value0)); if(m_useConstant) { jitter.PushCst64(m_value1); } else { jitter.PushRel64(offsetof(CONTEXT, value1)); } jitter.Cmp64(Jitter::CONDITION_GT); jitter.PullRel(offsetof(CONTEXT, resultGt)); } jitter.End(); m_function = CMemoryFunction(codeStream.GetBuffer(), codeStream.GetSize()); }
void CBasicBlock::Compile() { #ifndef AOT_USE_CACHE Framework::CMemStream stream; { static #ifdef AOT_BUILD_CACHE __declspec(thread) #endif CMipsJitter* jitter = nullptr; if(jitter == nullptr) { Jitter::CCodeGen* codeGen = Jitter::CreateCodeGen(); jitter = new CMipsJitter(codeGen); for(unsigned int i = 0; i < 4; i++) { jitter->SetVariableAsConstant( offsetof(CMIPS, m_State.nGPR[CMIPS::R0].nV[i]), 0); } } jitter->SetStream(&stream); jitter->Begin(); CompileRange(jitter); // codeGen.DumpVariables(0); // codeGen.EndQuota(); jitter->End(); } m_function = CMemoryFunction(stream.GetBuffer(), stream.GetSize()); #ifdef VTUNE_ENABLED if(iJIT_IsProfilingActive() == iJIT_SAMPLING_ON) { iJIT_Method_Load jmethod = {}; jmethod.method_id = iJIT_GetNewMethodID(); jmethod.class_file_name = ""; jmethod.source_file_name = __FILE__; jmethod.method_load_address = m_function.GetCode(); jmethod.method_size = m_function.GetSize(); jmethod.line_number_size = 0; auto functionName = string_format("BasicBlock_0x%08X_0x%08X", m_begin, m_end); jmethod.method_name = const_cast<char*>(functionName.c_str()); iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, reinterpret_cast<void*>(&jmethod)); } #endif #endif #ifdef AOT_ENABLED size_t blockSize = ((m_end - m_begin) / 4) + 1; auto blockData = new uint32[blockSize]; for(uint32 i = 0; i < blockSize; i++) { blockData[i] = m_context.m_pMemoryMap->GetWord(m_begin + (i * 4)); } uint32 blockChecksum = crc32(0, reinterpret_cast<Bytef*>(blockData), blockSize * 4); #endif #ifdef AOT_USE_CACHE AOT_BLOCK* blocksBegin = &_aot_firstBlock; AOT_BLOCK* blocksEnd = blocksBegin + _aot_blockCount; AOT_BLOCK blockRef = {blockChecksum, m_begin, m_end, nullptr}; static const auto blockComparer = [](const AOT_BLOCK& item1, const AOT_BLOCK& item2) { return item1.key < item2.key; }; // assert(std::is_sorted(blocksBegin, blocksEnd, blockComparer)); bool blockExists = std::binary_search(blocksBegin, blocksEnd, blockRef, blockComparer); auto blockIterator = std::lower_bound(blocksBegin, blocksEnd, blockRef, blockComparer); assert(blockExists); assert(blockIterator != blocksEnd); assert(blockIterator->key.crc == blockChecksum); assert(blockIterator->key.begin == m_begin); assert(blockIterator->key.end == m_end); m_function = reinterpret_cast<void (*)(void*)>(blockIterator->fct); #endif #ifdef AOT_BUILD_CACHE { std::lock_guard<std::mutex> lock(m_aotBlockOutputStreamMutex); m_aotBlockOutputStream->Write32(blockChecksum); m_aotBlockOutputStream->Write32(m_begin); m_aotBlockOutputStream->Write32(m_end); m_aotBlockOutputStream->Write(blockData, blockSize * 4); } #endif }
void Compile(const char* databasePathName, const char* cpuArchName, const char* imageFormatName, const char* outputPath) { CPsfVm virtualMachine; auto subSystem = std::make_shared<Iop::CPsfSubSystem>(false); virtualMachine.SetSubSystem(subSystem); Jitter::CCodeGen* codeGen = nullptr; Jitter::CObjectFile::CPU_ARCH cpuArch = Jitter::CObjectFile::CPU_ARCH_X86; if(!strcmp(cpuArchName, "x86")) { codeGen = new Jitter::CCodeGen_x86_32(); cpuArch = Jitter::CObjectFile::CPU_ARCH_X86; } else if(!strcmp(cpuArchName, "arm")) { codeGen = new Jitter::CCodeGen_Arm(); cpuArch = Jitter::CObjectFile::CPU_ARCH_ARM; } else { throw std::runtime_error("Invalid cpu target."); } std::unique_ptr<Jitter::CObjectFile> objectFile; if(!strcmp(imageFormatName, "coff")) { objectFile = std::make_unique<Jitter::CCoffObjectFile>(cpuArch); } else if(!strcmp(imageFormatName, "macho")) { objectFile = std::make_unique<Jitter::CMachoObjectFile>(cpuArch); } else { throw std::runtime_error("Invalid executable image type (must be coff or macho)."); } codeGen->RegisterExternalSymbols(objectFile.get()); objectFile->AddExternalSymbol("_MemoryUtils_GetByteProxy", &MemoryUtils_GetByteProxy); objectFile->AddExternalSymbol("_MemoryUtils_GetHalfProxy", &MemoryUtils_GetHalfProxy); objectFile->AddExternalSymbol("_MemoryUtils_GetWordProxy", &MemoryUtils_GetWordProxy); objectFile->AddExternalSymbol("_MemoryUtils_SetByteProxy", &MemoryUtils_SetByteProxy); objectFile->AddExternalSymbol("_MemoryUtils_SetHalfProxy", &MemoryUtils_SetHalfProxy); objectFile->AddExternalSymbol("_MemoryUtils_SetWordProxy", &MemoryUtils_SetWordProxy); objectFile->AddExternalSymbol("_LWL_Proxy", &LWL_Proxy); objectFile->AddExternalSymbol("_LWR_Proxy", &LWR_Proxy); objectFile->AddExternalSymbol("_SWL_Proxy", &SWL_Proxy); objectFile->AddExternalSymbol("_SWR_Proxy", &SWR_Proxy); filesystem::path databasePath(databasePathName); auto blocks = GetBlocksFromCache(databasePath); //Initialize Jitter Service auto jitter = new CMipsJitter(codeGen); for(unsigned int i = 0; i < 4; i++) { jitter->SetVariableAsConstant( offsetof(CMIPS, m_State.nGPR[CMIPS::R0].nV[i]), 0 ); } printf("Got %d blocks to compile.\r\n", blocks.size()); FunctionTable functionTable; functionTable.reserve(blocks.size()); for(const auto& blockCachePair : blocks) { const auto& blockKey = blockCachePair.first; auto functionName = "aotblock_" + std::to_string(blockKey.crc) + "_" + std::to_string(blockKey.begin) + "_" + std::to_string(blockKey.end); unsigned int functionSymbolIndex = CompileFunction(virtualMachine, jitter, blockCachePair.second, *objectFile, functionName, blockKey.begin, blockKey.end); FUNCTION_TABLE_ITEM tableItem = { blockKey, functionSymbolIndex }; functionTable.push_back(tableItem); } std::sort(functionTable.begin(), functionTable.end(), [] (const FUNCTION_TABLE_ITEM& item1, const FUNCTION_TABLE_ITEM& item2) { return item1.key < item2.key; } ); { Framework::CMemStream blockTableStream; Jitter::CObjectFile::INTERNAL_SYMBOL blockTableSymbol; blockTableSymbol.name = "__aot_firstBlock"; blockTableSymbol.location = Jitter::CObjectFile::INTERNAL_SYMBOL_LOCATION_DATA; for(const auto& functionTableItem : functionTable) { blockTableStream.Write32(functionTableItem.key.crc); blockTableStream.Write32(functionTableItem.key.begin); blockTableStream.Write32(functionTableItem.key.end); { Jitter::CObjectFile::SYMBOL_REFERENCE ref; ref.offset = static_cast<uint32>(blockTableStream.Tell()); ref.type = Jitter::CObjectFile::SYMBOL_TYPE_INTERNAL; ref.symbolIndex = functionTableItem.symbolIndex; blockTableSymbol.symbolReferences.push_back(ref); } blockTableStream.Write32(0); } blockTableSymbol.data = std::vector<uint8>(blockTableStream.GetBuffer(), blockTableStream.GetBuffer() + blockTableStream.GetLength()); objectFile->AddInternalSymbol(blockTableSymbol); } { Jitter::CObjectFile::INTERNAL_SYMBOL blockCountSymbol; blockCountSymbol.name = "__aot_blockCount"; blockCountSymbol.location = Jitter::CObjectFile::INTERNAL_SYMBOL_LOCATION_DATA; blockCountSymbol.data = std::vector<uint8>(4); *reinterpret_cast<uint32*>(blockCountSymbol.data.data()) = functionTable.size(); objectFile->AddInternalSymbol(blockCountSymbol); } objectFile->Write(Framework::CStdStream(outputPath, "wb")); }