[dev.ssa] cmd/compile: implement OCALLMETH
This mimics the way the old backend
compiles OCALLMETH.
Change-Id: I635c8e7a48c8b5619bd837f78fa6eeba83a57b2f
Reviewed-on: https://go-review.googlesource.com/12549
Reviewed-by: Keith Randall <khr@golang.org>
diff --git a/src/cmd/compile/internal/gc/ssa.go b/src/cmd/compile/internal/gc/ssa.go
index 32d42d8..4de0518 100644
--- a/src/cmd/compile/internal/gc/ssa.go
+++ b/src/cmd/compile/internal/gc/ssa.go
@@ -940,13 +940,30 @@
return s.constInt(s.config.Int, n.Left.Type.Bound)
}
- case OCALLFUNC:
- static := n.Left.Op == ONAME && n.Left.Class == PFUNC
+ case OCALLFUNC, OCALLMETH:
+ left := n.Left
+ static := left.Op == ONAME && left.Class == PFUNC
+
+ if n.Op == OCALLMETH {
+ // Rewrite to an OCALLFUNC: (p.f)(...) becomes (f)(p, ...)
+ // Take care not to modify the original AST.
+ if left.Op != ODOTMETH {
+ Fatal("OCALLMETH: n.Left not an ODOTMETH: %v", left)
+ }
+
+ newLeft := *left.Right
+ newLeft.Type = left.Type
+ if newLeft.Op == ONAME {
+ newLeft.Class = PFUNC
+ }
+ left = &newLeft
+ static = true
+ }
// evaluate closure
var closure *ssa.Value
if !static {
- closure = s.expr(n.Left)
+ closure = s.expr(left)
}
// run all argument assignments
@@ -955,13 +972,13 @@
bNext := s.f.NewBlock(ssa.BlockPlain)
var call *ssa.Value
if static {
- call = s.newValue1A(ssa.OpStaticCall, ssa.TypeMem, n.Left.Sym, s.mem())
+ call = s.newValue1A(ssa.OpStaticCall, ssa.TypeMem, left.Sym, s.mem())
} else {
entry := s.newValue2(ssa.OpLoad, s.config.Uintptr, closure, s.mem())
call = s.newValue3(ssa.OpClosureCall, ssa.TypeMem, entry, closure, s.mem())
}
- dowidth(n.Left.Type)
- call.AuxInt = n.Left.Type.Argwid // call operations carry the argsize of the callee along with them
+ dowidth(left.Type)
+ call.AuxInt = left.Type.Argwid // call operations carry the argsize of the callee along with them
b := s.endBlock()
b.Kind = ssa.BlockCall
b.Control = call
@@ -971,7 +988,7 @@
// read result from stack at the start of the fallthrough block
s.startBlock(bNext)
var titer Iter
- fp := Structfirst(&titer, Getoutarg(n.Left.Type))
+ fp := Structfirst(&titer, Getoutarg(left.Type))
if fp == nil {
// CALLFUNC has no return value. Continue with the next statement.
return nil