Skip to content

Commit fa0e9ab

Browse files
committed
object plain coding
objects are now encodable and decodable. But the interface changed. The Object interface is a plain.Encoder there is a function objects.PlainDecode(r io.Reader) (Object, error) for decoding (in order to dispatch the respective object decoder after an object header. Inside, this uses the following pattern (note upper/lower case) type object struct {...} func (o *object) plainEncode(w io.Writer) error // called by full objects func (o *object) plainDecode(r io.Reader) error // // implements plain decode, but privately to the package. type hdr struct { *object } func (h hdr) PlainDecode(r io.Reader) error example concrete object: type Array struct { object .... } func (a *Array) PlainEncode(w io.Writer) error // implements plain.Encoder // implements plain decoding, but only after the header. func (a *Array) plainDecode(r io.Reader) error
1 parent 5d9b2d7 commit fa0e9ab

File tree

19 files changed

+307
-193
lines changed

19 files changed

+307
-193
lines changed

memory/model.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ func NewModel(index indexing.T) *Model {
5252
z.class = Zero
5353
z.parent = zz
5454
z.root = zz
55-
z.obj = z
56-
res.AddPointsTo(z, z)
55+
z.obj = zz
56+
res.AddAddressOf(zz, zz)
5757
return res
5858
}
5959

objects/array.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919

2020
"github.com/go-air/pal/internal/plain"
2121
"github.com/go-air/pal/memory"
22+
"github.com/go-air/pal/typeset"
2223
)
2324

2425
type Array struct {
@@ -27,6 +28,10 @@ type Array struct {
2728
n int64
2829
}
2930

31+
func newArray(loc memory.Loc, ty typeset.Type) *Array {
32+
return &Array{object: object{kind: karray, loc: loc, typ: ty}}
33+
}
34+
3035
func (a *Array) Len() int64 {
3136
return a.n
3237
}
@@ -37,22 +42,17 @@ func (a *Array) At(i int) memory.Loc {
3742
}
3843

3944
func (a *Array) PlainEncode(w io.Writer) error {
40-
var err error
41-
err = plain.Put(w, "a ")
42-
if err != nil {
43-
return err
44-
}
45-
return plain.EncodeJoin(w, " ", &a.object, plain.Uint(a.elemSize), plain.Uint(a.n))
45+
return plain.EncodeJoin(w, " ", hdr{&a.object}, plain.Uint(a.elemSize), plain.Uint(a.n))
4646
}
4747

48-
func (a *Array) PlainDecode(r io.Reader) error {
48+
func (a *Array) plainDecode(r io.Reader) error {
4949
var err error
50-
err = plain.Expect(r, "a ")
50+
err = plain.Expect(r, " ")
5151
if err != nil {
5252
return err
5353
}
5454
esz, n := plain.Uint(a.elemSize), plain.Uint(a.n)
55-
err = plain.DecodeJoin(r, " ", &a.object, &esz, &n)
55+
err = plain.DecodeJoin(r, " ", &esz, &n)
5656
if err != nil {
5757
return err
5858
}

objects/array_test.go

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,25 +16,21 @@ package objects
1616

1717
import (
1818
"testing"
19-
20-
"github.com/go-air/pal/internal/plain"
2119
)
2220

23-
func clobArray(c plain.Coder) {
24-
a := c.(*Array)
21+
func clobArray(o Object) {
22+
a := o.(*Array)
2523
a.loc = 0
2624
a.typ = 0
2725
a.n = 0
2826
a.elemSize = 0
2927
}
3028

3129
func TestArray(t *testing.T) {
32-
a := &Array{}
33-
a.loc = 3
34-
a.typ = 7
30+
a := newArray(3, 7)
3531
a.n = 17
3632
a.elemSize = 5
37-
if err := plain.TestRoundTripClobber(a, clobArray, false); err != nil {
33+
if err := testRoundTrip(a, clobArray, false); err != nil {
3834
t.Error(err)
3935
}
4036
}

objects/builder.go

Lines changed: 11 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -186,9 +186,10 @@ func (b *Builder) Pointer(gtype *types.Pointer) *Pointer {
186186
// which may or may not be declared. `declName` must be empty
187187
// iff the associated function is not declared.
188188
func (b *Builder) Func(sig *types.Signature, declName string, opaque memory.Attrs) *Func {
189-
fn := &Func{declName: declName}
190-
fn.typ = b.ts.FromGoType(sig)
191-
_, fn.loc = b.Type(fn.typ).WithPointer()
189+
typ := b.ts.FromGoType(sig)
190+
_, obj := b.Type(typ).WithPointer()
191+
fn := newFunc(obj, typ)
192+
fn.declName = declName
192193

193194
b.mmod.AddAddressOf(fn.loc, fn.loc)
194195

@@ -199,7 +200,6 @@ func (b *Builder) Func(sig *types.Signature, declName string, opaque memory.Attr
199200
b.Class(memory.Local) // for all params and returns
200201

201202
recv := sig.Recv()
202-
var obj memory.Loc
203203

204204
if recv != nil {
205205
b.mgp.Type(b.ts.FromGoType(recv.Type()))
@@ -273,19 +273,15 @@ func (b *Builder) walkObj(m memory.Loc) {
273273
switch ty {
274274
case typeset.Pointer:
275275
if b.omap[m] == nil {
276-
ptr := &Pointer{}
277-
ptr.loc = m
278-
ptr.typ = ty
276+
ptr := newPointer(m, ty)
279277
b.omap[m] = ptr
280278
}
281279
}
282280
case typeset.Array:
283281
var arr *Array
284282
obj := b.omap[m]
285283
if obj == nil {
286-
arr = &Array{}
287-
arr.loc = m
288-
arr.typ = ty
284+
arr = newArray(m, ty)
289285
arr.n = int64(b.ts.ArrayLen(ty))
290286
arr.elemSize = int64(b.ts.Lsize(b.ts.Elem(ty)))
291287
b.omap[m] = arr
@@ -302,9 +298,7 @@ func (b *Builder) walkObj(m memory.Loc) {
302298
var strukt *Struct
303299
obj := b.omap[m]
304300
if obj == nil {
305-
strukt = &Struct{}
306-
strukt.loc = m
307-
strukt.typ = ty
301+
strukt = newStruct(m, ty)
308302
b.omap[m] = strukt
309303
} else {
310304
strukt = obj.(*Struct)
@@ -322,9 +316,7 @@ func (b *Builder) walkObj(m memory.Loc) {
322316
var ch *Chan
323317
obj := b.omap[m]
324318
if obj == nil {
325-
ch = &Chan{}
326-
ch.loc = m
327-
ch.typ = ty
319+
ch = newChan(m, ty)
328320
ch.slot = b.Type(b.ts.Elem(ty)).Gen()
329321
b.mmod.AddAddressOf(ch.loc, ch.slot)
330322
b.omap[m] = ch
@@ -336,9 +328,7 @@ func (b *Builder) walkObj(m memory.Loc) {
336328
var ma *Map
337329
obj := b.omap[m]
338330
if obj == nil {
339-
ma = &Map{}
340-
ma.loc = m
341-
ma.typ = ty
331+
ma = newMap(m, ty)
342332
ma.key = b.Type(b.ts.Key(ty)).Gen()
343333
ma.elem = b.Type(b.ts.Elem(ty)).Gen()
344334
b.mmod.AddAddressOf(ma.loc, ma.key)
@@ -353,9 +343,7 @@ func (b *Builder) walkObj(m memory.Loc) {
353343
var slice *Slice
354344
obj := b.omap[m]
355345
if obj == nil {
356-
slice = &Slice{}
357-
slice.loc = m
358-
slice.typ = b.mmod.Type(m)
346+
slice = newSlice(m, ty)
359347
slice.Len = b.indexing.Zero()
360348
slice.Cap = b.indexing.Zero()
361349
b.AddAddressOf(slice.loc, b.mmod.Zero())
@@ -371,9 +359,7 @@ func (b *Builder) walkObj(m memory.Loc) {
371359
var tuple *Tuple
372360
obj := b.omap[m]
373361
if obj == nil {
374-
tuple = &Tuple{}
375-
tuple.loc = m
376-
tuple.typ = ty
362+
tuple = newTuple(m, ty)
377363
b.omap[m] = tuple
378364
} else {
379365
tuple = obj.(*Tuple)

objects/chan.go

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919

2020
"github.com/go-air/pal/internal/plain"
2121
"github.com/go-air/pal/memory"
22+
"github.com/go-air/pal/typeset"
2223
)
2324

2425
// Chan object
@@ -31,6 +32,10 @@ type Chan struct {
3132
slot memory.Loc
3233
}
3334

35+
func newChan(loc memory.Loc, ty typeset.Type) *Chan {
36+
return &Chan{object: object{kind: kchan, loc: loc, typ: ty}}
37+
}
38+
3439
// Recv retrieves the data from the c and loads
3540
// it into dst.
3641
func (c *Chan) Recv(dst memory.Loc, mm *memory.Model) {
@@ -45,27 +50,15 @@ func (c *Chan) Send(src memory.Loc, mm *memory.Model) {
4550
}
4651

4752
func (c *Chan) PlainEncode(w io.Writer) error {
48-
var err error
49-
err = plain.Put(w, "c ")
50-
if err != nil {
51-
return err
52-
}
53-
if err = c.object.PlainEncode(w); err != nil {
54-
return err
55-
}
56-
return c.slot.PlainEncode(w)
53+
return plain.EncodeJoin(w, " ", hdr{&c.object}, c.slot)
5754
}
5855

59-
func (c *Chan) PlainDecode(r io.Reader) error {
56+
func (c *Chan) plainDecode(r io.Reader) error {
6057
var err error
61-
err = plain.Expect(r, "c ")
58+
err = plain.Expect(r, " ")
6259
if err != nil {
6360
return err
6461
}
65-
p := &c.object
66-
if err = p.PlainDecode(r); err != nil {
67-
return err
68-
}
6962
ps := &c.slot
7063
return ps.PlainDecode(r)
7164
}

objects/func.go

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ type Func struct {
3434
variadic bool
3535
}
3636

37+
func newFunc(loc memory.Loc, typ typeset.Type) *Func {
38+
return &Func{object: object{kind: kfunc, loc: loc, typ: typ}}
39+
}
40+
3741
func (f *Func) Declared() bool {
3842
return f.declName != ""
3943
}
@@ -67,11 +71,8 @@ func (f *Func) NumResults() int {
6771
}
6872

6973
func (f *Func) PlainEncode(w io.Writer) error {
70-
err := plain.Put(w, "f ")
71-
if err != nil {
72-
return err
73-
}
74-
err = plain.EncodeJoin(w, " ", f.fnobj, f.recv, plain.Uint(len(f.params)))
74+
err := plain.EncodeJoin(w, " ", hdr{&f.object},
75+
f.fnobj, f.recv, plain.Uint(len(f.params)))
7576
if f.variadic {
7677
err = plain.Put(w, "*")
7778
} else {
@@ -112,8 +113,8 @@ func (f *Func) PlainEncode(w io.Writer) error {
112113
return nil
113114
}
114115

115-
func (f *Func) PlainDecode(r io.Reader) error {
116-
err := plain.Expect(r, "f ")
116+
func (f *Func) plainDecode(r io.Reader) error {
117+
err := plain.Expect(r, " ")
117118
if err != nil {
118119
return err
119120
}
@@ -133,7 +134,7 @@ func (f *Func) PlainDecode(r io.Reader) error {
133134
case '.':
134135
f.variadic = false
135136
default:
136-
return fmt.Errorf("unexpected '%c'", buf[0])
137+
return fmt.Errorf("unexpected modifier '%c'", buf[0])
137138
}
138139
f.params = make([]memory.Loc, n)
139140
for i := plain.Uint(0); i < n; i++ {
@@ -149,7 +150,7 @@ func (f *Func) PlainDecode(r io.Reader) error {
149150
}
150151
err = plain.Expect(r, " ")
151152
if err != nil {
152-
return err
153+
return fmt.Errorf("unexpected space 2: %w\n", err)
153154
}
154155
err = (&n).PlainDecode(r)
155156
if err != nil {

objects/func_test.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,11 @@ import (
2020
"testing"
2121

2222
"github.com/go-air/pal/indexing"
23-
"github.com/go-air/pal/internal/plain"
2423
"github.com/go-air/pal/memory"
2524
)
2625

27-
func clobber(c plain.Coder) {
28-
f := c.(*Func)
26+
func fclob(o Object) {
27+
f := o.(*Func)
2928
f.declName = ""
3029
f.fnobj = 0
3130
f.recv = 0
@@ -43,7 +42,7 @@ func TestFuncPlain(t *testing.T) {
4342
sig := types.NewSignature(nil, parms, ress, false)
4443
b := NewBuilder("pkg", indexing.ConstVals())
4544
f := b.Func(sig, "declName", memory.IsOpaque)
46-
err := plain.TestRoundTripClobber(f, clobber, true)
45+
err := testRoundTrip(f, fclob, true)
4746
if err != nil {
4847
t.Error(err)
4948
}

objects/interface.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,6 @@ func (i *Interface) PlainEncode(w io.Writer) error {
2929
return nil
3030
}
3131

32-
func (i *Interface) PlainDecode(r io.Reader) error {
32+
func (i *Interface) plainDecode(r io.Reader) error {
3333
return nil
3434
}

objects/map.go

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919

2020
"github.com/go-air/pal/internal/plain"
2121
"github.com/go-air/pal/memory"
22+
"github.com/go-air/pal/typeset"
2223
)
2324

2425
type Map struct {
@@ -27,6 +28,10 @@ type Map struct {
2728
elem memory.Loc
2829
}
2930

31+
func newMap(loc memory.Loc, typ typeset.Type) *Map {
32+
return &Map{object: object{kind: kmap, loc: loc, typ: typ}}
33+
}
34+
3035
func (m *Map) Key() memory.Loc {
3136
return m.key
3237
}
@@ -46,26 +51,12 @@ func (m *Map) Lookup(dst memory.Loc, mm *memory.Model) {
4651
}
4752

4853
func (m *Map) PlainEncode(w io.Writer) error {
49-
var err error
50-
err = plain.Put(w, "m")
51-
if err != nil {
52-
return err
53-
}
54-
err = m.object.PlainEncode(w)
55-
if err != nil {
56-
return err
57-
}
58-
return plain.EncodeJoin(w, " ", m.key, m.elem)
54+
return plain.EncodeJoin(w, " ", hdr{&m.object}, m.key, m.elem)
5955
}
6056

61-
func (m *Map) PlainDecode(r io.Reader) error {
57+
func (m *Map) plainDecode(r io.Reader) error {
6258
var err error
63-
err = plain.Expect(r, "m")
64-
if err != nil {
65-
return err
66-
}
67-
pobj := &m.object
68-
err = pobj.PlainDecode(r)
59+
err = plain.Expect(r, " ")
6960
if err != nil {
7061
return err
7162
}

0 commit comments

Comments
 (0)