johnson 1.1.0

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