Try to fix invalid dtor call
This commit is contained in:
parent
a09394cacd
commit
d2dc34cdd3
6 changed files with 108 additions and 67 deletions
72
llvm/core.py
72
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))
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)'
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue