mirror of
https://github.com/golang/go
synced 2024-10-03 06:11:21 -06:00
bug fix: encOpFor etc. need to indirect
R=rsc DELTA=28 (7 added, 7 deleted, 14 changed) OCL=31312 CL=31322
This commit is contained in:
parent
d7f1f53e86
commit
0ae7882b5c
@ -388,7 +388,10 @@ var decOpMap = map[reflect.Type] decOp {
|
|||||||
|
|
||||||
func getDecEngine(rt reflect.Type) *decEngine
|
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)];
|
op, ok := decOpMap[reflect.Typeof(typ)];
|
||||||
if !ok {
|
if !ok {
|
||||||
// Special cases
|
// Special cases
|
||||||
@ -398,15 +401,13 @@ func decOpFor(typ reflect.Type) decOp {
|
|||||||
op = decUint8Array;
|
op = decUint8Array;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
elemOp := decOpFor(t.Elem());
|
elemOp, elemIndir := decOpFor(t.Elem());
|
||||||
_, elemIndir := indirect(t.Elem());
|
|
||||||
op = func(i *decInstr, state *DecState, p unsafe.Pointer) {
|
op = func(i *decInstr, state *DecState, p unsafe.Pointer) {
|
||||||
state.err = decodeSlice(t, state, uintptr(p), elemOp, t.Elem().Size(), i.indir, elemIndir);
|
state.err = decodeSlice(t, state, uintptr(p), elemOp, t.Elem().Size(), i.indir, elemIndir);
|
||||||
};
|
};
|
||||||
|
|
||||||
case *reflect.ArrayType:
|
case *reflect.ArrayType:
|
||||||
elemOp := decOpFor(t.Elem());
|
elemOp, elemIndir := decOpFor(t.Elem());
|
||||||
_, elemIndir := indirect(t.Elem());
|
|
||||||
op = func(i *decInstr, state *DecState, p unsafe.Pointer) {
|
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);
|
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 {
|
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 {
|
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.
|
// TODO(r): verify compatibility with corresponding field of data.
|
||||||
// For now, assume perfect correspondence between struct and gob.
|
// For now, assume perfect correspondence between struct and gob.
|
||||||
f := srt.Field(fieldnum);
|
f := srt.Field(fieldnum);
|
||||||
ftyp, indir := indirect(f.Type);
|
op, indir := decOpFor(f.Type);
|
||||||
op := decOpFor(ftyp);
|
|
||||||
engine.instr[fieldnum] = decInstr{op, fieldnum, indir, uintptr(f.Offset)};
|
engine.instr[fieldnum] = decInstr{op, fieldnum, indir, uintptr(f.Offset)};
|
||||||
}
|
}
|
||||||
return engine;
|
return engine;
|
||||||
|
@ -268,7 +268,6 @@ func encodeStruct(engine *encEngine, w io.Writer, basep uintptr) os.Error {
|
|||||||
p := unsafe.Pointer(basep+instr.offset);
|
p := unsafe.Pointer(basep+instr.offset);
|
||||||
if instr.indir > 0 {
|
if instr.indir > 0 {
|
||||||
if p = encIndirect(p, instr.indir); p == nil {
|
if p = encIndirect(p, instr.indir); p == nil {
|
||||||
state.fieldnum = i;
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -321,9 +320,13 @@ var encOpMap = map[reflect.Type] encOp {
|
|||||||
|
|
||||||
func getEncEngine(rt reflect.Type) *encEngine
|
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)];
|
op, ok := encOpMap[reflect.Typeof(typ)];
|
||||||
if !ok {
|
if !ok {
|
||||||
|
typ, _ := indirect(rt);
|
||||||
// Special cases
|
// Special cases
|
||||||
switch t := typ.(type) {
|
switch t := typ.(type) {
|
||||||
case *reflect.SliceType:
|
case *reflect.SliceType:
|
||||||
@ -332,8 +335,7 @@ func encOpFor(typ reflect.Type) encOp {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Slices have a header; we decode it to find the underlying array.
|
// Slices have a header; we decode it to find the underlying array.
|
||||||
elemOp := encOpFor(t.Elem());
|
elemOp, indir := encOpFor(t.Elem());
|
||||||
_, indir := indirect(t.Elem());
|
|
||||||
op = func(i *encInstr, state *EncState, p unsafe.Pointer) {
|
op = func(i *encInstr, state *EncState, p unsafe.Pointer) {
|
||||||
slice := (*reflect.SliceHeader)(p);
|
slice := (*reflect.SliceHeader)(p);
|
||||||
if slice.Len == 0 {
|
if slice.Len == 0 {
|
||||||
@ -344,8 +346,7 @@ func encOpFor(typ reflect.Type) encOp {
|
|||||||
};
|
};
|
||||||
case *reflect.ArrayType:
|
case *reflect.ArrayType:
|
||||||
// True arrays have size in the type.
|
// True arrays have size in the type.
|
||||||
elemOp := encOpFor(t.Elem());
|
elemOp, indir := encOpFor(t.Elem());
|
||||||
_, indir := indirect(t.Elem());
|
|
||||||
op = func(i *encInstr, state *EncState, p unsafe.Pointer) {
|
op = func(i *encInstr, state *EncState, p unsafe.Pointer) {
|
||||||
state.update(i);
|
state.update(i);
|
||||||
state.err = encodeArray(state.w, uintptr(p), elemOp, t.Elem().Size(), t.Len(), indir);
|
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 {
|
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
|
// 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
|
engine.instr = make([]encInstr, srt.NumField()+1); // +1 for terminator
|
||||||
for fieldnum := 0; fieldnum < srt.NumField(); fieldnum++ {
|
for fieldnum := 0; fieldnum < srt.NumField(); fieldnum++ {
|
||||||
f := srt.Field(fieldnum);
|
f := srt.Field(fieldnum);
|
||||||
ftyp, indir := indirect(f.Type);
|
op, indir := encOpFor(f.Type);
|
||||||
op := encOpFor(ftyp);
|
|
||||||
engine.instr[fieldnum] = encInstr{op, fieldnum, indir, uintptr(f.Offset)};
|
engine.instr[fieldnum] = encInstr{op, fieldnum, indir, uintptr(f.Offset)};
|
||||||
}
|
}
|
||||||
engine.instr[srt.NumField()] = encInstr{encStructTerminator, 0, 0, 0};
|
engine.instr[srt.NumField()] = encInstr{encStructTerminator, 0, 0, 0};
|
||||||
|
Loading…
Reference in New Issue
Block a user