proper handling of __iterator__ in getPropertyOp

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

proper handling of __iterator__ in getPropertyOp

Borislav Kapukaranov
Hi,

I'm having trouble handling __iterator__ in a custom getPropertyOp for a JSClass of mine. It is a largely common js class using most of the stubs with the exception of get, del and set for which I implemented the callbacks.
inline JSClass* getMyClass() {
    static JSClass my_class = {
        "myclass", JSCLASS_HAS_PRIVATE,
        JS_PropertyStub,  delProperty, getProperty, setProperty,
        JS_EnumerateStub,
        JS_ResolveStub,
        JS_ConvertStub,  dummy_finalize,
        JSCLASS_NO_OPTIONAL_MEMBERS
    };
    return &my_class;
}

The problem is that when I try to iterate in a for-in loop over objects of this class I get endless loading.
Currently I leave the vp in/out value intact and just return JS_TRUE in case of __iterator__. Also tried assigning undefined(jsval_void) and jsval_null to it but got the same result.

What is the proper way to handle __iterator__ in these callbacks? What I want to achieve is to use the default iteration logic.

Thanks,
Bobby
_______________________________________________
dev-tech-js-engine mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-js-engine
Reply | Threaded
Open this post in threaded view
|

Re: proper handling of __iterator__ in getPropertyOp

Till Schneidereit-2
Hi Bobby,

which version of SpiderMonkey are you working with? I'm not sure I'll be
able to help, but before anyone with more knowledge of this are of the
engine will be able to do so, this information is required.


thanks,
till


On Mon, Jan 27, 2014 at 1:47 PM, Borislav Kapukaranov <
[hidden email]> wrote:

> Hi,
>
> I'm having trouble handling __iterator__ in a custom getPropertyOp for a
> JSClass of mine. It is a largely common js class using most of the stubs
> with the exception of get, del and set for which I implemented the
> callbacks.
> inline JSClass* getMyClass() {
>     static JSClass my_class = {
>         "myclass", JSCLASS_HAS_PRIVATE,
>         JS_PropertyStub,  delProperty, getProperty, setProperty,
>         JS_EnumerateStub,
>         JS_ResolveStub,
>         JS_ConvertStub,  dummy_finalize,
>         JSCLASS_NO_OPTIONAL_MEMBERS
>     };
>     return &my_class;
> }
>
> The problem is that when I try to iterate in a for-in loop over objects of
> this class I get endless loading.
> Currently I leave the vp in/out value intact and just return JS_TRUE in
> case of __iterator__. Also tried assigning undefined(jsval_void) and
> jsval_null to it but got the same result.
>
> What is the proper way to handle __iterator__ in these callbacks? What I
> want to achieve is to use the default iteration logic.
>
> Thanks,
> Bobby
> _______________________________________________
> dev-tech-js-engine mailing list
> [hidden email]
> https://lists.mozilla.org/listinfo/dev-tech-js-engine
>
_______________________________________________
dev-tech-js-engine mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-js-engine
Reply | Threaded
Open this post in threaded view
|

Re: proper handling of __iterator__ in getPropertyOp

Borislav Kapukaranov
In reply to this post by Borislav Kapukaranov
Hi Till,

I'm using the previous spider monkey 17 (not the latest 24).

Cheers,
Bobby
_______________________________________________
dev-tech-js-engine mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-js-engine
Reply | Threaded
Open this post in threaded view
|

Re: proper handling of __iterator__ in getPropertyOp

Jason Orendorff-2
In reply to this post by Borislav Kapukaranov
On 1/27/14 4:47 AM, Borislav Kapukaranov wrote:
> The problem is that when I try to iterate in a for-in loop over objects of this class I get endless loading.
> Currently I leave the vp in/out value intact and just return JS_TRUE in case of __iterator__. Also tried assigning undefined(jsval_void) and jsval_null to it but got the same result.

That's what I would have recommended, so I'm surprised it doesn't work.

I would expect the getProperty hook to be called just once, and if it
returns undefined (JSVAL_VOID) then you should get normal property
enumeration behavior.

What do you mean by "endless loading"? Is the getProperty hook called
multiple times? Does the next JS statement ever execute? Can you stop
the program in a debugger (like GDB) and get a stack trace?

-j
_______________________________________________
dev-tech-js-engine mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-js-engine
Reply | Threaded
Open this post in threaded view
|

Re: proper handling of __iterator__ in getPropertyOp

Borislav Kapukaranov
In reply to this post by Borislav Kapukaranov
> What do you mean by "endless loading"? Is the getProperty hook called
>
> multiple times? Does the next JS statement ever execute? Can you stop
>
> the program in a debugger (like GDB) and get a stack trace?


Found out what was the issue. In addition to leaving the current __iterator__ value unchanged in the get hook I also had the JS_NEW_ENUMERATION property on along with an empty enumerate method(empty = just returning JS_TRUE). After removing the NEW_ENUM property and putting the enumerate stub back it worked.
I thought the stub just returns a JS_TRUE, but apparently I misjudged.

As for endless loading I meant that it kept looping inside jsiter.cpp::js::GetIterator(...) trying to get a snapshot.
_______________________________________________
dev-tech-js-engine mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-js-engine
Reply | Threaded
Open this post in threaded view
|

Re: proper handling of __iterator__ in getPropertyOp

Blake Kaplan
Borislav Kapukaranov <[hidden email]> wrote:
> Found out what was the issue. In addition to leaving the current
> __iterator__ value unchanged in the get hook I also had the
> JS_NEW_ENUMERATION property on along with an empty enumerate method(empty =
> just returning JS_TRUE). After removing the NEW_ENUM property and putting
> the enumerate stub back it worked.
> I thought the stub just returns a JS_TRUE, but apparently I misjudged.

JS_NEW_ENUMERATE allows you to entirely replace the enumerate behavior for an
object. This is in stark contrast to the "old" enumerate hook, which was
simply a chance (before enumeration started) to make sure that all lazy
properties were defined on the object and therefore not missed in for-in
loops. So the old-style enumeration stub can simply return JS_TRUE, but the
new-style one needs to do a bunch more work.
--
Blake Kaplan
_______________________________________________
dev-tech-js-engine mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-js-engine
Reply | Threaded
Open this post in threaded view
|

Re: proper handling of __iterator__ in getPropertyOp

Borislav Kapukaranov
> JS_NEW_ENUMERATE allows you to entirely replace the enumerate behavior for an
>
> object. This is in stark contrast to the "old" enumerate hook, which was
>
> simply a chance (before enumeration started) to make sure that all lazy
>
> properties were defined on the object and therefore not missed in for-in
>
> loops. So the old-style enumeration stub can simply return JS_TRUE, but the
>
> new-style one needs to do a bunch more work.
>
> --
>
> Blake Kaplan

Got it, thanks for the thorough reply! :)
_______________________________________________
dev-tech-js-engine mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-js-engine