// Copyright 2021 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package escape import ( "cmd/compile/internal/base" "cmd/compile/internal/ir" "cmd/compile/internal/typecheck" "cmd/compile/internal/types" ) // TODO(mdempsky): Desugaring doesn't belong during escape analysis, // but for now it's the most convenient place for some rewrites. // fixRecoverCall rewrites an ORECOVER call into ORECOVERFP, // adding an explicit frame pointer argument. // If call is not an ORECOVER call, it's left unmodified. func fixRecoverCall(call *ir.CallExpr) { if call.Op() != ir.ORECOVER { return } pos := call.Pos() // FP is equal to caller's SP plus FixedFrameSize(). var fp ir.Node = ir.NewCallExpr(pos, ir.OGETCALLERSP, nil, nil) if off := base.Ctxt.FixedFrameSize(); off != 0 { fp = ir.NewBinaryExpr(fp.Pos(), ir.OADD, fp, ir.NewInt(off)) } // TODO(mdempsky): Replace *int32 with unsafe.Pointer, without upsetting checkptr. fp = ir.NewConvExpr(pos, ir.OCONVNOP, types.NewPtr(types.Types[types.TINT32]), fp) call.SetOp(ir.ORECOVERFP) call.Args = []ir.Node{typecheck.Expr(fp)} }