Wednesday, June 12, 2013

On Harmony JavaScript Generators

Developers get easily excited when something so used, acclaimed, and desired in another land comes to their own ... or the one they think they own ...
This is the case of ECMAScript 6 Harmony Generators, something at this time you need to activate through the --harmony flag in node or going to about:flags in Google Chrome Canary url bar and enable experimental harmony/extension.
Once you've done that, you'll be able, still through Chrome Canary at this time, to test examples, benchmarks, and other things in this post ... ready? So here the first great news:

Generators Are Slower

At least two times slower than forEach and about 10 times slower than regular loops.
This is the result showed in this jsperf benchmark you can run too.
Of course generators are slower, there's a massive process behind each generator such:
{
  code: 'the generator function body',
  context: 'the bound/trapped context',
  scope: 'the whole scope used by the generator',
  handler: 'to perform iterations',
  state: 'the current generator private state',
  // inherited from GeneratorConstructorPrototype
  send: 'the method to address values',
  throw: 'the method to throw Errors',
  next: 'the method to keep looping'
}
// plus every 'next' or 'send' call
// will return a fresh new object
{
  value: 'the current value at this time',
  done: 'the boolean value that helps with iterations'
  // when done is true, an extra call
  // to .next() will throw an error!
}

Not Only Slower ...

The fact every interaction with a single generator creates N amount of objects means that the garbage collector will work more than necessary and the RAM will be easily saturated whenever your server does not have such big amount of it ... and cheap hosts are still the most common choice plus if the program/language is greedy, why should you spend more in hosting hardware? You should not, as easy as that.

... But Feel Free To Use Them

If you believe generators can help anything in your logic, infrastructure, system, and you don't need best performance for that situation go with generators. These have been used in Mozilla internals for a while since there when Firefox was version 3 or even lower, can you believe it?
So, if these worked before becoming part of a standard and before hardware was as good as it is today, there must be use cases where generators are a better choice ... right?

JavaScript Never Needed To Sleep !!!

Unfortunately, a part for some academic Fibonacci exercise or even worst some sleep(delay) example, there's no much more you'll find about how cools are generators in JS .. simply because JavaScript never really needed them, being an Event handler oriented/prone programming language, where events always worked even better than generators for other languages since events can be triggered at any point, not just in a synchronous "top-to-bottom" flow.

Coming From Mars

One common problem in JS is that every new comer would like to find what is missing the most from her/his own old programming language ...
  • PHP developers never complained about missing types, they'll rarely get how prototype inheritance works there though
  • Java developers complains about missing types ... they'll try to use the JS flexibility to make it as similar as Java as possible understanding inheritance slightly better than PHP devs and abusing closures by all means to make it as super() compatible as possible 'cause ParentClass.call(this); inside ChildClass constructor freaks them out
  • C# developers think they have all the best there ... forgetting C# is not statically compilable and it is derived from ECMAScript 4th Edition, almost 2 editions before current JavaScript specification ^_^
  • C++ developers will propose new optimized Virtual Machines every day and most likely will probably never use JS ... still they will decide how JS developers should use JS regardless
  • Python and Ruby developers will just laugh about all JS shenanigans thinking their favorite language has none of them or worst
Well, here the thing ... generators and yield keyword are really old concept from languages that have not being created to work asynchronously as JS does, included all those mentioned in above list.
That's why I believe generators aim is being misunderstood from JS community ... and once again, feel free to use them as much as you want, but please keep reading too, thanks!

Queuing The Delay

if you start waiting for events after other events in a generator way:
var file1 = yield readingFile('one'),
    file2 = yield readingFile('two'),
    combined = file1.value + file2.value;
Here the bad news: that won't work magically as you expect!
// a magic function with many yields ...
function* gottaCatchEmAll(fileN) {
  for (var i = 0; i < arguments.length; i++) {
    yield arguments[i];
  }
}

// a magic expected behavior that won't work
// as many might expect ...
var content = gottaCatchEmAll(
  'file1.txt',
  'file2.txt'
);
Until we call content.next(), we eventually store the object value if no error has been threw and the done property is false, no parallel file loading will be performed by all means!
That's correct, what node.js elegantly solved with what JS was offering already, is screwed again with this new approach that won't block and won't execute at the same time.

Still Room For New Users

The controversial part about generators is that these might be useful to synchronize sequential, inevitably delayed or dependent executions while still non blocking other handlers ... well, here a couple of thoughts:
  1. try to make a generator behave as you expect ... seriously!
  2. try to learn how to use a queue instead
Not kidding, the second part is much easier than expected plus is a Promise like approach compatible with every environment and it fits in a tweet.
function Queue(a,b){
setTimeout(a.next=function(){
return(b=a.shift())?!!b(a,arguments)||!0:!1
},0);
return a}

How Does That Work?

I've tried to explain that in details in this working with queues blog post and at the same time I have written a slightly improved queue so that arguments can be passed between callbacks.
var fs = require('fs');
var q = Queue([
  function onRead(queue, args){
    if (args) {
      // add result to the content
      queue.content.push(args[1]);
      // if there was an error ...
      if (args[0]) {
        // attach it to the queue object
        queue.error = args[0];
      }
    } else {
      // first time execution
      queue.content = [];
    }
    // if there's anything to read
    if (queue.files.length) {
      // add "priority queue" to itself
      queue.unshift(onRead);
      // so that once done ...
      fs.readFile(
        // ... reducing the number of files to read
        queue.files.shift(),
        // ... will be re-executed
        queue.next
      );
    } else {
      // simply fire the end of this thing
      queue.next();
    }
  },
  function theEnd(queue) {
    // if there was an error ...
    if (queue.error) {
      // throw it or do whatever!
      throw queue.error;
    }
    // otherwise simply show results
    console.log(queue.content.join(''));
  }
]);

// files to load
q.files = [
  'file1.txt',
  '/user/attempt/file2.txt'
];

OH Come On What Is That

If you think dealing with generators is easier and the real effort behind the yield keyword is less verbose than above abstract example over a single use case, I am here waiting for your link to show me the ease, the cross version/platform compatibility, the performance (and I am not talking about your latest MacBook Air device but hardware Raspberry-Pi like which is suitable and already used as a web server) of your generator based solution willing to reconsider my point of view and change some module in order to switch, even if not needed, to this new approach.
Right now I see this new entry as completely overrated, able to bring fragmentation between node.js and the Web, and unable to concretely simplify or solve parallel asynchronous operations as elegantly as events would do through emitters.
Thanks for your effort reading 'till the end.
Some comment outside this blog:
  • Alex Russel on performance, and my reply which is: bound functions are still slow. I am not expecting generators to be faster than bound functions at any time in the near future

Wednesday, June 05, 2013

ArchLinux Might Not Play Cool

Update

This rant, referred to that time, is still valid. However, the lastest ArchLinuxARM package has been updated after the big change and everything works again as expected. Thanks Arch Linux for updating all packages, appreciated!
I'm actually avoiding a title such WTF ArchLinux to not leave a mark for this awesome community ... I mean, the best of the best: an always updated Linux distro for many devices and architectures blazing fast on boot time and freaking lightweight so you can put any extra you want and nothing more .. how can anyone ask more ...

Kids Play Too Much There

No, really ... this is not about blaming anyone specifically but seriously, a change able to brick every device ain't cool guys, not at all.

Cannot Trust Pacman Anymore

The main tool designed to update your system is screwed for basically every single tutorial about installing Arch Linux I could find on the net. pacman is doomed by an update, philosophically superfluous, able to make the update manager itself a joke.
That's correct, now you need to update all tutorials out there that says that
to update your system, you should simply pacman -Syu and working magic happens
Now every single piece of internet related to pacman or how ArchLinux is updated won't work anymore.

Cubieboard Is Just One

Every single article that will make you happy about installing ArchLinux in this board, or any other, will piss you off if source files you download are before 4th of July 2013 because the moment you can say hooray, it worked and you'll keep following instructions that will tell you best thing ever to do after a successful ArchLinux installation is to pacman -Syu as first command will nicely fuck up all your effort.

Focusing On Something Else

I am a developer and I love tools. The OS is just one of them to me, the one that makes me work and experiment with things I do for working or things I do for myself.
If I cannot trust the fact Linux is there since ever and every related OS is using some rootfs structure that worked without problems untile now, I don't want to find that everything that was using that structure won't work anymore because of some decision that is not practically friendly with any user in the community since it's not compatible with the single package manager the community is using ... I mean .. seriously ... WTF!!!

Just A Haughty Community ?

Worst part is that I was going to humbly open a post in your forum then I've realized to do that I have to register and answer this question in order to do that:
What is the output of "date -u +%V$(uname)|sha256sum|sed 's/\W//g'"?
I've never seen anything dumber that that .. first of all, if that's because a possible robot, most likely runs over Linux and is able to simulate the question wrapped in quotes and produce automatic result, if this was an idiotic robot attempt, secondly because the moment I want register to the forum is probably because one of your community "hackers" did such dumb mistake that I cannot even test my ArchLinux machine anymore ... so, whoever thought that was a good way to welcome your forum members, has a very regular IQ, if not lower than that.

Focus On Something Else

The moment a community with a vibrant and excellent product as ArchLinux is starts wasting everybody time behind these philosophical changes that break everything in facts is the moment the community needs to breath 5 minutes and think what the hell is going on and what's really needed to make the community better instead of pissing everybody off about some decision that no matter if was OK and right, it should NOT have broken all users around that were trusting the package manager to simply work as explained and emphasized everywhere on the WEB
Apologies for the rant but ... bloody hell, I've got all my boards screwed because of this "little change" in the whole OS.

Even Dumber

The page that is telling us how to update things is suggesting
# pacman -Syu --ignore filesystem,bash
# pacman -S bash
# pacman -Su
... too bad the current latest updated pacman cannot be installed without the updated bash too ... congratulations!

Saturday, June 01, 2013

The node.js Relative Path Case

Right now, it sucks because ___, as @izs told me to start with, I could not find a simple way to resolve a path from a module that exported a function into another one.
Spoiler: the reason I am trying to resolve paths is to load fresh modules runtime in polpetta. However, this might be a bad practice.
@WebReflection Lest I commit malpractice, I must tell you this is a terrible idea. Now warned, rock on with your bad self. Hack away :)
Still, my point is that it might be handy to be able to resolve paths relatively form the invoker regardless the why, even if you should always ask yourself that ;)
This case is quite easy to misunderstand so I'll skip extra explanations now and put down some code.

relative.js

This example file aim is to log ASAP two different path resolutions: the one from the path, passing through the process.cwd(), and the one from the relative.js file itself.
Object.defineProperties(this, {
  parent: {
    get: function () {
      // used later on
      return module.parent;
    }
  },
  resolve: {
    value: function (path) {
      // it will resolve from this file
      // not from the invoker
      return require.resolve(path);
    }
  }
});

// path module resolves relatively
// from the current process.cwd()
console.log(require('path').resolve('.'));

// require resolves relatively from
// the current file
console.log(require.resolve('./relative.js'));
Running this from node terminal will most likely show something like:
require('./test/relative.js');
/Users/yourname/code
/Users/yourname/code/test/relative.js
Neither logs or resolution are actually OK if we would like to resolve relatively from that path.
If we would like to use that module method, talking about the resolve() one, we cannot trust the current path.
// will throw an error
require('./test/relative.js').resolve('./test/relative.js');

// will pass
require('./test/relative.js').resolve('./relative.js');
If we install that module through npm as global, or even local in some super folder, gosh knows where we should start the relative path resolution accordingly with the module itself, you know what I mean?

Being Relative To The Invoker Path

In order to be able to resolve relatively from the invoker, we need to know at least where is the invoker.
Thankfully, this is easy but be aware of the caching problem:
// relative.js
var
  path = require('path'),
  relativeDir = path.dirname(
    module.parent.filename
  )
;
this.resolve = function (module) {
  return require.resolve(
    path.join(relativeDir, module)
  );
};
At this point we can invoke the method as expected without having erros, from the process folder.
// will log the right path
require('./test/relative.js').resolve('./test/relative.js');
Good, we are able to resolve module names, problem is ... only from the very first one that required relative.js due module caching so that module.parent will be one, and only one, for any other module.

A Hacky Solution

In order to avoid the caching problem within the required module itself, I came up with such trick at the end of the file:
// .. same content described above ...

// remove the module itself from the cache
delete require.cache[__filename];
In this way every single module that will require('./some-path/relative.js') will have a fresh new version of that module so that module.parent, and its filename, will be always the right one: how cool is that?
I am able to resolve relatively from any outer module its path the same way require.resolve(path) would do inside that module which is exactly needed and the goal of require-updated so that any module can use paths as if these were resolved from the file itself in order to require some other file, relative, absolute, or globally installed.
Still I believe there should be a better way to do this ... what do you say?

Thursday, May 16, 2013

Object.setPrototypeOf(O, proto) IS in ES6

This one is a short one, just to confirm that finally Object.setPrototypeOf(obj, proto) made it into ES6.
The section 15.2.3.2 speaks clearly:
15.2.3.2 Object.setPrototypeOf ( O, proto )
When the setPrototypeOf function is called with arguments O and proto, the following steps are taken:
  1. If Type(O) is not Object, then throw a TypeError exception.
  2. If Type(proto) is neither Object or Null, then throw a TypeError exception.
  3. Let status be the result of calling the [[SetInheritance]] internal method of O with argument proto.
  4. ReturnIfAbrupt(status).
  5. If status is false, then throw a TypeError exception.
  6. Return O.
Without going into details, the most basic polyfill woud be like this:
(function(O,s){
O[s]||(O[s]=function(o,p){o.__proto__=p;return o})
}(Object,'setPrototypeOf'));
If you want to go into details, the full reliable polyfill is hard to write down due all inconsistencies across JS engines out there where the __proto__ setter cannot be reused which means it's not possible to trust this magic over objects created from null.
All you need to do is forget __proto__ and use the suggested polyfill until the day __proto__ can simply disappear from those specs pages.
Enjoy!
This is a full polyfill with some extra info you might want to analyze, whenever ployfill is strictly true or false.

Saturday, April 27, 2013

Few Modern JavaScript Inconsistencies

While the JavaScript weekly mailing list still points to 90s style articles about the old JavaScript Internet Explorer 5 was supporting too, the current world has different real problems to consider.
Here a quick list of things you might not know about the current status of JavaScript possibilities.

Reserved Words As Properties

Number one of the list is the myth that reserved words cannot be used as properties. Here platforms that cannot:

  1. iOS 4
  2. IE less than 9
  3. Android less than 2.1

So, basically, 99% of mobile browsers support properties such obj.delete(), used in most recent JavaScript specifications, while those jurassic browsers need the obj['delete']() convention.

// exactly same good old ES3 behavior
// using ES5 capabilities
Function.prototype.new = function () {
  var
    // grab the prototype
    p = this.prototype,
    // create from it
    o = Object.create(p),
    // invoke the real constructor
    r = this.apply(o, arguments);
  // if the result is not undefined or null
  // and the returned value is an object/function
  // overwrite the result
  return r != null && (
    typeof r === 'object' ||
    typeof r === 'function'
  ) ? r : o;
};

// you can be Rubyish now ^_^
var instance = MyClass.new(1, 2, 3);

// P.S. if you have problems with JSLint
// and the r != null part in above snippet
// it's just time for you to upgrade to JSHint

Please Do Not Support Too Old Browsers

As easy as that. As a developer, company, software provider, whatever, you are trapping yourself behind problems that will never be fixed in those browsers and you are limiting your customer too, embracing development for such old environment, instead of promoting an update that will benefit them in terms of both potentials, expenses, and security.
Any company that will say no to that should be kindly be abandoned, IMHO, they're already out of web/JS business and they don't realize yet.
I understand some graceful measurement should be taken in order to migrate old users, but as long as they feel confortable, they won't migrate sooner for sure.
Customers or people we'd like to let them access our service, should be informed somehow of new possibilities too.

Apple Drops 3 Years Old Software Too

If Apple not accepting non retina software anymore is not enough as an argument, think how many possibilities you are dropping to your software in order to work the same in those old browsers.
You chose Web technologies, you should catch up with these, end of the story.

Object.defineProperty() *Is* Available

Even my Palm Pre 2 webOS supports Object.defineProperty(), together with Object.defineProperties(), Object.getPrototypeOf() and Object.getOwnPropertyDescriptor()!
If you don't want to deal with all this verbosity but you like the power behind, redefine is really your best friend then!

The most widely adopted list of ES5 features down to Android 2.1 phones and webOS are:

  1. Object.create()
  2. Object.defineProperty()
  3. Object.defineProperties()
  4. Object.getOwnPropertyNames()
  5. Object.getOwnPropertyDescriptor()
  6. Object.getPrototypeOf()

Things like Object.freeze() might have been introduced later on so don't trust them ... but, whenever you wanna try that:

var freeze = Object.freeze || Object;
freeze({}); // frozen where possible

function returnFrozen(object) {
  return (Object.freeze || Object)(object);
}

As it is for "use strict"; and all other things that works best natively, above technique will work with Object.seal(), Object.preventExtensions(), and why not, a shimmable Object.isExtensible()

'isExtensible' in Object || (function(){
  // no way ES3 can prevent extension so ...
  Object.isExtensible = function (object) {
    // ... if an object, it's extensible
    return object != null && (
      typeof object === 'object' ||
      typeof object === 'function'
    )
  };
}());

Function.prototype get caller() {return WTF}

Generally speaking the caller property works since ever but there are cases where it does not and this is iOS5 and lower fault.
What am I talking about? About caller over getters, with or without __defineGetter__ old style approach, the new one fails too ^_^
Bear in mind iOS 5.1 and 6.0+ are just fine so you can still use that magic, if needed.
Note a part, that magic ain't disappearing any time soon so ... go on, use caller until there is an alternative: so far, not a single one ^_^

Function.prototype.bind()

It took literarily ages for WebKit to adopt this method so this is something available in all modern browsers but most likely not available with not so old mobile one: easy shim from callerOf!

(function (P, l) {
  'use strict';
  if (!P.bind) {
    P.bind = function (s) {
      var
        c = this,
        a = l.call(arguments, 1);
      return function bind() {
        return c.apply(s, a.concat(l.call(arguments)));
      };
    };
  }
}(Function.prototype, [].slice));

This is the kind of code that I would like to see in CDN, not just 50K libraries for client sake!

Avoid __proto__

Not only conceptually an error and used only to gain some arguable performance boost, __proto__ is absolutely something that IE 10 and 9 will never have in a consistent way.

If you want to transform a list into an array, just var slice = Function.call.bind([].slice); so that you can slice(whatever, optionalIndex) ALL the things, right? The bind() is there and costs nothing ... just use it!

Better Than Zepto

What this library is doing, except from ignoring IE as a Mobile browser, is a poor/quick&dirty design/convention to obtain a prototype swap instead of initializing things in the right way.
The previously linked code could be represented by exactly the same syntax:

// an IE9 and 10 compatible zero bullshit Zepto core
var emptyArray = [];
zepto.Z = function(dom, selector) {
  var result = Object.create($.fn);
  emptyArray.push.apply(
    result, dom || emptyArray
  );
  result.selector = selector || '';
  return result;
}

While performance might not be that good in some engine, and everybody knows that you should never $('select') twice per collection so actually, considering above snippet goes 400.000 objects per seconds, that's not a big/real deal at all!
If that is, I tell you something else is wrong in the app logic!
In any case, actually, there's some mobile platform there, those Zepto thinks is supporting, that scores more with lower results than with a prototype swap, which is the most common selector case, BlackBerry 10 is 8 thousands operations per seconds there compared with __proto__
Thomas Fuchs has been so nice in his repository I cannot even push/contributes these improvements ... surely he would get this one as an insult too, isn't it?

A Swap Oriented __proto__ Attempt

Assuming you still want to swap runtime classes because you cannot define a proper inheritance upfront, here a broken attempt to do that in IE8 and lower:

object = dunder(object, proto);

what's dunder()

dunder() is my attempt to bring a friendly cross platform way, included older IE, to swap proto at runtime.
It requires an assignment so, back to Zepto example, return dunder(dom || [], $.fn) would be all you need to make it work everywhere.

JSON.stringify(object, *replacer*)

This is Safari specific gotcha, and it's about the replacer.
While specs say that Let newElement be the result of calling the abstract operation Walk, passing val and **ToString**(I), Safari will send to the receiver the number 0 instead of the string '0'.
What's the big deal here? That in JavaScript, 0 == false while '0' == true so ... if you have this kind of check in your receiver thinking that if empty, nothing should be done:

if (key) {
  // parse your value
}

Improve that check with if (key === ''), probably the only place on earth where JSLint would have helped you for real instead of messing up your own code.

And for today, that's all folks!

Wednesday, April 24, 2013

Boot To Node.js In 7 Seconds On Arch Linux

This is a long story that started with me buying a Raspberry Pi with the goal of discovering how good performance could have been in such device used as dedicated server.
The story goes on with pcDuino too, and tricks you might want to know about booting up and building node on them.

Why A Pi As A Server

The story of computers is not actually that fair for same computers, as not fair is the Moore's law itself.
Bear in mind, I am not saying that's not working, all I am saying is that if in 6 months we've got double amount of transistors in some CPU, this does not mean we've been used the previous CPU at its best for last 6 months!

Gaming, immortal, consoles such PS2 can describe better than my words what I am talking about: hardware is good until what you need does not fit under that 100% of potentials!

ARM Is Powerful

Not only is becoming one of the most ambitious target for any Operating System, probably including Microsoft, ARM is also both powerful and power consumption aware, something we've never rarely thought about before .. I mean, a server that does not need much electricity so that if some blackout happens it does not dry whatever counter blackout part is playing in the building? And what about a web farm?

A Raspberry Pi Web Hosting Colocation

Yes, it's not just me, and actually ... WTF!
When I've invested a bit of extra time trying to have up and running my own idea of a co-location, raspberrycolocation.com was born instead and sold out ... gosh I'm always late at the party!
What this smart guys did, is to offer a full server for about $50, being absolutely the most competitive dedicated server company in the world right now ... that's as easy as that .... but ...

Arch linux

What those guys offer is a colocation for your own Pi, a device I honestly would never put into anybody else hands (and that's the feeling you have when that little thing works as hell with awesome performance under your own software) over the Raspbian distro, surely a stable, well tested, etc, etc linux based OS, unfortunately kinda/"slightlier" heavy :(
R-Pi aim is to be a cheap replacement for a PC and in this case Raspbian is the most suitable distro you have there.
However, if you are planning to do something different that does not requires a GUI, and RAM is only 512 there, or any other extra thing on top, Arch Linux becomes the best alternative for this device.

The part I love the most about Arch Linux, is that it basically embraces my same philosophy when it comes to JavaScript or, generally speaking, programming with dependencies .... the less I have and the more I know about the app, the faster I move when it comes to add something, fix something, or experiment! (you should try this approach instead of putting, as example, jQuery or Zepto by default in your web page, it works, trust me!)

Living On The Edge

This Aerosmith song is probably looping inside any Arch Linux contributor, as this distribution is nothing about having frozen modules that pass some test and until tested everywhere else will never work, this distro is about having always the latest available software in your system, which will result in a freaking cool, always updated one, as ready for production as much as your node.js project or website is ... I mean, isn't modern JavaScript culture about serving what's the best thing available today? I love that too!

410+ MB of RAM

You don't need me to try the Raspbian distro and check how much require('os').freemem(); command will return in node pre 0.11.2, you can install the package instead of compiling it on the hardware as I am doing, and do the math.
If the device has 512MB of RAM, 410+ after OS booted in about 8 seconds ain't that bad, right? And I am sure the distro coul dbe even more minimalistic ... as it is, as example in the following platform:

The Allwinner 10

If I have to be honest with you, I would rather consider this platform, or any of its new derived, more than a Pi.
I know, kids price not so friendly, but here you have an ARMv7 with most likely at least 1Ghz of clock speed and 1GB of RAM over some NAND which is alwas faster than inboard SD controller (I'll come back on this part too)

The pcDuino Case

As example, you can have an Arch Linux distro able to boot up in 6 seconds into node.js, with an average of 0.3% of CPU usage via SSH to monitor what's going on behind the top scene!

If you try to do the same with the minimalistic full Desktop version of Ubuntu for this device, you'll notice at least 6 to 9% of default CPU usage because of the graphic OS, plus 691511296 of available RAM after boot against a require('os').freemem() resut of 797020160 for the Arch Linux headless distro .. yeah, you heard that right!

Slow Down, You Punk!

While Raspberry Pi has a pretty decent and complete image of Arch Linux that includes all hardware activation at boot time, no led excluded, pcDuino is kinda "problematic" as any Allwinner platform is because of the not so stable graphic videos ... who cares indeed!

If your goal is to have a dedicated server on the palm of your hand, the graphic whatever is something you won't care at all. I agree this might sound confusing at the beginning, if you are not familiar with linux bootable distros, but hey ... the video is such a pain in your spine I am not sure you really want to know how to fix that, do you?

Install Arch Linux In Allwinner A10 ARM Devices

This post and its welcomeness are kinda the beginning of the story about Arch Linux.
What you think makes sense for an OS ... well, you are already out of sync: Arch is kinda the skeleton of that OS, anything else is your choice/matter/problem/duty, if you want to support that platform.

Even More Annoying

Is not just the fact if you are noob in *nix world you should drop this distro by default since nobody wants to deal with you, the instructions, even if you are part of that world, are kinda crap too.

Thank You André

Despite André post talks about a different A10 board, the used code is clearly something you might find handy, once re-elaborated as such:

In my case I had to:

sh a10.sh /dev/sdb pcduino-bootloader.tar.gz pcduino

after changing things might be different for other A10 boards.

As Result

I've been impressed by polpetta performance, as generic hard drive surfer/common intra-cloud, on a network of 15+ devices: not a glitch over these platforms under hand compiled node.js 11.2 versions.
The average ping for this device in the network is 1.3 milli seconds, which is nothing!
Are you sure your initial web business demands much more as dedicated server?
What if a $40 dollars board plus SD card is all you need, to measure your startup success?

What's With SD Cards

The situation around SD Cards is awkward at least. So here the thing, I haven't spot any difference between an 8GB Extreme Pro SanDisk micro SD Card, and an Ultra 32GB version of the micro usb card ... but more over, I don't think you need such amount of space for any of these devices since even looping through FileSystem tables has a cost I believe your cheap ARM dedicated web server should not take into consideration ;)

Have fun with hints on the web about how to build your first dedicated web host in no more than $100 for years, network a part!

Sunday, April 21, 2013

The __proto__ Comic

© all images from ragefac.es and some from knowyourmeme
Being a comic, sentences are not all real, mostly made up for this post.

TC39

WTF is this shit?!

es-discuss

The community needs it and the de-facto library with stars on github uses that instead of [].push.call(new SimplifiedDOMShit, NodeListResult)

TC39

OK, here what we can spec ... making it configurable, so that shit can be dropped at any time in any module

es-discuss

Community, we are going to spec __proto__ shenanigans all over so that any environment will have a special property able to cause more disasters than what eval did before: you should appreciate!

community

so, proto gonna be standard we don't have to change those 2 lines of code?!

me plus some other

what kind of horrible decision is this?

es-discuss

de-facto is de-facto, people use this, people want this! IE ... who cares !

just me

OK, probably this is just a massive misunderstanding between what's truly needed, and what should be proposed ... let's try to fight back in es-discuss ...

es-discuss

You don't understand, you are late, even if not spec'd yet, you are really late

just me

I gonna show you that JavaScript developers understand this is a no-go and it's bad for the language they use on daily basis as bad, and even worse than boring hasOwnProperty check has been for all these years!

still me

Hello Zepto, somebody thinks we are all bigots unable to make simple changes ... here the patch for you repo, it's green, it works, it has no side effect, it demonstrates we are not bigots, what do you say?

Zepto.js

You White Knight bla, bla, bla ... horse shit bla ...

just me

WTF? I can't even explain myself there, they blocked me ... what should I do?

still just me

... well, I gonna see if at least node.js community, with much more unified environment, would accept a proposal...

still me

Hello node, here a patch that is waiting for a patch in V8 so the patch gonna patch the patch, what do you say?

node.js

We don't extend the language and we don't impose coding standards on our users.

again me

Will you consider at least this .. or that ... ?

again node.js

But we're not going to float a patch that adds this feature to V8

still just me

... well, I gonna see if at least V8 will accept my flag that gonna affect node at startup ...

V8

Well, I don't know if V8 will ever accept my patch (pleas star that!) but actually there is no reason to not accept it, it does not change anything in core, it does not affect anythign around, is something that if explicitly set, enable something that might be specified like that in ES6 in any case so together with all harmony flags and stuff usable when you run d8 or node, what could possibly go wrong?
Let me hope, at least, this is not a conspiracy against my mental sanity ... and if you star it it might go in before node 1 is released, thank you!

sad thing is, Zepto patch was not affecting Zepto performance or logic, neither was breaking things.
Same thing was for node.js, so I started doubting JS community is able to be proactive when it comes to decisions made somewhere else and for the community.
Developers are pragmatic, they use what's available at that time. If this means create a standard out of it, JavaScript will be anarchy and not a language anymore.
And this, my friend, is unfortunately a specifications circle that is not bringing only good things to the JavaScript as your favorite programming language.

Playing With V8 Native And JavaScript

What my Don Quixote like adventure against __proto__ gave me, if nothing, is a better understanding about how V8 engine internals work and how to bind JavaScript to native and vice-versa.

Please Note

Nobody told me anything I've written in this article is true. These are all assumptions after pushing a patch to V8 and learning by mistakes, compilation errors, and "code around reading", done in a couple of hours so apologies in advance if some term or some concept is not perfectly and deeply explained.
Let's start with this!

JavaScript In JavaScript

This was kinda surprising to me, almost the whole ECMAScript is implemented in JavaScript itself.
In few words, what V8 does is not something like Rhino, reimplementing the whole language via a statically compiled one as Java is in Rhino case, V8 is rather the compiler for the specific ES syntax, following an example ...

JSON In JavaScript

It's funny when we compare in jsperf json2 vs native vs jQuery.json vs json3 etc etc, knowing that V8 native JSON is 90% JavaScript, isn't it?

// just a chunk/example from V8 JSON
function JSONParse(text, reviver) {
  var unfiltered = %ParseJson(TO_STRING_INLINE(text));
  if (IS_SPEC_FUNCTION(reviver)) {
    return Revive({'': unfiltered}, '', reviver);
  } else {
    return unfiltered;
  }
}

Above snippet is simply a compact one with few things non common in Javascript: %PrefixedFunctions(), and UPPERCASE_FUNCTIONS().
These could or could not be bound in any V8 JavaScript files and we can see these JS files are those that will create the JS environment we are going to use but let's see how those special things work, OK?

Interoperation Between C++ And JavaScript

runtime.cc and runtime.h files are dedicated to, as the name suggests, runtime JavaScript calls into C++ world.
The runtime.js files contains instead many JS functions used internally to satisfy ECMAScript specifications but not exposed to the outer world.
Bear in mind latter is not the only file that has not exposed JavaScript, while everything that will go out is defined at bootstrap, as you would expect, per each global context (here why two sandboxes have different native constructors) and you can find it in the bootstrapper.cc file.
Scroll a bit, and you'll see how all known Array, String, Boolean, etc, are initialized, while in array.js you can see how the prototype is created: it's again a mix of native and JavaScript, passing though macros!

How To RUNTIME_FUNCTION

RUNTIME_FUNCTION(
  // return type, for JS interaction
  // will be a MaybeObject* one
  MaybeObject*,

  // the exposed %DoNotExposeProtoSetter()
  // function in the hidden JS world
  // behind the user available scene
  Runtime_DoNotExposeProtoSetter
) {
  // isolate pointer is necessary to access
  // heap and all JS types in C++
  // even true or false are a specific type
  // we cannot return true directly, as example
  // or the type won't match
  NoHandleAllocation ha(isolate);
  // in this case, returning true or false
  // does not require allocation or new objects
  // we can simply use what's already in the heap
  return FLAG_expose_proto_setter ?
    // this is a flag defined at d8 launch,
    // I'll go there too
    isolate->heap()->false_value() :
    isolate->heap()->true_value();
    // returns a JS false or a JS true on
    // %DoNotExposeProtoSetter() invocation
}

Above function is the same I've used for the patch, it does not accept a thing, it checks a generic program flag and returns true or false accordingly.
As every developer with a bit of C background knows, when a function is declared, it should be defined in the file header too, so here the runtime.h declaration:

  /* __proto__ Setter */ \
  F(DoNotExposeProtoSetter, 0, 1) \
  \

F is the common shortcut for RUNTIME_FUNCTION_LIST_ALWAYS_N while the first argument is the length of accepted arguments, -1 if unknown or dynamic.
The second argument seems to be a default for all functions, stick with 1 and things gonna be fine.

Dealing With JS Objects

My patch has a quite simplified signature, if you are aiming to accept and/or return objects, you should do things in a slightly different way, here an example:

// function call :-)
RUNTIME_FUNCTION(MaybeObject*, Runtime_Call) {
  // required to handle the current function scope
  HandleScope scope(isolate);
  // arguments are checked runtime, always
  ASSERT(args.length() >= 2);
  int argc = args.length() - 2;
  CONVERT_ARG_CHECKED(JSReceiver, fun, argc + 1);
  // the `this` context :-)
  Object* receiver = args[0];

  // If there are too many arguments,
  // allocate argv via malloc.
  const int argv_small_size = 10;
  // now you know, functions with more than 10 args
  // are slower :-)
  Handle<Object> argv_small_buffer[argv_small_size];
  // ...

  // in case it needs to throw an error ...
  bool threw;
  Handle<JSReceiver> hfun(fun);
  Handle<Object> hreceiver(receiver, isolate);

  // the result, could be undefined too,
  // which is a type indeed
  Handle<Object> result =
      // note, threw passed by reference
      Execution::Call(hfun, hreceiver, argc, argv,
      &threw, true);

  // do not return anything if there was an error
  if (threw) return Failure::Exception();

  // eventually, we got a function.call()
  return *result;
  // don't you feel a bit like "f**k yeah" ?
}

I've removed some extra loop for malloc but basically that's the lifecycle of a JavaScript call invocation.

What About Macros

macros.py contains some (I believe) highly optimized and target specific (x86, x64, arm) function, able to use %_CPlusPlus() functions, and containing most common/used functions across all JavaScript APIs such IS_UNDEFINED(obj).
It also contains many constants used here and there such common date numbers:

const HoursPerDay      = 24;
const MinutesPerHour   = 60;
const SecondsPerMinute = 60;
const msPerSecond      = 1000;
const msPerMinute      = 60000;
const msPerHour        = 3600000;
const msPerDay         = 86400000;
const msPerMonth       = 2592000000;

Dunno you, but I find myself often writing similar variables so I wonder if we should simply have them as public static Date properties ... never mind ...

d8 Options And Flags

To complete my journey into V8, I had to set a --expose-proto-setter flag into d8, which is the command line tool or the dll what you'll have after a successful build of the V8 project.

flag-definitions.h is basically all you need to define a runtime flag providing a decent description that will show up if you d8 --help:

DEFINE_bool(
  // the flag name
  // d8 --expose_proto_setter
  // OR
  // d8 --expose-proto-setter
  // is the same
  expose_proto_setter,
  // the default value
  false,
  // the flag description, better if meaningful ...
  "exposes ObjectSetProto though __proto__ descriptor.set")

In order to access that flag in runtime, do not forget to prefix it as FLAG_expose_proto_setter.
Remember, even a simple value as boolean is cannot be handled like that in JS so check again the RUNTIME_FUNCTION example.

Building V8

There is a V8 page specific for this task, all I can add here is that make x64.release is the fastest way to have a ./out/x64/release/d8 executable and start playing, at least in most common/modern PCs or Macs.

And That's All Folks!

I know it does not seem much, but this article covers:

  1. how to define a launch-time flag for d8
  2. how to interact with C++ bindings for JS code
  3. how to optimize some macro function
  4. how to understand magic V8 JS syntax
  5. how to manipulate, create, change, augment, natives and their prototypes
In few words with these steps anyone could write her/his own version of JavaScript, relying in a robust, extremely fast, and cross platform engine, able to also interact with PHP or other languages.
Bear in mind I am not suggesting anyone out there should start subfragmenting V8, I am sayng that if you need a very specific thing in the environment for a very specific project, you should not be scared by changing what you need and you can also help V8 to be better trying changes directly without just filing bugs: isn't this what Open Source is good for too?

I hope you enjoyed this post, have a nice day!