Version 1 (modified by cotto, 5 years ago)

first version, direct copy/paste from irc, definitely needs reworking

<pmichaud> cotto_work: I do expect to try to generate smarter pir, yes. However, the structure of Parrot doesn't allow for a lot smarter PIR. <pmichaud> (I'm hoping parrot will change that... but I don't expect it to happen anytime in the near future.) <cotto_work> ok. How could Parrot enable smarter code generation? <Tene> The fix isn't too bad, but I haven't done it yet. <cotto_work> It sounds like that might fit in with Lorito. <pmichaud> cotto_work: well, one of the big stumbling blocks at the moment is that lexicals can only be PMCs <pmichaud> so anything that goes into a lexical ends up having to be boxed into a PMC <pmichaud> an even bigger stumbling block is that Parrot doesn't have a good lvalue model or assignment semantics <pmichaud> it tends to confuse "bind" with "assign" <pmichaud> at least, it does that for most of the default PMC types <pmichaud> there's also not a good reference model <pmichaud> for keeping track of object references <pmichaud> as a result, the code that nqp generates tends to have to be somewhat pessimistic, such as continually refetching lexical and global symbol tables because of the possibility of a symbol being rebound <Coke> pmichaud,tene: > puts [list [catch barf var] $var] <Coke> 1 {Could not find non-existent sub barf} <Coke> whee. <cotto_work> That explains some of the generated code then. * cconstantine has quit (Quit: cconstantine) <Coke> pmichaud: any issue with switching partcl-nqp to build with "nqp" instead of "parrot-nqp" for now? <Coke> (then I don't have to ping you to cut a new 'release' =-) <pmichaud> cotto_work: I do plan to have an option whereby code can say "assume this lexical/symbol isn't being rebound" <pmichaud> but since parrot doesn't have a good assignment model, most folks end up doing rebinds <pmichaud> partcl-nqp just went through this yesterday (until I fixed it this morning) whereby symbols were being re-bound to new PMCs instead of changing the value of an existing multiply-bound PMC <cotto_work> What's the difference between assignment and binding? <pmichaud> assignment changes the value of an existing PMC <pmichaud> binding causes a symbol table entry to point to a PMC <pmichaud> so, for example <pmichaud> $P0 = box 1 <pmichaud> $P1 = $P0 <pmichaud> these are examples of binding <pmichaud> if after the above, I do: $P0 = box 3 <pmichaud> then $P1 ends up still being bound to the PMC containing 1 <pmichaud> and $P0 is bound to a new PMC containing 3 <pmichaud> okay so far? <cotto_work> yes <pmichaud> $P0 = box 1 <pmichaud> $P1 = $P0 <pmichaud> assign $P0, 3 <pmichaud> in this case, $P0 and $P1 still point to the same PMC, and the value of that PMC has changed to 3 <pmichaud> still okay? <cotto_work> yes <pmichaud> that's the difference <pmichaud> now then, let's look at something like <pmichaud> $P0 = new ResizablePMCArray? <pmichaud> $P0[0] = 1 <pmichaud> $P1 = $P0[0] <pmichaud> in this case, $P1 and $P0[0] are pointing to the same PMC (containing 1) <pmichaud> but if we then do... <pmichaud> $P0[0] = 3 <pmichaud> that's a binding, not an assignment <pmichaud> such that $P1 refers to the old PMC (1), while $P0[0] refers to the new one (3) <pmichaud> in other words, changing the value in the array has broken the bind <moritz> pmichaud: this is becoming an FAQ... you should put that on a wiki page or so <pmichaud> moritz: well, I have a few hours car ride today, perhaps I can type it up. <pmichaud> but I also plan to do a NQP/compiler tutorial <Coke> pmichaud: is t/sanity.t working for you? <pmichaud> Coke: it was as of my last push <cotto_work> Thanks. <pmichaud> where it gets *really* nasty is with <pmichaud> $P0 = find_lex '$a' <pmichaud> 'foo'() <pmichaud> if the "foo" subroutine does store_lex '$a', $P99 to put a new value in lexical $a <pmichaud> then when we get back from 'foo', $P0 no longer points to the PMC associated with $a <dalek> nqp-rx: ae0666c | tene++ | t/nqp/44-try-catch.t: <dalek> nqp-rx: Update test plan <dalek> nqp-rx: review:  http://github.com/perl6/nqp-rx/commit/ae0666cf489a209c1aa2bffb1a829ce689a3b146 <pmichaud> because store_lex does a bind <pmichaud> and not an assign <cotto_work> Then $P0 will have an out-of-date value <pmichaud> exactly <pmichaud> so, every time we need access to $a, we end up having to do a re-fetch <pmichaud> because it's possible some other operation will have re-bound it to a different PMC <dalek> rakudo: 2eb38b5 | moritz++ | perl6.pir: <dalek> rakudo: alias Object and Mu, as suggested by jnthn++; wins us back quite a few tests <dalek> rakudo: review:  http://github.com/rakudo/rakudo/commit/2eb38b5bf07f1c4392a9d1d75f3fd1cf7d877105 <pmichaud> ideally there would be an opcode that makes it easier to do assignment <pmichaud> there is an opcode called 'assign', but it tends to do weird things with the built-in PMCs <pmichaud> for example <pmichaud> $P0 = new ResizablePMCArray? <pmichaud> store_lex '$a', $P0 <pmichaud> which sets $a to be a RPA <pmichaud> now we want to do the equivalent of $a = 3 -- i.e., change it to an Integer 3 <pmichaud> $P1 = find_lex '$a' <pmichaud> assign $P1, 3 # oooops! <cotto_work> That changes the length to 3, doesn't it? <pmichaud> what we want is $P1 to be an Integer 3 <pmichaud> right <pmichaud> so the 'assign' opcode doesn't do what we want here <pmichaud> late last year we added the 'copy' opcode to try to do this <pmichaud> so we'd have <pmichaud> $P1 = find_lex '$a' <pmichaud> $P2 = box 3 <pmichaud> copy $P1, $P2 (replace $P1 with $P2) * pjcj (~pjcj@…) has joined #parrot * slavorg gives channel operator status to pjcj <pmichaud> but it's horribly inefficient, because it involves making a clone of $P2 and then copying that structure into the PMC header for $P1 <pmichaud> but so far it's about the best we can do <pmichaud> everything gets worse when we start talking about aggregate access <pmichaud> because there's not a copy $P0[0], $P2 opcode yet <pmichaud> and this leads to allison's comment that it really should be the PMCs/vtables that determine behavior instead of opcodes <pmichaud> (which is where the model completely breaks down) <cotto_work> There's a lot conspiring to prevent good code generation from nqp. <cotto_work> Thanks you for that explanation. <pmichaud> sure thing! <dukeleto> 'ello <pmichaud> ultimately it's that Parrot (vtable and core types) doesn't have a good container/value/lvalue model <pmichaud> or, at least, one that doesn't map well to the HLL's we're targing. <pmichaud> *targeting