Completed binding for most of ExecutionEngine
This commit is contained in:
parent
25b498c8fa
commit
78f9c9a610
9 changed files with 391 additions and 9 deletions
|
|
@ -59,9 +59,17 @@ class BuiltinTypes(_Type):
|
||||||
|
|
||||||
Void = BuiltinTypes('void')
|
Void = BuiltinTypes('void')
|
||||||
Unsigned = BuiltinTypes('unsigned')
|
Unsigned = BuiltinTypes('unsigned')
|
||||||
|
UnsignedLongLong = BuiltinTypes('unsigned long long') # used in llvm-3.2
|
||||||
|
LongLong = BuiltinTypes('long long')
|
||||||
|
Float = BuiltinTypes('float')
|
||||||
|
Double = BuiltinTypes('double')
|
||||||
Uint64 = BuiltinTypes('uint64_t')
|
Uint64 = BuiltinTypes('uint64_t')
|
||||||
|
Size_t = BuiltinTypes('size_t')
|
||||||
|
VoidPtr = BuiltinTypes('void*')
|
||||||
Bool = BuiltinTypes('bool')
|
Bool = BuiltinTypes('bool')
|
||||||
|
StdString = BuiltinTypes('std::string')
|
||||||
ConstStdString = BuiltinTypes('const std::string')
|
ConstStdString = BuiltinTypes('const std::string')
|
||||||
|
ConstCharPtr = BuiltinTypes('const char*')
|
||||||
PyObjectPtr = BuiltinTypes('PyObject*')
|
PyObjectPtr = BuiltinTypes('PyObject*')
|
||||||
PyObjectPtr.format='O'
|
PyObjectPtr.format='O'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,45 @@ int py_str_to(PyObject *strobj, llvm::StringRef &strref){
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int py_str_to(PyObject *strobj, std::string &strref){
|
||||||
|
// type check
|
||||||
|
if (!PyString_Check(strobj)) {
|
||||||
|
// raises TypeError
|
||||||
|
PyErr_SetString(PyExc_TypeError, "Expecting a str");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// get len and buffer
|
||||||
|
const char * buf = PyString_AsString(strobj);
|
||||||
|
if (!buf) {
|
||||||
|
// raises TypeError
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// set output
|
||||||
|
strref = std::string(buf);
|
||||||
|
// success
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
int py_str_to(PyObject *strobj, const char* &strref){
|
||||||
|
// type check
|
||||||
|
if (!PyString_Check(strobj)) {
|
||||||
|
// raises TypeError
|
||||||
|
PyErr_SetString(PyExc_TypeError, "Expecting a str");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// get buffer
|
||||||
|
strref = PyString_AsString(strobj);
|
||||||
|
if (!strref) {
|
||||||
|
// raises TypeError
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// success
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
int py_int_to(PyObject *intobj, unsigned & val){
|
int py_int_to(PyObject *intobj, unsigned & val){
|
||||||
if (!PyInt_Check(intobj)) {
|
if (!PyInt_Check(intobj)) {
|
||||||
|
|
@ -37,6 +76,70 @@ int py_int_to(PyObject *intobj, unsigned & val){
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int py_int_to(PyObject *intobj, unsigned long long & val){
|
||||||
|
if (!PyInt_Check(intobj)) {
|
||||||
|
// raise TypeError
|
||||||
|
puts(PyString_AsString(PyObject_Str(PyObject_Type(intobj))));
|
||||||
|
PyErr_SetString(PyExc_TypeError, "Expecting an int 2");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
val = PyInt_AsUnsignedLongLongMask(intobj);
|
||||||
|
// success
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int py_int_to(PyObject *intobj, size_t & val){
|
||||||
|
unsigned long long ull;
|
||||||
|
if (py_int_to(intobj, ull)) {
|
||||||
|
val = (size_t)ull;
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
int py_int_to(PyObject *intobj, void* & val){
|
||||||
|
if (!PyLong_Check(intobj)) {
|
||||||
|
// raise TypeError
|
||||||
|
PyErr_SetString(PyExc_TypeError, "Expecting an int");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
val = PyLong_FromVoidPtr(intobj);
|
||||||
|
// success
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int py_float_to(PyObject *floatobj, double & val){
|
||||||
|
if (!PyFloat_Check(floatobj)) {
|
||||||
|
// raise TypeError
|
||||||
|
PyErr_SetString(PyExc_TypeError, "Expecting a float");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
val = PyFloat_AsDouble(floatobj);
|
||||||
|
if (PyErr_Occurred()){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// success
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
int py_float_to(PyObject *floatobj, float & val){
|
||||||
|
double db;
|
||||||
|
int status = py_float_to(floatobj, db);
|
||||||
|
if (status)
|
||||||
|
val = db;
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
int py_bool_to(PyObject *boolobj, bool & val){
|
int py_bool_to(PyObject *boolobj, bool & val){
|
||||||
if (!PyBool_Check(boolobj)) {
|
if (!PyBool_Check(boolobj)) {
|
||||||
|
|
@ -78,8 +181,18 @@ PyObject* py_bool_from(bool val){
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
PyObject* py_int_from(int val){
|
PyObject* py_int_from(const long long & val){
|
||||||
return PyInt_FromLong(val);
|
return PyLong_FromLongLong(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
PyObject* py_int_from(void * addr){
|
||||||
|
return PyLong_FromVoidPtr(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
PyObject* py_float_from(const double& val) {
|
||||||
|
return PyFloat_FromDouble(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
// casting
|
// casting
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
#include <llvm/Function.h>
|
#include <llvm/Function.h>
|
||||||
#include <llvm/Support/raw_ostream.h>
|
#include <llvm/Support/raw_ostream.h>
|
||||||
#include <llvm/ExecutionEngine/ExecutionEngine.h>
|
#include <llvm/ExecutionEngine/ExecutionEngine.h>
|
||||||
|
#include <llvm/ExecutionEngine/GenericValue.h>
|
||||||
|
|
||||||
namespace extra{
|
namespace extra{
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
@ -234,3 +235,108 @@ llvm::ExecutionEngine* ExecutionEngine_createJIT(
|
||||||
PyFile_WriteString(ErrorStr.c_str(), errout);
|
PyFile_WriteString(ErrorStr.c_str(), errout);
|
||||||
return ee;
|
return ee;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
llvm::GenericValue* GenericValue_CreateInt(llvm::Type* Ty, unsigned long long N,
|
||||||
|
bool IsSigned)
|
||||||
|
{
|
||||||
|
// Shamelessly copied from LLVM
|
||||||
|
llvm::GenericValue *GenVal = new llvm::GenericValue();
|
||||||
|
GenVal->IntVal = llvm::APInt(Ty->getIntegerBitWidth(), N, IsSigned);
|
||||||
|
return GenVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
llvm::GenericValue* GenericValue_CreateFloat(float Val)
|
||||||
|
{
|
||||||
|
llvm::GenericValue *GenVal = new llvm::GenericValue();
|
||||||
|
GenVal->FloatVal = Val;
|
||||||
|
return GenVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
llvm::GenericValue* GenericValue_CreateDouble(double Val)
|
||||||
|
{
|
||||||
|
llvm::GenericValue *GenVal = new llvm::GenericValue();
|
||||||
|
GenVal->DoubleVal = Val;
|
||||||
|
return GenVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
llvm::GenericValue* GenericValue_CreatePointer(void * Ptr)
|
||||||
|
{
|
||||||
|
llvm::GenericValue *GenVal = new llvm::GenericValue();
|
||||||
|
GenVal->PointerVal = Ptr;
|
||||||
|
return GenVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
unsigned GenericValue_ValueIntWidth(llvm::GenericValue *GenValRef)
|
||||||
|
{
|
||||||
|
return GenValRef->IntVal.getBitWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
unsigned long long GenericValue_ToUnsignedInt(llvm::GenericValue* GenVal)
|
||||||
|
{
|
||||||
|
return GenVal->IntVal.getZExtValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
long long GenericValue_ToSignedInt(llvm::GenericValue* GenVal)
|
||||||
|
{
|
||||||
|
return GenVal->IntVal.getSExtValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void* GenericValue_ToPointer(llvm::GenericValue* GenVal)
|
||||||
|
{
|
||||||
|
return GenVal->PointerVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
double GenericValue_ToFloat(llvm::GenericValue* GenVal, llvm::Type* Ty)
|
||||||
|
{
|
||||||
|
switch (Ty->getTypeID()) {
|
||||||
|
case llvm::Type::FloatTyID:
|
||||||
|
return GenVal->FloatVal;
|
||||||
|
default:
|
||||||
|
// Behavior undefined if type is not a float or a double
|
||||||
|
return GenVal->DoubleVal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
PyObject* ExecutionEngine_RunFunction(llvm::ExecutionEngine* EE,
|
||||||
|
llvm::Function* Fn, PyObject* Args)
|
||||||
|
{
|
||||||
|
using namespace llvm;
|
||||||
|
const char * GVN = "llvm::GenericValue";
|
||||||
|
if (!PyTuple_Check(Args)) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "Expect a tuple of args.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
std::vector<GenericValue> vec_args;
|
||||||
|
Py_ssize_t nargs = PyTuple_Size(Args);
|
||||||
|
vec_args.reserve(nargs);
|
||||||
|
for (Py_ssize_t i = 0; i < nargs; ++i) {
|
||||||
|
PyObject* obj = PyTuple_GetItem(Args, i);
|
||||||
|
if (!obj) {
|
||||||
|
PyErr_SetString(PyExc_RuntimeError, "Failed to index into args?");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
GenericValue* gv = static_cast<GenericValue*>(
|
||||||
|
PyCapsule_GetPointer(obj, GVN));
|
||||||
|
|
||||||
|
if (!gv) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
vec_args.push_back(*gv);
|
||||||
|
}
|
||||||
|
|
||||||
|
GenericValue ret = EE->runFunction(Fn, vec_args);
|
||||||
|
return pycapsule_new(new GenericValue(ret), GVN);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,11 @@ from Module import Module
|
||||||
from JITMemoryManager import JITMemoryManager
|
from JITMemoryManager import JITMemoryManager
|
||||||
from CodeGen import CodeGenOpt, Reloc, CodeModel
|
from CodeGen import CodeGenOpt, Reloc, CodeModel
|
||||||
from DataLayout import DataLayout
|
from DataLayout import DataLayout
|
||||||
|
from Value import Function, GlobalValue, BasicBlock, Constant
|
||||||
|
from GlobalVariable import GlobalVariable
|
||||||
|
from MachineCodeInfo import MachineCodeInfo
|
||||||
|
from GenericValue import GenericValue
|
||||||
|
from Type import Type
|
||||||
|
|
||||||
ExecutionEngine = llvm.Class()
|
ExecutionEngine = llvm.Class()
|
||||||
|
|
||||||
|
|
@ -32,3 +37,58 @@ class ExecutionEngine:
|
||||||
addModule = Method(Void, ptr(Module))
|
addModule = Method(Void, ptr(Module))
|
||||||
getDataLayout = Method(const(ownedptr(DataLayout)))
|
getDataLayout = Method(const(ownedptr(DataLayout)))
|
||||||
removeModule = Method(cast(Bool, bool), ptr(Module))
|
removeModule = Method(cast(Bool, bool), ptr(Module))
|
||||||
|
|
||||||
|
FindFunctionNamed = Method(ptr(Function), cast(str, ConstCharPtr))
|
||||||
|
getPointerToNamedFunction = Method(cast(VoidPtr, int),
|
||||||
|
cast(str, StdString),
|
||||||
|
cast(bool, Bool)).require_only(1)
|
||||||
|
|
||||||
|
runStaticConstructorsDestructors = Method(Void, cast(Bool, bool))
|
||||||
|
runStaticConstructorsDestructors |= Method(Void, ptr(Module),
|
||||||
|
cast(Bool, bool))
|
||||||
|
|
||||||
|
addGlobalMapping = Method(Void, ptr(GlobalValue), cast(int, VoidPtr))
|
||||||
|
clearAllGlobalMappings = Method()
|
||||||
|
clearGlobalMappingsFromModule = Method(Void, ptr(Module))
|
||||||
|
updateGlobalMapping = Method(cast(VoidPtr, int),
|
||||||
|
ptr(GlobalValue), cast(int, VoidPtr))
|
||||||
|
|
||||||
|
getPointerToGlobalIfAvailable = Method(cast(VoidPtr, int), ptr(GlobalValue))
|
||||||
|
getPointerToGlobal = Method(cast(VoidPtr, int), ptr(GlobalValue))
|
||||||
|
getPointerToFunction = Method(cast(VoidPtr, int), ptr(Function))
|
||||||
|
getPointerToBasicBlock = Method(cast(VoidPtr, int), ptr(BasicBlock))
|
||||||
|
getPointerToFunctionOrStub = Method(cast(VoidPtr, int), ptr(Function))
|
||||||
|
|
||||||
|
runJITOnFunction = Method(Void, ptr(Function), ptr(MachineCodeInfo))
|
||||||
|
runJITOnFunction.require_only(1)
|
||||||
|
|
||||||
|
getGlobalValueAtAddress = Method(const(ptr(GlobalValue)), cast(int, VoidPtr))
|
||||||
|
|
||||||
|
StoreValueToMemory = Method(Void, ref(GenericValue), ptr(GenericValue),
|
||||||
|
ptr(Type))
|
||||||
|
|
||||||
|
InitializeMemory = Method(Void, ptr(Constant), cast(int, VoidPtr))
|
||||||
|
|
||||||
|
recompileAndRelinkFunction = Method(cast(int, VoidPtr), ptr(Function))
|
||||||
|
|
||||||
|
freeMachineCodeForFunction = Method(Void, ptr(Function))
|
||||||
|
getOrEmitGlobalVariable = Method(cast(int, VoidPtr), ptr(GlobalVariable))
|
||||||
|
|
||||||
|
DisableLazyCompilation = Method(Void, cast(bool, Bool))
|
||||||
|
isCompilingLazily = Method(cast(Bool, bool))
|
||||||
|
isLazyCompilationDisabled = Method(cast(Bool, bool))
|
||||||
|
DisableGVCompilation = Method(Void, cast(bool, Bool))
|
||||||
|
isSymbolSearchingDisabled = Method(cast(Bool, bool))
|
||||||
|
RegisterTable = Method(Void, ptr(Function), cast(int, VoidPtr))
|
||||||
|
DeregisterTable = Method(Void, ptr(Function))
|
||||||
|
DeregisterAllTables = Method()
|
||||||
|
|
||||||
|
_runFunction = CustomMethod('ExecutionEngine_RunFunction',
|
||||||
|
PyObjectPtr, ptr(Function), PyObjectPtr)
|
||||||
|
|
||||||
|
@CustomPythonMethod
|
||||||
|
def runFunction(self, fn, args):
|
||||||
|
import capsule
|
||||||
|
unwrapped = map(capsule.unwrap, args)
|
||||||
|
return self._runFunction(fn, tuple(unwrapped))
|
||||||
|
|
||||||
|
|
|
||||||
34
newbinding/src/GenericValue.py
Normal file
34
newbinding/src/GenericValue.py
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
from binding import *
|
||||||
|
from namespace import llvm
|
||||||
|
from Type import Type
|
||||||
|
|
||||||
|
GenericValue = llvm.Class()
|
||||||
|
|
||||||
|
@GenericValue
|
||||||
|
class GenericValue:
|
||||||
|
delete = Destructor()
|
||||||
|
|
||||||
|
def _factory(name, *argtys):
|
||||||
|
return CustomStaticMethod('GenericValue_' + name,
|
||||||
|
ptr(GenericValue), *argtys)
|
||||||
|
|
||||||
|
CreateFloat = _factory('CreateFloat', cast(float, Float))
|
||||||
|
|
||||||
|
CreateDouble = _factory('CreateDouble', cast(float, Float))
|
||||||
|
|
||||||
|
CreateInt = _factory('CreateInt', ptr(Type),
|
||||||
|
cast(int, UnsignedLongLong), cast(bool, Bool))
|
||||||
|
|
||||||
|
CreatePointer = _factory('CreatePointer', cast(int, VoidPtr))
|
||||||
|
|
||||||
|
def _accessor(name, *argtys):
|
||||||
|
return CustomMethod('GenericValue_' + name, *argtys)
|
||||||
|
|
||||||
|
valueIntWidth = _accessor('ValueIntWidth', cast(Unsigned, int))
|
||||||
|
|
||||||
|
toSignedInt = _accessor('ToSignedInt', cast(UnsignedLongLong, int))
|
||||||
|
toUnsignedInt = _accessor('ToUnsignedInt', cast(LongLong, int))
|
||||||
|
|
||||||
|
toFloat = _accessor('ToFloat', cast(Double, float), ptr(Type))
|
||||||
|
|
||||||
|
toPointer = _accessor('ToPointer', cast(VoidPtr, int))
|
||||||
13
newbinding/src/MachineCodeInfo.py
Normal file
13
newbinding/src/MachineCodeInfo.py
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
from binding import *
|
||||||
|
from namespace import llvm
|
||||||
|
|
||||||
|
MachineCodeInfo = llvm.Class()
|
||||||
|
|
||||||
|
@MachineCodeInfo
|
||||||
|
class MachineCodeInfo:
|
||||||
|
_include_ = 'llvm/CodeGen/MachineCodeInfo.h'
|
||||||
|
setSize = Method(Void, cast(int, Size_t))
|
||||||
|
setAddress = Method(Void, cast(int, VoidPtr))
|
||||||
|
size = Method(cast(Size_t, int))
|
||||||
|
address = Method(cast(VoidPtr, int))
|
||||||
|
|
||||||
|
|
@ -44,4 +44,11 @@ class Module:
|
||||||
print_ = Method(Void, ref(raw_ostream), ptr(AssemblyAnnotationWriter))
|
print_ = Method(Void, ref(raw_ostream), ptr(AssemblyAnnotationWriter))
|
||||||
print_.realname = 'print'
|
print_.realname = 'print'
|
||||||
|
|
||||||
|
@CustomPythonMethod
|
||||||
|
def __str__(self):
|
||||||
|
import extra
|
||||||
|
os = extra.make_raw_ostream_for_printing()
|
||||||
|
self.print_(os, None)
|
||||||
|
return os.str()
|
||||||
|
|
||||||
dropAllReferences = Method()
|
dropAllReferences = Method()
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ from binding import *
|
||||||
from namespace import llvm
|
from namespace import llvm
|
||||||
from LLVMContext import LLVMContext
|
from LLVMContext import LLVMContext
|
||||||
from raw_ostream import raw_ostream
|
from raw_ostream import raw_ostream
|
||||||
|
from StringRef import StringRef
|
||||||
|
|
||||||
Type = llvm.Class()
|
Type = llvm.Class()
|
||||||
IntegerType = llvm.Class(Type)
|
IntegerType = llvm.Class(Type)
|
||||||
|
|
@ -52,6 +53,19 @@ class Type:
|
||||||
isIntegerTy = Method(cast(Bool, bool))
|
isIntegerTy = Method(cast(Bool, bool))
|
||||||
isIntegerTy |= Method(cast(Bool, bool), cast(int, Unsigned))
|
isIntegerTy |= Method(cast(Bool, bool), cast(int, Unsigned))
|
||||||
|
|
||||||
|
getIntegerBitWidth = Method(cast(Unsigned, int))
|
||||||
|
getFunctionParamType = Method(ptr(Type), cast(int, Unsigned))
|
||||||
|
getFunctionNumParams = Method(cast(int, Unsigned))
|
||||||
|
|
||||||
|
isFunctionVarArg = type_checker()
|
||||||
|
|
||||||
|
getStructName = Method(cast(StringRef, str))
|
||||||
|
getStructNumElements = Method(cast(Unsigned, int))
|
||||||
|
getStructElementType = Method(ptr(Type), cast(int, Unsigned))
|
||||||
|
getSequentialElementType = Method(ptr(Type))
|
||||||
|
|
||||||
|
# Factories
|
||||||
|
|
||||||
|
|
||||||
def type_factory():
|
def type_factory():
|
||||||
return StaticMethod(ptr(Type), ref(LLVMContext))
|
return StaticMethod(ptr(Type), ref(LLVMContext))
|
||||||
|
|
|
||||||
|
|
@ -28,25 +28,25 @@ print os.str()
|
||||||
int1ty = api.Type.getInt1Ty(context)
|
int1ty = api.Type.getInt1Ty(context)
|
||||||
int1ty.dump()
|
int1ty.dump()
|
||||||
|
|
||||||
print int1ty.isIntegerTy(1)
|
assert int1ty.isIntegerTy(1)
|
||||||
|
|
||||||
fnty = api.FunctionType.get(int1ty, False)
|
fnty = api.FunctionType.get(int1ty, False)
|
||||||
fnty.dump()
|
fnty.dump()
|
||||||
|
|
||||||
types = [int1ty, api.Type.getIntNTy(context, 21)]
|
types = [api.Type.getIntNTy(context, 8), api.Type.getIntNTy(context, 32)]
|
||||||
fnty = api.FunctionType.get(int1ty, types, False)
|
fnty = api.FunctionType.get(api.Type.getIntNTy(context, 8), types, False)
|
||||||
|
|
||||||
print fnty
|
print fnty
|
||||||
|
|
||||||
const = m.getOrInsertFunction("foo", fnty)
|
const = m.getOrInsertFunction("foo", fnty)
|
||||||
fn = extra.downcast(const, api.Function)
|
fn = const._downcast(api.Function)
|
||||||
print fn
|
print fn
|
||||||
assert fn.hasName()
|
assert fn.hasName()
|
||||||
assert 'foo' == fn.getName()
|
assert 'foo' == fn.getName()
|
||||||
fn.setName('bar')
|
fn.setName('bar')
|
||||||
assert 'bar' == fn.getName()
|
assert 'bar' == fn.getName()
|
||||||
|
|
||||||
assert fn.getReturnType() is int1ty
|
assert fn.getReturnType().isIntegerTy(8)
|
||||||
|
|
||||||
assert fnty is fn.getFunctionType()
|
assert fnty is fn.getFunctionType()
|
||||||
|
|
||||||
|
|
@ -70,13 +70,19 @@ assert bb.getTerminator() is None
|
||||||
arg0, arg1 = fn.getArgumentList()
|
arg0, arg1 = fn.getArgumentList()
|
||||||
print arg0, arg1
|
print arg0, arg1
|
||||||
|
|
||||||
ret = builder.CreateCall(fn, [arg0, arg1], '')
|
extended = builder.CreateZExt(arg0, arg1.getType())
|
||||||
|
result = builder.CreateAdd(extended, arg1)
|
||||||
|
ret = builder.CreateTrunc(result, fn.getReturnType())
|
||||||
builder.CreateRet(ret)
|
builder.CreateRet(ret)
|
||||||
|
|
||||||
|
print arg0.list_use()
|
||||||
|
|
||||||
print fn
|
print fn
|
||||||
|
|
||||||
errio = StringIO()
|
errio = StringIO()
|
||||||
ee = api.ExecutionEngine.createJIT(m)
|
print m
|
||||||
|
|
||||||
|
ee = api.ExecutionEngine.createJIT(m, errio)
|
||||||
print ee, errio.getvalue()
|
print ee, errio.getvalue()
|
||||||
print ee.getDataLayout().getStringRepresentation()
|
print ee.getDataLayout().getStringRepresentation()
|
||||||
|
|
||||||
|
|
@ -85,3 +91,24 @@ datalayout_str = 'e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-
|
||||||
assert datalayout_str == str(api.DataLayout.new(datalayout_str))
|
assert datalayout_str == str(api.DataLayout.new(datalayout_str))
|
||||||
assert datalayout_str == str(api.DataLayout.new(str(api.DataLayout.new(datalayout_str))))
|
assert datalayout_str == str(api.DataLayout.new(str(api.DataLayout.new(datalayout_str))))
|
||||||
|
|
||||||
|
fn2 = ee.FindFunctionNamed(fn.getName())
|
||||||
|
assert fn2 is fn
|
||||||
|
|
||||||
|
assert ee.getPointerToFunction(fn)
|
||||||
|
assert ee.getPointerToNamedFunction('printf')
|
||||||
|
|
||||||
|
gv0 = api.GenericValue.CreateInt(arg0.getType(), 12, False)
|
||||||
|
gv1 = api.GenericValue.CreateInt(arg1.getType(), -32, True)
|
||||||
|
|
||||||
|
assert gv0.valueIntWidth() == arg0.getType().getIntegerBitWidth()
|
||||||
|
assert gv1.valueIntWidth() == arg1.getType().getIntegerBitWidth()
|
||||||
|
|
||||||
|
assert gv0.toUnsignedInt() == 12
|
||||||
|
assert gv1.toSignedInt() == -32
|
||||||
|
|
||||||
|
gv1 = api.GenericValue.CreateInt(arg1.getType(), 32, False)
|
||||||
|
|
||||||
|
gvR = ee.runFunction(fn, (gv0, gv1))
|
||||||
|
|
||||||
|
assert 44 == gvR.toUnsignedInt()
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue