Welcome to the main channel on the development of MoarVM, a virtual machine for NQP and Rakudo (moarvm.org). This channel is being logged for historical purposes.
Set by lizmat on 24 May 2021.
Nicholas good *, * 07:00
lizmat /o Nicholas 07:04
Nicholas I assume that it's (relatively) sensible to merge the C11 atomics stuff now? 08:42
releasable6: help
releasable6 Nicholas, status | status link # See wiki for more examples: github.com/Raku/whateverable/wiki/Releasable
Nicholas releasable6: status
releasable6 Nicholas, Next release in ≈3 days and ≈10 hours. 1 blocker. Changelog for this release was not started yet
Nicholas, Details: gist.github.com/b445ca955c46fd8aed...8463e4ed7a
Nicholas but the atomics stuff is optional, and default off, so it seems safe
nine I say go for it 08:48
Geth__ MoarVM/master: 6 commits pushed by (Nicholas Clark)++ 11:38
MasterDuke so changing `!$obj.prec<iffy>` to `!nqp::getattr($obj.prec,Map,'$!storage')<iffy>` here github.com/rakudo/rakudo/blob/mast....nqp#L2745 causes the segfault not to happen 12:05
but that seems like masking over an underlying problem. i.e., why don't all infixes cause a segfault? 12:07
MasterDuke maybe the difference is that only infixes that return an empty hash from .prec cause the segfault? 12:10
m: dd &infix:<< +> >>.prec; dd &infix:<< +< >>.prec; dd &infix:<< +| >>.prec; dd &infix:<< ~< >>.prec; 12:12
camelia {}
{}
{:assoc("left"), :prec("t=")}
{}
nine But still, none of these may even cause a segfault.
MasterDuke those are just some examples. it looks like anything that returns {} from .prec will segfault, but other things do
nine i.e. they are not allowed to 12:13
MasterDuke oh yeah, definitely
but i think it's something in dispatching. disabling spesh doesn't change anything 12:14
i.e., dispatch is not de-containerizing in some cases 12:18
oh interesting. rakudo 2021.09 + that change in Optimizer.nqp segfaults also. so not new-disp's fault 12:23
MasterDuke adding `if (!del) die_no_ass_del(tc, st);` here github.com/MoarVM/MoarVM/blob/mast...ue.c#L1468 measn' 13:46
s/measn'/fixes the segfault/ 13:47
which is good.but i still don't know why it's getting the wrong repr anyway 13:48
nine It's getting the wrong repr?
MasterDuke well, it's a P6opaque. STABLE(obj)->debug_name == "Hash" 13:49
so for some of the infixes `.prec` returns a BOOTHash/VMHash. but when it's empty, it's an HLL hash 13:50
MasterDuke adding `trait_mod:<is>(&infix:«+<»,  :prec($multiplicative));` here github.com/rakudo/rakudo/blob/mast...ce.pm6#L67 also fixes the segfault (with a stock MoarVM) 14:11
and then `dd &infix:<< +> >>.prec` prints `{:assoc("left"), :prec("u=")}` 14:12
that change passes a spectest 14:16
let's see if i can sum up where things stand: `&infix:«+<»` didn't have its precedence set, therefore the call to `.prec` went through Code's method prec, which simple returns `my %`, which is an HLL hash and the optimizer can't operate on them directly, so the atkey goes through P6opaque and that's where the segfault happens because it's 14:24
ass_del_slot != -1, but get_obj_at_offset() still returns 0x0
the missing precedences in precedence.pm6 seems like an accidental omission, so those should be added, and that nicely fixes the segfault 14:27
anything else i'm not sure about
i don't know if there's some problem with `my %`, but it's only used a couple other times in rakudo 14:29
heh. removing those added precedences and instead changing github.com/rakudo/rakudo/blob/mast...de.pm6#L25 to `my % = ()` also fixes the segfault 14:33
interesting, there's definitely different ast for a sub returning `my %` vs `my % = ()` 14:37
gist.github.com/MasterDuke17/a8f3e...f6f7e8d3d3 not the easiest thing to read in a gist, but a vimdiff of the only relevant different in the asts 14:39
vrurg BTW, I was looking into feasibility of doing coercions via new-disp and it seems making little to no sense. The part with fallback to .COERCE and .new depends on value being coerced and this we barely can cache with new-disp. 15:19
jnthnwrthngtn vrurg: What do you mean by "the value being coerced"? The value itself, or the type of the value? 15:45
vrurg jnthnwrthngtn: The value itself. Custom methods may have `where` blocks, for example. 15:47
jnthnwrthngtn Hm, but what are the semantics of whether we use COERCE or new? 15:48
vrurg can we .Type -> then .COERCE($value) -> then .new($value) 15:49
.Type is doable.
And the thing I've missed and realized in about 10mins after the first message – I still can iterate method candidates and make sure there are no post-constraints attached to the parameter. 15:50
This would probably be 90%+ of all cases. 15:51
Then the only possible issue is if a method gets wrapped at run-time. But this we can explicitly spec as compile-time possibility only due to optimization needs. 15:52
MasterDuke huh. why don't the precedences in src/core.c/precedence.pm6 always match the ones in src/Perl6/Grammar.nqp ? 16:13
e.g., `my Mu $methodcall       := nqp::hash('prec', 'y=');` vs `my %methodcall      := nqp::hash('prec', 'y=', 'assoc', 'unary', 'dba', 'methodcall', 'fiddly', 1);` 16:14
MasterDuke `%named_unary` is missing entirely from precedence.pm6 16:15
jnthnwrthngtn vrurg: What, so if multi-dispatch to COERCE fails then we try `new`? 16:20
MasterDuke would there be any reason not to have the table and info in precedence.pm6 exactly match what's in Grammar.nqp? 16:31
vrurg jnthnwrthngtn: Kind of. If .cando($value) on target type COERCE fails. 16:43
I'll be afk for a couple of hours. 16:44
nine MasterDuke: oh, so there's probaby 2 bugs here. The severe one where MoarVM's at_key assumes without checking that if there's an associative delegate attribute, it's also initialized, leading to the segfault and the triggering one in the optimizer which expects a low level hash but gets an HLL one 16:54
MasterDuke for the first, is adding `if (!del) die_no_ass_del(tc, st);` (or a throw with a different error message) here github.com/MoarVM/MoarVM/blob/mast...ue.c#L1468 a correct fix? or should something more complicated be done? 16:59
for the second, i have no idea
nine MasterDuke: I'm leaning towards returning tc->instance->VMNull instead of throwing an exception. The type after all does support associative operations. It's just that there's no data yet, so we ought to pretend that there's just an empty hash there. 17:05
MasterDuke: for the thing in the optimizer, unless nqp::ishash($hash) { $hash := $hash.FLATTENABLE_HASH(); } seems to be the idiom for "downgrading" a possible HLL hash 17:06
lizmat I've merged MasterDuke's PR 17:25
please note that in RakuAST all of that precedence stuff is kept in *one* place :-)
nine I for one welcome our new AST overloards! 17:35
MasterDuke ah, that'll be nice 20:40
guess i won't bother syncing up the two places now 20:41
nine: re the optimizer, that sort of seems like papering over a problem, given that changing the `my %` to `my % = ()` makes the hash non-HLL 20:42