github.com/llvm-mirror/llgo@v0.0.0-20190322182713-bf6f0a60fce1/irgen/closures.go (about)

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