1
0
mirror of https://github.com/golang/go synced 2024-11-23 06:30:06 -07:00

cmd/compile/internal/noder: explicitly handle separate selectors

This CL separates out the handling of selector expressions for field
values, method values, and method expressions. Again part of
refactoring to make it possible to access runtime dictionaries where
needed.

No behavioral change; just duplicating and then streamlining the
existing code paths.

Change-Id: I53b2a344f4bdba2c9f37ef370dc9a091a3941021
Reviewed-on: https://go-review.googlesource.com/c/go/+/421818
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Keith Randall <khr@google.com>
This commit is contained in:
Matthew Dempsky 2022-08-05 20:40:45 -07:00
parent 2e6ffd6c5d
commit 88635b3862
3 changed files with 51 additions and 29 deletions

View File

@ -43,7 +43,9 @@ const (
exprGlobal // global variable or function
exprCompLit
exprFuncLit
exprSelector
exprFieldVal
exprMethodVal
exprMethodExpr
exprIndex
exprSlice
exprAssert

View File

@ -1881,36 +1881,41 @@ func (r *reader) expr() (res ir.Node) {
case exprFuncLit:
return r.funcLit()
case exprSelector:
var x ir.Node
if r.Bool() { // MethodExpr
if r.Bool() {
return r.dict.methodExprs[r.Len()]
}
case exprFieldVal:
x := r.expr()
pos := r.pos()
_, sym := r.selector()
n := ir.TypeNode(r.typ())
n.SetTypecheck(1)
x = n
} else { // FieldVal, MethodVal
x = r.expr()
}
return typecheck.Expr(ir.NewSelectorExpr(pos, ir.OXDOT, x, sym)).(*ir.SelectorExpr)
case exprMethodVal:
x := r.expr()
pos := r.pos()
_, sym := r.selector()
n := typecheck.Expr(ir.NewSelectorExpr(pos, ir.OXDOT, x, sym)).(*ir.SelectorExpr)
if n.Op() == ir.OMETHVALUE {
wrapper := methodValueWrapper{
rcvr: n.X.Type(),
method: n.Selection,
}
if r.importedDef() {
haveMethodValueWrappers = append(haveMethodValueWrappers, wrapper)
} else {
needMethodValueWrappers = append(needMethodValueWrappers, wrapper)
}
wrapper := methodValueWrapper{
rcvr: n.X.Type(),
method: n.Selection,
}
if r.importedDef() {
haveMethodValueWrappers = append(haveMethodValueWrappers, wrapper)
} else {
needMethodValueWrappers = append(needMethodValueWrappers, wrapper)
}
return n
case exprMethodExpr:
if r.Bool() {
return r.dict.methodExprs[r.Len()]
}
typ := r.typ()
pos := r.pos()
_, sym := r.selector()
return typecheck.Expr(ir.NewSelectorExpr(pos, ir.OXDOT, ir.TypeNode(typ), sym)).(*ir.SelectorExpr)
case exprIndex:
x := r.expr()
pos := r.pos()

View File

@ -1585,8 +1585,25 @@ func (w *writer) expr(expr syntax.Expr) {
sel, ok := w.p.info.Selections[expr]
assert(ok)
w.Code(exprSelector)
if w.Bool(sel.Kind() == types2.MethodExpr) {
switch sel.Kind() {
default:
w.p.fatalf(expr, "unexpected selection kind: %v", sel.Kind())
case types2.FieldVal:
w.Code(exprFieldVal)
w.expr(expr.X)
w.pos(expr)
w.selector(sel.Obj())
case types2.MethodVal:
w.Code(exprMethodVal)
w.expr(expr.X)
w.pos(expr)
w.selector(sel.Obj())
case types2.MethodExpr:
w.Code(exprMethodExpr)
tv, ok := w.p.info.Types[expr.X]
assert(ok)
assert(tv.IsType())
@ -1600,11 +1617,9 @@ func (w *writer) expr(expr syntax.Expr) {
}
w.typInfo(typInfo)
} else {
w.expr(expr.X)
w.pos(expr)
w.selector(sel.Obj())
}
w.pos(expr)
w.selector(sel.Obj())
case *syntax.IndexExpr:
_ = w.p.typeOf(expr.Index) // ensure this is an index expression, not an instantiation