Skip to content

Commit

Permalink
LRValue.Indirect for following pointer values.
Browse files Browse the repository at this point in the history
  • Loading branch information
markkurossi committed Jul 25, 2024
1 parent 18ee174 commit 78c7323
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 13 deletions.
34 changes: 33 additions & 1 deletion compiler/ast/lrvalue.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,38 @@ func (lrv *LRValue) BasePtrInfo() *ssa.PtrInfo {
return lrv.baseInfo
}

// Indirect returns LRValue for the value that lrv points to. If lrv
// is not a pointer, Indirect returns lrv.
func (lrv *LRValue) Indirect() *LRValue {
v := lrv.RValue()
if v.Type.Type != types.TPtr {
return lrv
}

ret := *lrv
ret.valueType = *lrv.valueType.ElementType
ret.value.PtrInfo = nil

if lrv.baseInfo.ContainerType.Type == types.TStruct {
ret.value.Type = types.Undefined

// Lookup struct field.
ret.structField = nil
for _, f := range lrv.baseValue.Type.Struct {
if f.Type.Offset == lrv.baseInfo.Offset {
ret.structField = &f
}
}
if ret.structField == nil {
panic("LRValue.Indirect: could not find struct field")
}
} else {
ret.value.Type = *lrv.value.Type.ElementType
}

return &ret
}

// Set sets the l-value to rv.
func (lrv LRValue) Set(rv ssa.Value) error {
if !ssa.CanAssign(lrv.valueType, rv) {
Expand Down Expand Up @@ -123,7 +155,7 @@ func (lrv LRValue) Set(rv ssa.Value) error {
// The l-value and r-value types are now resolved. Let's define
// the variable with correct type and value information,
// overriding any old values.
lrv.block.Bindings.Define(lValue, &rv)
lrv.baseInfo.Bindings.Define(lValue, &rv)

return nil
}
Expand Down
15 changes: 6 additions & 9 deletions compiler/ast/ssagen.go
Original file line number Diff line number Diff line change
Expand Up @@ -1833,7 +1833,7 @@ func (ast *Slice) SSA(block *ssa.Block, ctx *Codegen, gen *ssa.Generator) (
return nil, nil, ctx.Errorf(ast, "invalid expression")
}
expr := exprs[0]
elementType := expr.Deref()
elementType := expr.IndirectType()
if !elementType.Type.Array() {
return nil, nil, ctx.Errorf(ast, "invalid operation: cannot slice %v",
expr.Type.Type)
Expand Down Expand Up @@ -2182,6 +2182,7 @@ func (ast *Copy) SSA(block *ssa.Block, ctx *Codegen, gen *ssa.Generator) (
if err != nil {
return nil, nil, ctx.Error(ast.Dst, err.Error())
}
lrv = lrv.Indirect()
dst = lrv.RValue()
if !dst.Type.Type.Array() {
return nil, nil, ast.errf(ctx, ast.Dst, "got %v", dst.Type)
Expand All @@ -2200,6 +2201,7 @@ func (ast *Copy) SSA(block *ssa.Block, ctx *Codegen, gen *ssa.Generator) (
if err != nil {
return nil, nil, ctx.Error(ast.Dst, err.Error())
}
lrv = lrv.Indirect()
dst = lrv.RValue()
if !dst.Type.Type.Array() {
return nil, nil, ast.errf(ctx, ast.Dst, "got %v", dst.Type)
Expand All @@ -2225,12 +2227,7 @@ func (ast *Copy) SSA(block *ssa.Block, ctx *Codegen, gen *ssa.Generator) (
return nil, nil, ast.errf(ctx, ast.Src, "got multivalue %T", ast.Src)
}
src := v[0]
var srcType types.Info
if src.Type.Type == types.TPtr {
srcType = *src.Type.ElementType
} else {
srcType = src.Type
}
srcType := src.IndirectType()
if !srcType.Type.Array() {
return nil, nil, ast.errf(ctx, ast.Src, "got %v", src.Type)
}
Expand Down Expand Up @@ -2262,7 +2259,7 @@ func (ast *Copy) SSA(block *ssa.Block, ctx *Codegen, gen *ssa.Generator) (
block.AddInstr(ssa.NewSliceInstr(src, fromConst, toConst, tmp))
err := lrv.Set(tmp)
if err != nil {
return nil, nil, err
return nil, nil, ctx.Error(ast, err.Error())
}
} else {
// Src overwrites part of dst.
Expand All @@ -2285,7 +2282,7 @@ func (ast *Copy) SSA(block *ssa.Block, ctx *Codegen, gen *ssa.Generator) (

err := lrv.Set(tmp2)
if err != nil {
return nil, nil, err
return nil, nil, ctx.Error(ast, err.Error())
}
}

Expand Down
6 changes: 3 additions & 3 deletions compiler/ssa/value.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,9 @@ func (v Value) Check() {
}
}

// Deref returns the pointer element type of the value. For
// non-pointer values, this returns the value type itself.
func (v Value) Deref() types.Info {
// IndirectType returns the type that v points to. If v is not a
// pointer, IndirectType returns the type of v.
func (v Value) IndirectType() types.Info {
if v.Type.Type == types.TPtr {
return *v.Type.ElementType
}
Expand Down

0 comments on commit 78c7323

Please sign in to comment.