Object now has virtual get_own_property() and put_own_property() member
functions that can be overridden to provide custom behavior.
We use these virtuals to move Array-specific access behavior to Array.
- move() the property map when constructing ObjectExpression instead of
making a copy.
- Use key+value iterators to traverse the property map in the execute()
and dump() functions.
This function is ultimately supposed to be generic and allow any |this|
that has a length property, but for now it only works on our own Array
object type.
I'm not completely thrilled about Object::get() and Object::put() doing
special-case stuff for arrays, and we should probably come up with a
better abstraction for it.
But at least it works for now, which is really nice. :^)
This is pretty naive, we just walk up the prototype chain and call any
NativeProperty setter that we find. If we don't find one, we put/set
the value as an own property of the object itself.
FunctionExpression is mostly like FunctionDeclaration, except the name
is optional. Share the parsing logic in parse_function_node<NodeType>.
This allows us to do nice things like:
document.addEventListener("DOMContentLoaded", function() {
alert("Hello friends!");
});
This is pretty heavy and unoptimized, but it will do the trick for now.
Basically, Heap now has a HashTable<HandleImpl*> and you can call
JS::make_handle(T*) to construct a Handle<T> that guarantees that the
pointee will always survive GC until the Handle<T> is destroyed.
Now that Interpreter keeps all arguments in the CallFrame stack, we can
just pass a const-reference to the CallFrame's argument vector to each
function handler (instead of copying it.)
This patch adds a CallFrame stack to Interpreter, which keeps track of
the "this" value and all argument values passed in function calls.
Interpreter::gather_roots() scans the call stack, making sure that all
argument values get marked. :^)
We now scan the stack and CPU registers for potential pointers into the
GC heap, and include any valid Cell pointers in the set of roots.
This works pretty well but we'll also need to solve marking of things
passed to native functions, since those are currently in Vector<Value>
and the Vector storage is on the heap (not scanned.)
This commits makes effort towards tolerating some of javascript's quirks
when it comes to its type system, note that the interpreter's way of
handling type coercion is still not mature at all, for example, we still
have to implement NaN instead of just crashing when trying to parse a
string and failing.
Instead of every NativeFunction callback having to ask the Interpreter
for the current "this" value and then converting it to an Object etc,
just pass "this" as an Object* directly.
This patch adds NativeProperty, which can be used to implement object
properties that have C++ getters and/or setters.
Use this to move String.prototype.length to its correct place. :^)
To make sure that everyone has the same instance of StringPrototype,
hang a global prototype off of the Interpreter that can be fetched
when constructing new StringObjects.
This patch adds String.prototype.charAt() to demonstrate that prototype
property lookup works, and that you can call a prototype function on an
object, and it will do what you expect. :^)
Object will now traverse up the prototype chain when doing a get().
When a function is called on an object, that object will now also be
the "this" value inside the function. This stuff is probably not very
correct, but we will improve things as we go! :^)