1) What is the code before the "entry" label doing? It seems to be testing that nbargs=2, and if nbargs<2 it fills in %edx and %ebx with the undefined value... but the function (as seen in the LIR) expects 0 arguments. So if nbargs>0 there is a simple adjustment to do to the stack (pop ra; sp+=nbargs*4; push ra). Note that the implicit parameter "this" does not count as an argument (it is always passed in the calling convention).
2) The "ret $0" (3 bytes) is equivalent to "ret" (1 byte).
I guess you should bring this up at the meeting Wednesday. The return issue should be trivial to implement. The arguments one I don't know.
3) The code will be more compact, and perhaps just as fast, if the undefined value is stored in the context. That way the "movl $25,%eax" (5 bytes) can be replaced with "movl undef_offs(%ecx),%eax" (3 bytes). This trick can be used for other frequent constants (such as "true", "false", "null", 0, 1, 2). But there are better suggestions below...
Isn't moving data from the context to a register loading something from memory? How can that be faster than loading it directly from the (hopefully precached) code stream?
4) Another trick which can reduce the code size and possibly improve speed is to encode the special values ("true", "false", "null", "undefined", ...) using only the 8 low bits of a word (and with the two lowest bits equal to 01). The more significant bits, above the low 8 bits, can be any bit pattern because they ares never used in a test. So instead of "movl $25,%eax" (5 bytes) it would be sufficient to do "movb $25,%al" (2 bytes).
That should be feasible. As I keep saying, we need to keep a big TODO list of all the improvements we want to make after the bootstrap, and some kind of order of priority. I have a list of improvements I want to make to the IR/front-end myself. - Maxime