please explain why you propose using a C++/Java style OOP style. Why
not use the procedural variant?
For one, I believe the OOP style is the one we agreed on when we discussed this earlier today in your office. The OOP style is the one you've already been using in the parser code you've showed us.
Another reason is that the OOP style is clearer, and allows us to use things like the prototype chain for inheritance, as well as other JavaScript facilities. The whole point of programming this VM in JavaScript is to simplify the implementation and make us more productive.
There is also the issue of name collision. Your method won't be called meth(). It will need to be called FooMeth. Or, in a more realistic example BasicBlockGetParents(), or something of the sort. Longer, uglier method names everywhere. We also still would need to use local functions in the case where virtual method calls are actually what we want, thereby forcing us to use x.meth1() in some cases, and FooMeth2(x) in other cases.
Let's not adopt coding standards that complicate our lives and essentially turn JavaScript into C, and make our lives harder, because then, we might as well use a *proven* approach, such as implementing this all in C++. That would perform well. I can guarantee it. It has type annotations, and the compilers already do inlining for you. We wouldn't even need to worry about all this bootstrapping business...
It will be hard for a compiler to determine that the call x.meth()
is actually calling the method "meth" in Foo (not only does the compiler have to determine that x is always an instance of the constructor Foo, but you have to ensure that there have been no mutations of the field "meth" in the instance bound to x). So it is hard to inline that method in place of the call x.meth().
Being able to know this kind of thing is the whole point of my Ph.D. thesis, as far as I'm concerned. A pretty simple flow-insensitive analysis could deduce those facts, and I intend to do better than that. You also have to realize. Knowing the type of x in a call to x.foo() is essential to gaining high performance levels. Inlining foo(x) won't gain you that much if your foo() function is naively compiled and full of dynamic dispatch. Furthermore, I believe it's possible for us to set some fields as read-only, thereby avoiding the problem of the field being modified.
Moreover, space has to be reserved in all instances of Foo for all
the methods in the non-optimized case, and it is not clear how these fields can be eliminated.
Not if the fields are read only. Not if the methods belong to a class we inherit from in the prototype hierarchy. Furthermore, is space really that much of an issue at this point?
- Maxime