FCIMPL0(Object*, SystemNative::GetCommandLineArgs) { FCALL_CONTRACT; PTRARRAYREF strArray = NULL; HELPER_METHOD_FRAME_BEGIN_RET_1(strArray); LPWSTR commandLine; commandLine = WszGetCommandLine(); if (commandLine==NULL) COMPlusThrowOM(); DWORD numArgs = 0; LPWSTR* argv = SegmentCommandLine(commandLine, &numArgs); if (!argv) COMPlusThrowOM(); _ASSERTE(numArgs > 0); strArray = (PTRARRAYREF) AllocateObjectArray(numArgs, g_pStringClass); // Copy each argument into new Strings. for(unsigned int i=0; i<numArgs; i++) { STRINGREF str = StringObject::NewString(argv[i]); STRINGREF * destData = ((STRINGREF*)(strArray->GetDataPtr())) + i; SetObjectReference((OBJECTREF*)destData, (OBJECTREF)str, strArray->GetAppDomain()); } delete [] argv; HELPER_METHOD_FRAME_END(); return OBJECTREFToObject(strArray); }
FCIMPLEND void QCALLTYPE SystemNative::_GetCommandLine(QCall::StringHandleOnStack retString) { QCALL_CONTRACT; BEGIN_QCALL; LPCWSTR commandLine; if (g_pCachedCommandLine != NULL) { // Use the cached command line if available commandLine = g_pCachedCommandLine; } else { commandLine = WszGetCommandLine(); if (commandLine==NULL) COMPlusThrowOM(); } retString.Set(commandLine); END_QCALL; }
RegionInfoTable* RegionInfoTable::CreateInstance() { THROWSCOMPLUSEXCEPTION(); if (m_pDefaultTable==NULL) { Thread* pThread = GetThread(); pThread->EnablePreemptiveGC(); LOCKCOUNTINCL("CreateInstance in regioninfotable.cpp"); \ EnterCriticalSection(&m_ProtectDefaultTable); pThread->DisablePreemptiveGC(); EE_TRY_FOR_FINALLY { //Make sure that nobody allocated the table before us. if (m_pDefaultTable==NULL) { //Allocate the default table and verify that we got one. m_pDefaultTable = AllocateTable(); if (m_pDefaultTable==NULL) { COMPlusThrowOM(); } } } EE_FINALLY { //We need to leave the critical section regardless of whether //or not we were successful in allocating the table. LeaveCriticalSection(&m_ProtectDefaultTable); LOCKCOUNTDECL("CreateInstance in regioninfotable.cpp"); \ } EE_END_FINALLY; }
// get the method table for dynamic methods DynamicMethodTable* DomainFile::GetDynamicMethodTable() { CONTRACT (DynamicMethodTable*) { INSTANCE_CHECK; THROWS; GC_TRIGGERS; MODE_ANY; INJECT_FAULT(COMPlusThrowOM()); POSTCONDITION(CheckPointer(m_pDynamicMethodTable)); }
//--------------------------------------------------------------------------------------- // //static DictionaryLayout * DictionaryLayout::Allocate( WORD numSlots, LoaderAllocator * pAllocator, AllocMemTracker * pamTracker) { CONTRACT(DictionaryLayout*) { THROWS; GC_NOTRIGGER; INJECT_FAULT(COMPlusThrowOM(););
// This method computes the same result as COR_ILMETHOD_SECT_EH::Size(...) but // does so in a way that detects overflow if the number of exception clauses is // too great (in which case an OOM exception is thrown). We do this rather than // modifying COR_ILMETHOD_SECT_EH::Size because that routine is published in the // SDK and can't take breaking changes and because the overflow support (and // exception mechanism) we're using is only available to the VM. UINT32 ExceptionHandlingSize(unsigned uNumExceptions, COR_ILMETHOD_SECT_EH_CLAUSE_FAT* pClauses) { STANDARD_VM_CONTRACT; if (uNumExceptions == 0) return 0; // Speculatively compute the size for the slim version of the header. S_UINT32 uSmallSize = S_UINT32(sizeof(COR_ILMETHOD_SECT_EH_SMALL)) + (S_UINT32(sizeof(IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_SMALL)) * (S_UINT32(uNumExceptions - 1))); if (uSmallSize.IsOverflow()) COMPlusThrowOM(); if (uSmallSize.Value() > COR_ILMETHOD_SECT_SMALL_MAX_DATASIZE) goto FatCase; // Check whether any of the clauses won't fit in the slim case. for (UINT32 i = 0; i < uNumExceptions; i++) { COR_ILMETHOD_SECT_EH_CLAUSE_FAT* pFatClause = (COR_ILMETHOD_SECT_EH_CLAUSE_FAT*)&pClauses[i]; if (pFatClause->GetTryOffset() > 0xFFFF || pFatClause->GetTryLength() > 0xFF || pFatClause->GetHandlerOffset() > 0xFFFF || pFatClause->GetHandlerLength() > 0xFF) { goto FatCase; } } _ASSERTE(uSmallSize.Value() == COR_ILMETHOD_SECT_EH::Size(uNumExceptions, pClauses)); return uSmallSize.Value(); FatCase: S_UINT32 uFatSize = S_UINT32(sizeof(COR_ILMETHOD_SECT_EH_FAT)) + (S_UINT32(sizeof(IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT)) * (S_UINT32(uNumExceptions - 1))); if (uFatSize.IsOverflow()) COMPlusThrowOM(); _ASSERTE(uFatSize.Value() == COR_ILMETHOD_SECT_EH::Size(uNumExceptions, pClauses)); return uFatSize.Value(); }
LPVOID NLSTable::MapDataFile(LPCWSTR pMappingName, LPCWSTR pFileName, HANDLE *hFileMap) { THROWSCOMPLUSEXCEPTION(); // The following macro will delete pAnsiFileName when // getting out of the scope of this function. MAKE_ANSIPTR_FROMWIDE(pAnsiFileName, pFileName); if (!pAnsiFileName) { COMPlusThrowOM(); } return (MapDataFile(pMappingName, pAnsiFileName, hFileMap)); }
HANDLE NLSTable::OpenDataFile(LPCWSTR pFileName) { THROWSCOMPLUSEXCEPTION(); // The following marco will delete pAnsiFileName when // getting out of the scope of this function. MAKE_ANSIPTR_FROMWIDE(pAnsiFileName, pFileName); if (!pAnsiFileName) { COMPlusThrowOM(); } HANDLE hFile = OpenDataFile((LPCSTR)pAnsiFileName); _ASSERTE(hFile != INVALID_HANDLE_VALUE); return (hFile); }
FCIMPLEND void QCALLTYPE SystemNative::_GetCommandLine(QCall::StringHandleOnStack retString) { QCALL_CONTRACT; BEGIN_QCALL; LPCWSTR commandLine; commandLine = WszGetCommandLine(); if (commandLine==NULL) COMPlusThrowOM(); retString.Set(commandLine); END_QCALL; }
// SetMethodIL -- This function will create a method within the class void QCALLTYPE COMDynamicWrite::SetMethodIL(QCall::ModuleHandle pModule, INT32 tk, BOOL fIsInitLocal, LPCBYTE pBody, INT32 cbBody, LPCBYTE pLocalSig, INT32 sigLength, UINT16 maxStackSize, ExceptionInstance * pExceptions, INT32 numExceptions, INT32 * pTokenFixups, INT32 numTokenFixups) { QCALL_CONTRACT; BEGIN_QCALL; RefClassWriter * pRCW = pModule->GetReflectionModule()->GetClassWriter(); _ASSERTE(pRCW); _ASSERTE(pLocalSig); PCCOR_SIGNATURE pcSig = (PCCOR_SIGNATURE)pLocalSig; _ASSERTE(*pcSig == IMAGE_CEE_CS_CALLCONV_LOCAL_SIG); mdSignature pmLocalSigToken; if (sigLength==2 && pcSig[0]==0 && pcSig[1]==0) { //This is an empty local variable sig pmLocalSigToken=0; } else { IfFailThrow(pRCW->GetEmitter()->GetTokenFromSig( pcSig, sigLength, &pmLocalSigToken)); } COR_ILMETHOD_FAT fatHeader; // set fatHeader.Flags to CorILMethod_InitLocals if user wants to zero init the stack frame. // fatHeader.SetFlags(fIsInitLocal ? CorILMethod_InitLocals : 0); fatHeader.SetMaxStack(maxStackSize); fatHeader.SetLocalVarSigTok(pmLocalSigToken); fatHeader.SetCodeSize(cbBody); bool moreSections = (numExceptions != 0); unsigned codeSizeAligned = fatHeader.GetCodeSize(); if (moreSections) codeSizeAligned = AlignUp(codeSizeAligned, 4); // to insure EH section aligned unsigned headerSize = COR_ILMETHOD::Size(&fatHeader, numExceptions != 0); //Create the exception handlers. CQuickArray<COR_ILMETHOD_SECT_EH_CLAUSE_FAT> clauses; if (numExceptions > 0) { clauses.AllocThrows(numExceptions); for (int i = 0; i < numExceptions; i++) { clauses[i].SetFlags((CorExceptionFlag)(pExceptions[i].m_type)); clauses[i].SetTryOffset(pExceptions[i].m_start); clauses[i].SetTryLength(pExceptions[i].m_end - pExceptions[i].m_start); clauses[i].SetHandlerOffset(pExceptions[i].m_handle); clauses[i].SetHandlerLength(pExceptions[i].m_handleEnd - pExceptions[i].m_handle); if (pExceptions[i].m_type == COR_ILEXCEPTION_CLAUSE_FILTER) { clauses[i].SetFilterOffset(pExceptions[i].m_filterOffset); } else if (pExceptions[i].m_type!=COR_ILEXCEPTION_CLAUSE_FINALLY) { clauses[i].SetClassToken(pExceptions[i].m_exceptionType); } else { clauses[i].SetClassToken(mdTypeRefNil); } } } unsigned ehSize = ExceptionHandlingSize(numExceptions, clauses.Ptr()); S_UINT32 totalSizeSafe = S_UINT32(headerSize) + S_UINT32(codeSizeAligned) + S_UINT32(ehSize); if (totalSizeSafe.IsOverflow()) COMPlusThrowOM(); UINT32 totalSize = totalSizeSafe.Value(); ICeeGen* pGen = pRCW->GetCeeGen(); BYTE* buf = NULL; ULONG methodRVA; pGen->AllocateMethodBuffer(totalSize, &buf, &methodRVA); if (buf == NULL) COMPlusThrowOM(); _ASSERTE(buf != NULL); _ASSERTE((((size_t) buf) & 3) == 0); // header is dword aligned #ifdef _DEBUG BYTE* endbuf = &buf[totalSize]; #endif BYTE * startBuf = buf; // Emit the header buf += COR_ILMETHOD::Emit(headerSize, &fatHeader, moreSections, buf); //Emit the code //The fatHeader.CodeSize is a workaround to see if we have an interface or an //abstract method. Force enough verification in native to ensure that //this is true. if (fatHeader.GetCodeSize()!=0) { memcpy(buf, pBody, fatHeader.GetCodeSize()); } buf += codeSizeAligned; // Emit the eh CQuickArray<ULONG> ehTypeOffsets; if (numExceptions > 0) { // Allocate space for the the offsets to the TypeTokens in the Exception headers // in the IL stream. ehTypeOffsets.AllocThrows(numExceptions); // Emit the eh. This will update the array ehTypeOffsets with offsets // to Exception type tokens. The offsets are with reference to the // beginning of eh section. buf += COR_ILMETHOD_SECT_EH::Emit(ehSize, numExceptions, clauses.Ptr(), false, buf, ehTypeOffsets.Ptr()); } _ASSERTE(buf == endbuf); //Get the IL Section. HCEESECTION ilSection; IfFailThrow(pGen->GetIlSection(&ilSection)); // Token Fixup data... ULONG ilOffset = methodRVA + headerSize; //Add all of the relocs based on the info which I saved from ILGenerator. //Add the Token Fixups for (int iTokenFixup=0; iTokenFixup<numTokenFixups; iTokenFixup++) { IfFailThrow(pGen->AddSectionReloc(ilSection, pTokenFixups[iTokenFixup] + ilOffset, ilSection, srRelocMapToken)); } // Add token fixups for exception type tokens. for (int iException=0; iException < numExceptions; iException++) { if (ehTypeOffsets[iException] != (ULONG) -1) { IfFailThrow(pGen->AddSectionReloc( ilSection, ehTypeOffsets[iException] + codeSizeAligned + ilOffset, ilSection, srRelocMapToken)); } } //nasty interface workaround. What does this mean for abstract methods? if (fatHeader.GetCodeSize() != 0) { // add the starting address of the il blob to the il blob hash table // we need to find this information from out of process for debugger inspection // APIs so we have to store this information where we can get it later pModule->SetDynamicIL(mdToken(tk), TADDR(startBuf), FALSE); DWORD dwImplFlags; //Set the RVA of the method. IfFailThrow(pRCW->GetMDImport()->GetMethodImplProps(tk, NULL, &dwImplFlags)); dwImplFlags |= (miManaged | miIL); IfFailThrow(pRCW->GetEmitter()->SetMethodProps(tk, (DWORD) -1, methodRVA, dwImplFlags)); } END_QCALL; }