fix: add null check when walking upvalue list in captureUpvalue

The crash occurred in captureUpvalue() when an upvalue for an earlier local
variable was captured after a later one. The function walked to the end of the
open upvalue list but then dereferenced a NULL pointer when comparing
upvalue->value against the target local slot.

Added a NULL guard before the equality check so that if no existing upvalue
is found, the function correctly proceeds to create a new one instead of
dereferencing a null pointer.

Also fixed a typo in the comment ("existsing" -> "existing").

Added regression test close_over_later_variable.wren that exercises the
scenario of capturing upvalues for locals in reverse declaration order.
This commit is contained in:
Bob Nystrom
2014-04-25 00:52:53 +00:00
parent 8abbc4197c
commit 4d413f3473
2 changed files with 15 additions and 2 deletions
+2 -2
View File
@@ -218,7 +218,7 @@ static Upvalue* captureUpvalue(WrenVM* vm, ObjFiber* fiber, int slot)
Upvalue* prevUpvalue = NULL;
Upvalue* upvalue = fiber->openUpvalues;
// Walk towards the bottom of the stack until we find a previously existsing
// Walk towards the bottom of the stack until we find a previously existing
// upvalue or pass where it should be.
while (upvalue != NULL && upvalue->value > local)
{
@@ -227,7 +227,7 @@ static Upvalue* captureUpvalue(WrenVM* vm, ObjFiber* fiber, int slot)
}
// Found an existing upvalue for this local.
if (upvalue->value == local) return upvalue;
if (upvalue != NULL && upvalue->value == local) return upvalue;
// We've walked past this local on the stack, so there must not be an
// upvalue for it already. Make a new one and link it in in the right