Skip to content

Commit cabe421

Browse files
committed
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.
1 parent 4717849 commit cabe421

File tree

2 files changed

+29
-8
lines changed

2 files changed

+29
-8
lines changed

src/vm/moar/QAST/QASTCompilerMAST.nqp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -610,8 +610,9 @@ my class MASTCompilerInstance {
610610
MAST::InstructionList.new($il, $reg, $desired)
611611
}
612612

613-
method as_mast($qast, :$want) {
613+
method as_mast($qast, :$want, :$want-decont) {
614614
my $*WANT;
615+
my $*WANT-DECONT := $want-decont;
615616
if nqp::defined($want) {
616617
$*WANT := $want;
617618
if nqp::istype($qast, QAST::Want) {
@@ -1367,9 +1368,10 @@ my class MASTCompilerInstance {
13671368
# the last statement,
13681369
|| $resultchild == -1 && $result_count == $final_stmt_idx) {
13691370
# compile $_ with an explicit $want, either what's given or obj
1371+
my $want-decont := $*WANT-DECONT;
13701372
$last_stmt := nqp::defined($WANT)
1371-
?? self.as_mast($_, :want($WANT))
1372-
!! self.as_mast($_);
1373+
?? self.as_mast($_, :want($WANT), :$want-decont)
1374+
!! self.as_mast($_, :$want-decont);
13731375
if $last_stmt.result_kind == $MVM_reg_void {
13741376
$last_stmt := self.coerce($last_stmt, $MVM_reg_obj);
13751377
}
@@ -1592,6 +1594,13 @@ my class MASTCompilerInstance {
15921594
}
15931595
}
15941596

1597+
# If we want a decontainerized value, then we don't ever need a
1598+
# reference in this context either.
1599+
if $*WANT-DECONT {
1600+
$scope := 'lexical' if $scope eq 'lexicalref';
1601+
$scope := 'attribute' if $scope eq 'attributeref';
1602+
}
1603+
15951604
# Now go by scope.
15961605
my $name := $node.name;
15971606
my @ins;
@@ -1943,7 +1952,7 @@ my class MASTCompilerInstance {
19431952

19441953
multi method compile_node(QAST::Want $node, :$want) {
19451954
# If we're not in a coercive context, take the default.
1946-
self.as_mast($node[0])
1955+
self.as_mast($node[0], :want-decont($*WANT-DECONT))
19471956
}
19481957

19491958
multi method compile_node(QAST::IVal $iv, :$want) {

src/vm/moar/QAST/QASTOperationsMAST.nqp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -158,9 +158,10 @@ class QAST::MASTOperations {
158158
my int $operand := nqp::atpos_i(@operands_values, $operands_offset + $operand_num++);
159159
my int $operand_kind := ($operand +& $MVM_operand_type_mask);
160160
my int $constant_operand := !($operand +& $MVM_operand_rw_mask);
161+
my $want-decont := @deconts[$arg_num];
161162
my $arg := $operand_kind == $MVM_operand_type_var
162-
?? $qastcomp.as_mast($_)
163-
!! $qastcomp.as_mast($_, :want($operand_kind/8));
163+
?? $qastcomp.as_mast($_, :$want-decont)
164+
!! $qastcomp.as_mast($_, :want($operand_kind/8), :$want-decont);
164165
my int $arg_kind := $arg.result_kind;
165166

166167
if $arg_num == 0 && nqp::eqat($op, 'return_', 0) {
@@ -732,7 +733,7 @@ for <if unless with without> -> $op_name {
732733
$op[1].blocktype($orig_type);
733734
}
734735
else {
735-
@comp_ops[1] := $qastcomp.as_mast($op[1], :want($wanted));
736+
@comp_ops[1] := $qastcomp.as_mast($op[1], :want($wanted), :want-decont($*WANT-DECONT));
736737
}
737738
if needs_cond_passed($op[2]) {
738739
my $orig_type := $op[2].blocktype;
@@ -745,7 +746,7 @@ for <if unless with without> -> $op_name {
745746
$op[2].blocktype($orig_type);
746747
}
747748
elsif $op[2] {
748-
@comp_ops[2] := $qastcomp.as_mast($op[2], :want($wanted));
749+
@comp_ops[2] := $qastcomp.as_mast($op[2], :want($wanted), :want-decont($*WANT-DECONT));
749750
}
750751

751752
if (@comp_ops[0].result_kind == $MVM_reg_void) {
@@ -2521,6 +2522,17 @@ QAST::MASTOperations.add_core_moarop_mapping('iscont_i', 'iscont_i');
25212522
QAST::MASTOperations.add_core_moarop_mapping('iscont_n', 'iscont_n');
25222523
QAST::MASTOperations.add_core_moarop_mapping('iscont_s', 'iscont_s');
25232524
QAST::MASTOperations.add_core_moarop_mapping('isrwcont', 'isrwcont');
2525+
QAST::MASTOperations.add_core_op('decont', -> $qastcomp, $op {
2526+
if +$op.list != 1 {
2527+
nqp::die("The 'decont' op needs 1 operand, got " ~ +$op.list);
2528+
}
2529+
my $regalloc := $*REGALLOC;
2530+
my $res_reg := $regalloc.fresh_o();
2531+
my $expr := $qastcomp.as_mast($op[0], :want($MVM_reg_obj), :want-decont);
2532+
push_op($expr.instructions, 'decont', $res_reg, $expr.result_reg);
2533+
$regalloc.release_register($expr.result_reg, $MVM_reg_obj);
2534+
MAST::InstructionList.new($expr.instructions, $res_reg, $MVM_reg_obj)
2535+
});
25242536
QAST::MASTOperations.add_core_moarop_mapping('decont', 'decont');
25252537
QAST::MASTOperations.add_core_moarop_mapping('decont_i', 'decont_i');
25262538
QAST::MASTOperations.add_core_moarop_mapping('decont_n', 'decont_n');

0 commit comments

Comments
 (0)