jbarnette-johnson 1.0.0.200806240111 → 1.0.0.200807291507

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (269) hide show
  1. data/MANIFEST +1 -0
  2. data/Rakefile +3 -10
  3. data/bin/johnson +2 -1
  4. data/ext/spidermonkey/context.c +3 -4
  5. data/ext/spidermonkey/context.h +1 -1
  6. data/ext/spidermonkey/conversions.c +39 -33
  7. data/ext/spidermonkey/debugger.c +5 -5
  8. data/ext/spidermonkey/immutable_node.c.erb +11 -11
  9. data/ext/spidermonkey/jroot.h +4 -4
  10. data/ext/spidermonkey/js_land_proxy.c +9 -8
  11. data/ext/spidermonkey/ruby_land_proxy.c +5 -4
  12. data/ext/spidermonkey/runtime.c +1 -1
  13. data/johnson.gemspec +36 -0
  14. data/lib/hoe.rb +0 -7
  15. data/lib/johnson/cli/options.rb +10 -4
  16. data/lib/johnson/spidermonkey/runtime.rb +2 -2
  17. data/lib/johnson/version.rb +4 -2
  18. data/lib/johnson.rb +1 -0
  19. data/test/johnson/runtime_test.rb +11 -0
  20. data/test/johnson/spidermonkey/ruby_land_proxy_test.rb +6 -0
  21. data/vendor/spidermonkey/.cvsignore +9 -0
  22. data/vendor/spidermonkey/Makefile.in +462 -0
  23. data/vendor/spidermonkey/Makefile.ref +364 -0
  24. data/vendor/spidermonkey/README.html +820 -0
  25. data/vendor/spidermonkey/SpiderMonkey.rsp +12 -0
  26. data/vendor/spidermonkey/Y.js +19 -0
  27. data/vendor/spidermonkey/build.mk +43 -0
  28. data/vendor/spidermonkey/config/AIX4.1.mk +65 -0
  29. data/vendor/spidermonkey/config/AIX4.2.mk +64 -0
  30. data/vendor/spidermonkey/config/AIX4.3.mk +65 -0
  31. data/vendor/spidermonkey/config/Darwin.mk +83 -0
  32. data/vendor/spidermonkey/config/Darwin1.3.mk +81 -0
  33. data/vendor/spidermonkey/config/Darwin1.4.mk +41 -0
  34. data/vendor/spidermonkey/config/Darwin5.2.mk +81 -0
  35. data/vendor/spidermonkey/config/Darwin5.3.mk +81 -0
  36. data/vendor/spidermonkey/config/HP-UXB.10.10.mk +77 -0
  37. data/vendor/spidermonkey/config/HP-UXB.10.20.mk +77 -0
  38. data/vendor/spidermonkey/config/HP-UXB.11.00.mk +80 -0
  39. data/vendor/spidermonkey/config/IRIX.mk +87 -0
  40. data/vendor/spidermonkey/config/IRIX5.3.mk +44 -0
  41. data/vendor/spidermonkey/config/IRIX6.1.mk +44 -0
  42. data/vendor/spidermonkey/config/IRIX6.2.mk +44 -0
  43. data/vendor/spidermonkey/config/IRIX6.3.mk +44 -0
  44. data/vendor/spidermonkey/config/IRIX6.5.mk +44 -0
  45. data/vendor/spidermonkey/config/Linux_All.mk +103 -0
  46. data/vendor/spidermonkey/config/Mac_OS10.0.mk +82 -0
  47. data/vendor/spidermonkey/config/OSF1V4.0.mk +72 -0
  48. data/vendor/spidermonkey/config/OSF1V5.0.mk +69 -0
  49. data/vendor/spidermonkey/config/SunOS4.1.4.mk +101 -0
  50. data/vendor/spidermonkey/config/SunOS5.10.mk +50 -0
  51. data/vendor/spidermonkey/config/SunOS5.3.mk +91 -0
  52. data/vendor/spidermonkey/config/SunOS5.4.mk +92 -0
  53. data/vendor/spidermonkey/config/SunOS5.5.1.mk +44 -0
  54. data/vendor/spidermonkey/config/SunOS5.5.mk +87 -0
  55. data/vendor/spidermonkey/config/SunOS5.6.mk +89 -0
  56. data/vendor/spidermonkey/config/SunOS5.7.mk +44 -0
  57. data/vendor/spidermonkey/config/SunOS5.8.mk +44 -0
  58. data/vendor/spidermonkey/config/SunOS5.9.mk +44 -0
  59. data/vendor/spidermonkey/config/WINNT4.0.mk +117 -0
  60. data/vendor/spidermonkey/config/WINNT5.0.mk +117 -0
  61. data/vendor/spidermonkey/config/WINNT5.1.mk +117 -0
  62. data/vendor/spidermonkey/config/WINNT5.2.mk +117 -0
  63. data/vendor/spidermonkey/config/WINNT6.0.mk +117 -0
  64. data/vendor/spidermonkey/config/dgux.mk +64 -0
  65. data/vendor/spidermonkey/config.mk +192 -0
  66. data/vendor/spidermonkey/editline/Makefile.ref +144 -0
  67. data/vendor/spidermonkey/editline/README +83 -0
  68. data/vendor/spidermonkey/editline/editline.3 +175 -0
  69. data/vendor/spidermonkey/editline/editline.c +1369 -0
  70. data/vendor/spidermonkey/editline/editline.h +135 -0
  71. data/vendor/spidermonkey/editline/sysunix.c +182 -0
  72. data/vendor/spidermonkey/editline/unix.h +82 -0
  73. data/vendor/spidermonkey/fdlibm/.cvsignore +7 -0
  74. data/vendor/spidermonkey/fdlibm/Makefile.in +127 -0
  75. data/vendor/spidermonkey/fdlibm/Makefile.ref +192 -0
  76. data/vendor/spidermonkey/fdlibm/e_acos.c +147 -0
  77. data/vendor/spidermonkey/fdlibm/e_acosh.c +105 -0
  78. data/vendor/spidermonkey/fdlibm/e_asin.c +156 -0
  79. data/vendor/spidermonkey/fdlibm/e_atan2.c +165 -0
  80. data/vendor/spidermonkey/fdlibm/e_atanh.c +110 -0
  81. data/vendor/spidermonkey/fdlibm/e_cosh.c +133 -0
  82. data/vendor/spidermonkey/fdlibm/e_exp.c +202 -0
  83. data/vendor/spidermonkey/fdlibm/e_fmod.c +184 -0
  84. data/vendor/spidermonkey/fdlibm/e_gamma.c +71 -0
  85. data/vendor/spidermonkey/fdlibm/e_gamma_r.c +70 -0
  86. data/vendor/spidermonkey/fdlibm/e_hypot.c +173 -0
  87. data/vendor/spidermonkey/fdlibm/e_j0.c +524 -0
  88. data/vendor/spidermonkey/fdlibm/e_j1.c +523 -0
  89. data/vendor/spidermonkey/fdlibm/e_jn.c +315 -0
  90. data/vendor/spidermonkey/fdlibm/e_lgamma.c +71 -0
  91. data/vendor/spidermonkey/fdlibm/e_lgamma_r.c +347 -0
  92. data/vendor/spidermonkey/fdlibm/e_log.c +184 -0
  93. data/vendor/spidermonkey/fdlibm/e_log10.c +134 -0
  94. data/vendor/spidermonkey/fdlibm/e_pow.c +386 -0
  95. data/vendor/spidermonkey/fdlibm/e_rem_pio2.c +222 -0
  96. data/vendor/spidermonkey/fdlibm/e_remainder.c +120 -0
  97. data/vendor/spidermonkey/fdlibm/e_scalb.c +89 -0
  98. data/vendor/spidermonkey/fdlibm/e_sinh.c +122 -0
  99. data/vendor/spidermonkey/fdlibm/e_sqrt.c +497 -0
  100. data/vendor/spidermonkey/fdlibm/fdlibm.h +273 -0
  101. data/vendor/spidermonkey/fdlibm/fdlibm.mak +1453 -0
  102. data/vendor/spidermonkey/fdlibm/fdlibm.mdp +0 -0
  103. data/vendor/spidermonkey/fdlibm/k_cos.c +135 -0
  104. data/vendor/spidermonkey/fdlibm/k_rem_pio2.c +354 -0
  105. data/vendor/spidermonkey/fdlibm/k_sin.c +114 -0
  106. data/vendor/spidermonkey/fdlibm/k_standard.c +785 -0
  107. data/vendor/spidermonkey/fdlibm/k_tan.c +170 -0
  108. data/vendor/spidermonkey/fdlibm/s_asinh.c +101 -0
  109. data/vendor/spidermonkey/fdlibm/s_atan.c +175 -0
  110. data/vendor/spidermonkey/fdlibm/s_cbrt.c +133 -0
  111. data/vendor/spidermonkey/fdlibm/s_ceil.c +120 -0
  112. data/vendor/spidermonkey/fdlibm/s_copysign.c +72 -0
  113. data/vendor/spidermonkey/fdlibm/s_cos.c +118 -0
  114. data/vendor/spidermonkey/fdlibm/s_erf.c +356 -0
  115. data/vendor/spidermonkey/fdlibm/s_expm1.c +267 -0
  116. data/vendor/spidermonkey/fdlibm/s_fabs.c +70 -0
  117. data/vendor/spidermonkey/fdlibm/s_finite.c +71 -0
  118. data/vendor/spidermonkey/fdlibm/s_floor.c +121 -0
  119. data/vendor/spidermonkey/fdlibm/s_frexp.c +99 -0
  120. data/vendor/spidermonkey/fdlibm/s_ilogb.c +85 -0
  121. data/vendor/spidermonkey/fdlibm/s_isnan.c +74 -0
  122. data/vendor/spidermonkey/fdlibm/s_ldexp.c +66 -0
  123. data/vendor/spidermonkey/fdlibm/s_lib_version.c +73 -0
  124. data/vendor/spidermonkey/fdlibm/s_log1p.c +211 -0
  125. data/vendor/spidermonkey/fdlibm/s_logb.c +79 -0
  126. data/vendor/spidermonkey/fdlibm/s_matherr.c +64 -0
  127. data/vendor/spidermonkey/fdlibm/s_modf.c +132 -0
  128. data/vendor/spidermonkey/fdlibm/s_nextafter.c +124 -0
  129. data/vendor/spidermonkey/fdlibm/s_rint.c +131 -0
  130. data/vendor/spidermonkey/fdlibm/s_scalbn.c +107 -0
  131. data/vendor/spidermonkey/fdlibm/s_signgam.c +40 -0
  132. data/vendor/spidermonkey/fdlibm/s_significand.c +68 -0
  133. data/vendor/spidermonkey/fdlibm/s_sin.c +118 -0
  134. data/vendor/spidermonkey/fdlibm/s_tan.c +112 -0
  135. data/vendor/spidermonkey/fdlibm/s_tanh.c +122 -0
  136. data/vendor/spidermonkey/fdlibm/w_acos.c +78 -0
  137. data/vendor/spidermonkey/fdlibm/w_acosh.c +78 -0
  138. data/vendor/spidermonkey/fdlibm/w_asin.c +80 -0
  139. data/vendor/spidermonkey/fdlibm/w_atan2.c +79 -0
  140. data/vendor/spidermonkey/fdlibm/w_atanh.c +81 -0
  141. data/vendor/spidermonkey/fdlibm/w_cosh.c +77 -0
  142. data/vendor/spidermonkey/fdlibm/w_exp.c +88 -0
  143. data/vendor/spidermonkey/fdlibm/w_fmod.c +78 -0
  144. data/vendor/spidermonkey/fdlibm/w_gamma.c +85 -0
  145. data/vendor/spidermonkey/fdlibm/w_gamma_r.c +81 -0
  146. data/vendor/spidermonkey/fdlibm/w_hypot.c +78 -0
  147. data/vendor/spidermonkey/fdlibm/w_j0.c +105 -0
  148. data/vendor/spidermonkey/fdlibm/w_j1.c +106 -0
  149. data/vendor/spidermonkey/fdlibm/w_jn.c +128 -0
  150. data/vendor/spidermonkey/fdlibm/w_lgamma.c +85 -0
  151. data/vendor/spidermonkey/fdlibm/w_lgamma_r.c +81 -0
  152. data/vendor/spidermonkey/fdlibm/w_log.c +78 -0
  153. data/vendor/spidermonkey/fdlibm/w_log10.c +81 -0
  154. data/vendor/spidermonkey/fdlibm/w_pow.c +99 -0
  155. data/vendor/spidermonkey/fdlibm/w_remainder.c +77 -0
  156. data/vendor/spidermonkey/fdlibm/w_scalb.c +95 -0
  157. data/vendor/spidermonkey/fdlibm/w_sinh.c +77 -0
  158. data/vendor/spidermonkey/fdlibm/w_sqrt.c +77 -0
  159. data/vendor/spidermonkey/javascript-trace.d +73 -0
  160. data/vendor/spidermonkey/js.c +3951 -0
  161. data/vendor/spidermonkey/js.mak +4438 -0
  162. data/vendor/spidermonkey/js.mdp +0 -0
  163. data/vendor/spidermonkey/js.msg +307 -0
  164. data/vendor/spidermonkey/js.pkg +2 -0
  165. data/vendor/spidermonkey/js3240.rc +79 -0
  166. data/vendor/spidermonkey/jsOS240.def +654 -0
  167. data/vendor/spidermonkey/jsapi.c +5836 -0
  168. data/vendor/spidermonkey/jsapi.h +2624 -0
  169. data/vendor/spidermonkey/jsarena.c +450 -0
  170. data/vendor/spidermonkey/jsarena.h +318 -0
  171. data/vendor/spidermonkey/jsarray.c +2988 -0
  172. data/vendor/spidermonkey/jsarray.h +124 -0
  173. data/vendor/spidermonkey/jsatom.c +1045 -0
  174. data/vendor/spidermonkey/jsatom.h +442 -0
  175. data/vendor/spidermonkey/jsbit.h +253 -0
  176. data/vendor/spidermonkey/jsbool.c +176 -0
  177. data/vendor/spidermonkey/jsbool.h +73 -0
  178. data/vendor/spidermonkey/jsclist.h +139 -0
  179. data/vendor/spidermonkey/jscntxt.c +1348 -0
  180. data/vendor/spidermonkey/jscntxt.h +1120 -0
  181. data/vendor/spidermonkey/jscompat.h +57 -0
  182. data/vendor/spidermonkey/jsconfig.h +248 -0
  183. data/vendor/spidermonkey/jsconfig.mk +181 -0
  184. data/vendor/spidermonkey/jscpucfg.c +383 -0
  185. data/vendor/spidermonkey/jscpucfg.h +212 -0
  186. data/vendor/spidermonkey/jsdate.c +2398 -0
  187. data/vendor/spidermonkey/jsdate.h +124 -0
  188. data/vendor/spidermonkey/jsdbgapi.c +1799 -0
  189. data/vendor/spidermonkey/jsdbgapi.h +464 -0
  190. data/vendor/spidermonkey/jsdhash.c +868 -0
  191. data/vendor/spidermonkey/jsdhash.h +592 -0
  192. data/vendor/spidermonkey/jsdtoa.c +3167 -0
  193. data/vendor/spidermonkey/jsdtoa.h +130 -0
  194. data/vendor/spidermonkey/jsdtracef.c +317 -0
  195. data/vendor/spidermonkey/jsdtracef.h +77 -0
  196. data/vendor/spidermonkey/jsemit.c +6909 -0
  197. data/vendor/spidermonkey/jsemit.h +741 -0
  198. data/vendor/spidermonkey/jsexn.c +1371 -0
  199. data/vendor/spidermonkey/jsexn.h +96 -0
  200. data/vendor/spidermonkey/jsfile.c +2736 -0
  201. data/vendor/spidermonkey/jsfile.h +56 -0
  202. data/vendor/spidermonkey/jsfile.msg +90 -0
  203. data/vendor/spidermonkey/jsfun.c +2634 -0
  204. data/vendor/spidermonkey/jsfun.h +254 -0
  205. data/vendor/spidermonkey/jsgc.c +3554 -0
  206. data/vendor/spidermonkey/jsgc.h +403 -0
  207. data/vendor/spidermonkey/jshash.c +476 -0
  208. data/vendor/spidermonkey/jshash.h +151 -0
  209. data/vendor/spidermonkey/jsify.pl +485 -0
  210. data/vendor/spidermonkey/jsinterp.c +6981 -0
  211. data/vendor/spidermonkey/jsinterp.h +521 -0
  212. data/vendor/spidermonkey/jsinvoke.c +43 -0
  213. data/vendor/spidermonkey/jsiter.c +1067 -0
  214. data/vendor/spidermonkey/jsiter.h +122 -0
  215. data/vendor/spidermonkey/jskeyword.tbl +124 -0
  216. data/vendor/spidermonkey/jskwgen.c +460 -0
  217. data/vendor/spidermonkey/jslibmath.h +266 -0
  218. data/vendor/spidermonkey/jslock.c +1309 -0
  219. data/vendor/spidermonkey/jslock.h +313 -0
  220. data/vendor/spidermonkey/jslocko.asm +60 -0
  221. data/vendor/spidermonkey/jslog2.c +94 -0
  222. data/vendor/spidermonkey/jslong.c +264 -0
  223. data/vendor/spidermonkey/jslong.h +412 -0
  224. data/vendor/spidermonkey/jsmath.c +568 -0
  225. data/vendor/spidermonkey/jsmath.h +57 -0
  226. data/vendor/spidermonkey/jsnum.c +1228 -0
  227. data/vendor/spidermonkey/jsnum.h +283 -0
  228. data/vendor/spidermonkey/jsobj.c +5266 -0
  229. data/vendor/spidermonkey/jsobj.h +709 -0
  230. data/vendor/spidermonkey/jsopcode.c +5245 -0
  231. data/vendor/spidermonkey/jsopcode.h +394 -0
  232. data/vendor/spidermonkey/jsopcode.tbl +523 -0
  233. data/vendor/spidermonkey/jsotypes.h +202 -0
  234. data/vendor/spidermonkey/jsparse.c +6680 -0
  235. data/vendor/spidermonkey/jsparse.h +511 -0
  236. data/vendor/spidermonkey/jsprf.c +1262 -0
  237. data/vendor/spidermonkey/jsprf.h +150 -0
  238. data/vendor/spidermonkey/jsproto.tbl +128 -0
  239. data/vendor/spidermonkey/jsprvtd.h +267 -0
  240. data/vendor/spidermonkey/jspubtd.h +744 -0
  241. data/vendor/spidermonkey/jsregexp.c +4352 -0
  242. data/vendor/spidermonkey/jsregexp.h +183 -0
  243. data/vendor/spidermonkey/jsreops.tbl +145 -0
  244. data/vendor/spidermonkey/jsscan.c +2003 -0
  245. data/vendor/spidermonkey/jsscan.h +387 -0
  246. data/vendor/spidermonkey/jsscope.c +1948 -0
  247. data/vendor/spidermonkey/jsscope.h +418 -0
  248. data/vendor/spidermonkey/jsscript.c +1832 -0
  249. data/vendor/spidermonkey/jsscript.h +287 -0
  250. data/vendor/spidermonkey/jsshell.msg +50 -0
  251. data/vendor/spidermonkey/jsstddef.h +83 -0
  252. data/vendor/spidermonkey/jsstr.c +5004 -0
  253. data/vendor/spidermonkey/jsstr.h +641 -0
  254. data/vendor/spidermonkey/jstypes.h +475 -0
  255. data/vendor/spidermonkey/jsutil.c +345 -0
  256. data/vendor/spidermonkey/jsutil.h +157 -0
  257. data/vendor/spidermonkey/jsxdrapi.c +800 -0
  258. data/vendor/spidermonkey/jsxdrapi.h +218 -0
  259. data/vendor/spidermonkey/jsxml.c +8471 -0
  260. data/vendor/spidermonkey/jsxml.h +349 -0
  261. data/vendor/spidermonkey/lock_SunOS.s +119 -0
  262. data/vendor/spidermonkey/perfect.js +39 -0
  263. data/vendor/spidermonkey/plify_jsdhash.sed +36 -0
  264. data/vendor/spidermonkey/prmjtime.c +846 -0
  265. data/vendor/spidermonkey/prmjtime.h +103 -0
  266. data/vendor/spidermonkey/resource.h +15 -0
  267. data/vendor/spidermonkey/rules.mk +197 -0
  268. data/vendor/spidermonkey/win32.order +384 -0
  269. metadata +4 -3
@@ -0,0 +1,3167 @@
1
+ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2
+ *
3
+ * ***** BEGIN LICENSE BLOCK *****
4
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5
+ *
6
+ * The contents of this file are subject to the Mozilla Public License Version
7
+ * 1.1 (the "License"); you may not use this file except in compliance with
8
+ * the License. You may obtain a copy of the License at
9
+ * http://www.mozilla.org/MPL/
10
+ *
11
+ * Software distributed under the License is distributed on an "AS IS" basis,
12
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13
+ * for the specific language governing rights and limitations under the
14
+ * License.
15
+ *
16
+ * The Original Code is Mozilla Communicator client code, released
17
+ * March 31, 1998.
18
+ *
19
+ * The Initial Developer of the Original Code is
20
+ * Netscape Communications Corporation.
21
+ * Portions created by the Initial Developer are Copyright (C) 1998
22
+ * the Initial Developer. All Rights Reserved.
23
+ *
24
+ * Contributor(s):
25
+ *
26
+ * Alternatively, the contents of this file may be used under the terms of
27
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
28
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29
+ * in which case the provisions of the GPL or the LGPL are applicable instead
30
+ * of those above. If you wish to allow use of your version of this file only
31
+ * under the terms of either the GPL or the LGPL, and not to allow others to
32
+ * use your version of this file under the terms of the MPL, indicate your
33
+ * decision by deleting the provisions above and replace them with the notice
34
+ * and other provisions required by the GPL or the LGPL. If you do not delete
35
+ * the provisions above, a recipient may use your version of this file under
36
+ * the terms of any one of the MPL, the GPL or the LGPL.
37
+ *
38
+ * ***** END LICENSE BLOCK ***** */
39
+
40
+ /*
41
+ * Portable double to alphanumeric string and back converters.
42
+ */
43
+ #include "jsstddef.h"
44
+ #include "jslibmath.h"
45
+ #include "jstypes.h"
46
+ #include "jsdtoa.h"
47
+ #include "jsprf.h"
48
+ #include "jsutil.h" /* Added by JSIFY */
49
+ #include "jspubtd.h"
50
+ #include "jsnum.h"
51
+ #include "jsbit.h"
52
+
53
+ #ifdef JS_THREADSAFE
54
+ #include "prlock.h"
55
+ #endif
56
+
57
+ /****************************************************************
58
+ *
59
+ * The author of this software is David M. Gay.
60
+ *
61
+ * Copyright (c) 1991 by Lucent Technologies.
62
+ *
63
+ * Permission to use, copy, modify, and distribute this software for any
64
+ * purpose without fee is hereby granted, provided that this entire notice
65
+ * is included in all copies of any software which is or includes a copy
66
+ * or modification of this software and in all copies of the supporting
67
+ * documentation for such software.
68
+ *
69
+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
70
+ * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY
71
+ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
72
+ * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
73
+ *
74
+ ***************************************************************/
75
+
76
+ /* Please send bug reports to
77
+ David M. Gay
78
+ Bell Laboratories, Room 2C-463
79
+ 600 Mountain Avenue
80
+ Murray Hill, NJ 07974-0636
81
+ U.S.A.
82
+ dmg@bell-labs.com
83
+ */
84
+
85
+ /* On a machine with IEEE extended-precision registers, it is
86
+ * necessary to specify double-precision (53-bit) rounding precision
87
+ * before invoking strtod or dtoa. If the machine uses (the equivalent
88
+ * of) Intel 80x87 arithmetic, the call
89
+ * _control87(PC_53, MCW_PC);
90
+ * does this with many compilers. Whether this or another call is
91
+ * appropriate depends on the compiler; for this to work, it may be
92
+ * necessary to #include "float.h" or another system-dependent header
93
+ * file.
94
+ */
95
+
96
+ /* strtod for IEEE-arithmetic machines.
97
+ *
98
+ * This strtod returns a nearest machine number to the input decimal
99
+ * string (or sets err to JS_DTOA_ERANGE or JS_DTOA_ENOMEM). With IEEE
100
+ * arithmetic, ties are broken by the IEEE round-even rule. Otherwise
101
+ * ties are broken by biased rounding (add half and chop).
102
+ *
103
+ * Inspired loosely by William D. Clinger's paper "How to Read Floating
104
+ * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101].
105
+ *
106
+ * Modifications:
107
+ *
108
+ * 1. We only require IEEE double-precision
109
+ * arithmetic (not IEEE double-extended).
110
+ * 2. We get by with floating-point arithmetic in a case that
111
+ * Clinger missed -- when we're computing d * 10^n
112
+ * for a small integer d and the integer n is not too
113
+ * much larger than 22 (the maximum integer k for which
114
+ * we can represent 10^k exactly), we may be able to
115
+ * compute (d*10^k) * 10^(e-k) with just one roundoff.
116
+ * 3. Rather than a bit-at-a-time adjustment of the binary
117
+ * result in the hard case, we use floating-point
118
+ * arithmetic to determine the adjustment to within
119
+ * one bit; only in really hard cases do we need to
120
+ * compute a second residual.
121
+ * 4. Because of 3., we don't need a large table of powers of 10
122
+ * for ten-to-e (just some small tables, e.g. of 10^k
123
+ * for 0 <= k <= 22).
124
+ */
125
+
126
+ /*
127
+ * #define IEEE_8087 for IEEE-arithmetic machines where the least
128
+ * significant byte has the lowest address.
129
+ * #define IEEE_MC68k for IEEE-arithmetic machines where the most
130
+ * significant byte has the lowest address.
131
+ * #define Long int on machines with 32-bit ints and 64-bit longs.
132
+ * #define Sudden_Underflow for IEEE-format machines without gradual
133
+ * underflow (i.e., that flush to zero on underflow).
134
+ * #define No_leftright to omit left-right logic in fast floating-point
135
+ * computation of js_dtoa.
136
+ * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3.
137
+ * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines
138
+ * that use extended-precision instructions to compute rounded
139
+ * products and quotients) with IBM.
140
+ * #define ROUND_BIASED for IEEE-format with biased rounding.
141
+ * #define Inaccurate_Divide for IEEE-format with correctly rounded
142
+ * products but inaccurate quotients, e.g., for Intel i860.
143
+ * #define JS_HAVE_LONG_LONG on machines that have a "long long"
144
+ * integer type (of >= 64 bits). If long long is available and the name is
145
+ * something other than "long long", #define Llong to be the name,
146
+ * and if "unsigned Llong" does not work as an unsigned version of
147
+ * Llong, #define #ULLong to be the corresponding unsigned type.
148
+ * #define Bad_float_h if your system lacks a float.h or if it does not
149
+ * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP,
150
+ * FLT_RADIX, FLT_ROUNDS, and DBL_MAX.
151
+ * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n)
152
+ * if memory is available and otherwise does something you deem
153
+ * appropriate. If MALLOC is undefined, malloc will be invoked
154
+ * directly -- and assumed always to succeed.
155
+ * #define Omit_Private_Memory to omit logic (added Jan. 1998) for making
156
+ * memory allocations from a private pool of memory when possible.
157
+ * When used, the private pool is PRIVATE_MEM bytes long: 2000 bytes,
158
+ * unless #defined to be a different length. This default length
159
+ * suffices to get rid of MALLOC calls except for unusual cases,
160
+ * such as decimal-to-binary conversion of a very long string of
161
+ * digits.
162
+ * #define INFNAN_CHECK on IEEE systems to cause strtod to check for
163
+ * Infinity and NaN (case insensitively). On some systems (e.g.,
164
+ * some HP systems), it may be necessary to #define NAN_WORD0
165
+ * appropriately -- to the most significant word of a quiet NaN.
166
+ * (On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.)
167
+ * #define MULTIPLE_THREADS if the system offers preemptively scheduled
168
+ * multiple threads. In this case, you must provide (or suitably
169
+ * #define) two locks, acquired by ACQUIRE_DTOA_LOCK() and released
170
+ * by RELEASE_DTOA_LOCK(). (The second lock, accessed
171
+ * in pow5mult, ensures lazy evaluation of only one copy of high
172
+ * powers of 5; omitting this lock would introduce a small
173
+ * probability of wasting memory, but would otherwise be harmless.)
174
+ * You must also invoke freedtoa(s) to free the value s returned by
175
+ * dtoa. You may do so whether or not MULTIPLE_THREADS is #defined.
176
+ * #define NO_IEEE_Scale to disable new (Feb. 1997) logic in strtod that
177
+ * avoids underflows on inputs whose result does not underflow.
178
+ */
179
+ #ifdef IS_LITTLE_ENDIAN
180
+ #define IEEE_8087
181
+ #else
182
+ #define IEEE_MC68k
183
+ #endif
184
+
185
+ #ifndef Long
186
+ #define Long int32
187
+ #endif
188
+
189
+ #ifndef ULong
190
+ #define ULong uint32
191
+ #endif
192
+
193
+ #define Bug(errorMessageString) JS_ASSERT(!errorMessageString)
194
+
195
+ #include "stdlib.h"
196
+ #include "string.h"
197
+
198
+ #ifdef MALLOC
199
+ extern void *MALLOC(size_t);
200
+ #else
201
+ #define MALLOC malloc
202
+ #endif
203
+
204
+ #define Omit_Private_Memory
205
+ /* Private memory currently doesn't work with JS_THREADSAFE */
206
+ #ifndef Omit_Private_Memory
207
+ #ifndef PRIVATE_MEM
208
+ #define PRIVATE_MEM 2000
209
+ #endif
210
+ #define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))
211
+ static double private_mem[PRIVATE_mem], *pmem_next = private_mem;
212
+ #endif
213
+
214
+ #ifdef Bad_float_h
215
+ #undef __STDC__
216
+
217
+ #define DBL_DIG 15
218
+ #define DBL_MAX_10_EXP 308
219
+ #define DBL_MAX_EXP 1024
220
+ #define FLT_RADIX 2
221
+ #define FLT_ROUNDS 1
222
+ #define DBL_MAX 1.7976931348623157e+308
223
+
224
+
225
+
226
+ #ifndef LONG_MAX
227
+ #define LONG_MAX 2147483647
228
+ #endif
229
+
230
+ #else /* ifndef Bad_float_h */
231
+ #include "float.h"
232
+ #endif /* Bad_float_h */
233
+
234
+ #ifndef __MATH_H__
235
+ #include "math.h"
236
+ #endif
237
+
238
+ #ifndef CONST
239
+ #define CONST const
240
+ #endif
241
+
242
+ #if defined(IEEE_8087) + defined(IEEE_MC68k) != 1
243
+ Exactly one of IEEE_8087 or IEEE_MC68k should be defined.
244
+ #endif
245
+
246
+ #define word0(x) JSDOUBLE_HI32(x)
247
+ #define set_word0(x, y) JSDOUBLE_SET_HI32(x, y)
248
+ #define word1(x) JSDOUBLE_LO32(x)
249
+ #define set_word1(x, y) JSDOUBLE_SET_LO32(x, y)
250
+
251
+ #define Storeinc(a,b,c) (*(a)++ = (b) << 16 | (c) & 0xffff)
252
+
253
+ /* #define P DBL_MANT_DIG */
254
+ /* Ten_pmax = floor(P*log(2)/log(5)) */
255
+ /* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */
256
+ /* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */
257
+ /* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */
258
+
259
+ #define Exp_shift 20
260
+ #define Exp_shift1 20
261
+ #define Exp_msk1 0x100000
262
+ #define Exp_msk11 0x100000
263
+ #define Exp_mask 0x7ff00000
264
+ #define P 53
265
+ #define Bias 1023
266
+ #define Emin (-1022)
267
+ #define Exp_1 0x3ff00000
268
+ #define Exp_11 0x3ff00000
269
+ #define Ebits 11
270
+ #define Frac_mask 0xfffff
271
+ #define Frac_mask1 0xfffff
272
+ #define Ten_pmax 22
273
+ #define Bletch 0x10
274
+ #define Bndry_mask 0xfffff
275
+ #define Bndry_mask1 0xfffff
276
+ #define LSB 1
277
+ #define Sign_bit 0x80000000
278
+ #define Log2P 1
279
+ #define Tiny0 0
280
+ #define Tiny1 1
281
+ #define Quick_max 14
282
+ #define Int_max 14
283
+ #define Infinite(x) (word0(x) == 0x7ff00000) /* sufficient test for here */
284
+ #ifndef NO_IEEE_Scale
285
+ #define Avoid_Underflow
286
+ #endif
287
+
288
+
289
+
290
+ #ifdef RND_PRODQUOT
291
+ #define rounded_product(a,b) a = rnd_prod(a, b)
292
+ #define rounded_quotient(a,b) a = rnd_quot(a, b)
293
+ extern double rnd_prod(double, double), rnd_quot(double, double);
294
+ #else
295
+ #define rounded_product(a,b) a *= b
296
+ #define rounded_quotient(a,b) a /= b
297
+ #endif
298
+
299
+ #define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
300
+ #define Big1 0xffffffff
301
+
302
+ #ifndef JS_HAVE_LONG_LONG
303
+ #undef ULLong
304
+ #else /* long long available */
305
+ #ifndef Llong
306
+ #define Llong JSInt64
307
+ #endif
308
+ #ifndef ULLong
309
+ #define ULLong JSUint64
310
+ #endif
311
+ #endif /* JS_HAVE_LONG_LONG */
312
+
313
+ #ifdef JS_THREADSAFE
314
+ #define MULTIPLE_THREADS
315
+ static PRLock *freelist_lock;
316
+ #define ACQUIRE_DTOA_LOCK() \
317
+ JS_BEGIN_MACRO \
318
+ if (!initialized) \
319
+ InitDtoa(); \
320
+ PR_Lock(freelist_lock); \
321
+ JS_END_MACRO
322
+ #define RELEASE_DTOA_LOCK() PR_Unlock(freelist_lock)
323
+ #else
324
+ #undef MULTIPLE_THREADS
325
+ #define ACQUIRE_DTOA_LOCK() /*nothing*/
326
+ #define RELEASE_DTOA_LOCK() /*nothing*/
327
+ #endif
328
+
329
+ #define Kmax 15
330
+
331
+ struct Bigint {
332
+ struct Bigint *next; /* Free list link */
333
+ int32 k; /* lg2(maxwds) */
334
+ int32 maxwds; /* Number of words allocated for x */
335
+ int32 sign; /* Zero if positive, 1 if negative. Ignored by most Bigint routines! */
336
+ int32 wds; /* Actual number of words. If value is nonzero, the most significant word must be nonzero. */
337
+ ULong x[1]; /* wds words of number in little endian order */
338
+ };
339
+
340
+ #ifdef ENABLE_OOM_TESTING
341
+ /* Out-of-memory testing. Use a good testcase (over and over) and then use
342
+ * these routines to cause a memory failure on every possible Balloc allocation,
343
+ * to make sure that all out-of-memory paths can be followed. See bug 14044.
344
+ */
345
+
346
+ static int allocationNum; /* which allocation is next? */
347
+ static int desiredFailure; /* which allocation should fail? */
348
+
349
+ /**
350
+ * js_BigintTestingReset
351
+ *
352
+ * Call at the beginning of a test run to set the allocation failure position.
353
+ * (Set to 0 to just have the engine count allocations without failing.)
354
+ */
355
+ JS_PUBLIC_API(void)
356
+ js_BigintTestingReset(int newFailure)
357
+ {
358
+ allocationNum = 0;
359
+ desiredFailure = newFailure;
360
+ }
361
+
362
+ /**
363
+ * js_BigintTestingWhere
364
+ *
365
+ * Report the current allocation position. This is really only useful when you
366
+ * want to learn how many allocations a test run has.
367
+ */
368
+ JS_PUBLIC_API(int)
369
+ js_BigintTestingWhere()
370
+ {
371
+ return allocationNum;
372
+ }
373
+
374
+
375
+ /*
376
+ * So here's what you do: Set up a fantastic test case that exercises the
377
+ * elements of the code you wish. Set the failure point at 0 and run the test,
378
+ * then get the allocation position. This number is the number of allocations
379
+ * your test makes. Now loop from 1 to that number, setting the failure point
380
+ * at each loop count, and run the test over and over, causing failures at each
381
+ * step. Any memory failure *should* cause a Out-Of-Memory exception; if it
382
+ * doesn't, then there's still an error here.
383
+ */
384
+ #endif
385
+
386
+ typedef struct Bigint Bigint;
387
+
388
+ static Bigint *freelist[Kmax+1];
389
+
390
+ /*
391
+ * Allocate a Bigint with 2^k words.
392
+ * This is not threadsafe. The caller must use thread locks
393
+ */
394
+ static Bigint *Balloc(int32 k)
395
+ {
396
+ int32 x;
397
+ Bigint *rv;
398
+ #ifndef Omit_Private_Memory
399
+ uint32 len;
400
+ #endif
401
+
402
+ #ifdef ENABLE_OOM_TESTING
403
+ if (++allocationNum == desiredFailure) {
404
+ printf("Forced Failing Allocation number %d\n", allocationNum);
405
+ return NULL;
406
+ }
407
+ #endif
408
+
409
+ if ((rv = freelist[k]) != NULL)
410
+ freelist[k] = rv->next;
411
+ if (rv == NULL) {
412
+ x = 1 << k;
413
+ #ifdef Omit_Private_Memory
414
+ rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong));
415
+ #else
416
+ len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
417
+ /sizeof(double);
418
+ if (pmem_next - private_mem + len <= PRIVATE_mem) {
419
+ rv = (Bigint*)pmem_next;
420
+ pmem_next += len;
421
+ }
422
+ else
423
+ rv = (Bigint*)MALLOC(len*sizeof(double));
424
+ #endif
425
+ if (!rv)
426
+ return NULL;
427
+ rv->k = k;
428
+ rv->maxwds = x;
429
+ }
430
+ rv->sign = rv->wds = 0;
431
+ return rv;
432
+ }
433
+
434
+ static void Bfree(Bigint *v)
435
+ {
436
+ if (v) {
437
+ v->next = freelist[v->k];
438
+ freelist[v->k] = v;
439
+ }
440
+ }
441
+
442
+ #define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \
443
+ y->wds*sizeof(Long) + 2*sizeof(int32))
444
+
445
+ /* Return b*m + a. Deallocate the old b. Both a and m must be between 0 and
446
+ * 65535 inclusive. NOTE: old b is deallocated on memory failure.
447
+ */
448
+ static Bigint *multadd(Bigint *b, int32 m, int32 a)
449
+ {
450
+ int32 i, wds;
451
+ #ifdef ULLong
452
+ ULong *x;
453
+ ULLong carry, y;
454
+ #else
455
+ ULong carry, *x, y;
456
+ ULong xi, z;
457
+ #endif
458
+ Bigint *b1;
459
+
460
+ #ifdef ENABLE_OOM_TESTING
461
+ if (++allocationNum == desiredFailure) {
462
+ /* Faux allocation, because I'm not getting all of the failure paths
463
+ * without it.
464
+ */
465
+ printf("Forced Failing Allocation number %d\n", allocationNum);
466
+ Bfree(b);
467
+ return NULL;
468
+ }
469
+ #endif
470
+
471
+ wds = b->wds;
472
+ x = b->x;
473
+ i = 0;
474
+ carry = a;
475
+ do {
476
+ #ifdef ULLong
477
+ y = *x * (ULLong)m + carry;
478
+ carry = y >> 32;
479
+ *x++ = (ULong)(y & 0xffffffffUL);
480
+ #else
481
+ xi = *x;
482
+ y = (xi & 0xffff) * m + carry;
483
+ z = (xi >> 16) * m + (y >> 16);
484
+ carry = z >> 16;
485
+ *x++ = (z << 16) + (y & 0xffff);
486
+ #endif
487
+ }
488
+ while(++i < wds);
489
+ if (carry) {
490
+ if (wds >= b->maxwds) {
491
+ b1 = Balloc(b->k+1);
492
+ if (!b1) {
493
+ Bfree(b);
494
+ return NULL;
495
+ }
496
+ Bcopy(b1, b);
497
+ Bfree(b);
498
+ b = b1;
499
+ }
500
+ b->x[wds++] = (ULong)carry;
501
+ b->wds = wds;
502
+ }
503
+ return b;
504
+ }
505
+
506
+ static Bigint *s2b(CONST char *s, int32 nd0, int32 nd, ULong y9)
507
+ {
508
+ Bigint *b;
509
+ int32 i, k;
510
+ Long x, y;
511
+
512
+ x = (nd + 8) / 9;
513
+ for(k = 0, y = 1; x > y; y <<= 1, k++) ;
514
+ b = Balloc(k);
515
+ if (!b)
516
+ return NULL;
517
+ b->x[0] = y9;
518
+ b->wds = 1;
519
+
520
+ i = 9;
521
+ if (9 < nd0) {
522
+ s += 9;
523
+ do {
524
+ b = multadd(b, 10, *s++ - '0');
525
+ if (!b)
526
+ return NULL;
527
+ } while(++i < nd0);
528
+ s++;
529
+ }
530
+ else
531
+ s += 10;
532
+ for(; i < nd; i++) {
533
+ b = multadd(b, 10, *s++ - '0');
534
+ if (!b)
535
+ return NULL;
536
+ }
537
+ return b;
538
+ }
539
+
540
+
541
+ /* Return the number (0 through 32) of most significant zero bits in x. */
542
+ static int32 hi0bits(register ULong x)
543
+ {
544
+ #ifdef JS_HAS_BUILTIN_BITSCAN32
545
+ return( (!x) ? 32 : js_bitscan_clz32(x) );
546
+ #else
547
+ register int32 k = 0;
548
+
549
+ if (!(x & 0xffff0000)) {
550
+ k = 16;
551
+ x <<= 16;
552
+ }
553
+ if (!(x & 0xff000000)) {
554
+ k += 8;
555
+ x <<= 8;
556
+ }
557
+ if (!(x & 0xf0000000)) {
558
+ k += 4;
559
+ x <<= 4;
560
+ }
561
+ if (!(x & 0xc0000000)) {
562
+ k += 2;
563
+ x <<= 2;
564
+ }
565
+ if (!(x & 0x80000000)) {
566
+ k++;
567
+ if (!(x & 0x40000000))
568
+ return 32;
569
+ }
570
+ return k;
571
+ #endif /* JS_HAS_BUILTIN_BITSCAN32 */
572
+ }
573
+
574
+
575
+ /* Return the number (0 through 32) of least significant zero bits in y.
576
+ * Also shift y to the right past these 0 through 32 zeros so that y's
577
+ * least significant bit will be set unless y was originally zero. */
578
+ static int32 lo0bits(ULong *y)
579
+ {
580
+ #ifdef JS_HAS_BUILTIN_BITSCAN32
581
+ int32 k;
582
+ ULong x = *y;
583
+
584
+ if (x>1)
585
+ *y = ( x >> (k = js_bitscan_ctz32(x)) );
586
+ else
587
+ k = ((x ^ 1) << 5);
588
+ #else
589
+ register int32 k;
590
+ register ULong x = *y;
591
+
592
+ if (x & 7) {
593
+ if (x & 1)
594
+ return 0;
595
+ if (x & 2) {
596
+ *y = x >> 1;
597
+ return 1;
598
+ }
599
+ *y = x >> 2;
600
+ return 2;
601
+ }
602
+ k = 0;
603
+ if (!(x & 0xffff)) {
604
+ k = 16;
605
+ x >>= 16;
606
+ }
607
+ if (!(x & 0xff)) {
608
+ k += 8;
609
+ x >>= 8;
610
+ }
611
+ if (!(x & 0xf)) {
612
+ k += 4;
613
+ x >>= 4;
614
+ }
615
+ if (!(x & 0x3)) {
616
+ k += 2;
617
+ x >>= 2;
618
+ }
619
+ if (!(x & 1)) {
620
+ k++;
621
+ x >>= 1;
622
+ if (!x & 1)
623
+ return 32;
624
+ }
625
+ *y = x;
626
+ #endif /* JS_HAS_BUILTIN_BITSCAN32 */
627
+ return k;
628
+ }
629
+
630
+ /* Return a new Bigint with the given integer value, which must be nonnegative. */
631
+ static Bigint *i2b(int32 i)
632
+ {
633
+ Bigint *b;
634
+
635
+ b = Balloc(1);
636
+ if (!b)
637
+ return NULL;
638
+ b->x[0] = i;
639
+ b->wds = 1;
640
+ return b;
641
+ }
642
+
643
+ /* Return a newly allocated product of a and b. */
644
+ static Bigint *mult(CONST Bigint *a, CONST Bigint *b)
645
+ {
646
+ CONST Bigint *t;
647
+ Bigint *c;
648
+ int32 k, wa, wb, wc;
649
+ ULong y;
650
+ ULong *xc, *xc0, *xce;
651
+ CONST ULong *x, *xa, *xae, *xb, *xbe;
652
+ #ifdef ULLong
653
+ ULLong carry, z;
654
+ #else
655
+ ULong carry, z;
656
+ ULong z2;
657
+ #endif
658
+
659
+ if (a->wds < b->wds) {
660
+ t = a;
661
+ a = b;
662
+ b = t;
663
+ }
664
+ k = a->k;
665
+ wa = a->wds;
666
+ wb = b->wds;
667
+ wc = wa + wb;
668
+ if (wc > a->maxwds)
669
+ k++;
670
+ c = Balloc(k);
671
+ if (!c)
672
+ return NULL;
673
+ for(xc = c->x, xce = xc + wc; xc < xce; xc++)
674
+ *xc = 0;
675
+ xa = a->x;
676
+ xae = xa + wa;
677
+ xb = b->x;
678
+ xbe = xb + wb;
679
+ xc0 = c->x;
680
+ #ifdef ULLong
681
+ for(; xb < xbe; xc0++) {
682
+ if ((y = *xb++) != 0) {
683
+ x = xa;
684
+ xc = xc0;
685
+ carry = 0;
686
+ do {
687
+ z = *x++ * (ULLong)y + *xc + carry;
688
+ carry = z >> 32;
689
+ *xc++ = (ULong)(z & 0xffffffffUL);
690
+ }
691
+ while(x < xae);
692
+ *xc = (ULong)carry;
693
+ }
694
+ }
695
+ #else
696
+ for(; xb < xbe; xb++, xc0++) {
697
+ if ((y = *xb & 0xffff) != 0) {
698
+ x = xa;
699
+ xc = xc0;
700
+ carry = 0;
701
+ do {
702
+ z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
703
+ carry = z >> 16;
704
+ z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
705
+ carry = z2 >> 16;
706
+ Storeinc(xc, z2, z);
707
+ }
708
+ while(x < xae);
709
+ *xc = carry;
710
+ }
711
+ if ((y = *xb >> 16) != 0) {
712
+ x = xa;
713
+ xc = xc0;
714
+ carry = 0;
715
+ z2 = *xc;
716
+ do {
717
+ z = (*x & 0xffff) * y + (*xc >> 16) + carry;
718
+ carry = z >> 16;
719
+ Storeinc(xc, z, z2);
720
+ z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
721
+ carry = z2 >> 16;
722
+ }
723
+ while(x < xae);
724
+ *xc = z2;
725
+ }
726
+ }
727
+ #endif
728
+ for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
729
+ c->wds = wc;
730
+ return c;
731
+ }
732
+
733
+ /*
734
+ * 'p5s' points to a linked list of Bigints that are powers of 5.
735
+ * This list grows on demand, and it can only grow: it won't change
736
+ * in any other way. So if we read 'p5s' or the 'next' field of
737
+ * some Bigint on the list, and it is not NULL, we know it won't
738
+ * change to NULL or some other value. Only when the value of
739
+ * 'p5s' or 'next' is NULL do we need to acquire the lock and add
740
+ * a new Bigint to the list.
741
+ */
742
+
743
+ static Bigint *p5s;
744
+
745
+ #ifdef JS_THREADSAFE
746
+ static PRLock *p5s_lock;
747
+ #endif
748
+
749
+ /* Return b * 5^k. Deallocate the old b. k must be nonnegative. */
750
+ /* NOTE: old b is deallocated on memory failure. */
751
+ static Bigint *pow5mult(Bigint *b, int32 k)
752
+ {
753
+ Bigint *b1, *p5, *p51;
754
+ int32 i;
755
+ static CONST int32 p05[3] = { 5, 25, 125 };
756
+
757
+ if ((i = k & 3) != 0) {
758
+ b = multadd(b, p05[i-1], 0);
759
+ if (!b)
760
+ return NULL;
761
+ }
762
+
763
+ if (!(k >>= 2))
764
+ return b;
765
+ if (!(p5 = p5s)) {
766
+ #ifdef JS_THREADSAFE
767
+ /*
768
+ * We take great care to not call i2b() and Bfree()
769
+ * while holding the lock.
770
+ */
771
+ Bigint *wasted_effort = NULL;
772
+ p5 = i2b(625);
773
+ if (!p5) {
774
+ Bfree(b);
775
+ return NULL;
776
+ }
777
+ /* lock and check again */
778
+ PR_Lock(p5s_lock);
779
+ if (!p5s) {
780
+ /* first time */
781
+ p5s = p5;
782
+ p5->next = 0;
783
+ } else {
784
+ /* some other thread just beat us */
785
+ wasted_effort = p5;
786
+ p5 = p5s;
787
+ }
788
+ PR_Unlock(p5s_lock);
789
+ if (wasted_effort) {
790
+ Bfree(wasted_effort);
791
+ }
792
+ #else
793
+ /* first time */
794
+ p5 = p5s = i2b(625);
795
+ if (!p5) {
796
+ Bfree(b);
797
+ return NULL;
798
+ }
799
+ p5->next = 0;
800
+ #endif
801
+ }
802
+ for(;;) {
803
+ if (k & 1) {
804
+ b1 = mult(b, p5);
805
+ Bfree(b);
806
+ if (!b1)
807
+ return NULL;
808
+ b = b1;
809
+ }
810
+ if (!(k >>= 1))
811
+ break;
812
+ if (!(p51 = p5->next)) {
813
+ #ifdef JS_THREADSAFE
814
+ Bigint *wasted_effort = NULL;
815
+ p51 = mult(p5, p5);
816
+ if (!p51) {
817
+ Bfree(b);
818
+ return NULL;
819
+ }
820
+ PR_Lock(p5s_lock);
821
+ if (!p5->next) {
822
+ p5->next = p51;
823
+ p51->next = 0;
824
+ } else {
825
+ wasted_effort = p51;
826
+ p51 = p5->next;
827
+ }
828
+ PR_Unlock(p5s_lock);
829
+ if (wasted_effort) {
830
+ Bfree(wasted_effort);
831
+ }
832
+ #else
833
+ p51 = mult(p5,p5);
834
+ if (!p51) {
835
+ Bfree(b);
836
+ return NULL;
837
+ }
838
+ p51->next = 0;
839
+ p5->next = p51;
840
+ #endif
841
+ }
842
+ p5 = p51;
843
+ }
844
+ return b;
845
+ }
846
+
847
+ /* Return b * 2^k. Deallocate the old b. k must be nonnegative.
848
+ * NOTE: on memory failure, old b is deallocated. */
849
+ static Bigint *lshift(Bigint *b, int32 k)
850
+ {
851
+ int32 i, k1, n, n1;
852
+ Bigint *b1;
853
+ ULong *x, *x1, *xe, z;
854
+
855
+ n = k >> 5;
856
+ k1 = b->k;
857
+ n1 = n + b->wds + 1;
858
+ for(i = b->maxwds; n1 > i; i <<= 1)
859
+ k1++;
860
+ b1 = Balloc(k1);
861
+ if (!b1)
862
+ goto done;
863
+ x1 = b1->x;
864
+ for(i = 0; i < n; i++)
865
+ *x1++ = 0;
866
+ x = b->x;
867
+ xe = x + b->wds;
868
+ if (k &= 0x1f) {
869
+ k1 = 32 - k;
870
+ z = 0;
871
+ do {
872
+ *x1++ = *x << k | z;
873
+ z = *x++ >> k1;
874
+ }
875
+ while(x < xe);
876
+ if ((*x1 = z) != 0)
877
+ ++n1;
878
+ }
879
+ else do
880
+ *x1++ = *x++;
881
+ while(x < xe);
882
+ b1->wds = n1 - 1;
883
+ done:
884
+ Bfree(b);
885
+ return b1;
886
+ }
887
+
888
+ /* Return -1, 0, or 1 depending on whether a<b, a==b, or a>b, respectively. */
889
+ static int32 cmp(Bigint *a, Bigint *b)
890
+ {
891
+ ULong *xa, *xa0, *xb, *xb0;
892
+ int32 i, j;
893
+
894
+ i = a->wds;
895
+ j = b->wds;
896
+ #ifdef DEBUG
897
+ if (i > 1 && !a->x[i-1])
898
+ Bug("cmp called with a->x[a->wds-1] == 0");
899
+ if (j > 1 && !b->x[j-1])
900
+ Bug("cmp called with b->x[b->wds-1] == 0");
901
+ #endif
902
+ if (i -= j)
903
+ return i;
904
+ xa0 = a->x;
905
+ xa = xa0 + j;
906
+ xb0 = b->x;
907
+ xb = xb0 + j;
908
+ for(;;) {
909
+ if (*--xa != *--xb)
910
+ return *xa < *xb ? -1 : 1;
911
+ if (xa <= xa0)
912
+ break;
913
+ }
914
+ return 0;
915
+ }
916
+
917
+ static Bigint *diff(Bigint *a, Bigint *b)
918
+ {
919
+ Bigint *c;
920
+ int32 i, wa, wb;
921
+ ULong *xa, *xae, *xb, *xbe, *xc;
922
+ #ifdef ULLong
923
+ ULLong borrow, y;
924
+ #else
925
+ ULong borrow, y;
926
+ ULong z;
927
+ #endif
928
+
929
+ i = cmp(a,b);
930
+ if (!i) {
931
+ c = Balloc(0);
932
+ if (!c)
933
+ return NULL;
934
+ c->wds = 1;
935
+ c->x[0] = 0;
936
+ return c;
937
+ }
938
+ if (i < 0) {
939
+ c = a;
940
+ a = b;
941
+ b = c;
942
+ i = 1;
943
+ }
944
+ else
945
+ i = 0;
946
+ c = Balloc(a->k);
947
+ if (!c)
948
+ return NULL;
949
+ c->sign = i;
950
+ wa = a->wds;
951
+ xa = a->x;
952
+ xae = xa + wa;
953
+ wb = b->wds;
954
+ xb = b->x;
955
+ xbe = xb + wb;
956
+ xc = c->x;
957
+ borrow = 0;
958
+ #ifdef ULLong
959
+ do {
960
+ y = (ULLong)*xa++ - *xb++ - borrow;
961
+ borrow = y >> 32 & 1UL;
962
+ *xc++ = (ULong)(y & 0xffffffffUL);
963
+ }
964
+ while(xb < xbe);
965
+ while(xa < xae) {
966
+ y = *xa++ - borrow;
967
+ borrow = y >> 32 & 1UL;
968
+ *xc++ = (ULong)(y & 0xffffffffUL);
969
+ }
970
+ #else
971
+ do {
972
+ y = (*xa & 0xffff) - (*xb & 0xffff) - borrow;
973
+ borrow = (y & 0x10000) >> 16;
974
+ z = (*xa++ >> 16) - (*xb++ >> 16) - borrow;
975
+ borrow = (z & 0x10000) >> 16;
976
+ Storeinc(xc, z, y);
977
+ }
978
+ while(xb < xbe);
979
+ while(xa < xae) {
980
+ y = (*xa & 0xffff) - borrow;
981
+ borrow = (y & 0x10000) >> 16;
982
+ z = (*xa++ >> 16) - borrow;
983
+ borrow = (z & 0x10000) >> 16;
984
+ Storeinc(xc, z, y);
985
+ }
986
+ #endif
987
+ while(!*--xc)
988
+ wa--;
989
+ c->wds = wa;
990
+ return c;
991
+ }
992
+
993
+ /* Return the absolute difference between x and the adjacent greater-magnitude double number (ignoring exponent overflows). */
994
+ static double ulp(double x)
995
+ {
996
+ register Long L;
997
+ double a = 0;
998
+
999
+ L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
1000
+ #ifndef Sudden_Underflow
1001
+ if (L > 0) {
1002
+ #endif
1003
+ set_word0(a, L);
1004
+ set_word1(a, 0);
1005
+ #ifndef Sudden_Underflow
1006
+ }
1007
+ else {
1008
+ L = -L >> Exp_shift;
1009
+ if (L < Exp_shift) {
1010
+ set_word0(a, 0x80000 >> L);
1011
+ set_word1(a, 0);
1012
+ }
1013
+ else {
1014
+ set_word0(a, 0);
1015
+ L -= Exp_shift;
1016
+ set_word1(a, L >= 31 ? 1 : 1 << (31 - L));
1017
+ }
1018
+ }
1019
+ #endif
1020
+ return a;
1021
+ }
1022
+
1023
+
1024
+ static double b2d(Bigint *a, int32 *e)
1025
+ {
1026
+ ULong *xa, *xa0, w, y, z;
1027
+ int32 k;
1028
+ double d = 0;
1029
+ #define d0 word0(d)
1030
+ #define d1 word1(d)
1031
+ #define set_d0(x) set_word0(d, x)
1032
+ #define set_d1(x) set_word1(d, x)
1033
+
1034
+ xa0 = a->x;
1035
+ xa = xa0 + a->wds;
1036
+ y = *--xa;
1037
+ #ifdef DEBUG
1038
+ if (!y) Bug("zero y in b2d");
1039
+ #endif
1040
+ k = hi0bits(y);
1041
+ *e = 32 - k;
1042
+ if (k < Ebits) {
1043
+ set_d0(Exp_1 | y >> (Ebits - k));
1044
+ w = xa > xa0 ? *--xa : 0;
1045
+ set_d1(y << (32-Ebits + k) | w >> (Ebits - k));
1046
+ goto ret_d;
1047
+ }
1048
+ z = xa > xa0 ? *--xa : 0;
1049
+ if (k -= Ebits) {
1050
+ set_d0(Exp_1 | y << k | z >> (32 - k));
1051
+ y = xa > xa0 ? *--xa : 0;
1052
+ set_d1(z << k | y >> (32 - k));
1053
+ }
1054
+ else {
1055
+ set_d0(Exp_1 | y);
1056
+ set_d1(z);
1057
+ }
1058
+ ret_d:
1059
+ #undef d0
1060
+ #undef d1
1061
+ #undef set_d0
1062
+ #undef set_d1
1063
+ return d;
1064
+ }
1065
+
1066
+
1067
+ /* Convert d into the form b*2^e, where b is an odd integer. b is the returned
1068
+ * Bigint and e is the returned binary exponent. Return the number of significant
1069
+ * bits in b in bits. d must be finite and nonzero. */
1070
+ static Bigint *d2b(double d, int32 *e, int32 *bits)
1071
+ {
1072
+ Bigint *b;
1073
+ int32 de, i, k;
1074
+ ULong *x, y, z;
1075
+ #define d0 word0(d)
1076
+ #define d1 word1(d)
1077
+ #define set_d0(x) set_word0(d, x)
1078
+ #define set_d1(x) set_word1(d, x)
1079
+
1080
+ b = Balloc(1);
1081
+ if (!b)
1082
+ return NULL;
1083
+ x = b->x;
1084
+
1085
+ z = d0 & Frac_mask;
1086
+ set_d0(d0 & 0x7fffffff); /* clear sign bit, which we ignore */
1087
+ #ifdef Sudden_Underflow
1088
+ de = (int32)(d0 >> Exp_shift);
1089
+ z |= Exp_msk11;
1090
+ #else
1091
+ if ((de = (int32)(d0 >> Exp_shift)) != 0)
1092
+ z |= Exp_msk1;
1093
+ #endif
1094
+ if ((y = d1) != 0) {
1095
+ if ((k = lo0bits(&y)) != 0) {
1096
+ x[0] = y | z << (32 - k);
1097
+ z >>= k;
1098
+ }
1099
+ else
1100
+ x[0] = y;
1101
+ i = b->wds = (x[1] = z) ? 2 : 1;
1102
+ }
1103
+ else {
1104
+ JS_ASSERT(z);
1105
+ k = lo0bits(&z);
1106
+ x[0] = z;
1107
+ i = b->wds = 1;
1108
+ k += 32;
1109
+ }
1110
+ #ifndef Sudden_Underflow
1111
+ if (de) {
1112
+ #endif
1113
+ *e = de - Bias - (P-1) + k;
1114
+ *bits = P - k;
1115
+ #ifndef Sudden_Underflow
1116
+ }
1117
+ else {
1118
+ *e = de - Bias - (P-1) + 1 + k;
1119
+ *bits = 32*i - hi0bits(x[i-1]);
1120
+ }
1121
+ #endif
1122
+ return b;
1123
+ }
1124
+ #undef d0
1125
+ #undef d1
1126
+ #undef set_d0
1127
+ #undef set_d1
1128
+
1129
+
1130
+ static double ratio(Bigint *a, Bigint *b)
1131
+ {
1132
+ double da, db;
1133
+ int32 k, ka, kb;
1134
+
1135
+ da = b2d(a, &ka);
1136
+ db = b2d(b, &kb);
1137
+ k = ka - kb + 32*(a->wds - b->wds);
1138
+ if (k > 0)
1139
+ set_word0(da, word0(da) + k*Exp_msk1);
1140
+ else {
1141
+ k = -k;
1142
+ set_word0(db, word0(db) + k*Exp_msk1);
1143
+ }
1144
+ return da / db;
1145
+ }
1146
+
1147
+ static CONST double
1148
+ tens[] = {
1149
+ 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
1150
+ 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
1151
+ 1e20, 1e21, 1e22
1152
+ };
1153
+
1154
+ static CONST double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
1155
+ static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128,
1156
+ #ifdef Avoid_Underflow
1157
+ 9007199254740992.e-256
1158
+ #else
1159
+ 1e-256
1160
+ #endif
1161
+ };
1162
+ /* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */
1163
+ /* flag unnecessarily. It leads to a song and dance at the end of strtod. */
1164
+ #define Scale_Bit 0x10
1165
+ #define n_bigtens 5
1166
+
1167
+
1168
+ #ifdef INFNAN_CHECK
1169
+
1170
+ #ifndef NAN_WORD0
1171
+ #define NAN_WORD0 0x7ff80000
1172
+ #endif
1173
+
1174
+ #ifndef NAN_WORD1
1175
+ #define NAN_WORD1 0
1176
+ #endif
1177
+
1178
+ static int match(CONST char **sp, char *t)
1179
+ {
1180
+ int c, d;
1181
+ CONST char *s = *sp;
1182
+
1183
+ while(d = *t++) {
1184
+ if ((c = *++s) >= 'A' && c <= 'Z')
1185
+ c += 'a' - 'A';
1186
+ if (c != d)
1187
+ return 0;
1188
+ }
1189
+ *sp = s + 1;
1190
+ return 1;
1191
+ }
1192
+ #endif /* INFNAN_CHECK */
1193
+
1194
+
1195
+ #ifdef JS_THREADSAFE
1196
+ static JSBool initialized = JS_FALSE;
1197
+
1198
+ /* hacked replica of nspr _PR_InitDtoa */
1199
+ static void InitDtoa(void)
1200
+ {
1201
+ freelist_lock = PR_NewLock();
1202
+ p5s_lock = PR_NewLock();
1203
+ initialized = JS_TRUE;
1204
+ }
1205
+ #endif
1206
+
1207
+ void js_FinishDtoa(void)
1208
+ {
1209
+ int count;
1210
+ Bigint *temp;
1211
+
1212
+ #ifdef JS_THREADSAFE
1213
+ if (initialized == JS_TRUE) {
1214
+ PR_DestroyLock(freelist_lock);
1215
+ PR_DestroyLock(p5s_lock);
1216
+ initialized = JS_FALSE;
1217
+ }
1218
+ #endif
1219
+
1220
+ /* clear down the freelist array and p5s */
1221
+
1222
+ /* static Bigint *freelist[Kmax+1]; */
1223
+ for (count = 0; count <= Kmax; count++) {
1224
+ Bigint **listp = &freelist[count];
1225
+ while ((temp = *listp) != NULL) {
1226
+ *listp = temp->next;
1227
+ free(temp);
1228
+ }
1229
+ freelist[count] = NULL;
1230
+ }
1231
+
1232
+ /* static Bigint *p5s; */
1233
+ while (p5s) {
1234
+ temp = p5s;
1235
+ p5s = p5s->next;
1236
+ free(temp);
1237
+ }
1238
+ }
1239
+
1240
+ /* nspr2 watcom bug ifdef omitted */
1241
+
1242
+ JS_FRIEND_API(double)
1243
+ JS_strtod(CONST char *s00, char **se, int *err)
1244
+ {
1245
+ int32 scale;
1246
+ int32 bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign,
1247
+ e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
1248
+ CONST char *s, *s0, *s1;
1249
+ double aadj, aadj1, adj, rv, rv0;
1250
+ Long L;
1251
+ ULong y, z;
1252
+ Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
1253
+
1254
+ *err = 0;
1255
+
1256
+ bb = bd = bs = delta = NULL;
1257
+ sign = nz0 = nz = 0;
1258
+ rv = 0.;
1259
+
1260
+ /* Locking for Balloc's shared buffers that will be used in this block */
1261
+ ACQUIRE_DTOA_LOCK();
1262
+
1263
+ for(s = s00;;s++) switch(*s) {
1264
+ case '-':
1265
+ sign = 1;
1266
+ /* no break */
1267
+ case '+':
1268
+ if (*++s)
1269
+ goto break2;
1270
+ /* no break */
1271
+ case 0:
1272
+ s = s00;
1273
+ goto ret;
1274
+ case '\t':
1275
+ case '\n':
1276
+ case '\v':
1277
+ case '\f':
1278
+ case '\r':
1279
+ case ' ':
1280
+ continue;
1281
+ default:
1282
+ goto break2;
1283
+ }
1284
+ break2:
1285
+
1286
+ if (*s == '0') {
1287
+ nz0 = 1;
1288
+ while(*++s == '0') ;
1289
+ if (!*s)
1290
+ goto ret;
1291
+ }
1292
+ s0 = s;
1293
+ y = z = 0;
1294
+ for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
1295
+ if (nd < 9)
1296
+ y = 10*y + c - '0';
1297
+ else if (nd < 16)
1298
+ z = 10*z + c - '0';
1299
+ nd0 = nd;
1300
+ if (c == '.') {
1301
+ c = *++s;
1302
+ if (!nd) {
1303
+ for(; c == '0'; c = *++s)
1304
+ nz++;
1305
+ if (c > '0' && c <= '9') {
1306
+ s0 = s;
1307
+ nf += nz;
1308
+ nz = 0;
1309
+ goto have_dig;
1310
+ }
1311
+ goto dig_done;
1312
+ }
1313
+ for(; c >= '0' && c <= '9'; c = *++s) {
1314
+ have_dig:
1315
+ nz++;
1316
+ if (c -= '0') {
1317
+ nf += nz;
1318
+ for(i = 1; i < nz; i++)
1319
+ if (nd++ < 9)
1320
+ y *= 10;
1321
+ else if (nd <= DBL_DIG + 1)
1322
+ z *= 10;
1323
+ if (nd++ < 9)
1324
+ y = 10*y + c;
1325
+ else if (nd <= DBL_DIG + 1)
1326
+ z = 10*z + c;
1327
+ nz = 0;
1328
+ }
1329
+ }
1330
+ }
1331
+ dig_done:
1332
+ e = 0;
1333
+ if (c == 'e' || c == 'E') {
1334
+ if (!nd && !nz && !nz0) {
1335
+ s = s00;
1336
+ goto ret;
1337
+ }
1338
+ s00 = s;
1339
+ esign = 0;
1340
+ switch(c = *++s) {
1341
+ case '-':
1342
+ esign = 1;
1343
+ case '+':
1344
+ c = *++s;
1345
+ }
1346
+ if (c >= '0' && c <= '9') {
1347
+ while(c == '0')
1348
+ c = *++s;
1349
+ if (c > '0' && c <= '9') {
1350
+ L = c - '0';
1351
+ s1 = s;
1352
+ while((c = *++s) >= '0' && c <= '9')
1353
+ L = 10*L + c - '0';
1354
+ if (s - s1 > 8 || L > 19999)
1355
+ /* Avoid confusion from exponents
1356
+ * so large that e might overflow.
1357
+ */
1358
+ e = 19999; /* safe for 16 bit ints */
1359
+ else
1360
+ e = (int32)L;
1361
+ if (esign)
1362
+ e = -e;
1363
+ }
1364
+ else
1365
+ e = 0;
1366
+ }
1367
+ else
1368
+ s = s00;
1369
+ }
1370
+ if (!nd) {
1371
+ if (!nz && !nz0) {
1372
+ #ifdef INFNAN_CHECK
1373
+ /* Check for Nan and Infinity */
1374
+ switch(c) {
1375
+ case 'i':
1376
+ case 'I':
1377
+ if (match(&s,"nfinity")) {
1378
+ set_word0(rv, 0x7ff00000);
1379
+ set_word1(rv, 0);
1380
+ goto ret;
1381
+ }
1382
+ break;
1383
+ case 'n':
1384
+ case 'N':
1385
+ if (match(&s, "an")) {
1386
+ set_word0(rv, NAN_WORD0);
1387
+ set_word1(rv, NAN_WORD1);
1388
+ goto ret;
1389
+ }
1390
+ }
1391
+ #endif /* INFNAN_CHECK */
1392
+ s = s00;
1393
+ }
1394
+ goto ret;
1395
+ }
1396
+ e1 = e -= nf;
1397
+
1398
+ /* Now we have nd0 digits, starting at s0, followed by a
1399
+ * decimal point, followed by nd-nd0 digits. The number we're
1400
+ * after is the integer represented by those digits times
1401
+ * 10**e */
1402
+
1403
+ if (!nd0)
1404
+ nd0 = nd;
1405
+ k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
1406
+ rv = y;
1407
+ if (k > 9)
1408
+ rv = tens[k - 9] * rv + z;
1409
+ bd0 = 0;
1410
+ if (nd <= DBL_DIG
1411
+ #ifndef RND_PRODQUOT
1412
+ && FLT_ROUNDS == 1
1413
+ #endif
1414
+ ) {
1415
+ if (!e)
1416
+ goto ret;
1417
+ if (e > 0) {
1418
+ if (e <= Ten_pmax) {
1419
+ /* rv = */ rounded_product(rv, tens[e]);
1420
+ goto ret;
1421
+ }
1422
+ i = DBL_DIG - nd;
1423
+ if (e <= Ten_pmax + i) {
1424
+ /* A fancier test would sometimes let us do
1425
+ * this for larger i values.
1426
+ */
1427
+ e -= i;
1428
+ rv *= tens[i];
1429
+ /* rv = */ rounded_product(rv, tens[e]);
1430
+ goto ret;
1431
+ }
1432
+ }
1433
+ #ifndef Inaccurate_Divide
1434
+ else if (e >= -Ten_pmax) {
1435
+ /* rv = */ rounded_quotient(rv, tens[-e]);
1436
+ goto ret;
1437
+ }
1438
+ #endif
1439
+ }
1440
+ e1 += nd - k;
1441
+
1442
+ scale = 0;
1443
+
1444
+ /* Get starting approximation = rv * 10**e1 */
1445
+
1446
+ if (e1 > 0) {
1447
+ if ((i = e1 & 15) != 0)
1448
+ rv *= tens[i];
1449
+ if (e1 &= ~15) {
1450
+ if (e1 > DBL_MAX_10_EXP) {
1451
+ ovfl:
1452
+ *err = JS_DTOA_ERANGE;
1453
+ #ifdef __STDC__
1454
+ rv = HUGE_VAL;
1455
+ #else
1456
+ /* Can't trust HUGE_VAL */
1457
+ set_word0(rv, Exp_mask);
1458
+ set_word1(rv, 0);
1459
+ #endif
1460
+ if (bd0)
1461
+ goto retfree;
1462
+ goto ret;
1463
+ }
1464
+ e1 >>= 4;
1465
+ for(j = 0; e1 > 1; j++, e1 >>= 1)
1466
+ if (e1 & 1)
1467
+ rv *= bigtens[j];
1468
+ /* The last multiplication could overflow. */
1469
+ set_word0(rv, word0(rv) - P*Exp_msk1);
1470
+ rv *= bigtens[j];
1471
+ if ((z = word0(rv) & Exp_mask) > Exp_msk1*(DBL_MAX_EXP+Bias-P))
1472
+ goto ovfl;
1473
+ if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) {
1474
+ /* set to largest number */
1475
+ /* (Can't trust DBL_MAX) */
1476
+ set_word0(rv, Big0);
1477
+ set_word1(rv, Big1);
1478
+ }
1479
+ else
1480
+ set_word0(rv, word0(rv) + P*Exp_msk1);
1481
+ }
1482
+ }
1483
+ else if (e1 < 0) {
1484
+ e1 = -e1;
1485
+ if ((i = e1 & 15) != 0)
1486
+ rv /= tens[i];
1487
+ if (e1 &= ~15) {
1488
+ e1 >>= 4;
1489
+ if (e1 >= 1 << n_bigtens)
1490
+ goto undfl;
1491
+ #ifdef Avoid_Underflow
1492
+ if (e1 & Scale_Bit)
1493
+ scale = P;
1494
+ for(j = 0; e1 > 0; j++, e1 >>= 1)
1495
+ if (e1 & 1)
1496
+ rv *= tinytens[j];
1497
+ if (scale && (j = P + 1 - ((word0(rv) & Exp_mask)
1498
+ >> Exp_shift)) > 0) {
1499
+ /* scaled rv is denormal; zap j low bits */
1500
+ if (j >= 32) {
1501
+ set_word1(rv, 0);
1502
+ set_word0(rv, word0(rv) & (0xffffffff << (j-32)));
1503
+ if (!word0(rv))
1504
+ set_word0(rv, 1);
1505
+ }
1506
+ else
1507
+ set_word1(rv, word1(rv) & (0xffffffff << j));
1508
+ }
1509
+ #else
1510
+ for(j = 0; e1 > 1; j++, e1 >>= 1)
1511
+ if (e1 & 1)
1512
+ rv *= tinytens[j];
1513
+ /* The last multiplication could underflow. */
1514
+ rv0 = rv;
1515
+ rv *= tinytens[j];
1516
+ if (!rv) {
1517
+ rv = 2.*rv0;
1518
+ rv *= tinytens[j];
1519
+ #endif
1520
+ if (!rv) {
1521
+ undfl:
1522
+ rv = 0.;
1523
+ *err = JS_DTOA_ERANGE;
1524
+ if (bd0)
1525
+ goto retfree;
1526
+ goto ret;
1527
+ }
1528
+ #ifndef Avoid_Underflow
1529
+ set_word0(rv, Tiny0);
1530
+ set_word1(rv, Tiny1);
1531
+ /* The refinement below will clean
1532
+ * this approximation up.
1533
+ */
1534
+ }
1535
+ #endif
1536
+ }
1537
+ }
1538
+
1539
+ /* Now the hard part -- adjusting rv to the correct value.*/
1540
+
1541
+ /* Put digits into bd: true value = bd * 10^e */
1542
+
1543
+ bd0 = s2b(s0, nd0, nd, y);
1544
+ if (!bd0)
1545
+ goto nomem;
1546
+
1547
+ for(;;) {
1548
+ bd = Balloc(bd0->k);
1549
+ if (!bd)
1550
+ goto nomem;
1551
+ Bcopy(bd, bd0);
1552
+ bb = d2b(rv, &bbe, &bbbits); /* rv = bb * 2^bbe */
1553
+ if (!bb)
1554
+ goto nomem;
1555
+ bs = i2b(1);
1556
+ if (!bs)
1557
+ goto nomem;
1558
+
1559
+ if (e >= 0) {
1560
+ bb2 = bb5 = 0;
1561
+ bd2 = bd5 = e;
1562
+ }
1563
+ else {
1564
+ bb2 = bb5 = -e;
1565
+ bd2 = bd5 = 0;
1566
+ }
1567
+ if (bbe >= 0)
1568
+ bb2 += bbe;
1569
+ else
1570
+ bd2 -= bbe;
1571
+ bs2 = bb2;
1572
+ #ifdef Sudden_Underflow
1573
+ j = P + 1 - bbbits;
1574
+ #else
1575
+ #ifdef Avoid_Underflow
1576
+ j = bbe - scale;
1577
+ #else
1578
+ j = bbe;
1579
+ #endif
1580
+ i = j + bbbits - 1; /* logb(rv) */
1581
+ if (i < Emin) /* denormal */
1582
+ j += P - Emin;
1583
+ else
1584
+ j = P + 1 - bbbits;
1585
+ #endif
1586
+ bb2 += j;
1587
+ bd2 += j;
1588
+ #ifdef Avoid_Underflow
1589
+ bd2 += scale;
1590
+ #endif
1591
+ i = bb2 < bd2 ? bb2 : bd2;
1592
+ if (i > bs2)
1593
+ i = bs2;
1594
+ if (i > 0) {
1595
+ bb2 -= i;
1596
+ bd2 -= i;
1597
+ bs2 -= i;
1598
+ }
1599
+ if (bb5 > 0) {
1600
+ bs = pow5mult(bs, bb5);
1601
+ if (!bs)
1602
+ goto nomem;
1603
+ bb1 = mult(bs, bb);
1604
+ if (!bb1)
1605
+ goto nomem;
1606
+ Bfree(bb);
1607
+ bb = bb1;
1608
+ }
1609
+ if (bb2 > 0) {
1610
+ bb = lshift(bb, bb2);
1611
+ if (!bb)
1612
+ goto nomem;
1613
+ }
1614
+ if (bd5 > 0) {
1615
+ bd = pow5mult(bd, bd5);
1616
+ if (!bd)
1617
+ goto nomem;
1618
+ }
1619
+ if (bd2 > 0) {
1620
+ bd = lshift(bd, bd2);
1621
+ if (!bd)
1622
+ goto nomem;
1623
+ }
1624
+ if (bs2 > 0) {
1625
+ bs = lshift(bs, bs2);
1626
+ if (!bs)
1627
+ goto nomem;
1628
+ }
1629
+ delta = diff(bb, bd);
1630
+ if (!delta)
1631
+ goto nomem;
1632
+ dsign = delta->sign;
1633
+ delta->sign = 0;
1634
+ i = cmp(delta, bs);
1635
+ if (i < 0) {
1636
+ /* Error is less than half an ulp -- check for
1637
+ * special case of mantissa a power of two.
1638
+ */
1639
+ if (dsign || word1(rv) || word0(rv) & Bndry_mask
1640
+ #ifdef Avoid_Underflow
1641
+ || (word0(rv) & Exp_mask) <= Exp_msk1 + P*Exp_msk1
1642
+ #else
1643
+ || (word0(rv) & Exp_mask) <= Exp_msk1
1644
+ #endif
1645
+ ) {
1646
+ #ifdef Avoid_Underflow
1647
+ if (!delta->x[0] && delta->wds == 1)
1648
+ dsign = 2;
1649
+ #endif
1650
+ break;
1651
+ }
1652
+ delta = lshift(delta,Log2P);
1653
+ if (!delta)
1654
+ goto nomem;
1655
+ if (cmp(delta, bs) > 0)
1656
+ goto drop_down;
1657
+ break;
1658
+ }
1659
+ if (i == 0) {
1660
+ /* exactly half-way between */
1661
+ if (dsign) {
1662
+ if ((word0(rv) & Bndry_mask1) == Bndry_mask1
1663
+ && word1(rv) == 0xffffffff) {
1664
+ /*boundary case -- increment exponent*/
1665
+ set_word0(rv, (word0(rv) & Exp_mask) + Exp_msk1);
1666
+ set_word1(rv, 0);
1667
+ #ifdef Avoid_Underflow
1668
+ dsign = 0;
1669
+ #endif
1670
+ break;
1671
+ }
1672
+ }
1673
+ else if (!(word0(rv) & Bndry_mask) && !word1(rv)) {
1674
+ #ifdef Avoid_Underflow
1675
+ dsign = 2;
1676
+ #endif
1677
+ drop_down:
1678
+ /* boundary case -- decrement exponent */
1679
+ #ifdef Sudden_Underflow
1680
+ L = word0(rv) & Exp_mask;
1681
+ if (L <= Exp_msk1)
1682
+ goto undfl;
1683
+ L -= Exp_msk1;
1684
+ #else
1685
+ L = (word0(rv) & Exp_mask) - Exp_msk1;
1686
+ #endif
1687
+ set_word0(rv, L | Bndry_mask1);
1688
+ set_word1(rv, 0xffffffff);
1689
+ break;
1690
+ }
1691
+ #ifndef ROUND_BIASED
1692
+ if (!(word1(rv) & LSB))
1693
+ break;
1694
+ #endif
1695
+ if (dsign)
1696
+ rv += ulp(rv);
1697
+ #ifndef ROUND_BIASED
1698
+ else {
1699
+ rv -= ulp(rv);
1700
+ #ifndef Sudden_Underflow
1701
+ if (!rv)
1702
+ goto undfl;
1703
+ #endif
1704
+ }
1705
+ #ifdef Avoid_Underflow
1706
+ dsign = 1 - dsign;
1707
+ #endif
1708
+ #endif
1709
+ break;
1710
+ }
1711
+ if ((aadj = ratio(delta, bs)) <= 2.) {
1712
+ if (dsign)
1713
+ aadj = aadj1 = 1.;
1714
+ else if (word1(rv) || word0(rv) & Bndry_mask) {
1715
+ #ifndef Sudden_Underflow
1716
+ if (word1(rv) == Tiny1 && !word0(rv))
1717
+ goto undfl;
1718
+ #endif
1719
+ aadj = 1.;
1720
+ aadj1 = -1.;
1721
+ }
1722
+ else {
1723
+ /* special case -- power of FLT_RADIX to be */
1724
+ /* rounded down... */
1725
+
1726
+ if (aadj < 2./FLT_RADIX)
1727
+ aadj = 1./FLT_RADIX;
1728
+ else
1729
+ aadj *= 0.5;
1730
+ aadj1 = -aadj;
1731
+ }
1732
+ }
1733
+ else {
1734
+ aadj *= 0.5;
1735
+ aadj1 = dsign ? aadj : -aadj;
1736
+ #ifdef Check_FLT_ROUNDS
1737
+ switch(FLT_ROUNDS) {
1738
+ case 2: /* towards +infinity */
1739
+ aadj1 -= 0.5;
1740
+ break;
1741
+ case 0: /* towards 0 */
1742
+ case 3: /* towards -infinity */
1743
+ aadj1 += 0.5;
1744
+ }
1745
+ #else
1746
+ if (FLT_ROUNDS == 0)
1747
+ aadj1 += 0.5;
1748
+ #endif
1749
+ }
1750
+ y = word0(rv) & Exp_mask;
1751
+
1752
+ /* Check for overflow */
1753
+
1754
+ if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
1755
+ rv0 = rv;
1756
+ set_word0(rv, word0(rv) - P*Exp_msk1);
1757
+ adj = aadj1 * ulp(rv);
1758
+ rv += adj;
1759
+ if ((word0(rv) & Exp_mask) >=
1760
+ Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
1761
+ if (word0(rv0) == Big0 && word1(rv0) == Big1)
1762
+ goto ovfl;
1763
+ set_word0(rv, Big0);
1764
+ set_word1(rv, Big1);
1765
+ goto cont;
1766
+ }
1767
+ else
1768
+ set_word0(rv, word0(rv) + P*Exp_msk1);
1769
+ }
1770
+ else {
1771
+ #ifdef Sudden_Underflow
1772
+ if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
1773
+ rv0 = rv;
1774
+ set_word0(rv, word0(rv) + P*Exp_msk1);
1775
+ adj = aadj1 * ulp(rv);
1776
+ rv += adj;
1777
+ if ((word0(rv) & Exp_mask) <= P*Exp_msk1)
1778
+ {
1779
+ if (word0(rv0) == Tiny0
1780
+ && word1(rv0) == Tiny1)
1781
+ goto undfl;
1782
+ set_word0(rv, Tiny0);
1783
+ set_word1(rv, Tiny1);
1784
+ goto cont;
1785
+ }
1786
+ else
1787
+ set_word0(rv, word0(rv) - P*Exp_msk1);
1788
+ }
1789
+ else {
1790
+ adj = aadj1 * ulp(rv);
1791
+ rv += adj;
1792
+ }
1793
+ #else
1794
+ /* Compute adj so that the IEEE rounding rules will
1795
+ * correctly round rv + adj in some half-way cases.
1796
+ * If rv * ulp(rv) is denormalized (i.e.,
1797
+ * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
1798
+ * trouble from bits lost to denormalization;
1799
+ * example: 1.2e-307 .
1800
+ */
1801
+ #ifdef Avoid_Underflow
1802
+ if (y <= P*Exp_msk1 && aadj > 1.)
1803
+ #else
1804
+ if (y <= (P-1)*Exp_msk1 && aadj > 1.)
1805
+ #endif
1806
+ {
1807
+ aadj1 = (double)(int32)(aadj + 0.5);
1808
+ if (!dsign)
1809
+ aadj1 = -aadj1;
1810
+ }
1811
+ #ifdef Avoid_Underflow
1812
+ if (scale && y <= P*Exp_msk1)
1813
+ set_word0(aadj1, word0(aadj1) + (P+1)*Exp_msk1 - y);
1814
+ #endif
1815
+ adj = aadj1 * ulp(rv);
1816
+ rv += adj;
1817
+ #endif
1818
+ }
1819
+ z = word0(rv) & Exp_mask;
1820
+ #ifdef Avoid_Underflow
1821
+ if (!scale)
1822
+ #endif
1823
+ if (y == z) {
1824
+ /* Can we stop now? */
1825
+ L = (Long)aadj;
1826
+ aadj -= L;
1827
+ /* The tolerances below are conservative. */
1828
+ if (dsign || word1(rv) || word0(rv) & Bndry_mask) {
1829
+ if (aadj < .4999999 || aadj > .5000001)
1830
+ break;
1831
+ }
1832
+ else if (aadj < .4999999/FLT_RADIX)
1833
+ break;
1834
+ }
1835
+ cont:
1836
+ Bfree(bb);
1837
+ Bfree(bd);
1838
+ Bfree(bs);
1839
+ Bfree(delta);
1840
+ bb = bd = bs = delta = NULL;
1841
+ }
1842
+ #ifdef Avoid_Underflow
1843
+ if (scale) {
1844
+ rv0 = 0.;
1845
+ set_word0(rv0, Exp_1 - P*Exp_msk1);
1846
+ set_word1(rv0, 0);
1847
+ if ((word0(rv) & Exp_mask) <= P*Exp_msk1
1848
+ && word1(rv) & 1
1849
+ && dsign != 2) {
1850
+ if (dsign) {
1851
+ #ifdef Sudden_Underflow
1852
+ /* rv will be 0, but this would give the */
1853
+ /* right result if only rv *= rv0 worked. */
1854
+ set_word0(rv, word0(rv) + P*Exp_msk1);
1855
+ set_word0(rv0, Exp_1 - 2*P*Exp_msk1);
1856
+ #endif
1857
+ rv += ulp(rv);
1858
+ }
1859
+ else
1860
+ set_word1(rv, word1(rv) & ~1);
1861
+ }
1862
+ rv *= rv0;
1863
+ }
1864
+ #endif /* Avoid_Underflow */
1865
+ retfree:
1866
+ Bfree(bb);
1867
+ Bfree(bd);
1868
+ Bfree(bs);
1869
+ Bfree(bd0);
1870
+ Bfree(delta);
1871
+ ret:
1872
+ RELEASE_DTOA_LOCK();
1873
+ if (se)
1874
+ *se = (char *)s;
1875
+ return sign ? -rv : rv;
1876
+
1877
+ nomem:
1878
+ Bfree(bb);
1879
+ Bfree(bd);
1880
+ Bfree(bs);
1881
+ Bfree(bd0);
1882
+ Bfree(delta);
1883
+ RELEASE_DTOA_LOCK();
1884
+ *err = JS_DTOA_ENOMEM;
1885
+ return 0;
1886
+ }
1887
+
1888
+
1889
+ /* Return floor(b/2^k) and set b to be the remainder. The returned quotient must be less than 2^32. */
1890
+ static uint32 quorem2(Bigint *b, int32 k)
1891
+ {
1892
+ ULong mask;
1893
+ ULong result;
1894
+ ULong *bx, *bxe;
1895
+ int32 w;
1896
+ int32 n = k >> 5;
1897
+ k &= 0x1F;
1898
+ mask = (1<<k) - 1;
1899
+
1900
+ w = b->wds - n;
1901
+ if (w <= 0)
1902
+ return 0;
1903
+ JS_ASSERT(w <= 2);
1904
+ bx = b->x;
1905
+ bxe = bx + n;
1906
+ result = *bxe >> k;
1907
+ *bxe &= mask;
1908
+ if (w == 2) {
1909
+ JS_ASSERT(!(bxe[1] & ~mask));
1910
+ if (k)
1911
+ result |= bxe[1] << (32 - k);
1912
+ }
1913
+ n++;
1914
+ while (!*bxe && bxe != bx) {
1915
+ n--;
1916
+ bxe--;
1917
+ }
1918
+ b->wds = n;
1919
+ return result;
1920
+ }
1921
+
1922
+ /* Return floor(b/S) and set b to be the remainder. As added restrictions, b must not have
1923
+ * more words than S, the most significant word of S must not start with a 1 bit, and the
1924
+ * returned quotient must be less than 36. */
1925
+ static int32 quorem(Bigint *b, Bigint *S)
1926
+ {
1927
+ int32 n;
1928
+ ULong *bx, *bxe, q, *sx, *sxe;
1929
+ #ifdef ULLong
1930
+ ULLong borrow, carry, y, ys;
1931
+ #else
1932
+ ULong borrow, carry, y, ys;
1933
+ ULong si, z, zs;
1934
+ #endif
1935
+
1936
+ n = S->wds;
1937
+ JS_ASSERT(b->wds <= n);
1938
+ if (b->wds < n)
1939
+ return 0;
1940
+ sx = S->x;
1941
+ sxe = sx + --n;
1942
+ bx = b->x;
1943
+ bxe = bx + n;
1944
+ JS_ASSERT(*sxe <= 0x7FFFFFFF);
1945
+ q = *bxe / (*sxe + 1); /* ensure q <= true quotient */
1946
+ JS_ASSERT(q < 36);
1947
+ if (q) {
1948
+ borrow = 0;
1949
+ carry = 0;
1950
+ do {
1951
+ #ifdef ULLong
1952
+ ys = *sx++ * (ULLong)q + carry;
1953
+ carry = ys >> 32;
1954
+ y = *bx - (ys & 0xffffffffUL) - borrow;
1955
+ borrow = y >> 32 & 1UL;
1956
+ *bx++ = (ULong)(y & 0xffffffffUL);
1957
+ #else
1958
+ si = *sx++;
1959
+ ys = (si & 0xffff) * q + carry;
1960
+ zs = (si >> 16) * q + (ys >> 16);
1961
+ carry = zs >> 16;
1962
+ y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
1963
+ borrow = (y & 0x10000) >> 16;
1964
+ z = (*bx >> 16) - (zs & 0xffff) - borrow;
1965
+ borrow = (z & 0x10000) >> 16;
1966
+ Storeinc(bx, z, y);
1967
+ #endif
1968
+ }
1969
+ while(sx <= sxe);
1970
+ if (!*bxe) {
1971
+ bx = b->x;
1972
+ while(--bxe > bx && !*bxe)
1973
+ --n;
1974
+ b->wds = n;
1975
+ }
1976
+ }
1977
+ if (cmp(b, S) >= 0) {
1978
+ q++;
1979
+ borrow = 0;
1980
+ carry = 0;
1981
+ bx = b->x;
1982
+ sx = S->x;
1983
+ do {
1984
+ #ifdef ULLong
1985
+ ys = *sx++ + carry;
1986
+ carry = ys >> 32;
1987
+ y = *bx - (ys & 0xffffffffUL) - borrow;
1988
+ borrow = y >> 32 & 1UL;
1989
+ *bx++ = (ULong)(y & 0xffffffffUL);
1990
+ #else
1991
+ si = *sx++;
1992
+ ys = (si & 0xffff) + carry;
1993
+ zs = (si >> 16) + (ys >> 16);
1994
+ carry = zs >> 16;
1995
+ y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
1996
+ borrow = (y & 0x10000) >> 16;
1997
+ z = (*bx >> 16) - (zs & 0xffff) - borrow;
1998
+ borrow = (z & 0x10000) >> 16;
1999
+ Storeinc(bx, z, y);
2000
+ #endif
2001
+ } while(sx <= sxe);
2002
+ bx = b->x;
2003
+ bxe = bx + n;
2004
+ if (!*bxe) {
2005
+ while(--bxe > bx && !*bxe)
2006
+ --n;
2007
+ b->wds = n;
2008
+ }
2009
+ }
2010
+ return (int32)q;
2011
+ }
2012
+
2013
+ /* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
2014
+ *
2015
+ * Inspired by "How to Print Floating-Point Numbers Accurately" by
2016
+ * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101].
2017
+ *
2018
+ * Modifications:
2019
+ * 1. Rather than iterating, we use a simple numeric overestimate
2020
+ * to determine k = floor(log10(d)). We scale relevant
2021
+ * quantities using O(log2(k)) rather than O(k) multiplications.
2022
+ * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
2023
+ * try to generate digits strictly left to right. Instead, we
2024
+ * compute with fewer bits and propagate the carry if necessary
2025
+ * when rounding the final digit up. This is often faster.
2026
+ * 3. Under the assumption that input will be rounded nearest,
2027
+ * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
2028
+ * That is, we allow equality in stopping tests when the
2029
+ * round-nearest rule will give the same floating-point value
2030
+ * as would satisfaction of the stopping test with strict
2031
+ * inequality.
2032
+ * 4. We remove common factors of powers of 2 from relevant
2033
+ * quantities.
2034
+ * 5. When converting floating-point integers less than 1e16,
2035
+ * we use floating-point arithmetic rather than resorting
2036
+ * to multiple-precision integers.
2037
+ * 6. When asked to produce fewer than 15 digits, we first try
2038
+ * to get by with floating-point arithmetic; we resort to
2039
+ * multiple-precision integer arithmetic only if we cannot
2040
+ * guarantee that the floating-point calculation has given
2041
+ * the correctly rounded result. For k requested digits and
2042
+ * "uniformly" distributed input, the probability is
2043
+ * something like 10^(k-15) that we must resort to the Long
2044
+ * calculation.
2045
+ */
2046
+
2047
+ /* Always emits at least one digit. */
2048
+ /* If biasUp is set, then rounding in modes 2 and 3 will round away from zero
2049
+ * when the number is exactly halfway between two representable values. For example,
2050
+ * rounding 2.5 to zero digits after the decimal point will return 3 and not 2.
2051
+ * 2.49 will still round to 2, and 2.51 will still round to 3. */
2052
+ /* bufsize should be at least 20 for modes 0 and 1. For the other modes,
2053
+ * bufsize should be two greater than the maximum number of output characters expected. */
2054
+ static JSBool
2055
+ js_dtoa(double d, int mode, JSBool biasUp, int ndigits,
2056
+ int *decpt, int *sign, char **rve, char *buf, size_t bufsize)
2057
+ {
2058
+ /* Arguments ndigits, decpt, sign are similar to those
2059
+ of ecvt and fcvt; trailing zeros are suppressed from
2060
+ the returned string. If not null, *rve is set to point
2061
+ to the end of the return value. If d is +-Infinity or NaN,
2062
+ then *decpt is set to 9999.
2063
+
2064
+ mode:
2065
+ 0 ==> shortest string that yields d when read in
2066
+ and rounded to nearest.
2067
+ 1 ==> like 0, but with Steele & White stopping rule;
2068
+ e.g. with IEEE P754 arithmetic , mode 0 gives
2069
+ 1e23 whereas mode 1 gives 9.999999999999999e22.
2070
+ 2 ==> max(1,ndigits) significant digits. This gives a
2071
+ return value similar to that of ecvt, except
2072
+ that trailing zeros are suppressed.
2073
+ 3 ==> through ndigits past the decimal point. This
2074
+ gives a return value similar to that from fcvt,
2075
+ except that trailing zeros are suppressed, and
2076
+ ndigits can be negative.
2077
+ 4-9 should give the same return values as 2-3, i.e.,
2078
+ 4 <= mode <= 9 ==> same return as mode
2079
+ 2 + (mode & 1). These modes are mainly for
2080
+ debugging; often they run slower but sometimes
2081
+ faster than modes 2-3.
2082
+ 4,5,8,9 ==> left-to-right digit generation.
2083
+ 6-9 ==> don't try fast floating-point estimate
2084
+ (if applicable).
2085
+
2086
+ Values of mode other than 0-9 are treated as mode 0.
2087
+
2088
+ Sufficient space is allocated to the return value
2089
+ to hold the suppressed trailing zeros.
2090
+ */
2091
+
2092
+ int32 bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1,
2093
+ j, j1, k, k0, k_check, leftright, m2, m5, s2, s5,
2094
+ spec_case, try_quick;
2095
+ Long L;
2096
+ #ifndef Sudden_Underflow
2097
+ int32 denorm;
2098
+ ULong x;
2099
+ #endif
2100
+ Bigint *b, *b1, *delta, *mlo, *mhi, *S;
2101
+ double d2, ds, eps;
2102
+ char *s;
2103
+ const char *cs;
2104
+
2105
+ if (word0(d) & Sign_bit) {
2106
+ /* set sign for everything, including 0's and NaNs */
2107
+ *sign = 1;
2108
+ set_word0(d, word0(d) & ~Sign_bit); /* clear sign bit */
2109
+ }
2110
+ else
2111
+ *sign = 0;
2112
+
2113
+ if ((word0(d) & Exp_mask) == Exp_mask) {
2114
+ /* Infinity or NaN */
2115
+ *decpt = 9999;
2116
+ cs = !word1(d) && !(word0(d) & Frac_mask) ? "Infinity" : "NaN";
2117
+ if ((cs[0] == 'I' && bufsize < 9) || (cs[0] == 'N' && bufsize < 4)) {
2118
+ JS_ASSERT(JS_FALSE);
2119
+ /* JS_SetError(JS_BUFFER_OVERFLOW_ERROR, 0); */
2120
+ return JS_FALSE;
2121
+ }
2122
+ strcpy(buf, cs);
2123
+ if (rve) {
2124
+ *rve = buf[3] ? buf + 8 : buf + 3;
2125
+ JS_ASSERT(**rve == '\0');
2126
+ }
2127
+ return JS_TRUE;
2128
+ }
2129
+
2130
+ b = NULL; /* initialize for abort protection */
2131
+ S = NULL;
2132
+ mlo = mhi = NULL;
2133
+
2134
+ if (!d) {
2135
+ no_digits:
2136
+ *decpt = 1;
2137
+ if (bufsize < 2) {
2138
+ JS_ASSERT(JS_FALSE);
2139
+ /* JS_SetError(JS_BUFFER_OVERFLOW_ERROR, 0); */
2140
+ return JS_FALSE;
2141
+ }
2142
+ buf[0] = '0'; buf[1] = '\0'; /* copy "0" to buffer */
2143
+ if (rve)
2144
+ *rve = buf + 1;
2145
+ /* We might have jumped to "no_digits" from below, so we need
2146
+ * to be sure to free the potentially allocated Bigints to avoid
2147
+ * memory leaks. */
2148
+ Bfree(b);
2149
+ Bfree(S);
2150
+ if (mlo != mhi)
2151
+ Bfree(mlo);
2152
+ Bfree(mhi);
2153
+ return JS_TRUE;
2154
+ }
2155
+
2156
+ b = d2b(d, &be, &bbits);
2157
+ if (!b)
2158
+ goto nomem;
2159
+ #ifdef Sudden_Underflow
2160
+ i = (int32)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
2161
+ #else
2162
+ if ((i = (int32)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) != 0) {
2163
+ #endif
2164
+ d2 = d;
2165
+ set_word0(d2, word0(d2) & Frac_mask1);
2166
+ set_word0(d2, word0(d2) | Exp_11);
2167
+
2168
+ /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
2169
+ * log10(x) = log(x) / log(10)
2170
+ * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
2171
+ * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
2172
+ *
2173
+ * This suggests computing an approximation k to log10(d) by
2174
+ *
2175
+ * k = (i - Bias)*0.301029995663981
2176
+ * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
2177
+ *
2178
+ * We want k to be too large rather than too small.
2179
+ * The error in the first-order Taylor series approximation
2180
+ * is in our favor, so we just round up the constant enough
2181
+ * to compensate for any error in the multiplication of
2182
+ * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
2183
+ * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
2184
+ * adding 1e-13 to the constant term more than suffices.
2185
+ * Hence we adjust the constant term to 0.1760912590558.
2186
+ * (We could get a more accurate k by invoking log10,
2187
+ * but this is probably not worthwhile.)
2188
+ */
2189
+
2190
+ i -= Bias;
2191
+ #ifndef Sudden_Underflow
2192
+ denorm = 0;
2193
+ }
2194
+ else {
2195
+ /* d is denormalized */
2196
+
2197
+ i = bbits + be + (Bias + (P-1) - 1);
2198
+ x = i > 32 ? word0(d) << (64 - i) | word1(d) >> (i - 32) : word1(d) << (32 - i);
2199
+ d2 = x;
2200
+ set_word0(d2, word0(d2) - 31*Exp_msk1); /* adjust exponent */
2201
+ i -= (Bias + (P-1) - 1) + 1;
2202
+ denorm = 1;
2203
+ }
2204
+ #endif
2205
+ /* At this point d = f*2^i, where 1 <= f < 2. d2 is an approximation of f. */
2206
+ ds = (d2-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
2207
+ k = (int32)ds;
2208
+ if (ds < 0. && ds != k)
2209
+ k--; /* want k = floor(ds) */
2210
+ k_check = 1;
2211
+ if (k >= 0 && k <= Ten_pmax) {
2212
+ if (d < tens[k])
2213
+ k--;
2214
+ k_check = 0;
2215
+ }
2216
+ /* At this point floor(log10(d)) <= k <= floor(log10(d))+1.
2217
+ If k_check is zero, we're guaranteed that k = floor(log10(d)). */
2218
+ j = bbits - i - 1;
2219
+ /* At this point d = b/2^j, where b is an odd integer. */
2220
+ if (j >= 0) {
2221
+ b2 = 0;
2222
+ s2 = j;
2223
+ }
2224
+ else {
2225
+ b2 = -j;
2226
+ s2 = 0;
2227
+ }
2228
+ if (k >= 0) {
2229
+ b5 = 0;
2230
+ s5 = k;
2231
+ s2 += k;
2232
+ }
2233
+ else {
2234
+ b2 -= k;
2235
+ b5 = -k;
2236
+ s5 = 0;
2237
+ }
2238
+ /* At this point d/10^k = (b * 2^b2 * 5^b5) / (2^s2 * 5^s5), where b is an odd integer,
2239
+ b2 >= 0, b5 >= 0, s2 >= 0, and s5 >= 0. */
2240
+ if (mode < 0 || mode > 9)
2241
+ mode = 0;
2242
+ try_quick = 1;
2243
+ if (mode > 5) {
2244
+ mode -= 4;
2245
+ try_quick = 0;
2246
+ }
2247
+ leftright = 1;
2248
+ ilim = ilim1 = 0;
2249
+ switch(mode) {
2250
+ case 0:
2251
+ case 1:
2252
+ ilim = ilim1 = -1;
2253
+ i = 18;
2254
+ ndigits = 0;
2255
+ break;
2256
+ case 2:
2257
+ leftright = 0;
2258
+ /* no break */
2259
+ case 4:
2260
+ if (ndigits <= 0)
2261
+ ndigits = 1;
2262
+ ilim = ilim1 = i = ndigits;
2263
+ break;
2264
+ case 3:
2265
+ leftright = 0;
2266
+ /* no break */
2267
+ case 5:
2268
+ i = ndigits + k + 1;
2269
+ ilim = i;
2270
+ ilim1 = i - 1;
2271
+ if (i <= 0)
2272
+ i = 1;
2273
+ }
2274
+ /* ilim is the maximum number of significant digits we want, based on k and ndigits. */
2275
+ /* ilim1 is the maximum number of significant digits we want, based on k and ndigits,
2276
+ when it turns out that k was computed too high by one. */
2277
+
2278
+ /* Ensure space for at least i+1 characters, including trailing null. */
2279
+ if (bufsize <= (size_t)i) {
2280
+ Bfree(b);
2281
+ JS_ASSERT(JS_FALSE);
2282
+ return JS_FALSE;
2283
+ }
2284
+ s = buf;
2285
+
2286
+ if (ilim >= 0 && ilim <= Quick_max && try_quick) {
2287
+
2288
+ /* Try to get by with floating-point arithmetic. */
2289
+
2290
+ i = 0;
2291
+ d2 = d;
2292
+ k0 = k;
2293
+ ilim0 = ilim;
2294
+ ieps = 2; /* conservative */
2295
+ /* Divide d by 10^k, keeping track of the roundoff error and avoiding overflows. */
2296
+ if (k > 0) {
2297
+ ds = tens[k&0xf];
2298
+ j = k >> 4;
2299
+ if (j & Bletch) {
2300
+ /* prevent overflows */
2301
+ j &= Bletch - 1;
2302
+ d /= bigtens[n_bigtens-1];
2303
+ ieps++;
2304
+ }
2305
+ for(; j; j >>= 1, i++)
2306
+ if (j & 1) {
2307
+ ieps++;
2308
+ ds *= bigtens[i];
2309
+ }
2310
+ d /= ds;
2311
+ }
2312
+ else if ((j1 = -k) != 0) {
2313
+ d *= tens[j1 & 0xf];
2314
+ for(j = j1 >> 4; j; j >>= 1, i++)
2315
+ if (j & 1) {
2316
+ ieps++;
2317
+ d *= bigtens[i];
2318
+ }
2319
+ }
2320
+ /* Check that k was computed correctly. */
2321
+ if (k_check && d < 1. && ilim > 0) {
2322
+ if (ilim1 <= 0)
2323
+ goto fast_failed;
2324
+ ilim = ilim1;
2325
+ k--;
2326
+ d *= 10.;
2327
+ ieps++;
2328
+ }
2329
+ /* eps bounds the cumulative error. */
2330
+ eps = ieps*d + 7.;
2331
+ set_word0(eps, word0(eps) - (P-1)*Exp_msk1);
2332
+ if (ilim == 0) {
2333
+ S = mhi = 0;
2334
+ d -= 5.;
2335
+ if (d > eps)
2336
+ goto one_digit;
2337
+ if (d < -eps)
2338
+ goto no_digits;
2339
+ goto fast_failed;
2340
+ }
2341
+ #ifndef No_leftright
2342
+ if (leftright) {
2343
+ /* Use Steele & White method of only
2344
+ * generating digits needed.
2345
+ */
2346
+ eps = 0.5/tens[ilim-1] - eps;
2347
+ for(i = 0;;) {
2348
+ L = (Long)d;
2349
+ d -= L;
2350
+ *s++ = '0' + (char)L;
2351
+ if (d < eps)
2352
+ goto ret1;
2353
+ if (1. - d < eps) {
2354
+ #ifdef DEBUG
2355
+ /* Clear d to avoid precision warning. */
2356
+ d = 0;
2357
+ #endif
2358
+ goto bump_up;
2359
+ }
2360
+ if (++i >= ilim)
2361
+ break;
2362
+ eps *= 10.;
2363
+ d *= 10.;
2364
+ }
2365
+ }
2366
+ else {
2367
+ #endif
2368
+ /* Generate ilim digits, then fix them up. */
2369
+ eps *= tens[ilim-1];
2370
+ for(i = 1;; i++, d *= 10.) {
2371
+ L = (Long)d;
2372
+ d -= L;
2373
+ *s++ = '0' + (char)L;
2374
+ if (i == ilim) {
2375
+ if (d > 0.5 + eps) {
2376
+ #ifdef DEBUG
2377
+ /* Clear d to avoid precision warning. */
2378
+ d = 0;
2379
+ #endif
2380
+ goto bump_up;
2381
+ }
2382
+ else if (d < 0.5 - eps) {
2383
+ while(*--s == '0') ;
2384
+ s++;
2385
+ goto ret1;
2386
+ }
2387
+ break;
2388
+ }
2389
+ }
2390
+ #ifndef No_leftright
2391
+ }
2392
+ #endif
2393
+ fast_failed:
2394
+ s = buf;
2395
+ d = d2;
2396
+ k = k0;
2397
+ ilim = ilim0;
2398
+ }
2399
+
2400
+ /* Do we have a "small" integer? */
2401
+
2402
+ if (be >= 0 && k <= Int_max) {
2403
+ /* Yes. */
2404
+ ds = tens[k];
2405
+ if (ndigits < 0 && ilim <= 0) {
2406
+ S = mhi = 0;
2407
+ if (ilim < 0 || d < 5*ds || (!biasUp && d == 5*ds))
2408
+ goto no_digits;
2409
+ goto one_digit;
2410
+ }
2411
+
2412
+ /* Use true number of digits to limit looping. */
2413
+ for(i = 1; i<=k+1; i++) {
2414
+ L = (Long) (d / ds);
2415
+ d -= L*ds;
2416
+ #ifdef Check_FLT_ROUNDS
2417
+ /* If FLT_ROUNDS == 2, L will usually be high by 1 */
2418
+ if (d < 0) {
2419
+ L--;
2420
+ d += ds;
2421
+ }
2422
+ #endif
2423
+ *s++ = '0' + (char)L;
2424
+ if (i == ilim) {
2425
+ d += d;
2426
+ if ((d > ds) || (d == ds && (L & 1 || biasUp))) {
2427
+ bump_up:
2428
+ while(*--s == '9')
2429
+ if (s == buf) {
2430
+ k++;
2431
+ *s = '0';
2432
+ break;
2433
+ }
2434
+ ++*s++;
2435
+ }
2436
+ break;
2437
+ }
2438
+ d *= 10.;
2439
+ }
2440
+ #ifdef DEBUG
2441
+ if (d != 0.0) {
2442
+ fprintf(stderr,
2443
+ "WARNING: A loss of precision for double floating point is detected.\n"
2444
+ " The result of any operation on doubles can be meaningless.\n"
2445
+ " A possible cause is missing code to restore FPU state, see\n"
2446
+ " bug 360282 for details.\n");
2447
+ }
2448
+ #endif
2449
+ goto ret1;
2450
+ }
2451
+
2452
+ m2 = b2;
2453
+ m5 = b5;
2454
+ if (leftright) {
2455
+ if (mode < 2) {
2456
+ i =
2457
+ #ifndef Sudden_Underflow
2458
+ denorm ? be + (Bias + (P-1) - 1 + 1) :
2459
+ #endif
2460
+ 1 + P - bbits;
2461
+ /* i is 1 plus the number of trailing zero bits in d's significand. Thus,
2462
+ (2^m2 * 5^m5) / (2^(s2+i) * 5^s5) = (1/2 lsb of d)/10^k. */
2463
+ }
2464
+ else {
2465
+ j = ilim - 1;
2466
+ if (m5 >= j)
2467
+ m5 -= j;
2468
+ else {
2469
+ s5 += j -= m5;
2470
+ b5 += j;
2471
+ m5 = 0;
2472
+ }
2473
+ if ((i = ilim) < 0) {
2474
+ m2 -= i;
2475
+ i = 0;
2476
+ }
2477
+ /* (2^m2 * 5^m5) / (2^(s2+i) * 5^s5) = (1/2 * 10^(1-ilim))/10^k. */
2478
+ }
2479
+ b2 += i;
2480
+ s2 += i;
2481
+ mhi = i2b(1);
2482
+ if (!mhi)
2483
+ goto nomem;
2484
+ /* (mhi * 2^m2 * 5^m5) / (2^s2 * 5^s5) = one-half of last printed (when mode >= 2) or
2485
+ input (when mode < 2) significant digit, divided by 10^k. */
2486
+ }
2487
+ /* We still have d/10^k = (b * 2^b2 * 5^b5) / (2^s2 * 5^s5). Reduce common factors in
2488
+ b2, m2, and s2 without changing the equalities. */
2489
+ if (m2 > 0 && s2 > 0) {
2490
+ i = m2 < s2 ? m2 : s2;
2491
+ b2 -= i;
2492
+ m2 -= i;
2493
+ s2 -= i;
2494
+ }
2495
+
2496
+ /* Fold b5 into b and m5 into mhi. */
2497
+ if (b5 > 0) {
2498
+ if (leftright) {
2499
+ if (m5 > 0) {
2500
+ mhi = pow5mult(mhi, m5);
2501
+ if (!mhi)
2502
+ goto nomem;
2503
+ b1 = mult(mhi, b);
2504
+ if (!b1)
2505
+ goto nomem;
2506
+ Bfree(b);
2507
+ b = b1;
2508
+ }
2509
+ if ((j = b5 - m5) != 0) {
2510
+ b = pow5mult(b, j);
2511
+ if (!b)
2512
+ goto nomem;
2513
+ }
2514
+ }
2515
+ else {
2516
+ b = pow5mult(b, b5);
2517
+ if (!b)
2518
+ goto nomem;
2519
+ }
2520
+ }
2521
+ /* Now we have d/10^k = (b * 2^b2) / (2^s2 * 5^s5) and
2522
+ (mhi * 2^m2) / (2^s2 * 5^s5) = one-half of last printed or input significant digit, divided by 10^k. */
2523
+
2524
+ S = i2b(1);
2525
+ if (!S)
2526
+ goto nomem;
2527
+ if (s5 > 0) {
2528
+ S = pow5mult(S, s5);
2529
+ if (!S)
2530
+ goto nomem;
2531
+ }
2532
+ /* Now we have d/10^k = (b * 2^b2) / (S * 2^s2) and
2533
+ (mhi * 2^m2) / (S * 2^s2) = one-half of last printed or input significant digit, divided by 10^k. */
2534
+
2535
+ /* Check for special case that d is a normalized power of 2. */
2536
+ spec_case = 0;
2537
+ if (mode < 2) {
2538
+ if (!word1(d) && !(word0(d) & Bndry_mask)
2539
+ #ifndef Sudden_Underflow
2540
+ && word0(d) & (Exp_mask & Exp_mask << 1)
2541
+ #endif
2542
+ ) {
2543
+ /* The special case. Here we want to be within a quarter of the last input
2544
+ significant digit instead of one half of it when the decimal output string's value is less than d. */
2545
+ b2 += Log2P;
2546
+ s2 += Log2P;
2547
+ spec_case = 1;
2548
+ }
2549
+ }
2550
+
2551
+ /* Arrange for convenient computation of quotients:
2552
+ * shift left if necessary so divisor has 4 leading 0 bits.
2553
+ *
2554
+ * Perhaps we should just compute leading 28 bits of S once
2555
+ * and for all and pass them and a shift to quorem, so it
2556
+ * can do shifts and ors to compute the numerator for q.
2557
+ */
2558
+ if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) != 0)
2559
+ i = 32 - i;
2560
+ /* i is the number of leading zero bits in the most significant word of S*2^s2. */
2561
+ if (i > 4) {
2562
+ i -= 4;
2563
+ b2 += i;
2564
+ m2 += i;
2565
+ s2 += i;
2566
+ }
2567
+ else if (i < 4) {
2568
+ i += 28;
2569
+ b2 += i;
2570
+ m2 += i;
2571
+ s2 += i;
2572
+ }
2573
+ /* Now S*2^s2 has exactly four leading zero bits in its most significant word. */
2574
+ if (b2 > 0) {
2575
+ b = lshift(b, b2);
2576
+ if (!b)
2577
+ goto nomem;
2578
+ }
2579
+ if (s2 > 0) {
2580
+ S = lshift(S, s2);
2581
+ if (!S)
2582
+ goto nomem;
2583
+ }
2584
+ /* Now we have d/10^k = b/S and
2585
+ (mhi * 2^m2) / S = maximum acceptable error, divided by 10^k. */
2586
+ if (k_check) {
2587
+ if (cmp(b,S) < 0) {
2588
+ k--;
2589
+ b = multadd(b, 10, 0); /* we botched the k estimate */
2590
+ if (!b)
2591
+ goto nomem;
2592
+ if (leftright) {
2593
+ mhi = multadd(mhi, 10, 0);
2594
+ if (!mhi)
2595
+ goto nomem;
2596
+ }
2597
+ ilim = ilim1;
2598
+ }
2599
+ }
2600
+ /* At this point 1 <= d/10^k = b/S < 10. */
2601
+
2602
+ if (ilim <= 0 && mode > 2) {
2603
+ /* We're doing fixed-mode output and d is less than the minimum nonzero output in this mode.
2604
+ Output either zero or the minimum nonzero output depending on which is closer to d. */
2605
+ if (ilim < 0)
2606
+ goto no_digits;
2607
+ S = multadd(S,5,0);
2608
+ if (!S)
2609
+ goto nomem;
2610
+ i = cmp(b,S);
2611
+ if (i < 0 || (i == 0 && !biasUp)) {
2612
+ /* Always emit at least one digit. If the number appears to be zero
2613
+ using the current mode, then emit one '0' digit and set decpt to 1. */
2614
+ /*no_digits:
2615
+ k = -1 - ndigits;
2616
+ goto ret; */
2617
+ goto no_digits;
2618
+ }
2619
+ one_digit:
2620
+ *s++ = '1';
2621
+ k++;
2622
+ goto ret;
2623
+ }
2624
+ if (leftright) {
2625
+ if (m2 > 0) {
2626
+ mhi = lshift(mhi, m2);
2627
+ if (!mhi)
2628
+ goto nomem;
2629
+ }
2630
+
2631
+ /* Compute mlo -- check for special case
2632
+ * that d is a normalized power of 2.
2633
+ */
2634
+
2635
+ mlo = mhi;
2636
+ if (spec_case) {
2637
+ mhi = Balloc(mhi->k);
2638
+ if (!mhi)
2639
+ goto nomem;
2640
+ Bcopy(mhi, mlo);
2641
+ mhi = lshift(mhi, Log2P);
2642
+ if (!mhi)
2643
+ goto nomem;
2644
+ }
2645
+ /* mlo/S = maximum acceptable error, divided by 10^k, if the output is less than d. */
2646
+ /* mhi/S = maximum acceptable error, divided by 10^k, if the output is greater than d. */
2647
+
2648
+ for(i = 1;;i++) {
2649
+ dig = quorem(b,S) + '0';
2650
+ /* Do we yet have the shortest decimal string
2651
+ * that will round to d?
2652
+ */
2653
+ j = cmp(b, mlo);
2654
+ /* j is b/S compared with mlo/S. */
2655
+ delta = diff(S, mhi);
2656
+ if (!delta)
2657
+ goto nomem;
2658
+ j1 = delta->sign ? 1 : cmp(b, delta);
2659
+ Bfree(delta);
2660
+ /* j1 is b/S compared with 1 - mhi/S. */
2661
+ #ifndef ROUND_BIASED
2662
+ if (j1 == 0 && !mode && !(word1(d) & 1)) {
2663
+ if (dig == '9')
2664
+ goto round_9_up;
2665
+ if (j > 0)
2666
+ dig++;
2667
+ *s++ = (char)dig;
2668
+ goto ret;
2669
+ }
2670
+ #endif
2671
+ if ((j < 0) || (j == 0 && !mode
2672
+ #ifndef ROUND_BIASED
2673
+ && !(word1(d) & 1)
2674
+ #endif
2675
+ )) {
2676
+ if (j1 > 0) {
2677
+ /* Either dig or dig+1 would work here as the least significant decimal digit.
2678
+ Use whichever would produce a decimal value closer to d. */
2679
+ b = lshift(b, 1);
2680
+ if (!b)
2681
+ goto nomem;
2682
+ j1 = cmp(b, S);
2683
+ if (((j1 > 0) || (j1 == 0 && (dig & 1 || biasUp)))
2684
+ && (dig++ == '9'))
2685
+ goto round_9_up;
2686
+ }
2687
+ *s++ = (char)dig;
2688
+ goto ret;
2689
+ }
2690
+ if (j1 > 0) {
2691
+ if (dig == '9') { /* possible if i == 1 */
2692
+ round_9_up:
2693
+ *s++ = '9';
2694
+ goto roundoff;
2695
+ }
2696
+ *s++ = (char)dig + 1;
2697
+ goto ret;
2698
+ }
2699
+ *s++ = (char)dig;
2700
+ if (i == ilim)
2701
+ break;
2702
+ b = multadd(b, 10, 0);
2703
+ if (!b)
2704
+ goto nomem;
2705
+ if (mlo == mhi) {
2706
+ mlo = mhi = multadd(mhi, 10, 0);
2707
+ if (!mhi)
2708
+ goto nomem;
2709
+ }
2710
+ else {
2711
+ mlo = multadd(mlo, 10, 0);
2712
+ if (!mlo)
2713
+ goto nomem;
2714
+ mhi = multadd(mhi, 10, 0);
2715
+ if (!mhi)
2716
+ goto nomem;
2717
+ }
2718
+ }
2719
+ }
2720
+ else
2721
+ for(i = 1;; i++) {
2722
+ *s++ = (char)(dig = quorem(b,S) + '0');
2723
+ if (i >= ilim)
2724
+ break;
2725
+ b = multadd(b, 10, 0);
2726
+ if (!b)
2727
+ goto nomem;
2728
+ }
2729
+
2730
+ /* Round off last digit */
2731
+
2732
+ b = lshift(b, 1);
2733
+ if (!b)
2734
+ goto nomem;
2735
+ j = cmp(b, S);
2736
+ if ((j > 0) || (j == 0 && (dig & 1 || biasUp))) {
2737
+ roundoff:
2738
+ while(*--s == '9')
2739
+ if (s == buf) {
2740
+ k++;
2741
+ *s++ = '1';
2742
+ goto ret;
2743
+ }
2744
+ ++*s++;
2745
+ }
2746
+ else {
2747
+ /* Strip trailing zeros */
2748
+ while(*--s == '0') ;
2749
+ s++;
2750
+ }
2751
+ ret:
2752
+ Bfree(S);
2753
+ if (mhi) {
2754
+ if (mlo && mlo != mhi)
2755
+ Bfree(mlo);
2756
+ Bfree(mhi);
2757
+ }
2758
+ ret1:
2759
+ Bfree(b);
2760
+ JS_ASSERT(s < buf + bufsize);
2761
+ *s = '\0';
2762
+ if (rve)
2763
+ *rve = s;
2764
+ *decpt = k + 1;
2765
+ return JS_TRUE;
2766
+
2767
+ nomem:
2768
+ Bfree(S);
2769
+ if (mhi) {
2770
+ if (mlo && mlo != mhi)
2771
+ Bfree(mlo);
2772
+ Bfree(mhi);
2773
+ }
2774
+ Bfree(b);
2775
+ return JS_FALSE;
2776
+ }
2777
+
2778
+
2779
+ /* Mapping of JSDToStrMode -> js_dtoa mode */
2780
+ static const int dtoaModes[] = {
2781
+ 0, /* DTOSTR_STANDARD */
2782
+ 0, /* DTOSTR_STANDARD_EXPONENTIAL, */
2783
+ 3, /* DTOSTR_FIXED, */
2784
+ 2, /* DTOSTR_EXPONENTIAL, */
2785
+ 2}; /* DTOSTR_PRECISION */
2786
+
2787
+ JS_FRIEND_API(char *)
2788
+ JS_dtostr(char *buffer, size_t bufferSize, JSDToStrMode mode, int precision, double d)
2789
+ {
2790
+ int decPt; /* Position of decimal point relative to first digit returned by js_dtoa */
2791
+ int sign; /* Nonzero if the sign bit was set in d */
2792
+ int nDigits; /* Number of significand digits returned by js_dtoa */
2793
+ char *numBegin = buffer+2; /* Pointer to the digits returned by js_dtoa; the +2 leaves space for */
2794
+ /* the sign and/or decimal point */
2795
+ char *numEnd; /* Pointer past the digits returned by js_dtoa */
2796
+ JSBool dtoaRet;
2797
+
2798
+ JS_ASSERT(bufferSize >= (size_t)(mode <= DTOSTR_STANDARD_EXPONENTIAL ? DTOSTR_STANDARD_BUFFER_SIZE :
2799
+ DTOSTR_VARIABLE_BUFFER_SIZE(precision)));
2800
+
2801
+ if (mode == DTOSTR_FIXED && (d >= 1e21 || d <= -1e21))
2802
+ mode = DTOSTR_STANDARD; /* Change mode here rather than below because the buffer may not be large enough to hold a large integer. */
2803
+
2804
+ /* Locking for Balloc's shared buffers */
2805
+ ACQUIRE_DTOA_LOCK();
2806
+ dtoaRet = js_dtoa(d, dtoaModes[mode], mode >= DTOSTR_FIXED, precision, &decPt, &sign, &numEnd, numBegin, bufferSize-2);
2807
+ RELEASE_DTOA_LOCK();
2808
+ if (!dtoaRet)
2809
+ return 0;
2810
+
2811
+ nDigits = numEnd - numBegin;
2812
+
2813
+ /* If Infinity, -Infinity, or NaN, return the string regardless of the mode. */
2814
+ if (decPt != 9999) {
2815
+ JSBool exponentialNotation = JS_FALSE;
2816
+ int minNDigits = 0; /* Minimum number of significand digits required by mode and precision */
2817
+ char *p;
2818
+ char *q;
2819
+
2820
+ switch (mode) {
2821
+ case DTOSTR_STANDARD:
2822
+ if (decPt < -5 || decPt > 21)
2823
+ exponentialNotation = JS_TRUE;
2824
+ else
2825
+ minNDigits = decPt;
2826
+ break;
2827
+
2828
+ case DTOSTR_FIXED:
2829
+ if (precision >= 0)
2830
+ minNDigits = decPt + precision;
2831
+ else
2832
+ minNDigits = decPt;
2833
+ break;
2834
+
2835
+ case DTOSTR_EXPONENTIAL:
2836
+ JS_ASSERT(precision > 0);
2837
+ minNDigits = precision;
2838
+ /* Fall through */
2839
+ case DTOSTR_STANDARD_EXPONENTIAL:
2840
+ exponentialNotation = JS_TRUE;
2841
+ break;
2842
+
2843
+ case DTOSTR_PRECISION:
2844
+ JS_ASSERT(precision > 0);
2845
+ minNDigits = precision;
2846
+ if (decPt < -5 || decPt > precision)
2847
+ exponentialNotation = JS_TRUE;
2848
+ break;
2849
+ }
2850
+
2851
+ /* If the number has fewer than minNDigits, pad it with zeros at the end */
2852
+ if (nDigits < minNDigits) {
2853
+ p = numBegin + minNDigits;
2854
+ nDigits = minNDigits;
2855
+ do {
2856
+ *numEnd++ = '0';
2857
+ } while (numEnd != p);
2858
+ *numEnd = '\0';
2859
+ }
2860
+
2861
+ if (exponentialNotation) {
2862
+ /* Insert a decimal point if more than one significand digit */
2863
+ if (nDigits != 1) {
2864
+ numBegin--;
2865
+ numBegin[0] = numBegin[1];
2866
+ numBegin[1] = '.';
2867
+ }
2868
+ JS_snprintf(numEnd, bufferSize - (numEnd - buffer), "e%+d", decPt-1);
2869
+ } else if (decPt != nDigits) {
2870
+ /* Some kind of a fraction in fixed notation */
2871
+ JS_ASSERT(decPt <= nDigits);
2872
+ if (decPt > 0) {
2873
+ /* dd...dd . dd...dd */
2874
+ p = --numBegin;
2875
+ do {
2876
+ *p = p[1];
2877
+ p++;
2878
+ } while (--decPt);
2879
+ *p = '.';
2880
+ } else {
2881
+ /* 0 . 00...00dd...dd */
2882
+ p = numEnd;
2883
+ numEnd += 1 - decPt;
2884
+ q = numEnd;
2885
+ JS_ASSERT(numEnd < buffer + bufferSize);
2886
+ *numEnd = '\0';
2887
+ while (p != numBegin)
2888
+ *--q = *--p;
2889
+ for (p = numBegin + 1; p != q; p++)
2890
+ *p = '0';
2891
+ *numBegin = '.';
2892
+ *--numBegin = '0';
2893
+ }
2894
+ }
2895
+ }
2896
+
2897
+ /* If negative and neither -0.0 nor NaN, output a leading '-'. */
2898
+ if (sign &&
2899
+ !(word0(d) == Sign_bit && word1(d) == 0) &&
2900
+ !((word0(d) & Exp_mask) == Exp_mask &&
2901
+ (word1(d) || (word0(d) & Frac_mask)))) {
2902
+ *--numBegin = '-';
2903
+ }
2904
+ return numBegin;
2905
+ }
2906
+
2907
+
2908
+ /* Let b = floor(b / divisor), and return the remainder. b must be nonnegative.
2909
+ * divisor must be between 1 and 65536.
2910
+ * This function cannot run out of memory. */
2911
+ static uint32
2912
+ divrem(Bigint *b, uint32 divisor)
2913
+ {
2914
+ int32 n = b->wds;
2915
+ uint32 remainder = 0;
2916
+ ULong *bx;
2917
+ ULong *bp;
2918
+
2919
+ JS_ASSERT(divisor > 0 && divisor <= 65536);
2920
+
2921
+ if (!n)
2922
+ return 0; /* b is zero */
2923
+ bx = b->x;
2924
+ bp = bx + n;
2925
+ do {
2926
+ ULong a = *--bp;
2927
+ ULong dividend = remainder << 16 | a >> 16;
2928
+ ULong quotientHi = dividend / divisor;
2929
+ ULong quotientLo;
2930
+
2931
+ remainder = dividend - quotientHi*divisor;
2932
+ JS_ASSERT(quotientHi <= 0xFFFF && remainder < divisor);
2933
+ dividend = remainder << 16 | (a & 0xFFFF);
2934
+ quotientLo = dividend / divisor;
2935
+ remainder = dividend - quotientLo*divisor;
2936
+ JS_ASSERT(quotientLo <= 0xFFFF && remainder < divisor);
2937
+ *bp = quotientHi << 16 | quotientLo;
2938
+ } while (bp != bx);
2939
+ /* Decrease the size of the number if its most significant word is now zero. */
2940
+ if (bx[n-1] == 0)
2941
+ b->wds--;
2942
+ return remainder;
2943
+ }
2944
+
2945
+
2946
+ /* "-0.0000...(1073 zeros after decimal point)...0001\0" is the longest string that we could produce,
2947
+ * which occurs when printing -5e-324 in binary. We could compute a better estimate of the size of
2948
+ * the output string and malloc fewer bytes depending on d and base, but why bother? */
2949
+ #define DTOBASESTR_BUFFER_SIZE 1078
2950
+ #define BASEDIGIT(digit) ((char)(((digit) >= 10) ? 'a' - 10 + (digit) : '0' + (digit)))
2951
+
2952
+ JS_FRIEND_API(char *)
2953
+ JS_dtobasestr(int base, double d)
2954
+ {
2955
+ char *buffer; /* The output string */
2956
+ char *p; /* Pointer to current position in the buffer */
2957
+ char *pInt; /* Pointer to the beginning of the integer part of the string */
2958
+ char *q;
2959
+ uint32 digit;
2960
+ double di; /* d truncated to an integer */
2961
+ double df; /* The fractional part of d */
2962
+
2963
+ JS_ASSERT(base >= 2 && base <= 36);
2964
+
2965
+ buffer = (char*) malloc(DTOBASESTR_BUFFER_SIZE);
2966
+ if (buffer) {
2967
+ p = buffer;
2968
+ if (d < 0.0
2969
+ #if defined(XP_WIN) || defined(XP_OS2)
2970
+ && !((word0(d) & Exp_mask) == Exp_mask && ((word0(d) & Frac_mask) || word1(d))) /* Visual C++ doesn't know how to compare against NaN */
2971
+ #endif
2972
+ ) {
2973
+ *p++ = '-';
2974
+ d = -d;
2975
+ }
2976
+
2977
+ /* Check for Infinity and NaN */
2978
+ if ((word0(d) & Exp_mask) == Exp_mask) {
2979
+ strcpy(p, !word1(d) && !(word0(d) & Frac_mask) ? "Infinity" : "NaN");
2980
+ return buffer;
2981
+ }
2982
+
2983
+ /* Locking for Balloc's shared buffers */
2984
+ ACQUIRE_DTOA_LOCK();
2985
+
2986
+ /* Output the integer part of d with the digits in reverse order. */
2987
+ pInt = p;
2988
+ di = fd_floor(d);
2989
+ if (di <= 4294967295.0) {
2990
+ uint32 n = (uint32)di;
2991
+ if (n)
2992
+ do {
2993
+ uint32 m = n / base;
2994
+ digit = n - m*base;
2995
+ n = m;
2996
+ JS_ASSERT(digit < (uint32)base);
2997
+ *p++ = BASEDIGIT(digit);
2998
+ } while (n);
2999
+ else *p++ = '0';
3000
+ } else {
3001
+ int32 e;
3002
+ int32 bits; /* Number of significant bits in di; not used. */
3003
+ Bigint *b = d2b(di, &e, &bits);
3004
+ if (!b)
3005
+ goto nomem1;
3006
+ b = lshift(b, e);
3007
+ if (!b) {
3008
+ nomem1:
3009
+ Bfree(b);
3010
+ RELEASE_DTOA_LOCK();
3011
+ free(buffer);
3012
+ return NULL;
3013
+ }
3014
+ do {
3015
+ digit = divrem(b, base);
3016
+ JS_ASSERT(digit < (uint32)base);
3017
+ *p++ = BASEDIGIT(digit);
3018
+ } while (b->wds);
3019
+ Bfree(b);
3020
+ }
3021
+ /* Reverse the digits of the integer part of d. */
3022
+ q = p-1;
3023
+ while (q > pInt) {
3024
+ char ch = *pInt;
3025
+ *pInt++ = *q;
3026
+ *q-- = ch;
3027
+ }
3028
+
3029
+ df = d - di;
3030
+ if (df != 0.0) {
3031
+ /* We have a fraction. */
3032
+ int32 e, bbits, s2, done;
3033
+ Bigint *b, *s, *mlo, *mhi;
3034
+
3035
+ b = s = mlo = mhi = NULL;
3036
+
3037
+ *p++ = '.';
3038
+ b = d2b(df, &e, &bbits);
3039
+ if (!b) {
3040
+ nomem2:
3041
+ Bfree(b);
3042
+ Bfree(s);
3043
+ if (mlo != mhi)
3044
+ Bfree(mlo);
3045
+ Bfree(mhi);
3046
+ RELEASE_DTOA_LOCK();
3047
+ free(buffer);
3048
+ return NULL;
3049
+ }
3050
+ JS_ASSERT(e < 0);
3051
+ /* At this point df = b * 2^e. e must be less than zero because 0 < df < 1. */
3052
+
3053
+ s2 = -(int32)(word0(d) >> Exp_shift1 & Exp_mask>>Exp_shift1);
3054
+ #ifndef Sudden_Underflow
3055
+ if (!s2)
3056
+ s2 = -1;
3057
+ #endif
3058
+ s2 += Bias + P;
3059
+ /* 1/2^s2 = (nextDouble(d) - d)/2 */
3060
+ JS_ASSERT(-s2 < e);
3061
+ mlo = i2b(1);
3062
+ if (!mlo)
3063
+ goto nomem2;
3064
+ mhi = mlo;
3065
+ if (!word1(d) && !(word0(d) & Bndry_mask)
3066
+ #ifndef Sudden_Underflow
3067
+ && word0(d) & (Exp_mask & Exp_mask << 1)
3068
+ #endif
3069
+ ) {
3070
+ /* The special case. Here we want to be within a quarter of the last input
3071
+ significant digit instead of one half of it when the output string's value is less than d. */
3072
+ s2 += Log2P;
3073
+ mhi = i2b(1<<Log2P);
3074
+ if (!mhi)
3075
+ goto nomem2;
3076
+ }
3077
+ b = lshift(b, e + s2);
3078
+ if (!b)
3079
+ goto nomem2;
3080
+ s = i2b(1);
3081
+ if (!s)
3082
+ goto nomem2;
3083
+ s = lshift(s, s2);
3084
+ if (!s)
3085
+ goto nomem2;
3086
+ /* At this point we have the following:
3087
+ * s = 2^s2;
3088
+ * 1 > df = b/2^s2 > 0;
3089
+ * (d - prevDouble(d))/2 = mlo/2^s2;
3090
+ * (nextDouble(d) - d)/2 = mhi/2^s2. */
3091
+
3092
+ done = JS_FALSE;
3093
+ do {
3094
+ int32 j, j1;
3095
+ Bigint *delta;
3096
+
3097
+ b = multadd(b, base, 0);
3098
+ if (!b)
3099
+ goto nomem2;
3100
+ digit = quorem2(b, s2);
3101
+ if (mlo == mhi) {
3102
+ mlo = mhi = multadd(mlo, base, 0);
3103
+ if (!mhi)
3104
+ goto nomem2;
3105
+ }
3106
+ else {
3107
+ mlo = multadd(mlo, base, 0);
3108
+ if (!mlo)
3109
+ goto nomem2;
3110
+ mhi = multadd(mhi, base, 0);
3111
+ if (!mhi)
3112
+ goto nomem2;
3113
+ }
3114
+
3115
+ /* Do we yet have the shortest string that will round to d? */
3116
+ j = cmp(b, mlo);
3117
+ /* j is b/2^s2 compared with mlo/2^s2. */
3118
+ delta = diff(s, mhi);
3119
+ if (!delta)
3120
+ goto nomem2;
3121
+ j1 = delta->sign ? 1 : cmp(b, delta);
3122
+ Bfree(delta);
3123
+ /* j1 is b/2^s2 compared with 1 - mhi/2^s2. */
3124
+
3125
+ #ifndef ROUND_BIASED
3126
+ if (j1 == 0 && !(word1(d) & 1)) {
3127
+ if (j > 0)
3128
+ digit++;
3129
+ done = JS_TRUE;
3130
+ } else
3131
+ #endif
3132
+ if (j < 0 || (j == 0
3133
+ #ifndef ROUND_BIASED
3134
+ && !(word1(d) & 1)
3135
+ #endif
3136
+ )) {
3137
+ if (j1 > 0) {
3138
+ /* Either dig or dig+1 would work here as the least significant digit.
3139
+ Use whichever would produce an output value closer to d. */
3140
+ b = lshift(b, 1);
3141
+ if (!b)
3142
+ goto nomem2;
3143
+ j1 = cmp(b, s);
3144
+ if (j1 > 0) /* The even test (|| (j1 == 0 && (digit & 1))) is not here because it messes up odd base output
3145
+ * such as 3.5 in base 3. */
3146
+ digit++;
3147
+ }
3148
+ done = JS_TRUE;
3149
+ } else if (j1 > 0) {
3150
+ digit++;
3151
+ done = JS_TRUE;
3152
+ }
3153
+ JS_ASSERT(digit < (uint32)base);
3154
+ *p++ = BASEDIGIT(digit);
3155
+ } while (!done);
3156
+ Bfree(b);
3157
+ Bfree(s);
3158
+ if (mlo != mhi)
3159
+ Bfree(mlo);
3160
+ Bfree(mhi);
3161
+ }
3162
+ JS_ASSERT(p < buffer + DTOBASESTR_BUFFER_SIZE);
3163
+ *p = '\0';
3164
+ RELEASE_DTOA_LOCK();
3165
+ }
3166
+ return buffer;
3167
+ }