justinethier / cyclone

:cyclone: A brand-new compiler that allows practical application development using R7RS Scheme. We provide modern features and a stable system capable of generating fast native binaries.
http://justinethier.github.io/cyclone/
MIT License
823 stars 42 forks source link

Strange behaviour with (c-define ...) on master (after v0.26) #449

Closed arthurmaciel closed 3 years ago

arthurmaciel commented 3 years ago

@justinethier, could you please check if you also get this error with master?

(import (scheme base)
        (scheme write)
        ;; (cyclone foreign)
        )

(c-define scm-strlen int "strlen" string)

(define (fib n)
  (if (< n 2)
      n
      (+ (fib (- n 1)) (fib (- n 2)))))

(display (fib 20))

On v0.25:

$ cyclone /tmp/b.scm
$ /tmp/b
6765%   # <-- here this percentage sign is always printed
# Note also that even with `(cyclone foreign)` commented out, it works

On v0.26:

$ cyclone /tmp/b.scm
/tmp/b.c: In function ‘__lambda_1’:
/tmp/b.c:471:38: error: ‘__glo_scm_91strlen’ undeclared (first use in this function)
  471 | return_closcall3(data,  define_91c,  __glo_scm_91strlen, &c_7335, &c_7336);;;
      |                                      ^~~~~~~~~~~~~~~~~~
/tmp/b.c:119:30: note: in definition of macro ‘return_closcall3’
  119 |      object buf[3]; buf[0] = a1;buf[1] = a2;buf[2] = a3;\
      |                              ^~
/tmp/b.c:471:38: note: each undeclared identifier is reported only once for each function it appears in
  471 | return_closcall3(data,  define_91c,  __glo_scm_91strlen, &c_7335, &c_7336);;;
      |                                      ^~~~~~~~~~~~~~~~~~
/tmp/b.c:119:30: note: in definition of macro ‘return_closcall3’
  119 |      object buf[3]; buf[0] = a1;buf[1] = a2;buf[2] = a3;\
      |                              ^~
/tmp/b.c:471:25: error: ‘define_91c’ undeclared (first use in this function)
  471 | return_closcall3(data,  define_91c,  __glo_scm_91strlen, &c_7335, &c_7336);;;
      |                         ^~~~~~~~~~
/tmp/b.c:120:13: note: in definition of macro ‘return_closcall3’
  120 |      GC(td, clo, buf, 3); \
      |             ^~~
justinethier commented 3 years ago

Interesting, on master I am getting intermittent behavior between the error you noted above and the crash from issue #448

Well, sorry about all this. Let me spend some time getting this sorted out and stabilized...

arthurmaciel commented 3 years ago

@justinethier, I had the exact same code working with v0.26 recently. git bisect tells me here it might be the commit:

[c82e69a997dd3bb02ad2e59515937428ba9379ae] Added import-shared-object

justinethier commented 3 years ago

Looks like an issue with a compiler optimization that was recently re-enabled by patching the compiler to call record? instead of vector? to test for AST objects. Anyway -

Here is the default behavior, the compiler crashes every time:

justin@justin-OptiPlex-790 ~/Documents/cyclone $ cyclone   issue-449.scm
gc_move: bad tag obj=0x7fffd9b5f6c0 obj.tag=176
justin@justin-OptiPlex-790 ~/Documents/cyclone $ cyclone   issue-449.scm
gc_move: bad tag obj=0x7fffae714b40 obj.tag=238
justin@justin-OptiPlex-790 ~/Documents/cyclone $ cyclone   issue-449.scm
gc_move: bad tag obj=0x7ffc5e3eafa0 obj.tag=73
justin@justin-OptiPlex-790 ~/Documents/cyclone $ cyclone   issue-449.scm
gc_move: bad tag obj=0x7ffdac77ad70 obj.tag=139

On the other hand when we explicitly disable the optimization everything works fine:

justin@justin-OptiPlex-790 ~/Documents/cyclone $ cyclone  -no-memoization-optimizations  issue-449.scm
justin@justin-OptiPlex-790 ~/Documents/cyclone $ ./issue-449
6765justin@justin-OptiPlex-790 ~/Documents/cyclone $ cyclone  -no-memoization-optimizations  issue-449.scm
justin@justin-OptiPlex-790 ~/Documents/cyclone $ ./issue-449
6765justin@justin-OptiPlex-790 ~/Documents/cyclone $

The next step is to dig into that optimization and figure out how the compiler is broken so bad to both introduce a runtime GC failure as well as the C compilation error.

justinethier commented 3 years ago

Selectively disable optimizations that are not compatible with top-level define-c forms.

The reason why c-define still works even without the import is due to cyclone.scm importing the cgen module, which in turn imports (cyclone foreign). So the macro is compiled into the executable. I believe we can remove those dependencies, though, let me take a look...

justinethier commented 3 years ago

OK, compilation breaks without that dependency:

cyclone -A . scheme/cyclone/cgen.sld
Error: Unbound variable(s):
(c->scm)
justinethier commented 3 years ago

For now at least the cyclone foreign macros will be available at compile time even without the import. We may want to revisit this behavior in the future.

That aside, these compilation issues should now be resolved on master.

arthurmaciel commented 3 years ago

Thanks, @justinethier! It is working perfectly now.

With regard to (cyclone foreign) being available at compile time, maybe in the future we could rename all of its procedures and marcos with low-level names and the (cyclone foreign) itself could be just a re-exporting of them with the current names.