johnson 2.0.0.pre1 → 2.0.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (311) hide show
  1. data/CHANGELOG.rdoc +12 -0
  2. data/Manifest.txt +4 -285
  3. data/Rakefile +13 -20
  4. data/ext/tracemonkey/global.cc +4 -1
  5. data/ext/tracemonkey/js.cc +30 -33
  6. data/ext/tracemonkey/runtime.cc +96 -6
  7. data/ext/tracemonkey/split_global.cc +0 -5
  8. data/ext/tracemonkey/tracemonkey.h +2 -2
  9. data/lib/johnson.rb +2 -2
  10. data/lib/johnson/runtime.rb +25 -15
  11. data/lib/johnson/tracemonkey/runtime.rb +6 -3
  12. data/vendor/tracemonkey/config/system-headers +1 -3
  13. data/vendor/tracemonkey/jscntxt.h +5 -2
  14. data/vendor/tracemonkey/jsdbgapi.cpp +9 -1
  15. data/vendor/tracemonkey/jsdbgapi.h +4 -0
  16. data/vendor/tracemonkey/tests/ecma/NativeObjects/browser.js +0 -0
  17. data/vendor/tracemonkey/tests/ecma/NativeObjects/jstests.list +0 -0
  18. data/vendor/tracemonkey/tests/ecma_3_1/Object/jstests.list +1 -1
  19. data/vendor/tracemonkey/tests/js1_3/misc/browser.js +0 -0
  20. data/vendor/tracemonkey/tests/js1_3/misc/jstests.list +0 -0
  21. data/vendor/tracemonkey/tests/js1_5/Regress/jstests.list +4 -4
  22. data/vendor/tracemonkey/tests/js1_5/Scope/jstests.list +1 -1
  23. data/vendor/tracemonkey/tests/js1_5/decompilation/jstests.list +2 -2
  24. data/vendor/tracemonkey/tests/js1_7/decompilation/jstests.list +1 -1
  25. data/vendor/tracemonkey/tests/shell.js +2 -1
  26. metadata +51 -309
  27. data/ext/spidermonkey/context.c +0 -116
  28. data/ext/spidermonkey/context.h +0 -19
  29. data/ext/spidermonkey/conversions.c +0 -361
  30. data/ext/spidermonkey/conversions.h +0 -31
  31. data/ext/spidermonkey/debugger.c +0 -234
  32. data/ext/spidermonkey/debugger.h +0 -10
  33. data/ext/spidermonkey/extconf.rb +0 -32
  34. data/ext/spidermonkey/extensions.c +0 -37
  35. data/ext/spidermonkey/extensions.h +0 -12
  36. data/ext/spidermonkey/global.c +0 -40
  37. data/ext/spidermonkey/global.h +0 -11
  38. data/ext/spidermonkey/idhash.c +0 -16
  39. data/ext/spidermonkey/idhash.h +0 -8
  40. data/ext/spidermonkey/immutable_node.c +0 -1153
  41. data/ext/spidermonkey/immutable_node.c.erb +0 -523
  42. data/ext/spidermonkey/immutable_node.h +0 -22
  43. data/ext/spidermonkey/jroot.h +0 -197
  44. data/ext/spidermonkey/js_land_proxy.c +0 -620
  45. data/ext/spidermonkey/js_land_proxy.h +0 -20
  46. data/ext/spidermonkey/ruby_land_proxy.c +0 -618
  47. data/ext/spidermonkey/ruby_land_proxy.h +0 -38
  48. data/ext/spidermonkey/runtime.c +0 -396
  49. data/ext/spidermonkey/runtime.h +0 -27
  50. data/ext/spidermonkey/spidermonkey.c +0 -22
  51. data/ext/spidermonkey/spidermonkey.h +0 -29
  52. data/lib/johnson/spidermonkey.rb +0 -12
  53. data/lib/johnson/spidermonkey/context.rb +0 -10
  54. data/lib/johnson/spidermonkey/debugger.rb +0 -67
  55. data/lib/johnson/spidermonkey/immutable_node.rb +0 -282
  56. data/lib/johnson/spidermonkey/js_land_proxy.rb +0 -64
  57. data/lib/johnson/spidermonkey/mutable_tree_visitor.rb +0 -242
  58. data/lib/johnson/spidermonkey/ruby_land_proxy.rb +0 -17
  59. data/lib/johnson/spidermonkey/runtime.rb +0 -74
  60. data/test/johnson/spidermonkey/context_test.rb +0 -21
  61. data/test/johnson/spidermonkey/immutable_node_test.rb +0 -34
  62. data/test/johnson/spidermonkey/js_land_proxy_test.rb +0 -273
  63. data/test/johnson/spidermonkey/ruby_land_proxy_test.rb +0 -274
  64. data/test/johnson/spidermonkey/runtime_test.rb +0 -41
  65. data/vendor/spidermonkey/.cvsignore +0 -9
  66. data/vendor/spidermonkey/Makefile.in +0 -449
  67. data/vendor/spidermonkey/Makefile.ref +0 -365
  68. data/vendor/spidermonkey/README.html +0 -820
  69. data/vendor/spidermonkey/SpiderMonkey.rsp +0 -12
  70. data/vendor/spidermonkey/Y.js +0 -19
  71. data/vendor/spidermonkey/build.mk +0 -43
  72. data/vendor/spidermonkey/config.mk +0 -192
  73. data/vendor/spidermonkey/config/AIX4.1.mk +0 -65
  74. data/vendor/spidermonkey/config/AIX4.2.mk +0 -64
  75. data/vendor/spidermonkey/config/AIX4.3.mk +0 -65
  76. data/vendor/spidermonkey/config/Darwin.mk +0 -83
  77. data/vendor/spidermonkey/config/Darwin1.3.mk +0 -81
  78. data/vendor/spidermonkey/config/Darwin1.4.mk +0 -41
  79. data/vendor/spidermonkey/config/Darwin5.2.mk +0 -81
  80. data/vendor/spidermonkey/config/Darwin5.3.mk +0 -81
  81. data/vendor/spidermonkey/config/HP-UXB.10.10.mk +0 -77
  82. data/vendor/spidermonkey/config/HP-UXB.10.20.mk +0 -77
  83. data/vendor/spidermonkey/config/HP-UXB.11.00.mk +0 -80
  84. data/vendor/spidermonkey/config/IRIX.mk +0 -87
  85. data/vendor/spidermonkey/config/IRIX5.3.mk +0 -44
  86. data/vendor/spidermonkey/config/IRIX6.1.mk +0 -44
  87. data/vendor/spidermonkey/config/IRIX6.2.mk +0 -44
  88. data/vendor/spidermonkey/config/IRIX6.3.mk +0 -44
  89. data/vendor/spidermonkey/config/IRIX6.5.mk +0 -44
  90. data/vendor/spidermonkey/config/Linux_All.mk +0 -103
  91. data/vendor/spidermonkey/config/Mac_OS10.0.mk +0 -82
  92. data/vendor/spidermonkey/config/OSF1V4.0.mk +0 -72
  93. data/vendor/spidermonkey/config/OSF1V5.0.mk +0 -69
  94. data/vendor/spidermonkey/config/SunOS4.1.4.mk +0 -101
  95. data/vendor/spidermonkey/config/SunOS5.10.mk +0 -50
  96. data/vendor/spidermonkey/config/SunOS5.3.mk +0 -91
  97. data/vendor/spidermonkey/config/SunOS5.4.mk +0 -92
  98. data/vendor/spidermonkey/config/SunOS5.5.1.mk +0 -44
  99. data/vendor/spidermonkey/config/SunOS5.5.mk +0 -87
  100. data/vendor/spidermonkey/config/SunOS5.6.mk +0 -89
  101. data/vendor/spidermonkey/config/SunOS5.7.mk +0 -44
  102. data/vendor/spidermonkey/config/SunOS5.8.mk +0 -44
  103. data/vendor/spidermonkey/config/SunOS5.9.mk +0 -44
  104. data/vendor/spidermonkey/config/WINNT4.0.mk +0 -117
  105. data/vendor/spidermonkey/config/WINNT5.0.mk +0 -117
  106. data/vendor/spidermonkey/config/WINNT5.1.mk +0 -117
  107. data/vendor/spidermonkey/config/WINNT5.2.mk +0 -117
  108. data/vendor/spidermonkey/config/WINNT6.0.mk +0 -117
  109. data/vendor/spidermonkey/config/dgux.mk +0 -64
  110. data/vendor/spidermonkey/editline/Makefile.ref +0 -144
  111. data/vendor/spidermonkey/editline/README +0 -83
  112. data/vendor/spidermonkey/editline/editline.3 +0 -175
  113. data/vendor/spidermonkey/editline/editline.c +0 -1369
  114. data/vendor/spidermonkey/editline/editline.h +0 -135
  115. data/vendor/spidermonkey/editline/sysunix.c +0 -182
  116. data/vendor/spidermonkey/editline/unix.h +0 -82
  117. data/vendor/spidermonkey/fdlibm/.cvsignore +0 -7
  118. data/vendor/spidermonkey/fdlibm/Makefile.in +0 -127
  119. data/vendor/spidermonkey/fdlibm/Makefile.ref +0 -192
  120. data/vendor/spidermonkey/fdlibm/e_acos.c +0 -147
  121. data/vendor/spidermonkey/fdlibm/e_acosh.c +0 -105
  122. data/vendor/spidermonkey/fdlibm/e_asin.c +0 -156
  123. data/vendor/spidermonkey/fdlibm/e_atan2.c +0 -165
  124. data/vendor/spidermonkey/fdlibm/e_atanh.c +0 -110
  125. data/vendor/spidermonkey/fdlibm/e_cosh.c +0 -133
  126. data/vendor/spidermonkey/fdlibm/e_exp.c +0 -202
  127. data/vendor/spidermonkey/fdlibm/e_fmod.c +0 -184
  128. data/vendor/spidermonkey/fdlibm/e_gamma.c +0 -71
  129. data/vendor/spidermonkey/fdlibm/e_gamma_r.c +0 -70
  130. data/vendor/spidermonkey/fdlibm/e_hypot.c +0 -173
  131. data/vendor/spidermonkey/fdlibm/e_j0.c +0 -524
  132. data/vendor/spidermonkey/fdlibm/e_j1.c +0 -523
  133. data/vendor/spidermonkey/fdlibm/e_jn.c +0 -315
  134. data/vendor/spidermonkey/fdlibm/e_lgamma.c +0 -71
  135. data/vendor/spidermonkey/fdlibm/e_lgamma_r.c +0 -347
  136. data/vendor/spidermonkey/fdlibm/e_log.c +0 -184
  137. data/vendor/spidermonkey/fdlibm/e_log10.c +0 -134
  138. data/vendor/spidermonkey/fdlibm/e_pow.c +0 -386
  139. data/vendor/spidermonkey/fdlibm/e_rem_pio2.c +0 -222
  140. data/vendor/spidermonkey/fdlibm/e_remainder.c +0 -120
  141. data/vendor/spidermonkey/fdlibm/e_scalb.c +0 -89
  142. data/vendor/spidermonkey/fdlibm/e_sinh.c +0 -122
  143. data/vendor/spidermonkey/fdlibm/e_sqrt.c +0 -497
  144. data/vendor/spidermonkey/fdlibm/fdlibm.h +0 -273
  145. data/vendor/spidermonkey/fdlibm/fdlibm.mak +0 -1453
  146. data/vendor/spidermonkey/fdlibm/fdlibm.mdp +0 -0
  147. data/vendor/spidermonkey/fdlibm/k_cos.c +0 -135
  148. data/vendor/spidermonkey/fdlibm/k_rem_pio2.c +0 -354
  149. data/vendor/spidermonkey/fdlibm/k_sin.c +0 -114
  150. data/vendor/spidermonkey/fdlibm/k_standard.c +0 -785
  151. data/vendor/spidermonkey/fdlibm/k_tan.c +0 -170
  152. data/vendor/spidermonkey/fdlibm/s_asinh.c +0 -101
  153. data/vendor/spidermonkey/fdlibm/s_atan.c +0 -175
  154. data/vendor/spidermonkey/fdlibm/s_cbrt.c +0 -133
  155. data/vendor/spidermonkey/fdlibm/s_ceil.c +0 -120
  156. data/vendor/spidermonkey/fdlibm/s_copysign.c +0 -72
  157. data/vendor/spidermonkey/fdlibm/s_cos.c +0 -118
  158. data/vendor/spidermonkey/fdlibm/s_erf.c +0 -356
  159. data/vendor/spidermonkey/fdlibm/s_expm1.c +0 -267
  160. data/vendor/spidermonkey/fdlibm/s_fabs.c +0 -70
  161. data/vendor/spidermonkey/fdlibm/s_finite.c +0 -71
  162. data/vendor/spidermonkey/fdlibm/s_floor.c +0 -121
  163. data/vendor/spidermonkey/fdlibm/s_frexp.c +0 -99
  164. data/vendor/spidermonkey/fdlibm/s_ilogb.c +0 -85
  165. data/vendor/spidermonkey/fdlibm/s_isnan.c +0 -74
  166. data/vendor/spidermonkey/fdlibm/s_ldexp.c +0 -66
  167. data/vendor/spidermonkey/fdlibm/s_lib_version.c +0 -73
  168. data/vendor/spidermonkey/fdlibm/s_log1p.c +0 -211
  169. data/vendor/spidermonkey/fdlibm/s_logb.c +0 -79
  170. data/vendor/spidermonkey/fdlibm/s_matherr.c +0 -64
  171. data/vendor/spidermonkey/fdlibm/s_modf.c +0 -132
  172. data/vendor/spidermonkey/fdlibm/s_nextafter.c +0 -124
  173. data/vendor/spidermonkey/fdlibm/s_rint.c +0 -131
  174. data/vendor/spidermonkey/fdlibm/s_scalbn.c +0 -107
  175. data/vendor/spidermonkey/fdlibm/s_signgam.c +0 -40
  176. data/vendor/spidermonkey/fdlibm/s_significand.c +0 -68
  177. data/vendor/spidermonkey/fdlibm/s_sin.c +0 -118
  178. data/vendor/spidermonkey/fdlibm/s_tan.c +0 -112
  179. data/vendor/spidermonkey/fdlibm/s_tanh.c +0 -122
  180. data/vendor/spidermonkey/fdlibm/w_acos.c +0 -78
  181. data/vendor/spidermonkey/fdlibm/w_acosh.c +0 -78
  182. data/vendor/spidermonkey/fdlibm/w_asin.c +0 -80
  183. data/vendor/spidermonkey/fdlibm/w_atan2.c +0 -79
  184. data/vendor/spidermonkey/fdlibm/w_atanh.c +0 -81
  185. data/vendor/spidermonkey/fdlibm/w_cosh.c +0 -77
  186. data/vendor/spidermonkey/fdlibm/w_exp.c +0 -88
  187. data/vendor/spidermonkey/fdlibm/w_fmod.c +0 -78
  188. data/vendor/spidermonkey/fdlibm/w_gamma.c +0 -85
  189. data/vendor/spidermonkey/fdlibm/w_gamma_r.c +0 -81
  190. data/vendor/spidermonkey/fdlibm/w_hypot.c +0 -78
  191. data/vendor/spidermonkey/fdlibm/w_j0.c +0 -105
  192. data/vendor/spidermonkey/fdlibm/w_j1.c +0 -106
  193. data/vendor/spidermonkey/fdlibm/w_jn.c +0 -128
  194. data/vendor/spidermonkey/fdlibm/w_lgamma.c +0 -85
  195. data/vendor/spidermonkey/fdlibm/w_lgamma_r.c +0 -81
  196. data/vendor/spidermonkey/fdlibm/w_log.c +0 -78
  197. data/vendor/spidermonkey/fdlibm/w_log10.c +0 -81
  198. data/vendor/spidermonkey/fdlibm/w_pow.c +0 -99
  199. data/vendor/spidermonkey/fdlibm/w_remainder.c +0 -77
  200. data/vendor/spidermonkey/fdlibm/w_scalb.c +0 -95
  201. data/vendor/spidermonkey/fdlibm/w_sinh.c +0 -77
  202. data/vendor/spidermonkey/fdlibm/w_sqrt.c +0 -77
  203. data/vendor/spidermonkey/javascript-trace.d +0 -73
  204. data/vendor/spidermonkey/js.c +0 -3951
  205. data/vendor/spidermonkey/js.mdp +0 -0
  206. data/vendor/spidermonkey/js.msg +0 -308
  207. data/vendor/spidermonkey/js.pkg +0 -2
  208. data/vendor/spidermonkey/js3240.rc +0 -79
  209. data/vendor/spidermonkey/jsOS240.def +0 -654
  210. data/vendor/spidermonkey/jsapi.c +0 -5836
  211. data/vendor/spidermonkey/jsapi.h +0 -2624
  212. data/vendor/spidermonkey/jsarena.c +0 -450
  213. data/vendor/spidermonkey/jsarena.h +0 -318
  214. data/vendor/spidermonkey/jsarray.c +0 -2996
  215. data/vendor/spidermonkey/jsarray.h +0 -127
  216. data/vendor/spidermonkey/jsatom.c +0 -1045
  217. data/vendor/spidermonkey/jsatom.h +0 -442
  218. data/vendor/spidermonkey/jsbit.h +0 -253
  219. data/vendor/spidermonkey/jsbool.c +0 -176
  220. data/vendor/spidermonkey/jsbool.h +0 -73
  221. data/vendor/spidermonkey/jsclist.h +0 -139
  222. data/vendor/spidermonkey/jscntxt.c +0 -1348
  223. data/vendor/spidermonkey/jscntxt.h +0 -1120
  224. data/vendor/spidermonkey/jscompat.h +0 -57
  225. data/vendor/spidermonkey/jsconfig.h +0 -248
  226. data/vendor/spidermonkey/jsconfig.mk +0 -181
  227. data/vendor/spidermonkey/jscpucfg.c +0 -396
  228. data/vendor/spidermonkey/jscpucfg.h +0 -212
  229. data/vendor/spidermonkey/jsdate.c +0 -2390
  230. data/vendor/spidermonkey/jsdate.h +0 -124
  231. data/vendor/spidermonkey/jsdbgapi.c +0 -1802
  232. data/vendor/spidermonkey/jsdbgapi.h +0 -464
  233. data/vendor/spidermonkey/jsdhash.c +0 -868
  234. data/vendor/spidermonkey/jsdhash.h +0 -592
  235. data/vendor/spidermonkey/jsdtoa.c +0 -3167
  236. data/vendor/spidermonkey/jsdtoa.h +0 -130
  237. data/vendor/spidermonkey/jsdtracef.c +0 -317
  238. data/vendor/spidermonkey/jsdtracef.h +0 -77
  239. data/vendor/spidermonkey/jsemit.c +0 -6909
  240. data/vendor/spidermonkey/jsemit.h +0 -741
  241. data/vendor/spidermonkey/jsexn.c +0 -1371
  242. data/vendor/spidermonkey/jsexn.h +0 -96
  243. data/vendor/spidermonkey/jsfile.c +0 -2736
  244. data/vendor/spidermonkey/jsfile.h +0 -56
  245. data/vendor/spidermonkey/jsfile.msg +0 -90
  246. data/vendor/spidermonkey/jsfun.c +0 -2634
  247. data/vendor/spidermonkey/jsfun.h +0 -254
  248. data/vendor/spidermonkey/jsgc.c +0 -3562
  249. data/vendor/spidermonkey/jsgc.h +0 -403
  250. data/vendor/spidermonkey/jshash.c +0 -476
  251. data/vendor/spidermonkey/jshash.h +0 -151
  252. data/vendor/spidermonkey/jsify.pl +0 -485
  253. data/vendor/spidermonkey/jsinterp.c +0 -7007
  254. data/vendor/spidermonkey/jsinterp.h +0 -525
  255. data/vendor/spidermonkey/jsinvoke.c +0 -43
  256. data/vendor/spidermonkey/jsiter.c +0 -1067
  257. data/vendor/spidermonkey/jsiter.h +0 -122
  258. data/vendor/spidermonkey/jskeyword.tbl +0 -124
  259. data/vendor/spidermonkey/jskwgen.c +0 -460
  260. data/vendor/spidermonkey/jslibmath.h +0 -266
  261. data/vendor/spidermonkey/jslock.c +0 -1309
  262. data/vendor/spidermonkey/jslock.h +0 -313
  263. data/vendor/spidermonkey/jslocko.asm +0 -60
  264. data/vendor/spidermonkey/jslog2.c +0 -94
  265. data/vendor/spidermonkey/jslong.c +0 -264
  266. data/vendor/spidermonkey/jslong.h +0 -412
  267. data/vendor/spidermonkey/jsmath.c +0 -567
  268. data/vendor/spidermonkey/jsmath.h +0 -57
  269. data/vendor/spidermonkey/jsnum.c +0 -1239
  270. data/vendor/spidermonkey/jsnum.h +0 -283
  271. data/vendor/spidermonkey/jsobj.c +0 -5282
  272. data/vendor/spidermonkey/jsobj.h +0 -709
  273. data/vendor/spidermonkey/jsopcode.c +0 -5245
  274. data/vendor/spidermonkey/jsopcode.h +0 -394
  275. data/vendor/spidermonkey/jsopcode.tbl +0 -523
  276. data/vendor/spidermonkey/jsotypes.h +0 -202
  277. data/vendor/spidermonkey/jsparse.c +0 -6704
  278. data/vendor/spidermonkey/jsparse.h +0 -511
  279. data/vendor/spidermonkey/jsprf.c +0 -1264
  280. data/vendor/spidermonkey/jsprf.h +0 -150
  281. data/vendor/spidermonkey/jsproto.tbl +0 -128
  282. data/vendor/spidermonkey/jsprvtd.h +0 -267
  283. data/vendor/spidermonkey/jspubtd.h +0 -744
  284. data/vendor/spidermonkey/jsregexp.c +0 -4364
  285. data/vendor/spidermonkey/jsregexp.h +0 -183
  286. data/vendor/spidermonkey/jsreops.tbl +0 -145
  287. data/vendor/spidermonkey/jsscan.c +0 -2012
  288. data/vendor/spidermonkey/jsscan.h +0 -387
  289. data/vendor/spidermonkey/jsscope.c +0 -1957
  290. data/vendor/spidermonkey/jsscope.h +0 -418
  291. data/vendor/spidermonkey/jsscript.c +0 -1832
  292. data/vendor/spidermonkey/jsscript.h +0 -287
  293. data/vendor/spidermonkey/jsshell.msg +0 -50
  294. data/vendor/spidermonkey/jsstddef.h +0 -83
  295. data/vendor/spidermonkey/jsstr.c +0 -5005
  296. data/vendor/spidermonkey/jsstr.h +0 -641
  297. data/vendor/spidermonkey/jstypes.h +0 -475
  298. data/vendor/spidermonkey/jsutil.c +0 -345
  299. data/vendor/spidermonkey/jsutil.h +0 -157
  300. data/vendor/spidermonkey/jsxdrapi.c +0 -800
  301. data/vendor/spidermonkey/jsxdrapi.h +0 -218
  302. data/vendor/spidermonkey/jsxml.c +0 -8476
  303. data/vendor/spidermonkey/jsxml.h +0 -349
  304. data/vendor/spidermonkey/lock_SunOS.s +0 -119
  305. data/vendor/spidermonkey/perfect.js +0 -39
  306. data/vendor/spidermonkey/plify_jsdhash.sed +0 -36
  307. data/vendor/spidermonkey/prmjtime.c +0 -846
  308. data/vendor/spidermonkey/prmjtime.h +0 -103
  309. data/vendor/spidermonkey/resource.h +0 -15
  310. data/vendor/spidermonkey/rules.mk +0 -197
  311. data/vendor/spidermonkey/win32.order +0 -384
@@ -1,3167 +0,0 @@
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
- }