bug: compiled function behaves differently than interpreted

[email protected] Fri, 13 Dec 2024 19:44:33 -0000
Newsgroups gmane.editors.j.devel
Message-ID <173411907382.26.6704038610308829836__44709.7768237413$1734119112$gmane$org@mailman-web>
I initially discovered this in 1.9.2 with slime and all that, but I reproduced this on a build of d0a525323b640223bacfb17cde59db995f43cce9 from GitHub with ./abcl --noinit.  I don't have a completely minimized case, but it's pretty small.

uname -a:
Darwin sew-MBA.local 24.1.0 Darwin Kernel Version 24.1.0: Thu Oct 10 21:05:14 PDT 2024; root:xnu-11215.41.3~2/RELEASE_ARM64_T8103 arm64

Reproduction:
Armed Bear Common Lisp 1.9.3-dev
Java 23.0.1 Homebrew
OpenJDK 64-Bit Server VM
Low-level initialization completed in 0.158 seconds.
Startup completed in 0.698 seconds.
Type ":help" for a list of available commands.
CL-USER(1): (setq class (jcall "arrayType" (jstatic "forPrimitiveName" "java.lang.Class" "float")))
#<java.lang.Class class [F {6290834B}>
CL-USER(2): (defun represent (class)
  (cond
    ((jcall "isPrimitive" class)
     (intern (string-upcase (jcall "getName" class)) "KEYWORD"))
    ((jcall "isArray" class)
     (list :array (represent (jcall "componentType" class))))
    (t (jcall "getName" class))))
REPRESENT
CL-USER(3): (represent class)
(:ARRAY :FLOAT)
CL-USER(4): (compile 'represent)
REPRESENT
NIL
NIL
CL-USER(5): (represent class)
:FLOAT
:EXTERNAL
CL-USER(6): 

I think the interpreted result is correct, but either way it seems like a bug that they're different.

My story gets stranger.  I tried to reproduce it with DRIBBLE (for this email) and I couldn't:


COMMON-LISP-USER> (setq class (jcall "arrayType" (jstatic "forPrimitiveName" "java.lang.Class" "float")))

#<java.lang.Class class [F {194B1E17}> 
COMMON-LISP-USER> (defun represent (class)
  (cond
    ((jcall "isPrimitive" class)
     (intern (string-upcase (jcall "getName" class)) "KEYWORD"))
    ((jcall "isArray" class)
     (list :array (represent (jcall "componentType" class))))
    (t (jcall "getName" class))))

REPRESENT 
COMMON-LISP-USER> (represent class)

(:ARRAY :FLOAT) 
COMMON-LISP-USER> (compile 'represent)

REPRESENT 
COMMON-LISP-USER> (represent class)

(:ARRAY :FLOAT) 
COMMON-LISP-USER> (dribble)


If it's any help, I tried re-implementing the function a number of ways, and this was the first one I found that didn't exhibit the problem:
(defun represent (class)
  (if (jcall "isArray" class)
      (let*((component (jcall "componentType" class))
            (mangled (represent component)))
        (list :array mangled))
      (let ((classname (jcall "getName" class)))
        (if (jcall "isPrimitive" class)
            (alexandria:make-keyword (string-upcase classname))
            (jcall "getName" class)))))

Thanks all!