wren icon indicating copy to clipboard operation
wren copied to clipboard

Calling a no-parameters function with a parameter

Open andraaspar opened this issue 5 years ago • 9 comments

It seems like omitting a parameter in a function definition causes variables in the function body to take parameter values.

var f=Fn.new{
  var a=1
  System.print(a)
}
f.call(2) // 2

andraaspar avatar Feb 21 '20 15:02 andraaspar

(Not sure if this issue still exists, I'm using Wren in TIC-80 and that may be outdated. Sorry if it's old news.)

andraaspar avatar Feb 21 '20 15:02 andraaspar

This looks like it is still present in 0.2.0

From the docs: It is a runtime error if the number of arguments given is less than the arity of the function. If more arguments are given than the function’s arity they are ignored.

Unfortunately that last part doesn't seem to be true.

avivbeeri avatar Feb 21 '20 15:02 avivbeeri

Tip: you can try the latest version of Wren in your browser at https://wren.io/try.

What you see is a bug: the arguments are stored in the stack. According to the docs, superfluous arguments should be ignored, by it seems like they're actually passed and overwrite the local variables (which are on the stack too).

ChayimFriedman2 avatar Aug 10 '20 12:08 ChayimFriedman2

This is a known issue and will hopefully be addressed in 0.4.0 in some form.

ruby0x1 avatar Sep 18 '20 19:09 ruby0x1

Is this the same cause as the famous stack corruption issue?

ChayimFriedman2 avatar Sep 20 '20 17:09 ChayimFriedman2

It is, I tested with main branch and it doesn't seems to trigger the issue anymore. I suspect the stack error can still occurs if a foreign function triggers a stack resize using wrenEnsureSlots but it should be less lot visible than the issue seen there.

mhermier avatar Sep 20 '20 17:09 mhermier

Note that only one call type has been fixed by the other bug fix. This issue is still present on the other form.

ruby0x1 avatar Sep 25 '20 16:09 ruby0x1

Note also that, whilst this bug still occurs in 0.4.0 if you pass a function to a method:

(1..1).each {
    var a 
    System.print(a) // 1 rather than null
}

thankfully, it doesn't occur with fibers:

Fiber.new {
    var a
    System.print(a) // null rather than 1
}.call(1)

This is probably because the function passed to the fiber is special in that it can take at most a single argument and you can still call it with an argument even when none is specified in order to give Fiber.yield a return value.

var f = Fiber.new {
    var a
    System.print(a) // null rather than 1
    System.print(Fiber.yield()) // 2
}

f.call(1)
f.call(2)

PureFox48 avatar Nov 29 '22 16:11 PureFox48

Fixed with #1124. With a new fresh view, I found it pretty quickly. The ObjFn::arity was not used in wrenCallFunction resulting in approximative ObjFiber::stackTop adjustments. Fixing that exposed an secondary issue where ObjFn::arity was not set for all the ObjFn produced by the compiler. Fixing all these resolved issue and pass all the tests.

mhermier avatar Nov 29 '22 23:11 mhermier