From 895d1147300d13608763aa61b8ab2b9f56bd7662 Mon Sep 17 00:00:00 2001 From: Siu Kwan Lam Date: Mon, 28 Jan 2013 16:36:46 -0600 Subject: [PATCH] Add CustonPythonMethod and CustonPythonStaticMethod. --- newbinding/binding.py | 24 ++++++++++++++++++++++++ newbinding/src/BasicBlock.py | 3 +++ newbinding/src/DerivedTypes.py | 19 +++++++++++++++++-- newbinding/src/Value.py | 7 +++++++ newbinding/test2.py | 26 +++++++++++++++----------- 5 files changed, 66 insertions(+), 13 deletions(-) diff --git a/newbinding/binding.py b/newbinding/binding.py index 3538c9a..6668452 100644 --- a/newbinding/binding.py +++ b/newbinding/binding.py @@ -1,3 +1,4 @@ +import inspect, textwrap import functools import codegen as cg @@ -56,6 +57,7 @@ class Class(_Type): self.bases = bases self._is_defined = False self.methods = [] + self.pymethods = [] self.enums = [] self.includes = set() self.downcastables = set() @@ -76,6 +78,8 @@ class Class(_Type): self.enums.append(v) v.name = k v.parent = self + elif isinstance(v, CustomPythonMethod): + self.pymethods.append(v) elif k == '_include_': if isinstance(v, str): self.includes.add(v) @@ -122,6 +126,8 @@ class Class(_Type): enum.compile_py(writer) for meth in self.methods: meth.compile_py(writer) + for meth in self.pymethods: + meth.compile_py(writer) writer.println() @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) + diff --git a/newbinding/src/BasicBlock.py b/newbinding/src/BasicBlock.py index c7221a5..b0716cd 100644 --- a/newbinding/src/BasicBlock.py +++ b/newbinding/src/BasicBlock.py @@ -1,6 +1,7 @@ from binding import * from namespace import llvm from Value import Function, BasicBlock +from Instruction import Instruction, TerminatorInst from LLVMContext import LLVMContext from StringRef import StringRef @@ -12,6 +13,8 @@ class BasicBlock: ptr(BasicBlock)) getParent = Method(ptr(Function)) + getTerminator = Method(ptr(TerminatorInst)) + empty = Method(cast(Bool, bool)) dropAllReferences = Method() isLandingPad = Method(cast(Bool, bool)) diff --git a/newbinding/src/DerivedTypes.py b/newbinding/src/DerivedTypes.py index c57e01b..efce8b8 100644 --- a/newbinding/src/DerivedTypes.py +++ b/newbinding/src/DerivedTypes.py @@ -9,8 +9,23 @@ FunctionType = llvm.Class(Type) @FunctionType class FunctionType: _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)) getReturnType = Method(ptr(Type)) getParamType = Method(ptr(Type), cast(int, Unsigned)) diff --git a/newbinding/src/Value.py b/newbinding/src/Value.py index 3dd5644..5345337 100644 --- a/newbinding/src/Value.py +++ b/newbinding/src/Value.py @@ -37,3 +37,10 @@ class Value: hasOneUse = Method(cast(Bool, bool)) hasNUses = Method(cast(Bool, bool), cast(int, Unsigned)) 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() diff --git a/newbinding/test2.py b/newbinding/test2.py index 810a7ba..3e54aee 100644 --- a/newbinding/test2.py +++ b/newbinding/test2.py @@ -30,24 +30,18 @@ fnty = api.FunctionType.get(int1ty, False) fnty.dump() types = [int1ty, api.Type.getIntNTy(context, 21)] -svt = extra.make_small_vector_from_types(*types) -fnty = api.FunctionType.get(int1ty, svt, False) +fnty = api.FunctionType.get(int1ty, types, False) -os = extra.make_raw_ostream_for_printing() -fnty.print_(os) -print os.str() +print fnty const = m.getOrInsertFunction("foo", fnty) fn = extra.downcast(const, api.Function) -os = extra.make_raw_ostream_for_printing() -fn.print_(os, None) -print os.str() +print fn assert fn.hasName() assert 'foo' == fn.getName() fn.setName('bar') assert 'bar' == fn.getName() -os = extra.make_raw_ostream_for_printing() assert fn.getReturnType() is int1ty assert fnty is fn.getFunctionType() @@ -56,14 +50,24 @@ assert fn.isVarArg() == False assert fn.getIntrinsicID() == 0 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) print builder bb = api.BasicBlock.Create(context, "entry", fn, None) +assert bb.empty() builder.SetInsertPoint(bb) +assert bb.getTerminator() is None + builder.CreateRetVoid() -fn.dump() +assert not bb.empty() +assert bb.getTerminator() is not None + +print bb + +