Array property of custom object

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

Array property of custom object

Mihai Dobrescu
Hi,

I have created custom objects with methods and simple properties.
Now, I need to define a property of array type. How could this be done?
Is there an api? I naturally expect to access in javascript o.arr[i]. Should I create a custom object for this too?

Thanks.
_______________________________________________
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: Array property of custom object

Mihai Dobrescu
Nobody? Is it even possible? I couldn't find how.

_______________________________________________
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: Array property of custom object

Nicholas Nethercote
You posted on a weekend. The likelihood of you getting a response will
increase once the work week begins in the more heavily-populated
timezones. Even then there's no guarantee of a response.

On Mon, May 2, 2016 at 4:05 PM, Mihai Dobrescu <[hidden email]> wrote:
> Nobody? Is it even possible? I couldn't find how.
>
> _______________________________________________
> 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: Array property of custom object

Boris Zbarsky
In reply to this post by Mihai Dobrescu
On 4/30/16 1:41 PM, Mihai Dobrescu wrote:
> Now, I need to define a property of array type. How could this be done?

Other than with JS_NewArrayObject and JS_DefineProperty?  Why do those
not do what you want?

-Boris
_______________________________________________
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: Array property of custom object

Mihai Dobrescu
On Monday, May 2, 2016 at 11:14:01 AM UTC+3, Boris Zbarsky wrote:
> On 4/30/16 1:41 PM, Mihai Dobrescu wrote:
> > Now, I need to define a property of array type. How could this be done?
>
> Other than with JS_NewArrayObject and JS_DefineProperty?  Why do those
> not do what you want?
>
> -Boris

Actually, I don't now how to use them.
So far, I have used JS_PSGS to define properties to a custom object having a JSClass structure defined simply, with a class name, a finalizer and JSCLASS_HAS_PRIVATE flag.
_______________________________________________
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: Array property of custom object

Mihai Dobrescu
On Monday, May 2, 2016 at 11:48:36 AM UTC+3, Mihai Dobrescu wrote:

> On Monday, May 2, 2016 at 11:14:01 AM UTC+3, Boris Zbarsky wrote:
> > On 4/30/16 1:41 PM, Mihai Dobrescu wrote:
> > > Now, I need to define a property of array type. How could this be done?
> >
> > Other than with JS_NewArrayObject and JS_DefineProperty?  Why do those
> > not do what you want?
> >
> > -Boris
>
> Actually, I don't now how to use them.
> So far, I have used JS_PSGS to define properties to a custom object having a JSClass structure defined simply, with a class name, a finalizer and JSCLASS_HAS_PRIVATE flag.

Oh, I've forgot to mention that it has private data that owns the array, actually, defined like a char array[10]; That I need to access.
_______________________________________________
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: Array property of custom object

Mihai Dobrescu
In reply to this post by Boris Zbarsky
On Monday, May 2, 2016 at 11:14:01 AM UTC+3, Boris Zbarsky wrote:
> On 4/30/16 1:41 PM, Mihai Dobrescu wrote:
> > Now, I need to define a property of array type. How could this be done?
>
> Other than with JS_NewArrayObject and JS_DefineProperty?  Why do those
> not do what you want?
>
> -Boris

So, to be clear, I would expect to have a callback with the index of the array as parameter too... I guess here starts my confusion?
_______________________________________________
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: Array property of custom object

Boris Zbarsky
On 5/2/16 8:07 AM, Mihai Dobrescu wrote:
> So, to be clear, I would expect to have a callback with the index of the array as parameter too... I guess here starts my confusion?

OK.  Can you please back up and clearly describe what you're trying to do?

If your object is `o` and script does `o.arr`, what sort of thing should
it get?  Should it get an actual JS Array in the Array.isArray() sense?
  Should it get something that allows indexing into it (more details
below) but isn't actually an Array?  Something else?

When script does `var x = o.arr[5]`, what should happen? Should the
value just be read directly out of the storage of `o.arr` (whatever that
is)? Should some code you control run and allow you to provide the value
being returned? Something else?

When script does `o.arr[5] = 7`, what should happen?  Should the value
just be written into the storage of `o.arr` (whatever that is)?  Should
some code you control run and do something with the value being
provided?  Something else?

-Boris
_______________________________________________
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: Array property of custom object

Mihai Dobrescu
On Monday, May 2, 2016 at 8:08:32 PM UTC+3, Boris Zbarsky wrote:

> On 5/2/16 8:07 AM, Mihai Dobrescu wrote:
> > So, to be clear, I would expect to have a callback with the index of the array as parameter too... I guess here starts my confusion?
>
> OK.  Can you please back up and clearly describe what you're trying to do?
>
> If your object is `o` and script does `o.arr`, what sort of thing should
> it get?  Should it get an actual JS Array in the Array.isArray() sense?
>   Should it get something that allows indexing into it (more details
> below) but isn't actually an Array?  Something else?
>
> When script does `var x = o.arr[5]`, what should happen? Should the
> value just be read directly out of the storage of `o.arr` (whatever that
> is)? Should some code you control run and allow you to provide the value
> being returned? Something else?
>
> When script does `o.arr[5] = 7`, what should happen?  Should the value
> just be written into the storage of `o.arr` (whatever that is)?  Should
> some code you control run and do something with the value being
> provided?  Something else?
>
> -Boris

OK, I use objects with private data. For instance a structure instance defined like (this is a simple example) :

typedef struct S {
        int id;
        char info[100];
} Data;

In my case, I access "info" as char array (due to some API specs I wrap).

For "id" I use JS_PSGS macro to define it as a property for an object "jsData". It is used a wrapper of type jsInt with private data int.
The Set/Get methods will always work with the private data.

For "info", I need some Array wrapper for objects of type jsChar (it is not a string). jsChar will have some private data of type char.

So, I expect to access somehow a "jsData"'s property named "info", of type Array, in order to individually set or get each array's element.
I could write functions for that, but it is not natural. It is possible to need to loop through the array's elements too.
_______________________________________________
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: Array property of custom object

Boris Zbarsky
On 5/2/16 2:10 PM, Mihai Dobrescu wrote:
> For "info", I need some Array wrapper for objects of type jsChar (it is not a string). jsChar will have some private data of type char.

Sounds like you want to implement a proxy (in the js::Proxy sense) that
will do whatever it is you want.  It won't be an Array from the point of
view of JS consumers, but then again you don't want actual Array
behavior either (e.g. you don't want people doing push() on your thing),
right?

-Boris
_______________________________________________
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: Array property of custom object

Mihai Dobrescu
On Monday, May 2, 2016 at 10:06:56 PM UTC+3, Boris Zbarsky wrote:

> On 5/2/16 2:10 PM, Mihai Dobrescu wrote:
> > For "info", I need some Array wrapper for objects of type jsChar (it is not a string). jsChar will have some private data of type char.
>
> Sounds like you want to implement a proxy (in the js::Proxy sense) that
> will do whatever it is you want.  It won't be an Array from the point of
> view of JS consumers, but then again you don't want actual Array
> behavior either (e.g. you don't want people doing push() on your thing),
> right?
>
> -Boris

I need to e able to replace array elements, probably I will need to add/remove elements too. Aren't all the JS objects containing private data proxies (the one with the JSCLASS_HAS_PRIVATE flag)?
_______________________________________________
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: Array property of custom object

Boris Zbarsky
On 5/2/16 4:30 PM, Mihai Dobrescu wrote:
> I need to e able to replace array elements, probably I will need to add/remove elements too

OK. I have a hard time reconciling adding elements that with your claim
that your backing storage is a constant-sized array, but I assume you
know what you're doing.

> Aren't all the JS objects containing private data proxies (the one with the JSCLASS_HAS_PRIVATE flag)?

Not at all.

-Boris
_______________________________________________
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: Array property of custom object

Mihai Dobrescu
On Tuesday, May 3, 2016 at 5:01:42 AM UTC+3, Boris Zbarsky wrote:

> On 5/2/16 4:30 PM, Mihai Dobrescu wrote:
> > I need to e able to replace array elements, probably I will need to add/remove elements too
>
> OK. I have a hard time reconciling adding elements that with your claim
> that your backing storage is a constant-sized array, but I assume you
> know what you're doing.
>
> > Aren't all the JS objects containing private data proxies (the one with the JSCLASS_HAS_PRIVATE flag)?
>
> Not at all.
>
> -Boris

...well, I did not say js::proxies.

I could try to post a sample of my approach for a property getter t be passed to the JS_PSGS macro (extremely simplified as it is template based solution):

template<typename jsType, typename jsPropertyType, typename jsPropertyType::PrivateType PrivateType::*Property>
    static bool GetProperty(JSContext *cx, unsigned argc, JS::Value *vp)
    {
        JS::CallArgs args = CallArgsFromVp(argc, vp);

        PrivateType* data = (PrivateType*)(JS_GetPrivate(&args.thisv().toObject()));

        if (!data)
            return false; // whatever...

        JSObject *obj = JS_NewObject(cx, &jsDataClass<jsPropertyType>::fClass);

        JS_SetPrivate(obj, new jsPropertyType::PrivateType(data->*Property));

        args.rval().setObject(*obj);

        return true;
    }

where jsPropertyType is a wrapper for the property's type. jsType is the property owner wrapper object. All of these have a PrivateType typedef for the wrapped C type. It should be pretty clear for a person with SpiderMonkey knowledge.

It is my approach I could find for embedding API's types.

I could ask also, how do you know should be done? For any of these, simple and array properties. If you do it from scratch, what is your approach?

_______________________________________________
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: Array property of custom object

Mihai Dobrescu
On Tuesday, May 3, 2016 at 10:25:53 AM UTC+3, Mihai Dobrescu wrote:

> On Tuesday, May 3, 2016 at 5:01:42 AM UTC+3, Boris Zbarsky wrote:
> > On 5/2/16 4:30 PM, Mihai Dobrescu wrote:
> > > I need to e able to replace array elements, probably I will need to add/remove elements too
> >
> > OK. I have a hard time reconciling adding elements that with your claim
> > that your backing storage is a constant-sized array, but I assume you
> > know what you're doing.
> >
> > > Aren't all the JS objects containing private data proxies (the one with the JSCLASS_HAS_PRIVATE flag)?
> >
> > Not at all.
> >
> > -Boris
>
> ...well, I did not say js::proxies.
>
> I could try to post a sample of my approach for a property getter to be passed to the JS_PSGS macro (extremely simplified as it is template based solution):
>
> template<typename jsType, typename jsPropertyType, typename jsPropertyType::PrivateType PrivateType::*Property>
>     static bool GetProperty(JSContext *cx, unsigned argc, JS::Value *vp)
>     {
>         JS::CallArgs args = CallArgsFromVp(argc, vp);
>
>         PrivateType* data = (PrivateType*)(JS_GetPrivate(&args.thisv().toObject()));
>
>         if (!data)
>             return false; // whatever...
>
>         JSObject *obj = JS_NewObject(cx, &jsDataClass<jsPropertyType>::fClass);
>
>         JS_SetPrivate(obj, new jsPropertyType::PrivateType(data->*Property));
>
>         args.rval().setObject(*obj);
>
>         return true;
>     }
>
> where jsPropertyType is a wrapper for the property's type. jsType is the property owner wrapper object. All of these have a PrivateType typedef for the wrapped C type. It should be pretty clear for a person with SpiderMonkey knowledge.
>
> It is my approach I could find for embedding API's types.
>
> I could ask also, how do you know should be done? For any of these, simple and array properties. If you do it from scratch, what is your approach?

And I have to apologize for forgetting to say what is my issue: considering this approach, I fail to find a way to pass the index of the array element to access for some operation.
_______________________________________________
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: Array property of custom object

Boris Zbarsky
In reply to this post by Mihai Dobrescu
On 5/3/16 3:25 AM, Mihai Dobrescu wrote:
> ....well, I did not say js::proxies.

OK, let's not use "proxy" without clearly stating which of the many
meanings we're using, because that way lies only frustration.

> I could ask also, how do you know should be done? For any of these, simple and array properties. If you do it from scratch, what is your approach?

Let me try to state this more clearly.

If you want |var x = obj.arr| to return an object that will call code
you control when x[5] is read or set, and the precise set of property
names for which you want your code to be called is not known up front,
then obj.arr needs to be a js::Proxy.  The proxy handler's methods are
what will get called when x[5] is read or set.

If you do know the precise set of property names you care about up front
(e.g. you want your code to be called for x[N] where 0 <= N < 100, but
don't want your code called when N is 101), then you can get away with
defining a bunch of accessor properties on obj.arr instead of using a
js::Proxy.  Obviously for large N this could have deleterious memory
effects.

Does that help?

-Boris
_______________________________________________
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: Array property of custom object

Mihai Dobrescu
On Tuesday, May 3, 2016 at 6:12:03 PM UTC+3, Boris Zbarsky wrote:

> On 5/3/16 3:25 AM, Mihai Dobrescu wrote:
> > ....well, I did not say js::proxies.
>
> OK, let's not use "proxy" without clearly stating which of the many
> meanings we're using, because that way lies only frustration.
>
> > I could ask also, how do you know should be done? For any of these, simple and array properties. If you do it from scratch, what is your approach?
>
> Let me try to state this more clearly.
>
> If you want |var x = obj.arr| to return an object that will call code
> you control when x[5] is read or set, and the precise set of property
> names for which you want your code to be called is not known up front,
> then obj.arr needs to be a js::Proxy.  The proxy handler's methods are
> what will get called when x[5] is read or set.
>
> If you do know the precise set of property names you care about up front
> (e.g. you want your code to be called for x[N] where 0 <= N < 100, but
> don't want your code called when N is 101), then you can get away with
> defining a bunch of accessor properties on obj.arr instead of using a
> js::Proxy.  Obviously for large N this could have deleterious memory
> effects.
>
> Does that help?
>
> -Boris

Well, I think I was right, though. I did used all the juice of SpiderMonkey similarly to a js::proxy, as I had used the private data functionality and customized all ops as far as I could... although I did not use the js::proxy itself.

Now, I have the question how could I use js::proxy to attain my goal, being aware of its drawbacks. I'm sure it involves memory fragmentation and cpu load.
Will it make possible to simply iterate too?
_______________________________________________
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: Array property of custom object

Boris Zbarsky
On 5/3/16 11:28 AM, Mihai Dobrescu wrote:
> Now, I have the question how could I use js::proxy to attain my goal, being aware of its drawbacks. I'm sure it involves memory fragmentation and cpu load.

I don't see why it would involve "memory fragmentation".

To use a js::Proxy, you define an appropriate proxy handler to do
whatever you want.  Basically, you directly implement the various
internal methods from the ES spec for your object.

http://mxr.mozilla.org/mozilla-central/source/dom/base/WindowNamedPropertiesHandler.cpp 
has an example of a simple proxy that you might be able to repurpose.

> Will it make possible to simply iterate too?

I don't know what you mean by "iterate" exactly, but obviously a proxy
would allow you to do for-in enumeration (via
getOwnEnumerablePropertyKeys) and you can always do for-of iteration by
providing an iterator implementation for your object.

-Boris
_______________________________________________
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: Array property of custom object

Mihai Dobrescu
On Tuesday, May 3, 2016 at 6:49:08 PM UTC+3, Boris Zbarsky wrote:

> On 5/3/16 11:28 AM, Mihai Dobrescu wrote:
> > Now, I have the question how could I use js::proxy to attain my goal, being aware of its drawbacks. I'm sure it involves memory fragmentation and cpu load.
>
> I don't see why it would involve "memory fragmentation".
>
> To use a js::Proxy, you define an appropriate proxy handler to do
> whatever you want.  Basically, you directly implement the various
> internal methods from the ES spec for your object.
>
> http://mxr.mozilla.org/mozilla-central/source/dom/base/WindowNamedPropertiesHandler.cpp 
> has an example of a simple proxy that you might be able to repurpose.
>
> > Will it make possible to simply iterate too?
>
> I don't know what you mean by "iterate" exactly, but obviously a proxy
> would allow you to do for-in enumeration (via
> getOwnEnumerablePropertyKeys) and you can always do for-of iteration by
> providing an iterator implementation for your object.
>
> -Boris

By iteration I mean to loop through array's elements.
_______________________________________________
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: Array property of custom object

Boris Zbarsky
On 5/3/16 11:52 AM, Mihai Dobrescu wrote:
> By iteration I mean to loop through array's elements.

Yes, but my point is that there are multiple ways of doing this in JS,
which have subtly different behaviors.

-Boris

_______________________________________________
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: Array property of custom object

Mihai Dobrescu
On Tuesday, May 3, 2016 at 7:31:37 PM UTC+3, Boris Zbarsky wrote:
> On 5/3/16 11:52 AM, Mihai Dobrescu wrote:
> > By iteration I mean to loop through array's elements.
>
> Yes, but my point is that there are multiple ways of doing this in JS,
> which have subtly different behaviors.
>
> -Boris

Isn't there a generic trap for that in order to know the current item accessed?
_______________________________________________
dev-tech-js-engine mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-js-engine
12