pmatos / nora

An experimental Racket implementation using LLVM/MLIR

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Closure test crashes nora

pmatos opened this issue · comments

The following test crashes nora:

;; RUN: norac %s | FileCheck %s
;; CHECK: 12
(linklet () ()
  (define-values (fn) (values 0))
  (let-values (((x) (values 2)))
     (set! fn (lambda (y) (+ x y))))
  (let-values (((x) (values 3)))
     (fn 10)))

There's a warning from ubsan as well:

Cannot set undefined identifier.
Expected lambda expression in Application.
/home/pmatos/dev/nora/src/include/interpreter.h:43:52: runtime error: member call on null pointer of type 'ast::ValueNode'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /home/pmatos/dev/nora/src/include/interpreter.h:43:52 in
UndefinedBehaviorSanitizer:DEADLYSIGNAL
==23846==ERROR: UndefinedBehaviorSanitizer: SEGV on unknown address 0x000000000000 (pc 0x56310e36d3d7 bp 0x7ffebfb63690 sp 0x7ffebfb63650 T23846)
==23846==The signal is caused by a READ memory access.
==23846==Hint: address points to the zero page.
    #0 0x56310e36d3d7 in Interpreter::getResult() const /home/pmatos/dev/nora/src/include/interpreter.h:43:52
    #1 0x56310e36cae7 in main /home/pmatos/dev/nora/src/main.cpp:53:26
    #2 0x7f2ef4c3c78f  (/usr/lib/libc.so.6+0x2378f) (BuildId: 4a4bec3d95a1804443e852958fe59ed461135ce9)
    #3 0x7f2ef4c3c849 in __libc_start_main (/usr/lib/libc.so.6+0x23849) (BuildId: 4a4bec3d95a1804443e852958fe59ed461135ce9)
    #4 0x56310e33aa74 in _start (/home/pmatos/dev/nora/build/bin/norac+0x164a74) (BuildId: ff1360b6f90819159bf3d99f7e8a9ddb2f700ae2)

UndefinedBehaviorSanitizer can not provide additional info.
SUMMARY: UndefinedBehaviorSanitizer: SEGV /home/pmatos/dev/nora/src/include/interpreter.h:43:52 in Interpreter::getResult() const
==23846==ABORTING

I also think that even once this is fixed nora will print 13, rather than 12.

So we need to implement closures. We can define a function isClosure on a lambda that returns true if the lambda body has free variables. If so, it self-transforms the Lambda instance to a Closure instance that has an attached environment. When the Closure instance is interpreted, the environment containing the free variables in the Lambda body are captured.

Fixed by 050ba79