diff --git a/llvm/_core.cpp b/llvm/_core.cpp index b0f1919..2f99ae3 100644 --- a/llvm/_core.cpp +++ b/llvm/_core.cpp @@ -200,8 +200,11 @@ _wLLVMGetNativeCodeFromModule(PyObject * self, PyObject * args) m = (LLVMModuleRef) PyCapsule_GetPointer(arg_m, NULL); - if ( !(bytes = LLVMGetNativeCodeFromModule(m, arg_use_asm, &len)) ) - Py_RETURN_NONE; + std::string error; + bytes = LLVMGetNativeCodeFromModule(m, arg_use_asm, &len, error); + if ( !error.empty() ){ + PyErr_SetString(PyExc_RuntimeError, error.c_str()); + } ret = PyBytes_FromStringAndSize((char *)bytes, (Py_ssize_t)len); delete [] bytes; @@ -1013,7 +1016,13 @@ _wLLVMTargetMachineLookup(PyObject * self, PyObject * args) if (!PyArg_ParseTuple(args, "sssi", &arch, &cpu, &features, &opt)) return NULL; - LLVMTargetMachineRef tm = LLVMTargetMachineLookup(arch, cpu, features, opt); + std::string error; + LLVMTargetMachineRef tm = LLVMTargetMachineLookup(arch, cpu, features, opt, + error); + if(!error.empty()){ + PyErr_SetString(PyExc_RuntimeError, error.c_str()); + return NULL; + } return ctor_LLVMTargetMachineRef(tm); } @@ -1035,8 +1044,12 @@ _wLLVMTargetMachineEmitFile(PyObject * self, PyObject * args) tm = (LLVMTargetMachineRef) PyCapsule_GetPointer(arg_tm, NULL); m = (LLVMModuleRef) PyCapsule_GetPointer(arg_m, NULL); - if ( !(bytes = LLVMTargetMachineEmitFile(tm, m, arg_use_asm, &len)) ) - Py_RETURN_NONE; + std::string error; + bytes = LLVMTargetMachineEmitFile(tm, m, arg_use_asm, &len, error); + if ( !error.empty() ){ + PyErr_SetString(PyExc_RuntimeError, error.c_str()); + return NULL; + } ret = PyBytes_FromStringAndSize((char *)bytes, (Py_ssize_t)len); delete [] bytes; diff --git a/llvm/extra.cpp b/llvm/extra.cpp index 7e27d10..2fde2ba 100644 --- a/llvm/extra.cpp +++ b/llvm/extra.cpp @@ -133,10 +133,10 @@ int LLVMInitializeNativeTargetAsmPrinter() LLVMTargetMachineRef LLVMTargetMachineLookup(const char *arch, const char *cpu, - const char *features, int opt) + const char *features, int opt, + std::string &error) { using namespace llvm; - std::string error; Triple TheTriple; // begin borrow from LLVM 3.2 code @@ -153,7 +153,7 @@ LLVMTargetMachineRef LLVMTargetMachineLookup(const char *arch, const char *cpu, } if (!TheTarget) { - fprintf(stderr, "%s\n", error.c_str()); + error = "Unknown arch"; return NULL; } @@ -165,7 +165,7 @@ LLVMTargetMachineRef LLVMTargetMachineLookup(const char *arch, const char *cpu, // end borrow from LLVM 3.2 code if (!TheTarget->hasTargetMachine()){ - fprintf(stderr, "No target machine for %s\n", arch); + error = "No target machine for the arch"; return NULL; } @@ -177,7 +177,7 @@ LLVMTargetMachineRef LLVMTargetMachineLookup(const char *arch, const char *cpu, OptLevelMap[opt]); if (!tm){ - fprintf(stderr, "Cannot create target machine!\n"); + error = "Cannot create target machine"; return NULL; } return wrap(tm); @@ -198,7 +198,8 @@ void LLVMDisposeTargetMachine(LLVMTargetMachineRef tm){ unsigned char* LLVMTargetMachineEmitFile(LLVMTargetMachineRef tmref, LLVMModuleRef modref, - int assembly, unsigned * lenp) + int assembly, unsigned * lenp, + std::string &error) { using namespace llvm; assert(lenp); @@ -217,7 +218,7 @@ unsigned char* LLVMTargetMachineEmitFile(LLVMTargetMachineRef tmref, PassManager pm; if (!tm->getTargetData()){ - fprintf(stderr, "No target data in target machine"); + error = "No target data in target machine"; return NULL; } @@ -231,8 +232,7 @@ unsigned char* LLVMTargetMachineEmitFile(LLVMTargetMachineRef tmref, } if ( failed ) { - fprintf(stderr, "No support\n"); - fprintf(stderr, "%s\n", tm->getTargetData()->getStringRepresentation().c_str()); + error = "No support for emit file"; return NULL; } @@ -248,6 +248,7 @@ unsigned char* LLVMTargetMachineEmitFile(LLVMTargetMachineRef tmref, size_t bclen = bc.size(); unsigned char *bytes = new unsigned char[bclen]; if (!bytes){ + error = "Out of memory"; return NULL; } memcpy(bytes, bc.data(), bclen); @@ -295,7 +296,7 @@ LLVMTargetDataRef LLVMTargetMachineGetTargetData(LLVMTargetMachineRef tm) } unsigned char* LLVMGetNativeCodeFromModule(LLVMModuleRef module, int assembly, - unsigned * lenp) + unsigned * lenp, std::string &error) { using namespace llvm; assert(lenp); @@ -306,7 +307,7 @@ unsigned char* LLVMGetNativeCodeFromModule(LLVMModuleRef module, int assembly, // select native default machine TargetMachine * tm = EngineBuilder(modulep).selectTarget(); - return LLVMTargetMachineEmitFile(wrap(tm), module, assembly, lenp); + return LLVMTargetMachineEmitFile(wrap(tm), module, assembly, lenp, error); } static diff --git a/llvm/extra.h b/llvm/extra.h index 832d725..a335a58 100644 --- a/llvm/extra.h +++ b/llvm/extra.h @@ -49,7 +49,8 @@ int LLVMInitializeNativeTargetAsmPrinter(); LLVMTargetMachineRef LLVMTargetMachineLookup(const char *arch, const char *cpu, - const char *features, int opt); + const char *features, int opt, + std::string &error); /* * Wraps EngineBuilder::selectTarget @@ -66,7 +67,8 @@ void LLVMDisposeTargetMachine(LLVMTargetMachineRef tm); */ unsigned char* LLVMTargetMachineEmitFile(LLVMTargetMachineRef tmref, LLVMModuleRef modref, - int assembly, unsigned * lenp); + int assembly, unsigned * lenp, + std::string &error); /* * Wraps TargetMachine::getTargetData @@ -107,7 +109,7 @@ void LLVMPrintRegisteredTargetsForVersion(); * Wraps TargetMachine::addPassesToEmitFile */ unsigned char* LLVMGetNativeCodeFromModule(LLVMModuleRef module, int assembly, - unsigned * lenp); + unsigned * lenp, std::string &error); /* * Wraps IRBuilder::CreateFence diff --git a/test/targetmachines.py b/test/targetmachines.py index a91411d..9ce85dd 100644 --- a/test/targetmachines.py +++ b/test/targetmachines.py @@ -42,6 +42,11 @@ class TestTargetMachines(unittest.TestCase): m.verify() return m, func + def _build_bad_archname(self): + with self.assertRaises(RuntimeError): + tm = TargetMachine.lookup("ain't no arch name") + + if __name__ == '__main__': unittest.main()