ReactOS 0.4.17-dev-357-ga8f14ff
number.c File Reference
#include <math.h>
#include <locale.h>
#include <assert.h>
#include "jscript.h"
#include "wine/debug.h"
Include dependency graph for number.c:

Go to the source code of this file.

Classes

struct  NumberInstance
 

Macros

#define NUMBER_TOSTRING_BUF_SIZE   64
 
#define NUMBER_DTOA_SIZE   18
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (jscript)
 
static NumberInstancenumber_from_jsdisp (jsdisp_t *jsdisp)
 
static HRESULT numberval_this (jsval_t vthis, DOUBLE *ret)
 
static void number_to_str (double d, WCHAR *buf, int size, int *dec_point)
 
static jsstr_tnumber_to_fixed (double val, int prec)
 
static jsstr_tnumber_to_exponential (double val, int prec)
 
static HRESULT Number_toString (script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
 
HRESULT localize_number (script_ctx_t *ctx, DOUBLE val, BOOL new_format, jsstr_t **ret)
 
static HRESULT Number_toLocaleString (script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
 
static HRESULT Number_toFixed (script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
 
static HRESULT Number_toExponential (script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
 
static HRESULT Number_toPrecision (script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
 
static HRESULT Number_valueOf (script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
 
static HRESULT NumberConstr_value (script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
 
static HRESULT alloc_number (script_ctx_t *ctx, jsdisp_t *object_prototype, NumberInstance **ret)
 
HRESULT create_number_constr (script_ctx_t *ctx, jsdisp_t *object_prototype, jsdisp_t **ret)
 
HRESULT create_number (script_ctx_t *ctx, double value, jsdisp_t **ret)
 

Variables

static const builtin_prop_t Number_props []
 
static const builtin_info_t Number_info
 
static const builtin_info_t NumberInst_info
 

Macro Definition Documentation

◆ NUMBER_DTOA_SIZE

#define NUMBER_DTOA_SIZE   18

Definition at line 41 of file number.c.

◆ NUMBER_TOSTRING_BUF_SIZE

#define NUMBER_TOSTRING_BUF_SIZE   64

Definition at line 40 of file number.c.

Function Documentation

◆ alloc_number()

static HRESULT alloc_number ( script_ctx_t ctx,
jsdisp_t object_prototype,
NumberInstance **  ret 
)
static

Definition at line 660 of file number.c.

661{
664
665 number = calloc(1, sizeof(NumberInstance));
666 if(!number)
667 return E_OUTOFMEMORY;
668
669 if(object_prototype)
670 hres = init_dispex(&number->dispex, ctx, &Number_info, object_prototype);
671 else
672 hres = init_dispex_from_constr(&number->dispex, ctx, &NumberInst_info, ctx->number_constr);
673 if(FAILED(hres)) {
674 free(number);
675 return hres;
676 }
677
678 *ret = number;
679 return S_OK;
680}
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define free
Definition: debug_ros.c:5
return ret
Definition: mutex.c:146
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
HRESULT init_dispex_from_constr(jsdisp_t *dispex, script_ctx_t *ctx, const builtin_info_t *builtin_info, jsdisp_t *constr)
Definition: dispex.c:2512
HRESULT init_dispex(jsdisp_t *dispex, script_ctx_t *ctx, const builtin_info_t *builtin_info, jsdisp_t *prototype)
Definition: dispex.c:2454
static unsigned int number
Definition: dsound.c:1479
HRESULT hres
Definition: protocol.c:465
static const builtin_info_t NumberInst_info
Definition: number.c:605
static const builtin_info_t Number_info
Definition: number.c:599
#define calloc
Definition: rosglue.h:14

Referenced by create_number(), and create_number_constr().

◆ create_number()

HRESULT create_number ( script_ctx_t ctx,
double  value,
jsdisp_t **  ret 
)

Definition at line 699 of file number.c.

700{
703
705 if(FAILED(hres))
706 return hres;
707
708 number->value = value;
709
710 *ret = &number->dispex;
711 return S_OK;
712}
#define NULL
Definition: types.h:112
static HRESULT alloc_number(script_ctx_t *ctx, jsdisp_t *object_prototype, NumberInstance **ret)
Definition: number.c:660
Definition: pdh_main.c:96

Referenced by NumberConstr_value(), and to_object().

◆ create_number_constr()

HRESULT create_number_constr ( script_ctx_t ctx,
jsdisp_t object_prototype,
jsdisp_t **  ret 
)

Definition at line 682 of file number.c.

683{
686
687 hres = alloc_number(ctx, object_prototype, &number);
688 if(FAILED(hres))
689 return hres;
690
691 number->value = 0;
693 PROPF_CONSTR|1, &number->dispex, ret);
694
695 jsdisp_release(&number->dispex);
696 return hres;
697}
HRESULT create_builtin_constructor(script_ctx_t *ctx, builtin_invoke_t value_proc, const WCHAR *name, const builtin_info_t *builtin_info, DWORD flags, jsdisp_t *prototype, jsdisp_t **ret)
Definition: function.c:809
#define L(x)
Definition: resources.c:13
ULONG jsdisp_release(jsdisp_t *obj)
Definition: dispex.c:1911
const unsigned int PROPF_CONSTR
Definition: jsdisp.idl:34
static HRESULT NumberConstr_value(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: number.c:609

Referenced by init_constructors().

◆ localize_number()

HRESULT localize_number ( script_ctx_t ctx,
DOUBLE  val,
BOOL  new_format,
jsstr_t **  ret 
)

Definition at line 350 of file number.c.

351{
352 WCHAR buf[316], decimal[8], thousands[8], *numstr;
353 NUMBERFMTW *format = NULL, format_buf;
354 LCID lcid = ctx->lcid;
355#ifndef __REACTOS__
357#endif
358 unsigned convlen;
359 jsstr_t *str;
360 int len;
361
362 /* FIXME: Localize this */
363 if(!isfinite(val))
364 return to_string(ctx, jsval_number(val), ret);
365
366 /* Native never uses an exponent, even if the number is very large, it will in fact
367 return all the digits (with thousands separators). jscript.dll uses two digits for
368 fraction even if they are zero (likely default numDigits) and always returns them,
369 while mshtml's jscript uses 3 digits and trims trailing zeros (on same locale).
370 This is even for very small numbers, such as 0.0000999, which will simply be 0. */
371#ifdef __REACTOS__ /* FIXME: Inspect */
372 len = swprintf(buf, ARRAY_SIZE(buf), L"%.3f", val);
373#else
374 if(!(locale = _create_locale(LC_ALL, "C")))
375 return E_OUTOFMEMORY;
376 len = _swprintf_l(buf, ARRAY_SIZE(buf), L"%.3f", locale, val);
378#endif
379
380 if(new_format) {
381 WCHAR grouping[10];
382
383 format = &format_buf;
384 format->NumDigits = 3;
385 while(buf[--len] == '0')
386 format->NumDigits--;
387
388 /* same logic as VarFormatNumber */
389 grouping[2] = '\0';
390 if(!GetLocaleInfoW(lcid, LOCALE_SGROUPING, grouping, ARRAY_SIZE(grouping)))
391 format->Grouping = 3;
392 else
393 format->Grouping = (grouping[2] == '2' ? 32 : grouping[0] - '0');
394
395 if(!GetLocaleInfoW(lcid, LOCALE_ILZERO | LOCALE_RETURN_NUMBER, (WCHAR*)&format->LeadingZero, 2))
396 format->LeadingZero = 0;
397 if(!GetLocaleInfoW(lcid, LOCALE_INEGNUMBER | LOCALE_RETURN_NUMBER, (WCHAR*)&format->NegativeOrder, 2))
398 format->NegativeOrder = 1;
399 format->lpDecimalSep = decimal;
400 if(!GetLocaleInfoW(lcid, LOCALE_SDECIMAL, decimal, ARRAY_SIZE(decimal)))
401 wcscpy(decimal, L".");
402 format->lpThousandSep = thousands;
403 if(!GetLocaleInfoW(lcid, LOCALE_STHOUSAND, thousands, ARRAY_SIZE(thousands)))
404 wcscpy(thousands, L",");
405 }
406
407 if(!(convlen = GetNumberFormatW(lcid, 0, buf, format, NULL, 0)) ||
408 !(str = jsstr_alloc_buf(convlen - 1, &numstr)))
409 return E_OUTOFMEMORY;
410
411 if(!GetNumberFormatW(lcid, 0, buf, format, numstr, convlen)) {
413 return E_OUTOFMEMORY;
414 }
415
416 *ret = str;
417 return S_OK;
418}
#define ARRAY_SIZE(A)
Definition: main.h:20
Definition: _locale.h:75
INT WINAPI GetLocaleInfoW(LCID lcid, LCTYPE lctype, LPWSTR buffer, INT len)
Definition: locale.c:1675
LCID lcid
Definition: locale.c:5660
_ACRTIMP void __cdecl _free_locale(_locale_t)
Definition: locale.c:1183
_ACRTIMP _locale_t __cdecl _create_locale(int, const char *)
Definition: locale.c:1981
#define LC_ALL
Definition: locale.h:25
#define isfinite(x)
Definition: math.h:363
#define swprintf
Definition: precomp.h:40
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint GLfloat * val
Definition: glext.h:7180
GLenum GLsizei len
Definition: glext.h:6722
static HRESULT to_string(VARIANT *src, BSTR *dst)
Definition: host.c:46
jsstr_t * jsstr_alloc_buf(unsigned len, WCHAR **buf)
Definition: jsstr.c:69
static void jsstr_release(jsstr_t *str)
Definition: jsstr.h:107
static jsval_t jsval_number(double n)
Definition: jsval.h:153
INT WINAPI GetNumberFormatW(LCID lcid, DWORD dwFlags, LPCWSTR lpszValue, const NUMBERFMTW *lpFormat, LPWSTR lpNumberStr, int cchOut)
Definition: lcformat.c:1130
short WCHAR
Definition: pedump.c:58
const WCHAR * str
DWORD LCID
Definition: nls.h:13
wcscpy
Definition: jsstr.h:36
Definition: format.c:58
#define LOCALE_SGROUPING
Definition: winnls.h:54
#define LOCALE_SDECIMAL
Definition: winnls.h:52
#define LOCALE_STHOUSAND
Definition: winnls.h:53
#define LOCALE_INEGNUMBER
Definition: winnls.h:57
#define LOCALE_ILZERO
Definition: winnls.h:56

Referenced by Number_toLocaleString(), and to_locale_string().

◆ number_from_jsdisp()

static NumberInstance * number_from_jsdisp ( jsdisp_t jsdisp)
inlinestatic

Definition at line 43 of file number.c.

44{
45 return CONTAINING_RECORD(jsdisp, NumberInstance, dispex);
46}
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

Referenced by numberval_this().

◆ number_to_exponential()

static jsstr_t * number_to_exponential ( double  val,
int  prec 
)
inlinestatic

Definition at line 161 of file number.c.

162{
164 int dec_point, size, buf_size, exp_size = 1;
165 BOOL neg = FALSE;
166 jsstr_t *ret;
167 WCHAR *str;
168
169 if(val < 0) {
170 neg = TRUE;
171 val = -val;
172 }
173
174 buf_size = prec+2;
175 if(buf_size<2 || buf_size>NUMBER_DTOA_SIZE)
176 buf_size = NUMBER_DTOA_SIZE;
177 number_to_str(val, buf, buf_size, &dec_point);
178 buf_size--;
179 if(prec == -1)
180 for(; buf_size>1 && buf[buf_size-1]=='0'; buf_size--)
181 buf[buf_size-1] = 0;
182
183 size = 10;
184 while(dec_point>=size || dec_point<=-size) {
185 size *= 10;
186 exp_size++;
187 }
188
189 if(buf_size == 1)
190 size = buf_size+2+exp_size; /* 2 = strlen(e+) */
191 else if(prec == -1)
192 size = buf_size+3+exp_size; /* 3 = strlen(.e+) */
193 else
194 size = prec+4+exp_size; /* 4 = strlen(0.e+) */
195 if(neg)
196 size++;
197
199 if(!ret)
200 return NULL;
201
202 size = 0;
203 pbuf = buf;
204 if(neg)
205 str[size++] = '-';
206 str[size++] = *pbuf++;
207 if(buf_size != 1) {
208 str[size++] = '.';
209 while(*pbuf)
210 str[size++] = *pbuf++;
211 for(; prec>buf_size-1; prec--)
212 str[size++] = '0';
213 }
214 str[size++] = 'e';
215 if(dec_point >= 0) {
216 str[size++] = '+';
217 }else {
218 str[size++] = '-';
219 dec_point = -dec_point;
220 }
221 size += exp_size;
222 do {
223 str[--size] = '0'+dec_point%10;
224 dec_point /= 10;
225 }while(dec_point>0);
226 size += exp_size;
227 str[size] = 0;
228
229 return ret;
230}
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
GLsizeiptr size
Definition: glext.h:5919
#define NUMBER_DTOA_SIZE
Definition: number.c:41
static void number_to_str(double d, WCHAR *buf, int size, int *dec_point)
Definition: number.c:60
Definition: pbuf.h:186

Referenced by Number_toExponential(), and Number_toPrecision().

◆ number_to_fixed()

static jsstr_t * number_to_fixed ( double  val,
int  prec 
)
inlinestatic

Definition at line 97 of file number.c.

98{
100 int dec_point, size, buf_size, buf_pos;
101 BOOL neg = FALSE;
102 jsstr_t *ret;
103 WCHAR *str;
104
105 TRACE("%lf %d\n", val, prec);
106
107 if(val < 0) {
108 neg = TRUE;
109 val = -val;
110 }
111
112 if(val >= 1)
113 buf_size = log10(val)+prec+2;
114 else
115 buf_size = prec ? prec+1 : 2;
116 if(buf_size > NUMBER_DTOA_SIZE)
117 buf_size = NUMBER_DTOA_SIZE;
118
119 number_to_str(val, buf, buf_size, &dec_point);
120 dec_point++;
121 size = 0;
122 if(neg)
123 size++;
124 if(dec_point > 0)
125 size += dec_point;
126 else
127 size++;
128 if(prec)
129 size += prec+1;
130
132 if(!ret)
133 return NULL;
134
135 size = buf_pos = 0;
136 if(neg)
137 str[size++] = '-';
138 if(dec_point > 0) {
139 for(;buf_pos<buf_size-1 && dec_point; dec_point--)
140 str[size++] = buf[buf_pos++];
141 }else {
142 str[size++] = '0';
143 }
144 for(; dec_point>0; dec_point--)
145 str[size++] = '0';
146 if(prec) {
147 str[size++] = '.';
148
149 for(; dec_point<0 && prec; dec_point++, prec--)
150 str[size++] = '0';
151 for(; buf_pos<buf_size-1 && prec; prec--)
152 str[size++] = buf[buf_pos++];
153 for(; prec; prec--) {
154 str[size++] = '0';
155 }
156 }
157 str[size++] = 0;
158 return ret;
159}
double log10(double x)
Definition: freeldr.c:191
#define TRACE(s)
Definition: solgame.cpp:4

Referenced by Number_toFixed(), and Number_toPrecision().

◆ number_to_str()

static void number_to_str ( double  d,
WCHAR buf,
int  size,
int dec_point 
)
inlinestatic

Definition at line 60 of file number.c.

61{
63 int i;
64
65 /* TODO: this function should print doubles with bigger precision */
67
68 if(d == 0)
69 *dec_point = 0;
70 else
71 *dec_point = floor(log10(d));
72 l = d*pow(10, size-*dec_point-1);
73
74 if(l%10 >= 5)
75 l = l/10+1;
76 else
77 l /= 10;
78
79 buf[size-1] = 0;
80 for(i=size-2; i>=0; i--) {
81 buf[i] = '0'+l%10;
82 l /= 10;
83 }
84
85 /* log10 was wrong by 1 or rounding changed number of digits */
86 if(l) {
87 (*dec_point)++;
88 memmove(buf+1, buf, size-2);
89 buf[0] = '0'+l;
90 }else if(buf[0]=='0' && buf[1]>='1' && buf[1]<='9') {
91 (*dec_point)--;
92 memmove(buf, buf+1, size-2);
93 buf[size-2] = '0';
94 }
95}
r l[0]
Definition: byte_order.h:168
#define assert(_expr)
Definition: assert.h:32
_ACRTIMP double __cdecl floor(double)
Definition: floor.c:18
double pow(double x, double y)
Definition: freeldr.c:179
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define d
Definition: ke_i.h:81
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
uint64_t ULONGLONG
Definition: typedefs.h:67

Referenced by number_to_exponential(), and number_to_fixed().

◆ Number_toExponential()

static HRESULT Number_toExponential ( script_ctx_t ctx,
jsval_t  vthis,
WORD  flags,
unsigned  argc,
jsval_t argv,
jsval_t r 
)
static

Definition at line 485 of file number.c.

487{
488 DOUBLE val;
489 INT prec = 0;
490 jsstr_t *str;
492
493 TRACE("\n");
494
495 hres = numberval_this(vthis, &val);
496 if(FAILED(hres))
497 return hres;
498
499 if(argc) {
500 hres = to_int32(ctx, argv[0], &prec);
501 if(FAILED(hres))
502 return hres;
503
504 if(prec < 0 || prec > 20)
506 }
507
508 if(!isfinite(val)) {
510 if(FAILED(hres))
511 return hres;
512 }else {
513 if(!prec)
514 prec--;
516 if(!str)
517 return E_OUTOFMEMORY;
518 }
519
520 if(r)
521 *r = jsval_string(str);
522 else
524 return S_OK;
525}
MonoAssembly int argc
Definition: metahost.c:107
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
HRESULT to_int32(script_ctx_t *, jsval_t, INT *)
Definition: jsutils.c:735
#define JS_E_FRACTION_DIGITS_OUT_OF_RANGE
Definition: jscript.h:569
static jsval_t jsval_string(jsstr_t *str)
Definition: jsval.h:109
#define argv
Definition: mplay32.c:18
static HRESULT numberval_this(jsval_t vthis, DOUBLE *ret)
Definition: number.c:48
static jsstr_t * number_to_exponential(double val, int prec)
Definition: number.c:161
int32_t INT
Definition: typedefs.h:58
double DOUBLE
Definition: typedefs.h:70

◆ Number_toFixed()

static HRESULT Number_toFixed ( script_ctx_t ctx,
jsval_t  vthis,
WORD  flags,
unsigned  argc,
jsval_t argv,
jsval_t r 
)
static

Definition at line 445 of file number.c.

447{
448 DOUBLE val;
449 INT prec = 0;
450 jsstr_t *str;
452
453 TRACE("\n");
454
455 hres = numberval_this(vthis, &val);
456 if(FAILED(hres))
457 return hres;
458
459 if(argc) {
460 hres = to_int32(ctx, argv[0], &prec);
461 if(FAILED(hres))
462 return hres;
463
464 if(prec < 0 || prec > 20)
466 }
467
468 if(!isfinite(val)) {
470 if(FAILED(hres))
471 return hres;
472 }else {
473 str = number_to_fixed(val, prec);
474 if(!str)
475 return E_OUTOFMEMORY;
476 }
477
478 if(r)
479 *r = jsval_string(str);
480 else
482 return S_OK;
483}
static jsstr_t * number_to_fixed(double val, int prec)
Definition: number.c:97

◆ Number_toLocaleString()

static HRESULT Number_toLocaleString ( script_ctx_t ctx,
jsval_t  vthis,
WORD  flags,
unsigned  argc,
jsval_t argv,
jsval_t r 
)
static

Definition at line 420 of file number.c.

422{
423 jsstr_t *str;
425 DOUBLE val;
426
427 TRACE("\n");
428
429 hres = numberval_this(vthis, &val);
430 if(FAILED(hres)) {
432 return throw_error(ctx, JS_E_WRONG_THIS, L"Number");
433 return hres;
434 }
435
436 if(r) {
438 if(FAILED(hres))
439 return hres;
440 *r = jsval_string(str);
441 }
442 return S_OK;
443}
HRESULT throw_error(script_ctx_t *ctx, HRESULT error, const WCHAR *str)
Definition: error.c:398
#define SCRIPTLANGUAGEVERSION_ES5
Definition: jscript.h:53
#define JS_E_NUMBER_EXPECTED
Definition: jscript.h:554
#define JS_E_WRONG_THIS
Definition: jscript.h:582
HRESULT localize_number(script_ctx_t *ctx, DOUBLE val, BOOL new_format, jsstr_t **ret)
Definition: number.c:350

◆ Number_toPrecision()

static HRESULT Number_toPrecision ( script_ctx_t ctx,
jsval_t  vthis,
WORD  flags,
unsigned  argc,
jsval_t argv,
jsval_t r 
)
static

Definition at line 527 of file number.c.

529{
530 INT prec = 0, size;
531 jsstr_t *str;
532 DOUBLE val;
534
535 hres = numberval_this(vthis, &val);
536 if(FAILED(hres))
537 return hres;
538
539 if(argc && (ctx->version < 2 || !is_undefined(argv[0]))) {
540 hres = to_int32(ctx, argv[0], &prec);
541 if(FAILED(hres))
542 return hres;
543
544 if(prec<1 || prec>21)
546 }
547
548 if(!isfinite(val) || !prec) {
550 if(FAILED(hres))
551 return hres;
552 }else {
553 if(val != 0)
554 size = floor(log10(val>0 ? val : -val)) + 1;
555 else
556 size = 1;
557
558 if(size > prec)
559 str = number_to_exponential(val, prec-1);
560 else
561 str = number_to_fixed(val, prec-size);
562 if(!str)
563 return E_OUTOFMEMORY;
564 }
565
566 if(r)
567 *r = jsval_string(str);
568 else
570 return S_OK;
571}
#define JS_E_PRECISION_OUT_OF_RANGE
Definition: jscript.h:570
static BOOL is_undefined(jsval_t v)
Definition: jsval.h:180

◆ Number_toString()

static HRESULT Number_toString ( script_ctx_t ctx,
jsval_t  vthis,
WORD  flags,
unsigned  argc,
jsval_t argv,
jsval_t r 
)
static

Definition at line 233 of file number.c.

235{
236 INT radix = 10;
237 DOUBLE val;
238 jsstr_t *str;
240
241 TRACE("\n");
242
243 hres = numberval_this(vthis, &val);
244 if(FAILED(hres))
245 return hres;
246
247 if(argc && (ctx->version < SCRIPTLANGUAGEVERSION_ES5 || !is_undefined(argv[0]))) {
248 hres = to_int32(ctx, argv[0], &radix);
249 if(FAILED(hres))
250 return hres;
251
252 if(radix < 2 || radix > 36)
253 return JS_E_INVALIDARG;
254 }
255
256 if(radix==10 || !isfinite(val)) {
258 if(FAILED(hres))
259 return hres;
260 }else {
261 INT idx = 0;
262 DOUBLE integ, frac, log_radix = 0;
264 BOOL exp = FALSE;
265
266 if(val<0) {
267 val = -val;
268 buf[idx++] = '-';
269 }
270
271 while(1) {
272 integ = floor(val);
273 frac = val-integ;
274
275 if(integ == 0)
276 buf[idx++] = '0';
277 while(integ>=1 && idx<NUMBER_TOSTRING_BUF_SIZE) {
278 buf[idx] = fmod(integ, radix);
279 if(buf[idx]<10) buf[idx] += '0';
280 else buf[idx] += 'a'-10;
281 integ /= radix;
282 idx++;
283 }
284
286 INT beg = buf[0]=='-'?1:0;
287 INT end = idx-1;
288 WCHAR wch;
289
290 while(end > beg) {
291 wch = buf[beg];
292 buf[beg++] = buf[end];
293 buf[end--] = wch;
294 }
295 }
296
297 if(idx != NUMBER_TOSTRING_BUF_SIZE) buf[idx++] = '.';
298
299 while(frac>0 && idx<NUMBER_TOSTRING_BUF_SIZE) {
300 frac *= radix;
301 buf[idx] = fmod(frac, radix);
302 frac -= buf[idx];
303 if(buf[idx]<10) buf[idx] += '0';
304 else buf[idx] += 'a'-10;
305 idx++;
306 }
307
309 exp = TRUE;
310 idx = (buf[0]=='-') ? 1 : 0;
311 log_radix = floor(log(val)/log(radix));
312 val *= pow(radix, -log_radix);
313 continue;
314 }
315
316 break;
317 }
318
319 while(buf[idx-1] == '0') idx--;
320 if(buf[idx-1] == '.') idx--;
321
322 if(exp) {
323 if(log_radix==0)
324 buf[idx] = 0;
325 else {
326 WCHAR ch;
327
328 if(log_radix<0) {
329 log_radix = -log_radix;
330 ch = '-';
331 }
332 else ch = '+';
333 swprintf(&buf[idx], ARRAY_SIZE(buf) - idx, L"(e%c%d)", ch, (int)log_radix);
334 }
335 }
336 else buf[idx] = '\0';
337
339 if(!str)
340 return E_OUTOFMEMORY;
341 }
342
343 if(r)
344 *r = jsval_string(str);
345 else
347 return S_OK;
348}
unsigned int idx
Definition: utils.c:41
#define frac(x)
Definition: texture.c:364
unsigned char ch[4][2]
Definition: console.c:118
_ACRTIMP double __cdecl fmod(double, double)
GLuint GLuint end
Definition: gl.h:1545
#define JS_E_INVALIDARG
Definition: jscript.h:527
static jsstr_t * jsstr_alloc(const WCHAR *str)
Definition: jsstr.h:100
DWORD exp
Definition: msg.c:18625
#define NUMBER_TOSTRING_BUF_SIZE
Definition: number.c:40
#define log(outFile, fmt,...)
Definition: util.h:15
size_t const unsigned const radix
Definition: xtoa.cpp:37

◆ Number_valueOf()

static HRESULT Number_valueOf ( script_ctx_t ctx,
jsval_t  vthis,
WORD  flags,
unsigned  argc,
jsval_t argv,
jsval_t r 
)
static

Definition at line 573 of file number.c.

575{
577 DOUBLE val;
578
579 TRACE("\n");
580
581 hres = numberval_this(vthis, &val);
582 if(FAILED(hres))
583 return hres;
584
585 if(r)
586 *r = jsval_number(val);
587 return S_OK;
588}

◆ NumberConstr_value()

static HRESULT NumberConstr_value ( script_ctx_t ctx,
jsval_t  vthis,
WORD  flags,
unsigned  argc,
jsval_t argv,
jsval_t r 
)
static

Definition at line 609 of file number.c.

611{
612 double n;
614
615 TRACE("\n");
616
617 switch(flags) {
618 case INVOKE_FUNC:
619 if(!argc) {
620 if(r)
621 *r = jsval_number(0);
622 return S_OK;
623 }
624
625 hres = to_number(ctx, argv[0], &n);
626 if(FAILED(hres))
627 return hres;
628
629 if(r)
630 *r = jsval_number(n);
631 break;
632
633 case DISPATCH_CONSTRUCT: {
634 jsdisp_t *obj;
635
636 if(argc) {
637 hres = to_number(ctx, argv[0], &n);
638 if(FAILED(hres))
639 return hres;
640 }else {
641 n = 0;
642 }
643
644 if(r) {
645 hres = create_number(ctx, n, &obj);
646 if(FAILED(hres))
647 return hres;
648 *r = jsval_obj(obj);
649 }
650 break;
651 }
652 default:
653 FIXME("unimplemented flags %x\n", flags);
654 return E_NOTIMPL;
655 }
656
657 return S_OK;
658}
#define FIXME(fmt,...)
Definition: precomp.h:53
#define E_NOTIMPL
Definition: ddrawi.h:99
GLdouble n
Definition: glext.h:7729
GLbitfield flags
Definition: glext.h:7161
HRESULT to_number(script_ctx_t *, jsval_t, double *)
Definition: jsutils.c:630
static jsval_t jsval_obj(jsdisp_t *obj)
Definition: jsval.h:125
HRESULT create_number(script_ctx_t *ctx, double value, jsdisp_t **ret)
Definition: number.c:699

Referenced by create_number_constr().

◆ numberval_this()

static HRESULT numberval_this ( jsval_t  vthis,
DOUBLE ret 
)
inlinestatic

Definition at line 48 of file number.c.

49{
50 jsdisp_t *jsdisp;
51 if(is_number(vthis))
52 *ret = get_number(vthis);
53 else if(is_object_instance(vthis) && (jsdisp = to_jsdisp(get_object(vthis))) && is_class(jsdisp, JSCLASS_NUMBER))
54 *ret = number_from_jsdisp(jsdisp)->value;
55 else
57 return S_OK;
58}
jsdisp_t * to_jsdisp(IDispatch *disp)
Definition: dispex.c:2447
@ JSCLASS_NUMBER
Definition: jscript.h:112
static BOOL is_class(jsdisp_t *jsdisp, jsclass_t class)
Definition: jscript.h:503
static BOOL is_number(jsval_t v)
Definition: jsval.h:200
static double get_number(jsval_t v)
Definition: jsval.h:233
static IDispatch * get_object(jsval_t v)
Definition: jsval.h:228
static BOOL is_object_instance(jsval_t v)
Definition: jsval.h:175
static NumberInstance * number_from_jsdisp(jsdisp_t *jsdisp)
Definition: number.c:43
double value
Definition: number.c:37

Referenced by Number_toExponential(), Number_toFixed(), Number_toLocaleString(), Number_toPrecision(), Number_toString(), and Number_valueOf().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( jscript  )

Variable Documentation

◆ Number_info

const builtin_info_t Number_info
static
Initial value:
= {
.class = JSCLASS_NUMBER,
.props_cnt = ARRAY_SIZE(Number_props),
.props = Number_props,
}
static const builtin_prop_t Number_props[]
Definition: number.c:590

Definition at line 599 of file number.c.

Referenced by alloc_number().

◆ Number_props

const builtin_prop_t Number_props[]
static
Initial value:
= {
{L"toExponential", Number_toExponential, PROPF_METHOD|1},
{L"toLocaleString", Number_toLocaleString, PROPF_METHOD},
{L"toPrecision", Number_toPrecision, PROPF_METHOD|1},
{L"toString", Number_toString, PROPF_METHOD|1},
}
const unsigned int PROPF_METHOD
Definition: jsdisp.idl:33
static HRESULT Number_toString(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: number.c:233
static HRESULT Number_toFixed(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: number.c:445
static HRESULT Number_valueOf(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: number.c:573
static HRESULT Number_toExponential(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: number.c:485
static HRESULT Number_toLocaleString(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: number.c:420
static HRESULT Number_toPrecision(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: number.c:527

Definition at line 590 of file number.c.

◆ NumberInst_info

const builtin_info_t NumberInst_info
static
Initial value:
= {
.class = JSCLASS_NUMBER,
}

Definition at line 605 of file number.c.

Referenced by alloc_number().