From d2dc34cdd3f5d772be398efdbcd222ad6b1df826 Mon Sep 17 00:00:00 2001 From: Siu Kwan Lam Date: Wed, 13 Feb 2013 17:12:54 -0600 Subject: [PATCH] Try to fix invalid dtor call --- llvm/core.py | 72 +++++++++++++++++++++++++------------ llvmpy/capsule.py | 20 ++++++----- llvmpy/gen/binding.py | 2 +- llvmpy/gen/codegen.py | 4 ++- llvmpy/src/IRBuilder.py | 2 +- llvmpy/src/Instruction.py | 75 +++++++++++++++++++++------------------ 6 files changed, 108 insertions(+), 67 deletions(-) diff --git a/llvm/core.py b/llvm/core.py index 1c3184c..f2af943 100644 --- a/llvm/core.py +++ b/llvm/core.py @@ -475,28 +475,31 @@ class Module(llvm.Wrapper): def add_function(self, ty, name): """Add a function of given type with given name.""" - fn = self.get_function_named(name) - if fn is not None: - raise llvm.LLVMException("Duplicated function %s" % name) - return self.get_or_insert_function(ty, name) + return Function.new(self, ty, name) +# fn = self.get_function_named(name) +# if fn is not None: +# raise llvm.LLVMException("Duplicated function %s" % name) +# return self.get_or_insert_function(ty, name) def get_function_named(self, name): """Return a Function object representing function with given name.""" - fn = self._ptr.getFunction(name) - if fn is not None: - return _make_value(fn) + return Function.get(self, name) +# fn = self._ptr.getFunction(name) +# if fn is not None: +# return _make_value(fn) def get_or_insert_function(self, ty, name): """Like get_function_named(), but does add_function() first, if function is not present.""" - constant = self._ptr.getOrInsertFunction(name, ty._ptr) - try: - fn = constant._downcast(api.llvm.Function) - except ValueError: - # bitcasted to function type - return _make_value(constant) - else: - return _make_value(fn) + return Function.get_or_insert(self, ty, name) +# constant = self._ptr.getOrInsertFunction(name, ty._ptr) +# try: +# fn = constant._downcast(api.llvm.Function) +# except ValueError: +# # bitcasted to function type +# return _make_value(constant) +# else: +# return _make_value(fn) @property def functions(self): @@ -616,6 +619,10 @@ class Type(llvm.Wrapper): ptr = ptr._downcast(type(self)._type_) super(Type, self).__init__(ptr) + @property + def kind(self): + return self._ptr.getTypeID() + @staticmethod def int(bits=32): """Create an integer type having the given bit width.""" @@ -830,7 +837,6 @@ class FunctionType(Type): return self._ptr.getNumParams() - class StructType(Type): """Represents a structure type.""" _type_ = api.llvm.StructType @@ -1385,15 +1391,32 @@ class Function(GlobalValue): @staticmethod def new(module, func_ty, name): - return module.add_function(func_ty, name) + try: + fn = Function.get(module, name) + except llvm.LLVMException: + return Function.get_or_insert(module, func_ty, name) + else: + raise llvm.LLVMException("Duplicated function %s" % name) + @staticmethod def get_or_insert(module, func_ty, name): - return module.get_or_insert_function(func_ty, name) + constant = module._ptr.getOrInsertFunction(name, func_ty._ptr) + try: + fn = constant._downcast(api.llvm.Function) + except ValueError: + # bitcasted to function type + return _make_value(constant) + else: + return _make_value(fn) @staticmethod def get(module, name): - return module.get_function_named(name) + fn = module._ptr.getFunction(name) + if fn is None: + raise llvm.LLVMException("no function named `%s`" % name) + else: + return _make_value(fn) @staticmethod def intrinsic(module, intrinsic_id, types): @@ -1450,6 +1473,10 @@ class Function(GlobalValue): assert self.basic_block_count return _make_value(self._ptr.getEntryBlock()) + def get_entry_basic_block(self): + "Deprecated. Use entry_basic_block instead" + return self.entry_basic_block + def append_basic_block(self, name): context = api.llvm.getGlobalContext() bb = api.llvm.BasicBlock.Create(context, name, self._ptr, None) @@ -1857,6 +1884,7 @@ class Builder(llvm.Wrapper): """Position the builder at the end of the given block. Next instruction inserted will be last one in the block.""" + self._ptr.SetInsertPoint(bblk._ptr) def position_before(self, instr): @@ -2111,9 +2139,9 @@ class Builder(llvm.Wrapper): def insert_value(self, retval, rhs, idx, name=""): return _make_value(self._ptr.CreateInsertValue(retval._ptr, - rhs._ptr, - [idx], - name)) + rhs._ptr, + [idx], + name)) def phi(self, ty, name=""): return _make_value(self._ptr.CreatePHI(ty._ptr, 2, name)) diff --git a/llvmpy/capsule.py b/llvmpy/capsule.py index 03aa286..0b1f203 100644 --- a/llvmpy/capsule.py +++ b/llvmpy/capsule.py @@ -19,13 +19,14 @@ def set_debug(enabled): def _capsule_weakref_dtor(item): addr = item.pointer + name = item.name _addr2refct[addr] -= 1 refct = _addr2refct[addr] assert refct >= 0, "RefCt drop below 0" if refct == 0: - dtor = _addr2dtor.pop(addr, None) + dtor = _addr2dtor.pop((name, addr), None) if dtor is not None: - logger.debug('Destroy %s %s', item.name, hex(item.pointer)) + logger.debug('Destroy %s %s', name, hex(addr)) dtor(item.capsule) class Capsule(object): @@ -92,26 +93,28 @@ _cache = defaultdict(WeakValueDictionary) def release_ownership(old): logger.debug('Release %s', old) addr = Capsule.getPointer(old) - - if _addr2dtor.get(addr) is None: + name = Capsule.getName(old) + if _addr2dtor.get((name, addr)) is None: clsname = Capsule.getClassName(old) if not _pyclasses[clsname]._has_dtor(): return # Guard duplicated release raise Exception("Already released") - _addr2dtor[addr] = None + _addr2dtor[(name, addr)] = None def obtain_ownership(cap): cls = cap.get_class() if cls._has_dtor(): addr = cap.pointer + name = cap.name assert _addr2dtor[addr] is None - _addr2dtor[addr] = cls._delete_ + _addr2dtor[(name, addr)] = cls._delete_ def has_ownership(cap): addr = Capsule.getPointer(cap) - return _addr2dtor.get(addr) is not None + name = Capsule.getName(cap) + return _addr2dtor.get((name, addr)) is not None def wrap(cap, owned=False): '''Wrap a PyCapsule with the corresponding Wrapper class. @@ -125,11 +128,12 @@ def wrap(cap, owned=False): cap = Capsule(cap) cls = cap.get_class() addr = cap.pointer + name = cap.name try: # lookup cached object return _cache[cls][addr] except KeyError: if not owned and cls._has_dtor(): - _addr2dtor[addr] = cls._delete_ + _addr2dtor[(name, addr)] = cls._delete_ obj = cap.instantiate() _cache[cls][addr] = obj # cache it return obj diff --git a/llvmpy/gen/binding.py b/llvmpy/gen/binding.py index aaa33e4..4454d72 100644 --- a/llvmpy/gen/binding.py +++ b/llvmpy/gen/binding.py @@ -329,7 +329,7 @@ class Class(SubModule, _Type): fmt = 'PyCapsule_GetPointer(%(val)s, "%(name)s")' name = self.capsule_name raw = writer.declare('void*', fmt % locals()) - writer.die_if_false(raw) + writer.die_if_false(raw, verbose=name) ptrty = ptr(self).fullname ty = self.fullname fmt = 'typecast< %(ty)s >::from(%(raw)s)' diff --git a/llvmpy/gen/codegen.py b/llvmpy/gen/codegen.py index dd499d6..abde437 100644 --- a/llvmpy/gen/codegen.py +++ b/llvmpy/gen/codegen.py @@ -208,8 +208,10 @@ class CppCodeWriter(CodeWriterBase): self.return_null() return ret - def die_if_false(self, val): + def die_if_false(self, val, verbose=None): with self.block('if(!%(val)s)' % locals()): + if verbose: + self.println('puts("Error: %s");' % verbose) self.return_null() def raises(self, exccls, msg): diff --git a/llvmpy/src/IRBuilder.py b/llvmpy/src/IRBuilder.py index 445ff11..8590430 100644 --- a/llvmpy/src/IRBuilder.py +++ b/llvmpy/src/IRBuilder.py @@ -294,7 +294,7 @@ class IRBuilder: _CreateInsertValue.realname = 'CreateInsertValue' @CustomPythonMethod - def CreateInsertValue(self, args): + def CreateInsertValue(self, *args): from llvmpy import extra args = list(args) valuelist = args[2] diff --git a/llvmpy/src/Instruction.py b/llvmpy/src/Instruction.py index 9763e7c..4761e16 100644 --- a/llvmpy/src/Instruction.py +++ b/llvmpy/src/Instruction.py @@ -120,16 +120,17 @@ class Instruction: @AtomicCmpXchgInst class AtomicCmpXchgInst: - pass + _downcast_ = Value, Instruction @AtomicRMWInst class AtomicRMWInst: + _downcast_ = Value, Instruction BinOp = Enum('Xchg', 'Add', 'Sub', 'And', 'Nand', 'Or', 'Xor', 'Max', 'Min', 'UMax', 'UMin', 'FIRST_BINOP', 'LAST_BINOP', 'BAD_BINOP') @BinaryOperator class BinaryOperator: - pass + _downcast_ = Value, Instruction @CallInst class CallInst: @@ -159,6 +160,7 @@ class CallInst: @CmpInst class CmpInst: + _downcast_ = Value, Instruction 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', @@ -175,30 +177,31 @@ class CmpInst: @ExtractElementInst class ExtractElementInst: - pass + _downcast_ = Value, Instruction @FenceInst class FenceInst: - pass + _downcast_ = Value, Instruction @GetElementPtrInst class GetElementPtrInst: - pass + _downcast_ = Value, Instruction @InsertElementInst class InsertElementInst: - pass + _downcast_ = Value, Instruction @InsertValueInst class InsertValueInst: - pass + _downcast_ = Value, Instruction @LandingPadInst class LandingPadInst: - pass + _downcast_ = Value, Instruction @PHINode class PHINode: + _downcast_ = Value, Instruction getNumIncomingValues = Method(cast(Unsigned, int)) getIncomingValue = Method(ptr(Value), cast(int, Unsigned)) setIncomingValue = Method(Void, cast(int, Unsigned), ptr(Value)) @@ -210,15 +213,15 @@ class PHINode: @SelectInst class SelectInst: - pass + _downcast_ = Value, Instruction @ShuffleVectorInst class ShuffleVectorInst: - pass + _downcast_ = Value, Instruction @StoreInst class StoreInst: - _downcast_ = Instruction + _downcast_ = Value, Instruction isVolatile = Method(cast(Bool, bool)) isSimple = Method(cast(Bool, bool)) isUnordered = Method(cast(Bool, bool)) @@ -237,38 +240,40 @@ class StoreInst: @TerminatorInst class TerminatorInst: + _downcast_ = Value, Instruction getNumSuccessors = Method(cast(Unsigned, int)) getSuccessor = Method(ptr(BasicBlock), cast(int, Unsigned)) setSuccessor = Method(Void, cast(int, Unsigned), ptr(BasicBlock)) @UnaryInstruction class UnaryInstruction: - pass + _downcast_ = Value, Instruction #call @IntrinsicInst class IntrinsicInst: - pass + _include_ = 'llvm/IntrinsicInst.h' + _downcast_ = Value, Instruction #compare @FCmpInst class FCmpInst: - pass + _downcast_ = Value, Instruction @ICmpInst class ICmpInst: - pass + _downcast_ = Value, Instruction # terminator @BranchInst class BranchInst: - pass + _downcast_ = Value, Instruction @IndirectBrInst class IndirectBrInst: - pass + _downcast_ = Value, Instruction @InvokeInst class InvokeInst: @@ -284,14 +289,16 @@ class InvokeInst: @ResumeInst class ResumeInst: - pass + _downcast_ = Value, Instruction @ReturnInst class ReturnInst: - pass + _downcast_ = Value, Instruction @SwitchInst class SwitchInst: + _downcast_ = Value, Instruction + getCondition = Method(ptr(Value)) setCondition = Method(Void, ptr(Value)) getDefaultDest = Method(ptr(BasicBlock)) @@ -302,20 +309,20 @@ class SwitchInst: @UnreachableInst class UnreachableInst: - pass + _downcast_ = Value, Instruction # unary @AllocaInst class AllocaInst: - pass + _downcast_ = Value, Instruction @CastInst class CastInst: - pass + _downcast_ = Value, Instruction @ExtractValueInst class ExtractValueInst: - pass + _downcast_ = Value, Instruction @LoadInst class LoadInst: @@ -338,46 +345,46 @@ class LoadInst: @VAArgInst class VAArgInst: - pass + _downcast_ = Value, Instruction # intrinsic @DbgInfoIntrinsic class DbgInfoIntrinsic: - pass + _downcast_ = Value, Instruction @MemIntrinsic class MemIntrinsic: - pass + _downcast_ = Value, Instruction @VACopyInst class VACopyInst: - pass + _downcast_ = Value, Instruction @VAEndInst class VAEndInst: - pass + _downcast_ = Value, Instruction @VAStartInst class VAStartInst: - pass + _downcast_ = Value, Instruction @BitCastInst class BitCastInst: - pass + _downcast_ = Value, Instruction @FPExtInst class FPExtInst: - pass + _downcast_ = Value, Instruction @FPToSIInst class FPToSIInst: - pass + _downcast_ = Value, Instruction @FPToUIInst class FPToUIInst: - pass + _downcast_ = Value, Instruction @FPTruncInst class FPTruncInst: - pass + _downcast_ = Value, Instruction