Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Eliminate $ast<annotation> in favor or methods.
This makes it far easier to pick out annotation use amongst all the
keying into Match objects, for one. For another, it means we can be
smarter about allocating storage for annotations, saving a Hash being
allocated for many QAST nodes.
  • Loading branch information
jnthn committed Aug 4, 2014
1 parent 00b94e4 commit 5ad771c
Show file tree
Hide file tree
Showing 9 changed files with 59 additions and 50 deletions.
53 changes: 28 additions & 25 deletions src/NQP/Actions.nqp
Expand Up @@ -133,8 +133,9 @@ class NQP::Actions is HLL::Actions {
if $<statement> {
for $<statement> {
my $ast := $_.ast;
$ast := $ast<sink> if nqp::defined($ast<sink>);
if $ast<bareblock> { $ast := block_immediate($ast[0]); }
my $sunk := $ast.ann('sink');
$ast := $sunk if nqp::defined($sunk);
if $ast.ann('bareblock') { $ast := block_immediate($ast[0]); }
$ast := QAST::Stmts.new($ast) if nqp::istype($ast, QAST::Node);
$ast_list.push( $ast );
}
Expand Down Expand Up @@ -167,7 +168,7 @@ class NQP::Actions is HLL::Actions {
$ast := QAST::Op.new($ml<cond>.ast, $ast, :op(~$ml<sym>), :node($/) );
}
}
if $ast<var_initialized> {
if $ast.ann('var_initialized') {
# Variable declared and unconditionally initialized; can strip
# the added just-to-be-safe initialization of the lexical and
# just have the var decl.
Expand Down Expand Up @@ -206,7 +207,7 @@ class NQP::Actions is HLL::Actions {
}
$BLOCK.push($ast);
$BLOCK.node($/);
$BLOCK<handlers> := %*HANDLERS if %*HANDLERS;
$BLOCK.annotate('handlers', %*HANDLERS) if %*HANDLERS;
make $BLOCK;
}
else {
Expand Down Expand Up @@ -412,7 +413,8 @@ class NQP::Actions is HLL::Actions {
method statement_prefix:sym<try>($/) {
my $ast := $<blorst>.ast;
if nqp::istype($ast, QAST::Block) {
if $ast<handlers> && nqp::existskey($ast<handlers>, 'CATCH') {
my $handlers := $ast.ann('handlers');
if $handlers && nqp::existskey($handlers, 'CATCH') {
make $ast;
return 1;
}
Expand Down Expand Up @@ -823,7 +825,7 @@ class NQP::Actions is HLL::Actions {
));
if $<initializer> {
$ast := QAST::Op.new( :op('bind'), :node($/), $ast, $<initializer>.ast );
$ast<var_initialized> := 1;
$ast.annotate('var_initialized', 1);
}
$BLOCK.symbol($name, :scope('lexical'), :type($type) );
}
Expand Down Expand Up @@ -986,8 +988,8 @@ class NQP::Actions is HLL::Actions {
}

my $lex_ast := QAST::Op.new( :op('takeclosure'), $ast );
$lex_ast<sink> := $ast;
$lex_ast<block_ast> := $block;
$lex_ast.annotate('sink', $ast);
$lex_ast.annotate('block_ast', $block);
make $lex_ast;

# Apply traits.
Expand All @@ -1013,7 +1015,7 @@ class NQP::Actions is HLL::Actions {
$ast.blocktype('declaration_static');

# Always need an invocant.
unless $ast<signature_has_invocant> {
unless $ast.ann('signature_has_invocant') {
$ast[0].unshift(QAST::Var.new(
:name('self'), :scope('lexical'), :decl('param'),
:returns($*PACKAGE)
Expand Down Expand Up @@ -1042,7 +1044,7 @@ class NQP::Actions is HLL::Actions {
my $code := $*W.create_code($ast, $name, $is_dispatcher);
if $*MULTINESS eq 'multi' { attach_multi_signature($code, $ast); }
$*W.pkg_add_method($*PACKAGE, $meta_meth, $name, $code);
$ast<code_obj> := $code;
$ast.annotate('code_obj', $code);

# Install it in the package also if needed.
if $*SCOPE eq 'our' {
Expand All @@ -1067,9 +1069,9 @@ class NQP::Actions is HLL::Actions {

# Install AST node in match object, then apply traits.
my $lex_ast := QAST::Op.new( :op('takeclosure'), $ast );
$lex_ast<sink> := $ast;
$lex_ast<block_ast> := $ast;
$lex_ast<code_obj> := $ast<code_obj>;
$lex_ast.annotate('sink', $ast);
$lex_ast.annotate('block_ast', $ast);
$lex_ast.annotate('code_obj', $ast.ann('code_obj'));
make $lex_ast;
if $<trait> {
for $<trait> { $_.ast()($/); }
Expand Down Expand Up @@ -1111,8 +1113,9 @@ class NQP::Actions is HLL::Actions {
$types.push($_.returns =:= NQPMu
?? nqp::null()
!! $_.returns);
$definednesses.push($_<definedness> eq 'D' ?? 1 !!
$_<definedness> eq 'U' ?? 2 !! 0);
my $defann := $_.ann('definedness');
$definednesses.push($defann eq 'D' ?? 1 !!
$defann eq 'U' ?? 2 !! 0);
}
}
$*W.set_routine_signature($code_obj, $types, $definednesses);
Expand All @@ -1136,7 +1139,7 @@ class NQP::Actions is HLL::Actions {
QAST::Var.new( :name('self'), :scope('lexical'), :decl('var') ),
QAST::Var.new( :scope('lexical'), :name($inv.name) )
));
$BLOCK<signature_has_invocant> := 1
$BLOCK.annotate('signature_has_invocant', 1);
}
if $<parameter> {
for $<parameter> { $BLOCKINIT.push($_.ast); }
Expand Down Expand Up @@ -1188,7 +1191,7 @@ class NQP::Actions is HLL::Actions {

# Set definedness flag (XXX want a better way to do this).
if $<definedness> {
$ast<definedness> := ~$<definedness>[0];
$ast.annotate('definedness', ~$<definedness>[0]);
}

make $ast;
Expand Down Expand Up @@ -1242,8 +1245,8 @@ class NQP::Actions is HLL::Actions {
my $is_dispatcher := $*SCOPE eq 'proto';
make -> $match {
$*W.pkg_add_method($package, 'add_parrot_vtable_mapping', $name,
$match.ast<code_obj> //
$*W.create_code($match.ast<block_ast>, $name, $is_dispatcher));
$match.ast.ann('code_obj') //
$*W.create_code($match.ast.ann('block_ast'), $name, $is_dispatcher));
};
}
elsif $<longname> eq 'parrot_vtable_handler' {
Expand All @@ -1266,9 +1269,9 @@ class NQP::Actions is HLL::Actions {
elsif $<longname> eq 'export' {
make -> $match {
my $ast := $match.ast;
my $name := $ast<block_ast>.name;
$*EXPORT.WHO<DEFAULT>.WHO{'&' ~ $name} := $ast<code_obj> //
$*W.create_code($ast<block_ast>, $name, 0);
my $name := $ast.ann('block_ast').name;
$*EXPORT.WHO<DEFAULT>.WHO{'&' ~ $name} := $ast.ann('code_obj') //
$*W.create_code($ast.ann('block_ast'), $name, 0);
};
}
else {
Expand Down Expand Up @@ -1342,7 +1345,7 @@ class NQP::Actions is HLL::Actions {
:op<callmethod>, :name<new>,
lexical_package_lookup(['NQPRegexMethod'], $/),
$regex);
$ast<sink> := $regex;
$ast.annotate('sink', $regex);
}
make $ast;
}
Expand Down Expand Up @@ -1546,7 +1549,7 @@ class NQP::Actions is HLL::Actions {
method circumfix:sym<{ }>($/) {
if +$<pblock><blockoid><statementlist><statement> > 0 {
my $ast := QAST::Op.new( :op('takeclosure'), $<pblock>.ast );
$ast<bareblock> := 1;
$ast.annotate('bareblock', 1);
make $ast;
}
elsif $<pblock><blockoid><you_are_here> {
Expand Down Expand Up @@ -1618,7 +1621,7 @@ class NQP::Actions is HLL::Actions {
$regex);

# In sink context, we don't need the Regex::Regex object.
$ast<sink> := $regex;
$ast.annotate('sink', $regex);
make $ast;
}

Expand Down
12 changes: 3 additions & 9 deletions src/NQP/World.nqp
Expand Up @@ -48,9 +48,6 @@ class NQP::World is HLL::World {
method push_lexpad($/) {
# Create pad, link to outer and add to stack.
my $pad := QAST::Block.new( QAST::Stmts.new(), :node($/) );
if +@!BLOCKS {
$pad<outer> := @!BLOCKS[+@!BLOCKS - 1];
}
@!BLOCKS[+@!BLOCKS] := $pad;
$pad
}
Expand Down Expand Up @@ -265,12 +262,9 @@ class NQP::World is HLL::World {

# See if we already have our compile-time dummy. If not, create it.
my $fixups := QAST::Stmts.new();
my $dummy;
my $dummy := $ast.ann('compile_time_dummy');
my $code_ref_idx;
if nqp::defined($ast<compile_time_dummy>) {
$dummy := $ast<compile_time_dummy>;
}
else {
unless nqp::defined($dummy) {
# Create a fresh stub code, and set its name.
$dummy := nqp::freshcoderef($stub_code);
nqp::setcodename($dummy, $name);
Expand All @@ -280,7 +274,7 @@ class NQP::World is HLL::World {
nqp::markcodestub($dummy);
$code_ref_idx := self.add_root_code_ref($dummy, $ast);
%!code_stub_sc_idx{$ast.cuid()} := $code_ref_idx;
$ast<compile_time_dummy> := $dummy;
$ast.annotate('compile_time_dummy', $dummy);

# Things with code objects may be methods in roles or multi-dispatch
# routines. We need to handle their cloning and maintain the fixup
Expand Down
23 changes: 18 additions & 5 deletions src/QAST/Node.nqp
Expand Up @@ -3,15 +3,14 @@ class QAST::Node {
has @!array is positional_delegate;

# For annotations.
has %!hash is associative_delegate;
has %!annotations;

has $!node;
has $!returns;

method new(*@children, *%options) {
my $new := nqp::create(self);
nqp::bindattr($new, QAST::Node, '@!array', @children);
nqp::bindattr($new, QAST::Node, '%!hash', nqp::hash());
my $it := nqp::iterator(%options);
my $cur;
while $it {
Expand Down Expand Up @@ -58,14 +57,28 @@ class QAST::Node {
self.HOW.mixin(self, QAST::CompileTimeValue);
self.set_compile_time_value($value);
}

method hash() { %!hash }

method list() { @!array }
method pop() { nqp::pop(@!array) }
method push($value) { nqp::push(@!array, $value) }
method shift() { nqp::shift(@!array) }
method unshift($value) { nqp::unshift(@!array, $value) }


method annotate(str $key, $value) {
%!annotations := nqp::hash() unless nqp::ishash(%!annotations);
%!annotations{$key} := $value;
}

method ann(str $key) {
nqp::ishash(%!annotations)
?? %!annotations{$key}
!! NQPMu
}

method has_ann(str $key) {
nqp::ishash(%!annotations) && nqp::existskey(%!annotations, $key)
}

my %uniques;
method unique($prefix) {
my $id := nqp::existskey(%uniques, $prefix) ??
Expand Down
1 change: 0 additions & 1 deletion src/QAST/VM.nqp
Expand Up @@ -4,7 +4,6 @@ class QAST::VM is QAST::Node {
method new(*@children, *%alternatives) {
my $obj := nqp::create(self);
nqp::bindattr($obj, QAST::Node, '@!array', @children);
nqp::bindattr($obj, QAST::Node, '%!hash', nqp::hash());
nqp::bindattr($obj, QAST::VM, '%!alternatives', %alternatives);
$obj
}
Expand Down
2 changes: 1 addition & 1 deletion src/QRegex/NFA.nqp
Expand Up @@ -171,7 +171,7 @@ class QRegex::NFA {
my $subtype := $node.subtype;
if $node.name eq 'before' && !$node.negate {
my int $end := self.addstate();
self.regex_nfa($node[0][1]<orig_qast>, $from, $end);
self.regex_nfa($node[0][1].ann('orig_qast'), $from, $end);
self.fate($node, $end, $to);
}
elsif $subtype ne 'zerowidth' &&
Expand Down
2 changes: 1 addition & 1 deletion src/QRegex/P5Regex/Actions.nqp
Expand Up @@ -373,7 +373,7 @@ class QRegex::P5Regex::Actions is HLL::Actions {
self.store_regex_caps($code_obj, $block, capnames($qast, 0));
self.store_regex_nfa($code_obj, $block, QRegex::NFA.new.addnode($qast));

$block<orig_qast> := $qast;
$block.annotate('orig_qast', $qast);
$qast := QAST::Regex.new( :rxtype<concat>,
QAST::Regex.new( :rxtype<scan> ),
$qast,
Expand Down
2 changes: 1 addition & 1 deletion src/QRegex/P6Regex/Actions.nqp
Expand Up @@ -735,7 +735,7 @@ class QRegex::P6Regex::Actions is HLL::Actions {
}
}

$block<orig_qast> := $qast;
$block.annotate('orig_qast', $qast);
$qast := QAST::Regex.new( :rxtype<concat>,
$scan,
$qast,
Expand Down
2 changes: 1 addition & 1 deletion src/vm/jvm/QAST/Compiler.nqp
Expand Up @@ -4112,7 +4112,7 @@ class QAST::CompilerJAST {
my int $i := 1;
my $cur_block := $*BLOCK.outer();
while nqp::istype($cur_block, BlockInfo) {
if $cur_block.qast<DYN_COMP_WRAPPER> {
if $cur_block.qast.ann('DYN_COMP_WRAPPER') {
$cur_block := NQPMu;
}
else {
Expand Down
12 changes: 6 additions & 6 deletions src/vm/moar/QAST/QASTCompilerMAST.nqp
Expand Up @@ -300,11 +300,11 @@ my class MASTCompilerInstance {

# Compile, and evaluate to compilation unit.
self.as_mast($qast);
CATCH {
my $err := $!;
my $source := self.source_for_node($!last_op);
nqp::die("QAST -> MAST failed while compiling op " ~ $!last_op.op ~ "$source: $err");
}
#CATCH {
# my $err := $!;
# my $source := self.source_for_node($!last_op);
# nqp::die("QAST -> MAST failed while compiling op " ~ $!last_op.op ~ "$source: $err");
#}

$!mast_compunit
}
Expand Down Expand Up @@ -1218,7 +1218,7 @@ my class MASTCompilerInstance {
my $block := $*BLOCK;
# find the block where the lexical was declared, if any
while nqp::istype($block, BlockInfo) {
last if $block.qast<DYN_COMP_WRAPPER>;
last if $block.qast.ann('DYN_COMP_WRAPPER');
$lex := $block.lexical($name);
last if $lex;
$block := $block.outer;
Expand Down

0 comments on commit 5ad771c

Please sign in to comment.