Adding a method to the date object

View: New views
9 Messages — Rating Filter:   Alert me  

Adding a method to the date object

by Nicolas Zea :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I'm currently attempting to add an extra method to the built in date
object that allows me to acess the time stamp counter on my machine.

As such, I've created a new method, which is initialized using JS_FN.
Unfortunately, it appears that writing to the vp argument in the
method with the value I wish to return causes a seg fault further down
the line.

This is the method I'm using:

static JSBool
date_getRDTSC(JSContext *cx, uintN argc, jsval *vp)
{
  unsigned a, d;
  asm("cpuid");
  asm volatile("rdtsc" : "=a" (a), "=d" (d));

  *vp = INT_TO_JSVAL(((ticks)a) | (((ticks)d) << 32));
  return JS_TRUE;
}

The seg fault doesn't occur immediately, but later on at jsinterp.cpp:
5261. I'm using the RC source code for firefox 3.5.5pre (changeset
26464:be773dd62e6b from Oct 9 2009). I thought perhaps this may be an
issue with the JIT, so disabled it in about:config, but no luck. Am I
setting the return value for the jsfastnative function incorrectly? If
so, what is the appropriate way? The method used appears to be exactly
what js_NewNumberInRootedValue does (which is used by the normal
gettime method).

Thanks,
Nicolas
_______________________________________________
dev-tech-js-engine mailing list
dev-tech-js-engine@...
https://lists.mozilla.org/listinfo/dev-tech-js-engine

Re: Adding a method to the date object

by Jason Orendorff-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On 10/23/2009 06:19 PM, Nicolas wrote:

> I'm currently attempting to add an extra method to the built in date
> object that allows me to acess the time stamp counter on my machine.
>
> As such, I've created a new method, which is initialized using JS_FN.
> Unfortunately, it appears that writing to the vp argument in the
> method with the value I wish to return causes a seg fault further down
> the line.
>
> This is the method I'm using:
>
> static JSBool
> date_getRDTSC(JSContext *cx, uintN argc, jsval *vp)
> {
>    unsigned a, d;
>    asm("cpuid");
>    asm volatile("rdtsc" : "=a" (a), "=d" (d));
>
>    *vp = INT_TO_JSVAL(((ticks)a) | (((ticks)d)<<  32));
>    return JS_TRUE;
> }

This call to INT_TO_JSVAL is not quite right; see
   https://developer.mozilla.org/en/INT_TO_JSVAL

JavaScript has no 64-bit integer type.  To return a floating-point
approximation of the result, write:

   ticks result = ((ticks)a) | (((ticks)d)<<  32);
   return JS_NewNumberValue(cx, (jsdouble) result, vp);

You may wish to truncate your integer to 53 bits of precision; that's
how much a jsdouble can represent exactly.

Try this--but I expect you will still see crashes. Next, try commenting
out the asm statements and always returning 0, and see if it still crashes.

-j
_______________________________________________
dev-tech-js-engine mailing list
dev-tech-js-engine@...
https://lists.mozilla.org/listinfo/dev-tech-js-engine

Re: Adding a method to the date object

by Wes Garland :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Something to note, it is not necessary to modify jsdate.cpp to add methods
to the date object.  You should be able to modify Date from jsapi just like
you can from script -- just add properties.

This means that you can make your changes in your embedding, rather than in
spidermonkey itself, so you can avoid forking.

Wes

--
Wesley W. Garland
Director, Product Development
PageMail, Inc.
+1 613 542 2787 x 102
_______________________________________________
dev-tech-js-engine mailing list
dev-tech-js-engine@...
https://lists.mozilla.org/listinfo/dev-tech-js-engine

Re: Adding a method to the date object

by Nicolas Zea :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Oct 23, 6:47 pm, Jason Orendorff <jorendo...@...> wrote:

> On 10/23/2009 06:19 PM, Nicolas wrote:
>
>
>
>
>
> > I'm currently attempting to add an extra method to the built in date
> > object that allows me to acess the time stamp counter on my machine.
>
> > As such, I've created a new method, which is initialized using JS_FN.
> > Unfortunately, it appears that writing to the vp argument in the
> > method with the value I wish to return causes a seg fault further down
> > the line.
>
> > This is the method I'm using:
>
> > static JSBool
> > date_getRDTSC(JSContext *cx, uintN argc, jsval *vp)
> > {
> >    unsigned a, d;
> >    asm("cpuid");
> >    asm volatile("rdtsc" : "=a" (a), "=d" (d));
>
> >    *vp = INT_TO_JSVAL(((ticks)a) | (((ticks)d)<<  32));
> >    return JS_TRUE;
> > }
>
> This call to INT_TO_JSVAL is not quite right; see
>    https://developer.mozilla.org/en/INT_TO_JSVAL
>
> JavaScript has no 64-bit integer type.  To return a floating-point
> approximation of the result, write:
>
>    ticks result = ((ticks)a) | (((ticks)d)<<  32);
>    return JS_NewNumberValue(cx, (jsdouble) result, vp);
>
> You may wish to truncate your integer to 53 bits of precision; that's
> how much a jsdouble can represent exactly.
>
> Try this--but I expect you will still see crashes. Next, try commenting
> out the asm statements and always returning 0, and see if it still crashes.
>
> -j

Thanks for the quick responses. I switched it to be simply:

  d = 12345;
  *vp = INT_TO_JSVAL(d);
  return JS_TRUE;

and it worked fine. Then, when I brought back in the asm statements, I
once again started getting the seg faults. Which is weird, since I had
previously tried leaving in the asm statements, but not writing to
*vp, and it worked fine. In other words, the following causes a seg
fault:

  unsigned a, d;
  asm("cpuid");
  asm volatile("rdtsc" : "=a" (a), "=d" (d));

  d = 12345;
  *vp = INT_TO_JSVAL(d);
  return JS_TRUE;

while this does not

  unsigned a, d;
  asm("cpuid");
  asm volatile("rdtsc" : "=a" (a), "=d" (d));

  d = 12345;
  //*vp = INT_TO_JSVAL(d);
  //return JS_TRUE;
  return JS_FALSE;

Although if I change that to return JS_FALSE, there is still a seg
fault. In addition, I've used that exact same asm code in a non
jsfastnative function, without issue. Any idea what might be going on?
It looks to be something to do with the asm code, even when the result
isn't used, and returning JS_TRUE. I'm not sure how to figure out the
exact reason for the seg fault, since it's occurring after this code
is executed.

Do you happen to know what happens different with jsfastnatives when
JS_TRUE is returned vs JS_FALSE?

Cheers,
Nicolas
_______________________________________________
dev-tech-js-engine mailing list
dev-tech-js-engine@...
https://lists.mozilla.org/listinfo/dev-tech-js-engine

Re: Adding a method to the date object

by Nicolas Zea :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

>   unsigned a, d;
>   asm("cpuid");
>   asm volatile("rdtsc" : "=a" (a), "=d" (d));
>
>   d = 12345;
>   //*vp = INT_TO_JSVAL(d);
>   //return JS_TRUE;
>   return JS_FALSE;
>
> Although if I change that to return JS_FALSE, there is still a seg
> fault.

Sorry, typo, I meant to say when I switch it to be JS_TRUE, it seg
faults.
_______________________________________________
dev-tech-js-engine mailing list
dev-tech-js-engine@...
https://lists.mozilla.org/listinfo/dev-tech-js-engine

Re: Adding a method to the date object

by Jason Orendorff-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On 10/24/2009 02:32 PM, Nicolas wrote:
> Do you happen to know what happens different with jsfastnatives when
> JS_TRUE is returned vs JS_FALSE?

"On success, the callback must call JS_SET_RVAL (at least once) and
return JS_TRUE. On error or exception, it must return JS_FALSE."

https://developer.mozilla.org/en/JSFastNative

If you return JS_FALSE when no JS exception has been thrown, that raises
an uncatchable error:

https://developer.mozilla.org/En/SpiderMonkey/JSAPI_User_Guide#Uncatchable_errors

It's called uncatchable because JavaScript 'catch' and 'finally' blocks
are not executed. The engine unwinds the JS stack, and the most recent
pending JSAPI call returns an error-indicating value (JS_FALSE or NULL).

-j
_______________________________________________
dev-tech-js-engine mailing list
dev-tech-js-engine@...
https://lists.mozilla.org/listinfo/dev-tech-js-engine

Re: Adding a method to the date object

by Jason Orendorff-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On 10/24/2009 02:32 PM, Nicolas wrote:
> Then, when I brought back in the asm statements, I
> once again started getting the seg faults.

 >    asm("cpuid");

The cpuid instruction stores results in four registers, but your asm
statement doesn't tell the compiler that those registers are being
clobbered.

This can certainly cause the compiler to generate bad code which might
work fine or might crash, depending on the situation.

-j
_______________________________________________
dev-tech-js-engine mailing list
dev-tech-js-engine@...
https://lists.mozilla.org/listinfo/dev-tech-js-engine

Re: Adding a method to the date object

by Sam Mason :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Mon, Oct 26, 2009 at 11:13:05AM -0500, Jason Orendorff wrote:

> On 10/24/2009 02:32 PM, Nicolas wrote:
> >Then, when I brought back in the asm statements, I
> >once again started getting the seg faults.
> >    asm("cpuid");
>
> The cpuid instruction stores results in four registers, but your asm
> statement doesn't tell the compiler that those registers are being
> clobbered.
>
> This can certainly cause the compiler to generate bad code which might
> work fine or might crash, depending on the situation.

Yup, that would be my guess as well.  The following code:

  http://www.ece.cmu.edu/~pueschel/teaching/18-799B-CMU-spring05/material/rdtsc.h

does indeed tell GCC about more registers.  You could tell by having the
compiler generate the assembly output (-S normally does this) and check
to see what it's choosing to assign where.

--
  Sam  http://samason.me.uk/
_______________________________________________
dev-tech-js-engine mailing list
dev-tech-js-engine@...
https://lists.mozilla.org/listinfo/dev-tech-js-engine

Re: Adding a method to the date object

by Nicolas Zea :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Oct 26, 11:13 am, Jason Orendorff <jorendo...@...> wrote:

> On 10/24/2009 02:32 PM, Nicolas wrote:
>
> > Then, when I brought back in the asm statements, I
> > once again started getting the seg faults.
>
>  >    asm("cpuid");
>
> The cpuid instruction stores results in four registers, but your asm
> statement doesn't tell the compiler that those registers are being
> clobbered.
>
> This can certainly cause the compiler to generate bad code which might
> work fine or might crash, depending on the situation.
>
> -j

Ah! Yep, thanks for noticing that, it's working now (although the
overhead of the call is larger than when I had the call embedded in
the DOM). Anyways, thanks for the help!

-Nicolas
_______________________________________________
dev-tech-js-engine mailing list
dev-tech-js-engine@...
https://lists.mozilla.org/listinfo/dev-tech-js-engine