Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fix crashes when trying to compile CORE:: name references
  • Loading branch information
sorear committed Oct 26, 2011
1 parent 3c4b14d commit 05b5bb6
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 1 deletion.
3 changes: 2 additions & 1 deletion lib/CodeGen.cs
Expand Up @@ -3800,7 +3800,7 @@ public class DowncallReceiver : CallReceiver {

if (file != null) {
for (SubInfo csr2 = from;
csr2.unit == from.unit && // modify this unit only
csr2.used_in_scope != null && // modify only open units
!csr2.used_in_scope.ContainsKey(lkey);
csr2 = csr2.outer, levels--) {

Expand Down Expand Up @@ -3862,6 +3862,7 @@ public class DowncallReceiver : CallReceiver {
ret.Add(kv.Key);
ret.Add(kv.Value.pos);
}
s.used_in_scope = null;
return ret.ToArray();
} else if (cmd == "unit_stubbed_stashes") {
RuntimeUnit u = (RuntimeUnit)Handle.Unbox(args[1]);
Expand Down
87 changes: 87 additions & 0 deletions src/niecza
Expand Up @@ -69,6 +69,93 @@ augment grammar STD::Regex {
}

augment grammar STD {
my package DEBUG { our constant symtab = 0 };
method is_name($longname, $curlex = $*CURLEX) {
my $deb = $*DEBUG +& DEBUG::symtab;
self.deb("is_name $longname") if $deb;
if defined($longname.index("::(")) {
self.deb("computed name gets a free pass") if $deb;
return True;
}
my @parts = $longname.split('::');
shift @parts if @parts[0] eq '';
pop @parts if @parts && @parts[*-1] eq ''; # doesn't change ref validity

@parts[*-1] = $/ ~ @parts[*-1] if @parts && @parts[0] ~~ s/^(\W\W?)//;

self.deb("reparsed: @parts.perl()") if $deb;
return True if !@parts;

my ($pkg, $sub);

given @parts[0] {
when 'OUR' {
$pkg = $curlex<!sub>.cur_pkg;
shift @parts;
goto "packagey";
}
when 'PROCESS' | 'GLOBAL' {
$pkg = $*unit.abs_pkg(shift @parts);
goto "packagey";
}
when 'MY' { $sub = $curlex<!sub>; goto "lexy"; }
when 'OUTER' { $sub = $curlex<!sub>.?outer; goto "lexy"; }
when 'UNIT' { $sub = $curlex<!sub>.?to_unit; goto "lexy"; }
when 'CORE' { $sub = $curlex<!sub>.?true_setting; goto "lexy"; }
when 'SETTING' { $sub = $curlex<!sub>.?to_unit.?outer; goto "lexy"; }

when 'COMPILING' | 'DYNAMIC' | 'CALLER' | 'CLR' { return True }

default {
my @lexical = self.lookup_lex(@parts[0], $curlex);
if !@lexical || @parts[0] eq 'PARENT' {
return False if @parts == 1; # $x doesn't mean GLOBAL
$pkg = (@parts[0] ~~ /^\W/) ??
$curlex<!sub>.cur_pkg !!
$*unit.abs_pkg('GLOBAL');
} elsif @lexical[0] eq 'package' {
$pkg = @lexical[4];
shift @parts;
} else {
return @parts == 1;
}
goto "packagey";
}
}

lexy:
shift @parts;
return False unless $sub;
return True unless @parts;
given @parts[0] {
when 'OUTER' { $sub = $sub.?outer; goto "lexy"; }
when 'UNIT' { $sub = $sub.?to_unit; goto "lexy"; }
when 'SETTING' { $sub = $sub.?to_unit.?outer; goto "lexy"; }
when 'CALLER' { return True; }
}

my @lex = $sub.lookup_lex(@parts[0], $*FILE<name>, self.lineof(self.pos));
unless @lex {
self.deb("Lexical @parts[0] not found") if $deb;
return False;
}
if @lex[0] eq 'package' {
shift @parts;
$pkg = @lex[4];
goto "packagey";
}
else {
return @parts == 1;
}

packagey:
for @parts {
return False if !$pkg || !$*unit.exists($pkg.who, $_);
$pkg = $*unit.get($pkg.who, $_);
}

return True;
}
method nibble ($lang) {
temp %*RX; # prevent up-vars from leaking
self.cursor_fresh($lang).nibbler;
Expand Down

0 comments on commit 05b5bb6

Please sign in to comment.