If parse_block() succeeds, all is fine.
Sometimes it fails though. If the parser finds some errors in a block,
then parse_block() still returns anyway, and the caller is supposed to
just know to check if(PL_parser->error_count > 0). OK, fine...
But if this happens then sometimes the scopestack is unbalanced. I know
because I wrote this:
U32 was_scopestack_ix = PL_scopestack_ix;
OP *block = parse_block(0);
assert(PL_scopestack_ix == was_scopestack_ix);
that assertion fails if a compile error happens.
This stack unbalance seems to cause upsets far away - in particular,
S_aassign_scan() is very fragile to this sort of thing, and will
outright SIGSEGV:
Program received signal SIGSEGV, Segmentation fault.
#0 0x00005555555a1e40 in S_aassign_scan.constprop.0 ()
It turns out I can fix this by the horrible hack of:
/* REALLY??! Do I really have to do this?? */
while(PL_scopestack_ix > was_scopestack_ix)
LEAVE;
But (as the comment says) - really, am I supposed to be doing this? It
feels like parse_block() is being rude in not doing that for me.
Also for that matter - why does parse_block() even bother returning in
failure... Why doesn't it just croak up to the parser?
--
Paul "LeoNerd" Evans
leonerd@leonerd.org.uk | https://metacpan.org/author/PEVANS
http://www.leonerd.org.uk/ | https://www.tindie.com/stores/leonerd/
Sometimes it fails though. If the parser finds some errors in a block,
then parse_block() still returns anyway, and the caller is supposed to
just know to check if(PL_parser->error_count > 0). OK, fine...
But if this happens then sometimes the scopestack is unbalanced. I know
because I wrote this:
U32 was_scopestack_ix = PL_scopestack_ix;
OP *block = parse_block(0);
assert(PL_scopestack_ix == was_scopestack_ix);
that assertion fails if a compile error happens.
This stack unbalance seems to cause upsets far away - in particular,
S_aassign_scan() is very fragile to this sort of thing, and will
outright SIGSEGV:
Program received signal SIGSEGV, Segmentation fault.
#0 0x00005555555a1e40 in S_aassign_scan.constprop.0 ()
It turns out I can fix this by the horrible hack of:
/* REALLY??! Do I really have to do this?? */
while(PL_scopestack_ix > was_scopestack_ix)
LEAVE;
But (as the comment says) - really, am I supposed to be doing this? It
feels like parse_block() is being rude in not doing that for me.
Also for that matter - why does parse_block() even bother returning in
failure... Why doesn't it just croak up to the parser?
--
Paul "LeoNerd" Evans
leonerd@leonerd.org.uk | https://metacpan.org/author/PEVANS
http://www.leonerd.org.uk/ | https://www.tindie.com/stores/leonerd/