pmurias's blog

Final GSoC report

What's done?

A cross compiling nqp-js (running on top of parrot) passes all tests in nqp/t/nqp with the exception of test 49 (which does an equivalent of eval, which would be really tricky do in a cross compiler).
It also passes the serialization tests in nqp/t/serialization.
It also passes the same tests as nqp-parrot in nqp/t/qregex.
We use a custom harness for those to avoid compiling regex at runtime.

A standalone nqp-js (compiled with a cross compiling nqp-js and using a setting compiled by a cross compiling nqp-js) passes most of the tests in nqp/t/nqp (it fails 5 of them).

GSoc progress report

Got the nqp/t/qregex tests to pass.
It would be a good idead for me to document how the rules engines of the MoarVM, Parrot, JVM and JavaScript backends work.
They are pretty similiar as it's basically the translation of the same code.
Unfortunately some things get cargo culted.
Like parrot registers names ending up in MoarVM code.

This means the rules engines implementation is resonably sane.
Incorrect test description caused a lot of confusion.

GSoc progress report

All tests in nqp/t/nqp with the exception of test 49 are passing.

Test 49 among other things requires compiling regexes at runtime.

my $regex := "a+";
"aaaaa" ~~ /<$regex>/;

This is easy to do after bootstraping (when we have the whole compiler avaliable at runtime) or a bunch of crafty hacks.
After attempting to quick hack a workaround (which would involve starting up a new parrot process to cross compile a regex) it turned out our current cross compiling solution won't work. I decided to avoid waisting time on that and leave it to after the boostrap.

t/nqp directory in the nqp repository contains all the tests for the NQP language features.
There are also tests in t/qregex which are really a whole bunch of regex and their expected results on a suplied string.
(in a tab separated format + a harness).
And 3 tests in t/serialization which would involve a boring translation of serialization code from a different backend.

What seems to be a good direction is to get all the tests qast tests (which were written by Jonathan while porting nqp to the jvm) under JavaScript. They test the backend without requiring a parser. Doing that has uncovered a number of bugs in nqp-js. Major things like multi methods seem to work correctly but I have encoutered many small bugs. Which seems to imply that the nqp test suit needs to be more exaustive.
A few examples of those and their fixes:

nqp::null() was tested for truthfullness is some places, we are currently doing that using a .Bool method so I had instead of using a native javascript null switch to using a custom singleton for that.

Objects being false by default caused if $slurp {...emit some code for slurp...} not to work

\n not being implemented in regexes caused subst(/\n/,"\\n",:global) to loop infinitly:

Currently in nqp-js I'm using JavaScript arrays as nqp arrays (with a bunch of methods monkey patched on top of them).
That caused a problem as JavaScript alread has a push and unshift methods (hinting that it was somewhat inspired by Perl 5).
The tests thus far where using the nqp::push op for adding elements to arrays.
However QAST::Compiler::JavaScript uses the .push method
Example: nqp::push(@foo,$value) vs @foo.push($value).

My current calling convention is that $"named"),1) is translated to $,{"a":"named"},1).

Which ended up in strange things being added into arrays (Which resulted in some fun debugging).

Progress Report

While trying to get QASTNode.nqp to compile I noticed a strange error claiming that some code refs where missing from the serialization context.
By binarysecting the file (deleting line till the error goes away) it turned out that roles in modules where causing problems. Serializing roles requires serializing a closure, and modules are special that they require to be compiled twice, both to JavaScript and PIR (that is untill we are fully boostraped).
The thing that turned out to be causing trouble is that the JavaScript backend is using a slightly different bootstraping procedure.

Weekly GSoC progress report

I have finally implemented the closure deserialization correctly.
It required changing the way static lexicals are handle. (Static lexicals are the one declared by a QAST::Var node with a decl equal to 'static', which means they are bound to a serialized object and we are free to assume they don't get bound to at runtime). Previously for every code ref which was a part of a serialized object (but not a closure) I have emited code to recreat all the static lexicals for all of it's outer context. Needless to say the resulting code was long and ugly.

GSoC weekly raport - my rakudo breaking adventure

I tried to mimick the way subroutines are wrapped on rakudo and make test passed on parrot I commited the code.
And it broke nqp on the jvm. And I realised that rakudo on the jvm uses the HEAD revision on nqp and not a version specified in tools/build/NQP_REVISION. And after my commit make test broke on nqp.
I reverted the commit, and Jonathan Worthington figured out that I misunderstood what p6capture_lex did.

GSoC weekly raport.

The thing I'm currently working is proper deserialization of closures.

If we create closures at compile time (example in Perl 6 syntax), like:

my $count = 0;
sub foo {
my $id = $count++;
-> {
my $sub = BEGIN foo();

we need to be able to save them between compilations.

First inchstone.

I have started hacking on my GSoC project to create a JavaScript backend for NQP (a Perl 6 dialect), which will be grown into a full one for Rakudo in the future.
Today I have unbitrotted the existing code at by handling QAST::Var's with decl set to "static" (variables that don't change at runtime) the same as ones with "var" (normal ones). As such I have completed the first of 15 inchstones ;)

Syndicate content