From d001e4e55f302b5604c604cda266b56bf3fc3af1 Mon Sep 17 00:00:00 2001 From: Eduard Urbach Date: Fri, 26 Jul 2024 19:33:51 +0200 Subject: [PATCH] Fixed jump address calculation --- src/build/asm/Finalize.go | 60 +++++++++++++++++++++--------------- tests/programs/param-order.q | 16 ++++++++++ tests/programs_test.go | 1 + 3 files changed, 53 insertions(+), 24 deletions(-) create mode 100644 tests/programs/param-order.q diff --git a/src/build/asm/Finalize.go b/src/build/asm/Finalize.go index df8e4ac..5c3397d 100644 --- a/src/build/asm/Finalize.go +++ b/src/build/asm/Finalize.go @@ -57,23 +57,25 @@ func (a Assembler) Finalize() ([]byte, []byte) { code = x64.Call(code, 0x00_00_00_00) size := 4 label := x.Data.(*Label) - nextInstructionAddress := Address(len(code)) - pointers = append(pointers, &Pointer{ + pointer := &Pointer{ Position: Address(len(code) - size), OpSize: 1, Size: uint8(size), - Resolve: func() Address { - destination, exists := labels[label.Name] + } - if !exists { - panic("unknown call label") - } + pointer.Resolve = func() Address { + destination, exists := labels[label.Name] - distance := destination - nextInstructionAddress - return Address(distance) - }, - }) + if !exists { + panic("unknown jump label") + } + + distance := destination - (pointer.Position + Address(pointer.Size)) + return Address(distance) + } + + pointers = append(pointers, pointer) case COMMENT: continue @@ -106,23 +108,25 @@ func (a Assembler) Finalize() ([]byte, []byte) { size := 1 label := x.Data.(*Label) - nextInstructionAddress := Address(len(code)) - pointers = append(pointers, &Pointer{ + pointer := &Pointer{ Position: Address(len(code) - size), OpSize: 1, Size: uint8(size), - Resolve: func() Address { - destination, exists := labels[label.Name] + } - if !exists { - panic("unknown jump label") - } + pointer.Resolve = func() Address { + destination, exists := labels[label.Name] - distance := destination - nextInstructionAddress - return Address(distance) - }, - }) + if !exists { + panic("unknown jump label") + } + + distance := destination - (pointer.Position + Address(pointer.Size)) + return Address(distance) + } + + pointers = append(pointers, pointer) case LABEL: labels[x.Data.(*Label).Name] = Address(len(code)) @@ -269,8 +273,16 @@ restart: following.Position += offset } - code = append(left, jump...) - code = append(code, right...) + for key, address := range labels { + if address > pointer.Position { + labels[key] += offset + } + } + + code = make([]byte, len(left)+len(jump)+len(right)) + copy(code, left) + copy(code[len(left):], jump) + copy(code[len(left)+len(jump):], right) goto restart } diff --git a/tests/programs/param-order.q b/tests/programs/param-order.q new file mode 100644 index 0000000..a36d6e8 --- /dev/null +++ b/tests/programs/param-order.q @@ -0,0 +1,16 @@ +main() { + f(1, 2, 3, 4, 5, 6) +} + +f(a, b, c, d, e, f) { + return g(f, e, d, c, b, a) +} + +g(a, b, c, d, e, f) { + assert a == 6 + assert b == 5 + assert c == 4 + assert d == 3 + assert e == 2 + assert f == 1 +} \ No newline at end of file diff --git a/tests/programs_test.go b/tests/programs_test.go index ee99875..1282e2e 100644 --- a/tests/programs_test.go +++ b/tests/programs_test.go @@ -25,6 +25,7 @@ var programs = []struct { {"nested-calls", "", "", 4}, {"param", "", "", 3}, {"param-multi", "", "", 21}, + {"param-order", "", "", 0}, {"reuse", "", "", 3}, {"return", "", "", 6}, {"reassign", "", "", 2},