summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoraviau <alexandre@alexandreviau.net>2015-12-06 15:20:42 -0500
committeraviau <alexandre@alexandreviau.net>2015-12-06 15:20:42 -0500
commit23f48564206214cdb348161cc662fa4e41a12ebd (patch)
treeeafaa731dcbae2dc79bfa364df82ceebf60f7efa
parentfacf80ba6f19868d27ba23140fbd693c5fa696b9 (diff)
parent7c5cbb0dc24321a60e88ddbfcb3fd1c5d11da2b6 (diff)
Merge tag 'upstream/0.0_git20151130.0.357a44b'
Upstream version 0.0~git20151130.0.357a44b
-rw-r--r--codec/decode.go19
-rw-r--r--codec/fast-path.generated.go60
-rw-r--r--codec/fast-path.go.tmpl4
-rw-r--r--codec/gen-dec-array.go.tmpl4
-rw-r--r--codec/gen.generated.go4
-rw-r--r--codec/gen.go83
6 files changed, 114 insertions, 60 deletions
diff --git a/codec/decode.go b/codec/decode.go
index d842a24..7e56f1e 100644
--- a/codec/decode.go
+++ b/codec/decode.go
@@ -583,14 +583,16 @@ func (f *decFnInfo) kInterfaceNaked() (rvn reflect.Value) {
if d.mtid == 0 || d.mtid == mapIntfIntfTypId {
l := len(n.ms)
n.ms = append(n.ms, nil)
- d.decode(&n.ms[l])
- rvn = reflect.ValueOf(&n.ms[l]).Elem()
+ var v2 interface{} = &n.ms[l]
+ d.decode(v2)
+ rvn = reflect.ValueOf(v2).Elem()
n.ms = n.ms[:l]
} else if d.mtid == mapStrIntfTypId { // for json performance
l := len(n.ns)
n.ns = append(n.ns, nil)
- d.decode(&n.ns[l])
- rvn = reflect.ValueOf(&n.ns[l]).Elem()
+ var v2 interface{} = &n.ns[l]
+ d.decode(v2)
+ rvn = reflect.ValueOf(v2).Elem()
n.ns = n.ns[:l]
} else {
rvn = reflect.New(d.h.MapType).Elem()
@@ -601,8 +603,9 @@ func (f *decFnInfo) kInterfaceNaked() (rvn reflect.Value) {
if d.stid == 0 || d.stid == intfSliceTypId {
l := len(n.ss)
n.ss = append(n.ss, nil)
- d.decode(&n.ss[l])
- rvn = reflect.ValueOf(&n.ss[l]).Elem()
+ var v2 interface{} = &n.ss[l]
+ d.decode(v2)
+ rvn = reflect.ValueOf(v2).Elem()
n.ss = n.ss[:l]
} else {
rvn = reflect.New(d.h.SliceType).Elem()
@@ -615,9 +618,9 @@ func (f *decFnInfo) kInterfaceNaked() (rvn reflect.Value) {
l := len(n.is)
n.is = append(n.is, nil)
v2 := &n.is[l]
- n.is = n.is[:l]
d.decode(v2)
v = *v2
+ n.is = n.is[:l]
}
bfn := d.h.getExtForTag(tag)
if bfn == nil {
@@ -1453,8 +1456,8 @@ func (d *Decoder) swallow() {
l := len(n.is)
n.is = append(n.is, nil)
v2 := &n.is[l]
- n.is = n.is[:l]
d.decode(v2)
+ n.is = n.is[:l]
}
}
}
diff --git a/codec/fast-path.generated.go b/codec/fast-path.generated.go
index d968a50..5cac047 100644
--- a/codec/fast-path.generated.go
+++ b/codec/fast-path.generated.go
@@ -17712,7 +17712,7 @@ func (_ fastpathT) DecSliceIntfV(v []interface{}, checkNil bool, canChange bool,
changed = true
}
slh.End()
- return
+ return v, changed
}
if containerLenS > 0 {
@@ -17771,7 +17771,7 @@ func (_ fastpathT) DecSliceIntfV(v []interface{}, checkNil bool, canChange bool,
changed = true
}
slh.End()
- return
+ return v, changed
}
if cap(v) == 0 {
v = make([]interface{}, 1, 4)
@@ -17846,7 +17846,7 @@ func (_ fastpathT) DecSliceStringV(v []string, checkNil bool, canChange bool, d
changed = true
}
slh.End()
- return
+ return v, changed
}
if containerLenS > 0 {
@@ -17905,7 +17905,7 @@ func (_ fastpathT) DecSliceStringV(v []string, checkNil bool, canChange bool, d
changed = true
}
slh.End()
- return
+ return v, changed
}
if cap(v) == 0 {
v = make([]string, 1, 4)
@@ -17979,7 +17979,7 @@ func (_ fastpathT) DecSliceFloat32V(v []float32, checkNil bool, canChange bool,
changed = true
}
slh.End()
- return
+ return v, changed
}
if containerLenS > 0 {
@@ -18038,7 +18038,7 @@ func (_ fastpathT) DecSliceFloat32V(v []float32, checkNil bool, canChange bool,
changed = true
}
slh.End()
- return
+ return v, changed
}
if cap(v) == 0 {
v = make([]float32, 1, 4)
@@ -18112,7 +18112,7 @@ func (_ fastpathT) DecSliceFloat64V(v []float64, checkNil bool, canChange bool,
changed = true
}
slh.End()
- return
+ return v, changed
}
if containerLenS > 0 {
@@ -18171,7 +18171,7 @@ func (_ fastpathT) DecSliceFloat64V(v []float64, checkNil bool, canChange bool,
changed = true
}
slh.End()
- return
+ return v, changed
}
if cap(v) == 0 {
v = make([]float64, 1, 4)
@@ -18245,7 +18245,7 @@ func (_ fastpathT) DecSliceUintV(v []uint, checkNil bool, canChange bool, d *Dec
changed = true
}
slh.End()
- return
+ return v, changed
}
if containerLenS > 0 {
@@ -18304,7 +18304,7 @@ func (_ fastpathT) DecSliceUintV(v []uint, checkNil bool, canChange bool, d *Dec
changed = true
}
slh.End()
- return
+ return v, changed
}
if cap(v) == 0 {
v = make([]uint, 1, 4)
@@ -18378,7 +18378,7 @@ func (_ fastpathT) DecSliceUint16V(v []uint16, checkNil bool, canChange bool, d
changed = true
}
slh.End()
- return
+ return v, changed
}
if containerLenS > 0 {
@@ -18437,7 +18437,7 @@ func (_ fastpathT) DecSliceUint16V(v []uint16, checkNil bool, canChange bool, d
changed = true
}
slh.End()
- return
+ return v, changed
}
if cap(v) == 0 {
v = make([]uint16, 1, 4)
@@ -18511,7 +18511,7 @@ func (_ fastpathT) DecSliceUint32V(v []uint32, checkNil bool, canChange bool, d
changed = true
}
slh.End()
- return
+ return v, changed
}
if containerLenS > 0 {
@@ -18570,7 +18570,7 @@ func (_ fastpathT) DecSliceUint32V(v []uint32, checkNil bool, canChange bool, d
changed = true
}
slh.End()
- return
+ return v, changed
}
if cap(v) == 0 {
v = make([]uint32, 1, 4)
@@ -18644,7 +18644,7 @@ func (_ fastpathT) DecSliceUint64V(v []uint64, checkNil bool, canChange bool, d
changed = true
}
slh.End()
- return
+ return v, changed
}
if containerLenS > 0 {
@@ -18703,7 +18703,7 @@ func (_ fastpathT) DecSliceUint64V(v []uint64, checkNil bool, canChange bool, d
changed = true
}
slh.End()
- return
+ return v, changed
}
if cap(v) == 0 {
v = make([]uint64, 1, 4)
@@ -18777,7 +18777,7 @@ func (_ fastpathT) DecSliceUintptrV(v []uintptr, checkNil bool, canChange bool,
changed = true
}
slh.End()
- return
+ return v, changed
}
if containerLenS > 0 {
@@ -18836,7 +18836,7 @@ func (_ fastpathT) DecSliceUintptrV(v []uintptr, checkNil bool, canChange bool,
changed = true
}
slh.End()
- return
+ return v, changed
}
if cap(v) == 0 {
v = make([]uintptr, 1, 4)
@@ -18910,7 +18910,7 @@ func (_ fastpathT) DecSliceIntV(v []int, checkNil bool, canChange bool, d *Decod
changed = true
}
slh.End()
- return
+ return v, changed
}
if containerLenS > 0 {
@@ -18969,7 +18969,7 @@ func (_ fastpathT) DecSliceIntV(v []int, checkNil bool, canChange bool, d *Decod
changed = true
}
slh.End()
- return
+ return v, changed
}
if cap(v) == 0 {
v = make([]int, 1, 4)
@@ -19043,7 +19043,7 @@ func (_ fastpathT) DecSliceInt8V(v []int8, checkNil bool, canChange bool, d *Dec
changed = true
}
slh.End()
- return
+ return v, changed
}
if containerLenS > 0 {
@@ -19102,7 +19102,7 @@ func (_ fastpathT) DecSliceInt8V(v []int8, checkNil bool, canChange bool, d *Dec
changed = true
}
slh.End()
- return
+ return v, changed
}
if cap(v) == 0 {
v = make([]int8, 1, 4)
@@ -19176,7 +19176,7 @@ func (_ fastpathT) DecSliceInt16V(v []int16, checkNil bool, canChange bool, d *D
changed = true
}
slh.End()
- return
+ return v, changed
}
if containerLenS > 0 {
@@ -19235,7 +19235,7 @@ func (_ fastpathT) DecSliceInt16V(v []int16, checkNil bool, canChange bool, d *D
changed = true
}
slh.End()
- return
+ return v, changed
}
if cap(v) == 0 {
v = make([]int16, 1, 4)
@@ -19309,7 +19309,7 @@ func (_ fastpathT) DecSliceInt32V(v []int32, checkNil bool, canChange bool, d *D
changed = true
}
slh.End()
- return
+ return v, changed
}
if containerLenS > 0 {
@@ -19368,7 +19368,7 @@ func (_ fastpathT) DecSliceInt32V(v []int32, checkNil bool, canChange bool, d *D
changed = true
}
slh.End()
- return
+ return v, changed
}
if cap(v) == 0 {
v = make([]int32, 1, 4)
@@ -19442,7 +19442,7 @@ func (_ fastpathT) DecSliceInt64V(v []int64, checkNil bool, canChange bool, d *D
changed = true
}
slh.End()
- return
+ return v, changed
}
if containerLenS > 0 {
@@ -19501,7 +19501,7 @@ func (_ fastpathT) DecSliceInt64V(v []int64, checkNil bool, canChange bool, d *D
changed = true
}
slh.End()
- return
+ return v, changed
}
if cap(v) == 0 {
v = make([]int64, 1, 4)
@@ -19575,7 +19575,7 @@ func (_ fastpathT) DecSliceBoolV(v []bool, checkNil bool, canChange bool, d *Dec
changed = true
}
slh.End()
- return
+ return v, changed
}
if containerLenS > 0 {
@@ -19634,7 +19634,7 @@ func (_ fastpathT) DecSliceBoolV(v []bool, checkNil bool, canChange bool, d *Dec
changed = true
}
slh.End()
- return
+ return v, changed
}
if cap(v) == 0 {
v = make([]bool, 1, 4)
diff --git a/codec/fast-path.go.tmpl b/codec/fast-path.go.tmpl
index 58cc6df..3f43dc6 100644
--- a/codec/fast-path.go.tmpl
+++ b/codec/fast-path.go.tmpl
@@ -328,7 +328,7 @@ func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v []{{ .Elem }}, checkNil b
changed = true
}
slh.End()
- return
+ return v, changed
}
if containerLenS > 0 {
@@ -391,7 +391,7 @@ func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v []{{ .Elem }}, checkNil b
changed = true
}
slh.End()
- return
+ return v, changed
}
if cap(v) == 0 {
v = make([]{{ .Elem }}, 1, 4)
diff --git a/codec/gen-dec-array.go.tmpl b/codec/gen-dec-array.go.tmpl
index 2caae5b..08476a4 100644
--- a/codec/gen-dec-array.go.tmpl
+++ b/codec/gen-dec-array.go.tmpl
@@ -1,6 +1,7 @@
{{var "v"}} := {{if not isArray}}*{{end}}{{ .Varname }}
-{{var "h"}}, {{var "l"}} := z.DecSliceHelperStart() {{/* // helper, containerLenS */}}
+{{var "h"}}, {{var "l"}} := z.DecSliceHelperStart() {{/* // helper, containerLenS */}}{{if not isArray}}
var {{var "c"}} bool {{/* // changed */}}
+_ = {{var "c"}}{{end}}
if {{var "l"}} == 0 {
{{if isSlice }}if {{var "v"}} == nil {
{{var "v"}} = []{{ .Typ }}{}
@@ -26,6 +27,7 @@ if {{var "l"}} == 0 {
}
{{ else }} var {{var "rr"}}, {{var "rl"}} int {{/* // num2read, length of slice/array/chan */}}
var {{var "rt"}} bool {{/* truncated */}}
+ _, _, _ = {{var "rr"}}, {{var "rl"}}, {{var "rt"}}
if {{var "l"}} > cap({{var "v"}}) {
{{if isArray }}z.DecArrayCannotExpand(len({{var "v"}}), {{var "l"}})
{{ else }}{{if not .Immutable }}
diff --git a/codec/gen.generated.go b/codec/gen.generated.go
index fb6f4b8..151445d 100644
--- a/codec/gen.generated.go
+++ b/codec/gen.generated.go
@@ -68,8 +68,9 @@ z.DecSendContainerState(codecSelfer_containerMapEnd{{ .Sfx }})
const genDecListTmpl = `
{{var "v"}} := {{if not isArray}}*{{end}}{{ .Varname }}
-{{var "h"}}, {{var "l"}} := z.DecSliceHelperStart() {{/* // helper, containerLenS */}}
+{{var "h"}}, {{var "l"}} := z.DecSliceHelperStart() {{/* // helper, containerLenS */}}{{if not isArray}}
var {{var "c"}} bool {{/* // changed */}}
+_ = {{var "c"}}{{end}}
if {{var "l"}} == 0 {
{{if isSlice }}if {{var "v"}} == nil {
{{var "v"}} = []{{ .Typ }}{}
@@ -95,6 +96,7 @@ if {{var "l"}} == 0 {
}
{{ else }} var {{var "rr"}}, {{var "rl"}} int {{/* // num2read, length of slice/array/chan */}}
var {{var "rt"}} bool {{/* truncated */}}
+ _, _, _ = {{var "rr"}}, {{var "rl"}}, {{var "rt"}}
if {{var "l"}} > cap({{var "v"}}) {
{{if isArray }}z.DecArrayCannotExpand(len({{var "v"}}), {{var "l"}})
{{ else }}{{if not .Immutable }}
diff --git a/codec/gen.go b/codec/gen.go
index a075e7c..5b27675 100644
--- a/codec/gen.go
+++ b/codec/gen.go
@@ -566,9 +566,28 @@ func (x *genRunner) xtraSM(varname string, encode bool, t reflect.Type) {
} else {
x.linef("h.dec%s((*%s)(%s), d)", x.genMethodNameT(t), x.genTypeName(t), varname)
}
- if _, ok := x.tm[t]; !ok {
- x.tm[t] = struct{}{}
- x.ts = append(x.ts, t)
+ x.registerXtraT(t)
+}
+
+func (x *genRunner) registerXtraT(t reflect.Type) {
+ // recursively register the types
+ if _, ok := x.tm[t]; ok {
+ return
+ }
+ var tkey reflect.Type
+ switch t.Kind() {
+ case reflect.Chan, reflect.Slice, reflect.Array:
+ case reflect.Map:
+ tkey = t.Key()
+ default:
+ return
+ }
+ x.tm[t] = struct{}{}
+ x.ts = append(x.ts, t)
+ // check if this refers to any xtra types eg. a slice of array: add the array
+ x.registerXtraT(t.Elem())
+ if tkey != nil {
+ x.registerXtraT(tkey)
}
}
@@ -608,22 +627,33 @@ func (x *genRunner) encVar(varname string, t reflect.Type) {
}
-// enc will encode a variable (varname) of type T,
-// except t is of kind reflect.Struct or reflect.Array, wherein varname is of type *T (to prevent copying)
+// enc will encode a variable (varname) of type t,
+// except t is of kind reflect.Struct or reflect.Array, wherein varname is of type ptrTo(T) (to prevent copying)
func (x *genRunner) enc(varname string, t reflect.Type) {
- // varName here must be to a pointer to a struct/array, or to a value directly.
rtid := reflect.ValueOf(t).Pointer()
// We call CodecEncodeSelf if one of the following are honored:
// - the type already implements Selfer, call that
// - the type has a Selfer implementation just created, use that
// - the type is in the list of the ones we will generate for, but it is not currently being generated
+ mi := x.varsfx()
tptr := reflect.PtrTo(t)
tk := t.Kind()
if x.checkForSelfer(t, varname) {
- if t.Implements(selferTyp) || (tptr.Implements(selferTyp) && (tk == reflect.Array || tk == reflect.Struct)) {
- x.line(varname + ".CodecEncodeSelf(e)")
- return
+ if tk == reflect.Array || tk == reflect.Struct { // varname is of type *T
+ if tptr.Implements(selferTyp) || t.Implements(selferTyp) {
+ x.line(varname + ".CodecEncodeSelf(e)")
+ return
+ }
+ } else { // varname is of type T
+ if t.Implements(selferTyp) {
+ x.line(varname + ".CodecEncodeSelf(e)")
+ return
+ } else if tptr.Implements(selferTyp) {
+ x.linef("%ssf%s := &%s", genTempVarPfx, mi, varname)
+ x.linef("%ssf%s.CodecEncodeSelf(e)", genTempVarPfx, mi)
+ return
+ }
}
if _, ok := x.te[rtid]; ok {
@@ -653,7 +683,6 @@ func (x *genRunner) enc(varname string, t reflect.Type) {
// check if
// - type is RawExt
// - the type implements (Text|JSON|Binary)(Unm|M)arshal
- mi := x.varsfx()
x.linef("%sm%s := z.EncBinary()", genTempVarPfx, mi)
x.linef("_ = %sm%s", genTempVarPfx, mi)
x.line("if false {") //start if block
@@ -676,15 +705,31 @@ func (x *genRunner) enc(varname string, t reflect.Type) {
// first check if extensions are configued, before doing the interface conversion
x.linef("} else if z.HasExtensions() && z.EncExt(%s) {", varname)
}
- if t.Implements(binaryMarshalerTyp) || tptr.Implements(binaryMarshalerTyp) {
- x.linef("} else if %sm%s { z.EncBinaryMarshal(%v) ", genTempVarPfx, mi, varname)
- }
- if t.Implements(jsonMarshalerTyp) || tptr.Implements(jsonMarshalerTyp) {
- x.linef("} else if !%sm%s && z.IsJSONHandle() { z.EncJSONMarshal(%v) ", genTempVarPfx, mi, varname)
- } else if t.Implements(textMarshalerTyp) || tptr.Implements(textMarshalerTyp) {
- x.linef("} else if !%sm%s { z.EncTextMarshal(%v) ", genTempVarPfx, mi, varname)
+ if tk == reflect.Array || tk == reflect.Struct { // varname is of type *T
+ if t.Implements(binaryMarshalerTyp) || tptr.Implements(binaryMarshalerTyp) {
+ x.linef("} else if %sm%s { z.EncBinaryMarshal(%v) ", genTempVarPfx, mi, varname)
+ }
+ if t.Implements(jsonMarshalerTyp) || tptr.Implements(jsonMarshalerTyp) {
+ x.linef("} else if !%sm%s && z.IsJSONHandle() { z.EncJSONMarshal(%v) ", genTempVarPfx, mi, varname)
+ } else if t.Implements(textMarshalerTyp) || tptr.Implements(textMarshalerTyp) {
+ x.linef("} else if !%sm%s { z.EncTextMarshal(%v) ", genTempVarPfx, mi, varname)
+ }
+ } else { // varname is of type T
+ if t.Implements(binaryMarshalerTyp) {
+ x.linef("} else if %sm%s { z.EncBinaryMarshal(%v) ", genTempVarPfx, mi, varname)
+ } else if tptr.Implements(binaryMarshalerTyp) {
+ x.linef("} else if %sm%s { z.EncBinaryMarshal(&%v) ", genTempVarPfx, mi, varname)
+ }
+ if t.Implements(jsonMarshalerTyp) {
+ x.linef("} else if !%sm%s && z.IsJSONHandle() { z.EncJSONMarshal(%v) ", genTempVarPfx, mi, varname)
+ } else if tptr.Implements(jsonMarshalerTyp) {
+ x.linef("} else if !%sm%s && z.IsJSONHandle() { z.EncJSONMarshal(&%v) ", genTempVarPfx, mi, varname)
+ } else if t.Implements(textMarshalerTyp) {
+ x.linef("} else if !%sm%s { z.EncTextMarshal(%v) ", genTempVarPfx, mi, varname)
+ } else if tptr.Implements(textMarshalerTyp) {
+ x.linef("} else if !%sm%s { z.EncTextMarshal(&%v) ", genTempVarPfx, mi, varname)
+ }
}
-
x.line("} else {")
switch t.Kind() {
@@ -1020,6 +1065,8 @@ func (x *genRunner) decVar(varname string, t reflect.Type, canBeNil bool) {
}
}
+// dec will decode a variable (varname) of type ptrTo(t).
+// t is always a basetype (i.e. not of kind reflect.Ptr).
func (x *genRunner) dec(varname string, t reflect.Type) {
// assumptions:
// - the varname is to a pointer already. No need to take address of it