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

Enumeration API changes

2 views
Skip to first unread message

Jeff Walden

unread,
Jul 7, 2010, 8:47:52 PM7/7/10
to
In order to properly support ECMAScript 5's Object.getOwnPropertyNames method, which returns an array of the names of all properties on an object (including non-enumerable ones), we have had to make a couple changes to SpiderMonkey enumeration APIs that client users might implement.

First, JSIterateOp, which is currently (JSENUMERATE_INIT | JSENUMERATE_NEXT | JSENUMERATE_DESTROY), is gaining JSENUMERATE_INIT_ALL. This new enumeration indicates the start of iteration over all properties -- not just enumerable properties -- of the relevant object. It is used, and functions, otherwise identically to JSENUMERATE_INIT. All users will need to update implementations of JSClass.enumerate when JSCLASS_NEW_ENUMERATE has been specified, and friend users will need to update implementations of JSObjectOps.enumerate.

The short-term fix required by this is for users to handle JSENUMERATE_INIT_ALL anywhere where JSIterateOp is currently handled. If you handle it identically to how you handle JSENUMERATE_INIT, you'll compile without warnings and should avoid errors caused by not handling all JSIterateOp enumerations. Object.getOwnPropertyNames will return incorrect property lists if you do this, but at least you won't go horribly awry. Long-term, add non-enumerable lazy properties the resolve hook could add.

Second, JSClass.enumerate without JSCLASS_NEW_ENUMERATE must now define all lazy properties (those which would be added by JSClass.resolve if the relevant id were specified) on an object -- not just enumerable properties as happens now. The short-term fix is...nothing. You'll just get lies as with the previous case. Long-term, make it define everything.

Since these changes are mandated by ES5, we can't avoid making these JSAPI changes in at least some format. I don't see a way these could be minimized any further, but maybe I'm missing something obvious. Feel free to make suggestions here if you have them.

Questions, comments?

Jeff

Wes Garland

unread,
Jul 7, 2010, 9:11:31 PM7/7/10
to Jeff Walden, dev-tech-...@lists.mozilla.org
> Questions, comments?

YAY!

A nice way to enumerate non-enumerable props without resorting to the debug
API is a real bonus -- embedders have been wishing for this for a while.
(Use case: tab-completion in REPLs).

Additionally, IMHO, this shouldn't be much of a problem with embeddings
which are coded defensively. Expecting new enumeration phases is completely
foreseeable, meaning I tend to prefer patterns like

switch(how)
{
case JS_ENUMERATE_INIT:
/* code */
break;
case JS_ENUMERATE_NEXT:
/* code */
break;
case JS_ENUMERATE_DESTORY:
/* code */
break;
default:
GPSEE_NOT_REACHED("Unexpected enumeration phase");
return JS_TRUE;
}

...yielding an assertion with debug builds and correct operation with
release builds.

It might not be a bad idea to suggest this sort of defensive coding in the
embedder guide someday. There's a few APIs like this in the JSAPI (gc
callbacks immediately spring to mind).

Wes

--
Wesley W. Garland
Director, Product Development
PageMail, Inc.
+1 613 542 2787 x 102

Bo Lorentsen

unread,
Jul 8, 2010, 3:16:00 AM7/8/10
to dev-tech-...@lists.mozilla.org
On 2010-07-08 02:47, Jeff Walden wrote:
> Questions, comments?
Ahh, that explained why this JSENUMERATE_INIT_ALL was needed by the
jsapi from hg here the other day :-)

I like to know how to get to the information about the properties
already added to an object by jsapi. Normally when you are embedding,
you add some functions and maybe some properties, and then sometimes you
add a resolver to get lazy values.

Now, when embedding you ofcouse know the resolved lazy values, but how
do I get to enumerate over all the properties defined on the JSObject,
using the jsapi ?

As I understand it, the task is to compine ALL properties, both
functions, jsapi properties and lazy resolved ?

/BL

0 new messages