Beispiel #1
0
func sizeof(v reflect.Type) int {
	switch t := v.(type) {
	case *reflect.ArrayType:
		n := sizeof(t.Elem())
		if n < 0 {
			return -1
		}
		return t.Len() * n

	case *reflect.StructType:
		sum := 0
		for i, n := 0, t.NumField(); i < n; i++ {
			s := sizeof(t.Field(i).Type)
			if s < 0 {
				return -1
			}
			sum += s
		}
		return sum

	case *reflect.UintType, *reflect.IntType, *reflect.FloatType, *reflect.ComplexType:
		switch t := t.Kind(); t {
		case reflect.Int, reflect.Uint, reflect.Uintptr:
			return -1
		}
		return int(v.Size())
	}
	return -1
}
Beispiel #2
0
func defaultType(t reflect.Type) TypeDesc {
	switch t.Kind() {
	case reflect.Bool:
		return BooleanType
	case reflect.String:
		return UTF8Type
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return LongType
	case reflect.Float32:
		return FloatType
	case reflect.Float64:
		return DoubleType
	case reflect.Array:
		if t.Name() == "UUID" && t.Size() == 16 {
			return UUIDType
		}
		return UnknownType
	case reflect.Struct:
		if t.Name() == "Time" && t.PkgPath() == "time" {
			return DateType
		}
		return UnknownType
	case reflect.Slice:
		if et := t.Elem(); et.Kind() == reflect.Uint8 {
			return BytesType
		}
		return UnknownType
	}
	return UnknownType
}
Beispiel #3
0
func indexer(t reflect.Type) indexFunc {
	size := t.Size()
	return func(v handle, i int) handle {
		header := (*reflect.SliceHeader)(unsafe.Pointer(&v))
		return handle(header.Data + uintptr(i)*size)
	}
}
Beispiel #4
0
func sizeof(t reflect.Type) (int, error) {
	switch t.Kind() {
	case reflect.Array:
		n, err := sizeof(t.Elem())
		if err != nil {
			return 0, err
		}
		return t.Len() * n, nil

	case reflect.Struct:
		sum := 0
		for i, n := 0, t.NumField(); i < n; i++ {
			s, err := sizeof(t.Field(i).Type)
			if err != nil {
				return 0, err
			}
			sum += s
		}
		return sum, nil

	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
		reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
		reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128:
		return int(t.Size()), nil
	}
	return 0, errors.New("invalid type " + t.String())
}
Beispiel #5
0
// integerPromote determines if we can promote v to dType, and if so, return the promoted value.
// This is needed because msgpack always encodes values as the minimum sized int that can hold them.
func integerPromote(dType reflect.Type, v reflect.Value) (reflect.Value, bool) {

	vt := v.Type()
	dsz := dType.Size()
	vtsz := vt.Size()

	if isIntType(dType) && isIntType(vt) && vtsz <= dsz {
		pv := reflect.New(dType).Elem()
		pv.SetInt(v.Int())
		return pv, true
	}

	if isUintType(dType) && isUintType(vt) && vtsz <= dsz {
		pv := reflect.New(dType).Elem()
		pv.SetUint(v.Uint())
		return pv, true
	}

	if isIntType(dType) && isUintType(vt) && vtsz <= dsz {
		pv := reflect.New(dType).Elem()
		pv.SetInt(int64(v.Uint()))
		return pv, true
	}

	if isUintType(dType) && isIntType(vt) && vtsz <= dsz {
		pv := reflect.New(dType).Elem()
		pv.SetUint(uint64(v.Int()))
		return pv, true
	}

	return v, false
}
Beispiel #6
0
// sizeof returns the size >= 0 of variables for the given type or -1 if the type is not acceptable.
func sizeof(t reflect.Type) int {
	switch t.Kind() {
	case reflect.Array:
		if s := sizeof(t.Elem()); s >= 0 {
			return s * t.Len()
		}

	case reflect.Struct:
		sum := 0
		for i, n := 0, t.NumField(); i < n; i++ {
			s := sizeof(t.Field(i).Type)
			if s < 0 {
				return -1
			}
			sum += s
		}
		return sum

	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
		reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
		reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128, reflect.Ptr:
		return int(t.Size())
	}

	return -1
}
Beispiel #7
0
func benchmarkWriteSlice(b *testing.B, typ reflect.Type, count int) {
	slice := reflect.MakeSlice(reflect.SliceOf(typ), count, count).Interface()
	b.SetBytes(int64(count * int(typ.Size())))
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		Write(ioutil.Discard, BigEndian, slice)
	}
}
Beispiel #8
0
func benchmarkReadSlice(b *testing.B, typ reflect.Type, count int) {
	fr := &fakeReader{}
	slice := reflect.MakeSlice(reflect.SliceOf(typ), count, count).Interface()
	b.SetBytes(int64(count * int(typ.Size())))
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		Read(fr, BigEndian, slice)
	}
}
Beispiel #9
0
func structMatchGeneric(t *testing.T, ta, tb reflect.Type, sza, szb uintptr) {
	if sza != szb {
		t.Errorf("type size mismatch: %s(%d) != %s(%d)",
			ta.Name(), ta.Size(), tb.Name(), tb.Size())
		t.Fail()
	}

	if ta.Kind() != tb.Kind() {
		t.Errorf("type kind mismatch: %s=%s != %s=%s",
			ta.Name(), ta.Kind(), tb.Name(), tb.Kind())
		t.Fail()
	}
}
Beispiel #10
0
func sse2Reflect(t reflect.Type) sse2type {
	elemSize := uint(0)
	if t.Kind() == reflect.Array {
		elemSize = uint(t.Elem().Size())
	}
	return sse2type{
		name:     t.Name(),
		size:     uint(t.Size()),
		elemSize: elemSize,
		align:    uint(t.Size()),
		t:        t,
	}
}
Beispiel #11
0
func indexSetter(t reflect.Type) indexSetFunc {
	size := t.Size()
	return func(v handle, i int, val handle) {
		header := (*reflect.SliceHeader)(unsafe.Pointer(&v))
		var dst []byte
		dh := (*reflect.SliceHeader)(unsafe.Pointer(&dst))
		dh.Len = int(size)
		dh.Data = header.Data + uintptr(i)*size
		var src []byte
		sh := (*reflect.SliceHeader)(unsafe.Pointer(&src))
		sh.Len = int(size)
		sh.Data = uintptr(val)
		copy(dst, src)
	}
}
Beispiel #12
0
func MatchHeaders(b reflect.Type, slice interface{}, header reflect.SliceHeader) (e error) {
	h, s, al := SliceHeader(slice)
	switch {
	case s != int(b.Size()):
		e = HeaderMismatch{"%v: slice element size should be %v not %v", b.Name(), b.Size(), s}
	case al != b.Align():
		e = HeaderMismatch{"%v: slice element alignment should be %v not %v", b.Name(), b.Align(), al}
	case h.Data != header.Data:
		e = HeaderMismatch{"%v: slice headers should point to the same memory: %v - %v", b.Name(), h.Data, header.Data}
	case h.Len != header.Len:
		e = HeaderMismatch{"%v: slice header lengths should be the same: %v - %v", b.Name(), h.Len, header.Len}
	case h.Cap != header.Cap:
		e = HeaderMismatch{"%v: slice header capacities should be the same: %v - %v", b.Name(), h.Cap, header.Cap}
	}
	return
}
Beispiel #13
0
func swapper(t reflect.Type) swapFunc {
	size := t.Size()
	tmp := make([]byte, size)
	return func(v handle, i, j int) {
		header := (*reflect.SliceHeader)(unsafe.Pointer(&v))
		var si []byte
		hi := (*reflect.SliceHeader)(unsafe.Pointer(&si))
		hi.Len = int(size)
		hi.Data = header.Data + uintptr(i)*size
		var sj []byte
		hj := (*reflect.SliceHeader)(unsafe.Pointer(&sj))
		hj.Len = int(size)
		hj.Data = header.Data + uintptr(j)*size
		copy(tmp, sj)
		copy(sj, si)
		copy(si, tmp)
	}
}
Beispiel #14
0
func NewMesh(attrs interface{}, indicies []uint32) *Mesh {
	mesh := new(Mesh)
	mesh.Attrs = attrs
	mesh.Indicies = indicies
	gl33.GenVertexArrays(1, &mesh.vao)
	gl33.BindVertexArray(mesh.vao)
	attrsValue := reflect.ValueOf(attrs)
	mesh.vertexBO = NewBuffer(gl33.ARRAY_BUFFER, gl33.STATIC_DRAW, attrs)
	vertexSpec := attrsValue.Type().Elem()
	if vertexSpec.Kind() != reflect.Struct && vertexSpec.Kind() != reflect.Array {
		panic("attrs is not a slice of structs or arrays")
	}
	var num int
	if vertexSpec.Kind() == reflect.Struct {
		num = vertexSpec.NumField()
	} else {
		num = vertexSpec.Len()
	}
	for i, offset := 0, uintptr(0); i < num; i++ {
		var field reflect.Type
		var type_ gl33.Enum
		var dimensions int
		if vertexSpec.Kind() == reflect.Struct {
			field = vertexSpec.Field(i).Type
		} else {
			field = vertexSpec.Elem()
		}
		if field.Kind() == reflect.Array {
			type_ = glType(field.Elem().Kind())
			dimensions = field.Len()
		} else {
			type_ = glType(field.Kind())
			dimensions = 1
		}
		setupAttrib(gl33.Uint(i), type_, dimensions, offset, int(vertexSpec.Size()))
		offset += field.Size()
	}
	mesh.indexBO = NewBuffer(gl33.ELEMENT_ARRAY_BUFFER, gl33.STATIC_DRAW, indicies)
	return mesh
}
Beispiel #15
0
func structMatch(t *testing.T, ta, tb reflect.Type) {
	structMatchGeneric(t, ta, tb, ta.Size(), tb.Size())
}
Beispiel #16
0
func new_dataTypeFromType(t reflect.Type) *DataType {

	var dt *DataType = nil

	switch t.Kind() {

	case reflect.Int:
		dt = T_NATIVE_INT // FIXME: .Copy() instead ?

	case reflect.Int8:
		dt = T_NATIVE_INT8

	case reflect.Int16:
		dt = T_NATIVE_INT16

	case reflect.Int32:
		dt = T_NATIVE_INT32

	case reflect.Int64:
		dt = T_NATIVE_INT64

	case reflect.Uint:
		dt = T_NATIVE_UINT // FIXME: .Copy() instead ?

	case reflect.Uint8:
		dt = T_NATIVE_UINT8

	case reflect.Uint16:
		dt = T_NATIVE_UINT16

	case reflect.Uint32:
		dt = T_NATIVE_UINT32

	case reflect.Uint64:
		dt = T_NATIVE_UINT64

	case reflect.Float32:
		dt = T_NATIVE_FLOAT

	case reflect.Float64:
		dt = T_NATIVE_DOUBLE

	case reflect.String:
		dt = T_GO_STRING
		//dt = T_C_S1

	case reflect.Array:
		elem_type := new_dataTypeFromType(t.Elem())
		n := t.Len()
		dims := []int{n}
		adt, err := NewArrayType(elem_type, dims)
		if err != nil {
			panic(err)
		}
		dt, err = adt.Copy()
		if err != nil {
			panic(err)
		}

	case reflect.Slice:
		elem_type := new_dataTypeFromType(t.Elem())
		vlen_dt, err := NewVarLenType(elem_type)
		if err != nil {
			panic(err)
		}
		dt, err = vlen_dt.Copy()
		if err != nil {
			panic(err)
		}

	case reflect.Struct:
		sz := int(t.Size())
		hdf_dt, err := CreateDataType(T_COMPOUND, sz)
		if err != nil {
			panic(err)
		}
		cdt := &CompType{*hdf_dt}
		n := t.NumField()
		for i := 0; i < n; i++ {
			f := t.Field(i)
			var field_dt *DataType = nil
			field_dt = new_dataTypeFromType(f.Type)
			offset := int(f.Offset + 0)
			if field_dt == nil {
				panic(fmt.Sprintf("pb with field [%d-%s]", i, f.Name))
			}
			field_name := string(f.Tag)
			if len(field_name) == 0 {
				field_name = f.Name
			}
			err = cdt.Insert(field_name, offset, field_dt)
			if err != nil {
				panic(fmt.Sprintf("pb with field [%d-%s]: %s", i, f.Name, err))
			}
		}
		cdt.Lock()
		dt, err = cdt.Copy()
		if err != nil {
			panic(err)
		}

	case reflect.Ptr:
		panic("sorry, pointers not yet supported")

	default:
		panic(fmt.Sprintf("unhandled kind (%d)", t.Kind()))
	}

	return dt
}
Beispiel #17
0
// Value returns an arbitrary value of the given type.
// If the type implements the Generator interface, that will be used.
// Note: in order to create arbitrary values for structs, all the members must be public.
func Value(t reflect.Type, rand *rand.Rand) (value reflect.Value, ok bool) {
	if m, ok := reflect.MakeZero(t).Interface().(Generator); ok {
		return m.Generate(rand, complexSize), true
	}

	switch concrete := t.(type) {
	case *reflect.BoolType:
		return reflect.NewValue(rand.Int()&1 == 0), true
	case *reflect.Float32Type:
		return reflect.NewValue(randFloat32(rand)), true
	case *reflect.Float64Type:
		return reflect.NewValue(randFloat64(rand)), true
	case *reflect.FloatType:
		if t.Size() == 4 {
			return reflect.NewValue(float(randFloat32(rand))), true
		} else {
			return reflect.NewValue(float(randFloat64(rand))), true
		}
	case *reflect.Int16Type:
		return reflect.NewValue(int16(randInt64(rand))), true
	case *reflect.Int32Type:
		return reflect.NewValue(int32(randInt64(rand))), true
	case *reflect.Int64Type:
		return reflect.NewValue(randInt64(rand)), true
	case *reflect.Int8Type:
		return reflect.NewValue(int8(randInt64(rand))), true
	case *reflect.IntType:
		return reflect.NewValue(int(randInt64(rand))), true
	case *reflect.MapType:
		numElems := rand.Intn(complexSize)
		m := reflect.MakeMap(concrete)
		for i := 0; i < numElems; i++ {
			key, ok1 := Value(concrete.Key(), rand)
			value, ok2 := Value(concrete.Elem(), rand)
			if !ok1 || !ok2 {
				return nil, false
			}
			m.SetElem(key, value)
		}
		return m, true
	case *reflect.PtrType:
		v, ok := Value(concrete.Elem(), rand)
		if !ok {
			return nil, false
		}
		p := reflect.MakeZero(concrete)
		p.(*reflect.PtrValue).PointTo(v)
		return p, true
	case *reflect.SliceType:
		numElems := rand.Intn(complexSize)
		s := reflect.MakeSlice(concrete, numElems, numElems)
		for i := 0; i < numElems; i++ {
			v, ok := Value(concrete.Elem(), rand)
			if !ok {
				return nil, false
			}
			s.Elem(i).SetValue(v)
		}
		return s, true
	case *reflect.StringType:
		numChars := rand.Intn(complexSize)
		codePoints := make([]int, numChars)
		for i := 0; i < numChars; i++ {
			codePoints[i] = rand.Intn(0x10ffff)
		}
		return reflect.NewValue(string(codePoints)), true
	case *reflect.StructType:
		s := reflect.MakeZero(t).(*reflect.StructValue)
		for i := 0; i < s.NumField(); i++ {
			v, ok := Value(concrete.Field(i).Type, rand)
			if !ok {
				return nil, false
			}
			s.Field(i).SetValue(v)
		}
		return s, true
	case *reflect.Uint16Type:
		return reflect.NewValue(uint16(randInt64(rand))), true
	case *reflect.Uint32Type:
		return reflect.NewValue(uint32(randInt64(rand))), true
	case *reflect.Uint64Type:
		return reflect.NewValue(uint64(randInt64(rand))), true
	case *reflect.Uint8Type:
		return reflect.NewValue(uint8(randInt64(rand))), true
	case *reflect.UintType:
		return reflect.NewValue(uint(randInt64(rand))), true
	case *reflect.UintptrType:
		return reflect.NewValue(uintptr(randInt64(rand))), true
	default:
		return nil, false
	}

	return
}
Beispiel #18
0
func AddApis(am Apis) {
	for _, a := range am {
		f := r.ValueOf(a.Fnc)
		if f.Kind() != r.Ptr {
			panic("outside: " + r.TypeOf(a.Fnc).String() + " supplied : Pointer to function expected")
		}
		fn := f.Elem()
		fnt := fn.Type()
		var apiCall func(i []r.Value) []r.Value
		//Allow 2 returns and put err in 2nd if supplied
		var ot, et r.Type
		nOut := fnt.NumOut()
		if nOut >= 1 {
			ot = fnt.Out(0)
		}
		if nOut == 2 {
			et = fnt.Out(1)
		}
		p, unicode := apiAddr(a.Ep)
		if p != nil {
			fai, sli, fao, slo := funcAnalysis(fnt)
			// name := a.Ep
			retSizeArg := -1
			if nOut >= 1 && ot.Kind() == r.Slice {
				if sa, ok := ot.MethodByName("SizeArg"); ok {
					retSizeArg = int(sa.Func.Call([]r.Value{r.Indirect(r.New(ot))})[0].Int() - 1)
				}
			}
			var hasErrorMethod bool
			var ea r.Method
			if ot != nil {
				ea, hasErrorMethod = ot.MethodByName("Error")
			}
			apiCall = func(i []r.Value) []r.Value {
				TOT++
				var rr r.Value
				inStructs(unicode, i, fai, sli)
				ina := inArgs(unicode, i)
				r1, r2, f, err := p.call(ina...)
				// Printf("%s %v %v %b %x %b %x\n", name, i, ot, fai, sli, fao, slo)
				outStructs(unicode, i, fao, slo)
				if ot != nil {
					if runtime.GOARCH == "amd64" || ot.Size() == 4 {
						rr = r.ValueOf(r1)
					} else if fnt.Out(0).Kind() == r.Float64 || fnt.Out(0).Kind() == r.Float32 {
						rr = r.ValueOf(f)
					} else {
						rr = r.ValueOf((uint64(r2) << 32) | uint64(r1))
					}
					vrsa := rsaNo
					if retSizeArg != -1 {
						vrsa = i[retSizeArg]
					}
					v1 := convert(rr, ot, unicode, vrsa)
					if hasErrorMethod {
						// TODO(t): for linux - error strategy
						var ret []r.Value
						if err == nil {
							ret = ea.Func.Call([]r.Value{v1, r.Zero(r.TypeOf(new(error)).Elem())}) // issue 6871
						} else {
							ret = ea.Func.Call([]r.Value{v1, r.ValueOf(err)})
						}
						v1 = ret[0]
						if e := ret[1].Interface(); e != nil {
							err = e.(error)
						} else {
							err = nil
						}
					}
					if et == nil {
						return []r.Value{v1}
					} else {
						return []r.Value{v1, convert(r.ValueOf(err), et, unicode, rsaNo)}
					}
				} else {
					return nil
				}
			}
		} else {
			apiCall = func(i []r.Value) []r.Value {
				panic(`outside: call of non-existent procedure "` + string(a.Ep) + `"`)
			}
		}
		v := r.MakeFunc(fn.Type(), apiCall)
		fn.Set(v)
	}
}
Beispiel #19
0
// NewDatatypeFromType creates a new Datatype from a reflect.Type.
func NewDataTypeFromType(t reflect.Type) (*Datatype, error) {

	var dt *Datatype = nil
	var err error

	switch t.Kind() {

	case reflect.Int:
		dt, err = T_NATIVE_INT.Copy()

	case reflect.Int8:
		dt, err = T_NATIVE_INT8.Copy()

	case reflect.Int16:
		dt, err = T_NATIVE_INT16.Copy()

	case reflect.Int32:
		dt, err = T_NATIVE_INT32.Copy()

	case reflect.Int64:
		dt, err = T_NATIVE_INT64.Copy()

	case reflect.Uint:
		dt, err = T_NATIVE_UINT.Copy()

	case reflect.Uint8:
		dt, err = T_NATIVE_UINT8.Copy()

	case reflect.Uint16:
		dt, err = T_NATIVE_UINT16.Copy()

	case reflect.Uint32:
		dt, err = T_NATIVE_UINT32.Copy()

	case reflect.Uint64:
		dt, err = T_NATIVE_UINT64.Copy()

	case reflect.Float32:
		dt, err = T_NATIVE_FLOAT.Copy()

	case reflect.Float64:
		dt, err = T_NATIVE_DOUBLE.Copy()

	case reflect.String:
		dt, err = T_GO_STRING.Copy()

	case reflect.Array:
		elem_type, err := NewDataTypeFromType(t.Elem())
		if err != nil {
			return nil, err
		}

		dims := getArrayDims(t)

		adt, err := NewArrayType(elem_type, dims)
		if err != nil {
			return nil, err
		}

		dt, err = adt.Copy()
		if err != nil {
			return nil, err
		}

	case reflect.Struct:
		sz := int(t.Size())
		hdf_dt, err := CreateDatatype(T_COMPOUND, sz)
		if err != nil {
			return nil, err
		}
		cdt := &CompoundType{*hdf_dt}
		n := t.NumField()
		for i := 0; i < n; i++ {
			f := t.Field(i)
			var field_dt *Datatype = nil
			field_dt, err = NewDataTypeFromType(f.Type)
			if err != nil {
				return nil, err
			}
			offset := int(f.Offset + 0)
			if field_dt == nil {
				return nil, fmt.Errorf("pb with field [%d-%s]", i, f.Name)
			}
			field_name := string(f.Tag)
			if len(field_name) == 0 {
				field_name = f.Name
			}
			err = cdt.Insert(field_name, offset, field_dt)
			if err != nil {
				return nil, fmt.Errorf("pb with field [%d-%s]: %s", i, f.Name, err)
			}
		}
		cdt.Lock()
		dt, err = cdt.Copy()
		if err != nil {
			return nil, err
		}

	default:
		// Should never happen.
		panic(fmt.Sprintf("unhandled kind (%v)", t.Kind()))
	}

	return dt, err
}
Beispiel #20
0
func structMatchFixed(t *testing.T, ta, tb reflect.Type, szb uintptr) {
	structMatchGeneric(t, ta, tb, ta.Size(), szb)
}
Beispiel #21
0
// PointerToByteArray convert to bytes array.
//
// Warning:
// While it is technically possible to have count be an arbitrary large number,
// it is unwise to do so. Attempting to do so is undefined and may have security
// or stability issues. The security issues from including outside boundary data
// or stability issues from attempting to extend outside the bounds of the
// current data block and causing an OS fault.
func PointerToByteArray(ptr uintptr, count uint32, t reflect.Type) []byte {
	byteCount := count * uint32(t.Size())
	slicehdr := reflect.SliceHeader{Data: ptr, Len: int(byteCount), Cap: int(byteCount)}
	return *(*[]byte)(unsafe.Pointer(&slicehdr))
}