Beispiel #1
0
func (c *funcContext) loadStruct(array, target string, s *types.Struct) string {
	view := c.newVariable("_view")
	code := fmt.Sprintf("%s = new DataView(%s.buffer, %s.byteOffset)", view, array, array)
	var fields []*types.Var
	var collectFields func(s *types.Struct, path string)
	collectFields = func(s *types.Struct, path string) {
		for i := 0; i < s.NumFields(); i++ {
			field := s.Field(i)
			if fs, isStruct := field.Type().Underlying().(*types.Struct); isStruct {
				collectFields(fs, path+"."+fieldName(s, i))
				continue
			}
			fields = append(fields, types.NewVar(0, nil, path+"."+fieldName(s, i), field.Type()))
		}
	}
	collectFields(s, target)
	offsets := sizes32.Offsetsof(fields)
	for i, field := range fields {
		switch t := field.Type().Underlying().(type) {
		case *types.Basic:
			if isNumeric(t) {
				if is64Bit(t) {
					code += fmt.Sprintf(", %s = new %s(%s.getUint32(%d, true), %s.getUint32(%d, true))", field.Name(), c.typeName(field.Type()), view, offsets[i]+4, view, offsets[i])
					break
				}
				code += fmt.Sprintf(", %s = %s.get%s(%d, true)", field.Name(), view, toJavaScriptType(t), offsets[i])
			}
		case *types.Array:
			code += fmt.Sprintf(`, %s = new ($nativeArray(%s))(%s.buffer, $min(%s.byteOffset + %d, %s.buffer.byteLength))`, field.Name(), typeKind(t.Elem()), array, array, offsets[i], array)
		}
	}
	return code
}
Beispiel #2
0
func (d *DIBuilder) descriptorStruct(t *types.Struct, name string) llvm.Value {
	fields := make([]*types.Var, t.NumFields())
	for i := range fields {
		fields[i] = t.Field(i)
	}
	offsets := d.sizes.Offsetsof(fields)
	members := make([]llvm.Value, len(fields))
	for i, f := range fields {
		// TODO(axw) file/line where member is defined.
		t := f.Type()
		members[i] = d.builder.CreateMemberType(d.cu, llvm.DIMemberType{
			Name:         f.Name(),
			Type:         d.DIType(t),
			SizeInBits:   uint64(d.sizes.Sizeof(t) * 8),
			AlignInBits:  uint64(d.sizes.Alignof(t) * 8),
			OffsetInBits: uint64(offsets[i] * 8),
		})
	}
	// TODO(axw) file/line where struct is defined.
	return d.builder.CreateStructType(d.cu, llvm.DIStructType{
		Name:        name,
		SizeInBits:  uint64(d.sizes.Sizeof(t) * 8),
		AlignInBits: uint64(d.sizes.Alignof(t) * 8),
		Elements:    members,
	})
}
Beispiel #3
0
func fieldOffset(str *types.Struct, fldNum int) int64 {
	fieldList := make([]*types.Var, str.NumFields())
	for f := 0; f < str.NumFields(); f++ {
		fieldList[f] = str.Field(f)
	}
	return haxeStdSizes.Offsetsof(fieldList)[fldNum]
}
Beispiel #4
0
// matchStructArgType reports whether all the elements of the struct match the expected
// type. For instance, with "%d" all the elements must be printable with the "%d" format.
func (f *File) matchStructArgType(t printfArgType, typ *types.Struct, arg ast.Expr, inProgress map[types.Type]bool) bool {
	for i := 0; i < typ.NumFields(); i++ {
		if !f.matchArgTypeInternal(t, typ.Field(i).Type(), arg, inProgress) {
			return false
		}
	}
	return true
}
Beispiel #5
0
func exportedFields(T *types.Struct) []*types.Var {
	var fields []*types.Var
	for i := 0; i < T.NumFields(); i++ {
		f := T.Field(i)
		if !f.Exported() {
			continue
		}
		fields = append(fields, f)
	}
	return fields
}
Beispiel #6
0
func (g *goGen) genStruct(obj *types.TypeName, typ *types.Struct) {
	//fmt.Printf("obj: %#v\ntyp: %#v\n", obj, typ)
	pkgname := obj.Pkg().Name()
	g.Printf("//export GoPy_%[1]s\n", obj.Name())
	g.Printf("type GoPy_%[1]s unsafe.Pointer\n\n", obj.Name())

	for i := 0; i < typ.NumFields(); i++ {
		f := typ.Field(i)
		if !f.Exported() {
			continue
		}

		ft := f.Type()
		ftname := g.qualifiedType(ft)
		if needWrapType(ft) {
			ftname = fmt.Sprintf("GoPy_%[1]s_field_%d", obj.Name(), i+1)
			g.Printf("//export %s\n", ftname)
			g.Printf("type %s unsafe.Pointer\n\n", ftname)
		}

		g.Printf("//export GoPy_%[1]s_getter_%[2]d\n", obj.Name(), i+1)
		g.Printf("func GoPy_%[1]s_getter_%[2]d(self GoPy_%[1]s) %[3]s {\n",
			obj.Name(), i+1,
			ftname,
		)
		g.Indent()
		g.Printf(
			"ret := (*%[1]s)(unsafe.Pointer(self))\n",
			pkgname+"."+obj.Name(),
		)

		if needWrapType(f.Type()) {
			dt := getTypedesc(f.Type())
			g.Printf("%s(unsafe.Pointer(&ret.%s))\n", dt.cgotype, f.Name())
		} else {
			g.Printf("return ret.%s\n", f.Name())
		}
		g.Outdent()
		g.Printf("}\n\n")
	}

	g.Printf("//export GoPy_%[1]s_new\n", obj.Name())
	g.Printf("func GoPy_%[1]s_new() GoPy_%[1]s {\n", obj.Name())
	g.Indent()
	g.Printf("return (GoPy_%[1]s)(unsafe.Pointer(&%[2]s.%[1]s{}))\n",
		obj.Name(),
		pkgname,
	)
	g.Outdent()
	g.Printf("}\n\n")
}
Beispiel #7
0
func optimalSize(str *types.Struct, sizes *gcSizes) int64 {
	nf := str.NumFields()
	fields := make([]*types.Var, nf)
	alignofs := make([]int64, nf)
	sizeofs := make([]int64, nf)
	for i := 0; i < nf; i++ {
		fields[i] = str.Field(i)
		ft := fields[i].Type()
		alignofs[i] = sizes.Alignof(ft)
		sizeofs[i] = sizes.Sizeof(ft)
	}
	sort.Sort(&byAlignAndSize{fields, alignofs, sizeofs})
	return sizes.Sizeof(types.NewStruct(fields, nil))
}
Beispiel #8
0
func (g *Grapher) assignStructFieldPaths(styp *types.Struct, prefix []string, pkgscope bool) {
	for i := 0; i < styp.NumFields(); i++ {
		f := styp.Field(i)
		path := append(append([]string{}, prefix...), f.Name())
		g.paths[f] = path

		g.exported[f] = ast.IsExported(f.Name())
		g.pkgscope[f] = pkgscope

		// recurse to anonymous structs (named structs are assigned directly)
		// TODO(sqs): handle arrays of structs, etc.
		if styp, ok := derefType(f.Type()).(*types.Struct); ok {
			g.assignStructFieldPaths(styp, path, pkgscope)
		}
	}
}
Beispiel #9
0
// Returns which field index is an embedded storable.Document, or -1 if none.
func (p *Processor) processFields(s *types.Struct, done []*types.Struct) (base int, fields []*Field) {
	c := s.NumFields()

	base = -1
	fields = make([]*Field, 0)

	for i := 0; i < c; i++ {
		f := s.Field(i)
		if !f.Exported() {
			continue
		}

		t := reflect.StructTag(s.Tag(i))
		if f.Type().String() == BaseDocument {
			base = i
		}

		field := NewField(f.Name(), f.Type().Underlying().String(), t)
		field.CheckedNode = f
		str := p.tryGetStruct(f.Type())
		if f.Type().String() != BaseDocument && str != nil {
			field.Type = getStructType(f.Type())

			d := false
			for _, v := range done {
				if v == str {
					d = true
					break
				}
			}
			if !d {
				_, subfs := p.processFields(str, append(done, str))
				field.SetFields(subfs)
			}
		}

		fields = append(fields, field)
	}

	return base, fields
}
Beispiel #10
0
//iterate over a struct's fields recursively and add its fields to the candidate list
func findStructFields(str *types.Struct, prefix string, fset *token.FileSet) []UnexportCandidate {
	candidates := []UnexportCandidate{}
	for i := 0; i < str.NumFields(); i++ {
		field := str.Field(i)
		if !field.Exported() || field.Anonymous() {
			continue
		}
		// Tags are a likely indicator that this field is used by something
		// like json or xml that uses reflection. Skip it to be safe.
		// TODO: override flag? whitelist?
		if str.Tag(i) != "" {
			continue
		}
		candidate := UnexportCandidate{field.Name(), prefix + "." + field.Name(), fset.Position(field.Pos())}
		candidates = append(candidates, candidate)
		if nested, ok := field.Type().(*types.Struct); ok {
			candidates = append(candidates, findStructFields(nested, candidate.DisplayName, fset)...)
		}
	}
	return candidates
}
Beispiel #11
0
func Struct(path string, st reflect.StructTag, u *types.Struct, named *types.Named) IObj {
	rv := IStruct{}
	rv.name = strings.Split(st.Get("json"), ",")[0]
	rv.typ = getname(named, u)
	rv.description = st.Get("description")
	rv.path = pathAppend(path, rv.name)

	for i := 0; i < u.NumFields(); i++ {
		rv2 := dump(rv.path, u.Field(i).Type(), reflect.StructTag(u.Tag(i)))
		if rv2 == nil {
			continue
		}
		if st, ok := rv2.(IStruct); ok && st.name == "" {
			for _, j := range st.items {
				rv.items = append(rv.items, j)
			}
		} else {
			rv.items = append(rv.items, rv2)
		}
	}

	return rv
}
Beispiel #12
0
func (p *Processor) processFields(s *types.Struct) int {
	c := s.NumFields()

	base := -1
	fields := make([]*Field, 0)
	if _, ok := p.fieldsForStr[s]; !ok {
		p.fieldsForStr[s] = &fields
	}

	for i := 0; i < c; i++ {
		f := s.Field(i)
		if !f.Exported() {
			continue
		}

		t := reflect.StructTag(s.Tag(i))
		if f.Type().String() == BaseDocument {
			base = i
		}

		field := NewField(f.Name(), f.Type().Underlying().String(), t)
		str := p.tryGetStruct(f.Type())
		if f.Type().String() != BaseDocument && str != nil {
			field.Type = getStructType(f.Type())
			field.CheckedNode = f
			_, ok := p.fieldsForStr[str]
			if !ok {
				p.processFields(str)
			}
		}

		fields = append(fields, field)
	}

	return base
}