示例#1
0
def destroyClosure(refcAddr, cx):  # assuming nonnull
    cdt = closureDestructorType(cx)
    sizep, funcpp, funcp, voidp = cx.local(), cx.local(), cx.local(), cx.local(
    )
    cx.useBuiltin('~free')
    return [
        inst.linearGEP(refcAddr, '%size_t', sizep, -1),
        inst.bitcast('%size_t*', lt.Pointer(cdt, cx), sizep, funcpp),
        inst.load(cdt, funcpp, funcp),
        inst.bitcast('%size_t*', '%voidptr', sizep, voidp),
        'call void %s(%%voidptr %s)' % (funcp, voidp)
    ]
示例#2
0
 def compile(self, cx, out):
     expr, tagged, ptr = cx.local(), cx.local(), cx.local()
     sideType = lu.sumSideType(cx.s[self.type].parms[self.side].llvm(cx))
     return self.expr.compile(cx, expr) + \
         lu.formAggregate(sideType, cx, tagged, self.side, expr) \
          + lu.heapCreate(sideType, tagged, cx, ptr) + [
         inst.bitcast('%s*' % sideType, self.type.llvm(cx), ptr, out)]
示例#3
0
 def compile(self, cx, out):
     psum, pside, p = cx.local(), cx.local(), cx.local()
     tp = self.type.llvm(cx)
     sst = lu.sumSideType(tp)
     return self.expr.compile(cx, psum) + [
         inst.bitcast('i1*', '%s*' % sst, psum, pside),
         inst.structGEP(pside, sst, p, 1),
         inst.load(tp, p, out)] + mem.reference(out, self.type, cx) + \
         mem.unreference(psum, self.expr.type, cx)
示例#4
0
def heapCreate(ltype, value, cx, out):
    voidp, rcp, rcval = cx.local(), cx.local(), cx.local()
    cx.useBuiltin('~malloc')
    rctype = mem.rctype(ltype, cx)
    return formAggregate(rctype, cx, rcval, 1, value) + [
        '%s = call %%voidptr @malloc(%%size_t %d)' % (voidp, rctype.size),
        inst.bitcast('%voidptr', lt.Pointer(rctype, cx), voidp, rcp),
        inst.store(rctype, rcval, rcp),
        inst.structGEP(rcp, rctype, out, 1)
    ]
示例#5
0
def createClosure(clType, clStuff, destructor, cx, out):
    t = closureTypeFull(clType, cx)
    voidp, rcp, rcval = cx.local(), cx.local(), cx.local()
    cx.useBuiltin('~malloc')
    return lu.formAggregate(t, cx, rcval, destructor, 1, clStuff) + [
        '%s = call %%voidptr @malloc(%%size_t %d)' % (voidp, t.size),
        inst.bitcast('%voidptr', lt.Pointer(t, cx), voidp, rcp),
        inst.store(t, rcval, rcp),
        inst.structGEP(rcp, t, out, 2)
    ]
示例#6
0
 def destroySide(i):
     lt_i = mtype.parms[i].llvm(cx)
     sst = lu.sumSideType(lt_i)
     r, sp, mp = cx.local(), cx.local(), cx.local()
     unrefCode = unreference(r, mtype.parms[i], cx)
     if not unrefCode: return []
     return [
         inst.bitcast('i1*', lt.Pointer(sst, cx), '%object', sp),
         inst.structGEP(sp, sst, mp, 1),
         inst.load(lt_i, mp, r)
     ] + unrefCode
示例#7
0
def closureDestructorDefinition(name, clType, items, cx):
    sig = 'void %s(%%voidptr %%cl)' % name
    clTypeFull = closureTypeFull(clType, cx)
    body = []
    for i, (ltype, unrefCode, reg) in enumerate(items):
        unrefCode = unrefCode(cx)
        if unrefCode:
            body += [inst.extractvalue(clType, '%stuff', i, reg)] + unrefCode
    if body:
        body = [
            inst.bitcast('%voidptr', lt.Pointer(clTypeFull, cx), '%cl', '%p'),
            inst.structGEP('%p', clTypeFull, '%stuffP', 2),
            inst.load(clType, '%stuffP', '%stuff')
        ] + body
    body += ['call void @free(%voidptr %cl)', inst.ret()]
    return lu.formatFunctionDef(sig, body, cx.llvmVersion)
示例#8
0
 def getDestructor(self, mtype):  # for sum types
     smtype = self.canonicalStr(mtype)
     if smtype in self.destructors:
         return self.destructors[smtype]
     name = self.destructor()
     self.destructors[smtype] = name
     self.useBuiltin('~free')
     dbody = ['; ' + smtype] + mem.sumDestructorBody(mtype, self)
     sig = 'void %s(%s %%object)' % (name, mtype.llvm(self))
     dbody += mem.getPtrToRefcount('%object', 'i1*', self, '%prefc') + [
         inst.bitcast('%size_t*', '%voidptr', '%prefc', '%pvoid'),
         'call void @free(%voidptr %pvoid)',
         inst.ret()
     ]
     self.destructorDefinitions.append(
         formatFunctionDef(sig, dbody, self.llvmVersion))
     return name
示例#9
0
def unreference(v, mtype, cx):
    mtype = cx.s[mtype]
    if canonicalStorage(mtype, cx.s) is StorageType.POINTER:
        sizep, refc = cx.local(), cx.local()
        return [inst.bitcast('i1*', '%size_t*', v, sizep),
                inst.linearGEP(sizep, '%size_t', refc, -1)] + \
            heapRefcountDecrement(refc,
                ['call void %s(i1* %s)' % (cx.getDestructor(mtype), v)], cx)
    elif isinstance(mtype, types.Product):
        code = []
        for i in 0, 1:
            r = cx.local()
            refcode = unreference(r, mtype.parms[i], cx)
            if refcode:
                code += lu.extractProductElement(mtype, v, i, cx, r)
                code += refcode
        return code
    elif isinstance(mtype, types.Arrow):
        r, prefc = cx.local(), cx.local()
        return lu.funcObjClosure(v, mtype, cx, r) + nullChecked(
            r, cx.voidptr,
            getPtrToRefcount(r, cx.voidptr, cx, prefc) +
            heapRefcountDecrement(prefc, destroyClosure(prefc, cx), cx), cx)
    return []
示例#10
0
def getPtrToRefcount(addr, ptrType, cx, out):
    sizeptr = cx.local()
    return [
        inst.bitcast(ptrType, '%size_t*', addr, sizeptr),
        inst.linearGEP(sizeptr, '%size_t', out, -1)
    ]