janet-lang / janet

A dynamic language and bytecode vm
https://janet-lang.org
MIT License
3.38k stars 217 forks source link

Splicing a tuple into an indexed literal causes subsequent form to compile incorrectly #1330

Closed ianthehenry closed 7 months ago

ianthehenry commented 8 months ago

Interesting bug where it seems like a splice is persisting after the expression it occurs in. This program:

(defn main [&]
  (def a [1 2 3])
  (def b [;a])
  (pp a))

Raises with error: <function pp> called with 4 arguments, expected 1. Commenting out the line with the splice causes it to work as expected.

Tested on Janet 1.32.1-cc5beda0 macos/aarch64/clang.

The following variations do not have the bug:

(defn main [&]
  (def a [1 2 3])
  (def b (tuple ;a))
  (pp a))

(defn main [&]
  (def a [1 2 3])
  (def b [;[1 2 3]])
  (pp a))

(defn main [&]
  (def a @[1 2 3])
  (def b [;a])
  (pp a))

Though this one also fails:

(defn main [&]
  (def a [1 2 3])
  (def b @[;a])
  (pp a))
sogaiu commented 8 months ago

Confirmed in Janet 1.32.1-56f33f51 linux/x64/gcc and Janet 1.32.1-9593c930 linux/x64/gcc.

sogaiu commented 8 months ago

Fails in:

Works ok in:

May be it's https://github.com/janet-lang/janet/commit/fcca9bbab3d64ed51259745dec2dfaffcc20c3d1, as the commit before it, dbb21874, seems to be ok.

bakpakin commented 7 months ago

Pushed a fix in a9176a77e6a93a5e10b5c069e9b1c88d4b25e40e - the issue seems to be that certain bytecode instructions were being aggressively optimized out despite have side effects (clearing the call stack), making the next function call get extra arguments.

sogaiu commented 7 months ago

All of the reported examples work fine here now :+1: