]> Cypherpunks repositories - gostls13.git/commitdiff
bug fix: encOpFor etc. need to indirect
authorRob Pike <r@golang.org>
Wed, 8 Jul 2009 04:05:24 +0000 (21:05 -0700)
committerRob Pike <r@golang.org>
Wed, 8 Jul 2009 04:05:24 +0000 (21:05 -0700)
R=rsc
DELTA=28  (7 added, 7 deleted, 14 changed)
OCL=31312
CL=31322

src/pkg/gob/decode.go
src/pkg/gob/encode.go

index b6d9d6fd168592364e59af76bf03d58208d4eb21..1b3e3104a80e50d680f84f83cf91f2f86ec12648 100644 (file)
@@ -388,7 +388,10 @@ var decOpMap = map[reflect.Type] decOp {
 
 func getDecEngine(rt reflect.Type) *decEngine
 
-func decOpFor(typ reflect.Type) decOp {
+// Return the decoding op for the base type under rt and
+// the indirection count to reach it.
+func decOpFor(rt reflect.Type) (decOp, int) {
+       typ, indir := indirect(rt);
        op, ok := decOpMap[reflect.Typeof(typ)];
        if !ok {
                // Special cases
@@ -398,15 +401,13 @@ func decOpFor(typ reflect.Type) decOp {
                                op = decUint8Array;
                                break;
                        }
-                       elemOp := decOpFor(t.Elem());
-                       _, elemIndir := indirect(t.Elem());
+                       elemOp, elemIndir := decOpFor(t.Elem());
                        op = func(i *decInstr, state *DecState, p unsafe.Pointer) {
                                state.err = decodeSlice(t, state, uintptr(p), elemOp, t.Elem().Size(), i.indir, elemIndir);
                        };
 
                case *reflect.ArrayType:
-                       elemOp := decOpFor(t.Elem());
-                       _, elemIndir := indirect(t.Elem());
+                       elemOp, elemIndir := decOpFor(t.Elem());
                        op = func(i *decInstr, state *DecState, p unsafe.Pointer) {
                                state.err = decodeArray(t, state, uintptr(p), elemOp, t.Elem().Size(), t.Len(), i.indir, elemIndir);
                        };
@@ -420,9 +421,9 @@ func decOpFor(typ reflect.Type) decOp {
                }
        }
        if op == nil {
-               panicln("decode can't handle type", typ.String());
+               panicln("decode can't handle type", rt.String());
        }
-       return op
+       return op, indir
 }
 
 func compileDec(rt reflect.Type, typ Type) *decEngine {
@@ -438,8 +439,7 @@ func compileDec(rt reflect.Type, typ Type) *decEngine {
                // TODO(r): verify compatibility with corresponding field of data.
                // For now, assume perfect correspondence between struct and gob.
                f := srt.Field(fieldnum);
-               ftyp, indir := indirect(f.Type);
-               op := decOpFor(ftyp);
+               op, indir := decOpFor(f.Type);
                engine.instr[fieldnum] = decInstr{op, fieldnum, indir, uintptr(f.Offset)};
        }
        return engine;
index 484d623dec325bfb014f9e2698a910720d17ed51..f32180c3a97064e666c70a8ec6e1118353ac35d4 100644 (file)
@@ -268,7 +268,6 @@ func encodeStruct(engine *encEngine, w io.Writer, basep uintptr) os.Error {
                p := unsafe.Pointer(basep+instr.offset);
                if instr.indir > 0 {
                        if p = encIndirect(p, instr.indir); p == nil {
-                               state.fieldnum = i;
                                continue
                        }
                }
@@ -321,9 +320,13 @@ var encOpMap = map[reflect.Type] encOp {
 
 func getEncEngine(rt reflect.Type) *encEngine
 
-func encOpFor(typ reflect.Type) encOp {
+// Return the encoding op for the base type under rt and
+// the indirection count to reach it.
+func encOpFor(rt reflect.Type) (encOp, int) {
+       typ, indir := indirect(rt);
        op, ok := encOpMap[reflect.Typeof(typ)];
        if !ok {
+               typ, _ := indirect(rt);
                // Special cases
                switch t := typ.(type) {
                case *reflect.SliceType:
@@ -332,8 +335,7 @@ func encOpFor(typ reflect.Type) encOp {
                                break;
                        }
                        // Slices have a header; we decode it to find the underlying array.
-                       elemOp := encOpFor(t.Elem());
-                       _, indir := indirect(t.Elem());
+                       elemOp, indir := encOpFor(t.Elem());
                        op = func(i *encInstr, state *EncState, p unsafe.Pointer) {
                                slice := (*reflect.SliceHeader)(p);
                                if slice.Len == 0 {
@@ -344,8 +346,7 @@ func encOpFor(typ reflect.Type) encOp {
                        };
                case *reflect.ArrayType:
                        // True arrays have size in the type.
-                       elemOp := encOpFor(t.Elem());
-                       _, indir := indirect(t.Elem());
+                       elemOp, indir := encOpFor(t.Elem());
                        op = func(i *encInstr, state *EncState, p unsafe.Pointer) {
                                state.update(i);
                                state.err = encodeArray(state.w, uintptr(p), elemOp, t.Elem().Size(), t.Len(), indir);
@@ -360,9 +361,9 @@ func encOpFor(typ reflect.Type) encOp {
                }
        }
        if op == nil {
-               panicln("encode can't handle type", typ.String());
+               panicln("encode can't handle type", rt.String());
        }
-       return op
+       return op, indir
 }
 
 // The local Type was compiled from the actual value, so we know
@@ -377,8 +378,7 @@ func compileEnc(rt reflect.Type, typ Type) *encEngine {
        engine.instr = make([]encInstr, srt.NumField()+1);      // +1 for terminator
        for fieldnum := 0; fieldnum < srt.NumField(); fieldnum++ {
                f := srt.Field(fieldnum);
-               ftyp, indir := indirect(f.Type);
-               op := encOpFor(ftyp);
+               op, indir := encOpFor(f.Type);
                engine.instr[fieldnum] = encInstr{op, fieldnum, indir, uintptr(f.Offset)};
        }
        engine.instr[srt.NumField()] = encInstr{encStructTerminator, 0, 0, 0};