This is the mail archive of the kawa@sourceware.org mailing list for the Kawa project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: GSOC | Extending Common Lisp support


On 21 June 2012 05:30, Jamison Hope <jrh@theptrgroup.com> wrote:
> $ svn diff gnu/expr/Declaration.java

Thanks, this solves the module export problem. Per, you're code didn't
help the module export problem for me (probably I misunderstood your
input).

> Anyway, with any of those changes in place, #'do and #'case run without
> compilation error, but they give the wrong answers.

I can get the right answer for the case example with my change below,
DO is behaving in a confusing way for me still.

> Note that falsehood in CL is checked by comparing for object equality
> with EmptyList.emptyList. However, IsEqv#apply2 performs
>
> Âpublic Object apply2 (Object arg1, Object arg2)
> Â{
> Â Âreturn language.booleanObject(apply(arg1, arg2));
> Â }
>
> using the language from its constructor -- in this case, Scheme. So,
> Boolean.FALSE != EmptyList.emptyList, and false becomes true.

So what I think we'd want is instead of IsEqv, IsEq's apply2 method
calling language.booleanType, we'd rather have
Language.getDefault().booleanType. That's a problem because when the
primitives.lisp file is being evaluated, we haven't finished setting
up the Language environment from the common-line parameters. You get
around this for CL by add the following line to initLisp() (which is
eventually called from the repl.java setup when it invokes
Language.getInstance().

Language.setCurrentLanguage(this);

Then we dispatch to the correct booleanType method in Lisp2 and the
correct answer is obtained for the case example. DO is emitting (to me
at least) some very weird bytecode. Since you need to have fiddled
with the module export stuff to get these results, I'll post the
disassembly here (sorry for the long message)

Scheme first:

#|kawa:1|# (define (f) (do ((i 1 (+ i 1))) ((= i 10) 'fin) (display i)))
#|kawa:2|# (disassemble f)
In class atInteractiveLevel$1

Method name:"f" public static Signature: ()java.lang.Object
Attribute "Code", length:89, max_stack:3, max_locals:1, code_length:31
  0: getstatic <Field atInteractiveLevel$1.Lit0 gnu.math.IntNum>
  3: astore_0
  4: aload_0
  5: bipush 10
  7: i2l
  8: invokestatic <Method gnu.math.IntNum.compare (gnu.math.IntNum,long)int>
 11: ifeq 27
 14: aload_0
 15: invokestatic <Method kawa.lib.ports.display (java.lang.Object)void>
 18: aload_0
 19: iconst_1
 20: invokestatic <Method gnu.math.IntNum.add
(gnu.math.IntNum,int)gnu.math.IntNum>
 23: astore_0
 24: goto 4
 27: getstatic <Field atInteractiveLevel$1.Lit1 gnu.mapping.SimpleSymbol>
 30: areturn
Attribute "StackMapTable", length:10, number of entries: 3
  offset: 4 - append_frame - define 1 more locals
    0: gnu.math.IntNum
  offset: 14 - same_frame
  offset: 27 - same_frame
Attribute "LineNumberTable", length:6, count: 1
  line: 1 at pc: 0
Attribute "LocalVariableTable", length:12, count: 1
  slot#0: name: i, type: gnu.math.IntNum (pc: 4 length: 26)

That wasn't surprising. Contrast with CL:

#|kawa:1|# (defun f () (do ((i 1 (+ i 1))) ((= i 10) 'fin) (display i)))
#|kawa:2|# (disassemble #'f)
In class atInteractiveLevel$1

Method name:"f" public static Signature: ()java.lang.Object
Attribute "Code", length:169, max_stack:5, max_locals:1, code_length:71
  0: getstatic <Field atInteractiveLevel$1.Lit0 gnu.math.IntNum>
  3: astore_0
  4: getstatic <Field atInteractiveLevel$1.loc$not gnu.mapping.Location>
  7: invokevirtual <Method gnu.mapping.Location.get ()java.lang.Object>
 10: invokestatic <Method gnu.mapping.Promise.force
(java.lang.Object)java.lang.Object>
 13: checkcast <Class gnu.mapping.Procedure>
 16: aload_0
 17: bipush 10
 19: i2l
 20: invokestatic <Method gnu.math.IntNum.compare (gnu.math.IntNum,long)int>
 23: ifne 32
 26: getstatic <Field atInteractiveLevel$1.Lit1 java.lang.Boolean>
 29: goto 35
 32: getstatic <Field atInteractiveLevel$1.Lit2 java.lang.Boolean>
 35: invokevirtual <Method gnu.mapping.Procedure.apply1
(java.lang.Object)java.lang.Object>
 38: getstatic <Field atInteractiveLevel$1.Lit3 gnu.lists.EmptyList>
 41: if_acmpeq 57
 44: aload_0
 45: invokestatic <Method kawa.lib.ports.display (java.lang.Object)void>
 48: aload_0
 49: iconst_1
 50: invokestatic <Method gnu.math.IntNum.add
(gnu.math.IntNum,int)gnu.math.IntNum>
 53: astore_0
 54: goto 4
 57: getstatic <Field atInteractiveLevel$1.Lit4 gnu.mapping.SimpleSymbol>
 60: areturn
 61: dup
 62: ldc <String "/dev/stdin">
 64: iconst_1
 65: bipush 13
 67: invokevirtual <Method
gnu.mapping.UnboundLocationException.setLine
(java.lang.String,int,int)void>
 70: athrow
Exceptions (count: 1):
  start: 7, end: 10, handler: 61, type: gnu.mapping.UnboundLocationException
Attribute "StackMapTable", length:42, number of entries: 8
  offset: 4 - append_frame - define 1 more locals
    0: gnu.math.IntNum
  offset: 10 - same_locals_1_stack_item_frame
    0: java.lang.Object
  offset: 26 - same_locals_1_stack_item_frame
    0: gnu.mapping.Procedure
  offset: 32 - same_locals_1_stack_item_frame
    0: gnu.mapping.Procedure
  offset: 35 - full_frame.  Locals count: 1
    0: gnu.math.IntNum
    (end of locals)         Stack count: 2
    0: gnu.mapping.Procedure
    1: java.lang.Boolean
  offset: 44 - same_frame
  offset: 57 - same_frame
  offset: 61 - same_locals_1_stack_item_frame
    0: gnu.mapping.UnboundLocationException
Attribute "LineNumberTable", length:6, count: 1
  line: 1 at pc: 0
Attribute "LocalVariableTable", length:12, count: 1
  slot#0: name: i, type: gnu.math.IntNum (pc: 4 length: 56)

Why is line 4 getting changed from aload_0 to a get/force/cast dance?
I decided to look at the out of --debug-print-expr. For Scheme, we
get:

[Module:atInteractiveLevel$1
(Module/atInteractiveLevel$1/1/
* (Declarations: f/15/fl:408c8::gnu.mapping.Procedure)
  (Define line:1:1 /Declaration[f/15]
    (Lambda/f/5/fl:0 line:1:9 ()
      (Let#15 line:1:13
        ((%do%loop/56/fl:40048(ignorable) = (Quote #!undefined)))
        (Begin line:1:13
          (Set /Declaration[%do%loop/56]
            (Lambda/23/fl:0 (i/62/fl:40040(ignorable))
*             (If (Apply (Ref/27/Declaration[applyToArgs/2])
*                   (Ref/23/Declaration[not/72])
                    (Apply line:1:33 (Ref/26/Declaration[applyToArgs/2])
                      (Ref/24/Declaration[=/78])
                      (Ref/25/Declaration[i/62])
                      (Quote 10)))
                (Begin line:1:49
                  (Apply line:1:49 (Ref/33/Declaration[applyToArgs/2])
                    (Ref/31/Declaration[display/114])
                    (Ref/32/Declaration[i/62]))
                  (Apply (Ref/39/Declaration[applyToArgs/2])
                    (Ref/34/Declaration[%do%loop/56])
                    (Apply line:1:23 (Ref/38/Declaration[applyToArgs/2])
                      (Ref/36/Declaration[+/132])
                      (Ref/37/Declaration[i/62])
                      (Quote 1))))
                (Begin line:1:13  (Quote #!void ::void) (Quote fin)))))
          (Apply (Ref/45/Declaration[applyToArgs/2])
            (Ref/43/Declaration[%do%loop/56])
            (Quote 1)))))))]

The lines marked with an asterix indicate points of difference between
that and the corresponding output for CL:

[Module:atInteractiveLevel$1
(Module/atInteractiveLevel$1/1/ (Declarations: f/2/fl:8c2)
*
  (Define line:1:1 /Declaration[f/2]
    (Lambda/f/2/fl:0 line:1:10 ()
      (Let#13 line:1:13
        ((%do%loop/54/fl:40048(ignorable) = (Quote #!undefined)))
        (Begin line:1:13
          (Set /Declaration[%do%loop/54]
            (Lambda/20/fl:0 (i/57/fl:40040(ignorable))
 *            (If (Apply (Ref/22/not)
 *                  (Apply line:1:33 (Ref/23/Declaration[=/60])
 *                    (Ref/24/Declaration[i/57])
                      (Quote 10)))
                (Begin line:1:49
                  (Apply line:1:49 (Ref/28/Declaration[display/89])
                    (Ref/29/Declaration[i/57]))
                  (Apply (Ref/30/Declaration[%do%loop/54])
                    (Apply line:1:23 (Ref/32/Declaration[+/107])
                      (Ref/33/Declaration[i/57])
                      (Quote 1))))
                (Begin line:1:13  (Quote #!void ::void) (Quote fin)))))
          (Apply (Ref/37/Declaration[%do%loop/54]) (Quote 1)))))))]

I know that I can transform the CL output to look a bit closer to the
Scheme output by moving the SchemeCompilation#makeApply method and
associated applyFieldDecl up into Translator so that Lisp2Compilation
can use applyToArgs.

The output of CL is now:

[Module:atInteractiveLevel$1
(Module/atInteractiveLevel$1/1/ (Declarations: f/3/fl:8c2)
*
  (Define line:1:1 /Declaration[f/3]
    (Lambda/f/2/fl:0 line:1:10 ()
      (Let#13 line:1:13
        ((%do%loop/55/fl:40048(ignorable) = (Quote #!undefined)))
        (Begin line:1:13
          (Set /Declaration[%do%loop/55]
            (Lambda/20/fl:0 (i/58/fl:40040(ignorable))
              (If (Apply (Ref/26/Declaration[applyToArgs/2])
*                   (Ref/22/not)
                    (Apply line:1:33 (Ref/25/Declaration[applyToArgs/2])
                      (Ref/23/Declaration[=/61])
                      (Ref/24/Declaration[i/58])
                      (Quote 10)))
                (Begin line:1:49
                  (Apply line:1:49 (Ref/32/Declaration[applyToArgs/2])
                    (Ref/30/Declaration[display/90])
                    (Ref/31/Declaration[i/58]))
                  (Apply (Ref/38/Declaration[applyToArgs/2])
                    (Ref/33/Declaration[%do%loop/55])
                    (Apply line:1:23 (Ref/37/Declaration[applyToArgs/2])
                      (Ref/35/Declaration[+/108])
                      (Ref/36/Declaration[i/58])
                      (Quote 1))))
                (Begin line:1:13  (Quote #!void ::void) (Quote fin)))))
          (Apply (Ref/44/Declaration[applyToArgs/2])
            (Ref/42/Declaration[%do%loop/55])
            (Quote 1)))))))]

So I'm still missing the (Declarations:
f/15/fl:408c8::gnu.mapping.Procedure) line, and more importantly,
instead of (Ref/23/Declaration[not/72]) in Scheme, I have only
(Ref/22/not) in CL. I can't yet explain why this is causing the
problem, nor can I yet explain how to transform the latter into the
former, but my hunch is that it is this difference that is causing the
problem.

Charles.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]