Subj : Re: GetProperty To : Jochen Stier From : Brendan Eich Date : Tue Feb 10 2004 05:41 pm Jochen Stier wrote: >Hi Brendan. > > >First of all, thx for working on the JS engine. I am integrating it into an >App that uses OpenInventor. I am trying to give some scripting access to this API. > > Cool -- I am ex-SGI ('85-'92), glad to hear of an OpenInventor/SpiderMonkey combo. >My question concerns jsdouble and especially DOUBLE_TO_JSVAL. I am trying to >give javascript access to a SbVec3f object, which is straight from the >OpenInventor Api. This vector object has an array of 3 floats (!) for x, y >and z coordinates. I am using something like > >JSPropertySpec ScrSFVec3f::sJSProperties[] = >{ > { "", 0, JSPROP_INDEX }, > { 0 } >}; > > > You want (char *)0, or some other index than 0, instead of "", in the first initializer above. But you don't need to predefine indexed properties at all, generally, unless you want them to be JSPROP_READONLY or whatever. So I'm wondering why you are declaring this JSPropertySpec array at all. >to allow access to this array via the JSGetProperty > Do you mean JS_GetProperty? > method. Unfortunately I >cannot use DOUBLE_TO_JSVAL on a float, or a pointer to a float. So I have to >create temporary double, like the lValue in the following example. > >JSBool ScrSFVec3f::JSGetProperty(JSContext* iContext, JSObject* iObject, >jsval id, jsval *vp) >{ > if (JSVAL_IS_INT (id)) > { > SoSFVec3f* lVector = (SoSFVec3f*) JS_GetPrivate(iContext, >iObject); > > static double lValue; > lValue = lVector->getValue()[JSVAL_TO_INT(id)]; > *vp = DOUBLE_TO_JSVAL(&lValue); > > This is an invalid use of the API. Do not tag any old jsdouble (double, same thing) address as a jsval -- only those allocated by the GC should be so tagged. It may be that the value fits in an int jsval, btw, so you shouldn't be making a double jsval here if you don't need to. You should instead return JS_NewNumberValue(iContext, lValue, vp). > } > > return JS_TRUE; >} > > >Now, my question is if the Javascript engine makes a copy of the double, or >does it come back to the >memory location of lValue whenever it needs to read the value of the double. >This is important for the >following javascript > > It's important for the above example too -- you're returning the address of a stack temporary that goes out of scope as soon as ScrSFVec3f::JSGetProperty returns! Be careful with pointers (addresses) in C ;-). >var l = new SbVec3f; > >l[0] = l[0] + l[1] + l[2]; > > >In my example the static double lValue will be constantly overriden ! This >assignment will not work unless the >JS engine makes copies of the doubles. I guess I will try this out myself to >see what happens.... But maybe you >have something to add... > > The implementation detail leaking out via jsapi.h, whereby certain jsdoubles in memory (namely, those allocated from the GC heap), can be addressed via tagged pointers (jsvals), does not mean that you can so tag any old double's address. Sorry the API was leaky; it seemed ok at the time. The good news is that you can use JS_NewNumberValue and let the engine optimize to int-tagged jsvals where possible. Not sure how much this helps in practice for your app, though. /be .