Permalink
Browse files

Start conveying decont context in QAST -> MAST.

This means that we can, in various cases where we used to take a
reference to a native lexical/attribute, now simply just get it
boxed instead.
  • Loading branch information...
jnthn committed Jun 14, 2017
1 parent 4717849 commit cabe421f025ad1196f78f351c21a7b5b73ea90cd
Showing with 29 additions and 8 deletions.
  1. +13 −4 src/vm/moar/QAST/QASTCompilerMAST.nqp
  2. +16 −4 src/vm/moar/QAST/QASTOperationsMAST.nqp
@@ -610,8 +610,9 @@ my class MASTCompilerInstance {
MAST::InstructionList.new($il, $reg, $desired)
}
method as_mast($qast, :$want) {
method as_mast($qast, :$want, :$want-decont) {
my $*WANT;
my $*WANT-DECONT := $want-decont;
if nqp::defined($want) {
$*WANT := $want;
if nqp::istype($qast, QAST::Want) {
@@ -1367,9 +1368,10 @@ my class MASTCompilerInstance {
# the last statement,
|| $resultchild == -1 && $result_count == $final_stmt_idx) {
# compile $_ with an explicit $want, either what's given or obj
my $want-decont := $*WANT-DECONT;
$last_stmt := nqp::defined($WANT)
?? self.as_mast($_, :want($WANT))
!! self.as_mast($_);
?? self.as_mast($_, :want($WANT), :$want-decont)
!! self.as_mast($_, :$want-decont);
if $last_stmt.result_kind == $MVM_reg_void {
$last_stmt := self.coerce($last_stmt, $MVM_reg_obj);
}
@@ -1592,6 +1594,13 @@ my class MASTCompilerInstance {
}
}
# If we want a decontainerized value, then we don't ever need a
# reference in this context either.
if $*WANT-DECONT {
$scope := 'lexical' if $scope eq 'lexicalref';
$scope := 'attribute' if $scope eq 'attributeref';
}
# Now go by scope.
my $name := $node.name;
my @ins;
@@ -1943,7 +1952,7 @@ my class MASTCompilerInstance {
multi method compile_node(QAST::Want $node, :$want) {
# If we're not in a coercive context, take the default.
self.as_mast($node[0])
self.as_mast($node[0], :want-decont($*WANT-DECONT))
}
multi method compile_node(QAST::IVal $iv, :$want) {
@@ -158,9 +158,10 @@ class QAST::MASTOperations {
my int $operand := nqp::atpos_i(@operands_values, $operands_offset + $operand_num++);
my int $operand_kind := ($operand +& $MVM_operand_type_mask);
my int $constant_operand := !($operand +& $MVM_operand_rw_mask);
my $want-decont := @deconts[$arg_num];
my $arg := $operand_kind == $MVM_operand_type_var
?? $qastcomp.as_mast($_)
!! $qastcomp.as_mast($_, :want($operand_kind/8));
?? $qastcomp.as_mast($_, :$want-decont)
!! $qastcomp.as_mast($_, :want($operand_kind/8), :$want-decont);
my int $arg_kind := $arg.result_kind;
if $arg_num == 0 && nqp::eqat($op, 'return_', 0) {
@@ -732,7 +733,7 @@ for <if unless with without> -> $op_name {
$op[1].blocktype($orig_type);
}
else {
@comp_ops[1] := $qastcomp.as_mast($op[1], :want($wanted));
@comp_ops[1] := $qastcomp.as_mast($op[1], :want($wanted), :want-decont($*WANT-DECONT));
}
if needs_cond_passed($op[2]) {
my $orig_type := $op[2].blocktype;
@@ -745,7 +746,7 @@ for <if unless with without> -> $op_name {
$op[2].blocktype($orig_type);
}
elsif $op[2] {
@comp_ops[2] := $qastcomp.as_mast($op[2], :want($wanted));
@comp_ops[2] := $qastcomp.as_mast($op[2], :want($wanted), :want-decont($*WANT-DECONT));
}
if (@comp_ops[0].result_kind == $MVM_reg_void) {
@@ -2521,6 +2522,17 @@ QAST::MASTOperations.add_core_moarop_mapping('iscont_i', 'iscont_i');
QAST::MASTOperations.add_core_moarop_mapping('iscont_n', 'iscont_n');
QAST::MASTOperations.add_core_moarop_mapping('iscont_s', 'iscont_s');
QAST::MASTOperations.add_core_moarop_mapping('isrwcont', 'isrwcont');
QAST::MASTOperations.add_core_op('decont', -> $qastcomp, $op {
if +$op.list != 1 {
nqp::die("The 'decont' op needs 1 operand, got " ~ +$op.list);
}
my $regalloc := $*REGALLOC;
my $res_reg := $regalloc.fresh_o();
my $expr := $qastcomp.as_mast($op[0], :want($MVM_reg_obj), :want-decont);
push_op($expr.instructions, 'decont', $res_reg, $expr.result_reg);
$regalloc.release_register($expr.result_reg, $MVM_reg_obj);
MAST::InstructionList.new($expr.instructions, $res_reg, $MVM_reg_obj)
});
QAST::MASTOperations.add_core_moarop_mapping('decont', 'decont');
QAST::MASTOperations.add_core_moarop_mapping('decont_i', 'decont_i');
QAST::MASTOperations.add_core_moarop_mapping('decont_n', 'decont_n');

0 comments on commit cabe421

Please sign in to comment.