FreeWRL

 view release on metacpan or  search on metacpan

JS/js/ChangeLog  view on Meta::CPAN

- Fixed standard class bootstrapping bug that left an extra Object instance
  in the middle of the prototype chain for Date, RegExp, etc. (all but Object
  and Function) instances.

- String.prototype.split ECMAv1 conformance restoration (split-by-empty-string
  was stupidly broken last time).

Tag JSREF_RELEASE_19980219 (2/16/98):

- Fixed very recent i++ (for undefined i) crash-bug (also prior, longstanding
  bug where i++ for undefined i resulted in NaN).

- ECMA conformance for [[DefaultValue]] (8.6.2.6), ToBoolean (9.2), and null
  (default) this-parameter handling (10.2.3).

- New bytecodes paving the way for ECMA-conformant for/in loops and unqualified
  name assignment.

- JS1.2 String.prototype.replace did not emulate Perl4's expansion of $` to be
  the global left context (not from last local match).  Essentially the same
  bug bit replace for the empty-string global match case, which "bumps along"

JS/js/ChangeLog  view on Meta::CPAN

  - bitwise logical and shift operators use the correct ECMA type conversions,
    intermediate types, and boundary behavior.
  - Array.prototype.push emulates Perl5 for JS versions other than 1.2; there
    it emulated Perl4, except when no arguments were passed (it would return
    the array object bound to this in that case; fixed to return undefined).
  - All generic Array methods now update a length property, in case no such
    property existed in the object that delegates to Array.prototype, or that
    refers to the particular method.
  - Except for JS1.2, Array.prototype.splice always returns an array, even when
    given no arguments or a zero-length slice.  JS1.2 compatibility continues.
  - NaN Date fixes.
  - JSFunctionSpec's nargs member now species the "best arity" of the function,
    which ECMA specifies as the value of the function's length property.  So to
    allocate local GC roots, use the new extra member of JSFunctionSpec and let
    nargs count only the minimum or optimum number of desired arguments.
  - Relational and equality operator fixes too gnarly and subtle to describe
    here, affecting mainly the hint argument (or lack of it) to valueOf.
  - A new JS_IsConstructing API and underlying support, so ECMA [[Call]] and
    [[Construct]] can be distinguished.
  - A JS_InitClass extension to tolerate NULL for the constructor native C
    function argument -- this causes a class like Math to be created, where

JS/js/ChangeLog  view on Meta::CPAN


  In a future release, the final JS1.3 version will return object and array
  initializer strings from {Object,Array}.prototype.toSource methods, rather
  than toString, for ECMA and backward compatibility.

- More ECMA conformance fixes, apart from Unicode:
  - New ECMA-conformant jsdate.c by Mike McCabe (mccabe@netscape.com).
  - Improved equality and relational operator implementations.
  - Correct division operator result sign.
  - The unary-plus operator.
  - NaN and Infinity top-level properties.
  - Setting a read-only property fails silently, rather than stopping the
    script with an error report.
  - Deleting a permanent property fails with a false return from the delete
    operator.  If the property is not in the object addressed in the delete
    expression, or it is successfully deleted, the expression results in true.

- The beginnings of finer-grained, non-nesting/low-level locking in jslock.h,
  used in jsstr.c for the deflated_string_cache_lock.  For this version, you
  need to provide a PRLock typedef and PR_NewLock, PR_DestroyLock, PR_Lock,
  and PR_Unlock functions that implement a binary semaphore.

JS/js/ChangeLog  view on Meta::CPAN

  release; it precludes too many alternative GC implementations.

- ECMA conformant Date API, including get/setFullYear and the UTC variants
  to all the get/set methods.

- ECMA conformant Number.MIN_VALUE, which is the smallest denorm now, not
  the smallest normal as in all past JS versions.

- ECMA comformant isFinite() function.

- ECMA signed 0 and NaN number to string conversions.

- Watcom (__WATCOMC__) support for PC builds.

Quick update (4/27/97):
- Prototypes are no longer constructed in JS_InitClass.  If you want a class
  prototype to be constructed by the native 'constructor' function passed to
  JS_InitClass, you can save JS_InitClass's return value and do it yourself:

    proto = JS_InitClass(...);
    ok = JS_CallFunctionName(cx, proto, "constructor", argc, argc, &rval);

JS/js/README  view on Meta::CPAN


- prprintf.c, prprintf.h

  Portable, buffer-overrun-resistant sprintf and friends.

  For no good reason save lack of time, the %e, %f, and %g formats cause your
  system's native sprintf, rather than PR_dtoa, to be used.  This bug doesn't
  affect JSRef, because it uses its own PR_dtoa call in jsnum.c to convert
  from double to string, but it's a bug that we'll fix later, and one you
  should be aware of if you intend to use a PR_*printf function with your own
  floating type arguments -- various vendor sprintf's mishandle NaN, +/-Inf,
  and some even print normal floating values inaccurately.

- prtime.c, prtime.h

  Time functions.  These interfaces are named in a way that makes local vs.
  universal time confusion likely.  Caveat emptor, and we're working on it.
  To make matters worse, Java (and therefore JavaScript) uses "local" time
  numbers (offsets from the epoch) in its Date class.

JS/js/jsapi.c  view on Meta::CPAN

#include "jsscript.h"
#include "jsstr.h"

#if defined(JS_PARANOID_REQUEST) && defined(JS_THREADSAFE)
#define CHECK_REQUEST(cx)	PR_ASSERT(cx->requestDepth)
#else
#define CHECK_REQUEST(cx)	((void)0)
#endif

JS_PUBLIC_API(jsval)
JS_GetNaNValue(JSContext *cx)
{
    CHECK_REQUEST(cx);
    return DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
}

JS_PUBLIC_API(jsval)
JS_GetNegativeInfinityValue(JSContext *cx)
{
    CHECK_REQUEST(cx);
    return DOUBLE_TO_JSVAL(cx->runtime->jsNegativeInfinity);
}

JS_PUBLIC_API(jsval)

JS/js/jsapi.h  view on Meta::CPAN

 */
#define JSVAL_VOID              INT_TO_JSVAL(0 - JSVAL_INT_POW2(30))
#define JSVAL_NULL              OBJECT_TO_JSVAL(0)
#define JSVAL_ZERO              INT_TO_JSVAL(0)
#define JSVAL_ONE               INT_TO_JSVAL(1)
#define JSVAL_FALSE             BOOLEAN_TO_JSVAL(JS_FALSE)
#define JSVAL_TRUE              BOOLEAN_TO_JSVAL(JS_TRUE)

/* Don't want to export data, so provide accessors for non-inline jsvals. */
extern JS_PUBLIC_API(jsval)
JS_GetNaNValue(JSContext *cx);

extern JS_PUBLIC_API(jsval)
JS_GetNegativeInfinityValue(JSContext *cx);

extern JS_PUBLIC_API(jsval)
JS_GetPositiveInfinityValue(JSContext *cx);

extern JS_PUBLIC_API(jsval)
JS_GetEmptyStringValue(JSContext *cx);

JS/js/jsbool.c  view on Meta::CPAN

	}
    }
    if (JSVAL_IS_STRING(v)) {
	b = JSVAL_TO_STRING(v)->length ? JS_TRUE : JS_FALSE;
    }
    if (JSVAL_IS_INT(v)) {
	b = JSVAL_TO_INT(v) ? JS_TRUE : JS_FALSE;
    }
    if (JSVAL_IS_DOUBLE(v)) {
	d = *JSVAL_TO_DOUBLE(v);
	b = (!JSDOUBLE_IS_NaN(d) && d != 0) ? JS_TRUE : JS_FALSE;
    }
    if (JSVAL_IS_BOOLEAN(v)) {
	b = JSVAL_TO_BOOLEAN(v);
    }
    *bp = b;
    return JS_TRUE;
}

JS/js/jscntxt.c  view on Meta::CPAN

    if (js_InterpreterHooks && js_InterpreterHooks->destroyContext) {
	/* This is a stub, but in case it removes roots, call it now. */
        js_InterpreterHooks->destroyContext(cx);
    }

    if (rtempty) {
	/* Unpin all pinned atoms before final GC. */
	js_UnpinPinnedAtoms(&rt->atomState);

	/* Unlock GC things held by runtime pointers. */
	js_UnlockGCThing(cx, rt->jsNaN);
	js_UnlockGCThing(cx, rt->jsNegativeInfinity);
	js_UnlockGCThing(cx, rt->jsPositiveInfinity);
	js_UnlockGCThing(cx, rt->emptyString);

	/*
	 * Clear these so they get recreated if the standard classes are
	 * initialized again.
	 */
	rt->jsNaN = NULL;
	rt->jsNegativeInfinity = NULL;
	rt->jsPositiveInfinity = NULL;
	rt->emptyString = NULL;

	/* Clear debugging state to remove GC roots. */
	JS_ClearAllTraps(cx);
	JS_ClearAllWatchPoints(cx);
    }

    /* Remove more GC roots in regExpStatics, then collect garbage. */

JS/js/jscntxt.h  view on Meta::CPAN


    /* Random number generator state, used by jsmath.c. */
    JSBool              rngInitialized;
    int64               rngMultiplier;
    int64               rngAddend;
    int64               rngMask;
    int64               rngSeed;
    jsdouble            rngDscale;

    /* Well-known numbers held for use by this runtime's contexts. */
    jsdouble            *jsNaN;
    jsdouble            *jsNegativeInfinity;
    jsdouble            *jsPositiveInfinity;

    /* Empty string held for use by this runtime's contexts. */
    JSString            *emptyString;

    /* List of active contexts sharing this runtime. */
    PRCList             contextList;

    /* These are used for debugging -- see jsprvtd.h and jsdbgapi.h. */

JS/js/jsdate.c  view on Meta::CPAN

static jsdouble LocalTZA;

static jsdouble
DaylightSavingTA(jsdouble t)
{
    int64 PR_t;
    int64 ms2us;
    int64 offset;
    jsdouble result;

    /* abort if NaN */
    if (JSDOUBLE_IS_NaN(t))
        return t;

    /* put our t in an LL, and map it to usec for prtime */
    LL_D2L(PR_t, t);
    LL_I2L(ms2us, PR_USEC_PER_MSEC);
    LL_MUL(PR_t, PR_t, ms2us);

    offset = PR_DSTOffset(PR_t);

    LL_DIV(offset, offset, ms2us);

JS/js/jsdate.c  view on Meta::CPAN

    result = yearday
             + monthday
             + date - 1;
    return result;
}

#define MakeDate(day, time) (day * msPerDay + time)

#define TIMECLIP(d) ((JSDOUBLE_IS_FINITE(d) \
                      && !((d < 0 ? -d : d) > HalfTimeDomain)) \
                     ? js_DoubleToInteger(d + (+0.)) : *(cx->runtime->jsNaN))

/**
 * end of ECMA 'support' functions
 */

/*
 * Other Support routines and definitions
 */

static JSClass date_class = {

JS/js/jsdate.c  view on Meta::CPAN

date_UTC(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
    jsdouble array[MAXARGS];
    uintN loop;
    jsdouble d;

    for (loop = 0; loop < MAXARGS; loop++) {
        if (loop < argc) {
            if (!js_ValueToNumber(cx, argv[loop], &d))
                return JS_FALSE;
            /* return NaN if any arg is NaN */
            if (!JSDOUBLE_IS_FINITE(d)) {
                return js_NewNumberValue(cx, d, rval);
            }
            array[loop] = floor(d);
        } else {
            array[loop] = 0;
        }
    }

    /* adjust 2-digit years into the 20th century */

JS/js/jsdate.c  view on Meta::CPAN

static JSBool
date_parse(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
    JSString *str;
    jsdouble result;

    str = js_ValueToString(cx, argv[0]);
    if (!str)
        return JS_FALSE;
    if (!date_parseString(str->chars, &result)) {
        *rval = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
        return JS_TRUE;
    }

    result = TIMECLIP(result);
    return js_NewNumberValue(cx, result, rval);
}

/*
 * Check that obj is an object of class Date, and get the date value.
 * Return NULL on failure.

JS/js/jsdate.c  view on Meta::CPAN


    jsdouble time;
    jsdouble result;

    jsdouble *date = date_getProlog(cx, obj, argv);
    if (!date)
        return JS_FALSE;

    result = *date;

    /* just return NaN if the date is already NaN */
    if (!JSDOUBLE_IS_FINITE(result))
        return js_NewNumberValue(cx, result, rval);

    /* Satisfy the ECMA rule that if a function is called with
     * fewer arguments than the specified formal arguments, the
     * remaining arguments are set to undefined.  Seems like all
     * the Date.setWhatever functions in ECMA are only varargs
     * beyond the first argument; this should be set to undefined
     * if it's not given.  This means that "d = new Date();
     * d.setMilliseconds()" returns NaN.  Blech.
     */
    if (argc == 0)
        argc = 1;   /* should be safe, because length of all settors is 1 */
    else if (argc > maxargs)
        argc = maxargs;  /* clamp argc */

    for (i = 0; i < argc; i++) {
        if (!js_ValueToNumber(cx, argv[i], &args[i]))
            return JS_FALSE;
        if (!JSDOUBLE_IS_FINITE(args[i])) {
            *date = *(cx->runtime->jsNaN);
            return js_NewNumberValue(cx, *date, rval);
        }
        args[i] = js_DoubleToInteger(args[i]);
    }

    if (local)
        lorutime = LocalTime(result);
    else
        lorutime = result;

JS/js/jsdate.c  view on Meta::CPAN

    /* see complaint about ECMA in date_MakeTime */
    if (argc == 0)
        argc = 1;   /* should be safe, because length of all settors is 1 */
    else if (argc > maxargs)
        argc = maxargs;   /* clamp argc */

    for (i = 0; i < argc; i++) {
        if (!js_ValueToNumber(cx, argv[i], &args[i]))
            return JS_FALSE;
        if (!JSDOUBLE_IS_FINITE(args[i])) {
            *date = *(cx->runtime->jsNaN);
            return js_NewNumberValue(cx, *date, rval);
        }
        args[i] = js_DoubleToInteger(args[i]);
    }

    /* return NaN if date is NaN and we're not setting the year,
     * If we are, use 0 as the time. */
    if (!(JSDOUBLE_IS_FINITE(result))) {
        if (argc < 3)
            return js_NewNumberValue(cx, result, rval);
        else
            lorutime = +0.;
    } else {
        if (local)
            lorutime = LocalTime(result);
        else

JS/js/jsdate.c  view on Meta::CPAN


    jsdouble *date = date_getProlog(cx, obj, argv);
    if (!date)
        return JS_FALSE;

    result = *date;

    if (!js_ValueToNumber(cx, argv[0], &year))
        return JS_FALSE;
    if (!JSDOUBLE_IS_FINITE(year)) {
        *date = *(cx->runtime->jsNaN);
        return js_NewNumberValue(cx, *date, rval);
    }

    year = js_DoubleToInteger(year);

    if (!JSDOUBLE_IS_FINITE(result)) {
        t = +0.0;
    } else {
        t = LocalTime(result);
    }

JS/js/jsdate.c  view on Meta::CPAN


    day = MakeDay(year, MonthFromTime(t), DateFromTime(t));
    result = MakeDate(day, TimeWithinDay(t));
    result = UTC(result);

    *date = TIMECLIP(result);
    return js_NewNumberValue(cx, *date, rval);
}

/* constants for toString, toUTCString */
static char js_NaN_date_str[] = "Invalid Date";
static const char* days[] =
{
   "Sun","Mon","Tue","Wed","Thu","Fri","Sat"
};
static const char* months[] =
{
   "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};

static JSBool
date_toGMTString(JSContext *cx, JSObject *obj, uintN argc,
                 jsval *argv, jsval *rval)
{
    char buf[100];
    JSString *str;
    jsdouble *date = date_getProlog(cx, obj, argv);
    if (!date)
        return JS_FALSE;

    if (!JSDOUBLE_IS_FINITE(*date)) {
        PR_snprintf(buf, sizeof buf, js_NaN_date_str);
    } else {
        jsdouble temp = *date;

        /* Avoid dependence on PR_FormatTimeUSEnglish, because it
         * requires a PRTime... which only has 16-bit years.  Sub-ECMA.
         */
        PR_snprintf(buf, sizeof buf, "%s, %.2d %s %.4d %.2d:%.2d:%.2d GMT",
                    days[WeekDay(temp)],
                    DateFromTime(temp),
                    months[MonthFromTime(temp)],

JS/js/jsdate.c  view on Meta::CPAN

                    jsval *argv, jsval *rval)
{
    char buf[100];
    JSString *str;
    PRTime split;
    jsdouble *date = date_getProlog(cx, obj, argv);
    if (!date)
        return JS_FALSE;

    if (!JSDOUBLE_IS_FINITE(*date)) {
        PR_snprintf(buf, sizeof buf, js_NaN_date_str);
    } else {
        jsdouble local = LocalTime(*date);
        new_explode(local, &split);

        /* let PRTime format it.  Use '%#c' for windows, because '%c' is
         * backward-compatible and non-y2k with msvc; '%#c' requests that a
         * full year be used in the result string.
         */
        PR_FormatTime(buf, sizeof buf,
#ifdef _WIN32

JS/js/jsdate.c  view on Meta::CPAN

/* helper function */
static JSBool
date_format(JSContext *cx, jsdouble date, jsval *rval)
{
    char buf[100];
    JSString *str;
    char tzbuf[100];
    PRTime split;

    if (!JSDOUBLE_IS_FINITE(date)) {
        PR_snprintf(buf, sizeof buf, js_NaN_date_str);
    } else {
        jsdouble local = LocalTime(date);

        /* offset from GMT in minutes.  The offset includes daylight savings,
           if it applies. */
        jsint minutes = (jsint) floor((LocalTZA + DaylightSavingTA(date))
                                      / msPerMinute);

        /* map 510 minutes to 0830 hours */
        intN offset = (minutes / 60) * 100 + minutes % 60;

JS/js/jsdate.c  view on Meta::CPAN

            /* the argument is a string; parse it. */
            date = date_constructor(cx, obj);
            if (!date)
                return JS_FALSE;

            str = js_ValueToString(cx, argv[0]);
            if (!str)
                return JS_FALSE;

            if (!date_parseString(str->chars, date))
                *date = *(cx->runtime->jsNaN);
            *date = TIMECLIP(*date);
        }
    } else {
        jsdouble array[MAXARGS];
        uintN loop;
        jsdouble d;
        jsdouble day;
        jsdouble time;

        for (loop = 0; loop < MAXARGS; loop++) {
            if (loop < argc) {
                if (!js_ValueToNumber(cx, argv[loop], &d))
                    return JS_FALSE;
                /* if any arg is NaN, make a NaN date object
                   and return */
                if (!JSDOUBLE_IS_FINITE(d)) {
                    date = date_constructor(cx, obj);
                    if (!date)
                        return JS_FALSE;
                    *date = *(cx->runtime->jsNaN);
                    return JS_TRUE;
                }
                array[loop] = js_DoubleToInteger(d);
            } else {
                array[loop] = 0;
            }
        }

        date = date_constructor(cx, obj);
        if (!date)

JS/js/jsdate.c  view on Meta::CPAN

    JSObject *proto;
    jsdouble *proto_date;

    /* set static LocalTZA */
    LocalTZA = -(PR_LocalGMTDifference() * msPerSecond);
    proto = JS_InitClass(cx, obj, NULL, &date_class, Date, MAXARGS,
                         NULL, date_methods, NULL, date_static_methods);
    if (!proto)
        return NULL;

    /* Set the value of the Date.prototype date to NaN */
    proto_date = date_constructor(cx, proto);
    if (!proto_date)
        return NULL;
    *proto_date = *(cx->runtime->jsNaN);

    return proto;
}

JS_FRIEND_API(JSObject *)
js_NewDateObject(JSContext* cx, int year, int mon, int mday,
                 int hour, int min, int sec)
{
    JSObject *obj;
    jsdouble *date;

JS/js/jsdate.c  view on Meta::CPAN

}

extern JS_FRIEND_API(void)
js_DateSetYear(JSContext *cx, JSObject *obj, int year)
{
    jsdouble local;
    jsdouble *date = date_getProlog(cx, obj, NULL);
    if (!date)
        return;
    local = LocalTime(*date);
    /* reset date if it was NaN */
    if (JSDOUBLE_IS_NaN(local))
        local = 0;
    local = date_msecFromDate(year,
                              MonthFromTime(local),
                              DateFromTime(local),
                              HourFromTime(local),
                              MinFromTime(local),
                              SecFromTime(local),
                              msFromTime(local));
    *date = UTC(local);
}

extern JS_FRIEND_API(void)
js_DateSetMonth(JSContext *cx, JSObject *obj, int month)
{
    jsdouble local;
    jsdouble *date = date_getProlog(cx, obj, NULL);
    if (!date)
        return;
    local = LocalTime(*date);
    /* bail if date was NaN */
    if (JSDOUBLE_IS_NaN(local))
        return;
    local = date_msecFromDate(YearFromTime(local),
                              month,
                              DateFromTime(local),
                              HourFromTime(local),
                              MinFromTime(local),
                              SecFromTime(local),
                              msFromTime(local));
    *date = UTC(local);
}

extern JS_FRIEND_API(void)
js_DateSetDate(JSContext *cx, JSObject *obj, int date)
{
    jsdouble local;
    jsdouble *datep = date_getProlog(cx, obj, NULL);
    if (!datep)
        return;
    local = LocalTime(*datep);
    if (JSDOUBLE_IS_NaN(local))
        return;
    local = date_msecFromDate(YearFromTime(local),
                              MonthFromTime(local),
                              date,
                              HourFromTime(local),
                              MinFromTime(local),
                              SecFromTime(local),
                              msFromTime(local));
    *datep = UTC(local);
}

extern JS_FRIEND_API(void)
js_DateSetHours(JSContext *cx, JSObject *obj, int hours)
{
    jsdouble local;
    jsdouble *date = date_getProlog(cx, obj, NULL);
    if (!date)
        return;
    local = LocalTime(*date);
    if (JSDOUBLE_IS_NaN(local))
        return;
    local = date_msecFromDate(YearFromTime(local),
                              MonthFromTime(local),
                              DateFromTime(local),
                              hours,
                              MinFromTime(local),
                              SecFromTime(local),
                              msFromTime(local));
    *date = UTC(local);
}

extern JS_FRIEND_API(void)
js_DateSetMinutes(JSContext *cx, JSObject *obj, int minutes)
{
    jsdouble local;
    jsdouble *date = date_getProlog(cx, obj, NULL);
    if (!date)
        return;
    local = LocalTime(*date);
    if (JSDOUBLE_IS_NaN(local))
        return;
    local = date_msecFromDate(YearFromTime(local),
                              MonthFromTime(local),
                              DateFromTime(local),
                              HourFromTime(local),
                              minutes,
                              SecFromTime(local),
                              msFromTime(local));
    *date = UTC(local);
}

extern JS_FRIEND_API(void)
js_DateSetSeconds(JSContext *cx, JSObject *obj, int seconds)
{
    jsdouble local;
    jsdouble *date = date_getProlog(cx, obj, NULL);
    if (!date)
        return;
    local = LocalTime(*date);
    if (JSDOUBLE_IS_NaN(local))
        return;
    local = date_msecFromDate(YearFromTime(local),
                              MonthFromTime(local),
                              DateFromTime(local),
                              HourFromTime(local),
                              MinFromTime(local),
                              seconds,
                              msFromTime(local));
    *date = UTC(local);
}

JS/js/jsinterp.c  view on Meta::CPAN

	  case JSOP_BITXOR:
	    BITWISE_OP(^);
	    break;

	  case JSOP_BITAND:
	    BITWISE_OP(&);
	    break;

#ifdef XP_PC
#define COMPARE_DOUBLES(LVAL, OP, RVAL, IFNAN)                                \
    ((JSDOUBLE_IS_NaN(LVAL) || JSDOUBLE_IS_NaN(RVAL))                         \
     ? (IFNAN)                                                                \
     : (LVAL) OP (RVAL))
#else
#define COMPARE_DOUBLES(LVAL, OP, RVAL, IFNAN) ((LVAL) OP (RVAL))
#endif

#define RELATIONAL_OP(OP) {                                                   \
    rval = POP();                                                             \
    lval = POP();                                                             \
    /* Optimize for two int-tagged operands (typical loop control). */        \
    if ((lval & rval) & JSVAL_INT) {                                          \
	ltmp = lval ^ JSVAL_VOID;                                             \
	rtmp = rval ^ JSVAL_VOID;                                             \
	if (ltmp && rtmp) {                                                   \
	    cond = JSVAL_TO_INT(lval) OP JSVAL_TO_INT(rval);                  \
	} else {                                                              \
	    d  = ltmp ? JSVAL_TO_INT(lval) : *rt->jsNaN;                      \
	    d2 = rtmp ? JSVAL_TO_INT(rval) : *rt->jsNaN;                      \
	    cond = COMPARE_DOUBLES(d, OP, d2, JS_FALSE);                      \
	}                                                                     \
    } else {                                                                  \
	VALUE_TO_PRIMITIVE(cx, lval, JSTYPE_NUMBER, &lval);                   \
	/* Need lval for strcmp or ToNumber later, so root it via sp[0]. */   \
	sp[0] = lval;                                                         \
	VALUE_TO_PRIMITIVE(cx, rval, JSTYPE_NUMBER, &rval);                   \
	if (JSVAL_IS_STRING(lval) && JSVAL_IS_STRING(rval)) {                 \
	    str  = JSVAL_TO_STRING(lval);                                     \
	    str2 = JSVAL_TO_STRING(rval);                                     \

JS/js/jsinterp.c  view on Meta::CPAN

    if (ltmp == rtmp) {                                                       \
	if (ltmp == JSVAL_STRING) {                                           \
	    str  = JSVAL_TO_STRING(lval);                                     \
	    str2 = JSVAL_TO_STRING(rval);                                     \
	    cond = js_CompareStrings(str, str2) OP 0;                         \
	} else if (ltmp == JSVAL_DOUBLE) {                                    \
	    d  = *JSVAL_TO_DOUBLE(lval);                                      \
	    d2 = *JSVAL_TO_DOUBLE(rval);                                      \
	    cond = COMPARE_DOUBLES(d, OP, d2, IFNAN);                         \
	} else {                                                              \
	    /* Handle all undefined (=>NaN) and int combinations. */          \
	    cond = lval OP rval;                                              \
	}                                                                     \
    } else {                                                                  \
	if (JSVAL_IS_NULL(lval) || JSVAL_IS_VOID(lval)) {                     \
	    cond = (JSVAL_IS_NULL(rval) || JSVAL_IS_VOID(rval)) OP 1;         \
	} else if (JSVAL_IS_NULL(rval) || JSVAL_IS_VOID(rval)) {              \
	    cond = 1 OP 0;                                                    \
	} else {                                                              \
	    if (ltmp == JSVAL_OBJECT) {                                       \
		VALUE_TO_PRIMITIVE(cx, lval, JSTYPE_VOID, &lval);             \

JS/js/jsinterp.c  view on Meta::CPAN


	  case JSOP_MUL:
	    BINARY_OP(*);
	    break;

	  case JSOP_DIV:
	    POP_NUMBER(cx, d2);
	    POP_NUMBER(cx, d);
	    if (d2 == 0) {
#ifdef XP_PC
		/* XXX MSVC miscompiles such that (NaN == 0) */
		if (JSDOUBLE_IS_NaN(d2))
		    rval = DOUBLE_TO_JSVAL(rt->jsNaN);
		else
#endif
		if (d == 0 || JSDOUBLE_IS_NaN(d))
		    rval = DOUBLE_TO_JSVAL(rt->jsNaN);
		else if ((JSDOUBLE_HI32(d) ^ JSDOUBLE_HI32(d2)) >> 31)
		    rval = DOUBLE_TO_JSVAL(rt->jsNegativeInfinity);
		else
		    rval = DOUBLE_TO_JSVAL(rt->jsPositiveInfinity);
		PUSH_OPND(rval);
	    } else {
		d /= d2;
		PUSH_NUMBER(cx, d);
	    }
	    break;

	  case JSOP_MOD:
	    POP_NUMBER(cx, d2);
	    POP_NUMBER(cx, d);
	    if (d2 == 0) {
		PUSH_OPND(DOUBLE_TO_JSVAL(rt->jsNaN));
	    } else {
#ifdef XP_PC
	      /* Workaround MS fmod bug where 42 % (1/0) => NaN, not 42. */
	      if (!(JSDOUBLE_IS_FINITE(d) && JSDOUBLE_IS_INFINITE(d2)))
#endif
		d = fmod(d, d2);
		PUSH_NUMBER(cx, d);
	    }
	    break;

	  case JSOP_NOT:
	    POP_BOOLEAN(cx, rval, cond);
	    PUSH_OPND(BOOLEAN_TO_JSVAL(!cond));

JS/js/jsnum.c  view on Meta::CPAN

#ifdef IS_LITTLE_ENDIAN
	uint32 lo, hi;
#else
	uint32 hi, lo;
#endif
    } s;
    jsdouble d;
};

static JSBool
num_isNaN(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
    jsdouble x;

    if (!js_ValueToNumber(cx, argv[0], &x))
	return JS_FALSE;
    *rval = BOOLEAN_TO_JSVAL(JSDOUBLE_IS_NaN(x));
    return JS_TRUE;
}

static JSBool
num_isFinite(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
    jsdouble x;

    if (!js_ValueToNumber(cx, argv[0], &x))
	return JS_FALSE;

JS/js/jsnum.c  view on Meta::CPAN

	       jsval *rval)
{
    JSString *str;
    jsdouble d, *dp;
    jschar *ep;

    str = js_ValueToString(cx, argv[0]);
    if (!str)
	return JS_FALSE;
    if (!js_strtod(str->chars, &ep, &d) || ep == str->chars) {
	*rval = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
    } else {
	dp = js_NewDouble(cx, d);
	if (!dp)
	    return JS_FALSE;
	*rval = DOUBLE_TO_JSVAL(dp);
    }
    return JS_TRUE;
}

static JSBool

JS/js/jsnum.c  view on Meta::CPAN

    str = js_ValueToString(cx, argv[0]);
    if (!str)
	return JS_FALSE;
    if (argc > 1) {
	if (!js_ValueToECMAInt32(cx, argv[1], &base))
	    return JS_FALSE;
    } else {
	base = 0;
    }
    if (!js_strtol(str->chars, &ep, base, &d)) {
	*rval = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
    } else {
	if (!js_NewNumberValue(cx, d, rval))
	    return JS_FALSE;
    }
    return JS_TRUE;
}

static JSFunctionSpec number_functions[] = {
    {"isNaN",           num_isNaN,              1},
    {"isFinite",        num_isFinite,           1},
    {"parseFloat",      num_parseFloat,         1},
    {"parseInt",        num_parseInt,           2},
    {0}
};

static JSClass number_class = {
    "Number",
    JSCLASS_HAS_PRIVATE,
    JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,

JS/js/jsnum.c  view on Meta::CPAN

#if JS_HAS_TOSOURCE
    {js_toSource_str,   num_toSource,   0},
#endif
    {js_toString_str,	num_toString,	0},
    {js_valueOf_str,	num_valueOf,	0},
    {0}
};

/* NB: Keep this in synch with number_constants[]. */
enum nc_slot {
    NC_NaN,
    NC_POSITIVE_INFINITY,
    NC_NEGATIVE_INFINITY,
    NC_MAX_VALUE,
    NC_MIN_VALUE,
    NC_LIMIT
};

/*
 * Some to most C compilers forbid spelling these at compile time, or barf
 * if you try, so all but MAX_VALUE are set at runtime by js_InitNumberClass
 * using union dpun.
 */
static JSConstDoubleSpec number_constants[] = {
    {0,                         "NaN"},
    {0,                         "POSITIVE_INFINITY"},
    {0,                         "NEGATIVE_INFINITY"},
    {1.7976931348623157E+308,   "MAX_VALUE"},
    {0,                         "MIN_VALUE"},
    {0}
};

static jsdouble NaN;

JSObject *
js_InitNumberClass(JSContext *cx, JSObject *obj)
{
    JSRuntime *rt;
    union dpun u;
    JSObject *proto, *ctor;

    rt = cx->runtime;
    if (!rt->jsNaN) {
#ifdef XP_PC
#ifdef XP_OS2
	/*DSR071597 - I have no idea what this really does other than mucking with the floating     */
	/*point unit, but it does fix a "floating point underflow" exception I am getting, and there*/
	/*is similar code in the Hursley java. Making sure we have the same code in Javascript      */
	/*where Netscape was calling control87 on Windows...                                        */
	_control87(MCW_EM+PC_53+RC_NEAR,MCW_EM+MCW_PC+MCW_RC);
#else
	_control87(MCW_EM, MCW_EM);
#endif
#endif

	u.s.hi = JSDOUBLE_HI32_EXPMASK | JSDOUBLE_HI32_MANTMASK;
	u.s.lo = 0xffffffff;
	number_constants[NC_NaN].dval = NaN = u.d;
	rt->jsNaN = js_NewDouble(cx, NaN);
	if (!rt->jsNaN || !js_LockGCThing(cx, rt->jsNaN))
	    return NULL;

	u.s.hi = JSDOUBLE_HI32_EXPMASK;
	u.s.lo = 0x00000000;
	number_constants[NC_POSITIVE_INFINITY].dval = u.d;
	rt->jsPositiveInfinity = js_NewDouble(cx, u.d);
	if (!rt->jsPositiveInfinity ||
	    !js_LockGCThing(cx, rt->jsPositiveInfinity)) {
	    return NULL;
	}

JS/js/jsnum.c  view on Meta::CPAN


    proto = JS_InitClass(cx, obj, NULL, &number_class, Number, 1,
			 NULL, number_methods, NULL, NULL);
    if (!proto || !(ctor = JS_GetConstructor(cx, proto)))
	return NULL;
    OBJ_SET_SLOT(cx, proto, JSSLOT_PRIVATE, JSVAL_ZERO);
    if (!JS_DefineConstDoubles(cx, ctor, number_constants))
	return NULL;

    /* ECMA 15.1.1.1 */
    if (!JS_DefineProperty(cx, obj, "NaN", DOUBLE_TO_JSVAL(rt->jsNaN),
			   NULL, NULL, 0)) {
	return NULL;
    }

    /* ECMA 15.1.1.2 */
    if (!JS_DefineProperty(cx, obj, "Infinity",
			   DOUBLE_TO_JSVAL(rt->jsPositiveInfinity),
			   NULL, NULL, 0)) {
	return NULL;
    }

JS/js/jsnum.c  view on Meta::CPAN

    dp = js_AllocGCThing(cx, GCX_DOUBLE);
    if (!dp)
	return NULL;
    *dp = d;
    return dp;
}

void
js_FinalizeDouble(JSContext *cx, jsdouble *dp)
{
    *dp = NaN;
}

JSBool
js_NewDoubleValue(JSContext *cx, jsdouble d, jsval *rval)
{
    jsdouble *dp;

    dp = js_NewDouble(cx, d);
    if (!dp)
	return JS_FALSE;

JS/js/jsnum.c  view on Meta::CPAN

#if JS_BUG_FALLIBLE_TONUM
	str = js_DecompileValueGenerator(cx, v, NULL);
badstr:
	if (str) {
	    JS_ReportError(cx, "%s is not a number",
			   JS_GetStringBytes(str));
	}
	return JS_FALSE;
#else
badstr:
	*dp = *cx->runtime->jsNaN;
#endif
    }
    return JS_TRUE;
}

JSBool
js_ValueToECMAInt32(JSContext *cx, jsval v, int32 *ip)
{
    jsdouble d;

JS/js/jsnum.c  view on Meta::CPAN

}

JSBool
js_ValueToInt32(JSContext *cx, jsval v, int32 *ip)
{
    jsdouble d;
    JSString *str;

    if (!js_ValueToNumber(cx, v, &d))
	return JS_FALSE;
    if (JSDOUBLE_IS_NaN(d) || d <= -2147483649.0 || 2147483648.0 <= d) {
	str = js_DecompileValueGenerator(cx, v, NULL);
	if (str) {
	    JS_ReportError(cx, "can't convert %s to an integer",
			   JS_GetStringBytes(str));
	}
	return JS_FALSE;
    }
    *ip = (int32)floor(d + 0.5);     /* Round to nearest */
    return JS_TRUE;
}

JS/js/jsnum.c  view on Meta::CPAN

}

jsdouble
js_DoubleToInteger(jsdouble d)
{
    JSBool neg;

    if (d == 0)
	return d;
    if (!JSDOUBLE_IS_FINITE(d)) {
	if (JSDOUBLE_IS_NaN(d))
	    return 0;
	return d;
    }
    neg = (d < 0);
    d = floor(neg ? -d : d);
    return neg ? -d : d;
}

/* XXXbe rewrite me! */
JSBool

JS/js/jsnum.h  view on Meta::CPAN

#define JSDOUBLE_HI32(x)        (((uint32 *)&(x))[1])
#define JSDOUBLE_LO32(x)        (((uint32 *)&(x))[0])
#else
#define JSDOUBLE_HI32(x)        (((uint32 *)&(x))[0])
#define JSDOUBLE_LO32(x)        (((uint32 *)&(x))[1])
#endif
#define JSDOUBLE_HI32_SIGNBIT   0x80000000
#define JSDOUBLE_HI32_EXPMASK   0x7ff00000
#define JSDOUBLE_HI32_MANTMASK  0x000fffff

#define JSDOUBLE_IS_NaN(x)                                                    \
    ((JSDOUBLE_HI32(x) & JSDOUBLE_HI32_EXPMASK) == JSDOUBLE_HI32_EXPMASK &&   \
     (JSDOUBLE_LO32(x) || (JSDOUBLE_HI32(x) & JSDOUBLE_HI32_MANTMASK)))

#define JSDOUBLE_IS_INFINITE(x)                                               \
    ((JSDOUBLE_HI32(x) & ~JSDOUBLE_HI32_SIGNBIT) == JSDOUBLE_HI32_EXPMASK &&   \
     !JSDOUBLE_LO32(x))

#define JSDOUBLE_IS_FINITE(x)                                                 \
    ((JSDOUBLE_HI32(x) & JSDOUBLE_HI32_EXPMASK) != JSDOUBLE_HI32_EXPMASK)

#define JSDOUBLE_IS_NEGZERO(d)  (JSDOUBLE_HI32(d) == JSDOUBLE_HI32_SIGNBIT && \
				 JSDOUBLE_LO32(d) == 0)

#define JSDOUBLE_IS_INT_2(d, i)	(!JSDOUBLE_IS_NEGZERO(d) && (jsdouble)i == d)

#ifdef XP_PC
/* XXX MSVC miscompiles NaN floating point comparisons for ==, !=, <, and <= */
#define JSDOUBLE_IS_INT(d, i)	(!JSDOUBLE_IS_NaN(d) && JSDOUBLE_IS_INT_2(d, i))
#else
#define JSDOUBLE_IS_INT(d, i)	JSDOUBLE_IS_INT_2(d, i)
#endif

/* Initialize the Number class, returning its prototype object. */
extern JSObject *
js_InitNumberClass(JSContext *cx, JSObject *obj);

/* GC-allocate a new JS number. */
extern jsdouble *

JS/js/jsnum.h  view on Meta::CPAN


/*
 * Convert a value to a number, then to a uint16 according to the ECMA rules
 * for ToUint16.
 */
extern JSBool
js_ValueToUint16(JSContext *cx, jsval v, uint16 *ip);

/*
 * Convert a jsdouble to an integral number, stored in a jsdouble.
 * If d is NaN, return 0.  If d is an infinity, return it without conversion.
 */
extern jsdouble
js_DoubleToInteger(jsdouble d);

extern JSBool
js_strtod(const jschar *s, jschar **ep, jsdouble *dp);

extern JSBool
js_strtol(const jschar *s, jschar **ep, jsint radix, jsdouble *dp);

JS/js/jsparse.c  view on Meta::CPAN

		d -= d2;
		break;

	      case JSOP_MUL:
		d *= d2;
		break;

	      case JSOP_DIV:
		if (d2 == 0) {
#ifdef XP_PC
		    /* XXX MSVC miscompiles such that (NaN == 0) */
		    if (JSDOUBLE_IS_NaN(d2))
			d = *cx->runtime->jsNaN;
		    else
#endif
		    if (d == 0 || JSDOUBLE_IS_NaN(d))
			d = *cx->runtime->jsNaN;
		    else if ((JSDOUBLE_HI32(d) ^ JSDOUBLE_HI32(d2)) >> 31)
			d = *cx->runtime->jsNegativeInfinity;
		    else
			d = *cx->runtime->jsPositiveInfinity;
		} else {
		    d /= d2;
		}
		break;

	      case JSOP_MOD:
		if (d2 == 0) {
		    d = *cx->runtime->jsNaN;
		} else {
#ifdef XP_PC
		  /* Workaround MS fmod bug where 42 % (1/0) => NaN, not 42. */
		  if (!(JSDOUBLE_IS_FINITE(d) && JSDOUBLE_IS_INFINITE(d2)))
#endif
		    d = fmod(d, d2);
		}
		break;

	      default:;
	    }
	    pn->pn_type = TOK_NUMBER;
	    pn->pn_op = JSOP_NUMBER;

JS/js/jsstr.c  view on Meta::CPAN


    str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
    if (!str)
	return JS_FALSE;
    argv[-1] = STRING_TO_JSVAL(str);

    if (!js_ValueToNumber(cx, argv[0], &d))
	return JS_FALSE;
    d = js_DoubleToInteger(d);
    if (d < 0 || str->length <= d) {
        *rval = JS_GetNaNValue(cx);
    } else {
        index = (size_t)d;
        *rval = INT_TO_JSVAL((jsint)str->chars[index]);
    }
    return JS_TRUE;
}

jsint
js_BoyerMooreHorspool(const jschar *text, jsint textlen,
		      const jschar *pat, jsint patlen,

JS/js/jsstr.c  view on Meta::CPAN

    str2 = js_ValueToString(cx, argv[0]);
    if (!str2)
	return JS_FALSE;
    argv[0] = STRING_TO_JSVAL(str2);
    pat = str2->chars;
    patlen = (jsint)str2->length;

    if (argc > 1) {
	if (!js_ValueToNumber(cx, argv[1], &d))
	    return JS_FALSE;
        if (JSDOUBLE_IS_NaN(d)) {
            i = textlen;
        } else {
            d = js_DoubleToInteger(d);
            if (d < 0)
                i = 0;
            else if (d > textlen - patlen)
                i = textlen - patlen;
            else
                i = (jsint)d;
        }

JS/js/prdtoa.c  view on Meta::CPAN

 *	   calculation.
 */

static PRBool
PR_dtoa(double d, int mode, int ndigits,
	int *decpt, int *sign, char **rve, char *buf, size_t bufsize)
{
	/*	Arguments ndigits, decpt, sign are similar to those
		of ecvt and fcvt; trailing zeros are suppressed from
		the returned string.  If not null, *rve is set to point
		to the end of the return value.  If d is +-Infinity or NaN,
		then *decpt is set to 9999.

		mode:
		0 ==> shortest string that yields d when read in
		and rounded to nearest.
		1 ==> like 0, but with Steele & White stopping rule;
		e.g. with IEEE P754 arithmetic , mode 0 gives
		1e23 whereas mode 1 gives 9.999999999999999e22.
		2 ==> max(1,ndigits) significant digits.  This gives a
		return value similar to that of ecvt, except

JS/js/prdtoa.c  view on Meta::CPAN

	Bigint *result = 0;
	static int32 result_k;
	PRBool retval;
        size_t strsize;

#ifdef JS_THREADSAFE
	if (!initialized) InitDtoa();
#endif

	if (word0(d) & Sign_bit) {
		/* set sign for everything, including 0's and NaNs */
		*sign = 1;
		word0(d) &= ~Sign_bit;	/* clear sign bit */
	}
	else
		*sign = 0;

#if defined(IEEE_Arith) + defined(VAX)
#ifdef IEEE_Arith
	if ((word0(d) & Exp_mask) == Exp_mask)
#else
		if (word0(d)  == 0x8000)
#endif
			{
				/* Infinity or NaN */
				*decpt = 9999;
				s =
#ifdef IEEE_Arith
					!word1(d) && !(word0(d) & 0xfffff) ? "Infinity" :
#endif
					"NaN";
				if ((s[0] == 'I' && bufsize < 9) || (s[0] == 'N' && bufsize < 4)) {
					PR_ASSERT(PR_FALSE);
/* 					PR_SetError(PR_BUFFER_OVERFLOW_ERROR, 0); */
					return PR_FALSE;
				}
				strcpy(buf, s);
				if (rve) {
					*rve =
#ifdef IEEE_Arith
						buf[3] ? buf + 8 :

JS/js/prdtoa.c  view on Meta::CPAN

	}
	/* XXX Why use mode 1? */
	if (PR_dtoa(fval,1,prcsn,&decpt,&sign,&endnum,num,bufsz)
			== PR_FALSE) {
		buf[0] = '\0';
		goto done;
	}
	numdigits = endnum - num;
	nump = num;

	/* If negative and not signed zero and not a NaN, print leading "-". */
	if (sign &&
	    !(word0(fval) == Sign_bit && word1(fval) == 0) &&
	    !((word0(fval) & Exp_mask) == Exp_mask &&
	      (word1(fval) || (word0(fval) & 0xfffff)))) {
	    *bufp++ = '-';
	}

	if(decpt == 9999){
		while((*bufp++ = *nump++) != 0) ;
		goto done;



( run in 0.791 second using v1.01-cache-2.11-cpan-fd5d4e115d8 )