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,1371 +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 standard exception implementation.
43
- */
44
-
45
- #include "jsstddef.h"
46
- #include <stdlib.h>
47
- #include <string.h>
48
- #include "jstypes.h"
49
- #include "jsbit.h"
50
- #include "jsutil.h" /* Added by JSIFY */
51
- #include "jsprf.h"
52
- #include "jsapi.h"
53
- #include "jscntxt.h"
54
- #include "jsconfig.h"
55
- #include "jsdbgapi.h"
56
- #include "jsexn.h"
57
- #include "jsfun.h"
58
- #include "jsinterp.h"
59
- #include "jsnum.h"
60
- #include "jsobj.h"
61
- #include "jsopcode.h"
62
- #include "jsscope.h"
63
- #include "jsscript.h"
64
-
65
- /* Forward declarations for js_ErrorClass's initializer. */
66
- static JSBool
67
- Exception(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
68
-
69
- static void
70
- exn_finalize(JSContext *cx, JSObject *obj);
71
-
72
- static void
73
- exn_trace(JSTracer *trc, JSObject *obj);
74
-
75
- static void
76
- exn_finalize(JSContext *cx, JSObject *obj);
77
-
78
- static JSBool
79
- exn_enumerate(JSContext *cx, JSObject *obj);
80
-
81
- static JSBool
82
- exn_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
83
- JSObject **objp);
84
-
85
- JSClass js_ErrorClass = {
86
- js_Error_str,
87
- JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE | JSCLASS_MARK_IS_TRACE |
88
- JSCLASS_HAS_CACHED_PROTO(JSProto_Error),
89
- JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
90
- exn_enumerate, (JSResolveOp)exn_resolve, JS_ConvertStub, exn_finalize,
91
- NULL, NULL, NULL, Exception,
92
- NULL, NULL, JS_CLASS_TRACE(exn_trace), NULL
93
- };
94
-
95
- typedef struct JSStackTraceElem {
96
- JSString *funName;
97
- size_t argc;
98
- const char *filename;
99
- uintN ulineno;
100
- } JSStackTraceElem;
101
-
102
- typedef struct JSExnPrivate {
103
- /* A copy of the JSErrorReport originally generated. */
104
- JSErrorReport *errorReport;
105
- JSString *message;
106
- JSString *filename;
107
- uintN lineno;
108
- size_t stackDepth;
109
- JSStackTraceElem stackElems[1];
110
- } JSExnPrivate;
111
-
112
- static JSString *
113
- StackTraceToString(JSContext *cx, JSExnPrivate *priv);
114
-
115
- static JSErrorReport *
116
- CopyErrorReport(JSContext *cx, JSErrorReport *report)
117
- {
118
- /*
119
- * We use a single malloc block to make a deep copy of JSErrorReport with
120
- * the following layout:
121
- * JSErrorReport
122
- * array of copies of report->messageArgs
123
- * jschar array with characters for all messageArgs
124
- * jschar array with characters for ucmessage
125
- * jschar array with characters for uclinebuf and uctokenptr
126
- * char array with characters for linebuf and tokenptr
127
- * char array with characters for filename
128
- * Such layout together with the properties enforced by the following
129
- * asserts does not need any extra alignment padding.
130
- */
131
- JS_STATIC_ASSERT(sizeof(JSErrorReport) % sizeof(const char *) == 0);
132
- JS_STATIC_ASSERT(sizeof(const char *) % sizeof(jschar) == 0);
133
-
134
- size_t filenameSize;
135
- size_t linebufSize;
136
- size_t uclinebufSize;
137
- size_t ucmessageSize;
138
- size_t i, argsArraySize, argsCopySize, argSize;
139
- size_t mallocSize;
140
- JSErrorReport *copy;
141
- uint8 *cursor;
142
-
143
- #define JS_CHARS_SIZE(jschars) ((js_strlen(jschars) + 1) * sizeof(jschar))
144
-
145
- filenameSize = report->filename ? strlen(report->filename) + 1 : 0;
146
- linebufSize = report->linebuf ? strlen(report->linebuf) + 1 : 0;
147
- uclinebufSize = report->uclinebuf ? JS_CHARS_SIZE(report->uclinebuf) : 0;
148
- ucmessageSize = 0;
149
- argsArraySize = 0;
150
- argsCopySize = 0;
151
- if (report->ucmessage) {
152
- ucmessageSize = JS_CHARS_SIZE(report->ucmessage);
153
- if (report->messageArgs) {
154
- for (i = 0; report->messageArgs[i]; ++i)
155
- argsCopySize += JS_CHARS_SIZE(report->messageArgs[i]);
156
-
157
- /* Non-null messageArgs should have at least one non-null arg. */
158
- JS_ASSERT(i != 0);
159
- argsArraySize = (i + 1) * sizeof(const jschar *);
160
- }
161
- }
162
-
163
- /*
164
- * The mallocSize can not overflow since it represents the sum of the
165
- * sizes of already allocated objects.
166
- */
167
- mallocSize = sizeof(JSErrorReport) + argsArraySize + argsCopySize +
168
- ucmessageSize + uclinebufSize + linebufSize + filenameSize;
169
- cursor = (uint8 *)JS_malloc(cx, mallocSize);
170
- if (!cursor)
171
- return NULL;
172
-
173
- copy = (JSErrorReport *)cursor;
174
- memset(cursor, 0, sizeof(JSErrorReport));
175
- cursor += sizeof(JSErrorReport);
176
-
177
- if (argsArraySize != 0) {
178
- copy->messageArgs = (const jschar **)cursor;
179
- cursor += argsArraySize;
180
- for (i = 0; report->messageArgs[i]; ++i) {
181
- copy->messageArgs[i] = (const jschar *)cursor;
182
- argSize = JS_CHARS_SIZE(report->messageArgs[i]);
183
- memcpy(cursor, report->messageArgs[i], argSize);
184
- cursor += argSize;
185
- }
186
- copy->messageArgs[i] = NULL;
187
- JS_ASSERT(cursor == (uint8 *)copy->messageArgs[0] + argsCopySize);
188
- }
189
-
190
- if (report->ucmessage) {
191
- copy->ucmessage = (const jschar *)cursor;
192
- memcpy(cursor, report->ucmessage, ucmessageSize);
193
- cursor += ucmessageSize;
194
- }
195
-
196
- if (report->uclinebuf) {
197
- copy->uclinebuf = (const jschar *)cursor;
198
- memcpy(cursor, report->uclinebuf, uclinebufSize);
199
- cursor += uclinebufSize;
200
- if (report->uctokenptr) {
201
- copy->uctokenptr = copy->uclinebuf + (report->uctokenptr -
202
- report->uclinebuf);
203
- }
204
- }
205
-
206
- if (report->linebuf) {
207
- copy->linebuf = (const char *)cursor;
208
- memcpy(cursor, report->linebuf, linebufSize);
209
- cursor += linebufSize;
210
- if (report->tokenptr) {
211
- copy->tokenptr = copy->linebuf + (report->tokenptr -
212
- report->linebuf);
213
- }
214
- }
215
-
216
- if (report->filename) {
217
- copy->filename = (const char *)cursor;
218
- memcpy(cursor, report->filename, filenameSize);
219
- }
220
- JS_ASSERT(cursor + filenameSize == (uint8 *)copy + mallocSize);
221
-
222
- /* Copy non-pointer members. */
223
- copy->lineno = report->lineno;
224
- copy->errorNumber = report->errorNumber;
225
-
226
- /* Note that this is before it gets flagged with JSREPORT_EXCEPTION */
227
- copy->flags = report->flags;
228
-
229
- #undef JS_CHARS_SIZE
230
- return copy;
231
- }
232
-
233
- static jsval *
234
- GetStackTraceValueBuffer(JSExnPrivate *priv)
235
- {
236
- /*
237
- * We use extra memory after JSExnPrivateInfo.stackElems to store jsvals
238
- * that helps to produce more informative stack traces. The following
239
- * assert allows us to assume that no gap after stackElems is necessary to
240
- * align the buffer properly.
241
- */
242
- JS_STATIC_ASSERT(sizeof(JSStackTraceElem) % sizeof(jsval) == 0);
243
-
244
- return (jsval *)(priv->stackElems + priv->stackDepth);
245
- }
246
-
247
- static JSBool
248
- InitExnPrivate(JSContext *cx, JSObject *exnObject, JSString *message,
249
- JSString *filename, uintN lineno, JSErrorReport *report)
250
- {
251
- JSCheckAccessOp checkAccess;
252
- JSErrorReporter older;
253
- JSExceptionState *state;
254
- jsval callerid, v;
255
- JSStackFrame *fp, *fpstop;
256
- size_t stackDepth, valueCount, size;
257
- JSBool overflow;
258
- JSExnPrivate *priv;
259
- JSStackTraceElem *elem;
260
- jsval *values;
261
-
262
- JS_ASSERT(OBJ_GET_CLASS(cx, exnObject) == &js_ErrorClass);
263
-
264
- /*
265
- * Prepare stack trace data.
266
- *
267
- * Set aside any error reporter for cx and save its exception state
268
- * so we can suppress any checkAccess failures. Such failures should stop
269
- * the backtrace procedure, not result in a failure of this constructor.
270
- */
271
- checkAccess = cx->runtime->checkObjectAccess;
272
- older = JS_SetErrorReporter(cx, NULL);
273
- state = JS_SaveExceptionState(cx);
274
-
275
- callerid = ATOM_KEY(cx->runtime->atomState.callerAtom);
276
- stackDepth = 0;
277
- valueCount = 0;
278
- for (fp = cx->fp; fp; fp = fp->down) {
279
- if (fp->fun && fp->argv) {
280
- v = JSVAL_NULL;
281
- if (checkAccess &&
282
- !checkAccess(cx, fp->callee, callerid, JSACC_READ, &v)) {
283
- break;
284
- }
285
- valueCount += fp->argc;
286
- }
287
- ++stackDepth;
288
- }
289
- JS_RestoreExceptionState(cx, state);
290
- JS_SetErrorReporter(cx, older);
291
- fpstop = fp;
292
-
293
- size = offsetof(JSExnPrivate, stackElems);
294
- overflow = (stackDepth > ((size_t)-1 - size) / sizeof(JSStackTraceElem));
295
- size += stackDepth * sizeof(JSStackTraceElem);
296
- overflow |= (valueCount > ((size_t)-1 - size) / sizeof(jsval));
297
- size += valueCount * sizeof(jsval);
298
- if (overflow) {
299
- js_ReportAllocationOverflow(cx);
300
- return JS_FALSE;
301
- }
302
- priv = (JSExnPrivate *)JS_malloc(cx, size);
303
- if (!priv)
304
- return JS_FALSE;
305
-
306
- /*
307
- * We initialize errorReport with a copy of report after setting the
308
- * private slot, to prevent GC accessing a junk value we clear the field
309
- * here.
310
- */
311
- priv->errorReport = NULL;
312
- priv->message = message;
313
- priv->filename = filename;
314
- priv->lineno = lineno;
315
- priv->stackDepth = stackDepth;
316
-
317
- values = GetStackTraceValueBuffer(priv);
318
- elem = priv->stackElems;
319
- for (fp = cx->fp; fp != fpstop; fp = fp->down) {
320
- if (!fp->fun) {
321
- elem->funName = NULL;
322
- elem->argc = 0;
323
- } else {
324
- elem->funName = fp->fun->atom
325
- ? ATOM_TO_STRING(fp->fun->atom)
326
- : cx->runtime->emptyString;
327
- elem->argc = fp->argc;
328
- memcpy(values, fp->argv, fp->argc * sizeof(jsval));
329
- values += fp->argc;
330
- }
331
- elem->ulineno = 0;
332
- elem->filename = NULL;
333
- if (fp->script) {
334
- elem->filename = fp->script->filename;
335
- if (fp->regs)
336
- elem->ulineno = js_PCToLineNumber(cx, fp->script, fp->regs->pc);
337
- }
338
- ++elem;
339
- }
340
- JS_ASSERT(priv->stackElems + stackDepth == elem);
341
- JS_ASSERT(GetStackTraceValueBuffer(priv) + valueCount == values);
342
-
343
- STOBJ_SET_SLOT(exnObject, JSSLOT_PRIVATE, PRIVATE_TO_JSVAL(priv));
344
-
345
- if (report) {
346
- /*
347
- * Construct a new copy of the error report struct. We can't use the
348
- * error report struct that was passed in, because it's allocated on
349
- * the stack, and also because it may point to transient data in the
350
- * JSTokenStream.
351
- */
352
- priv->errorReport = CopyErrorReport(cx, report);
353
- if (!priv->errorReport) {
354
- /* The finalizer realeases priv since it is in the private slot. */
355
- return JS_FALSE;
356
- }
357
- }
358
-
359
- return JS_TRUE;
360
- }
361
-
362
- static JSExnPrivate *
363
- GetExnPrivate(JSContext *cx, JSObject *obj)
364
- {
365
- jsval privateValue;
366
- JSExnPrivate *priv;
367
-
368
- JS_ASSERT(OBJ_GET_CLASS(cx, obj) == &js_ErrorClass);
369
- privateValue = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
370
- if (JSVAL_IS_VOID(privateValue))
371
- return NULL;
372
- priv = (JSExnPrivate *)JSVAL_TO_PRIVATE(privateValue);
373
- JS_ASSERT(priv);
374
- return priv;
375
- }
376
-
377
- static void
378
- exn_trace(JSTracer *trc, JSObject *obj)
379
- {
380
- JSExnPrivate *priv;
381
- JSStackTraceElem *elem;
382
- size_t vcount, i;
383
- jsval *vp, v;
384
-
385
- priv = GetExnPrivate(trc->context, obj);
386
- if (priv) {
387
- if (priv->message)
388
- JS_CALL_STRING_TRACER(trc, priv->message, "exception message");
389
- if (priv->filename)
390
- JS_CALL_STRING_TRACER(trc, priv->filename, "exception filename");
391
-
392
- elem = priv->stackElems;
393
- for (vcount = i = 0; i != priv->stackDepth; ++i, ++elem) {
394
- if (elem->funName) {
395
- JS_CALL_STRING_TRACER(trc, elem->funName,
396
- "stack trace function name");
397
- }
398
- if (IS_GC_MARKING_TRACER(trc) && elem->filename)
399
- js_MarkScriptFilename(elem->filename);
400
- vcount += elem->argc;
401
- }
402
- vp = GetStackTraceValueBuffer(priv);
403
- for (i = 0; i != vcount; ++i, ++vp) {
404
- v = *vp;
405
- JS_CALL_VALUE_TRACER(trc, v, "stack trace argument");
406
- }
407
- }
408
- }
409
-
410
- static void
411
- exn_finalize(JSContext *cx, JSObject *obj)
412
- {
413
- JSExnPrivate *priv;
414
-
415
- priv = GetExnPrivate(cx, obj);
416
- if (priv) {
417
- if (priv->errorReport)
418
- JS_free(cx, priv->errorReport);
419
- JS_free(cx, priv);
420
- }
421
- }
422
-
423
- static JSBool
424
- exn_enumerate(JSContext *cx, JSObject *obj)
425
- {
426
- JSAtomState *atomState;
427
- uintN i;
428
- JSAtom *atom;
429
- JSObject *pobj;
430
- JSProperty *prop;
431
-
432
- JS_STATIC_ASSERT(sizeof(JSAtomState) <= (size_t)(uint16)-1);
433
- static const uint16 offsets[] = {
434
- (uint16)offsetof(JSAtomState, messageAtom),
435
- (uint16)offsetof(JSAtomState, fileNameAtom),
436
- (uint16)offsetof(JSAtomState, lineNumberAtom),
437
- (uint16)offsetof(JSAtomState, stackAtom),
438
- };
439
-
440
- atomState = &cx->runtime->atomState;
441
- for (i = 0; i != JS_ARRAY_LENGTH(offsets); ++i) {
442
- atom = *(JSAtom **)((uint8 *)atomState + offsets[i]);
443
- if (!js_LookupProperty(cx, obj, ATOM_TO_JSID(atom), &pobj, &prop))
444
- return JS_FALSE;
445
- if (prop)
446
- OBJ_DROP_PROPERTY(cx, pobj, prop);
447
- }
448
- return JS_TRUE;
449
- }
450
-
451
- static JSBool
452
- exn_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
453
- JSObject **objp)
454
- {
455
- JSExnPrivate *priv;
456
- JSString *str;
457
- JSAtom *atom;
458
- JSString *stack;
459
- const char *prop;
460
- jsval v;
461
-
462
- *objp = NULL;
463
- priv = GetExnPrivate(cx, obj);
464
- if (priv && JSVAL_IS_STRING(id)) {
465
- str = JSVAL_TO_STRING(id);
466
-
467
- atom = cx->runtime->atomState.messageAtom;
468
- if (str == ATOM_TO_STRING(atom)) {
469
- prop = js_message_str;
470
- v = STRING_TO_JSVAL(priv->message);
471
- goto define;
472
- }
473
-
474
- atom = cx->runtime->atomState.fileNameAtom;
475
- if (str == ATOM_TO_STRING(atom)) {
476
- prop = js_fileName_str;
477
- v = STRING_TO_JSVAL(priv->filename);
478
- goto define;
479
- }
480
-
481
- atom = cx->runtime->atomState.lineNumberAtom;
482
- if (str == ATOM_TO_STRING(atom)) {
483
- prop = js_lineNumber_str;
484
- v = INT_TO_JSVAL(priv->lineno);
485
- goto define;
486
- }
487
-
488
- atom = cx->runtime->atomState.stackAtom;
489
- if (str == ATOM_TO_STRING(atom)) {
490
- stack = StackTraceToString(cx, priv);
491
- if (!stack)
492
- return JS_FALSE;
493
-
494
- /* Allow to GC all things that were used to build stack trace. */
495
- priv->stackDepth = 0;
496
- prop = js_stack_str;
497
- v = STRING_TO_JSVAL(stack);
498
- goto define;
499
- }
500
- }
501
- return JS_TRUE;
502
-
503
- define:
504
- if (!JS_DefineProperty(cx, obj, prop, v, NULL, NULL, JSPROP_ENUMERATE))
505
- return JS_FALSE;
506
- *objp = obj;
507
- return JS_TRUE;
508
- }
509
-
510
- JSErrorReport *
511
- js_ErrorFromException(JSContext *cx, jsval exn)
512
- {
513
- JSObject *obj;
514
- JSExnPrivate *priv;
515
-
516
- if (JSVAL_IS_PRIMITIVE(exn))
517
- return NULL;
518
- obj = JSVAL_TO_OBJECT(exn);
519
- if (OBJ_GET_CLASS(cx, obj) != &js_ErrorClass)
520
- return NULL;
521
- priv = GetExnPrivate(cx, obj);
522
- if (!priv)
523
- return NULL;
524
- return priv->errorReport;
525
- }
526
-
527
- struct JSExnSpec {
528
- int protoIndex;
529
- const char *name;
530
- JSProtoKey key;
531
- JSNative native;
532
- };
533
-
534
- /*
535
- * All *Error constructors share the same JSClass, js_ErrorClass. But each
536
- * constructor function for an *Error class must have a distinct native 'call'
537
- * function pointer, in order for instanceof to work properly across multiple
538
- * standard class sets. See jsfun.c:fun_hasInstance.
539
- */
540
- #define MAKE_EXCEPTION_CTOR(name) \
541
- static JSBool \
542
- name(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) \
543
- { \
544
- return Exception(cx, obj, argc, argv, rval); \
545
- }
546
-
547
- MAKE_EXCEPTION_CTOR(Error)
548
- MAKE_EXCEPTION_CTOR(InternalError)
549
- MAKE_EXCEPTION_CTOR(EvalError)
550
- MAKE_EXCEPTION_CTOR(RangeError)
551
- MAKE_EXCEPTION_CTOR(ReferenceError)
552
- MAKE_EXCEPTION_CTOR(SyntaxError)
553
- MAKE_EXCEPTION_CTOR(TypeError)
554
- MAKE_EXCEPTION_CTOR(URIError)
555
-
556
- #undef MAKE_EXCEPTION_CTOR
557
-
558
- static struct JSExnSpec exceptions[] = {
559
- {JSEXN_NONE, js_Error_str, JSProto_Error, Error},
560
- {JSEXN_ERR, js_InternalError_str, JSProto_InternalError, InternalError},
561
- {JSEXN_ERR, js_EvalError_str, JSProto_EvalError, EvalError},
562
- {JSEXN_ERR, js_RangeError_str, JSProto_RangeError, RangeError},
563
- {JSEXN_ERR, js_ReferenceError_str, JSProto_ReferenceError, ReferenceError},
564
- {JSEXN_ERR, js_SyntaxError_str, JSProto_SyntaxError, SyntaxError},
565
- {JSEXN_ERR, js_TypeError_str, JSProto_TypeError, TypeError},
566
- {JSEXN_ERR, js_URIError_str, JSProto_URIError, URIError},
567
- {0, NULL, JSProto_Null, NULL}
568
- };
569
-
570
- static JSString *
571
- ValueToShortSource(JSContext *cx, jsval v)
572
- {
573
- JSString *str;
574
-
575
- /* Avoid toSource bloat and fallibility for object types. */
576
- if (JSVAL_IS_PRIMITIVE(v)) {
577
- str = js_ValueToSource(cx, v);
578
- } else if (VALUE_IS_FUNCTION(cx, v)) {
579
- /*
580
- * XXX Avoid function decompilation bloat for now.
581
- */
582
- str = JS_GetFunctionId(JS_ValueToFunction(cx, v));
583
- if (!str && !(str = js_ValueToSource(cx, v))) {
584
- /*
585
- * Continue to soldier on if the function couldn't be
586
- * converted into a string.
587
- */
588
- JS_ClearPendingException(cx);
589
- str = JS_NewStringCopyZ(cx, "[unknown function]");
590
- }
591
- } else {
592
- /*
593
- * XXX Avoid toString on objects, it takes too long and uses too much
594
- * memory, for too many classes (see Mozilla bug 166743).
595
- */
596
- char buf[100];
597
- JS_snprintf(buf, sizeof buf, "[object %s]",
598
- OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(v))->name);
599
- str = JS_NewStringCopyZ(cx, buf);
600
- }
601
- return str;
602
- }
603
-
604
- static JSString *
605
- StackTraceToString(JSContext *cx, JSExnPrivate *priv)
606
- {
607
- jschar *stackbuf;
608
- size_t stacklen, stackmax;
609
- JSStackTraceElem *elem, *endElem;
610
- jsval *values;
611
- size_t i;
612
- JSString *str;
613
- const char *cp;
614
- char ulnbuf[11];
615
-
616
- /* After this point, failing control flow must goto bad. */
617
- stackbuf = NULL;
618
- stacklen = stackmax = 0;
619
-
620
- /* Limit the stackbuf length to a reasonable value to avoid overflow checks. */
621
- #define STACK_LENGTH_LIMIT JS_BIT(20)
622
-
623
- #define APPEND_CHAR_TO_STACK(c) \
624
- JS_BEGIN_MACRO \
625
- if (stacklen == stackmax) { \
626
- void *ptr_; \
627
- if (stackmax >= STACK_LENGTH_LIMIT) \
628
- goto done; \
629
- stackmax = stackmax ? 2 * stackmax : 64; \
630
- ptr_ = JS_realloc(cx, stackbuf, (stackmax+1) * sizeof(jschar)); \
631
- if (!ptr_) \
632
- goto bad; \
633
- stackbuf = (jschar *) ptr_; \
634
- } \
635
- stackbuf[stacklen++] = (c); \
636
- JS_END_MACRO
637
-
638
- #define APPEND_STRING_TO_STACK(str) \
639
- JS_BEGIN_MACRO \
640
- JSString *str_ = str; \
641
- jschar *chars_; \
642
- size_t length_; \
643
- \
644
- JSSTRING_CHARS_AND_LENGTH(str_, chars_, length_); \
645
- if (length_ > stackmax - stacklen) { \
646
- void *ptr_; \
647
- if (stackmax >= STACK_LENGTH_LIMIT || \
648
- length_ >= STACK_LENGTH_LIMIT - stacklen) { \
649
- goto done; \
650
- } \
651
- stackmax = JS_BIT(JS_CeilingLog2(stacklen + length_)); \
652
- ptr_ = JS_realloc(cx, stackbuf, (stackmax+1) * sizeof(jschar)); \
653
- if (!ptr_) \
654
- goto bad; \
655
- stackbuf = (jschar *) ptr_; \
656
- } \
657
- js_strncpy(stackbuf + stacklen, chars_, length_); \
658
- stacklen += length_; \
659
- JS_END_MACRO
660
-
661
- values = GetStackTraceValueBuffer(priv);
662
- elem = priv->stackElems;
663
- for (endElem = elem + priv->stackDepth; elem != endElem; elem++) {
664
- if (elem->funName) {
665
- APPEND_STRING_TO_STACK(elem->funName);
666
- APPEND_CHAR_TO_STACK('(');
667
- for (i = 0; i != elem->argc; i++, values++) {
668
- if (i > 0)
669
- APPEND_CHAR_TO_STACK(',');
670
- str = ValueToShortSource(cx, *values);
671
- if (!str)
672
- goto bad;
673
- APPEND_STRING_TO_STACK(str);
674
- }
675
- APPEND_CHAR_TO_STACK(')');
676
- }
677
- APPEND_CHAR_TO_STACK('@');
678
- if (elem->filename) {
679
- for (cp = elem->filename; *cp; cp++)
680
- APPEND_CHAR_TO_STACK(*cp);
681
- }
682
- APPEND_CHAR_TO_STACK(':');
683
- JS_snprintf(ulnbuf, sizeof ulnbuf, "%u", elem->ulineno);
684
- for (cp = ulnbuf; *cp; cp++)
685
- APPEND_CHAR_TO_STACK(*cp);
686
- APPEND_CHAR_TO_STACK('\n');
687
- }
688
- #undef APPEND_CHAR_TO_STACK
689
- #undef APPEND_STRING_TO_STACK
690
- #undef STACK_LENGTH_LIMIT
691
-
692
- done:
693
- if (stacklen == 0) {
694
- JS_ASSERT(!stackbuf);
695
- return cx->runtime->emptyString;
696
- }
697
- if (stacklen < stackmax) {
698
- /*
699
- * Realloc can fail when shrinking on some FreeBSD versions, so
700
- * don't use JS_realloc here; simply let the oversized allocation
701
- * be owned by the string in that rare case.
702
- */
703
- void *shrunk = JS_realloc(cx, stackbuf, (stacklen+1) * sizeof(jschar));
704
- if (shrunk)
705
- stackbuf = (jschar *) shrunk;
706
- }
707
-
708
- stackbuf[stacklen] = 0;
709
- str = js_NewString(cx, stackbuf, stacklen);
710
- if (str)
711
- return str;
712
-
713
- bad:
714
- if (stackbuf)
715
- JS_free(cx, stackbuf);
716
- return NULL;
717
- }
718
-
719
- /* XXXbe Consolidate the ugly truth that we don't treat filename as UTF-8
720
- with these two functions. */
721
- static JSString *
722
- FilenameToString(JSContext *cx, const char *filename)
723
- {
724
- return JS_NewStringCopyZ(cx, filename);
725
- }
726
-
727
- static const char *
728
- StringToFilename(JSContext *cx, JSString *str)
729
- {
730
- return js_GetStringBytes(cx, str);
731
- }
732
-
733
- static JSBool
734
- Exception(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
735
- {
736
- uint32 lineno;
737
- JSString *message, *filename;
738
- JSStackFrame *fp;
739
-
740
- if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) {
741
- /*
742
- * ECMA ed. 3, 15.11.1 requires Error, etc., to construct even when
743
- * called as functions, without operator new. But as we do not give
744
- * each constructor a distinct JSClass, whose .name member is used by
745
- * js_NewObject to find the class prototype, we must get the class
746
- * prototype ourselves.
747
- */
748
- if (!OBJ_GET_PROPERTY(cx, JSVAL_TO_OBJECT(argv[-2]),
749
- ATOM_TO_JSID(cx->runtime->atomState
750
- .classPrototypeAtom),
751
- rval))
752
- return JS_FALSE;
753
- obj = js_NewObject(cx, &js_ErrorClass, JSVAL_TO_OBJECT(*rval), NULL, 0);
754
- if (!obj)
755
- return JS_FALSE;
756
- *rval = OBJECT_TO_JSVAL(obj);
757
- }
758
-
759
- /*
760
- * If it's a new object of class Exception, then null out the private
761
- * data so that the finalizer doesn't attempt to free it.
762
- */
763
- if (OBJ_GET_CLASS(cx, obj) == &js_ErrorClass)
764
- STOBJ_SET_SLOT(obj, JSSLOT_PRIVATE, JSVAL_VOID);
765
-
766
- /* Set the 'message' property. */
767
- if (argc != 0) {
768
- message = js_ValueToString(cx, argv[0]);
769
- if (!message)
770
- return JS_FALSE;
771
- argv[0] = STRING_TO_JSVAL(message);
772
- } else {
773
- message = cx->runtime->emptyString;
774
- }
775
-
776
- /* Set the 'fileName' property. */
777
- if (argc > 1) {
778
- filename = js_ValueToString(cx, argv[1]);
779
- if (!filename)
780
- return JS_FALSE;
781
- argv[1] = STRING_TO_JSVAL(filename);
782
- fp = NULL;
783
- } else {
784
- fp = JS_GetScriptedCaller(cx, NULL);
785
- if (fp) {
786
- filename = FilenameToString(cx, fp->script->filename);
787
- if (!filename)
788
- return JS_FALSE;
789
- } else {
790
- filename = cx->runtime->emptyString;
791
- }
792
- }
793
-
794
- /* Set the 'lineNumber' property. */
795
- if (argc > 2) {
796
- lineno = js_ValueToECMAUint32(cx, &argv[2]);
797
- if (JSVAL_IS_NULL(argv[2]))
798
- return JS_FALSE;
799
- } else {
800
- if (!fp)
801
- fp = JS_GetScriptedCaller(cx, NULL);
802
- lineno = (fp && fp->regs)
803
- ? js_PCToLineNumber(cx, fp->script, fp->regs->pc)
804
- : 0;
805
- }
806
-
807
- return (OBJ_GET_CLASS(cx, obj) != &js_ErrorClass) ||
808
- InitExnPrivate(cx, obj, message, filename, lineno, NULL);
809
- }
810
-
811
- /*
812
- * Convert to string.
813
- *
814
- * This method only uses JavaScript-modifiable properties name, message. It
815
- * is left to the host to check for private data and report filename and line
816
- * number information along with this message.
817
- */
818
- static JSBool
819
- exn_toString(JSContext *cx, uintN argc, jsval *vp)
820
- {
821
- JSObject *obj;
822
- jsval v;
823
- JSString *name, *message, *result;
824
- jschar *chars, *cp;
825
- size_t name_length, message_length, length;
826
-
827
- obj = JS_THIS_OBJECT(cx, vp);
828
- if (!obj ||
829
- !OBJ_GET_PROPERTY(cx, obj,
830
- ATOM_TO_JSID(cx->runtime->atomState.nameAtom),
831
- &v)) {
832
- return JS_FALSE;
833
- }
834
- name = JSVAL_IS_STRING(v) ? JSVAL_TO_STRING(v) : cx->runtime->emptyString;
835
- *vp = STRING_TO_JSVAL(name);
836
-
837
- if (!JS_GetProperty(cx, obj, js_message_str, &v))
838
- return JS_FALSE;
839
- message = JSVAL_IS_STRING(v) ? JSVAL_TO_STRING(v)
840
- : cx->runtime->emptyString;
841
-
842
- if (JSSTRING_LENGTH(message) != 0) {
843
- name_length = JSSTRING_LENGTH(name);
844
- message_length = JSSTRING_LENGTH(message);
845
- length = (name_length ? name_length + 2 : 0) + message_length;
846
- cp = chars = (jschar *) JS_malloc(cx, (length + 1) * sizeof(jschar));
847
- if (!chars)
848
- return JS_FALSE;
849
-
850
- if (name_length) {
851
- js_strncpy(cp, JSSTRING_CHARS(name), name_length);
852
- cp += name_length;
853
- *cp++ = ':'; *cp++ = ' ';
854
- }
855
- js_strncpy(cp, JSSTRING_CHARS(message), message_length);
856
- cp += message_length;
857
- *cp = 0;
858
-
859
- result = js_NewString(cx, chars, length);
860
- if (!result) {
861
- JS_free(cx, chars);
862
- return JS_FALSE;
863
- }
864
- } else {
865
- result = name;
866
- }
867
-
868
- *vp = STRING_TO_JSVAL(result);
869
- return JS_TRUE;
870
- }
871
-
872
- #if JS_HAS_TOSOURCE
873
- /*
874
- * Return a string that may eval to something similar to the original object.
875
- */
876
- static JSBool
877
- exn_toSource(JSContext *cx, uintN argc, jsval *vp)
878
- {
879
- JSObject *obj;
880
- JSString *name, *message, *filename, *lineno_as_str, *result;
881
- jsval localroots[3] = {JSVAL_NULL, JSVAL_NULL, JSVAL_NULL};
882
- JSTempValueRooter tvr;
883
- JSBool ok;
884
- uint32 lineno;
885
- size_t lineno_length, name_length, message_length, filename_length, length;
886
- jschar *chars, *cp;
887
-
888
- obj = JS_THIS_OBJECT(cx, vp);
889
- if (!obj ||
890
- !OBJ_GET_PROPERTY(cx, obj,
891
- ATOM_TO_JSID(cx->runtime->atomState.nameAtom),
892
- vp)) {
893
- return JS_FALSE;
894
- }
895
- name = js_ValueToString(cx, *vp);
896
- if (!name)
897
- return JS_FALSE;
898
- *vp = STRING_TO_JSVAL(name);
899
-
900
- /* After this, control must flow through label out: to exit. */
901
- JS_PUSH_TEMP_ROOT(cx, 3, localroots, &tvr);
902
-
903
- ok = JS_GetProperty(cx, obj, js_message_str, &localroots[0]) &&
904
- (message = js_ValueToSource(cx, localroots[0]));
905
- if (!ok)
906
- goto out;
907
- localroots[0] = STRING_TO_JSVAL(message);
908
-
909
- ok = JS_GetProperty(cx, obj, js_fileName_str, &localroots[1]) &&
910
- (filename = js_ValueToSource(cx, localroots[1]));
911
- if (!ok)
912
- goto out;
913
- localroots[1] = STRING_TO_JSVAL(filename);
914
-
915
- ok = JS_GetProperty(cx, obj, js_lineNumber_str, &localroots[2]);
916
- if (!ok)
917
- goto out;
918
- lineno = js_ValueToECMAUint32 (cx, &localroots[2]);
919
- ok = !JSVAL_IS_NULL(localroots[2]);
920
- if (!ok)
921
- goto out;
922
-
923
- if (lineno != 0) {
924
- lineno_as_str = js_ValueToString(cx, localroots[2]);
925
- if (!lineno_as_str) {
926
- ok = JS_FALSE;
927
- goto out;
928
- }
929
- lineno_length = JSSTRING_LENGTH(lineno_as_str);
930
- } else {
931
- lineno_as_str = NULL;
932
- lineno_length = 0;
933
- }
934
-
935
- /* Magic 8, for the characters in ``(new ())''. */
936
- name_length = JSSTRING_LENGTH(name);
937
- message_length = JSSTRING_LENGTH(message);
938
- length = 8 + name_length + message_length;
939
-
940
- filename_length = JSSTRING_LENGTH(filename);
941
- if (filename_length != 0) {
942
- /* append filename as ``, {filename}'' */
943
- length += 2 + filename_length;
944
- if (lineno_as_str) {
945
- /* append lineno as ``, {lineno_as_str}'' */
946
- length += 2 + lineno_length;
947
- }
948
- } else {
949
- if (lineno_as_str) {
950
- /*
951
- * no filename, but have line number,
952
- * need to append ``, "", {lineno_as_str}''
953
- */
954
- length += 6 + lineno_length;
955
- }
956
- }
957
-
958
- cp = chars = (jschar *) JS_malloc(cx, (length + 1) * sizeof(jschar));
959
- if (!chars) {
960
- ok = JS_FALSE;
961
- goto out;
962
- }
963
-
964
- *cp++ = '('; *cp++ = 'n'; *cp++ = 'e'; *cp++ = 'w'; *cp++ = ' ';
965
- js_strncpy(cp, JSSTRING_CHARS(name), name_length);
966
- cp += name_length;
967
- *cp++ = '(';
968
- if (message_length != 0) {
969
- js_strncpy(cp, JSSTRING_CHARS(message), message_length);
970
- cp += message_length;
971
- }
972
-
973
- if (filename_length != 0) {
974
- /* append filename as ``, {filename}'' */
975
- *cp++ = ','; *cp++ = ' ';
976
- js_strncpy(cp, JSSTRING_CHARS(filename), filename_length);
977
- cp += filename_length;
978
- } else {
979
- if (lineno_as_str) {
980
- /*
981
- * no filename, but have line number,
982
- * need to append ``, "", {lineno_as_str}''
983
- */
984
- *cp++ = ','; *cp++ = ' '; *cp++ = '"'; *cp++ = '"';
985
- }
986
- }
987
- if (lineno_as_str) {
988
- /* append lineno as ``, {lineno_as_str}'' */
989
- *cp++ = ','; *cp++ = ' ';
990
- js_strncpy(cp, JSSTRING_CHARS(lineno_as_str), lineno_length);
991
- cp += lineno_length;
992
- }
993
-
994
- *cp++ = ')'; *cp++ = ')'; *cp = 0;
995
-
996
- result = js_NewString(cx, chars, length);
997
- if (!result) {
998
- JS_free(cx, chars);
999
- ok = JS_FALSE;
1000
- goto out;
1001
- }
1002
- *vp = STRING_TO_JSVAL(result);
1003
- ok = JS_TRUE;
1004
-
1005
- out:
1006
- JS_POP_TEMP_ROOT(cx, &tvr);
1007
- return ok;
1008
- }
1009
- #endif
1010
-
1011
- static JSFunctionSpec exception_methods[] = {
1012
- #if JS_HAS_TOSOURCE
1013
- JS_FN(js_toSource_str, exn_toSource, 0,0,0),
1014
- #endif
1015
- JS_FN(js_toString_str, exn_toString, 0,0,0),
1016
- JS_FS_END
1017
- };
1018
-
1019
- JSObject *
1020
- js_InitExceptionClasses(JSContext *cx, JSObject *obj)
1021
- {
1022
- JSObject *obj_proto, *protos[JSEXN_LIMIT];
1023
- int i;
1024
-
1025
- /*
1026
- * If lazy class initialization occurs for any Error subclass, then all
1027
- * classes are initialized, starting with Error. To avoid reentry and
1028
- * redundant initialization, we must not pass a null proto parameter to
1029
- * js_NewObject below, when called for the Error superclass. We need to
1030
- * ensure that Object.prototype is the proto of Error.prototype.
1031
- *
1032
- * See the equivalent code to ensure that parent_proto is non-null when
1033
- * JS_InitClass calls js_NewObject, in jsapi.c.
1034
- */
1035
- if (!js_GetClassPrototype(cx, obj, INT_TO_JSID(JSProto_Object),
1036
- &obj_proto)) {
1037
- return NULL;
1038
- }
1039
-
1040
- if (!js_EnterLocalRootScope(cx))
1041
- return NULL;
1042
-
1043
- /* Initialize the prototypes first. */
1044
- for (i = 0; exceptions[i].name != 0; i++) {
1045
- JSAtom *atom;
1046
- JSFunction *fun;
1047
- JSString *nameString;
1048
- int protoIndex = exceptions[i].protoIndex;
1049
-
1050
- /* Make the prototype for the current constructor name. */
1051
- protos[i] = js_NewObject(cx, &js_ErrorClass,
1052
- (protoIndex != JSEXN_NONE)
1053
- ? protos[protoIndex]
1054
- : obj_proto,
1055
- obj, 0);
1056
- if (!protos[i])
1057
- break;
1058
-
1059
- /* So exn_finalize knows whether to destroy private data. */
1060
- STOBJ_SET_SLOT(protos[i], JSSLOT_PRIVATE, JSVAL_VOID);
1061
-
1062
- /* Make a constructor function for the current name. */
1063
- atom = cx->runtime->atomState.classAtoms[exceptions[i].key];
1064
- fun = js_DefineFunction(cx, obj, atom, exceptions[i].native, 3, 0);
1065
- if (!fun)
1066
- break;
1067
-
1068
- /* Make this constructor make objects of class Exception. */
1069
- fun->u.n.clasp = &js_ErrorClass;
1070
-
1071
- /* Make the prototype and constructor links. */
1072
- if (!js_SetClassPrototype(cx, FUN_OBJECT(fun), protos[i],
1073
- JSPROP_READONLY | JSPROP_PERMANENT)) {
1074
- break;
1075
- }
1076
-
1077
- /* proto bootstrap bit from JS_InitClass omitted. */
1078
- nameString = JS_NewStringCopyZ(cx, exceptions[i].name);
1079
- if (!nameString)
1080
- break;
1081
-
1082
- /* Add the name property to the prototype. */
1083
- if (!JS_DefineProperty(cx, protos[i], js_name_str,
1084
- STRING_TO_JSVAL(nameString),
1085
- NULL, NULL,
1086
- JSPROP_ENUMERATE)) {
1087
- break;
1088
- }
1089
-
1090
- /* Finally, stash the constructor for later uses. */
1091
- if (!js_SetClassObject(cx, obj, exceptions[i].key, FUN_OBJECT(fun)))
1092
- break;
1093
- }
1094
-
1095
- js_LeaveLocalRootScope(cx);
1096
- if (exceptions[i].name)
1097
- return NULL;
1098
-
1099
- /*
1100
- * Add an empty message property. (To Exception.prototype only,
1101
- * because this property will be the same for all the exception
1102
- * protos.)
1103
- */
1104
- if (!JS_DefineProperty(cx, protos[0], js_message_str,
1105
- STRING_TO_JSVAL(cx->runtime->emptyString),
1106
- NULL, NULL, JSPROP_ENUMERATE)) {
1107
- return NULL;
1108
- }
1109
- if (!JS_DefineProperty(cx, protos[0], js_fileName_str,
1110
- STRING_TO_JSVAL(cx->runtime->emptyString),
1111
- NULL, NULL, JSPROP_ENUMERATE)) {
1112
- return NULL;
1113
- }
1114
- if (!JS_DefineProperty(cx, protos[0], js_lineNumber_str,
1115
- INT_TO_JSVAL(0),
1116
- NULL, NULL, JSPROP_ENUMERATE)) {
1117
- return NULL;
1118
- }
1119
-
1120
- /*
1121
- * Add methods only to Exception.prototype, because ostensibly all
1122
- * exception types delegate to that.
1123
- */
1124
- if (!JS_DefineFunctions(cx, protos[0], exception_methods))
1125
- return NULL;
1126
-
1127
- return protos[0];
1128
- }
1129
-
1130
- const JSErrorFormatString*
1131
- js_GetLocalizedErrorMessage(JSContext* cx, void *userRef, const char *locale,
1132
- const uintN errorNumber)
1133
- {
1134
- const JSErrorFormatString *errorString = NULL;
1135
-
1136
- if (cx->localeCallbacks && cx->localeCallbacks->localeGetErrorMessage) {
1137
- errorString = cx->localeCallbacks
1138
- ->localeGetErrorMessage(userRef, locale, errorNumber);
1139
- }
1140
- if (!errorString)
1141
- errorString = js_GetErrorMessage(userRef, locale, errorNumber);
1142
- return errorString;
1143
- }
1144
-
1145
- #if defined ( DEBUG_mccabe ) && defined ( PRINTNAMES )
1146
- /* For use below... get character strings for error name and exception name */
1147
- static struct exnname { char *name; char *exception; } errortoexnname[] = {
1148
- #define MSG_DEF(name, number, count, exception, format) \
1149
- {#name, #exception},
1150
- #include "js.msg"
1151
- #undef MSG_DEF
1152
- };
1153
- #endif /* DEBUG */
1154
-
1155
- JSBool
1156
- js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp)
1157
- {
1158
- JSErrNum errorNumber;
1159
- const JSErrorFormatString *errorString;
1160
- JSExnType exn;
1161
- jsval tv[4];
1162
- JSTempValueRooter tvr;
1163
- JSBool ok;
1164
- JSObject *errProto, *errObject;
1165
- JSString *messageStr, *filenameStr;
1166
-
1167
- /*
1168
- * Tell our caller to report immediately if cx has no active frames, or if
1169
- * this report is just a warning.
1170
- */
1171
- JS_ASSERT(reportp);
1172
- if (!cx->fp || JSREPORT_IS_WARNING(reportp->flags))
1173
- return JS_FALSE;
1174
-
1175
- /* Find the exception index associated with this error. */
1176
- errorNumber = (JSErrNum) reportp->errorNumber;
1177
- errorString = js_GetLocalizedErrorMessage(cx, NULL, NULL, errorNumber);
1178
- exn = errorString ? (JSExnType) errorString->exnType : JSEXN_NONE;
1179
- JS_ASSERT(exn < JSEXN_LIMIT);
1180
-
1181
- #if defined( DEBUG_mccabe ) && defined ( PRINTNAMES )
1182
- /* Print the error name and the associated exception name to stderr */
1183
- fprintf(stderr, "%s\t%s\n",
1184
- errortoexnname[errorNumber].name,
1185
- errortoexnname[errorNumber].exception);
1186
- #endif
1187
-
1188
- /*
1189
- * Return false (no exception raised) if no exception is associated
1190
- * with the given error number.
1191
- */
1192
- if (exn == JSEXN_NONE)
1193
- return JS_FALSE;
1194
-
1195
- /*
1196
- * Prevent runaway recursion, via cx->generatingError. If an out-of-memory
1197
- * error occurs, no exception object will be created, but we don't assume
1198
- * that OOM is the only kind of error that subroutines of this function
1199
- * called below might raise.
1200
- */
1201
- if (cx->generatingError)
1202
- return JS_FALSE;
1203
-
1204
- /* After this point the control must flow through the label out. */
1205
- cx->generatingError = JS_TRUE;
1206
-
1207
- /* Protect the newly-created strings below from nesting GCs. */
1208
- memset(tv, 0, sizeof tv);
1209
- JS_PUSH_TEMP_ROOT(cx, JS_ARRAY_LENGTH(tv), tv, &tvr);
1210
-
1211
- /*
1212
- * Try to get an appropriate prototype by looking up the corresponding
1213
- * exception constructor name in the scope chain of the current context's
1214
- * top stack frame, or in the global object if no frame is active.
1215
- */
1216
- ok = js_GetClassPrototype(cx, NULL, INT_TO_JSID(exceptions[exn].key),
1217
- &errProto);
1218
- if (!ok)
1219
- goto out;
1220
- tv[0] = OBJECT_TO_JSVAL(errProto);
1221
-
1222
- errObject = js_NewObject(cx, &js_ErrorClass, errProto, NULL, 0);
1223
- if (!errObject) {
1224
- ok = JS_FALSE;
1225
- goto out;
1226
- }
1227
- tv[1] = OBJECT_TO_JSVAL(errObject);
1228
-
1229
- messageStr = JS_NewStringCopyZ(cx, message);
1230
- if (!messageStr) {
1231
- ok = JS_FALSE;
1232
- goto out;
1233
- }
1234
- tv[2] = STRING_TO_JSVAL(messageStr);
1235
-
1236
- filenameStr = JS_NewStringCopyZ(cx, reportp->filename);
1237
- if (!filenameStr) {
1238
- ok = JS_FALSE;
1239
- goto out;
1240
- }
1241
- tv[3] = STRING_TO_JSVAL(filenameStr);
1242
-
1243
- ok = InitExnPrivate(cx, errObject, messageStr, filenameStr,
1244
- reportp->lineno, reportp);
1245
- if (!ok)
1246
- goto out;
1247
-
1248
- JS_SetPendingException(cx, OBJECT_TO_JSVAL(errObject));
1249
-
1250
- /* Flag the error report passed in to indicate an exception was raised. */
1251
- reportp->flags |= JSREPORT_EXCEPTION;
1252
-
1253
- out:
1254
- JS_POP_TEMP_ROOT(cx, &tvr);
1255
- cx->generatingError = JS_FALSE;
1256
- return ok;
1257
- }
1258
-
1259
- JSBool
1260
- js_ReportUncaughtException(JSContext *cx)
1261
- {
1262
- jsval exn;
1263
- JSObject *exnObject;
1264
- jsval roots[5];
1265
- JSTempValueRooter tvr;
1266
- JSErrorReport *reportp, report;
1267
- JSString *str;
1268
- const char *bytes;
1269
- JSBool ok;
1270
-
1271
- if (!JS_IsExceptionPending(cx))
1272
- return JS_TRUE;
1273
-
1274
- if (!JS_GetPendingException(cx, &exn))
1275
- return JS_FALSE;
1276
-
1277
- memset(roots, 0, sizeof roots);
1278
- JS_PUSH_TEMP_ROOT(cx, JS_ARRAY_LENGTH(roots), roots, &tvr);
1279
-
1280
- /*
1281
- * Because js_ValueToString below could error and an exception object
1282
- * could become unrooted, we must root exnObject. Later, if exnObject is
1283
- * non-null, we need to root other intermediates, so allocate an operand
1284
- * stack segment to protect all of these values.
1285
- */
1286
- if (JSVAL_IS_PRIMITIVE(exn)) {
1287
- exnObject = NULL;
1288
- } else {
1289
- exnObject = JSVAL_TO_OBJECT(exn);
1290
- roots[0] = exn;
1291
- }
1292
-
1293
- JS_ClearPendingException(cx);
1294
- reportp = js_ErrorFromException(cx, exn);
1295
-
1296
- /* XXX L10N angels cry once again (see also jsemit.c, /L10N gaffes/) */
1297
- str = js_ValueToString(cx, exn);
1298
- if (!str) {
1299
- bytes = "unknown (can't convert to string)";
1300
- } else {
1301
- roots[1] = STRING_TO_JSVAL(str);
1302
- bytes = js_GetStringBytes(cx, str);
1303
- if (!bytes) {
1304
- ok = JS_FALSE;
1305
- goto out;
1306
- }
1307
- }
1308
- ok = JS_TRUE;
1309
-
1310
- if (!reportp &&
1311
- exnObject &&
1312
- OBJ_GET_CLASS(cx, exnObject) == &js_ErrorClass) {
1313
- const char *filename;
1314
- uint32 lineno;
1315
-
1316
- ok = JS_GetProperty(cx, exnObject, js_message_str, &roots[2]);
1317
- if (!ok)
1318
- goto out;
1319
- if (JSVAL_IS_STRING(roots[2])) {
1320
- bytes = js_GetStringBytes(cx, JSVAL_TO_STRING(roots[2]));
1321
- if (!bytes) {
1322
- ok = JS_FALSE;
1323
- goto out;
1324
- }
1325
- }
1326
-
1327
- ok = JS_GetProperty(cx, exnObject, js_fileName_str, &roots[3]);
1328
- if (!ok)
1329
- goto out;
1330
- str = js_ValueToString(cx, roots[3]);
1331
- if (!str) {
1332
- ok = JS_FALSE;
1333
- goto out;
1334
- }
1335
- filename = StringToFilename(cx, str);
1336
- if (!filename) {
1337
- ok = JS_FALSE;
1338
- goto out;
1339
- }
1340
-
1341
- ok = JS_GetProperty(cx, exnObject, js_lineNumber_str, &roots[4]);
1342
- if (!ok)
1343
- goto out;
1344
- lineno = js_ValueToECMAUint32 (cx, &roots[4]);
1345
- ok = !JSVAL_IS_NULL(roots[4]);
1346
- if (!ok)
1347
- goto out;
1348
-
1349
- reportp = &report;
1350
- memset(&report, 0, sizeof report);
1351
- report.filename = filename;
1352
- report.lineno = (uintN) lineno;
1353
- }
1354
-
1355
- if (!reportp) {
1356
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
1357
- JSMSG_UNCAUGHT_EXCEPTION, bytes);
1358
- } else {
1359
- /* Flag the error as an exception. */
1360
- reportp->flags |= JSREPORT_EXCEPTION;
1361
-
1362
- /* Pass the exception object. */
1363
- JS_SetPendingException(cx, exn);
1364
- js_ReportErrorAgain(cx, bytes, reportp);
1365
- JS_ClearPendingException(cx);
1366
- }
1367
-
1368
- out:
1369
- JS_POP_TEMP_ROOT(cx, &tvr);
1370
- return ok;
1371
- }