public inbox for
 help / color / mirror / Atom feed
From: Panicz Maciej Godek <>
To: Per Bothner <>
Subject: Re: Exception in thread "main" java.lang.InternalError: bad type SP:0 st.l:1
Date: Fri, 25 Feb 2022 17:26:46 +0100	[thread overview]
Message-ID: <> (raw)
In-Reply-To: <>

pt., 25 lut 2022 o 02:32 Per Bothner <> 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(
> >          at gnu.bytecode.Label.define(
> >          at gnu.expr.LambdaExp.compileEnd(
> >          at gnu.expr.LambdaExp.compileAsInlined(
> >          at gnu.expr.ApplyExp.compile(
> >          ...
> >          at gnu.expr.ModuleExp.evalModule1(
> >          at
> >          at
> >          at kawa.repl.processArgs(
> >          at kawa.repl.main(
> >
> > 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:

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

> 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,

  reply	other threads:[~2022-02-25 16:27 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-24 21:49 Panicz Maciej Godek
2022-02-25  1:31 ` Per Bothner
2022-02-25 16:26   ` Panicz Maciej Godek [this message]
2022-02-25 17:11     ` Per Bothner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='' \ \ \ \

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).