73 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			73 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Go
		
	
	
	
| //===- errors.go - IR generation for run-time panics ----------------------===//
 | |
| //
 | |
| //                     The LLVM Compiler Infrastructure
 | |
| //
 | |
| // This file is distributed under the University of Illinois Open Source
 | |
| // License. See LICENSE.TXT for details.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| //
 | |
| // This file implements IR generation for triggering run-time panics.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| package irgen
 | |
| 
 | |
| import (
 | |
| 	"llvm.org/llvm/bindings/go/llvm"
 | |
| )
 | |
| 
 | |
| const (
 | |
| 	// From go-runtime-error.c
 | |
| 	gccgoRuntimeErrorSLICE_INDEX_OUT_OF_BOUNDS  = 0
 | |
| 	gccgoRuntimeErrorARRAY_INDEX_OUT_OF_BOUNDS  = 1
 | |
| 	gccgoRuntimeErrorSTRING_INDEX_OUT_OF_BOUNDS = 2
 | |
| 	gccgoRuntimeErrorSLICE_SLICE_OUT_OF_BOUNDS  = 3
 | |
| 	gccgoRuntimeErrorARRAY_SLICE_OUT_OF_BOUNDS  = 4
 | |
| 	gccgoRuntimeErrorSTRING_SLICE_OUT_OF_BOUNDS = 5
 | |
| 	gccgoRuntimeErrorNIL_DEREFERENCE            = 6
 | |
| 	gccgoRuntimeErrorMAKE_SLICE_OUT_OF_BOUNDS   = 7
 | |
| 	gccgoRuntimeErrorMAKE_MAP_OUT_OF_BOUNDS     = 8
 | |
| 	gccgoRuntimeErrorMAKE_CHAN_OUT_OF_BOUNDS    = 9
 | |
| 	gccgoRuntimeErrorDIVISION_BY_ZERO           = 10
 | |
| 	gccgoRuntimeErrorCount                      = 11
 | |
| )
 | |
| 
 | |
| func (fr *frame) setBranchWeightMetadata(br llvm.Value, trueweight, falseweight uint64) {
 | |
| 	mdprof := llvm.MDKindID("prof")
 | |
| 
 | |
| 	mdnode := llvm.GlobalContext().MDNode([]llvm.Metadata{
 | |
| 		llvm.GlobalContext().MDString("branch_weights"),
 | |
| 		llvm.ConstInt(llvm.Int32Type(), trueweight, false).ConstantAsMetadata(),
 | |
| 		llvm.ConstInt(llvm.Int32Type(), falseweight, false).ConstantAsMetadata(),
 | |
| 	})
 | |
| 
 | |
| 	br.SetMetadata(mdprof, mdnode)
 | |
| }
 | |
| 
 | |
| func (fr *frame) condBrRuntimeError(cond llvm.Value, errcode uint64) {
 | |
| 	if cond.IsNull() {
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	errorbb := fr.runtimeErrorBlocks[errcode]
 | |
| 	newbb := errorbb.C == nil
 | |
| 	if newbb {
 | |
| 		errorbb = llvm.AddBasicBlock(fr.function, "")
 | |
| 		fr.runtimeErrorBlocks[errcode] = errorbb
 | |
| 	}
 | |
| 
 | |
| 	contbb := llvm.AddBasicBlock(fr.function, "")
 | |
| 
 | |
| 	br := fr.builder.CreateCondBr(cond, errorbb, contbb)
 | |
| 	fr.setBranchWeightMetadata(br, 1, 1000)
 | |
| 
 | |
| 	if newbb {
 | |
| 		fr.builder.SetInsertPointAtEnd(errorbb)
 | |
| 		fr.runtime.runtimeError.call(fr, llvm.ConstInt(llvm.Int32Type(), errcode, false))
 | |
| 		fr.builder.CreateUnreachable()
 | |
| 	}
 | |
| 
 | |
| 	fr.builder.SetInsertPointAtEnd(contbb)
 | |
| }
 |