Zack Williams | e940c7a | 2019-08-21 14:25:39 -0700 | [diff] [blame] | 1 | package reflect2 |
| 2 | |
| 3 | import ( |
| 4 | "reflect" |
| 5 | "unsafe" |
| 6 | ) |
| 7 | |
| 8 | type UnsafeArrayType struct { |
| 9 | unsafeType |
| 10 | elemRType unsafe.Pointer |
| 11 | pElemRType unsafe.Pointer |
| 12 | elemSize uintptr |
| 13 | likePtr bool |
| 14 | } |
| 15 | |
| 16 | func newUnsafeArrayType(cfg *frozenConfig, type1 reflect.Type) *UnsafeArrayType { |
| 17 | return &UnsafeArrayType{ |
| 18 | unsafeType: *newUnsafeType(cfg, type1), |
| 19 | elemRType: unpackEFace(type1.Elem()).data, |
| 20 | pElemRType: unpackEFace(reflect.PtrTo(type1.Elem())).data, |
| 21 | elemSize: type1.Elem().Size(), |
| 22 | likePtr: likePtrType(type1), |
| 23 | } |
| 24 | } |
| 25 | |
| 26 | func (type2 *UnsafeArrayType) LikePtr() bool { |
| 27 | return type2.likePtr |
| 28 | } |
| 29 | |
| 30 | func (type2 *UnsafeArrayType) Indirect(obj interface{}) interface{} { |
| 31 | objEFace := unpackEFace(obj) |
| 32 | assertType("Type.Indirect argument 1", type2.ptrRType, objEFace.rtype) |
| 33 | return type2.UnsafeIndirect(objEFace.data) |
| 34 | } |
| 35 | |
| 36 | func (type2 *UnsafeArrayType) UnsafeIndirect(ptr unsafe.Pointer) interface{} { |
| 37 | if type2.likePtr { |
| 38 | return packEFace(type2.rtype, *(*unsafe.Pointer)(ptr)) |
| 39 | } |
| 40 | return packEFace(type2.rtype, ptr) |
| 41 | } |
| 42 | |
| 43 | func (type2 *UnsafeArrayType) SetIndex(obj interface{}, index int, elem interface{}) { |
| 44 | objEFace := unpackEFace(obj) |
| 45 | assertType("ArrayType.SetIndex argument 1", type2.ptrRType, objEFace.rtype) |
| 46 | elemEFace := unpackEFace(elem) |
| 47 | assertType("ArrayType.SetIndex argument 3", type2.pElemRType, elemEFace.rtype) |
| 48 | type2.UnsafeSetIndex(objEFace.data, index, elemEFace.data) |
| 49 | } |
| 50 | |
| 51 | func (type2 *UnsafeArrayType) UnsafeSetIndex(obj unsafe.Pointer, index int, elem unsafe.Pointer) { |
| 52 | elemPtr := arrayAt(obj, index, type2.elemSize, "i < s.Len") |
| 53 | typedmemmove(type2.elemRType, elemPtr, elem) |
| 54 | } |
| 55 | |
| 56 | func (type2 *UnsafeArrayType) GetIndex(obj interface{}, index int) interface{} { |
| 57 | objEFace := unpackEFace(obj) |
| 58 | assertType("ArrayType.GetIndex argument 1", type2.ptrRType, objEFace.rtype) |
| 59 | elemPtr := type2.UnsafeGetIndex(objEFace.data, index) |
| 60 | return packEFace(type2.pElemRType, elemPtr) |
| 61 | } |
| 62 | |
| 63 | func (type2 *UnsafeArrayType) UnsafeGetIndex(obj unsafe.Pointer, index int) unsafe.Pointer { |
| 64 | return arrayAt(obj, index, type2.elemSize, "i < s.Len") |
| 65 | } |