public inbox for kawa@sourceware.org
 help / color / mirror / Atom feed
* Exception in thread "main" java.lang.InternalError: bad type SP:0 st.l:1
@ 2022-02-24 21:49 Panicz Maciej Godek
  2022-02-25  1:31 ` Per Bothner
  0 siblings, 1 reply; 4+ messages in thread
From: Panicz Maciej Godek @ 2022-02-24 21:49 UTC (permalink / raw)
  To: kawa

Hi,
I'm working on my code, and after some recent modificationsI get the
following error when I try to import my module:

Exception in thread "main" java.lang.InternalError: bad type SP:0 st.l:1
code:primitive.sequenceExtent(gnu.lists.Pair,Screen)Extent
        at gnu.bytecode.Label.setTypes(Label.java:106)
        at gnu.bytecode.Label.define(Label.java:231)
        at gnu.expr.LambdaExp.compileEnd(LambdaExp.java:640)
        at gnu.expr.LambdaExp.compileAsInlined(LambdaExp.java:1522)
        at gnu.expr.ApplyExp.compile(ApplyExp.java:378)
        ...
        at gnu.expr.ModuleExp.evalModule1(ModuleExp.java:246)
        at kawa.Shell.run(Shell.java:293)
        at kawa.Shell.run(Shell.java:183)
        at kawa.repl.processArgs(repl.java:724)
        at kawa.repl.main(repl.java:830)

How do I even approach debugging this?

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Exception in thread "main" java.lang.InternalError: bad type SP:0 st.l:1
  2022-02-24 21:49 Exception in thread "main" java.lang.InternalError: bad type SP:0 st.l:1 Panicz Maciej Godek
@ 2022-02-25  1:31 ` Per Bothner
  2022-02-25 16:26   ` Panicz Maciej Godek
  0 siblings, 1 reply; 4+ messages in thread
From: Per Bothner @ 2022-02-25  1:31 UTC (permalink / raw)
  To: Panicz Maciej Godek, kawa



On 2/24/22 13:49, Panicz Maciej Godek via Kawa wrote:
> Hi,
> I'm working on my code, and after some recent modificationsI get the
> following error when I try to import my module:
> 
> Exception in thread "main" java.lang.InternalError: bad type SP:0 st.l:1
> code:primitive.sequenceExtent(gnu.lists.Pair,Screen)Extent
>          at gnu.bytecode.Label.setTypes(Label.java:106)
>          at gnu.bytecode.Label.define(Label.java:231)
>          at gnu.expr.LambdaExp.compileEnd(LambdaExp.java:640)
>          at gnu.expr.LambdaExp.compileAsInlined(LambdaExp.java:1522)
>          at gnu.expr.ApplyExp.compile(ApplyExp.java:378)
>          ...
>          at gnu.expr.ModuleExp.evalModule1(ModuleExp.java:246)
>          at kawa.Shell.run(Shell.java:293)
>          at kawa.Shell.run(Shell.java:183)
>          at kawa.repl.processArgs(repl.java:724)
>          at kawa.repl.main(repl.java:830)
> 
> How do I even approach debugging this?

I haven't seen one of those in a while.  This can be tricky, and requires
some understanding of the JVM.  It is almost by definition a bug in Kawa,
not your code.

This is basically a failed consistency check during bytecode generation.
Consider an if-expression:

    (if test-expression then-expression else-expression)

This is compiled to something like:

L0:
   evaluate test-expression
   [for simplicity assume the result is a boolean on the JVM stack]
   if pop-value() is false goto L2
L1:
   evaluate then-expression
   goto L3
L2:
   evaluate else-expression
L3:

The JVM verifier requires that the state of the JVM stack *and* the local variables
after the then-expression and after the else-expression be consistent.
The most simple inconsistency (and the one causing the exception) is that the
length of the stack be the same.  There are other rules, but they're more complicated.
For example if then-branch can set local variable 4 to int and the else-branch
could set it to a float.  That is OK - as long as no code following L3 tries to
use the value of variable 4.  If the then-branch sets stack position 2 to a
java.lang.Integer and the else-branch sets it to a java.lang.Float, that is
OK - as long as code following L3 treats it as the common supertype java.lang.Number.

The JVM bytecode verifier originally had to infer these types by analysing how
the various bytescodes change the type-state.  Java 6 added a "StackMapTable" attribute
which adds information about the type-state in the .class file.
This makes byte-code verification much faster, since the verifier
only to to check that the bytecode is consistent with the StackMapTable.

In your case, one execution path leaves the stack with length 1,
and another leaves the stack with length 0.  You need to figure out
which is correct and why the other one is wrong.  The flag
--debug-print-final-expr is useful for getting the how the source
code looks after various transformations and before code-generation.
You need to understand how that tree maps into bytecode, which is
difficult. The more you can simplify your code the better.

You'll learn a lot about Kawa and the JVM if you can figure this out.
If not, I might be able to take a look - if you can simplify as
much as you can first.
-- 
	--Per Bothner
per@bothner.com   http://per.bothner.com/

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Exception in thread "main" java.lang.InternalError: bad type SP:0 st.l:1
  2022-02-25  1:31 ` Per Bothner
@ 2022-02-25 16:26   ` Panicz Maciej Godek
  2022-02-25 17:11     ` Per Bothner
  0 siblings, 1 reply; 4+ messages in thread
From: Panicz Maciej Godek @ 2022-02-25 16:26 UTC (permalink / raw)
  To: Per Bothner; +Cc: kawa

pt., 25 lut 2022 o 02:32 Per Bothner <per@bothner.com> napisał(a):

>
>
> On 2/24/22 13:49, Panicz Maciej Godek via Kawa wrote:
> > Hi,
> > I'm working on my code, and after some recent modificationsI get the
> > following error when I try to import my module:
> >
> > Exception in thread "main" java.lang.InternalError: bad type SP:0 st.l:1
> > code:primitive.sequenceExtent(gnu.lists.Pair,Screen)Extent
> >          at gnu.bytecode.Label.setTypes(Label.java:106)
> >          at gnu.bytecode.Label.define(Label.java:231)
> >          at gnu.expr.LambdaExp.compileEnd(LambdaExp.java:640)
> >          at gnu.expr.LambdaExp.compileAsInlined(LambdaExp.java:1522)
> >          at gnu.expr.ApplyExp.compile(ApplyExp.java:378)
> >          ...
> >          at gnu.expr.ModuleExp.evalModule1(ModuleExp.java:246)
> >          at kawa.Shell.run(Shell.java:293)
> >          at kawa.Shell.run(Shell.java:183)
> >          at kawa.repl.processArgs(repl.java:724)
> >          at kawa.repl.main(repl.java:830)
> >
> > How do I even approach debugging this?
>
> I haven't seen one of those in a while.  This can be tricky, and requires
> some understanding of the JVM.  It is almost by definition a bug in Kawa,
> not your code.
>
>
Actually, there were a number of bugs in my hastily refactored code.
I don't exactly know the root cause. I suppose that the reason for this was
that due to uncautious refactoring, I have passed "object" class instead of
an actual value (which was meant to be a cons pair in that context). But I
also had some erroneous type annotations.

If you're curious, this commit fixed the bug for me:
https://github.com/panicz/grasp-android/commit/0cc6226bd9773728610b7501fbf0eda1e3110d65

(to reproduce the bug, it should be sufficient to import the (primitive)
module)

>
> This is basically a failed consistency check during bytecode generation.
> Consider an if-expression:
>
>     (if test-expression then-expression else-expression)
>
> This is compiled to something like:
>
> L0:
>    evaluate test-expression
>    [for simplicity assume the result is a boolean on the JVM stack]
>    if pop-value() is false goto L2
> L1:
>    evaluate then-expression
>    goto L3
> L2:
>    evaluate else-expression
> L3:
>
> The JVM verifier requires that the state of the JVM stack *and* the local
> variables
> after the then-expression and after the else-expression be consistent.
> The most simple inconsistency (and the one causing the exception) is that
> the
> length of the stack be the same.  There are other rules, but they're more
> complicated.
> For example if then-branch can set local variable 4 to int and the
> else-branch
> could set it to a float.  That is OK - as long as no code following L3
> tries to
> use the value of variable 4.  If the then-branch sets stack position 2 to a
> java.lang.Integer and the else-branch sets it to a java.lang.Float, that is
> OK - as long as code following L3 treats it as the common supertype
> java.lang.Number.
>
> The JVM bytecode verifier originally had to infer these types by analysing
> how
> the various bytescodes change the type-state.  Java 6 added a
> "StackMapTable" attribute
> which adds information about the type-state in the .class file.
> This makes byte-code verification much faster, since the verifier
> only to to check that the bytecode is consistent with the StackMapTable.
>
> In your case, one execution path leaves the stack with length 1,
> and another leaves the stack with length 0.  You need to figure out
> which is correct and why the other one is wrong.  The flag
> --debug-print-final-expr is useful for getting the how the source
> code looks after various transformations and before code-generation.
> You need to understand how that tree maps into bytecode, which is
> difficult. The more you can simplify your code the better.
>
> You'll learn a lot about Kawa and the JVM if you can figure this out.
> If not, I might be able to take a look - if you can simplify as
> much as you can first.
>
>
Thanks for the detailed explanation. I expect that one day, I will learn
how JVM and Kawa operate under the hood, but that day is yet to come.

I was a bit surprised that I got that weird stack trace, but actually the
top of the stack did contain the sufficient hint (i.e. the name of the
function that caused the trouble).

Anyway, thanks for taking the trouble of explaining all that to me!

Best regards,
Panicz

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Exception in thread "main" java.lang.InternalError: bad type SP:0 st.l:1
  2022-02-25 16:26   ` Panicz Maciej Godek
@ 2022-02-25 17:11     ` Per Bothner
  0 siblings, 0 replies; 4+ messages in thread
From: Per Bothner @ 2022-02-25 17:11 UTC (permalink / raw)
  To: Panicz Maciej Godek; +Cc: kawa

On 2/25/22 08:26, Panicz Maciej Godek wrote:
> pt., 25 lut 2022 o 02:32 Per Bothner <per@bothner.com <mailto:per@bothner.com>> napisał(a):

>     I haven't seen one of those in a while.  This can be tricky, and requires
>     some understanding of the JVM.  It is almost by definition a bug in Kawa,
>     not your code.
> 
> Actually, there were a number of bugs in my hastily refactored code.

Anything that causes a compile-time exception instead of a helpful error message
is almost-by-definition a Kawa compiler bug.
(Not counting exceptions while expanding a syntax-case macro.)
But some of them might be difficult to disagnose or fix!
-- 
	--Per Bothner
per@bothner.com   http://per.bothner.com/

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2022-02-25 17:12 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-24 21:49 Exception in thread "main" java.lang.InternalError: bad type SP:0 st.l:1 Panicz Maciej Godek
2022-02-25  1:31 ` Per Bothner
2022-02-25 16:26   ` Panicz Maciej Godek
2022-02-25 17:11     ` Per Bothner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).