resolve records the address range occupied by an object.
(obj reflect.Value, ref *wire.Ref)
| 183 | |
| 184 | // resolve records the address range occupied by an object. |
| 185 | func (es *encodeState) resolve(obj reflect.Value, ref *wire.Ref) { |
| 186 | addr := obj.Pointer() |
| 187 | |
| 188 | // Is this a map pointer? Just record the single address. It is not |
| 189 | // possible to take any pointers into the map internals. |
| 190 | if obj.Kind() == reflect.Map { |
| 191 | if addr == 0 { |
| 192 | // Just leave the nil reference alone. This is fine, we |
| 193 | // may need to encode as a reference in this way. We |
| 194 | // return nil for our objectEncodeState so that anyone |
| 195 | // depending on this value knows there's nothing there. |
| 196 | return |
| 197 | } |
| 198 | seg, gap := es.values.Find(addr) |
| 199 | if seg.Ok() { |
| 200 | // Ensure the map types match. |
| 201 | existing := seg.Value() |
| 202 | if existing.obj.Type() != obj.Type() { |
| 203 | Failf("overlapping map objects at 0x%x: [new object] %#v [existing object type] %s", addr, obj, existing.obj) |
| 204 | } |
| 205 | |
| 206 | // No sense recording refs, maps may not be replaced by |
| 207 | // covering objects, they are maximal. |
| 208 | ref.Root = wire.Uint(existing.id) |
| 209 | return |
| 210 | } |
| 211 | |
| 212 | // Record the map. |
| 213 | r := addrRange{addr, addr + 1} |
| 214 | oes := &objectEncodeState{ |
| 215 | id: es.nextID(), |
| 216 | obj: obj, |
| 217 | how: encodeMapAsValue, |
| 218 | } |
| 219 | // Use Insert instead of InsertWithoutMergingUnchecked when race |
| 220 | // detection is enabled to get additional sanity-checking from Merge. |
| 221 | if !raceEnabled { |
| 222 | es.values.InsertWithoutMergingUnchecked(gap, r, oes) |
| 223 | } else { |
| 224 | es.values.Insert(gap, r, oes) |
| 225 | } |
| 226 | es.pending[oes.id] = oes |
| 227 | es.deferred.PushBack(oes) |
| 228 | |
| 229 | // See above: no ref recording. |
| 230 | ref.Root = wire.Uint(oes.id) |
| 231 | return |
| 232 | } |
| 233 | |
| 234 | // If not a map, then the object must be a pointer. |
| 235 | if obj.Kind() != reflect.Ptr { |
| 236 | Failf("attempt to record non-map and non-pointer object %#v", obj) |
| 237 | } |
| 238 | |
| 239 | obj = obj.Elem() // Value from here. |
| 240 | |
| 241 | // Is this a zero-sized type? |
| 242 | typ := obj.Type() |
no test coverage detected