Try to fix invalid dtor call

This commit is contained in:
Siu Kwan Lam 2013-02-13 17:12:54 -06:00
commit d2dc34cdd3
6 changed files with 108 additions and 67 deletions

View file

@ -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))

View file

@ -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

View file

@ -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)'

View file

@ -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):

View file

@ -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]

View file

@ -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