Add Module bitcode writer/parser
This commit is contained in:
parent
961c5e99e1
commit
168510222f
7 changed files with 138 additions and 14 deletions
|
|
@ -26,6 +26,11 @@ class Namespace(object):
|
|||
self.functions.append(fn)
|
||||
return fn
|
||||
|
||||
def CustomFunction(self, *args):
|
||||
fn = CustomFunction(self, *args)
|
||||
self.functions.append(fn)
|
||||
return fn
|
||||
|
||||
def Enum(self, name, *value_names):
|
||||
enum = Enum(*value_names)
|
||||
enum.parent = self
|
||||
|
|
@ -444,13 +449,22 @@ class Function(Method):
|
|||
with writer.function(self.name, varargs='args') as varargs:
|
||||
unwrapped = writer.unwrap_many(varargs)
|
||||
self.process_ownedptr_args(writer, unwrapped)
|
||||
func = self.fullname.split('::', 1)[1].replace('::', '.')
|
||||
func = self.name
|
||||
ret = writer.call('_api.%s' % func,
|
||||
varargs=unwrapped)
|
||||
wrapped = writer.wrap(ret, self.is_return_ownedptr())
|
||||
writer.return_value(wrapped)
|
||||
writer.println()
|
||||
|
||||
class CustomFunction(Function):
|
||||
def __init__(self, parent, name, realname, return_type=Void, *args):
|
||||
super(CustomFunction, self).__init__(parent, name, return_type, *args)
|
||||
self.realname = realname
|
||||
|
||||
@property
|
||||
def fullname(self):
|
||||
return self.realname
|
||||
|
||||
class Destructor(Method):
|
||||
_kind_ = 'dtor'
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
#include <llvm/Value.h>
|
||||
#include <llvm/Function.h>
|
||||
#include <llvm/Support/raw_ostream.h>
|
||||
#include <llvm/Support/MemoryBuffer.h>
|
||||
#include <llvm/Bitcode/ReaderWriter.h>
|
||||
#include <llvm/ExecutionEngine/ExecutionEngine.h>
|
||||
#include <llvm/ExecutionEngine/GenericValue.h>
|
||||
|
||||
|
|
@ -405,3 +407,61 @@ PyObject* EngineBuilder_selectTarget(llvm::EngineBuilder* eb,
|
|||
return pycapsule_new(eb, "llvm::EngineBuilder");
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
PyObject* llvm_ParseBitCodeFile(llvm::StringRef Buf, llvm::LLVMContext& Ctx,
|
||||
PyObject* FObj=NULL)
|
||||
{
|
||||
using namespace llvm;
|
||||
MemoryBuffer* MB = MemoryBuffer::getMemBuffer(Buf);
|
||||
Module* M;
|
||||
if (FObj) {
|
||||
std::string ErrStr;
|
||||
M = ParseBitcodeFile(MB, Ctx, &ErrStr);
|
||||
if (-1 == PyFile_WriteString(ErrStr.c_str(), FObj)) {
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
M = ParseBitcodeFile(MB, Ctx);
|
||||
}
|
||||
delete MB;
|
||||
return pycapsule_new(M, "llvm::Module");
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
PyObject* llvm_WriteBitcodeToFile(const llvm::Module *M, PyObject* FObj)
|
||||
{
|
||||
using namespace llvm;
|
||||
llvm::SmallVector<char, 32> sv;
|
||||
llvm::raw_svector_ostream rso(sv);
|
||||
llvm::WriteBitcodeToFile(M, rso);
|
||||
rso.flush();
|
||||
StringRef ref = rso.str();
|
||||
PyObject* buf = PyString_FromStringAndSize(ref.data(), ref.size());
|
||||
if (-1 == PyFile_WriteObject(buf, FObj, Py_PRINT_RAW)){
|
||||
return NULL;
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static
|
||||
PyObject* llvm_getBitcodeTargetTriple(llvm::StringRef Buf,
|
||||
llvm::LLVMContext& Ctx,
|
||||
PyObject* FObj = NULL)
|
||||
{
|
||||
using namespace llvm;
|
||||
MemoryBuffer* MB = MemoryBuffer::getMemBuffer(Buf);
|
||||
std::string Triple;
|
||||
if (FObj) {
|
||||
std::string ErrStr;
|
||||
Triple = getBitcodeTargetTriple(MB, Ctx, &ErrStr);
|
||||
if (-1 == PyFile_WriteString(ErrStr.c_str(), FObj)) {
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
Triple = getBitcodeTargetTriple(MB, Ctx);
|
||||
}
|
||||
delete MB;
|
||||
return PyString_FromString(Triple.c_str());
|
||||
}
|
||||
|
|
|
|||
30
newbinding/src/Bitcode/ReaderWriter.py
Normal file
30
newbinding/src/Bitcode/ReaderWriter.py
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
from binding import *
|
||||
from ..namespace import llvm
|
||||
from ..ADT.StringRef import StringRef
|
||||
from ..Module import Module
|
||||
from ..LLVMContext import LLVMContext
|
||||
|
||||
llvm.includes.add('llvm/Bitcode/ReaderWriter.h')
|
||||
|
||||
ParseBitCodeFile = llvm.CustomFunction('ParseBitCodeFile',
|
||||
'llvm_ParseBitCodeFile',
|
||||
PyObjectPtr, # returns Module*
|
||||
cast(str, StringRef),
|
||||
ref(LLVMContext),
|
||||
PyObjectPtr, # file-like object
|
||||
).require_only(2)
|
||||
|
||||
WriteBitcodeToFile = llvm.CustomFunction('WriteBitcodeToFile',
|
||||
'llvm_WriteBitcodeToFile',
|
||||
PyObjectPtr, # return None
|
||||
ptr(Module),
|
||||
PyObjectPtr, # file-like object
|
||||
)
|
||||
|
||||
getBitcodeTargetTriple = llvm.CustomFunction('getBitcodeTargetTriple',
|
||||
'llvm_getBitcodeTargetTriple',
|
||||
PyObjectPtr, # return str
|
||||
cast(str, StringRef),
|
||||
ref(LLVMContext),
|
||||
PyObjectPtr, # file-like object
|
||||
).require_only(2)
|
||||
10
newbinding/src/Bitcode/__init__.py
Normal file
10
newbinding/src/Bitcode/__init__.py
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import os.path, importlib
|
||||
|
||||
def _init():
|
||||
for fname in os.listdir(os.path.dirname(__file__)):
|
||||
if ((fname.endswith('.py') or fname.endswith('.pyc')) and
|
||||
not fname.startswith('__init__')):
|
||||
modname = os.path.basename(fname).rsplit('.', 1)[0]
|
||||
importlib.import_module('.' + modname, __name__)
|
||||
|
||||
_init()
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
from binding import *
|
||||
from ..namespace import llvm
|
||||
|
||||
MemoryBuffer = llvm.Class()
|
||||
|
||||
@MemoryBuffer
|
||||
class MemoryBuffer:
|
||||
_include_ = 'llvm/Support/MemoryBuffer.h'
|
||||
|
||||
|
|
@ -1,12 +1,15 @@
|
|||
import os.path, importlib
|
||||
|
||||
def _init():
|
||||
for fname in os.listdir(os.path.dirname(__file__)):
|
||||
if ((fname.endswith('.py') or fname.endswith('.pyc')) and
|
||||
not fname.startswith('__init__')):
|
||||
base = os.path.dirname(__file__)
|
||||
for fname in os.listdir(base):
|
||||
print fname
|
||||
is_python_script = fname.endswith('.py') or fname.endswith('.pyc')
|
||||
is_init_script = fname.startswith('__init__')
|
||||
is_directory = os.path.isdir(os.path.join(base, fname))
|
||||
if (is_directory or is_python_script) and not is_init_script :
|
||||
modname = os.path.basename(fname).rsplit('.', 1)[0]
|
||||
importlib.import_module('.' + modname, __name__)
|
||||
|
||||
_init()
|
||||
|
||||
import Transforms, ADT, Support, Assembly, ExecutionEngine, CodeGen, Target
|
||||
|
|
|
|||
|
|
@ -135,6 +135,22 @@ def test_basic_jit_use():
|
|||
|
||||
assert 44 == gvR.toUnsignedInt()
|
||||
|
||||
# write bitcode
|
||||
bc_buffer = StringIO()
|
||||
api.WriteBitcodeToFile(m, bc_buffer)
|
||||
bc = bc_buffer.getvalue()
|
||||
bc_buffer.close()
|
||||
|
||||
# read bitcode
|
||||
errbuf = StringIO()
|
||||
m2 = api.ParseBitCodeFile(bc, context, errbuf)
|
||||
if not m2:
|
||||
raise Exception(errbuf.getvalue())
|
||||
else:
|
||||
m2.setModuleIdentifier(m.getModuleIdentifier())
|
||||
assert str(m2) == str(m)
|
||||
|
||||
|
||||
def test_engine_builder():
|
||||
api.InitializeNativeTarget()
|
||||
context = api.getGlobalContext()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue