johnson 2.0.0.pre1 → 2.0.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (311) hide show
  1. data/CHANGELOG.rdoc +12 -0
  2. data/Manifest.txt +4 -285
  3. data/Rakefile +13 -20
  4. data/ext/tracemonkey/global.cc +4 -1
  5. data/ext/tracemonkey/js.cc +30 -33
  6. data/ext/tracemonkey/runtime.cc +96 -6
  7. data/ext/tracemonkey/split_global.cc +0 -5
  8. data/ext/tracemonkey/tracemonkey.h +2 -2
  9. data/lib/johnson.rb +2 -2
  10. data/lib/johnson/runtime.rb +25 -15
  11. data/lib/johnson/tracemonkey/runtime.rb +6 -3
  12. data/vendor/tracemonkey/config/system-headers +1 -3
  13. data/vendor/tracemonkey/jscntxt.h +5 -2
  14. data/vendor/tracemonkey/jsdbgapi.cpp +9 -1
  15. data/vendor/tracemonkey/jsdbgapi.h +4 -0
  16. data/vendor/tracemonkey/tests/ecma/NativeObjects/browser.js +0 -0
  17. data/vendor/tracemonkey/tests/ecma/NativeObjects/jstests.list +0 -0
  18. data/vendor/tracemonkey/tests/ecma_3_1/Object/jstests.list +1 -1
  19. data/vendor/tracemonkey/tests/js1_3/misc/browser.js +0 -0
  20. data/vendor/tracemonkey/tests/js1_3/misc/jstests.list +0 -0
  21. data/vendor/tracemonkey/tests/js1_5/Regress/jstests.list +4 -4
  22. data/vendor/tracemonkey/tests/js1_5/Scope/jstests.list +1 -1
  23. data/vendor/tracemonkey/tests/js1_5/decompilation/jstests.list +2 -2
  24. data/vendor/tracemonkey/tests/js1_7/decompilation/jstests.list +1 -1
  25. data/vendor/tracemonkey/tests/shell.js +2 -1
  26. metadata +51 -309
  27. data/ext/spidermonkey/context.c +0 -116
  28. data/ext/spidermonkey/context.h +0 -19
  29. data/ext/spidermonkey/conversions.c +0 -361
  30. data/ext/spidermonkey/conversions.h +0 -31
  31. data/ext/spidermonkey/debugger.c +0 -234
  32. data/ext/spidermonkey/debugger.h +0 -10
  33. data/ext/spidermonkey/extconf.rb +0 -32
  34. data/ext/spidermonkey/extensions.c +0 -37
  35. data/ext/spidermonkey/extensions.h +0 -12
  36. data/ext/spidermonkey/global.c +0 -40
  37. data/ext/spidermonkey/global.h +0 -11
  38. data/ext/spidermonkey/idhash.c +0 -16
  39. data/ext/spidermonkey/idhash.h +0 -8
  40. data/ext/spidermonkey/immutable_node.c +0 -1153
  41. data/ext/spidermonkey/immutable_node.c.erb +0 -523
  42. data/ext/spidermonkey/immutable_node.h +0 -22
  43. data/ext/spidermonkey/jroot.h +0 -197
  44. data/ext/spidermonkey/js_land_proxy.c +0 -620
  45. data/ext/spidermonkey/js_land_proxy.h +0 -20
  46. data/ext/spidermonkey/ruby_land_proxy.c +0 -618
  47. data/ext/spidermonkey/ruby_land_proxy.h +0 -38
  48. data/ext/spidermonkey/runtime.c +0 -396
  49. data/ext/spidermonkey/runtime.h +0 -27
  50. data/ext/spidermonkey/spidermonkey.c +0 -22
  51. data/ext/spidermonkey/spidermonkey.h +0 -29
  52. data/lib/johnson/spidermonkey.rb +0 -12
  53. data/lib/johnson/spidermonkey/context.rb +0 -10
  54. data/lib/johnson/spidermonkey/debugger.rb +0 -67
  55. data/lib/johnson/spidermonkey/immutable_node.rb +0 -282
  56. data/lib/johnson/spidermonkey/js_land_proxy.rb +0 -64
  57. data/lib/johnson/spidermonkey/mutable_tree_visitor.rb +0 -242
  58. data/lib/johnson/spidermonkey/ruby_land_proxy.rb +0 -17
  59. data/lib/johnson/spidermonkey/runtime.rb +0 -74
  60. data/test/johnson/spidermonkey/context_test.rb +0 -21
  61. data/test/johnson/spidermonkey/immutable_node_test.rb +0 -34
  62. data/test/johnson/spidermonkey/js_land_proxy_test.rb +0 -273
  63. data/test/johnson/spidermonkey/ruby_land_proxy_test.rb +0 -274
  64. data/test/johnson/spidermonkey/runtime_test.rb +0 -41
  65. data/vendor/spidermonkey/.cvsignore +0 -9
  66. data/vendor/spidermonkey/Makefile.in +0 -449
  67. data/vendor/spidermonkey/Makefile.ref +0 -365
  68. data/vendor/spidermonkey/README.html +0 -820
  69. data/vendor/spidermonkey/SpiderMonkey.rsp +0 -12
  70. data/vendor/spidermonkey/Y.js +0 -19
  71. data/vendor/spidermonkey/build.mk +0 -43
  72. data/vendor/spidermonkey/config.mk +0 -192
  73. data/vendor/spidermonkey/config/AIX4.1.mk +0 -65
  74. data/vendor/spidermonkey/config/AIX4.2.mk +0 -64
  75. data/vendor/spidermonkey/config/AIX4.3.mk +0 -65
  76. data/vendor/spidermonkey/config/Darwin.mk +0 -83
  77. data/vendor/spidermonkey/config/Darwin1.3.mk +0 -81
  78. data/vendor/spidermonkey/config/Darwin1.4.mk +0 -41
  79. data/vendor/spidermonkey/config/Darwin5.2.mk +0 -81
  80. data/vendor/spidermonkey/config/Darwin5.3.mk +0 -81
  81. data/vendor/spidermonkey/config/HP-UXB.10.10.mk +0 -77
  82. data/vendor/spidermonkey/config/HP-UXB.10.20.mk +0 -77
  83. data/vendor/spidermonkey/config/HP-UXB.11.00.mk +0 -80
  84. data/vendor/spidermonkey/config/IRIX.mk +0 -87
  85. data/vendor/spidermonkey/config/IRIX5.3.mk +0 -44
  86. data/vendor/spidermonkey/config/IRIX6.1.mk +0 -44
  87. data/vendor/spidermonkey/config/IRIX6.2.mk +0 -44
  88. data/vendor/spidermonkey/config/IRIX6.3.mk +0 -44
  89. data/vendor/spidermonkey/config/IRIX6.5.mk +0 -44
  90. data/vendor/spidermonkey/config/Linux_All.mk +0 -103
  91. data/vendor/spidermonkey/config/Mac_OS10.0.mk +0 -82
  92. data/vendor/spidermonkey/config/OSF1V4.0.mk +0 -72
  93. data/vendor/spidermonkey/config/OSF1V5.0.mk +0 -69
  94. data/vendor/spidermonkey/config/SunOS4.1.4.mk +0 -101
  95. data/vendor/spidermonkey/config/SunOS5.10.mk +0 -50
  96. data/vendor/spidermonkey/config/SunOS5.3.mk +0 -91
  97. data/vendor/spidermonkey/config/SunOS5.4.mk +0 -92
  98. data/vendor/spidermonkey/config/SunOS5.5.1.mk +0 -44
  99. data/vendor/spidermonkey/config/SunOS5.5.mk +0 -87
  100. data/vendor/spidermonkey/config/SunOS5.6.mk +0 -89
  101. data/vendor/spidermonkey/config/SunOS5.7.mk +0 -44
  102. data/vendor/spidermonkey/config/SunOS5.8.mk +0 -44
  103. data/vendor/spidermonkey/config/SunOS5.9.mk +0 -44
  104. data/vendor/spidermonkey/config/WINNT4.0.mk +0 -117
  105. data/vendor/spidermonkey/config/WINNT5.0.mk +0 -117
  106. data/vendor/spidermonkey/config/WINNT5.1.mk +0 -117
  107. data/vendor/spidermonkey/config/WINNT5.2.mk +0 -117
  108. data/vendor/spidermonkey/config/WINNT6.0.mk +0 -117
  109. data/vendor/spidermonkey/config/dgux.mk +0 -64
  110. data/vendor/spidermonkey/editline/Makefile.ref +0 -144
  111. data/vendor/spidermonkey/editline/README +0 -83
  112. data/vendor/spidermonkey/editline/editline.3 +0 -175
  113. data/vendor/spidermonkey/editline/editline.c +0 -1369
  114. data/vendor/spidermonkey/editline/editline.h +0 -135
  115. data/vendor/spidermonkey/editline/sysunix.c +0 -182
  116. data/vendor/spidermonkey/editline/unix.h +0 -82
  117. data/vendor/spidermonkey/fdlibm/.cvsignore +0 -7
  118. data/vendor/spidermonkey/fdlibm/Makefile.in +0 -127
  119. data/vendor/spidermonkey/fdlibm/Makefile.ref +0 -192
  120. data/vendor/spidermonkey/fdlibm/e_acos.c +0 -147
  121. data/vendor/spidermonkey/fdlibm/e_acosh.c +0 -105
  122. data/vendor/spidermonkey/fdlibm/e_asin.c +0 -156
  123. data/vendor/spidermonkey/fdlibm/e_atan2.c +0 -165
  124. data/vendor/spidermonkey/fdlibm/e_atanh.c +0 -110
  125. data/vendor/spidermonkey/fdlibm/e_cosh.c +0 -133
  126. data/vendor/spidermonkey/fdlibm/e_exp.c +0 -202
  127. data/vendor/spidermonkey/fdlibm/e_fmod.c +0 -184
  128. data/vendor/spidermonkey/fdlibm/e_gamma.c +0 -71
  129. data/vendor/spidermonkey/fdlibm/e_gamma_r.c +0 -70
  130. data/vendor/spidermonkey/fdlibm/e_hypot.c +0 -173
  131. data/vendor/spidermonkey/fdlibm/e_j0.c +0 -524
  132. data/vendor/spidermonkey/fdlibm/e_j1.c +0 -523
  133. data/vendor/spidermonkey/fdlibm/e_jn.c +0 -315
  134. data/vendor/spidermonkey/fdlibm/e_lgamma.c +0 -71
  135. data/vendor/spidermonkey/fdlibm/e_lgamma_r.c +0 -347
  136. data/vendor/spidermonkey/fdlibm/e_log.c +0 -184
  137. data/vendor/spidermonkey/fdlibm/e_log10.c +0 -134
  138. data/vendor/spidermonkey/fdlibm/e_pow.c +0 -386
  139. data/vendor/spidermonkey/fdlibm/e_rem_pio2.c +0 -222
  140. data/vendor/spidermonkey/fdlibm/e_remainder.c +0 -120
  141. data/vendor/spidermonkey/fdlibm/e_scalb.c +0 -89
  142. data/vendor/spidermonkey/fdlibm/e_sinh.c +0 -122
  143. data/vendor/spidermonkey/fdlibm/e_sqrt.c +0 -497
  144. data/vendor/spidermonkey/fdlibm/fdlibm.h +0 -273
  145. data/vendor/spidermonkey/fdlibm/fdlibm.mak +0 -1453
  146. data/vendor/spidermonkey/fdlibm/fdlibm.mdp +0 -0
  147. data/vendor/spidermonkey/fdlibm/k_cos.c +0 -135
  148. data/vendor/spidermonkey/fdlibm/k_rem_pio2.c +0 -354
  149. data/vendor/spidermonkey/fdlibm/k_sin.c +0 -114
  150. data/vendor/spidermonkey/fdlibm/k_standard.c +0 -785
  151. data/vendor/spidermonkey/fdlibm/k_tan.c +0 -170
  152. data/vendor/spidermonkey/fdlibm/s_asinh.c +0 -101
  153. data/vendor/spidermonkey/fdlibm/s_atan.c +0 -175
  154. data/vendor/spidermonkey/fdlibm/s_cbrt.c +0 -133
  155. data/vendor/spidermonkey/fdlibm/s_ceil.c +0 -120
  156. data/vendor/spidermonkey/fdlibm/s_copysign.c +0 -72
  157. data/vendor/spidermonkey/fdlibm/s_cos.c +0 -118
  158. data/vendor/spidermonkey/fdlibm/s_erf.c +0 -356
  159. data/vendor/spidermonkey/fdlibm/s_expm1.c +0 -267
  160. data/vendor/spidermonkey/fdlibm/s_fabs.c +0 -70
  161. data/vendor/spidermonkey/fdlibm/s_finite.c +0 -71
  162. data/vendor/spidermonkey/fdlibm/s_floor.c +0 -121
  163. data/vendor/spidermonkey/fdlibm/s_frexp.c +0 -99
  164. data/vendor/spidermonkey/fdlibm/s_ilogb.c +0 -85
  165. data/vendor/spidermonkey/fdlibm/s_isnan.c +0 -74
  166. data/vendor/spidermonkey/fdlibm/s_ldexp.c +0 -66
  167. data/vendor/spidermonkey/fdlibm/s_lib_version.c +0 -73
  168. data/vendor/spidermonkey/fdlibm/s_log1p.c +0 -211
  169. data/vendor/spidermonkey/fdlibm/s_logb.c +0 -79
  170. data/vendor/spidermonkey/fdlibm/s_matherr.c +0 -64
  171. data/vendor/spidermonkey/fdlibm/s_modf.c +0 -132
  172. data/vendor/spidermonkey/fdlibm/s_nextafter.c +0 -124
  173. data/vendor/spidermonkey/fdlibm/s_rint.c +0 -131
  174. data/vendor/spidermonkey/fdlibm/s_scalbn.c +0 -107
  175. data/vendor/spidermonkey/fdlibm/s_signgam.c +0 -40
  176. data/vendor/spidermonkey/fdlibm/s_significand.c +0 -68
  177. data/vendor/spidermonkey/fdlibm/s_sin.c +0 -118
  178. data/vendor/spidermonkey/fdlibm/s_tan.c +0 -112
  179. data/vendor/spidermonkey/fdlibm/s_tanh.c +0 -122
  180. data/vendor/spidermonkey/fdlibm/w_acos.c +0 -78
  181. data/vendor/spidermonkey/fdlibm/w_acosh.c +0 -78
  182. data/vendor/spidermonkey/fdlibm/w_asin.c +0 -80
  183. data/vendor/spidermonkey/fdlibm/w_atan2.c +0 -79
  184. data/vendor/spidermonkey/fdlibm/w_atanh.c +0 -81
  185. data/vendor/spidermonkey/fdlibm/w_cosh.c +0 -77
  186. data/vendor/spidermonkey/fdlibm/w_exp.c +0 -88
  187. data/vendor/spidermonkey/fdlibm/w_fmod.c +0 -78
  188. data/vendor/spidermonkey/fdlibm/w_gamma.c +0 -85
  189. data/vendor/spidermonkey/fdlibm/w_gamma_r.c +0 -81
  190. data/vendor/spidermonkey/fdlibm/w_hypot.c +0 -78
  191. data/vendor/spidermonkey/fdlibm/w_j0.c +0 -105
  192. data/vendor/spidermonkey/fdlibm/w_j1.c +0 -106
  193. data/vendor/spidermonkey/fdlibm/w_jn.c +0 -128
  194. data/vendor/spidermonkey/fdlibm/w_lgamma.c +0 -85
  195. data/vendor/spidermonkey/fdlibm/w_lgamma_r.c +0 -81
  196. data/vendor/spidermonkey/fdlibm/w_log.c +0 -78
  197. data/vendor/spidermonkey/fdlibm/w_log10.c +0 -81
  198. data/vendor/spidermonkey/fdlibm/w_pow.c +0 -99
  199. data/vendor/spidermonkey/fdlibm/w_remainder.c +0 -77
  200. data/vendor/spidermonkey/fdlibm/w_scalb.c +0 -95
  201. data/vendor/spidermonkey/fdlibm/w_sinh.c +0 -77
  202. data/vendor/spidermonkey/fdlibm/w_sqrt.c +0 -77
  203. data/vendor/spidermonkey/javascript-trace.d +0 -73
  204. data/vendor/spidermonkey/js.c +0 -3951
  205. data/vendor/spidermonkey/js.mdp +0 -0
  206. data/vendor/spidermonkey/js.msg +0 -308
  207. data/vendor/spidermonkey/js.pkg +0 -2
  208. data/vendor/spidermonkey/js3240.rc +0 -79
  209. data/vendor/spidermonkey/jsOS240.def +0 -654
  210. data/vendor/spidermonkey/jsapi.c +0 -5836
  211. data/vendor/spidermonkey/jsapi.h +0 -2624
  212. data/vendor/spidermonkey/jsarena.c +0 -450
  213. data/vendor/spidermonkey/jsarena.h +0 -318
  214. data/vendor/spidermonkey/jsarray.c +0 -2996
  215. data/vendor/spidermonkey/jsarray.h +0 -127
  216. data/vendor/spidermonkey/jsatom.c +0 -1045
  217. data/vendor/spidermonkey/jsatom.h +0 -442
  218. data/vendor/spidermonkey/jsbit.h +0 -253
  219. data/vendor/spidermonkey/jsbool.c +0 -176
  220. data/vendor/spidermonkey/jsbool.h +0 -73
  221. data/vendor/spidermonkey/jsclist.h +0 -139
  222. data/vendor/spidermonkey/jscntxt.c +0 -1348
  223. data/vendor/spidermonkey/jscntxt.h +0 -1120
  224. data/vendor/spidermonkey/jscompat.h +0 -57
  225. data/vendor/spidermonkey/jsconfig.h +0 -248
  226. data/vendor/spidermonkey/jsconfig.mk +0 -181
  227. data/vendor/spidermonkey/jscpucfg.c +0 -396
  228. data/vendor/spidermonkey/jscpucfg.h +0 -212
  229. data/vendor/spidermonkey/jsdate.c +0 -2390
  230. data/vendor/spidermonkey/jsdate.h +0 -124
  231. data/vendor/spidermonkey/jsdbgapi.c +0 -1802
  232. data/vendor/spidermonkey/jsdbgapi.h +0 -464
  233. data/vendor/spidermonkey/jsdhash.c +0 -868
  234. data/vendor/spidermonkey/jsdhash.h +0 -592
  235. data/vendor/spidermonkey/jsdtoa.c +0 -3167
  236. data/vendor/spidermonkey/jsdtoa.h +0 -130
  237. data/vendor/spidermonkey/jsdtracef.c +0 -317
  238. data/vendor/spidermonkey/jsdtracef.h +0 -77
  239. data/vendor/spidermonkey/jsemit.c +0 -6909
  240. data/vendor/spidermonkey/jsemit.h +0 -741
  241. data/vendor/spidermonkey/jsexn.c +0 -1371
  242. data/vendor/spidermonkey/jsexn.h +0 -96
  243. data/vendor/spidermonkey/jsfile.c +0 -2736
  244. data/vendor/spidermonkey/jsfile.h +0 -56
  245. data/vendor/spidermonkey/jsfile.msg +0 -90
  246. data/vendor/spidermonkey/jsfun.c +0 -2634
  247. data/vendor/spidermonkey/jsfun.h +0 -254
  248. data/vendor/spidermonkey/jsgc.c +0 -3562
  249. data/vendor/spidermonkey/jsgc.h +0 -403
  250. data/vendor/spidermonkey/jshash.c +0 -476
  251. data/vendor/spidermonkey/jshash.h +0 -151
  252. data/vendor/spidermonkey/jsify.pl +0 -485
  253. data/vendor/spidermonkey/jsinterp.c +0 -7007
  254. data/vendor/spidermonkey/jsinterp.h +0 -525
  255. data/vendor/spidermonkey/jsinvoke.c +0 -43
  256. data/vendor/spidermonkey/jsiter.c +0 -1067
  257. data/vendor/spidermonkey/jsiter.h +0 -122
  258. data/vendor/spidermonkey/jskeyword.tbl +0 -124
  259. data/vendor/spidermonkey/jskwgen.c +0 -460
  260. data/vendor/spidermonkey/jslibmath.h +0 -266
  261. data/vendor/spidermonkey/jslock.c +0 -1309
  262. data/vendor/spidermonkey/jslock.h +0 -313
  263. data/vendor/spidermonkey/jslocko.asm +0 -60
  264. data/vendor/spidermonkey/jslog2.c +0 -94
  265. data/vendor/spidermonkey/jslong.c +0 -264
  266. data/vendor/spidermonkey/jslong.h +0 -412
  267. data/vendor/spidermonkey/jsmath.c +0 -567
  268. data/vendor/spidermonkey/jsmath.h +0 -57
  269. data/vendor/spidermonkey/jsnum.c +0 -1239
  270. data/vendor/spidermonkey/jsnum.h +0 -283
  271. data/vendor/spidermonkey/jsobj.c +0 -5282
  272. data/vendor/spidermonkey/jsobj.h +0 -709
  273. data/vendor/spidermonkey/jsopcode.c +0 -5245
  274. data/vendor/spidermonkey/jsopcode.h +0 -394
  275. data/vendor/spidermonkey/jsopcode.tbl +0 -523
  276. data/vendor/spidermonkey/jsotypes.h +0 -202
  277. data/vendor/spidermonkey/jsparse.c +0 -6704
  278. data/vendor/spidermonkey/jsparse.h +0 -511
  279. data/vendor/spidermonkey/jsprf.c +0 -1264
  280. data/vendor/spidermonkey/jsprf.h +0 -150
  281. data/vendor/spidermonkey/jsproto.tbl +0 -128
  282. data/vendor/spidermonkey/jsprvtd.h +0 -267
  283. data/vendor/spidermonkey/jspubtd.h +0 -744
  284. data/vendor/spidermonkey/jsregexp.c +0 -4364
  285. data/vendor/spidermonkey/jsregexp.h +0 -183
  286. data/vendor/spidermonkey/jsreops.tbl +0 -145
  287. data/vendor/spidermonkey/jsscan.c +0 -2012
  288. data/vendor/spidermonkey/jsscan.h +0 -387
  289. data/vendor/spidermonkey/jsscope.c +0 -1957
  290. data/vendor/spidermonkey/jsscope.h +0 -418
  291. data/vendor/spidermonkey/jsscript.c +0 -1832
  292. data/vendor/spidermonkey/jsscript.h +0 -287
  293. data/vendor/spidermonkey/jsshell.msg +0 -50
  294. data/vendor/spidermonkey/jsstddef.h +0 -83
  295. data/vendor/spidermonkey/jsstr.c +0 -5005
  296. data/vendor/spidermonkey/jsstr.h +0 -641
  297. data/vendor/spidermonkey/jstypes.h +0 -475
  298. data/vendor/spidermonkey/jsutil.c +0 -345
  299. data/vendor/spidermonkey/jsutil.h +0 -157
  300. data/vendor/spidermonkey/jsxdrapi.c +0 -800
  301. data/vendor/spidermonkey/jsxdrapi.h +0 -218
  302. data/vendor/spidermonkey/jsxml.c +0 -8476
  303. data/vendor/spidermonkey/jsxml.h +0 -349
  304. data/vendor/spidermonkey/lock_SunOS.s +0 -119
  305. data/vendor/spidermonkey/perfect.js +0 -39
  306. data/vendor/spidermonkey/plify_jsdhash.sed +0 -36
  307. data/vendor/spidermonkey/prmjtime.c +0 -846
  308. data/vendor/spidermonkey/prmjtime.h +0 -103
  309. data/vendor/spidermonkey/resource.h +0 -15
  310. data/vendor/spidermonkey/rules.mk +0 -197
  311. data/vendor/spidermonkey/win32.order +0 -384
@@ -1,2390 +0,0 @@
1
- /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2
- * vim: set ts=8 sw=4 et tw=78:
3
- *
4
- * ***** BEGIN LICENSE BLOCK *****
5
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6
- *
7
- * The contents of this file are subject to the Mozilla Public License Version
8
- * 1.1 (the "License"); you may not use this file except in compliance with
9
- * the License. You may obtain a copy of the License at
10
- * http://www.mozilla.org/MPL/
11
- *
12
- * Software distributed under the License is distributed on an "AS IS" basis,
13
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14
- * for the specific language governing rights and limitations under the
15
- * License.
16
- *
17
- * The Original Code is Mozilla Communicator client code, released
18
- * March 31, 1998.
19
- *
20
- * The Initial Developer of the Original Code is
21
- * Netscape Communications Corporation.
22
- * Portions created by the Initial Developer are Copyright (C) 1998
23
- * the Initial Developer. All Rights Reserved.
24
- *
25
- * Contributor(s):
26
- *
27
- * Alternatively, the contents of this file may be used under the terms of
28
- * either of the GNU General Public License Version 2 or later (the "GPL"),
29
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30
- * in which case the provisions of the GPL or the LGPL are applicable instead
31
- * of those above. If you wish to allow use of your version of this file only
32
- * under the terms of either the GPL or the LGPL, and not to allow others to
33
- * use your version of this file under the terms of the MPL, indicate your
34
- * decision by deleting the provisions above and replace them with the notice
35
- * and other provisions required by the GPL or the LGPL. If you do not delete
36
- * the provisions above, a recipient may use your version of this file under
37
- * the terms of any one of the MPL, the GPL or the LGPL.
38
- *
39
- * ***** END LICENSE BLOCK ***** */
40
-
41
- /*
42
- * JS date methods.
43
- */
44
-
45
- /*
46
- * "For example, OS/360 devotes 26 bytes of the permanently
47
- * resident date-turnover routine to the proper handling of
48
- * December 31 on leap years (when it is Day 366). That
49
- * might have been left to the operator."
50
- *
51
- * Frederick Brooks, 'The Second-System Effect'.
52
- */
53
-
54
- #include "jsstddef.h"
55
- #include <ctype.h>
56
- #include <locale.h>
57
- #include <math.h>
58
- #include <stdlib.h>
59
- #include <string.h>
60
- #include "jstypes.h"
61
- #include "jsprf.h"
62
- #include "prmjtime.h"
63
- #include "jsutil.h" /* Added by JSIFY */
64
- #include "jsapi.h"
65
- #include "jsconfig.h"
66
- #include "jscntxt.h"
67
- #include "jsdate.h"
68
- #include "jsinterp.h"
69
- #include "jsnum.h"
70
- #include "jsobj.h"
71
- #include "jsstr.h"
72
-
73
- /*
74
- * The JS 'Date' object is patterned after the Java 'Date' object.
75
- * Here is an script:
76
- *
77
- * today = new Date();
78
- *
79
- * print(today.toLocaleString());
80
- *
81
- * weekDay = today.getDay();
82
- *
83
- *
84
- * These Java (and ECMA-262) methods are supported:
85
- *
86
- * UTC
87
- * getDate (getUTCDate)
88
- * getDay (getUTCDay)
89
- * getHours (getUTCHours)
90
- * getMinutes (getUTCMinutes)
91
- * getMonth (getUTCMonth)
92
- * getSeconds (getUTCSeconds)
93
- * getMilliseconds (getUTCMilliseconds)
94
- * getTime
95
- * getTimezoneOffset
96
- * getYear
97
- * getFullYear (getUTCFullYear)
98
- * parse
99
- * setDate (setUTCDate)
100
- * setHours (setUTCHours)
101
- * setMinutes (setUTCMinutes)
102
- * setMonth (setUTCMonth)
103
- * setSeconds (setUTCSeconds)
104
- * setMilliseconds (setUTCMilliseconds)
105
- * setTime
106
- * setYear (setFullYear, setUTCFullYear)
107
- * toGMTString (toUTCString)
108
- * toLocaleString
109
- * toString
110
- *
111
- *
112
- * These Java methods are not supported
113
- *
114
- * setDay
115
- * before
116
- * after
117
- * equals
118
- * hashCode
119
- */
120
-
121
- /*
122
- * 11/97 - jsdate.c has been rewritten to conform to the ECMA-262 language
123
- * definition and reduce dependence on NSPR. NSPR is used to get the current
124
- * time in milliseconds, the time zone offset, and the daylight savings time
125
- * offset for a given time. NSPR is also used for Date.toLocaleString(), for
126
- * locale-specific formatting, and to get a string representing the timezone.
127
- * (Which turns out to be platform-dependent.)
128
- *
129
- * To do:
130
- * (I did some performance tests by timing how long it took to run what
131
- * I had of the js ECMA conformance tests.)
132
- *
133
- * - look at saving results across multiple calls to supporting
134
- * functions; the toString functions compute some of the same values
135
- * multiple times. Although - I took a quick stab at this, and I lost
136
- * rather than gained. (Fractionally.) Hard to tell what compilers/processors
137
- * are doing these days.
138
- *
139
- * - look at tweaking function return types to return double instead
140
- * of int; this seems to make things run slightly faster sometimes.
141
- * (though it could be architecture-dependent.) It'd be good to see
142
- * how this does on win32. (Tried it on irix.) Types could use a
143
- * general going-over.
144
- */
145
-
146
- /*
147
- * Supporting functions - ECMA 15.9.1.*
148
- */
149
-
150
- #define HalfTimeDomain 8.64e15
151
- #define HoursPerDay 24.0
152
- #define MinutesPerDay (HoursPerDay * MinutesPerHour)
153
- #define MinutesPerHour 60.0
154
- #define SecondsPerDay (MinutesPerDay * SecondsPerMinute)
155
- #define SecondsPerHour (MinutesPerHour * SecondsPerMinute)
156
- #define SecondsPerMinute 60.0
157
-
158
- #if defined(XP_WIN) || defined(XP_OS2)
159
- /* Work around msvc double optimization bug by making these runtime values; if
160
- * they're available at compile time, msvc optimizes division by them by
161
- * computing the reciprocal and multiplying instead of dividing - this loses
162
- * when the reciprocal isn't representable in a double.
163
- */
164
- static jsdouble msPerSecond = 1000.0;
165
- static jsdouble msPerDay = SecondsPerDay * 1000.0;
166
- static jsdouble msPerHour = SecondsPerHour * 1000.0;
167
- static jsdouble msPerMinute = SecondsPerMinute * 1000.0;
168
- #else
169
- #define msPerDay (SecondsPerDay * msPerSecond)
170
- #define msPerHour (SecondsPerHour * msPerSecond)
171
- #define msPerMinute (SecondsPerMinute * msPerSecond)
172
- #define msPerSecond 1000.0
173
- #endif
174
-
175
- #define Day(t) floor((t) / msPerDay)
176
-
177
- static jsdouble
178
- TimeWithinDay(jsdouble t)
179
- {
180
- jsdouble result;
181
- result = fmod(t, msPerDay);
182
- if (result < 0)
183
- result += msPerDay;
184
- return result;
185
- }
186
-
187
- #define DaysInYear(y) ((y) % 4 == 0 && ((y) % 100 || ((y) % 400 == 0)) \
188
- ? 366 : 365)
189
-
190
- /* math here has to be f.p, because we need
191
- * floor((1968 - 1969) / 4) == -1
192
- */
193
- #define DayFromYear(y) (365 * ((y)-1970) + floor(((y)-1969)/4.0) \
194
- - floor(((y)-1901)/100.0) + floor(((y)-1601)/400.0))
195
- #define TimeFromYear(y) (DayFromYear(y) * msPerDay)
196
-
197
- static jsint
198
- YearFromTime(jsdouble t)
199
- {
200
- jsint y = (jsint) floor(t /(msPerDay*365.2425)) + 1970;
201
- jsdouble t2 = (jsdouble) TimeFromYear(y);
202
-
203
- if (t2 > t) {
204
- y--;
205
- } else {
206
- if (t2 + msPerDay * DaysInYear(y) <= t)
207
- y++;
208
- }
209
- return y;
210
- }
211
-
212
- #define InLeapYear(t) (JSBool) (DaysInYear(YearFromTime(t)) == 366)
213
-
214
- #define DayWithinYear(t, year) ((intN) (Day(t) - DayFromYear(year)))
215
-
216
- /*
217
- * The following array contains the day of year for the first day of
218
- * each month, where index 0 is January, and day 0 is January 1.
219
- */
220
- static jsdouble firstDayOfMonth[2][12] = {
221
- {0.0, 31.0, 59.0, 90.0, 120.0, 151.0, 181.0, 212.0, 243.0, 273.0, 304.0, 334.0},
222
- {0.0, 31.0, 60.0, 91.0, 121.0, 152.0, 182.0, 213.0, 244.0, 274.0, 305.0, 335.0}
223
- };
224
-
225
- #define DayFromMonth(m, leap) firstDayOfMonth[leap][(intN)m];
226
-
227
- static intN
228
- MonthFromTime(jsdouble t)
229
- {
230
- intN d, step;
231
- jsint year = YearFromTime(t);
232
- d = DayWithinYear(t, year);
233
-
234
- if (d < (step = 31))
235
- return 0;
236
- step += (InLeapYear(t) ? 29 : 28);
237
- if (d < step)
238
- return 1;
239
- if (d < (step += 31))
240
- return 2;
241
- if (d < (step += 30))
242
- return 3;
243
- if (d < (step += 31))
244
- return 4;
245
- if (d < (step += 30))
246
- return 5;
247
- if (d < (step += 31))
248
- return 6;
249
- if (d < (step += 31))
250
- return 7;
251
- if (d < (step += 30))
252
- return 8;
253
- if (d < (step += 31))
254
- return 9;
255
- if (d < (step += 30))
256
- return 10;
257
- return 11;
258
- }
259
-
260
- static intN
261
- DateFromTime(jsdouble t)
262
- {
263
- intN d, step, next;
264
- jsint year = YearFromTime(t);
265
- d = DayWithinYear(t, year);
266
-
267
- if (d <= (next = 30))
268
- return d + 1;
269
- step = next;
270
- next += (InLeapYear(t) ? 29 : 28);
271
- if (d <= next)
272
- return d - step;
273
- step = next;
274
- if (d <= (next += 31))
275
- return d - step;
276
- step = next;
277
- if (d <= (next += 30))
278
- return d - step;
279
- step = next;
280
- if (d <= (next += 31))
281
- return d - step;
282
- step = next;
283
- if (d <= (next += 30))
284
- return d - step;
285
- step = next;
286
- if (d <= (next += 31))
287
- return d - step;
288
- step = next;
289
- if (d <= (next += 31))
290
- return d - step;
291
- step = next;
292
- if (d <= (next += 30))
293
- return d - step;
294
- step = next;
295
- if (d <= (next += 31))
296
- return d - step;
297
- step = next;
298
- if (d <= (next += 30))
299
- return d - step;
300
- step = next;
301
- return d - step;
302
- }
303
-
304
- static intN
305
- WeekDay(jsdouble t)
306
- {
307
- jsint result;
308
- result = (jsint) Day(t) + 4;
309
- result = result % 7;
310
- if (result < 0)
311
- result += 7;
312
- return (intN) result;
313
- }
314
-
315
- #define MakeTime(hour, min, sec, ms) \
316
- ((((hour) * MinutesPerHour + (min)) * SecondsPerMinute + (sec)) * msPerSecond + (ms))
317
-
318
- static jsdouble
319
- MakeDay(jsdouble year, jsdouble month, jsdouble date)
320
- {
321
- JSBool leap;
322
- jsdouble yearday;
323
- jsdouble monthday;
324
-
325
- year += floor(month / 12);
326
-
327
- month = fmod(month, 12.0);
328
- if (month < 0)
329
- month += 12;
330
-
331
- leap = (DaysInYear((jsint) year) == 366);
332
-
333
- yearday = floor(TimeFromYear(year) / msPerDay);
334
- monthday = DayFromMonth(month, leap);
335
-
336
- return yearday + monthday + date - 1;
337
- }
338
-
339
- #define MakeDate(day, time) ((day) * msPerDay + (time))
340
-
341
- /*
342
- * Years and leap years on which Jan 1 is a Sunday, Monday, etc.
343
- *
344
- * yearStartingWith[0][i] is an example non-leap year where
345
- * Jan 1 appears on Sunday (i == 0), Monday (i == 1), etc.
346
- *
347
- * yearStartingWith[1][i] is an example leap year where
348
- * Jan 1 appears on Sunday (i == 0), Monday (i == 1), etc.
349
- */
350
- static jsint yearStartingWith[2][7] = {
351
- {1978, 1973, 1974, 1975, 1981, 1971, 1977},
352
- {1984, 1996, 1980, 1992, 1976, 1988, 1972}
353
- };
354
-
355
- /*
356
- * Find a year for which any given date will fall on the same weekday.
357
- *
358
- * This function should be used with caution when used other than
359
- * for determining DST; it hasn't been proven not to produce an
360
- * incorrect year for times near year boundaries.
361
- */
362
- static jsint
363
- EquivalentYearForDST(jsint year)
364
- {
365
- jsint day;
366
- JSBool isLeapYear;
367
-
368
- day = (jsint) DayFromYear(year) + 4;
369
- day = day % 7;
370
- if (day < 0)
371
- day += 7;
372
-
373
- isLeapYear = (DaysInYear(year) == 366);
374
-
375
- return yearStartingWith[isLeapYear][day];
376
- }
377
-
378
- /* LocalTZA gets set by js_InitDateClass() */
379
- static jsdouble LocalTZA;
380
-
381
- static jsdouble
382
- DaylightSavingTA(jsdouble t)
383
- {
384
- volatile int64 PR_t;
385
- int64 ms2us;
386
- int64 offset;
387
- jsdouble result;
388
-
389
- /* abort if NaN */
390
- if (JSDOUBLE_IS_NaN(t))
391
- return t;
392
-
393
- /*
394
- * If earlier than 1970 or after 2038, potentially beyond the ken of
395
- * many OSes, map it to an equivalent year before asking.
396
- */
397
- if (t < 0.0 || t > 2145916800000.0) {
398
- jsint year;
399
- jsdouble day;
400
-
401
- year = EquivalentYearForDST(YearFromTime(t));
402
- day = MakeDay(year, MonthFromTime(t), DateFromTime(t));
403
- t = MakeDate(day, TimeWithinDay(t));
404
- }
405
-
406
- /* put our t in an LL, and map it to usec for prtime */
407
- JSLL_D2L(PR_t, t);
408
- JSLL_I2L(ms2us, PRMJ_USEC_PER_MSEC);
409
- JSLL_MUL(PR_t, PR_t, ms2us);
410
-
411
- offset = PRMJ_DSTOffset(PR_t);
412
-
413
- JSLL_DIV(offset, offset, ms2us);
414
- JSLL_L2D(result, offset);
415
- return result;
416
- }
417
-
418
-
419
- #define AdjustTime(t) fmod(LocalTZA + DaylightSavingTA(t), msPerDay)
420
-
421
- #define LocalTime(t) ((t) + AdjustTime(t))
422
-
423
- static jsdouble
424
- UTC(jsdouble t)
425
- {
426
- return t - AdjustTime(t - LocalTZA);
427
- }
428
-
429
- static intN
430
- HourFromTime(jsdouble t)
431
- {
432
- intN result = (intN) fmod(floor(t/msPerHour), HoursPerDay);
433
- if (result < 0)
434
- result += (intN)HoursPerDay;
435
- return result;
436
- }
437
-
438
- static intN
439
- MinFromTime(jsdouble t)
440
- {
441
- intN result = (intN) fmod(floor(t / msPerMinute), MinutesPerHour);
442
- if (result < 0)
443
- result += (intN)MinutesPerHour;
444
- return result;
445
- }
446
-
447
- static intN
448
- SecFromTime(jsdouble t)
449
- {
450
- intN result = (intN) fmod(floor(t / msPerSecond), SecondsPerMinute);
451
- if (result < 0)
452
- result += (intN)SecondsPerMinute;
453
- return result;
454
- }
455
-
456
- static intN
457
- msFromTime(jsdouble t)
458
- {
459
- intN result = (intN) fmod(t, msPerSecond);
460
- if (result < 0)
461
- result += (intN)msPerSecond;
462
- return result;
463
- }
464
-
465
- #define TIMECLIP(d) ((JSDOUBLE_IS_FINITE(d) \
466
- && !((d < 0 ? -d : d) > HalfTimeDomain)) \
467
- ? js_DoubleToInteger(d + (+0.)) : *cx->runtime->jsNaN)
468
-
469
- /**
470
- * end of ECMA 'support' functions
471
- */
472
-
473
- /*
474
- * Other Support routines and definitions
475
- */
476
-
477
- /*
478
- * We use the first reseved slot to store UTC time, and the second for caching
479
- * the local time. The initial value of the cache entry is NaN.
480
- */
481
- #define JSSLOT_UTC_TIME JSSLOT_PRIVATE
482
- #define JSSLOT_LOCAL_TIME (JSSLOT_PRIVATE + 1)
483
-
484
- #define DATE_RESERVED_SLOTS 2
485
-
486
- JSClass js_DateClass = {
487
- js_Date_str,
488
- JSCLASS_HAS_RESERVED_SLOTS(DATE_RESERVED_SLOTS) |
489
- JSCLASS_HAS_CACHED_PROTO(JSProto_Date),
490
- JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
491
- JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
492
- JSCLASS_NO_OPTIONAL_MEMBERS
493
- };
494
-
495
- /* for use by date_parse */
496
-
497
- static const char* wtb[] = {
498
- "am", "pm",
499
- "monday", "tuesday", "wednesday", "thursday", "friday",
500
- "saturday", "sunday",
501
- "january", "february", "march", "april", "may", "june",
502
- "july", "august", "september", "october", "november", "december",
503
- "gmt", "ut", "utc",
504
- "est", "edt",
505
- "cst", "cdt",
506
- "mst", "mdt",
507
- "pst", "pdt"
508
- /* time zone table needs to be expanded */
509
- };
510
-
511
- static int ttb[] = {
512
- -1, -2, 0, 0, 0, 0, 0, 0, 0, /* AM/PM */
513
- 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
514
- 10000 + 0, 10000 + 0, 10000 + 0, /* GMT/UT/UTC */
515
- 10000 + 5 * 60, 10000 + 4 * 60, /* EST/EDT */
516
- 10000 + 6 * 60, 10000 + 5 * 60, /* CST/CDT */
517
- 10000 + 7 * 60, 10000 + 6 * 60, /* MST/MDT */
518
- 10000 + 8 * 60, 10000 + 7 * 60 /* PST/PDT */
519
- };
520
-
521
- /* helper for date_parse */
522
- static JSBool
523
- date_regionMatches(const char* s1, int s1off, const jschar* s2, int s2off,
524
- int count, int ignoreCase)
525
- {
526
- JSBool result = JS_FALSE;
527
- /* return true if matches, otherwise, false */
528
-
529
- while (count > 0 && s1[s1off] && s2[s2off]) {
530
- if (ignoreCase) {
531
- if (JS_TOLOWER((jschar)s1[s1off]) != JS_TOLOWER(s2[s2off])) {
532
- break;
533
- }
534
- } else {
535
- if ((jschar)s1[s1off] != s2[s2off]) {
536
- break;
537
- }
538
- }
539
- s1off++;
540
- s2off++;
541
- count--;
542
- }
543
-
544
- if (count == 0) {
545
- result = JS_TRUE;
546
- }
547
-
548
- return result;
549
- }
550
-
551
- /* find UTC time from given date... no 1900 correction! */
552
- static jsdouble
553
- date_msecFromDate(jsdouble year, jsdouble mon, jsdouble mday, jsdouble hour,
554
- jsdouble min, jsdouble sec, jsdouble msec)
555
- {
556
- jsdouble day;
557
- jsdouble msec_time;
558
- jsdouble result;
559
-
560
- day = MakeDay(year, mon, mday);
561
- msec_time = MakeTime(hour, min, sec, msec);
562
- result = MakeDate(day, msec_time);
563
- return result;
564
- }
565
-
566
- /* compute the time in msec (unclipped) from the given args */
567
- #define MAXARGS 7
568
-
569
- static JSBool
570
- date_msecFromArgs(JSContext *cx, uintN argc, jsval *argv, jsdouble *rval)
571
- {
572
- uintN loop;
573
- jsdouble array[MAXARGS];
574
- jsdouble d;
575
- jsdouble msec_time;
576
-
577
- for (loop = 0; loop < MAXARGS; loop++) {
578
- if (loop < argc) {
579
- d = js_ValueToNumber(cx, &argv[loop]);
580
- if (JSVAL_IS_NULL(argv[loop]))
581
- return JS_FALSE;
582
- /* return NaN if any arg is not finite */
583
- if (!JSDOUBLE_IS_FINITE(d)) {
584
- *rval = *cx->runtime->jsNaN;
585
- return JS_TRUE;
586
- }
587
- array[loop] = js_DoubleToInteger(d);
588
- } else {
589
- if (loop == 2) {
590
- array[loop] = 1; /* Default the date argument to 1. */
591
- } else {
592
- array[loop] = 0;
593
- }
594
- }
595
- }
596
-
597
- /* adjust 2-digit years into the 20th century */
598
- if (array[0] >= 0 && array[0] <= 99)
599
- array[0] += 1900;
600
-
601
- msec_time = date_msecFromDate(array[0], array[1], array[2],
602
- array[3], array[4], array[5], array[6]);
603
- *rval = msec_time;
604
- return JS_TRUE;
605
- }
606
-
607
-
608
- /*
609
- * See ECMA 15.9.4.[3-10];
610
- */
611
- static JSBool
612
- date_UTC(JSContext *cx, uintN argc, jsval *vp)
613
- {
614
- jsdouble msec_time;
615
-
616
- if (!date_msecFromArgs(cx, argc, vp + 2, &msec_time))
617
- return JS_FALSE;
618
-
619
- msec_time = TIMECLIP(msec_time);
620
-
621
- return js_NewNumberInRootedValue(cx, msec_time, vp);
622
- }
623
-
624
- static JSBool
625
- date_parseString(JSString *str, jsdouble *result)
626
- {
627
- jsdouble msec;
628
-
629
- const jschar *s;
630
- size_t limit;
631
- size_t i = 0;
632
- int year = -1;
633
- int mon = -1;
634
- int mday = -1;
635
- int hour = -1;
636
- int min = -1;
637
- int sec = -1;
638
- int c = -1;
639
- int n = -1;
640
- int tzoffset = -1;
641
- int prevc = 0;
642
- JSBool seenplusminus = JS_FALSE;
643
- int temp;
644
- JSBool seenmonthname = JS_FALSE;
645
-
646
- JSSTRING_CHARS_AND_LENGTH(str, s, limit);
647
- if (limit == 0)
648
- goto syntax;
649
- while (i < limit) {
650
- c = s[i];
651
- i++;
652
- if (c <= ' ' || c == ',' || c == '-') {
653
- if (c == '-' && '0' <= s[i] && s[i] <= '9') {
654
- prevc = c;
655
- }
656
- continue;
657
- }
658
- if (c == '(') { /* comments) */
659
- int depth = 1;
660
- while (i < limit) {
661
- c = s[i];
662
- i++;
663
- if (c == '(') depth++;
664
- else if (c == ')')
665
- if (--depth <= 0)
666
- break;
667
- }
668
- continue;
669
- }
670
- if ('0' <= c && c <= '9') {
671
- n = c - '0';
672
- while (i < limit && '0' <= (c = s[i]) && c <= '9') {
673
- n = n * 10 + c - '0';
674
- i++;
675
- }
676
-
677
- /* allow TZA before the year, so
678
- * 'Wed Nov 05 21:49:11 GMT-0800 1997'
679
- * works */
680
-
681
- /* uses of seenplusminus allow : in TZA, so Java
682
- * no-timezone style of GMT+4:30 works
683
- */
684
-
685
- if ((prevc == '+' || prevc == '-')/* && year>=0 */) {
686
- /* make ':' case below change tzoffset */
687
- seenplusminus = JS_TRUE;
688
-
689
- /* offset */
690
- if (n < 24)
691
- n = n * 60; /* EG. "GMT-3" */
692
- else
693
- n = n % 100 + n / 100 * 60; /* eg "GMT-0430" */
694
- if (prevc == '+') /* plus means east of GMT */
695
- n = -n;
696
- if (tzoffset != 0 && tzoffset != -1)
697
- goto syntax;
698
- tzoffset = n;
699
- } else if (prevc == '/' && mon >= 0 && mday >= 0 && year < 0) {
700
- if (c <= ' ' || c == ',' || c == '/' || i >= limit)
701
- year = n;
702
- else
703
- goto syntax;
704
- } else if (c == ':') {
705
- if (hour < 0)
706
- hour = /*byte*/ n;
707
- else if (min < 0)
708
- min = /*byte*/ n;
709
- else
710
- goto syntax;
711
- } else if (c == '/') {
712
- /* until it is determined that mon is the actual
713
- month, keep it as 1-based rather than 0-based */
714
- if (mon < 0)
715
- mon = /*byte*/ n;
716
- else if (mday < 0)
717
- mday = /*byte*/ n;
718
- else
719
- goto syntax;
720
- } else if (i < limit && c != ',' && c > ' ' && c != '-' && c != '(') {
721
- goto syntax;
722
- } else if (seenplusminus && n < 60) { /* handle GMT-3:30 */
723
- if (tzoffset < 0)
724
- tzoffset -= n;
725
- else
726
- tzoffset += n;
727
- } else if (hour >= 0 && min < 0) {
728
- min = /*byte*/ n;
729
- } else if (prevc == ':' && min >= 0 && sec < 0) {
730
- sec = /*byte*/ n;
731
- } else if (mon < 0) {
732
- mon = /*byte*/n;
733
- } else if (mon >= 0 && mday < 0) {
734
- mday = /*byte*/ n;
735
- } else if (mon >= 0 && mday >= 0 && year < 0) {
736
- year = n;
737
- } else {
738
- goto syntax;
739
- }
740
- prevc = 0;
741
- } else if (c == '/' || c == ':' || c == '+' || c == '-') {
742
- prevc = c;
743
- } else {
744
- size_t st = i - 1;
745
- int k;
746
- while (i < limit) {
747
- c = s[i];
748
- if (!(('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z')))
749
- break;
750
- i++;
751
- }
752
- if (i <= st + 1)
753
- goto syntax;
754
- for (k = JS_ARRAY_LENGTH(wtb); --k >= 0;)
755
- if (date_regionMatches(wtb[k], 0, s, st, i-st, 1)) {
756
- int action = ttb[k];
757
- if (action != 0) {
758
- if (action < 0) {
759
- /*
760
- * AM/PM. Count 12:30 AM as 00:30, 12:30 PM as
761
- * 12:30, instead of blindly adding 12 if PM.
762
- */
763
- JS_ASSERT(action == -1 || action == -2);
764
- if (hour > 12 || hour < 0) {
765
- goto syntax;
766
- } else {
767
- if (action == -1 && hour == 12) { /* am */
768
- hour = 0;
769
- } else if (action == -2 && hour != 12) { /* pm */
770
- hour += 12;
771
- }
772
- }
773
- } else if (action <= 13) { /* month! */
774
- /* Adjust mon to be 1-based until the final values
775
- for mon, mday and year are adjusted below */
776
- if (seenmonthname) {
777
- goto syntax;
778
- }
779
- seenmonthname = JS_TRUE;
780
- temp = /*byte*/ (action - 2) + 1;
781
-
782
- if (mon < 0) {
783
- mon = temp;
784
- } else if (mday < 0) {
785
- mday = mon;
786
- mon = temp;
787
- } else if (year < 0) {
788
- year = mon;
789
- mon = temp;
790
- } else {
791
- goto syntax;
792
- }
793
- } else {
794
- tzoffset = action - 10000;
795
- }
796
- }
797
- break;
798
- }
799
- if (k < 0)
800
- goto syntax;
801
- prevc = 0;
802
- }
803
- }
804
- if (year < 0 || mon < 0 || mday < 0)
805
- goto syntax;
806
- /*
807
- Case 1. The input string contains an English month name.
808
- The form of the string can be month f l, or f month l, or
809
- f l month which each evaluate to the same date.
810
- If f and l are both greater than or equal to 70, or
811
- both less than 70, the date is invalid.
812
- The year is taken to be the greater of the values f, l.
813
- If the year is greater than or equal to 70 and less than 100,
814
- it is considered to be the number of years after 1900.
815
- Case 2. The input string is of the form "f/m/l" where f, m and l are
816
- integers, e.g. 7/16/45.
817
- Adjust the mon, mday and year values to achieve 100% MSIE
818
- compatibility.
819
- a. If 0 <= f < 70, f/m/l is interpreted as month/day/year.
820
- i. If year < 100, it is the number of years after 1900
821
- ii. If year >= 100, it is the number of years after 0.
822
- b. If 70 <= f < 100
823
- i. If m < 70, f/m/l is interpreted as
824
- year/month/day where year is the number of years after
825
- 1900.
826
- ii. If m >= 70, the date is invalid.
827
- c. If f >= 100
828
- i. If m < 70, f/m/l is interpreted as
829
- year/month/day where year is the number of years after 0.
830
- ii. If m >= 70, the date is invalid.
831
- */
832
- if (seenmonthname) {
833
- if ((mday >= 70 && year >= 70) || (mday < 70 && year < 70)) {
834
- goto syntax;
835
- }
836
- if (mday > year) {
837
- temp = year;
838
- year = mday;
839
- mday = temp;
840
- }
841
- if (year >= 70 && year < 100) {
842
- year += 1900;
843
- }
844
- } else if (mon < 70) { /* (a) month/day/year */
845
- if (year < 100) {
846
- year += 1900;
847
- }
848
- } else if (mon < 100) { /* (b) year/month/day */
849
- if (mday < 70) {
850
- temp = year;
851
- year = mon + 1900;
852
- mon = mday;
853
- mday = temp;
854
- } else {
855
- goto syntax;
856
- }
857
- } else { /* (c) year/month/day */
858
- if (mday < 70) {
859
- temp = year;
860
- year = mon;
861
- mon = mday;
862
- mday = temp;
863
- } else {
864
- goto syntax;
865
- }
866
- }
867
- mon -= 1; /* convert month to 0-based */
868
- if (sec < 0)
869
- sec = 0;
870
- if (min < 0)
871
- min = 0;
872
- if (hour < 0)
873
- hour = 0;
874
- if (tzoffset == -1) { /* no time zone specified, have to use local */
875
- jsdouble msec_time;
876
- msec_time = date_msecFromDate(year, mon, mday, hour, min, sec, 0);
877
-
878
- *result = UTC(msec_time);
879
- return JS_TRUE;
880
- }
881
-
882
- msec = date_msecFromDate(year, mon, mday, hour, min, sec, 0);
883
- msec += tzoffset * msPerMinute;
884
- *result = msec;
885
- return JS_TRUE;
886
-
887
- syntax:
888
- /* syntax error */
889
- *result = 0;
890
- return JS_FALSE;
891
- }
892
-
893
- static JSBool
894
- date_parse(JSContext *cx, uintN argc, jsval *vp)
895
- {
896
- JSString *str;
897
- jsdouble result;
898
-
899
- str = js_ValueToString(cx, vp[2]);
900
- if (!str)
901
- return JS_FALSE;
902
- if (!date_parseString(str, &result)) {
903
- *vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
904
- return JS_TRUE;
905
- }
906
-
907
- result = TIMECLIP(result);
908
- return js_NewNumberInRootedValue(cx, result, vp);
909
- }
910
-
911
- static JSBool
912
- date_now(JSContext *cx, uintN argc, jsval *vp)
913
- {
914
- int64 us, ms, us2ms;
915
- jsdouble msec_time;
916
-
917
- us = PRMJ_Now();
918
- JSLL_UI2L(us2ms, PRMJ_USEC_PER_MSEC);
919
- JSLL_DIV(ms, us, us2ms);
920
- JSLL_L2D(msec_time, ms);
921
-
922
- return js_NewDoubleInRootedValue(cx, msec_time, vp);
923
- }
924
-
925
- /*
926
- * Get UTC time from the date object. Returns false if the object is not
927
- * Date type.
928
- */
929
- static JSBool
930
- GetUTCTime(JSContext *cx, JSObject *obj, jsval *vp, jsdouble *dp)
931
- {
932
- if (!JS_InstanceOf(cx, obj, &js_DateClass, vp ? vp + 2 : NULL))
933
- return JS_FALSE;
934
- *dp = *JSVAL_TO_DOUBLE(obj->fslots[JSSLOT_UTC_TIME]);
935
- return JS_TRUE;
936
- }
937
-
938
- /*
939
- * Set UTC time slot with a pointer pointing to a jsdouble. This function is
940
- * used only for setting UTC time to some predefined values, such as NaN.
941
- *
942
- * It also invalidates cached local time.
943
- */
944
- static JSBool
945
- SetUTCTimePtr(JSContext *cx, JSObject *obj, jsval *vp, jsdouble *dp)
946
- {
947
- if (vp && !JS_InstanceOf(cx, obj, &js_DateClass, vp + 2))
948
- return JS_FALSE;
949
- JS_ASSERT_IF(!vp, STOBJ_GET_CLASS(obj) == &js_DateClass);
950
-
951
- /* Invalidate local time cache. */
952
- obj->fslots[JSSLOT_LOCAL_TIME] = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
953
- obj->fslots[JSSLOT_UTC_TIME] = DOUBLE_TO_JSVAL(dp);
954
- return JS_TRUE;
955
- }
956
-
957
- /*
958
- * Set UTC time to a given time.
959
- */
960
- static JSBool
961
- SetUTCTime(JSContext *cx, JSObject *obj, jsval *vp, jsdouble t)
962
- {
963
- jsdouble *dp = js_NewWeaklyRootedDouble(cx, t);
964
- if (!dp)
965
- return JS_FALSE;
966
- return SetUTCTimePtr(cx, obj, vp, dp);
967
- }
968
-
969
- /*
970
- * Get the local time, cache it if necessary. If UTC time is not finite
971
- * (e.g., NaN), the local time slot is set to the UTC time without conversion.
972
- */
973
- static JSBool
974
- GetAndCacheLocalTime(JSContext *cx, JSObject *obj, jsval *vp, jsdouble *dp)
975
- {
976
- jsval v;
977
- jsdouble result;
978
- jsdouble *cached;
979
-
980
- if (!obj || !JS_InstanceOf(cx, obj, &js_DateClass, vp ? vp + 2 : NULL))
981
- return JS_FALSE;
982
- v = obj->fslots[JSSLOT_LOCAL_TIME];
983
-
984
- result = *JSVAL_TO_DOUBLE(v);
985
-
986
- if (JSDOUBLE_IS_NaN(result)) {
987
- if (!GetUTCTime(cx, obj, vp, &result))
988
- return JS_FALSE;
989
-
990
- /* if result is NaN, it couldn't be finite. */
991
- if (JSDOUBLE_IS_FINITE(result))
992
- result = LocalTime(result);
993
-
994
- cached = js_NewWeaklyRootedDouble(cx, result);
995
- if (!cached)
996
- return JS_FALSE;
997
-
998
- obj->fslots[JSSLOT_LOCAL_TIME] = DOUBLE_TO_JSVAL(cached);
999
- }
1000
-
1001
- *dp = result;
1002
- return JS_TRUE;
1003
- }
1004
-
1005
- /*
1006
- * See ECMA 15.9.5.4 thru 15.9.5.23
1007
- */
1008
- static JSBool
1009
- date_getTime(JSContext *cx, uintN argc, jsval *vp)
1010
- {
1011
- jsdouble result;
1012
-
1013
- return GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result) &&
1014
- js_NewNumberInRootedValue(cx, result, vp);
1015
- }
1016
-
1017
- static JSBool
1018
- GetYear(JSContext *cx, JSBool fullyear, jsval *vp)
1019
- {
1020
- jsdouble result;
1021
-
1022
- if (!GetAndCacheLocalTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result))
1023
- return JS_FALSE;
1024
-
1025
- if (JSDOUBLE_IS_FINITE(result)) {
1026
- result = YearFromTime(result);
1027
-
1028
- /* Follow ECMA-262 to the letter, contrary to IE JScript. */
1029
- if (!fullyear)
1030
- result -= 1900;
1031
- }
1032
-
1033
- return js_NewNumberInRootedValue(cx, result, vp);
1034
- }
1035
-
1036
- static JSBool
1037
- date_getYear(JSContext *cx, uintN argc, jsval *vp)
1038
- {
1039
- return GetYear(cx, JS_FALSE, vp);
1040
- }
1041
-
1042
- static JSBool
1043
- date_getFullYear(JSContext *cx, uintN argc, jsval *vp)
1044
- {
1045
- return GetYear(cx, JS_TRUE, vp);
1046
- }
1047
-
1048
- static JSBool
1049
- date_getUTCFullYear(JSContext *cx, uintN argc, jsval *vp)
1050
- {
1051
- jsdouble result;
1052
-
1053
- if (!GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result))
1054
- return JS_FALSE;
1055
-
1056
- if (JSDOUBLE_IS_FINITE(result))
1057
- result = YearFromTime(result);
1058
-
1059
- return js_NewNumberInRootedValue(cx, result, vp);
1060
- }
1061
-
1062
- static JSBool
1063
- date_getMonth(JSContext *cx, uintN argc, jsval *vp)
1064
- {
1065
- jsdouble result;
1066
-
1067
- if (!GetAndCacheLocalTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result))
1068
- return JS_FALSE;
1069
-
1070
- if (JSDOUBLE_IS_FINITE(result))
1071
- result = MonthFromTime(result);
1072
-
1073
- return js_NewNumberInRootedValue(cx, result, vp);
1074
- }
1075
-
1076
- static JSBool
1077
- date_getUTCMonth(JSContext *cx, uintN argc, jsval *vp)
1078
- {
1079
- jsdouble result;
1080
-
1081
- if (!GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result))
1082
- return JS_FALSE;
1083
-
1084
- if (JSDOUBLE_IS_FINITE(result))
1085
- result = MonthFromTime(result);
1086
-
1087
- return js_NewNumberInRootedValue(cx, result, vp);
1088
- }
1089
-
1090
- static JSBool
1091
- date_getDate(JSContext *cx, uintN argc, jsval *vp)
1092
- {
1093
- jsdouble result;
1094
-
1095
- if (!GetAndCacheLocalTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result))
1096
- return JS_FALSE;
1097
-
1098
- if (JSDOUBLE_IS_FINITE(result))
1099
- result = DateFromTime(result);
1100
-
1101
- return js_NewNumberInRootedValue(cx, result, vp);
1102
- }
1103
-
1104
- static JSBool
1105
- date_getUTCDate(JSContext *cx, uintN argc, jsval *vp)
1106
- {
1107
- jsdouble result;
1108
-
1109
- if (!GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result))
1110
- return JS_FALSE;
1111
-
1112
- if (JSDOUBLE_IS_FINITE(result))
1113
- result = DateFromTime(result);
1114
-
1115
- return js_NewNumberInRootedValue(cx, result, vp);
1116
- }
1117
-
1118
- static JSBool
1119
- date_getDay(JSContext *cx, uintN argc, jsval *vp)
1120
- {
1121
- jsdouble result;
1122
-
1123
- if (!GetAndCacheLocalTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result))
1124
- return JS_FALSE;
1125
-
1126
- if (JSDOUBLE_IS_FINITE(result))
1127
- result = WeekDay(result);
1128
-
1129
- return js_NewNumberInRootedValue(cx, result, vp);
1130
- }
1131
-
1132
- static JSBool
1133
- date_getUTCDay(JSContext *cx, uintN argc, jsval *vp)
1134
- {
1135
- jsdouble result;
1136
-
1137
- if (!GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result))
1138
- return JS_FALSE;
1139
-
1140
- if (JSDOUBLE_IS_FINITE(result))
1141
- result = WeekDay(result);
1142
-
1143
- return js_NewNumberInRootedValue(cx, result, vp);
1144
- }
1145
-
1146
- static JSBool
1147
- date_getHours(JSContext *cx, uintN argc, jsval *vp)
1148
- {
1149
- jsdouble result;
1150
-
1151
- if (!GetAndCacheLocalTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result))
1152
- return JS_FALSE;
1153
-
1154
- if (JSDOUBLE_IS_FINITE(result))
1155
- result = HourFromTime(result);
1156
-
1157
- return js_NewNumberInRootedValue(cx, result, vp);
1158
- }
1159
-
1160
- static JSBool
1161
- date_getUTCHours(JSContext *cx, uintN argc, jsval *vp)
1162
- {
1163
- jsdouble result;
1164
-
1165
- if (!GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result))
1166
- return JS_FALSE;
1167
-
1168
- if (JSDOUBLE_IS_FINITE(result))
1169
- result = HourFromTime(result);
1170
-
1171
- return js_NewNumberInRootedValue(cx, result, vp);
1172
- }
1173
-
1174
- static JSBool
1175
- date_getMinutes(JSContext *cx, uintN argc, jsval *vp)
1176
- {
1177
- jsdouble result;
1178
-
1179
- if (!GetAndCacheLocalTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result))
1180
- return JS_FALSE;
1181
-
1182
- if (JSDOUBLE_IS_FINITE(result))
1183
- result = MinFromTime(result);
1184
-
1185
- return js_NewNumberInRootedValue(cx, result, vp);
1186
- }
1187
-
1188
- static JSBool
1189
- date_getUTCMinutes(JSContext *cx, uintN argc, jsval *vp)
1190
- {
1191
- jsdouble result;
1192
-
1193
- if (!GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result))
1194
- return JS_FALSE;
1195
-
1196
- if (JSDOUBLE_IS_FINITE(result))
1197
- result = MinFromTime(result);
1198
-
1199
- return js_NewNumberInRootedValue(cx, result, vp);
1200
- }
1201
-
1202
- /* Date.getSeconds is mapped to getUTCSeconds */
1203
-
1204
- static JSBool
1205
- date_getUTCSeconds(JSContext *cx, uintN argc, jsval *vp)
1206
- {
1207
- jsdouble result;
1208
-
1209
- if (!GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result))
1210
- return JS_FALSE;
1211
-
1212
- if (JSDOUBLE_IS_FINITE(result))
1213
- result = SecFromTime(result);
1214
-
1215
- return js_NewNumberInRootedValue(cx, result, vp);
1216
- }
1217
-
1218
- /* Date.getMilliseconds is mapped to getUTCMilliseconds */
1219
-
1220
- static JSBool
1221
- date_getUTCMilliseconds(JSContext *cx, uintN argc, jsval *vp)
1222
- {
1223
- jsdouble result;
1224
-
1225
- if (!GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result))
1226
- return JS_FALSE;
1227
-
1228
- if (JSDOUBLE_IS_FINITE(result))
1229
- result = msFromTime(result);
1230
-
1231
- return js_NewNumberInRootedValue(cx, result, vp);
1232
- }
1233
-
1234
- static JSBool
1235
- date_getTimezoneOffset(JSContext *cx, uintN argc, jsval *vp)
1236
- {
1237
- JSObject *obj;
1238
- jsdouble utctime, localtime, result;
1239
-
1240
- obj = JS_THIS_OBJECT(cx, vp);
1241
- if (!GetUTCTime(cx, obj, vp, &utctime))
1242
- return JS_FALSE;
1243
- if (!GetAndCacheLocalTime(cx, obj, NULL, &localtime))
1244
- return JS_FALSE;
1245
-
1246
- /*
1247
- * Return the time zone offset in minutes for the current locale that is
1248
- * appropriate for this time. This value would be a constant except for
1249
- * daylight savings time.
1250
- */
1251
- result = (utctime - localtime) / msPerMinute;
1252
- return js_NewNumberInRootedValue(cx, result, vp);
1253
- }
1254
-
1255
- static JSBool
1256
- date_setTime(JSContext *cx, uintN argc, jsval *vp)
1257
- {
1258
- jsdouble result;
1259
-
1260
- result = js_ValueToNumber(cx, &vp[2]);
1261
- if (JSVAL_IS_NULL(vp[2]))
1262
- return JS_FALSE;
1263
-
1264
- result = TIMECLIP(result);
1265
-
1266
- if (!SetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, result))
1267
- return JS_FALSE;
1268
-
1269
- return js_NewNumberInRootedValue(cx, result, vp);
1270
- }
1271
-
1272
- static JSBool
1273
- date_makeTime(JSContext *cx, uintN maxargs, JSBool local, uintN argc, jsval *vp)
1274
- {
1275
- JSObject *obj;
1276
- jsval *argv;
1277
- uintN i;
1278
- jsdouble args[4], *argp, *stop;
1279
- jsdouble hour, min, sec, msec;
1280
- jsdouble lorutime; /* Local or UTC version of *date */
1281
-
1282
- jsdouble msec_time;
1283
- jsdouble result;
1284
-
1285
- obj = JS_THIS_OBJECT(cx, vp);
1286
- if (!GetUTCTime(cx, obj, vp, &result))
1287
- return JS_FALSE;
1288
-
1289
- /* just return NaN if the date is already NaN */
1290
- if (!JSDOUBLE_IS_FINITE(result))
1291
- return js_NewNumberInRootedValue(cx, result, vp);
1292
-
1293
- /*
1294
- * Satisfy the ECMA rule that if a function is called with
1295
- * fewer arguments than the specified formal arguments, the
1296
- * remaining arguments are set to undefined. Seems like all
1297
- * the Date.setWhatever functions in ECMA are only varargs
1298
- * beyond the first argument; this should be set to undefined
1299
- * if it's not given. This means that "d = new Date();
1300
- * d.setMilliseconds()" returns NaN. Blech.
1301
- */
1302
- if (argc == 0)
1303
- argc = 1; /* should be safe, because length of all setters is 1 */
1304
- else if (argc > maxargs)
1305
- argc = maxargs; /* clamp argc */
1306
- JS_ASSERT(1 <= argc && argc <= 4);
1307
-
1308
- argv = vp + 2;
1309
- for (i = 0; i < argc; i++) {
1310
- args[i] = js_ValueToNumber(cx, &argv[i]);
1311
- if (JSVAL_IS_NULL(argv[i]))
1312
- return JS_FALSE;
1313
- if (!JSDOUBLE_IS_FINITE(args[i])) {
1314
- if (!SetUTCTimePtr(cx, obj, NULL, cx->runtime->jsNaN))
1315
- return JS_FALSE;
1316
- *vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
1317
- return JS_TRUE;
1318
- }
1319
- args[i] = js_DoubleToInteger(args[i]);
1320
- }
1321
-
1322
- if (local)
1323
- lorutime = LocalTime(result);
1324
- else
1325
- lorutime = result;
1326
-
1327
- argp = args;
1328
- stop = argp + argc;
1329
- if (maxargs >= 4 && argp < stop)
1330
- hour = *argp++;
1331
- else
1332
- hour = HourFromTime(lorutime);
1333
-
1334
- if (maxargs >= 3 && argp < stop)
1335
- min = *argp++;
1336
- else
1337
- min = MinFromTime(lorutime);
1338
-
1339
- if (maxargs >= 2 && argp < stop)
1340
- sec = *argp++;
1341
- else
1342
- sec = SecFromTime(lorutime);
1343
-
1344
- if (maxargs >= 1 && argp < stop)
1345
- msec = *argp;
1346
- else
1347
- msec = msFromTime(lorutime);
1348
-
1349
- msec_time = MakeTime(hour, min, sec, msec);
1350
- result = MakeDate(Day(lorutime), msec_time);
1351
-
1352
- /* fprintf(stderr, "%f\n", result); */
1353
-
1354
- if (local)
1355
- result = UTC(result);
1356
-
1357
- /* fprintf(stderr, "%f\n", result); */
1358
-
1359
- result = TIMECLIP(result);
1360
- if (!SetUTCTime(cx, obj, NULL, result))
1361
- return JS_FALSE;
1362
-
1363
- return js_NewNumberInRootedValue(cx, result, vp);
1364
- }
1365
-
1366
- static JSBool
1367
- date_setMilliseconds(JSContext *cx, uintN argc, jsval *vp)
1368
- {
1369
- return date_makeTime(cx, 1, JS_TRUE, argc, vp);
1370
- }
1371
-
1372
- static JSBool
1373
- date_setUTCMilliseconds(JSContext *cx, uintN argc, jsval *vp)
1374
- {
1375
- return date_makeTime(cx, 1, JS_FALSE, argc, vp);
1376
- }
1377
-
1378
- static JSBool
1379
- date_setSeconds(JSContext *cx, uintN argc, jsval *vp)
1380
- {
1381
- return date_makeTime(cx, 2, JS_TRUE, argc, vp);
1382
- }
1383
-
1384
- static JSBool
1385
- date_setUTCSeconds(JSContext *cx, uintN argc, jsval *vp)
1386
- {
1387
- return date_makeTime(cx, 2, JS_FALSE, argc, vp);
1388
- }
1389
-
1390
- static JSBool
1391
- date_setMinutes(JSContext *cx, uintN argc, jsval *vp)
1392
- {
1393
- return date_makeTime(cx, 3, JS_TRUE, argc, vp);
1394
- }
1395
-
1396
- static JSBool
1397
- date_setUTCMinutes(JSContext *cx, uintN argc, jsval *vp)
1398
- {
1399
- return date_makeTime(cx, 3, JS_FALSE, argc, vp);
1400
- }
1401
-
1402
- static JSBool
1403
- date_setHours(JSContext *cx, uintN argc, jsval *vp)
1404
- {
1405
- return date_makeTime(cx, 4, JS_TRUE, argc, vp);
1406
- }
1407
-
1408
- static JSBool
1409
- date_setUTCHours(JSContext *cx, uintN argc, jsval *vp)
1410
- {
1411
- return date_makeTime(cx, 4, JS_FALSE, argc, vp);
1412
- }
1413
-
1414
- static JSBool
1415
- date_makeDate(JSContext *cx, uintN maxargs, JSBool local, uintN argc, jsval *vp)
1416
- {
1417
- JSObject *obj;
1418
- jsval *argv;
1419
- uintN i;
1420
- jsdouble lorutime; /* local or UTC version of *date */
1421
- jsdouble args[3], *argp, *stop;
1422
- jsdouble year, month, day;
1423
- jsdouble result;
1424
-
1425
- obj = JS_THIS_OBJECT(cx, vp);
1426
- if (!GetUTCTime(cx, obj, vp, &result))
1427
- return JS_FALSE;
1428
-
1429
- /* see complaint about ECMA in date_MakeTime */
1430
- if (argc == 0)
1431
- argc = 1; /* should be safe, because length of all setters is 1 */
1432
- else if (argc > maxargs)
1433
- argc = maxargs; /* clamp argc */
1434
- JS_ASSERT(1 <= argc && argc <= 3);
1435
-
1436
- argv = vp + 2;
1437
- for (i = 0; i < argc; i++) {
1438
- args[i] = js_ValueToNumber(cx, &argv[i]);
1439
- if (JSVAL_IS_NULL(argv[i]))
1440
- return JS_FALSE;
1441
- if (!JSDOUBLE_IS_FINITE(args[i])) {
1442
- if (!SetUTCTimePtr(cx, obj, NULL, cx->runtime->jsNaN))
1443
- return JS_FALSE;
1444
- *vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
1445
- return JS_TRUE;
1446
- }
1447
- args[i] = js_DoubleToInteger(args[i]);
1448
- }
1449
-
1450
- /* return NaN if date is NaN and we're not setting the year,
1451
- * If we are, use 0 as the time. */
1452
- if (!(JSDOUBLE_IS_FINITE(result))) {
1453
- if (maxargs < 3)
1454
- return js_NewNumberInRootedValue(cx, result, vp);
1455
- lorutime = +0.;
1456
- } else {
1457
- lorutime = local ? LocalTime(result) : result;
1458
- }
1459
-
1460
- argp = args;
1461
- stop = argp + argc;
1462
- if (maxargs >= 3 && argp < stop)
1463
- year = *argp++;
1464
- else
1465
- year = YearFromTime(lorutime);
1466
-
1467
- if (maxargs >= 2 && argp < stop)
1468
- month = *argp++;
1469
- else
1470
- month = MonthFromTime(lorutime);
1471
-
1472
- if (maxargs >= 1 && argp < stop)
1473
- day = *argp++;
1474
- else
1475
- day = DateFromTime(lorutime);
1476
-
1477
- day = MakeDay(year, month, day); /* day within year */
1478
- result = MakeDate(day, TimeWithinDay(lorutime));
1479
-
1480
- if (local)
1481
- result = UTC(result);
1482
-
1483
- result = TIMECLIP(result);
1484
- if (!SetUTCTime(cx, obj, NULL, result))
1485
- return JS_FALSE;
1486
-
1487
- return js_NewNumberInRootedValue(cx, result, vp);
1488
- }
1489
-
1490
- static JSBool
1491
- date_setDate(JSContext *cx, uintN argc, jsval *vp)
1492
- {
1493
- return date_makeDate(cx, 1, JS_TRUE, argc, vp);
1494
- }
1495
-
1496
- static JSBool
1497
- date_setUTCDate(JSContext *cx, uintN argc, jsval *vp)
1498
- {
1499
- return date_makeDate(cx, 1, JS_FALSE, argc, vp);
1500
- }
1501
-
1502
- static JSBool
1503
- date_setMonth(JSContext *cx, uintN argc, jsval *vp)
1504
- {
1505
- return date_makeDate(cx, 2, JS_TRUE, argc, vp);
1506
- }
1507
-
1508
- static JSBool
1509
- date_setUTCMonth(JSContext *cx, uintN argc, jsval *vp)
1510
- {
1511
- return date_makeDate(cx, 2, JS_FALSE, argc, vp);
1512
- }
1513
-
1514
- static JSBool
1515
- date_setFullYear(JSContext *cx, uintN argc, jsval *vp)
1516
- {
1517
- return date_makeDate(cx, 3, JS_TRUE, argc, vp);
1518
- }
1519
-
1520
- static JSBool
1521
- date_setUTCFullYear(JSContext *cx, uintN argc, jsval *vp)
1522
- {
1523
- return date_makeDate(cx, 3, JS_FALSE, argc, vp);
1524
- }
1525
-
1526
- static JSBool
1527
- date_setYear(JSContext *cx, uintN argc, jsval *vp)
1528
- {
1529
- JSObject *obj;
1530
- jsdouble t;
1531
- jsdouble year;
1532
- jsdouble day;
1533
- jsdouble result;
1534
-
1535
- obj = JS_THIS_OBJECT(cx, vp);
1536
- if (!GetUTCTime(cx, obj, vp, &result))
1537
- return JS_FALSE;
1538
-
1539
- year = js_ValueToNumber(cx, &vp[2]);
1540
- if (JSVAL_IS_NULL(vp[2]))
1541
- return JS_FALSE;
1542
- if (!JSDOUBLE_IS_FINITE(year)) {
1543
- if (!SetUTCTimePtr(cx, obj, NULL, cx->runtime->jsNaN))
1544
- return JS_FALSE;
1545
- return js_NewNumberInRootedValue(cx, *cx->runtime->jsNaN, vp);
1546
- }
1547
-
1548
- year = js_DoubleToInteger(year);
1549
-
1550
- if (!JSDOUBLE_IS_FINITE(result)) {
1551
- t = +0.0;
1552
- } else {
1553
- t = LocalTime(result);
1554
- }
1555
-
1556
- if (year >= 0 && year <= 99)
1557
- year += 1900;
1558
-
1559
- day = MakeDay(year, MonthFromTime(t), DateFromTime(t));
1560
- result = MakeDate(day, TimeWithinDay(t));
1561
- result = UTC(result);
1562
-
1563
- result = TIMECLIP(result);
1564
- if (!SetUTCTime(cx, obj, NULL, result))
1565
- return JS_FALSE;
1566
-
1567
- return js_NewNumberInRootedValue(cx, result, vp);
1568
- }
1569
-
1570
- /* constants for toString, toUTCString */
1571
- static char js_NaN_date_str[] = "Invalid Date";
1572
- static const char* days[] =
1573
- {
1574
- "Sun","Mon","Tue","Wed","Thu","Fri","Sat"
1575
- };
1576
- static const char* months[] =
1577
- {
1578
- "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1579
- };
1580
-
1581
- static JSBool
1582
- date_toGMTString(JSContext *cx, uintN argc, jsval *vp)
1583
- {
1584
- char buf[100];
1585
- JSString *str;
1586
- jsdouble utctime;
1587
-
1588
- if (!GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &utctime))
1589
- return JS_FALSE;
1590
-
1591
- if (!JSDOUBLE_IS_FINITE(utctime)) {
1592
- JS_snprintf(buf, sizeof buf, js_NaN_date_str);
1593
- } else {
1594
- /* Avoid dependence on PRMJ_FormatTimeUSEnglish, because it
1595
- * requires a PRMJTime... which only has 16-bit years. Sub-ECMA.
1596
- */
1597
- JS_snprintf(buf, sizeof buf, "%s, %.2d %s %.4d %.2d:%.2d:%.2d GMT",
1598
- days[WeekDay(utctime)],
1599
- DateFromTime(utctime),
1600
- months[MonthFromTime(utctime)],
1601
- YearFromTime(utctime),
1602
- HourFromTime(utctime),
1603
- MinFromTime(utctime),
1604
- SecFromTime(utctime));
1605
- }
1606
- str = JS_NewStringCopyZ(cx, buf);
1607
- if (!str)
1608
- return JS_FALSE;
1609
- *vp = STRING_TO_JSVAL(str);
1610
- return JS_TRUE;
1611
- }
1612
-
1613
- /* for Date.toLocaleString; interface to PRMJTime date struct.
1614
- */
1615
- static void
1616
- new_explode(jsdouble timeval, PRMJTime *split)
1617
- {
1618
- jsint year = YearFromTime(timeval);
1619
-
1620
- split->tm_usec = (int32) msFromTime(timeval) * 1000;
1621
- split->tm_sec = (int8) SecFromTime(timeval);
1622
- split->tm_min = (int8) MinFromTime(timeval);
1623
- split->tm_hour = (int8) HourFromTime(timeval);
1624
- split->tm_mday = (int8) DateFromTime(timeval);
1625
- split->tm_mon = (int8) MonthFromTime(timeval);
1626
- split->tm_wday = (int8) WeekDay(timeval);
1627
- split->tm_year = year;
1628
- split->tm_yday = (int16) DayWithinYear(timeval, year);
1629
-
1630
- /* not sure how this affects things, but it doesn't seem
1631
- to matter. */
1632
- split->tm_isdst = (DaylightSavingTA(timeval) != 0);
1633
- }
1634
-
1635
- typedef enum formatspec {
1636
- FORMATSPEC_FULL, FORMATSPEC_DATE, FORMATSPEC_TIME
1637
- } formatspec;
1638
-
1639
- /* helper function */
1640
- static JSBool
1641
- date_format(JSContext *cx, jsdouble date, formatspec format, jsval *rval)
1642
- {
1643
- char buf[100];
1644
- JSString *str;
1645
- char tzbuf[100];
1646
- JSBool usetz;
1647
- size_t i, tzlen;
1648
- PRMJTime split;
1649
-
1650
- if (!JSDOUBLE_IS_FINITE(date)) {
1651
- JS_snprintf(buf, sizeof buf, js_NaN_date_str);
1652
- } else {
1653
- jsdouble local = LocalTime(date);
1654
-
1655
- /* offset from GMT in minutes. The offset includes daylight savings,
1656
- if it applies. */
1657
- jsint minutes = (jsint) floor(AdjustTime(date) / msPerMinute);
1658
-
1659
- /* map 510 minutes to 0830 hours */
1660
- intN offset = (minutes / 60) * 100 + minutes % 60;
1661
-
1662
- /* print as "Wed Nov 05 19:38:03 GMT-0800 (PST) 1997" The TZA is
1663
- * printed as 'GMT-0800' rather than as 'PST' to avoid
1664
- * operating-system dependence on strftime (which
1665
- * PRMJ_FormatTimeUSEnglish calls, for %Z only.) win32 prints
1666
- * PST as 'Pacific Standard Time.' This way we always know
1667
- * what we're getting, and can parse it if we produce it.
1668
- * The OS TZA string is included as a comment.
1669
- */
1670
-
1671
- /* get a timezone string from the OS to include as a
1672
- comment. */
1673
- new_explode(date, &split);
1674
- if (PRMJ_FormatTime(tzbuf, sizeof tzbuf, "(%Z)", &split) != 0) {
1675
-
1676
- /* Decide whether to use the resulting timezone string.
1677
- *
1678
- * Reject it if it contains any non-ASCII, non-alphanumeric
1679
- * characters. It's then likely in some other character
1680
- * encoding, and we probably won't display it correctly.
1681
- */
1682
- usetz = JS_TRUE;
1683
- tzlen = strlen(tzbuf);
1684
- if (tzlen > 100) {
1685
- usetz = JS_FALSE;
1686
- } else {
1687
- for (i = 0; i < tzlen; i++) {
1688
- jschar c = tzbuf[i];
1689
- if (c > 127 ||
1690
- !(isalpha(c) || isdigit(c) ||
1691
- c == ' ' || c == '(' || c == ')')) {
1692
- usetz = JS_FALSE;
1693
- }
1694
- }
1695
- }
1696
-
1697
- /* Also reject it if it's not parenthesized or if it's '()'. */
1698
- if (tzbuf[0] != '(' || tzbuf[1] == ')')
1699
- usetz = JS_FALSE;
1700
- } else
1701
- usetz = JS_FALSE;
1702
-
1703
- switch (format) {
1704
- case FORMATSPEC_FULL:
1705
- /*
1706
- * Avoid dependence on PRMJ_FormatTimeUSEnglish, because it
1707
- * requires a PRMJTime... which only has 16-bit years. Sub-ECMA.
1708
- */
1709
- /* Tue Oct 31 2000 09:41:40 GMT-0800 (PST) */
1710
- JS_snprintf(buf, sizeof buf,
1711
- "%s %s %.2d %.4d %.2d:%.2d:%.2d GMT%+.4d%s%s",
1712
- days[WeekDay(local)],
1713
- months[MonthFromTime(local)],
1714
- DateFromTime(local),
1715
- YearFromTime(local),
1716
- HourFromTime(local),
1717
- MinFromTime(local),
1718
- SecFromTime(local),
1719
- offset,
1720
- usetz ? " " : "",
1721
- usetz ? tzbuf : "");
1722
- break;
1723
- case FORMATSPEC_DATE:
1724
- /* Tue Oct 31 2000 */
1725
- JS_snprintf(buf, sizeof buf,
1726
- "%s %s %.2d %.4d",
1727
- days[WeekDay(local)],
1728
- months[MonthFromTime(local)],
1729
- DateFromTime(local),
1730
- YearFromTime(local));
1731
- break;
1732
- case FORMATSPEC_TIME:
1733
- /* 09:41:40 GMT-0800 (PST) */
1734
- JS_snprintf(buf, sizeof buf,
1735
- "%.2d:%.2d:%.2d GMT%+.4d%s%s",
1736
- HourFromTime(local),
1737
- MinFromTime(local),
1738
- SecFromTime(local),
1739
- offset,
1740
- usetz ? " " : "",
1741
- usetz ? tzbuf : "");
1742
- break;
1743
- }
1744
- }
1745
-
1746
- str = JS_NewStringCopyZ(cx, buf);
1747
- if (!str)
1748
- return JS_FALSE;
1749
- *rval = STRING_TO_JSVAL(str);
1750
- return JS_TRUE;
1751
- }
1752
-
1753
- static JSBool
1754
- date_toLocaleHelper(JSContext *cx, const char *format, jsval *vp)
1755
- {
1756
- JSObject *obj;
1757
- char buf[100];
1758
- JSString *str;
1759
- PRMJTime split;
1760
- jsdouble utctime;
1761
-
1762
- obj = JS_THIS_OBJECT(cx, vp);
1763
- if (!GetUTCTime(cx, obj, vp, &utctime))
1764
- return JS_FALSE;
1765
-
1766
- if (!JSDOUBLE_IS_FINITE(utctime)) {
1767
- JS_snprintf(buf, sizeof buf, js_NaN_date_str);
1768
- } else {
1769
- intN result_len;
1770
- jsdouble local = LocalTime(utctime);
1771
- new_explode(local, &split);
1772
-
1773
- /* let PRMJTime format it. */
1774
- result_len = PRMJ_FormatTime(buf, sizeof buf, format, &split);
1775
-
1776
- /* If it failed, default to toString. */
1777
- if (result_len == 0)
1778
- return date_format(cx, utctime, FORMATSPEC_FULL, vp);
1779
-
1780
- /* Hacked check against undesired 2-digit year 00/00/00 form. */
1781
- if (strcmp(format, "%x") == 0 && result_len >= 6 &&
1782
- /* Format %x means use OS settings, which may have 2-digit yr, so
1783
- hack end of 3/11/22 or 11.03.22 or 11Mar22 to use 4-digit yr...*/
1784
- !isdigit(buf[result_len - 3]) &&
1785
- isdigit(buf[result_len - 2]) && isdigit(buf[result_len - 1]) &&
1786
- /* ...but not if starts with 4-digit year, like 2022/3/11. */
1787
- !(isdigit(buf[0]) && isdigit(buf[1]) &&
1788
- isdigit(buf[2]) && isdigit(buf[3]))) {
1789
- JS_snprintf(buf + (result_len - 2), (sizeof buf) - (result_len - 2),
1790
- "%d", js_DateGetYear(cx, obj));
1791
- }
1792
-
1793
- }
1794
-
1795
- if (cx->localeCallbacks && cx->localeCallbacks->localeToUnicode)
1796
- return cx->localeCallbacks->localeToUnicode(cx, buf, vp);
1797
-
1798
- str = JS_NewStringCopyZ(cx, buf);
1799
- if (!str)
1800
- return JS_FALSE;
1801
- *vp = STRING_TO_JSVAL(str);
1802
- return JS_TRUE;
1803
- }
1804
-
1805
- static JSBool
1806
- date_toLocaleString(JSContext *cx, uintN argc, jsval *vp)
1807
- {
1808
- /* Use '%#c' for windows, because '%c' is
1809
- * backward-compatible and non-y2k with msvc; '%#c' requests that a
1810
- * full year be used in the result string.
1811
- */
1812
- return date_toLocaleHelper(cx,
1813
- #if defined(_WIN32) && !defined(__MWERKS__)
1814
- "%#c"
1815
- #else
1816
- "%c"
1817
- #endif
1818
- , vp);
1819
- }
1820
-
1821
- static JSBool
1822
- date_toLocaleDateString(JSContext *cx, uintN argc, jsval *vp)
1823
- {
1824
- /* Use '%#x' for windows, because '%x' is
1825
- * backward-compatible and non-y2k with msvc; '%#x' requests that a
1826
- * full year be used in the result string.
1827
- */
1828
- return date_toLocaleHelper(cx,
1829
- #if defined(_WIN32) && !defined(__MWERKS__)
1830
- "%#x"
1831
- #else
1832
- "%x"
1833
- #endif
1834
- , vp);
1835
- }
1836
-
1837
- static JSBool
1838
- date_toLocaleTimeString(JSContext *cx, uintN argc, jsval *vp)
1839
- {
1840
- return date_toLocaleHelper(cx, "%X", vp);
1841
- }
1842
-
1843
- static JSBool
1844
- date_toLocaleFormat(JSContext *cx, uintN argc, jsval *vp)
1845
- {
1846
- JSString *fmt;
1847
- const char *fmtbytes;
1848
-
1849
- if (argc == 0)
1850
- return date_toLocaleString(cx, argc, vp);
1851
-
1852
- fmt = js_ValueToString(cx, vp[2]);
1853
- if (!fmt)
1854
- return JS_FALSE;
1855
- vp[2] = STRING_TO_JSVAL(fmt);
1856
- fmtbytes = js_GetStringBytes(cx, fmt);
1857
- if (!fmtbytes)
1858
- return JS_FALSE;
1859
-
1860
- return date_toLocaleHelper(cx, fmtbytes, vp);
1861
- }
1862
-
1863
- static JSBool
1864
- date_toTimeString(JSContext *cx, uintN argc, jsval *vp)
1865
- {
1866
- jsdouble utctime;
1867
-
1868
- if (!GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &utctime))
1869
- return JS_FALSE;
1870
- return date_format(cx, utctime, FORMATSPEC_TIME, vp);
1871
- }
1872
-
1873
- static JSBool
1874
- date_toDateString(JSContext *cx, uintN argc, jsval *vp)
1875
- {
1876
- jsdouble utctime;
1877
-
1878
- if (!GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &utctime))
1879
- return JS_FALSE;
1880
- return date_format(cx, utctime, FORMATSPEC_DATE, vp);
1881
- }
1882
-
1883
- #if JS_HAS_TOSOURCE
1884
- #include <string.h>
1885
- #include "jsdtoa.h"
1886
-
1887
- static JSBool
1888
- date_toSource(JSContext *cx, uintN argc, jsval *vp)
1889
- {
1890
- jsdouble utctime;
1891
- char buf[DTOSTR_STANDARD_BUFFER_SIZE], *numStr, *bytes;
1892
- JSString *str;
1893
-
1894
- if (!GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &utctime))
1895
- return JS_FALSE;
1896
-
1897
- numStr = JS_dtostr(buf, sizeof buf, DTOSTR_STANDARD, 0, utctime);
1898
- if (!numStr) {
1899
- JS_ReportOutOfMemory(cx);
1900
- return JS_FALSE;
1901
- }
1902
-
1903
- bytes = JS_smprintf("(new %s(%s))", js_Date_str, numStr);
1904
- if (!bytes) {
1905
- JS_ReportOutOfMemory(cx);
1906
- return JS_FALSE;
1907
- }
1908
-
1909
- str = JS_NewString(cx, bytes, strlen(bytes));
1910
- if (!str) {
1911
- free(bytes);
1912
- return JS_FALSE;
1913
- }
1914
- *vp = STRING_TO_JSVAL(str);
1915
- return JS_TRUE;
1916
- }
1917
- #endif
1918
-
1919
- static JSBool
1920
- date_toString(JSContext *cx, uintN argc, jsval *vp)
1921
- {
1922
- jsdouble utctime;
1923
-
1924
- if (!GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &utctime))
1925
- return JS_FALSE;
1926
- return date_format(cx, utctime, FORMATSPEC_FULL, vp);
1927
- }
1928
-
1929
- static JSBool
1930
- date_valueOf(JSContext *cx, uintN argc, jsval *vp)
1931
- {
1932
- JSString *str, *str2;
1933
-
1934
- /* It is an error to call date_valueOf on a non-date object, but we don't
1935
- * need to check for that explicitly here because every path calls
1936
- * GetUTCTime, which does the check.
1937
- */
1938
-
1939
- /* If called directly with no arguments, convert to a time number. */
1940
- if (argc == 0)
1941
- return date_getTime(cx, argc, vp);
1942
-
1943
- /* Convert to number only if the hint was given, otherwise favor string. */
1944
- str = js_ValueToString(cx, vp[2]);
1945
- if (!str)
1946
- return JS_FALSE;
1947
- str2 = ATOM_TO_STRING(cx->runtime->atomState.typeAtoms[JSTYPE_NUMBER]);
1948
- if (js_EqualStrings(str, str2))
1949
- return date_getTime(cx, argc, vp);
1950
- return date_toString(cx, argc, vp);
1951
- }
1952
-
1953
-
1954
- /*
1955
- * creation and destruction
1956
- */
1957
-
1958
- static JSFunctionSpec date_static_methods[] = {
1959
- JS_FN("UTC", date_UTC, 2,MAXARGS,0),
1960
- JS_FN("parse", date_parse, 1,1,0),
1961
- JS_FN("now", date_now, 0,0,0),
1962
- JS_FS_END
1963
- };
1964
-
1965
- static JSFunctionSpec date_methods[] = {
1966
- JS_FN("getTime", date_getTime, 0,0,0),
1967
- JS_FN("getTimezoneOffset", date_getTimezoneOffset, 0,0,0),
1968
- JS_FN("getYear", date_getYear, 0,0,0),
1969
- JS_FN("getFullYear", date_getFullYear, 0,0,0),
1970
- JS_FN("getUTCFullYear", date_getUTCFullYear, 0,0,0),
1971
- JS_FN("getMonth", date_getMonth, 0,0,0),
1972
- JS_FN("getUTCMonth", date_getUTCMonth, 0,0,0),
1973
- JS_FN("getDate", date_getDate, 0,0,0),
1974
- JS_FN("getUTCDate", date_getUTCDate, 0,0,0),
1975
- JS_FN("getDay", date_getDay, 0,0,0),
1976
- JS_FN("getUTCDay", date_getUTCDay, 0,0,0),
1977
- JS_FN("getHours", date_getHours, 0,0,0),
1978
- JS_FN("getUTCHours", date_getUTCHours, 0,0,0),
1979
- JS_FN("getMinutes", date_getMinutes, 0,0,0),
1980
- JS_FN("getUTCMinutes", date_getUTCMinutes, 0,0,0),
1981
- JS_FN("getSeconds", date_getUTCSeconds, 0,0,0),
1982
- JS_FN("getUTCSeconds", date_getUTCSeconds, 0,0,0),
1983
- JS_FN("getMilliseconds", date_getUTCMilliseconds, 0,0,0),
1984
- JS_FN("getUTCMilliseconds", date_getUTCMilliseconds, 0,0,0),
1985
- JS_FN("setTime", date_setTime, 1,1,0),
1986
- JS_FN("setYear", date_setYear, 1,1,0),
1987
- JS_FN("setFullYear", date_setFullYear, 1,3,0),
1988
- JS_FN("setUTCFullYear", date_setUTCFullYear, 1,3,0),
1989
- JS_FN("setMonth", date_setMonth, 1,2,0),
1990
- JS_FN("setUTCMonth", date_setUTCMonth, 1,2,0),
1991
- JS_FN("setDate", date_setDate, 1,1,0),
1992
- JS_FN("setUTCDate", date_setUTCDate, 1,1,0),
1993
- JS_FN("setHours", date_setHours, 1,4,0),
1994
- JS_FN("setUTCHours", date_setUTCHours, 1,4,0),
1995
- JS_FN("setMinutes", date_setMinutes, 1,3,0),
1996
- JS_FN("setUTCMinutes", date_setUTCMinutes, 1,3,0),
1997
- JS_FN("setSeconds", date_setSeconds, 1,2,0),
1998
- JS_FN("setUTCSeconds", date_setUTCSeconds, 1,2,0),
1999
- JS_FN("setMilliseconds", date_setMilliseconds, 1,1,0),
2000
- JS_FN("setUTCMilliseconds", date_setUTCMilliseconds, 1,1,0),
2001
- JS_FN("toUTCString", date_toGMTString, 0,0,0),
2002
- JS_FN(js_toLocaleString_str, date_toLocaleString, 0,0,0),
2003
- JS_FN("toLocaleDateString", date_toLocaleDateString, 0,0,0),
2004
- JS_FN("toLocaleTimeString", date_toLocaleTimeString, 0,0,0),
2005
- JS_FN("toLocaleFormat", date_toLocaleFormat, 0,0,0),
2006
- JS_FN("toDateString", date_toDateString, 0,0,0),
2007
- JS_FN("toTimeString", date_toTimeString, 0,0,0),
2008
- #if JS_HAS_TOSOURCE
2009
- JS_FN(js_toSource_str, date_toSource, 0,0,0),
2010
- #endif
2011
- JS_FN(js_toString_str, date_toString, 0,0,0),
2012
- JS_FN(js_valueOf_str, date_valueOf, 0,0,0),
2013
- JS_FS_END
2014
- };
2015
-
2016
- static jsdouble *
2017
- date_constructor(JSContext *cx, JSObject* obj)
2018
- {
2019
- jsdouble *date;
2020
-
2021
- date = js_NewWeaklyRootedDouble(cx, 0.0);
2022
- if (!date)
2023
- return NULL;
2024
-
2025
- obj->fslots[JSSLOT_UTC_TIME] = DOUBLE_TO_JSVAL(date);
2026
- obj->fslots[JSSLOT_LOCAL_TIME] = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
2027
- return date;
2028
- }
2029
-
2030
- static JSBool
2031
- Date(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2032
- {
2033
- jsdouble *date;
2034
- JSString *str;
2035
- jsdouble d;
2036
-
2037
- /* Date called as function. */
2038
- if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) {
2039
- int64 us, ms, us2ms;
2040
- jsdouble msec_time;
2041
-
2042
- /* NSPR 2.0 docs say 'We do not support PRMJ_NowMS and PRMJ_NowS',
2043
- * so compute ms from PRMJ_Now.
2044
- */
2045
- us = PRMJ_Now();
2046
- JSLL_UI2L(us2ms, PRMJ_USEC_PER_MSEC);
2047
- JSLL_DIV(ms, us, us2ms);
2048
- JSLL_L2D(msec_time, ms);
2049
-
2050
- return date_format(cx, msec_time, FORMATSPEC_FULL, rval);
2051
- }
2052
-
2053
- /* Date called as constructor. */
2054
- if (argc == 0) {
2055
- int64 us, ms, us2ms;
2056
- jsdouble msec_time;
2057
-
2058
- date = date_constructor(cx, obj);
2059
- if (!date)
2060
- return JS_FALSE;
2061
-
2062
- us = PRMJ_Now();
2063
- JSLL_UI2L(us2ms, PRMJ_USEC_PER_MSEC);
2064
- JSLL_DIV(ms, us, us2ms);
2065
- JSLL_L2D(msec_time, ms);
2066
-
2067
- *date = msec_time;
2068
- } else if (argc == 1) {
2069
- if (!JSVAL_IS_STRING(argv[0])) {
2070
- /* the argument is a millisecond number */
2071
- d = js_ValueToNumber(cx, &argv[0]);
2072
- if (JSVAL_IS_NULL(argv[0]))
2073
- return JS_FALSE;
2074
- date = date_constructor(cx, obj);
2075
- if (!date)
2076
- return JS_FALSE;
2077
- *date = TIMECLIP(d);
2078
- } else {
2079
- /* the argument is a string; parse it. */
2080
- date = date_constructor(cx, obj);
2081
- if (!date)
2082
- return JS_FALSE;
2083
-
2084
- str = js_ValueToString(cx, argv[0]);
2085
- if (!str)
2086
- return JS_FALSE;
2087
-
2088
- if (!date_parseString(str, date))
2089
- *date = *cx->runtime->jsNaN;
2090
- *date = TIMECLIP(*date);
2091
- }
2092
- } else {
2093
- jsdouble *date;
2094
- jsdouble msec_time;
2095
-
2096
- if (!date_msecFromArgs(cx, argc, argv, &msec_time))
2097
- return JS_FALSE;
2098
-
2099
- date = date_constructor(cx, obj);
2100
- if (!date)
2101
- return JS_FALSE;
2102
-
2103
- if (JSDOUBLE_IS_FINITE(msec_time)) {
2104
- msec_time = UTC(msec_time);
2105
- msec_time = TIMECLIP(msec_time);
2106
- }
2107
-
2108
- *date = msec_time;
2109
- }
2110
- return JS_TRUE;
2111
- }
2112
-
2113
- JSObject *
2114
- js_InitDateClass(JSContext *cx, JSObject *obj)
2115
- {
2116
- JSObject *proto;
2117
- jsdouble *proto_date;
2118
-
2119
- /* set static LocalTZA */
2120
- LocalTZA = -(PRMJ_LocalGMTDifference() * msPerSecond);
2121
- proto = JS_InitClass(cx, obj, NULL, &js_DateClass, Date, MAXARGS,
2122
- NULL, date_methods, NULL, date_static_methods);
2123
- if (!proto)
2124
- return NULL;
2125
-
2126
- /* Alias toUTCString with toGMTString. (ECMA B.2.6) */
2127
- if (!JS_AliasProperty(cx, proto, "toUTCString", "toGMTString"))
2128
- return NULL;
2129
-
2130
- /* Set the value of the Date.prototype date to NaN */
2131
- proto_date = date_constructor(cx, proto);
2132
- if (!proto_date)
2133
- return NULL;
2134
- *proto_date = *cx->runtime->jsNaN;
2135
-
2136
- return proto;
2137
- }
2138
-
2139
- JS_FRIEND_API(JSObject *)
2140
- js_NewDateObjectMsec(JSContext *cx, jsdouble msec_time)
2141
- {
2142
- JSObject *obj;
2143
- jsdouble *date;
2144
-
2145
- obj = js_NewObject(cx, &js_DateClass, NULL, NULL, 0);
2146
- if (!obj)
2147
- return NULL;
2148
-
2149
- date = date_constructor(cx, obj);
2150
- if (!date)
2151
- return NULL;
2152
-
2153
- *date = msec_time;
2154
- return obj;
2155
- }
2156
-
2157
- JS_FRIEND_API(JSObject *)
2158
- js_NewDateObject(JSContext* cx, int year, int mon, int mday,
2159
- int hour, int min, int sec)
2160
- {
2161
- JSObject *obj;
2162
- jsdouble msec_time;
2163
-
2164
- JS_ASSERT(mon < 12);
2165
- msec_time = date_msecFromDate(year, mon, mday, hour, min, sec, 0);
2166
- obj = js_NewDateObjectMsec(cx, UTC(msec_time));
2167
- return obj;
2168
- }
2169
-
2170
- JS_FRIEND_API(JSBool)
2171
- js_DateIsValid(JSContext *cx, JSObject* obj)
2172
- {
2173
- jsdouble utctime;
2174
- return GetUTCTime(cx, obj, NULL, &utctime) && !JSDOUBLE_IS_NaN(utctime);
2175
- }
2176
-
2177
- JS_FRIEND_API(int)
2178
- js_DateGetYear(JSContext *cx, JSObject* obj)
2179
- {
2180
- jsdouble localtime;
2181
-
2182
- /* Preserve legacy API behavior of returning 0 for invalid dates. */
2183
- if (!GetAndCacheLocalTime(cx, obj, NULL, &localtime) ||
2184
- JSDOUBLE_IS_NaN(localtime)) {
2185
- return 0;
2186
- }
2187
-
2188
- return (int) YearFromTime(localtime);
2189
- }
2190
-
2191
- JS_FRIEND_API(int)
2192
- js_DateGetMonth(JSContext *cx, JSObject* obj)
2193
- {
2194
- jsdouble localtime;
2195
-
2196
- if (!GetAndCacheLocalTime(cx, obj, NULL, &localtime) ||
2197
- JSDOUBLE_IS_NaN(localtime)) {
2198
- return 0;
2199
- }
2200
-
2201
- return (int) MonthFromTime(localtime);
2202
- }
2203
-
2204
- JS_FRIEND_API(int)
2205
- js_DateGetDate(JSContext *cx, JSObject* obj)
2206
- {
2207
- jsdouble localtime;
2208
-
2209
- if (!GetAndCacheLocalTime(cx, obj, NULL, &localtime) ||
2210
- JSDOUBLE_IS_NaN(localtime)) {
2211
- return 0;
2212
- }
2213
-
2214
- return (int) DateFromTime(localtime);
2215
- }
2216
-
2217
- JS_FRIEND_API(int)
2218
- js_DateGetHours(JSContext *cx, JSObject* obj)
2219
- {
2220
- jsdouble localtime;
2221
-
2222
- if (!GetAndCacheLocalTime(cx, obj, NULL, &localtime) ||
2223
- JSDOUBLE_IS_NaN(localtime)) {
2224
- return 0;
2225
- }
2226
-
2227
- return (int) HourFromTime(localtime);
2228
- }
2229
-
2230
- JS_FRIEND_API(int)
2231
- js_DateGetMinutes(JSContext *cx, JSObject* obj)
2232
- {
2233
- jsdouble localtime;
2234
-
2235
- if (!GetAndCacheLocalTime(cx, obj, NULL, &localtime) ||
2236
- JSDOUBLE_IS_NaN(localtime)) {
2237
- return 0;
2238
- }
2239
-
2240
- return (int) MinFromTime(localtime);
2241
- }
2242
-
2243
- JS_FRIEND_API(int)
2244
- js_DateGetSeconds(JSContext *cx, JSObject* obj)
2245
- {
2246
- jsdouble utctime;
2247
-
2248
- if (!GetUTCTime(cx, obj, NULL, &utctime) || JSDOUBLE_IS_NaN(utctime))
2249
- return 0;
2250
-
2251
- return (int) SecFromTime(utctime);
2252
- }
2253
-
2254
- JS_FRIEND_API(void)
2255
- js_DateSetYear(JSContext *cx, JSObject *obj, int year)
2256
- {
2257
- jsdouble local;
2258
-
2259
- if (!GetAndCacheLocalTime(cx, obj, NULL, &local))
2260
- return;
2261
-
2262
- /* reset date if it was NaN */
2263
- if (JSDOUBLE_IS_NaN(local))
2264
- local = 0;
2265
-
2266
- local = date_msecFromDate(year,
2267
- MonthFromTime(local),
2268
- DateFromTime(local),
2269
- HourFromTime(local),
2270
- MinFromTime(local),
2271
- SecFromTime(local),
2272
- msFromTime(local));
2273
-
2274
- /* SetUTCTime also invalidates local time cache. */
2275
- SetUTCTime(cx, obj, NULL, UTC(local));
2276
- }
2277
-
2278
- JS_FRIEND_API(void)
2279
- js_DateSetMonth(JSContext *cx, JSObject *obj, int month)
2280
- {
2281
- jsdouble local;
2282
-
2283
- JS_ASSERT(month < 12);
2284
-
2285
- if (!GetAndCacheLocalTime(cx, obj, NULL, &local))
2286
- return;
2287
-
2288
- /* bail if date was NaN */
2289
- if (JSDOUBLE_IS_NaN(local))
2290
- return;
2291
-
2292
- local = date_msecFromDate(YearFromTime(local),
2293
- month,
2294
- DateFromTime(local),
2295
- HourFromTime(local),
2296
- MinFromTime(local),
2297
- SecFromTime(local),
2298
- msFromTime(local));
2299
- SetUTCTime(cx, obj, NULL, UTC(local));
2300
- }
2301
-
2302
- JS_FRIEND_API(void)
2303
- js_DateSetDate(JSContext *cx, JSObject *obj, int date)
2304
- {
2305
- jsdouble local;
2306
-
2307
- if (!GetAndCacheLocalTime(cx, obj, NULL, &local))
2308
- return;
2309
-
2310
- if (JSDOUBLE_IS_NaN(local))
2311
- return;
2312
-
2313
- local = date_msecFromDate(YearFromTime(local),
2314
- MonthFromTime(local),
2315
- date,
2316
- HourFromTime(local),
2317
- MinFromTime(local),
2318
- SecFromTime(local),
2319
- msFromTime(local));
2320
- SetUTCTime(cx, obj, NULL, UTC(local));
2321
- }
2322
-
2323
- JS_FRIEND_API(void)
2324
- js_DateSetHours(JSContext *cx, JSObject *obj, int hours)
2325
- {
2326
- jsdouble local;
2327
-
2328
- if (!GetAndCacheLocalTime(cx, obj, NULL, &local))
2329
- return;
2330
-
2331
- if (JSDOUBLE_IS_NaN(local))
2332
- return;
2333
- local = date_msecFromDate(YearFromTime(local),
2334
- MonthFromTime(local),
2335
- DateFromTime(local),
2336
- hours,
2337
- MinFromTime(local),
2338
- SecFromTime(local),
2339
- msFromTime(local));
2340
- SetUTCTime(cx, obj, NULL, UTC(local));
2341
- }
2342
-
2343
- JS_FRIEND_API(void)
2344
- js_DateSetMinutes(JSContext *cx, JSObject *obj, int minutes)
2345
- {
2346
- jsdouble local;
2347
-
2348
- if (!GetAndCacheLocalTime(cx, obj, NULL, &local))
2349
- return;
2350
-
2351
- if (JSDOUBLE_IS_NaN(local))
2352
- return;
2353
- local = date_msecFromDate(YearFromTime(local),
2354
- MonthFromTime(local),
2355
- DateFromTime(local),
2356
- HourFromTime(local),
2357
- minutes,
2358
- SecFromTime(local),
2359
- msFromTime(local));
2360
- SetUTCTime(cx, obj, NULL, UTC(local));
2361
- }
2362
-
2363
- JS_FRIEND_API(void)
2364
- js_DateSetSeconds(JSContext *cx, JSObject *obj, int seconds)
2365
- {
2366
- jsdouble local;
2367
-
2368
- if (!GetAndCacheLocalTime(cx, obj, NULL, &local))
2369
- return;
2370
-
2371
- if (JSDOUBLE_IS_NaN(local))
2372
- return;
2373
- local = date_msecFromDate(YearFromTime(local),
2374
- MonthFromTime(local),
2375
- DateFromTime(local),
2376
- HourFromTime(local),
2377
- MinFromTime(local),
2378
- seconds,
2379
- msFromTime(local));
2380
- SetUTCTime(cx, obj, NULL, UTC(local));
2381
- }
2382
-
2383
- JS_FRIEND_API(jsdouble)
2384
- js_DateGetMsecSinceEpoch(JSContext *cx, JSObject *obj)
2385
- {
2386
- jsdouble utctime;
2387
- if (!GetUTCTime(cx, obj, NULL, &utctime))
2388
- return 0;
2389
- return utctime;
2390
- }