本文整理匯總了Golang中github.com/axw/gollvm/llvm.ConstArray函數的典型用法代碼示例。如果您正苦於以下問題:Golang ConstArray函數的具體用法?Golang ConstArray怎麽用?Golang ConstArray使用的例子?那麽, 這裏精選的函數代碼示例或許可以為您提供幫助。
在下文中一共展示了ConstArray函數的14個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的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: Compile
//.........這裏部分代碼省略.........
defer func() {
if e := recover(); e != nil {
compiler.module.Dispose()
panic(e)
}
}()
// Create a struct responsible for mapping static types to LLVM types,
// and to runtime/dynamic type values.
var resolver Resolver = compiler
compiler.FunctionCache = NewFunctionCache(compiler)
compiler.types = NewTypeMap(compiler.llvmtypes, compiler.module.Module, importpath, compiler.FunctionCache, resolver)
// Create a Builder, for building LLVM instructions.
compiler.builder = newBuilder(compiler.types)
defer compiler.builder.Dispose()
compiler.debug_info = &llvm.DebugInfo{}
// Compile each file in the package.
for _, file := range files {
compiler.compile_unit = &llvm.CompileUnitDescriptor{
Language: llvm.DW_LANG_Go,
Path: llvm.FileDescriptor(fset.File(file.Pos()).Name()),
Producer: LLGOProducer,
Runtime: LLGORuntimeVersion,
}
compiler.pushDebugContext(&compiler.compile_unit.Path)
for _, decl := range file.Decls {
compiler.VisitDecl(decl)
}
compiler.popDebugContext()
if len(compiler.debug_context) > 0 {
log.Panicln(compiler.debug_context)
}
compiler.module.AddNamedMetadataOperand("llvm.dbg.cu", compiler.debug_info.MDNode(compiler.compile_unit))
}
// Export runtime type information.
compiler.exportRuntimeTypes()
// Wrap "main.main" in a call to runtime.main.
if importpath == "main" {
err = compiler.createMainFunction()
if err != nil {
return nil, err
}
} else {
var e = exporter{compiler: compiler}
if err := e.Export(pkg); err != nil {
return nil, err
}
}
// Create global constructors. The initfuncs/varinitfuncs
// slices are in the order of visitation; we generate the
// list of constructors in the reverse order.
//
// The llgo linker will link modules in the order of
// package dependency, i.e. if A requires B, then llgo-link
// will link the modules in the order A, B. The "runtime"
// package is always last.
//
// At program initialisation, the runtime initialisation
// function (runtime.main) will invoke the constructors
// in reverse order.
var initfuncs [][]llvm.Value
if compiler.varinitfuncs != nil {
initfuncs = append(initfuncs, compiler.varinitfuncs)
}
if compiler.initfuncs != nil {
initfuncs = append(initfuncs, compiler.initfuncs)
}
if initfuncs != nil {
ctortype := llvm.PointerType(llvm.Int8Type(), 0)
var ctors []llvm.Value
var index int = 0
for _, initfuncs := range initfuncs {
for _, fnptr := range initfuncs {
name := fmt.Sprintf("__llgo.ctor.%s.%d", importpath, index)
fnptr.SetName(name)
fnptr = llvm.ConstBitCast(fnptr, ctortype)
ctors = append(ctors, fnptr)
index++
}
}
for i, n := 0, len(ctors); i < n/2; i++ {
ctors[i], ctors[n-i-1] = ctors[n-i-1], ctors[i]
}
ctorsInit := llvm.ConstArray(ctortype, ctors)
ctorsVar := llvm.AddGlobal(compiler.module.Module, ctorsInit.Type(), "runtime.ctors")
ctorsVar.SetInitializer(ctorsInit)
ctorsVar.SetLinkage(llvm.AppendingLinkage)
}
// Create debug metadata.
//compiler.createMetadata()
return compiler.module, nil
}
示例4: Compile
func (compiler *compiler) Compile(fset *token.FileSet,
pkg *ast.Package,
exprTypes map[ast.Expr]types.Type) (m *Module, err error) {
// FIXME create a compilation state, rather than storing in 'compiler'.
compiler.fileset = fset
compiler.pkg = pkg
compiler.initfuncs = make([]Value, 0)
// Create a Builder, for building LLVM instructions.
compiler.builder = llvm.GlobalContext().NewBuilder()
defer compiler.builder.Dispose()
// Create a TargetMachine from the OS & Arch.
triple := fmt.Sprintf("%s-unknown-%s",
getTripleArchName(compiler.targetArch),
compiler.targetOs)
var machine llvm.TargetMachine
for target := llvm.FirstTarget(); target.C != nil && machine.C == nil; target = target.NextTarget() {
if target.Name() == compiler.targetArch {
machine = target.CreateTargetMachine(triple, "", "",
llvm.CodeGenLevelDefault,
llvm.RelocDefault,
llvm.CodeModelDefault)
defer machine.Dispose()
}
}
if machine.C == nil {
err = fmt.Errorf("Invalid target triple: %s", triple)
return
}
// Create a Module, which contains the LLVM bitcode. Dispose it on panic,
// otherwise we'll set a finalizer at the end. The caller may invoke
// Dispose manually, which will render the finalizer a no-op.
modulename := pkg.Name
compiler.target = machine.TargetData()
compiler.module = &Module{llvm.NewModule(modulename), modulename, false}
compiler.module.SetTarget(triple)
compiler.module.SetDataLayout(compiler.target.String())
defer func() {
if e := recover(); e != nil {
compiler.module.Dispose()
panic(e)
//err = e.(error)
}
}()
compiler.types = NewTypeMap(compiler.module.Module, compiler.target, exprTypes)
// Create a mapping from objects back to packages, so we can create the
// appropriate symbol names.
compiler.pkgmap = createPackageMap(pkg)
// Compile each file in the package.
for _, file := range pkg.Files {
file.Scope.Outer = pkg.Scope
compiler.filescope = file.Scope
compiler.scope = file.Scope
compiler.fixConstDecls(file)
for _, decl := range file.Decls {
compiler.VisitDecl(decl)
}
}
// Define intrinsics for use by the runtime: malloc, free, memcpy, etc.
compiler.defineRuntimeIntrinsics()
// Create global constructors.
//
// XXX When imports are handled, we'll need to defer creating
// llvm.global_ctors until we create an executable. This is
// due to (a) imports having to be initialised before the
// importer, and (b) LLVM having no specified order of
// initialisation for ctors with the same priority.
if len(compiler.initfuncs) > 0 {
elttypes := []llvm.Type{
llvm.Int32Type(),
llvm.PointerType(
llvm.FunctionType(llvm.VoidType(), nil, false), 0)}
ctortype := llvm.StructType(elttypes, false)
ctors := make([]llvm.Value, len(compiler.initfuncs))
for i, fn := range compiler.initfuncs {
struct_values := []llvm.Value{
llvm.ConstInt(llvm.Int32Type(), 1, false),
fn.LLVMValue()}
ctors[i] = llvm.ConstStruct(struct_values, false)
}
global_ctors_init := llvm.ConstArray(ctortype, ctors)
global_ctors_var := llvm.AddGlobal(
compiler.module.Module, global_ctors_init.Type(),
"llvm.global_ctors")
global_ctors_var.SetInitializer(global_ctors_init)
global_ctors_var.SetLinkage(llvm.AppendingLinkage)
}
// Create debug metadata.
compiler.createMetadata()
return compiler.module, nil
//.........這裏部分代碼省略.........
示例5: 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
}
示例6: VisitCompositeLit
func (c *compiler) VisitCompositeLit(lit *ast.CompositeLit) Value {
typ := c.types.expr[lit]
var valuemap map[interface{}]Value
var valuelist []Value
_, isstruct := types.Underlying(typ).(*types.Struct)
if lit.Elts != nil {
for _, elt := range lit.Elts {
var value Value
if kv, iskv := elt.(*ast.KeyValueExpr); iskv {
value = c.VisitExpr(kv.Value)
if valuemap == nil {
valuemap = make(map[interface{}]Value)
}
var key interface{}
if isstruct {
key = kv.Key.(*ast.Ident).Name
} else {
key = c.VisitExpr(kv.Key)
}
valuemap[key] = value
} else {
value = c.VisitExpr(elt)
valuelist = append(valuelist, value)
}
}
}
// For array/slice types, convert key:value to contiguous
// values initialiser.
switch types.Underlying(typ).(type) {
case *types.Array, *types.Slice:
if len(valuemap) > 0 {
maxi := int64(-1)
for key, _ := range valuemap {
i := key.(ConstValue).Int64()
if i < 0 {
panic("array index must be non-negative integer constant")
} else if i > maxi {
maxi = i
}
}
valuelist = make([]Value, maxi+1)
for key, value := range valuemap {
i := key.(ConstValue).Int64()
valuelist[i] = value
}
}
}
origtyp := typ
switch typ := types.Underlying(typ).(type) {
case *types.Array:
elttype := typ.Elt
llvmelttype := c.types.ToLLVM(elttype)
llvmvalues := make([]llvm.Value, typ.Len)
for i := range llvmvalues {
var value Value
if i < len(valuelist) {
value = valuelist[i]
}
if value == nil {
llvmvalues[i] = llvm.ConstNull(llvmelttype)
} else if _, ok := value.(ConstValue); ok || value.LLVMValue().IsConstant() {
llvmvalues[i] = value.Convert(elttype).LLVMValue()
} else {
llvmvalues[i] = llvm.Undef(llvmelttype)
}
}
array := llvm.ConstArray(llvmelttype, llvmvalues)
for i, value := range valuelist {
if llvmvalues[i].IsUndef() {
value := value.Convert(elttype).LLVMValue()
array = c.builder.CreateInsertValue(array, value, i, "")
}
}
return c.NewLLVMValue(array, origtyp)
case *types.Slice:
ptr := c.createTypeMalloc(c.types.ToLLVM(typ))
eltType := c.types.ToLLVM(typ.Elt)
arrayType := llvm.ArrayType(eltType, len(valuelist))
valuesPtr := c.createMalloc(llvm.SizeOf(arrayType))
valuesPtr = c.builder.CreateIntToPtr(valuesPtr, llvm.PointerType(eltType, 0), "")
//valuesPtr = c.builder.CreateBitCast(valuesPtr, llvm.PointerType(valuesPtr.Type(), 0), "")
// TODO check result of mallocs
length := llvm.ConstInt(llvm.Int32Type(), uint64(len(valuelist)), false)
c.builder.CreateStore(valuesPtr, c.builder.CreateStructGEP(ptr, 0, "")) // data
c.builder.CreateStore(length, c.builder.CreateStructGEP(ptr, 1, "")) // len
c.builder.CreateStore(length, c.builder.CreateStructGEP(ptr, 2, "")) // cap
null := llvm.ConstNull(c.types.ToLLVM(typ.Elt))
for i, value := range valuelist {
index := llvm.ConstInt(llvm.Int32Type(), uint64(i), false)
valuePtr := c.builder.CreateGEP(valuesPtr, []llvm.Value{index}, "")
if value == nil {
c.builder.CreateStore(null, valuePtr)
} else {
c.builder.CreateStore(value.Convert(typ.Elt).LLVMValue(), valuePtr)
}
//.........這裏部分代碼省略.........
示例7: Compile
//.........這裏部分代碼省略.........
// Create a Module, which contains the LLVM bitcode. Dispose it on panic,
// otherwise we'll set a finalizer at the end. The caller may invoke
// Dispose manually, which will render the finalizer a no-op.
modulename := pkg.Name
compiler.module = &Module{llvm.NewModule(modulename), modulename, false}
compiler.module.SetTarget(compiler.TargetTriple)
compiler.module.SetDataLayout(compiler.target.String())
defer func() {
if e := recover(); e != nil {
compiler.module.Dispose()
panic(e)
//err = e.(error)
}
}()
// Create a mapping from objects back to packages, so we can create the
// appropriate symbol names.
compiler.pkgmap = createPackageMap(pkg, importpath)
// Create a struct responsible for mapping static types to LLVM types,
// and to runtime/dynamic type values.
var resolver Resolver = compiler
compiler.FunctionCache = NewFunctionCache(compiler)
compiler.types = NewTypeMap(compiler.llvmtypes, compiler.module.Module, importpath, exprTypes, compiler.FunctionCache, resolver)
// Compile each file in the package.
for _, file := range pkg.Files {
file.Scope.Outer = pkg.Scope
compiler.filescope = file.Scope
compiler.scope = file.Scope
compiler.fixConstDecls(file)
for _, decl := range file.Decls {
compiler.VisitDecl(decl)
}
}
// Define intrinsics for use by the runtime: malloc, free, memcpy, etc.
// These could be defined in LLVM IR, and may be moved there later.
if pkg.Name == "runtime" {
compiler.defineRuntimeIntrinsics()
}
// Export runtime type information.
if pkg.Name == "runtime" {
compiler.exportBuiltinRuntimeTypes()
}
// Wrap "main.main" in a call to runtime.main.
if pkg.Name == "main" {
err = compiler.createMainFunction()
if err != nil {
return nil, err
}
}
// Create global constructors. The initfuncs/varinitfuncs
// slices are in the order of visitation; we generate the
// list of constructors in the reverse order.
//
// The llgo linker will link modules in the order of
// package dependency, i.e. if A requires B, then llgo-link
// will link the modules in the order A, B. The "runtime"
// package is always last.
//
// At program initialisation, the runtime initialisation
// function (runtime.main) will invoke the constructors
// in reverse order.
var initfuncs [][]Value
if compiler.varinitfuncs != nil {
initfuncs = append(initfuncs, compiler.varinitfuncs)
}
if compiler.initfuncs != nil {
initfuncs = append(initfuncs, compiler.initfuncs)
}
if initfuncs != nil {
ctortype := llvm.PointerType(llvm.FunctionType(llvm.VoidType(), nil, false), 0)
var ctors []llvm.Value
var index int = 0
for _, initfuncs := range initfuncs {
for _, fn := range initfuncs {
fnval := fn.LLVMValue()
fnval.SetName("__llgo.ctor." + compiler.importpath + strconv.Itoa(index))
ctors = append(ctors, fnval)
index++
}
}
for i, n := 0, len(ctors); i < n/2; i++ {
ctors[i], ctors[n-i-1] = ctors[n-i-1], ctors[i]
}
ctorsInit := llvm.ConstArray(ctortype, ctors)
ctorsVar := llvm.AddGlobal(compiler.module.Module, ctorsInit.Type(), "runtime.ctors")
ctorsVar.SetInitializer(ctorsInit)
ctorsVar.SetLinkage(llvm.AppendingLinkage)
}
// Create debug metadata.
//compiler.createMetadata()
return compiler.module, nil
}
示例8: VisitCompositeLit
//.........這裏部分代碼省略.........
for key, _ := range valuemap {
key, _ := exact.Uint64Val(key.(exact.Value))
if key > maxkey {
maxkey = key
}
}
valuelist = make([]Value, maxkey+1)
for key, value := range valuemap {
key, _ := exact.Uint64Val(key.(exact.Value))
valuelist[key] = value
}
}
}
origtyp := typ
switch typ := typ.Underlying().(type) {
case *types.Array:
elttype := typ.Elem()
llvmelttype := c.types.ToLLVM(elttype)
llvmvalues := make([]llvm.Value, typ.Len())
for i := range llvmvalues {
var value Value
if i < len(valuelist) {
value = valuelist[i]
}
if value == nil {
llvmvalues[i] = llvm.ConstNull(llvmelttype)
} else if value.LLVMValue().IsConstant() {
llvmvalues[i] = value.Convert(elttype).LLVMValue()
} else {
llvmvalues[i] = llvm.Undef(llvmelttype)
}
}
array := llvm.ConstArray(llvmelttype, llvmvalues)
for i, value := range valuelist {
if llvmvalues[i].IsUndef() {
value := value.Convert(elttype).LLVMValue()
array = c.builder.CreateInsertValue(array, value, i, "")
}
}
return c.NewValue(array, origtyp)
case *types.Slice:
ptr := c.createTypeMalloc(c.types.ToLLVM(typ))
eltType := c.types.ToLLVM(typ.Elem())
arrayType := llvm.ArrayType(eltType, len(valuelist))
valuesPtr := c.createMalloc(llvm.SizeOf(arrayType))
valuesPtr = c.builder.CreateIntToPtr(valuesPtr, llvm.PointerType(eltType, 0), "")
//valuesPtr = c.builder.CreateBitCast(valuesPtr, llvm.PointerType(valuesPtr.Type(), 0), "")
length := llvm.ConstInt(c.types.inttype, uint64(len(valuelist)), false)
c.builder.CreateStore(valuesPtr, c.builder.CreateStructGEP(ptr, 0, "")) // data
c.builder.CreateStore(length, c.builder.CreateStructGEP(ptr, 1, "")) // len
c.builder.CreateStore(length, c.builder.CreateStructGEP(ptr, 2, "")) // cap
null := llvm.ConstNull(c.types.ToLLVM(typ.Elem()))
for i, value := range valuelist {
index := llvm.ConstInt(llvm.Int32Type(), uint64(i), false)
valuePtr := c.builder.CreateGEP(valuesPtr, []llvm.Value{index}, "")
if value == nil {
c.builder.CreateStore(null, valuePtr)
} else {
c.builder.CreateStore(value.Convert(typ.Elem()).LLVMValue(), valuePtr)
}
}
m := c.NewValue(ptr, types.NewPointer(origtyp))
示例9: VisitCompositeLit
func (c *compiler) VisitCompositeLit(lit *ast.CompositeLit) Value {
typ := c.GetType(lit.Type)
var valuemap map[interface{}]Value
var valuelist []Value
_, isstruct := types.Underlying(typ).(*types.Struct)
if lit.Elts != nil {
for _, elt := range lit.Elts {
var value Value
if kv, iskv := elt.(*ast.KeyValueExpr); iskv {
value = c.VisitExpr(kv.Value)
if valuemap == nil {
valuemap = make(map[interface{}]Value)
}
var key interface{}
if isstruct {
key = kv.Key.(*ast.Ident).Name
} else {
key = c.VisitExpr(kv.Key)
}
valuemap[key] = value
} else {
value = c.VisitExpr(elt)
valuelist = append(valuelist, value)
}
}
}
// For array/slice types, convert key:value to contiguous
// values initialiser.
switch types.Underlying(typ).(type) {
case *types.Array, *types.Slice:
if len(valuemap) > 0 {
maxi := int64(-1)
for key, _ := range valuemap {
i := key.(ConstValue).Int64()
if i < 0 {
panic("array index must be non-negative integer constant")
} else if i > maxi {
maxi = i
}
}
valuelist = make([]Value, maxi+1)
for key, value := range valuemap {
i := key.(ConstValue).Int64()
valuelist[i] = value
}
}
}
origtyp := typ
switch typ := types.Underlying(typ).(type) {
case *types.Array:
typ.Len = uint64(len(valuelist))
elttype := typ.Elt
llvm_values := make([]llvm.Value, typ.Len)
for i, value := range valuelist {
if value == nil {
llvm_values[i] = llvm.ConstNull(c.types.ToLLVM(elttype))
} else {
llvm_values[i] = value.Convert(elttype).LLVMValue()
}
}
// TODO set non-const values after creating const array.
return c.NewLLVMValue(
llvm.ConstArray(c.types.ToLLVM(elttype), llvm_values), origtyp)
case *types.Slice:
ptr := c.builder.CreateMalloc(c.types.ToLLVM(typ), "")
length := llvm.ConstInt(llvm.Int32Type(), uint64(len(valuelist)), false)
valuesPtr := c.builder.CreateArrayMalloc(c.types.ToLLVM(typ.Elt), length, "")
//valuesPtr = c.builder.CreateBitCast(valuesPtr, llvm.PointerType(valuesPtr.Type(), 0), "")
// TODO check result of mallocs
c.builder.CreateStore(valuesPtr, c.builder.CreateStructGEP(ptr, 0, "")) // data
c.builder.CreateStore(length, c.builder.CreateStructGEP(ptr, 1, "")) // len
c.builder.CreateStore(length, c.builder.CreateStructGEP(ptr, 2, "")) // cap
null := llvm.ConstNull(c.types.ToLLVM(typ.Elt))
for i, value := range valuelist {
index := llvm.ConstInt(llvm.Int32Type(), uint64(i), false)
valuePtr := c.builder.CreateGEP(valuesPtr, []llvm.Value{index}, "")
if value == nil {
c.builder.CreateStore(null, valuePtr)
} else {
c.builder.CreateStore(value.Convert(typ.Elt).LLVMValue(), valuePtr)
}
}
m := c.NewLLVMValue(ptr, &types.Pointer{Base: origtyp})
return m.makePointee()
case *types.Struct:
values := valuelist
struct_value := c.builder.CreateMalloc(c.types.ToLLVM(typ), "")
if valuemap != nil {
for key, value := range valuemap {
fieldName := key.(string)
index := typ.FieldIndices[fieldName]
for len(values) <= int(index) {
values = append(values, nil)
}
values[index] = value
}
//.........這裏部分代碼省略.........
示例10: Compile
//.........這裏部分代碼省略.........
}
compiler.pkg = pkg
importpath = pkgpath(pkg)
// Create a Module, which contains the LLVM bitcode. Dispose it on panic,
// otherwise we'll set a finalizer at the end. The caller may invoke
// Dispose manually, which will render the finalizer a no-op.
modulename := importpath
compiler.module = &Module{llvm.NewModule(modulename), modulename, false}
compiler.module.SetTarget(compiler.TargetTriple)
compiler.module.SetDataLayout(compiler.target.String())
defer func() {
if e := recover(); e != nil {
compiler.module.Dispose()
panic(e)
}
}()
// Create a struct responsible for mapping static types to LLVM types,
// and to runtime/dynamic type values.
var resolver Resolver = compiler
compiler.FunctionCache = NewFunctionCache(compiler)
compiler.types = NewTypeMap(compiler.llvmtypes, compiler.module.Module, importpath, exprtypes, compiler.FunctionCache, resolver)
// Create a Builder, for building LLVM instructions.
compiler.builder = newBuilder(compiler.types)
defer compiler.builder.Dispose()
// Compile each file in the package.
for _, file := range files {
for _, decl := range file.Decls {
compiler.VisitDecl(decl)
}
}
// Define intrinsics for use by the runtime: malloc, free, memcpy, etc.
// These could be defined in LLVM IR, and may be moved there later.
if importpath == "runtime" {
compiler.defineRuntimeIntrinsics()
}
// Export runtime type information.
if importpath == "runtime" {
compiler.exportBuiltinRuntimeTypes()
}
// Wrap "main.main" in a call to runtime.main.
if importpath == "main" {
err = compiler.createMainFunction()
if err != nil {
return nil, err
}
}
// Create global constructors. The initfuncs/varinitfuncs
// slices are in the order of visitation; we generate the
// list of constructors in the reverse order.
//
// The llgo linker will link modules in the order of
// package dependency, i.e. if A requires B, then llgo-link
// will link the modules in the order A, B. The "runtime"
// package is always last.
//
// At program initialisation, the runtime initialisation
// function (runtime.main) will invoke the constructors
// in reverse order.
var initfuncs [][]llvm.Value
if compiler.varinitfuncs != nil {
initfuncs = append(initfuncs, compiler.varinitfuncs)
}
if compiler.initfuncs != nil {
initfuncs = append(initfuncs, compiler.initfuncs)
}
if initfuncs != nil {
ctortype := llvm.PointerType(llvm.Int8Type(), 0)
var ctors []llvm.Value
var index int = 0
for _, initfuncs := range initfuncs {
for _, fnptr := range initfuncs {
name := fmt.Sprintf("__llgo.ctor.%s.%d", importpath, index)
fnptr.SetName(name)
fnptr = llvm.ConstBitCast(fnptr, ctortype)
ctors = append(ctors, fnptr)
index++
}
}
for i, n := 0, len(ctors); i < n/2; i++ {
ctors[i], ctors[n-i-1] = ctors[n-i-1], ctors[i]
}
ctorsInit := llvm.ConstArray(ctortype, ctors)
ctorsVar := llvm.AddGlobal(compiler.module.Module, ctorsInit.Type(), "runtime.ctors")
ctorsVar.SetInitializer(ctorsInit)
ctorsVar.SetLinkage(llvm.AppendingLinkage)
}
// Create debug metadata.
//compiler.createMetadata()
return compiler.module, nil
}
示例11: 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 {
//.........這裏部分代碼省略.........
示例12: Compile
func (compiler *compiler) Compile(fset *token.FileSet,
pkg *ast.Package, importpath string,
exprTypes map[ast.Expr]types.Type) (m *Module, err error) {
// FIXME I'd prefer if we didn't modify global state. Perhaps
// we should always take a copy of types.Universe?
defer func() {
types.Universe.Lookup("true").Data = types.Const{true}
types.Universe.Lookup("false").Data = types.Const{false}
}()
// FIXME create a compilation state, rather than storing in 'compiler'.
compiler.fileset = fset
compiler.pkg = pkg
compiler.importpath = importpath
compiler.initfuncs = nil
compiler.varinitfuncs = nil
// Create a Builder, for building LLVM instructions.
compiler.builder = llvm.GlobalContext().NewBuilder()
defer compiler.builder.Dispose()
// Create a Module, which contains the LLVM bitcode. Dispose it on panic,
// otherwise we'll set a finalizer at the end. The caller may invoke
// Dispose manually, which will render the finalizer a no-op.
modulename := pkg.Name
compiler.module = &Module{llvm.NewModule(modulename), modulename, false}
compiler.module.SetTarget(compiler.TargetTriple)
compiler.module.SetDataLayout(compiler.target.String())
defer func() {
if e := recover(); e != nil {
compiler.module.Dispose()
panic(e)
//err = e.(error)
}
}()
// Create a mapping from objects back to packages, so we can create the
// appropriate symbol names.
compiler.pkgmap = createPackageMap(pkg, importpath)
// Create a struct responsible for mapping static types to LLVM types,
// and to runtime/dynamic type values.
var resolver Resolver = compiler
compiler.FunctionCache = NewFunctionCache(compiler)
compiler.types = NewTypeMap(compiler.llvmtypes, compiler.module.Module, importpath, exprTypes, compiler.FunctionCache, resolver)
// Compile each file in the package.
for _, file := range pkg.Files {
file.Scope.Outer = pkg.Scope
compiler.filescope = file.Scope
compiler.scope = file.Scope
compiler.fixConstDecls(file)
for _, decl := range file.Decls {
compiler.VisitDecl(decl)
}
}
// Define intrinsics for use by the runtime: malloc, free, memcpy, etc.
// These could be defined in LLVM IR, and may be moved there later.
if pkg.Name == "runtime" {
compiler.defineRuntimeIntrinsics()
}
// Export runtime type information.
if pkg.Name == "runtime" {
compiler.exportBuiltinRuntimeTypes()
}
// Create global constructors. The initfuncs/varinitfuncs
// slices are in the order of visitation, and that is how
// their priorities are assigned.
//
// The llgo linker (llgo-link) is responsible for reordering
// global constructors according to package dependency order.
var initfuncs [][]Value
if compiler.varinitfuncs != nil {
initfuncs = append(initfuncs, compiler.varinitfuncs)
}
if compiler.initfuncs != nil {
initfuncs = append(initfuncs, compiler.initfuncs)
}
if initfuncs != nil {
elttypes := []llvm.Type{llvm.Int32Type(), llvm.PointerType(llvm.FunctionType(llvm.VoidType(), nil, false), 0)}
ctortype := llvm.StructType(elttypes, false)
var ctors []llvm.Value
var priority uint64 = 1
for _, initfuncs := range initfuncs {
for _, fn := range initfuncs {
priorityval := llvm.ConstInt(llvm.Int32Type(), uint64(priority), false)
struct_values := []llvm.Value{priorityval, fn.LLVMValue()}
ctors = append(ctors, llvm.ConstStruct(struct_values, false))
priority++
}
}
global_ctors_init := llvm.ConstArray(ctortype, ctors)
global_ctors_var := llvm.AddGlobal(compiler.module.Module, global_ctors_init.Type(), "llvm.global_ctors")
global_ctors_var.SetInitializer(global_ctors_init)
global_ctors_var.SetLinkage(llvm.AppendingLinkage)
}
//.........這裏部分代碼省略.........
示例13: Compile
//.........這裏部分代碼省略.........
machine = target.CreateTargetMachine(triple, "", "",
llvm.CodeGenLevelDefault,
llvm.RelocDefault,
llvm.CodeModelDefault)
defer machine.Dispose()
}
}
if machine.C == nil {
err = fmt.Errorf("Invalid target triple: %s", triple)
return
}
// Create a Module, which contains the LLVM bitcode. Dispose it on panic,
// otherwise we'll set a finalizer at the end. The caller may invoke
// Dispose manually, which will render the finalizer a no-op.
modulename := pkg.Name
compiler.target = machine.TargetData()
compiler.module = &Module{llvm.NewModule(modulename), modulename, false}
compiler.module.SetTarget(triple)
compiler.module.SetDataLayout(compiler.target.String())
defer func() {
if e := recover(); e != nil {
compiler.module.Dispose()
panic(e)
//err = e.(error)
}
}()
// Create a mapping from objects back to packages, so we can create the
// appropriate symbol names.
compiler.pkgmap = createPackageMap(pkg, importpath)
// Create a struct responsible for mapping static types to LLVM types,
// and to runtime/dynamic type values.
var resolver Resolver = compiler
llvmtypemap := NewLLVMTypeMap(compiler.module.Module, compiler.target)
compiler.FunctionCache = NewFunctionCache(compiler)
compiler.types = NewTypeMap(llvmtypemap, importpath, exprTypes, compiler.FunctionCache, compiler.pkgmap, resolver)
// Compile each file in the package.
for _, file := range pkg.Files {
file.Scope.Outer = pkg.Scope
compiler.filescope = file.Scope
compiler.scope = file.Scope
compiler.fixConstDecls(file)
for _, decl := range file.Decls {
compiler.VisitDecl(decl)
}
}
// Define intrinsics for use by the runtime: malloc, free, memcpy, etc.
// These could be defined in LLVM IR, and may be moved there later.
if pkg.Name == "runtime" {
compiler.defineRuntimeIntrinsics()
}
// Export runtime type information.
if pkg.Name == "runtime" {
compiler.exportBuiltinRuntimeTypes()
}
// Create global constructors.
//
// XXX When imports are handled, we'll need to defer creating
// llvm.global_ctors until we create an executable. This is
// due to (a) imports having to be initialised before the
// importer, and (b) LLVM having no specified order of
// initialisation for ctors with the same priority.
var initfuncs [][]Value
if compiler.varinitfuncs != nil {
initfuncs = append(initfuncs, compiler.varinitfuncs)
}
if compiler.initfuncs != nil {
initfuncs = append(initfuncs, compiler.initfuncs)
}
if initfuncs != nil {
elttypes := []llvm.Type{llvm.Int32Type(), llvm.PointerType(llvm.FunctionType(llvm.VoidType(), nil, false), 0)}
ctortype := llvm.StructType(elttypes, false)
var ctors []llvm.Value
var priority uint64
for _, initfuncs := range initfuncs {
for _, fn := range initfuncs {
priorityval := llvm.ConstInt(llvm.Int32Type(), uint64(priority), false)
struct_values := []llvm.Value{priorityval, fn.LLVMValue()}
ctors = append(ctors, llvm.ConstStruct(struct_values, false))
priority++
}
}
global_ctors_init := llvm.ConstArray(ctortype, ctors)
global_ctors_var := llvm.AddGlobal(compiler.module.Module, global_ctors_init.Type(), "llvm.global_ctors")
global_ctors_var.SetInitializer(global_ctors_init)
global_ctors_var.SetLinkage(llvm.AppendingLinkage)
}
// Create debug metadata.
//compiler.createMetadata()
return compiler.module, nil
}
示例14: 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
}