forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			37 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			37 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			Go
		
	
	
	
//===- closures.go - IR generation for closures ---------------------------===//
 | 
						|
//
 | 
						|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 | 
						|
// See https://llvm.org/LICENSE.txt for license information.
 | 
						|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 | 
						|
//
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
//
 | 
						|
// This file implements IR generation for closures.
 | 
						|
//
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
 | 
						|
package irgen
 | 
						|
 | 
						|
import (
 | 
						|
	"llvm.org/llgo/third_party/gotools/go/types"
 | 
						|
)
 | 
						|
 | 
						|
// makeClosure creates a closure from a function pointer and
 | 
						|
// a set of bindings. The bindings are addresses of captured
 | 
						|
// variables.
 | 
						|
func (fr *frame) makeClosure(fn *govalue, bindings []*govalue) *govalue {
 | 
						|
	govalues := append([]*govalue{fn}, bindings...)
 | 
						|
	fields := make([]*types.Var, len(govalues))
 | 
						|
	for i, v := range govalues {
 | 
						|
		field := types.NewField(0, nil, "_", v.Type(), false)
 | 
						|
		fields[i] = field
 | 
						|
	}
 | 
						|
	block := fr.createTypeMalloc(types.NewStruct(fields, nil))
 | 
						|
	for i, v := range govalues {
 | 
						|
		addressPtr := fr.builder.CreateStructGEP(block, i, "")
 | 
						|
		fr.builder.CreateStore(v.value, addressPtr)
 | 
						|
	}
 | 
						|
	closure := fr.builder.CreateBitCast(block, fn.value.Type(), "")
 | 
						|
	return newValue(closure, fn.Type())
 | 
						|
}
 |