Ticket #803 (closed bug: fixed)

Opened 5 years ago

Last modified 5 years ago

PCT emits bogus code for getattribute on named register variable

Reported by: Austin_Hastings Owned by: pmichaud
Priority: normal Milestone:
Component: PCT Version: 1.3.0
Severity: high Keywords: PCT, register, getattribute
Cc: Language:
Patch status: Platform:

Description

When I have a 'register' variable holding a PMC, references to an attribute of that variable generate code that assumes a $Pxx register holds the value, even though no coercion or load has been emitted.

    # gimme = r_obj.height;
    .local pmc r_obj
    .local pmc gimme
    getattribute $P35, $P35, "height"
    set gimme, $P35

In Close, I am compiling this test code:

extern pmc Obj;

class Test
	:phylum(P6object)
{
	pmc test1() {
		return ::Obj.height;
	}

	pmc test2() {
		pmc r_obj = ::Obj;
		return r_obj.height;
	}
	
	pmc test3(pmc arg) {
		return arg.height;
	}

        # ...
}

The test1 and test3 code looks valid, but the test2 case, where the object is in a register, is bogus. (Some lines deleted for clarity.)

.HLL "close"
.namespace ["Test"]

.sub "test1"  :subid("17_1246552156")
    get_hll_global $P33, "Obj"
    getattribute $P33, $P33, "height"
    .return ($P33)
.end

.sub "test2"  :subid("18_1246552156")
    .local pmc r_obj
    get_hll_global $P35, "Obj"
    set r_obj, $P35
    getattribute $P36, $P36, "height"
    .return ($P36)
.end

.sub "test3"  :subid("19_1246552156")
    .param pmc param_38
    .lex "arg", param_38
    find_lex $P40, "arg"
    getattribute $P40, $P40, "height"
    .return ($P40)
.end

Note that in test2, above, the object is fetched via $P35, but then the getattribute opcode is emitted referencing $P36, as though it was assuming that fetching the base would result in something like set $P36, r_obj being generated. Partial PAST tree (there are times I wish the dumper were a little less terse...):

    [7] => PMC 'PAST;Block'  {
        <blocktype> => "declaration"
        <name> => "test1"
        <lstype> => "function body"
        <hll> => \past
        <namespace> => ResizablePMCArray (size:1) [
            \past[0]
        ]
        <source> => \past
        <pos> => 682
        <is_function> => 1
        <params> => "uplifted"
        <pirflags> => ""
        <rtype> => undef
        <scope> => "package"
        <is_rooted> => 0
        [0] => PMC 'PAST;Stmts'  {
            <name> => "local variables"
        }
        [1] => PMC 'PAST;Stmts'  {
            <source> => \past
            <pos> => 694
            <name> => "compound_stmt"
            [0] => PMC 'PAST;Op'  {
                <name> => "return"
                <source> => \past
                <pos> => 699
                <pasttype> => "pirop"
                <pirop> => "return"
                [0] => PMC 'PAST;Var'  {
                    <name> => "height"
                    <source> => \past
                    <pos> => 711
                    <isdecl> => 0
                    <scope> => "attribute"
                    [0] => PMC 'PAST;Var'  {
                        <source> => \past
                        <pos> => 706
                        <scope> => \past
                        <name> => "Obj"
                        <is_rooted> => 0
                        <hll> => \past
                        <namespace> => ResizablePMCArray (size:0) [
                        ]
                        <decl> => \past
                    }
                }
            }
        }
    }
    [8] => PMC 'PAST;Block'  {
        <blocktype> => "declaration"
        <name> => "test2"
        <lstype> => "function body"
        <hll> => \past
        <namespace> => \past
        <source> => \past
        <pos> => 728
        <is_function> => 1
        <params> => "uplifted"
        <pirflags> => ""
        <rtype> => undef
        <scope> => \past
        <is_rooted> => 0
        <symtable> => Hash {
            "r_obj" => Hash {
                "decl" => PMC 'PAST;Var'  {
                    <isdecl> => 1
                    <source> => \past
                    <pos> => 745
                    <pirflags> => ""
                    <scope> => \past["fname"]["decl"]
                    <type> => "pmc"
                    <is_rooted> => 0
                    <hll> => \past
                    <name> => "r_obj"
                    <namespace> => \past
                    <viviself> => PMC 'PAST;Var'  {
                        <source> => \past
                        <pos> => 757
                        <scope> => \past
                        <name> => "Obj"
                        <is_rooted> => 0
                        <hll> => \past
                        <namespace> => ResizablePMCArray (size:0) [
                        ]
                        <decl> => \past
                    }
                    <lvalue> => 1
                }
            }
        }
        [0] => PMC 'PAST;Stmts'  {
            <name> => "local variables"
        }
        [1] => PMC 'PAST;Stmts'  {
            <source> => \past
            <pos> => 740
            <name> => "compound_stmt"
            [0] => \past["r_obj"]["decl"]
            [1] => PMC 'PAST;Op'  {
                <name> => "return"
                <source> => \past
                <pos> => 767
                <pasttype> => "pirop"
                <pirop> => "return"
                [0] => PMC 'PAST;Var'  {
                    <name> => "height"
                    <source> => \past
                    <pos> => 779
                    <isdecl> => 0
                    <scope> => "attribute"
                    [0] => PMC 'PAST;Var'  {
                        <source> => \past
                        <pos> => 774
                        <scope> => \past["fname"]["decl"]
                        <name> => "r_obj"
                        <is_rooted> => 0
                        <hll> => \past
                        <namespace> => \past
                        <decl> => \past["r_obj"]["decl"]
                    }
                }
            }
        }
    }
    [9] => PMC 'PAST;Block'  {
        <blocktype> => "declaration"
        <name> => "test3"
        <lstype> => "function body"
        <hll> => \past
        <namespace> => \past
        <source> => \past
        <pos> => 797
        <is_function> => 1
        <symtable> => Hash {
            "arg" => Hash {
                "decl" => PMC 'PAST;Var'  {
                    <isdecl> => 1
                    <source> => \past
                    <pos> => 807
                    <pirflags> => ""
                    <scope> => \past["filename"]["decl"]
                    <type> => "pmc"
                    <is_rooted> => 0
                    <hll> => \past
                    <name> => "arg"
                    <namespace> => \past
                }
            }
        }
        <params> => "uplifted"
        <pirflags> => ""
        <rtype> => undef
        <scope> => \past
        <is_rooted> => 0
        [0] => PMC 'PAST;Stmts'  {
            <name> => "local variables"
        }
        [1] => \past["arg"]["decl"]
        [2] => PMC 'PAST;Stmts'  {
            <source> => \past
            <pos> => 816
            <name> => "compound_stmt"
            [0] => PMC 'PAST;Op'  {
                <name> => "return"
                <source> => \past
                <pos> => 821
                <pasttype> => "pirop"
                <pirop> => "return"
                [0] => PMC 'PAST;Var'  {
                    <name> => "height"
                    <source> => \past
                    <pos> => 831
                    <isdecl> => 0
                    <scope> => "attribute"
                    [0] => PMC 'PAST;Var'  {
                        <source> => \past
                        <pos> => 828
                        <scope> => "lexical"
                        <name> => "arg"
                        <is_rooted> => 0
                        <hll> => \past
                        <namespace> => \past
                        <decl> => \past["arg"]["decl"]
                    }
                }
            }
        }
    }

Change History

Changed 5 years ago by pmichaud

  • status changed from new to assigned

Now fixed in r39895. Here's the NQP program I used to test and verify it:

$ cat x.nqp
Q:PIR { load_bytecode 'PCT.pbc' };

# build simple PAST tree to test
my $block := PAST::Block.new();
$block.push(
    PAST::Var.new(
        :name("someAttr"), 
        :scope("attribute"),
        PAST::Var.new( :name('Global'), :scope('package') )
    )
);
$block.push(
    PAST::Var.new(
        :name("someAttr"), 
        :scope("attribute"),
        PAST::Var.new( :name('myreg'), :scope('register') )
    )
);

my $str := PAST::Compiler.compile($block, :target('pir'));
say($str);
$ ./parrot nqp.pbc x.nqp

.namespace []
.sub "_block30"  :anon :subid("15_1246853334")
.annotate "line", 0
    get_global $P32, "Global"
    getattribute $P33, $P32, "someAttr"
    getattribute $P34, myreg, "someAttr"
    .return ($P34)
.end

$ 

Thanks!

Pm

Changed 5 years ago by pmichaud

  • status changed from assigned to closed
  • resolution set to fixed
Note: See TracTickets for help on using tickets.