All of DataLayout, IRBuilder and started on ExecutionEngine.
This commit is contained in:
parent
59d0dfddc7
commit
437b1e9490
20 changed files with 688 additions and 41 deletions
|
|
@ -5,11 +5,15 @@ import codegen as cg
|
||||||
_rank = 0
|
_rank = 0
|
||||||
namespaces = {}
|
namespaces = {}
|
||||||
|
|
||||||
|
RESERVED = frozenset(['None'])
|
||||||
|
|
||||||
class Namespace(object):
|
class Namespace(object):
|
||||||
def __init__(self, name):
|
def __init__(self, name):
|
||||||
self.name = name
|
self.name = name
|
||||||
|
self.enums = []
|
||||||
self.classes = []
|
self.classes = []
|
||||||
self.functions = []
|
self.functions = []
|
||||||
|
self.includes = set()
|
||||||
namespaces[name] = self
|
namespaces[name] = self
|
||||||
|
|
||||||
def Class(self, *bases):
|
def Class(self, *bases):
|
||||||
|
|
@ -22,6 +26,13 @@ class Namespace(object):
|
||||||
self.functions.append(fn)
|
self.functions.append(fn)
|
||||||
return fn
|
return fn
|
||||||
|
|
||||||
|
def Enum(self, name, *value_names):
|
||||||
|
enum = Enum(*value_names)
|
||||||
|
enum.parent = self
|
||||||
|
enum.name = name
|
||||||
|
self.enums.append(enum)
|
||||||
|
return enum
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def fullname(self):
|
def fullname(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
@ -43,11 +54,16 @@ class BuiltinTypes(_Type):
|
||||||
def wrap(self, writer, var):
|
def wrap(self, writer, var):
|
||||||
return var
|
return var
|
||||||
|
|
||||||
|
def unwrap(self, writer, var):
|
||||||
|
return var
|
||||||
|
|
||||||
Void = BuiltinTypes('void')
|
Void = BuiltinTypes('void')
|
||||||
Unsigned = BuiltinTypes('unsigned')
|
Unsigned = BuiltinTypes('unsigned')
|
||||||
|
Uint64 = BuiltinTypes('uint64_t')
|
||||||
Bool = BuiltinTypes('bool')
|
Bool = BuiltinTypes('bool')
|
||||||
ConstStdString = BuiltinTypes('const std::string')
|
ConstStdString = BuiltinTypes('const std::string')
|
||||||
PyObjectPtr = BuiltinTypes('PyObject*')
|
PyObjectPtr = BuiltinTypes('PyObject*')
|
||||||
|
PyObjectPtr.format='O'
|
||||||
|
|
||||||
class Class(_Type):
|
class Class(_Type):
|
||||||
format = 'O'
|
format = 'O'
|
||||||
|
|
@ -78,6 +94,7 @@ class Class(_Type):
|
||||||
self.enums.append(v)
|
self.enums.append(v)
|
||||||
v.name = k
|
v.name = k
|
||||||
v.parent = self
|
v.parent = self
|
||||||
|
setattr(self, k, v)
|
||||||
elif isinstance(v, CustomPythonMethod):
|
elif isinstance(v, CustomPythonMethod):
|
||||||
self.pymethods.append(v)
|
self.pymethods.append(v)
|
||||||
elif k == '_include_':
|
elif k == '_include_':
|
||||||
|
|
@ -108,7 +125,7 @@ class Class(_Type):
|
||||||
fmt = '{ "%(name)s", (PyCFunction)%(func)s, METH_VARARGS, NULL },'
|
fmt = '{ "%(name)s", (PyCFunction)%(func)s, METH_VARARGS, NULL },'
|
||||||
for meth in self.methods:
|
for meth in self.methods:
|
||||||
name = meth.name
|
name = meth.name
|
||||||
func = cg.mangle(meth.fullname)
|
func = meth.c_name
|
||||||
writer.println(fmt % locals())
|
writer.println(fmt % locals())
|
||||||
writer.println('{ NULL },')
|
writer.println('{ NULL },')
|
||||||
writer.println('};')
|
writer.println('};')
|
||||||
|
|
@ -161,9 +178,12 @@ class Class(_Type):
|
||||||
return casted
|
return casted
|
||||||
|
|
||||||
class Enum(object):
|
class Enum(object):
|
||||||
|
format = 'O'
|
||||||
|
|
||||||
def __init__(self, *value_names):
|
def __init__(self, *value_names):
|
||||||
self.parent = None
|
self.parent = None
|
||||||
self.value_names = value_names
|
self.value_names = value_names
|
||||||
|
self.includes = set()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def fullname(self):
|
def fullname(self):
|
||||||
|
|
@ -191,11 +211,34 @@ class Enum(object):
|
||||||
writer.raises(ValueError, 'Invalid enum %s' % v)
|
writer.raises(ValueError, 'Invalid enum %s' % v)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
def unwrap(self, writer, val):
|
||||||
|
tostring = 'PyString_AsString(%(val)s)' % locals()
|
||||||
|
string = writer.declare('const char*', tostring)
|
||||||
|
ret = writer.declare('%s::%s' % (self.parent, self.name))
|
||||||
|
parent = self.parent
|
||||||
|
iffmt = 'if (string_equal(%(string)s, "%(v)s"))'
|
||||||
|
for i, v in enumerate(self.value_names):
|
||||||
|
with writer.block(iffmt % locals()):
|
||||||
|
fmt = '%(ret)s = %(parent)s::%(v)s;'
|
||||||
|
writer.println(fmt % locals())
|
||||||
|
if i == 0:
|
||||||
|
iffmt = 'else ' + iffmt
|
||||||
|
with writer.block('else'):
|
||||||
|
writer.raises(ValueError, 'Invalid enum.')
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def compile_cpp(self, writer):
|
||||||
|
pass
|
||||||
|
|
||||||
def compile_py(self, writer):
|
def compile_py(self, writer):
|
||||||
with writer.block('class %s:' % self.name):
|
with writer.block('class %s:' % self.name):
|
||||||
writer.println('_llvm_type_ = "%s"' % self.fullname)
|
writer.println('_llvm_type_ = "%s"' % self.fullname)
|
||||||
for v in self.value_names:
|
for v in self.value_names:
|
||||||
writer.println('%(v)s = "%(v)s"' % locals())
|
if v in RESERVED:
|
||||||
|
k = '%s_' % v
|
||||||
|
else:
|
||||||
|
k = v
|
||||||
|
writer.println('%(k)s = "%(v)s"' % locals())
|
||||||
writer.println()
|
writer.println()
|
||||||
|
|
||||||
class Method(object):
|
class Method(object):
|
||||||
|
|
@ -236,11 +279,15 @@ class Method(object):
|
||||||
def realname(self, v):
|
def realname(self, v):
|
||||||
self.__realname = v
|
self.__realname = v
|
||||||
|
|
||||||
|
@property
|
||||||
|
def c_name(self):
|
||||||
|
return cg.mangle("%s_%s" % (self.parent, self.name))
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.fullname
|
return self.fullname
|
||||||
|
|
||||||
def compile_cpp(self, writer):
|
def compile_cpp(self, writer):
|
||||||
with writer.py_function(self.fullname):
|
with writer.py_function(self.c_name):
|
||||||
if len(self.signatures) == 1:
|
if len(self.signatures) == 1:
|
||||||
sig = self.signatures[0]
|
sig = self.signatures[0]
|
||||||
retty = sig[0]
|
retty = sig[0]
|
||||||
|
|
@ -270,13 +317,40 @@ class Method(object):
|
||||||
with decl as (this, varargs):
|
with decl as (this, varargs):
|
||||||
unwrap_this = writer.unwrap(this)
|
unwrap_this = writer.unwrap(this)
|
||||||
unwrapped = writer.unwrap_many(varargs)
|
unwrapped = writer.unwrap_many(varargs)
|
||||||
|
self.process_ownedptr_args(writer, unwrapped)
|
||||||
|
|
||||||
func = '.'.join([self.parent.name, self.name])
|
func = '.'.join([self.parent.name, self.name])
|
||||||
ret = writer.call('_api.%s' % func,
|
ret = writer.call('_api.%s' % func,
|
||||||
args=(unwrap_this,), varargs=unwrapped)
|
args=(unwrap_this,), varargs=unwrapped)
|
||||||
wrapped = writer.wrap(ret)
|
|
||||||
|
wrapped = writer.wrap(ret, self.is_return_ownedptr())
|
||||||
|
|
||||||
writer.return_value(wrapped)
|
writer.return_value(wrapped)
|
||||||
writer.println()
|
writer.println()
|
||||||
|
|
||||||
|
def require_only(self, num):
|
||||||
|
'''Require only "num" of argument.
|
||||||
|
'''
|
||||||
|
assert len(self.signatures) == 1
|
||||||
|
sig = self.signatures[0]
|
||||||
|
ret = sig[0]
|
||||||
|
args = sig[1:]
|
||||||
|
arg_ct = len(args)
|
||||||
|
|
||||||
|
for i in range(num, arg_ct):
|
||||||
|
self._add_signature(ret, *args[:i])
|
||||||
|
|
||||||
|
return self
|
||||||
|
|
||||||
|
def is_return_ownedptr(self):
|
||||||
|
retty = self.signatures[0][0]
|
||||||
|
return isinstance(retty, ownedptr)
|
||||||
|
|
||||||
|
def process_ownedptr_args(self, writer, unwrapped):
|
||||||
|
argtys = self.signatures[0][1:]
|
||||||
|
for i, ty in enumerate(argtys):
|
||||||
|
if isinstance(ty, ownedptr):
|
||||||
|
writer.release_ownership('%s[%d]' % (unwrapped, i))
|
||||||
|
|
||||||
class CustomMethod(Method):
|
class CustomMethod(Method):
|
||||||
def __init__(self, methodname, retty, *argtys):
|
def __init__(self, methodname, retty, *argtys):
|
||||||
|
|
@ -289,7 +363,6 @@ class CustomMethod(Method):
|
||||||
writer.return_value(retty.wrap(writer, ret))
|
writer.return_value(retty.wrap(writer, ret))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class StaticMethod(Method):
|
class StaticMethod(Method):
|
||||||
|
|
||||||
def compile_cpp_body(self, writer, retty, argtys):
|
def compile_cpp_body(self, writer, retty, argtys):
|
||||||
|
|
@ -307,12 +380,24 @@ class StaticMethod(Method):
|
||||||
decl = writer.function(self.name, varargs='args')
|
decl = writer.function(self.name, varargs='args')
|
||||||
with decl as varargs:
|
with decl as varargs:
|
||||||
unwrapped = writer.unwrap_many(varargs)
|
unwrapped = writer.unwrap_many(varargs)
|
||||||
|
self.process_ownedptr_args(writer, unwrapped)
|
||||||
|
|
||||||
func = '.'.join([self.parent.name, self.name])
|
func = '.'.join([self.parent.name, self.name])
|
||||||
ret = writer.call('_api.%s' % func, varargs=unwrapped)
|
ret = writer.call('_api.%s' % func, varargs=unwrapped)
|
||||||
wrapped = writer.wrap(ret)
|
wrapped = writer.wrap(ret, self.is_return_ownedptr())
|
||||||
writer.return_value(wrapped)
|
writer.return_value(wrapped)
|
||||||
writer.println()
|
writer.println()
|
||||||
|
|
||||||
|
class CustomStaticMethod(StaticMethod):
|
||||||
|
def __init__(self, methodname, retty, *argtys):
|
||||||
|
super(CustomStaticMethod, self).__init__(retty, *argtys)
|
||||||
|
self.methodname = methodname
|
||||||
|
|
||||||
|
def compile_cpp_body(self, writer, retty, argtys):
|
||||||
|
args = writer.parse_arguments('args', *argtys)
|
||||||
|
ret = writer.call(self.methodname, retty.fullname, *args)
|
||||||
|
writer.return_value(retty.wrap(writer, ret))
|
||||||
|
|
||||||
class Function(Method):
|
class Function(Method):
|
||||||
_kind_ = 'func'
|
_kind_ = 'func'
|
||||||
|
|
||||||
|
|
@ -329,10 +414,11 @@ class Function(Method):
|
||||||
def compile_py(self, writer):
|
def compile_py(self, writer):
|
||||||
with writer.function(self.name, varargs='args') as varargs:
|
with writer.function(self.name, varargs='args') as varargs:
|
||||||
unwrapped = writer.unwrap_many(varargs)
|
unwrapped = writer.unwrap_many(varargs)
|
||||||
|
self.process_ownedptr_args(writer, unwrapped)
|
||||||
func = self.fullname.split('::', 1)[1].replace('::', '.')
|
func = self.fullname.split('::', 1)[1].replace('::', '.')
|
||||||
ret = writer.call('_api.%s' % func,
|
ret = writer.call('_api.%s' % func,
|
||||||
varargs=unwrapped)
|
varargs=unwrapped)
|
||||||
wrapped = writer.wrap(ret)
|
wrapped = writer.wrap(ret, self.is_return_ownedptr())
|
||||||
writer.return_value(wrapped)
|
writer.return_value(wrapped)
|
||||||
writer.println()
|
writer.println()
|
||||||
|
|
||||||
|
|
@ -400,10 +486,14 @@ class ptr(_Type):
|
||||||
def __init__(self, element):
|
def __init__(self, element):
|
||||||
assert isinstance(element, Class)
|
assert isinstance(element, Class)
|
||||||
self.element = element
|
self.element = element
|
||||||
|
self.const = False
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def fullname(self):
|
def fullname(self):
|
||||||
return '%s*' % self.element
|
if self.const:
|
||||||
|
return 'const %s*' % self.element
|
||||||
|
else:
|
||||||
|
return '%s*' % self.element
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def format(self):
|
def format(self):
|
||||||
|
|
@ -420,6 +510,13 @@ class ptr(_Type):
|
||||||
return writer.pycapsule_new(val, self.element.capsule_name,
|
return writer.pycapsule_new(val, self.element.capsule_name,
|
||||||
self.element.fullname)
|
self.element.fullname)
|
||||||
|
|
||||||
|
class ownedptr(ptr):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def const(ptr):
|
||||||
|
ptr.const = True
|
||||||
|
return ptr
|
||||||
|
|
||||||
class cast(_Type):
|
class cast(_Type):
|
||||||
format = 'O'
|
format = 'O'
|
||||||
|
|
||||||
|
|
@ -458,7 +555,6 @@ class cast(_Type):
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class CustomPythonMethod(object):
|
class CustomPythonMethod(object):
|
||||||
def __init__(self, fn):
|
def __init__(self, fn):
|
||||||
src = inspect.getsource(fn)
|
src = inspect.getsource(fn)
|
||||||
|
|
|
||||||
|
|
@ -23,10 +23,11 @@ class WeakRef(ref):
|
||||||
|
|
||||||
_pyclasses = {}
|
_pyclasses = {}
|
||||||
_addr2obj = WeakValueDictionary()
|
_addr2obj = WeakValueDictionary()
|
||||||
_owners = {}
|
_owners = {} # address to weak reference
|
||||||
|
|
||||||
def _sentry(ptr):
|
def _sentry(ptr):
|
||||||
assert _capsule.check(ptr)
|
if not _capsule.check(ptr):
|
||||||
|
raise ValueError('Must provide a PyCapsule object.')
|
||||||
|
|
||||||
def classof(cap):
|
def classof(cap):
|
||||||
cls = _capsule.getClassName(cap)
|
cls = _capsule.getClassName(cap)
|
||||||
|
|
@ -38,17 +39,16 @@ def _capsule_destructor(weak):
|
||||||
addr = _capsule.getPointer(cap)
|
addr = _capsule.getPointer(cap)
|
||||||
cls = _capsule.getClassName(cap)
|
cls = _capsule.getClassName(cap)
|
||||||
logger.debug("destroy pointer 0x%08X to %s", addr, cls)
|
logger.debug("destroy pointer 0x%08X to %s", addr, cls)
|
||||||
weak.dtor(cap)
|
# weak.dtor(cap)
|
||||||
del _owners[addr]
|
del _owners[addr]
|
||||||
|
|
||||||
def release_ownership(old):
|
def release_ownership(old):
|
||||||
addr = _capsule.getPointer(old)
|
addr = _capsule.getPointer(old)
|
||||||
if hasattr(old, '_delete_'):
|
oldweak = _owners[addr]
|
||||||
oldweak = _owners[addr]
|
oldweak.owning = False # dis-own
|
||||||
oldweak.owning = False # dis-own
|
del _owners[addr]
|
||||||
del _owners[addr]
|
|
||||||
|
|
||||||
def wrap(cap):
|
def wrap(cap, owned=False):
|
||||||
'''Wrap a PyCapsule with the corresponding Wrapper class.
|
'''Wrap a PyCapsule with the corresponding Wrapper class.
|
||||||
If `cap` is not a PyCapsule, returns `cap`
|
If `cap` is not a PyCapsule, returns `cap`
|
||||||
'''
|
'''
|
||||||
|
|
@ -66,7 +66,8 @@ def wrap(cap):
|
||||||
obj = cls(cap)
|
obj = cls(cap)
|
||||||
_addr2obj[addr] = obj # cache object by address
|
_addr2obj[addr] = obj # cache object by address
|
||||||
# set ownership if *cls* defines *_delete_*
|
# set ownership if *cls* defines *_delete_*
|
||||||
if hasattr(cls, '_delete_'):
|
if not owned and hasattr(cls, '_delete_'):
|
||||||
|
assert addr not in _owners, "has existing owner"
|
||||||
weak = WeakRef(obj, _capsule_destructor)
|
weak = WeakRef(obj, _capsule_destructor)
|
||||||
_owners[addr] = weak
|
_owners[addr] = weak
|
||||||
weak.capsule = cap
|
weak.capsule = cap
|
||||||
|
|
@ -84,10 +85,11 @@ def wrap(cap):
|
||||||
|
|
||||||
def downcast(old, new):
|
def downcast(old, new):
|
||||||
assert old is not new
|
assert old is not new
|
||||||
|
assert _capsule.getPointer(old) not in _owners
|
||||||
oldcls = classof(old)
|
oldcls = classof(old)
|
||||||
newcls = classof(new)
|
newcls = classof(new)
|
||||||
assert issubclass(newcls, oldcls)
|
assert issubclass(newcls, oldcls)
|
||||||
release_ownership(old)
|
# release_ownership(old)
|
||||||
del _addr2obj[_capsule.getPointer(old)] # clear cache
|
del _addr2obj[_capsule.getPointer(old)] # clear cache
|
||||||
return wrap(new)
|
return wrap(new)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -104,10 +104,9 @@ class CodeWriterBase(object):
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def py_function(self, name):
|
def py_function(self, name):
|
||||||
mangled = mangle(name)
|
|
||||||
self.println('static')
|
self.println('static')
|
||||||
self.println('PyObject*')
|
self.println('PyObject*')
|
||||||
with self.block('%(mangled)s(PyObject* self, PyObject* args)' % locals()):
|
with self.block('%(name)s(PyObject* self, PyObject* args)' % locals()):
|
||||||
self.used_symbols.add('self')
|
self.used_symbols.add('self')
|
||||||
self.used_symbols.add('args')
|
self.used_symbols.add('args')
|
||||||
yield
|
yield
|
||||||
|
|
@ -175,7 +174,7 @@ class CppCodeWriter(CodeWriterBase):
|
||||||
arglist = ', '.join(args)
|
arglist = ', '.join(args)
|
||||||
stmt = '%(func)s(%(arglist)s)' % locals()
|
stmt = '%(func)s(%(arglist)s)' % locals()
|
||||||
if retty == 'void':
|
if retty == 'void':
|
||||||
self.println(stmt)
|
self.println(stmt + ';')
|
||||||
else:
|
else:
|
||||||
return self.declare(retty, stmt)
|
return self.declare(retty, stmt)
|
||||||
|
|
||||||
|
|
@ -247,6 +246,9 @@ class PyCodeWriter(CodeWriterBase):
|
||||||
yield
|
yield
|
||||||
self.used_symbols = self.old
|
self.used_symbols = self.old
|
||||||
|
|
||||||
|
def release_ownership(self, val):
|
||||||
|
self.println('capsule.release_ownership(%(val)s)' % locals())
|
||||||
|
|
||||||
def unwrap_many(self, args):
|
def unwrap_many(self, args):
|
||||||
unwrapped = self.new_symbol('unwrapped')
|
unwrapped = self.new_symbol('unwrapped')
|
||||||
self.println('%(unwrapped)s = map(capsule.unwrap, %(args)s)' % locals())
|
self.println('%(unwrapped)s = map(capsule.unwrap, %(args)s)' % locals())
|
||||||
|
|
@ -255,9 +257,9 @@ class PyCodeWriter(CodeWriterBase):
|
||||||
def unwrap(self, val):
|
def unwrap(self, val):
|
||||||
return self.call('capsule.unwrap', args=(val,), ret='unwrapped')
|
return self.call('capsule.unwrap', args=(val,), ret='unwrapped')
|
||||||
|
|
||||||
def wrap(self, val):
|
def wrap(self, val, owned):
|
||||||
wrapped = self.new_symbol('wrapped')
|
wrapped = self.new_symbol('wrapped')
|
||||||
self.println('%(wrapped)s = capsule.wrap(%(val)s)' % locals())
|
self.println('%(wrapped)s = capsule.wrap(%(val)s, %(owned)s)' % locals())
|
||||||
return wrapped
|
return wrapped
|
||||||
|
|
||||||
def call(self, func, args=(), varargs=None, ret='ret'):
|
def call(self, func, args=(), varargs=None, ret='ret'):
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ populate_submodules(module, submodules);
|
||||||
|
|
||||||
def populate_headers(println):
|
def populate_headers(println):
|
||||||
includes = [
|
includes = [
|
||||||
|
'cstring',
|
||||||
'llvm_binding/conversion.h',
|
'llvm_binding/conversion.h',
|
||||||
'llvm_binding/binding.h',
|
'llvm_binding/binding.h',
|
||||||
'llvm_binding/capsule_context.h',
|
'llvm_binding/capsule_context.h',
|
||||||
|
|
@ -70,6 +71,9 @@ def main():
|
||||||
for cls in ns.classes:
|
for cls in ns.classes:
|
||||||
print cls
|
print cls
|
||||||
units.append(cls)
|
units.append(cls)
|
||||||
|
for enum in ns.enums:
|
||||||
|
print enum
|
||||||
|
units.append(enum)
|
||||||
|
|
||||||
# add extra stuffs
|
# add extra stuffs
|
||||||
downcastlist = []
|
downcastlist = []
|
||||||
|
|
@ -84,7 +88,7 @@ def main():
|
||||||
units.append(fn)
|
units.append(fn)
|
||||||
|
|
||||||
|
|
||||||
# generate cpp source
|
# Generate C++ source
|
||||||
with open('%s.cpp' % outputfilename, 'w') as cppfile:
|
with open('%s.cpp' % outputfilename, 'w') as cppfile:
|
||||||
println = wrap_println_from_file(cppfile)
|
println = wrap_println_from_file(cppfile)
|
||||||
|
|
||||||
|
|
@ -93,6 +97,8 @@ def main():
|
||||||
|
|
||||||
# required headers
|
# required headers
|
||||||
includes = set()
|
includes = set()
|
||||||
|
for ns in namespaces.values():
|
||||||
|
includes |= ns.includes
|
||||||
for u in units:
|
for u in units:
|
||||||
includes |= u.includes
|
includes |= u.includes
|
||||||
|
|
||||||
|
|
@ -128,7 +134,7 @@ static
|
||||||
for u in units:
|
for u in units:
|
||||||
if isinstance(u, Function):
|
if isinstance(u, Function):
|
||||||
name = u.name
|
name = u.name
|
||||||
func = codegen.mangle(u.fullname)
|
func = u.c_name
|
||||||
writer.println(fmt % locals())
|
writer.println(fmt % locals())
|
||||||
writer.println('{ NULL },')
|
writer.println('{ NULL },')
|
||||||
writer.println('};')
|
writer.println('};')
|
||||||
|
|
@ -154,6 +160,7 @@ static
|
||||||
|
|
||||||
println(extension_entry % {'module': '_api', 'methtable': 'methtable'})
|
println(extension_entry % {'module': '_api', 'methtable': 'methtable'})
|
||||||
|
|
||||||
|
# Generate Python source
|
||||||
with open('%s.py' % outputfilename, 'w') as pyfile:
|
with open('%s.py' % outputfilename, 'w') as pyfile:
|
||||||
println = wrap_println_from_file(pyfile)
|
println = wrap_println_from_file(pyfile)
|
||||||
println('import _api, capsule')
|
println('import _api, capsule')
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,16 @@ PyObject* pycapsule_new(void* ptr,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
PyObject* pycapsule_new(const void* ptr,
|
||||||
|
const char* basename,
|
||||||
|
const char* classname=NULL)
|
||||||
|
{
|
||||||
|
// Use const_cast to strip the constantness.
|
||||||
|
// Let the user take the responsibility.
|
||||||
|
return pycapsule_new(const_cast<void*>(ptr), basename, classname);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif //LLVMPY_CAPSULE_CONTEXT_H_
|
#endif //LLVMPY_CAPSULE_CONTEXT_H_
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
#include <llvm/Value.h>
|
#include <llvm/Value.h>
|
||||||
#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>
|
||||||
|
|
||||||
namespace extra{
|
namespace extra{
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
@ -97,11 +97,34 @@ PyObject* make_small_vector_from_values(PyObject* self, PyObject* args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
PyObject* make_small_vector_from_unsigned(PyObject* self, PyObject* args)
|
||||||
|
{
|
||||||
|
using llvm::Value;
|
||||||
|
typedef llvm::SmallVector<unsigned, 8> SmallVector_Unsigned;
|
||||||
|
|
||||||
|
SmallVector_Unsigned* SV = new SmallVector_Unsigned;
|
||||||
|
Py_ssize_t size = PyTuple_Size(args);
|
||||||
|
for (Py_ssize_t i = 0; i < size; ++i) {
|
||||||
|
PyObject* item = PyTuple_GetItem(args, i);
|
||||||
|
if (!item) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
unsigned value = PyLong_AsUnsignedLong(item);
|
||||||
|
if (PyErr_Occurred()){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
SV->push_back(value);
|
||||||
|
}
|
||||||
|
return pycapsule_new(SV, "llvm::SmallVector<unsigned,8>");
|
||||||
|
}
|
||||||
|
|
||||||
static PyMethodDef extra_methodtable[] = {
|
static PyMethodDef extra_methodtable[] = {
|
||||||
#define method(func) { #func, (PyCFunction)func, METH_VARARGS, NULL }
|
#define method(func) { #func, (PyCFunction)func, METH_VARARGS, NULL }
|
||||||
method( make_raw_ostream_for_printing ),
|
method( make_raw_ostream_for_printing ),
|
||||||
method( make_small_vector_from_types ),
|
method( make_small_vector_from_types ),
|
||||||
method( make_small_vector_from_values ),
|
method( make_small_vector_from_values ),
|
||||||
|
method( make_small_vector_from_unsigned ),
|
||||||
#undef method
|
#undef method
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
@ -139,11 +162,20 @@ PyObject* iplist_to_pylist(iplist &IPL, const char * capsuleName,
|
||||||
className);
|
className);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
bool string_equal(const char *A, const char *B){
|
||||||
|
for (; *A and *B; ++A, ++B) {
|
||||||
|
if (*A != *B) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////
|
||||||
static
|
static
|
||||||
PyObject* Value_use_iterator_to_list(llvm::Value* val)
|
PyObject* Value_use_iterator_to_list(llvm::Value* val)
|
||||||
{
|
{
|
||||||
return iterator_to_pylist(val->use_begin(), val->use_end(),
|
return iterator_to_pylist(val->use_begin(), val->use_end(),
|
||||||
"llvm::Value", "llvm::User");
|
"llvm::Value", "llvm::User");
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
|
|
@ -159,3 +191,46 @@ PyObject* Function_getBasicBlockList(llvm::Function* fn)
|
||||||
return iplist_to_pylist(fn->getBasicBlockList(), "llvm::Value",
|
return iplist_to_pylist(fn->getBasicBlockList(), "llvm::Value",
|
||||||
"llvm::BasicBlock");
|
"llvm::BasicBlock");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* errout --- can be any file object
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
llvm::ExecutionEngine* ExecutionEngine_create(
|
||||||
|
llvm::Module* M,
|
||||||
|
bool ForceInterpreter = false,
|
||||||
|
PyObject* errout = 0,
|
||||||
|
llvm::CodeGenOpt::Level OptLevel = llvm::CodeGenOpt::Default,
|
||||||
|
bool GVsWithCode = true)
|
||||||
|
{
|
||||||
|
using namespace llvm;
|
||||||
|
std::string ErrorStr;
|
||||||
|
ExecutionEngine *ee = ExecutionEngine::create(M, ForceInterpreter,
|
||||||
|
&ErrorStr, OptLevel,
|
||||||
|
GVsWithCode);
|
||||||
|
PyFile_WriteString(ErrorStr.c_str(), errout);
|
||||||
|
return ee;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* errout --- can be any file object
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
llvm::ExecutionEngine* ExecutionEngine_createJIT(
|
||||||
|
llvm::Module* M,
|
||||||
|
PyObject* errout = 0,
|
||||||
|
llvm::JITMemoryManager* JMM = 0,
|
||||||
|
llvm::CodeGenOpt::Level OL = llvm::CodeGenOpt::Default,
|
||||||
|
bool GCsWithCode = true,
|
||||||
|
llvm::Reloc::Model RM = llvm::Reloc::Default,
|
||||||
|
llvm::CodeModel::Model CMM = llvm::CodeModel::JITDefault)
|
||||||
|
{
|
||||||
|
using namespace llvm;
|
||||||
|
std::string ErrorStr;
|
||||||
|
ExecutionEngine *ee = ExecutionEngine::createJIT(M, &ErrorStr, JMM, OL,
|
||||||
|
GCsWithCode, RM, CMM);
|
||||||
|
PyFile_WriteString(ErrorStr.c_str(), errout);
|
||||||
|
return ee;
|
||||||
|
}
|
||||||
|
|
|
||||||
19
newbinding/src/CodeGen.py
Normal file
19
newbinding/src/CodeGen.py
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
from binding import *
|
||||||
|
from namespace import llvm
|
||||||
|
|
||||||
|
@llvm.Class()
|
||||||
|
class Reloc:
|
||||||
|
Model = Enum('Default', 'Static', 'PIC_', 'DynamicNoPIC')
|
||||||
|
|
||||||
|
@llvm.Class()
|
||||||
|
class CodeModel:
|
||||||
|
Model = Enum('Default', 'JITDefault', 'Small', 'Kernel', 'Medium', 'Large')
|
||||||
|
|
||||||
|
@llvm.Class()
|
||||||
|
class TLSModel:
|
||||||
|
Model = Enum('GeneralDynamic', 'LocalDynamic', 'InitialExec', 'LocalExec')
|
||||||
|
|
||||||
|
@llvm.Class()
|
||||||
|
class CodeGenOpt:
|
||||||
|
'Actually a namespace'
|
||||||
|
Level = Enum('None', 'Less', 'Default', 'Aggressive')
|
||||||
97
newbinding/src/DataLayout.py
Normal file
97
newbinding/src/DataLayout.py
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
from binding import *
|
||||||
|
from namespace import llvm
|
||||||
|
from LLVMContext import LLVMContext
|
||||||
|
from StringRef import StringRef
|
||||||
|
from Module import Module
|
||||||
|
from Type import Type, IntegerType, StructType
|
||||||
|
from SmallVector import SmallVector_Value
|
||||||
|
from GlobalVariable import GlobalVariable
|
||||||
|
|
||||||
|
DataLayout = llvm.Class()
|
||||||
|
StructLayout = llvm.Class()
|
||||||
|
|
||||||
|
@DataLayout
|
||||||
|
class DataLayout:
|
||||||
|
_include_ = 'llvm/DataLayout.h'
|
||||||
|
|
||||||
|
_new_string = Constructor(cast(str, StringRef))
|
||||||
|
_new_module = Constructor(ptr(Module))
|
||||||
|
|
||||||
|
@CustomPythonStaticMethod
|
||||||
|
def new(arg):
|
||||||
|
if isinstance(arg, Module):
|
||||||
|
return DataLayout._new_module(arg)
|
||||||
|
else:
|
||||||
|
return DataLayout._new_string(arg)
|
||||||
|
|
||||||
|
delete = Destructor()
|
||||||
|
|
||||||
|
isLittleEndian = Method(cast(Bool, bool))
|
||||||
|
isBigEndian = Method(cast(Bool, bool))
|
||||||
|
|
||||||
|
getStringRepresentation = Method(cast(StringRef, str))
|
||||||
|
|
||||||
|
@CustomPythonMethod
|
||||||
|
def __str__(self):
|
||||||
|
return self.getStringRepresentation()
|
||||||
|
|
||||||
|
isLegalInteger = Method(cast(Bool, bool), cast(int, Unsigned))
|
||||||
|
isIllegalInteger = Method(cast(Bool, bool), cast(int, Unsigned))
|
||||||
|
exceedsNaturalStackAlignment = Method(cast(Bool, bool), cast(int, Unsigned))
|
||||||
|
fitsInLegalInteger = Method(cast(Bool, bool), cast(int, Unsigned))
|
||||||
|
|
||||||
|
getPointerABIAlignment = Method(cast(Unsigned, int),
|
||||||
|
cast(int, Unsigned)).require_only(0)
|
||||||
|
getPointerPrefAlignment = Method(cast(Unsigned, int),
|
||||||
|
cast(int, Unsigned)).require_only(0)
|
||||||
|
getPointerSize = Method(cast(Unsigned, int),
|
||||||
|
cast(int, Unsigned)).require_only(0)
|
||||||
|
getPointerSizeInBits = Method(cast(Unsigned, int),
|
||||||
|
cast(int, Unsigned)).require_only(0)
|
||||||
|
|
||||||
|
getTypeSizeInBits = Method(cast(Uint64, int), ptr(Type))
|
||||||
|
getTypeStoreSize = Method(cast(Uint64, int), ptr(Type))
|
||||||
|
getTypeStoreSizeInBits = Method(cast(Uint64, int), ptr(Type))
|
||||||
|
getTypeAllocSize = Method(cast(Uint64, int), ptr(Type))
|
||||||
|
getTypeAllocSizeInBits = Method(cast(Uint64, int), ptr(Type))
|
||||||
|
|
||||||
|
getABITypeAlignment = Method(cast(Unsigned, int), ptr(Type))
|
||||||
|
getABIIntegerTypeAlignment = Method(cast(Unsigned, int), cast(int, Unsigned))
|
||||||
|
getCallFrameTypeAlignment = Method(cast(Unsigned, int), ptr(Type))
|
||||||
|
getPrefTypeAlignment = Method(cast(Unsigned, int), ptr(Type))
|
||||||
|
getPreferredTypeAlignmentShift = Method(cast(Unsigned, int), ptr(Type))
|
||||||
|
|
||||||
|
_getIntPtrType = Method(ptr(IntegerType),
|
||||||
|
ref(LLVMContext), cast(int, Unsigned))
|
||||||
|
_getIntPtrType.require_only(1)
|
||||||
|
_getIntPtrType.realname = 'getIntPtrType'
|
||||||
|
|
||||||
|
_getIntPtrType2 = Method(ptr(Type), ptr(Type))
|
||||||
|
_getIntPtrType2.realname = 'getIntPtrType'
|
||||||
|
|
||||||
|
@CustomPythonMethod
|
||||||
|
def getIntPtrType(self, *args):
|
||||||
|
if isinstance(args[0], LLVMContext):
|
||||||
|
return self._getIntPtrType(*args)
|
||||||
|
else:
|
||||||
|
return self._getIntPtrType(*args)
|
||||||
|
|
||||||
|
_getIndexedOffset = Method(cast(Uint64, int), ptr(Type),
|
||||||
|
ref(SmallVector_Value))
|
||||||
|
_getIndexedOffset.realname = 'getIndexedOffset'
|
||||||
|
|
||||||
|
@CustomPythonMethod
|
||||||
|
def getIndexedOffset(self, *args):
|
||||||
|
import extra
|
||||||
|
args = list(args)
|
||||||
|
args[1] = extra.make_small_vector_from_values(args[1])
|
||||||
|
return self.getIndexedOffset(*args)
|
||||||
|
|
||||||
|
getStructLayout = Method(const(ptr(StructLayout)), ptr(StructType))
|
||||||
|
|
||||||
|
getPreferredAlignment = Method(cast(Unsigned, int), ptr(GlobalVariable))
|
||||||
|
getPreferredAlignmentLog = Method(cast(Unsigned, int), ptr(GlobalVariable))
|
||||||
|
|
||||||
|
@StructLayout
|
||||||
|
class StructLayout:
|
||||||
|
pass
|
||||||
34
newbinding/src/ExecutionEngine.py
Normal file
34
newbinding/src/ExecutionEngine.py
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
from binding import *
|
||||||
|
from namespace import llvm
|
||||||
|
from Module import Module
|
||||||
|
from JITMemoryManager import JITMemoryManager
|
||||||
|
from CodeGen import CodeGenOpt, Reloc, CodeModel
|
||||||
|
from DataLayout import DataLayout
|
||||||
|
|
||||||
|
ExecutionEngine = llvm.Class()
|
||||||
|
|
||||||
|
@ExecutionEngine
|
||||||
|
class ExecutionEngine:
|
||||||
|
_include_ = ('llvm/ExecutionEngine/ExecutionEngine.h',
|
||||||
|
'llvm/ExecutionEngine/JIT.h') # force linking of jit
|
||||||
|
|
||||||
|
delete = Destructor()
|
||||||
|
|
||||||
|
create = CustomStaticMethod('ExecutionEngine_create',
|
||||||
|
ptr(ExecutionEngine),
|
||||||
|
ownedptr(Module), cast(bool, Bool),
|
||||||
|
PyObjectPtr, CodeGenOpt.Level,
|
||||||
|
cast(bool, Bool)).require_only(1)
|
||||||
|
|
||||||
|
createJIT = CustomStaticMethod('ExecutionEngine_createJIT',
|
||||||
|
ptr(ExecutionEngine),
|
||||||
|
ownedptr(Module), PyObjectPtr,
|
||||||
|
ptr(JITMemoryManager),
|
||||||
|
CodeGenOpt.Level,
|
||||||
|
cast(bool, Bool),
|
||||||
|
Reloc.Model,
|
||||||
|
CodeModel.Model).require_only(1)
|
||||||
|
|
||||||
|
addModule = Method(Void, ptr(Module))
|
||||||
|
getDataLayout = Method(const(ownedptr(DataLayout)))
|
||||||
|
removeModule = Method(cast(Bool, bool), ptr(Module))
|
||||||
8
newbinding/src/GlobalVariable.py
Normal file
8
newbinding/src/GlobalVariable.py
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
from binding import *
|
||||||
|
from namespace import llvm
|
||||||
|
from GlobalValue import GlobalValue
|
||||||
|
|
||||||
|
@llvm.Class(GlobalValue)
|
||||||
|
class GlobalVariable:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
@ -2,10 +2,16 @@ from binding import *
|
||||||
from namespace import llvm
|
from namespace import llvm
|
||||||
from LLVMContext import LLVMContext
|
from LLVMContext import LLVMContext
|
||||||
from BasicBlock import BasicBlock
|
from BasicBlock import BasicBlock
|
||||||
from Instruction import ReturnInst, CallInst
|
from Instruction import ReturnInst, CallInst, BranchInst, SwitchInst
|
||||||
from SmallVector import SmallVector_Value
|
from Instruction import IndirectBrInst, InvokeInst, ResumeInst, PHINode
|
||||||
|
from Instruction import UnreachableInst, AllocaInst, LoadInst, StoreInst
|
||||||
|
from Instruction import FenceInst, AtomicCmpXchgInst, AtomicRMWInst, CmpInst
|
||||||
|
from Instruction import LandingPadInst, VAArgInst
|
||||||
|
from Instruction import AtomicOrdering, SynchronizationScope
|
||||||
|
from SmallVector import SmallVector_Value, SmallVector_Unsigned
|
||||||
from StringRef import StringRef
|
from StringRef import StringRef
|
||||||
from Value import Value
|
from Value import Value, MDNode
|
||||||
|
from Type import Type, IntegerType
|
||||||
|
|
||||||
IRBuilder = llvm.Class()
|
IRBuilder = llvm.Class()
|
||||||
|
|
||||||
|
|
@ -24,15 +30,238 @@ class IRBuilder:
|
||||||
CreateRetVoid = Method(ptr(ReturnInst))
|
CreateRetVoid = Method(ptr(ReturnInst))
|
||||||
CreateRet = Method(ptr(ReturnInst), ptr(Value))
|
CreateRet = Method(ptr(ReturnInst), ptr(Value))
|
||||||
|
|
||||||
_CreateCall = Method(ptr(CallInst), ptr(Value), ref(SmallVector_Value),
|
CreateBr = Method(ptr(BranchInst), ptr(BasicBlock))
|
||||||
|
|
||||||
|
|
||||||
|
CreateCondBr = Method(ptr(BranchInst), ptr(Value), ptr(BasicBlock),
|
||||||
|
ptr(BasicBlock), ptr(MDNode)).require_only(3)
|
||||||
|
|
||||||
|
CreateSwitch = Method(ptr(SwitchInst), ptr(Value), ptr(BasicBlock),
|
||||||
|
cast(int, Unsigned), ptr(MDNode)).require_only(2)
|
||||||
|
|
||||||
|
CreateIndirectBr = Method(ptr(IndirectBrInst), ptr(Value),
|
||||||
|
cast(int, Unsigned)).require_only(1)
|
||||||
|
|
||||||
|
CreateInvoke = Method(ptr(InvokeInst), ptr(Value), ptr(BasicBlock),
|
||||||
|
ptr(BasicBlock), ref(SmallVector_Value),
|
||||||
|
cast(str, StringRef)).require_only(4)
|
||||||
|
|
||||||
|
CreateResume = Method(ptr(ResumeInst), ptr(Value))
|
||||||
|
|
||||||
|
CreateUnreachable = Method(ptr(UnreachableInst))
|
||||||
|
|
||||||
|
def _binop_has_nsw_nuw():
|
||||||
|
sig = [ptr(Value), ptr(Value), ptr(Value), cast(str, StringRef),
|
||||||
|
cast(bool, Bool), cast(bool, Bool)]
|
||||||
|
op = Method(*sig).require_only(2)
|
||||||
|
return op
|
||||||
|
|
||||||
|
CreateAdd = _binop_has_nsw_nuw()
|
||||||
|
CreateSub = _binop_has_nsw_nuw()
|
||||||
|
CreateMul = _binop_has_nsw_nuw()
|
||||||
|
CreateShl = _binop_has_nsw_nuw()
|
||||||
|
|
||||||
|
def _binop_is_exact():
|
||||||
|
sig = [ptr(Value), ptr(Value), ptr(Value), cast(str, StringRef),
|
||||||
|
cast(bool, Bool)]
|
||||||
|
op = Method(*sig).require_only(2)
|
||||||
|
return op
|
||||||
|
|
||||||
|
CreateUDiv = _binop_is_exact()
|
||||||
|
CreateSDiv = _binop_is_exact()
|
||||||
|
CreateLShr = _binop_is_exact()
|
||||||
|
CreateAShr = _binop_is_exact()
|
||||||
|
|
||||||
|
def _binop_basic():
|
||||||
|
sig = [ptr(Value), ptr(Value), ptr(Value), cast(str, StringRef)]
|
||||||
|
op = Method(*sig).require_only(2)
|
||||||
|
return op
|
||||||
|
|
||||||
|
CreateURem = _binop_basic()
|
||||||
|
CreateSRem = _binop_basic()
|
||||||
|
CreateAnd = _binop_basic()
|
||||||
|
CreateOr = _binop_basic()
|
||||||
|
CreateXor = _binop_basic()
|
||||||
|
|
||||||
|
def _float_binop():
|
||||||
|
sig = [ptr(Value), ptr(Value), ptr(Value), cast(str, StringRef),
|
||||||
|
ptr(MDNode)]
|
||||||
|
op = Method(*sig).require_only(2)
|
||||||
|
return op
|
||||||
|
|
||||||
|
CreateFAdd = _float_binop()
|
||||||
|
CreateFSub = _float_binop()
|
||||||
|
CreateFMul = _float_binop()
|
||||||
|
CreateFDiv = _float_binop()
|
||||||
|
CreateFRem = _float_binop()
|
||||||
|
|
||||||
|
def _unop_has_nsw_nuw():
|
||||||
|
sig = [ptr(Value), ptr(Value), cast(str, StringRef),
|
||||||
|
cast(bool, Bool), cast(bool, Bool)]
|
||||||
|
op = Method(*sig).require_only(1)
|
||||||
|
return op
|
||||||
|
|
||||||
|
CreateNeg = _unop_has_nsw_nuw()
|
||||||
|
|
||||||
|
def _float_unop():
|
||||||
|
sig = [ptr(Value), ptr(Value), cast(str, StringRef), ptr(MDNode)]
|
||||||
|
op = Method(*sig).require_only(1)
|
||||||
|
return op
|
||||||
|
|
||||||
|
CreateFNeg = _float_unop()
|
||||||
|
|
||||||
|
CreateNot = Method(ptr(Value),
|
||||||
|
ptr(Value), cast(str, StringRef)).require_only(1)
|
||||||
|
|
||||||
|
|
||||||
|
CreateAlloca = Method(ptr(AllocaInst), ptr(Type), ptr(Value),
|
||||||
|
cast(str, StringRef)).require_only(2)
|
||||||
|
|
||||||
|
CreateLoad = Method(ptr(LoadInst),
|
||||||
|
ptr(Value), cast(str, StringRef)).require_only(1)
|
||||||
|
|
||||||
|
CreateStore = Method(ptr(StoreInst), ptr(Value), ptr(Value),
|
||||||
|
cast(bool, Bool)).require_only(2)
|
||||||
|
|
||||||
|
CreateAlignedLoad = Method(ptr(LoadInst), ptr(Value), cast(int, Unsigned),
|
||||||
|
cast(bool, Bool), cast(str, StringRef))
|
||||||
|
CreateAlignedLoad.require_only(2)
|
||||||
|
|
||||||
|
CreateAlignedStore = Method(ptr(StoreInst), ptr(Value), ptr(Value),
|
||||||
|
cast(int, Unsigned), cast(bool, Bool))
|
||||||
|
CreateAlignedStore.require_only(3)
|
||||||
|
|
||||||
|
CreateFence = Method(ptr(FenceInst),
|
||||||
|
AtomicOrdering, SynchronizationScope).require_only(1)
|
||||||
|
|
||||||
|
CreateAtomicCmpXchg = Method(ptr(AtomicCmpXchgInst), ptr(Value), ptr(Value),
|
||||||
|
ptr(Value), AtomicOrdering, SynchronizationScope)
|
||||||
|
CreateAtomicCmpXchg.require_only(4)
|
||||||
|
|
||||||
|
CreateAtomicRMW = Method(ptr(AtomicRMWInst), AtomicRMWInst.BinOp,
|
||||||
|
ptr(Value), ptr(Value), AtomicOrdering,
|
||||||
|
SynchronizationScope)
|
||||||
|
CreateAtomicRMW.require_only(4)
|
||||||
|
|
||||||
|
_CreateGEP = Method(ptr(Value), ptr(Value), ref(SmallVector_Value),
|
||||||
|
cast(str, StringRef))
|
||||||
|
_CreateGEP.require_only(2)
|
||||||
|
_CreateGEP.realname = 'CreateGEP'
|
||||||
|
|
||||||
|
@CustomPythonMethod
|
||||||
|
def CreateGEP(self, *args):
|
||||||
|
import extra
|
||||||
|
args = list(args)
|
||||||
|
valuelist = args[1]
|
||||||
|
args[1] = extra.make_small_vector_from_values(*valuelist)
|
||||||
|
return self._CreateGEP(*args)
|
||||||
|
|
||||||
|
_CreateInBoundsGEP = Method(ptr(Value), ptr(Value), ref(SmallVector_Value),
|
||||||
cast(str, StringRef))
|
cast(str, StringRef))
|
||||||
_CreateCall |= Method(ptr(CallInst), ptr(Value), ref(SmallVector_Value))
|
_CreateInBoundsGEP.require_only(2)
|
||||||
|
_CreateInBoundsGEP.realname = 'CreateInBoundsGEP'
|
||||||
|
|
||||||
|
@CustomPythonMethod
|
||||||
|
def CreateInBoundsGEP(self, *args):
|
||||||
|
import extra
|
||||||
|
args = list(args)
|
||||||
|
valuelist = args[1]
|
||||||
|
args[1] = extra.make_small_vector_from_values(*valuelist)
|
||||||
|
return self._CreateInBoundsGEP(*args)
|
||||||
|
|
||||||
|
CreateStructGEP = Method(ptr(Value), ptr(Value), cast(int, Unsigned),
|
||||||
|
cast(str, StringRef)).require_only(2)
|
||||||
|
|
||||||
|
CreateGlobalStringPtr = Method(ptr(Value), cast(str, StringRef),
|
||||||
|
cast(str, StringRef)).require_only(1)
|
||||||
|
|
||||||
|
def _value_type():
|
||||||
|
sig = [ptr(Value), ptr(Value), ptr(Type), cast(str, StringRef)]
|
||||||
|
op = Method(*sig).require_only(2)
|
||||||
|
return op
|
||||||
|
|
||||||
|
CreateTrunc = _value_type()
|
||||||
|
CreateZExt = _value_type()
|
||||||
|
CreateSExt = _value_type()
|
||||||
|
CreateZExtOrTrunc = Method(ptr(Value), ptr(Value), ptr(IntegerType),
|
||||||
|
cast(str, StringRef)).require_only(2)
|
||||||
|
CreateSExtOrTrunc = Method(ptr(Value), ptr(Value), ptr(IntegerType),
|
||||||
|
cast(str, StringRef)).require_only(2)
|
||||||
|
CreateFPToUI = _value_type()
|
||||||
|
CreateFPToSI = _value_type()
|
||||||
|
CreateUIToFP = _value_type()
|
||||||
|
CreateSIToFP = _value_type()
|
||||||
|
CreateFPTrunc = _value_type()
|
||||||
|
CreateFPExt = _value_type()
|
||||||
|
CreatePtrToInt = _value_type()
|
||||||
|
CreateIntToPtr = _value_type()
|
||||||
|
CreateBitCast = _value_type()
|
||||||
|
CreateZExtOrBitCast = _value_type()
|
||||||
|
CreateSExtOrBitCast = _value_type()
|
||||||
|
# Skip CreateCast
|
||||||
|
CreateTruncOrBitCast = _value_type()
|
||||||
|
CreateIntCast = Method(ptr(Value), ptr(Value), ptr(Type), cast(bool, Bool),
|
||||||
|
cast(str, StringRef)).require_only(3)
|
||||||
|
CreateFPCast = _value_type()
|
||||||
|
|
||||||
|
_CreateCall = Method(ptr(CallInst), ptr(Value), ref(SmallVector_Value),
|
||||||
|
cast(str, StringRef)).require_only(2)
|
||||||
_CreateCall.realname = 'CreateCall'
|
_CreateCall.realname = 'CreateCall'
|
||||||
|
|
||||||
|
# Skip specialized CreateICmp* and CreateFCmp*
|
||||||
|
|
||||||
|
CreateICmp = Method(ptr(Value), CmpInst.Predicate, ptr(Value), ptr(Value),
|
||||||
|
cast(str, StringRef)).require_only(3)
|
||||||
|
|
||||||
|
CreateFCmp = Method(ptr(Value), CmpInst.Predicate, ptr(Value), ptr(Value),
|
||||||
|
cast(str, StringRef)).require_only(3)
|
||||||
|
|
||||||
|
CreatePHI = Method(ptr(PHINode), ptr(Type), cast(int, Unsigned),
|
||||||
|
cast(str, StringRef)).require_only(2)
|
||||||
|
|
||||||
@CustomPythonMethod
|
@CustomPythonMethod
|
||||||
def CreateCall(self, *args):
|
def CreateCall(self, *args):
|
||||||
import extra
|
import extra
|
||||||
args = list(args)
|
args = list(args)
|
||||||
valuelist = args[1]
|
valuelist = args[1]
|
||||||
args[1] = extra.make_small_vector_from_values(*valuelist)
|
args[1] = extra.make_small_vector_from_values(*valuelist)
|
||||||
return IRBuilder._CreateCall(self, *args)
|
return self._CreateCall(*args)
|
||||||
|
|
||||||
|
CreateSelect = Method(ptr(Value), ptr(Value), ptr(Value), ptr(Value),
|
||||||
|
cast(str, StringRef)).require_only(3)
|
||||||
|
|
||||||
|
CreateVAArg = Method(ptr(VAArgInst), ptr(Value), ptr(Type),
|
||||||
|
cast(str, StringRef)).require_only(2)
|
||||||
|
|
||||||
|
CreateExtractElement = _binop_basic()
|
||||||
|
|
||||||
|
CreateInsertElement = Method(ptr(Value), ptr(Value), ptr(Value), ptr(Value),
|
||||||
|
cast(str, StringRef)).require_only(3)
|
||||||
|
|
||||||
|
CreateShuffleVector = Method(ptr(Value), ptr(Value), ptr(Value),
|
||||||
|
ptr(Value), cast(str, StringRef))
|
||||||
|
CreateShuffleVector.require_only(3)
|
||||||
|
|
||||||
|
CreateExtractValue = Method(ptr(Value), ptr(Value), ref(SmallVector_Unsigned),
|
||||||
|
cast(str, StringRef))
|
||||||
|
CreateExtractValue.require_only(2)
|
||||||
|
|
||||||
|
CreateInsertValue = Method(ptr(Value), ptr(Value), ptr(Value),
|
||||||
|
ref(SmallVector_Unsigned), cast(str, StringRef))
|
||||||
|
CreateInsertValue.require_only(3)
|
||||||
|
|
||||||
|
CreateLandingPad = Method(ptr(LandingPadInst), ptr(Type), ptr(Value),
|
||||||
|
cast(int, Unsigned), cast(str, StringRef))
|
||||||
|
CreateLandingPad.require_only(3)
|
||||||
|
|
||||||
|
CreateIsNull = Method(ptr(Value), ptr(Value), cast(str, StringRef))
|
||||||
|
CreateIsNull.require_only(1)
|
||||||
|
|
||||||
|
CreateIsNotNull = Method(ptr(Value), ptr(Value), cast(str, StringRef))
|
||||||
|
CreateIsNotNull.require_only(1)
|
||||||
|
|
||||||
|
CreatePtrDiff = _binop_basic()
|
||||||
|
|
||||||
|
# New in llvm 3.3
|
||||||
|
#CreateVectorSplat = Method(ptr(Value), cast(int, Unsigned), ptr(Value),
|
||||||
|
# cast(str, StringRef))
|
||||||
|
|
|
||||||
|
|
@ -26,9 +26,9 @@ IntrinsicInst = llvm.Class(CallInst)
|
||||||
FCmpInst = llvm.Class(CmpInst)
|
FCmpInst = llvm.Class(CmpInst)
|
||||||
ICmpInst = llvm.Class(CmpInst)
|
ICmpInst = llvm.Class(CmpInst)
|
||||||
|
|
||||||
|
|
||||||
BranchInst = llvm.Class(TerminatorInst)
|
BranchInst = llvm.Class(TerminatorInst)
|
||||||
IndirectBrInst = llvm.Class(TerminatorInst)
|
IndirectBrInst = llvm.Class(TerminatorInst)
|
||||||
|
InvokeInst = llvm.Class(TerminatorInst)
|
||||||
ResumeInst = llvm.Class(TerminatorInst)
|
ResumeInst = llvm.Class(TerminatorInst)
|
||||||
ReturnInst = llvm.Class(TerminatorInst)
|
ReturnInst = llvm.Class(TerminatorInst)
|
||||||
SwitchInst = llvm.Class(TerminatorInst)
|
SwitchInst = llvm.Class(TerminatorInst)
|
||||||
|
|
@ -56,14 +56,14 @@ FPTruncInst = llvm.Class(CastInst)
|
||||||
class Instruction:
|
class Instruction:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@AtomicCmpXchgInst
|
@AtomicCmpXchgInst
|
||||||
class AtomicCmpXchgInst:
|
class AtomicCmpXchgInst:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@AtomicRMWInst
|
@AtomicRMWInst
|
||||||
class AtomicRMWInst:
|
class AtomicRMWInst:
|
||||||
pass
|
BinOp = Enum('Xchg', 'Add', 'Sub', 'And', 'Nand', 'Or', 'Xor', 'Max', 'Min',
|
||||||
|
'UMax', 'UMin', 'FIRST_BINOP', 'LAST_BINOP', 'BAD_BINOP')
|
||||||
|
|
||||||
@BinaryOperator
|
@BinaryOperator
|
||||||
class BinaryOperator:
|
class BinaryOperator:
|
||||||
|
|
@ -75,7 +75,17 @@ class CallInst:
|
||||||
|
|
||||||
@CmpInst
|
@CmpInst
|
||||||
class CmpInst:
|
class CmpInst:
|
||||||
pass
|
Predicate = Enum('FCMP_FALSE', 'FCMP_OEQ', 'FCMP_OGT', 'FCMP_OGE',
|
||||||
|
'FCMP_OLT', 'FCMP_OLE', 'FCMP_ONE', 'FCMP_ORD', 'FCMP_UNO',
|
||||||
|
'FCMP_UEQ', 'FCMP_UGT', 'FCMP_UGE', 'FCMP_ULT', 'FCMP_ULE',
|
||||||
|
'FCMP_UNE', 'FCMP_TRUE', 'FIRST_FCMP_PREDICATE',
|
||||||
|
'LAST_FCMP_PREDICATE',
|
||||||
|
'BAD_FCMP_PREDICATE',
|
||||||
|
'ICMP_EQ', 'ICMP_NE', 'ICMP_UGT', 'ICMP_UGE', 'ICMP_ULT',
|
||||||
|
'ICMP_ULE', 'ICMP_SGT', 'ICMP_SGE', 'ICMP_SLT', 'ICMP_SLE',
|
||||||
|
'FIRST_ICMP_PREDICATE',
|
||||||
|
'LAST_ICMP_PREDICATE',
|
||||||
|
'BAD_ICMP_PREDICATE',)
|
||||||
|
|
||||||
@ExtractElementInst
|
@ExtractElementInst
|
||||||
class ExtractElementInst:
|
class ExtractElementInst:
|
||||||
|
|
@ -146,11 +156,14 @@ class ICmpInst:
|
||||||
class BranchInst:
|
class BranchInst:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@IndirectBrInst
|
@IndirectBrInst
|
||||||
class IndirectBrInst:
|
class IndirectBrInst:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@InvokeInst
|
||||||
|
class InvokeInst:
|
||||||
|
pass
|
||||||
|
|
||||||
@ResumeInst
|
@ResumeInst
|
||||||
class ResumeInst:
|
class ResumeInst:
|
||||||
pass
|
pass
|
||||||
|
|
@ -228,3 +241,12 @@ class FPToUIInst:
|
||||||
@FPTruncInst
|
@FPTruncInst
|
||||||
class FPTruncInst:
|
class FPTruncInst:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
AtomicOrdering = llvm.Enum('AtomicOrdering',
|
||||||
|
'NotAtomic', 'Unordered', 'Monotonic', 'Acquire',
|
||||||
|
'Release', 'AcquireRelease',
|
||||||
|
'SequentiallyConsistent')
|
||||||
|
|
||||||
|
SynchronizationScope = llvm.Enum('SynchronizationScope',
|
||||||
|
'SingleThread', 'CrossThread')
|
||||||
|
|
||||||
|
|
|
||||||
7
newbinding/src/JITMemoryManager.py
Normal file
7
newbinding/src/JITMemoryManager.py
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
from binding import *
|
||||||
|
from namespace import llvm
|
||||||
|
|
||||||
|
@llvm.Class()
|
||||||
|
class JITMemoryManager:
|
||||||
|
pass
|
||||||
|
|
||||||
7
newbinding/src/Metadata.py
Normal file
7
newbinding/src/Metadata.py
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
from binding import *
|
||||||
|
from namespace import llvm
|
||||||
|
from Value import MDNode
|
||||||
|
|
||||||
|
@MDNode
|
||||||
|
class MDNode:
|
||||||
|
pass
|
||||||
|
|
@ -36,7 +36,8 @@ class Module:
|
||||||
appendModuleInlineAsm = Method(Void, cast(str, StringRef))
|
appendModuleInlineAsm = Method(Void, cast(str, StringRef))
|
||||||
|
|
||||||
# Function Accessors
|
# Function Accessors
|
||||||
getOrInsertFunction = Method(ptr(Constant), cast(str, StringRef), ptr(FunctionType))
|
getOrInsertFunction = Method(ptr(Constant), cast(str, StringRef),
|
||||||
|
ptr(FunctionType))
|
||||||
|
|
||||||
# Utilities
|
# Utilities
|
||||||
dump = Method(Void)
|
dump = Method(Void)
|
||||||
|
|
|
||||||
|
|
@ -11,3 +11,7 @@ class SmallVector_Value:
|
||||||
_realname_ = 'SmallVector<llvm::Value*,8>'
|
_realname_ = 'SmallVector<llvm::Value*,8>'
|
||||||
delete = Destructor()
|
delete = Destructor()
|
||||||
|
|
||||||
|
@llvm.Class()
|
||||||
|
class SmallVector_Unsigned:
|
||||||
|
_realname_ = 'SmallVector<unsigned,8>'
|
||||||
|
delete = Destructor()
|
||||||
|
|
|
||||||
8
newbinding/src/TargetSelect.py
Normal file
8
newbinding/src/TargetSelect.py
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
from binding import *
|
||||||
|
from namespace import llvm
|
||||||
|
|
||||||
|
llvm.includes.add('llvm/Support/TargetSelect.h')
|
||||||
|
|
||||||
|
llvm.Function('InitializeNativeTarget')
|
||||||
|
#llvm.Function('InitializeAllTargets')
|
||||||
|
|
||||||
|
|
@ -6,6 +6,7 @@ from raw_ostream import raw_ostream
|
||||||
Type = llvm.Class()
|
Type = llvm.Class()
|
||||||
IntegerType = llvm.Class(Type)
|
IntegerType = llvm.Class(Type)
|
||||||
CompositeType = llvm.Class(Type)
|
CompositeType = llvm.Class(Type)
|
||||||
|
StructType = llvm.Class(CompositeType)
|
||||||
SequentialType = llvm.Class(CompositeType)
|
SequentialType = llvm.Class(CompositeType)
|
||||||
PointerType = llvm.Class(SequentialType)
|
PointerType = llvm.Class(SequentialType)
|
||||||
|
|
||||||
|
|
@ -113,3 +114,6 @@ class SequentialType:
|
||||||
class PointerType:
|
class PointerType:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@StructType
|
||||||
|
class StructType:
|
||||||
|
pass
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ from StringRef import StringRef
|
||||||
Value = llvm.Class()
|
Value = llvm.Class()
|
||||||
# forward declarations
|
# forward declarations
|
||||||
Argument = llvm.Class(Value)
|
Argument = llvm.Class(Value)
|
||||||
|
MDNode = llvm.Class(Value)
|
||||||
User = llvm.Class(Value)
|
User = llvm.Class(Value)
|
||||||
BasicBlock = llvm.Class(Value)
|
BasicBlock = llvm.Class(Value)
|
||||||
Constant = llvm.Class(User)
|
Constant = llvm.Class(User)
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,11 @@
|
||||||
import api
|
import api
|
||||||
import extra
|
import extra
|
||||||
import _capsule
|
import _capsule
|
||||||
|
from StringIO import StringIO
|
||||||
api.capsule.set_debug(True)
|
api.capsule.set_debug(True)
|
||||||
|
|
||||||
|
|
||||||
|
api.InitializeNativeTarget()
|
||||||
context = api.getGlobalContext()
|
context = api.getGlobalContext()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -71,3 +75,13 @@ builder.CreateRet(ret)
|
||||||
|
|
||||||
print fn
|
print fn
|
||||||
|
|
||||||
|
errio = StringIO()
|
||||||
|
ee = api.ExecutionEngine.createJIT(m)
|
||||||
|
print ee, errio.getvalue()
|
||||||
|
print ee.getDataLayout().getStringRepresentation()
|
||||||
|
|
||||||
|
datalayout_str = 'e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-f32:32:32-f64:64:64-f128:128:128-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64'
|
||||||
|
|
||||||
|
assert datalayout_str == str(api.DataLayout.new(datalayout_str))
|
||||||
|
assert datalayout_str == str(api.DataLayout.new(str(api.DataLayout.new(datalayout_str))))
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue