本文整理汇总了Golang中github.com/axw/gollvm/llvm.Value.SetInitializer方法的典型用法代码示例。如果您正苦于以下问题:Golang Value.SetInitializer方法的具体用法?Golang Value.SetInitializer怎么用?Golang Value.SetInitializer使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类github.com/axw/gollvm/llvm.Value
的用法示例。
在下文中一共展示了Value.SetInitializer方法的10个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: makeSlice
func (tm *TypeMap) makeSlice(values []llvm.Value, slicetyp llvm.Type) llvm.Value {
ptrtyp := slicetyp.StructElementTypes()[0]
var globalptr llvm.Value
if len(values) > 0 {
array := llvm.ConstArray(ptrtyp.ElementType(), values)
globalptr = llvm.AddGlobal(tm.module, array.Type(), "")
globalptr.SetInitializer(array)
globalptr = llvm.ConstBitCast(globalptr, ptrtyp)
} else {
globalptr = llvm.ConstNull(ptrtyp)
}
len_ := llvm.ConstInt(tm.inttype, uint64(len(values)), false)
slice := llvm.ConstNull(slicetyp)
slice = llvm.ConstInsertValue(slice, globalptr, []uint32{0})
slice = llvm.ConstInsertValue(slice, len_, []uint32{1})
slice = llvm.ConstInsertValue(slice, len_, []uint32{2})
return slice
}
示例2: interfaceRuntimeType
func (tm *TypeMap) interfaceRuntimeType(i *types.Interface) (global, ptr llvm.Value) {
rtype := tm.makeRtype(i, reflect.Interface)
interfaceType := llvm.ConstNull(tm.runtimeInterfaceType)
interfaceType = llvm.ConstInsertValue(interfaceType, rtype, []uint32{0})
imethods := make([]llvm.Value, i.NumMethods())
for index := range imethods {
method := i.Method(index)
//name, pkgPath, type
imethod := llvm.ConstNull(tm.runtimeImethod)
name := tm.globalStringPtr(method.Name())
name = llvm.ConstBitCast(name, tm.runtimeImethod.StructElementTypes()[0])
imethod = llvm.ConstInsertValue(imethod, name, []uint32{0})
//imethod = llvm.ConstInsertValue(imethod, , []uint32{1})
//imethod = llvm.ConstInsertValue(imethod, , []uint32{2})
imethods[index] = imethod
}
var imethodsGlobalPtr llvm.Value
imethodPtrType := llvm.PointerType(tm.runtimeImethod, 0)
if len(imethods) > 0 {
imethodsArray := llvm.ConstArray(tm.runtimeImethod, imethods)
imethodsGlobalPtr = llvm.AddGlobal(tm.module, imethodsArray.Type(), "")
imethodsGlobalPtr.SetInitializer(imethodsArray)
imethodsGlobalPtr = llvm.ConstBitCast(imethodsGlobalPtr, imethodPtrType)
} else {
imethodsGlobalPtr = llvm.ConstNull(imethodPtrType)
}
len_ := llvm.ConstInt(tm.inttype, uint64(i.NumMethods()), false)
imethodsSliceType := tm.runtimeInterfaceType.StructElementTypes()[1]
imethodsSlice := llvm.ConstNull(imethodsSliceType)
imethodsSlice = llvm.ConstInsertValue(imethodsSlice, imethodsGlobalPtr, []uint32{0})
imethodsSlice = llvm.ConstInsertValue(imethodsSlice, len_, []uint32{1})
imethodsSlice = llvm.ConstInsertValue(imethodsSlice, len_, []uint32{2})
interfaceType = llvm.ConstInsertValue(interfaceType, imethodsSlice, []uint32{1})
return tm.makeRuntimeTypeGlobal(interfaceType)
}
示例3: convertV2I
// convertV2I converts a value to an interface.
func (v *LLVMValue) convertV2I(iface *types.Interface) *LLVMValue {
var srcname *types.Named
srctyp := v.Type()
if name, isname := srctyp.(*types.Named); isname {
srcname = name
srctyp = name.Underlying()
}
var isptr bool
if p, fromptr := srctyp.(*types.Pointer); fromptr {
isptr = true
srctyp = p.Elem()
if name, isname := srctyp.(*types.Named); isname {
srcname = name
srctyp = name.Underlying()
}
}
iface_struct_type := v.compiler.types.ToLLVM(iface)
element_types := iface_struct_type.StructElementTypes()
zero_iface_struct := llvm.ConstNull(iface_struct_type)
iface_struct := zero_iface_struct
builder := v.compiler.builder
var ptr llvm.Value
lv := v.LLVMValue()
if lv.Type().TypeKind() == llvm.PointerTypeKind {
ptr = builder.CreateBitCast(lv, element_types[1], "")
} else {
// If the value fits exactly in a pointer, then we can just
// bitcast it. Otherwise we need to malloc, and create a shim
// function to load the receiver.
c := v.compiler
ptrsize := c.target.PointerSize()
if c.target.TypeStoreSize(lv.Type()) <= uint64(ptrsize) {
bits := c.target.TypeSizeInBits(lv.Type())
if bits > 0 {
lv = c.coerce(lv, llvm.IntType(int(bits)))
ptr = builder.CreateIntToPtr(lv, element_types[1], "")
} else {
ptr = llvm.ConstNull(element_types[1])
}
} else {
if lv.IsConstant() {
ptr = llvm.AddGlobal(c.module.Module, lv.Type(), "")
ptr.SetInitializer(lv)
} else {
ptr = c.createTypeMalloc(lv.Type())
builder.CreateStore(lv, ptr)
}
ptr = builder.CreateBitCast(ptr, element_types[1], "")
isptr = true
}
}
runtimeType := v.compiler.types.ToRuntime(v.Type())
runtimeType = builder.CreateBitCast(runtimeType, element_types[0], "")
iface_struct = builder.CreateInsertValue(iface_struct, runtimeType, 0, "")
iface_struct = builder.CreateInsertValue(iface_struct, ptr, 1, "")
if srcname != nil {
// Look up the method by name.
for i := 0; i < iface.NumMethods(); i++ {
m := iface.Method(i)
method := v.compiler.methods(srcname).lookup(m.Name(), isptr)
methodident := v.compiler.objectdata[method].Ident
llvm_value := v.compiler.Resolve(methodident).LLVMValue()
llvm_value = builder.CreateExtractValue(llvm_value, 0, "")
llvm_value = builder.CreateBitCast(llvm_value, element_types[i+2], "")
iface_struct = builder.CreateInsertValue(iface_struct, llvm_value, i+2, "")
}
}
return v.compiler.NewValue(iface_struct, iface)
}
示例4: NewConstValue
func (c *compiler) NewConstValue(v exact.Value, typ types.Type) *LLVMValue {
switch {
case v.Kind() == exact.Unknown:
// TODO nil literals should be represented more appropriately once the exact-package supports it.
llvmtyp := c.types.ToLLVM(typ)
return c.NewValue(llvm.ConstNull(llvmtyp), typ)
case isString(typ):
if isUntyped(typ) {
typ = types.Typ[types.String]
}
llvmtyp := c.types.ToLLVM(typ)
strval := exact.StringVal(v)
strlen := len(strval)
i8ptr := llvm.PointerType(llvm.Int8Type(), 0)
var ptr llvm.Value
if strlen > 0 {
init := llvm.ConstString(strval, false)
ptr = llvm.AddGlobal(c.module.Module, init.Type(), "")
ptr.SetInitializer(init)
ptr = llvm.ConstBitCast(ptr, i8ptr)
} else {
ptr = llvm.ConstNull(i8ptr)
}
len_ := llvm.ConstInt(c.types.inttype, uint64(strlen), false)
llvmvalue := llvm.Undef(llvmtyp)
llvmvalue = llvm.ConstInsertValue(llvmvalue, ptr, []uint32{0})
llvmvalue = llvm.ConstInsertValue(llvmvalue, len_, []uint32{1})
return c.NewValue(llvmvalue, typ)
case isInteger(typ):
if isUntyped(typ) {
typ = types.Typ[types.Int]
}
llvmtyp := c.types.ToLLVM(typ)
var llvmvalue llvm.Value
if isUnsigned(typ) {
v, _ := exact.Uint64Val(v)
llvmvalue = llvm.ConstInt(llvmtyp, v, false)
} else {
v, _ := exact.Int64Val(v)
llvmvalue = llvm.ConstInt(llvmtyp, uint64(v), true)
}
return c.NewValue(llvmvalue, typ)
case isBoolean(typ):
if isUntyped(typ) {
typ = types.Typ[types.Bool]
}
var llvmvalue llvm.Value
if exact.BoolVal(v) {
llvmvalue = llvm.ConstAllOnes(llvm.Int1Type())
} else {
llvmvalue = llvm.ConstNull(llvm.Int1Type())
}
return c.NewValue(llvmvalue, typ)
case isFloat(typ):
if isUntyped(typ) {
typ = types.Typ[types.Float64]
}
llvmtyp := c.types.ToLLVM(typ)
floatval, _ := exact.Float64Val(v)
llvmvalue := llvm.ConstFloat(llvmtyp, floatval)
return c.NewValue(llvmvalue, typ)
case typ == types.Typ[types.UnsafePointer]:
llvmtyp := c.types.ToLLVM(typ)
v, _ := exact.Uint64Val(v)
llvmvalue := llvm.ConstInt(llvmtyp, v, false)
return c.NewValue(llvmvalue, typ)
case isComplex(typ):
if isUntyped(typ) {
typ = types.Typ[types.Complex128]
}
llvmtyp := c.types.ToLLVM(typ)
floattyp := llvmtyp.StructElementTypes()[0]
llvmvalue := llvm.ConstNull(llvmtyp)
realv := exact.Real(v)
imagv := exact.Imag(v)
realfloatval, _ := exact.Float64Val(realv)
imagfloatval, _ := exact.Float64Val(imagv)
llvmre := llvm.ConstFloat(floattyp, realfloatval)
llvmim := llvm.ConstFloat(floattyp, imagfloatval)
llvmvalue = llvm.ConstInsertValue(llvmvalue, llvmre, []uint32{0})
llvmvalue = llvm.ConstInsertValue(llvmvalue, llvmim, []uint32{1})
return c.NewValue(llvmvalue, typ)
}
// Special case for string -> [](byte|rune)
if u, ok := typ.Underlying().(*types.Slice); ok && isInteger(u.Elem()) {
if v.Kind() == exact.String {
strval := c.NewConstValue(v, types.Typ[types.String])
return strval.Convert(typ).(*LLVMValue)
}
}
panic(fmt.Sprintf("unhandled: t=%s(%T), v=%v(%T)", c.types.TypeString(typ), typ, v, v))
}
示例5: pointerRuntimeType
func (tm *TypeMap) pointerRuntimeType(p *types.Pointer) (global, ptr llvm.Value) {
// Is the base type a named type from another package? If so, we'll
// create a reference to the externally defined symbol.
linkage := llvm.LinkOnceAnyLinkage
switch elem := p.Elem().(type) {
case *types.Basic:
if tm.pkgpath != "runtime" {
global := llvm.AddGlobal(tm.module, tm.runtime.rtype.llvm, typeSymbol(typeString(p)))
global.SetInitializer(llvm.ConstNull(tm.runtime.rtype.llvm))
global.SetLinkage(llvm.CommonLinkage)
return global, global
}
linkage = llvm.ExternalLinkage
case *types.Named:
path := "runtime"
if pkg := elem.Obj().Pkg(); pkg != nil {
path = pkg.Path()
}
if path != tm.pkgpath {
global := llvm.AddGlobal(tm.module, tm.runtime.rtype.llvm, typeSymbol(typeString(p)))
global.SetInitializer(llvm.ConstNull(tm.runtime.rtype.llvm))
global.SetLinkage(llvm.CommonLinkage)
return global, global
}
linkage = llvm.ExternalLinkage
}
rtype := tm.makeRtype(p, reflect.Ptr)
if n, ok := p.Elem().(*types.Named); ok {
uncommonTypeInit := tm.uncommonType(n, p)
uncommonType := llvm.AddGlobal(tm.module, uncommonTypeInit.Type(), "")
uncommonType.SetInitializer(uncommonTypeInit)
rtype = llvm.ConstInsertValue(rtype, uncommonType, []uint32{9})
}
ptrType := llvm.ConstNull(tm.runtime.ptrType.llvm)
var baseTypeGlobal llvm.Value
if p.Elem().Underlying() == p {
// Recursive pointer.
ptrType = llvm.ConstInsertValue(ptrType, rtype, []uint32{0})
global, ptr = tm.makeRuntimeTypeGlobal(ptrType, typeString(p))
baseTypeGlobal = global
// Update the global with its own pointer in the elem field.
ptrType = global.Initializer()
ptrType = llvm.ConstInsertValue(ptrType, ptr, []uint32{1})
global.SetInitializer(ptrType)
} else {
var baseTypePtr llvm.Value
baseTypeGlobal, baseTypePtr = tm.toRuntime(p.Elem())
ptrType = llvm.ConstInsertValue(ptrType, rtype, []uint32{0})
ptrType = llvm.ConstInsertValue(ptrType, baseTypePtr, []uint32{1})
global, ptr = tm.makeRuntimeTypeGlobal(ptrType, typeString(p))
}
global.SetLinkage(linkage)
// Set ptrToThis in the base type's rtype.
baseType := baseTypeGlobal.Initializer()
if !baseType.IsNull() {
if baseType.Type() == tm.runtime.rtype.llvm {
baseType = llvm.ConstInsertValue(baseType, ptr, []uint32{10})
} else {
rtype := llvm.ConstExtractValue(baseType, []uint32{0})
rtype = llvm.ConstInsertValue(rtype, ptr, []uint32{10})
baseType = llvm.ConstInsertValue(baseType, rtype, []uint32{0})
}
baseTypeGlobal.SetInitializer(baseType)
}
return global, ptr
}
示例6: uncommonType
func (tm *TypeMap) uncommonType(n *types.Named, ptr bool) llvm.Value {
uncommonTypeInit := llvm.ConstNull(tm.runtimeUncommonType)
namePtr := tm.globalStringPtr(n.Obj().Name())
uncommonTypeInit = llvm.ConstInsertValue(uncommonTypeInit, namePtr, []uint32{0})
// FIXME clean this up
var pkgpathPtr llvm.Value
var path string
if data, ok := tm.functions.objectdata[n.Obj()]; ok {
path = pkgpath(data.Package)
}
if path != "" {
pkgpathPtr = tm.globalStringPtr(path)
uncommonTypeInit = llvm.ConstInsertValue(uncommonTypeInit, pkgpathPtr, []uint32{1})
}
methodset := tm.functions.methods(n)
methodfuncs := methodset.nonptr
if ptr {
methodfuncs = methodset.ptr
}
// Store methods.
methods := make([]llvm.Value, len(methodfuncs))
for i, mfunc := range methodfuncs {
ftyp := mfunc.Type().(*types.Signature)
method := llvm.ConstNull(tm.runtimeMethod)
name := tm.globalStringPtr(mfunc.Name())
name = llvm.ConstBitCast(name, tm.runtimeMethod.StructElementTypes()[0])
// name
method = llvm.ConstInsertValue(method, name, []uint32{0})
// pkgPath
method = llvm.ConstInsertValue(method, pkgpathPtr, []uint32{1})
// mtyp (method type, no receiver)
{
ftyp := types.NewSignature(nil, ftyp.Params(), ftyp.Results(), ftyp.IsVariadic())
mtyp := tm.ToRuntime(ftyp)
method = llvm.ConstInsertValue(method, mtyp, []uint32{2})
}
// typ (function type, with receiver)
typ := tm.ToRuntime(ftyp)
method = llvm.ConstInsertValue(method, typ, []uint32{3})
// tfn (standard method/function pointer for plain method calls)
tfn := tm.resolver.Resolve(tm.functions.objectdata[mfunc].Ident).LLVMValue()
tfn = llvm.ConstExtractValue(tfn, []uint32{0})
tfn = llvm.ConstPtrToInt(tfn, tm.target.IntPtrType())
// ifn (single-word receiver function pointer for interface calls)
ifn := tfn
if !ptr && tm.Sizeof(ftyp.Recv().Type()) > int64(tm.target.PointerSize()) {
mfunc := methodset.lookup(mfunc.Name(), true)
ifn = tm.resolver.Resolve(tm.functions.objectdata[mfunc].Ident).LLVMValue()
ifn = llvm.ConstExtractValue(ifn, []uint32{0})
ifn = llvm.ConstPtrToInt(ifn, tm.target.IntPtrType())
}
method = llvm.ConstInsertValue(method, ifn, []uint32{4})
method = llvm.ConstInsertValue(method, tfn, []uint32{5})
methods[i] = method
}
var methodsGlobalPtr llvm.Value
if len(methods) > 0 {
methodsArray := llvm.ConstArray(tm.runtimeMethod, methods)
methodsGlobalPtr = llvm.AddGlobal(tm.module, methodsArray.Type(), "")
methodsGlobalPtr.SetInitializer(methodsArray)
i32zero := llvm.ConstNull(llvm.Int32Type())
methodsGlobalPtr = llvm.ConstGEP(methodsGlobalPtr, []llvm.Value{i32zero, i32zero})
} else {
methodsGlobalPtr = llvm.ConstNull(llvm.PointerType(tm.runtimeMethod, 0))
}
len_ := llvm.ConstInt(tm.inttype, uint64(len(methods)), false)
methodsSliceType := tm.runtimeUncommonType.StructElementTypes()[2]
methodsSlice := llvm.ConstNull(methodsSliceType)
methodsSlice = llvm.ConstInsertValue(methodsSlice, methodsGlobalPtr, []uint32{0})
methodsSlice = llvm.ConstInsertValue(methodsSlice, len_, []uint32{1})
methodsSlice = llvm.ConstInsertValue(methodsSlice, len_, []uint32{2})
uncommonTypeInit = llvm.ConstInsertValue(uncommonTypeInit, methodsSlice, []uint32{2})
return uncommonTypeInit
}
示例7: pointerRuntimeType
func (tm *TypeMap) pointerRuntimeType(p *types.Pointer) (global, ptr llvm.Value) {
// Is the base type a named type from another package? If so, we'll
// create a reference to the externally defined symbol.
var globalname string
if n, ok := p.Elem().(*types.Named); ok {
// FIXME horrible circular relationship
var path string
if data, ok := tm.functions.objectdata[n.Obj()]; ok {
path = pkgpath(data.Package)
}
if path == "" {
path = "runtime"
}
globalname = "__llgo.type.*" + path + "." + n.Obj().Name()
if path != tm.pkgpath {
global := llvm.AddGlobal(tm.module, tm.runtimeType, globalname)
global.SetInitializer(llvm.ConstNull(tm.runtimeType))
global.SetLinkage(llvm.CommonLinkage)
return global, global
}
}
rtype := tm.makeRtype(p, reflect.Ptr)
if n, ok := p.Elem().(*types.Named); ok {
uncommonTypeInit := tm.uncommonType(n, true)
uncommonType := llvm.AddGlobal(tm.module, uncommonTypeInit.Type(), "")
uncommonType.SetInitializer(uncommonTypeInit)
rtype = llvm.ConstInsertValue(rtype, uncommonType, []uint32{9})
}
ptrType := llvm.ConstNull(tm.runtimePtrType)
var baseTypeGlobal llvm.Value
if p.Elem().Underlying() == p {
// Recursive pointer.
ptrType = llvm.ConstInsertValue(ptrType, rtype, []uint32{0})
global, ptr = tm.makeRuntimeTypeGlobal(ptrType)
baseTypeGlobal = global
// Update the global with its own pointer in the elem field.
ptrType = global.Initializer()
ptrType = llvm.ConstInsertValue(ptrType, ptr, []uint32{1})
global.SetInitializer(ptrType)
} else {
var baseTypePtr llvm.Value
baseTypeGlobal, baseTypePtr = tm.toRuntime(p.Elem())
ptrType = llvm.ConstInsertValue(ptrType, rtype, []uint32{0})
ptrType = llvm.ConstInsertValue(ptrType, baseTypePtr, []uint32{1})
global, ptr = tm.makeRuntimeTypeGlobal(ptrType)
}
global.SetName(globalname)
// Set ptrToThis in the base type's rtype.
baseType := baseTypeGlobal.Initializer()
if baseType.Type() == tm.runtimeType {
baseType = llvm.ConstInsertValue(baseType, ptr, []uint32{10})
} else {
rtype := llvm.ConstExtractValue(baseType, []uint32{0})
rtype = llvm.ConstInsertValue(rtype, ptr, []uint32{10})
baseType = llvm.ConstInsertValue(baseType, rtype, []uint32{0})
}
baseTypeGlobal.SetInitializer(baseType)
return global, ptr
}
示例8: pointerRuntimeType
func (tm *TypeMap) pointerRuntimeType(p *types.Pointer) (global, ptr llvm.Value) {
// Is the base type a named type from another package? If so, we'll
// create a reference to the externally defined symbol.
var globalname string
switch elem := p.Elem().(type) {
case *types.Basic:
globalname = "__llgo.type.*runtime." + tm.TypeString(elem)
if tm.pkgpath != "runtime" {
global := llvm.AddGlobal(tm.module, tm.runtimeType, globalname)
global.SetInitializer(llvm.ConstNull(tm.runtimeType))
global.SetLinkage(llvm.CommonLinkage)
return global, global
}
case *types.Named:
qname, path := tm.qualifiedName(elem)
globalname = "__llgo.type.*" + qname
if path != tm.pkgpath {
global := llvm.AddGlobal(tm.module, tm.runtimeType, globalname)
global.SetInitializer(llvm.ConstNull(tm.runtimeType))
global.SetLinkage(llvm.CommonLinkage)
return global, global
} else if !isGlobalObject(elem.Obj()) {
globalname = ""
}
}
rtype := tm.makeRtype(p, reflect.Ptr)
if n, ok := p.Elem().(*types.Named); ok {
uncommonTypeInit := tm.uncommonType(n, true)
uncommonType := llvm.AddGlobal(tm.module, uncommonTypeInit.Type(), "")
uncommonType.SetInitializer(uncommonTypeInit)
rtype = llvm.ConstInsertValue(rtype, uncommonType, []uint32{9})
}
ptrType := llvm.ConstNull(tm.runtimePtrType)
var baseTypeGlobal llvm.Value
if p.Elem().Underlying() == p {
// Recursive pointer.
ptrType = llvm.ConstInsertValue(ptrType, rtype, []uint32{0})
global, ptr = tm.makeRuntimeTypeGlobal(ptrType)
baseTypeGlobal = global
// Update the global with its own pointer in the elem field.
ptrType = global.Initializer()
ptrType = llvm.ConstInsertValue(ptrType, ptr, []uint32{1})
global.SetInitializer(ptrType)
} else {
var baseTypePtr llvm.Value
baseTypeGlobal, baseTypePtr = tm.toRuntime(p.Elem())
ptrType = llvm.ConstInsertValue(ptrType, rtype, []uint32{0})
ptrType = llvm.ConstInsertValue(ptrType, baseTypePtr, []uint32{1})
global, ptr = tm.makeRuntimeTypeGlobal(ptrType)
}
global.SetName(globalname)
// Set ptrToThis in the base type's rtype.
baseType := baseTypeGlobal.Initializer()
if baseType.Type() == tm.runtimeType {
baseType = llvm.ConstInsertValue(baseType, ptr, []uint32{10})
} else {
rtype := llvm.ConstExtractValue(baseType, []uint32{0})
rtype = llvm.ConstInsertValue(rtype, ptr, []uint32{10})
baseType = llvm.ConstInsertValue(baseType, rtype, []uint32{0})
}
baseTypeGlobal.SetInitializer(baseType)
return global, ptr
}
示例9: nameRuntimeType
func (tm *TypeMap) nameRuntimeType(n *types.Name) (global, ptr llvm.Value) {
pkgpath := tm.pkgmap[n.Obj]
if pkgpath == "" {
// XXX "builtin"?
pkgpath = "runtime"
}
globalname := "__llgo.type.name." + pkgpath + "." + n.Obj.Name
if pkgpath != tm.pkgpath {
// We're not compiling the package from whence the type came,
// so we'll just create a pointer to it here.
global := llvm.AddGlobal(tm.module, tm.runtimeType, globalname)
global.SetInitializer(llvm.ConstNull(tm.runtimeType))
global.SetLinkage(llvm.CommonLinkage)
return global, global
}
underlying := n.Underlying
if name, ok := underlying.(*types.Name); ok {
underlying = name.Underlying
}
global, ptr = tm.makeRuntimeType(underlying)
globalInit := global.Initializer()
// Locate the common type.
underlyingRuntimeType := llvm.ConstExtractValue(globalInit, []uint32{1})
commonType := underlyingRuntimeType
if underlyingRuntimeType.Type() != tm.runtimeCommonType {
commonType = llvm.ConstExtractValue(commonType, []uint32{0})
}
// Insert the uncommon type.
uncommonTypeInit := llvm.ConstNull(tm.runtimeUncommonType)
namePtr := tm.globalStringPtr(n.Obj.Name)
uncommonTypeInit = llvm.ConstInsertValue(uncommonTypeInit, namePtr, []uint32{0})
pkgpathPtr := tm.globalStringPtr(pkgpath)
uncommonTypeInit = llvm.ConstInsertValue(uncommonTypeInit, pkgpathPtr, []uint32{1})
// Replace the commonType's string representation.
commonType = llvm.ConstInsertValue(commonType, namePtr, []uint32{8})
methods := make([]llvm.Value, len(n.Methods))
for index, m := range n.Methods {
method := llvm.ConstNull(tm.runtimeMethod)
name := tm.globalStringPtr(m.Name)
name = llvm.ConstBitCast(name, tm.runtimeMethod.StructElementTypes()[0])
// name
method = llvm.ConstInsertValue(method, name, []uint32{0})
// pkgPath
method = llvm.ConstInsertValue(method, pkgpathPtr, []uint32{1})
// mtyp (method type, no receiver)
ftyp := m.Type.(*types.Func)
{
recv := ftyp.Recv
ftyp.Recv = nil
mtyp := tm.ToRuntime(ftyp)
method = llvm.ConstInsertValue(method, mtyp, []uint32{2})
ftyp.Recv = recv
}
// typ (function type, with receiver)
typ := tm.ToRuntime(ftyp)
method = llvm.ConstInsertValue(method, typ, []uint32{3})
// ifn (single-word receiver function pointer for interface calls)
ifn := tm.resolver.Resolve(m).LLVMValue() // TODO generate trampoline as necessary.
ifn = llvm.ConstPtrToInt(ifn, tm.target.IntPtrType())
method = llvm.ConstInsertValue(method, ifn, []uint32{4})
// tfn (standard method/function pointer for plain method calls)
tfn := tm.resolver.Resolve(m).LLVMValue()
tfn = llvm.ConstPtrToInt(tfn, tm.target.IntPtrType())
method = llvm.ConstInsertValue(method, tfn, []uint32{5})
methods[index] = method
}
var methodsGlobalPtr llvm.Value
if len(methods) > 0 {
methodsArray := llvm.ConstArray(tm.runtimeMethod, methods)
methodsGlobalPtr = llvm.AddGlobal(tm.module, methodsArray.Type(), "")
methodsGlobalPtr.SetInitializer(methodsArray)
i32zero := llvm.ConstNull(llvm.Int32Type())
methodsGlobalPtr = llvm.ConstGEP(methodsGlobalPtr, []llvm.Value{i32zero, i32zero})
} else {
methodsGlobalPtr = llvm.ConstNull(llvm.PointerType(tm.runtimeMethod, 0))
}
len_ := llvm.ConstInt(llvm.Int32Type(), uint64(len(methods)), false)
methodsSliceType := tm.runtimeUncommonType.StructElementTypes()[2]
methodsSlice := llvm.ConstNull(methodsSliceType)
methodsSlice = llvm.ConstInsertValue(methodsSlice, methodsGlobalPtr, []uint32{0})
methodsSlice = llvm.ConstInsertValue(methodsSlice, len_, []uint32{1})
methodsSlice = llvm.ConstInsertValue(methodsSlice, len_, []uint32{2})
uncommonTypeInit = llvm.ConstInsertValue(uncommonTypeInit, methodsSlice, []uint32{2})
uncommonType := llvm.AddGlobal(tm.module, uncommonTypeInit.Type(), "")
uncommonType.SetInitializer(uncommonTypeInit)
commonType = llvm.ConstInsertValue(commonType, uncommonType, []uint32{9})
// Update the global's initialiser. Note that we take a copy
// of the underlying type; we're not updating a shared type.
if underlyingRuntimeType.Type() != tm.runtimeCommonType {
underlyingRuntimeType = llvm.ConstInsertValue(underlyingRuntimeType, commonType, []uint32{0})
} else {
//.........这里部分代码省略.........
示例10: uncommonType
func (tm *TypeMap) uncommonType(n *types.Name, ptr bool) llvm.Value {
uncommonTypeInit := llvm.ConstNull(tm.runtimeUncommonType)
namePtr := tm.globalStringPtr(n.Obj.Name)
uncommonTypeInit = llvm.ConstInsertValue(uncommonTypeInit, namePtr, []uint32{0})
var pkgpathPtr llvm.Value
if n.Package != "" {
pkgpathPtr = tm.globalStringPtr(n.Package)
uncommonTypeInit = llvm.ConstInsertValue(uncommonTypeInit, pkgpathPtr, []uint32{1})
}
// Store methods.
methods := make([]llvm.Value, 0, len(n.Methods))
for _, m := range n.Methods {
ftyp := m.Type.(*types.Func)
ptrrecv := !types.Identical(ftyp.Recv.Type.(types.Type), n)
if !ptr && ptrrecv {
// For a type T, we only store methods where the
// receiver is T and not *T. For *T we store both.
continue
}
method := llvm.ConstNull(tm.runtimeMethod)
name := tm.globalStringPtr(m.Name)
name = llvm.ConstBitCast(name, tm.runtimeMethod.StructElementTypes()[0])
// name
method = llvm.ConstInsertValue(method, name, []uint32{0})
// pkgPath
method = llvm.ConstInsertValue(method, pkgpathPtr, []uint32{1})
// mtyp (method type, no receiver)
{
recv := ftyp.Recv
ftyp.Recv = nil
mtyp := tm.ToRuntime(ftyp)
method = llvm.ConstInsertValue(method, mtyp, []uint32{2})
ftyp.Recv = recv
}
// typ (function type, with receiver)
typ := tm.ToRuntime(ftyp)
method = llvm.ConstInsertValue(method, typ, []uint32{3})
// tfn (standard method/function pointer for plain method calls)
tfn := tm.resolver.Resolve(m).LLVMValue()
tfn = llvm.ConstPtrToInt(tfn, tm.target.IntPtrType())
// ifn (single-word receiver function pointer for interface calls)
ifn := tfn
needload := ptr && !ptrrecv
if !needload {
recvtyp := tm.ToLLVM(ftyp.Recv.Type.(types.Type))
needload = int(tm.target.TypeAllocSize(recvtyp)) > tm.target.PointerSize()
}
if needload {
// If the receiver type is wider than a word, we
// need to use an intermediate function which takes
// a pointer-receiver, loads it, and then calls the
// standard receiver function.
fname := fmt.Sprintf("*%s.%s", ftyp.Recv.Type, m.Name)
ifn = tm.module.NamedFunction(fname)
ifn = llvm.ConstPtrToInt(ifn, tm.target.IntPtrType())
}
method = llvm.ConstInsertValue(method, ifn, []uint32{4})
method = llvm.ConstInsertValue(method, tfn, []uint32{5})
methods = append(methods, method)
}
var methodsGlobalPtr llvm.Value
if len(methods) > 0 {
methodsArray := llvm.ConstArray(tm.runtimeMethod, methods)
methodsGlobalPtr = llvm.AddGlobal(tm.module, methodsArray.Type(), "")
methodsGlobalPtr.SetInitializer(methodsArray)
i32zero := llvm.ConstNull(llvm.Int32Type())
methodsGlobalPtr = llvm.ConstGEP(methodsGlobalPtr, []llvm.Value{i32zero, i32zero})
} else {
methodsGlobalPtr = llvm.ConstNull(llvm.PointerType(tm.runtimeMethod, 0))
}
len_ := llvm.ConstInt(llvm.Int32Type(), uint64(len(methods)), false)
methodsSliceType := tm.runtimeUncommonType.StructElementTypes()[2]
methodsSlice := llvm.ConstNull(methodsSliceType)
methodsSlice = llvm.ConstInsertValue(methodsSlice, methodsGlobalPtr, []uint32{0})
methodsSlice = llvm.ConstInsertValue(methodsSlice, len_, []uint32{1})
methodsSlice = llvm.ConstInsertValue(methodsSlice, len_, []uint32{2})
uncommonTypeInit = llvm.ConstInsertValue(uncommonTypeInit, methodsSlice, []uint32{2})
return uncommonTypeInit
}