public inbox for kawa@sourceware.org
 help / color / mirror / Atom feed
* java.lang.RuntimeException: invoke: no method named `$000a' in class gnu.expr.PrimProcedure
@ 2022-02-28 23:10 Panicz Maciej Godek
  2022-03-01  0:19 ` Per Bothner
  0 siblings, 1 reply; 2+ messages in thread
From: Panicz Maciej Godek @ 2022-02-28 23:10 UTC (permalink / raw)
  To: kawa

I have a new problem. When I invoke a function, I get the following error:

java.lang.RuntimeException: invoke: no method named `$000a' in class
gnu.expr.PrimProcedure

The definition of the function is a bit complex, but I'll paste it here
anyway:

(define (cursor-under left::real top::real elems
   #!key (screen::Screen (current-screen)) (context::Cursor '()))
  ::Cursor
  (let ((box (extent elems screen))
        (max-width 0)
        (max-line-height (screen:min-line-height))
        (side 0)
        (ceiling 0)
        (index (first-index elems)))

    (define (check-spaces! spaces::string)::Cursor
      (WARN "check-spaces! (" spaces")")
      (call/cc
       (lambda (return)
         (for i from 0 below (length spaces)
           (WARN i)
           (cond ((eq? (spaces i) #\newline)
                  (set! ceiling (+ ceiling max-line-height))
                  (when (is top < ceiling)
                    (return (recons* i index context)))
                  (set! side 0)
                  (set! max-line-height (screen:min-line-height)))
                 (else
                  (set! side (+ side 1))
                  (when (and (is side < left <= (+ side 1))
                             (is top <= max-line-height))
                     (return (recons* i index context)))
                  (set! max-width (max max-width side)))))
         (set! index (next-index index elems))
         #!null)))

    (define (advance! extent::Extent)::Null
      (WARN "advance!" extent)
      (set! side (+ side extent:width))
      (set! max-line-height (max extent:height max-line-height))
      (set! max-width (max side max-width))
      (set! index (next-index index elems))
      #!null)

    (define (check! part extent::Extent)::Cursor
      (WARN "check!" part extent)
      (if (and (is side <= left <= (+ side extent:width))
               (is ceiling <= top <= (+ ceiling extent:height)))
         (let ((cursor (recons index context)))
           (or (and (pair? part)
               (cursor-under (- left side)
                             (- top ceiling)
                             part
                             screen: screen
                             context: cursor))
               cursor))
        (advance! extent)))

    (define (check-separating-bar! pair)::Cursor
      (WARN "check-separating-bar!" pair)
      (cond ((should-the-bar-be-horizontal? pair)
             (let ((bar-height (screen:horizontal-bar-height)))
               (if (is ceiling <= top <= (+ ceiling bar-height))
                  (recons index context)
                 (advance! (Extent width: 0
                                   height: bar-height)))))
            (else
             (let ((bar-width (screen:vertical-bar-width)))
               (if (is side <= left (+ side bar-width))
                   (recons index context)
                 (advance! (Extent width: bar-width
                                   height: 0)))))))

    (define (check-next! pair)::Cursor
      (WARN "check-next!" pair)
      (or (check! (head pair) (head-extent pair screen))
          (check-spaces! (post-head-space pair))
          (and (dotted? pair)
               (or (check-separating-bar! pair)
                   (check-spaces! (pre-tail-space pair))
          (check! (tail pair) (tail-extent pair screen))
          (check-spaces! (post-tail-space pair))))
          (and (pair? pair)
               (check-next! pair))))

    (or (and (is 0 <= left < (screen:paren-width))
             (is 0 <= top < box:height)
             (recons index context))
        (check-spaces! (pre-head-space elems))
        (check-next! elems)
        (and (is (- box:width (screen:paren-width)) <= left <= box:width)
             (is 0 <= top < box:height)
             (recons index context))
        #!null)))

According to my diagnostic messages, the exception comes from the
"check-spaces!" subroutine: I only see the first message printed, and the
remaining ones aren't there.

"for" is a macro defined in the following way:

https://github.com/panicz/grasp-android/blob/master/stages/retreat/GRASP/src/for.scm

The above usage should correspond to the last syntax-rule

    ((_ var from start below end actions ...)
     (let loop ((var start))
       (if (< var end)
         (begin
           actions ...
           (loop (+ var 1))))))

and it hasn't been problematic (it works fine on small test cases in the
REPL).

I've noticed a few things that eplacing (length spaces) with (string-length
spaces) somewhat fixes the problem (the value of spaces in the context of
the bug is "\n"), but there appears to be another problem: the for-loop
never terminates and the value of i is always 0.

I suppose there could be some bug in the treatment of continuations when
call/cc appears in the body of a method (but it's only a hypothesis).

Anyway, I wonder if Kawa provides a way of performing an early return from
a method (other than call/cc)?

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

* Re: java.lang.RuntimeException: invoke: no method named `$000a' in class gnu.expr.PrimProcedure
  2022-02-28 23:10 java.lang.RuntimeException: invoke: no method named `$000a' in class gnu.expr.PrimProcedure Panicz Maciej Godek
@ 2022-03-01  0:19 ` Per Bothner
  0 siblings, 0 replies; 2+ messages in thread
From: Per Bothner @ 2022-03-01  0:19 UTC (permalink / raw)
  To: Panicz Maciej Godek, kawa



On 2/28/22 15:10, Panicz Maciej Godek via Kawa wrote:
> I have a new problem. When I invoke a function, I get the following error:
> 
> java.lang.RuntimeException: invoke: no method named `$000a' in class
> gnu.expr.PrimProcedure

This is an exception thrown by the 'invoke' procedure:

https://www.gnu.org/software/kawa/Method-operations.html#idm45230715888224

This is a way to explicitly call a Java method. 'invoke' can appear in user-code, and
sometimes the compiler generates call to it.  In this case it looks like the
compiler has translated some form to the equivalent of (invoke OBJECT '$000a ARGS ...).
With appropriate type information about OBJECT and the ARGS, in further steps
the compiler can translate this to an inline JVM invokexxx instruction,
but when it doesn't have the needed type information it will invoke at run-time.
The call to invoke should should up in the --debug-print-final-expr output.
Probably for some reason the method $000a isn't being generated or it
is generated in the wrong class.

> I suppose there could be some bug in the treatment of continuations when
> call/cc appears in the body of a method (but it's only a hypothesis).

Could well be.  Kawa will try to optimze call/cc when invoking and handling the
continuation are in the same method, but because Kawa does a lot of
inlining and other optimizations it could well have gotten confused.

> Anyway, I wonder if Kawa provides a way of performing an early return from
> a method (other than call/cc)?

Well you could use exceptions: primitive-throw with try-catch.  call/cc is
basically compiled into that anyway, except when it can be optimized to a goto.
-- 
	--Per Bothner
per@bothner.com   http://per.bothner.com/

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

end of thread, other threads:[~2022-03-01  0:20 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-28 23:10 java.lang.RuntimeException: invoke: no method named `$000a' in class gnu.expr.PrimProcedure Panicz Maciej Godek
2022-03-01  0:19 ` 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).