Add CustonPythonMethod and CustonPythonStaticMethod.

This commit is contained in:
Siu Kwan Lam 2013-01-28 16:36:46 -06:00
commit 895d114730
5 changed files with 66 additions and 13 deletions

View file

@ -1,3 +1,4 @@
import inspect, textwrap
import functools import functools
import codegen as cg import codegen as cg
@ -56,6 +57,7 @@ class Class(_Type):
self.bases = bases self.bases = bases
self._is_defined = False self._is_defined = False
self.methods = [] self.methods = []
self.pymethods = []
self.enums = [] self.enums = []
self.includes = set() self.includes = set()
self.downcastables = set() self.downcastables = set()
@ -76,6 +78,8 @@ class Class(_Type):
self.enums.append(v) self.enums.append(v)
v.name = k v.name = k
v.parent = self v.parent = self
elif isinstance(v, CustomPythonMethod):
self.pymethods.append(v)
elif k == '_include_': elif k == '_include_':
if isinstance(v, str): if isinstance(v, str):
self.includes.add(v) self.includes.add(v)
@ -122,6 +126,8 @@ class Class(_Type):
enum.compile_py(writer) enum.compile_py(writer)
for meth in self.methods: for meth in self.methods:
meth.compile_py(writer) meth.compile_py(writer)
for meth in self.pymethods:
meth.compile_py(writer)
writer.println() writer.println()
@property @property
@ -453,3 +459,21 @@ class cast(_Type):
class CustomPythonMethod(object):
def __init__(self, fn):
src = inspect.getsource(fn)
lines = textwrap.dedent(src).splitlines()
for i, line in enumerate(lines):
if not line.startswith('@'):
break
self.sourcelines = lines[i:]
def compile_py(self, writer):
for line in self.sourcelines:
writer.println(line)
class CustomPythonStaticMethod(CustomPythonMethod):
def compile_py(self, writer):
writer.println('@staticmethod')
super(CustomPythonStaticMethod, self).compile_py(writer)

View file

@ -1,6 +1,7 @@
from binding import * from binding import *
from namespace import llvm from namespace import llvm
from Value import Function, BasicBlock from Value import Function, BasicBlock
from Instruction import Instruction, TerminatorInst
from LLVMContext import LLVMContext from LLVMContext import LLVMContext
from StringRef import StringRef from StringRef import StringRef
@ -12,6 +13,8 @@ class BasicBlock:
ptr(BasicBlock)) ptr(BasicBlock))
getParent = Method(ptr(Function)) getParent = Method(ptr(Function))
getTerminator = Method(ptr(TerminatorInst))
empty = Method(cast(Bool, bool)) empty = Method(cast(Bool, bool))
dropAllReferences = Method() dropAllReferences = Method()
isLandingPad = Method(cast(Bool, bool)) isLandingPad = Method(cast(Bool, bool))

View file

@ -9,8 +9,23 @@ FunctionType = llvm.Class(Type)
@FunctionType @FunctionType
class FunctionType: class FunctionType:
_include_ = 'llvm/DerivedTypes.h' _include_ = 'llvm/DerivedTypes.h'
get = StaticMethod(ptr(FunctionType), ptr(Type), cast(bool, Bool))
get |= StaticMethod(ptr(FunctionType), ptr(Type), ref(SmallVector_Type), cast(bool, Bool)) _get = StaticMethod(ptr(FunctionType), ptr(Type), cast(bool, Bool))
_get |= StaticMethod(ptr(FunctionType), ptr(Type), ref(SmallVector_Type),
cast(bool, Bool))
_get.realname = 'get'
@CustomPythonStaticMethod
def get(*args):
import extra
if len(args) == 3:
typelist = args[1]
sv = extra.make_small_vector_from_types(*typelist)
return FunctionType._get(args[0], sv, args[2])
else:
return FunctionType._get(*args)
isVarArg = Method(cast(Bool, bool)) isVarArg = Method(cast(Bool, bool))
getReturnType = Method(ptr(Type)) getReturnType = Method(ptr(Type))
getParamType = Method(ptr(Type), cast(int, Unsigned)) getParamType = Method(ptr(Type), cast(int, Unsigned))

View file

@ -37,3 +37,10 @@ class Value:
hasOneUse = Method(cast(Bool, bool)) hasOneUse = Method(cast(Bool, bool))
hasNUses = Method(cast(Bool, bool), cast(int, Unsigned)) hasNUses = Method(cast(Bool, bool), cast(int, Unsigned))
isUsedInBasicBlock = Method(cast(Bool, bool), BasicBlock) isUsedInBasicBlock = Method(cast(Bool, bool), BasicBlock)
@CustomPythonMethod
def __str__(self):
import extra
os = extra.make_raw_ostream_for_printing()
self.print_(os, None)
return os.str()

View file

@ -30,24 +30,18 @@ fnty = api.FunctionType.get(int1ty, False)
fnty.dump() fnty.dump()
types = [int1ty, api.Type.getIntNTy(context, 21)] types = [int1ty, api.Type.getIntNTy(context, 21)]
svt = extra.make_small_vector_from_types(*types) fnty = api.FunctionType.get(int1ty, types, False)
fnty = api.FunctionType.get(int1ty, svt, False)
os = extra.make_raw_ostream_for_printing() print fnty
fnty.print_(os)
print os.str()
const = m.getOrInsertFunction("foo", fnty) const = m.getOrInsertFunction("foo", fnty)
fn = extra.downcast(const, api.Function) fn = extra.downcast(const, api.Function)
os = extra.make_raw_ostream_for_printing() print fn
fn.print_(os, None)
print os.str()
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()
os = extra.make_raw_ostream_for_printing()
assert fn.getReturnType() is int1ty assert fn.getReturnType() is int1ty
assert fnty is fn.getFunctionType() assert fnty is fn.getFunctionType()
@ -56,14 +50,24 @@ assert fn.isVarArg() == False
assert fn.getIntrinsicID() == 0 assert fn.getIntrinsicID() == 0
assert not fn.isIntrinsic() assert not fn.isIntrinsic()
print fn.list_use() fn_uselist = fn.list_use()
assert isinstance(fn_uselist, list)
assert len(fn_uselist) == 0
builder = api.IRBuilder.new(context) builder = api.IRBuilder.new(context)
print builder print builder
bb = api.BasicBlock.Create(context, "entry", fn, None) bb = api.BasicBlock.Create(context, "entry", fn, None)
assert bb.empty()
builder.SetInsertPoint(bb) builder.SetInsertPoint(bb)
assert bb.getTerminator() is None
builder.CreateRetVoid() builder.CreateRetVoid()
fn.dump() assert not bb.empty()
assert bb.getTerminator() is not None
print bb