github.com/axw/llgo@v0.0.0-20160805011314-95b5fe4dca20/irgen/closures.go (about)

     1  //===- closures.go - IR generation for closures ---------------------------===//
     2  //
     3  //                     The LLVM Compiler Infrastructure
     4  //
     5  // This file is distributed under the University of Illinois Open Source
     6  // License. See LICENSE.TXT for details.
     7  //
     8  //===----------------------------------------------------------------------===//
     9  //
    10  // This file implements IR generation for closures.
    11  //
    12  //===----------------------------------------------------------------------===//
    13  
    14  package irgen
    15  
    16  import (
    17  	"llvm.org/llgo/third_party/gotools/go/types"
    18  )
    19  
    20  // makeClosure creates a closure from a function pointer and
    21  // a set of bindings. The bindings are addresses of captured
    22  // variables.
    23  func (fr *frame) makeClosure(fn *govalue, bindings []*govalue) *govalue {
    24  	govalues := append([]*govalue{fn}, bindings...)
    25  	fields := make([]*types.Var, len(govalues))
    26  	for i, v := range govalues {
    27  		field := types.NewField(0, nil, "_", v.Type(), false)
    28  		fields[i] = field
    29  	}
    30  	block := fr.createTypeMalloc(types.NewStruct(fields, nil))
    31  	for i, v := range govalues {
    32  		addressPtr := fr.builder.CreateStructGEP(block, i, "")
    33  		fr.builder.CreateStore(v.value, addressPtr)
    34  	}
    35  	closure := fr.builder.CreateBitCast(block, fn.value.Type(), "")
    36  	return newValue(closure, fn.Type())
    37  }