Skip to content

Commit

Permalink
Implement struct padding
Browse files Browse the repository at this point in the history
Fixes #6
  • Loading branch information
Samadi van Koten committed Nov 8, 2020
1 parent e2762b8 commit 71ad7e4
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 11 deletions.
1 change: 1 addition & 0 deletions codegen.go
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,7 @@ func (f FuncType) GenZero(c *Compiler, loc Operand) {
func (s StructType) GenZero(c *Compiler, loc Operand) {
off := 0
for _, field := range s.compositeType {
off = -(-off & -field.Ty.Metrics().Align) // Align upwards
floc := loc
if off > 0 {
ftmp := c.Temporary()
Expand Down
14 changes: 14 additions & 0 deletions compiler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -336,17 +336,22 @@ func TestStruct(t *testing.T) {
testCompile(t, `
type Foo struct { a, b I32; c I64 }
type Bar struct { a, b, c I8 }
type Baz struct { a I8; b I64; c I8 }
fn fooFn(_ Foo)
fn barFn(_ Bar)
fn bazFn(_ Baz)
pub fn main() I32 {
var foo Foo
fooFn(foo)
var bar Bar
barFn(bar)
var baz Baz
bazFn(baz)
return 0
}
`, `
type :b3 = { b 3 }
type :blb = { b, l, b }
type :w2l = { w 2, l }
export function w $main() {
@start
Expand All @@ -368,6 +373,15 @@ func TestStruct(t *testing.T) {
call $barFn(:b3 %t4)
%t7 =l alloc8 24
storeb 0, %t7
%t8 =l add %t7, 8
storel 0, %t8
%t9 =l add %t7, 16
storeb 0, %t9
call $bazFn(:blb %t7)
ret 0
}
`)
Expand Down
39 changes: 28 additions & 11 deletions types.go
Original file line number Diff line number Diff line change
Expand Up @@ -365,13 +365,7 @@ func (s StructType) Concrete() ConcreteType {
return s
}
func (s StructType) Metrics() (m TypeMetrics) {
for _, field := range s.compositeType {
fm := field.Ty.Metrics()
if m.Align < fm.Align {
m.Align = fm.Align
}
m.Size += fm.Size
}
m.Size, m.Align = s.metrics("")
return
}
func (s StructType) Format(indent int) string {
Expand All @@ -398,14 +392,37 @@ func (s StructType) layout(c *Compiler) CompositeLayout {
return layout
}
func (s StructType) Offset(name string) int {
n := 0
if name == "" {
return -1
} else {
off, _ := s.metrics(name)
return off
}
}
func (s StructType) metrics(name string) (off int, align int) {
// This is the internal function behind both Metrics and Offset
// name == "" -> Metrics
// name != "" -> Offset

for _, field := range s.compositeType {
m := field.Ty.Metrics()
off = -(-off & -m.Align) // Align upwards
if field.Name == name {
return n
return
}
off += m.Size

if m.Align > align {
align = m.Align
}
n += field.Ty.Metrics().Size
}
return -1

if name == "" {
off = -(-off & -align) // Align struct size to max alignment for arrays
return
} else {
return -1, -1
}
}

func (a UnionType) Equals(other Type) bool {
Expand Down

0 comments on commit 71ad7e4

Please sign in to comment.