diff options
Diffstat (limited to 'pkg/compiler')
| -rw-r--r-- | pkg/compiler/types.go | 54 |
1 files changed, 51 insertions, 3 deletions
diff --git a/pkg/compiler/types.go b/pkg/compiler/types.go index e77f80a3d..70a0bd565 100644 --- a/pkg/compiler/types.go +++ b/pkg/compiler/types.go @@ -210,14 +210,62 @@ var typePtr = &typeDesc{ base.TypeSize = 8 } base.TypeAlign = getIntAlignment(comp, base) + elem := comp.genType(args[1], 0) + elemDir := genDir(args[0]) return &prog.PtrType{ - TypeCommon: base.TypeCommon, - Elem: comp.genType(args[1], 0), - ElemDir: genDir(args[0]), + TypeCommon: base.TypeCommon, + Elem: elem, + ElemDir: elemDir, + SquashableElem: isSquashableElem(elem, elemDir), } }, } +func isSquashableElem(elem prog.Type, dir prog.Dir) bool { + if dir != prog.DirIn { + return false + } + // Check if the pointer element contains something that can be complex, and does not contain + // anything unsupported we don't want to sqaush. Prog package later checks at runtime + // if a concrete arg actually contains something complex. But we look at the whole type + // to understand if it contains anything unsupported b/c a union may contain e.g. a complex struct + // and a filename we don't want to squash, or an array may contain something unsupported, + // but has 0 size in a concrete argument. + complex, unsupported := false, false + prog.ForeachArgType(elem, func(t prog.Type, ctx *prog.TypeCtx) { + switch typ := t.(type) { + case *prog.StructType: + if typ.Varlen() { + complex = true + } + if typ.OverlayField != 0 { + // Squashing of structs with out_overlay is not supported. + // If we do it, we need to be careful to either squash out part as well, + // or remove any resources in the out part from the prog. + unsupported = true + } + case *prog.UnionType: + if typ.Varlen() && len(typ.Fields) > 5 { + complex = true + } + case *prog.PtrType: + // Squashing of pointers is not supported b/c if we do it + // we will pass random garbage as pointers. + unsupported = true + case *prog.BufferType: + switch typ.Kind { + case prog.BufferFilename, prog.BufferGlob, prog.BufferCompressed: + // Squashing file names may lead to unwanted escaping paths (e.g. "/"), + // squashing compressed buffers is not useful since we uncompress them ourselves + // (not the kernel). + unsupported = true + } + } + ctx.Stop = unsupported + }) + return complex && !unsupported +} + var typeVoid = &typeDesc{ Names: []string{"void"}, CantBeOpt: true, |
