Added convert module from/to bitcode.

git-svn-id: http://llvm-py.googlecode.com/svn/trunk@28 8d1e9007-1d4e-0410-b67e-1979fd6579aa
This commit is contained in:
mdevan.foobar 2008-08-03 16:01:02 +00:00
commit 392f2e7e79
5 changed files with 118 additions and 11 deletions

View file

@ -42,15 +42,14 @@ _wrap_dumper(LLVMDumpModuleToString, LLVMModuleRef)
static PyObject *
_wLLVMVerifyModule(PyObject *self, PyObject *args)
{
PyObject *obj;
char *outmsg = 0;
char *outmsg;
PyObject *ret;
LLVMModuleRef m;
if (!PyArg_ParseTuple(args, "O", &obj))
if (!(m = (LLVMModuleRef)get_object_arg(args)))
return NULL;
m = (LLVMModuleRef) PyCObject_AsVoidPtr(obj);
outmsg = 0;
(void) LLVMVerifyModule(m, LLVMReturnStatusAction, &outmsg);
if (outmsg) {
@ -63,6 +62,53 @@ _wLLVMVerifyModule(PyObject *self, PyObject *args)
return ret;
}
static PyObject *
_wLLVMGetModuleFromBitcode(PyObject *self, PyObject *args)
{
PyObject *obj, *ret;
Py_ssize_t len;
char *start, *outmsg;
LLVMModuleRef m;
if (!PyArg_ParseTuple(args, "O", &obj))
return NULL;
start = PyString_AsString(obj);
len = PyString_Size(obj);
outmsg = 0;
m = LLVMGetModuleFromBitcode(start, len, &outmsg);
if (!m) {
if (outmsg) {
ret = PyString_FromString(outmsg);
LLVMDisposeMessage(outmsg);
return ret;
} else {
Py_RETURN_NONE;
}
}
return ctor_LLVMModuleRef(m);
}
static PyObject *
_wLLVMGetBitcodeFromModule(PyObject *self, PyObject *args)
{
PyObject *ret;
unsigned len;
unsigned char *bytes;
LLVMModuleRef m;
if (!(m = (LLVMModuleRef)get_object_arg(args)))
return NULL;
if (!(bytes = LLVMGetBitcodeFromModule(m, &len)))
Py_RETURN_NONE;
ret = PyString_FromStringAndSize((char *)bytes, (Py_ssize_t)len);
LLVMDisposeMessage((char *)bytes);
return ret;
}
/*===----------------------------------------------------------------------===*/
/* Types */
@ -805,6 +851,8 @@ static PyMethodDef core_methods[] = {
_method( LLVMDisposeModule )
_method( LLVMDumpModuleToString )
_method( LLVMVerifyModule )
_method( LLVMGetModuleFromBitcode )
_method( LLVMGetBitcodeFromModule )
/* Types */

View file

@ -721,6 +721,20 @@ class Module(llvm.Ownable):
"""
return Module(_core.LLVMModuleCreateWithName(id))
@staticmethod
def from_bitcode(fileobj):
"""Create a Module instance from the contents of a bitcode
file."""
data = fileobj.read()
ret = _core.LLVMGetModuleFromBitcode(data)
if not ret:
raise llvm.LLVMException, "Unable to create module from bitcode"
elif isinstance(ret, str):
raise llvm.LLVMException, ret
else:
return Module(ret)
def __init__(self, ptr):
"""DO NOT CALL DIRECTLY.
@ -837,6 +851,15 @@ class Module(llvm.Ownable):
if ret != "":
raise llvm.LLVMException, ret
def to_bitcode(self, fileobj):
"""Write bitcode representation of module to given file-like
object."""
data = _core.LLVMGetBitcodeFromModule(self.ptr)
if not data:
raise llvm.LLVMException, "Unable to create bitcode"
fileobj.write(data)
#===----------------------------------------------------------------------===
# Types

View file

@ -4,7 +4,13 @@
* Python bindings.
*/
#include <cassert>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/GlobalVariable.h"
@ -13,13 +19,10 @@
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/CallSite.h"
#include "llvm/IntrinsicInst.h"
#include <cassert>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include "llvm/Analysis/Verifier.h"
#include "llvm-c/Core.h"
#include "llvm/Analysis/Verifier.h"
#include "extra.h"
using namespace llvm;
@ -99,3 +102,32 @@ LLVMValueRef LLVMGetIntrinsic(LLVMModuleRef M, int ID,
return wrap(intfunc);
}
LLVMModuleRef LLVMGetModuleFromBitcode(const char *BC, unsigned Len,
char **OutMessage)
{
MemoryBuffer *mb = MemoryBuffer::getMemBufferCopy(BC, BC+Len);
if (!mb)
return NULL;
std::string msg;
LLVMModuleRef mr = wrap(ParseBitcodeFile(mb, &msg));
if (!mr)
*OutMessage = strdup(msg.c_str());
delete mb;
return mr;
}
unsigned char *LLVMGetBitcodeFromModule(LLVMModuleRef M, unsigned *Len)
{
std::ostringstream buf;
WriteBitcodeToFile(unwrap(M), buf);
const std::string& s = buf.str();
size_t len = s.size();
unsigned char *bytes = (unsigned char *)malloc(len);
if (!bytes)
return NULL;
memcpy(bytes, s.data(), len);
*Len = len;
return bytes;
}

View file

@ -47,7 +47,11 @@ LLVMValueRef LLVMBuildGetResult(LLVMBuilderRef, LLVMValueRef V,
unsigned Index, const char *Name);
LLVMValueRef LLVMGetIntrinsic(LLVMModuleRef B, int ID,
LLVMTypeRef *Types, unsigned Count);
LLVMTypeRef *Types, unsigned Count);
LLVMModuleRef LLVMGetModuleFromBitcode(const char *BC, unsigned Len,
char **OutMessage);
unsigned char *LLVMGetBitcodeFromModule(LLVMModuleRef M, unsigned *Len);
#ifdef __cplusplus
} /* extern "C" */

View file

@ -50,7 +50,7 @@ def call_setup(llvm_config):
ldflags = _run(llvm_config + ' --ldflags')
libs_core, objs_core = get_libs_and_objs(llvm_config,
['core', 'analysis', 'scalaropts', 'executionengine',
'jit', 'native', 'interpreter'])
'jit', 'native', 'interpreter', 'bitreader', 'bitwriter'])
std_libs = [ 'pthread', 'm' ]
if not sys.platform.startswith("openbsd"):