Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LambdaCall for statements #90

Open
quasilyte opened this issue Jul 5, 2017 · 3 comments
Open

LambdaCall for statements #90

quasilyte opened this issue Jul 5, 2017 · 3 comments

Comments

@quasilyte
Copy link
Owner

Function listed below is inlined, but it leads to compiler panic.

func utf8CharWidth(ch rune) int {
	switch {
	case ch <= 127:
		return 1
	case ch <= 2048:
		return 2
	case ch <= 65536:
		return 3
	default:
		return 4
	}
}
Debug info
[]           %empty 0 ''=> []
[]           %xlambda-enter 0 ''=> []
[]           constant 0 ''=> [<0> ]
[<0> ]       constant 1 ''=> [<0> <1> ]
[<0> <1> ]   num<= 0 ''=> [? ]
[? ]         goto-if-nil 2 'else'=> []
[]           %scope-enter 0 ''=> []
[]           constant 2 ''=> [<2> ]
[<2> ]       %xlambda-ret 0 'lambda-ret'=> [<2> ]
[<2> ]       %scope-leave 0 ''=> []
[]           goto 1 'endif'=> []
[]           label 2 'else'=> []
[]           constant 0 ''=> [<0> ]
[<0> ]       constant 3 ''=> [<0> <3> ]
[<0> <3> ]   num<= 0 ''=> [? ]
[? ]         goto-if-nil 4 'else'=> []
[]           %scope-enter 0 ''=> []
[]           constant 4 ''=> [<4> ]
[<4> ]       %xlambda-ret 0 'lambda-ret'=> [<4> ]
[<4> ]       %scope-leave 0 ''=> []
[]           goto 3 'endif'=> []
[]           label 4 'else'=> []
[]           constant 0 ''=> [<0> ]
[<0> ]       constant 5 ''=> [<0> <5> ]
[<0> <5> ]   num<= 0 ''=> [? ]
[? ]         goto-if-nil 6 'else'=> []
[]           %scope-enter 0 ''=> []
[]           constant 6 ''=> [<6> ]
[<6> ]       %xlambda-ret 0 'lambda-ret'=> [<6> ]
[<6> ]       %scope-leave 0 ''=> []
[]           goto 5 'endif'=> []
[]           label 6 'else'=> []
[]           %scope-enter 0 ''=> []
[]           constant 7 ''=> [<7> ]
[<7> ]       %xlambda-ret 0 'lambda-ret'=> [<7> ]
[<7> ]       %scope-leave 0 ''=> []
[]           label 5 'endif'=> []
[]           label 3 'endif'=> []
[]           label 1 'endif'=> []
[]           %xlambda-ret-label 0 'lambda-ret'
st.len=0 depth=0
panic: runtime error: slice bounds out of range [recovered]
	panic: runtime error: slice bounds out of range

goroutine 1 [running]:
exn.Catch(0x69f140, 0x829f30, 0x829f30, 0x82a160)
	/home/quasilyte/CODE/elgo/src/exn/exn.go:75 +0xb1
main.main.func1()
	/home/quasilyte/CODE/elgo/src/main/translate_package/translate_package.go:44 +0x43
panic(0x69f140, 0x829f30)
	/usr/local/go/src/runtime/panic.go:489 +0x2cf
backends/lapc/asm.(*converterY).convertInstr(0xc4201d9b70, 0xc42022cf30)
	/home/quasilyte/CODE/elgo/src/backends/lapc/asm/y_make.go:82 +0x93d
backends/lapc/asm.(*converterY).convert(0xc4201d9b70, 0xc42022c7b0)
	/home/quasilyte/CODE/elgo/src/backends/lapc/asm/y_make.go:54 +0x218
backends/lapc/asm.(*converterY).Convert(0xc4201d9b70, 0xc42022c7b0, 0xc42022cfc0, 0x0)
	/home/quasilyte/CODE/elgo/src/backends/lapc/asm/y_make.go:42 +0x35
backends/lapc/asm.makeY(0x8501c0, 0x0, 0x0, 0xc42022c7b0, 0xc42023a0e0, 0x6c6780)
	/home/quasilyte/CODE/elgo/src/backends/lapc/asm/y_make.go:38 +0x243
backends/lapc/asm.(*Assembler).Assemble(0xc42023c080, 0x8501c0, 0x0, 0x0, 0xc42023a0e0, 0xc4201d9cb0, 0x4b3a8b, 0xc4200ac0c0, 0xc4201d9c98)
	/home/quasilyte/CODE/elgo/src/backends/lapc/asm/assembler.go:32 +0x86

Bug reason: switch statement leaves no data on the stack.
lambda-ret expects there to be at least 1 value after evaluation.

This particular line triggers a panic:

cy.st.Discard(uint16(cy.st.Len() - depth - 1))
// cy.st.Len() => 0
// depth => 0

In correct code, cy.st.Len() should return 1.

Possible solution:
introduce temporary stack variable for cases like these.
Return statements should assign to that temporary.

@quasilyte
Copy link
Owner Author

Will make sexp.Switch.Cost() return -1 to forbid inlining of switch containing functions
until this issue is resolved.

quasilyte added a commit that referenced this issue Jul 5, 2017
@quasilyte
Copy link
Owner Author

After the bug is fixed, regression test must be added.

@quasilyte
Copy link
Owner Author

Worth mentioning that any statement inlined with LambdaCall leads to compilation error.

I will remove LambdaCall inlining from master branch temporary.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant