github.com/axw/llgo@v0.0.0-20160805011314-95b5fe4dca20/irgen/errors.go (about) 1 //===- errors.go - IR generation for run-time panics ----------------------===// 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 triggering run-time panics. 11 // 12 //===----------------------------------------------------------------------===// 13 14 package irgen 15 16 import ( 17 "llvm.org/llvm/bindings/go/llvm" 18 ) 19 20 const ( 21 // From go-runtime-error.c 22 gccgoRuntimeErrorSLICE_INDEX_OUT_OF_BOUNDS = 0 23 gccgoRuntimeErrorARRAY_INDEX_OUT_OF_BOUNDS = 1 24 gccgoRuntimeErrorSTRING_INDEX_OUT_OF_BOUNDS = 2 25 gccgoRuntimeErrorSLICE_SLICE_OUT_OF_BOUNDS = 3 26 gccgoRuntimeErrorARRAY_SLICE_OUT_OF_BOUNDS = 4 27 gccgoRuntimeErrorSTRING_SLICE_OUT_OF_BOUNDS = 5 28 gccgoRuntimeErrorNIL_DEREFERENCE = 6 29 gccgoRuntimeErrorMAKE_SLICE_OUT_OF_BOUNDS = 7 30 gccgoRuntimeErrorMAKE_MAP_OUT_OF_BOUNDS = 8 31 gccgoRuntimeErrorMAKE_CHAN_OUT_OF_BOUNDS = 9 32 gccgoRuntimeErrorDIVISION_BY_ZERO = 10 33 gccgoRuntimeErrorCount = 11 34 ) 35 36 func (fr *frame) setBranchWeightMetadata(br llvm.Value, trueweight, falseweight uint64) { 37 mdprof := llvm.MDKindID("prof") 38 39 mdnode := llvm.GlobalContext().MDNode([]llvm.Metadata{ 40 llvm.GlobalContext().MDString("branch_weights"), 41 llvm.ConstInt(llvm.Int32Type(), trueweight, false).ConstantAsMetadata(), 42 llvm.ConstInt(llvm.Int32Type(), falseweight, false).ConstantAsMetadata(), 43 }) 44 45 br.SetMetadata(mdprof, mdnode) 46 } 47 48 func (fr *frame) condBrRuntimeError(cond llvm.Value, errcode uint64) { 49 if cond.IsNull() { 50 return 51 } 52 53 errorbb := fr.runtimeErrorBlocks[errcode] 54 newbb := errorbb.C == nil 55 if newbb { 56 errorbb = llvm.AddBasicBlock(fr.function, "") 57 fr.runtimeErrorBlocks[errcode] = errorbb 58 } 59 60 contbb := llvm.AddBasicBlock(fr.function, "") 61 62 br := fr.builder.CreateCondBr(cond, errorbb, contbb) 63 fr.setBranchWeightMetadata(br, 1, 1000) 64 65 if newbb { 66 fr.builder.SetInsertPointAtEnd(errorbb) 67 fr.runtime.runtimeError.call(fr, llvm.ConstInt(llvm.Int32Type(), errcode, false)) 68 fr.builder.CreateUnreachable() 69 } 70 71 fr.builder.SetInsertPointAtEnd(contbb) 72 }