зеркало из https://github.com/mozilla/gecko-dev.git
Bug 590834 - Clean up number-to-string code. r=jwalden.
This commit is contained in:
Родитель
bf6194eb25
Коммит
8883e09bc0
|
@ -38,7 +38,7 @@
|
|||
|
||||
#include "CTypes.h"
|
||||
#include "Library.h"
|
||||
#include "jsdtoa.h"
|
||||
#include "jsnum.h"
|
||||
#include <limits>
|
||||
|
||||
#include <math.h>
|
||||
|
@ -2352,9 +2352,8 @@ BuildDataSource(JSContext* cx,
|
|||
case TYPE_##name: { \
|
||||
/* Serialize as a primitive double. */ \
|
||||
double fp = *static_cast<type*>(data); \
|
||||
char buf[DTOSTR_STANDARD_BUFFER_SIZE]; \
|
||||
char* str = js_dtostr(JS_THREAD_DATA(cx)->dtoaState, buf, sizeof(buf), \
|
||||
DTOSTR_STANDARD, 0, fp); \
|
||||
ToCStringBuf cbuf; \
|
||||
char* str = NumberToCString(cx, &cbuf, fp); \
|
||||
if (!str) { \
|
||||
JS_ReportOutOfMemory(cx); \
|
||||
return false; \
|
||||
|
|
|
@ -60,7 +60,6 @@
|
|||
#include "jscntxt.h"
|
||||
#include "jsversion.h"
|
||||
#include "jsdate.h"
|
||||
#include "jsdtoa.h"
|
||||
#include "jsemit.h"
|
||||
#include "jsexn.h"
|
||||
#include "jsfun.h"
|
||||
|
|
|
@ -90,7 +90,6 @@
|
|||
#include "jscntxt.h"
|
||||
#include "jsversion.h"
|
||||
#include "jsdbgapi.h" /* for js_TraceWatchPoints */
|
||||
#include "jsdtoa.h"
|
||||
#include "jsfun.h"
|
||||
#include "jsgc.h"
|
||||
#include "jsinterp.h"
|
||||
|
|
|
@ -1152,9 +1152,12 @@ struct JSThreadData {
|
|||
DtoaState *dtoaState;
|
||||
|
||||
/*
|
||||
* State used to cache some double-to-string conversions. A stupid
|
||||
* optimization aimed directly at v8-splay.js, which stupidly converts
|
||||
* many doubles multiple times in a row.
|
||||
* A single-entry cache for some base-10 double-to-string conversions.
|
||||
* This helps date-format-xparb.js. It also avoids skewing the results
|
||||
* for v8-splay.js when measured by the SunSpider harness, where the splay
|
||||
* tree initialization (which includes many repeated double-to-string
|
||||
* conversions) is erroneously included in the measurement; see bug
|
||||
* 562553.
|
||||
*/
|
||||
struct {
|
||||
jsdouble d;
|
||||
|
|
|
@ -2342,19 +2342,20 @@ date_toDateString(JSContext *cx, uintN argc, Value *vp)
|
|||
|
||||
#if JS_HAS_TOSOURCE
|
||||
#include <string.h>
|
||||
#include "jsdtoa.h"
|
||||
#include "jsnum.h"
|
||||
|
||||
static JSBool
|
||||
date_toSource(JSContext *cx, uintN argc, Value *vp)
|
||||
{
|
||||
jsdouble utctime;
|
||||
char buf[DTOSTR_STANDARD_BUFFER_SIZE], *numStr, *bytes;
|
||||
char *numStr, *bytes;
|
||||
JSString *str;
|
||||
|
||||
if (!GetUTCTime(cx, ComputeThisFromVp(cx, vp), vp, &utctime))
|
||||
return JS_FALSE;
|
||||
|
||||
numStr = js_dtostr(JS_THREAD_DATA(cx)->dtoaState, buf, sizeof buf, DTOSTR_STANDARD, 0, utctime);
|
||||
ToCStringBuf cbuf;
|
||||
numStr = NumberToCString(cx, &cbuf, utctime);
|
||||
if (!numStr) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
return JS_FALSE;
|
||||
|
|
|
@ -103,9 +103,18 @@ typedef enum JSDToStrMode {
|
|||
#define DTOSTR_VARIABLE_BUFFER_SIZE(precision) ((precision)+24 > DTOSTR_STANDARD_BUFFER_SIZE ? (precision)+24 : DTOSTR_STANDARD_BUFFER_SIZE)
|
||||
|
||||
/*
|
||||
* Convert dval according to the given mode and return a pointer to the resulting ASCII string.
|
||||
* The result is held somewhere in buffer, but not necessarily at the beginning. The size of
|
||||
* buffer is given in bufferSize, and must be at least as large as given by the above macros.
|
||||
* DO NOT USE THIS FUNCTION IF YOU CAN AVOID IT. js::NumberToCString() is a
|
||||
* better function to use.
|
||||
*
|
||||
* Convert dval according to the given mode and return a pointer to the
|
||||
* resulting ASCII string. If mode == DTOSTR_STANDARD and precision == 0 it's
|
||||
* equivalent to ToString() as specified by ECMA-262-5 section 9.8.1, but it
|
||||
* doesn't handle integers specially so should be avoided in that case (that's
|
||||
* why js::NumberToCString() is better).
|
||||
*
|
||||
* The result is held somewhere in buffer, but not necessarily at the
|
||||
* beginning. The size of buffer is given in bufferSize, and must be at least
|
||||
* as large as given by the above macros.
|
||||
*
|
||||
* Return NULL if out of memory.
|
||||
*/
|
||||
|
@ -114,15 +123,22 @@ js_dtostr(DtoaState *state, char *buffer, size_t bufferSize, JSDToStrMode mode,
|
|||
double dval);
|
||||
|
||||
/*
|
||||
* Convert d to a string in the given base. The integral part of d will be printed exactly
|
||||
* in that base, regardless of how large it is, because there is no exponential notation for non-base-ten
|
||||
* numbers. The fractional part will be rounded to as few digits as possible while still preserving
|
||||
* the round-trip property (analogous to that of printing decimal numbers). In other words, if one were
|
||||
* to read the resulting string in via a hypothetical base-number-reading routine that rounds to the nearest
|
||||
* IEEE double (and to an even significand if there are two equally near doubles), then the result would
|
||||
* equal d (except for -0.0, which converts to "0", and NaN, which is not equal to itself).
|
||||
* DO NOT USE THIS FUNCTION IF YOU CAN AVOID IT. js::NumberToCString() is a
|
||||
* better function to use.
|
||||
*
|
||||
* Return NULL if out of memory. If the result is not NULL, it must be released via free().
|
||||
* Convert d to a string in the given base. The integral part of d will be
|
||||
* printed exactly in that base, regardless of how large it is, because there
|
||||
* is no exponential notation for non-base-ten numbers. The fractional part
|
||||
* will be rounded to as few digits as possible while still preserving the
|
||||
* round-trip property (analogous to that of printing decimal numbers). In
|
||||
* other words, if one were to read the resulting string in via a hypothetical
|
||||
* base-number-reading routine that rounds to the nearest IEEE double (and to
|
||||
* an even significand if there are two equally near doubles), then the result
|
||||
* would equal d (except for -0.0, which converts to "0", and NaN, which is
|
||||
* not equal to itself).
|
||||
*
|
||||
* Return NULL if out of memory. If the result is not NULL, it must be
|
||||
* released via js_free().
|
||||
*/
|
||||
char *
|
||||
js_dtobasestr(DtoaState *state, int base, double d);
|
||||
|
|
|
@ -50,7 +50,6 @@
|
|||
#include "jsstdint.h"
|
||||
#include "jsbit.h"
|
||||
#include "jscntxt.h"
|
||||
#include "jsdtoa.h"
|
||||
#include "jsgc.h"
|
||||
#include "jslock.h"
|
||||
#include "jsscope.h"
|
||||
|
|
151
js/src/jsnum.cpp
151
js/src/jsnum.cpp
|
@ -559,7 +559,6 @@ Number(JSContext *cx, uintN argc, Value *vp)
|
|||
static JSBool
|
||||
num_toSource(JSContext *cx, uintN argc, Value *vp)
|
||||
{
|
||||
char numBuf[DTOSTR_STANDARD_BUFFER_SIZE], *numStr;
|
||||
char buf[64];
|
||||
JSString *str;
|
||||
|
||||
|
@ -567,8 +566,8 @@ num_toSource(JSContext *cx, uintN argc, Value *vp)
|
|||
if (!js_GetPrimitiveThis(cx, vp, &js_NumberClass, &primp))
|
||||
return JS_FALSE;
|
||||
double d = primp->toNumber();
|
||||
numStr = js_dtostr(JS_THREAD_DATA(cx)->dtoaState, numBuf, sizeof numBuf,
|
||||
DTOSTR_STANDARD, 0, d);
|
||||
ToCStringBuf cbuf;
|
||||
char *numStr = NumberToCString(cx, &cbuf, d);
|
||||
if (!numStr) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
return JS_FALSE;
|
||||
|
@ -582,17 +581,28 @@ num_toSource(JSContext *cx, uintN argc, Value *vp)
|
|||
}
|
||||
#endif
|
||||
|
||||
/* The buf must be big enough for MIN_INT to fit including '-' and '\0'. */
|
||||
ToCStringBuf::ToCStringBuf() :dbuf(NULL)
|
||||
{
|
||||
JS_STATIC_ASSERT(sbufSize >= DTOSTR_STANDARD_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
ToCStringBuf::~ToCStringBuf()
|
||||
{
|
||||
if (dbuf)
|
||||
js_free(dbuf);
|
||||
}
|
||||
|
||||
/* Returns a non-NULL pointer to inside cbuf. */
|
||||
static char *
|
||||
IntToCString(jsint i, jsint base, char *buf, size_t bufSize)
|
||||
IntToCString(ToCStringBuf *cbuf, jsint i, jsint base = 10)
|
||||
{
|
||||
char *cp;
|
||||
jsuint u;
|
||||
|
||||
u = (i < 0) ? -i : i;
|
||||
|
||||
cp = buf + bufSize; /* one past last buffer cell */
|
||||
*--cp = '\0'; /* null terminate the string to be */
|
||||
cp = cbuf->sbuf + cbuf->sbufSize; /* one past last buffer cell */
|
||||
*--cp = '\0'; /* null terminate the string to be */
|
||||
|
||||
/*
|
||||
* Build the string from behind. We use multiply and subtraction
|
||||
|
@ -625,7 +635,7 @@ IntToCString(jsint i, jsint base, char *buf, size_t bufSize)
|
|||
if (i < 0)
|
||||
*--cp = '-';
|
||||
|
||||
JS_ASSERT(cp >= buf);
|
||||
JS_ASSERT(cp >= cbuf->sbuf);
|
||||
return cp;
|
||||
}
|
||||
|
||||
|
@ -645,8 +655,9 @@ num_toString(JSContext *cx, uintN argc, Value *vp)
|
|||
return JS_FALSE;
|
||||
|
||||
if (base < 2 || base > 36) {
|
||||
char numBuf[12];
|
||||
char *numStr = IntToCString(base, 10, numBuf, sizeof numBuf);
|
||||
ToCStringBuf cbuf;
|
||||
char *numStr = IntToCString(&cbuf, base); /* convert the base itself to a string */
|
||||
JS_ASSERT(numStr);
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_RADIX,
|
||||
numStr);
|
||||
return JS_FALSE;
|
||||
|
@ -808,12 +819,10 @@ num_to(JSContext *cx, JSDToStrMode zeroArgMode, JSDToStrMode oneArgMode,
|
|||
return JS_FALSE;
|
||||
precision = js_DoubleToInteger(precision);
|
||||
if (precision < precisionMin || precision > precisionMax) {
|
||||
numStr = js_dtostr(JS_THREAD_DATA(cx)->dtoaState, buf, sizeof buf,
|
||||
DTOSTR_STANDARD, 0, precision);
|
||||
if (!numStr)
|
||||
JS_ReportOutOfMemory(cx);
|
||||
else
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_PRECISION_RANGE, numStr);
|
||||
ToCStringBuf cbuf;
|
||||
numStr = IntToCString(&cbuf, jsint(precision));
|
||||
JS_ASSERT(numStr);
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_PRECISION_RANGE, numStr);
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -845,8 +854,8 @@ num_toFixed(JSContext *cx, uintN argc, Value *vp)
|
|||
static JSBool
|
||||
num_toExponential(JSContext *cx, uintN argc, Value *vp)
|
||||
{
|
||||
return num_to(cx, DTOSTR_STANDARD_EXPONENTIAL, DTOSTR_EXPONENTIAL, 0,
|
||||
MAX_PRECISION, 1, argc, vp);
|
||||
return num_to(cx, DTOSTR_STANDARD_EXPONENTIAL, DTOSTR_EXPONENTIAL, 0, MAX_PRECISION, 1,
|
||||
argc, vp);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
|
@ -1023,33 +1032,32 @@ js_InitNumberClass(JSContext *cx, JSObject *obj)
|
|||
return proto;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a number to C string. The buf must be large enough to accommodate
|
||||
* the result, including '-' and '\0', if base == 10 or d is an integer that
|
||||
* fits in 32 bits. The caller must free the resulting pointer if it does not
|
||||
* point into buf.
|
||||
*/
|
||||
namespace js {
|
||||
|
||||
static char *
|
||||
NumberToCString(JSContext *cx, jsdouble d, jsint base, char *buf, size_t bufSize)
|
||||
FracNumberToCString(JSContext *cx, ToCStringBuf *cbuf, jsdouble d, jsint base = 10)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
{
|
||||
int32 _;
|
||||
JS_ASSERT(!JSDOUBLE_IS_INT32(d, &_));
|
||||
}
|
||||
#endif
|
||||
return (base == 10)
|
||||
? js_dtostr(JS_THREAD_DATA(cx)->dtoaState, cbuf->sbuf, cbuf->sbufSize,
|
||||
DTOSTR_STANDARD, 0, d)
|
||||
: cbuf->dbuf = js_dtobasestr(JS_THREAD_DATA(cx)->dtoaState, base, d);
|
||||
}
|
||||
|
||||
char *
|
||||
NumberToCString(JSContext *cx, ToCStringBuf *cbuf, jsdouble d, jsint base/* = 10*/)
|
||||
{
|
||||
int32_t i;
|
||||
char *numStr;
|
||||
return (JSDOUBLE_IS_INT32(d, &i))
|
||||
? IntToCString(cbuf, i, base)
|
||||
: FracNumberToCString(cx, cbuf, d, base);
|
||||
}
|
||||
|
||||
JS_ASSERT(bufSize >= DTOSTR_STANDARD_BUFFER_SIZE);
|
||||
if (JSDOUBLE_IS_INT32(d, &i)) {
|
||||
numStr = IntToCString(i, base, buf, bufSize);
|
||||
} else {
|
||||
if (base == 10)
|
||||
numStr = js_dtostr(JS_THREAD_DATA(cx)->dtoaState, buf, bufSize,
|
||||
DTOSTR_STANDARD, 0, d);
|
||||
else
|
||||
numStr = js_dtobasestr(JS_THREAD_DATA(cx)->dtoaState, base, d);
|
||||
if (!numStr) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return numStr;
|
||||
}
|
||||
|
||||
JSString * JS_FASTCALL
|
||||
|
@ -1058,22 +1066,17 @@ js_IntToString(JSContext *cx, jsint i)
|
|||
if (jsuint(i) < INT_STRING_LIMIT)
|
||||
return JSString::intString(i);
|
||||
|
||||
char buf[12];
|
||||
return js_NewStringCopyZ(cx, IntToCString(i, 10, buf, sizeof buf));
|
||||
ToCStringBuf cbuf;
|
||||
return js_NewStringCopyZ(cx, IntToCString(&cbuf, i));
|
||||
}
|
||||
|
||||
static JSString * JS_FASTCALL
|
||||
js_NumberToStringWithBase(JSContext *cx, jsdouble d, jsint base)
|
||||
{
|
||||
/*
|
||||
* The longest possible result here that would need to fit in buf is
|
||||
* (-0x80000000).toString(2), which has length 33. (This can produce
|
||||
* longer results, but in those cases buf is not used; see comment at
|
||||
* NumberToCString.)
|
||||
*/
|
||||
char buf[34];
|
||||
ToCStringBuf cbuf;
|
||||
char *numStr;
|
||||
JSString *s;
|
||||
JSThreadData *data;
|
||||
|
||||
/*
|
||||
* Caller is responsible for error reporting. When called from trace,
|
||||
|
@ -1092,19 +1095,35 @@ js_NumberToStringWithBase(JSContext *cx, jsdouble d, jsint base)
|
|||
return JSString::intString(i);
|
||||
return JSString::unitString(jschar('a' + i - 10));
|
||||
}
|
||||
|
||||
data = JS_THREAD_DATA(cx);
|
||||
if (data->dtoaCache.s && data->dtoaCache.base == base && data->dtoaCache.d == d)
|
||||
return data->dtoaCache.s;
|
||||
|
||||
numStr = IntToCString(&cbuf, i, base);
|
||||
JS_ASSERT(!cbuf.dbuf && numStr >= cbuf.sbuf && numStr < cbuf.sbuf + cbuf.sbufSize);
|
||||
} else {
|
||||
data = JS_THREAD_DATA(cx);
|
||||
if (data->dtoaCache.s && data->dtoaCache.base == base && data->dtoaCache.d == d)
|
||||
return data->dtoaCache.s;
|
||||
|
||||
numStr = FracNumberToCString(cx, &cbuf, d, base);
|
||||
if (!numStr) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
return NULL;
|
||||
}
|
||||
JS_ASSERT_IF(base == 10,
|
||||
!cbuf.dbuf && numStr >= cbuf.sbuf && numStr < cbuf.sbuf + cbuf.sbufSize);
|
||||
JS_ASSERT_IF(base != 10,
|
||||
cbuf.dbuf && cbuf.dbuf == numStr);
|
||||
}
|
||||
JSThreadData *data = JS_THREAD_DATA(cx);
|
||||
if (data->dtoaCache.s && data->dtoaCache.base == base && data->dtoaCache.d == d)
|
||||
return data->dtoaCache.s;
|
||||
numStr = NumberToCString(cx, d, base, buf, sizeof buf);
|
||||
if (!numStr)
|
||||
return NULL;
|
||||
|
||||
s = js_NewStringCopyZ(cx, numStr);
|
||||
if (!(numStr >= buf && numStr < buf + sizeof buf))
|
||||
js_free(numStr);
|
||||
|
||||
data->dtoaCache.base = base;
|
||||
data->dtoaCache.d = d;
|
||||
data->dtoaCache.s = s;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -1118,24 +1137,24 @@ JSBool JS_FASTCALL
|
|||
js_NumberValueToCharBuffer(JSContext *cx, const Value &v, JSCharBuffer &cb)
|
||||
{
|
||||
/* Convert to C-string. */
|
||||
static const size_t arrSize = DTOSTR_STANDARD_BUFFER_SIZE;
|
||||
char arr[arrSize];
|
||||
ToCStringBuf cbuf;
|
||||
const char *cstr;
|
||||
if (v.isInt32()) {
|
||||
cstr = IntToCString(v.toInt32(), 10, arr, arrSize);
|
||||
cstr = IntToCString(&cbuf, v.toInt32());
|
||||
} else {
|
||||
cstr = js_dtostr(JS_THREAD_DATA(cx)->dtoaState, arr, arrSize,
|
||||
DTOSTR_STANDARD, 0, v.toDouble());
|
||||
cstr = NumberToCString(cx, &cbuf, v.toDouble());
|
||||
if (!cstr) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
if (!cstr)
|
||||
return JS_FALSE;
|
||||
|
||||
/*
|
||||
* Inflate to jschar string. The input C-string characters are < 127, so
|
||||
* even if jschars are UTF-8, all chars should map to one jschar.
|
||||
*/
|
||||
size_t cstrlen = strlen(cstr);
|
||||
JS_ASSERT(cstrlen < arrSize);
|
||||
JS_ASSERT(!cbuf.dbuf && cstrlen < cbuf.sbufSize);
|
||||
size_t sizeBefore = cb.length();
|
||||
if (!cb.growByUninitialized(cstrlen))
|
||||
return JS_FALSE;
|
||||
|
|
|
@ -189,6 +189,11 @@ extern const char js_parseInt_str[];
|
|||
extern JSString * JS_FASTCALL
|
||||
js_IntToString(JSContext *cx, jsint i);
|
||||
|
||||
/*
|
||||
* When base == 10, this function implements ToString() as specified by
|
||||
* ECMA-262-5 section 9.8.1; but note that it handles integers specially for
|
||||
* performance. See also js::NumberToCString().
|
||||
*/
|
||||
extern JSString * JS_FASTCALL
|
||||
js_NumberToString(JSContext *cx, jsdouble d);
|
||||
|
||||
|
@ -201,6 +206,35 @@ js_NumberValueToCharBuffer(JSContext *cx, const js::Value &v, JSCharBuffer &cb);
|
|||
|
||||
namespace js {
|
||||
|
||||
/*
|
||||
* Usually a small amount of static storage is enough, but sometimes we need
|
||||
* to dynamically allocate much more. This struct encapsulates that.
|
||||
* Dynamically allocated memory will be freed when the object is destroyed.
|
||||
*/
|
||||
struct ToCStringBuf
|
||||
{
|
||||
/*
|
||||
* The longest possible result that would need to fit in sbuf is
|
||||
* (-0x80000000).toString(2), which has length 33. Longer cases are
|
||||
* possible, but they'll go in dbuf.
|
||||
*/
|
||||
static const size_t sbufSize = 34;
|
||||
char sbuf[sbufSize];
|
||||
char *dbuf; /* must be allocated with js_malloc() */
|
||||
|
||||
ToCStringBuf();
|
||||
~ToCStringBuf();
|
||||
};
|
||||
|
||||
/*
|
||||
* Convert a number to a C string. When base==10, this function implements
|
||||
* ToString() as specified by ECMA-262-5 section 9.8.1. It handles integral
|
||||
* values cheaply. Return NULL if we ran out of memory. See also
|
||||
* js_NumberToCString().
|
||||
*/
|
||||
extern char *
|
||||
NumberToCString(JSContext *cx, ToCStringBuf *cbuf, jsdouble d, jsint base = 10);
|
||||
|
||||
/*
|
||||
* The largest positive integer such that all positive integers less than it
|
||||
* may be precisely represented using the IEEE-754 double-precision format.
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
#include "jsatom.h"
|
||||
#include "jsbool.h"
|
||||
#include "jscntxt.h"
|
||||
#include "jsdtoa.h"
|
||||
#include "jsfun.h"
|
||||
#include "jsinterp.h"
|
||||
#include "jsiter.h"
|
||||
|
@ -527,21 +526,11 @@ Str(JSContext *cx, jsid id, JSObject *holder, StringifyContext *scx, Value *vp,
|
|||
return js_AppendLiteral(scx->cb, "null");
|
||||
}
|
||||
|
||||
char numBuf[DTOSTR_STANDARD_BUFFER_SIZE], *numStr;
|
||||
jsdouble d = vp->isInt32() ? jsdouble(vp->toInt32()) : vp->toDouble();
|
||||
numStr = js_dtostr(JS_THREAD_DATA(cx)->dtoaState, numBuf, sizeof numBuf,
|
||||
DTOSTR_STANDARD, 0, d);
|
||||
if (!numStr) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
jschar dstr[DTOSTR_STANDARD_BUFFER_SIZE];
|
||||
size_t dbufSize = DTOSTR_STANDARD_BUFFER_SIZE;
|
||||
if (!js_InflateStringToBuffer(cx, numStr, strlen(numStr), dstr, &dbufSize))
|
||||
JSCharBuffer cb(cx);
|
||||
if (!js_NumberValueToCharBuffer(cx, *vp, cb))
|
||||
return JS_FALSE;
|
||||
|
||||
return scx->cb.append(dstr, dbufSize);
|
||||
return scx->cb.append(cb.begin(), cb.length());
|
||||
}
|
||||
|
||||
if (vp->isObject() && !IsFunctionObject(*vp) && !IsXML(*vp)) {
|
||||
|
|
|
@ -52,7 +52,6 @@
|
|||
#include "jsstdint.h"
|
||||
#include "jsarena.h" /* Added by JSIFY */
|
||||
#include "jsutil.h" /* Added by JSIFY */
|
||||
#include "jsdtoa.h"
|
||||
#include "jsprf.h"
|
||||
#include "jsapi.h"
|
||||
#include "jsarray.h"
|
||||
|
@ -1126,7 +1125,7 @@ SprintDoubleValue(Sprinter *sp, jsval v, JSOp *opp)
|
|||
{
|
||||
jsdouble d;
|
||||
ptrdiff_t todo;
|
||||
char *s, buf[DTOSTR_STANDARD_BUFFER_SIZE];
|
||||
char *s;
|
||||
|
||||
JS_ASSERT(JSVAL_IS_DOUBLE(v));
|
||||
d = JSVAL_TO_DOUBLE(v);
|
||||
|
@ -1143,8 +1142,8 @@ SprintDoubleValue(Sprinter *sp, jsval v, JSOp *opp)
|
|||
: "1 / 0");
|
||||
*opp = JSOP_DIV;
|
||||
} else {
|
||||
s = js_dtostr(JS_THREAD_DATA(sp->context)->dtoaState, buf, sizeof buf,
|
||||
DTOSTR_STANDARD, 0, d);
|
||||
ToCStringBuf cbuf;
|
||||
s = NumberToCString(sp->context, &cbuf, d);
|
||||
if (!s) {
|
||||
JS_ReportOutOfMemory(sp->context);
|
||||
return -1;
|
||||
|
|
|
@ -56,7 +56,6 @@
|
|||
#include "jsarena.h" /* Added by JSIFY */
|
||||
#include "jsbit.h"
|
||||
#include "jsutil.h" /* Added by JSIFY */
|
||||
#include "jsdtoa.h"
|
||||
#include "jsprf.h"
|
||||
#include "jsapi.h"
|
||||
#include "jsatom.h"
|
||||
|
|
Загрузка…
Ссылка в новой задаче