02:34
<devsnek>
I wonder if there's any point to implementing atomics and sab in engine262
02:34
<devsnek>
could maybe validate some of the logic
02:38
<Bakkot>
you aren't currently using generators in engine262, right?
02:41
<Bakkot>
if so, it is probably not that much work to add multithreading; you just add a babel transform which turns every AO into a generator, wraps every call to an AO so that it invokes and consumes the whole generator and gives you the return value, and wraps every expression with `yield`
02:52
<devsnek>
Bakkot: I use generators to implement generators
02:53
<devsnek>
it doesn't bubble through AOs though
02:53
<devsnek>
kind of a mess
02:56
<Bakkot>
hmm
02:56
<Bakkot>
step one implement generators from scratch
02:56
<devsnek>
lol
02:56
<Bakkot>
step two implement multithreading by making everything a generator
02:57
<devsnek>
well I was thinking, I might not be able to test actual multithreading but I could at least test that the spec steps generally make sense
02:58
<devsnek>
I am also working on a bytecode evaluator (called "boost"), I could do more in depth validation with that if I ever finish it
02:58
<Bakkot>
designing a bytecode for JS is a fun exercise
02:59
<Bakkot>
mostly the try/finally bits
02:59
<devsnek>
took me a good while to realize new expressions can be two opcodes
03:00
<devsnek>
I do try/catch by pushing an instruction pointer and current stack depth into an array
03:01
<devsnek>
instruction pointer of the catch block anyway
03:01
<devsnek>
doesn't support finally blocks yet
03:01
<Bakkot>
catch is pretty easy, finally is somewhat trickier
03:01
<Bakkot>
getting finally right was like 25% of the entire effort of building the VM when I tried this
03:01
<devsnek>
I guess it's a desugaring problem
03:01
<Bakkot>
yup
03:01
<devsnek>
try finally = catch that throws at the end
03:02
<devsnek>
try catch finally = try catch that catches and then catch that throws
03:02
<devsnek>
maybe
03:02
<Bakkot>
`try { } catch (e) {} finally {}` is 100% equivalent to `try { try {} catch (e) {} } finally {}`
03:03
<devsnek>
that's fun
03:03
<devsnek>
actually wait it has to deal with return instructions too
03:03
<Bakkot>
yeah return and break are the part that make this hard
03:03
<devsnek>
I guess you have to push a fake return location
03:04
<Bakkot>
let me see if I can get permission to open source the fuzzer I wrote for this
03:04
<devsnek>
ooo
03:04
<Bakkot>
(it's the obvious thing you'd do if you set out to write a fuzzer for this problem, nothing special)
03:04
<Bakkot>
(just I have already written it)
03:05
<devsnek>
I tell myself I'll start fuzzing after I pass all of test262
03:05
<devsnek>
haven't gotten that far yet
03:05
<Bakkot>
the fun cases are stuff like `x: try { return 0; } finally { if (Math.random() < 5) break x; }`
03:05
<Bakkot>
`< .5`, not 5
03:06
<devsnek>
I haven't done labels yet either
03:06
<devsnek>
I guess that won't be too hard to add
17:17
<devsnek>
rkirsling: still failing like 10k tests but looking pretty good in terms of test262 coverage https://gc.gy/62624842.png
17:17
<devsnek>
er
17:17
<devsnek>
rwaldron: ^
20:06
<devsnek>
I feel like this might've been brought up before but it's weird that return is sometimes an await and sometimes not
20:06
<devsnek>
in async vs async generator
20:07
<ljharb>
hm, i would assume it never needs the await
20:08
<devsnek>
it's better for it to include the await
20:08
<devsnek>
cuz of try/catch
20:10
<ljharb>
in the spec?
20:11
<devsnek>
I mean so you don't need to write `return await`
20:13
<ljharb>
right but you might not want the await
20:14
<ljharb>
the way it works in async function imo is the right way; i think there was discussion about this for async generators late in the process, but i don't remember the outcome
20:33
<Bakkot>
I know we discussed it for `yield`, see https://github.com/tc39/proposal-async-iteration/issues/93
20:34
<Bakkot>
I would guess that `return` implicitly unwraps in async generators so that it matches `yield`
20:34
<Bakkot>
it is a bit odd though
20:36
<Bakkot>
oh, wait, that happens because the value from `return` isn't going to get wrapped in a promise
20:38
<Bakkot>
if `return` didn't implicit await you could end up with `{ done: true, value: [a promise] }`, which would be weird
20:38
<Bakkot>
(at least, I assume this is the reason)
20:39
<ljharb>
ah right, yes, that was the reason
20:39
<devsnek>
that doesn't have to be an await
20:39
<ljharb>
iirc, i'd have preferred syntactically requiring `return await`, but instead we went with implicit await
20:39
<devsnek>
it could be a `.then(fulfill)`
20:39
<devsnek>
pushing the error to the caller instead of the returner
20:40
<Bakkot>
that would be weirder still
20:40
<devsnek>
it makes more sense to me than the await
20:42
<Bakkot>
actually wait maybe I don't understand the proposal
20:42
<Bakkot>
what would `(async function*(){ return Promise.reject(0); })` return?
20:42
<Bakkot>
(and the first couple of `.next`s)
20:43
<devsnek>
idk off the top of my head
20:43
<devsnek>
i could plug my idea into engine262 in a bit
23:56
<Bakkot>
bradleymeck: did you have a repo for the arbitrary-module-specifiers proposal?
23:56
<Bakkot>
could find it on tc39/proposals