Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Implementing array-style iteration from an extension

10 views
Skip to first unread message

Steve Fink

unread,
Aug 2, 2010, 8:32:03 PM8/2/10
to dev-tech-...@lists.mozilla.org
I have a class that somewhat mimics an array interface, but I can't get
iteration to work:

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.

Steve Fink

unread,
Aug 3, 2010, 5:40:39 PM8/3/10
to dev-tech-...@lists.mozilla.org
On 08/02/2010 05:32 PM, Steve Fink wrote:
> I have a class that somewhat mimics an array interface, but I can't get
> iteration to work:

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?

0 new messages