js> a = jscalls.entries
({})
js> a.length
37
js> a[0]
({function:"(execute)", script:"typein", lineno:1, enter:true, when:(new
Date(1280793591938791))})
js> for (i in a) { print(i); }
js>
(Note: it attempts to look up the jsid "__iterator__" in that last
example, but not in the plain printout cases.)
The ({function: ... }) line is correct. That is what all of the elements
should contain.
Here's my class:
static JSClass jscalls_entries_class = {
"jscalls_entries_class", JSCLASS_NEW_ENUMERATE,
JS_PropertyStub, JS_PropertyStub,
jscalls_getEntry, JS_PropertyStub,
(JSEnumerateOp)jscalls_enumerate, JS_ResolveStub,
JS_ConvertStub, NULL,
JSCLASS_NO_OPTIONAL_MEMBERS
};
This is passed to JS_NewObject:
JSObject *entries = JS_NewObject(cx, &jscalls_entries_class, NULL,
NULL);
When the js shell tries to print out the "array", jscalls_enumerate gets
called with the expected series of actions: JSENUMERATE_INIT once, then
a whole bunch of JSENUMERATE_NEXTs until I do *statep = JSVAL_NULL. I am
setting *idp to 0, 1, 2, ... correctly and returning JS_TRUE. What else
do I need to do? It is iterating over the values, but then seemingly not
using those values for anything.
The problem seems to be that returned indices for lookup isn't enough;
it then wants to resolve those to actual properties. To do that, I could
override the resolve operation, but that still requires me to create
actual properties and store them on the object.
That's not what I want. I want something that presents a JSArray-like
interface but maintains all data internally in C++ code.
JSArray does it by overriding the actual property lookup. According to
MDC, I could do this by setting a JSGetPropertyOps field in my JSClass
definition, but that doesn't seem to match the current code in m-c (or
tracemonkey). The place where that should be is called 'reserved0',
which is unused.
So how should I implement an object that handles numeric index lookups
without prepopulating it with tons of silly properties? Is there some
way of overriding property lookup?