smparkes-johnson 1.1.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (1078) hide show
  1. data/.autotest +14 -0
  2. data/CHANGELOG.rdoc +21 -0
  3. data/Manifest.txt +1077 -0
  4. data/README.rdoc +51 -0
  5. data/Rakefile +140 -0
  6. data/bin/johnson +106 -0
  7. data/ext/spidermonkey/context.c +116 -0
  8. data/ext/spidermonkey/context.h +19 -0
  9. data/ext/spidermonkey/conversions.c +354 -0
  10. data/ext/spidermonkey/conversions.h +31 -0
  11. data/ext/spidermonkey/debugger.c +234 -0
  12. data/ext/spidermonkey/debugger.h +10 -0
  13. data/ext/spidermonkey/extconf.rb +32 -0
  14. data/ext/spidermonkey/extensions.c +37 -0
  15. data/ext/spidermonkey/extensions.h +12 -0
  16. data/ext/spidermonkey/global.c +40 -0
  17. data/ext/spidermonkey/global.h +11 -0
  18. data/ext/spidermonkey/idhash.c +16 -0
  19. data/ext/spidermonkey/idhash.h +8 -0
  20. data/ext/spidermonkey/immutable_node.c +1153 -0
  21. data/ext/spidermonkey/immutable_node.c.erb +523 -0
  22. data/ext/spidermonkey/immutable_node.h +22 -0
  23. data/ext/spidermonkey/jroot.h +197 -0
  24. data/ext/spidermonkey/js_land_proxy.c +610 -0
  25. data/ext/spidermonkey/js_land_proxy.h +20 -0
  26. data/ext/spidermonkey/ruby_land_proxy.c +611 -0
  27. data/ext/spidermonkey/ruby_land_proxy.h +38 -0
  28. data/ext/spidermonkey/runtime.c +396 -0
  29. data/ext/spidermonkey/runtime.h +27 -0
  30. data/ext/spidermonkey/spidermonkey.c +22 -0
  31. data/ext/spidermonkey/spidermonkey.h +29 -0
  32. data/ext/tracemonkey/context.cc +125 -0
  33. data/ext/tracemonkey/context.h +19 -0
  34. data/ext/tracemonkey/conversions.cc +355 -0
  35. data/ext/tracemonkey/conversions.h +32 -0
  36. data/ext/tracemonkey/debugger.cc +234 -0
  37. data/ext/tracemonkey/debugger.h +10 -0
  38. data/ext/tracemonkey/extconf.rb +37 -0
  39. data/ext/tracemonkey/extensions.cc +37 -0
  40. data/ext/tracemonkey/extensions.h +12 -0
  41. data/ext/tracemonkey/global.cc +40 -0
  42. data/ext/tracemonkey/global.h +11 -0
  43. data/ext/tracemonkey/idhash.cc +16 -0
  44. data/ext/tracemonkey/idhash.h +8 -0
  45. data/ext/tracemonkey/immutable_node.cc +1199 -0
  46. data/ext/tracemonkey/immutable_node.cc.erb +559 -0
  47. data/ext/tracemonkey/immutable_node.h +22 -0
  48. data/ext/tracemonkey/jroot.h +215 -0
  49. data/ext/tracemonkey/js_land_proxy.cc +610 -0
  50. data/ext/tracemonkey/js_land_proxy.h +20 -0
  51. data/ext/tracemonkey/ruby_land_proxy.cc +611 -0
  52. data/ext/tracemonkey/ruby_land_proxy.h +38 -0
  53. data/ext/tracemonkey/runtime.cc +454 -0
  54. data/ext/tracemonkey/runtime.h +27 -0
  55. data/ext/tracemonkey/split_global.cc +392 -0
  56. data/ext/tracemonkey/split_global.h +11 -0
  57. data/ext/tracemonkey/tracemonkey.cc +23 -0
  58. data/ext/tracemonkey/tracemonkey.h +32 -0
  59. data/lib/johnson/cli/options.rb +67 -0
  60. data/lib/johnson/cli.rb +8 -0
  61. data/lib/johnson/error.rb +4 -0
  62. data/lib/johnson/js/cli.js +30 -0
  63. data/lib/johnson/js/prelude.js +118 -0
  64. data/lib/johnson/nodes/binary_node.rb +65 -0
  65. data/lib/johnson/nodes/for.rb +14 -0
  66. data/lib/johnson/nodes/for_in.rb +12 -0
  67. data/lib/johnson/nodes/function.rb +13 -0
  68. data/lib/johnson/nodes/list.rb +28 -0
  69. data/lib/johnson/nodes/node.rb +68 -0
  70. data/lib/johnson/nodes/ternary_node.rb +20 -0
  71. data/lib/johnson/nodes.rb +7 -0
  72. data/lib/johnson/parser/syntax_error.rb +13 -0
  73. data/lib/johnson/parser.rb +22 -0
  74. data/lib/johnson/ruby_land_proxy.rb +81 -0
  75. data/lib/johnson/runtime.rb +141 -0
  76. data/lib/johnson/spidermonkey/context.rb +10 -0
  77. data/lib/johnson/spidermonkey/debugger.rb +67 -0
  78. data/lib/johnson/spidermonkey/immutable_node.rb +282 -0
  79. data/lib/johnson/spidermonkey/js_land_proxy.rb +64 -0
  80. data/lib/johnson/spidermonkey/mutable_tree_visitor.rb +242 -0
  81. data/lib/johnson/spidermonkey/ruby_land_proxy.rb +17 -0
  82. data/lib/johnson/spidermonkey/runtime.rb +92 -0
  83. data/lib/johnson/spidermonkey.rb +12 -0
  84. data/lib/johnson/tracemonkey/context.rb +10 -0
  85. data/lib/johnson/tracemonkey/debugger.rb +67 -0
  86. data/lib/johnson/tracemonkey/immutable_node.rb +282 -0
  87. data/lib/johnson/tracemonkey/js_land_proxy.rb +64 -0
  88. data/lib/johnson/tracemonkey/mutable_tree_visitor.rb +242 -0
  89. data/lib/johnson/tracemonkey/ruby_land_proxy.rb +17 -0
  90. data/lib/johnson/tracemonkey/runtime.rb +98 -0
  91. data/lib/johnson/tracemonkey.rb +13 -0
  92. data/lib/johnson/visitable.rb +16 -0
  93. data/lib/johnson/visitors/dot_visitor.rb +169 -0
  94. data/lib/johnson/visitors/ecma_visitor.rb +323 -0
  95. data/lib/johnson/visitors/enumerating_visitor.rb +15 -0
  96. data/lib/johnson/visitors/sexp_visitor.rb +174 -0
  97. data/lib/johnson/visitors/visitor.rb +91 -0
  98. data/lib/johnson/visitors.rb +5 -0
  99. data/lib/johnson.rb +53 -0
  100. data/test/generic/johnson_test.rb +16 -0
  101. data/test/generic/parser_test.rb +276 -0
  102. data/test/helper.rb +82 -0
  103. data/test/johnson/generic/browser_test.rb +43 -0
  104. data/test/johnson/generic/conversions/array_test.rb +70 -0
  105. data/test/johnson/generic/conversions/boolean_test.rb +17 -0
  106. data/test/johnson/generic/conversions/callable_test.rb +34 -0
  107. data/test/johnson/generic/conversions/file_test.rb +15 -0
  108. data/test/johnson/generic/conversions/helper.rb +1 -0
  109. data/test/johnson/generic/conversions/nil_test.rb +20 -0
  110. data/test/johnson/generic/conversions/number_test.rb +34 -0
  111. data/test/johnson/generic/conversions/regexp_test.rb +24 -0
  112. data/test/johnson/generic/conversions/string_test.rb +38 -0
  113. data/test/johnson/generic/conversions/struct_test.rb +15 -0
  114. data/test/johnson/generic/conversions/symbol_test.rb +19 -0
  115. data/test/johnson/generic/conversions/thread_test.rb +24 -0
  116. data/test/johnson/generic/default_test.rb +12 -0
  117. data/test/johnson/generic/error_test.rb +9 -0
  118. data/test/johnson/generic/extensions_test.rb +56 -0
  119. data/test/johnson/generic/helper.rb +1 -0
  120. data/test/johnson/generic/nodes/array_literal_test.rb +57 -0
  121. data/test/johnson/generic/nodes/array_node_test.rb +26 -0
  122. data/test/johnson/generic/nodes/binary_node_test.rb +61 -0
  123. data/test/johnson/generic/nodes/bracket_access_test.rb +16 -0
  124. data/test/johnson/generic/nodes/delete_test.rb +11 -0
  125. data/test/johnson/generic/nodes/do_while_test.rb +12 -0
  126. data/test/johnson/generic/nodes/dot_accessor_test.rb +15 -0
  127. data/test/johnson/generic/nodes/export_test.rb +11 -0
  128. data/test/johnson/generic/nodes/for_test.rb +54 -0
  129. data/test/johnson/generic/nodes/function_test.rb +71 -0
  130. data/test/johnson/generic/nodes/helper.rb +1 -0
  131. data/test/johnson/generic/nodes/if_test.rb +51 -0
  132. data/test/johnson/generic/nodes/import_test.rb +15 -0
  133. data/test/johnson/generic/nodes/label_test.rb +19 -0
  134. data/test/johnson/generic/nodes/let_test.rb +31 -0
  135. data/test/johnson/generic/nodes/object_literal_test.rb +110 -0
  136. data/test/johnson/generic/nodes/return_test.rb +16 -0
  137. data/test/johnson/generic/nodes/semi_test.rb +8 -0
  138. data/test/johnson/generic/nodes/switch_test.rb +55 -0
  139. data/test/johnson/generic/nodes/ternary_test.rb +25 -0
  140. data/test/johnson/generic/nodes/throw_test.rb +9 -0
  141. data/test/johnson/generic/nodes/try_node_test.rb +89 -0
  142. data/test/johnson/generic/nodes/typeof_test.rb +11 -0
  143. data/test/johnson/generic/nodes/unary_node_test.rb +23 -0
  144. data/test/johnson/generic/nodes/void_test.rb +11 -0
  145. data/test/johnson/generic/nodes/while_test.rb +26 -0
  146. data/test/johnson/generic/nodes/with_test.rb +10 -0
  147. data/test/johnson/generic/prelude_test.rb +79 -0
  148. data/test/johnson/generic/runtime_test.rb +140 -0
  149. data/test/johnson/generic/version_test.rb +13 -0
  150. data/test/johnson/generic/visitors/dot_visitor_test.rb +39 -0
  151. data/test/johnson/generic/visitors/enumerating_visitor_test.rb +12 -0
  152. data/test/johnson/generic/visitors/helper.rb +1 -0
  153. data/test/johnson/spidermonkey/context_test.rb +21 -0
  154. data/test/johnson/spidermonkey/immutable_node_test.rb +34 -0
  155. data/test/johnson/spidermonkey/js_land_proxy_test.rb +277 -0
  156. data/test/johnson/spidermonkey/ruby_land_proxy_test.rb +270 -0
  157. data/test/johnson/spidermonkey/runtime_test.rb +41 -0
  158. data/test/johnson/tracemonkey/context_test.rb +21 -0
  159. data/test/johnson/tracemonkey/immutable_node_test.rb +34 -0
  160. data/test/johnson/tracemonkey/js_land_proxy_test.rb +277 -0
  161. data/test/johnson/tracemonkey/ruby_land_proxy_test.rb +270 -0
  162. data/test/johnson/tracemonkey/runtime_test.rb +41 -0
  163. data/test/johnson/tracemonkey/split_global_test.rb +32 -0
  164. data/vendor/spidermonkey/.cvsignore +9 -0
  165. data/vendor/spidermonkey/Makefile.in +449 -0
  166. data/vendor/spidermonkey/Makefile.ref +365 -0
  167. data/vendor/spidermonkey/README.html +820 -0
  168. data/vendor/spidermonkey/SpiderMonkey.rsp +12 -0
  169. data/vendor/spidermonkey/Y.js +19 -0
  170. data/vendor/spidermonkey/build.mk +43 -0
  171. data/vendor/spidermonkey/config/AIX4.1.mk +65 -0
  172. data/vendor/spidermonkey/config/AIX4.2.mk +64 -0
  173. data/vendor/spidermonkey/config/AIX4.3.mk +65 -0
  174. data/vendor/spidermonkey/config/Darwin.mk +83 -0
  175. data/vendor/spidermonkey/config/Darwin1.3.mk +81 -0
  176. data/vendor/spidermonkey/config/Darwin1.4.mk +41 -0
  177. data/vendor/spidermonkey/config/Darwin5.2.mk +81 -0
  178. data/vendor/spidermonkey/config/Darwin5.3.mk +81 -0
  179. data/vendor/spidermonkey/config/HP-UXB.10.10.mk +77 -0
  180. data/vendor/spidermonkey/config/HP-UXB.10.20.mk +77 -0
  181. data/vendor/spidermonkey/config/HP-UXB.11.00.mk +80 -0
  182. data/vendor/spidermonkey/config/IRIX.mk +87 -0
  183. data/vendor/spidermonkey/config/IRIX5.3.mk +44 -0
  184. data/vendor/spidermonkey/config/IRIX6.1.mk +44 -0
  185. data/vendor/spidermonkey/config/IRIX6.2.mk +44 -0
  186. data/vendor/spidermonkey/config/IRIX6.3.mk +44 -0
  187. data/vendor/spidermonkey/config/IRIX6.5.mk +44 -0
  188. data/vendor/spidermonkey/config/Linux_All.mk +103 -0
  189. data/vendor/spidermonkey/config/Mac_OS10.0.mk +82 -0
  190. data/vendor/spidermonkey/config/OSF1V4.0.mk +72 -0
  191. data/vendor/spidermonkey/config/OSF1V5.0.mk +69 -0
  192. data/vendor/spidermonkey/config/SunOS4.1.4.mk +101 -0
  193. data/vendor/spidermonkey/config/SunOS5.10.mk +50 -0
  194. data/vendor/spidermonkey/config/SunOS5.3.mk +91 -0
  195. data/vendor/spidermonkey/config/SunOS5.4.mk +92 -0
  196. data/vendor/spidermonkey/config/SunOS5.5.1.mk +44 -0
  197. data/vendor/spidermonkey/config/SunOS5.5.mk +87 -0
  198. data/vendor/spidermonkey/config/SunOS5.6.mk +89 -0
  199. data/vendor/spidermonkey/config/SunOS5.7.mk +44 -0
  200. data/vendor/spidermonkey/config/SunOS5.8.mk +44 -0
  201. data/vendor/spidermonkey/config/SunOS5.9.mk +44 -0
  202. data/vendor/spidermonkey/config/WINNT4.0.mk +117 -0
  203. data/vendor/spidermonkey/config/WINNT5.0.mk +117 -0
  204. data/vendor/spidermonkey/config/WINNT5.1.mk +117 -0
  205. data/vendor/spidermonkey/config/WINNT5.2.mk +117 -0
  206. data/vendor/spidermonkey/config/WINNT6.0.mk +117 -0
  207. data/vendor/spidermonkey/config/dgux.mk +64 -0
  208. data/vendor/spidermonkey/config.mk +192 -0
  209. data/vendor/spidermonkey/editline/Makefile.ref +144 -0
  210. data/vendor/spidermonkey/editline/README +83 -0
  211. data/vendor/spidermonkey/editline/editline.3 +175 -0
  212. data/vendor/spidermonkey/editline/editline.c +1369 -0
  213. data/vendor/spidermonkey/editline/editline.h +135 -0
  214. data/vendor/spidermonkey/editline/sysunix.c +182 -0
  215. data/vendor/spidermonkey/editline/unix.h +82 -0
  216. data/vendor/spidermonkey/fdlibm/.cvsignore +7 -0
  217. data/vendor/spidermonkey/fdlibm/Makefile.in +127 -0
  218. data/vendor/spidermonkey/fdlibm/Makefile.ref +192 -0
  219. data/vendor/spidermonkey/fdlibm/e_acos.c +147 -0
  220. data/vendor/spidermonkey/fdlibm/e_acosh.c +105 -0
  221. data/vendor/spidermonkey/fdlibm/e_asin.c +156 -0
  222. data/vendor/spidermonkey/fdlibm/e_atan2.c +165 -0
  223. data/vendor/spidermonkey/fdlibm/e_atanh.c +110 -0
  224. data/vendor/spidermonkey/fdlibm/e_cosh.c +133 -0
  225. data/vendor/spidermonkey/fdlibm/e_exp.c +202 -0
  226. data/vendor/spidermonkey/fdlibm/e_fmod.c +184 -0
  227. data/vendor/spidermonkey/fdlibm/e_gamma.c +71 -0
  228. data/vendor/spidermonkey/fdlibm/e_gamma_r.c +70 -0
  229. data/vendor/spidermonkey/fdlibm/e_hypot.c +173 -0
  230. data/vendor/spidermonkey/fdlibm/e_j0.c +524 -0
  231. data/vendor/spidermonkey/fdlibm/e_j1.c +523 -0
  232. data/vendor/spidermonkey/fdlibm/e_jn.c +315 -0
  233. data/vendor/spidermonkey/fdlibm/e_lgamma.c +71 -0
  234. data/vendor/spidermonkey/fdlibm/e_lgamma_r.c +347 -0
  235. data/vendor/spidermonkey/fdlibm/e_log.c +184 -0
  236. data/vendor/spidermonkey/fdlibm/e_log10.c +134 -0
  237. data/vendor/spidermonkey/fdlibm/e_pow.c +386 -0
  238. data/vendor/spidermonkey/fdlibm/e_rem_pio2.c +222 -0
  239. data/vendor/spidermonkey/fdlibm/e_remainder.c +120 -0
  240. data/vendor/spidermonkey/fdlibm/e_scalb.c +89 -0
  241. data/vendor/spidermonkey/fdlibm/e_sinh.c +122 -0
  242. data/vendor/spidermonkey/fdlibm/e_sqrt.c +497 -0
  243. data/vendor/spidermonkey/fdlibm/fdlibm.h +273 -0
  244. data/vendor/spidermonkey/fdlibm/fdlibm.mak +1453 -0
  245. data/vendor/spidermonkey/fdlibm/fdlibm.mdp +0 -0
  246. data/vendor/spidermonkey/fdlibm/k_cos.c +135 -0
  247. data/vendor/spidermonkey/fdlibm/k_rem_pio2.c +354 -0
  248. data/vendor/spidermonkey/fdlibm/k_sin.c +114 -0
  249. data/vendor/spidermonkey/fdlibm/k_standard.c +785 -0
  250. data/vendor/spidermonkey/fdlibm/k_tan.c +170 -0
  251. data/vendor/spidermonkey/fdlibm/s_asinh.c +101 -0
  252. data/vendor/spidermonkey/fdlibm/s_atan.c +175 -0
  253. data/vendor/spidermonkey/fdlibm/s_cbrt.c +133 -0
  254. data/vendor/spidermonkey/fdlibm/s_ceil.c +120 -0
  255. data/vendor/spidermonkey/fdlibm/s_copysign.c +72 -0
  256. data/vendor/spidermonkey/fdlibm/s_cos.c +118 -0
  257. data/vendor/spidermonkey/fdlibm/s_erf.c +356 -0
  258. data/vendor/spidermonkey/fdlibm/s_expm1.c +267 -0
  259. data/vendor/spidermonkey/fdlibm/s_fabs.c +70 -0
  260. data/vendor/spidermonkey/fdlibm/s_finite.c +71 -0
  261. data/vendor/spidermonkey/fdlibm/s_floor.c +121 -0
  262. data/vendor/spidermonkey/fdlibm/s_frexp.c +99 -0
  263. data/vendor/spidermonkey/fdlibm/s_ilogb.c +85 -0
  264. data/vendor/spidermonkey/fdlibm/s_isnan.c +74 -0
  265. data/vendor/spidermonkey/fdlibm/s_ldexp.c +66 -0
  266. data/vendor/spidermonkey/fdlibm/s_lib_version.c +73 -0
  267. data/vendor/spidermonkey/fdlibm/s_log1p.c +211 -0
  268. data/vendor/spidermonkey/fdlibm/s_logb.c +79 -0
  269. data/vendor/spidermonkey/fdlibm/s_matherr.c +64 -0
  270. data/vendor/spidermonkey/fdlibm/s_modf.c +132 -0
  271. data/vendor/spidermonkey/fdlibm/s_nextafter.c +124 -0
  272. data/vendor/spidermonkey/fdlibm/s_rint.c +131 -0
  273. data/vendor/spidermonkey/fdlibm/s_scalbn.c +107 -0
  274. data/vendor/spidermonkey/fdlibm/s_signgam.c +40 -0
  275. data/vendor/spidermonkey/fdlibm/s_significand.c +68 -0
  276. data/vendor/spidermonkey/fdlibm/s_sin.c +118 -0
  277. data/vendor/spidermonkey/fdlibm/s_tan.c +112 -0
  278. data/vendor/spidermonkey/fdlibm/s_tanh.c +122 -0
  279. data/vendor/spidermonkey/fdlibm/w_acos.c +78 -0
  280. data/vendor/spidermonkey/fdlibm/w_acosh.c +78 -0
  281. data/vendor/spidermonkey/fdlibm/w_asin.c +80 -0
  282. data/vendor/spidermonkey/fdlibm/w_atan2.c +79 -0
  283. data/vendor/spidermonkey/fdlibm/w_atanh.c +81 -0
  284. data/vendor/spidermonkey/fdlibm/w_cosh.c +77 -0
  285. data/vendor/spidermonkey/fdlibm/w_exp.c +88 -0
  286. data/vendor/spidermonkey/fdlibm/w_fmod.c +78 -0
  287. data/vendor/spidermonkey/fdlibm/w_gamma.c +85 -0
  288. data/vendor/spidermonkey/fdlibm/w_gamma_r.c +81 -0
  289. data/vendor/spidermonkey/fdlibm/w_hypot.c +78 -0
  290. data/vendor/spidermonkey/fdlibm/w_j0.c +105 -0
  291. data/vendor/spidermonkey/fdlibm/w_j1.c +106 -0
  292. data/vendor/spidermonkey/fdlibm/w_jn.c +128 -0
  293. data/vendor/spidermonkey/fdlibm/w_lgamma.c +85 -0
  294. data/vendor/spidermonkey/fdlibm/w_lgamma_r.c +81 -0
  295. data/vendor/spidermonkey/fdlibm/w_log.c +78 -0
  296. data/vendor/spidermonkey/fdlibm/w_log10.c +81 -0
  297. data/vendor/spidermonkey/fdlibm/w_pow.c +99 -0
  298. data/vendor/spidermonkey/fdlibm/w_remainder.c +77 -0
  299. data/vendor/spidermonkey/fdlibm/w_scalb.c +95 -0
  300. data/vendor/spidermonkey/fdlibm/w_sinh.c +77 -0
  301. data/vendor/spidermonkey/fdlibm/w_sqrt.c +77 -0
  302. data/vendor/spidermonkey/javascript-trace.d +73 -0
  303. data/vendor/spidermonkey/js.c +3951 -0
  304. data/vendor/spidermonkey/js.mdp +0 -0
  305. data/vendor/spidermonkey/js.msg +308 -0
  306. data/vendor/spidermonkey/js.pkg +2 -0
  307. data/vendor/spidermonkey/js3240.rc +79 -0
  308. data/vendor/spidermonkey/jsOS240.def +654 -0
  309. data/vendor/spidermonkey/jsapi.c +5836 -0
  310. data/vendor/spidermonkey/jsapi.h +2624 -0
  311. data/vendor/spidermonkey/jsarena.c +450 -0
  312. data/vendor/spidermonkey/jsarena.h +318 -0
  313. data/vendor/spidermonkey/jsarray.c +2996 -0
  314. data/vendor/spidermonkey/jsarray.h +127 -0
  315. data/vendor/spidermonkey/jsatom.c +1045 -0
  316. data/vendor/spidermonkey/jsatom.h +442 -0
  317. data/vendor/spidermonkey/jsbit.h +253 -0
  318. data/vendor/spidermonkey/jsbool.c +176 -0
  319. data/vendor/spidermonkey/jsbool.h +73 -0
  320. data/vendor/spidermonkey/jsclist.h +139 -0
  321. data/vendor/spidermonkey/jscntxt.c +1348 -0
  322. data/vendor/spidermonkey/jscntxt.h +1120 -0
  323. data/vendor/spidermonkey/jscompat.h +57 -0
  324. data/vendor/spidermonkey/jsconfig.h +248 -0
  325. data/vendor/spidermonkey/jsconfig.mk +181 -0
  326. data/vendor/spidermonkey/jscpucfg.c +396 -0
  327. data/vendor/spidermonkey/jscpucfg.h +212 -0
  328. data/vendor/spidermonkey/jsdate.c +2390 -0
  329. data/vendor/spidermonkey/jsdate.h +124 -0
  330. data/vendor/spidermonkey/jsdbgapi.c +1802 -0
  331. data/vendor/spidermonkey/jsdbgapi.h +464 -0
  332. data/vendor/spidermonkey/jsdhash.c +868 -0
  333. data/vendor/spidermonkey/jsdhash.h +592 -0
  334. data/vendor/spidermonkey/jsdtoa.c +3167 -0
  335. data/vendor/spidermonkey/jsdtoa.h +130 -0
  336. data/vendor/spidermonkey/jsdtracef.c +317 -0
  337. data/vendor/spidermonkey/jsdtracef.h +77 -0
  338. data/vendor/spidermonkey/jsemit.c +6909 -0
  339. data/vendor/spidermonkey/jsemit.h +741 -0
  340. data/vendor/spidermonkey/jsexn.c +1371 -0
  341. data/vendor/spidermonkey/jsexn.h +96 -0
  342. data/vendor/spidermonkey/jsfile.c +2736 -0
  343. data/vendor/spidermonkey/jsfile.h +56 -0
  344. data/vendor/spidermonkey/jsfile.msg +90 -0
  345. data/vendor/spidermonkey/jsfun.c +2634 -0
  346. data/vendor/spidermonkey/jsfun.h +254 -0
  347. data/vendor/spidermonkey/jsgc.c +3562 -0
  348. data/vendor/spidermonkey/jsgc.h +403 -0
  349. data/vendor/spidermonkey/jshash.c +476 -0
  350. data/vendor/spidermonkey/jshash.h +151 -0
  351. data/vendor/spidermonkey/jsify.pl +485 -0
  352. data/vendor/spidermonkey/jsinterp.c +7007 -0
  353. data/vendor/spidermonkey/jsinterp.h +525 -0
  354. data/vendor/spidermonkey/jsinvoke.c +43 -0
  355. data/vendor/spidermonkey/jsiter.c +1067 -0
  356. data/vendor/spidermonkey/jsiter.h +122 -0
  357. data/vendor/spidermonkey/jskeyword.tbl +124 -0
  358. data/vendor/spidermonkey/jskwgen.c +460 -0
  359. data/vendor/spidermonkey/jslibmath.h +266 -0
  360. data/vendor/spidermonkey/jslock.c +1309 -0
  361. data/vendor/spidermonkey/jslock.h +313 -0
  362. data/vendor/spidermonkey/jslocko.asm +60 -0
  363. data/vendor/spidermonkey/jslog2.c +94 -0
  364. data/vendor/spidermonkey/jslong.c +264 -0
  365. data/vendor/spidermonkey/jslong.h +412 -0
  366. data/vendor/spidermonkey/jsmath.c +567 -0
  367. data/vendor/spidermonkey/jsmath.h +57 -0
  368. data/vendor/spidermonkey/jsnum.c +1239 -0
  369. data/vendor/spidermonkey/jsnum.h +283 -0
  370. data/vendor/spidermonkey/jsobj.c +5282 -0
  371. data/vendor/spidermonkey/jsobj.h +709 -0
  372. data/vendor/spidermonkey/jsopcode.c +5245 -0
  373. data/vendor/spidermonkey/jsopcode.h +394 -0
  374. data/vendor/spidermonkey/jsopcode.tbl +523 -0
  375. data/vendor/spidermonkey/jsotypes.h +202 -0
  376. data/vendor/spidermonkey/jsparse.c +6704 -0
  377. data/vendor/spidermonkey/jsparse.h +511 -0
  378. data/vendor/spidermonkey/jsprf.c +1264 -0
  379. data/vendor/spidermonkey/jsprf.h +150 -0
  380. data/vendor/spidermonkey/jsproto.tbl +128 -0
  381. data/vendor/spidermonkey/jsprvtd.h +267 -0
  382. data/vendor/spidermonkey/jspubtd.h +744 -0
  383. data/vendor/spidermonkey/jsregexp.c +4364 -0
  384. data/vendor/spidermonkey/jsregexp.h +183 -0
  385. data/vendor/spidermonkey/jsreops.tbl +145 -0
  386. data/vendor/spidermonkey/jsscan.c +2012 -0
  387. data/vendor/spidermonkey/jsscan.h +387 -0
  388. data/vendor/spidermonkey/jsscope.c +1957 -0
  389. data/vendor/spidermonkey/jsscope.h +418 -0
  390. data/vendor/spidermonkey/jsscript.c +1832 -0
  391. data/vendor/spidermonkey/jsscript.h +287 -0
  392. data/vendor/spidermonkey/jsshell.msg +50 -0
  393. data/vendor/spidermonkey/jsstddef.h +83 -0
  394. data/vendor/spidermonkey/jsstr.c +5005 -0
  395. data/vendor/spidermonkey/jsstr.h +641 -0
  396. data/vendor/spidermonkey/jstypes.h +475 -0
  397. data/vendor/spidermonkey/jsutil.c +345 -0
  398. data/vendor/spidermonkey/jsutil.h +157 -0
  399. data/vendor/spidermonkey/jsxdrapi.c +800 -0
  400. data/vendor/spidermonkey/jsxdrapi.h +218 -0
  401. data/vendor/spidermonkey/jsxml.c +8476 -0
  402. data/vendor/spidermonkey/jsxml.h +349 -0
  403. data/vendor/spidermonkey/lock_SunOS.s +119 -0
  404. data/vendor/spidermonkey/perfect.js +39 -0
  405. data/vendor/spidermonkey/plify_jsdhash.sed +36 -0
  406. data/vendor/spidermonkey/prmjtime.c +846 -0
  407. data/vendor/spidermonkey/prmjtime.h +103 -0
  408. data/vendor/spidermonkey/resource.h +15 -0
  409. data/vendor/spidermonkey/rules.mk +197 -0
  410. data/vendor/spidermonkey/win32.order +384 -0
  411. data/vendor/tracemonkey/Makefile.in +668 -0
  412. data/vendor/tracemonkey/Makefile.ref +483 -0
  413. data/vendor/tracemonkey/README.html +54 -0
  414. data/vendor/tracemonkey/SpiderMonkey.rsp +11 -0
  415. data/vendor/tracemonkey/Y.js +19 -0
  416. data/vendor/tracemonkey/aclocal.m4 +9 -0
  417. data/vendor/tracemonkey/bench.sh +5 -0
  418. data/vendor/tracemonkey/build/autoconf/acoutput-fast.pl +202 -0
  419. data/vendor/tracemonkey/build/autoconf/altoptions.m4 +154 -0
  420. data/vendor/tracemonkey/build/autoconf/config.guess +1537 -0
  421. data/vendor/tracemonkey/build/autoconf/config.sub +1595 -0
  422. data/vendor/tracemonkey/build/autoconf/install-sh +119 -0
  423. data/vendor/tracemonkey/build/autoconf/make-makefile +315 -0
  424. data/vendor/tracemonkey/build/autoconf/match-dir.sh +101 -0
  425. data/vendor/tracemonkey/build/autoconf/moznbytetype.m4 +136 -0
  426. data/vendor/tracemonkey/build/autoconf/nspr.m4 +82 -0
  427. data/vendor/tracemonkey/build/autoconf/pkg.m4 +59 -0
  428. data/vendor/tracemonkey/build/autoconf/update-makefile.sh +118 -0
  429. data/vendor/tracemonkey/build/cygwin-wrapper +75 -0
  430. data/vendor/tracemonkey/build/hcc +111 -0
  431. data/vendor/tracemonkey/build/hcpp +155 -0
  432. data/vendor/tracemonkey/build/unix/mddepend.pl +165 -0
  433. data/vendor/tracemonkey/build/unix/uniq.pl +63 -0
  434. data/vendor/tracemonkey/build/win32/pgomerge.py +40 -0
  435. data/vendor/tracemonkey/builtins.tbl +91 -0
  436. data/vendor/tracemonkey/call.js +13 -0
  437. data/vendor/tracemonkey/config/Makefile.in +106 -0
  438. data/vendor/tracemonkey/config/Moz/Milestone.pm +232 -0
  439. data/vendor/tracemonkey/config/autoconf.mk.in +362 -0
  440. data/vendor/tracemonkey/config/check-sync-dirs.py +103 -0
  441. data/vendor/tracemonkey/config/check-sync-exceptions +7 -0
  442. data/vendor/tracemonkey/config/config.mk +881 -0
  443. data/vendor/tracemonkey/config/fastcwd.pl +66 -0
  444. data/vendor/tracemonkey/config/gcc_hidden.h +2 -0
  445. data/vendor/tracemonkey/config/insure.mk +53 -0
  446. data/vendor/tracemonkey/config/make-system-wrappers.pl +59 -0
  447. data/vendor/tracemonkey/config/milestone.pl +112 -0
  448. data/vendor/tracemonkey/config/milestone.txt +13 -0
  449. data/vendor/tracemonkey/config/mkdepend/Makefile.in +84 -0
  450. data/vendor/tracemonkey/config/mkdepend/cppsetup.c +233 -0
  451. data/vendor/tracemonkey/config/mkdepend/def.h +184 -0
  452. data/vendor/tracemonkey/config/mkdepend/ifparser.c +551 -0
  453. data/vendor/tracemonkey/config/mkdepend/ifparser.h +83 -0
  454. data/vendor/tracemonkey/config/mkdepend/imakemdep.h +733 -0
  455. data/vendor/tracemonkey/config/mkdepend/include.c +337 -0
  456. data/vendor/tracemonkey/config/mkdepend/main.c +860 -0
  457. data/vendor/tracemonkey/config/mkdepend/mkdepend.man +382 -0
  458. data/vendor/tracemonkey/config/mkdepend/parse.c +686 -0
  459. data/vendor/tracemonkey/config/mkdepend/pr.c +124 -0
  460. data/vendor/tracemonkey/config/nfspwd.pl +50 -0
  461. data/vendor/tracemonkey/config/nsinstall.c +481 -0
  462. data/vendor/tracemonkey/config/nsinstall.py +155 -0
  463. data/vendor/tracemonkey/config/pathsub.c +247 -0
  464. data/vendor/tracemonkey/config/pathsub.h +74 -0
  465. data/vendor/tracemonkey/config/preprocessor.pl +671 -0
  466. data/vendor/tracemonkey/config/revdepth-nt.pl +48 -0
  467. data/vendor/tracemonkey/config/revdepth.pl +51 -0
  468. data/vendor/tracemonkey/config/rules.mk +2310 -0
  469. data/vendor/tracemonkey/config/static-checking-config.mk +21 -0
  470. data/vendor/tracemonkey/config/static-checking.js +92 -0
  471. data/vendor/tracemonkey/config/string-format.js +61 -0
  472. data/vendor/tracemonkey/config/system-headers +1035 -0
  473. data/vendor/tracemonkey/config/version.mk +85 -0
  474. data/vendor/tracemonkey/config/version_win.pl +442 -0
  475. data/vendor/tracemonkey/config.mk +206 -0
  476. data/vendor/tracemonkey/configure +14183 -0
  477. data/vendor/tracemonkey/configure.in +5363 -0
  478. data/vendor/tracemonkey/correct/check-3d-morph.js +55 -0
  479. data/vendor/tracemonkey/correct/check-3d-raytrace.js +445 -0
  480. data/vendor/tracemonkey/correct/check-access-binary-trees.js +52 -0
  481. data/vendor/tracemonkey/correct/check-access-fannkuch.js +66 -0
  482. data/vendor/tracemonkey/correct/check-access-nbody.js +171 -0
  483. data/vendor/tracemonkey/correct/check-access-nsieve.js +40 -0
  484. data/vendor/tracemonkey/correct/check-bitops-3bit-bits-in-byte.js +35 -0
  485. data/vendor/tracemonkey/correct/check-bitops-bits-in-byte.js +24 -0
  486. data/vendor/tracemonkey/correct/check-bitops-bitwise-and.js +29 -0
  487. data/vendor/tracemonkey/correct/check-bitops-nsieve-bits.js +40 -0
  488. data/vendor/tracemonkey/correct/check-controlflow-recursive.js +27 -0
  489. data/vendor/tracemonkey/correct/check-date-format-tofte.js +302 -0
  490. data/vendor/tracemonkey/correct/check-date-format-xparb.js +421 -0
  491. data/vendor/tracemonkey/correct/check-mont.js +119 -0
  492. data/vendor/tracemonkey/correct.sh +23 -0
  493. data/vendor/tracemonkey/dtoa.c +3335 -0
  494. data/vendor/tracemonkey/editline/Makefile.in +55 -0
  495. data/vendor/tracemonkey/editline/Makefile.ref +143 -0
  496. data/vendor/tracemonkey/editline/README +83 -0
  497. data/vendor/tracemonkey/editline/editline.3 +175 -0
  498. data/vendor/tracemonkey/editline/editline.c +1371 -0
  499. data/vendor/tracemonkey/editline/editline.h +135 -0
  500. data/vendor/tracemonkey/editline/sysunix.c +182 -0
  501. data/vendor/tracemonkey/editline/unix.h +82 -0
  502. data/vendor/tracemonkey/if.js +13 -0
  503. data/vendor/tracemonkey/imacro_asm.js.in +396 -0
  504. data/vendor/tracemonkey/imacros.c.out +1034 -0
  505. data/vendor/tracemonkey/imacros.jsasm +770 -0
  506. data/vendor/tracemonkey/javascript-trace.d +73 -0
  507. data/vendor/tracemonkey/jitstats.tbl +55 -0
  508. data/vendor/tracemonkey/js-config.h.in +82 -0
  509. data/vendor/tracemonkey/js-config.in +111 -0
  510. data/vendor/tracemonkey/js.mdp +0 -0
  511. data/vendor/tracemonkey/js.msg +312 -0
  512. data/vendor/tracemonkey/js3240.rc +79 -0
  513. data/vendor/tracemonkey/jsOS240.def +654 -0
  514. data/vendor/tracemonkey/jsapi.cpp +6005 -0
  515. data/vendor/tracemonkey/jsapi.h +2727 -0
  516. data/vendor/tracemonkey/jsarena.cpp +450 -0
  517. data/vendor/tracemonkey/jsarena.h +318 -0
  518. data/vendor/tracemonkey/jsarray.cpp +3664 -0
  519. data/vendor/tracemonkey/jsarray.h +238 -0
  520. data/vendor/tracemonkey/jsatom.cpp +1244 -0
  521. data/vendor/tracemonkey/jsatom.h +493 -0
  522. data/vendor/tracemonkey/jsbit.h +249 -0
  523. data/vendor/tracemonkey/jsbool.cpp +184 -0
  524. data/vendor/tracemonkey/jsbool.h +88 -0
  525. data/vendor/tracemonkey/jsbuiltins.cpp +415 -0
  526. data/vendor/tracemonkey/jsbuiltins.h +456 -0
  527. data/vendor/tracemonkey/jsclist.h +139 -0
  528. data/vendor/tracemonkey/jscntxt.cpp +1816 -0
  529. data/vendor/tracemonkey/jscntxt.h +1541 -0
  530. data/vendor/tracemonkey/jscompat.h +57 -0
  531. data/vendor/tracemonkey/jsconfig.mk +181 -0
  532. data/vendor/tracemonkey/jscpucfg.cpp +194 -0
  533. data/vendor/tracemonkey/jscpucfg.h +91 -0
  534. data/vendor/tracemonkey/jsdate.cpp +2465 -0
  535. data/vendor/tracemonkey/jsdate.h +129 -0
  536. data/vendor/tracemonkey/jsdbgapi.cpp +2017 -0
  537. data/vendor/tracemonkey/jsdbgapi.h +500 -0
  538. data/vendor/tracemonkey/jsdhash.cpp +876 -0
  539. data/vendor/tracemonkey/jsdhash.h +588 -0
  540. data/vendor/tracemonkey/jsdtoa.cpp +572 -0
  541. data/vendor/tracemonkey/jsdtoa.h +131 -0
  542. data/vendor/tracemonkey/jsdtracef.c +318 -0
  543. data/vendor/tracemonkey/jsdtracef.h +81 -0
  544. data/vendor/tracemonkey/jsemit.cpp +7292 -0
  545. data/vendor/tracemonkey/jsemit.h +802 -0
  546. data/vendor/tracemonkey/jsexn.cpp +1337 -0
  547. data/vendor/tracemonkey/jsexn.h +96 -0
  548. data/vendor/tracemonkey/jsfile.cpp +2747 -0
  549. data/vendor/tracemonkey/jsfile.h +56 -0
  550. data/vendor/tracemonkey/jsfile.msg +90 -0
  551. data/vendor/tracemonkey/jsfun.cpp +3089 -0
  552. data/vendor/tracemonkey/jsfun.h +366 -0
  553. data/vendor/tracemonkey/jsgc.cpp +3816 -0
  554. data/vendor/tracemonkey/jsgc.h +429 -0
  555. data/vendor/tracemonkey/jshash.cpp +477 -0
  556. data/vendor/tracemonkey/jshash.h +151 -0
  557. data/vendor/tracemonkey/jsify.pl +483 -0
  558. data/vendor/tracemonkey/jsinterp.cpp +7441 -0
  559. data/vendor/tracemonkey/jsinterp.h +666 -0
  560. data/vendor/tracemonkey/jsinvoke.cpp +42 -0
  561. data/vendor/tracemonkey/jsiter.cpp +1040 -0
  562. data/vendor/tracemonkey/jsiter.h +140 -0
  563. data/vendor/tracemonkey/jskeyword.tbl +124 -0
  564. data/vendor/tracemonkey/jskwgen.cpp +460 -0
  565. data/vendor/tracemonkey/jslibmath.h +69 -0
  566. data/vendor/tracemonkey/jslock.cpp +1512 -0
  567. data/vendor/tracemonkey/jslock.h +325 -0
  568. data/vendor/tracemonkey/jslocko.asm +60 -0
  569. data/vendor/tracemonkey/jslog2.cpp +111 -0
  570. data/vendor/tracemonkey/jslong.h +167 -0
  571. data/vendor/tracemonkey/jsmath.cpp +806 -0
  572. data/vendor/tracemonkey/jsmath.h +63 -0
  573. data/vendor/tracemonkey/jsnum.cpp +1374 -0
  574. data/vendor/tracemonkey/jsnum.h +280 -0
  575. data/vendor/tracemonkey/jsobj.cpp +6165 -0
  576. data/vendor/tracemonkey/jsobj.h +873 -0
  577. data/vendor/tracemonkey/json.cpp +1338 -0
  578. data/vendor/tracemonkey/json.h +108 -0
  579. data/vendor/tracemonkey/jsopcode.cpp +5484 -0
  580. data/vendor/tracemonkey/jsopcode.h +434 -0
  581. data/vendor/tracemonkey/jsopcode.tbl +591 -0
  582. data/vendor/tracemonkey/jsoplengen.cpp +121 -0
  583. data/vendor/tracemonkey/jsotypes.h +202 -0
  584. data/vendor/tracemonkey/jsparse.cpp +9272 -0
  585. data/vendor/tracemonkey/jsparse.h +900 -0
  586. data/vendor/tracemonkey/jsprf.cpp +1262 -0
  587. data/vendor/tracemonkey/jsprf.h +150 -0
  588. data/vendor/tracemonkey/jsproto.tbl +117 -0
  589. data/vendor/tracemonkey/jsprvtd.h +366 -0
  590. data/vendor/tracemonkey/jspubtd.h +585 -0
  591. data/vendor/tracemonkey/jsregexp.cpp +5051 -0
  592. data/vendor/tracemonkey/jsregexp.h +199 -0
  593. data/vendor/tracemonkey/jsreops.tbl +145 -0
  594. data/vendor/tracemonkey/jsscan.cpp +2040 -0
  595. data/vendor/tracemonkey/jsscan.h +467 -0
  596. data/vendor/tracemonkey/jsscope.cpp +1966 -0
  597. data/vendor/tracemonkey/jsscope.h +487 -0
  598. data/vendor/tracemonkey/jsscript.cpp +1932 -0
  599. data/vendor/tracemonkey/jsscript.h +345 -0
  600. data/vendor/tracemonkey/jsshell.msg +54 -0
  601. data/vendor/tracemonkey/jsstack.js +167 -0
  602. data/vendor/tracemonkey/jsstaticcheck.h +69 -0
  603. data/vendor/tracemonkey/jsstddef.h +87 -0
  604. data/vendor/tracemonkey/jsstdint.h +96 -0
  605. data/vendor/tracemonkey/jsstr.cpp +5277 -0
  606. data/vendor/tracemonkey/jsstr.h +702 -0
  607. data/vendor/tracemonkey/jstracer.cpp +10991 -0
  608. data/vendor/tracemonkey/jstracer.h +794 -0
  609. data/vendor/tracemonkey/jstypes.h +481 -0
  610. data/vendor/tracemonkey/jsutil.cpp +361 -0
  611. data/vendor/tracemonkey/jsutil.h +178 -0
  612. data/vendor/tracemonkey/jsversion.h +243 -0
  613. data/vendor/tracemonkey/jswince.asm +44 -0
  614. data/vendor/tracemonkey/jsxdrapi.cpp +800 -0
  615. data/vendor/tracemonkey/jsxdrapi.h +220 -0
  616. data/vendor/tracemonkey/jsxml.cpp +8327 -0
  617. data/vendor/tracemonkey/jsxml.h +305 -0
  618. data/vendor/tracemonkey/liveconnect/LiveConnect.dsp +157 -0
  619. data/vendor/tracemonkey/liveconnect/LiveConnectShell.dsp +120 -0
  620. data/vendor/tracemonkey/liveconnect/LiveConnectShell.dsw +44 -0
  621. data/vendor/tracemonkey/liveconnect/Makefile.in +105 -0
  622. data/vendor/tracemonkey/liveconnect/Makefile.ref +169 -0
  623. data/vendor/tracemonkey/liveconnect/README.html +712 -0
  624. data/vendor/tracemonkey/liveconnect/_jni/netscape_javascript_JSException.h +14 -0
  625. data/vendor/tracemonkey/liveconnect/_jni/netscape_javascript_JSObject.h +155 -0
  626. data/vendor/tracemonkey/liveconnect/classes/Makefile.in +89 -0
  627. data/vendor/tracemonkey/liveconnect/classes/Makefile.ref +57 -0
  628. data/vendor/tracemonkey/liveconnect/classes/netscape/Makefile.ref +47 -0
  629. data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/JSException.java +140 -0
  630. data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/JSObject.java +183 -0
  631. data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/JSProxy.java +58 -0
  632. data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/JSRunnable.java +70 -0
  633. data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/JSUtil.java +59 -0
  634. data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/Makefile.ref +53 -0
  635. data/vendor/tracemonkey/liveconnect/config/AIX4.1.mk +45 -0
  636. data/vendor/tracemonkey/liveconnect/config/AIX4.2.mk +45 -0
  637. data/vendor/tracemonkey/liveconnect/config/AIX4.3.mk +50 -0
  638. data/vendor/tracemonkey/liveconnect/config/HP-UXB.10.10.mk +43 -0
  639. data/vendor/tracemonkey/liveconnect/config/HP-UXB.10.20.mk +43 -0
  640. data/vendor/tracemonkey/liveconnect/config/HP-UXB.11.00.mk +43 -0
  641. data/vendor/tracemonkey/liveconnect/config/IRIX6.2.mk +43 -0
  642. data/vendor/tracemonkey/liveconnect/config/IRIX6.3.mk +43 -0
  643. data/vendor/tracemonkey/liveconnect/config/IRIX6.5.mk +43 -0
  644. data/vendor/tracemonkey/liveconnect/config/Linux_All.mk +73 -0
  645. data/vendor/tracemonkey/liveconnect/config/OSF1V4.0.mk +65 -0
  646. data/vendor/tracemonkey/liveconnect/config/OSF1V5.0.mk +62 -0
  647. data/vendor/tracemonkey/liveconnect/config/SunOS5.5.1.mk +55 -0
  648. data/vendor/tracemonkey/liveconnect/config/SunOS5.6.mk +39 -0
  649. data/vendor/tracemonkey/liveconnect/config/SunOS5.7.mk +39 -0
  650. data/vendor/tracemonkey/liveconnect/config/SunOS5.8.mk +39 -0
  651. data/vendor/tracemonkey/liveconnect/config/WINNT4.0.mk +53 -0
  652. data/vendor/tracemonkey/liveconnect/jsj.c +886 -0
  653. data/vendor/tracemonkey/liveconnect/jsj.msg +98 -0
  654. data/vendor/tracemonkey/liveconnect/jsj_JSObject.c +1377 -0
  655. data/vendor/tracemonkey/liveconnect/jsj_JavaArray.c +474 -0
  656. data/vendor/tracemonkey/liveconnect/jsj_JavaClass.c +737 -0
  657. data/vendor/tracemonkey/liveconnect/jsj_JavaMember.c +191 -0
  658. data/vendor/tracemonkey/liveconnect/jsj_JavaObject.c +1079 -0
  659. data/vendor/tracemonkey/liveconnect/jsj_JavaPackage.c +569 -0
  660. data/vendor/tracemonkey/liveconnect/jsj_array.c +207 -0
  661. data/vendor/tracemonkey/liveconnect/jsj_class.c +770 -0
  662. data/vendor/tracemonkey/liveconnect/jsj_convert.c +902 -0
  663. data/vendor/tracemonkey/liveconnect/jsj_field.c +421 -0
  664. data/vendor/tracemonkey/liveconnect/jsj_hash.c +488 -0
  665. data/vendor/tracemonkey/liveconnect/jsj_hash.h +161 -0
  666. data/vendor/tracemonkey/liveconnect/jsj_method.c +1825 -0
  667. data/vendor/tracemonkey/liveconnect/jsj_nodl.c +1 -0
  668. data/vendor/tracemonkey/liveconnect/jsj_private.h +677 -0
  669. data/vendor/tracemonkey/liveconnect/jsj_simpleapi.c +219 -0
  670. data/vendor/tracemonkey/liveconnect/jsj_utils.c +513 -0
  671. data/vendor/tracemonkey/liveconnect/jsjava.h +316 -0
  672. data/vendor/tracemonkey/liveconnect/netscape_javascript_JSObject.h +155 -0
  673. data/vendor/tracemonkey/liveconnect/nsCLiveconnect.cpp +785 -0
  674. data/vendor/tracemonkey/liveconnect/nsCLiveconnect.h +197 -0
  675. data/vendor/tracemonkey/liveconnect/nsCLiveconnectFactory.cpp +118 -0
  676. data/vendor/tracemonkey/liveconnect/nsCLiveconnectFactory.h +76 -0
  677. data/vendor/tracemonkey/liveconnect/nsILiveconnect.h +197 -0
  678. data/vendor/tracemonkey/liveconnect/nsISecureLiveconnect.h +94 -0
  679. data/vendor/tracemonkey/liveconnect/nsISecurityContext.h +136 -0
  680. data/vendor/tracemonkey/lock_SunOS.s +119 -0
  681. data/vendor/tracemonkey/mandelbrot-results.js +3 -0
  682. data/vendor/tracemonkey/math-partial-sums.js +32 -0
  683. data/vendor/tracemonkey/math-trace-tests.js +507 -0
  684. data/vendor/tracemonkey/md5.js +289 -0
  685. data/vendor/tracemonkey/nanojit/Assembler.cpp +1984 -0
  686. data/vendor/tracemonkey/nanojit/Assembler.h +375 -0
  687. data/vendor/tracemonkey/nanojit/Fragmento.cpp +651 -0
  688. data/vendor/tracemonkey/nanojit/Fragmento.h +237 -0
  689. data/vendor/tracemonkey/nanojit/LIR.cpp +2314 -0
  690. data/vendor/tracemonkey/nanojit/LIR.h +879 -0
  691. data/vendor/tracemonkey/nanojit/LIRopcode.tbl +252 -0
  692. data/vendor/tracemonkey/nanojit/Native.h +127 -0
  693. data/vendor/tracemonkey/nanojit/NativeARM.cpp +1742 -0
  694. data/vendor/tracemonkey/nanojit/NativeARM.h +844 -0
  695. data/vendor/tracemonkey/nanojit/NativeSparc.cpp +1130 -0
  696. data/vendor/tracemonkey/nanojit/NativeSparc.h +948 -0
  697. data/vendor/tracemonkey/nanojit/NativeThumb.cpp +1322 -0
  698. data/vendor/tracemonkey/nanojit/NativeThumb.h +525 -0
  699. data/vendor/tracemonkey/nanojit/Nativei386.cpp +1748 -0
  700. data/vendor/tracemonkey/nanojit/Nativei386.h +857 -0
  701. data/vendor/tracemonkey/nanojit/RegAlloc.cpp +183 -0
  702. data/vendor/tracemonkey/nanojit/RegAlloc.h +95 -0
  703. data/vendor/tracemonkey/nanojit/TraceTreeDrawer.cpp +306 -0
  704. data/vendor/tracemonkey/nanojit/TraceTreeDrawer.h +88 -0
  705. data/vendor/tracemonkey/nanojit/avmplus.cpp +56 -0
  706. data/vendor/tracemonkey/nanojit/avmplus.h +1016 -0
  707. data/vendor/tracemonkey/nanojit/nanojit.h +253 -0
  708. data/vendor/tracemonkey/perfect.js +39 -0
  709. data/vendor/tracemonkey/plify_jsdhash.sed +35 -0
  710. data/vendor/tracemonkey/prmjtime.cpp +869 -0
  711. data/vendor/tracemonkey/prmjtime.h +103 -0
  712. data/vendor/tracemonkey/ref-config/AIX4.1.mk +65 -0
  713. data/vendor/tracemonkey/ref-config/AIX4.2.mk +64 -0
  714. data/vendor/tracemonkey/ref-config/AIX4.3.mk +65 -0
  715. data/vendor/tracemonkey/ref-config/Darwin.mk +85 -0
  716. data/vendor/tracemonkey/ref-config/Darwin1.3.mk +81 -0
  717. data/vendor/tracemonkey/ref-config/Darwin1.4.mk +41 -0
  718. data/vendor/tracemonkey/ref-config/Darwin5.2.mk +81 -0
  719. data/vendor/tracemonkey/ref-config/Darwin5.3.mk +81 -0
  720. data/vendor/tracemonkey/ref-config/Darwin64.mk +72 -0
  721. data/vendor/tracemonkey/ref-config/HP-UXB.10.10.mk +77 -0
  722. data/vendor/tracemonkey/ref-config/HP-UXB.10.20.mk +77 -0
  723. data/vendor/tracemonkey/ref-config/HP-UXB.11.00.mk +80 -0
  724. data/vendor/tracemonkey/ref-config/IRIX.mk +87 -0
  725. data/vendor/tracemonkey/ref-config/IRIX5.3.mk +44 -0
  726. data/vendor/tracemonkey/ref-config/IRIX6.1.mk +44 -0
  727. data/vendor/tracemonkey/ref-config/IRIX6.2.mk +44 -0
  728. data/vendor/tracemonkey/ref-config/IRIX6.3.mk +44 -0
  729. data/vendor/tracemonkey/ref-config/IRIX6.5.mk +44 -0
  730. data/vendor/tracemonkey/ref-config/Linux_All.mk +105 -0
  731. data/vendor/tracemonkey/ref-config/Mac_OS10.0.mk +82 -0
  732. data/vendor/tracemonkey/ref-config/OSF1V4.0.mk +72 -0
  733. data/vendor/tracemonkey/ref-config/OSF1V5.0.mk +69 -0
  734. data/vendor/tracemonkey/ref-config/SunOS4.1.4.mk +101 -0
  735. data/vendor/tracemonkey/ref-config/SunOS5.10.mk +50 -0
  736. data/vendor/tracemonkey/ref-config/SunOS5.3.mk +91 -0
  737. data/vendor/tracemonkey/ref-config/SunOS5.4.mk +92 -0
  738. data/vendor/tracemonkey/ref-config/SunOS5.5.1.mk +44 -0
  739. data/vendor/tracemonkey/ref-config/SunOS5.5.mk +87 -0
  740. data/vendor/tracemonkey/ref-config/SunOS5.6.mk +89 -0
  741. data/vendor/tracemonkey/ref-config/SunOS5.7.mk +44 -0
  742. data/vendor/tracemonkey/ref-config/SunOS5.8.mk +44 -0
  743. data/vendor/tracemonkey/ref-config/SunOS5.9.mk +44 -0
  744. data/vendor/tracemonkey/ref-config/WINNT4.0.mk +118 -0
  745. data/vendor/tracemonkey/ref-config/WINNT5.0.mk +118 -0
  746. data/vendor/tracemonkey/ref-config/WINNT5.1.mk +118 -0
  747. data/vendor/tracemonkey/ref-config/WINNT5.2.mk +118 -0
  748. data/vendor/tracemonkey/ref-config/WINNT6.0.mk +118 -0
  749. data/vendor/tracemonkey/ref-config/dgux.mk +64 -0
  750. data/vendor/tracemonkey/resource.h +15 -0
  751. data/vendor/tracemonkey/rules.mk +206 -0
  752. data/vendor/tracemonkey/shell/Makefile.in +72 -0
  753. data/vendor/tracemonkey/shell/js.cpp +4719 -0
  754. data/vendor/tracemonkey/t/3d-cube.js +337 -0
  755. data/vendor/tracemonkey/t/3d-morph.js +54 -0
  756. data/vendor/tracemonkey/t/3d-raytrace.js +441 -0
  757. data/vendor/tracemonkey/t/access-binary-trees.js +50 -0
  758. data/vendor/tracemonkey/t/access-fannkuch.js +66 -0
  759. data/vendor/tracemonkey/t/access-nbody.js +169 -0
  760. data/vendor/tracemonkey/t/access-nsieve.js +38 -0
  761. data/vendor/tracemonkey/t/bitops-3bit-bits-in-byte.js +32 -0
  762. data/vendor/tracemonkey/t/bitops-bits-in-byte.js +21 -0
  763. data/vendor/tracemonkey/t/bitops-bitwise-and.js +28 -0
  764. data/vendor/tracemonkey/t/bitops-nsieve-bits.js +32 -0
  765. data/vendor/tracemonkey/t/controlflow-recursive.js +25 -0
  766. data/vendor/tracemonkey/t/crypto-aes.js +422 -0
  767. data/vendor/tracemonkey/t/crypto-md5.js +286 -0
  768. data/vendor/tracemonkey/t/crypto-sha1.js +224 -0
  769. data/vendor/tracemonkey/t/date-format-tofte.js +299 -0
  770. data/vendor/tracemonkey/t/date-format-xparb.js +417 -0
  771. data/vendor/tracemonkey/t/math-cordic.js +95 -0
  772. data/vendor/tracemonkey/t/math-partial-sums.js +33 -0
  773. data/vendor/tracemonkey/t/math-spectral-norm.js +51 -0
  774. data/vendor/tracemonkey/t/regexp-dna.js +1712 -0
  775. data/vendor/tracemonkey/t/string-base64.js +135 -0
  776. data/vendor/tracemonkey/t/string-fasta.js +85 -0
  777. data/vendor/tracemonkey/t/string-tagcloud.js +265 -0
  778. data/vendor/tracemonkey/t/string-unpack-code.js +68 -0
  779. data/vendor/tracemonkey/t/string-validate-input.js +89 -0
  780. data/vendor/tracemonkey/time.sh +13 -0
  781. data/vendor/tracemonkey/trace-test.js +5564 -0
  782. data/vendor/tracemonkey/v8/base.js +187 -0
  783. data/vendor/tracemonkey/v8/crypto.js +1689 -0
  784. data/vendor/tracemonkey/v8/deltablue.js +880 -0
  785. data/vendor/tracemonkey/v8/earley-boyer.js +4682 -0
  786. data/vendor/tracemonkey/v8/raytrace.js +3418 -0
  787. data/vendor/tracemonkey/v8/richards.js +539 -0
  788. data/vendor/tracemonkey/v8/run-crypto.js +44 -0
  789. data/vendor/tracemonkey/v8/run-deltablue.js +44 -0
  790. data/vendor/tracemonkey/v8/run-earley-boyer.js +44 -0
  791. data/vendor/tracemonkey/v8/run-raytrace.js +44 -0
  792. data/vendor/tracemonkey/v8/run-richards.js +44 -0
  793. data/vendor/tracemonkey/v8/run.js +49 -0
  794. data/vendor/tracemonkey/vprof/readme.txt +93 -0
  795. data/vendor/tracemonkey/vprof/vprof.cpp +360 -0
  796. data/vendor/tracemonkey/vprof/vprof.h +245 -0
  797. data/vendor/tracemonkey/xpconnect/Makefile.in +67 -0
  798. data/vendor/tracemonkey/xpconnect/crashtests/117307-1.html +20 -0
  799. data/vendor/tracemonkey/xpconnect/crashtests/193710.html +11 -0
  800. data/vendor/tracemonkey/xpconnect/crashtests/290162-1.html +5 -0
  801. data/vendor/tracemonkey/xpconnect/crashtests/326615-1.html +16 -0
  802. data/vendor/tracemonkey/xpconnect/crashtests/328553-1.html +13 -0
  803. data/vendor/tracemonkey/xpconnect/crashtests/346258-1.html +12 -0
  804. data/vendor/tracemonkey/xpconnect/crashtests/346512-1-frame1.xhtml +16 -0
  805. data/vendor/tracemonkey/xpconnect/crashtests/346512-1-frame2.xhtml +15 -0
  806. data/vendor/tracemonkey/xpconnect/crashtests/346512-1.xhtml +30 -0
  807. data/vendor/tracemonkey/xpconnect/crashtests/382133-1.html +3 -0
  808. data/vendor/tracemonkey/xpconnect/crashtests/386680-1.html +22 -0
  809. data/vendor/tracemonkey/xpconnect/crashtests/394810-1.html +4 -0
  810. data/vendor/tracemonkey/xpconnect/crashtests/400349-1.html +20 -0
  811. data/vendor/tracemonkey/xpconnect/crashtests/403356-1.html +13 -0
  812. data/vendor/tracemonkey/xpconnect/crashtests/418139-1.svg +22 -0
  813. data/vendor/tracemonkey/xpconnect/crashtests/420513-1.html +11 -0
  814. data/vendor/tracemonkey/xpconnect/crashtests/453935-1.html +37 -0
  815. data/vendor/tracemonkey/xpconnect/crashtests/462926.html +12 -0
  816. data/vendor/tracemonkey/xpconnect/crashtests/468552-1.html +18 -0
  817. data/vendor/tracemonkey/xpconnect/crashtests/471366-1.html +12 -0
  818. data/vendor/tracemonkey/xpconnect/crashtests/475185-1.html +13 -0
  819. data/vendor/tracemonkey/xpconnect/crashtests/475291-1.html +14 -0
  820. data/vendor/tracemonkey/xpconnect/crashtests/503286-1.html +23 -0
  821. data/vendor/tracemonkey/xpconnect/crashtests/crashtests.list +21 -0
  822. data/vendor/tracemonkey/xpconnect/idl/Makefile.in +78 -0
  823. data/vendor/tracemonkey/xpconnect/idl/XPCIDispatch.idl +51 -0
  824. data/vendor/tracemonkey/xpconnect/idl/mozIJSSubScriptLoader.idl +64 -0
  825. data/vendor/tracemonkey/xpconnect/idl/nsIActiveXSecurityPolicy.idl +67 -0
  826. data/vendor/tracemonkey/xpconnect/idl/nsIDispatchSupport.idl +119 -0
  827. data/vendor/tracemonkey/xpconnect/idl/nsIJSContextStack.idl +85 -0
  828. data/vendor/tracemonkey/xpconnect/idl/nsIJSRuntimeService.idl +51 -0
  829. data/vendor/tracemonkey/xpconnect/idl/nsIScriptError.idl +102 -0
  830. data/vendor/tracemonkey/xpconnect/idl/nsIScriptableInterfaces.idl +67 -0
  831. data/vendor/tracemonkey/xpconnect/idl/nsIXPCScriptNotify.idl +66 -0
  832. data/vendor/tracemonkey/xpconnect/idl/nsIXPCScriptable.idl +183 -0
  833. data/vendor/tracemonkey/xpconnect/idl/nsIXPCSecurityManager.idl +114 -0
  834. data/vendor/tracemonkey/xpconnect/idl/nsIXPConnect.idl +819 -0
  835. data/vendor/tracemonkey/xpconnect/idl/xpcIJSModuleLoader.idl +95 -0
  836. data/vendor/tracemonkey/xpconnect/idl/xpcIJSWeakReference.idl +49 -0
  837. data/vendor/tracemonkey/xpconnect/idl/xpccomponents.idl +254 -0
  838. data/vendor/tracemonkey/xpconnect/idl/xpcexception.idl +66 -0
  839. data/vendor/tracemonkey/xpconnect/idl/xpcjsid.idl +83 -0
  840. data/vendor/tracemonkey/xpconnect/loader/ISO8601DateUtils.jsm +176 -0
  841. data/vendor/tracemonkey/xpconnect/loader/Makefile.in +63 -0
  842. data/vendor/tracemonkey/xpconnect/loader/XPCOMUtils.jsm +267 -0
  843. data/vendor/tracemonkey/xpconnect/loader/mozJSComponentLoader.cpp +1717 -0
  844. data/vendor/tracemonkey/xpconnect/loader/mozJSComponentLoader.h +172 -0
  845. data/vendor/tracemonkey/xpconnect/loader/mozJSLoaderConstructors.h +101 -0
  846. data/vendor/tracemonkey/xpconnect/loader/mozJSSubScriptLoader.cpp +360 -0
  847. data/vendor/tracemonkey/xpconnect/loader/mozJSSubScriptLoader.h +66 -0
  848. data/vendor/tracemonkey/xpconnect/public/Makefile.in +54 -0
  849. data/vendor/tracemonkey/xpconnect/public/nsAXPCNativeCallContext.h +89 -0
  850. data/vendor/tracemonkey/xpconnect/public/nsAutoJSValHolder.h +168 -0
  851. data/vendor/tracemonkey/xpconnect/public/xpc_map_end.h +327 -0
  852. data/vendor/tracemonkey/xpconnect/sample/Makefile.in +71 -0
  853. data/vendor/tracemonkey/xpconnect/sample/README +39 -0
  854. data/vendor/tracemonkey/xpconnect/sample/xpcsample1.cpp +337 -0
  855. data/vendor/tracemonkey/xpconnect/sample/xpcsample1.idl +82 -0
  856. data/vendor/tracemonkey/xpconnect/sample/xpcsample1.js +21 -0
  857. data/vendor/tracemonkey/xpconnect/shell/Makefile.in +106 -0
  858. data/vendor/tracemonkey/xpconnect/shell/jsshell.msg +50 -0
  859. data/vendor/tracemonkey/xpconnect/shell/xpcshell.cpp +1817 -0
  860. data/vendor/tracemonkey/xpconnect/shell/xpcshellMacUtils.h +43 -0
  861. data/vendor/tracemonkey/xpconnect/shell/xpcshellMacUtils.mm +54 -0
  862. data/vendor/tracemonkey/xpconnect/src/Makefile.in +228 -0
  863. data/vendor/tracemonkey/xpconnect/src/README +3 -0
  864. data/vendor/tracemonkey/xpconnect/src/XPCCrossOriginWrapper.cpp +1186 -0
  865. data/vendor/tracemonkey/xpconnect/src/XPCDispConvert.cpp +593 -0
  866. data/vendor/tracemonkey/xpconnect/src/XPCDispInlines.h +667 -0
  867. data/vendor/tracemonkey/xpconnect/src/XPCDispInterface.cpp +383 -0
  868. data/vendor/tracemonkey/xpconnect/src/XPCDispObject.cpp +516 -0
  869. data/vendor/tracemonkey/xpconnect/src/XPCDispParamPropJSClass.cpp +223 -0
  870. data/vendor/tracemonkey/xpconnect/src/XPCDispParams.cpp +103 -0
  871. data/vendor/tracemonkey/xpconnect/src/XPCDispPrivate.h +1401 -0
  872. data/vendor/tracemonkey/xpconnect/src/XPCDispTearOff.cpp +547 -0
  873. data/vendor/tracemonkey/xpconnect/src/XPCDispTypeInfo.cpp +471 -0
  874. data/vendor/tracemonkey/xpconnect/src/XPCIDispatchClassInfo.cpp +139 -0
  875. data/vendor/tracemonkey/xpconnect/src/XPCIDispatchExtension.cpp +362 -0
  876. data/vendor/tracemonkey/xpconnect/src/XPCNativeWrapper.cpp +1350 -0
  877. data/vendor/tracemonkey/xpconnect/src/XPCNativeWrapper.h +88 -0
  878. data/vendor/tracemonkey/xpconnect/src/XPCSafeJSObjectWrapper.cpp +1148 -0
  879. data/vendor/tracemonkey/xpconnect/src/XPCSystemOnlyWrapper.cpp +718 -0
  880. data/vendor/tracemonkey/xpconnect/src/XPCWrapper.cpp +850 -0
  881. data/vendor/tracemonkey/xpconnect/src/XPCWrapper.h +394 -0
  882. data/vendor/tracemonkey/xpconnect/src/dom_quickstubs.qsconf +568 -0
  883. data/vendor/tracemonkey/xpconnect/src/nsDispatchSupport.cpp +348 -0
  884. data/vendor/tracemonkey/xpconnect/src/nsScriptError.cpp +201 -0
  885. data/vendor/tracemonkey/xpconnect/src/nsXPConnect.cpp +2609 -0
  886. data/vendor/tracemonkey/xpconnect/src/qsgen.py +1487 -0
  887. data/vendor/tracemonkey/xpconnect/src/xpc.msg +217 -0
  888. data/vendor/tracemonkey/xpconnect/src/xpcJSWeakReference.cpp +148 -0
  889. data/vendor/tracemonkey/xpconnect/src/xpcJSWeakReference.h +56 -0
  890. data/vendor/tracemonkey/xpconnect/src/xpccallcontext.cpp +579 -0
  891. data/vendor/tracemonkey/xpconnect/src/xpccomponents.cpp +4144 -0
  892. data/vendor/tracemonkey/xpconnect/src/xpccontext.cpp +115 -0
  893. data/vendor/tracemonkey/xpconnect/src/xpcconvert.cpp +2298 -0
  894. data/vendor/tracemonkey/xpconnect/src/xpcdebug.cpp +481 -0
  895. data/vendor/tracemonkey/xpconnect/src/xpcexception.cpp +502 -0
  896. data/vendor/tracemonkey/xpconnect/src/xpcforwards.h +114 -0
  897. data/vendor/tracemonkey/xpconnect/src/xpcinlines.h +772 -0
  898. data/vendor/tracemonkey/xpconnect/src/xpcjsid.cpp +1025 -0
  899. data/vendor/tracemonkey/xpconnect/src/xpcjsruntime.cpp +1342 -0
  900. data/vendor/tracemonkey/xpconnect/src/xpclog.cpp +128 -0
  901. data/vendor/tracemonkey/xpconnect/src/xpclog.h +101 -0
  902. data/vendor/tracemonkey/xpconnect/src/xpcmaps.cpp +761 -0
  903. data/vendor/tracemonkey/xpconnect/src/xpcmaps.h +713 -0
  904. data/vendor/tracemonkey/xpconnect/src/xpcmodule.cpp +136 -0
  905. data/vendor/tracemonkey/xpconnect/src/xpcprivate.h +4138 -0
  906. data/vendor/tracemonkey/xpconnect/src/xpcquickstubs.cpp +1128 -0
  907. data/vendor/tracemonkey/xpconnect/src/xpcquickstubs.h +480 -0
  908. data/vendor/tracemonkey/xpconnect/src/xpcruntimesvc.cpp +179 -0
  909. data/vendor/tracemonkey/xpconnect/src/xpcstack.cpp +342 -0
  910. data/vendor/tracemonkey/xpconnect/src/xpcstring.cpp +139 -0
  911. data/vendor/tracemonkey/xpconnect/src/xpcthreadcontext.cpp +599 -0
  912. data/vendor/tracemonkey/xpconnect/src/xpcthrower.cpp +399 -0
  913. data/vendor/tracemonkey/xpconnect/src/xpcvariant.cpp +850 -0
  914. data/vendor/tracemonkey/xpconnect/src/xpcwrappedjs.cpp +670 -0
  915. data/vendor/tracemonkey/xpconnect/src/xpcwrappedjsclass.cpp +2015 -0
  916. data/vendor/tracemonkey/xpconnect/src/xpcwrappednative.cpp +3482 -0
  917. data/vendor/tracemonkey/xpconnect/src/xpcwrappednativeinfo.cpp +945 -0
  918. data/vendor/tracemonkey/xpconnect/src/xpcwrappednativejsops.cpp +2003 -0
  919. data/vendor/tracemonkey/xpconnect/src/xpcwrappednativeproto.cpp +302 -0
  920. data/vendor/tracemonkey/xpconnect/src/xpcwrappednativescope.cpp +991 -0
  921. data/vendor/tracemonkey/xpconnect/tests/Makefile.in +75 -0
  922. data/vendor/tracemonkey/xpconnect/tests/TestXPC.cpp +785 -0
  923. data/vendor/tracemonkey/xpconnect/tests/chrome/Makefile.in +51 -0
  924. data/vendor/tracemonkey/xpconnect/tests/chrome/test_bug500931.xul +43 -0
  925. data/vendor/tracemonkey/xpconnect/tests/components/Makefile.in +85 -0
  926. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_array.cpp +388 -0
  927. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_attributes.cpp +305 -0
  928. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_calljs.cpp +135 -0
  929. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_child.cpp +225 -0
  930. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_const.cpp +76 -0
  931. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_domstring.cpp +118 -0
  932. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_echo.cpp +616 -0
  933. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_in.cpp +204 -0
  934. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_inout.cpp +171 -0
  935. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_module.cpp +77 -0
  936. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_multiple.cpp +554 -0
  937. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_noisy.cpp +154 -0
  938. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_out.cpp +335 -0
  939. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_overloaded.cpp +250 -0
  940. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_private.h +192 -0
  941. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_string.cpp +185 -0
  942. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_variant.cpp +355 -0
  943. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/StdAfx.cpp +12 -0
  944. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/StdAfx.h +28 -0
  945. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCDispUtilities.h +28 -0
  946. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.cpp +86 -0
  947. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.def +9 -0
  948. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.dsp +318 -0
  949. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.dsw +29 -0
  950. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.idl +454 -0
  951. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.rc +145 -0
  952. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispSimple.cpp +44 -0
  953. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispSimple.h +56 -0
  954. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispSimple.rgs +23 -0
  955. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestArrays.cpp +221 -0
  956. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestArrays.h +53 -0
  957. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestArrays.rgs +23 -0
  958. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestMethods.cpp +699 -0
  959. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestMethods.h +138 -0
  960. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestMethods.rgs +23 -0
  961. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestNoIDispatch.cpp +23 -0
  962. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestNoIDispatch.h +41 -0
  963. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestNoIDispatch.rgs +23 -0
  964. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestProperties.cpp +256 -0
  965. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestProperties.h +88 -0
  966. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestProperties.rgs +23 -0
  967. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOff.cpp +23 -0
  968. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOff.h +43 -0
  969. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOff.rgs +23 -0
  970. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOn.cpp +29 -0
  971. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOn.h +45 -0
  972. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOn.rgs +23 -0
  973. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestWrappedJS.cpp +177 -0
  974. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestWrappedJS.h +50 -0
  975. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestWrappedJS.rgs +23 -0
  976. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/resource.h +36 -0
  977. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/Arrays/XPCIDispatchArrayTests.js +54 -0
  978. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/Attributes/XPCIDispatchAttributeTests.js +150 -0
  979. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/General/XPCIDispatchInstantiations.js +122 -0
  980. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/General/XPCStress.js +58 -0
  981. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/Methods/XPCIDispatchMethodTests.js +376 -0
  982. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/shell.js +377 -0
  983. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedJS/General/XPCIDispatchTestWrappedJS.js +76 -0
  984. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedJS/shell.js +377 -0
  985. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/exectests.cmd +1 -0
  986. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/jsDriver.pl +1288 -0
  987. data/vendor/tracemonkey/xpconnect/tests/idl/Makefile.in +61 -0
  988. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest.idl +312 -0
  989. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest2.idl +51 -0
  990. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_attributes.idl +67 -0
  991. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_calljs.idl +59 -0
  992. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_const.idl +61 -0
  993. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_domstring.idl +59 -0
  994. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_in.idl +88 -0
  995. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_inout.idl +86 -0
  996. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_multiple.idl +77 -0
  997. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_out.idl +142 -0
  998. data/vendor/tracemonkey/xpconnect/tests/js/checkid.js +82 -0
  999. data/vendor/tracemonkey/xpconnect/tests/js/evaluate.js +311 -0
  1000. data/vendor/tracemonkey/xpconnect/tests/js/exceptions-2.js +153 -0
  1001. data/vendor/tracemonkey/xpconnect/tests/js/exceptions-3.js +194 -0
  1002. data/vendor/tracemonkey/xpconnect/tests/js/exceptions-4.js +297 -0
  1003. data/vendor/tracemonkey/xpconnect/tests/js/exceptions-5.js +343 -0
  1004. data/vendor/tracemonkey/xpconnect/tests/js/exceptions.js +230 -0
  1005. data/vendor/tracemonkey/xpconnect/tests/js/javascript.js +96 -0
  1006. data/vendor/tracemonkey/xpconnect/tests/js/multiple-2.js +151 -0
  1007. data/vendor/tracemonkey/xpconnect/tests/js/multiple-3.js +148 -0
  1008. data/vendor/tracemonkey/xpconnect/tests/js/multiple-4.js +152 -0
  1009. data/vendor/tracemonkey/xpconnect/tests/js/multiple.js +137 -0
  1010. data/vendor/tracemonkey/xpconnect/tests/js/notscriptable.js +104 -0
  1011. data/vendor/tracemonkey/xpconnect/tests/js/old/simpletest.js +36 -0
  1012. data/vendor/tracemonkey/xpconnect/tests/js/old/speed.js +60 -0
  1013. data/vendor/tracemonkey/xpconnect/tests/js/old/testxpc.js +464 -0
  1014. data/vendor/tracemonkey/xpconnect/tests/js/old/threads.js +74 -0
  1015. data/vendor/tracemonkey/xpconnect/tests/js/old/try.js +27 -0
  1016. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_array.js +308 -0
  1017. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_callcontext.js +68 -0
  1018. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_echo.js +636 -0
  1019. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_enum_and_sort.js +28 -0
  1020. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_enum_constants.js +15 -0
  1021. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_enum_create.js +200 -0
  1022. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_exceptions.js +167 -0
  1023. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_ids.js +135 -0
  1024. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_observer.js +36 -0
  1025. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_overloaded.js +14 -0
  1026. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_primitives.js +141 -0
  1027. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_propertybag.js +36 -0
  1028. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_variant.js +339 -0
  1029. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_variant_array.js +30 -0
  1030. data/vendor/tracemonkey/xpconnect/tests/js/readonlyattributes.js +74 -0
  1031. data/vendor/tracemonkey/xpconnect/tests/js/readwriteattributes.js +101 -0
  1032. data/vendor/tracemonkey/xpconnect/tests/js/scriptable.js +120 -0
  1033. data/vendor/tracemonkey/xpconnect/tests/js/testin.js +203 -0
  1034. data/vendor/tracemonkey/xpconnect/tests/js/xpcfun.js +234 -0
  1035. data/vendor/tracemonkey/xpconnect/tests/js/xpctest_primitives.js +200 -0
  1036. data/vendor/tracemonkey/xpconnect/tests/mochitest/Makefile.in +66 -0
  1037. data/vendor/tracemonkey/xpconnect/tests/mochitest/bug500931_helper.html +7 -0
  1038. data/vendor/tracemonkey/xpconnect/tests/mochitest/inner.html +7 -0
  1039. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug361111.xul +29 -0
  1040. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug384632.html +32 -0
  1041. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug390488.html +65 -0
  1042. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug393269.html +46 -0
  1043. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug396851.html +43 -0
  1044. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug428021.html +41 -0
  1045. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug446584.html +49 -0
  1046. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug448587.html +31 -0
  1047. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug462428.html +42 -0
  1048. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug478438.html +66 -0
  1049. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug484107.html +100 -0
  1050. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug484459.html +36 -0
  1051. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug500691.html +28 -0
  1052. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_wrappers.html +116 -0
  1053. data/vendor/tracemonkey/xpconnect/tests/unit/bogus_element_type.jsm +1 -0
  1054. data/vendor/tracemonkey/xpconnect/tests/unit/bogus_exports_type.jsm +1 -0
  1055. data/vendor/tracemonkey/xpconnect/tests/unit/bug451678_subscript.js +2 -0
  1056. data/vendor/tracemonkey/xpconnect/tests/unit/component_import.js +144 -0
  1057. data/vendor/tracemonkey/xpconnect/tests/unit/recursive_importA.jsm +44 -0
  1058. data/vendor/tracemonkey/xpconnect/tests/unit/recursive_importB.jsm +45 -0
  1059. data/vendor/tracemonkey/xpconnect/tests/unit/syntax_error.jsm +1 -0
  1060. data/vendor/tracemonkey/xpconnect/tests/unit/test_bogus_files.js +88 -0
  1061. data/vendor/tracemonkey/xpconnect/tests/unit/test_bug408412.js +51 -0
  1062. data/vendor/tracemonkey/xpconnect/tests/unit/test_bug451678.js +52 -0
  1063. data/vendor/tracemonkey/xpconnect/tests/unit/test_bug_442086.js +68 -0
  1064. data/vendor/tracemonkey/xpconnect/tests/unit/test_import.js +127 -0
  1065. data/vendor/tracemonkey/xpconnect/tests/unit/test_js_weak_references.js +63 -0
  1066. data/vendor/tracemonkey/xpconnect/tests/unit/test_recursive_import.js +62 -0
  1067. data/vendor/tracemonkey/xpconnect/tools/Makefile.in +49 -0
  1068. data/vendor/tracemonkey/xpconnect/tools/idl/Makefile.in +53 -0
  1069. data/vendor/tracemonkey/xpconnect/tools/idl/nsIXPCToolsCompiler.idl +60 -0
  1070. data/vendor/tracemonkey/xpconnect/tools/idl/nsIXPCToolsProfiler.idl +57 -0
  1071. data/vendor/tracemonkey/xpconnect/tools/js/CompileJSFiles.js +28 -0
  1072. data/vendor/tracemonkey/xpconnect/tools/js/ListJSFiles.js +18 -0
  1073. data/vendor/tracemonkey/xpconnect/tools/src/Makefile.in +76 -0
  1074. data/vendor/tracemonkey/xpconnect/tools/src/nsXPCToolsCompiler.cpp +161 -0
  1075. data/vendor/tracemonkey/xpconnect/tools/src/nsXPCToolsModule.cpp +65 -0
  1076. data/vendor/tracemonkey/xpconnect/tools/src/nsXPCToolsProfiler.cpp +370 -0
  1077. data/vendor/tracemonkey/xpconnect/tools/src/xpctools_private.h +236 -0
  1078. metadata +1164 -0
@@ -0,0 +1,4719 @@
1
+ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2
+ * vim: set ts=8 sw=4 et tw=99:
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 shell.
43
+ */
44
+ #include "jsstddef.h"
45
+ #include <errno.h>
46
+ #include <math.h>
47
+ #include <stdio.h>
48
+ #include <stdlib.h>
49
+ #include <string.h>
50
+ #include <signal.h>
51
+ #include <locale.h>
52
+ #include "jstypes.h"
53
+ #include "jsarena.h"
54
+ #include "jsutil.h"
55
+ #include "jsprf.h"
56
+ #include "jsapi.h"
57
+ #include "jsarray.h"
58
+ #include "jsatom.h"
59
+ #include "jsbuiltins.h"
60
+ #include "jscntxt.h"
61
+ #include "jsdate.h"
62
+ #include "jsdbgapi.h"
63
+ #include "jsemit.h"
64
+ #include "jsfun.h"
65
+ #include "jsgc.h"
66
+ #include "jsiter.h"
67
+ #include "jslock.h"
68
+ #include "jsnum.h"
69
+ #include "jsobj.h"
70
+ #include "jsparse.h"
71
+ #include "jsscope.h"
72
+ #include "jsscript.h"
73
+
74
+ #include "prmjtime.h"
75
+
76
+ #ifdef LIVECONNECT
77
+ #include "jsjava.h"
78
+ #endif
79
+
80
+ #ifdef JSDEBUGGER
81
+ #include "jsdebug.h"
82
+ #ifdef JSDEBUGGER_JAVA_UI
83
+ #include "jsdjava.h"
84
+ #endif /* JSDEBUGGER_JAVA_UI */
85
+ #ifdef JSDEBUGGER_C_UI
86
+ #include "jsdb.h"
87
+ #endif /* JSDEBUGGER_C_UI */
88
+ #endif /* JSDEBUGGER */
89
+
90
+ #ifdef XP_UNIX
91
+ #include <unistd.h>
92
+ #include <sys/types.h>
93
+ #include <sys/wait.h>
94
+ #endif
95
+
96
+ #if defined(XP_WIN) || defined(XP_OS2)
97
+ #include <io.h> /* for isatty() */
98
+ #endif
99
+
100
+ typedef enum JSShellExitCode {
101
+ EXITCODE_RUNTIME_ERROR = 3,
102
+ EXITCODE_FILE_NOT_FOUND = 4,
103
+ EXITCODE_OUT_OF_MEMORY = 5,
104
+ EXITCODE_TIMEOUT = 6
105
+ } JSShellExitCode;
106
+
107
+ size_t gStackChunkSize = 8192;
108
+
109
+ /* Assume that we can not use more than 5e5 bytes of C stack by default. */
110
+ static size_t gMaxStackSize = 500000;
111
+
112
+ #ifdef JS_THREADSAFE
113
+ static PRUintn gStackBaseThreadIndex;
114
+ #else
115
+ static jsuword gStackBase;
116
+ #endif
117
+
118
+ static size_t gScriptStackQuota = JS_DEFAULT_SCRIPT_STACK_QUOTA;
119
+
120
+ /*
121
+ * Limit the timeout to 30 minutes to prevent an overflow on platfoms
122
+ * that represent the time internally in microseconds using 32-bit int.
123
+ */
124
+ static jsdouble MAX_TIMEOUT_INTERVAL = 1800.0;
125
+ static jsdouble gTimeoutInterval = -1.0;
126
+ static volatile bool gCanceled = false;
127
+
128
+ static JSBool
129
+ SetTimeoutValue(JSContext *cx, jsdouble t);
130
+
131
+ static bool
132
+ InitWatchdog(JSRuntime *rt);
133
+
134
+ static void
135
+ KillWatchdog();
136
+
137
+ static bool
138
+ ScheduleWatchdog(JSRuntime *rt, jsdouble t);
139
+
140
+ static void
141
+ CancelExecution(JSRuntime *rt);
142
+
143
+ /*
144
+ * Watchdog thread state.
145
+ */
146
+ #ifdef JS_THREADSAFE
147
+
148
+ static PRLock *gWatchdogLock = NULL;
149
+ static PRCondVar *gWatchdogWakeup = NULL;
150
+ static PRThread *gWatchdogThread = NULL;
151
+ static bool gWatchdogHasTimeout = false;
152
+ static PRIntervalTime gWatchdogTimeout = 0;
153
+
154
+ static PRCondVar *gSleepWakeup = NULL;
155
+
156
+ /*
157
+ * Holding the gcLock already guarantees that the context list is locked when
158
+ * the watchdog thread walks it.
159
+ */
160
+
161
+ #define WITH_LOCKED_CONTEXT_LIST(x) \
162
+ JS_BEGIN_MACRO \
163
+ x; \
164
+ JS_END_MACRO
165
+
166
+ #else
167
+
168
+ static JSRuntime *gRuntime = NULL;
169
+
170
+ /*
171
+ * Since signal handlers can't block, we must disable them before manipulating
172
+ * the context list.
173
+ */
174
+ #define WITH_LOCKED_CONTEXT_LIST(x) \
175
+ JS_BEGIN_MACRO \
176
+ ScheduleWatchdog(gRuntime, -1); \
177
+ x; \
178
+ ScheduleWatchdog(gRuntime, gTimeoutInterval); \
179
+ JS_END_MACRO
180
+ #endif
181
+
182
+ int gExitCode = 0;
183
+ JSBool gQuitting = JS_FALSE;
184
+ FILE *gErrFile = NULL;
185
+ FILE *gOutFile = NULL;
186
+
187
+ static JSBool reportWarnings = JS_TRUE;
188
+ static JSBool compileOnly = JS_FALSE;
189
+
190
+ typedef enum JSShellErrNum {
191
+ #define MSG_DEF(name, number, count, exception, format) \
192
+ name = number,
193
+ #include "jsshell.msg"
194
+ #undef MSG_DEF
195
+ JSShellErr_Limit
196
+ #undef MSGDEF
197
+ } JSShellErrNum;
198
+
199
+ static const JSErrorFormatString *
200
+ my_GetErrorMessage(void *userRef, const char *locale, const uintN errorNumber);
201
+ static JSObject *
202
+ split_setup(JSContext *cx);
203
+
204
+ #ifdef EDITLINE
205
+ JS_BEGIN_EXTERN_C
206
+ JS_EXTERN_API(char) *readline(const char *prompt);
207
+ JS_EXTERN_API(void) add_history(char *line);
208
+ JS_END_EXTERN_C
209
+ #endif
210
+
211
+ static char *
212
+ GetLine(FILE *file, const char * prompt)
213
+ {
214
+ size_t size;
215
+ char *buffer;
216
+ #ifdef EDITLINE
217
+ /*
218
+ * Use readline only if file is stdin, because there's no way to specify
219
+ * another handle. Are other filehandles interactive?
220
+ */
221
+ if (file == stdin) {
222
+ char *linep = readline(prompt);
223
+ /*
224
+ * We set it to zero to avoid complaining about inappropriate ioctl
225
+ * for device in the case of EOF. Looks like errno == 251 if line is
226
+ * finished with EOF and errno == 25 (EINVAL on Mac) if there is
227
+ * nothing left to read.
228
+ */
229
+ if (errno == 251 || errno == 25 || errno == EINVAL)
230
+ errno = 0;
231
+ if (!linep)
232
+ return NULL;
233
+ if (linep[0] != '\0')
234
+ add_history(linep);
235
+ return linep;
236
+ }
237
+ #endif
238
+ size_t len = 0;
239
+ if (*prompt != '\0') {
240
+ fprintf(gOutFile, "%s", prompt);
241
+ fflush(gOutFile);
242
+ }
243
+ size = 80;
244
+ buffer = (char *) malloc(size);
245
+ if (!buffer)
246
+ return NULL;
247
+ char *current = buffer;
248
+ while (fgets(current, size - len, file)) {
249
+ len += strlen(current);
250
+ char *t = buffer + len - 1;
251
+ if (*t == '\n') {
252
+ /* Line was read. We remove '\n' and exit. */
253
+ *t = '\0';
254
+ return buffer;
255
+ }
256
+ if (len + 1 == size) {
257
+ size = size * 2;
258
+ char *tmp = (char *) realloc(buffer, size);
259
+ if (!tmp) {
260
+ free(buffer);
261
+ return NULL;
262
+ }
263
+ buffer = tmp;
264
+ }
265
+ current = buffer + len;
266
+ }
267
+ if (len && !ferror(file))
268
+ return buffer;
269
+ free(buffer);
270
+ return NULL;
271
+ }
272
+
273
+ /*
274
+ * State to store as JSContext private.
275
+ *
276
+ * We declare such timestamp as volatile as they are updated in the operation
277
+ * callback without taking any locks. Any possible race can only lead to more
278
+ * frequent callback calls. This is safe as the callback does everything based
279
+ * on timing.
280
+ */
281
+ struct JSShellContextData {
282
+ volatile JSIntervalTime startTime;
283
+ };
284
+
285
+ static JSShellContextData *
286
+ NewContextData()
287
+ {
288
+ /* Prevent creation of new contexts after we have been canceled. */
289
+ if (gCanceled)
290
+ return NULL;
291
+
292
+ JSShellContextData *data = (JSShellContextData *)
293
+ calloc(sizeof(JSShellContextData), 1);
294
+ if (!data)
295
+ return NULL;
296
+ data->startTime = js_IntervalNow();
297
+ return data;
298
+ }
299
+
300
+ static inline JSShellContextData *
301
+ GetContextData(JSContext *cx)
302
+ {
303
+ JSShellContextData *data = (JSShellContextData *) JS_GetContextPrivate(cx);
304
+
305
+ JS_ASSERT(data);
306
+ return data;
307
+ }
308
+
309
+ static JSBool
310
+ ShellOperationCallback(JSContext *cx)
311
+ {
312
+ if (!gCanceled)
313
+ return JS_TRUE;
314
+
315
+ JS_ClearPendingException(cx);
316
+ return JS_FALSE;
317
+ }
318
+
319
+ static void
320
+ SetThreadStackLimit(JSContext *cx)
321
+ {
322
+ jsuword stackLimit;
323
+
324
+ if (gMaxStackSize == 0) {
325
+ /*
326
+ * Disable checking for stack overflow if limit is zero.
327
+ */
328
+ stackLimit = 0;
329
+ } else {
330
+ jsuword stackBase;
331
+ #ifdef JS_THREADSAFE
332
+ stackBase = (jsuword) PR_GetThreadPrivate(gStackBaseThreadIndex);
333
+ #else
334
+ stackBase = gStackBase;
335
+ #endif
336
+ JS_ASSERT(stackBase != 0);
337
+ #if JS_STACK_GROWTH_DIRECTION > 0
338
+ stackLimit = stackBase + gMaxStackSize;
339
+ #else
340
+ stackLimit = stackBase - gMaxStackSize;
341
+ #endif
342
+ }
343
+ JS_SetThreadStackLimit(cx, stackLimit);
344
+
345
+ }
346
+
347
+ static void
348
+ SetContextOptions(JSContext *cx)
349
+ {
350
+ SetThreadStackLimit(cx);
351
+ JS_SetScriptStackQuota(cx, gScriptStackQuota);
352
+ JS_SetOperationCallback(cx, ShellOperationCallback);
353
+ }
354
+
355
+ static void
356
+ Process(JSContext *cx, JSObject *obj, char *filename, JSBool forceTTY)
357
+ {
358
+ JSBool ok, hitEOF;
359
+ JSScript *script;
360
+ jsval result;
361
+ JSString *str;
362
+ char *buffer;
363
+ size_t size;
364
+ int lineno;
365
+ int startline;
366
+ FILE *file;
367
+ uint32 oldopts;
368
+
369
+ if (forceTTY || !filename || strcmp(filename, "-") == 0) {
370
+ file = stdin;
371
+ } else {
372
+ file = fopen(filename, "r");
373
+ if (!file) {
374
+ JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL,
375
+ JSSMSG_CANT_OPEN, filename, strerror(errno));
376
+ gExitCode = EXITCODE_FILE_NOT_FOUND;
377
+ return;
378
+ }
379
+ }
380
+
381
+ SetContextOptions(cx);
382
+
383
+ if (!forceTTY && !isatty(fileno(file))) {
384
+ /*
385
+ * It's not interactive - just execute it.
386
+ *
387
+ * Support the UNIX #! shell hack; gobble the first line if it starts
388
+ * with '#'. TODO - this isn't quite compatible with sharp variables,
389
+ * as a legal js program (using sharp variables) might start with '#'.
390
+ * But that would require multi-character lookahead.
391
+ */
392
+ int ch = fgetc(file);
393
+ if (ch == '#') {
394
+ while((ch = fgetc(file)) != EOF) {
395
+ if (ch == '\n' || ch == '\r')
396
+ break;
397
+ }
398
+ }
399
+ ungetc(ch, file);
400
+
401
+ oldopts = JS_GetOptions(cx);
402
+ JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO | JSOPTION_NO_SCRIPT_RVAL);
403
+ script = JS_CompileFileHandle(cx, obj, filename, file);
404
+ JS_SetOptions(cx, oldopts);
405
+ if (script) {
406
+ if (!compileOnly)
407
+ (void)JS_ExecuteScript(cx, obj, script, NULL);
408
+ JS_DestroyScript(cx, script);
409
+ }
410
+
411
+ if (file != stdin)
412
+ fclose(file);
413
+ return;
414
+ }
415
+
416
+ /* It's an interactive filehandle; drop into read-eval-print loop. */
417
+ lineno = 1;
418
+ hitEOF = JS_FALSE;
419
+ buffer = NULL;
420
+ do {
421
+ /*
422
+ * Accumulate lines until we get a 'compilable unit' - one that either
423
+ * generates an error (before running out of source) or that compiles
424
+ * cleanly. This should be whenever we get a complete statement that
425
+ * coincides with the end of a line.
426
+ */
427
+ startline = lineno;
428
+ size_t len = 0; /* initialize to avoid warnings */
429
+ do {
430
+ ScheduleWatchdog(cx->runtime, -1);
431
+ jsrefcount rc = JS_SuspendRequest(cx);
432
+ gCanceled = false;
433
+ errno = 0;
434
+ char *line = GetLine(file, startline == lineno ? "js> " : "");
435
+ if (!line) {
436
+ JS_ResumeRequest(cx, rc);
437
+ if (errno) {
438
+ JS_ReportError(cx, strerror(errno));
439
+ free(buffer);
440
+ return;
441
+ }
442
+ hitEOF = JS_TRUE;
443
+ break;
444
+ }
445
+ if (!buffer) {
446
+ buffer = line;
447
+ len = strlen(buffer);
448
+ size = len + 1;
449
+ } else {
450
+ /*
451
+ * len + 1 is required to store '\n' in the end of line.
452
+ */
453
+ size_t newlen = strlen(line) + (len ? len + 1 : 0);
454
+ if (newlen + 1 > size) {
455
+ size = newlen + 1 > size * 2 ? newlen + 1 : size * 2;
456
+ char *newBuf = (char *) realloc(buffer, size);
457
+ if (!newBuf) {
458
+ free(buffer);
459
+ free(line);
460
+ JS_ResumeRequest(cx, rc);
461
+ JS_ReportOutOfMemory(cx);
462
+ return;
463
+ }
464
+ buffer = newBuf;
465
+ }
466
+ char *current = buffer + len;
467
+ if (startline != lineno)
468
+ *current++ = '\n';
469
+ strcpy(current, line);
470
+ len = newlen;
471
+ free(line);
472
+ }
473
+ lineno++;
474
+ JS_ResumeRequest(cx, rc);
475
+ if (!ScheduleWatchdog(cx->runtime, gTimeoutInterval)) {
476
+ hitEOF = JS_TRUE;
477
+ break;
478
+ }
479
+ } while (!JS_BufferIsCompilableUnit(cx, obj, buffer, len));
480
+
481
+ if (hitEOF && !buffer)
482
+ break;
483
+
484
+ /* Clear any pending exception from previous failed compiles. */
485
+ JS_ClearPendingException(cx);
486
+
487
+ /* Even though we're interactive, we have a compile-n-go opportunity. */
488
+ oldopts = JS_GetOptions(cx);
489
+ if (!compileOnly)
490
+ JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO);
491
+ script = JS_CompileScript(cx, obj, buffer, len, "typein",
492
+ startline);
493
+ if (!compileOnly)
494
+ JS_SetOptions(cx, oldopts);
495
+
496
+ if (script) {
497
+ if (!compileOnly) {
498
+ ok = JS_ExecuteScript(cx, obj, script, &result);
499
+ if (ok && !JSVAL_IS_VOID(result)) {
500
+ str = JS_ValueToString(cx, result);
501
+ if (str)
502
+ fprintf(gOutFile, "%s\n", JS_GetStringBytes(str));
503
+ else
504
+ ok = JS_FALSE;
505
+ }
506
+ }
507
+ JS_DestroyScript(cx, script);
508
+ }
509
+ *buffer = '\0';
510
+ } while (!hitEOF && !gQuitting);
511
+
512
+ free(buffer);
513
+ fprintf(gOutFile, "\n");
514
+ if (file != stdin)
515
+ fclose(file);
516
+ return;
517
+ }
518
+
519
+ static int
520
+ usage(void)
521
+ {
522
+ fprintf(gErrFile, "%s\n", JS_GetImplementationVersion());
523
+ fprintf(gErrFile, "usage: js [-zKPswWxCij] [-t timeoutSeconds] [-c stackchunksize] [-o option] [-v version] [-f scriptfile] [-e script] [-S maxstacksize] "
524
+ #ifdef JS_GC_ZEAL
525
+ "[-Z gczeal] "
526
+ #endif
527
+ "[scriptfile] [scriptarg...]\n");
528
+ return 2;
529
+ }
530
+
531
+ static struct {
532
+ const char *name;
533
+ uint32 flag;
534
+ } js_options[] = {
535
+ {"strict", JSOPTION_STRICT},
536
+ {"werror", JSOPTION_WERROR},
537
+ {"atline", JSOPTION_ATLINE},
538
+ {"xml", JSOPTION_XML},
539
+ {"relimit", JSOPTION_RELIMIT},
540
+ {"anonfunfix", JSOPTION_ANONFUNFIX},
541
+ {"jit", JSOPTION_JIT},
542
+ {NULL, 0}
543
+ };
544
+
545
+ extern JSClass global_class;
546
+
547
+ static int
548
+ ProcessArgs(JSContext *cx, JSObject *obj, char **argv, int argc)
549
+ {
550
+ int i, j, length;
551
+ JSObject *argsObj;
552
+ char *filename = NULL;
553
+ JSBool isInteractive = JS_TRUE;
554
+ JSBool forceTTY = JS_FALSE;
555
+
556
+ /*
557
+ * Scan past all optional arguments so we can create the arguments object
558
+ * before processing any -f options, which must interleave properly with
559
+ * -v and -w options. This requires two passes, and without getopt, we'll
560
+ * have to keep the option logic here and in the second for loop in sync.
561
+ */
562
+ for (i = 0; i < argc; i++) {
563
+ if (argv[i][0] != '-' || argv[i][1] == '\0') {
564
+ ++i;
565
+ break;
566
+ }
567
+ switch (argv[i][1]) {
568
+ case 'c':
569
+ case 'f':
570
+ case 'e':
571
+ case 'v':
572
+ case 'S':
573
+ case 't':
574
+ #ifdef JS_GC_ZEAL
575
+ case 'Z':
576
+ #endif
577
+ ++i;
578
+ break;
579
+ default:;
580
+ }
581
+ }
582
+
583
+ /*
584
+ * Create arguments early and define it to root it, so it's safe from any
585
+ * GC calls nested below, and so it is available to -f <file> arguments.
586
+ */
587
+ argsObj = JS_NewArrayObject(cx, 0, NULL);
588
+ if (!argsObj)
589
+ return 1;
590
+ if (!JS_DefineProperty(cx, obj, "arguments", OBJECT_TO_JSVAL(argsObj),
591
+ NULL, NULL, 0)) {
592
+ return 1;
593
+ }
594
+
595
+ length = argc - i;
596
+ for (j = 0; j < length; j++) {
597
+ JSString *str = JS_NewStringCopyZ(cx, argv[i++]);
598
+ if (!str)
599
+ return 1;
600
+ if (!JS_DefineElement(cx, argsObj, j, STRING_TO_JSVAL(str),
601
+ NULL, NULL, JSPROP_ENUMERATE)) {
602
+ return 1;
603
+ }
604
+ }
605
+
606
+ for (i = 0; i < argc; i++) {
607
+ if (argv[i][0] != '-' || argv[i][1] == '\0') {
608
+ filename = argv[i++];
609
+ isInteractive = JS_FALSE;
610
+ break;
611
+ }
612
+
613
+ switch (argv[i][1]) {
614
+ case 'v':
615
+ if (++i == argc)
616
+ return usage();
617
+
618
+ JS_SetVersion(cx, (JSVersion) atoi(argv[i]));
619
+ break;
620
+
621
+ #ifdef JS_GC_ZEAL
622
+ case 'Z':
623
+ if (++i == argc)
624
+ return usage();
625
+ JS_SetGCZeal(cx, atoi(argv[i]));
626
+ break;
627
+ #endif
628
+
629
+ case 'w':
630
+ reportWarnings = JS_TRUE;
631
+ break;
632
+
633
+ case 'W':
634
+ reportWarnings = JS_FALSE;
635
+ break;
636
+
637
+ case 's':
638
+ JS_ToggleOptions(cx, JSOPTION_STRICT);
639
+ break;
640
+
641
+ case 'E':
642
+ JS_ToggleOptions(cx, JSOPTION_RELIMIT);
643
+ break;
644
+
645
+ case 'x':
646
+ JS_ToggleOptions(cx, JSOPTION_XML);
647
+ break;
648
+
649
+ case 'j':
650
+ JS_ToggleOptions(cx, JSOPTION_JIT);
651
+ #if defined(JS_TRACER) && defined(DEBUG)
652
+ extern struct JSClass jitstats_class;
653
+ extern void js_InitJITStatsClass(JSContext *cx, JSObject *glob);
654
+ js_InitJITStatsClass(cx, JS_GetGlobalObject(cx));
655
+ JS_DefineObject(cx, JS_GetGlobalObject(cx), "tracemonkey",
656
+ &jitstats_class, NULL, 0);
657
+ #endif
658
+ break;
659
+
660
+ case 'o':
661
+ if (++i == argc)
662
+ return usage();
663
+
664
+ for (j = 0; js_options[j].name; ++j) {
665
+ if (strcmp(js_options[j].name, argv[i]) == 0) {
666
+ JS_ToggleOptions(cx, js_options[j].flag);
667
+ break;
668
+ }
669
+ }
670
+ break;
671
+
672
+ case 'P':
673
+ if (JS_GET_CLASS(cx, JS_GetPrototype(cx, obj)) != &global_class) {
674
+ JSObject *gobj;
675
+
676
+ if (!JS_SealObject(cx, obj, JS_TRUE))
677
+ return JS_FALSE;
678
+ gobj = JS_NewObject(cx, &global_class, NULL, NULL);
679
+ if (!gobj)
680
+ return JS_FALSE;
681
+ if (!JS_SetPrototype(cx, gobj, obj))
682
+ return JS_FALSE;
683
+ JS_SetParent(cx, gobj, NULL);
684
+ JS_SetGlobalObject(cx, gobj);
685
+ obj = gobj;
686
+ }
687
+ break;
688
+
689
+ case 't':
690
+ if (++i == argc)
691
+ return usage();
692
+
693
+ if (!SetTimeoutValue(cx, atof(argv[i])))
694
+ return JS_FALSE;
695
+
696
+ break;
697
+
698
+ case 'c':
699
+ /* set stack chunk size */
700
+ gStackChunkSize = atoi(argv[++i]);
701
+ break;
702
+
703
+ case 'f':
704
+ if (++i == argc)
705
+ return usage();
706
+
707
+ Process(cx, obj, argv[i], JS_FALSE);
708
+ if (gExitCode != 0)
709
+ return gExitCode;
710
+
711
+ /*
712
+ * XXX: js -f foo.js should interpret foo.js and then
713
+ * drop into interactive mode, but that breaks the test
714
+ * harness. Just execute foo.js for now.
715
+ */
716
+ isInteractive = JS_FALSE;
717
+ break;
718
+
719
+ case 'e':
720
+ {
721
+ jsval rval;
722
+
723
+ if (++i == argc)
724
+ return usage();
725
+
726
+ /* Pass a filename of -e to imitate PERL */
727
+ JS_EvaluateScript(cx, obj, argv[i], strlen(argv[i]),
728
+ "-e", 1, &rval);
729
+
730
+ isInteractive = JS_FALSE;
731
+ break;
732
+
733
+ }
734
+ case 'C':
735
+ compileOnly = JS_TRUE;
736
+ isInteractive = JS_FALSE;
737
+ break;
738
+
739
+ case 'i':
740
+ isInteractive = forceTTY = JS_TRUE;
741
+ break;
742
+
743
+ case 'S':
744
+ if (++i == argc)
745
+ return usage();
746
+
747
+ /* Set maximum stack size. */
748
+ gMaxStackSize = atoi(argv[i]);
749
+ break;
750
+
751
+ case 'z':
752
+ obj = split_setup(cx);
753
+ if (!obj)
754
+ return gExitCode;
755
+ break;
756
+ #ifdef MOZ_SHARK
757
+ case 'k':
758
+ JS_ConnectShark();
759
+ break;
760
+ #endif
761
+ default:
762
+ return usage();
763
+ }
764
+ }
765
+
766
+ if (filename || isInteractive)
767
+ Process(cx, obj, filename, forceTTY);
768
+ return gExitCode;
769
+ }
770
+
771
+ static JSBool
772
+ Version(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
773
+ {
774
+ if (argc > 0 && JSVAL_IS_INT(argv[0]))
775
+ *rval = INT_TO_JSVAL(JS_SetVersion(cx, (JSVersion) JSVAL_TO_INT(argv[0])));
776
+ else
777
+ *rval = INT_TO_JSVAL(JS_GetVersion(cx));
778
+ return JS_TRUE;
779
+ }
780
+
781
+ static JSBool
782
+ Options(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
783
+ {
784
+ uint32 optset, flag;
785
+ uintN i, j, found;
786
+ JSString *str;
787
+ const char *opt;
788
+ char *names;
789
+
790
+ optset = 0;
791
+ for (i = 0; i < argc; i++) {
792
+ str = JS_ValueToString(cx, argv[i]);
793
+ if (!str)
794
+ return JS_FALSE;
795
+ opt = JS_GetStringBytes(str);
796
+ for (j = 0; js_options[j].name; j++) {
797
+ if (strcmp(js_options[j].name, opt) == 0) {
798
+ optset |= js_options[j].flag;
799
+ break;
800
+ }
801
+ }
802
+ }
803
+ optset = JS_ToggleOptions(cx, optset);
804
+
805
+ names = NULL;
806
+ found = 0;
807
+ while (optset != 0) {
808
+ flag = optset;
809
+ optset &= optset - 1;
810
+ flag &= ~optset;
811
+ for (j = 0; js_options[j].name; j++) {
812
+ if (js_options[j].flag == flag) {
813
+ names = JS_sprintf_append(names, "%s%s",
814
+ names ? "," : "", js_options[j].name);
815
+ found++;
816
+ break;
817
+ }
818
+ }
819
+ }
820
+ if (!found)
821
+ names = strdup("");
822
+ if (!names) {
823
+ JS_ReportOutOfMemory(cx);
824
+ return JS_FALSE;
825
+ }
826
+
827
+ str = JS_NewString(cx, names, strlen(names));
828
+ if (!str) {
829
+ free(names);
830
+ return JS_FALSE;
831
+ }
832
+ *rval = STRING_TO_JSVAL(str);
833
+ return JS_TRUE;
834
+ }
835
+
836
+ static JSBool
837
+ Load(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
838
+ {
839
+ uintN i;
840
+ JSString *str;
841
+ const char *filename;
842
+ JSScript *script;
843
+ JSBool ok;
844
+ uint32 oldopts;
845
+
846
+ for (i = 0; i < argc; i++) {
847
+ str = JS_ValueToString(cx, argv[i]);
848
+ if (!str)
849
+ return JS_FALSE;
850
+ argv[i] = STRING_TO_JSVAL(str);
851
+ filename = JS_GetStringBytes(str);
852
+ errno = 0;
853
+ oldopts = JS_GetOptions(cx);
854
+ JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO | JSOPTION_NO_SCRIPT_RVAL);
855
+ script = JS_CompileFile(cx, obj, filename);
856
+ JS_SetOptions(cx, oldopts);
857
+ if (!script) {
858
+ ok = JS_FALSE;
859
+ } else {
860
+ ok = !compileOnly
861
+ ? JS_ExecuteScript(cx, obj, script, NULL)
862
+ : JS_TRUE;
863
+ JS_DestroyScript(cx, script);
864
+ }
865
+ if (!ok)
866
+ return JS_FALSE;
867
+ }
868
+
869
+ return JS_TRUE;
870
+ }
871
+
872
+ /*
873
+ * function readline()
874
+ * Provides a hook for scripts to read a line from stdin.
875
+ */
876
+ static JSBool
877
+ ReadLine(JSContext *cx, uintN argc, jsval *vp)
878
+ {
879
+ #define BUFSIZE 256
880
+ FILE *from;
881
+ char *buf, *tmp;
882
+ size_t bufsize, buflength, gotlength;
883
+ JSBool sawNewline;
884
+ JSString *str;
885
+
886
+ from = stdin;
887
+ buflength = 0;
888
+ bufsize = BUFSIZE;
889
+ buf = (char *) JS_malloc(cx, bufsize);
890
+ if (!buf)
891
+ return JS_FALSE;
892
+
893
+ sawNewline = JS_FALSE;
894
+ while ((gotlength =
895
+ js_fgets(buf + buflength, bufsize - buflength, from)) > 0) {
896
+ buflength += gotlength;
897
+
898
+ /* Are we done? */
899
+ if (buf[buflength - 1] == '\n') {
900
+ buf[buflength - 1] = '\0';
901
+ sawNewline = JS_TRUE;
902
+ break;
903
+ } else if (buflength < bufsize - 1) {
904
+ break;
905
+ }
906
+
907
+ /* Else, grow our buffer for another pass. */
908
+ bufsize *= 2;
909
+ if (bufsize > buflength) {
910
+ tmp = (char *) JS_realloc(cx, buf, bufsize);
911
+ } else {
912
+ JS_ReportOutOfMemory(cx);
913
+ tmp = NULL;
914
+ }
915
+
916
+ if (!tmp) {
917
+ JS_free(cx, buf);
918
+ return JS_FALSE;
919
+ }
920
+
921
+ buf = tmp;
922
+ }
923
+
924
+ /* Treat the empty string specially. */
925
+ if (buflength == 0) {
926
+ *vp = feof(from) ? JSVAL_NULL : JS_GetEmptyStringValue(cx);
927
+ JS_free(cx, buf);
928
+ return JS_TRUE;
929
+ }
930
+
931
+ /* Shrink the buffer to the real size. */
932
+ tmp = (char *) JS_realloc(cx, buf, buflength);
933
+ if (!tmp) {
934
+ JS_free(cx, buf);
935
+ return JS_FALSE;
936
+ }
937
+
938
+ buf = tmp;
939
+
940
+ /*
941
+ * Turn buf into a JSString. Note that buflength includes the trailing null
942
+ * character.
943
+ */
944
+ str = JS_NewString(cx, buf, sawNewline ? buflength - 1 : buflength);
945
+ if (!str) {
946
+ JS_free(cx, buf);
947
+ return JS_FALSE;
948
+ }
949
+
950
+ *vp = STRING_TO_JSVAL(str);
951
+ return JS_TRUE;
952
+ }
953
+
954
+ static JSBool
955
+ Print(JSContext *cx, uintN argc, jsval *vp)
956
+ {
957
+ jsval *argv;
958
+ uintN i;
959
+ JSString *str;
960
+ char *bytes;
961
+
962
+ argv = JS_ARGV(cx, vp);
963
+ for (i = 0; i < argc; i++) {
964
+ str = JS_ValueToString(cx, argv[i]);
965
+ if (!str)
966
+ return JS_FALSE;
967
+ bytes = JS_EncodeString(cx, str);
968
+ if (!bytes)
969
+ return JS_FALSE;
970
+ fprintf(gOutFile, "%s%s", i ? " " : "", bytes);
971
+ JS_free(cx, bytes);
972
+ }
973
+
974
+ fputc('\n', gOutFile);
975
+ fflush(gOutFile);
976
+
977
+ JS_SET_RVAL(cx, vp, JSVAL_VOID);
978
+ return JS_TRUE;
979
+ }
980
+
981
+ static JSBool
982
+ Help(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
983
+
984
+ static JSBool
985
+ Quit(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
986
+ {
987
+ #ifdef LIVECONNECT
988
+ JSJ_SimpleShutdown();
989
+ #endif
990
+
991
+ JS_ConvertArguments(cx, argc, argv,"/ i", &gExitCode);
992
+
993
+ gQuitting = JS_TRUE;
994
+ return JS_FALSE;
995
+ }
996
+
997
+ static const char *
998
+ ToSource(JSContext *cx, jsval *vp)
999
+ {
1000
+ JSString *str = JS_ValueToSource(cx, *vp);
1001
+ if (str) {
1002
+ *vp = STRING_TO_JSVAL(str);
1003
+ return JS_GetStringBytes(str);
1004
+ }
1005
+ JS_ClearPendingException(cx);
1006
+ return "<<error converting value to string>>";
1007
+ }
1008
+
1009
+ static JSBool
1010
+ AssertEq(JSContext *cx, uintN argc, jsval *vp)
1011
+ {
1012
+ if (argc != 2) {
1013
+ JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL,
1014
+ (argc > 2) ? JSSMSG_TOO_MANY_ARGS : JSSMSG_NOT_ENOUGH_ARGS,
1015
+ "assertEq");
1016
+ return JS_FALSE;
1017
+ }
1018
+
1019
+ jsval *argv = JS_ARGV(cx, vp);
1020
+ if (!js_StrictlyEqual(cx, argv[0], argv[1])) {
1021
+ const char *actual = ToSource(cx, &argv[0]);
1022
+ const char *expected = ToSource(cx, &argv[1]);
1023
+ JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL, JSSMSG_ASSERT_EQ_FAILED,
1024
+ actual, expected);
1025
+ return JS_FALSE;
1026
+ }
1027
+ JS_SET_RVAL(cx, vp, JSVAL_VOID);
1028
+ return JS_TRUE;
1029
+ }
1030
+
1031
+ static JSBool
1032
+ GC(JSContext *cx, uintN argc, jsval *vp)
1033
+ {
1034
+ JSRuntime *rt;
1035
+ uint32 preBytes;
1036
+
1037
+ rt = cx->runtime;
1038
+ preBytes = rt->gcBytes;
1039
+ JS_GC(cx);
1040
+
1041
+ char buf[256];
1042
+ JS_snprintf(buf, sizeof(buf), "before %lu, after %lu, break %08lx\n",
1043
+ (unsigned long)preBytes, (unsigned long)rt->gcBytes,
1044
+ #ifdef XP_UNIX
1045
+ (unsigned long)sbrk(0)
1046
+ #else
1047
+ 0
1048
+ #endif
1049
+ );
1050
+ #ifdef JS_GCMETER
1051
+ js_DumpGCStats(rt, stdout);
1052
+ #endif
1053
+ *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, buf));
1054
+ return JS_TRUE;
1055
+ }
1056
+
1057
+ static JSBool
1058
+ GCParameter(JSContext *cx, uintN argc, jsval *vp)
1059
+ {
1060
+ JSString *str;
1061
+ const char *paramName;
1062
+ JSGCParamKey param;
1063
+ uint32 value;
1064
+
1065
+ if (argc == 0) {
1066
+ str = JS_ValueToString(cx, JSVAL_VOID);
1067
+ JS_ASSERT(str);
1068
+ } else {
1069
+ str = JS_ValueToString(cx, vp[2]);
1070
+ if (!str)
1071
+ return JS_FALSE;
1072
+ vp[2] = STRING_TO_JSVAL(str);
1073
+ }
1074
+ paramName = JS_GetStringBytes(str);
1075
+ if (!paramName)
1076
+ return JS_FALSE;
1077
+ if (strcmp(paramName, "maxBytes") == 0) {
1078
+ param = JSGC_MAX_BYTES;
1079
+ } else if (strcmp(paramName, "maxMallocBytes") == 0) {
1080
+ param = JSGC_MAX_MALLOC_BYTES;
1081
+ } else if (strcmp(paramName, "gcStackpoolLifespan") == 0) {
1082
+ param = JSGC_STACKPOOL_LIFESPAN;
1083
+ } else if (strcmp(paramName, "gcBytes") == 0) {
1084
+ param = JSGC_BYTES;
1085
+ } else if (strcmp(paramName, "gcNumber") == 0) {
1086
+ param = JSGC_NUMBER;
1087
+ } else if (strcmp(paramName, "gcTriggerFactor") == 0) {
1088
+ param = JSGC_TRIGGER_FACTOR;
1089
+ } else {
1090
+ JS_ReportError(cx,
1091
+ "the first argument argument must be maxBytes, "
1092
+ "maxMallocBytes, gcStackpoolLifespan, gcBytes, "
1093
+ "gcNumber or gcTriggerFactor");
1094
+ return JS_FALSE;
1095
+ }
1096
+
1097
+ if (argc == 1) {
1098
+ value = JS_GetGCParameter(cx->runtime, param);
1099
+ return JS_NewNumberValue(cx, value, &vp[0]);
1100
+ }
1101
+
1102
+ if (param == JSGC_NUMBER ||
1103
+ param == JSGC_BYTES) {
1104
+ JS_ReportError(cx, "Attempt to change read-only parameter %s",
1105
+ paramName);
1106
+ return JS_FALSE;
1107
+ }
1108
+
1109
+ if (!JS_ValueToECMAUint32(cx, vp[3], &value)) {
1110
+ JS_ReportError(cx,
1111
+ "the second argument must be convertable to uint32 "
1112
+ "with non-zero value");
1113
+ return JS_FALSE;
1114
+ }
1115
+ if (param == JSGC_TRIGGER_FACTOR && value < 100) {
1116
+ JS_ReportError(cx,
1117
+ "the gcTriggerFactor value must be >= 100");
1118
+ return JS_FALSE;
1119
+ }
1120
+ JS_SetGCParameter(cx->runtime, param, value);
1121
+ *vp = JSVAL_VOID;
1122
+ return JS_TRUE;
1123
+ }
1124
+
1125
+ #ifdef JS_GC_ZEAL
1126
+ static JSBool
1127
+ GCZeal(JSContext *cx, uintN argc, jsval *vp)
1128
+ {
1129
+ uint32 zeal;
1130
+
1131
+ if (!JS_ValueToECMAUint32(cx, argc == 0 ? JSVAL_VOID : vp[2], &zeal))
1132
+ return JS_FALSE;
1133
+ JS_SetGCZeal(cx, (uint8)zeal);
1134
+ *vp = JSVAL_VOID;
1135
+ return JS_TRUE;
1136
+ }
1137
+ #endif /* JS_GC_ZEAL */
1138
+
1139
+ typedef struct JSCountHeapNode JSCountHeapNode;
1140
+
1141
+ struct JSCountHeapNode {
1142
+ void *thing;
1143
+ int32 kind;
1144
+ JSCountHeapNode *next;
1145
+ };
1146
+
1147
+ typedef struct JSCountHeapTracer {
1148
+ JSTracer base;
1149
+ JSDHashTable visited;
1150
+ JSBool ok;
1151
+ JSCountHeapNode *traceList;
1152
+ JSCountHeapNode *recycleList;
1153
+ } JSCountHeapTracer;
1154
+
1155
+ static void
1156
+ CountHeapNotify(JSTracer *trc, void *thing, uint32 kind)
1157
+ {
1158
+ JSCountHeapTracer *countTracer;
1159
+ JSDHashEntryStub *entry;
1160
+ JSCountHeapNode *node;
1161
+
1162
+ JS_ASSERT(trc->callback == CountHeapNotify);
1163
+ countTracer = (JSCountHeapTracer *)trc;
1164
+ if (!countTracer->ok)
1165
+ return;
1166
+
1167
+ entry = (JSDHashEntryStub *)
1168
+ JS_DHashTableOperate(&countTracer->visited, thing, JS_DHASH_ADD);
1169
+ if (!entry) {
1170
+ JS_ReportOutOfMemory(trc->context);
1171
+ countTracer->ok = JS_FALSE;
1172
+ return;
1173
+ }
1174
+ if (entry->key)
1175
+ return;
1176
+ entry->key = thing;
1177
+
1178
+ node = countTracer->recycleList;
1179
+ if (node) {
1180
+ countTracer->recycleList = node->next;
1181
+ } else {
1182
+ node = (JSCountHeapNode *) JS_malloc(trc->context, sizeof *node);
1183
+ if (!node) {
1184
+ countTracer->ok = JS_FALSE;
1185
+ return;
1186
+ }
1187
+ }
1188
+ node->thing = thing;
1189
+ node->kind = kind;
1190
+ node->next = countTracer->traceList;
1191
+ countTracer->traceList = node;
1192
+ }
1193
+
1194
+ static JSBool
1195
+ CountHeap(JSContext *cx, uintN argc, jsval *vp)
1196
+ {
1197
+ void* startThing;
1198
+ int32 startTraceKind;
1199
+ jsval v;
1200
+ int32 traceKind, i;
1201
+ JSString *str;
1202
+ char *bytes;
1203
+ JSCountHeapTracer countTracer;
1204
+ JSCountHeapNode *node;
1205
+ size_t counter;
1206
+
1207
+ static const struct {
1208
+ const char *name;
1209
+ int32 kind;
1210
+ } traceKindNames[] = {
1211
+ { "all", -1 },
1212
+ { "object", JSTRACE_OBJECT },
1213
+ { "double", JSTRACE_DOUBLE },
1214
+ { "string", JSTRACE_STRING },
1215
+ #if JS_HAS_XML_SUPPORT
1216
+ { "xml", JSTRACE_XML },
1217
+ #endif
1218
+ };
1219
+
1220
+ startThing = NULL;
1221
+ startTraceKind = 0;
1222
+ if (argc > 0) {
1223
+ v = JS_ARGV(cx, vp)[0];
1224
+ if (JSVAL_IS_TRACEABLE(v)) {
1225
+ startThing = JSVAL_TO_TRACEABLE(v);
1226
+ startTraceKind = JSVAL_TRACE_KIND(v);
1227
+ } else if (v != JSVAL_NULL) {
1228
+ JS_ReportError(cx,
1229
+ "the first argument is not null or a heap-allocated "
1230
+ "thing");
1231
+ return JS_FALSE;
1232
+ }
1233
+ }
1234
+
1235
+ traceKind = -1;
1236
+ if (argc > 1) {
1237
+ str = JS_ValueToString(cx, JS_ARGV(cx, vp)[1]);
1238
+ if (!str)
1239
+ return JS_FALSE;
1240
+ bytes = JS_GetStringBytes(str);
1241
+ if (!bytes)
1242
+ return JS_FALSE;
1243
+ for (i = 0; ;) {
1244
+ if (strcmp(bytes, traceKindNames[i].name) == 0) {
1245
+ traceKind = traceKindNames[i].kind;
1246
+ break;
1247
+ }
1248
+ if (++i == JS_ARRAY_LENGTH(traceKindNames)) {
1249
+ JS_ReportError(cx, "trace kind name '%s' is unknown", bytes);
1250
+ return JS_FALSE;
1251
+ }
1252
+ }
1253
+ }
1254
+
1255
+ JS_TRACER_INIT(&countTracer.base, cx, CountHeapNotify);
1256
+ if (!JS_DHashTableInit(&countTracer.visited, JS_DHashGetStubOps(),
1257
+ NULL, sizeof(JSDHashEntryStub),
1258
+ JS_DHASH_DEFAULT_CAPACITY(100))) {
1259
+ JS_ReportOutOfMemory(cx);
1260
+ return JS_FALSE;
1261
+ }
1262
+ countTracer.ok = JS_TRUE;
1263
+ countTracer.traceList = NULL;
1264
+ countTracer.recycleList = NULL;
1265
+
1266
+ if (!startThing) {
1267
+ JS_TraceRuntime(&countTracer.base);
1268
+ } else {
1269
+ JS_SET_TRACING_NAME(&countTracer.base, "root");
1270
+ JS_CallTracer(&countTracer.base, startThing, startTraceKind);
1271
+ }
1272
+
1273
+ counter = 0;
1274
+ while ((node = countTracer.traceList) != NULL) {
1275
+ if (traceKind == -1 || node->kind == traceKind)
1276
+ counter++;
1277
+ countTracer.traceList = node->next;
1278
+ node->next = countTracer.recycleList;
1279
+ countTracer.recycleList = node;
1280
+ JS_TraceChildren(&countTracer.base, node->thing, node->kind);
1281
+ }
1282
+ while ((node = countTracer.recycleList) != NULL) {
1283
+ countTracer.recycleList = node->next;
1284
+ JS_free(cx, node);
1285
+ }
1286
+ JS_DHashTableFinish(&countTracer.visited);
1287
+
1288
+ return countTracer.ok && JS_NewNumberValue(cx, (jsdouble) counter, vp);
1289
+ }
1290
+
1291
+ static JSScript *
1292
+ ValueToScript(JSContext *cx, jsval v)
1293
+ {
1294
+ JSScript *script = NULL;
1295
+ JSFunction *fun;
1296
+
1297
+ if (!JSVAL_IS_PRIMITIVE(v)) {
1298
+ JSObject *obj = JSVAL_TO_OBJECT(v);
1299
+ JSClass *clasp = JS_GET_CLASS(cx, obj);
1300
+
1301
+ if (clasp == &js_ScriptClass) {
1302
+ script = (JSScript *) JS_GetPrivate(cx, obj);
1303
+ } else if (clasp == &js_GeneratorClass) {
1304
+ JSGenerator *gen = (JSGenerator *) JS_GetPrivate(cx, obj);
1305
+ fun = gen->frame.fun;
1306
+ script = FUN_SCRIPT(fun);
1307
+ }
1308
+ }
1309
+
1310
+ if (!script) {
1311
+ fun = JS_ValueToFunction(cx, v);
1312
+ if (!fun)
1313
+ return NULL;
1314
+ script = FUN_SCRIPT(fun);
1315
+ if (!script) {
1316
+ JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL,
1317
+ JSSMSG_SCRIPTS_ONLY);
1318
+ }
1319
+ }
1320
+
1321
+ return script;
1322
+ }
1323
+
1324
+ static JSBool
1325
+ GetTrapArgs(JSContext *cx, uintN argc, jsval *argv, JSScript **scriptp,
1326
+ int32 *ip)
1327
+ {
1328
+ jsval v;
1329
+ uintN intarg;
1330
+ JSScript *script;
1331
+
1332
+ *scriptp = JS_GetScriptedCaller(cx, NULL)->script;
1333
+ *ip = 0;
1334
+ if (argc != 0) {
1335
+ v = argv[0];
1336
+ intarg = 0;
1337
+ if (!JSVAL_IS_PRIMITIVE(v) &&
1338
+ (JS_GET_CLASS(cx, JSVAL_TO_OBJECT(v)) == &js_FunctionClass ||
1339
+ JS_GET_CLASS(cx, JSVAL_TO_OBJECT(v)) == &js_ScriptClass)) {
1340
+ script = ValueToScript(cx, v);
1341
+ if (!script)
1342
+ return JS_FALSE;
1343
+ *scriptp = script;
1344
+ intarg++;
1345
+ }
1346
+ if (argc > intarg) {
1347
+ if (!JS_ValueToInt32(cx, argv[intarg], ip))
1348
+ return JS_FALSE;
1349
+ }
1350
+ }
1351
+ return JS_TRUE;
1352
+ }
1353
+
1354
+ static JSTrapStatus
1355
+ TrapHandler(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval,
1356
+ void *closure)
1357
+ {
1358
+ JSString *str;
1359
+ JSStackFrame *caller;
1360
+
1361
+ str = (JSString *) closure;
1362
+ caller = JS_GetScriptedCaller(cx, NULL);
1363
+ if (!JS_EvaluateScript(cx, caller->scopeChain,
1364
+ JS_GetStringBytes(str), JS_GetStringLength(str),
1365
+ caller->script->filename, caller->script->lineno,
1366
+ rval)) {
1367
+ return JSTRAP_ERROR;
1368
+ }
1369
+ if (!JSVAL_IS_VOID(*rval))
1370
+ return JSTRAP_RETURN;
1371
+ return JSTRAP_CONTINUE;
1372
+ }
1373
+
1374
+ static JSBool
1375
+ Trap(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1376
+ {
1377
+ JSString *str;
1378
+ JSScript *script;
1379
+ int32 i;
1380
+
1381
+ if (argc == 0) {
1382
+ JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL, JSSMSG_TRAP_USAGE);
1383
+ return JS_FALSE;
1384
+ }
1385
+ argc--;
1386
+ str = JS_ValueToString(cx, argv[argc]);
1387
+ if (!str)
1388
+ return JS_FALSE;
1389
+ argv[argc] = STRING_TO_JSVAL(str);
1390
+ if (!GetTrapArgs(cx, argc, argv, &script, &i))
1391
+ return JS_FALSE;
1392
+ return JS_SetTrap(cx, script, script->code + i, TrapHandler, str);
1393
+ }
1394
+
1395
+ static JSBool
1396
+ Untrap(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1397
+ {
1398
+ JSScript *script;
1399
+ int32 i;
1400
+
1401
+ if (!GetTrapArgs(cx, argc, argv, &script, &i))
1402
+ return JS_FALSE;
1403
+ JS_ClearTrap(cx, script, script->code + i, NULL, NULL);
1404
+ return JS_TRUE;
1405
+ }
1406
+
1407
+ static JSBool
1408
+ LineToPC(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1409
+ {
1410
+ JSScript *script;
1411
+ int32 i;
1412
+ uintN lineno;
1413
+ jsbytecode *pc;
1414
+
1415
+ if (argc == 0) {
1416
+ JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL, JSSMSG_LINE2PC_USAGE);
1417
+ return JS_FALSE;
1418
+ }
1419
+ script = JS_GetScriptedCaller(cx, NULL)->script;
1420
+ if (!GetTrapArgs(cx, argc, argv, &script, &i))
1421
+ return JS_FALSE;
1422
+ lineno = (i == 0) ? script->lineno : (uintN)i;
1423
+ pc = JS_LineNumberToPC(cx, script, lineno);
1424
+ if (!pc)
1425
+ return JS_FALSE;
1426
+ *rval = INT_TO_JSVAL(PTRDIFF(pc, script->code, jsbytecode));
1427
+ return JS_TRUE;
1428
+ }
1429
+
1430
+ static JSBool
1431
+ PCToLine(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1432
+ {
1433
+ JSScript *script;
1434
+ int32 i;
1435
+ uintN lineno;
1436
+
1437
+ if (!GetTrapArgs(cx, argc, argv, &script, &i))
1438
+ return JS_FALSE;
1439
+ lineno = JS_PCToLineNumber(cx, script, script->code + i);
1440
+ if (!lineno)
1441
+ return JS_FALSE;
1442
+ *rval = INT_TO_JSVAL(lineno);
1443
+ return JS_TRUE;
1444
+ }
1445
+
1446
+ #ifdef DEBUG
1447
+
1448
+ static void
1449
+ UpdateSwitchTableBounds(JSContext *cx, JSScript *script, uintN offset,
1450
+ uintN *start, uintN *end)
1451
+ {
1452
+ jsbytecode *pc;
1453
+ JSOp op;
1454
+ ptrdiff_t jmplen;
1455
+ jsint low, high, n;
1456
+
1457
+ pc = script->code + offset;
1458
+ op = js_GetOpcode(cx, script, pc);
1459
+ switch (op) {
1460
+ case JSOP_TABLESWITCHX:
1461
+ jmplen = JUMPX_OFFSET_LEN;
1462
+ goto jump_table;
1463
+ case JSOP_TABLESWITCH:
1464
+ jmplen = JUMP_OFFSET_LEN;
1465
+ jump_table:
1466
+ pc += jmplen;
1467
+ low = GET_JUMP_OFFSET(pc);
1468
+ pc += JUMP_OFFSET_LEN;
1469
+ high = GET_JUMP_OFFSET(pc);
1470
+ pc += JUMP_OFFSET_LEN;
1471
+ n = high - low + 1;
1472
+ break;
1473
+
1474
+ case JSOP_LOOKUPSWITCHX:
1475
+ jmplen = JUMPX_OFFSET_LEN;
1476
+ goto lookup_table;
1477
+ case JSOP_LOOKUPSWITCH:
1478
+ jmplen = JUMP_OFFSET_LEN;
1479
+ lookup_table:
1480
+ pc += jmplen;
1481
+ n = GET_INDEX(pc);
1482
+ pc += INDEX_LEN;
1483
+ jmplen += JUMP_OFFSET_LEN;
1484
+ break;
1485
+
1486
+ default:
1487
+ /* [condswitch] switch does not have any jump or lookup tables. */
1488
+ JS_ASSERT(op == JSOP_CONDSWITCH);
1489
+ return;
1490
+ }
1491
+
1492
+ *start = (uintN)(pc - script->code);
1493
+ *end = *start + (uintN)(n * jmplen);
1494
+ }
1495
+
1496
+ static void
1497
+ SrcNotes(JSContext *cx, JSScript *script)
1498
+ {
1499
+ uintN offset, delta, caseOff, switchTableStart, switchTableEnd;
1500
+ jssrcnote *notes, *sn;
1501
+ JSSrcNoteType type;
1502
+ const char *name;
1503
+ uint32 index;
1504
+ JSAtom *atom;
1505
+ JSString *str;
1506
+
1507
+ fprintf(gOutFile, "\nSource notes:\n");
1508
+ offset = 0;
1509
+ notes = SCRIPT_NOTES(script);
1510
+ switchTableEnd = switchTableStart = 0;
1511
+ for (sn = notes; !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) {
1512
+ delta = SN_DELTA(sn);
1513
+ offset += delta;
1514
+ type = (JSSrcNoteType) SN_TYPE(sn);
1515
+ name = js_SrcNoteSpec[type].name;
1516
+ if (type == SRC_LABEL) {
1517
+ /* Check if the source note is for a switch case. */
1518
+ if (switchTableStart <= offset && offset < switchTableEnd) {
1519
+ name = "case";
1520
+ } else {
1521
+ JS_ASSERT(js_GetOpcode(cx, script, script->code + offset) == JSOP_NOP);
1522
+ }
1523
+ }
1524
+ fprintf(gOutFile, "%3u: %5u [%4u] %-8s",
1525
+ (uintN) PTRDIFF(sn, notes, jssrcnote), offset, delta, name);
1526
+ switch (type) {
1527
+ case SRC_SETLINE:
1528
+ fprintf(gOutFile, " lineno %u", (uintN) js_GetSrcNoteOffset(sn, 0));
1529
+ break;
1530
+ case SRC_FOR:
1531
+ fprintf(gOutFile, " cond %u update %u tail %u",
1532
+ (uintN) js_GetSrcNoteOffset(sn, 0),
1533
+ (uintN) js_GetSrcNoteOffset(sn, 1),
1534
+ (uintN) js_GetSrcNoteOffset(sn, 2));
1535
+ break;
1536
+ case SRC_IF_ELSE:
1537
+ fprintf(gOutFile, " else %u elseif %u",
1538
+ (uintN) js_GetSrcNoteOffset(sn, 0),
1539
+ (uintN) js_GetSrcNoteOffset(sn, 1));
1540
+ break;
1541
+ case SRC_COND:
1542
+ case SRC_WHILE:
1543
+ case SRC_PCBASE:
1544
+ case SRC_PCDELTA:
1545
+ case SRC_DECL:
1546
+ case SRC_BRACE:
1547
+ fprintf(gOutFile, " offset %u", (uintN) js_GetSrcNoteOffset(sn, 0));
1548
+ break;
1549
+ case SRC_LABEL:
1550
+ case SRC_LABELBRACE:
1551
+ case SRC_BREAK2LABEL:
1552
+ case SRC_CONT2LABEL:
1553
+ index = js_GetSrcNoteOffset(sn, 0);
1554
+ JS_GET_SCRIPT_ATOM(script, index, atom);
1555
+ JS_ASSERT(ATOM_IS_STRING(atom));
1556
+ str = ATOM_TO_STRING(atom);
1557
+ fprintf(gOutFile, " atom %u (", index);
1558
+ js_FileEscapedString(gOutFile, str, 0);
1559
+ putc(')', gOutFile);
1560
+ break;
1561
+ case SRC_FUNCDEF: {
1562
+ const char *bytes;
1563
+ JSObject *obj;
1564
+ JSFunction *fun;
1565
+
1566
+ index = js_GetSrcNoteOffset(sn, 0);
1567
+ JS_GET_SCRIPT_OBJECT(script, index, obj);
1568
+ fun = (JSFunction *) JS_GetPrivate(cx, obj);
1569
+ str = JS_DecompileFunction(cx, fun, JS_DONT_PRETTY_PRINT);
1570
+ bytes = str ? JS_GetStringBytes(str) : "N/A";
1571
+ fprintf(gOutFile, " function %u (%s)", index, bytes);
1572
+ break;
1573
+ }
1574
+ case SRC_SWITCH:
1575
+ fprintf(gOutFile, " length %u", (uintN) js_GetSrcNoteOffset(sn, 0));
1576
+ caseOff = (uintN) js_GetSrcNoteOffset(sn, 1);
1577
+ if (caseOff)
1578
+ fprintf(gOutFile, " first case offset %u", caseOff);
1579
+ UpdateSwitchTableBounds(cx, script, offset,
1580
+ &switchTableStart, &switchTableEnd);
1581
+ break;
1582
+ case SRC_CATCH:
1583
+ delta = (uintN) js_GetSrcNoteOffset(sn, 0);
1584
+ if (delta) {
1585
+ if (script->main[offset] == JSOP_LEAVEBLOCK)
1586
+ fprintf(gOutFile, " stack depth %u", delta);
1587
+ else
1588
+ fprintf(gOutFile, " guard delta %u", delta);
1589
+ }
1590
+ break;
1591
+ default:;
1592
+ }
1593
+ fputc('\n', gOutFile);
1594
+ }
1595
+ }
1596
+
1597
+ static JSBool
1598
+ Notes(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1599
+ {
1600
+ uintN i;
1601
+ JSScript *script;
1602
+
1603
+ for (i = 0; i < argc; i++) {
1604
+ script = ValueToScript(cx, argv[i]);
1605
+ if (!script)
1606
+ continue;
1607
+
1608
+ SrcNotes(cx, script);
1609
+ }
1610
+ return JS_TRUE;
1611
+ }
1612
+
1613
+ JS_STATIC_ASSERT(JSTRY_CATCH == 0);
1614
+ JS_STATIC_ASSERT(JSTRY_FINALLY == 1);
1615
+ JS_STATIC_ASSERT(JSTRY_ITER == 2);
1616
+
1617
+ static const char* const TryNoteNames[] = { "catch", "finally", "iter" };
1618
+
1619
+ static JSBool
1620
+ TryNotes(JSContext *cx, JSScript *script)
1621
+ {
1622
+ JSTryNote *tn, *tnlimit;
1623
+
1624
+ if (script->trynotesOffset == 0)
1625
+ return JS_TRUE;
1626
+
1627
+ tn = JS_SCRIPT_TRYNOTES(script)->vector;
1628
+ tnlimit = tn + JS_SCRIPT_TRYNOTES(script)->length;
1629
+ fprintf(gOutFile, "\nException table:\n"
1630
+ "kind stack start end\n");
1631
+ do {
1632
+ JS_ASSERT(tn->kind < JS_ARRAY_LENGTH(TryNoteNames));
1633
+ fprintf(gOutFile, " %-7s %6u %8u %8u\n",
1634
+ TryNoteNames[tn->kind], tn->stackDepth,
1635
+ tn->start, tn->start + tn->length);
1636
+ } while (++tn != tnlimit);
1637
+ return JS_TRUE;
1638
+ }
1639
+
1640
+ static JSBool
1641
+ Disassemble(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1642
+ {
1643
+ JSBool lines;
1644
+ uintN i;
1645
+ JSScript *script;
1646
+
1647
+ if (argc > 0 &&
1648
+ JSVAL_IS_STRING(argv[0]) &&
1649
+ !strcmp(JS_GetStringBytes(JSVAL_TO_STRING(argv[0])), "-l")) {
1650
+ lines = JS_TRUE;
1651
+ argv++, argc--;
1652
+ } else {
1653
+ lines = JS_FALSE;
1654
+ }
1655
+ for (i = 0; i < argc; i++) {
1656
+ script = ValueToScript(cx, argv[i]);
1657
+ if (!script)
1658
+ return JS_FALSE;
1659
+ if (VALUE_IS_FUNCTION(cx, argv[i])) {
1660
+ JSFunction *fun = JS_ValueToFunction(cx, argv[i]);
1661
+ if (fun && (fun->flags & ~7U)) {
1662
+ uint16 flags = fun->flags;
1663
+ fputs("flags:", stdout);
1664
+
1665
+ #define SHOW_FLAG(flag) if (flags & JSFUN_##flag) fputs(" " #flag, stdout);
1666
+
1667
+ SHOW_FLAG(LAMBDA);
1668
+ SHOW_FLAG(SETTER);
1669
+ SHOW_FLAG(GETTER);
1670
+ SHOW_FLAG(BOUND_METHOD);
1671
+ SHOW_FLAG(HEAVYWEIGHT);
1672
+ SHOW_FLAG(THISP_STRING);
1673
+ SHOW_FLAG(THISP_NUMBER);
1674
+ SHOW_FLAG(THISP_BOOLEAN);
1675
+ SHOW_FLAG(EXPR_CLOSURE);
1676
+ SHOW_FLAG(TRACEABLE);
1677
+
1678
+ #undef SHOW_FLAG
1679
+
1680
+ if (FUN_NULL_CLOSURE(fun))
1681
+ fputs(" NULL_CLOSURE", stdout);
1682
+ else if (FUN_FLAT_CLOSURE(fun))
1683
+ fputs(" FLAT_CLOSURE", stdout);
1684
+ putchar('\n');
1685
+ }
1686
+ }
1687
+
1688
+ if (!js_Disassemble(cx, script, lines, stdout))
1689
+ return JS_FALSE;
1690
+ SrcNotes(cx, script);
1691
+ TryNotes(cx, script);
1692
+ }
1693
+ return JS_TRUE;
1694
+ }
1695
+
1696
+ static JSBool
1697
+ DisassFile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1698
+ {
1699
+ JSString *str;
1700
+ const char *filename;
1701
+ JSScript *script;
1702
+ JSBool ok;
1703
+ uint32 oldopts;
1704
+
1705
+ if (!argc)
1706
+ return JS_TRUE;
1707
+
1708
+ str = JS_ValueToString(cx, argv[0]);
1709
+ if (!str)
1710
+ return JS_FALSE;
1711
+ argv[0] = STRING_TO_JSVAL(str);
1712
+
1713
+ filename = JS_GetStringBytes(str);
1714
+ oldopts = JS_GetOptions(cx);
1715
+ JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO | JSOPTION_NO_SCRIPT_RVAL);
1716
+ script = JS_CompileFile(cx, obj, filename);
1717
+ JS_SetOptions(cx, oldopts);
1718
+ if (!script)
1719
+ return JS_FALSE;
1720
+
1721
+ obj = JS_NewScriptObject(cx, script);
1722
+ if (!obj)
1723
+ return JS_FALSE;
1724
+
1725
+ *rval = OBJECT_TO_JSVAL(obj); /* I like to root it, root it. */
1726
+ ok = Disassemble(cx, obj, 1, rval, rval); /* gross, but works! */
1727
+ *rval = JSVAL_VOID;
1728
+
1729
+ return ok;
1730
+ }
1731
+
1732
+ static JSBool
1733
+ DisassWithSrc(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
1734
+ jsval *rval)
1735
+ {
1736
+ #define LINE_BUF_LEN 512
1737
+ uintN i, len, line1, line2, bupline;
1738
+ JSScript *script;
1739
+ FILE *file;
1740
+ char linebuf[LINE_BUF_LEN];
1741
+ jsbytecode *pc, *end;
1742
+ JSBool ok;
1743
+ static char sep[] = ";-------------------------";
1744
+
1745
+ ok = JS_TRUE;
1746
+ for (i = 0; ok && i < argc; i++) {
1747
+ script = ValueToScript(cx, argv[i]);
1748
+ if (!script)
1749
+ return JS_FALSE;
1750
+
1751
+ if (!script->filename) {
1752
+ JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL,
1753
+ JSSMSG_FILE_SCRIPTS_ONLY);
1754
+ return JS_FALSE;
1755
+ }
1756
+
1757
+ file = fopen(script->filename, "r");
1758
+ if (!file) {
1759
+ JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL,
1760
+ JSSMSG_CANT_OPEN, script->filename,
1761
+ strerror(errno));
1762
+ return JS_FALSE;
1763
+ }
1764
+
1765
+ pc = script->code;
1766
+ end = pc + script->length;
1767
+
1768
+ /* burn the leading lines */
1769
+ line2 = JS_PCToLineNumber(cx, script, pc);
1770
+ for (line1 = 0; line1 < line2 - 1; line1++)
1771
+ fgets(linebuf, LINE_BUF_LEN, file);
1772
+
1773
+ bupline = 0;
1774
+ while (pc < end) {
1775
+ line2 = JS_PCToLineNumber(cx, script, pc);
1776
+
1777
+ if (line2 < line1) {
1778
+ if (bupline != line2) {
1779
+ bupline = line2;
1780
+ fprintf(gOutFile, "%s %3u: BACKUP\n", sep, line2);
1781
+ }
1782
+ } else {
1783
+ if (bupline && line1 == line2)
1784
+ fprintf(gOutFile, "%s %3u: RESTORE\n", sep, line2);
1785
+ bupline = 0;
1786
+ while (line1 < line2) {
1787
+ if (!fgets(linebuf, LINE_BUF_LEN, file)) {
1788
+ JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL,
1789
+ JSSMSG_UNEXPECTED_EOF,
1790
+ script->filename);
1791
+ ok = JS_FALSE;
1792
+ goto bail;
1793
+ }
1794
+ line1++;
1795
+ fprintf(gOutFile, "%s %3u: %s", sep, line1, linebuf);
1796
+ }
1797
+ }
1798
+
1799
+ len = js_Disassemble1(cx, script, pc,
1800
+ PTRDIFF(pc, script->code, jsbytecode),
1801
+ JS_TRUE, stdout);
1802
+ if (!len) {
1803
+ ok = JS_FALSE;
1804
+ goto bail;
1805
+ }
1806
+ pc += len;
1807
+ }
1808
+
1809
+ bail:
1810
+ fclose(file);
1811
+ }
1812
+ return ok;
1813
+ #undef LINE_BUF_LEN
1814
+ }
1815
+
1816
+ static JSBool
1817
+ Tracing(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1818
+ {
1819
+ FILE *file;
1820
+
1821
+ if (argc == 0) {
1822
+ *rval = BOOLEAN_TO_JSVAL(cx->tracefp != 0);
1823
+ return JS_TRUE;
1824
+ }
1825
+
1826
+ switch (JS_TypeOfValue(cx, argv[0])) {
1827
+ case JSTYPE_NUMBER:
1828
+ case JSTYPE_BOOLEAN: {
1829
+ JSBool bval;
1830
+ if (!JS_ValueToBoolean(cx, argv[0], &bval))
1831
+ goto bad_argument;
1832
+ file = bval ? stderr : NULL;
1833
+ break;
1834
+ }
1835
+ case JSTYPE_STRING: {
1836
+ char *name = JS_GetStringBytes(JSVAL_TO_STRING(argv[0]));
1837
+ file = fopen(name, "w");
1838
+ if (!file) {
1839
+ JS_ReportError(cx, "tracing: couldn't open output file %s: %s",
1840
+ name, strerror(errno));
1841
+ return JS_FALSE;
1842
+ }
1843
+ break;
1844
+ }
1845
+ default:
1846
+ goto bad_argument;
1847
+ }
1848
+ if (cx->tracefp && cx->tracefp != stderr)
1849
+ fclose((FILE *)cx->tracefp);
1850
+ cx->tracefp = file;
1851
+ cx->tracePrevPc = NULL;
1852
+ return JS_TRUE;
1853
+
1854
+ bad_argument:
1855
+ JSString *str = JS_ValueToString(cx, argv[0]);
1856
+ if (!str)
1857
+ return JS_FALSE;
1858
+ JS_ReportError(cx, "tracing: illegal argument %s",
1859
+ JS_GetStringBytes(str));
1860
+ return JS_FALSE;
1861
+ }
1862
+
1863
+ static void
1864
+ DumpScope(JSContext *cx, JSObject *obj, FILE *fp)
1865
+ {
1866
+ uintN i;
1867
+ JSScope *scope;
1868
+ JSScopeProperty *sprop;
1869
+ jsval v;
1870
+ JSString *str;
1871
+
1872
+ i = 0;
1873
+ scope = OBJ_SCOPE(obj);
1874
+ for (sprop = SCOPE_LAST_PROP(scope); sprop; sprop = sprop->parent) {
1875
+ if (SCOPE_HAD_MIDDLE_DELETE(scope) && !SCOPE_HAS_PROPERTY(scope, sprop))
1876
+ continue;
1877
+ fprintf(fp, "%3u %p ", i, (void *)sprop);
1878
+
1879
+ v = ID_TO_VALUE(sprop->id);
1880
+ if (JSID_IS_INT(sprop->id)) {
1881
+ fprintf(fp, "[%ld]", (long)JSVAL_TO_INT(v));
1882
+ } else {
1883
+ if (JSID_IS_ATOM(sprop->id)) {
1884
+ str = JSVAL_TO_STRING(v);
1885
+ } else {
1886
+ JS_ASSERT(JSID_IS_OBJECT(sprop->id));
1887
+ str = js_ValueToString(cx, v);
1888
+ fputs("object ", fp);
1889
+ }
1890
+ if (!str)
1891
+ fputs("<error>", fp);
1892
+ else
1893
+ js_FileEscapedString(fp, str, '"');
1894
+ }
1895
+ #define DUMP_ATTR(name) if (sprop->attrs & JSPROP_##name) fputs(" " #name, fp)
1896
+ DUMP_ATTR(ENUMERATE);
1897
+ DUMP_ATTR(READONLY);
1898
+ DUMP_ATTR(PERMANENT);
1899
+ DUMP_ATTR(GETTER);
1900
+ DUMP_ATTR(SETTER);
1901
+ #undef DUMP_ATTR
1902
+
1903
+ fprintf(fp, " slot %lu flags %x shortid %d\n",
1904
+ (unsigned long)sprop->slot, sprop->flags, sprop->shortid);
1905
+ }
1906
+ }
1907
+
1908
+ static JSBool
1909
+ DumpStats(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1910
+ {
1911
+ uintN i;
1912
+ JSString *str;
1913
+ const char *bytes;
1914
+ jsid id;
1915
+ JSObject *obj2;
1916
+ JSProperty *prop;
1917
+ jsval value;
1918
+
1919
+ for (i = 0; i < argc; i++) {
1920
+ str = JS_ValueToString(cx, argv[i]);
1921
+ if (!str)
1922
+ return JS_FALSE;
1923
+ argv[i] = STRING_TO_JSVAL(str);
1924
+ bytes = JS_GetStringBytes(str);
1925
+ if (strcmp(bytes, "arena") == 0) {
1926
+ #ifdef JS_ARENAMETER
1927
+ JS_DumpArenaStats(stdout);
1928
+ #endif
1929
+ } else if (strcmp(bytes, "atom") == 0) {
1930
+ js_DumpAtoms(cx, gOutFile);
1931
+ } else if (strcmp(bytes, "global") == 0) {
1932
+ DumpScope(cx, cx->globalObject, stdout);
1933
+ } else {
1934
+ if (!JS_ValueToId(cx, STRING_TO_JSVAL(str), &id))
1935
+ return JS_FALSE;
1936
+ if (!js_FindProperty(cx, id, &obj, &obj2, &prop))
1937
+ return JS_FALSE;
1938
+ if (prop) {
1939
+ OBJ_DROP_PROPERTY(cx, obj2, prop);
1940
+ if (!OBJ_GET_PROPERTY(cx, obj, id, &value))
1941
+ return JS_FALSE;
1942
+ }
1943
+ if (!prop || !JSVAL_IS_OBJECT(value)) {
1944
+ fprintf(gErrFile, "js: invalid stats argument %s\n",
1945
+ bytes);
1946
+ continue;
1947
+ }
1948
+ obj = JSVAL_TO_OBJECT(value);
1949
+ if (obj)
1950
+ DumpScope(cx, obj, stdout);
1951
+ }
1952
+ }
1953
+ return JS_TRUE;
1954
+ }
1955
+
1956
+ static JSBool
1957
+ DumpHeap(JSContext *cx, uintN argc, jsval *vp)
1958
+ {
1959
+ char *fileName;
1960
+ jsval v;
1961
+ void* startThing;
1962
+ uint32 startTraceKind;
1963
+ const char *badTraceArg;
1964
+ void *thingToFind;
1965
+ size_t maxDepth;
1966
+ void *thingToIgnore;
1967
+ FILE *dumpFile;
1968
+ JSBool ok;
1969
+
1970
+ fileName = NULL;
1971
+ if (argc > 0) {
1972
+ v = JS_ARGV(cx, vp)[0];
1973
+ if (v != JSVAL_NULL) {
1974
+ JSString *str;
1975
+
1976
+ str = JS_ValueToString(cx, v);
1977
+ if (!str)
1978
+ return JS_FALSE;
1979
+ JS_ARGV(cx, vp)[0] = STRING_TO_JSVAL(str);
1980
+ fileName = JS_GetStringBytes(str);
1981
+ }
1982
+ }
1983
+
1984
+ startThing = NULL;
1985
+ startTraceKind = 0;
1986
+ if (argc > 1) {
1987
+ v = JS_ARGV(cx, vp)[1];
1988
+ if (JSVAL_IS_TRACEABLE(v)) {
1989
+ startThing = JSVAL_TO_TRACEABLE(v);
1990
+ startTraceKind = JSVAL_TRACE_KIND(v);
1991
+ } else if (v != JSVAL_NULL) {
1992
+ badTraceArg = "start";
1993
+ goto not_traceable_arg;
1994
+ }
1995
+ }
1996
+
1997
+ thingToFind = NULL;
1998
+ if (argc > 2) {
1999
+ v = JS_ARGV(cx, vp)[2];
2000
+ if (JSVAL_IS_TRACEABLE(v)) {
2001
+ thingToFind = JSVAL_TO_TRACEABLE(v);
2002
+ } else if (v != JSVAL_NULL) {
2003
+ badTraceArg = "toFind";
2004
+ goto not_traceable_arg;
2005
+ }
2006
+ }
2007
+
2008
+ maxDepth = (size_t)-1;
2009
+ if (argc > 3) {
2010
+ v = JS_ARGV(cx, vp)[3];
2011
+ if (v != JSVAL_NULL) {
2012
+ uint32 depth;
2013
+
2014
+ if (!JS_ValueToECMAUint32(cx, v, &depth))
2015
+ return JS_FALSE;
2016
+ maxDepth = depth;
2017
+ }
2018
+ }
2019
+
2020
+ thingToIgnore = NULL;
2021
+ if (argc > 4) {
2022
+ v = JS_ARGV(cx, vp)[4];
2023
+ if (JSVAL_IS_TRACEABLE(v)) {
2024
+ thingToIgnore = JSVAL_TO_TRACEABLE(v);
2025
+ } else if (v != JSVAL_NULL) {
2026
+ badTraceArg = "toIgnore";
2027
+ goto not_traceable_arg;
2028
+ }
2029
+ }
2030
+
2031
+ if (!fileName) {
2032
+ dumpFile = stdout;
2033
+ } else {
2034
+ dumpFile = fopen(fileName, "w");
2035
+ if (!dumpFile) {
2036
+ JS_ReportError(cx, "can't open %s: %s", fileName, strerror(errno));
2037
+ return JS_FALSE;
2038
+ }
2039
+ }
2040
+
2041
+ ok = JS_DumpHeap(cx, dumpFile, startThing, startTraceKind, thingToFind,
2042
+ maxDepth, thingToIgnore);
2043
+ if (dumpFile != stdout)
2044
+ fclose(dumpFile);
2045
+ return ok;
2046
+
2047
+ not_traceable_arg:
2048
+ JS_ReportError(cx, "argument '%s' is not null or a heap-allocated thing",
2049
+ badTraceArg);
2050
+ return JS_FALSE;
2051
+ }
2052
+
2053
+ #endif /* DEBUG */
2054
+
2055
+ #ifdef TEST_CVTARGS
2056
+ #include <ctype.h>
2057
+
2058
+ static const char *
2059
+ EscapeWideString(jschar *w)
2060
+ {
2061
+ static char enuf[80];
2062
+ static char hex[] = "0123456789abcdef";
2063
+ jschar u;
2064
+ unsigned char b, c;
2065
+ int i, j;
2066
+
2067
+ if (!w)
2068
+ return "";
2069
+ for (i = j = 0; i < sizeof enuf - 1; i++, j++) {
2070
+ u = w[j];
2071
+ if (u == 0)
2072
+ break;
2073
+ b = (unsigned char)(u >> 8);
2074
+ c = (unsigned char)(u);
2075
+ if (b) {
2076
+ if (i >= sizeof enuf - 6)
2077
+ break;
2078
+ enuf[i++] = '\\';
2079
+ enuf[i++] = 'u';
2080
+ enuf[i++] = hex[b >> 4];
2081
+ enuf[i++] = hex[b & 15];
2082
+ enuf[i++] = hex[c >> 4];
2083
+ enuf[i] = hex[c & 15];
2084
+ } else if (!isprint(c)) {
2085
+ if (i >= sizeof enuf - 4)
2086
+ break;
2087
+ enuf[i++] = '\\';
2088
+ enuf[i++] = 'x';
2089
+ enuf[i++] = hex[c >> 4];
2090
+ enuf[i] = hex[c & 15];
2091
+ } else {
2092
+ enuf[i] = (char)c;
2093
+ }
2094
+ }
2095
+ enuf[i] = 0;
2096
+ return enuf;
2097
+ }
2098
+
2099
+ #include <stdarg.h>
2100
+
2101
+ static JSBool
2102
+ ZZ_formatter(JSContext *cx, const char *format, JSBool fromJS, jsval **vpp,
2103
+ va_list *app)
2104
+ {
2105
+ jsval *vp;
2106
+ va_list ap;
2107
+ jsdouble re, im;
2108
+
2109
+ printf("entering ZZ_formatter");
2110
+ vp = *vpp;
2111
+ ap = *app;
2112
+ if (fromJS) {
2113
+ if (!JS_ValueToNumber(cx, vp[0], &re))
2114
+ return JS_FALSE;
2115
+ if (!JS_ValueToNumber(cx, vp[1], &im))
2116
+ return JS_FALSE;
2117
+ *va_arg(ap, jsdouble *) = re;
2118
+ *va_arg(ap, jsdouble *) = im;
2119
+ } else {
2120
+ re = va_arg(ap, jsdouble);
2121
+ im = va_arg(ap, jsdouble);
2122
+ if (!JS_NewNumberValue(cx, re, &vp[0]))
2123
+ return JS_FALSE;
2124
+ if (!JS_NewNumberValue(cx, im, &vp[1]))
2125
+ return JS_FALSE;
2126
+ }
2127
+ *vpp = vp + 2;
2128
+ *app = ap;
2129
+ printf("leaving ZZ_formatter");
2130
+ return JS_TRUE;
2131
+ }
2132
+
2133
+ static JSBool
2134
+ ConvertArgs(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2135
+ {
2136
+ JSBool b = JS_FALSE;
2137
+ jschar c = 0;
2138
+ int32 i = 0, j = 0;
2139
+ uint32 u = 0;
2140
+ jsdouble d = 0, I = 0, re = 0, im = 0;
2141
+ char *s = NULL;
2142
+ JSString *str = NULL;
2143
+ jschar *w = NULL;
2144
+ JSObject *obj2 = NULL;
2145
+ JSFunction *fun = NULL;
2146
+ jsval v = JSVAL_VOID;
2147
+ JSBool ok;
2148
+
2149
+ if (!JS_AddArgumentFormatter(cx, "ZZ", ZZ_formatter))
2150
+ return JS_FALSE;;
2151
+ ok = JS_ConvertArguments(cx, argc, argv, "b/ciujdIsSWofvZZ*",
2152
+ &b, &c, &i, &u, &j, &d, &I, &s, &str, &w, &obj2,
2153
+ &fun, &v, &re, &im);
2154
+ JS_RemoveArgumentFormatter(cx, "ZZ");
2155
+ if (!ok)
2156
+ return JS_FALSE;
2157
+ fprintf(gOutFile,
2158
+ "b %u, c %x (%c), i %ld, u %lu, j %ld\n",
2159
+ b, c, (char)c, i, u, j);
2160
+ fprintf(gOutFile,
2161
+ "d %g, I %g, s %s, S %s, W %s, obj %s, fun %s\n"
2162
+ "v %s, re %g, im %g\n",
2163
+ d, I, s, str ? JS_GetStringBytes(str) : "", EscapeWideString(w),
2164
+ JS_GetStringBytes(JS_ValueToString(cx, OBJECT_TO_JSVAL(obj2))),
2165
+ fun ? JS_GetStringBytes(JS_DecompileFunction(cx, fun, 4)) : "",
2166
+ JS_GetStringBytes(JS_ValueToString(cx, v)), re, im);
2167
+ return JS_TRUE;
2168
+ }
2169
+ #endif
2170
+
2171
+ static JSBool
2172
+ BuildDate(JSContext *cx, uintN argc, jsval *vp)
2173
+ {
2174
+ char version[20] = "\n";
2175
+ #if JS_VERSION < 150
2176
+ sprintf(version, " for version %d\n", JS_VERSION);
2177
+ #endif
2178
+ fprintf(gOutFile, "built on %s at %s%s", __DATE__, __TIME__, version);
2179
+ *vp = JSVAL_VOID;
2180
+ return JS_TRUE;
2181
+ }
2182
+
2183
+ static JSBool
2184
+ Clear(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2185
+ {
2186
+ if (argc != 0 && !JS_ValueToObject(cx, argv[0], &obj))
2187
+ return JS_FALSE;
2188
+ JS_ClearScope(cx, obj);
2189
+ return JS_TRUE;
2190
+ }
2191
+
2192
+ static JSBool
2193
+ Intern(JSContext *cx, uintN argc, jsval *vp)
2194
+ {
2195
+ JSString *str;
2196
+
2197
+ str = JS_ValueToString(cx, argc == 0 ? JSVAL_VOID : vp[2]);
2198
+ if (!str)
2199
+ return JS_FALSE;
2200
+ if (!JS_InternUCStringN(cx, JS_GetStringChars(str),
2201
+ JS_GetStringLength(str))) {
2202
+ return JS_FALSE;
2203
+ }
2204
+ *vp = JSVAL_VOID;
2205
+ return JS_TRUE;
2206
+ }
2207
+
2208
+ static JSBool
2209
+ Clone(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2210
+ {
2211
+ JSObject *funobj, *parent, *clone;
2212
+
2213
+ if (VALUE_IS_FUNCTION(cx, argv[0])) {
2214
+ funobj = JSVAL_TO_OBJECT(argv[0]);
2215
+ } else {
2216
+ JSFunction *fun = JS_ValueToFunction(cx, argv[0]);
2217
+ if (!fun)
2218
+ return JS_FALSE;
2219
+ funobj = JS_GetFunctionObject(fun);
2220
+ }
2221
+ if (argc > 1) {
2222
+ if (!JS_ValueToObject(cx, argv[1], &parent))
2223
+ return JS_FALSE;
2224
+ } else {
2225
+ parent = JS_GetParent(cx, funobj);
2226
+ }
2227
+ clone = JS_CloneFunctionObject(cx, funobj, parent);
2228
+ if (!clone)
2229
+ return JS_FALSE;
2230
+ *rval = OBJECT_TO_JSVAL(clone);
2231
+ return JS_TRUE;
2232
+ }
2233
+
2234
+ static JSBool
2235
+ Seal(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2236
+ {
2237
+ JSObject *target;
2238
+ JSBool deep = JS_FALSE;
2239
+
2240
+ if (!JS_ConvertArguments(cx, argc, argv, "o/b", &target, &deep))
2241
+ return JS_FALSE;
2242
+ if (!target)
2243
+ return JS_TRUE;
2244
+ return JS_SealObject(cx, target, deep);
2245
+ }
2246
+
2247
+ static JSBool
2248
+ GetPDA(JSContext *cx, uintN argc, jsval *vp)
2249
+ {
2250
+ JSObject *vobj, *aobj, *pdobj;
2251
+ JSBool ok;
2252
+ JSPropertyDescArray pda;
2253
+ JSPropertyDesc *pd;
2254
+ uint32 i;
2255
+ jsval v;
2256
+
2257
+ if (!JS_ValueToObject(cx, argc == 0 ? JSVAL_VOID : vp[2], &vobj))
2258
+ return JS_FALSE;
2259
+ if (!vobj) {
2260
+ *vp = JSVAL_VOID;
2261
+ return JS_TRUE;
2262
+ }
2263
+
2264
+ aobj = JS_NewArrayObject(cx, 0, NULL);
2265
+ if (!aobj)
2266
+ return JS_FALSE;
2267
+ *vp = OBJECT_TO_JSVAL(aobj);
2268
+
2269
+ ok = JS_GetPropertyDescArray(cx, vobj, &pda);
2270
+ if (!ok)
2271
+ return JS_FALSE;
2272
+ pd = pda.array;
2273
+ for (i = 0; i < pda.length; i++, pd++) {
2274
+ pdobj = JS_NewObject(cx, NULL, NULL, NULL);
2275
+ if (!pdobj) {
2276
+ ok = JS_FALSE;
2277
+ break;
2278
+ }
2279
+
2280
+ /* Protect pdobj from GC by setting it as an element of aobj now */
2281
+ v = OBJECT_TO_JSVAL(pdobj);
2282
+ ok = JS_SetElement(cx, aobj, i, &v);
2283
+ if (!ok)
2284
+ break;
2285
+
2286
+ ok = JS_SetProperty(cx, pdobj, "id", &pd->id) &&
2287
+ JS_SetProperty(cx, pdobj, "value", &pd->value) &&
2288
+ (v = INT_TO_JSVAL(pd->flags),
2289
+ JS_SetProperty(cx, pdobj, "flags", &v)) &&
2290
+ (v = INT_TO_JSVAL(pd->slot),
2291
+ JS_SetProperty(cx, pdobj, "slot", &v)) &&
2292
+ JS_SetProperty(cx, pdobj, "alias", &pd->alias);
2293
+ if (!ok)
2294
+ break;
2295
+ }
2296
+ JS_PutPropertyDescArray(cx, &pda);
2297
+ return ok;
2298
+ }
2299
+
2300
+ static JSBool
2301
+ GetSLX(JSContext *cx, uintN argc, jsval *vp)
2302
+ {
2303
+ JSScript *script;
2304
+
2305
+ script = ValueToScript(cx, argc == 0 ? JSVAL_VOID : vp[2]);
2306
+ if (!script)
2307
+ return JS_FALSE;
2308
+ *vp = INT_TO_JSVAL(js_GetScriptLineExtent(script));
2309
+ return JS_TRUE;
2310
+ }
2311
+
2312
+ static JSBool
2313
+ ToInt32(JSContext *cx, uintN argc, jsval *vp)
2314
+ {
2315
+ int32 i;
2316
+
2317
+ if (!JS_ValueToInt32(cx, argc == 0 ? JSVAL_VOID : vp[2], &i))
2318
+ return JS_FALSE;
2319
+ return JS_NewNumberValue(cx, i, vp);
2320
+ }
2321
+
2322
+ static JSBool
2323
+ StringsAreUTF8(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
2324
+ jsval *rval)
2325
+ {
2326
+ *rval = JS_CStringsAreUTF8() ? JSVAL_TRUE : JSVAL_FALSE;
2327
+ return JS_TRUE;
2328
+ }
2329
+
2330
+ static JSBool
2331
+ StackQuota(JSContext *cx, uintN argc, jsval *vp)
2332
+ {
2333
+ uint32 n;
2334
+
2335
+ if (argc == 0)
2336
+ return JS_NewNumberValue(cx, (double) gScriptStackQuota, vp);
2337
+ if (!JS_ValueToECMAUint32(cx, JS_ARGV(cx, vp)[0], &n))
2338
+ return JS_FALSE;
2339
+ gScriptStackQuota = n;
2340
+ JS_SetScriptStackQuota(cx, gScriptStackQuota);
2341
+ JS_SET_RVAL(cx, vp, JSVAL_VOID);
2342
+ return JS_TRUE;
2343
+ }
2344
+
2345
+ static const char* badUTF8 = "...\xC0...";
2346
+ static const char* bigUTF8 = "...\xFB\xBF\xBF\xBF\xBF...";
2347
+ static const jschar badSurrogate[] = { 'A', 'B', 'C', 0xDEEE, 'D', 'E', 0 };
2348
+
2349
+ static JSBool
2350
+ TestUTF8(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2351
+ {
2352
+ int32 mode = 1;
2353
+ jschar chars[20];
2354
+ size_t charsLength = 5;
2355
+ char bytes[20];
2356
+ size_t bytesLength = 20;
2357
+ if (argc && !JS_ValueToInt32(cx, *argv, &mode))
2358
+ return JS_FALSE;
2359
+
2360
+ /* The following throw errors if compiled with UTF-8. */
2361
+ switch (mode) {
2362
+ /* mode 1: malformed UTF-8 string. */
2363
+ case 1:
2364
+ JS_NewStringCopyZ(cx, badUTF8);
2365
+ break;
2366
+ /* mode 2: big UTF-8 character. */
2367
+ case 2:
2368
+ JS_NewStringCopyZ(cx, bigUTF8);
2369
+ break;
2370
+ /* mode 3: bad surrogate character. */
2371
+ case 3:
2372
+ JS_EncodeCharacters(cx, badSurrogate, 6, bytes, &bytesLength);
2373
+ break;
2374
+ /* mode 4: use a too small buffer. */
2375
+ case 4:
2376
+ JS_DecodeBytes(cx, "1234567890", 10, chars, &charsLength);
2377
+ break;
2378
+ default:
2379
+ JS_ReportError(cx, "invalid mode parameter");
2380
+ return JS_FALSE;
2381
+ }
2382
+ return !JS_IsExceptionPending (cx);
2383
+ }
2384
+
2385
+ static JSBool
2386
+ ThrowError(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2387
+ {
2388
+ JS_ReportError(cx, "This is an error");
2389
+ return JS_FALSE;
2390
+ }
2391
+
2392
+ #define LAZY_STANDARD_CLASSES
2393
+
2394
+ /* A class for easily testing the inner/outer object callbacks. */
2395
+ typedef struct ComplexObject {
2396
+ JSBool isInner;
2397
+ JSBool frozen;
2398
+ JSObject *inner;
2399
+ JSObject *outer;
2400
+ } ComplexObject;
2401
+
2402
+ static JSObject *
2403
+ split_create_outer(JSContext *cx);
2404
+
2405
+ static JSObject *
2406
+ split_create_inner(JSContext *cx, JSObject *outer);
2407
+
2408
+ static ComplexObject *
2409
+ split_get_private(JSContext *cx, JSObject *obj);
2410
+
2411
+ static JSBool
2412
+ split_addProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
2413
+ {
2414
+ ComplexObject *cpx;
2415
+ jsid asId;
2416
+
2417
+ cpx = split_get_private(cx, obj);
2418
+ if (!cpx)
2419
+ return JS_TRUE;
2420
+ if (!cpx->isInner && cpx->inner) {
2421
+ /* Make sure to define this property on the inner object. */
2422
+ if (!JS_ValueToId(cx, *vp, &asId))
2423
+ return JS_FALSE;
2424
+ return OBJ_DEFINE_PROPERTY(cx, cpx->inner, asId, *vp, NULL, NULL,
2425
+ JSPROP_ENUMERATE, NULL);
2426
+ }
2427
+ return JS_TRUE;
2428
+ }
2429
+
2430
+ static JSBool
2431
+ split_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
2432
+ {
2433
+ ComplexObject *cpx;
2434
+
2435
+ cpx = split_get_private(cx, obj);
2436
+ if (!cpx)
2437
+ return JS_TRUE;
2438
+ if (!cpx->isInner && cpx->inner) {
2439
+ if (JSVAL_IS_STRING(id)) {
2440
+ JSString *str;
2441
+
2442
+ str = JSVAL_TO_STRING(id);
2443
+ return JS_GetUCProperty(cx, cpx->inner, JS_GetStringChars(str),
2444
+ JS_GetStringLength(str), vp);
2445
+ }
2446
+ if (JSVAL_IS_INT(id))
2447
+ return JS_GetElement(cx, cpx->inner, JSVAL_TO_INT(id), vp);
2448
+ return JS_TRUE;
2449
+ }
2450
+
2451
+ return JS_TRUE;
2452
+ }
2453
+
2454
+ static JSBool
2455
+ split_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
2456
+ {
2457
+ ComplexObject *cpx;
2458
+
2459
+ cpx = split_get_private(cx, obj);
2460
+ if (!cpx)
2461
+ return JS_TRUE;
2462
+ if (!cpx->isInner && cpx->inner) {
2463
+ if (JSVAL_IS_STRING(id)) {
2464
+ JSString *str;
2465
+
2466
+ str = JSVAL_TO_STRING(id);
2467
+ return JS_SetUCProperty(cx, cpx->inner, JS_GetStringChars(str),
2468
+ JS_GetStringLength(str), vp);
2469
+ }
2470
+ if (JSVAL_IS_INT(id))
2471
+ return JS_SetElement(cx, cpx->inner, JSVAL_TO_INT(id), vp);
2472
+ return JS_TRUE;
2473
+ }
2474
+
2475
+ return JS_TRUE;
2476
+ }
2477
+
2478
+ static JSBool
2479
+ split_delProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
2480
+ {
2481
+ ComplexObject *cpx;
2482
+ jsid asId;
2483
+
2484
+ cpx = split_get_private(cx, obj);
2485
+ if (!cpx)
2486
+ return JS_TRUE;
2487
+ if (!cpx->isInner && cpx->inner) {
2488
+ /* Make sure to define this property on the inner object. */
2489
+ if (!JS_ValueToId(cx, *vp, &asId))
2490
+ return JS_FALSE;
2491
+ return OBJ_DELETE_PROPERTY(cx, cpx->inner, asId, vp);
2492
+ }
2493
+ return JS_TRUE;
2494
+ }
2495
+
2496
+ static JSBool
2497
+ split_enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
2498
+ jsval *statep, jsid *idp)
2499
+ {
2500
+ ComplexObject *cpx;
2501
+ JSObject *iterator;
2502
+
2503
+ switch (enum_op) {
2504
+ case JSENUMERATE_INIT:
2505
+ cpx = (ComplexObject *) JS_GetPrivate(cx, obj);
2506
+
2507
+ if (!cpx->isInner && cpx->inner)
2508
+ obj = cpx->inner;
2509
+
2510
+ iterator = JS_NewPropertyIterator(cx, obj);
2511
+ if (!iterator)
2512
+ return JS_FALSE;
2513
+
2514
+ *statep = OBJECT_TO_JSVAL(iterator);
2515
+ if (idp)
2516
+ *idp = JSVAL_ZERO;
2517
+ break;
2518
+
2519
+ case JSENUMERATE_NEXT:
2520
+ iterator = (JSObject*)JSVAL_TO_OBJECT(*statep);
2521
+ if (!JS_NextProperty(cx, iterator, idp))
2522
+ return JS_FALSE;
2523
+
2524
+ if (!JSVAL_IS_VOID(*idp))
2525
+ break;
2526
+ /* Fall through. */
2527
+
2528
+ case JSENUMERATE_DESTROY:
2529
+ /* Let GC at our iterator object. */
2530
+ *statep = JSVAL_NULL;
2531
+ break;
2532
+ }
2533
+
2534
+ return JS_TRUE;
2535
+ }
2536
+
2537
+ static JSBool
2538
+ split_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
2539
+ JSObject **objp)
2540
+ {
2541
+ ComplexObject *cpx;
2542
+
2543
+ cpx = split_get_private(cx, obj);
2544
+ if (!cpx)
2545
+ return JS_TRUE;
2546
+ if (!cpx->isInner && cpx->inner) {
2547
+ jsid asId;
2548
+ JSProperty *prop;
2549
+
2550
+ if (!JS_ValueToId(cx, id, &asId))
2551
+ return JS_FALSE;
2552
+
2553
+ if (!OBJ_LOOKUP_PROPERTY(cx, cpx->inner, asId, objp, &prop))
2554
+ return JS_FALSE;
2555
+ if (prop)
2556
+ OBJ_DROP_PROPERTY(cx, cpx->inner, prop);
2557
+
2558
+ return JS_TRUE;
2559
+ }
2560
+
2561
+ #ifdef LAZY_STANDARD_CLASSES
2562
+ if (!(flags & JSRESOLVE_ASSIGNING)) {
2563
+ JSBool resolved;
2564
+
2565
+ if (!JS_ResolveStandardClass(cx, obj, id, &resolved))
2566
+ return JS_FALSE;
2567
+
2568
+ if (resolved) {
2569
+ *objp = obj;
2570
+ return JS_TRUE;
2571
+ }
2572
+ }
2573
+ #endif
2574
+
2575
+ /* XXX For additional realism, let's resolve some random property here. */
2576
+ return JS_TRUE;
2577
+ }
2578
+
2579
+ static void
2580
+ split_finalize(JSContext *cx, JSObject *obj)
2581
+ {
2582
+ JS_free(cx, JS_GetPrivate(cx, obj));
2583
+ }
2584
+
2585
+ static uint32
2586
+ split_mark(JSContext *cx, JSObject *obj, void *arg)
2587
+ {
2588
+ ComplexObject *cpx;
2589
+
2590
+ cpx = (ComplexObject *) JS_GetPrivate(cx, obj);
2591
+
2592
+ if (!cpx->isInner && cpx->inner) {
2593
+ /* Mark the inner object. */
2594
+ JS_MarkGCThing(cx, cpx->inner, "ComplexObject.inner", arg);
2595
+ }
2596
+
2597
+ return 0;
2598
+ }
2599
+
2600
+ static JSObject *
2601
+ split_outerObject(JSContext *cx, JSObject *obj)
2602
+ {
2603
+ ComplexObject *cpx;
2604
+
2605
+ cpx = (ComplexObject *) JS_GetPrivate(cx, obj);
2606
+ return cpx->isInner ? cpx->outer : obj;
2607
+ }
2608
+
2609
+ static JSBool
2610
+ split_equality(JSContext *cx, JSObject *obj, jsval v, JSBool *bp);
2611
+
2612
+ static JSObject *
2613
+ split_innerObject(JSContext *cx, JSObject *obj)
2614
+ {
2615
+ ComplexObject *cpx;
2616
+
2617
+ cpx = (ComplexObject *) JS_GetPrivate(cx, obj);
2618
+ if (cpx->frozen) {
2619
+ JS_ASSERT(!cpx->isInner);
2620
+ return obj;
2621
+ }
2622
+ return !cpx->isInner ? cpx->inner : obj;
2623
+ }
2624
+
2625
+ static JSExtendedClass split_global_class = {
2626
+ {"split_global",
2627
+ JSCLASS_NEW_RESOLVE | JSCLASS_NEW_ENUMERATE | JSCLASS_HAS_PRIVATE |
2628
+ JSCLASS_GLOBAL_FLAGS | JSCLASS_IS_EXTENDED,
2629
+ split_addProperty, split_delProperty,
2630
+ split_getProperty, split_setProperty,
2631
+ (JSEnumerateOp)split_enumerate,
2632
+ (JSResolveOp)split_resolve,
2633
+ JS_ConvertStub, split_finalize,
2634
+ NULL, NULL, NULL, NULL, NULL, NULL,
2635
+ split_mark, NULL},
2636
+ split_equality, split_outerObject, split_innerObject,
2637
+ NULL, NULL, NULL, NULL, NULL
2638
+ };
2639
+
2640
+ static JSBool
2641
+ split_equality(JSContext *cx, JSObject *obj, jsval v, JSBool *bp)
2642
+ {
2643
+ *bp = JS_FALSE;
2644
+ if (JSVAL_IS_PRIMITIVE(v))
2645
+ return JS_TRUE;
2646
+
2647
+ JSObject *obj2 = JSVAL_TO_OBJECT(v);
2648
+ if (JS_GET_CLASS(cx, obj2) != &split_global_class.base)
2649
+ return JS_TRUE;
2650
+
2651
+ ComplexObject *cpx = (ComplexObject *) JS_GetPrivate(cx, obj2);
2652
+ JS_ASSERT(!cpx->isInner);
2653
+
2654
+ ComplexObject *ourCpx = (ComplexObject *) JS_GetPrivate(cx, obj);
2655
+ JS_ASSERT(!ourCpx->isInner);
2656
+
2657
+ *bp = (cpx == ourCpx);
2658
+ return JS_TRUE;
2659
+ }
2660
+
2661
+ JSObject *
2662
+ split_create_outer(JSContext *cx)
2663
+ {
2664
+ ComplexObject *cpx;
2665
+ JSObject *obj;
2666
+
2667
+ cpx = (ComplexObject *) JS_malloc(cx, sizeof *obj);
2668
+ if (!cpx)
2669
+ return NULL;
2670
+ cpx->isInner = JS_FALSE;
2671
+ cpx->frozen = JS_TRUE;
2672
+ cpx->inner = NULL;
2673
+ cpx->outer = NULL;
2674
+
2675
+ obj = JS_NewObject(cx, &split_global_class.base, NULL, NULL);
2676
+ if (!obj || !JS_SetParent(cx, obj, NULL)) {
2677
+ JS_free(cx, cpx);
2678
+ return NULL;
2679
+ }
2680
+
2681
+ if (!JS_SetPrivate(cx, obj, cpx)) {
2682
+ JS_free(cx, cpx);
2683
+ return NULL;
2684
+ }
2685
+
2686
+ return obj;
2687
+ }
2688
+
2689
+ static JSObject *
2690
+ split_create_inner(JSContext *cx, JSObject *outer)
2691
+ {
2692
+ ComplexObject *cpx, *outercpx;
2693
+ JSObject *obj;
2694
+
2695
+ JS_ASSERT(JS_GET_CLASS(cx, outer) == &split_global_class.base);
2696
+
2697
+ cpx = (ComplexObject *) JS_malloc(cx, sizeof *cpx);
2698
+ if (!cpx)
2699
+ return NULL;
2700
+ cpx->isInner = JS_TRUE;
2701
+ cpx->frozen = JS_FALSE;
2702
+ cpx->inner = NULL;
2703
+ cpx->outer = outer;
2704
+
2705
+ obj = JS_NewObject(cx, &split_global_class.base, NULL, NULL);
2706
+ if (!obj || !JS_SetParent(cx, obj, NULL) || !JS_SetPrivate(cx, obj, cpx)) {
2707
+ JS_free(cx, cpx);
2708
+ return NULL;
2709
+ }
2710
+
2711
+ outercpx = (ComplexObject *) JS_GetPrivate(cx, outer);
2712
+ outercpx->inner = obj;
2713
+ outercpx->frozen = JS_FALSE;
2714
+
2715
+ return obj;
2716
+ }
2717
+
2718
+ static ComplexObject *
2719
+ split_get_private(JSContext *cx, JSObject *obj)
2720
+ {
2721
+ do {
2722
+ if (JS_GET_CLASS(cx, obj) == &split_global_class.base)
2723
+ return (ComplexObject *) JS_GetPrivate(cx, obj);
2724
+ obj = JS_GetParent(cx, obj);
2725
+ } while (obj);
2726
+
2727
+ return NULL;
2728
+ }
2729
+
2730
+ static JSBool
2731
+ sandbox_enumerate(JSContext *cx, JSObject *obj)
2732
+ {
2733
+ jsval v;
2734
+ JSBool b;
2735
+
2736
+ if (!JS_GetProperty(cx, obj, "lazy", &v) || !JS_ValueToBoolean(cx, v, &b))
2737
+ return JS_FALSE;
2738
+ return !b || JS_EnumerateStandardClasses(cx, obj);
2739
+ }
2740
+
2741
+ static JSBool
2742
+ sandbox_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
2743
+ JSObject **objp)
2744
+ {
2745
+ jsval v;
2746
+ JSBool b, resolved;
2747
+
2748
+ if (!JS_GetProperty(cx, obj, "lazy", &v) || !JS_ValueToBoolean(cx, v, &b))
2749
+ return JS_FALSE;
2750
+ if (b && (flags & JSRESOLVE_ASSIGNING) == 0) {
2751
+ if (!JS_ResolveStandardClass(cx, obj, id, &resolved))
2752
+ return JS_FALSE;
2753
+ if (resolved) {
2754
+ *objp = obj;
2755
+ return JS_TRUE;
2756
+ }
2757
+ }
2758
+ *objp = NULL;
2759
+ return JS_TRUE;
2760
+ }
2761
+
2762
+ static JSClass sandbox_class = {
2763
+ "sandbox",
2764
+ JSCLASS_NEW_RESOLVE,
2765
+ JS_PropertyStub, JS_PropertyStub,
2766
+ JS_PropertyStub, JS_PropertyStub,
2767
+ sandbox_enumerate, (JSResolveOp)sandbox_resolve,
2768
+ JS_ConvertStub, JS_FinalizeStub,
2769
+ JSCLASS_NO_OPTIONAL_MEMBERS
2770
+ };
2771
+
2772
+ static JSBool
2773
+ EvalInContext(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
2774
+ jsval *rval)
2775
+ {
2776
+ JSString *str;
2777
+ JSObject *sobj;
2778
+ JSContext *scx;
2779
+ const jschar *src;
2780
+ size_t srclen;
2781
+ JSBool lazy, ok;
2782
+ jsval v;
2783
+ JSStackFrame *fp;
2784
+
2785
+ sobj = NULL;
2786
+ if (!JS_ConvertArguments(cx, argc, argv, "S / o", &str, &sobj))
2787
+ return JS_FALSE;
2788
+
2789
+ WITH_LOCKED_CONTEXT_LIST(
2790
+ scx = JS_NewContext(JS_GetRuntime(cx), gStackChunkSize)
2791
+ );
2792
+ if (!scx) {
2793
+ JS_ReportOutOfMemory(cx);
2794
+ return JS_FALSE;
2795
+ }
2796
+ JS_SetOptions(scx, JS_GetOptions(cx));
2797
+
2798
+ JS_BeginRequest(scx);
2799
+ src = JS_GetStringChars(str);
2800
+ srclen = JS_GetStringLength(str);
2801
+ lazy = JS_FALSE;
2802
+ if (srclen == 4 &&
2803
+ src[0] == 'l' && src[1] == 'a' && src[2] == 'z' && src[3] == 'y') {
2804
+ lazy = JS_TRUE;
2805
+ srclen = 0;
2806
+ }
2807
+
2808
+ if (!sobj) {
2809
+ sobj = JS_NewObject(scx, &sandbox_class, NULL, NULL);
2810
+ if (!sobj || (!lazy && !JS_InitStandardClasses(scx, sobj))) {
2811
+ ok = JS_FALSE;
2812
+ goto out;
2813
+ }
2814
+ v = BOOLEAN_TO_JSVAL(lazy);
2815
+ ok = JS_SetProperty(cx, sobj, "lazy", &v);
2816
+ if (!ok)
2817
+ goto out;
2818
+ }
2819
+
2820
+ if (srclen == 0) {
2821
+ *rval = OBJECT_TO_JSVAL(sobj);
2822
+ ok = JS_TRUE;
2823
+ } else {
2824
+ fp = JS_GetScriptedCaller(cx, NULL);
2825
+ JS_SetGlobalObject(scx, sobj);
2826
+ JS_ToggleOptions(scx, JSOPTION_DONT_REPORT_UNCAUGHT);
2827
+ ok = JS_EvaluateUCScript(scx, sobj, src, srclen,
2828
+ fp->script->filename,
2829
+ JS_PCToLineNumber(cx, fp->script,
2830
+ fp->regs->pc),
2831
+ rval);
2832
+ if (!ok) {
2833
+ if (JS_GetPendingException(scx, &v))
2834
+ JS_SetPendingException(cx, v);
2835
+ else
2836
+ JS_ReportOutOfMemory(cx);
2837
+ }
2838
+ }
2839
+
2840
+ out:
2841
+ JS_EndRequest(scx);
2842
+ WITH_LOCKED_CONTEXT_LIST(
2843
+ JS_DestroyContextNoGC(scx)
2844
+ );
2845
+ return ok;
2846
+ }
2847
+
2848
+ static JSBool
2849
+ ShapeOf(JSContext *cx, uintN argc, jsval *vp)
2850
+ {
2851
+ jsval v = JS_ARGV(cx, vp)[0];
2852
+ if (!JSVAL_IS_OBJECT(v)) {
2853
+ JS_ReportError(cx, "shapeOf: object expected");
2854
+ return JS_FALSE;
2855
+ }
2856
+ JSObject *obj = JSVAL_TO_OBJECT(v);
2857
+ if (!obj) {
2858
+ *vp = JSVAL_ZERO;
2859
+ return JS_TRUE;
2860
+ }
2861
+ if (!OBJ_IS_NATIVE(obj)) {
2862
+ *vp = INT_TO_JSVAL(-1);
2863
+ return JS_TRUE;
2864
+ }
2865
+ return JS_NewNumberValue(cx, OBJ_SHAPE(obj), vp);
2866
+ }
2867
+
2868
+ #ifdef JS_THREADSAFE
2869
+
2870
+ /*
2871
+ * Check that t1 comes strictly before t2. The function correctly deals with
2872
+ * PRIntervalTime wrap-around between t2 and t1 assuming that t2 and t1 stays
2873
+ * within INT32_MAX from each other. We use MAX_TIMEOUT_INTERVAL to enforce
2874
+ * this restriction.
2875
+ */
2876
+ static bool
2877
+ IsBefore(PRIntervalTime t1, PRIntervalTime t2)
2878
+ {
2879
+ return int32(t1 - t2) < 0;
2880
+ }
2881
+
2882
+ static JSBool
2883
+ Sleep_fn(JSContext *cx, uintN argc, jsval *vp)
2884
+ {
2885
+ PRIntervalTime t_ticks;
2886
+
2887
+ if (argc == 0) {
2888
+ t_ticks = 0;
2889
+ } else {
2890
+ jsdouble t_secs;
2891
+
2892
+ if (!JS_ValueToNumber(cx, argc == 0 ? JSVAL_VOID : vp[2], &t_secs))
2893
+ return JS_FALSE;
2894
+
2895
+ /* NB: The next condition also filter out NaNs. */
2896
+ if (!(t_secs <= MAX_TIMEOUT_INTERVAL)) {
2897
+ JS_ReportError(cx, "Excessive sleep interval");
2898
+ return JS_FALSE;
2899
+ }
2900
+ t_ticks = (t_secs <= 0.0)
2901
+ ? 0
2902
+ : PRIntervalTime(PR_TicksPerSecond() * t_secs);
2903
+ }
2904
+ if (t_ticks == 0) {
2905
+ JS_YieldRequest(cx);
2906
+ } else {
2907
+ jsrefcount rc = JS_SuspendRequest(cx);
2908
+ PR_Lock(gWatchdogLock);
2909
+ PRIntervalTime to_wakeup = PR_IntervalNow() + t_ticks;
2910
+ for (;;) {
2911
+ PR_WaitCondVar(gSleepWakeup, t_ticks);
2912
+ if (gCanceled)
2913
+ break;
2914
+ PRIntervalTime now = PR_IntervalNow();
2915
+ if (!IsBefore(now, to_wakeup))
2916
+ break;
2917
+ t_ticks = to_wakeup - now;
2918
+ }
2919
+ PR_Unlock(gWatchdogLock);
2920
+ JS_ResumeRequest(cx, rc);
2921
+ }
2922
+ return !gCanceled;
2923
+ }
2924
+
2925
+ typedef struct ScatterThreadData ScatterThreadData;
2926
+ typedef struct ScatterData ScatterData;
2927
+
2928
+ typedef enum ScatterStatus {
2929
+ SCATTER_WAIT,
2930
+ SCATTER_GO,
2931
+ SCATTER_CANCEL
2932
+ } ScatterStatus;
2933
+
2934
+ struct ScatterData {
2935
+ ScatterThreadData *threads;
2936
+ jsval *results;
2937
+ PRLock *lock;
2938
+ PRCondVar *cvar;
2939
+ ScatterStatus status;
2940
+ };
2941
+
2942
+ struct ScatterThreadData {
2943
+ jsint index;
2944
+ ScatterData *shared;
2945
+ PRThread *thr;
2946
+ JSContext *cx;
2947
+ jsval fn;
2948
+ };
2949
+
2950
+ static void
2951
+ DoScatteredWork(JSContext *cx, ScatterThreadData *td)
2952
+ {
2953
+ jsval *rval = &td->shared->results[td->index];
2954
+
2955
+ if (!JS_CallFunctionValue(cx, NULL, td->fn, 0, NULL, rval)) {
2956
+ *rval = JSVAL_VOID;
2957
+ JS_GetPendingException(cx, rval);
2958
+ JS_ClearPendingException(cx);
2959
+ }
2960
+ }
2961
+
2962
+ static void
2963
+ RunScatterThread(void *arg)
2964
+ {
2965
+ int stackDummy;
2966
+ ScatterThreadData *td;
2967
+ ScatterStatus st;
2968
+ JSContext *cx;
2969
+
2970
+ if (PR_FAILURE == PR_SetThreadPrivate(gStackBaseThreadIndex, &stackDummy))
2971
+ return;
2972
+
2973
+ td = (ScatterThreadData *)arg;
2974
+ cx = td->cx;
2975
+
2976
+ /* Wait for our signal. */
2977
+ PR_Lock(td->shared->lock);
2978
+ while ((st = td->shared->status) == SCATTER_WAIT)
2979
+ PR_WaitCondVar(td->shared->cvar, PR_INTERVAL_NO_TIMEOUT);
2980
+ PR_Unlock(td->shared->lock);
2981
+
2982
+ if (st == SCATTER_CANCEL)
2983
+ return;
2984
+
2985
+ /* We are good to go. */
2986
+ JS_SetContextThread(cx);
2987
+ SetThreadStackLimit(cx);
2988
+ JS_BeginRequest(cx);
2989
+ DoScatteredWork(cx, td);
2990
+ JS_EndRequest(cx);
2991
+ JS_ClearContextThread(cx);
2992
+ }
2993
+
2994
+ /*
2995
+ * scatter(fnArray) - Call each function in `fnArray` without arguments, each
2996
+ * in a different thread. When all threads have finished, return an array: the
2997
+ * return values. Errors are not propagated; if any of the function calls
2998
+ * fails, the corresponding element in the results array gets the exception
2999
+ * object, if any, else (undefined).
3000
+ */
3001
+ static JSBool
3002
+ Scatter(JSContext *cx, uintN argc, jsval *vp)
3003
+ {
3004
+ jsuint i;
3005
+ jsuint n; /* number of threads */
3006
+ JSObject *inArr;
3007
+ JSObject *arr;
3008
+ ScatterData sd;
3009
+ JSBool ok;
3010
+ jsrefcount rc;
3011
+
3012
+ sd.lock = NULL;
3013
+ sd.cvar = NULL;
3014
+ sd.results = NULL;
3015
+ sd.threads = NULL;
3016
+ sd.status = SCATTER_WAIT;
3017
+
3018
+ if (argc == 0 || JSVAL_IS_PRIMITIVE(JS_ARGV(cx, vp)[0])) {
3019
+ JS_ReportError(cx, "the first argument must be an object");
3020
+ goto fail;
3021
+ }
3022
+
3023
+ inArr = JSVAL_TO_OBJECT(JS_ARGV(cx, vp)[0]);
3024
+ ok = JS_GetArrayLength(cx, inArr, &n);
3025
+ if (!ok)
3026
+ goto out;
3027
+ if (n == 0)
3028
+ goto success;
3029
+
3030
+ sd.lock = PR_NewLock();
3031
+ if (!sd.lock)
3032
+ goto fail;
3033
+
3034
+ sd.cvar = PR_NewCondVar(sd.lock);
3035
+ if (!sd.cvar)
3036
+ goto fail;
3037
+
3038
+ sd.results = (jsval *) malloc(n * sizeof(jsval));
3039
+ if (!sd.results)
3040
+ goto fail;
3041
+ for (i = 0; i < n; i++) {
3042
+ sd.results[i] = JSVAL_VOID;
3043
+ ok = JS_AddRoot(cx, &sd.results[i]);
3044
+ if (!ok) {
3045
+ while (i-- > 0)
3046
+ JS_RemoveRoot(cx, &sd.results[i]);
3047
+ free(sd.results);
3048
+ sd.results = NULL;
3049
+ goto fail;
3050
+ }
3051
+ }
3052
+
3053
+ sd.threads = (ScatterThreadData *) malloc(n * sizeof(ScatterThreadData));
3054
+ if (!sd.threads)
3055
+ goto fail;
3056
+ for (i = 0; i < n; i++) {
3057
+ sd.threads[i].index = i;
3058
+ sd.threads[i].shared = &sd;
3059
+ sd.threads[i].thr = NULL;
3060
+ sd.threads[i].cx = NULL;
3061
+ sd.threads[i].fn = JSVAL_NULL;
3062
+
3063
+ ok = JS_AddRoot(cx, &sd.threads[i].fn);
3064
+ if (ok && !JS_GetElement(cx, inArr, (jsint) i, &sd.threads[i].fn)) {
3065
+ JS_RemoveRoot(cx, &sd.threads[i].fn);
3066
+ ok = JS_FALSE;
3067
+ }
3068
+ if (!ok) {
3069
+ while (i-- > 0)
3070
+ JS_RemoveRoot(cx, &sd.threads[i].fn);
3071
+ free(sd.threads);
3072
+ sd.threads = NULL;
3073
+ goto fail;
3074
+ }
3075
+ }
3076
+
3077
+ for (i = 1; i < n; i++) {
3078
+ JSContext *newcx;
3079
+ WITH_LOCKED_CONTEXT_LIST(
3080
+ newcx = JS_NewContext(JS_GetRuntime(cx), 8192)
3081
+ );
3082
+ if (!newcx)
3083
+ goto fail;
3084
+ JS_SetGlobalObject(newcx, JS_GetGlobalObject(cx));
3085
+ JS_ClearContextThread(newcx);
3086
+ sd.threads[i].cx = newcx;
3087
+ }
3088
+
3089
+ for (i = 1; i < n; i++) {
3090
+ PRThread *t = PR_CreateThread(PR_USER_THREAD,
3091
+ RunScatterThread,
3092
+ &sd.threads[i],
3093
+ PR_PRIORITY_NORMAL,
3094
+ PR_GLOBAL_THREAD,
3095
+ PR_JOINABLE_THREAD,
3096
+ 0);
3097
+ if (!t) {
3098
+ /* Failed to start thread. */
3099
+ PR_Lock(sd.lock);
3100
+ sd.status = SCATTER_CANCEL;
3101
+ PR_NotifyAllCondVar(sd.cvar);
3102
+ PR_Unlock(sd.lock);
3103
+ while (i-- > 1)
3104
+ PR_JoinThread(sd.threads[i].thr);
3105
+ goto fail;
3106
+ }
3107
+
3108
+ sd.threads[i].thr = t;
3109
+ }
3110
+ PR_Lock(sd.lock);
3111
+ sd.status = SCATTER_GO;
3112
+ PR_NotifyAllCondVar(sd.cvar);
3113
+ PR_Unlock(sd.lock);
3114
+
3115
+ DoScatteredWork(cx, &sd.threads[0]);
3116
+
3117
+ rc = JS_SuspendRequest(cx);
3118
+ for (i = 1; i < n; i++) {
3119
+ PR_JoinThread(sd.threads[i].thr);
3120
+ }
3121
+ JS_ResumeRequest(cx, rc);
3122
+
3123
+ success:
3124
+ arr = JS_NewArrayObject(cx, n, sd.results);
3125
+ if (!arr)
3126
+ goto fail;
3127
+ *vp = OBJECT_TO_JSVAL(arr);
3128
+ ok = JS_TRUE;
3129
+
3130
+ out:
3131
+ if (sd.threads) {
3132
+ JSContext *acx;
3133
+
3134
+ for (i = 0; i < n; i++) {
3135
+ JS_RemoveRoot(cx, &sd.threads[i].fn);
3136
+ acx = sd.threads[i].cx;
3137
+ if (acx) {
3138
+ JS_SetContextThread(acx);
3139
+ WITH_LOCKED_CONTEXT_LIST(
3140
+ JS_DestroyContext(acx)
3141
+ );
3142
+ }
3143
+ }
3144
+ free(sd.threads);
3145
+ }
3146
+ if (sd.results) {
3147
+ for (i = 0; i < n; i++)
3148
+ JS_RemoveRoot(cx, &sd.results[i]);
3149
+ free(sd.results);
3150
+ }
3151
+ if (sd.cvar)
3152
+ PR_DestroyCondVar(sd.cvar);
3153
+ if (sd.lock)
3154
+ PR_DestroyLock(sd.lock);
3155
+
3156
+ return ok;
3157
+
3158
+ fail:
3159
+ ok = JS_FALSE;
3160
+ goto out;
3161
+ }
3162
+
3163
+ static bool
3164
+ InitWatchdog(JSRuntime *rt)
3165
+ {
3166
+ JS_ASSERT(!gWatchdogThread);
3167
+ gWatchdogLock = PR_NewLock();
3168
+ if (gWatchdogLock) {
3169
+ gWatchdogWakeup = PR_NewCondVar(gWatchdogLock);
3170
+ if (gWatchdogWakeup) {
3171
+ gSleepWakeup = PR_NewCondVar(gWatchdogLock);
3172
+ if (gSleepWakeup)
3173
+ return true;
3174
+ PR_DestroyCondVar(gWatchdogWakeup);
3175
+ }
3176
+ PR_DestroyLock(gWatchdogLock);
3177
+ }
3178
+ return false;
3179
+ }
3180
+
3181
+ static void
3182
+ KillWatchdog()
3183
+ {
3184
+ PRThread *thread;
3185
+
3186
+ PR_Lock(gWatchdogLock);
3187
+ thread = gWatchdogThread;
3188
+ if (thread) {
3189
+ /*
3190
+ * The watchdog thread is running, tell it to terminate waking it up
3191
+ * if necessary.
3192
+ */
3193
+ gWatchdogThread = NULL;
3194
+ PR_NotifyCondVar(gWatchdogWakeup);
3195
+ }
3196
+ PR_Unlock(gWatchdogLock);
3197
+ if (thread)
3198
+ PR_JoinThread(thread);
3199
+ PR_DestroyCondVar(gSleepWakeup);
3200
+ PR_DestroyCondVar(gWatchdogWakeup);
3201
+ PR_DestroyLock(gWatchdogLock);
3202
+ }
3203
+
3204
+ static void
3205
+ WatchdogMain(void *arg)
3206
+ {
3207
+ JSRuntime *rt = (JSRuntime *) arg;
3208
+
3209
+ PR_Lock(gWatchdogLock);
3210
+ while (gWatchdogThread) {
3211
+ PRIntervalTime now = PR_IntervalNow();
3212
+ if (gWatchdogHasTimeout && !IsBefore(now, gWatchdogTimeout)) {
3213
+ /*
3214
+ * The timeout has just expired. Trigger the operation callback
3215
+ * outside the lock.
3216
+ */
3217
+ gWatchdogHasTimeout = false;
3218
+ PR_Unlock(gWatchdogLock);
3219
+ CancelExecution(rt);
3220
+ PR_Lock(gWatchdogLock);
3221
+
3222
+ /* Wake up any threads doing sleep. */
3223
+ PR_NotifyAllCondVar(gSleepWakeup);
3224
+ } else {
3225
+ PRIntervalTime sleepDuration = gWatchdogHasTimeout
3226
+ ? gWatchdogTimeout - now
3227
+ : PR_INTERVAL_NO_TIMEOUT;
3228
+ #ifdef DEBUG
3229
+ PRStatus status =
3230
+ #endif
3231
+ PR_WaitCondVar(gWatchdogWakeup, sleepDuration);
3232
+ JS_ASSERT(status == PR_SUCCESS);
3233
+ }
3234
+ }
3235
+ PR_Unlock(gWatchdogLock);
3236
+ }
3237
+
3238
+ static bool
3239
+ ScheduleWatchdog(JSRuntime *rt, jsdouble t)
3240
+ {
3241
+ if (t <= 0) {
3242
+ PR_Lock(gWatchdogLock);
3243
+ gWatchdogHasTimeout = false;
3244
+ PR_Unlock(gWatchdogLock);
3245
+ return true;
3246
+ }
3247
+
3248
+ PRIntervalTime interval = PRIntervalTime(ceil(t * PR_TicksPerSecond()));
3249
+ PRIntervalTime timeout = PR_IntervalNow() + interval;
3250
+ PR_Lock(gWatchdogLock);
3251
+ if (!gWatchdogThread) {
3252
+ JS_ASSERT(!gWatchdogHasTimeout);
3253
+ gWatchdogThread = PR_CreateThread(PR_USER_THREAD,
3254
+ WatchdogMain,
3255
+ rt,
3256
+ PR_PRIORITY_NORMAL,
3257
+ PR_LOCAL_THREAD,
3258
+ PR_JOINABLE_THREAD,
3259
+ 0);
3260
+ if (!gWatchdogThread) {
3261
+ PR_Unlock(gWatchdogLock);
3262
+ return false;
3263
+ }
3264
+ } else if (!gWatchdogHasTimeout || IsBefore(timeout, gWatchdogTimeout)) {
3265
+ PR_NotifyCondVar(gWatchdogWakeup);
3266
+ }
3267
+ gWatchdogHasTimeout = true;
3268
+ gWatchdogTimeout = timeout;
3269
+ PR_Unlock(gWatchdogLock);
3270
+ return true;
3271
+ }
3272
+
3273
+ #else /* !JS_THREADSAFE */
3274
+
3275
+ #ifdef XP_WIN
3276
+ static HANDLE gTimerHandle = 0;
3277
+
3278
+ VOID CALLBACK
3279
+ TimerCallback(PVOID lpParameter, BOOLEAN TimerOrWaitFired)
3280
+ {
3281
+ CancelExecution((JSRuntime *) lpParameter);
3282
+ }
3283
+
3284
+ #else
3285
+
3286
+ static void
3287
+ AlarmHandler(int sig)
3288
+ {
3289
+ CancelExecution(gRuntime);
3290
+ }
3291
+
3292
+ #endif
3293
+
3294
+ static bool
3295
+ InitWatchdog(JSRuntime *rt)
3296
+ {
3297
+ gRuntime = rt;
3298
+ return true;
3299
+ }
3300
+
3301
+ static void
3302
+ KillWatchdog()
3303
+ {
3304
+ ScheduleWatchdog(gRuntime, -1);
3305
+ }
3306
+
3307
+ static bool
3308
+ ScheduleWatchdog(JSRuntime *rt, jsdouble t)
3309
+ {
3310
+ #ifdef XP_WIN
3311
+ if (gTimerHandle) {
3312
+ DeleteTimerQueueTimer(NULL, gTimerHandle, NULL);
3313
+ gTimerHandle = 0;
3314
+ }
3315
+ if (t > 0 &&
3316
+ !CreateTimerQueueTimer(&gTimerHandle,
3317
+ NULL,
3318
+ (WAITORTIMERCALLBACK)TimerCallback,
3319
+ rt,
3320
+ DWORD(ceil(t * 1000.0)),
3321
+ 0,
3322
+ WT_EXECUTEINTIMERTHREAD | WT_EXECUTEONLYONCE)) {
3323
+ gTimerHandle = 0;
3324
+ return false;
3325
+ }
3326
+ #else
3327
+ /* FIXME: use setitimer when available for sub-second resolution. */
3328
+ if (t <= 0) {
3329
+ alarm(0);
3330
+ signal(SIGALRM, NULL);
3331
+ } else {
3332
+ signal(SIGALRM, AlarmHandler); /* set the Alarm signal capture */
3333
+ alarm(ceil(t));
3334
+ }
3335
+ #endif
3336
+ return true;
3337
+ }
3338
+
3339
+ #endif /* !JS_THREADSAFE */
3340
+
3341
+ static void
3342
+ CancelExecution(JSRuntime *rt)
3343
+ {
3344
+ gCanceled = true;
3345
+ if (gExitCode == 0)
3346
+ gExitCode = EXITCODE_TIMEOUT;
3347
+ JS_TriggerAllOperationCallbacks(rt);
3348
+
3349
+ static const char msg[] = "Script runs for too long, terminating.\n";
3350
+ #if defined(XP_UNIX) && !defined(JS_THREADSAFE)
3351
+ /* It is not safe to call fputs from signals. */
3352
+ write(2, msg, sizeof(msg) - 1);
3353
+ #else
3354
+ fputs(msg, stderr);
3355
+ #endif
3356
+ }
3357
+
3358
+ static JSBool
3359
+ SetTimeoutValue(JSContext *cx, jsdouble t)
3360
+ {
3361
+ /* NB: The next condition also filter out NaNs. */
3362
+ if (!(t <= MAX_TIMEOUT_INTERVAL)) {
3363
+ JS_ReportError(cx, "Excessive timeout value");
3364
+ return JS_FALSE;
3365
+ }
3366
+ gTimeoutInterval = t;
3367
+ if (!ScheduleWatchdog(cx->runtime, t)) {
3368
+ JS_ReportError(cx, "Failed to create the watchdog");
3369
+ return JS_FALSE;
3370
+ }
3371
+ return JS_TRUE;
3372
+ }
3373
+
3374
+ static JSBool
3375
+ Timeout(JSContext *cx, uintN argc, jsval *vp)
3376
+ {
3377
+ if (argc == 0)
3378
+ return JS_NewNumberValue(cx, gTimeoutInterval, vp);
3379
+
3380
+ if (argc > 1) {
3381
+ JS_ReportError(cx, "Wrong number of arguments");
3382
+ return JS_FALSE;
3383
+ }
3384
+
3385
+ jsdouble t;
3386
+ if (!JS_ValueToNumber(cx, JS_ARGV(cx, vp)[0], &t))
3387
+ return JS_FALSE;
3388
+
3389
+ *vp = JSVAL_VOID;
3390
+ return SetTimeoutValue(cx, t);
3391
+ }
3392
+
3393
+ static JSBool
3394
+ Elapsed(JSContext *cx, uintN argc, jsval *vp)
3395
+ {
3396
+ if (argc == 0) {
3397
+ double d = 0.0;
3398
+ JSShellContextData *data = GetContextData(cx);
3399
+ if (data)
3400
+ d = js_IntervalNow() - data->startTime;
3401
+ return JS_NewNumberValue(cx, d, vp);
3402
+ }
3403
+ JS_ReportError(cx, "Wrong number of arguments");
3404
+ return JS_FALSE;
3405
+ }
3406
+
3407
+ #ifdef XP_UNIX
3408
+
3409
+ #include <fcntl.h>
3410
+ #include <sys/stat.h>
3411
+
3412
+ /*
3413
+ * Returns a JS_malloc'd string (that the caller needs to JS_free)
3414
+ * containing the directory (non-leaf) part of |from| prepended to |leaf|.
3415
+ * If |from| is empty or a leaf, MakeAbsolutePathname returns a copy of leaf.
3416
+ * Returns NULL to indicate an error.
3417
+ */
3418
+ static char *
3419
+ MakeAbsolutePathname(JSContext *cx, const char *from, const char *leaf)
3420
+ {
3421
+ size_t dirlen;
3422
+ char *dir;
3423
+ const char *slash = NULL, *cp;
3424
+
3425
+ cp = from;
3426
+ while (*cp) {
3427
+ if (*cp == '/'
3428
+ #ifdef XP_WIN
3429
+ || *cp == '\\'
3430
+ #endif
3431
+ ) {
3432
+ slash = cp;
3433
+ }
3434
+
3435
+ ++cp;
3436
+ }
3437
+
3438
+ if (!slash) {
3439
+ /* We were given a leaf or |from| was empty. */
3440
+ return JS_strdup(cx, leaf);
3441
+ }
3442
+
3443
+ /* Else, we were given a real pathname, return that + the leaf. */
3444
+ dirlen = slash - from + 1;
3445
+ dir = (char*) JS_malloc(cx, dirlen + strlen(leaf) + 1);
3446
+ if (!dir)
3447
+ return NULL;
3448
+
3449
+ strncpy(dir, from, dirlen);
3450
+ strcpy(dir + dirlen, leaf); /* Note: we can't use strcat here. */
3451
+
3452
+ return dir;
3453
+ }
3454
+
3455
+ #endif // XP_UNIX
3456
+
3457
+ static JSBool
3458
+ Snarf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
3459
+ {
3460
+ JSString *str;
3461
+ const char *filename;
3462
+ const char *pathname;
3463
+ JSStackFrame *fp;
3464
+ JSBool ok;
3465
+ size_t cc, len;
3466
+ char *buf;
3467
+ FILE *file;
3468
+
3469
+ str = JS_ValueToString(cx, argv[0]);
3470
+ if (!str)
3471
+ return JS_FALSE;
3472
+ filename = JS_GetStringBytes(str);
3473
+
3474
+ /* Get the currently executing script's name. */
3475
+ fp = JS_GetScriptedCaller(cx, NULL);
3476
+ JS_ASSERT(fp && fp->script->filename);
3477
+ #ifdef XP_UNIX
3478
+ pathname = MakeAbsolutePathname(cx, fp->script->filename, filename);
3479
+ if (!pathname)
3480
+ return JS_FALSE;
3481
+ #else
3482
+ pathname = filename;
3483
+ #endif
3484
+
3485
+ ok = JS_FALSE;
3486
+ len = 0;
3487
+ buf = NULL;
3488
+ file = fopen(pathname, "rb");
3489
+ if (!file) {
3490
+ JS_ReportError(cx, "can't open %s: %s", pathname, strerror(errno));
3491
+ } else {
3492
+ if (fseek(file, 0, SEEK_END) == EOF) {
3493
+ JS_ReportError(cx, "can't seek end of %s", pathname);
3494
+ } else {
3495
+ len = ftell(file);
3496
+ if (fseek(file, 0, SEEK_SET) == EOF) {
3497
+ JS_ReportError(cx, "can't seek start of %s", pathname);
3498
+ } else {
3499
+ buf = (char*) JS_malloc(cx, len + 1);
3500
+ if (buf) {
3501
+ cc = fread(buf, 1, len, file);
3502
+ if (cc != len) {
3503
+ JS_free(cx, buf);
3504
+ JS_ReportError(cx, "can't read %s: %s", pathname,
3505
+ (ptrdiff_t(cc) < 0) ? strerror(errno) : "short read");
3506
+ } else {
3507
+ len = (size_t)cc;
3508
+ ok = JS_TRUE;
3509
+ }
3510
+ }
3511
+ }
3512
+ }
3513
+ fclose(file);
3514
+ }
3515
+ JS_free(cx, (void*)pathname);
3516
+ if (!ok) {
3517
+ JS_free(cx, buf);
3518
+ return ok;
3519
+ }
3520
+
3521
+ buf[len] = '\0';
3522
+ str = JS_NewString(cx, buf, len);
3523
+ if (!str) {
3524
+ JS_free(cx, buf);
3525
+ return JS_FALSE;
3526
+ }
3527
+ *rval = STRING_TO_JSVAL(str);
3528
+ return JS_TRUE;
3529
+ }
3530
+
3531
+ /* We use a mix of JS_FS and JS_FN to test both kinds of natives. */
3532
+ static JSFunctionSpec shell_functions[] = {
3533
+ JS_FS("version", Version, 0,0,0),
3534
+ JS_FS("options", Options, 0,0,0),
3535
+ JS_FS("load", Load, 1,0,0),
3536
+ JS_FN("readline", ReadLine, 0,0),
3537
+ JS_FN("print", Print, 0,0),
3538
+ JS_FS("help", Help, 0,0,0),
3539
+ JS_FS("quit", Quit, 0,0,0),
3540
+ JS_FN("assertEq", AssertEq, 2,0),
3541
+ JS_FN("gc", GC, 0,0),
3542
+ JS_FN("gcparam", GCParameter, 2,0),
3543
+ JS_FN("countHeap", CountHeap, 0,0),
3544
+ #ifdef JS_GC_ZEAL
3545
+ JS_FN("gczeal", GCZeal, 1,0),
3546
+ #endif
3547
+ JS_FS("trap", Trap, 3,0,0),
3548
+ JS_FS("untrap", Untrap, 2,0,0),
3549
+ JS_FS("line2pc", LineToPC, 0,0,0),
3550
+ JS_FS("pc2line", PCToLine, 0,0,0),
3551
+ JS_FN("stackQuota", StackQuota, 0,0),
3552
+ JS_FS("stringsAreUTF8", StringsAreUTF8, 0,0,0),
3553
+ JS_FS("testUTF8", TestUTF8, 1,0,0),
3554
+ JS_FS("throwError", ThrowError, 0,0,0),
3555
+ #ifdef DEBUG
3556
+ JS_FS("dis", Disassemble, 1,0,0),
3557
+ JS_FS("disfile", DisassFile, 1,0,0),
3558
+ JS_FS("dissrc", DisassWithSrc, 1,0,0),
3559
+ JS_FN("dumpHeap", DumpHeap, 0,0),
3560
+ JS_FS("notes", Notes, 1,0,0),
3561
+ JS_FS("tracing", Tracing, 0,0,0),
3562
+ JS_FS("stats", DumpStats, 1,0,0),
3563
+ #endif
3564
+ #ifdef TEST_CVTARGS
3565
+ JS_FS("cvtargs", ConvertArgs, 0,0,12),
3566
+ #endif
3567
+ JS_FN("build", BuildDate, 0,0),
3568
+ JS_FS("clear", Clear, 0,0,0),
3569
+ JS_FN("intern", Intern, 1,0),
3570
+ JS_FS("clone", Clone, 1,0,0),
3571
+ JS_FS("seal", Seal, 1,0,1),
3572
+ JS_FN("getpda", GetPDA, 1,0),
3573
+ JS_FN("getslx", GetSLX, 1,0),
3574
+ JS_FN("toint32", ToInt32, 1,0),
3575
+ JS_FS("evalcx", EvalInContext, 1,0,0),
3576
+ JS_FN("shapeOf", ShapeOf, 1,0),
3577
+ #ifdef MOZ_SHARK
3578
+ JS_FS("startShark", js_StartShark, 0,0,0),
3579
+ JS_FS("stopShark", js_StopShark, 0,0,0),
3580
+ JS_FS("connectShark", js_ConnectShark, 0,0,0),
3581
+ JS_FS("disconnectShark",js_DisconnectShark, 0,0,0),
3582
+ #endif
3583
+ #ifdef MOZ_CALLGRIND
3584
+ JS_FS("startCallgrind", js_StartCallgrind, 0,0,0),
3585
+ JS_FS("stopCallgrind", js_StopCallgrind, 0,0,0),
3586
+ JS_FS("dumpCallgrind", js_DumpCallgrind, 1,0,0),
3587
+ #endif
3588
+ #ifdef MOZ_VTUNE
3589
+ JS_FS("startVtune", js_StartVtune, 1,0,0),
3590
+ JS_FS("stopVtune", js_StopVtune, 0,0,0),
3591
+ JS_FS("pauseVtune", js_PauseVtune, 0,0,0),
3592
+ JS_FS("resumeVtune", js_ResumeVtune, 0,0,0),
3593
+ #endif
3594
+ #ifdef DEBUG_ARRAYS
3595
+ JS_FS("arrayInfo", js_ArrayInfo, 1,0,0),
3596
+ #endif
3597
+ #ifdef JS_THREADSAFE
3598
+ JS_FN("sleep", Sleep_fn, 1,0),
3599
+ JS_FN("scatter", Scatter, 1,0),
3600
+ #endif
3601
+ JS_FS("snarf", Snarf, 0,0,0),
3602
+ JS_FN("timeout", Timeout, 1,0),
3603
+ JS_FN("elapsed", Elapsed, 0,0),
3604
+ JS_FS_END
3605
+ };
3606
+
3607
+ static const char shell_help_header[] =
3608
+ "Command Description\n"
3609
+ "======= ===========\n";
3610
+
3611
+ static const char *const shell_help_messages[] = {
3612
+ "version([number]) Get or set JavaScript version number",
3613
+ "options([option ...]) Get or toggle JavaScript options",
3614
+ "load(['foo.js' ...]) Load files named by string arguments",
3615
+ "readline() Read a single line from stdin",
3616
+ "print([exp ...]) Evaluate and print expressions",
3617
+ "help([name ...]) Display usage and help messages",
3618
+ "quit() Quit the shell",
3619
+ "assertEq(actual, expected)\n"
3620
+ " Throw if the two arguments are not ===",
3621
+ "gc() Run the garbage collector",
3622
+ "gcparam(name, value)\n"
3623
+ " Wrapper for JS_SetGCParameter. The name must be either 'maxBytes' or\n"
3624
+ " 'maxMallocBytes' and the value must be convertable to a positive uint32",
3625
+ "countHeap([start[, kind]])\n"
3626
+ " Count the number of live GC things in the heap or things reachable from\n"
3627
+ " start when it is given and is not null. kind is either 'all' (default) to\n"
3628
+ " count all things or one of 'object', 'double', 'string', 'function',\n"
3629
+ " 'qname', 'namespace', 'xml' to count only things of that kind",
3630
+ #ifdef JS_GC_ZEAL
3631
+ "gczeal(level) How zealous the garbage collector should be",
3632
+ #endif
3633
+ "trap([fun, [pc,]] exp) Trap bytecode execution",
3634
+ "untrap(fun[, pc]) Remove a trap",
3635
+ "line2pc([fun,] line) Map line number to PC",
3636
+ "pc2line(fun[, pc]) Map PC to line number",
3637
+ "stackQuota([number]) Query/set script stack quota",
3638
+ "stringsAreUTF8() Check if strings are UTF-8 encoded",
3639
+ "testUTF8(mode) Perform UTF-8 tests (modes are 1 to 4)",
3640
+ "throwError() Throw an error from JS_ReportError",
3641
+ #ifdef DEBUG
3642
+ "dis([fun]) Disassemble functions into bytecodes",
3643
+ "disfile('foo.js') Disassemble script file into bytecodes",
3644
+ "dissrc([fun]) Disassemble functions with source lines",
3645
+ "dumpHeap([fileName[, start[, toFind[, maxDepth[, toIgnore]]]]])\n"
3646
+ " Interface to JS_DumpHeap with output sent to file",
3647
+ "notes([fun]) Show source notes for functions",
3648
+ "tracing([true|false|filename]) Turn bytecode execution tracing on/off.\n"
3649
+ " With filename, send to file.\n",
3650
+ "stats([string ...]) Dump 'arena', 'atom', 'global' stats",
3651
+ #endif
3652
+ #ifdef TEST_CVTARGS
3653
+ "cvtargs(arg1..., arg12) Test argument formatter",
3654
+ #endif
3655
+ "build() Show build date and time",
3656
+ "clear([obj]) Clear properties of object",
3657
+ "intern(str) Internalize str in the atom table",
3658
+ "clone(fun[, scope]) Clone function object",
3659
+ "seal(obj[, deep]) Seal object, or object graph if deep",
3660
+ "getpda(obj) Get the property descriptors for obj",
3661
+ "getslx(obj) Get script line extent",
3662
+ "toint32(n) Testing hook for JS_ValueToInt32",
3663
+ "evalcx(s[, o])\n"
3664
+ " Evaluate s in optional sandbox object o\n"
3665
+ " if (s == '' && !o) return new o with eager standard classes\n"
3666
+ " if (s == 'lazy' && !o) return new o with lazy standard classes",
3667
+ "shapeOf(obj) Get the shape of obj (an implementation detail)",
3668
+ #ifdef MOZ_SHARK
3669
+ "startShark() Start a Shark session.\n"
3670
+ " Shark must be running with programatic sampling",
3671
+ "stopShark() Stop a running Shark session",
3672
+ "connectShark() Connect to Shark.\n"
3673
+ " The -k switch does this automatically",
3674
+ "disconnectShark() Disconnect from Shark",
3675
+ #endif
3676
+ #ifdef MOZ_CALLGRIND
3677
+ "startCallgrind() Start callgrind instrumentation",
3678
+ "stopCallgrind() Stop callgrind instumentation",
3679
+ "dumpCallgrind([name]) Dump callgrind counters",
3680
+ #endif
3681
+ #ifdef MOZ_VTUNE
3682
+ "startVtune([filename]) Start vtune instrumentation",
3683
+ "stopVtune() Stop vtune instumentation",
3684
+ "pauseVtune() Pause vtune collection",
3685
+ "resumeVtune() Resume vtune collection",
3686
+ #endif
3687
+ #ifdef DEBUG_ARRAYS
3688
+ "arrayInfo(a1, a2, ...) Report statistics about arrays",
3689
+ #endif
3690
+ #ifdef JS_THREADSAFE
3691
+ "sleep(dt) Sleep for dt seconds",
3692
+ "scatter(fns) Call functions concurrently (ignoring errors)",
3693
+ #endif
3694
+ "snarf(filename) Read filename into returned string",
3695
+ "timeout([seconds])\n"
3696
+ " Get/Set the limit in seconds for the execution time for the current context.\n"
3697
+ " A negative value (default) means that the execution time is unlimited.",
3698
+ "elapsed() Execution time elapsed for the current context.\n",
3699
+ };
3700
+
3701
+ /* Help messages must match shell functions. */
3702
+ JS_STATIC_ASSERT(JS_ARRAY_LENGTH(shell_help_messages) + 1 ==
3703
+ JS_ARRAY_LENGTH(shell_functions));
3704
+
3705
+ #ifdef DEBUG
3706
+ static void
3707
+ CheckHelpMessages()
3708
+ {
3709
+ const char *const *m;
3710
+ const char *lp;
3711
+
3712
+ /* Each message must begin with "function_name(" prefix. */
3713
+ for (m = shell_help_messages; m != JS_ARRAY_END(shell_help_messages); ++m) {
3714
+ lp = strchr(*m, '(');
3715
+ JS_ASSERT(lp);
3716
+ JS_ASSERT(memcmp(shell_functions[m - shell_help_messages].name,
3717
+ *m, lp - *m) == 0);
3718
+ }
3719
+ }
3720
+ #else
3721
+ # define CheckHelpMessages() ((void) 0)
3722
+ #endif
3723
+
3724
+ static JSBool
3725
+ Help(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
3726
+ {
3727
+ uintN i, j;
3728
+ int did_header, did_something;
3729
+ JSType type;
3730
+ JSFunction *fun;
3731
+ JSString *str;
3732
+ const char *bytes;
3733
+
3734
+ fprintf(gOutFile, "%s\n", JS_GetImplementationVersion());
3735
+ if (argc == 0) {
3736
+ fputs(shell_help_header, gOutFile);
3737
+ for (i = 0; shell_functions[i].name; i++)
3738
+ fprintf(gOutFile, "%s\n", shell_help_messages[i]);
3739
+ } else {
3740
+ did_header = 0;
3741
+ for (i = 0; i < argc; i++) {
3742
+ did_something = 0;
3743
+ type = JS_TypeOfValue(cx, argv[i]);
3744
+ if (type == JSTYPE_FUNCTION) {
3745
+ fun = JS_ValueToFunction(cx, argv[i]);
3746
+ str = fun->atom ? ATOM_TO_STRING(fun->atom) : NULL;
3747
+ } else if (type == JSTYPE_STRING) {
3748
+ str = JSVAL_TO_STRING(argv[i]);
3749
+ } else {
3750
+ str = NULL;
3751
+ }
3752
+ if (str) {
3753
+ bytes = JS_GetStringBytes(str);
3754
+ for (j = 0; shell_functions[j].name; j++) {
3755
+ if (!strcmp(bytes, shell_functions[j].name)) {
3756
+ if (!did_header) {
3757
+ did_header = 1;
3758
+ fputs(shell_help_header, gOutFile);
3759
+ }
3760
+ did_something = 1;
3761
+ fprintf(gOutFile, "%s\n", shell_help_messages[j]);
3762
+ break;
3763
+ }
3764
+ }
3765
+ }
3766
+ if (!did_something) {
3767
+ str = JS_ValueToString(cx, argv[i]);
3768
+ if (!str)
3769
+ return JS_FALSE;
3770
+ fprintf(gErrFile, "Sorry, no help for %s\n",
3771
+ JS_GetStringBytes(str));
3772
+ }
3773
+ }
3774
+ }
3775
+ return JS_TRUE;
3776
+ }
3777
+
3778
+ static JSObject *
3779
+ split_setup(JSContext *cx)
3780
+ {
3781
+ JSObject *outer, *inner, *arguments;
3782
+
3783
+ outer = split_create_outer(cx);
3784
+ if (!outer)
3785
+ return NULL;
3786
+ JS_SetGlobalObject(cx, outer);
3787
+
3788
+ inner = split_create_inner(cx, outer);
3789
+ if (!inner)
3790
+ return NULL;
3791
+
3792
+ if (!JS_DefineFunctions(cx, inner, shell_functions))
3793
+ return NULL;
3794
+ JS_ClearScope(cx, outer);
3795
+
3796
+ /* Create a dummy arguments object. */
3797
+ arguments = JS_NewArrayObject(cx, 0, NULL);
3798
+ if (!arguments ||
3799
+ !JS_DefineProperty(cx, inner, "arguments", OBJECT_TO_JSVAL(arguments),
3800
+ NULL, NULL, 0)) {
3801
+ return NULL;
3802
+ }
3803
+
3804
+ #ifndef LAZY_STANDARD_CLASSES
3805
+ if (!JS_InitStandardClasses(cx, inner))
3806
+ return NULL;
3807
+ #endif
3808
+
3809
+ return inner;
3810
+ }
3811
+
3812
+ /*
3813
+ * Define a JS object called "it". Give it class operations that printf why
3814
+ * they're being called for tutorial purposes.
3815
+ */
3816
+ enum its_tinyid {
3817
+ ITS_COLOR, ITS_HEIGHT, ITS_WIDTH, ITS_FUNNY, ITS_ARRAY, ITS_RDONLY,
3818
+ ITS_CUSTOM, ITS_CUSTOMRDONLY
3819
+ };
3820
+
3821
+ static JSBool
3822
+ its_getter(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
3823
+ {
3824
+ jsval *val = (jsval *) JS_GetPrivate(cx, obj);
3825
+ *vp = val ? *val : JSVAL_VOID;
3826
+ return JS_TRUE;
3827
+ }
3828
+
3829
+ static JSBool
3830
+ its_setter(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
3831
+ {
3832
+ jsval *val = (jsval *) JS_GetPrivate(cx, obj);
3833
+ if (val) {
3834
+ *val = *vp;
3835
+ return JS_TRUE;
3836
+ }
3837
+
3838
+ val = new jsval;
3839
+ if (!val) {
3840
+ JS_ReportOutOfMemory(cx);
3841
+ return JS_FALSE;
3842
+ }
3843
+
3844
+ if (!JS_AddRoot(cx, val)) {
3845
+ delete val;
3846
+ return JS_FALSE;
3847
+ }
3848
+
3849
+ if (!JS_SetPrivate(cx, obj, (void*)val)) {
3850
+ JS_RemoveRoot(cx, val);
3851
+ delete val;
3852
+ return JS_FALSE;
3853
+ }
3854
+
3855
+ *val = *vp;
3856
+ return JS_TRUE;
3857
+ }
3858
+
3859
+ static JSPropertySpec its_props[] = {
3860
+ {"color", ITS_COLOR, JSPROP_ENUMERATE, NULL, NULL},
3861
+ {"height", ITS_HEIGHT, JSPROP_ENUMERATE, NULL, NULL},
3862
+ {"width", ITS_WIDTH, JSPROP_ENUMERATE, NULL, NULL},
3863
+ {"funny", ITS_FUNNY, JSPROP_ENUMERATE, NULL, NULL},
3864
+ {"array", ITS_ARRAY, JSPROP_ENUMERATE, NULL, NULL},
3865
+ {"rdonly", ITS_RDONLY, JSPROP_READONLY, NULL, NULL},
3866
+ {"custom", ITS_CUSTOM, JSPROP_ENUMERATE,
3867
+ its_getter, its_setter},
3868
+ {"customRdOnly", ITS_CUSTOMRDONLY, JSPROP_ENUMERATE | JSPROP_READONLY,
3869
+ its_getter, its_setter},
3870
+ {NULL,0,0,NULL,NULL}
3871
+ };
3872
+
3873
+ static JSBool
3874
+ its_item(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
3875
+ {
3876
+ *rval = OBJECT_TO_JSVAL(obj);
3877
+ if (argc != 0)
3878
+ JS_SetCallReturnValue2(cx, argv[0]);
3879
+ return JS_TRUE;
3880
+ }
3881
+
3882
+ static JSBool
3883
+ its_bindMethod(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
3884
+ jsval *rval)
3885
+ {
3886
+ char *name;
3887
+ JSObject *method;
3888
+
3889
+ if (!JS_ConvertArguments(cx, argc, argv, "so", &name, &method))
3890
+ return JS_FALSE;
3891
+
3892
+ *rval = OBJECT_TO_JSVAL(method);
3893
+
3894
+ if (JS_TypeOfValue(cx, *rval) != JSTYPE_FUNCTION) {
3895
+ JSString *valstr = JS_ValueToString(cx, *rval);
3896
+ if (valstr) {
3897
+ JS_ReportError(cx, "can't bind method %s to non-callable object %s",
3898
+ name, JS_GetStringBytes(valstr));
3899
+ }
3900
+ return JS_FALSE;
3901
+ }
3902
+
3903
+ if (!JS_DefineProperty(cx, obj, name, *rval, NULL, NULL, JSPROP_ENUMERATE))
3904
+ return JS_FALSE;
3905
+
3906
+ return JS_SetParent(cx, method, obj);
3907
+ }
3908
+
3909
+ static JSFunctionSpec its_methods[] = {
3910
+ {"item", its_item, 0,0,0},
3911
+ {"bindMethod", its_bindMethod, 2,0,0},
3912
+ {NULL,NULL,0,0,0}
3913
+ };
3914
+
3915
+ #ifdef JSD_LOWLEVEL_SOURCE
3916
+ /*
3917
+ * This facilitates sending source to JSD (the debugger system) in the shell
3918
+ * where the source is loaded using the JSFILE hack in jsscan. The function
3919
+ * below is used as a callback for the jsdbgapi JS_SetSourceHandler hook.
3920
+ * A more normal embedding (e.g. mozilla) loads source itself and can send
3921
+ * source directly to JSD without using this hook scheme.
3922
+ */
3923
+ static void
3924
+ SendSourceToJSDebugger(const char *filename, uintN lineno,
3925
+ jschar *str, size_t length,
3926
+ void **listenerTSData, JSDContext* jsdc)
3927
+ {
3928
+ JSDSourceText *jsdsrc = (JSDSourceText *) *listenerTSData;
3929
+
3930
+ if (!jsdsrc) {
3931
+ if (!filename)
3932
+ filename = "typein";
3933
+ if (1 == lineno) {
3934
+ jsdsrc = JSD_NewSourceText(jsdc, filename);
3935
+ } else {
3936
+ jsdsrc = JSD_FindSourceForURL(jsdc, filename);
3937
+ if (jsdsrc && JSD_SOURCE_PARTIAL !=
3938
+ JSD_GetSourceStatus(jsdc, jsdsrc)) {
3939
+ jsdsrc = NULL;
3940
+ }
3941
+ }
3942
+ }
3943
+ if (jsdsrc) {
3944
+ jsdsrc = JSD_AppendUCSourceText(jsdc,jsdsrc, str, length,
3945
+ JSD_SOURCE_PARTIAL);
3946
+ }
3947
+ *listenerTSData = jsdsrc;
3948
+ }
3949
+ #endif /* JSD_LOWLEVEL_SOURCE */
3950
+
3951
+ static JSBool its_noisy; /* whether to be noisy when finalizing it */
3952
+ static JSBool its_enum_fail;/* whether to fail when enumerating it */
3953
+
3954
+ static JSBool
3955
+ its_addProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
3956
+ {
3957
+ if (its_noisy) {
3958
+ fprintf(gOutFile, "adding its property %s,",
3959
+ JS_GetStringBytes(JS_ValueToString(cx, id)));
3960
+ fprintf(gOutFile, " initial value %s\n",
3961
+ JS_GetStringBytes(JS_ValueToString(cx, *vp)));
3962
+ }
3963
+ return JS_TRUE;
3964
+ }
3965
+
3966
+ static JSBool
3967
+ its_delProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
3968
+ {
3969
+ if (its_noisy) {
3970
+ fprintf(gOutFile, "deleting its property %s,",
3971
+ JS_GetStringBytes(JS_ValueToString(cx, id)));
3972
+ fprintf(gOutFile, " current value %s\n",
3973
+ JS_GetStringBytes(JS_ValueToString(cx, *vp)));
3974
+ }
3975
+ return JS_TRUE;
3976
+ }
3977
+
3978
+ static JSBool
3979
+ its_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
3980
+ {
3981
+ if (its_noisy) {
3982
+ fprintf(gOutFile, "getting its property %s,",
3983
+ JS_GetStringBytes(JS_ValueToString(cx, id)));
3984
+ fprintf(gOutFile, " current value %s\n",
3985
+ JS_GetStringBytes(JS_ValueToString(cx, *vp)));
3986
+ }
3987
+ return JS_TRUE;
3988
+ }
3989
+
3990
+ static JSBool
3991
+ its_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
3992
+ {
3993
+ char *str;
3994
+ if (its_noisy) {
3995
+ fprintf(gOutFile, "setting its property %s,",
3996
+ JS_GetStringBytes(JS_ValueToString(cx, id)));
3997
+ fprintf(gOutFile, " new value %s\n",
3998
+ JS_GetStringBytes(JS_ValueToString(cx, *vp)));
3999
+ }
4000
+
4001
+ if (!JSVAL_IS_STRING(id))
4002
+ return JS_TRUE;
4003
+
4004
+ str = JS_GetStringBytes(JSVAL_TO_STRING(id));
4005
+ if (!strcmp(str, "noisy"))
4006
+ return JS_ValueToBoolean(cx, *vp, &its_noisy);
4007
+ else if (!strcmp(str, "enum_fail"))
4008
+ return JS_ValueToBoolean(cx, *vp, &its_enum_fail);
4009
+
4010
+ return JS_TRUE;
4011
+ }
4012
+
4013
+ /*
4014
+ * Its enumerator, implemented using the "new" enumerate API,
4015
+ * see class flags.
4016
+ */
4017
+ static JSBool
4018
+ its_enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
4019
+ jsval *statep, jsid *idp)
4020
+ {
4021
+ JSObject *iterator;
4022
+
4023
+ switch (enum_op) {
4024
+ case JSENUMERATE_INIT:
4025
+ if (its_noisy)
4026
+ fprintf(gOutFile, "enumerate its properties\n");
4027
+
4028
+ iterator = JS_NewPropertyIterator(cx, obj);
4029
+ if (!iterator)
4030
+ return JS_FALSE;
4031
+
4032
+ *statep = OBJECT_TO_JSVAL(iterator);
4033
+ if (idp)
4034
+ *idp = JSVAL_ZERO;
4035
+ break;
4036
+
4037
+ case JSENUMERATE_NEXT:
4038
+ if (its_enum_fail) {
4039
+ JS_ReportError(cx, "its enumeration failed");
4040
+ return JS_FALSE;
4041
+ }
4042
+
4043
+ iterator = (JSObject *) JSVAL_TO_OBJECT(*statep);
4044
+ if (!JS_NextProperty(cx, iterator, idp))
4045
+ return JS_FALSE;
4046
+
4047
+ if (!JSVAL_IS_VOID(*idp))
4048
+ break;
4049
+ /* Fall through. */
4050
+
4051
+ case JSENUMERATE_DESTROY:
4052
+ /* Allow our iterator object to be GC'd. */
4053
+ *statep = JSVAL_NULL;
4054
+ break;
4055
+ }
4056
+
4057
+ return JS_TRUE;
4058
+ }
4059
+
4060
+ static JSBool
4061
+ its_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
4062
+ JSObject **objp)
4063
+ {
4064
+ if (its_noisy) {
4065
+ fprintf(gOutFile, "resolving its property %s, flags {%s,%s,%s}\n",
4066
+ JS_GetStringBytes(JS_ValueToString(cx, id)),
4067
+ (flags & JSRESOLVE_QUALIFIED) ? "qualified" : "",
4068
+ (flags & JSRESOLVE_ASSIGNING) ? "assigning" : "",
4069
+ (flags & JSRESOLVE_DETECTING) ? "detecting" : "");
4070
+ }
4071
+ return JS_TRUE;
4072
+ }
4073
+
4074
+ static JSBool
4075
+ its_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
4076
+ {
4077
+ if (its_noisy)
4078
+ fprintf(gOutFile, "converting it to %s type\n", JS_GetTypeName(cx, type));
4079
+ return JS_TRUE;
4080
+ }
4081
+
4082
+ static void
4083
+ its_finalize(JSContext *cx, JSObject *obj)
4084
+ {
4085
+ jsval *rootedVal;
4086
+ if (its_noisy)
4087
+ fprintf(gOutFile, "finalizing it\n");
4088
+ rootedVal = (jsval *) JS_GetPrivate(cx, obj);
4089
+ if (rootedVal) {
4090
+ JS_RemoveRoot(cx, rootedVal);
4091
+ JS_SetPrivate(cx, obj, NULL);
4092
+ delete rootedVal;
4093
+ }
4094
+ }
4095
+
4096
+ static JSClass its_class = {
4097
+ "It", JSCLASS_NEW_RESOLVE | JSCLASS_NEW_ENUMERATE | JSCLASS_HAS_PRIVATE,
4098
+ its_addProperty, its_delProperty, its_getProperty, its_setProperty,
4099
+ (JSEnumerateOp)its_enumerate, (JSResolveOp)its_resolve,
4100
+ its_convert, its_finalize,
4101
+ JSCLASS_NO_OPTIONAL_MEMBERS
4102
+ };
4103
+
4104
+ JSErrorFormatString jsShell_ErrorFormatString[JSErr_Limit] = {
4105
+ #define MSG_DEF(name, number, count, exception, format) \
4106
+ { format, count, JSEXN_ERR } ,
4107
+ #include "jsshell.msg"
4108
+ #undef MSG_DEF
4109
+ };
4110
+
4111
+ static const JSErrorFormatString *
4112
+ my_GetErrorMessage(void *userRef, const char *locale, const uintN errorNumber)
4113
+ {
4114
+ if ((errorNumber > 0) && (errorNumber < JSShellErr_Limit))
4115
+ return &jsShell_ErrorFormatString[errorNumber];
4116
+ return NULL;
4117
+ }
4118
+
4119
+ static void
4120
+ my_ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
4121
+ {
4122
+ int i, j, k, n;
4123
+ char *prefix, *tmp;
4124
+ const char *ctmp;
4125
+
4126
+ if (!report) {
4127
+ fprintf(gErrFile, "%s\n", message);
4128
+ return;
4129
+ }
4130
+
4131
+ /* Conditionally ignore reported warnings. */
4132
+ if (JSREPORT_IS_WARNING(report->flags) && !reportWarnings)
4133
+ return;
4134
+
4135
+ prefix = NULL;
4136
+ if (report->filename)
4137
+ prefix = JS_smprintf("%s:", report->filename);
4138
+ if (report->lineno) {
4139
+ tmp = prefix;
4140
+ prefix = JS_smprintf("%s%u: ", tmp ? tmp : "", report->lineno);
4141
+ JS_free(cx, tmp);
4142
+ }
4143
+ if (JSREPORT_IS_WARNING(report->flags)) {
4144
+ tmp = prefix;
4145
+ prefix = JS_smprintf("%s%swarning: ",
4146
+ tmp ? tmp : "",
4147
+ JSREPORT_IS_STRICT(report->flags) ? "strict " : "");
4148
+ JS_free(cx, tmp);
4149
+ }
4150
+
4151
+ /* embedded newlines -- argh! */
4152
+ while ((ctmp = strchr(message, '\n')) != 0) {
4153
+ ctmp++;
4154
+ if (prefix)
4155
+ fputs(prefix, gErrFile);
4156
+ fwrite(message, 1, ctmp - message, gErrFile);
4157
+ message = ctmp;
4158
+ }
4159
+
4160
+ /* If there were no filename or lineno, the prefix might be empty */
4161
+ if (prefix)
4162
+ fputs(prefix, gErrFile);
4163
+ fputs(message, gErrFile);
4164
+
4165
+ if (!report->linebuf) {
4166
+ fputc('\n', gErrFile);
4167
+ goto out;
4168
+ }
4169
+
4170
+ /* report->linebuf usually ends with a newline. */
4171
+ n = strlen(report->linebuf);
4172
+ fprintf(gErrFile, ":\n%s%s%s%s",
4173
+ prefix,
4174
+ report->linebuf,
4175
+ (n > 0 && report->linebuf[n-1] == '\n') ? "" : "\n",
4176
+ prefix);
4177
+ n = PTRDIFF(report->tokenptr, report->linebuf, char);
4178
+ for (i = j = 0; i < n; i++) {
4179
+ if (report->linebuf[i] == '\t') {
4180
+ for (k = (j + 8) & ~7; j < k; j++) {
4181
+ fputc('.', gErrFile);
4182
+ }
4183
+ continue;
4184
+ }
4185
+ fputc('.', gErrFile);
4186
+ j++;
4187
+ }
4188
+ fputs("^\n", gErrFile);
4189
+ out:
4190
+ if (!JSREPORT_IS_WARNING(report->flags)) {
4191
+ if (report->errorNumber == JSMSG_OUT_OF_MEMORY) {
4192
+ gExitCode = EXITCODE_OUT_OF_MEMORY;
4193
+ } else {
4194
+ gExitCode = EXITCODE_RUNTIME_ERROR;
4195
+ }
4196
+ }
4197
+ JS_free(cx, prefix);
4198
+ }
4199
+
4200
+ #if defined(SHELL_HACK) && defined(DEBUG) && defined(XP_UNIX)
4201
+ static JSBool
4202
+ Exec(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
4203
+ {
4204
+ JSFunction *fun;
4205
+ const char *name, **nargv;
4206
+ uintN i, nargc;
4207
+ JSString *str;
4208
+ pid_t pid;
4209
+ int status;
4210
+
4211
+ fun = JS_ValueToFunction(cx, argv[-2]);
4212
+ if (!fun)
4213
+ return JS_FALSE;
4214
+ if (!fun->atom)
4215
+ return JS_TRUE;
4216
+ name = JS_GetStringBytes(ATOM_TO_STRING(fun->atom));
4217
+ nargc = 1 + argc;
4218
+ nargv = JS_malloc(cx, (nargc + 1) * sizeof(char *));
4219
+ if (!nargv)
4220
+ return JS_FALSE;
4221
+ nargv[0] = name;
4222
+ for (i = 1; i < nargc; i++) {
4223
+ str = JS_ValueToString(cx, argv[i-1]);
4224
+ if (!str) {
4225
+ JS_free(cx, nargv);
4226
+ return JS_FALSE;
4227
+ }
4228
+ nargv[i] = JS_GetStringBytes(str);
4229
+ }
4230
+ nargv[nargc] = 0;
4231
+ pid = fork();
4232
+ switch (pid) {
4233
+ case -1:
4234
+ perror("js");
4235
+ break;
4236
+ case 0:
4237
+ (void) execvp(name, (char **)nargv);
4238
+ perror("js");
4239
+ exit(127);
4240
+ default:
4241
+ while (waitpid(pid, &status, 0) < 0 && errno == EINTR)
4242
+ continue;
4243
+ break;
4244
+ }
4245
+ JS_free(cx, nargv);
4246
+ return JS_TRUE;
4247
+ }
4248
+ #endif
4249
+
4250
+ static JSBool
4251
+ global_enumerate(JSContext *cx, JSObject *obj)
4252
+ {
4253
+ #ifdef LAZY_STANDARD_CLASSES
4254
+ return JS_EnumerateStandardClasses(cx, obj);
4255
+ #else
4256
+ return JS_TRUE;
4257
+ #endif
4258
+ }
4259
+
4260
+ static JSBool
4261
+ global_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
4262
+ JSObject **objp)
4263
+ {
4264
+ #ifdef LAZY_STANDARD_CLASSES
4265
+ if ((flags & JSRESOLVE_ASSIGNING) == 0) {
4266
+ JSBool resolved;
4267
+
4268
+ if (!JS_ResolveStandardClass(cx, obj, id, &resolved))
4269
+ return JS_FALSE;
4270
+ if (resolved) {
4271
+ *objp = obj;
4272
+ return JS_TRUE;
4273
+ }
4274
+ }
4275
+ #endif
4276
+
4277
+ #if defined(SHELL_HACK) && defined(DEBUG) && defined(XP_UNIX)
4278
+ if ((flags & (JSRESOLVE_QUALIFIED | JSRESOLVE_ASSIGNING)) == 0) {
4279
+ /*
4280
+ * Do this expensive hack only for unoptimized Unix builds, which are
4281
+ * not used for benchmarking.
4282
+ */
4283
+ char *path, *comp, *full;
4284
+ const char *name;
4285
+ JSBool ok, found;
4286
+ JSFunction *fun;
4287
+
4288
+ if (!JSVAL_IS_STRING(id))
4289
+ return JS_TRUE;
4290
+ path = getenv("PATH");
4291
+ if (!path)
4292
+ return JS_TRUE;
4293
+ path = JS_strdup(cx, path);
4294
+ if (!path)
4295
+ return JS_FALSE;
4296
+ name = JS_GetStringBytes(JSVAL_TO_STRING(id));
4297
+ ok = JS_TRUE;
4298
+ for (comp = strtok(path, ":"); comp; comp = strtok(NULL, ":")) {
4299
+ if (*comp != '\0') {
4300
+ full = JS_smprintf("%s/%s", comp, name);
4301
+ if (!full) {
4302
+ JS_ReportOutOfMemory(cx);
4303
+ ok = JS_FALSE;
4304
+ break;
4305
+ }
4306
+ } else {
4307
+ full = (char *)name;
4308
+ }
4309
+ found = (access(full, X_OK) == 0);
4310
+ if (*comp != '\0')
4311
+ free(full);
4312
+ if (found) {
4313
+ fun = JS_DefineFunction(cx, obj, name, Exec, 0,
4314
+ JSPROP_ENUMERATE);
4315
+ ok = (fun != NULL);
4316
+ if (ok)
4317
+ *objp = obj;
4318
+ break;
4319
+ }
4320
+ }
4321
+ JS_free(cx, path);
4322
+ return ok;
4323
+ }
4324
+ #else
4325
+ return JS_TRUE;
4326
+ #endif
4327
+ }
4328
+
4329
+ JSClass global_class = {
4330
+ "global", JSCLASS_NEW_RESOLVE | JSCLASS_GLOBAL_FLAGS | JSCLASS_HAS_PRIVATE,
4331
+ JS_PropertyStub, JS_PropertyStub,
4332
+ JS_PropertyStub, JS_PropertyStub,
4333
+ global_enumerate, (JSResolveOp) global_resolve,
4334
+ JS_ConvertStub, its_finalize,
4335
+ JSCLASS_NO_OPTIONAL_MEMBERS
4336
+ };
4337
+
4338
+ static JSBool
4339
+ env_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
4340
+ {
4341
+ /* XXX porting may be easy, but these don't seem to supply setenv by default */
4342
+ #if !defined XP_BEOS && !defined XP_OS2 && !defined SOLARIS
4343
+ JSString *idstr, *valstr;
4344
+ const char *name, *value;
4345
+ int rv;
4346
+
4347
+ idstr = JS_ValueToString(cx, id);
4348
+ valstr = JS_ValueToString(cx, *vp);
4349
+ if (!idstr || !valstr)
4350
+ return JS_FALSE;
4351
+ name = JS_GetStringBytes(idstr);
4352
+ value = JS_GetStringBytes(valstr);
4353
+ #if defined XP_WIN || defined HPUX || defined OSF1 || defined IRIX
4354
+ {
4355
+ char *waste = JS_smprintf("%s=%s", name, value);
4356
+ if (!waste) {
4357
+ JS_ReportOutOfMemory(cx);
4358
+ return JS_FALSE;
4359
+ }
4360
+ rv = putenv(waste);
4361
+ #ifdef XP_WIN
4362
+ /*
4363
+ * HPUX9 at least still has the bad old non-copying putenv.
4364
+ *
4365
+ * Per mail from <s.shanmuganathan@digital.com>, OSF1 also has a putenv
4366
+ * that will crash if you pass it an auto char array (so it must place
4367
+ * its argument directly in the char *environ[] array).
4368
+ */
4369
+ free(waste);
4370
+ #endif
4371
+ }
4372
+ #else
4373
+ rv = setenv(name, value, 1);
4374
+ #endif
4375
+ if (rv < 0) {
4376
+ JS_ReportError(cx, "can't set envariable %s to %s", name, value);
4377
+ return JS_FALSE;
4378
+ }
4379
+ *vp = STRING_TO_JSVAL(valstr);
4380
+ #endif /* !defined XP_BEOS && !defined XP_OS2 && !defined SOLARIS */
4381
+ return JS_TRUE;
4382
+ }
4383
+
4384
+ static JSBool
4385
+ env_enumerate(JSContext *cx, JSObject *obj)
4386
+ {
4387
+ static JSBool reflected;
4388
+ char **evp, *name, *value;
4389
+ JSString *valstr;
4390
+ JSBool ok;
4391
+
4392
+ if (reflected)
4393
+ return JS_TRUE;
4394
+
4395
+ for (evp = (char **)JS_GetPrivate(cx, obj); (name = *evp) != NULL; evp++) {
4396
+ value = strchr(name, '=');
4397
+ if (!value)
4398
+ continue;
4399
+ *value++ = '\0';
4400
+ valstr = JS_NewStringCopyZ(cx, value);
4401
+ if (!valstr) {
4402
+ ok = JS_FALSE;
4403
+ } else {
4404
+ ok = JS_DefineProperty(cx, obj, name, STRING_TO_JSVAL(valstr),
4405
+ NULL, NULL, JSPROP_ENUMERATE);
4406
+ }
4407
+ value[-1] = '=';
4408
+ if (!ok)
4409
+ return JS_FALSE;
4410
+ }
4411
+
4412
+ reflected = JS_TRUE;
4413
+ return JS_TRUE;
4414
+ }
4415
+
4416
+ static JSBool
4417
+ env_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
4418
+ JSObject **objp)
4419
+ {
4420
+ JSString *idstr, *valstr;
4421
+ const char *name, *value;
4422
+
4423
+ if (flags & JSRESOLVE_ASSIGNING)
4424
+ return JS_TRUE;
4425
+
4426
+ idstr = JS_ValueToString(cx, id);
4427
+ if (!idstr)
4428
+ return JS_FALSE;
4429
+ name = JS_GetStringBytes(idstr);
4430
+ value = getenv(name);
4431
+ if (value) {
4432
+ valstr = JS_NewStringCopyZ(cx, value);
4433
+ if (!valstr)
4434
+ return JS_FALSE;
4435
+ if (!JS_DefineProperty(cx, obj, name, STRING_TO_JSVAL(valstr),
4436
+ NULL, NULL, JSPROP_ENUMERATE)) {
4437
+ return JS_FALSE;
4438
+ }
4439
+ *objp = obj;
4440
+ }
4441
+ return JS_TRUE;
4442
+ }
4443
+
4444
+ static JSClass env_class = {
4445
+ "environment", JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE,
4446
+ JS_PropertyStub, JS_PropertyStub,
4447
+ JS_PropertyStub, env_setProperty,
4448
+ env_enumerate, (JSResolveOp) env_resolve,
4449
+ JS_ConvertStub, JS_FinalizeStub,
4450
+ JSCLASS_NO_OPTIONAL_MEMBERS
4451
+ };
4452
+
4453
+ #ifdef NARCISSUS
4454
+
4455
+ static JSBool
4456
+ defineProperty(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
4457
+ jsval *rval)
4458
+ {
4459
+ JSString *str;
4460
+ jsval value;
4461
+ JSBool dontDelete, readOnly, dontEnum;
4462
+ const jschar *chars;
4463
+ size_t length;
4464
+ uintN attrs;
4465
+
4466
+ dontDelete = readOnly = dontEnum = JS_FALSE;
4467
+ if (!JS_ConvertArguments(cx, argc, argv, "Sv/bbb",
4468
+ &str, &value, &dontDelete, &readOnly, &dontEnum)) {
4469
+ return JS_FALSE;
4470
+ }
4471
+ chars = JS_GetStringChars(str);
4472
+ length = JS_GetStringLength(str);
4473
+ attrs = dontEnum ? 0 : JSPROP_ENUMERATE;
4474
+ if (dontDelete)
4475
+ attrs |= JSPROP_PERMANENT;
4476
+ if (readOnly)
4477
+ attrs |= JSPROP_READONLY;
4478
+ return JS_DefineUCProperty(cx, obj, chars, length, value, NULL, NULL,
4479
+ attrs);
4480
+ }
4481
+
4482
+ static JSBool
4483
+ Evaluate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
4484
+ {
4485
+ /* function evaluate(source, filename, lineno) { ... } */
4486
+ JSString *source;
4487
+ const char *filename = "";
4488
+ jsuint lineno = 0;
4489
+ uint32 oldopts;
4490
+ JSBool ok;
4491
+
4492
+ if (argc == 0) {
4493
+ *rval = JSVAL_VOID;
4494
+ return JS_TRUE;
4495
+ }
4496
+
4497
+ if (!JS_ConvertArguments(cx, argc, argv, "S/su",
4498
+ &source, &filename, &lineno)) {
4499
+ return JS_FALSE;
4500
+ }
4501
+
4502
+ oldopts = JS_GetOptions(cx);
4503
+ JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO);
4504
+ ok = JS_EvaluateUCScript(cx, obj, JS_GetStringChars(source),
4505
+ JS_GetStringLength(source), filename,
4506
+ lineno, rval);
4507
+ JS_SetOptions(cx, oldopts);
4508
+
4509
+ return ok;
4510
+ }
4511
+
4512
+ #endif /* NARCISSUS */
4513
+
4514
+ static JSBool
4515
+ ContextCallback(JSContext *cx, uintN contextOp)
4516
+ {
4517
+ JSShellContextData *data;
4518
+
4519
+ switch (contextOp) {
4520
+ case JSCONTEXT_NEW: {
4521
+ data = NewContextData();
4522
+ if (!data)
4523
+ return JS_FALSE;
4524
+ JS_SetContextPrivate(cx, data);
4525
+ JS_SetErrorReporter(cx, my_ErrorReporter);
4526
+ JS_SetVersion(cx, JSVERSION_LATEST);
4527
+ SetContextOptions(cx);
4528
+ break;
4529
+ case JSCONTEXT_DESTROY:
4530
+ data = GetContextData(cx);
4531
+ JS_SetContextPrivate(cx, NULL);
4532
+ free(data);
4533
+ break;
4534
+ }
4535
+
4536
+ default:
4537
+ break;
4538
+ }
4539
+ return JS_TRUE;
4540
+ }
4541
+
4542
+ int
4543
+ main(int argc, char **argv, char **envp)
4544
+ {
4545
+ int stackDummy;
4546
+ JSRuntime *rt;
4547
+ JSContext *cx;
4548
+ JSObject *glob, *it, *envobj;
4549
+ int result;
4550
+ #ifdef LIVECONNECT
4551
+ JavaVM *java_vm = NULL;
4552
+ #endif
4553
+ #ifdef JSDEBUGGER
4554
+ JSDContext *jsdc;
4555
+ #ifdef JSDEBUGGER_JAVA_UI
4556
+ JNIEnv *java_env;
4557
+ JSDJContext *jsdjc;
4558
+ #endif
4559
+ #ifdef JSDEBUGGER_C_UI
4560
+ JSBool jsdbc;
4561
+ #endif /* JSDEBUGGER_C_UI */
4562
+ #endif /* JSDEBUGGER */
4563
+
4564
+ CheckHelpMessages();
4565
+ setlocale(LC_ALL, "");
4566
+
4567
+ #ifdef JS_THREADSAFE
4568
+ if (PR_FAILURE == PR_NewThreadPrivateIndex(&gStackBaseThreadIndex, NULL) ||
4569
+ PR_FAILURE == PR_SetThreadPrivate(gStackBaseThreadIndex, &stackDummy)) {
4570
+ return 1;
4571
+ }
4572
+ #else
4573
+ gStackBase = (jsuword) &stackDummy;
4574
+ #endif
4575
+
4576
+ #ifdef XP_OS2
4577
+ /* these streams are normally line buffered on OS/2 and need a \n, *
4578
+ * so we need to unbuffer then to get a reasonable prompt */
4579
+ setbuf(stdout,0);
4580
+ setbuf(stderr,0);
4581
+ #endif
4582
+
4583
+ gErrFile = stderr;
4584
+ gOutFile = stdout;
4585
+
4586
+ argc--;
4587
+ argv++;
4588
+
4589
+ rt = JS_NewRuntime(64L * 1024L * 1024L);
4590
+ if (!rt)
4591
+ return 1;
4592
+
4593
+ if (!InitWatchdog(rt))
4594
+ return 1;
4595
+
4596
+ JS_SetContextCallback(rt, ContextCallback);
4597
+
4598
+ WITH_LOCKED_CONTEXT_LIST(
4599
+ cx = JS_NewContext(rt, gStackChunkSize)
4600
+ );
4601
+ if (!cx)
4602
+ return 1;
4603
+
4604
+ JS_SetGCParameterForThread(cx, JSGC_MAX_CODE_CACHE_BYTES, 16 * 1024 * 1024);
4605
+
4606
+ JS_BeginRequest(cx);
4607
+
4608
+ glob = JS_NewObject(cx, &global_class, NULL, NULL);
4609
+ if (!glob)
4610
+ return 1;
4611
+ #ifdef LAZY_STANDARD_CLASSES
4612
+ JS_SetGlobalObject(cx, glob);
4613
+ #else
4614
+ if (!JS_InitStandardClasses(cx, glob))
4615
+ return 1;
4616
+ #endif
4617
+ if (!JS_DefineFunctions(cx, glob, shell_functions))
4618
+ return 1;
4619
+
4620
+ it = JS_DefineObject(cx, glob, "it", &its_class, NULL, 0);
4621
+ if (!it)
4622
+ return 1;
4623
+ if (!JS_DefineProperties(cx, it, its_props))
4624
+ return 1;
4625
+ if (!JS_DefineFunctions(cx, it, its_methods))
4626
+ return 1;
4627
+
4628
+ if (!JS_DefineProperty(cx, glob, "custom", JSVAL_VOID, its_getter,
4629
+ its_setter, 0))
4630
+ return 1;
4631
+ if (!JS_DefineProperty(cx, glob, "customRdOnly", JSVAL_VOID, its_getter,
4632
+ its_setter, JSPROP_READONLY))
4633
+ return 1;
4634
+
4635
+ #ifdef JSDEBUGGER
4636
+ /*
4637
+ * XXX A command line option to enable debugging (or not) would be good
4638
+ */
4639
+ jsdc = JSD_DebuggerOnForUser(rt, NULL, NULL);
4640
+ if (!jsdc)
4641
+ return 1;
4642
+ JSD_JSContextInUse(jsdc, cx);
4643
+ #ifdef JSD_LOWLEVEL_SOURCE
4644
+ JS_SetSourceHandler(rt, SendSourceToJSDebugger, jsdc);
4645
+ #endif /* JSD_LOWLEVEL_SOURCE */
4646
+ #ifdef JSDEBUGGER_JAVA_UI
4647
+ jsdjc = JSDJ_CreateContext();
4648
+ if (! jsdjc)
4649
+ return 1;
4650
+ JSDJ_SetJSDContext(jsdjc, jsdc);
4651
+ java_env = JSDJ_CreateJavaVMAndStartDebugger(jsdjc);
4652
+ #ifdef LIVECONNECT
4653
+ if (java_env)
4654
+ (*java_env)->GetJavaVM(java_env, &java_vm);
4655
+ #endif
4656
+ /*
4657
+ * XXX This would be the place to wait for the debugger to start.
4658
+ * Waiting would be nice in general, but especially when a js file
4659
+ * is passed on the cmd line.
4660
+ */
4661
+ #endif /* JSDEBUGGER_JAVA_UI */
4662
+ #ifdef JSDEBUGGER_C_UI
4663
+ jsdbc = JSDB_InitDebugger(rt, jsdc, 0);
4664
+ #endif /* JSDEBUGGER_C_UI */
4665
+ #endif /* JSDEBUGGER */
4666
+
4667
+ #ifdef LIVECONNECT
4668
+ if (!JSJ_SimpleInit(cx, glob, java_vm, getenv("CLASSPATH")))
4669
+ return 1;
4670
+ #endif
4671
+
4672
+ envobj = JS_DefineObject(cx, glob, "environment", &env_class, NULL, 0);
4673
+ if (!envobj || !JS_SetPrivate(cx, envobj, envp))
4674
+ return 1;
4675
+
4676
+ #ifdef NARCISSUS
4677
+ {
4678
+ jsval v;
4679
+ static const char Object_prototype[] = "Object.prototype";
4680
+
4681
+ if (!JS_DefineFunction(cx, glob, "evaluate", Evaluate, 3, 0))
4682
+ return 1;
4683
+
4684
+ if (!JS_EvaluateScript(cx, glob,
4685
+ Object_prototype, sizeof Object_prototype - 1,
4686
+ NULL, 0, &v)) {
4687
+ return 1;
4688
+ }
4689
+ if (!JS_DefineFunction(cx, JSVAL_TO_OBJECT(v), "__defineProperty__",
4690
+ defineProperty, 5, 0)) {
4691
+ return 1;
4692
+ }
4693
+ }
4694
+ #endif
4695
+
4696
+ result = ProcessArgs(cx, glob, argv, argc);
4697
+
4698
+ #ifdef JSDEBUGGER
4699
+ if (jsdc) {
4700
+ #ifdef JSDEBUGGER_C_UI
4701
+ if (jsdbc)
4702
+ JSDB_TermDebugger(jsdc);
4703
+ #endif /* JSDEBUGGER_C_UI */
4704
+ JSD_DebuggerOff(jsdc);
4705
+ }
4706
+ #endif /* JSDEBUGGER */
4707
+
4708
+ JS_EndRequest(cx);
4709
+
4710
+ WITH_LOCKED_CONTEXT_LIST(
4711
+ JS_DestroyContext(cx)
4712
+ );
4713
+
4714
+ KillWatchdog();
4715
+
4716
+ JS_DestroyRuntime(rt);
4717
+ JS_ShutDown();
4718
+ return result;
4719
+ }