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,2996 @@
1
+ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2
+ * vim: set sw=4 ts=8 et tw=78:
3
+ *
4
+ * ***** BEGIN LICENSE BLOCK *****
5
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6
+ *
7
+ * The contents of this file are subject to the Mozilla Public License Version
8
+ * 1.1 (the "License"); you may not use this file except in compliance with
9
+ * the License. You may obtain a copy of the License at
10
+ * http://www.mozilla.org/MPL/
11
+ *
12
+ * Software distributed under the License is distributed on an "AS IS" basis,
13
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14
+ * for the specific language governing rights and limitations under the
15
+ * License.
16
+ *
17
+ * The Original Code is Mozilla Communicator client code, released
18
+ * March 31, 1998.
19
+ *
20
+ * The Initial Developer of the Original Code is
21
+ * Netscape Communications Corporation.
22
+ * Portions created by the Initial Developer are Copyright (C) 1998
23
+ * the Initial Developer. All Rights Reserved.
24
+ *
25
+ * Contributor(s):
26
+ *
27
+ * Alternatively, the contents of this file may be used under the terms of
28
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
29
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30
+ * in which case the provisions of the GPL or the LGPL are applicable instead
31
+ * of those above. If you wish to allow use of your version of this file only
32
+ * under the terms of either the GPL or the LGPL, and not to allow others to
33
+ * use your version of this file under the terms of the MPL, indicate your
34
+ * decision by deleting the provisions above and replace them with the notice
35
+ * and other provisions required by the GPL or the LGPL. If you do not delete
36
+ * the provisions above, a recipient may use your version of this file under
37
+ * the terms of any one of the MPL, the GPL or the LGPL.
38
+ *
39
+ * ***** END LICENSE BLOCK ***** */
40
+
41
+ /*
42
+ * JS array class.
43
+ *
44
+ * Array objects begin as "dense" arrays, optimized for numeric-only property
45
+ * access over a vector of slots (obj->dslots) with high load factor. Array
46
+ * methods optimize for denseness by testing that the object's class is
47
+ * &js_ArrayClass, and can then directly manipulate the slots for efficiency.
48
+ *
49
+ * We track these pieces of metadata for arrays in dense mode:
50
+ * - the array's length property as a uint32, in JSSLOT_ARRAY_LENGTH,
51
+ * - the number of indices that are filled (non-holes), in JSSLOT_ARRAY_COUNT,
52
+ * - the net number of slots starting at dslots (DENSELEN), in dslots[-1] if
53
+ * dslots is non-NULL.
54
+ *
55
+ * In dense mode, holes in the array are represented by JSVAL_HOLE. The final
56
+ * slot in fslots (JSSLOT_ARRAY_LOOKUP_HOLDER) is used to store the single jsid
57
+ * "in use" by a lookupProperty caller.
58
+ *
59
+ * Arrays are converted to use js_SlowArrayClass when any of these conditions
60
+ * are met:
61
+ * - the load factor (COUNT / DENSELEN) is less than 0.25, and there are
62
+ * more than MIN_SPARSE_INDEX slots total
63
+ * - a property is set that is non-numeric (and not "length"); or
64
+ * - a hole is filled below DENSELEN (possibly implicitly through methods like
65
+ * |reverse| or |splice|).
66
+ *
67
+ * In the latter two cases, property creation order is no longer index order,
68
+ * which necessitates use of a structure that keeps track of property creation
69
+ * order. (ES4, due to expectations baked into web script, requires that
70
+ * enumeration order be the order in which properties were created.)
71
+ *
72
+ * An alternative in the latter case (out-of-order index set) would be to
73
+ * maintain the scope to track property enumeration order, but still use
74
+ * the fast slot access. That would have the same memory cost as just using
75
+ * a js_SlowArrayClass, but have the same performance characteristics as
76
+ * a dense array for slot accesses, at some cost in code complexity.
77
+ */
78
+ #include "jsstddef.h"
79
+ #include <stdlib.h>
80
+ #include <string.h>
81
+ #include "jstypes.h"
82
+ #include "jsutil.h" /* Added by JSIFY */
83
+ #include "jsapi.h"
84
+ #include "jsarray.h"
85
+ #include "jsatom.h"
86
+ #include "jsbit.h"
87
+ #include "jsbool.h"
88
+ #include "jscntxt.h"
89
+ #include "jsconfig.h"
90
+ #include "jsdbgapi.h" /* for js_TraceWatchPoints */
91
+ #include "jsdtoa.h"
92
+ #include "jsfun.h"
93
+ #include "jsgc.h"
94
+ #include "jsinterp.h"
95
+ #include "jslock.h"
96
+ #include "jsnum.h"
97
+ #include "jsobj.h"
98
+ #include "jsscope.h"
99
+ #include "jsstr.h"
100
+
101
+ /* 2^32 - 1 as a number and a string */
102
+ #define MAXINDEX 4294967295u
103
+ #define MAXSTR "4294967295"
104
+
105
+ #define ARRAY_SET_DENSE_LENGTH(obj, max) \
106
+ (JS_ASSERT((obj)->dslots), (obj)->dslots[-1] = (jsval)(max))
107
+
108
+ /* Small arrays are dense, no matter what. */
109
+ #define MIN_SPARSE_INDEX 32
110
+
111
+ #define INDEX_TOO_BIG(index) ((index) > JS_BIT(29) - 1)
112
+ #define INDEX_TOO_SPARSE(array, index) \
113
+ (INDEX_TOO_BIG(index) || \
114
+ ((index) > ARRAY_DENSE_LENGTH(array) && (index) >= MIN_SPARSE_INDEX && \
115
+ (index) > (uint32)((array)->fslots[JSSLOT_ARRAY_COUNT] + 1) * 4))
116
+
117
+ JS_STATIC_ASSERT(sizeof(JSScopeProperty) > 4 * sizeof(jsval));
118
+
119
+ #define ENSURE_SLOW_ARRAY(cx, obj) \
120
+ (OBJ_GET_CLASS(cx, obj) == &js_SlowArrayClass || js_MakeArraySlow(cx, obj))
121
+
122
+ /*
123
+ * Determine if the id represents an array index or an XML property index.
124
+ *
125
+ * An id is an array index according to ECMA by (15.4):
126
+ *
127
+ * "Array objects give special treatment to a certain class of property names.
128
+ * A property name P (in the form of a string value) is an array index if and
129
+ * only if ToString(ToUint32(P)) is equal to P and ToUint32(P) is not equal
130
+ * to 2^32-1."
131
+ *
132
+ * In our implementation, it would be sufficient to check for JSVAL_IS_INT(id)
133
+ * except that by using signed 32-bit integers we miss the top half of the
134
+ * valid range. This function checks the string representation itself; note
135
+ * that calling a standard conversion routine might allow strings such as
136
+ * "08" or "4.0" as array indices, which they are not.
137
+ */
138
+ JSBool
139
+ js_IdIsIndex(jsval id, jsuint *indexp)
140
+ {
141
+ JSString *str;
142
+ jschar *cp;
143
+
144
+ if (JSVAL_IS_INT(id)) {
145
+ jsint i;
146
+ i = JSVAL_TO_INT(id);
147
+ if (i < 0)
148
+ return JS_FALSE;
149
+ *indexp = (jsuint)i;
150
+ return JS_TRUE;
151
+ }
152
+
153
+ /* NB: id should be a string, but jsxml.c may call us with an object id. */
154
+ if (!JSVAL_IS_STRING(id))
155
+ return JS_FALSE;
156
+
157
+ str = JSVAL_TO_STRING(id);
158
+ cp = JSSTRING_CHARS(str);
159
+ if (JS7_ISDEC(*cp) && JSSTRING_LENGTH(str) < sizeof(MAXSTR)) {
160
+ jsuint index = JS7_UNDEC(*cp++);
161
+ jsuint oldIndex = 0;
162
+ jsuint c = 0;
163
+ if (index != 0) {
164
+ while (JS7_ISDEC(*cp)) {
165
+ oldIndex = index;
166
+ c = JS7_UNDEC(*cp);
167
+ index = 10*index + c;
168
+ cp++;
169
+ }
170
+ }
171
+
172
+ /* Ensure that all characters were consumed and we didn't overflow. */
173
+ if (*cp == 0 &&
174
+ (oldIndex < (MAXINDEX / 10) ||
175
+ (oldIndex == (MAXINDEX / 10) && c < (MAXINDEX % 10))))
176
+ {
177
+ *indexp = index;
178
+ return JS_TRUE;
179
+ }
180
+ }
181
+ return JS_FALSE;
182
+ }
183
+
184
+ static jsuint
185
+ ValueIsLength(JSContext *cx, jsval* vp)
186
+ {
187
+ jsint i;
188
+ jsdouble d;
189
+ jsuint length;
190
+
191
+ if (JSVAL_IS_INT(*vp)) {
192
+ i = JSVAL_TO_INT(*vp);
193
+ if (i < 0)
194
+ goto error;
195
+ return (jsuint) i;
196
+ }
197
+
198
+ d = js_ValueToNumber(cx, vp);
199
+ if (JSVAL_IS_NULL(*vp))
200
+ goto error;
201
+
202
+ if (JSDOUBLE_IS_NaN(d))
203
+ goto error;
204
+ length = (jsuint) d;
205
+ if (d != (jsdouble) length)
206
+ goto error;
207
+ return length;
208
+
209
+ error:
210
+ JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
211
+ JSMSG_BAD_ARRAY_LENGTH);
212
+ *vp = JSVAL_NULL;
213
+ return 0;
214
+ }
215
+
216
+ JSBool
217
+ js_GetLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp)
218
+ {
219
+ JSTempValueRooter tvr;
220
+ jsid id;
221
+ JSBool ok;
222
+ jsint i;
223
+
224
+ if (OBJ_IS_ARRAY(cx, obj)) {
225
+ *lengthp = obj->fslots[JSSLOT_ARRAY_LENGTH];
226
+ return JS_TRUE;
227
+ }
228
+
229
+ JS_PUSH_SINGLE_TEMP_ROOT(cx, JSVAL_NULL, &tvr);
230
+ id = ATOM_TO_JSID(cx->runtime->atomState.lengthAtom);
231
+ ok = OBJ_GET_PROPERTY(cx, obj, id, &tvr.u.value);
232
+ if (ok) {
233
+ if (JSVAL_IS_INT(tvr.u.value)) {
234
+ i = JSVAL_TO_INT(tvr.u.value);
235
+ *lengthp = (jsuint)i; /* jsuint cast does ToUint32 */
236
+ } else {
237
+ *lengthp = js_ValueToECMAUint32(cx, &tvr.u.value);
238
+ ok = !JSVAL_IS_NULL(tvr.u.value);
239
+ }
240
+ }
241
+ JS_POP_TEMP_ROOT(cx, &tvr);
242
+ return ok;
243
+ }
244
+
245
+ static JSBool
246
+ IndexToValue(JSContext *cx, jsuint index, jsval *vp)
247
+ {
248
+ if (index <= JSVAL_INT_MAX) {
249
+ *vp = INT_TO_JSVAL(index);
250
+ return JS_TRUE;
251
+ }
252
+ return JS_NewDoubleValue(cx, (jsdouble)index, vp);
253
+ }
254
+
255
+ static JSBool
256
+ IndexToId(JSContext *cx, jsuint index, jsid *idp)
257
+ {
258
+ JSString *str;
259
+
260
+ if (index <= JSVAL_INT_MAX) {
261
+ *idp = INT_TO_JSID(index);
262
+ return JS_TRUE;
263
+ }
264
+ str = js_NumberToString(cx, index);
265
+ if (!str)
266
+ return JS_FALSE;
267
+ return js_ValueToStringId(cx, STRING_TO_JSVAL(str), idp);
268
+ }
269
+
270
+ static JSBool
271
+ BigIndexToId(JSContext *cx, JSObject *obj, jsuint index, JSBool createAtom,
272
+ jsid *idp)
273
+ {
274
+ jschar buf[10], *start;
275
+ JSClass *clasp;
276
+ JSAtom *atom;
277
+ JS_STATIC_ASSERT((jsuint)-1 == 4294967295U);
278
+
279
+ JS_ASSERT(index > JSVAL_INT_MAX);
280
+
281
+ start = JS_ARRAY_END(buf);
282
+ do {
283
+ --start;
284
+ *start = (jschar)('0' + index % 10);
285
+ index /= 10;
286
+ } while (index != 0);
287
+
288
+ /*
289
+ * Skip the atomization if the class is known to store atoms corresponding
290
+ * to big indexes together with elements. In such case we know that the
291
+ * array does not have an element at the given index if its atom does not
292
+ * exist. Fast arrays (clasp == &js_ArrayClass) don't use atoms for
293
+ * any indexes, though it would be rare to see them have a big index
294
+ * in any case.
295
+ */
296
+ if (!createAtom &&
297
+ ((clasp = OBJ_GET_CLASS(cx, obj)) == &js_SlowArrayClass ||
298
+ clasp == &js_ArgumentsClass ||
299
+ clasp == &js_ObjectClass)) {
300
+ atom = js_GetExistingStringAtom(cx, start, JS_ARRAY_END(buf) - start);
301
+ if (!atom) {
302
+ *idp = JSVAL_VOID;
303
+ return JS_TRUE;
304
+ }
305
+ } else {
306
+ atom = js_AtomizeChars(cx, start, JS_ARRAY_END(buf) - start, 0);
307
+ if (!atom)
308
+ return JS_FALSE;
309
+ }
310
+
311
+ *idp = ATOM_TO_JSID(atom);
312
+ return JS_TRUE;
313
+ }
314
+
315
+ static JSBool
316
+ ResizeSlots(JSContext *cx, JSObject *obj, uint32 oldlen, uint32 len)
317
+ {
318
+ jsval *slots, *newslots;
319
+
320
+ if (len == 0) {
321
+ if (obj->dslots) {
322
+ JS_free(cx, obj->dslots - 1);
323
+ obj->dslots = NULL;
324
+ }
325
+ return JS_TRUE;
326
+ }
327
+
328
+ if (len > ~(uint32)0 / sizeof(jsval)) {
329
+ js_ReportAllocationOverflow(cx);
330
+ return JS_FALSE;
331
+ }
332
+
333
+ slots = obj->dslots ? obj->dslots - 1 : NULL;
334
+ newslots = (jsval *) JS_realloc(cx, slots, sizeof (jsval) * (len + 1));
335
+ if (!newslots)
336
+ return JS_FALSE;
337
+
338
+ obj->dslots = newslots + 1;
339
+ ARRAY_SET_DENSE_LENGTH(obj, len);
340
+
341
+ for (slots = obj->dslots + oldlen; slots < obj->dslots + len; slots++)
342
+ *slots = JSVAL_HOLE;
343
+
344
+ return JS_TRUE;
345
+ }
346
+
347
+ #define ARRAY_GROWBY 8
348
+
349
+ static JSBool
350
+ EnsureLength(JSContext *cx, JSObject *obj, uint32 len)
351
+ {
352
+ uint32 oldlen = ARRAY_DENSE_LENGTH(obj);
353
+
354
+ if (len > oldlen) {
355
+ return ResizeSlots(cx, obj, oldlen,
356
+ len + ARRAY_GROWBY - (len % ARRAY_GROWBY));
357
+ }
358
+ return JS_TRUE;
359
+ }
360
+
361
+ /*
362
+ * If the property at the given index exists, get its value into location
363
+ * pointed by vp and set *hole to false. Otherwise set *hole to true and *vp
364
+ * to JSVAL_VOID. This function assumes that the location pointed by vp is
365
+ * properly rooted and can be used as GC-protected storage for temporaries.
366
+ */
367
+ static JSBool
368
+ GetArrayElement(JSContext *cx, JSObject *obj, jsuint index, JSBool *hole,
369
+ jsval *vp)
370
+ {
371
+ jsid id;
372
+ JSObject *obj2;
373
+ JSProperty *prop;
374
+
375
+ if (OBJ_IS_DENSE_ARRAY(cx, obj) && index < ARRAY_DENSE_LENGTH(obj) &&
376
+ (*vp = obj->dslots[index]) != JSVAL_HOLE) {
377
+ *hole = JS_FALSE;
378
+ return JS_TRUE;
379
+ }
380
+
381
+ if (index <= JSVAL_INT_MAX) {
382
+ id = INT_TO_JSID(index);
383
+ } else {
384
+ if (!BigIndexToId(cx, obj, index, JS_FALSE, &id))
385
+ return JS_FALSE;
386
+ if (id == JSVAL_VOID) {
387
+ *hole = JS_TRUE;
388
+ *vp = JSVAL_VOID;
389
+ return JS_TRUE;
390
+ }
391
+ }
392
+
393
+ if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop))
394
+ return JS_FALSE;
395
+ if (!prop) {
396
+ *hole = JS_TRUE;
397
+ *vp = JSVAL_VOID;
398
+ } else {
399
+ OBJ_DROP_PROPERTY(cx, obj2, prop);
400
+ if (!OBJ_GET_PROPERTY(cx, obj, id, vp))
401
+ return JS_FALSE;
402
+ *hole = JS_FALSE;
403
+ }
404
+ return JS_TRUE;
405
+ }
406
+
407
+ /*
408
+ * Set the value of the property at the given index to v assuming v is rooted.
409
+ */
410
+ static JSBool
411
+ SetArrayElement(JSContext *cx, JSObject *obj, jsuint index, jsval v)
412
+ {
413
+ jsid id;
414
+
415
+ if (OBJ_IS_DENSE_ARRAY(cx, obj)) {
416
+ if (INDEX_TOO_SPARSE(obj, index)) {
417
+ if (!js_MakeArraySlow(cx, obj))
418
+ return JS_FALSE;
419
+ } else {
420
+
421
+ if (!EnsureLength(cx, obj, index + 1))
422
+ return JS_FALSE;
423
+ if (index >= (uint32)obj->fslots[JSSLOT_ARRAY_LENGTH])
424
+ obj->fslots[JSSLOT_ARRAY_LENGTH] = index + 1;
425
+ if (obj->dslots[index] == JSVAL_HOLE)
426
+ obj->fslots[JSSLOT_ARRAY_COUNT]++;
427
+ obj->dslots[index] = v;
428
+ return JS_TRUE;
429
+ }
430
+ }
431
+
432
+ if (index <= JSVAL_INT_MAX) {
433
+ id = INT_TO_JSID(index);
434
+ } else {
435
+ if (!BigIndexToId(cx, obj, index, JS_TRUE, &id))
436
+ return JS_FALSE;
437
+ JS_ASSERT(id != JSVAL_VOID);
438
+ }
439
+ return OBJ_SET_PROPERTY(cx, obj, id, &v);
440
+ }
441
+
442
+ static JSBool
443
+ DeleteArrayElement(JSContext *cx, JSObject *obj, jsuint index)
444
+ {
445
+ jsid id;
446
+ jsval junk;
447
+
448
+ if (OBJ_IS_DENSE_ARRAY(cx, obj)) {
449
+ if (index < ARRAY_DENSE_LENGTH(obj)) {
450
+ if (obj->dslots[index] != JSVAL_HOLE)
451
+ obj->fslots[JSSLOT_ARRAY_COUNT]--;
452
+ obj->dslots[index] = JSVAL_HOLE;
453
+ }
454
+ return JS_TRUE;
455
+ }
456
+
457
+ if (index <= JSVAL_INT_MAX) {
458
+ id = INT_TO_JSID(index);
459
+ } else {
460
+ if (!BigIndexToId(cx, obj, index, JS_FALSE, &id))
461
+ return JS_FALSE;
462
+ if (id == JSVAL_VOID)
463
+ return JS_TRUE;
464
+ }
465
+ return OBJ_DELETE_PROPERTY(cx, obj, id, &junk);
466
+ }
467
+
468
+ /*
469
+ * When hole is true, delete the property at the given index. Otherwise set
470
+ * its value to v assuming v is rooted.
471
+ */
472
+ static JSBool
473
+ SetOrDeleteArrayElement(JSContext *cx, JSObject *obj, jsuint index,
474
+ JSBool hole, jsval v)
475
+ {
476
+ if (hole) {
477
+ JS_ASSERT(v == JSVAL_VOID);
478
+ return DeleteArrayElement(cx, obj, index);
479
+ }
480
+ return SetArrayElement(cx, obj, index, v);
481
+ }
482
+
483
+ JSBool
484
+ js_SetLengthProperty(JSContext *cx, JSObject *obj, jsuint length)
485
+ {
486
+ jsval v;
487
+ jsid id;
488
+
489
+ if (!IndexToValue(cx, length, &v))
490
+ return JS_FALSE;
491
+ id = ATOM_TO_JSID(cx->runtime->atomState.lengthAtom);
492
+ return OBJ_SET_PROPERTY(cx, obj, id, &v);
493
+ }
494
+
495
+ JSBool
496
+ js_HasLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp)
497
+ {
498
+ JSErrorReporter older;
499
+ JSTempValueRooter tvr;
500
+ jsid id;
501
+ JSBool ok;
502
+
503
+ older = JS_SetErrorReporter(cx, NULL);
504
+ JS_PUSH_SINGLE_TEMP_ROOT(cx, JSVAL_NULL, &tvr);
505
+ id = ATOM_TO_JSID(cx->runtime->atomState.lengthAtom);
506
+ ok = OBJ_GET_PROPERTY(cx, obj, id, &tvr.u.value);
507
+ JS_SetErrorReporter(cx, older);
508
+ if (ok) {
509
+ *lengthp = ValueIsLength(cx, &tvr.u.value);
510
+ ok = !JSVAL_IS_NULL(tvr.u.value);
511
+ }
512
+ JS_POP_TEMP_ROOT(cx, &tvr);
513
+ return ok;
514
+ }
515
+
516
+ JSBool
517
+ js_IsArrayLike(JSContext *cx, JSObject *obj, JSBool *answerp, jsuint *lengthp)
518
+ {
519
+ JSClass *clasp;
520
+
521
+ clasp = OBJ_GET_CLASS(cx, obj);
522
+ *answerp = (clasp == &js_ArgumentsClass || clasp == &js_ArrayClass ||
523
+ clasp == &js_SlowArrayClass);
524
+ if (!*answerp) {
525
+ *lengthp = 0;
526
+ return JS_TRUE;
527
+ }
528
+ return js_GetLengthProperty(cx, obj, lengthp);
529
+ }
530
+
531
+ /*
532
+ * The 'length' property of all native Array instances is a shared permanent
533
+ * property of Array.prototype, so it appears to be a direct property of each
534
+ * array instance delegating to that Array.prototype. It accesses the private
535
+ * slot reserved by js_ArrayClass.
536
+ *
537
+ * Since SpiderMonkey supports cross-class prototype-based delegation, we have
538
+ * to be careful about the length getter and setter being called on an object
539
+ * not of Array class. For the getter, we search obj's prototype chain for the
540
+ * array that caused this getter to be invoked. In the setter case to overcome
541
+ * the JSPROP_SHARED attribute, we must define a shadowing length property.
542
+ */
543
+ static JSBool
544
+ array_length_getter(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
545
+ {
546
+ do {
547
+ if (OBJ_IS_ARRAY(cx, obj))
548
+ return IndexToValue(cx, obj->fslots[JSSLOT_ARRAY_LENGTH], vp);
549
+ } while ((obj = OBJ_GET_PROTO(cx, obj)) != NULL);
550
+ return JS_TRUE;
551
+ }
552
+
553
+ static JSBool
554
+ array_length_setter(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
555
+ {
556
+ jsuint newlen, oldlen, gap, index;
557
+ jsval junk;
558
+ JSObject *iter;
559
+ JSTempValueRooter tvr;
560
+ JSBool ok;
561
+
562
+ if (!OBJ_IS_ARRAY(cx, obj)) {
563
+ jsid lengthId = ATOM_TO_JSID(cx->runtime->atomState.lengthAtom);
564
+
565
+ return OBJ_DEFINE_PROPERTY(cx, obj, lengthId, *vp, NULL, NULL,
566
+ JSPROP_ENUMERATE, NULL);
567
+ }
568
+
569
+ newlen = ValueIsLength(cx, vp);
570
+ if (JSVAL_IS_NULL(*vp))
571
+ return JS_FALSE;
572
+ oldlen = obj->fslots[JSSLOT_ARRAY_LENGTH];
573
+
574
+ if (oldlen == newlen)
575
+ return JS_TRUE;
576
+
577
+ if (!IndexToValue(cx, newlen, vp))
578
+ return JS_FALSE;
579
+
580
+ if (oldlen < newlen) {
581
+ obj->fslots[JSSLOT_ARRAY_LENGTH] = newlen;
582
+ return JS_TRUE;
583
+ }
584
+
585
+ if (OBJ_IS_DENSE_ARRAY(cx, obj)) {
586
+ /* Don't reallocate if we're not actually shrinking our slots. */
587
+ jsuint oldsize = ARRAY_DENSE_LENGTH(obj);
588
+ if (oldsize >= newlen && !ResizeSlots(cx, obj, oldsize, newlen))
589
+ return JS_FALSE;
590
+ } else if (oldlen - newlen < (1 << 24)) {
591
+ do {
592
+ --oldlen;
593
+ if (!JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) ||
594
+ !DeleteArrayElement(cx, obj, oldlen)) {
595
+ return JS_FALSE;
596
+ }
597
+ } while (oldlen != newlen);
598
+ } else {
599
+ /*
600
+ * We are going to remove a lot of indexes in a presumably sparse
601
+ * array. So instead of looping through indexes between newlen and
602
+ * oldlen, we iterate through all properties and remove those that
603
+ * correspond to indexes in the half-open range [newlen, oldlen). See
604
+ * bug 322135.
605
+ */
606
+ iter = JS_NewPropertyIterator(cx, obj);
607
+ if (!iter)
608
+ return JS_FALSE;
609
+
610
+ /* Protect iter against GC in OBJ_DELETE_PROPERTY. */
611
+ JS_PUSH_TEMP_ROOT_OBJECT(cx, iter, &tvr);
612
+ gap = oldlen - newlen;
613
+ for (;;) {
614
+ ok = (JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) &&
615
+ JS_NextProperty(cx, iter, &id));
616
+ if (!ok)
617
+ break;
618
+ if (id == JSVAL_VOID)
619
+ break;
620
+ if (js_IdIsIndex(id, &index) && index - newlen < gap) {
621
+ ok = OBJ_DELETE_PROPERTY(cx, obj, id, &junk);
622
+ if (!ok)
623
+ break;
624
+ }
625
+ }
626
+ JS_POP_TEMP_ROOT(cx, &tvr);
627
+ if (!ok)
628
+ return JS_FALSE;
629
+ }
630
+
631
+ obj->fslots[JSSLOT_ARRAY_LENGTH] = newlen;
632
+ return JS_TRUE;
633
+ }
634
+
635
+ static JSBool
636
+ array_lookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
637
+ JSProperty **propp)
638
+ {
639
+ uint32 i;
640
+
641
+ if (!OBJ_IS_DENSE_ARRAY(cx, obj))
642
+ return js_LookupProperty(cx, obj, id, objp, propp);
643
+
644
+ /*
645
+ * We have only indexed properties up to DENSELEN (excepting holes), plus
646
+ * the length property. For all else, we delegate to the prototype.
647
+ */
648
+ if (id != ATOM_TO_JSID(cx->runtime->atomState.lengthAtom) &&
649
+ (!js_IdIsIndex(id, &i) ||
650
+ obj->fslots[JSSLOT_ARRAY_LENGTH] == 0 ||
651
+ i >= ARRAY_DENSE_LENGTH(obj) ||
652
+ obj->dslots[i] == JSVAL_HOLE))
653
+ {
654
+ JSObject *proto = STOBJ_GET_PROTO(obj);
655
+
656
+ if (!proto) {
657
+ *objp = NULL;
658
+ *propp = NULL;
659
+ return JS_TRUE;
660
+ }
661
+
662
+ return OBJ_LOOKUP_PROPERTY(cx, proto, id, objp, propp);
663
+ }
664
+
665
+ /* FIXME 417501: threadsafety: could race with a lookup on another thread.
666
+ * If we can only have a single lookup active per context, we could
667
+ * pigeonhole this on the context instead. */
668
+ JS_ASSERT(STOBJ_GET_SLOT(obj, JSSLOT_ARRAY_LOOKUP_HOLDER) == JSVAL_VOID);
669
+ STOBJ_SET_SLOT(obj, JSSLOT_ARRAY_LOOKUP_HOLDER, (jsval)id);
670
+ *propp = (JSProperty *)&(obj->fslots[JSSLOT_ARRAY_LOOKUP_HOLDER]);
671
+ *objp = obj;
672
+ return JS_TRUE;
673
+ }
674
+
675
+ static void
676
+ array_dropProperty(JSContext *cx, JSObject *obj, JSProperty *prop)
677
+ {
678
+ JS_ASSERT(!OBJ_IS_DENSE_ARRAY(cx, obj) ||
679
+ STOBJ_GET_SLOT(obj, JSSLOT_ARRAY_LOOKUP_HOLDER) != JSVAL_VOID);
680
+ #ifdef DEBUG
681
+ STOBJ_SET_SLOT(obj, JSSLOT_ARRAY_LOOKUP_HOLDER, JSVAL_VOID);
682
+ #endif
683
+ }
684
+
685
+ static JSBool
686
+ array_getProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
687
+ {
688
+ uint32 i;
689
+
690
+ if (id == ATOM_TO_JSID(cx->runtime->atomState.lengthAtom))
691
+ return IndexToValue(cx, obj->fslots[JSSLOT_ARRAY_LENGTH], vp);
692
+
693
+ if (id == ATOM_TO_JSID(cx->runtime->atomState.protoAtom)) {
694
+ *vp = STOBJ_GET_SLOT(obj, JSSLOT_PROTO);
695
+ return JS_TRUE;
696
+ }
697
+
698
+ if (!OBJ_IS_DENSE_ARRAY(cx, obj))
699
+ return js_GetProperty(cx, obj, id, vp);
700
+
701
+ if (!js_IdIsIndex(ID_TO_VALUE(id), &i) || i >= ARRAY_DENSE_LENGTH(obj) ||
702
+ obj->dslots[i] == JSVAL_HOLE) {
703
+ JSObject *obj2;
704
+ JSProperty *prop;
705
+ JSScopeProperty *sprop;
706
+
707
+ JSObject *proto = STOBJ_GET_PROTO(obj);
708
+ if (!proto) {
709
+ *vp = JSVAL_VOID;
710
+ return JS_TRUE;
711
+ }
712
+
713
+ *vp = JSVAL_VOID;
714
+ if (js_LookupPropertyWithFlags(cx, proto, id, 0, &obj2, &prop) < 0)
715
+ return JS_FALSE;
716
+
717
+ if (prop && OBJ_IS_NATIVE(obj2)) {
718
+ sprop = (JSScopeProperty *) prop;
719
+ if (!js_NativeGet(cx, obj, obj2, sprop, vp))
720
+ return JS_FALSE;
721
+ }
722
+
723
+ if (prop)
724
+ OBJ_DROP_PROPERTY(cx, obj2, prop);
725
+ return JS_TRUE;
726
+ }
727
+
728
+ *vp = obj->dslots[i];
729
+ return JS_TRUE;
730
+ }
731
+
732
+ static JSBool
733
+ slowarray_addProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
734
+ {
735
+ jsuint index, length;
736
+
737
+ if (!js_IdIsIndex(id, &index))
738
+ return JS_TRUE;
739
+ length = obj->fslots[JSSLOT_ARRAY_LENGTH];
740
+ if (index >= length)
741
+ obj->fslots[JSSLOT_ARRAY_LENGTH] = index + 1;
742
+ return JS_TRUE;
743
+ }
744
+
745
+ static void
746
+ slowarray_trace(JSTracer *trc, JSObject *obj)
747
+ {
748
+ uint32 length = obj->fslots[JSSLOT_ARRAY_LENGTH];
749
+
750
+ JS_ASSERT(STOBJ_GET_CLASS(obj) == &js_SlowArrayClass);
751
+
752
+ /*
753
+ * Move JSSLOT_ARRAY_LENGTH aside to prevent the GC from treating
754
+ * untagged integer values as objects or strings.
755
+ */
756
+ obj->fslots[JSSLOT_ARRAY_LENGTH] = JSVAL_VOID;
757
+ js_TraceObject(trc, obj);
758
+ obj->fslots[JSSLOT_ARRAY_LENGTH] = length;
759
+ }
760
+
761
+ static JSObjectOps js_SlowArrayObjectOps;
762
+
763
+ static JSObjectOps *
764
+ slowarray_getObjectOps(JSContext *cx, JSClass *clasp)
765
+ {
766
+ return &js_SlowArrayObjectOps;
767
+ }
768
+
769
+ static JSBool
770
+ array_setProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
771
+ {
772
+ uint32 i;
773
+
774
+ if (id == ATOM_TO_JSID(cx->runtime->atomState.lengthAtom))
775
+ return array_length_setter(cx, obj, id, vp);
776
+
777
+ if (!OBJ_IS_DENSE_ARRAY(cx, obj))
778
+ return js_SetProperty(cx, obj, id, vp);
779
+
780
+ if (!js_IdIsIndex(id, &i) || INDEX_TOO_SPARSE(obj, i)) {
781
+ if (!js_MakeArraySlow(cx, obj))
782
+ return JS_FALSE;
783
+ return js_SetProperty(cx, obj, id, vp);
784
+ }
785
+
786
+ if (!EnsureLength(cx, obj, i + 1))
787
+ return JS_FALSE;
788
+
789
+ if (i >= (uint32)obj->fslots[JSSLOT_ARRAY_LENGTH])
790
+ obj->fslots[JSSLOT_ARRAY_LENGTH] = i + 1;
791
+ if (obj->dslots[i] == JSVAL_HOLE)
792
+ obj->fslots[JSSLOT_ARRAY_COUNT]++;
793
+ obj->dslots[i] = *vp;
794
+ return JS_TRUE;
795
+ }
796
+
797
+ static JSBool
798
+ array_defineProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,
799
+ JSPropertyOp getter, JSPropertyOp setter, uintN attrs,
800
+ JSProperty **propp)
801
+ {
802
+ uint32 i;
803
+
804
+ if (id == ATOM_TO_JSID(cx->runtime->atomState.lengthAtom))
805
+ return JS_TRUE;
806
+
807
+ if (!js_IdIsIndex(ID_TO_VALUE(id), &i) || attrs != JSPROP_ENUMERATE) {
808
+ if (!ENSURE_SLOW_ARRAY(cx, obj))
809
+ return JS_FALSE;
810
+ return js_DefineProperty(cx, obj, id, value, getter, setter, attrs,
811
+ propp);
812
+ }
813
+
814
+ return array_setProperty(cx, obj, id, &value);
815
+ }
816
+
817
+ static JSBool
818
+ array_getAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop,
819
+ uintN *attrsp)
820
+ {
821
+ *attrsp = id == ATOM_TO_JSID(cx->runtime->atomState.lengthAtom)
822
+ ? JSPROP_PERMANENT : JSPROP_ENUMERATE;
823
+ return JS_TRUE;
824
+ }
825
+
826
+ static JSBool
827
+ array_setAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop,
828
+ uintN *attrsp)
829
+ {
830
+ JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
831
+ JSMSG_CANT_SET_ARRAY_ATTRS);
832
+ return JS_FALSE;
833
+ }
834
+
835
+ static JSBool
836
+ array_deleteProperty(JSContext *cx, JSObject *obj, jsval id, jsval *rval)
837
+ {
838
+ uint32 i;
839
+
840
+ if (!OBJ_IS_DENSE_ARRAY(cx, obj))
841
+ return js_DeleteProperty(cx, obj, id, rval);
842
+
843
+ if (id == ATOM_TO_JSID(cx->runtime->atomState.lengthAtom)) {
844
+ *rval = JSVAL_FALSE;
845
+ return JS_TRUE;
846
+ }
847
+
848
+ if (js_IdIsIndex(id, &i) && i < ARRAY_DENSE_LENGTH(obj) &&
849
+ obj->dslots[i] != JSVAL_HOLE) {
850
+ obj->fslots[JSSLOT_ARRAY_COUNT]--;
851
+ obj->dslots[i] = JSVAL_HOLE;
852
+ }
853
+
854
+ *rval = JSVAL_TRUE;
855
+ return JS_TRUE;
856
+ }
857
+
858
+ /*
859
+ * JSObjectOps.enumerate implementation.
860
+ *
861
+ * For a fast array, JSENUMERATE_INIT captures in the enumeration state both
862
+ * the length of the array and the bitmap indicating the positions of holes in
863
+ * the array. This ensures that adding or deleting array elements does not
864
+ * affect the sequence of indexes JSENUMERATE_NEXT returns.
865
+ *
866
+ * For a common case of an array without holes, to represent the state we pack
867
+ * the (nextEnumerationIndex, arrayLength) pair as a pseudo-boolean jsval.
868
+ * This is possible when length <= PACKED_UINT_PAIR_BITS. For arrays with
869
+ * greater length or holes we allocate the JSIndexIterState structure and
870
+ * store it as an int-tagged private pointer jsval. For a slow array we
871
+ * delegate the enumeration implementation to js_Enumerate in
872
+ * slowarray_enumerate.
873
+ *
874
+ * Array mutations can turn a fast array into a slow one after the enumeration
875
+ * starts. When this happens, slowarray_enumerate receives a state created
876
+ * when the array was fast. To distinguish such fast state from a slow state,
877
+ * which is an int-tagged pointer that js_Enumerate creates, we set not one
878
+ * but two lowest bits when tagging a JSIndexIterState pointer -- see
879
+ * INDEX_ITER_TAG usage below. Thus, when slowarray_enumerate receives a state
880
+ * tagged with JSVAL_BOOLEAN or with two lowest bits set, it knows that this
881
+ * is a fast state so it calls array_enumerate to continue enumerating the
882
+ * indexes present in the original fast array.
883
+ */
884
+
885
+ #define PACKED_UINT_PAIR_BITS 14
886
+ #define PACKED_UINT_PAIR_MASK JS_BITMASK(PACKED_UINT_PAIR_BITS)
887
+
888
+ #define UINT_PAIR_TO_BOOLEAN_JSVAL(i,j) \
889
+ (JS_ASSERT((uint32) (i) <= PACKED_UINT_PAIR_MASK), \
890
+ JS_ASSERT((uint32) (j) <= PACKED_UINT_PAIR_MASK), \
891
+ ((jsval) (i) << (PACKED_UINT_PAIR_BITS + JSVAL_TAGBITS)) | \
892
+ ((jsval) (j) << (JSVAL_TAGBITS)) | \
893
+ (jsval) JSVAL_BOOLEAN)
894
+
895
+ #define BOOLEAN_JSVAL_TO_UINT_PAIR(v,i,j) \
896
+ (JS_ASSERT(JSVAL_TAG(v) == JSVAL_BOOLEAN), \
897
+ (i) = (uint32) ((v) >> (PACKED_UINT_PAIR_BITS + JSVAL_TAGBITS)), \
898
+ (j) = (uint32) ((v) >> JSVAL_TAGBITS) & PACKED_UINT_PAIR_MASK, \
899
+ JS_ASSERT((i) <= PACKED_UINT_PAIR_MASK))
900
+
901
+ JS_STATIC_ASSERT(PACKED_UINT_PAIR_BITS * 2 + JSVAL_TAGBITS <= JS_BITS_PER_WORD);
902
+
903
+ typedef struct JSIndexIterState {
904
+ uint32 index;
905
+ uint32 length;
906
+ JSBool hasHoles;
907
+
908
+ /*
909
+ * Variable-length bitmap representing array's holes. It must not be
910
+ * accessed when hasHoles is false.
911
+ */
912
+ jsbitmap holes[1];
913
+ } JSIndexIterState;
914
+
915
+ #define INDEX_ITER_TAG 3
916
+
917
+ JS_STATIC_ASSERT(JSVAL_INT == 1);
918
+
919
+ static JSBool
920
+ array_enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
921
+ jsval *statep, jsid *idp)
922
+ {
923
+ uint32 length, i;
924
+ JSIndexIterState *ii;
925
+
926
+ switch (enum_op) {
927
+ case JSENUMERATE_INIT:
928
+ JS_ASSERT(OBJ_IS_DENSE_ARRAY(cx, obj));
929
+ length = ARRAY_DENSE_LENGTH(obj);
930
+ if (idp && !IndexToId(cx, length, idp))
931
+ return JS_FALSE;
932
+ ii = NULL;
933
+ for (i = 0; i != length; ++i) {
934
+ if (obj->dslots[i] == JSVAL_HOLE) {
935
+ if (!ii) {
936
+ ii = (JSIndexIterState *)
937
+ JS_malloc(cx, offsetof(JSIndexIterState, holes) +
938
+ JS_BITMAP_SIZE(length));
939
+ if (!ii)
940
+ return JS_FALSE;
941
+ ii->hasHoles = JS_TRUE;
942
+ memset(ii->holes, 0, JS_BITMAP_SIZE(length));
943
+ }
944
+ JS_SET_BIT(ii->holes, i);
945
+ }
946
+ }
947
+ if (!ii) {
948
+ /* Array has no holes. */
949
+ if (length <= PACKED_UINT_PAIR_MASK) {
950
+ *statep = UINT_PAIR_TO_BOOLEAN_JSVAL(0, length);
951
+ break;
952
+ }
953
+ ii = (JSIndexIterState *)
954
+ JS_malloc(cx, offsetof(JSIndexIterState, holes));
955
+ if (!ii)
956
+ return JS_FALSE;
957
+ ii->hasHoles = JS_FALSE;
958
+ }
959
+ ii->index = 0;
960
+ ii->length = length;
961
+ *statep = (jsval) ii | INDEX_ITER_TAG;
962
+ JS_ASSERT(*statep & JSVAL_INT);
963
+ break;
964
+
965
+ case JSENUMERATE_NEXT:
966
+ if (JSVAL_TAG(*statep) == JSVAL_BOOLEAN) {
967
+ BOOLEAN_JSVAL_TO_UINT_PAIR(*statep, i, length);
968
+ if (i != length) {
969
+ *idp = INT_TO_JSID(i);
970
+ *statep = UINT_PAIR_TO_BOOLEAN_JSVAL(i + 1, length);
971
+ break;
972
+ }
973
+ } else {
974
+ JS_ASSERT((*statep & INDEX_ITER_TAG) == INDEX_ITER_TAG);
975
+ ii = (JSIndexIterState *) (*statep & ~INDEX_ITER_TAG);
976
+ i = ii->index;
977
+ if (i != ii->length) {
978
+ /* Skip holes if any. */
979
+ if (ii->hasHoles) {
980
+ while (JS_TEST_BIT(ii->holes, i) && ++i != ii->length)
981
+ continue;
982
+ }
983
+ if (i != ii->length) {
984
+ ii->index = i + 1;
985
+ return IndexToId(cx, i, idp);
986
+ }
987
+ }
988
+ }
989
+ /* FALL THROUGH */
990
+
991
+ case JSENUMERATE_DESTROY:
992
+ if (JSVAL_TAG(*statep) != JSVAL_BOOLEAN) {
993
+ JS_ASSERT((*statep & INDEX_ITER_TAG) == INDEX_ITER_TAG);
994
+ ii = (JSIndexIterState *) (*statep & ~INDEX_ITER_TAG);
995
+ JS_free(cx, ii);
996
+ }
997
+ *statep = JSVAL_NULL;
998
+ break;
999
+ }
1000
+ return JS_TRUE;
1001
+ }
1002
+
1003
+ static JSBool
1004
+ slowarray_enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
1005
+ jsval *statep, jsid *idp)
1006
+ {
1007
+ JSBool ok;
1008
+
1009
+ /* Are we continuing an enumeration that started when we were dense? */
1010
+ if (enum_op != JSENUMERATE_INIT) {
1011
+ if (JSVAL_TAG(*statep) == JSVAL_BOOLEAN ||
1012
+ (*statep & INDEX_ITER_TAG) == INDEX_ITER_TAG) {
1013
+ return array_enumerate(cx, obj, enum_op, statep, idp);
1014
+ }
1015
+ JS_ASSERT((*statep & INDEX_ITER_TAG) == JSVAL_INT);
1016
+ }
1017
+ ok = js_Enumerate(cx, obj, enum_op, statep, idp);
1018
+ JS_ASSERT(*statep == JSVAL_NULL || (*statep & INDEX_ITER_TAG) == JSVAL_INT);
1019
+ return ok;
1020
+ }
1021
+
1022
+ static void
1023
+ array_finalize(JSContext *cx, JSObject *obj)
1024
+ {
1025
+ if (obj->dslots)
1026
+ JS_free(cx, obj->dslots - 1);
1027
+ obj->dslots = NULL;
1028
+ }
1029
+
1030
+ static void
1031
+ array_trace(JSTracer *trc, JSObject *obj)
1032
+ {
1033
+ uint32 length;
1034
+ size_t i;
1035
+ jsval v;
1036
+
1037
+ JS_ASSERT(OBJ_IS_DENSE_ARRAY(cx, obj));
1038
+
1039
+ length = ARRAY_DENSE_LENGTH(obj);
1040
+ for (i = 0; i < length; i++) {
1041
+ v = obj->dslots[i];
1042
+ if (JSVAL_IS_TRACEABLE(v)) {
1043
+ JS_SET_TRACING_INDEX(trc, "array_dslots", i);
1044
+ JS_CallTracer(trc, JSVAL_TO_TRACEABLE(v), JSVAL_TRACE_KIND(v));
1045
+ }
1046
+ }
1047
+
1048
+ for (i = JSSLOT_PROTO; i <= JSSLOT_PARENT; ++i) {
1049
+ v = STOBJ_GET_SLOT(obj, i);
1050
+ if (JSVAL_IS_TRACEABLE(v)) {
1051
+ JS_SET_TRACING_DETAILS(trc, js_PrintObjectSlotName, obj, i);
1052
+ JS_CallTracer(trc, JSVAL_TO_TRACEABLE(v), JSVAL_TRACE_KIND(v));
1053
+ }
1054
+ }
1055
+ }
1056
+
1057
+ static JSObjectMap *
1058
+ array_newObjectMap(JSContext *cx, jsrefcount nrefs, JSObjectOps *ops,
1059
+ JSClass *clasp, JSObject *obj)
1060
+ {
1061
+ #ifdef DEBUG
1062
+ extern JSClass js_ArrayClass;
1063
+ extern JSObjectOps js_ArrayObjectOps;
1064
+ #endif
1065
+ JSObjectMap *map = (JSObjectMap *) JS_malloc(cx, sizeof(*map));
1066
+ if (!map)
1067
+ return NULL;
1068
+
1069
+ map->nrefs = nrefs;
1070
+ JS_ASSERT(ops == &js_ArrayObjectOps);
1071
+ map->ops = ops;
1072
+ JS_ASSERT(clasp == &js_ArrayClass);
1073
+ map->freeslot = JSSLOT_FREE(clasp);
1074
+
1075
+ return map;
1076
+ }
1077
+
1078
+ void
1079
+ array_destroyObjectMap(JSContext *cx, JSObjectMap *map)
1080
+ {
1081
+ JS_free(cx, map);
1082
+ }
1083
+
1084
+ JSObjectOps js_ArrayObjectOps = {
1085
+ array_newObjectMap, array_destroyObjectMap,
1086
+ array_lookupProperty, array_defineProperty,
1087
+ array_getProperty, array_setProperty,
1088
+ array_getAttributes, array_setAttributes,
1089
+ array_deleteProperty, js_DefaultValue,
1090
+ array_enumerate, js_CheckAccess,
1091
+ NULL, array_dropProperty,
1092
+ NULL, NULL,
1093
+ NULL, js_HasInstance,
1094
+ js_SetProtoOrParent, js_SetProtoOrParent,
1095
+ array_trace, NULL,
1096
+ NULL, NULL
1097
+ };
1098
+
1099
+ static JSObjectOps *
1100
+ array_getObjectOps(JSContext *cx, JSClass *clasp)
1101
+ {
1102
+ return &js_ArrayObjectOps;
1103
+ }
1104
+
1105
+ JSClass js_ArrayClass = {
1106
+ "Array",
1107
+ JSCLASS_HAS_PRIVATE | JSCLASS_HAS_CACHED_PROTO(JSProto_Array) |
1108
+ JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_NEW_ENUMERATE,
1109
+ JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
1110
+ JS_EnumerateStub, JS_ResolveStub, js_TryValueOf, array_finalize,
1111
+ array_getObjectOps, NULL, NULL, NULL,
1112
+ NULL, NULL, NULL, NULL
1113
+ };
1114
+
1115
+ JSClass js_SlowArrayClass = {
1116
+ "Array",
1117
+ JSCLASS_HAS_PRIVATE | JSCLASS_HAS_CACHED_PROTO(JSProto_Array),
1118
+ slowarray_addProperty, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
1119
+ JS_EnumerateStub, JS_ResolveStub, js_TryValueOf, JS_FinalizeStub,
1120
+ slowarray_getObjectOps, NULL, NULL, NULL,
1121
+ NULL, NULL, NULL, NULL
1122
+ };
1123
+
1124
+ /*
1125
+ * Convert an array object from fast-and-dense to slow-and-flexible.
1126
+ */
1127
+ JSBool
1128
+ js_MakeArraySlow(JSContext *cx, JSObject *obj)
1129
+ {
1130
+ JSObjectMap *map, *oldmap;
1131
+ uint32 i, length;
1132
+
1133
+ JS_ASSERT(OBJ_GET_CLASS(cx, obj) == &js_ArrayClass);
1134
+
1135
+ /* Create a native scope. */
1136
+ map = js_NewObjectMap(cx, obj->map->nrefs, &js_SlowArrayObjectOps,
1137
+ &js_SlowArrayClass, obj);
1138
+ if (!map)
1139
+ return JS_FALSE;
1140
+
1141
+ length = ARRAY_DENSE_LENGTH(obj);
1142
+ if (length) {
1143
+ map->freeslot = STOBJ_NSLOTS(obj) + JS_INITIAL_NSLOTS;
1144
+ obj->dslots[-1] = JS_INITIAL_NSLOTS + length;
1145
+ } else {
1146
+ map->freeslot = STOBJ_NSLOTS(obj);
1147
+ }
1148
+
1149
+ /* Create new properties pointing to existing values in dslots */
1150
+ for (i = 0; i < length; i++) {
1151
+ jsid id;
1152
+ JSScopeProperty *sprop;
1153
+
1154
+ if (!JS_ValueToId(cx, INT_TO_JSVAL(i), &id))
1155
+ goto out_bad;
1156
+
1157
+ if (obj->dslots[i] == JSVAL_HOLE) {
1158
+ obj->dslots[i] = JSVAL_VOID;
1159
+ continue;
1160
+ }
1161
+
1162
+ sprop = js_AddScopeProperty(cx, (JSScope *)map, id, NULL, NULL,
1163
+ i + JS_INITIAL_NSLOTS, JSPROP_ENUMERATE,
1164
+ 0, 0);
1165
+ if (!sprop)
1166
+ goto out_bad;
1167
+ }
1168
+
1169
+ /* Render our formerly-reserved count property GC-safe. */
1170
+ obj->fslots[JSSLOT_ARRAY_COUNT] = JSVAL_VOID;
1171
+
1172
+ /* Make sure we preserve any flags borrowing bits in JSSLOT_CLASS. */
1173
+ obj->fslots[JSSLOT_CLASS] ^= (jsval) &js_ArrayClass;
1174
+ obj->fslots[JSSLOT_CLASS] |= (jsval) &js_SlowArrayClass;
1175
+
1176
+ /* Swap in our new map. */
1177
+ oldmap = obj->map;
1178
+ obj->map = map;
1179
+ array_destroyObjectMap(cx, oldmap);
1180
+
1181
+ return JS_TRUE;
1182
+
1183
+ out_bad:
1184
+ js_DestroyObjectMap(cx, map);
1185
+ return JS_FALSE;
1186
+ }
1187
+
1188
+ enum ArrayToStringOp {
1189
+ TO_STRING,
1190
+ TO_LOCALE_STRING,
1191
+ TO_SOURCE
1192
+ };
1193
+
1194
+ /*
1195
+ * When op is TO_STRING or TO_LOCALE_STRING sep indicates a separator to use
1196
+ * or "," when sep is NULL.
1197
+ * When op is TO_SOURCE sep must be NULL.
1198
+ */
1199
+ static JSBool
1200
+ array_join_sub(JSContext *cx, JSObject *obj, enum ArrayToStringOp op,
1201
+ JSString *sep, jsval *rval)
1202
+ {
1203
+ JSBool ok, hole;
1204
+ jsuint length, index;
1205
+ jschar *chars, *ochars;
1206
+ size_t nchars, growth, seplen, tmplen, extratail;
1207
+ const jschar *sepstr;
1208
+ JSString *str;
1209
+ JSHashEntry *he;
1210
+ JSAtom *atom;
1211
+
1212
+ JS_CHECK_RECURSION(cx, return JS_FALSE);
1213
+
1214
+ ok = js_GetLengthProperty(cx, obj, &length);
1215
+ if (!ok)
1216
+ return JS_FALSE;
1217
+
1218
+ he = js_EnterSharpObject(cx, obj, NULL, &chars);
1219
+ if (!he)
1220
+ return JS_FALSE;
1221
+ #ifdef DEBUG
1222
+ growth = (size_t) -1;
1223
+ #endif
1224
+
1225
+ if (op == TO_SOURCE) {
1226
+ if (IS_SHARP(he)) {
1227
+ #if JS_HAS_SHARP_VARS
1228
+ nchars = js_strlen(chars);
1229
+ #else
1230
+ chars[0] = '[';
1231
+ chars[1] = ']';
1232
+ chars[2] = 0;
1233
+ nchars = 2;
1234
+ #endif
1235
+ goto make_string;
1236
+ }
1237
+
1238
+ /*
1239
+ * Always allocate 2 extra chars for closing ']' and terminating 0
1240
+ * and then preallocate 1 + extratail to include starting '['.
1241
+ */
1242
+ extratail = 2;
1243
+ growth = (1 + extratail) * sizeof(jschar);
1244
+ if (!chars) {
1245
+ nchars = 0;
1246
+ chars = (jschar *) malloc(growth);
1247
+ if (!chars)
1248
+ goto done;
1249
+ } else {
1250
+ MAKE_SHARP(he);
1251
+ nchars = js_strlen(chars);
1252
+ growth += nchars * sizeof(jschar);
1253
+ chars = (jschar *)realloc((ochars = chars), growth);
1254
+ if (!chars) {
1255
+ free(ochars);
1256
+ goto done;
1257
+ }
1258
+ }
1259
+ chars[nchars++] = '[';
1260
+ JS_ASSERT(sep == NULL);
1261
+ sepstr = NULL; /* indicates to use ", " as separator */
1262
+ seplen = 2;
1263
+ } else {
1264
+ /*
1265
+ * Free any sharp variable definition in chars. Normally, we would
1266
+ * MAKE_SHARP(he) so that only the first sharp variable annotation is
1267
+ * a definition, and all the rest are references, but in the current
1268
+ * case of (op != TO_SOURCE), we don't need chars at all.
1269
+ */
1270
+ if (chars)
1271
+ JS_free(cx, chars);
1272
+ chars = NULL;
1273
+ nchars = 0;
1274
+ extratail = 1; /* allocate extra char for terminating 0 */
1275
+
1276
+ /* Return the empty string on a cycle as well as on empty join. */
1277
+ if (IS_BUSY(he) || length == 0) {
1278
+ js_LeaveSharpObject(cx, NULL);
1279
+ *rval = JS_GetEmptyStringValue(cx);
1280
+ return ok;
1281
+ }
1282
+
1283
+ /* Flag he as BUSY so we can distinguish a cycle from a join-point. */
1284
+ MAKE_BUSY(he);
1285
+
1286
+ if (sep) {
1287
+ JSSTRING_CHARS_AND_LENGTH(sep, sepstr, seplen);
1288
+ } else {
1289
+ sepstr = NULL; /* indicates to use "," as separator */
1290
+ seplen = 1;
1291
+ }
1292
+ }
1293
+
1294
+ /* Use rval to locally root each element value as we loop and convert. */
1295
+ for (index = 0; index < length; index++) {
1296
+ ok = (JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) &&
1297
+ GetArrayElement(cx, obj, index, &hole, rval));
1298
+ if (!ok)
1299
+ goto done;
1300
+ if (hole ||
1301
+ (op != TO_SOURCE &&
1302
+ (JSVAL_IS_VOID(*rval) || JSVAL_IS_NULL(*rval)))) {
1303
+ str = cx->runtime->emptyString;
1304
+ } else {
1305
+ if (op == TO_LOCALE_STRING) {
1306
+ JSObject *robj;
1307
+
1308
+ atom = cx->runtime->atomState.toLocaleStringAtom;
1309
+ ok = js_ValueToObject(cx, *rval, &robj);
1310
+ if (ok) {
1311
+ /* Re-use *rval to protect robj temporarily. */
1312
+ *rval = OBJECT_TO_JSVAL(robj);
1313
+ ok = js_TryMethod(cx, robj, atom, 0, NULL, rval);
1314
+ }
1315
+ if (!ok)
1316
+ goto done;
1317
+ str = js_ValueToString(cx, *rval);
1318
+ } else if (op == TO_STRING) {
1319
+ str = js_ValueToString(cx, *rval);
1320
+ } else {
1321
+ JS_ASSERT(op == TO_SOURCE);
1322
+ str = js_ValueToSource(cx, *rval);
1323
+ }
1324
+ if (!str) {
1325
+ ok = JS_FALSE;
1326
+ goto done;
1327
+ }
1328
+ }
1329
+
1330
+ /*
1331
+ * Do not append separator after the last element unless it is a hole
1332
+ * and we are in toSource. In that case we append single ",".
1333
+ */
1334
+ if (index + 1 == length)
1335
+ seplen = (hole && op == TO_SOURCE) ? 1 : 0;
1336
+
1337
+ /* Allocate 1 at end for closing bracket and zero. */
1338
+ tmplen = JSSTRING_LENGTH(str);
1339
+ growth = nchars + tmplen + seplen + extratail;
1340
+ if (nchars > growth || tmplen > growth ||
1341
+ growth > (size_t)-1 / sizeof(jschar)) {
1342
+ if (chars) {
1343
+ free(chars);
1344
+ chars = NULL;
1345
+ }
1346
+ goto done;
1347
+ }
1348
+ growth *= sizeof(jschar);
1349
+ JS_COUNT_OPERATION(cx, JSOW_ALLOCATION);
1350
+ if (!chars) {
1351
+ chars = (jschar *) malloc(growth);
1352
+ if (!chars)
1353
+ goto done;
1354
+ } else {
1355
+ chars = (jschar *) realloc((ochars = chars), growth);
1356
+ if (!chars) {
1357
+ free(ochars);
1358
+ goto done;
1359
+ }
1360
+ }
1361
+
1362
+ js_strncpy(&chars[nchars], JSSTRING_CHARS(str), tmplen);
1363
+ nchars += tmplen;
1364
+
1365
+ if (seplen) {
1366
+ if (sepstr) {
1367
+ js_strncpy(&chars[nchars], sepstr, seplen);
1368
+ } else {
1369
+ JS_ASSERT(seplen == 1 || seplen == 2);
1370
+ chars[nchars] = ',';
1371
+ if (seplen == 2)
1372
+ chars[nchars + 1] = ' ';
1373
+ }
1374
+ nchars += seplen;
1375
+ }
1376
+ }
1377
+
1378
+ done:
1379
+ if (op == TO_SOURCE) {
1380
+ if (chars)
1381
+ chars[nchars++] = ']';
1382
+ } else {
1383
+ CLEAR_BUSY(he);
1384
+ }
1385
+ js_LeaveSharpObject(cx, NULL);
1386
+ if (!ok) {
1387
+ if (chars)
1388
+ free(chars);
1389
+ return ok;
1390
+ }
1391
+
1392
+ make_string:
1393
+ if (!chars) {
1394
+ JS_ReportOutOfMemory(cx);
1395
+ return JS_FALSE;
1396
+ }
1397
+ chars[nchars] = 0;
1398
+ JS_ASSERT(growth == (size_t)-1 || (nchars + 1) * sizeof(jschar) == growth);
1399
+ str = js_NewString(cx, chars, nchars);
1400
+ if (!str) {
1401
+ free(chars);
1402
+ return JS_FALSE;
1403
+ }
1404
+ *rval = STRING_TO_JSVAL(str);
1405
+ return JS_TRUE;
1406
+ }
1407
+
1408
+ #if JS_HAS_TOSOURCE
1409
+ static JSBool
1410
+ array_toSource(JSContext *cx, uintN argc, jsval *vp)
1411
+ {
1412
+ JSObject *obj;
1413
+
1414
+ obj = JS_THIS_OBJECT(cx, vp);
1415
+ if (OBJ_GET_CLASS(cx, obj) != &js_SlowArrayClass &&
1416
+ !JS_InstanceOf(cx, obj, &js_ArrayClass, vp + 2)) {
1417
+ return JS_FALSE;
1418
+ }
1419
+ return array_join_sub(cx, obj, TO_SOURCE, NULL, vp);
1420
+ }
1421
+ #endif
1422
+
1423
+ static JSBool
1424
+ array_toString(JSContext *cx, uintN argc, jsval *vp)
1425
+ {
1426
+ JSObject *obj;
1427
+
1428
+ obj = JS_THIS_OBJECT(cx, vp);
1429
+ if (OBJ_GET_CLASS(cx, obj) != &js_SlowArrayClass &&
1430
+ !JS_InstanceOf(cx, obj, &js_ArrayClass, vp + 2)) {
1431
+ return JS_FALSE;
1432
+ }
1433
+ return array_join_sub(cx, obj, TO_STRING, NULL, vp);
1434
+ }
1435
+
1436
+ static JSBool
1437
+ array_toLocaleString(JSContext *cx, uintN argc, jsval *vp)
1438
+ {
1439
+ JSObject *obj;
1440
+
1441
+ obj = JS_THIS_OBJECT(cx, vp);
1442
+ if (OBJ_GET_CLASS(cx, obj) != &js_SlowArrayClass &&
1443
+ !JS_InstanceOf(cx, obj, &js_ArrayClass, vp + 2)) {
1444
+ return JS_FALSE;
1445
+ }
1446
+
1447
+ /*
1448
+ * Passing comma here as the separator. Need a way to get a
1449
+ * locale-specific version.
1450
+ */
1451
+ return array_join_sub(cx, obj, TO_LOCALE_STRING, NULL, vp);
1452
+ }
1453
+
1454
+ static JSBool
1455
+ InitArrayElements(JSContext *cx, JSObject *obj, jsuint start, jsuint end,
1456
+ jsval *vector)
1457
+ {
1458
+ if (OBJ_IS_DENSE_ARRAY(cx, obj)) {
1459
+ if (!EnsureLength(cx, obj, end))
1460
+ return JS_FALSE;
1461
+
1462
+ if (end > (uint32)obj->fslots[JSSLOT_ARRAY_LENGTH])
1463
+ obj->fslots[JSSLOT_ARRAY_LENGTH] = end;
1464
+
1465
+ memcpy(obj->dslots + start, vector, sizeof(jsval) * (end - start));
1466
+ return JS_TRUE;
1467
+ }
1468
+
1469
+ while (start != end) {
1470
+ if (!JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) ||
1471
+ !SetArrayElement(cx, obj, start++, *vector++)) {
1472
+ return JS_FALSE;
1473
+ }
1474
+ }
1475
+ return JS_TRUE;
1476
+ }
1477
+
1478
+ static JSBool
1479
+ InitArrayObject(JSContext *cx, JSObject *obj, jsuint length, jsval *vector)
1480
+ {
1481
+ JS_ASSERT(OBJ_IS_ARRAY(cx, obj));
1482
+
1483
+ obj->fslots[JSSLOT_ARRAY_LENGTH] = length;
1484
+
1485
+ if (vector) {
1486
+ if (!EnsureLength(cx, obj, length))
1487
+ return JS_FALSE;
1488
+ memcpy(obj->dslots, vector, length * sizeof (jsval));
1489
+ obj->fslots[JSSLOT_ARRAY_COUNT] = length;
1490
+ } else {
1491
+ obj->fslots[JSSLOT_ARRAY_COUNT] = 0;
1492
+ }
1493
+ return JS_TRUE;
1494
+ }
1495
+
1496
+ /*
1497
+ * Perl-inspired join, reverse, and sort.
1498
+ */
1499
+ static JSBool
1500
+ array_join(JSContext *cx, uintN argc, jsval *vp)
1501
+ {
1502
+ JSString *str;
1503
+ JSObject *obj;
1504
+
1505
+ if (JSVAL_IS_VOID(vp[2])) {
1506
+ str = NULL;
1507
+ } else {
1508
+ str = js_ValueToString(cx, vp[2]);
1509
+ if (!str)
1510
+ return JS_FALSE;
1511
+ vp[2] = STRING_TO_JSVAL(str);
1512
+ }
1513
+ obj = JS_THIS_OBJECT(cx, vp);
1514
+ return obj && array_join_sub(cx, obj, TO_STRING, str, vp);
1515
+ }
1516
+
1517
+ static JSBool
1518
+ array_reverse(JSContext *cx, uintN argc, jsval *vp)
1519
+ {
1520
+ JSObject *obj;
1521
+ JSTempValueRooter tvr;
1522
+ jsuint len, half, i;
1523
+ JSBool ok, hole, hole2;
1524
+
1525
+ obj = JS_THIS_OBJECT(cx, vp);
1526
+ if (!obj || !js_GetLengthProperty(cx, obj, &len))
1527
+ return JS_FALSE;
1528
+
1529
+ ok = JS_TRUE;
1530
+ JS_PUSH_SINGLE_TEMP_ROOT(cx, JSVAL_NULL, &tvr);
1531
+ half = len / 2;
1532
+ for (i = 0; i < half; i++) {
1533
+ ok = JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) &&
1534
+ GetArrayElement(cx, obj, i, &hole, &tvr.u.value) &&
1535
+ GetArrayElement(cx, obj, len - i - 1, &hole2, vp) &&
1536
+ SetOrDeleteArrayElement(cx, obj, len - i - 1, hole, tvr.u.value) &&
1537
+ SetOrDeleteArrayElement(cx, obj, i, hole2, *vp);
1538
+ if (!ok)
1539
+ break;
1540
+ }
1541
+ JS_POP_TEMP_ROOT(cx, &tvr);
1542
+
1543
+ *vp = OBJECT_TO_JSVAL(obj);
1544
+ return ok;
1545
+ }
1546
+
1547
+ typedef struct MSortArgs {
1548
+ size_t elsize;
1549
+ JSComparator cmp;
1550
+ void *arg;
1551
+ JSBool fastcopy;
1552
+ } MSortArgs;
1553
+
1554
+ /* Helper function for js_MergeSort. */
1555
+ static JSBool
1556
+ MergeArrays(MSortArgs *msa, void *src, void *dest, size_t run1, size_t run2)
1557
+ {
1558
+ void *arg, *a, *b, *c;
1559
+ size_t elsize, runtotal;
1560
+ int cmp_result;
1561
+ JSComparator cmp;
1562
+ JSBool fastcopy;
1563
+
1564
+ runtotal = run1 + run2;
1565
+
1566
+ elsize = msa->elsize;
1567
+ cmp = msa->cmp;
1568
+ arg = msa->arg;
1569
+ fastcopy = msa->fastcopy;
1570
+
1571
+ #define CALL_CMP(a, b) \
1572
+ if (!cmp(arg, (a), (b), &cmp_result)) return JS_FALSE;
1573
+
1574
+ /* Copy runs already in sorted order. */
1575
+ b = (char *)src + run1 * elsize;
1576
+ a = (char *)b - elsize;
1577
+ CALL_CMP(a, b);
1578
+ if (cmp_result <= 0) {
1579
+ memcpy(dest, src, runtotal * elsize);
1580
+ return JS_TRUE;
1581
+ }
1582
+
1583
+ #define COPY_ONE(p,q,n) \
1584
+ (fastcopy ? (void)(*(jsval*)(p) = *(jsval*)(q)) : (void)memcpy(p, q, n))
1585
+
1586
+ a = src;
1587
+ c = dest;
1588
+ for (; runtotal != 0; runtotal--) {
1589
+ JSBool from_a = run2 == 0;
1590
+ if (!from_a && run1 != 0) {
1591
+ CALL_CMP(a,b);
1592
+ from_a = cmp_result <= 0;
1593
+ }
1594
+
1595
+ if (from_a) {
1596
+ COPY_ONE(c, a, elsize);
1597
+ run1--;
1598
+ a = (char *)a + elsize;
1599
+ } else {
1600
+ COPY_ONE(c, b, elsize);
1601
+ run2--;
1602
+ b = (char *)b + elsize;
1603
+ }
1604
+ c = (char *)c + elsize;
1605
+ }
1606
+ #undef COPY_ONE
1607
+ #undef CALL_CMP
1608
+
1609
+ return JS_TRUE;
1610
+ }
1611
+
1612
+ /*
1613
+ * This sort is stable, i.e. sequence of equal elements is preserved.
1614
+ * See also bug #224128.
1615
+ */
1616
+ JSBool
1617
+ js_MergeSort(void *src, size_t nel, size_t elsize,
1618
+ JSComparator cmp, void *arg, void *tmp)
1619
+ {
1620
+ void *swap, *vec1, *vec2;
1621
+ MSortArgs msa;
1622
+ size_t i, j, lo, hi, run;
1623
+ JSBool fastcopy;
1624
+ int cmp_result;
1625
+
1626
+ /* Avoid memcpy overhead for word-sized and word-aligned elements. */
1627
+ fastcopy = (elsize == sizeof(jsval) &&
1628
+ (((jsuword) src | (jsuword) tmp) & JSVAL_ALIGN) == 0);
1629
+ #define COPY_ONE(p,q,n) \
1630
+ (fastcopy ? (void)(*(jsval*)(p) = *(jsval*)(q)) : (void)memcpy(p, q, n))
1631
+ #define CALL_CMP(a, b) \
1632
+ if (!cmp(arg, (a), (b), &cmp_result)) return JS_FALSE;
1633
+ #define INS_SORT_INT 4
1634
+
1635
+ /*
1636
+ * Apply insertion sort to small chunks to reduce the number of merge
1637
+ * passes needed.
1638
+ */
1639
+ for (lo = 0; lo < nel; lo += INS_SORT_INT) {
1640
+ hi = lo + INS_SORT_INT;
1641
+ if (hi >= nel)
1642
+ hi = nel;
1643
+ for (i = lo + 1; i < hi; i++) {
1644
+ vec1 = (char *)src + i * elsize;
1645
+ vec2 = (char *)vec1 - elsize;
1646
+ for (j = i; j > lo; j--) {
1647
+ CALL_CMP(vec2, vec1);
1648
+ /* "<=" instead of "<" insures the sort is stable */
1649
+ if (cmp_result <= 0) {
1650
+ break;
1651
+ }
1652
+
1653
+ /* Swap elements, using "tmp" as tmp storage */
1654
+ COPY_ONE(tmp, vec2, elsize);
1655
+ COPY_ONE(vec2, vec1, elsize);
1656
+ COPY_ONE(vec1, tmp, elsize);
1657
+ vec1 = vec2;
1658
+ vec2 = (char *)vec1 - elsize;
1659
+ }
1660
+ }
1661
+ }
1662
+ #undef CALL_CMP
1663
+ #undef COPY_ONE
1664
+
1665
+ msa.elsize = elsize;
1666
+ msa.cmp = cmp;
1667
+ msa.arg = arg;
1668
+ msa.fastcopy = fastcopy;
1669
+
1670
+ vec1 = src;
1671
+ vec2 = tmp;
1672
+ for (run = INS_SORT_INT; run < nel; run *= 2) {
1673
+ for (lo = 0; lo < nel; lo += 2 * run) {
1674
+ hi = lo + run;
1675
+ if (hi >= nel) {
1676
+ memcpy((char *)vec2 + lo * elsize, (char *)vec1 + lo * elsize,
1677
+ (nel - lo) * elsize);
1678
+ break;
1679
+ }
1680
+ if (!MergeArrays(&msa, (char *)vec1 + lo * elsize,
1681
+ (char *)vec2 + lo * elsize, run,
1682
+ hi + run > nel ? nel - hi : run)) {
1683
+ return JS_FALSE;
1684
+ }
1685
+ }
1686
+ swap = vec1;
1687
+ vec1 = vec2;
1688
+ vec2 = swap;
1689
+ }
1690
+ if (src != vec1)
1691
+ memcpy(src, tmp, nel * elsize);
1692
+
1693
+ return JS_TRUE;
1694
+ }
1695
+
1696
+ typedef struct CompareArgs {
1697
+ JSContext *context;
1698
+ jsval fval;
1699
+ jsval *elemroot; /* stack needed for js_Invoke */
1700
+ } CompareArgs;
1701
+
1702
+ static JSBool
1703
+ sort_compare(void *arg, const void *a, const void *b, int *result)
1704
+ {
1705
+ jsval av = *(const jsval *)a, bv = *(const jsval *)b;
1706
+ CompareArgs *ca = (CompareArgs *) arg;
1707
+ JSContext *cx = ca->context;
1708
+ jsval *invokevp, *sp;
1709
+ jsdouble cmp;
1710
+
1711
+ /**
1712
+ * array_sort deals with holes and undefs on its own and they should not
1713
+ * come here.
1714
+ */
1715
+ JS_ASSERT(av != JSVAL_VOID);
1716
+ JS_ASSERT(bv != JSVAL_VOID);
1717
+
1718
+ if (!JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP))
1719
+ return JS_FALSE;
1720
+
1721
+ invokevp = ca->elemroot;
1722
+ sp = invokevp;
1723
+ *sp++ = ca->fval;
1724
+ *sp++ = JSVAL_NULL;
1725
+ *sp++ = av;
1726
+ *sp++ = bv;
1727
+
1728
+ if (!js_Invoke(cx, 2, invokevp, 0))
1729
+ return JS_FALSE;
1730
+
1731
+ cmp = js_ValueToNumber(cx, invokevp);
1732
+ if (JSVAL_IS_NULL(*invokevp))
1733
+ return JS_FALSE;
1734
+
1735
+ /* Clamp cmp to -1, 0, 1. */
1736
+ *result = 0;
1737
+ if (!JSDOUBLE_IS_NaN(cmp) && cmp != 0)
1738
+ *result = cmp > 0 ? 1 : -1;
1739
+
1740
+ /*
1741
+ * XXX else report some kind of error here? ECMA talks about 'consistent
1742
+ * compare functions' that don't return NaN, but is silent about what the
1743
+ * result should be. So we currently ignore it.
1744
+ */
1745
+
1746
+ return JS_TRUE;
1747
+ }
1748
+
1749
+ static int
1750
+ sort_compare_strings(void *arg, const void *a, const void *b, int *result)
1751
+ {
1752
+ jsval av = *(const jsval *)a, bv = *(const jsval *)b;
1753
+
1754
+ JS_ASSERT(JSVAL_IS_STRING(av));
1755
+ JS_ASSERT(JSVAL_IS_STRING(bv));
1756
+ if (!JS_CHECK_OPERATION_LIMIT((JSContext *)arg, JSOW_JUMP))
1757
+ return JS_FALSE;
1758
+
1759
+ *result = (int) js_CompareStrings(JSVAL_TO_STRING(av), JSVAL_TO_STRING(bv));
1760
+ return JS_TRUE;
1761
+ }
1762
+
1763
+ /*
1764
+ * The array_sort function below assumes JSVAL_NULL is zero in order to
1765
+ * perform initialization using memset. Other parts of SpiderMonkey likewise
1766
+ * "know" that JSVAL_NULL is zero; this static assertion covers all cases.
1767
+ */
1768
+ JS_STATIC_ASSERT(JSVAL_NULL == 0);
1769
+
1770
+ static JSBool
1771
+ array_sort(JSContext *cx, uintN argc, jsval *vp)
1772
+ {
1773
+ jsval *argv, fval, *vec, *mergesort_tmp, v;
1774
+ JSObject *obj;
1775
+ CompareArgs ca;
1776
+ jsuint len, newlen, i, undefs;
1777
+ JSTempValueRooter tvr;
1778
+ JSBool hole, ok;
1779
+ size_t elemsize;
1780
+ JSString *str;
1781
+
1782
+ /*
1783
+ * Optimize the default compare function case if all of obj's elements
1784
+ * have values of type string.
1785
+ */
1786
+ JSBool all_strings;
1787
+
1788
+ argv = JS_ARGV(cx, vp);
1789
+ if (argc > 0) {
1790
+ if (JSVAL_IS_PRIMITIVE(argv[0])) {
1791
+ JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
1792
+ JSMSG_BAD_SORT_ARG);
1793
+ return JS_FALSE;
1794
+ }
1795
+ fval = argv[0]; /* non-default compare function */
1796
+ } else {
1797
+ fval = JSVAL_NULL;
1798
+ }
1799
+
1800
+ obj = JS_THIS_OBJECT(cx, vp);
1801
+ if (!obj || !js_GetLengthProperty(cx, obj, &len))
1802
+ return JS_FALSE;
1803
+ if (len == 0) {
1804
+ *vp = OBJECT_TO_JSVAL(obj);
1805
+ return JS_TRUE;
1806
+ }
1807
+
1808
+ /*
1809
+ * We need a temporary array of 2 * len jsvals to hold the array elements
1810
+ * and the scratch space for merge sort. Check that its size does not
1811
+ * overflow size_t, which would allow for indexing beyond the end of the
1812
+ * malloc'd vector.
1813
+ */
1814
+ #if JS_BITS_PER_WORD == 32
1815
+ if ((size_t)len > ~(size_t)0 / (2 * sizeof(jsval))) {
1816
+ js_ReportAllocationOverflow(cx);
1817
+ return JS_FALSE;
1818
+ }
1819
+ #endif
1820
+ vec = (jsval *) JS_malloc(cx, 2 * (size_t) len * sizeof(jsval));
1821
+ if (!vec)
1822
+ return JS_FALSE;
1823
+
1824
+ /*
1825
+ * Initialize vec as a root. We will clear elements of vec one by
1826
+ * one while increasing tvr.count when we know that the property at
1827
+ * the corresponding index exists and its value must be rooted.
1828
+ *
1829
+ * In this way when sorting a huge mostly sparse array we will not
1830
+ * access the tail of vec corresponding to properties that do not
1831
+ * exist, allowing OS to avoiding committing RAM. See bug 330812.
1832
+ *
1833
+ * After this point control must flow through label out: to exit.
1834
+ */
1835
+ JS_PUSH_TEMP_ROOT(cx, 0, vec, &tvr);
1836
+
1837
+ /*
1838
+ * By ECMA 262, 15.4.4.11, a property that does not exist (which we
1839
+ * call a "hole") is always greater than an existing property with
1840
+ * value undefined and that is always greater than any other property.
1841
+ * Thus to sort holes and undefs we simply count them, sort the rest
1842
+ * of elements, append undefs after them and then make holes after
1843
+ * undefs.
1844
+ */
1845
+ undefs = 0;
1846
+ newlen = 0;
1847
+ all_strings = JS_TRUE;
1848
+ for (i = 0; i < len; i++) {
1849
+ ok = JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP);
1850
+ if (!ok)
1851
+ goto out;
1852
+
1853
+ /* Clear vec[newlen] before including it in the rooted set. */
1854
+ vec[newlen] = JSVAL_NULL;
1855
+ tvr.count = newlen + 1;
1856
+ ok = GetArrayElement(cx, obj, i, &hole, &vec[newlen]);
1857
+ if (!ok)
1858
+ goto out;
1859
+
1860
+ if (hole)
1861
+ continue;
1862
+
1863
+ if (vec[newlen] == JSVAL_VOID) {
1864
+ ++undefs;
1865
+ continue;
1866
+ }
1867
+
1868
+ /* We know JSVAL_IS_STRING yields 0 or 1, so avoid a branch via &=. */
1869
+ all_strings &= JSVAL_IS_STRING(vec[newlen]);
1870
+
1871
+ ++newlen;
1872
+ }
1873
+
1874
+ if (newlen == 0) {
1875
+ /* The array has only holes and undefs. */
1876
+ ok = JS_TRUE;
1877
+ goto out;
1878
+ }
1879
+
1880
+ /*
1881
+ * The first newlen elements of vec are copied from the array object
1882
+ * (above). The remaining newlen positions are used as GC-rooted scratch
1883
+ * space for mergesort. We must clear the space before including it to
1884
+ * the root set covered by tvr.count. We assume JSVAL_NULL==0 to optimize
1885
+ * initialization using memset.
1886
+ */
1887
+ mergesort_tmp = vec + newlen;
1888
+ memset(mergesort_tmp, 0, newlen * sizeof(jsval));
1889
+ tvr.count = newlen * 2;
1890
+
1891
+ /* Here len == 2 * (newlen + undefs + number_of_holes). */
1892
+ if (fval == JSVAL_NULL) {
1893
+ /*
1894
+ * Sort using the default comparator converting all elements to
1895
+ * strings.
1896
+ */
1897
+ if (all_strings) {
1898
+ elemsize = sizeof(jsval);
1899
+ } else {
1900
+ /*
1901
+ * To avoid string conversion on each compare we do it only once
1902
+ * prior to sorting. But we also need the space for the original
1903
+ * values to recover the sorting result. To reuse
1904
+ * sort_compare_strings we move the original values to the odd
1905
+ * indexes in vec, put the string conversion results in the even
1906
+ * indexes and pass 2 * sizeof(jsval) as an element size to the
1907
+ * sorting function. In this way sort_compare_strings will only
1908
+ * see the string values when it casts the compare arguments as
1909
+ * pointers to jsval.
1910
+ *
1911
+ * This requires doubling the temporary storage including the
1912
+ * scratch space for the merge sort. Since vec already contains
1913
+ * the rooted scratch space for newlen elements at the tail, we
1914
+ * can use it to rearrange and convert to strings first and try
1915
+ * realloc only when we know that we successfully converted all
1916
+ * the elements.
1917
+ */
1918
+ #if JS_BITS_PER_WORD == 32
1919
+ if ((size_t)newlen > ~(size_t)0 / (4 * sizeof(jsval))) {
1920
+ js_ReportAllocationOverflow(cx);
1921
+ ok = JS_FALSE;
1922
+ goto out;
1923
+ }
1924
+ #endif
1925
+
1926
+ /*
1927
+ * Rearrange and string-convert the elements of the vector from
1928
+ * the tail here and, after sorting, move the results back
1929
+ * starting from the start to prevent overwrite the existing
1930
+ * elements.
1931
+ */
1932
+ i = newlen;
1933
+ do {
1934
+ --i;
1935
+ ok = JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP);
1936
+ if (!ok)
1937
+ goto out;
1938
+ v = vec[i];
1939
+ str = js_ValueToString(cx, v);
1940
+ if (!str) {
1941
+ ok = JS_FALSE;
1942
+ goto out;
1943
+ }
1944
+ vec[2 * i] = STRING_TO_JSVAL(str);
1945
+ vec[2 * i + 1] = v;
1946
+ } while (i != 0);
1947
+
1948
+ JS_ASSERT(tvr.u.array == vec);
1949
+ vec = (jsval *) JS_realloc(cx, vec,
1950
+ 4 * (size_t) newlen * sizeof(jsval));
1951
+ if (!vec) {
1952
+ vec = tvr.u.array;
1953
+ ok = JS_FALSE;
1954
+ goto out;
1955
+ }
1956
+ tvr.u.array = vec;
1957
+ mergesort_tmp = vec + 2 * newlen;
1958
+ memset(mergesort_tmp, 0, newlen * 2 * sizeof(jsval));
1959
+ tvr.count = newlen * 4;
1960
+ elemsize = 2 * sizeof(jsval);
1961
+ }
1962
+ ok = js_MergeSort(vec, (size_t) newlen, elemsize,
1963
+ sort_compare_strings, cx, mergesort_tmp);
1964
+ if (!ok)
1965
+ goto out;
1966
+ if (!all_strings) {
1967
+ /*
1968
+ * We want to make the following loop fast and to unroot the
1969
+ * cached results of toString invocations before the operation
1970
+ * callback has a chance to run the GC. For this reason we do
1971
+ * not call JS_CHECK_OPERATION_LIMIT in the loop.
1972
+ */
1973
+ i = 0;
1974
+ do {
1975
+ vec[i] = vec[2 * i + 1];
1976
+ } while (++i != newlen);
1977
+ }
1978
+ } else {
1979
+ void *mark;
1980
+
1981
+ ca.context = cx;
1982
+ ca.fval = fval;
1983
+ ca.elemroot = js_AllocStack(cx, 2 + 2, &mark);
1984
+ if (!ca.elemroot) {
1985
+ ok = JS_FALSE;
1986
+ goto out;
1987
+ }
1988
+ ok = js_MergeSort(vec, (size_t) newlen, sizeof(jsval),
1989
+ sort_compare, &ca, mergesort_tmp);
1990
+ js_FreeStack(cx, mark);
1991
+ if (!ok)
1992
+ goto out;
1993
+ }
1994
+
1995
+ /*
1996
+ * We no longer need to root the scratch space for the merge sort, so
1997
+ * unroot it now to make the job of a potential GC under InitArrayElements
1998
+ * easier.
1999
+ */
2000
+ tvr.count = newlen;
2001
+ ok = InitArrayElements(cx, obj, 0, newlen, vec);
2002
+ if (!ok)
2003
+ goto out;
2004
+
2005
+ out:
2006
+ JS_POP_TEMP_ROOT(cx, &tvr);
2007
+ JS_free(cx, vec);
2008
+ if (!ok)
2009
+ return JS_FALSE;
2010
+
2011
+ /* Set undefs that sorted after the rest of elements. */
2012
+ while (undefs != 0) {
2013
+ --undefs;
2014
+ if (!JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) ||
2015
+ !SetArrayElement(cx, obj, newlen++, JSVAL_VOID)) {
2016
+ return JS_FALSE;
2017
+ }
2018
+ }
2019
+
2020
+ /* Re-create any holes that sorted to the end of the array. */
2021
+ while (len > newlen) {
2022
+ if (!JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) ||
2023
+ !DeleteArrayElement(cx, obj, --len)) {
2024
+ return JS_FALSE;
2025
+ }
2026
+ }
2027
+ *vp = OBJECT_TO_JSVAL(obj);
2028
+ return JS_TRUE;
2029
+ }
2030
+
2031
+ /*
2032
+ * Perl-inspired push, pop, shift, unshift, and splice methods.
2033
+ */
2034
+ static JSBool
2035
+ array_push_slowly(JSContext *cx, JSObject *obj, uintN argc, jsval *vp)
2036
+ {
2037
+ jsuint length, newlength;
2038
+
2039
+ if (!js_GetLengthProperty(cx, obj, &length))
2040
+ return JS_FALSE;
2041
+ newlength = length + argc;
2042
+ if (!InitArrayElements(cx, obj, length, newlength, vp + 2))
2043
+ return JS_FALSE;
2044
+
2045
+ /* Per ECMA-262, return the new array length. */
2046
+ if (!IndexToValue(cx, newlength, vp))
2047
+ return JS_FALSE;
2048
+ return js_SetLengthProperty(cx, obj, newlength);
2049
+ }
2050
+
2051
+ static JSBool
2052
+ array_push(JSContext *cx, uintN argc, jsval *vp)
2053
+ {
2054
+ JSObject *obj;
2055
+ uint32 length;
2056
+
2057
+ /* Insist on one argument and obj of the expected class. */
2058
+ obj = JS_THIS_OBJECT(cx, vp);
2059
+ if (!obj)
2060
+ return JS_FALSE;
2061
+ if (argc != 1 || !OBJ_IS_DENSE_ARRAY(cx, obj))
2062
+ return array_push_slowly(cx, obj, argc, vp);
2063
+
2064
+ length = obj->fslots[JSSLOT_ARRAY_LENGTH];
2065
+ if (INDEX_TOO_SPARSE(obj, length)) {
2066
+ if (!js_MakeArraySlow(cx, obj))
2067
+ return JS_FALSE;
2068
+ return array_push_slowly(cx, obj, argc, vp);
2069
+ }
2070
+
2071
+ if (!EnsureLength(cx, obj, length + 1))
2072
+ return JS_FALSE;
2073
+ obj->fslots[JSSLOT_ARRAY_LENGTH] = length + 1;
2074
+
2075
+ JS_ASSERT(obj->dslots[length] == JSVAL_HOLE);
2076
+ obj->fslots[JSSLOT_ARRAY_COUNT]++;
2077
+ obj->dslots[length] = vp[2];
2078
+ return IndexToValue(cx, obj->fslots[JSSLOT_ARRAY_LENGTH], vp);
2079
+ }
2080
+
2081
+ JSBool
2082
+ array_pop(JSContext *cx, uintN argc, jsval *vp)
2083
+ {
2084
+ JSObject *obj;
2085
+ jsuint index;
2086
+ JSBool hole;
2087
+
2088
+ obj = JS_THIS_OBJECT(cx, vp);
2089
+ if (!obj)
2090
+ return JS_FALSE;
2091
+ if (OBJ_IS_DENSE_ARRAY(cx, obj)) {
2092
+ index = obj->fslots[JSSLOT_ARRAY_LENGTH];
2093
+ if (index == 0) {
2094
+ *vp = JSVAL_VOID;
2095
+ return JS_TRUE;
2096
+ }
2097
+ index--;
2098
+ if (!GetArrayElement(cx, obj, index, &hole, vp))
2099
+ return JS_FALSE;
2100
+ if (!hole && !DeleteArrayElement(cx, obj, index))
2101
+ return JS_FALSE;
2102
+ obj->fslots[JSSLOT_ARRAY_LENGTH] = index;
2103
+ return JS_TRUE;
2104
+ }
2105
+
2106
+ if (!js_GetLengthProperty(cx, obj, &index))
2107
+ return JS_FALSE;
2108
+ if (index == 0) {
2109
+ *vp = JSVAL_VOID;
2110
+ } else {
2111
+ index--;
2112
+
2113
+ /* Get the to-be-deleted property's value into vp. */
2114
+ if (!GetArrayElement(cx, obj, index, &hole, vp))
2115
+ return JS_FALSE;
2116
+ if (!hole && !DeleteArrayElement(cx, obj, index))
2117
+ return JS_FALSE;
2118
+ }
2119
+ return js_SetLengthProperty(cx, obj, index);
2120
+ }
2121
+
2122
+ static JSBool
2123
+ array_shift(JSContext *cx, uintN argc, jsval *vp)
2124
+ {
2125
+ JSObject *obj;
2126
+ jsuint length, i;
2127
+ JSBool hole, ok;
2128
+ JSTempValueRooter tvr;
2129
+
2130
+ obj = JS_THIS_OBJECT(cx, vp);
2131
+ if (!obj || !js_GetLengthProperty(cx, obj, &length))
2132
+ return JS_FALSE;
2133
+ if (length == 0) {
2134
+ *vp = JSVAL_VOID;
2135
+ } else {
2136
+ length--;
2137
+
2138
+ /* Get the to-be-deleted property's value into vp ASAP. */
2139
+ if (!GetArrayElement(cx, obj, 0, &hole, vp))
2140
+ return JS_FALSE;
2141
+
2142
+ /* Slide down the array above the first element. */
2143
+ ok = JS_TRUE;
2144
+ JS_PUSH_SINGLE_TEMP_ROOT(cx, JSVAL_NULL, &tvr);
2145
+ for (i = 0; i != length; i++) {
2146
+ ok = JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) &&
2147
+ GetArrayElement(cx, obj, i + 1, &hole, &tvr.u.value) &&
2148
+ SetOrDeleteArrayElement(cx, obj, i, hole, tvr.u.value);
2149
+ if (!ok)
2150
+ break;
2151
+ }
2152
+ JS_POP_TEMP_ROOT(cx, &tvr);
2153
+ if (!ok)
2154
+ return JS_FALSE;
2155
+
2156
+ /* Delete the only or last element when it exist. */
2157
+ if (!hole && !DeleteArrayElement(cx, obj, length))
2158
+ return JS_FALSE;
2159
+ }
2160
+ return js_SetLengthProperty(cx, obj, length);
2161
+ }
2162
+
2163
+ static JSBool
2164
+ array_unshift(JSContext *cx, uintN argc, jsval *vp)
2165
+ {
2166
+ JSObject *obj;
2167
+ jsval *argv;
2168
+ jsuint length, last;
2169
+ JSBool hole, ok;
2170
+ JSTempValueRooter tvr;
2171
+
2172
+ obj = JS_THIS_OBJECT(cx, vp);
2173
+ if (!obj || !js_GetLengthProperty(cx, obj, &length))
2174
+ return JS_FALSE;
2175
+ if (argc > 0) {
2176
+ /* Slide up the array to make room for argc at the bottom. */
2177
+ argv = JS_ARGV(cx, vp);
2178
+ if (length > 0) {
2179
+ last = length;
2180
+ ok = JS_TRUE;
2181
+ JS_PUSH_SINGLE_TEMP_ROOT(cx, JSVAL_NULL, &tvr);
2182
+ do {
2183
+ --last;
2184
+ ok = JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) &&
2185
+ GetArrayElement(cx, obj, last, &hole, &tvr.u.value) &&
2186
+ SetOrDeleteArrayElement(cx, obj, last + argc, hole,
2187
+ tvr.u.value);
2188
+ if (!ok)
2189
+ break;
2190
+ } while (last != 0);
2191
+ JS_POP_TEMP_ROOT(cx, &tvr);
2192
+ if (!ok)
2193
+ return JS_FALSE;
2194
+ }
2195
+
2196
+ /* Copy from argv to the bottom of the array. */
2197
+ if (!InitArrayElements(cx, obj, 0, argc, argv))
2198
+ return JS_FALSE;
2199
+
2200
+ length += argc;
2201
+ if (!js_SetLengthProperty(cx, obj, length))
2202
+ return JS_FALSE;
2203
+ }
2204
+
2205
+ /* Follow Perl by returning the new array length. */
2206
+ return IndexToValue(cx, length, vp);
2207
+ }
2208
+
2209
+ static JSBool
2210
+ array_splice(JSContext *cx, uintN argc, jsval *vp)
2211
+ {
2212
+ jsval *argv;
2213
+ JSObject *obj;
2214
+ jsuint length, begin, end, count, delta, last;
2215
+ jsdouble d;
2216
+ JSBool hole, ok;
2217
+ JSObject *obj2;
2218
+ JSTempValueRooter tvr;
2219
+
2220
+ /* Nothing to do if no args. Otherwise get length. */
2221
+ if (argc == 0)
2222
+ return JS_TRUE;
2223
+ argv = JS_ARGV(cx, vp);
2224
+ obj = JS_THIS_OBJECT(cx, vp);
2225
+ if (!obj || !js_GetLengthProperty(cx, obj, &length))
2226
+ return JS_FALSE;
2227
+
2228
+ /* Convert the first argument into a starting index. */
2229
+ d = js_ValueToNumber(cx, argv);
2230
+ if (JSVAL_IS_NULL(*argv))
2231
+ return JS_FALSE;
2232
+ d = js_DoubleToInteger(d);
2233
+ if (d < 0) {
2234
+ d += length;
2235
+ if (d < 0)
2236
+ d = 0;
2237
+ } else if (d > length) {
2238
+ d = length;
2239
+ }
2240
+ begin = (jsuint)d; /* d has been clamped to uint32 */
2241
+ argc--;
2242
+ argv++;
2243
+
2244
+ /* Convert the second argument from a count into a fencepost index. */
2245
+ delta = length - begin;
2246
+ if (argc == 0) {
2247
+ count = delta;
2248
+ end = length;
2249
+ } else {
2250
+ d = js_ValueToNumber(cx, argv);
2251
+ if (JSVAL_IS_NULL(*argv))
2252
+ return JS_FALSE;
2253
+ d = js_DoubleToInteger(d);
2254
+ if (d < 0)
2255
+ d = 0;
2256
+ else if (d > delta)
2257
+ d = delta;
2258
+ count = (jsuint)d;
2259
+ end = begin + count;
2260
+ argc--;
2261
+ argv++;
2262
+ }
2263
+
2264
+ /*
2265
+ * Create a new array value to return. Our ECMA v2 proposal specs
2266
+ * that splice always returns an array value, even when given no
2267
+ * arguments. We think this is best because it eliminates the need
2268
+ * for callers to do an extra test to handle the empty splice case.
2269
+ */
2270
+ obj2 = js_NewArrayObject(cx, 0, NULL);
2271
+ if (!obj2)
2272
+ return JS_FALSE;
2273
+ *vp = OBJECT_TO_JSVAL(obj2);
2274
+
2275
+ /* After this, control must flow through label out: to exit. */
2276
+ JS_PUSH_SINGLE_TEMP_ROOT(cx, JSVAL_NULL, &tvr);
2277
+
2278
+ /* If there are elements to remove, put them into the return value. */
2279
+ if (count > 0) {
2280
+ for (last = begin; last < end; last++) {
2281
+ ok = JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) &&
2282
+ GetArrayElement(cx, obj, last, &hole, &tvr.u.value);
2283
+ if (!ok)
2284
+ goto out;
2285
+
2286
+ /* Copy tvr.u.value to new array unless it's a hole. */
2287
+ if (!hole) {
2288
+ ok = SetArrayElement(cx, obj2, last - begin, tvr.u.value);
2289
+ if (!ok)
2290
+ goto out;
2291
+ }
2292
+ }
2293
+
2294
+ ok = js_SetLengthProperty(cx, obj2, end - begin);
2295
+ if (!ok)
2296
+ goto out;
2297
+ }
2298
+
2299
+ /* Find the direction (up or down) to copy and make way for argv. */
2300
+ if (argc > count) {
2301
+ delta = (jsuint)argc - count;
2302
+ last = length;
2303
+ /* (uint) end could be 0, so can't use vanilla >= test */
2304
+ while (last-- > end) {
2305
+ ok = JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) &&
2306
+ GetArrayElement(cx, obj, last, &hole, &tvr.u.value) &&
2307
+ SetOrDeleteArrayElement(cx, obj, last + delta, hole,
2308
+ tvr.u.value);
2309
+ if (!ok)
2310
+ goto out;
2311
+ }
2312
+ length += delta;
2313
+ } else if (argc < count) {
2314
+ delta = count - (jsuint)argc;
2315
+ for (last = end; last < length; last++) {
2316
+ ok = JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) &&
2317
+ GetArrayElement(cx, obj, last, &hole, &tvr.u.value) &&
2318
+ SetOrDeleteArrayElement(cx, obj, last - delta, hole,
2319
+ tvr.u.value);
2320
+ if (!ok)
2321
+ goto out;
2322
+ }
2323
+ length -= delta;
2324
+ }
2325
+
2326
+ /* Copy from argv into the hole to complete the splice. */
2327
+ ok = InitArrayElements(cx, obj, begin, begin + argc, argv);
2328
+ if (!ok)
2329
+ goto out;
2330
+
2331
+ /* Update length in case we deleted elements from the end. */
2332
+ ok = js_SetLengthProperty(cx, obj, length);
2333
+
2334
+ out:
2335
+ JS_POP_TEMP_ROOT(cx, &tvr);
2336
+ return ok;
2337
+ }
2338
+
2339
+ /*
2340
+ * Python-esque sequence operations.
2341
+ */
2342
+ static JSBool
2343
+ array_concat(JSContext *cx, uintN argc, jsval *vp)
2344
+ {
2345
+ jsval *argv, v;
2346
+ JSObject *nobj, *aobj;
2347
+ jsuint length, alength, slot;
2348
+ uintN i;
2349
+ JSBool hole, ok;
2350
+ JSTempValueRooter tvr;
2351
+
2352
+ /* Treat our |this| object as the first argument; see ECMA 15.4.4.4. */
2353
+ argv = JS_ARGV(cx, vp) - 1;
2354
+ JS_ASSERT(JS_THIS_OBJECT(cx, vp) == JSVAL_TO_OBJECT(argv[0]));
2355
+
2356
+ /* Create a new Array object and root it using *vp. */
2357
+ aobj = JS_THIS_OBJECT(cx, vp);
2358
+ if (OBJ_IS_DENSE_ARRAY(cx, aobj)) {
2359
+ nobj = js_NewArrayObject(cx, ARRAY_DENSE_LENGTH(aobj), aobj->dslots);
2360
+ if (!nobj)
2361
+ return JS_FALSE;
2362
+ length = aobj->fslots[JSSLOT_ARRAY_LENGTH];
2363
+ nobj->fslots[JSSLOT_ARRAY_LENGTH] = length;
2364
+ *vp = OBJECT_TO_JSVAL(nobj);
2365
+ if (argc == 0)
2366
+ return JS_TRUE;
2367
+ argc--;
2368
+ argv++;
2369
+ } else {
2370
+ nobj = js_NewArrayObject(cx, 0, NULL);
2371
+ if (!nobj)
2372
+ return JS_FALSE;
2373
+ *vp = OBJECT_TO_JSVAL(nobj);
2374
+ length = 0;
2375
+ }
2376
+
2377
+ /* After this, control must flow through label out: to exit. */
2378
+ JS_PUSH_SINGLE_TEMP_ROOT(cx, JSVAL_NULL, &tvr);
2379
+
2380
+ /* Loop over [0, argc] to concat args into nobj, expanding all Arrays. */
2381
+ for (i = 0; i <= argc; i++) {
2382
+ ok = JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP);
2383
+ if (!ok)
2384
+ goto out;
2385
+ v = argv[i];
2386
+ if (!JSVAL_IS_PRIMITIVE(v)) {
2387
+ JSObject *wobj;
2388
+
2389
+ aobj = JSVAL_TO_OBJECT(v);
2390
+ wobj = js_GetWrappedObject(cx, aobj);
2391
+ if (OBJ_IS_ARRAY(cx, wobj)) {
2392
+ ok = OBJ_GET_PROPERTY(cx, aobj,
2393
+ ATOM_TO_JSID(cx->runtime->atomState
2394
+ .lengthAtom),
2395
+ &tvr.u.value);
2396
+ if (!ok)
2397
+ goto out;
2398
+ alength = ValueIsLength(cx, &tvr.u.value);
2399
+ ok = !JSVAL_IS_NULL(tvr.u.value);
2400
+ if (!ok)
2401
+ goto out;
2402
+ for (slot = 0; slot < alength; slot++) {
2403
+ ok = JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) &&
2404
+ GetArrayElement(cx, aobj, slot, &hole,
2405
+ &tvr.u.value);
2406
+ if (!ok)
2407
+ goto out;
2408
+
2409
+ /*
2410
+ * Per ECMA 262, 15.4.4.4, step 9, ignore non-existent
2411
+ * properties.
2412
+ */
2413
+ if (!hole) {
2414
+ ok = SetArrayElement(cx, nobj, length + slot,
2415
+ tvr.u.value);
2416
+ if (!ok)
2417
+ goto out;
2418
+ }
2419
+ }
2420
+ length += alength;
2421
+ continue;
2422
+ }
2423
+ }
2424
+
2425
+ ok = SetArrayElement(cx, nobj, length, v);
2426
+ if (!ok)
2427
+ goto out;
2428
+ length++;
2429
+ }
2430
+
2431
+ ok = js_SetLengthProperty(cx, nobj, length);
2432
+
2433
+ out:
2434
+ JS_POP_TEMP_ROOT(cx, &tvr);
2435
+ return ok;
2436
+ }
2437
+
2438
+ static JSBool
2439
+ array_slice(JSContext *cx, uintN argc, jsval *vp)
2440
+ {
2441
+ jsval *argv;
2442
+ JSObject *nobj, *obj;
2443
+ jsuint length, begin, end, slot;
2444
+ jsdouble d;
2445
+ JSBool hole, ok;
2446
+ JSTempValueRooter tvr;
2447
+
2448
+ argv = JS_ARGV(cx, vp);
2449
+
2450
+ obj = JS_THIS_OBJECT(cx, vp);
2451
+ if (!obj || !js_GetLengthProperty(cx, obj, &length))
2452
+ return JS_FALSE;
2453
+ begin = 0;
2454
+ end = length;
2455
+
2456
+ if (argc > 0) {
2457
+ d = js_ValueToNumber(cx, &argv[0]);
2458
+ if (JSVAL_IS_NULL(argv[0]))
2459
+ return JS_FALSE;
2460
+ d = js_DoubleToInteger(d);
2461
+ if (d < 0) {
2462
+ d += length;
2463
+ if (d < 0)
2464
+ d = 0;
2465
+ } else if (d > length) {
2466
+ d = length;
2467
+ }
2468
+ begin = (jsuint)d;
2469
+
2470
+ if (argc > 1) {
2471
+ d = js_ValueToNumber(cx, &argv[1]);
2472
+ if (JSVAL_IS_NULL(argv[1]))
2473
+ return JS_FALSE;
2474
+ d = js_DoubleToInteger(d);
2475
+ if (d < 0) {
2476
+ d += length;
2477
+ if (d < 0)
2478
+ d = 0;
2479
+ } else if (d > length) {
2480
+ d = length;
2481
+ }
2482
+ end = (jsuint)d;
2483
+ }
2484
+ }
2485
+
2486
+ if (begin > end)
2487
+ begin = end;
2488
+
2489
+ if (OBJ_IS_DENSE_ARRAY(cx, obj) && end <= ARRAY_DENSE_LENGTH(obj)) {
2490
+ nobj = js_NewArrayObject(cx, end - begin, obj->dslots + begin);
2491
+ if (!nobj)
2492
+ return JS_FALSE;
2493
+ *vp = OBJECT_TO_JSVAL(nobj);
2494
+ return JS_TRUE;
2495
+ }
2496
+
2497
+ /* Create a new Array object and root it using *vp. */
2498
+ nobj = js_NewArrayObject(cx, 0, NULL);
2499
+ if (!nobj)
2500
+ return JS_FALSE;
2501
+ *vp = OBJECT_TO_JSVAL(nobj);
2502
+
2503
+ /* After this, control must flow through label out: to exit. */
2504
+ JS_PUSH_SINGLE_TEMP_ROOT(cx, JSVAL_NULL, &tvr);
2505
+
2506
+ for (slot = begin; slot < end; slot++) {
2507
+ ok = JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) &&
2508
+ GetArrayElement(cx, obj, slot, &hole, &tvr.u.value);
2509
+ if (!ok)
2510
+ goto out;
2511
+ if (!hole) {
2512
+ ok = SetArrayElement(cx, nobj, slot - begin, tvr.u.value);
2513
+ if (!ok)
2514
+ goto out;
2515
+ }
2516
+ }
2517
+ ok = js_SetLengthProperty(cx, nobj, end - begin);
2518
+
2519
+ out:
2520
+ JS_POP_TEMP_ROOT(cx, &tvr);
2521
+ return ok;
2522
+ }
2523
+
2524
+ #if JS_HAS_ARRAY_EXTRAS
2525
+
2526
+ static JSBool
2527
+ array_indexOfHelper(JSContext *cx, JSBool isLast, uintN argc, jsval *vp)
2528
+ {
2529
+ JSObject *obj;
2530
+ jsuint length, i, stop;
2531
+ jsint direction;
2532
+ JSBool hole;
2533
+
2534
+ obj = JS_THIS_OBJECT(cx, vp);
2535
+ if (!obj || !js_GetLengthProperty(cx, obj, &length))
2536
+ return JS_FALSE;
2537
+ if (length == 0)
2538
+ goto not_found;
2539
+
2540
+ if (argc <= 1) {
2541
+ i = isLast ? length - 1 : 0;
2542
+ } else {
2543
+ jsdouble start;
2544
+
2545
+ start = js_ValueToNumber(cx, &vp[3]);
2546
+ if (JSVAL_IS_NULL(vp[3]))
2547
+ return JS_FALSE;
2548
+ start = js_DoubleToInteger(start);
2549
+ if (start < 0) {
2550
+ start += length;
2551
+ if (start < 0) {
2552
+ if (isLast)
2553
+ goto not_found;
2554
+ i = 0;
2555
+ } else {
2556
+ i = (jsuint)start;
2557
+ }
2558
+ } else if (start >= length) {
2559
+ if (!isLast)
2560
+ goto not_found;
2561
+ i = length - 1;
2562
+ } else {
2563
+ i = (jsuint)start;
2564
+ }
2565
+ }
2566
+
2567
+ if (isLast) {
2568
+ stop = 0;
2569
+ direction = -1;
2570
+ } else {
2571
+ stop = length - 1;
2572
+ direction = 1;
2573
+ }
2574
+
2575
+ for (;;) {
2576
+ if (!JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) ||
2577
+ !GetArrayElement(cx, obj, (jsuint)i, &hole, vp)) {
2578
+ return JS_FALSE;
2579
+ }
2580
+ if (!hole && js_StrictlyEqual(cx, *vp, vp[2]))
2581
+ return js_NewNumberInRootedValue(cx, i, vp);
2582
+ if (i == stop)
2583
+ goto not_found;
2584
+ i += direction;
2585
+ }
2586
+
2587
+ not_found:
2588
+ *vp = INT_TO_JSVAL(-1);
2589
+ return JS_TRUE;
2590
+ }
2591
+
2592
+ static JSBool
2593
+ array_indexOf(JSContext *cx, uintN argc, jsval *vp)
2594
+ {
2595
+ return array_indexOfHelper(cx, JS_FALSE, argc, vp);
2596
+ }
2597
+
2598
+ static JSBool
2599
+ array_lastIndexOf(JSContext *cx, uintN argc, jsval *vp)
2600
+ {
2601
+ return array_indexOfHelper(cx, JS_TRUE, argc, vp);
2602
+ }
2603
+
2604
+ /* Order is important; extras that take a predicate funarg must follow MAP. */
2605
+ typedef enum ArrayExtraMode {
2606
+ FOREACH,
2607
+ REDUCE,
2608
+ REDUCE_RIGHT,
2609
+ MAP,
2610
+ FILTER,
2611
+ SOME,
2612
+ EVERY
2613
+ } ArrayExtraMode;
2614
+
2615
+ #define REDUCE_MODE(mode) ((mode) == REDUCE || (mode) == REDUCE_RIGHT)
2616
+
2617
+ static JSBool
2618
+ array_extra(JSContext *cx, ArrayExtraMode mode, uintN argc, jsval *vp)
2619
+ {
2620
+ JSObject *obj;
2621
+ jsuint length, newlen;
2622
+ jsval *argv, *elemroot, *invokevp, *sp;
2623
+ JSBool ok, cond, hole;
2624
+ JSObject *callable, *thisp, *newarr;
2625
+ jsint start, end, step, i;
2626
+ void *mark;
2627
+
2628
+ obj = JS_THIS_OBJECT(cx, vp);
2629
+ if (!obj || !js_GetLengthProperty(cx, obj, &length))
2630
+ return JS_FALSE;
2631
+
2632
+ /*
2633
+ * First, get or compute our callee, so that we error out consistently
2634
+ * when passed a non-callable object.
2635
+ */
2636
+ argv = vp + 2;
2637
+ callable = js_ValueToCallableObject(cx, &argv[0], JSV2F_SEARCH_STACK);
2638
+ if (!callable)
2639
+ return JS_FALSE;
2640
+
2641
+ /*
2642
+ * Set our initial return condition, used for zero-length array cases
2643
+ * (and pre-size our map return to match our known length, for all cases).
2644
+ */
2645
+ #ifdef __GNUC__ /* quell GCC overwarning */
2646
+ newlen = 0;
2647
+ newarr = NULL;
2648
+ #endif
2649
+ start = 0, end = length, step = 1;
2650
+
2651
+ switch (mode) {
2652
+ case REDUCE_RIGHT:
2653
+ start = length - 1, end = -1, step = -1;
2654
+ /* FALL THROUGH */
2655
+ case REDUCE:
2656
+ if (length == 0 && argc == 1) {
2657
+ JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
2658
+ JSMSG_EMPTY_ARRAY_REDUCE);
2659
+ return JS_FALSE;
2660
+ }
2661
+ if (argc >= 2) {
2662
+ *vp = argv[1];
2663
+ } else {
2664
+ do {
2665
+ if (!GetArrayElement(cx, obj, start, &hole, vp))
2666
+ return JS_FALSE;
2667
+ start += step;
2668
+ } while (hole && start != end);
2669
+
2670
+ if (hole && start == end) {
2671
+ JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
2672
+ JSMSG_EMPTY_ARRAY_REDUCE);
2673
+ return JS_FALSE;
2674
+ }
2675
+ }
2676
+ break;
2677
+ case MAP:
2678
+ case FILTER:
2679
+ newlen = (mode == MAP) ? length : 0;
2680
+ newarr = js_NewArrayObject(cx, newlen, NULL);
2681
+ if (!newarr)
2682
+ return JS_FALSE;
2683
+ *vp = OBJECT_TO_JSVAL(newarr);
2684
+ break;
2685
+ case SOME:
2686
+ *vp = JSVAL_FALSE;
2687
+ break;
2688
+ case EVERY:
2689
+ *vp = JSVAL_TRUE;
2690
+ break;
2691
+ case FOREACH:
2692
+ *vp = JSVAL_VOID;
2693
+ break;
2694
+ }
2695
+
2696
+ if (length == 0)
2697
+ return JS_TRUE;
2698
+
2699
+ if (argc > 1 && !REDUCE_MODE(mode)) {
2700
+ if (!js_ValueToObject(cx, argv[1], &thisp))
2701
+ return JS_FALSE;
2702
+ argv[1] = OBJECT_TO_JSVAL(thisp);
2703
+ } else {
2704
+ thisp = NULL;
2705
+ }
2706
+
2707
+ /*
2708
+ * For all but REDUCE, we call with 3 args (value, index, array). REDUCE
2709
+ * requires 4 args (accum, value, index, array).
2710
+ */
2711
+ argc = 3 + REDUCE_MODE(mode);
2712
+ elemroot = js_AllocStack(cx, 1 + 2 + argc, &mark);
2713
+ if (!elemroot)
2714
+ return JS_FALSE;
2715
+
2716
+ /* From this point the control must flow through out:. */
2717
+ ok = JS_TRUE;
2718
+ invokevp = elemroot + 1;
2719
+
2720
+ for (i = start; i != end; i += step) {
2721
+ ok = JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) &&
2722
+ GetArrayElement(cx, obj, i, &hole, elemroot);
2723
+ if (!ok)
2724
+ goto out;
2725
+ if (hole)
2726
+ continue;
2727
+
2728
+ /*
2729
+ * Push callable and 'this', then args. We must do this for every
2730
+ * iteration around the loop since js_Invoke uses spbase[0] for return
2731
+ * value storage, while some native functions use spbase[1] for local
2732
+ * rooting.
2733
+ */
2734
+ sp = invokevp;
2735
+ *sp++ = OBJECT_TO_JSVAL(callable);
2736
+ *sp++ = OBJECT_TO_JSVAL(thisp);
2737
+ if (REDUCE_MODE(mode))
2738
+ *sp++ = *vp;
2739
+ *sp++ = *elemroot;
2740
+ *sp++ = INT_TO_JSVAL(i);
2741
+ *sp++ = OBJECT_TO_JSVAL(obj);
2742
+
2743
+ /* Do the call. */
2744
+ ok = js_Invoke(cx, argc, invokevp, 0);
2745
+ if (!ok)
2746
+ break;
2747
+
2748
+ if (mode > MAP)
2749
+ cond = js_ValueToBoolean(*invokevp);
2750
+ #ifdef __GNUC__ /* quell GCC overwarning */
2751
+ else
2752
+ cond = JS_FALSE;
2753
+ #endif
2754
+
2755
+ switch (mode) {
2756
+ case FOREACH:
2757
+ break;
2758
+ case REDUCE:
2759
+ case REDUCE_RIGHT:
2760
+ *vp = *invokevp;
2761
+ break;
2762
+ case MAP:
2763
+ ok = SetArrayElement(cx, newarr, i, *invokevp);
2764
+ if (!ok)
2765
+ goto out;
2766
+ break;
2767
+ case FILTER:
2768
+ if (!cond)
2769
+ break;
2770
+ /* The filter passed *elemroot, so push it onto our result. */
2771
+ ok = SetArrayElement(cx, newarr, newlen++, *elemroot);
2772
+ if (!ok)
2773
+ goto out;
2774
+ break;
2775
+ case SOME:
2776
+ if (cond) {
2777
+ *vp = JSVAL_TRUE;
2778
+ goto out;
2779
+ }
2780
+ break;
2781
+ case EVERY:
2782
+ if (!cond) {
2783
+ *vp = JSVAL_FALSE;
2784
+ goto out;
2785
+ }
2786
+ break;
2787
+ }
2788
+ }
2789
+
2790
+ out:
2791
+ js_FreeStack(cx, mark);
2792
+ if (ok && mode == FILTER)
2793
+ ok = js_SetLengthProperty(cx, newarr, newlen);
2794
+ return ok;
2795
+ }
2796
+
2797
+ static JSBool
2798
+ array_forEach(JSContext *cx, uintN argc, jsval *vp)
2799
+ {
2800
+ return array_extra(cx, FOREACH, argc, vp);
2801
+ }
2802
+
2803
+ static JSBool
2804
+ array_map(JSContext *cx, uintN argc, jsval *vp)
2805
+ {
2806
+ return array_extra(cx, MAP, argc, vp);
2807
+ }
2808
+
2809
+ static JSBool
2810
+ array_reduce(JSContext *cx, uintN argc, jsval *vp)
2811
+ {
2812
+ return array_extra(cx, REDUCE, argc, vp);
2813
+ }
2814
+
2815
+ static JSBool
2816
+ array_reduceRight(JSContext *cx, uintN argc, jsval *vp)
2817
+ {
2818
+ return array_extra(cx, REDUCE_RIGHT, argc, vp);
2819
+ }
2820
+
2821
+ static JSBool
2822
+ array_filter(JSContext *cx, uintN argc, jsval *vp)
2823
+ {
2824
+ return array_extra(cx, FILTER, argc, vp);
2825
+ }
2826
+
2827
+ static JSBool
2828
+ array_some(JSContext *cx, uintN argc, jsval *vp)
2829
+ {
2830
+ return array_extra(cx, SOME, argc, vp);
2831
+ }
2832
+
2833
+ static JSBool
2834
+ array_every(JSContext *cx, uintN argc, jsval *vp)
2835
+ {
2836
+ return array_extra(cx, EVERY, argc, vp);
2837
+ }
2838
+ #endif
2839
+
2840
+ static JSPropertySpec array_props[] = {
2841
+ {js_length_str, -1, JSPROP_SHARED | JSPROP_PERMANENT,
2842
+ array_length_getter, array_length_setter},
2843
+ {0,0,0,0,0}
2844
+ };
2845
+
2846
+ static JSFunctionSpec array_methods[] = {
2847
+ #if JS_HAS_TOSOURCE
2848
+ JS_FN(js_toSource_str, array_toSource, 0,0,0),
2849
+ #endif
2850
+ JS_FN(js_toString_str, array_toString, 0,0,0),
2851
+ JS_FN(js_toLocaleString_str,array_toLocaleString,0,0,0),
2852
+
2853
+ /* Perl-ish methods. */
2854
+ JS_FN("join", array_join, 1,1,JSFUN_GENERIC_NATIVE),
2855
+ JS_FN("reverse", array_reverse, 0,0,JSFUN_GENERIC_NATIVE),
2856
+ JS_FN("sort", array_sort, 0,1,JSFUN_GENERIC_NATIVE),
2857
+ JS_FN("push", array_push, 1,1,JSFUN_GENERIC_NATIVE),
2858
+ JS_FN("pop", array_pop, 0,0,JSFUN_GENERIC_NATIVE),
2859
+ JS_FN("shift", array_shift, 0,0,JSFUN_GENERIC_NATIVE),
2860
+ JS_FN("unshift", array_unshift, 0,1,JSFUN_GENERIC_NATIVE),
2861
+ JS_FN("splice", array_splice, 0,2,JSFUN_GENERIC_NATIVE),
2862
+
2863
+ /* Pythonic sequence methods. */
2864
+ JS_FN("concat", array_concat, 0,1,JSFUN_GENERIC_NATIVE),
2865
+ JS_FN("slice", array_slice, 0,2,JSFUN_GENERIC_NATIVE),
2866
+
2867
+ #if JS_HAS_ARRAY_EXTRAS
2868
+ JS_FN("indexOf", array_indexOf, 1,1,JSFUN_GENERIC_NATIVE),
2869
+ JS_FN("lastIndexOf", array_lastIndexOf, 1,1,JSFUN_GENERIC_NATIVE),
2870
+ JS_FN("forEach", array_forEach, 1,1,JSFUN_GENERIC_NATIVE),
2871
+ JS_FN("map", array_map, 1,1,JSFUN_GENERIC_NATIVE),
2872
+ JS_FN("reduce", array_reduce, 1,1,JSFUN_GENERIC_NATIVE),
2873
+ JS_FN("reduceRight", array_reduceRight, 1,1,JSFUN_GENERIC_NATIVE),
2874
+ JS_FN("filter", array_filter, 1,1,JSFUN_GENERIC_NATIVE),
2875
+ JS_FN("some", array_some, 1,1,JSFUN_GENERIC_NATIVE),
2876
+ JS_FN("every", array_every, 1,1,JSFUN_GENERIC_NATIVE),
2877
+ #endif
2878
+
2879
+ JS_FS_END
2880
+ };
2881
+
2882
+ static JSBool
2883
+ Array(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2884
+ {
2885
+ jsuint length;
2886
+ jsval *vector;
2887
+
2888
+ /* If called without new, replace obj with a new Array object. */
2889
+ if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) {
2890
+ obj = js_NewObject(cx, &js_ArrayClass, NULL, NULL, 0);
2891
+ if (!obj)
2892
+ return JS_FALSE;
2893
+ *rval = OBJECT_TO_JSVAL(obj);
2894
+ }
2895
+
2896
+ if (argc == 0) {
2897
+ length = 0;
2898
+ vector = NULL;
2899
+ } else if (argc > 1) {
2900
+ length = (jsuint) argc;
2901
+ vector = argv;
2902
+ } else if (!JSVAL_IS_NUMBER(argv[0])) {
2903
+ length = 1;
2904
+ vector = argv;
2905
+ } else {
2906
+ length = ValueIsLength(cx, &argv[0]);
2907
+ if (JSVAL_IS_NULL(argv[0]))
2908
+ return JS_FALSE;
2909
+ vector = NULL;
2910
+ }
2911
+ return InitArrayObject(cx, obj, length, vector);
2912
+ }
2913
+
2914
+ JSObject *
2915
+ js_InitArrayClass(JSContext *cx, JSObject *obj)
2916
+ {
2917
+ JSObject *proto;
2918
+
2919
+ /* Initialize the ops structure used by slow arrays */
2920
+ memcpy(&js_SlowArrayObjectOps, &js_ObjectOps, sizeof(JSObjectOps));
2921
+ js_SlowArrayObjectOps.trace = slowarray_trace;
2922
+ js_SlowArrayObjectOps.enumerate = slowarray_enumerate;
2923
+ js_SlowArrayObjectOps.call = NULL;
2924
+
2925
+ proto = JS_InitClass(cx, obj, NULL, &js_ArrayClass, Array, 1,
2926
+ array_props, array_methods, NULL, NULL);
2927
+
2928
+ /* Initialize the Array prototype object so it gets a length property. */
2929
+ if (!proto || !InitArrayObject(cx, proto, 0, NULL))
2930
+ return NULL;
2931
+ return proto;
2932
+ }
2933
+
2934
+ JSObject *
2935
+ js_NewArrayObject(JSContext *cx, jsuint length, jsval *vector)
2936
+ {
2937
+ JSTempValueRooter tvr;
2938
+ JSObject *obj;
2939
+
2940
+ obj = js_NewObject(cx, &js_ArrayClass, NULL, NULL, 0);
2941
+ if (!obj)
2942
+ return NULL;
2943
+
2944
+ JS_PUSH_TEMP_ROOT_OBJECT(cx, obj, &tvr);
2945
+ if (!InitArrayObject(cx, obj, length, vector))
2946
+ obj = NULL;
2947
+ JS_POP_TEMP_ROOT(cx, &tvr);
2948
+
2949
+ /* Set/clear newborn root, in case we lost it. */
2950
+ cx->weakRoots.newborn[GCX_OBJECT] = obj;
2951
+ return obj;
2952
+ }
2953
+
2954
+ JSObject *
2955
+ js_NewSlowArrayObject(JSContext *cx)
2956
+ {
2957
+ JSObject *obj = js_NewObject(cx, &js_SlowArrayClass, NULL, NULL, 0);
2958
+ if (obj)
2959
+ obj->fslots[JSSLOT_ARRAY_LENGTH] = 0;
2960
+ return obj;
2961
+ }
2962
+
2963
+ #ifdef DEBUG_ARRAYS
2964
+ JSBool
2965
+ js_ArrayInfo(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2966
+ {
2967
+ uintN i;
2968
+ JSObject *array;
2969
+
2970
+ for (i = 0; i < argc; i++) {
2971
+ char *bytes;
2972
+
2973
+ bytes = js_DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, argv[i],
2974
+ NULL);
2975
+ if (!bytes)
2976
+ return JS_FALSE;
2977
+ if (JSVAL_IS_PRIMITIVE(argv[i]) ||
2978
+ !OBJ_IS_ARRAY(cx, (array = JSVAL_TO_OBJECT(argv[i])))) {
2979
+ fprintf(stderr, "%s: not array\n", bytes);
2980
+ JS_free(cx, bytes);
2981
+ continue;
2982
+ }
2983
+ fprintf(stderr, "%s: %s (len %lu", bytes,
2984
+ OBJ_IS_DENSE_ARRAY(cx, array) ? "dense" : "sparse",
2985
+ array->fslots[JSSLOT_ARRAY_LENGTH]);
2986
+ if (OBJ_IS_DENSE_ARRAY(cx, array)) {
2987
+ fprintf(stderr, ", count %lu, denselen %lu",
2988
+ array->fslots[JSSLOT_ARRAY_COUNT],
2989
+ ARRAY_DENSE_LENGTH(array));
2990
+ }
2991
+ fputs(")\n", stderr);
2992
+ JS_free(cx, bytes);
2993
+ }
2994
+ return JS_TRUE;
2995
+ }
2996
+ #endif