Open GoogleCodeExporter opened 8 years ago
TL;DR: there is a possible cause for this at the bottom of this update.
If I start with the r599 code base and edit parse.c to remove 4 lines of code,
the problem goes away. Functions ParseFor() and ParseBlock() contain the
following pattern at the head/tail; removing them suppresses the problem.
Head: int PrevScopeID = 0, ScopeID = VariableScopeBegin(Parser, &PrevScopeID);
Tail: VariableScopeEnd(Parser, ScopeID, PrevScopeID);
If I reenable those lines and add #define VAR_SCOPE_DEBUG to interpreter.h, I
get the following edited output:
Marks-iMac:picoc-test heilpern$ ./picoc -i
def uid_t 0 (unistd.h:1:12)
def gid_t 0 (unistd.h:1:31)
def pid_t 0 (unistd.h:1:50)
def off_t 0 (unistd.h:1:69)
def size_t 0 (unistd.h:1:88)
def ssize_t 0 (unistd.h:1:108)
def useconds_t 0 (unistd.h:1:129)
def intptr_t 0 (unistd.h:1:152)
def time_t 56957788 (time.h:1:12)
def clock_t 56957788 (time.h:1:32)
def va_list dac0dbf0 (stdio.h:1:31)
def FILE dac0dbf0 (stdio.h:1:68)
def bool 92c4ae4 (stdbool.h:1:12)
starting picoc v2.2 beta r599M
picoc> void a() {}
^
:1:
>>> out of scope: optopt 0 0
>>> out of scope: EIDRM 0 90
>>> out of scope: remove 0 1452638800
>>> out of scope: SEEK_CUR 0 1
[ many other symbols removed from this list, for brevity]
>>> out of scope: BUFSIZ 0 1024
>>> out of scope: clock 0 1452638800
>>> out of scope: setreuid 0 1452638800
picoc> printf("test\n");
^
:2: 'printf' is out of scope
picoc>
Probable root cause: in VariableScopeBegin, a "ScopeID" is generated and
returned. When run in interactive mode, Parser->SourceText (which is used to
generate the ID) is 0, leading to a 0 ScopeID. I am assuming that this is an
invalid scope ID and is instead assigned to all globals -- causing them to go
out of scope when the current scope (intended to be some block with a non-zero
scope id) closes its scope.
The full block of code at that location is:
Parser->ScopeID = (int)(intptr_t)(Parser->SourceText) * ((int)(intptr_t)(Parser->Pos) / sizeof(char*));
/* or maybe a more human-readable hash for debugging? */
/* Parser->ScopeID = Parser->Line * 0x10000 + Parser->CharacterPos; */
If I comment out the first line assigning the (0) ScopeID, and instead remove
the comments around the "human readable" line, my problem goes away.
Original comment by m...@heilpern.com
on 30 Oct 2013 at 7:04
One more comment… the code seems to want to set the ScopeID as a hash and
"hope for no collisions". It seems to me that the most straight forward way to
do this is to simply let Parser->ScopeID = OldScopeID. That is, since we can't
have two scopes using the same address for saving the previous scope (since the
only way to get that would include invalidating an old scope), there's no fancy
computation needed.
Original comment by m...@heilpern.com
on 30 Oct 2013 at 7:08
Original issue reported on code.google.com by
m...@heilpern.com
on 30 Oct 2013 at 5:44