johnson 1.2.0 → 2.0.0.pre0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (782) hide show
  1. data/CHANGELOG.rdoc +8 -0
  2. data/Manifest.txt +762 -48
  3. data/README.rdoc +2 -1
  4. data/Rakefile +90 -18
  5. data/ext/spidermonkey/conversions.c +9 -2
  6. data/ext/spidermonkey/ruby_land_proxy.c +1 -1
  7. data/ext/spidermonkey/runtime.h +1 -1
  8. data/ext/tracemonkey/context.cc +125 -0
  9. data/ext/tracemonkey/context.h +19 -0
  10. data/ext/tracemonkey/conversions.cc +365 -0
  11. data/ext/tracemonkey/conversions.h +32 -0
  12. data/ext/tracemonkey/debugger.cc +234 -0
  13. data/ext/tracemonkey/debugger.h +10 -0
  14. data/ext/tracemonkey/extconf.rb +37 -0
  15. data/ext/tracemonkey/extensions.cc +37 -0
  16. data/ext/tracemonkey/extensions.h +12 -0
  17. data/ext/tracemonkey/global.cc +40 -0
  18. data/ext/tracemonkey/global.h +11 -0
  19. data/ext/tracemonkey/idhash.cc +16 -0
  20. data/ext/tracemonkey/idhash.h +8 -0
  21. data/ext/tracemonkey/immutable_node.cc +1199 -0
  22. data/ext/tracemonkey/immutable_node.cc.erb +559 -0
  23. data/ext/tracemonkey/immutable_node.h +22 -0
  24. data/ext/tracemonkey/jroot.h +215 -0
  25. data/ext/tracemonkey/js_land_proxy.cc +620 -0
  26. data/ext/tracemonkey/js_land_proxy.h +20 -0
  27. data/ext/tracemonkey/ruby_land_proxy.cc +618 -0
  28. data/ext/tracemonkey/ruby_land_proxy.h +38 -0
  29. data/ext/tracemonkey/runtime.cc +454 -0
  30. data/ext/tracemonkey/runtime.h +27 -0
  31. data/ext/tracemonkey/split_global.cc +392 -0
  32. data/ext/tracemonkey/split_global.h +11 -0
  33. data/ext/tracemonkey/tracemonkey.cc +23 -0
  34. data/ext/tracemonkey/tracemonkey.h +32 -0
  35. data/lib/johnson.rb +12 -4
  36. data/lib/johnson/error.rb +5 -0
  37. data/lib/johnson/js/prelude.js +16 -1
  38. data/lib/johnson/parser.rb +2 -1
  39. data/lib/johnson/runtime.rb +87 -26
  40. data/lib/johnson/spidermonkey/runtime.rb +7 -16
  41. data/lib/johnson/tracemonkey.rb +13 -0
  42. data/lib/johnson/tracemonkey/context.rb +10 -0
  43. data/lib/johnson/tracemonkey/debugger.rb +67 -0
  44. data/lib/johnson/tracemonkey/immutable_node.rb +282 -0
  45. data/lib/johnson/tracemonkey/js_land_proxy.rb +64 -0
  46. data/lib/johnson/tracemonkey/mutable_tree_visitor.rb +242 -0
  47. data/lib/johnson/tracemonkey/ruby_land_proxy.rb +17 -0
  48. data/lib/johnson/tracemonkey/runtime.rb +80 -0
  49. data/test/{johnson_test.rb → generic/johnson_test.rb} +1 -1
  50. data/test/{parser_test.rb → generic/parser_test.rb} +1 -1
  51. data/test/helper.rb +23 -4
  52. data/test/johnson/{browser_test.rb → generic/browser_test.rb} +1 -1
  53. data/test/johnson/{conversions → generic/conversions}/array_test.rb +1 -1
  54. data/test/johnson/{conversions → generic/conversions}/boolean_test.rb +1 -1
  55. data/test/johnson/{conversions → generic/conversions}/callable_test.rb +1 -1
  56. data/test/johnson/{conversions → generic/conversions}/file_test.rb +1 -1
  57. data/test/johnson/generic/conversions/helper.rb +1 -0
  58. data/test/johnson/{conversions → generic/conversions}/nil_test.rb +1 -1
  59. data/test/johnson/{conversions → generic/conversions}/number_test.rb +1 -1
  60. data/test/johnson/{conversions → generic/conversions}/regexp_test.rb +1 -1
  61. data/test/johnson/{conversions → generic/conversions}/string_test.rb +1 -1
  62. data/test/johnson/{conversions → generic/conversions}/struct_test.rb +1 -1
  63. data/test/johnson/{conversions → generic/conversions}/symbol_test.rb +1 -1
  64. data/test/johnson/{conversions → generic/conversions}/thread_test.rb +1 -1
  65. data/test/johnson/{custom_conversions_test.rb → generic/custom_conversions_test.rb} +1 -1
  66. data/test/johnson/generic/default_test.rb +12 -0
  67. data/test/johnson/{error_test.rb → generic/error_test.rb} +1 -1
  68. data/test/johnson/{extensions_test.rb → generic/extensions_test.rb} +1 -1
  69. data/test/johnson/generic/helper.rb +1 -0
  70. data/test/johnson/{nodes → generic/nodes}/array_literal_test.rb +1 -1
  71. data/test/johnson/{nodes → generic/nodes}/array_node_test.rb +1 -1
  72. data/test/johnson/{nodes → generic/nodes}/binary_node_test.rb +1 -1
  73. data/test/johnson/{nodes → generic/nodes}/bracket_access_test.rb +1 -1
  74. data/test/johnson/{nodes → generic/nodes}/delete_test.rb +1 -1
  75. data/test/johnson/{nodes → generic/nodes}/do_while_test.rb +1 -1
  76. data/test/johnson/{nodes → generic/nodes}/dot_accessor_test.rb +1 -1
  77. data/test/johnson/generic/nodes/export_test.rb +11 -0
  78. data/test/johnson/{nodes → generic/nodes}/for_test.rb +1 -1
  79. data/test/johnson/{nodes → generic/nodes}/function_test.rb +1 -1
  80. data/test/johnson/generic/nodes/helper.rb +1 -0
  81. data/test/johnson/{nodes → generic/nodes}/if_test.rb +16 -6
  82. data/test/johnson/generic/nodes/import_test.rb +15 -0
  83. data/test/johnson/{nodes → generic/nodes}/label_test.rb +1 -1
  84. data/test/johnson/{nodes → generic/nodes}/let_test.rb +1 -1
  85. data/test/johnson/{nodes → generic/nodes}/object_literal_test.rb +1 -1
  86. data/test/johnson/{nodes → generic/nodes}/return_test.rb +1 -1
  87. data/test/johnson/{nodes → generic/nodes}/semi_test.rb +1 -1
  88. data/test/johnson/{nodes → generic/nodes}/switch_test.rb +1 -1
  89. data/test/johnson/{nodes → generic/nodes}/ternary_test.rb +1 -1
  90. data/test/johnson/{nodes → generic/nodes}/throw_test.rb +1 -1
  91. data/test/johnson/{nodes → generic/nodes}/try_node_test.rb +36 -6
  92. data/test/johnson/{nodes → generic/nodes}/typeof_test.rb +1 -1
  93. data/test/johnson/{nodes → generic/nodes}/unary_node_test.rb +1 -1
  94. data/test/johnson/{nodes → generic/nodes}/void_test.rb +1 -1
  95. data/test/johnson/{nodes → generic/nodes}/while_test.rb +1 -1
  96. data/test/johnson/{nodes → generic/nodes}/with_test.rb +1 -1
  97. data/test/johnson/{prelude_test.rb → generic/prelude_test.rb} +1 -1
  98. data/test/johnson/{runtime_test.rb → generic/runtime_test.rb} +3 -6
  99. data/test/johnson/generic/version_test.rb +13 -0
  100. data/test/johnson/{visitors → generic/visitors}/dot_visitor_test.rb +1 -1
  101. data/test/johnson/{visitors → generic/visitors}/enumerating_visitor_test.rb +1 -1
  102. data/test/johnson/generic/visitors/helper.rb +1 -0
  103. data/test/johnson/spidermonkey/js_land_proxy_test.rb +1 -5
  104. data/test/johnson/spidermonkey/ruby_land_proxy_test.rb +11 -7
  105. data/test/johnson/tracemonkey/context_test.rb +21 -0
  106. data/test/johnson/tracemonkey/immutable_node_test.rb +34 -0
  107. data/test/johnson/tracemonkey/js_land_proxy_test.rb +273 -0
  108. data/test/johnson/tracemonkey/ruby_land_proxy_test.rb +274 -0
  109. data/test/johnson/tracemonkey/runtime_test.rb +41 -0
  110. data/test/johnson/tracemonkey/split_global_test.rb +32 -0
  111. data/vendor/spidermonkey/js.pkg +2 -0
  112. data/vendor/tracemonkey/Makefile.in +668 -0
  113. data/vendor/tracemonkey/Makefile.ref +483 -0
  114. data/vendor/tracemonkey/README.html +54 -0
  115. data/vendor/tracemonkey/SpiderMonkey.rsp +11 -0
  116. data/vendor/tracemonkey/Y.js +19 -0
  117. data/vendor/tracemonkey/aclocal.m4 +9 -0
  118. data/vendor/tracemonkey/bench.sh +5 -0
  119. data/vendor/tracemonkey/build/autoconf/acoutput-fast.pl +202 -0
  120. data/vendor/tracemonkey/build/autoconf/altoptions.m4 +154 -0
  121. data/vendor/tracemonkey/build/autoconf/config.guess +1537 -0
  122. data/vendor/tracemonkey/build/autoconf/config.sub +1595 -0
  123. data/vendor/tracemonkey/build/autoconf/install-sh +119 -0
  124. data/vendor/tracemonkey/build/autoconf/make-makefile +315 -0
  125. data/vendor/tracemonkey/build/autoconf/match-dir.sh +101 -0
  126. data/vendor/tracemonkey/build/autoconf/moznbytetype.m4 +136 -0
  127. data/vendor/tracemonkey/build/autoconf/nspr.m4 +82 -0
  128. data/vendor/tracemonkey/build/autoconf/pkg.m4 +59 -0
  129. data/vendor/tracemonkey/build/autoconf/update-makefile.sh +118 -0
  130. data/vendor/tracemonkey/build/cygwin-wrapper +75 -0
  131. data/vendor/tracemonkey/build/hcc +111 -0
  132. data/vendor/tracemonkey/build/hcpp +155 -0
  133. data/vendor/tracemonkey/build/unix/mddepend.pl +165 -0
  134. data/vendor/tracemonkey/build/unix/uniq.pl +63 -0
  135. data/vendor/tracemonkey/build/win32/pgomerge.py +40 -0
  136. data/vendor/tracemonkey/builtins.tbl +91 -0
  137. data/vendor/tracemonkey/call.js +13 -0
  138. data/vendor/tracemonkey/config.mk +206 -0
  139. data/vendor/tracemonkey/config/Makefile.in +106 -0
  140. data/vendor/tracemonkey/config/Moz/Milestone.pm +232 -0
  141. data/vendor/tracemonkey/config/autoconf.mk.in +362 -0
  142. data/vendor/tracemonkey/config/check-sync-dirs.py +103 -0
  143. data/vendor/tracemonkey/config/check-sync-exceptions +7 -0
  144. data/vendor/tracemonkey/config/config.mk +881 -0
  145. data/vendor/tracemonkey/config/fastcwd.pl +66 -0
  146. data/vendor/tracemonkey/config/gcc_hidden.h +2 -0
  147. data/vendor/tracemonkey/config/insure.mk +53 -0
  148. data/vendor/tracemonkey/config/make-system-wrappers.pl +59 -0
  149. data/vendor/tracemonkey/config/milestone.pl +112 -0
  150. data/vendor/tracemonkey/config/milestone.txt +13 -0
  151. data/vendor/tracemonkey/config/mkdepend/Makefile.in +84 -0
  152. data/vendor/tracemonkey/config/mkdepend/cppsetup.c +233 -0
  153. data/vendor/tracemonkey/config/mkdepend/def.h +184 -0
  154. data/vendor/tracemonkey/config/mkdepend/ifparser.c +551 -0
  155. data/vendor/tracemonkey/config/mkdepend/ifparser.h +83 -0
  156. data/vendor/tracemonkey/config/mkdepend/imakemdep.h +733 -0
  157. data/vendor/tracemonkey/config/mkdepend/include.c +337 -0
  158. data/vendor/tracemonkey/config/mkdepend/main.c +860 -0
  159. data/vendor/tracemonkey/config/mkdepend/mkdepend.man +382 -0
  160. data/vendor/tracemonkey/config/mkdepend/parse.c +686 -0
  161. data/vendor/tracemonkey/config/mkdepend/pr.c +124 -0
  162. data/vendor/tracemonkey/config/nfspwd.pl +50 -0
  163. data/vendor/tracemonkey/config/nsinstall.c +481 -0
  164. data/vendor/tracemonkey/config/nsinstall.py +155 -0
  165. data/vendor/tracemonkey/config/pathsub.c +247 -0
  166. data/vendor/tracemonkey/config/pathsub.h +74 -0
  167. data/vendor/tracemonkey/config/preprocessor.pl +671 -0
  168. data/vendor/tracemonkey/config/revdepth-nt.pl +48 -0
  169. data/vendor/tracemonkey/config/revdepth.pl +51 -0
  170. data/vendor/tracemonkey/config/rules.mk +2310 -0
  171. data/vendor/tracemonkey/config/static-checking-config.mk +21 -0
  172. data/vendor/tracemonkey/config/static-checking.js +92 -0
  173. data/vendor/tracemonkey/config/string-format.js +61 -0
  174. data/vendor/tracemonkey/config/system-headers +1035 -0
  175. data/vendor/tracemonkey/config/version.mk +85 -0
  176. data/vendor/tracemonkey/config/version_win.pl +442 -0
  177. data/vendor/tracemonkey/configure +14183 -0
  178. data/vendor/tracemonkey/configure.in +5363 -0
  179. data/vendor/tracemonkey/correct.sh +23 -0
  180. data/vendor/tracemonkey/correct/check-3d-morph.js +55 -0
  181. data/vendor/tracemonkey/correct/check-3d-raytrace.js +445 -0
  182. data/vendor/tracemonkey/correct/check-access-binary-trees.js +52 -0
  183. data/vendor/tracemonkey/correct/check-access-fannkuch.js +66 -0
  184. data/vendor/tracemonkey/correct/check-access-nbody.js +171 -0
  185. data/vendor/tracemonkey/correct/check-access-nsieve.js +40 -0
  186. data/vendor/tracemonkey/correct/check-bitops-3bit-bits-in-byte.js +35 -0
  187. data/vendor/tracemonkey/correct/check-bitops-bits-in-byte.js +24 -0
  188. data/vendor/tracemonkey/correct/check-bitops-bitwise-and.js +29 -0
  189. data/vendor/tracemonkey/correct/check-bitops-nsieve-bits.js +40 -0
  190. data/vendor/tracemonkey/correct/check-controlflow-recursive.js +27 -0
  191. data/vendor/tracemonkey/correct/check-date-format-tofte.js +302 -0
  192. data/vendor/tracemonkey/correct/check-date-format-xparb.js +421 -0
  193. data/vendor/tracemonkey/correct/check-mont.js +119 -0
  194. data/vendor/tracemonkey/dtoa.c +3335 -0
  195. data/vendor/tracemonkey/editline/Makefile.in +55 -0
  196. data/vendor/tracemonkey/editline/Makefile.ref +143 -0
  197. data/vendor/tracemonkey/editline/README +83 -0
  198. data/vendor/tracemonkey/editline/editline.3 +175 -0
  199. data/vendor/tracemonkey/editline/editline.c +1371 -0
  200. data/vendor/tracemonkey/editline/editline.h +135 -0
  201. data/vendor/tracemonkey/editline/sysunix.c +182 -0
  202. data/vendor/tracemonkey/editline/unix.h +82 -0
  203. data/vendor/tracemonkey/if.js +13 -0
  204. data/vendor/tracemonkey/imacro_asm.js.in +396 -0
  205. data/vendor/tracemonkey/imacros.c.out +1034 -0
  206. data/vendor/tracemonkey/imacros.jsasm +770 -0
  207. data/vendor/tracemonkey/javascript-trace.d +73 -0
  208. data/vendor/tracemonkey/jitstats.tbl +55 -0
  209. data/vendor/tracemonkey/js-config.h.in +82 -0
  210. data/vendor/tracemonkey/js-config.in +111 -0
  211. data/vendor/tracemonkey/js.mdp +0 -0
  212. data/vendor/tracemonkey/js.msg +312 -0
  213. data/vendor/tracemonkey/js3240.rc +79 -0
  214. data/vendor/tracemonkey/jsOS240.def +654 -0
  215. data/vendor/tracemonkey/jsapi.cpp +6005 -0
  216. data/vendor/tracemonkey/jsapi.h +2727 -0
  217. data/vendor/tracemonkey/jsarena.cpp +450 -0
  218. data/vendor/tracemonkey/jsarena.h +318 -0
  219. data/vendor/tracemonkey/jsarray.cpp +3664 -0
  220. data/vendor/tracemonkey/jsarray.h +238 -0
  221. data/vendor/tracemonkey/jsatom.cpp +1244 -0
  222. data/vendor/tracemonkey/jsatom.h +493 -0
  223. data/vendor/tracemonkey/jsbit.h +249 -0
  224. data/vendor/tracemonkey/jsbool.cpp +184 -0
  225. data/vendor/tracemonkey/jsbool.h +88 -0
  226. data/vendor/tracemonkey/jsbuiltins.cpp +415 -0
  227. data/vendor/tracemonkey/jsbuiltins.h +456 -0
  228. data/vendor/tracemonkey/jsclist.h +139 -0
  229. data/vendor/tracemonkey/jscntxt.cpp +1816 -0
  230. data/vendor/tracemonkey/jscntxt.h +1541 -0
  231. data/vendor/tracemonkey/jscompat.h +57 -0
  232. data/vendor/tracemonkey/jsconfig.mk +181 -0
  233. data/vendor/tracemonkey/jscpucfg.cpp +194 -0
  234. data/vendor/tracemonkey/jscpucfg.h +91 -0
  235. data/vendor/tracemonkey/jsdate.cpp +2465 -0
  236. data/vendor/tracemonkey/jsdate.h +129 -0
  237. data/vendor/tracemonkey/jsdbgapi.cpp +2017 -0
  238. data/vendor/tracemonkey/jsdbgapi.h +500 -0
  239. data/vendor/tracemonkey/jsdhash.cpp +876 -0
  240. data/vendor/tracemonkey/jsdhash.h +588 -0
  241. data/vendor/tracemonkey/jsdtoa.cpp +572 -0
  242. data/vendor/tracemonkey/jsdtoa.h +131 -0
  243. data/vendor/tracemonkey/jsdtracef.c +318 -0
  244. data/vendor/tracemonkey/jsdtracef.h +81 -0
  245. data/vendor/tracemonkey/jsemit.cpp +7292 -0
  246. data/vendor/tracemonkey/jsemit.h +802 -0
  247. data/vendor/tracemonkey/jsexn.cpp +1337 -0
  248. data/vendor/tracemonkey/jsexn.h +96 -0
  249. data/vendor/tracemonkey/jsfile.cpp +2747 -0
  250. data/vendor/tracemonkey/jsfile.h +56 -0
  251. data/vendor/tracemonkey/jsfile.msg +90 -0
  252. data/vendor/tracemonkey/jsfun.cpp +3089 -0
  253. data/vendor/tracemonkey/jsfun.h +366 -0
  254. data/vendor/tracemonkey/jsgc.cpp +3816 -0
  255. data/vendor/tracemonkey/jsgc.h +429 -0
  256. data/vendor/tracemonkey/jshash.cpp +477 -0
  257. data/vendor/tracemonkey/jshash.h +151 -0
  258. data/vendor/tracemonkey/jsify.pl +483 -0
  259. data/vendor/tracemonkey/jsinterp.cpp +7441 -0
  260. data/vendor/tracemonkey/jsinterp.h +666 -0
  261. data/vendor/tracemonkey/jsinvoke.cpp +42 -0
  262. data/vendor/tracemonkey/jsiter.cpp +1040 -0
  263. data/vendor/tracemonkey/jsiter.h +140 -0
  264. data/vendor/tracemonkey/jskeyword.tbl +124 -0
  265. data/vendor/tracemonkey/jskwgen.cpp +460 -0
  266. data/vendor/tracemonkey/jslibmath.h +69 -0
  267. data/vendor/tracemonkey/jslock.cpp +1512 -0
  268. data/vendor/tracemonkey/jslock.h +325 -0
  269. data/vendor/tracemonkey/jslocko.asm +60 -0
  270. data/vendor/tracemonkey/jslog2.cpp +111 -0
  271. data/vendor/tracemonkey/jslong.h +167 -0
  272. data/vendor/tracemonkey/jsmath.cpp +806 -0
  273. data/vendor/tracemonkey/jsmath.h +63 -0
  274. data/vendor/tracemonkey/jsnum.cpp +1374 -0
  275. data/vendor/tracemonkey/jsnum.h +280 -0
  276. data/vendor/tracemonkey/jsobj.cpp +6165 -0
  277. data/vendor/tracemonkey/jsobj.h +870 -0
  278. data/vendor/tracemonkey/json.cpp +1338 -0
  279. data/vendor/tracemonkey/json.h +108 -0
  280. data/vendor/tracemonkey/jsopcode.cpp +5484 -0
  281. data/vendor/tracemonkey/jsopcode.h +434 -0
  282. data/vendor/tracemonkey/jsopcode.tbl +591 -0
  283. data/vendor/tracemonkey/jsoplengen.cpp +121 -0
  284. data/vendor/tracemonkey/jsotypes.h +202 -0
  285. data/vendor/tracemonkey/jsparse.cpp +9257 -0
  286. data/vendor/tracemonkey/jsparse.h +900 -0
  287. data/vendor/tracemonkey/jsprf.cpp +1262 -0
  288. data/vendor/tracemonkey/jsprf.h +150 -0
  289. data/vendor/tracemonkey/jsproto.tbl +117 -0
  290. data/vendor/tracemonkey/jsprvtd.h +366 -0
  291. data/vendor/tracemonkey/jspubtd.h +585 -0
  292. data/vendor/tracemonkey/jsregexp.cpp +5051 -0
  293. data/vendor/tracemonkey/jsregexp.h +199 -0
  294. data/vendor/tracemonkey/jsreops.tbl +145 -0
  295. data/vendor/tracemonkey/jsscan.cpp +2040 -0
  296. data/vendor/tracemonkey/jsscan.h +467 -0
  297. data/vendor/tracemonkey/jsscope.cpp +1966 -0
  298. data/vendor/tracemonkey/jsscope.h +487 -0
  299. data/vendor/tracemonkey/jsscript.cpp +1932 -0
  300. data/vendor/tracemonkey/jsscript.h +345 -0
  301. data/vendor/tracemonkey/jsshell.msg +54 -0
  302. data/vendor/tracemonkey/jsstack.js +167 -0
  303. data/vendor/tracemonkey/jsstaticcheck.h +69 -0
  304. data/vendor/tracemonkey/jsstddef.h +87 -0
  305. data/vendor/tracemonkey/jsstdint.h +96 -0
  306. data/vendor/tracemonkey/jsstr.cpp +5277 -0
  307. data/vendor/tracemonkey/jsstr.h +702 -0
  308. data/vendor/tracemonkey/jstracer.cpp +10991 -0
  309. data/vendor/tracemonkey/jstracer.h +794 -0
  310. data/vendor/tracemonkey/jstypes.h +481 -0
  311. data/vendor/tracemonkey/jsutil.cpp +361 -0
  312. data/vendor/tracemonkey/jsutil.h +178 -0
  313. data/vendor/tracemonkey/jsversion.h +243 -0
  314. data/vendor/tracemonkey/jswince.asm +44 -0
  315. data/vendor/tracemonkey/jsxdrapi.cpp +800 -0
  316. data/vendor/tracemonkey/jsxdrapi.h +220 -0
  317. data/vendor/tracemonkey/jsxml.cpp +8327 -0
  318. data/vendor/tracemonkey/jsxml.h +305 -0
  319. data/vendor/tracemonkey/liveconnect/LiveConnect.dsp +157 -0
  320. data/vendor/tracemonkey/liveconnect/LiveConnectShell.dsp +120 -0
  321. data/vendor/tracemonkey/liveconnect/LiveConnectShell.dsw +44 -0
  322. data/vendor/tracemonkey/liveconnect/Makefile.in +105 -0
  323. data/vendor/tracemonkey/liveconnect/Makefile.ref +169 -0
  324. data/vendor/tracemonkey/liveconnect/README.html +712 -0
  325. data/vendor/tracemonkey/liveconnect/_jni/netscape_javascript_JSException.h +14 -0
  326. data/vendor/tracemonkey/liveconnect/_jni/netscape_javascript_JSObject.h +155 -0
  327. data/vendor/tracemonkey/liveconnect/classes/Makefile.in +89 -0
  328. data/vendor/tracemonkey/liveconnect/classes/Makefile.ref +57 -0
  329. data/vendor/tracemonkey/liveconnect/classes/netscape/Makefile.ref +47 -0
  330. data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/JSException.java +140 -0
  331. data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/JSObject.java +183 -0
  332. data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/JSProxy.java +58 -0
  333. data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/JSRunnable.java +70 -0
  334. data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/JSUtil.java +59 -0
  335. data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/Makefile.ref +53 -0
  336. data/vendor/tracemonkey/liveconnect/config/AIX4.1.mk +45 -0
  337. data/vendor/tracemonkey/liveconnect/config/AIX4.2.mk +45 -0
  338. data/vendor/tracemonkey/liveconnect/config/AIX4.3.mk +50 -0
  339. data/vendor/tracemonkey/liveconnect/config/HP-UXB.10.10.mk +43 -0
  340. data/vendor/tracemonkey/liveconnect/config/HP-UXB.10.20.mk +43 -0
  341. data/vendor/tracemonkey/liveconnect/config/HP-UXB.11.00.mk +43 -0
  342. data/vendor/tracemonkey/liveconnect/config/IRIX6.2.mk +43 -0
  343. data/vendor/tracemonkey/liveconnect/config/IRIX6.3.mk +43 -0
  344. data/vendor/tracemonkey/liveconnect/config/IRIX6.5.mk +43 -0
  345. data/vendor/tracemonkey/liveconnect/config/Linux_All.mk +73 -0
  346. data/vendor/tracemonkey/liveconnect/config/OSF1V4.0.mk +65 -0
  347. data/vendor/tracemonkey/liveconnect/config/OSF1V5.0.mk +62 -0
  348. data/vendor/tracemonkey/liveconnect/config/SunOS5.5.1.mk +55 -0
  349. data/vendor/tracemonkey/liveconnect/config/SunOS5.6.mk +39 -0
  350. data/vendor/tracemonkey/liveconnect/config/SunOS5.7.mk +39 -0
  351. data/vendor/tracemonkey/liveconnect/config/SunOS5.8.mk +39 -0
  352. data/vendor/tracemonkey/liveconnect/config/WINNT4.0.mk +53 -0
  353. data/vendor/tracemonkey/liveconnect/jsj.c +886 -0
  354. data/vendor/tracemonkey/liveconnect/jsj.msg +98 -0
  355. data/vendor/tracemonkey/liveconnect/jsj_JSObject.c +1377 -0
  356. data/vendor/tracemonkey/liveconnect/jsj_JavaArray.c +474 -0
  357. data/vendor/tracemonkey/liveconnect/jsj_JavaClass.c +737 -0
  358. data/vendor/tracemonkey/liveconnect/jsj_JavaMember.c +191 -0
  359. data/vendor/tracemonkey/liveconnect/jsj_JavaObject.c +1079 -0
  360. data/vendor/tracemonkey/liveconnect/jsj_JavaPackage.c +569 -0
  361. data/vendor/tracemonkey/liveconnect/jsj_array.c +207 -0
  362. data/vendor/tracemonkey/liveconnect/jsj_class.c +770 -0
  363. data/vendor/tracemonkey/liveconnect/jsj_convert.c +902 -0
  364. data/vendor/tracemonkey/liveconnect/jsj_field.c +421 -0
  365. data/vendor/tracemonkey/liveconnect/jsj_hash.c +488 -0
  366. data/vendor/tracemonkey/liveconnect/jsj_hash.h +161 -0
  367. data/vendor/tracemonkey/liveconnect/jsj_method.c +1825 -0
  368. data/vendor/tracemonkey/liveconnect/jsj_nodl.c +1 -0
  369. data/vendor/tracemonkey/liveconnect/jsj_private.h +677 -0
  370. data/vendor/tracemonkey/liveconnect/jsj_simpleapi.c +219 -0
  371. data/vendor/tracemonkey/liveconnect/jsj_utils.c +513 -0
  372. data/vendor/tracemonkey/liveconnect/jsjava.h +316 -0
  373. data/vendor/tracemonkey/liveconnect/netscape_javascript_JSObject.h +155 -0
  374. data/vendor/tracemonkey/liveconnect/nsCLiveconnect.cpp +785 -0
  375. data/vendor/tracemonkey/liveconnect/nsCLiveconnect.h +197 -0
  376. data/vendor/tracemonkey/liveconnect/nsCLiveconnectFactory.cpp +118 -0
  377. data/vendor/tracemonkey/liveconnect/nsCLiveconnectFactory.h +76 -0
  378. data/vendor/tracemonkey/liveconnect/nsILiveconnect.h +197 -0
  379. data/vendor/tracemonkey/liveconnect/nsISecureLiveconnect.h +94 -0
  380. data/vendor/tracemonkey/liveconnect/nsISecurityContext.h +136 -0
  381. data/vendor/tracemonkey/lock_SunOS.s +119 -0
  382. data/vendor/tracemonkey/mandelbrot-results.js +3 -0
  383. data/vendor/tracemonkey/math-partial-sums.js +32 -0
  384. data/vendor/tracemonkey/math-trace-tests.js +507 -0
  385. data/vendor/tracemonkey/md5.js +289 -0
  386. data/vendor/tracemonkey/nanojit/Assembler.cpp +1984 -0
  387. data/vendor/tracemonkey/nanojit/Assembler.h +375 -0
  388. data/vendor/tracemonkey/nanojit/Fragmento.cpp +651 -0
  389. data/vendor/tracemonkey/nanojit/Fragmento.h +237 -0
  390. data/vendor/tracemonkey/nanojit/LIR.cpp +2314 -0
  391. data/vendor/tracemonkey/nanojit/LIR.h +879 -0
  392. data/vendor/tracemonkey/nanojit/LIRopcode.tbl +252 -0
  393. data/vendor/tracemonkey/nanojit/Native.h +127 -0
  394. data/vendor/tracemonkey/nanojit/NativeARM.cpp +1742 -0
  395. data/vendor/tracemonkey/nanojit/NativeARM.h +844 -0
  396. data/vendor/tracemonkey/nanojit/NativeSparc.cpp +1130 -0
  397. data/vendor/tracemonkey/nanojit/NativeSparc.h +948 -0
  398. data/vendor/tracemonkey/nanojit/NativeThumb.cpp +1322 -0
  399. data/vendor/tracemonkey/nanojit/NativeThumb.h +525 -0
  400. data/vendor/tracemonkey/nanojit/Nativei386.cpp +1748 -0
  401. data/vendor/tracemonkey/nanojit/Nativei386.h +857 -0
  402. data/vendor/tracemonkey/nanojit/RegAlloc.cpp +183 -0
  403. data/vendor/tracemonkey/nanojit/RegAlloc.h +95 -0
  404. data/vendor/tracemonkey/nanojit/TraceTreeDrawer.cpp +306 -0
  405. data/vendor/tracemonkey/nanojit/TraceTreeDrawer.h +88 -0
  406. data/vendor/tracemonkey/nanojit/avmplus.cpp +56 -0
  407. data/vendor/tracemonkey/nanojit/avmplus.h +1016 -0
  408. data/vendor/tracemonkey/nanojit/nanojit.h +253 -0
  409. data/vendor/tracemonkey/perfect.js +39 -0
  410. data/vendor/tracemonkey/plify_jsdhash.sed +35 -0
  411. data/vendor/tracemonkey/prmjtime.cpp +869 -0
  412. data/vendor/tracemonkey/prmjtime.h +103 -0
  413. data/vendor/tracemonkey/ref-config/AIX4.1.mk +65 -0
  414. data/vendor/tracemonkey/ref-config/AIX4.2.mk +64 -0
  415. data/vendor/tracemonkey/ref-config/AIX4.3.mk +65 -0
  416. data/vendor/tracemonkey/ref-config/Darwin.mk +85 -0
  417. data/vendor/tracemonkey/ref-config/Darwin1.3.mk +81 -0
  418. data/vendor/tracemonkey/ref-config/Darwin1.4.mk +41 -0
  419. data/vendor/tracemonkey/ref-config/Darwin5.2.mk +81 -0
  420. data/vendor/tracemonkey/ref-config/Darwin5.3.mk +81 -0
  421. data/vendor/tracemonkey/ref-config/Darwin64.mk +72 -0
  422. data/vendor/tracemonkey/ref-config/HP-UXB.10.10.mk +77 -0
  423. data/vendor/tracemonkey/ref-config/HP-UXB.10.20.mk +77 -0
  424. data/vendor/tracemonkey/ref-config/HP-UXB.11.00.mk +80 -0
  425. data/vendor/tracemonkey/ref-config/IRIX.mk +87 -0
  426. data/vendor/tracemonkey/ref-config/IRIX5.3.mk +44 -0
  427. data/vendor/tracemonkey/ref-config/IRIX6.1.mk +44 -0
  428. data/vendor/tracemonkey/ref-config/IRIX6.2.mk +44 -0
  429. data/vendor/tracemonkey/ref-config/IRIX6.3.mk +44 -0
  430. data/vendor/tracemonkey/ref-config/IRIX6.5.mk +44 -0
  431. data/vendor/tracemonkey/ref-config/Linux_All.mk +105 -0
  432. data/vendor/tracemonkey/ref-config/Mac_OS10.0.mk +82 -0
  433. data/vendor/tracemonkey/ref-config/OSF1V4.0.mk +72 -0
  434. data/vendor/tracemonkey/ref-config/OSF1V5.0.mk +69 -0
  435. data/vendor/tracemonkey/ref-config/SunOS4.1.4.mk +101 -0
  436. data/vendor/tracemonkey/ref-config/SunOS5.10.mk +50 -0
  437. data/vendor/tracemonkey/ref-config/SunOS5.3.mk +91 -0
  438. data/vendor/tracemonkey/ref-config/SunOS5.4.mk +92 -0
  439. data/vendor/tracemonkey/ref-config/SunOS5.5.1.mk +44 -0
  440. data/vendor/tracemonkey/ref-config/SunOS5.5.mk +87 -0
  441. data/vendor/tracemonkey/ref-config/SunOS5.6.mk +89 -0
  442. data/vendor/tracemonkey/ref-config/SunOS5.7.mk +44 -0
  443. data/vendor/tracemonkey/ref-config/SunOS5.8.mk +44 -0
  444. data/vendor/tracemonkey/ref-config/SunOS5.9.mk +44 -0
  445. data/vendor/tracemonkey/ref-config/WINNT4.0.mk +118 -0
  446. data/vendor/tracemonkey/ref-config/WINNT5.0.mk +118 -0
  447. data/vendor/tracemonkey/ref-config/WINNT5.1.mk +118 -0
  448. data/vendor/tracemonkey/ref-config/WINNT5.2.mk +118 -0
  449. data/vendor/tracemonkey/ref-config/WINNT6.0.mk +118 -0
  450. data/vendor/tracemonkey/ref-config/dgux.mk +64 -0
  451. data/vendor/tracemonkey/resource.h +15 -0
  452. data/vendor/tracemonkey/rules.mk +206 -0
  453. data/vendor/tracemonkey/shell/Makefile.in +72 -0
  454. data/vendor/tracemonkey/shell/js.cpp +4719 -0
  455. data/vendor/tracemonkey/t/3d-cube.js +337 -0
  456. data/vendor/tracemonkey/t/3d-morph.js +54 -0
  457. data/vendor/tracemonkey/t/3d-raytrace.js +441 -0
  458. data/vendor/tracemonkey/t/access-binary-trees.js +50 -0
  459. data/vendor/tracemonkey/t/access-fannkuch.js +66 -0
  460. data/vendor/tracemonkey/t/access-nbody.js +169 -0
  461. data/vendor/tracemonkey/t/access-nsieve.js +38 -0
  462. data/vendor/tracemonkey/t/bitops-3bit-bits-in-byte.js +32 -0
  463. data/vendor/tracemonkey/t/bitops-bits-in-byte.js +21 -0
  464. data/vendor/tracemonkey/t/bitops-bitwise-and.js +28 -0
  465. data/vendor/tracemonkey/t/bitops-nsieve-bits.js +32 -0
  466. data/vendor/tracemonkey/t/controlflow-recursive.js +25 -0
  467. data/vendor/tracemonkey/t/crypto-aes.js +422 -0
  468. data/vendor/tracemonkey/t/crypto-md5.js +286 -0
  469. data/vendor/tracemonkey/t/crypto-sha1.js +224 -0
  470. data/vendor/tracemonkey/t/date-format-tofte.js +299 -0
  471. data/vendor/tracemonkey/t/date-format-xparb.js +417 -0
  472. data/vendor/tracemonkey/t/math-cordic.js +95 -0
  473. data/vendor/tracemonkey/t/math-partial-sums.js +33 -0
  474. data/vendor/tracemonkey/t/math-spectral-norm.js +51 -0
  475. data/vendor/tracemonkey/t/regexp-dna.js +1712 -0
  476. data/vendor/tracemonkey/t/string-base64.js +135 -0
  477. data/vendor/tracemonkey/t/string-fasta.js +85 -0
  478. data/vendor/tracemonkey/t/string-tagcloud.js +265 -0
  479. data/vendor/tracemonkey/t/string-unpack-code.js +68 -0
  480. data/vendor/tracemonkey/t/string-validate-input.js +89 -0
  481. data/vendor/tracemonkey/time.sh +13 -0
  482. data/vendor/tracemonkey/trace-test.js +5564 -0
  483. data/vendor/tracemonkey/v8/base.js +187 -0
  484. data/vendor/tracemonkey/v8/crypto.js +1689 -0
  485. data/vendor/tracemonkey/v8/deltablue.js +880 -0
  486. data/vendor/tracemonkey/v8/earley-boyer.js +4682 -0
  487. data/vendor/tracemonkey/v8/raytrace.js +3418 -0
  488. data/vendor/tracemonkey/v8/richards.js +539 -0
  489. data/vendor/tracemonkey/v8/run-crypto.js +44 -0
  490. data/vendor/tracemonkey/v8/run-deltablue.js +44 -0
  491. data/vendor/tracemonkey/v8/run-earley-boyer.js +44 -0
  492. data/vendor/tracemonkey/v8/run-raytrace.js +44 -0
  493. data/vendor/tracemonkey/v8/run-richards.js +44 -0
  494. data/vendor/tracemonkey/v8/run.js +49 -0
  495. data/vendor/tracemonkey/vprof/readme.txt +93 -0
  496. data/vendor/tracemonkey/vprof/vprof.cpp +360 -0
  497. data/vendor/tracemonkey/vprof/vprof.h +245 -0
  498. data/vendor/tracemonkey/xpconnect/Makefile.in +67 -0
  499. data/vendor/tracemonkey/xpconnect/crashtests/117307-1.html +20 -0
  500. data/vendor/tracemonkey/xpconnect/crashtests/193710.html +11 -0
  501. data/vendor/tracemonkey/xpconnect/crashtests/290162-1.html +5 -0
  502. data/vendor/tracemonkey/xpconnect/crashtests/326615-1.html +16 -0
  503. data/vendor/tracemonkey/xpconnect/crashtests/328553-1.html +13 -0
  504. data/vendor/tracemonkey/xpconnect/crashtests/346258-1.html +12 -0
  505. data/vendor/tracemonkey/xpconnect/crashtests/346512-1-frame1.xhtml +16 -0
  506. data/vendor/tracemonkey/xpconnect/crashtests/346512-1-frame2.xhtml +15 -0
  507. data/vendor/tracemonkey/xpconnect/crashtests/346512-1.xhtml +30 -0
  508. data/vendor/tracemonkey/xpconnect/crashtests/382133-1.html +3 -0
  509. data/vendor/tracemonkey/xpconnect/crashtests/386680-1.html +22 -0
  510. data/vendor/tracemonkey/xpconnect/crashtests/394810-1.html +4 -0
  511. data/vendor/tracemonkey/xpconnect/crashtests/400349-1.html +20 -0
  512. data/vendor/tracemonkey/xpconnect/crashtests/403356-1.html +13 -0
  513. data/vendor/tracemonkey/xpconnect/crashtests/418139-1.svg +22 -0
  514. data/vendor/tracemonkey/xpconnect/crashtests/420513-1.html +11 -0
  515. data/vendor/tracemonkey/xpconnect/crashtests/453935-1.html +37 -0
  516. data/vendor/tracemonkey/xpconnect/crashtests/462926.html +12 -0
  517. data/vendor/tracemonkey/xpconnect/crashtests/468552-1.html +18 -0
  518. data/vendor/tracemonkey/xpconnect/crashtests/471366-1.html +12 -0
  519. data/vendor/tracemonkey/xpconnect/crashtests/475185-1.html +13 -0
  520. data/vendor/tracemonkey/xpconnect/crashtests/475291-1.html +14 -0
  521. data/vendor/tracemonkey/xpconnect/crashtests/503286-1.html +23 -0
  522. data/vendor/tracemonkey/xpconnect/crashtests/crashtests.list +21 -0
  523. data/vendor/tracemonkey/xpconnect/idl/Makefile.in +78 -0
  524. data/vendor/tracemonkey/xpconnect/idl/XPCIDispatch.idl +51 -0
  525. data/vendor/tracemonkey/xpconnect/idl/mozIJSSubScriptLoader.idl +64 -0
  526. data/vendor/tracemonkey/xpconnect/idl/nsIActiveXSecurityPolicy.idl +67 -0
  527. data/vendor/tracemonkey/xpconnect/idl/nsIDispatchSupport.idl +119 -0
  528. data/vendor/tracemonkey/xpconnect/idl/nsIJSContextStack.idl +85 -0
  529. data/vendor/tracemonkey/xpconnect/idl/nsIJSRuntimeService.idl +51 -0
  530. data/vendor/tracemonkey/xpconnect/idl/nsIScriptError.idl +102 -0
  531. data/vendor/tracemonkey/xpconnect/idl/nsIScriptableInterfaces.idl +67 -0
  532. data/vendor/tracemonkey/xpconnect/idl/nsIXPCScriptNotify.idl +66 -0
  533. data/vendor/tracemonkey/xpconnect/idl/nsIXPCScriptable.idl +183 -0
  534. data/vendor/tracemonkey/xpconnect/idl/nsIXPCSecurityManager.idl +114 -0
  535. data/vendor/tracemonkey/xpconnect/idl/nsIXPConnect.idl +819 -0
  536. data/vendor/tracemonkey/xpconnect/idl/xpcIJSModuleLoader.idl +95 -0
  537. data/vendor/tracemonkey/xpconnect/idl/xpcIJSWeakReference.idl +49 -0
  538. data/vendor/tracemonkey/xpconnect/idl/xpccomponents.idl +254 -0
  539. data/vendor/tracemonkey/xpconnect/idl/xpcexception.idl +66 -0
  540. data/vendor/tracemonkey/xpconnect/idl/xpcjsid.idl +83 -0
  541. data/vendor/tracemonkey/xpconnect/loader/ISO8601DateUtils.jsm +176 -0
  542. data/vendor/tracemonkey/xpconnect/loader/Makefile.in +63 -0
  543. data/vendor/tracemonkey/xpconnect/loader/XPCOMUtils.jsm +267 -0
  544. data/vendor/tracemonkey/xpconnect/loader/mozJSComponentLoader.cpp +1717 -0
  545. data/vendor/tracemonkey/xpconnect/loader/mozJSComponentLoader.h +172 -0
  546. data/vendor/tracemonkey/xpconnect/loader/mozJSLoaderConstructors.h +101 -0
  547. data/vendor/tracemonkey/xpconnect/loader/mozJSSubScriptLoader.cpp +360 -0
  548. data/vendor/tracemonkey/xpconnect/loader/mozJSSubScriptLoader.h +66 -0
  549. data/vendor/tracemonkey/xpconnect/public/Makefile.in +54 -0
  550. data/vendor/tracemonkey/xpconnect/public/nsAXPCNativeCallContext.h +89 -0
  551. data/vendor/tracemonkey/xpconnect/public/nsAutoJSValHolder.h +168 -0
  552. data/vendor/tracemonkey/xpconnect/public/xpc_map_end.h +327 -0
  553. data/vendor/tracemonkey/xpconnect/sample/Makefile.in +71 -0
  554. data/vendor/tracemonkey/xpconnect/sample/README +39 -0
  555. data/vendor/tracemonkey/xpconnect/sample/xpcsample1.cpp +337 -0
  556. data/vendor/tracemonkey/xpconnect/sample/xpcsample1.idl +82 -0
  557. data/vendor/tracemonkey/xpconnect/sample/xpcsample1.js +21 -0
  558. data/vendor/tracemonkey/xpconnect/shell/Makefile.in +106 -0
  559. data/vendor/tracemonkey/xpconnect/shell/jsshell.msg +50 -0
  560. data/vendor/tracemonkey/xpconnect/shell/xpcshell.cpp +1817 -0
  561. data/vendor/tracemonkey/xpconnect/shell/xpcshellMacUtils.h +43 -0
  562. data/vendor/tracemonkey/xpconnect/shell/xpcshellMacUtils.mm +54 -0
  563. data/vendor/tracemonkey/xpconnect/src/Makefile.in +228 -0
  564. data/vendor/tracemonkey/xpconnect/src/README +3 -0
  565. data/vendor/tracemonkey/xpconnect/src/XPCCrossOriginWrapper.cpp +1186 -0
  566. data/vendor/tracemonkey/xpconnect/src/XPCDispConvert.cpp +593 -0
  567. data/vendor/tracemonkey/xpconnect/src/XPCDispInlines.h +667 -0
  568. data/vendor/tracemonkey/xpconnect/src/XPCDispInterface.cpp +383 -0
  569. data/vendor/tracemonkey/xpconnect/src/XPCDispObject.cpp +516 -0
  570. data/vendor/tracemonkey/xpconnect/src/XPCDispParamPropJSClass.cpp +223 -0
  571. data/vendor/tracemonkey/xpconnect/src/XPCDispParams.cpp +103 -0
  572. data/vendor/tracemonkey/xpconnect/src/XPCDispPrivate.h +1401 -0
  573. data/vendor/tracemonkey/xpconnect/src/XPCDispTearOff.cpp +547 -0
  574. data/vendor/tracemonkey/xpconnect/src/XPCDispTypeInfo.cpp +471 -0
  575. data/vendor/tracemonkey/xpconnect/src/XPCIDispatchClassInfo.cpp +139 -0
  576. data/vendor/tracemonkey/xpconnect/src/XPCIDispatchExtension.cpp +362 -0
  577. data/vendor/tracemonkey/xpconnect/src/XPCNativeWrapper.cpp +1350 -0
  578. data/vendor/tracemonkey/xpconnect/src/XPCNativeWrapper.h +88 -0
  579. data/vendor/tracemonkey/xpconnect/src/XPCSafeJSObjectWrapper.cpp +1148 -0
  580. data/vendor/tracemonkey/xpconnect/src/XPCSystemOnlyWrapper.cpp +718 -0
  581. data/vendor/tracemonkey/xpconnect/src/XPCWrapper.cpp +850 -0
  582. data/vendor/tracemonkey/xpconnect/src/XPCWrapper.h +394 -0
  583. data/vendor/tracemonkey/xpconnect/src/dom_quickstubs.qsconf +568 -0
  584. data/vendor/tracemonkey/xpconnect/src/nsDispatchSupport.cpp +348 -0
  585. data/vendor/tracemonkey/xpconnect/src/nsScriptError.cpp +201 -0
  586. data/vendor/tracemonkey/xpconnect/src/nsXPConnect.cpp +2609 -0
  587. data/vendor/tracemonkey/xpconnect/src/qsgen.py +1487 -0
  588. data/vendor/tracemonkey/xpconnect/src/xpc.msg +217 -0
  589. data/vendor/tracemonkey/xpconnect/src/xpcJSWeakReference.cpp +148 -0
  590. data/vendor/tracemonkey/xpconnect/src/xpcJSWeakReference.h +56 -0
  591. data/vendor/tracemonkey/xpconnect/src/xpccallcontext.cpp +579 -0
  592. data/vendor/tracemonkey/xpconnect/src/xpccomponents.cpp +4144 -0
  593. data/vendor/tracemonkey/xpconnect/src/xpccontext.cpp +115 -0
  594. data/vendor/tracemonkey/xpconnect/src/xpcconvert.cpp +2298 -0
  595. data/vendor/tracemonkey/xpconnect/src/xpcdebug.cpp +481 -0
  596. data/vendor/tracemonkey/xpconnect/src/xpcexception.cpp +502 -0
  597. data/vendor/tracemonkey/xpconnect/src/xpcforwards.h +114 -0
  598. data/vendor/tracemonkey/xpconnect/src/xpcinlines.h +772 -0
  599. data/vendor/tracemonkey/xpconnect/src/xpcjsid.cpp +1025 -0
  600. data/vendor/tracemonkey/xpconnect/src/xpcjsruntime.cpp +1342 -0
  601. data/vendor/tracemonkey/xpconnect/src/xpclog.cpp +128 -0
  602. data/vendor/tracemonkey/xpconnect/src/xpclog.h +101 -0
  603. data/vendor/tracemonkey/xpconnect/src/xpcmaps.cpp +761 -0
  604. data/vendor/tracemonkey/xpconnect/src/xpcmaps.h +713 -0
  605. data/vendor/tracemonkey/xpconnect/src/xpcmodule.cpp +136 -0
  606. data/vendor/tracemonkey/xpconnect/src/xpcprivate.h +4138 -0
  607. data/vendor/tracemonkey/xpconnect/src/xpcquickstubs.cpp +1128 -0
  608. data/vendor/tracemonkey/xpconnect/src/xpcquickstubs.h +480 -0
  609. data/vendor/tracemonkey/xpconnect/src/xpcruntimesvc.cpp +179 -0
  610. data/vendor/tracemonkey/xpconnect/src/xpcstack.cpp +342 -0
  611. data/vendor/tracemonkey/xpconnect/src/xpcstring.cpp +139 -0
  612. data/vendor/tracemonkey/xpconnect/src/xpcthreadcontext.cpp +599 -0
  613. data/vendor/tracemonkey/xpconnect/src/xpcthrower.cpp +399 -0
  614. data/vendor/tracemonkey/xpconnect/src/xpcvariant.cpp +850 -0
  615. data/vendor/tracemonkey/xpconnect/src/xpcwrappedjs.cpp +670 -0
  616. data/vendor/tracemonkey/xpconnect/src/xpcwrappedjsclass.cpp +2015 -0
  617. data/vendor/tracemonkey/xpconnect/src/xpcwrappednative.cpp +3482 -0
  618. data/vendor/tracemonkey/xpconnect/src/xpcwrappednativeinfo.cpp +945 -0
  619. data/vendor/tracemonkey/xpconnect/src/xpcwrappednativejsops.cpp +2003 -0
  620. data/vendor/tracemonkey/xpconnect/src/xpcwrappednativeproto.cpp +302 -0
  621. data/vendor/tracemonkey/xpconnect/src/xpcwrappednativescope.cpp +991 -0
  622. data/vendor/tracemonkey/xpconnect/tests/Makefile.in +75 -0
  623. data/vendor/tracemonkey/xpconnect/tests/TestXPC.cpp +785 -0
  624. data/vendor/tracemonkey/xpconnect/tests/chrome/Makefile.in +51 -0
  625. data/vendor/tracemonkey/xpconnect/tests/chrome/test_bug500931.xul +43 -0
  626. data/vendor/tracemonkey/xpconnect/tests/components/Makefile.in +85 -0
  627. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_array.cpp +388 -0
  628. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_attributes.cpp +305 -0
  629. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_calljs.cpp +135 -0
  630. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_child.cpp +225 -0
  631. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_const.cpp +76 -0
  632. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_domstring.cpp +118 -0
  633. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_echo.cpp +616 -0
  634. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_in.cpp +204 -0
  635. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_inout.cpp +171 -0
  636. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_module.cpp +77 -0
  637. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_multiple.cpp +554 -0
  638. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_noisy.cpp +154 -0
  639. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_out.cpp +335 -0
  640. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_overloaded.cpp +250 -0
  641. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_private.h +192 -0
  642. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_string.cpp +185 -0
  643. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_variant.cpp +355 -0
  644. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/StdAfx.cpp +12 -0
  645. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/StdAfx.h +28 -0
  646. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCDispUtilities.h +28 -0
  647. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.cpp +86 -0
  648. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.def +9 -0
  649. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.dsp +318 -0
  650. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.dsw +29 -0
  651. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.idl +454 -0
  652. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.rc +145 -0
  653. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispSimple.cpp +44 -0
  654. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispSimple.h +56 -0
  655. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispSimple.rgs +23 -0
  656. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestArrays.cpp +221 -0
  657. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestArrays.h +53 -0
  658. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestArrays.rgs +23 -0
  659. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestMethods.cpp +699 -0
  660. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestMethods.h +138 -0
  661. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestMethods.rgs +23 -0
  662. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestNoIDispatch.cpp +23 -0
  663. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestNoIDispatch.h +41 -0
  664. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestNoIDispatch.rgs +23 -0
  665. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestProperties.cpp +256 -0
  666. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestProperties.h +88 -0
  667. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestProperties.rgs +23 -0
  668. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOff.cpp +23 -0
  669. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOff.h +43 -0
  670. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOff.rgs +23 -0
  671. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOn.cpp +29 -0
  672. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOn.h +45 -0
  673. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOn.rgs +23 -0
  674. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestWrappedJS.cpp +177 -0
  675. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestWrappedJS.h +50 -0
  676. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestWrappedJS.rgs +23 -0
  677. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/resource.h +36 -0
  678. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/Arrays/XPCIDispatchArrayTests.js +54 -0
  679. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/Attributes/XPCIDispatchAttributeTests.js +150 -0
  680. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/General/XPCIDispatchInstantiations.js +122 -0
  681. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/General/XPCStress.js +58 -0
  682. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/Methods/XPCIDispatchMethodTests.js +376 -0
  683. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/shell.js +377 -0
  684. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedJS/General/XPCIDispatchTestWrappedJS.js +76 -0
  685. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedJS/shell.js +377 -0
  686. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/exectests.cmd +1 -0
  687. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/jsDriver.pl +1288 -0
  688. data/vendor/tracemonkey/xpconnect/tests/idl/Makefile.in +61 -0
  689. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest.idl +312 -0
  690. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest2.idl +51 -0
  691. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_attributes.idl +67 -0
  692. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_calljs.idl +59 -0
  693. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_const.idl +61 -0
  694. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_domstring.idl +59 -0
  695. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_in.idl +88 -0
  696. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_inout.idl +86 -0
  697. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_multiple.idl +77 -0
  698. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_out.idl +142 -0
  699. data/vendor/tracemonkey/xpconnect/tests/js/checkid.js +82 -0
  700. data/vendor/tracemonkey/xpconnect/tests/js/evaluate.js +311 -0
  701. data/vendor/tracemonkey/xpconnect/tests/js/exceptions-2.js +153 -0
  702. data/vendor/tracemonkey/xpconnect/tests/js/exceptions-3.js +194 -0
  703. data/vendor/tracemonkey/xpconnect/tests/js/exceptions-4.js +297 -0
  704. data/vendor/tracemonkey/xpconnect/tests/js/exceptions-5.js +343 -0
  705. data/vendor/tracemonkey/xpconnect/tests/js/exceptions.js +230 -0
  706. data/vendor/tracemonkey/xpconnect/tests/js/javascript.js +96 -0
  707. data/vendor/tracemonkey/xpconnect/tests/js/multiple-2.js +151 -0
  708. data/vendor/tracemonkey/xpconnect/tests/js/multiple-3.js +148 -0
  709. data/vendor/tracemonkey/xpconnect/tests/js/multiple-4.js +152 -0
  710. data/vendor/tracemonkey/xpconnect/tests/js/multiple.js +137 -0
  711. data/vendor/tracemonkey/xpconnect/tests/js/notscriptable.js +104 -0
  712. data/vendor/tracemonkey/xpconnect/tests/js/old/simpletest.js +36 -0
  713. data/vendor/tracemonkey/xpconnect/tests/js/old/speed.js +60 -0
  714. data/vendor/tracemonkey/xpconnect/tests/js/old/testxpc.js +464 -0
  715. data/vendor/tracemonkey/xpconnect/tests/js/old/threads.js +74 -0
  716. data/vendor/tracemonkey/xpconnect/tests/js/old/try.js +27 -0
  717. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_array.js +308 -0
  718. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_callcontext.js +68 -0
  719. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_echo.js +636 -0
  720. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_enum_and_sort.js +28 -0
  721. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_enum_constants.js +15 -0
  722. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_enum_create.js +200 -0
  723. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_exceptions.js +167 -0
  724. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_ids.js +135 -0
  725. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_observer.js +36 -0
  726. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_overloaded.js +14 -0
  727. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_primitives.js +141 -0
  728. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_propertybag.js +36 -0
  729. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_variant.js +339 -0
  730. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_variant_array.js +30 -0
  731. data/vendor/tracemonkey/xpconnect/tests/js/readonlyattributes.js +74 -0
  732. data/vendor/tracemonkey/xpconnect/tests/js/readwriteattributes.js +101 -0
  733. data/vendor/tracemonkey/xpconnect/tests/js/scriptable.js +120 -0
  734. data/vendor/tracemonkey/xpconnect/tests/js/testin.js +203 -0
  735. data/vendor/tracemonkey/xpconnect/tests/js/xpcfun.js +234 -0
  736. data/vendor/tracemonkey/xpconnect/tests/js/xpctest_primitives.js +200 -0
  737. data/vendor/tracemonkey/xpconnect/tests/mochitest/Makefile.in +66 -0
  738. data/vendor/tracemonkey/xpconnect/tests/mochitest/bug500931_helper.html +7 -0
  739. data/vendor/tracemonkey/xpconnect/tests/mochitest/inner.html +7 -0
  740. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug361111.xul +29 -0
  741. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug384632.html +32 -0
  742. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug390488.html +65 -0
  743. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug393269.html +46 -0
  744. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug396851.html +43 -0
  745. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug428021.html +41 -0
  746. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug446584.html +49 -0
  747. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug448587.html +31 -0
  748. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug462428.html +42 -0
  749. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug478438.html +66 -0
  750. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug484107.html +100 -0
  751. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug484459.html +36 -0
  752. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug500691.html +28 -0
  753. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_wrappers.html +116 -0
  754. data/vendor/tracemonkey/xpconnect/tests/unit/bogus_element_type.jsm +1 -0
  755. data/vendor/tracemonkey/xpconnect/tests/unit/bogus_exports_type.jsm +1 -0
  756. data/vendor/tracemonkey/xpconnect/tests/unit/bug451678_subscript.js +2 -0
  757. data/vendor/tracemonkey/xpconnect/tests/unit/component_import.js +144 -0
  758. data/vendor/tracemonkey/xpconnect/tests/unit/recursive_importA.jsm +44 -0
  759. data/vendor/tracemonkey/xpconnect/tests/unit/recursive_importB.jsm +45 -0
  760. data/vendor/tracemonkey/xpconnect/tests/unit/syntax_error.jsm +1 -0
  761. data/vendor/tracemonkey/xpconnect/tests/unit/test_bogus_files.js +88 -0
  762. data/vendor/tracemonkey/xpconnect/tests/unit/test_bug408412.js +51 -0
  763. data/vendor/tracemonkey/xpconnect/tests/unit/test_bug451678.js +52 -0
  764. data/vendor/tracemonkey/xpconnect/tests/unit/test_bug_442086.js +68 -0
  765. data/vendor/tracemonkey/xpconnect/tests/unit/test_import.js +127 -0
  766. data/vendor/tracemonkey/xpconnect/tests/unit/test_js_weak_references.js +63 -0
  767. data/vendor/tracemonkey/xpconnect/tests/unit/test_recursive_import.js +62 -0
  768. data/vendor/tracemonkey/xpconnect/tools/Makefile.in +49 -0
  769. data/vendor/tracemonkey/xpconnect/tools/idl/Makefile.in +53 -0
  770. data/vendor/tracemonkey/xpconnect/tools/idl/nsIXPCToolsCompiler.idl +60 -0
  771. data/vendor/tracemonkey/xpconnect/tools/idl/nsIXPCToolsProfiler.idl +57 -0
  772. data/vendor/tracemonkey/xpconnect/tools/js/CompileJSFiles.js +28 -0
  773. data/vendor/tracemonkey/xpconnect/tools/js/ListJSFiles.js +18 -0
  774. data/vendor/tracemonkey/xpconnect/tools/src/Makefile.in +76 -0
  775. data/vendor/tracemonkey/xpconnect/tools/src/nsXPCToolsCompiler.cpp +161 -0
  776. data/vendor/tracemonkey/xpconnect/tools/src/nsXPCToolsModule.cpp +65 -0
  777. data/vendor/tracemonkey/xpconnect/tools/src/nsXPCToolsProfiler.cpp +370 -0
  778. data/vendor/tracemonkey/xpconnect/tools/src/xpctools_private.h +236 -0
  779. metadata +782 -107
  780. data/test/johnson/nodes/export_test.rb +0 -9
  781. data/test/johnson/nodes/import_test.rb +0 -13
  782. data/test/johnson/version_test.rb +0 -13
@@ -0,0 +1,56 @@
1
+ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2
+ *
3
+ * ***** BEGIN LICENSE BLOCK *****
4
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5
+ *
6
+ * The contents of this file are subject to the Mozilla Public License Version
7
+ * 1.1 (the "License"); you may not use this file except in compliance with
8
+ * the License. You may obtain a copy of the License at
9
+ * http://www.mozilla.org/MPL/
10
+ *
11
+ * Software distributed under the License is distributed on an "AS IS" basis,
12
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13
+ * for the specific language governing rights and limitations under the
14
+ * License.
15
+ *
16
+ * The Original Code is Mozilla Communicator client code, released
17
+ * March 31, 1998.
18
+ *
19
+ * The Initial Developer of the Original Code is
20
+ * Netscape Communications Corporation.
21
+ * Portions created by the Initial Developer are Copyright (C) 1998
22
+ * the Initial Developer. All Rights Reserved.
23
+ *
24
+ * Contributor(s):
25
+ *
26
+ * Alternatively, the contents of this file may be used under the terms of
27
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
28
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29
+ * in which case the provisions of the GPL or the LGPL are applicable instead
30
+ * of those above. If you wish to allow use of your version of this file only
31
+ * under the terms of either the GPL or the LGPL, and not to allow others to
32
+ * use your version of this file under the terms of the MPL, indicate your
33
+ * decision by deleting the provisions above and replace them with the notice
34
+ * and other provisions required by the GPL or the LGPL. If you do not delete
35
+ * the provisions above, a recipient may use your version of this file under
36
+ * the terms of any one of the MPL, the GPL or the LGPL.
37
+ *
38
+ * ***** END LICENSE BLOCK ***** */
39
+
40
+ #ifndef _jsfile_h__
41
+ #define _jsfile_h__
42
+
43
+ #if JS_HAS_FILE_OBJECT
44
+
45
+ #include "jsobj.h"
46
+
47
+ extern JS_PUBLIC_API(JSObject*)
48
+ js_InitFileClass(JSContext *cx, JSObject* obj);
49
+
50
+ extern JS_PUBLIC_API(JSObject*)
51
+ js_NewFileObject(JSContext *cx, char *bytes);
52
+
53
+ extern JSClass js_FileClass;
54
+
55
+ #endif /* JS_HAS_FILE_OBJECT */
56
+ #endif /* _jsfile_h__ */
@@ -0,0 +1,90 @@
1
+ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2
+ *
3
+ * ***** BEGIN LICENSE BLOCK *****
4
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5
+ *
6
+ * The contents of this file are subject to the Mozilla Public License Version
7
+ * 1.1 (the "License"); you may not use this file except in compliance with
8
+ * the License. You may obtain a copy of the License at
9
+ * http://www.mozilla.org/MPL/
10
+ *
11
+ * Software distributed under the License is distributed on an "AS IS" basis,
12
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13
+ * for the specific language governing rights and limitations under the
14
+ * License.
15
+ *
16
+ * The Original Code is Mozilla Communicator client code, released
17
+ * March 31, 1998.
18
+ *
19
+ * The Initial Developer of the Original Code is
20
+ * Netscape Communications Corporation.
21
+ * Portions created by the Initial Developer are Copyright (C) 1998
22
+ * the Initial Developer. All Rights Reserved.
23
+ *
24
+ * Contributor(s):
25
+ *
26
+ * Alternatively, the contents of this file may be used under the terms of
27
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
28
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29
+ * in which case the provisions of the GPL or the LGPL are applicable instead
30
+ * of those above. If you wish to allow use of your version of this file only
31
+ * under the terms of either the GPL or the LGPL, and not to allow others to
32
+ * use your version of this file under the terms of the MPL, indicate your
33
+ * decision by deleting the provisions above and replace them with the notice
34
+ * and other provisions required by the GPL or the LGPL. If you do not delete
35
+ * the provisions above, a recipient may use your version of this file under
36
+ * the terms of any one of the MPL, the GPL or the LGPL.
37
+ *
38
+ * ***** END LICENSE BLOCK ***** */
39
+
40
+ /*
41
+ Error messages for jsfile.c. See js.msg for format specification.
42
+ */
43
+
44
+ MSG_DEF(JSFILEMSG_NOT_AN_ERROR, 0, 0, JSEXN_NONE, "<Error #0 is reserved>")
45
+ MSG_DEF(JSFILEMSG_FILE_CONSTRUCTOR_UNDEFINED_ERROR, 1, 0, JSEXN_NONE, "File constructor is undefined")
46
+ MSG_DEF(JSFILEMSG_FILE_CURRENTDIR_UNDEFINED_ERROR, 2, 0, JSEXN_NONE, "File.currentDir is undefined")
47
+ MSG_DEF(JSFILEMSG_FIRST_ARGUMENT_OPEN_NOT_STRING_ERROR, 3, 1, JSEXN_NONE, "The first argument {0} to file.open must be a string")
48
+ MSG_DEF(JSFILEMSG_SECOND_ARGUMENT_OPEN_NOT_STRING_ERROR, 4, 0, JSEXN_NONE, "The second argument to file.open must be a string")
49
+ MSG_DEF(JSFILEMSG_CANNOT_COPY_FILE_OPEN_FOR_WRITING_ERROR, 5, 1, JSEXN_NONE, "Cannot copy file {0} open for writing")
50
+ MSG_DEF(JSFILEMSG_CANNOT_ACCESS_FILE_INFO_ERROR, 6, 1, JSEXN_NONE, "Cannot access file information for {0}")
51
+ MSG_DEF(JSFILEMSG_COPY_READ_ERROR, 7, 1, JSEXN_NONE, "An error occured while attempting to read a file {0} to copy")
52
+ MSG_DEF(JSFILEMSG_COPY_WRITE_ERROR, 8, 1, JSEXN_NONE, "An error occured while attempting to copy into file {0}")
53
+ MSG_DEF(JSFILEMSG_EXPECTS_ONE_ARG_ERROR, 9, 0, JSEXN_NONE, "Operation {0} expects one argument, not {1}")
54
+ MSG_DEF(JSFILEMSG_CANNOT_FLUSH_CLOSE_FILE_ERROR, 10, 1, JSEXN_NONE, "Cannot flush closed file {0}")
55
+ MSG_DEF(JSFILEMSG_CANNOT_OPEN_WRITING_ERROR, 11, 1, JSEXN_NONE, "Cannot open file {0} for writing")
56
+ MSG_DEF(JSFILEMSG_WRITEALL_EXPECTS_ONE_ARG_ERROR, 12, 0, JSEXN_NONE, "writeAll expects one argument")
57
+ MSG_DEF(JSFILEMSG_FIRST_ARGUMENT_WRITEALL_NOT_ARRAY_ERROR, 13, 0, JSEXN_NONE, "writeAll expects an array as an argument")
58
+ MSG_DEF(JSFILEMSG_UNUSED0, 14, 0, JSEXN_NONE, "Unused error message slot")
59
+ MSG_DEF(JSFILEMSG_CANNOT_OPEN_FILE_ERROR, 15, 1, JSEXN_NONE, "Cannot open file {0}")
60
+ MSG_DEF(JSFILEMSG_FIRST_ARGUMENT_CONSTRUCTOR_NOT_STRING_ERROR, 16, 1, JSEXN_NONE, "The argument to the File constructor {0} must be a string")
61
+ MSG_DEF(JSFILEMSG_BIDIRECTIONAL_PIPE_NOT_SUPPORTED, 17, 0, JSEXN_NONE, "Bidirectional pipes are not supported")
62
+ MSG_DEF(JSFILEMSG_OPEN_MODE_NOT_SUPPORTED_WITH_PIPES, 18, 2, JSEXN_NONE, "The opening mode you have chosen {0} is not supported by the pipe you are trying to open: {1}")
63
+ MSG_DEF(JSFILEMSG_OPEN_FAILED, 19, 1, JSEXN_NONE, "open on file {0} failed")
64
+ MSG_DEF(JSFILEMSG_CLOSE_FAILED, 20, 1, JSEXN_NONE, "close on file {0} failed")
65
+ MSG_DEF(JSFILEMSG_PCLOSE_FAILED, 21, 1, JSEXN_NONE, "pclose on file {0} failed")
66
+ MSG_DEF(JSFILEMSG_REMOVE_FAILED, 22, 1, JSEXN_NONE, "remove on file {0} failed")
67
+ MSG_DEF(JSFILEMSG_CANNOT_ACCESS_FILE_STATUS, 23, 1, JSEXN_NONE, "Cannot access file status for {0}")
68
+ MSG_DEF(JSFILEMSG_RENAME_FAILED, 24, 2, JSEXN_NONE, "Cannot rename {0} to {1}")
69
+ MSG_DEF(JSFILEMSG_WRITE_FAILED, 25, 1, JSEXN_NONE, "Write failed on file {0}")
70
+ MSG_DEF(JSFILEMSG_READ_FAILED, 26, 1, JSEXN_NONE, "Read failed on file {0}")
71
+ MSG_DEF(JSFILEMSG_SKIP_FAILED, 27, 1, JSEXN_NONE, "Skip failed on file {0}")
72
+ MSG_DEF(JSFILEMSG_FIRST_ARGUMENT_MUST_BE_A_FUNCTION_OR_REGEX, 28, 1, JSEXN_NONE, "The first argument to file.list must be a function or a regex")
73
+ MSG_DEF(JSFILEMSG_CANNOT_DO_LIST_ON_A_FILE, 29, 1, JSEXN_NONE, "{0} must be a directory, cannot do list")
74
+ MSG_DEF(JSFILEMSG_NATIVE_OPERATION_IS_NOT_SUPPORTED, 30, 2, JSEXN_NONE, "Native operation {0} is not supported on {1}")
75
+ MSG_DEF(JSFILEMSG_CANNOT_SET_PRIVATE_FILE, 31, 1, JSEXN_NONE, "Cannot set private data for file {0}")
76
+ MSG_DEF(JSFILEMSG_FIRST_ARGUMENT_MUST_BE_A_NUMBER, 32, 2, JSEXN_NONE, "First argument to {0} must be a number, not {1}")
77
+ MSG_DEF(JSFILEMSG_CANNOT_WRITE, 33, 1, JSEXN_NONE, "Cannot write to {0}, file mode is different")
78
+ MSG_DEF(JSFILEMSG_CANNOT_READ, 34, 1, JSEXN_NONE, "Cannot read from {0}, file mode is different")
79
+ MSG_DEF(JSFILEMSG_CANNOT_FLUSH, 35, 1, JSEXN_NONE, "Flush failed on {0}")
80
+ MSG_DEF(JSFILEMSG_OP_FAILED, 36, 1, JSEXN_NONE, "File operation {0} failed")
81
+ MSG_DEF(JSFILEMSG_FILE_MUST_BE_OPEN, 37, 1, JSEXN_NONE, "File must be open for {0}")
82
+ MSG_DEF(JSFILEMSG_FILE_MUST_BE_CLOSED, 38, 1, JSEXN_NONE, "File must be closed for {0}")
83
+ MSG_DEF(JSFILEMSG_NO_RANDOM_ACCESS, 39, 1, JSEXN_NONE, "File {0} doesn't allow random access")
84
+ MSG_DEF(JSFILEMSG_OBJECT_CREATION_FAILED, 40, 1, JSEXN_NONE, "Couldn't create {0}")
85
+ MSG_DEF(JSFILEMSG_CANNOT_OPEN_DIR, 41, 1, JSEXN_NONE, "Couldn't open directory {0}")
86
+ MSG_DEF(JSFILEMSG_CANNOT_REPORT_POSITION, 42, 1, JSEXN_NONE, "Couldn't report position for {0}")
87
+ MSG_DEF(JSFILEMSG_CANNOT_SET_POSITION, 43, 1, JSEXN_NONE, "Couldn't set position for {0}")
88
+ MSG_DEF(JSFILEMSG_INIT_FAILED, 44, 0, JSEXN_NONE, "File class initialization failed")
89
+
90
+
@@ -0,0 +1,3089 @@
1
+ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2
+ * vim: set ts=8 sw=4 et tw=99:
3
+ *
4
+ * ***** BEGIN LICENSE BLOCK *****
5
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6
+ *
7
+ * The contents of this file are subject to the Mozilla Public License Version
8
+ * 1.1 (the "License"); you may not use this file except in compliance with
9
+ * the License. You may obtain a copy of the License at
10
+ * http://www.mozilla.org/MPL/
11
+ *
12
+ * Software distributed under the License is distributed on an "AS IS" basis,
13
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14
+ * for the specific language governing rights and limitations under the
15
+ * License.
16
+ *
17
+ * The Original Code is Mozilla Communicator client code, released
18
+ * March 31, 1998.
19
+ *
20
+ * The Initial Developer of the Original Code is
21
+ * Netscape Communications Corporation.
22
+ * Portions created by the Initial Developer are Copyright (C) 1998
23
+ * the Initial Developer. All Rights Reserved.
24
+ *
25
+ * Contributor(s):
26
+ *
27
+ * Alternatively, the contents of this file may be used under the terms of
28
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
29
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30
+ * in which case the provisions of the GPL or the LGPL are applicable instead
31
+ * of those above. If you wish to allow use of your version of this file only
32
+ * under the terms of either the GPL or the LGPL, and not to allow others to
33
+ * use your version of this file under the terms of the MPL, indicate your
34
+ * decision by deleting the provisions above and replace them with the notice
35
+ * and other provisions required by the GPL or the LGPL. If you do not delete
36
+ * the provisions above, a recipient may use your version of this file under
37
+ * the terms of any one of the MPL, the GPL or the LGPL.
38
+ *
39
+ * ***** END LICENSE BLOCK ***** */
40
+
41
+ /*
42
+ * JS function support.
43
+ */
44
+ #include "jsstddef.h"
45
+ #include <string.h>
46
+ #include "jstypes.h"
47
+ #include "jsbit.h"
48
+ #include "jsutil.h" /* Added by JSIFY */
49
+ #include "jsapi.h"
50
+ #include "jsarray.h"
51
+ #include "jsatom.h"
52
+ #include "jsbuiltins.h"
53
+ #include "jscntxt.h"
54
+ #include "jsversion.h"
55
+ #include "jsdbgapi.h"
56
+ #include "jsemit.h"
57
+ #include "jsfun.h"
58
+ #include "jsgc.h"
59
+ #include "jsinterp.h"
60
+ #include "jslock.h"
61
+ #include "jsnum.h"
62
+ #include "jsobj.h"
63
+ #include "jsopcode.h"
64
+ #include "jsparse.h"
65
+ #include "jsscan.h"
66
+ #include "jsscope.h"
67
+ #include "jsscript.h"
68
+ #include "jsstr.h"
69
+ #include "jsexn.h"
70
+ #include "jsstaticcheck.h"
71
+
72
+ #if JS_HAS_GENERATORS
73
+ # include "jsiter.h"
74
+ #endif
75
+
76
+ #if JS_HAS_XDR
77
+ # include "jsxdrapi.h"
78
+ #endif
79
+
80
+ /* Generic function/call/arguments tinyids -- also reflected bit numbers. */
81
+ enum {
82
+ CALL_ARGUMENTS = -1, /* predefined arguments local variable */
83
+ ARGS_LENGTH = -2, /* number of actual args, arity if inactive */
84
+ ARGS_CALLEE = -3, /* reference from arguments to active funobj */
85
+ FUN_ARITY = -4, /* number of formal parameters; desired argc */
86
+ FUN_NAME = -5, /* function name, "" if anonymous */
87
+ FUN_CALLER = -6 /* Function.prototype.caller, backward compat */
88
+ };
89
+
90
+ #if JSFRAME_OVERRIDE_BITS < 8
91
+ # error "not enough override bits in JSStackFrame.flags!"
92
+ #endif
93
+
94
+ #define TEST_OVERRIDE_BIT(fp, tinyid) \
95
+ ((fp)->flags & JS_BIT(JSFRAME_OVERRIDE_SHIFT - ((tinyid) + 1)))
96
+
97
+ #define SET_OVERRIDE_BIT(fp, tinyid) \
98
+ ((fp)->flags |= JS_BIT(JSFRAME_OVERRIDE_SHIFT - ((tinyid) + 1)))
99
+
100
+ JSBool
101
+ js_GetArgsValue(JSContext *cx, JSStackFrame *fp, jsval *vp)
102
+ {
103
+ JSObject *argsobj;
104
+
105
+ if (TEST_OVERRIDE_BIT(fp, CALL_ARGUMENTS)) {
106
+ JS_ASSERT(fp->callobj);
107
+ return OBJ_GET_PROPERTY(cx, fp->callobj,
108
+ ATOM_TO_JSID(cx->runtime->atomState
109
+ .argumentsAtom),
110
+ vp);
111
+ }
112
+ argsobj = js_GetArgsObject(cx, fp);
113
+ if (!argsobj)
114
+ return JS_FALSE;
115
+ *vp = OBJECT_TO_JSVAL(argsobj);
116
+ return JS_TRUE;
117
+ }
118
+
119
+ static JSBool
120
+ MarkArgDeleted(JSContext *cx, JSStackFrame *fp, uintN slot)
121
+ {
122
+ JSObject *argsobj;
123
+ jsval bmapval, bmapint;
124
+ size_t nbits, nbytes;
125
+ jsbitmap *bitmap;
126
+
127
+ argsobj = fp->argsobj;
128
+ (void) JS_GetReservedSlot(cx, argsobj, 0, &bmapval);
129
+ nbits = fp->argc;
130
+ JS_ASSERT(slot < nbits);
131
+ if (JSVAL_IS_VOID(bmapval)) {
132
+ if (nbits <= JSVAL_INT_BITS) {
133
+ bmapint = 0;
134
+ bitmap = (jsbitmap *) &bmapint;
135
+ } else {
136
+ nbytes = JS_HOWMANY(nbits, JS_BITS_PER_WORD) * sizeof(jsbitmap);
137
+ bitmap = (jsbitmap *) JS_malloc(cx, nbytes);
138
+ if (!bitmap)
139
+ return JS_FALSE;
140
+ memset(bitmap, 0, nbytes);
141
+ bmapval = PRIVATE_TO_JSVAL(bitmap);
142
+ JS_SetReservedSlot(cx, argsobj, 0, bmapval);
143
+ }
144
+ } else {
145
+ if (nbits <= JSVAL_INT_BITS) {
146
+ bmapint = JSVAL_TO_INT(bmapval);
147
+ bitmap = (jsbitmap *) &bmapint;
148
+ } else {
149
+ bitmap = (jsbitmap *) JSVAL_TO_PRIVATE(bmapval);
150
+ }
151
+ }
152
+ JS_SET_BIT(bitmap, slot);
153
+ if (bitmap == (jsbitmap *) &bmapint) {
154
+ bmapval = INT_TO_JSVAL(bmapint);
155
+ JS_SetReservedSlot(cx, argsobj, 0, bmapval);
156
+ }
157
+ return JS_TRUE;
158
+ }
159
+
160
+ /* NB: Infallible predicate, false does not mean error/exception. */
161
+ static JSBool
162
+ ArgWasDeleted(JSContext *cx, JSStackFrame *fp, uintN slot)
163
+ {
164
+ JSObject *argsobj;
165
+ jsval bmapval, bmapint;
166
+ jsbitmap *bitmap;
167
+
168
+ argsobj = fp->argsobj;
169
+ (void) JS_GetReservedSlot(cx, argsobj, 0, &bmapval);
170
+ if (JSVAL_IS_VOID(bmapval))
171
+ return JS_FALSE;
172
+ if (fp->argc <= JSVAL_INT_BITS) {
173
+ bmapint = JSVAL_TO_INT(bmapval);
174
+ bitmap = (jsbitmap *) &bmapint;
175
+ } else {
176
+ bitmap = (jsbitmap *) JSVAL_TO_PRIVATE(bmapval);
177
+ }
178
+ return JS_TEST_BIT(bitmap, slot) != 0;
179
+ }
180
+
181
+ JSBool
182
+ js_GetArgsProperty(JSContext *cx, JSStackFrame *fp, jsid id, jsval *vp)
183
+ {
184
+ jsval val;
185
+ JSObject *obj;
186
+ uintN slot;
187
+
188
+ if (TEST_OVERRIDE_BIT(fp, CALL_ARGUMENTS)) {
189
+ JS_ASSERT(fp->callobj);
190
+ if (!OBJ_GET_PROPERTY(cx, fp->callobj,
191
+ ATOM_TO_JSID(cx->runtime->atomState
192
+ .argumentsAtom),
193
+ &val)) {
194
+ return JS_FALSE;
195
+ }
196
+ if (JSVAL_IS_PRIMITIVE(val)) {
197
+ obj = js_ValueToNonNullObject(cx, val);
198
+ if (!obj)
199
+ return JS_FALSE;
200
+ } else {
201
+ obj = JSVAL_TO_OBJECT(val);
202
+ }
203
+ return OBJ_GET_PROPERTY(cx, obj, id, vp);
204
+ }
205
+
206
+ *vp = JSVAL_VOID;
207
+ if (JSID_IS_INT(id)) {
208
+ slot = (uintN) JSID_TO_INT(id);
209
+ if (slot < fp->argc) {
210
+ if (fp->argsobj && ArgWasDeleted(cx, fp, slot))
211
+ return OBJ_GET_PROPERTY(cx, fp->argsobj, id, vp);
212
+ *vp = fp->argv[slot];
213
+ } else {
214
+ /*
215
+ * Per ECMA-262 Ed. 3, 10.1.8, last bulleted item, do not share
216
+ * storage between the formal parameter and arguments[k] for all
217
+ * fp->argc <= k && k < fp->fun->nargs. For example, in
218
+ *
219
+ * function f(x) { x = 42; return arguments[0]; }
220
+ * f();
221
+ *
222
+ * the call to f should return undefined, not 42. If fp->argsobj
223
+ * is null at this point, as it would be in the example, return
224
+ * undefined in *vp.
225
+ */
226
+ if (fp->argsobj)
227
+ return OBJ_GET_PROPERTY(cx, fp->argsobj, id, vp);
228
+ }
229
+ } else {
230
+ if (id == ATOM_TO_JSID(cx->runtime->atomState.lengthAtom)) {
231
+ if (fp->argsobj && TEST_OVERRIDE_BIT(fp, ARGS_LENGTH))
232
+ return OBJ_GET_PROPERTY(cx, fp->argsobj, id, vp);
233
+ *vp = INT_TO_JSVAL((jsint) fp->argc);
234
+ }
235
+ }
236
+ return JS_TRUE;
237
+ }
238
+
239
+ JSObject *
240
+ js_GetArgsObject(JSContext *cx, JSStackFrame *fp)
241
+ {
242
+ JSObject *argsobj, *global, *parent;
243
+
244
+ /*
245
+ * We must be in a function activation; the function must be lightweight
246
+ * or else fp must have a variable object.
247
+ */
248
+ JS_ASSERT(fp->fun && (!(fp->fun->flags & JSFUN_HEAVYWEIGHT) || fp->varobj));
249
+
250
+ /* Skip eval and debugger frames. */
251
+ while (fp->flags & JSFRAME_SPECIAL)
252
+ fp = fp->down;
253
+
254
+ /* Create an arguments object for fp only if it lacks one. */
255
+ argsobj = fp->argsobj;
256
+ if (argsobj)
257
+ return argsobj;
258
+
259
+ /* Link the new object to fp so it can get actual argument values. */
260
+ argsobj = js_NewObject(cx, &js_ArgumentsClass, NULL, NULL, 0);
261
+ if (!argsobj || !JS_SetPrivate(cx, argsobj, fp)) {
262
+ cx->weakRoots.newborn[GCX_OBJECT] = NULL;
263
+ return NULL;
264
+ }
265
+
266
+ /*
267
+ * Give arguments an intrinsic scope chain link to fp's global object.
268
+ * Since the arguments object lacks a prototype because js_ArgumentsClass
269
+ * is not initialized, js_NewObject won't assign a default parent to it.
270
+ *
271
+ * Therefore if arguments is used as the head of an eval scope chain (via
272
+ * a direct or indirect call to eval(program, arguments)), any reference
273
+ * to a standard class object in the program will fail to resolve due to
274
+ * js_GetClassPrototype not being able to find a global object containing
275
+ * the standard prototype by starting from arguments and following parent.
276
+ */
277
+ global = fp->scopeChain;
278
+ while ((parent = OBJ_GET_PARENT(cx, global)) != NULL)
279
+ global = parent;
280
+ STOBJ_SET_PARENT(argsobj, global);
281
+ fp->argsobj = argsobj;
282
+ return argsobj;
283
+ }
284
+
285
+ static JSBool
286
+ args_enumerate(JSContext *cx, JSObject *obj);
287
+
288
+ JS_FRIEND_API(JSBool)
289
+ js_PutArgsObject(JSContext *cx, JSStackFrame *fp)
290
+ {
291
+ JSObject *argsobj;
292
+ jsval bmapval, rval;
293
+ JSBool ok;
294
+ JSRuntime *rt;
295
+
296
+ /*
297
+ * Reuse args_enumerate here to reflect fp's actual arguments as indexed
298
+ * elements of argsobj. Do this first, before clearing and freeing the
299
+ * deleted argument slot bitmap, because args_enumerate depends on that.
300
+ */
301
+ argsobj = fp->argsobj;
302
+ ok = args_enumerate(cx, argsobj);
303
+
304
+ /*
305
+ * Now clear the deleted argument number bitmap slot and free the bitmap,
306
+ * if one was actually created due to 'delete arguments[0]' or similar.
307
+ */
308
+ (void) JS_GetReservedSlot(cx, argsobj, 0, &bmapval);
309
+ if (!JSVAL_IS_VOID(bmapval)) {
310
+ JS_SetReservedSlot(cx, argsobj, 0, JSVAL_VOID);
311
+ if (fp->argc > JSVAL_INT_BITS)
312
+ JS_free(cx, JSVAL_TO_PRIVATE(bmapval));
313
+ }
314
+
315
+ /*
316
+ * Now get the prototype properties so we snapshot fp->fun and fp->argc
317
+ * before fp goes away.
318
+ */
319
+ rt = cx->runtime;
320
+ ok &= js_GetProperty(cx, argsobj, ATOM_TO_JSID(rt->atomState.calleeAtom),
321
+ &rval);
322
+ ok &= js_SetProperty(cx, argsobj, ATOM_TO_JSID(rt->atomState.calleeAtom),
323
+ &rval);
324
+ ok &= js_GetProperty(cx, argsobj, ATOM_TO_JSID(rt->atomState.lengthAtom),
325
+ &rval);
326
+ ok &= js_SetProperty(cx, argsobj, ATOM_TO_JSID(rt->atomState.lengthAtom),
327
+ &rval);
328
+
329
+ /*
330
+ * Clear the private pointer to fp, which is about to go away (js_Invoke).
331
+ * Do this last because the args_enumerate and js_GetProperty calls above
332
+ * need to follow the private slot to find fp.
333
+ */
334
+ ok &= JS_SetPrivate(cx, argsobj, NULL);
335
+ fp->argsobj = NULL;
336
+ return ok;
337
+ }
338
+
339
+ static JSBool
340
+ args_delProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
341
+ {
342
+ jsint slot;
343
+ JSStackFrame *fp;
344
+
345
+ if (!JSVAL_IS_INT(id))
346
+ return JS_TRUE;
347
+ fp = (JSStackFrame *)
348
+ JS_GetInstancePrivate(cx, obj, &js_ArgumentsClass, NULL);
349
+ if (!fp)
350
+ return JS_TRUE;
351
+ JS_ASSERT(fp->argsobj);
352
+
353
+ slot = JSVAL_TO_INT(id);
354
+ switch (slot) {
355
+ case ARGS_CALLEE:
356
+ case ARGS_LENGTH:
357
+ SET_OVERRIDE_BIT(fp, slot);
358
+ break;
359
+
360
+ default:
361
+ if ((uintN)slot < fp->argc && !MarkArgDeleted(cx, fp, slot))
362
+ return JS_FALSE;
363
+ break;
364
+ }
365
+ return JS_TRUE;
366
+ }
367
+
368
+ static JS_REQUIRES_STACK JSObject *
369
+ WrapEscapingClosure(JSContext *cx, JSStackFrame *fp, JSObject *funobj, JSFunction *fun)
370
+ {
371
+ JS_ASSERT(GET_FUNCTION_PRIVATE(cx, funobj) == fun);
372
+ JS_ASSERT(fun->optimizedClosure());
373
+ JS_ASSERT(!fun->u.i.wrapper);
374
+
375
+ /*
376
+ * We do not attempt to reify Call and Block objects on demand for outer
377
+ * scopes. This could be done (see the "v8" patch in bug 494235) but it is
378
+ * fragile in the face of ongoing compile-time optimization. Instead, the
379
+ * _DBG* opcodes used by wrappers created here must cope with unresolved
380
+ * upvars and throw them as reference errors. Caveat debuggers!
381
+ */
382
+ JSObject *scopeChain = js_GetScopeChain(cx, fp);
383
+ if (!scopeChain)
384
+ return NULL;
385
+
386
+ JSObject *wfunobj = js_NewObjectWithGivenProto(cx, &js_FunctionClass,
387
+ funobj, scopeChain, 0);
388
+ if (!wfunobj)
389
+ return NULL;
390
+ JSAutoTempValueRooter tvr(cx, wfunobj);
391
+
392
+ JSFunction *wfun = (JSFunction *) wfunobj;
393
+ wfunobj->fslots[JSSLOT_PRIVATE] = PRIVATE_TO_JSVAL(wfun);
394
+ wfun->nargs = 0;
395
+ wfun->flags = fun->flags | JSFUN_HEAVYWEIGHT;
396
+ wfun->u.i.nvars = 0;
397
+ wfun->u.i.nupvars = 0;
398
+ wfun->u.i.skipmin = fun->u.i.skipmin;
399
+ wfun->u.i.wrapper = true;
400
+ wfun->u.i.script = NULL;
401
+ wfun->u.i.names.taggedAtom = NULL;
402
+ wfun->atom = fun->atom;
403
+
404
+ if (fun->hasLocalNames()) {
405
+ void *mark = JS_ARENA_MARK(&cx->tempPool);
406
+ jsuword *names = js_GetLocalNameArray(cx, fun, &cx->tempPool);
407
+ if (!names)
408
+ return NULL;
409
+
410
+ JSBool ok = true;
411
+ for (uintN i = 0, n = fun->countLocalNames(); i != n; i++) {
412
+ jsuword name = names[i];
413
+ JSAtom *atom = JS_LOCAL_NAME_TO_ATOM(name);
414
+ JSLocalKind localKind = (i < fun->nargs)
415
+ ? JSLOCAL_ARG
416
+ : (i < fun->countArgsAndVars())
417
+ ? (JS_LOCAL_NAME_IS_CONST(name)
418
+ ? JSLOCAL_CONST
419
+ : JSLOCAL_VAR)
420
+ : JSLOCAL_UPVAR;
421
+
422
+ ok = js_AddLocal(cx, wfun, atom, localKind);
423
+ if (!ok)
424
+ break;
425
+ }
426
+
427
+ JS_ARENA_RELEASE(&cx->tempPool, mark);
428
+ if (!ok)
429
+ return NULL;
430
+ JS_ASSERT(wfun->nargs == fun->nargs);
431
+ JS_ASSERT(wfun->u.i.nvars == fun->u.i.nvars);
432
+ JS_ASSERT(wfun->u.i.nupvars == fun->u.i.nupvars);
433
+ js_FreezeLocalNames(cx, wfun);
434
+ }
435
+
436
+ JSScript *script = fun->u.i.script;
437
+ jssrcnote *snbase = SCRIPT_NOTES(script);
438
+ jssrcnote *sn = snbase;
439
+ while (!SN_IS_TERMINATOR(sn))
440
+ sn = SN_NEXT(sn);
441
+ uintN nsrcnotes = (sn - snbase) + 1;
442
+
443
+ /* NB: GC must not occur before wscript is homed in wfun->u.i.script. */
444
+ JSScript *wscript = js_NewScript(cx, script->length, nsrcnotes,
445
+ script->atomMap.length,
446
+ (script->objectsOffset != 0)
447
+ ? JS_SCRIPT_OBJECTS(script)->length
448
+ : 0,
449
+ fun->u.i.nupvars,
450
+ (script->regexpsOffset != 0)
451
+ ? JS_SCRIPT_REGEXPS(script)->length
452
+ : 0,
453
+ (script->trynotesOffset != 0)
454
+ ? JS_SCRIPT_TRYNOTES(script)->length
455
+ : 0);
456
+ if (!wscript)
457
+ return NULL;
458
+
459
+ memcpy(wscript->code, script->code, script->length);
460
+ wscript->main = wscript->code + (script->main - script->code);
461
+
462
+ memcpy(SCRIPT_NOTES(wscript), snbase, nsrcnotes);
463
+ memcpy(wscript->atomMap.vector, script->atomMap.vector,
464
+ wscript->atomMap.length * sizeof(JSAtom *));
465
+ if (script->objectsOffset != 0) {
466
+ memcpy(JS_SCRIPT_OBJECTS(wscript)->vector, JS_SCRIPT_OBJECTS(script)->vector,
467
+ JS_SCRIPT_OBJECTS(wscript)->length * sizeof(JSObject *));
468
+ }
469
+ if (script->regexpsOffset != 0) {
470
+ memcpy(JS_SCRIPT_REGEXPS(wscript)->vector, JS_SCRIPT_REGEXPS(script)->vector,
471
+ JS_SCRIPT_REGEXPS(wscript)->length * sizeof(JSObject *));
472
+ }
473
+ if (script->trynotesOffset != 0) {
474
+ memcpy(JS_SCRIPT_TRYNOTES(wscript)->vector, JS_SCRIPT_TRYNOTES(script)->vector,
475
+ JS_SCRIPT_TRYNOTES(wscript)->length * sizeof(JSTryNote));
476
+ }
477
+
478
+ if (wfun->u.i.nupvars != 0) {
479
+ JS_ASSERT(wfun->u.i.nupvars == JS_SCRIPT_UPVARS(wscript)->length);
480
+ memcpy(JS_SCRIPT_UPVARS(wscript)->vector, JS_SCRIPT_UPVARS(script)->vector,
481
+ wfun->u.i.nupvars * sizeof(uint32));
482
+ }
483
+
484
+ jsbytecode *pc = wscript->code;
485
+ while (*pc != JSOP_STOP) {
486
+ /* XYZZYbe should copy JSOP_TRAP? */
487
+ JSOp op = js_GetOpcode(cx, wscript, pc);
488
+ const JSCodeSpec *cs = &js_CodeSpec[op];
489
+ ptrdiff_t oplen = cs->length;
490
+ if (oplen < 0)
491
+ oplen = js_GetVariableBytecodeLength(pc);
492
+
493
+ /*
494
+ * Rewrite JSOP_{GET,CALL}DSLOT as JSOP_{GET,CALL}UPVAR_DBG for the
495
+ * case where fun is an escaping flat closure. This works because the
496
+ * UPVAR and DSLOT ops by design have the same format: an upvar index
497
+ * immediate operand.
498
+ */
499
+ switch (op) {
500
+ case JSOP_GETUPVAR: *pc = JSOP_GETUPVAR_DBG; break;
501
+ case JSOP_CALLUPVAR: *pc = JSOP_CALLUPVAR_DBG; break;
502
+ case JSOP_GETDSLOT: *pc = JSOP_GETUPVAR_DBG; break;
503
+ case JSOP_CALLDSLOT: *pc = JSOP_CALLUPVAR_DBG; break;
504
+ case JSOP_DEFFUN_FC: *pc = JSOP_DEFFUN_DBGFC; break;
505
+ case JSOP_DEFLOCALFUN_FC: *pc = JSOP_DEFLOCALFUN_DBGFC; break;
506
+ case JSOP_LAMBDA_FC: *pc = JSOP_LAMBDA_DBGFC; break;
507
+ default:;
508
+ }
509
+ pc += oplen;
510
+ }
511
+
512
+ /*
513
+ * Fill in the rest of wscript. This means if you add members to JSScript
514
+ * you must update this code. FIXME: factor into JSScript::clone method.
515
+ */
516
+ wscript->flags = script->flags;
517
+ wscript->version = script->version;
518
+ wscript->nfixed = script->nfixed;
519
+ wscript->filename = script->filename;
520
+ wscript->lineno = script->lineno;
521
+ wscript->nslots = script->nslots;
522
+ wscript->staticLevel = script->staticLevel;
523
+ wscript->principals = script->principals;
524
+ if (wscript->principals)
525
+ JSPRINCIPALS_HOLD(cx, wscript->principals);
526
+ #ifdef CHECK_SCRIPT_OWNER
527
+ wscript->owner = script->owner;
528
+ #endif
529
+
530
+ /* Deoptimize wfun from FUN_{FLAT,NULL}_CLOSURE to FUN_INTERPRETED. */
531
+ FUN_SET_KIND(wfun, JSFUN_INTERPRETED);
532
+ wfun->u.i.script = wscript;
533
+ return wfunobj;
534
+ }
535
+
536
+ static JSBool
537
+ args_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
538
+ {
539
+ jsint slot;
540
+ JSStackFrame *fp;
541
+
542
+ if (!JSVAL_IS_INT(id))
543
+ return JS_TRUE;
544
+ fp = (JSStackFrame *)
545
+ JS_GetInstancePrivate(cx, obj, &js_ArgumentsClass, NULL);
546
+ if (!fp)
547
+ return JS_TRUE;
548
+ JS_ASSERT(fp->argsobj);
549
+
550
+ slot = JSVAL_TO_INT(id);
551
+ switch (slot) {
552
+ case ARGS_CALLEE:
553
+ if (!TEST_OVERRIDE_BIT(fp, slot)) {
554
+ /*
555
+ * If this function or one in it needs upvars that reach above it
556
+ * in the scope chain, it must not be a null closure (it could be a
557
+ * flat closure, or an unoptimized closure -- the latter itself not
558
+ * necessarily heavyweight). Rather than wrap here, we simply throw
559
+ * to reduce code size and tell debugger users the truth instead of
560
+ * passing off a fibbing wrapper.
561
+ */
562
+ if (fp->fun->needsWrapper()) {
563
+ JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
564
+ JSMSG_OPTIMIZED_CLOSURE_LEAK);
565
+ return JS_FALSE;
566
+ }
567
+ *vp = OBJECT_TO_JSVAL(fp->callee);
568
+ }
569
+ break;
570
+
571
+ case ARGS_LENGTH:
572
+ if (!TEST_OVERRIDE_BIT(fp, slot))
573
+ *vp = INT_TO_JSVAL((jsint)fp->argc);
574
+ break;
575
+
576
+ default:
577
+ if ((uintN)slot < fp->argc && !ArgWasDeleted(cx, fp, slot))
578
+ *vp = fp->argv[slot];
579
+ break;
580
+ }
581
+ return JS_TRUE;
582
+ }
583
+
584
+ static JSBool
585
+ args_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
586
+ {
587
+ JSStackFrame *fp;
588
+ jsint slot;
589
+
590
+ if (!JSVAL_IS_INT(id))
591
+ return JS_TRUE;
592
+ fp = (JSStackFrame *)
593
+ JS_GetInstancePrivate(cx, obj, &js_ArgumentsClass, NULL);
594
+ if (!fp)
595
+ return JS_TRUE;
596
+ JS_ASSERT(fp->argsobj);
597
+
598
+ slot = JSVAL_TO_INT(id);
599
+ switch (slot) {
600
+ case ARGS_CALLEE:
601
+ case ARGS_LENGTH:
602
+ SET_OVERRIDE_BIT(fp, slot);
603
+ break;
604
+
605
+ default:
606
+ if (FUN_INTERPRETED(fp->fun) &&
607
+ (uintN)slot < fp->argc &&
608
+ !ArgWasDeleted(cx, fp, slot)) {
609
+ fp->argv[slot] = *vp;
610
+ }
611
+ break;
612
+ }
613
+ return JS_TRUE;
614
+ }
615
+
616
+ static JSBool
617
+ args_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
618
+ JSObject **objp)
619
+ {
620
+ JSStackFrame *fp;
621
+ uintN slot;
622
+ JSString *str;
623
+ JSAtom *atom;
624
+ intN tinyid;
625
+ jsval value;
626
+
627
+ *objp = NULL;
628
+ fp = (JSStackFrame *)
629
+ JS_GetInstancePrivate(cx, obj, &js_ArgumentsClass, NULL);
630
+ if (!fp)
631
+ return JS_TRUE;
632
+ JS_ASSERT(fp->argsobj);
633
+
634
+ if (JSVAL_IS_INT(id)) {
635
+ slot = JSVAL_TO_INT(id);
636
+ if (slot < fp->argc && !ArgWasDeleted(cx, fp, slot)) {
637
+ /* XXX ECMA specs DontEnum, contrary to other array-like objects */
638
+ if (!js_DefineProperty(cx, obj, INT_JSVAL_TO_JSID(id),
639
+ fp->argv[slot],
640
+ args_getProperty, args_setProperty,
641
+ 0, NULL)) {
642
+ return JS_FALSE;
643
+ }
644
+ *objp = obj;
645
+ }
646
+ } else if (JSVAL_IS_STRING(id)) {
647
+ str = JSVAL_TO_STRING(id);
648
+ atom = cx->runtime->atomState.lengthAtom;
649
+ if (str == ATOM_TO_STRING(atom)) {
650
+ tinyid = ARGS_LENGTH;
651
+ value = INT_TO_JSVAL(fp->argc);
652
+ } else {
653
+ atom = cx->runtime->atomState.calleeAtom;
654
+ if (str == ATOM_TO_STRING(atom)) {
655
+ tinyid = ARGS_CALLEE;
656
+ value = OBJECT_TO_JSVAL(fp->callee);
657
+ } else {
658
+ atom = NULL;
659
+
660
+ /* Quell GCC overwarnings. */
661
+ tinyid = 0;
662
+ value = JSVAL_NULL;
663
+ }
664
+ }
665
+
666
+ if (atom && !TEST_OVERRIDE_BIT(fp, tinyid)) {
667
+ if (!js_DefineNativeProperty(cx, obj, ATOM_TO_JSID(atom), value,
668
+ args_getProperty, args_setProperty, 0,
669
+ SPROP_HAS_SHORTID, tinyid, NULL)) {
670
+ return JS_FALSE;
671
+ }
672
+ *objp = obj;
673
+ }
674
+ }
675
+
676
+ return JS_TRUE;
677
+ }
678
+
679
+ static JSBool
680
+ args_enumerate(JSContext *cx, JSObject *obj)
681
+ {
682
+ JSStackFrame *fp;
683
+ JSObject *pobj;
684
+ JSProperty *prop;
685
+ uintN slot, argc;
686
+
687
+ fp = (JSStackFrame *)
688
+ JS_GetInstancePrivate(cx, obj, &js_ArgumentsClass, NULL);
689
+ if (!fp)
690
+ return JS_TRUE;
691
+ JS_ASSERT(fp->argsobj);
692
+
693
+ /*
694
+ * Trigger reflection with value snapshot in args_resolve using a series
695
+ * of js_LookupProperty calls. We handle length, callee, and the indexed
696
+ * argument properties. We know that args_resolve covers all these cases
697
+ * and creates direct properties of obj, but that it may fail to resolve
698
+ * length or callee if overridden.
699
+ */
700
+ if (!js_LookupProperty(cx, obj,
701
+ ATOM_TO_JSID(cx->runtime->atomState.lengthAtom),
702
+ &pobj, &prop)) {
703
+ return JS_FALSE;
704
+ }
705
+ if (prop)
706
+ OBJ_DROP_PROPERTY(cx, pobj, prop);
707
+
708
+ if (!js_LookupProperty(cx, obj,
709
+ ATOM_TO_JSID(cx->runtime->atomState.calleeAtom),
710
+ &pobj, &prop)) {
711
+ return JS_FALSE;
712
+ }
713
+ if (prop)
714
+ OBJ_DROP_PROPERTY(cx, pobj, prop);
715
+
716
+ argc = fp->argc;
717
+ for (slot = 0; slot < argc; slot++) {
718
+ if (!js_LookupProperty(cx, obj, INT_TO_JSID((jsint)slot), &pobj, &prop))
719
+ return JS_FALSE;
720
+ if (prop)
721
+ OBJ_DROP_PROPERTY(cx, pobj, prop);
722
+ }
723
+ return JS_TRUE;
724
+ }
725
+
726
+ #if JS_HAS_GENERATORS
727
+ /*
728
+ * If a generator-iterator's arguments or call object escapes, it needs to
729
+ * mark its generator object.
730
+ */
731
+ static void
732
+ args_or_call_trace(JSTracer *trc, JSObject *obj)
733
+ {
734
+ JSStackFrame *fp;
735
+
736
+ fp = (JSStackFrame *) JS_GetPrivate(trc->context, obj);
737
+ if (fp && (fp->flags & JSFRAME_GENERATOR)) {
738
+ JS_CALL_OBJECT_TRACER(trc, FRAME_TO_GENERATOR(fp)->obj,
739
+ "FRAME_TO_GENERATOR(fp)->obj");
740
+ }
741
+ }
742
+ #else
743
+ # define args_or_call_trace NULL
744
+ #endif
745
+
746
+ /*
747
+ * The Arguments class is not initialized via JS_InitClass, and must not be,
748
+ * because its name is "Object". Per ECMA, that causes instances of it to
749
+ * delegate to the object named by Object.prototype. It also ensures that
750
+ * arguments.toString() returns "[object Object]".
751
+ *
752
+ * The JSClass functions below collaborate to lazily reflect and synchronize
753
+ * actual argument values, argument count, and callee function object stored
754
+ * in a JSStackFrame with their corresponding property values in the frame's
755
+ * arguments object.
756
+ */
757
+ JSClass js_ArgumentsClass = {
758
+ js_Object_str,
759
+ JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE | JSCLASS_HAS_RESERVED_SLOTS(1) |
760
+ JSCLASS_MARK_IS_TRACE | JSCLASS_HAS_CACHED_PROTO(JSProto_Object),
761
+ JS_PropertyStub, args_delProperty,
762
+ args_getProperty, args_setProperty,
763
+ args_enumerate, (JSResolveOp) args_resolve,
764
+ JS_ConvertStub, JS_FinalizeStub,
765
+ NULL, NULL,
766
+ NULL, NULL,
767
+ NULL, NULL,
768
+ JS_CLASS_TRACE(args_or_call_trace), NULL
769
+ };
770
+
771
+ #define JSSLOT_CALLEE (JSSLOT_PRIVATE + 1)
772
+ #define JSSLOT_CALL_ARGUMENTS (JSSLOT_PRIVATE + 2)
773
+ #define CALL_CLASS_FIXED_RESERVED_SLOTS 2
774
+
775
+ /*
776
+ * A Declarative Environment object stores its active JSStackFrame pointer in
777
+ * its private slot, just as Call and Arguments objects do.
778
+ */
779
+ JSClass js_DeclEnvClass = {
780
+ js_Object_str,
781
+ JSCLASS_HAS_PRIVATE | JSCLASS_HAS_CACHED_PROTO(JSProto_Object),
782
+ JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
783
+ JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
784
+ JSCLASS_NO_OPTIONAL_MEMBERS
785
+ };
786
+
787
+ static JS_REQUIRES_STACK JSBool
788
+ CheckForEscapingClosure(JSContext *cx, JSObject *obj, jsval *vp)
789
+ {
790
+ JS_ASSERT(STOBJ_GET_CLASS(obj) == &js_CallClass ||
791
+ STOBJ_GET_CLASS(obj) == &js_DeclEnvClass);
792
+
793
+ jsval v = *vp;
794
+
795
+ if (VALUE_IS_FUNCTION(cx, v)) {
796
+ JSObject *funobj = JSVAL_TO_OBJECT(v);
797
+ JSFunction *fun = GET_FUNCTION_PRIVATE(cx, funobj);
798
+
799
+ /*
800
+ * Any escaping null or flat closure that reaches above itself or
801
+ * contains nested functions that reach above it must be wrapped.
802
+ * We can wrap only when this Call or Declarative Environment obj
803
+ * still has an active stack frame associated with it.
804
+ */
805
+ if (fun->needsWrapper()) {
806
+ JSStackFrame *fp = (JSStackFrame *) JS_GetPrivate(cx, obj);
807
+ if (fp) {
808
+ JSObject *wrapper = WrapEscapingClosure(cx, fp, funobj, fun);
809
+ if (!wrapper)
810
+ return false;
811
+ *vp = OBJECT_TO_JSVAL(wrapper);
812
+ return true;
813
+ }
814
+
815
+ JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
816
+ JSMSG_OPTIMIZED_CLOSURE_LEAK);
817
+ return false;
818
+ }
819
+ }
820
+ return true;
821
+ }
822
+
823
+ static JS_REQUIRES_STACK JSBool
824
+ CalleeGetter(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
825
+ {
826
+ return CheckForEscapingClosure(cx, obj, vp);
827
+ }
828
+
829
+ JSObject *
830
+ js_GetCallObject(JSContext *cx, JSStackFrame *fp)
831
+ {
832
+ JSObject *callobj;
833
+
834
+ /* Create a call object for fp only if it lacks one. */
835
+ JS_ASSERT(fp->fun);
836
+ callobj = fp->callobj;
837
+ if (callobj)
838
+ return callobj;
839
+
840
+ #ifdef DEBUG
841
+ /* A call object should be a frame's outermost scope chain element. */
842
+ JSClass *classp = OBJ_GET_CLASS(cx, fp->scopeChain);
843
+ if (classp == &js_WithClass || classp == &js_BlockClass || classp == &js_CallClass)
844
+ JS_ASSERT(OBJ_GET_PRIVATE(cx, fp->scopeChain) != fp);
845
+ #endif
846
+
847
+ /*
848
+ * Create the call object, using the frame's enclosing scope as its
849
+ * parent, and link the call to its stack frame. For a named function
850
+ * expression Call's parent points to an environment object holding
851
+ * function's name.
852
+ */
853
+ JSAtom *lambdaName = (fp->fun->flags & JSFUN_LAMBDA) ? fp->fun->atom : NULL;
854
+ if (lambdaName) {
855
+ JSObject *env = js_NewObjectWithGivenProto(cx, &js_DeclEnvClass, NULL,
856
+ fp->scopeChain, 0);
857
+ if (!env)
858
+ return NULL;
859
+ env->fslots[JSSLOT_PRIVATE] = PRIVATE_TO_JSVAL(fp);
860
+
861
+ /* Root env before js_DefineNativeProperty (-> JSClass.addProperty). */
862
+ fp->scopeChain = env;
863
+ if (!js_DefineNativeProperty(cx, fp->scopeChain, ATOM_TO_JSID(lambdaName),
864
+ OBJECT_TO_JSVAL(fp->callee),
865
+ CalleeGetter, NULL,
866
+ JSPROP_PERMANENT | JSPROP_READONLY,
867
+ 0, 0, NULL)) {
868
+ return NULL;
869
+ }
870
+ }
871
+
872
+ callobj = js_NewObjectWithGivenProto(cx, &js_CallClass, NULL,
873
+ fp->scopeChain, 0);
874
+ if (!callobj)
875
+ return NULL;
876
+
877
+ JS_SetPrivate(cx, callobj, fp);
878
+ JS_ASSERT(fp->fun == GET_FUNCTION_PRIVATE(cx, fp->callee));
879
+ STOBJ_SET_SLOT(callobj, JSSLOT_CALLEE, OBJECT_TO_JSVAL(fp->callee));
880
+ fp->callobj = callobj;
881
+
882
+ /*
883
+ * Push callobj on the top of the scope chain, and make it the
884
+ * variables object.
885
+ */
886
+ fp->scopeChain = callobj;
887
+ fp->varobj = callobj;
888
+ return callobj;
889
+ }
890
+
891
+ static JSFunction *
892
+ GetCallObjectFunction(JSObject *obj)
893
+ {
894
+ jsval v;
895
+
896
+ JS_ASSERT(STOBJ_GET_CLASS(obj) == &js_CallClass);
897
+ v = STOBJ_GET_SLOT(obj, JSSLOT_CALLEE);
898
+ if (JSVAL_IS_VOID(v)) {
899
+ /* Newborn or prototype object. */
900
+ return NULL;
901
+ }
902
+ JS_ASSERT(!JSVAL_IS_PRIMITIVE(v));
903
+ return GET_FUNCTION_PRIVATE(cx, JSVAL_TO_OBJECT(v));
904
+ }
905
+
906
+ JS_FRIEND_API(JSBool)
907
+ js_PutCallObject(JSContext *cx, JSStackFrame *fp)
908
+ {
909
+ JSObject *callobj;
910
+ JSBool ok;
911
+ JSFunction *fun;
912
+ uintN n;
913
+ JSScope *scope;
914
+
915
+ /*
916
+ * Since for a call object all fixed slots happen to be taken, we can copy
917
+ * arguments and variables straight into JSObject.dslots.
918
+ */
919
+ JS_STATIC_ASSERT(JS_INITIAL_NSLOTS - JSSLOT_PRIVATE ==
920
+ 1 + CALL_CLASS_FIXED_RESERVED_SLOTS);
921
+
922
+ callobj = fp->callobj;
923
+ if (!callobj)
924
+ return JS_TRUE;
925
+
926
+ /*
927
+ * Get the arguments object to snapshot fp's actual argument values.
928
+ */
929
+ ok = JS_TRUE;
930
+ if (fp->argsobj) {
931
+ if (!TEST_OVERRIDE_BIT(fp, CALL_ARGUMENTS)) {
932
+ STOBJ_SET_SLOT(callobj, JSSLOT_CALL_ARGUMENTS,
933
+ OBJECT_TO_JSVAL(fp->argsobj));
934
+ }
935
+ ok &= js_PutArgsObject(cx, fp);
936
+ }
937
+
938
+ fun = fp->fun;
939
+ JS_ASSERT(fun == GetCallObjectFunction(callobj));
940
+ n = fun->countArgsAndVars();
941
+ if (n != 0) {
942
+ JS_LOCK_OBJ(cx, callobj);
943
+ n += JS_INITIAL_NSLOTS;
944
+ if (n > STOBJ_NSLOTS(callobj))
945
+ ok &= js_ReallocSlots(cx, callobj, n, JS_TRUE);
946
+ scope = OBJ_SCOPE(callobj);
947
+ if (ok) {
948
+ memcpy(callobj->dslots, fp->argv, fun->nargs * sizeof(jsval));
949
+ memcpy(callobj->dslots + fun->nargs, fp->slots,
950
+ fun->u.i.nvars * sizeof(jsval));
951
+ if (scope->object == callobj && n > scope->freeslot)
952
+ scope->freeslot = n;
953
+ }
954
+ JS_UNLOCK_SCOPE(cx, scope);
955
+ }
956
+
957
+ /*
958
+ * Clear private pointers to fp, which is about to go away (js_Invoke).
959
+ * Do this last because js_GetProperty calls above need to follow the
960
+ * call object's private slot to find fp.
961
+ */
962
+ if ((fun->flags & JSFUN_LAMBDA) && fun->atom) {
963
+ JSObject *env = STOBJ_GET_PARENT(callobj);
964
+
965
+ JS_ASSERT(STOBJ_GET_CLASS(env) == &js_DeclEnvClass);
966
+ JS_ASSERT(STOBJ_GET_PRIVATE(env) == fp);
967
+ JS_SetPrivate(cx, env, NULL);
968
+ }
969
+
970
+ JS_SetPrivate(cx, callobj, NULL);
971
+ fp->callobj = NULL;
972
+ return ok;
973
+ }
974
+
975
+ static JSBool
976
+ call_enumerate(JSContext *cx, JSObject *obj)
977
+ {
978
+ JSFunction *fun;
979
+ uintN n, i;
980
+ void *mark;
981
+ jsuword *names;
982
+ JSBool ok;
983
+ JSAtom *name;
984
+ JSObject *pobj;
985
+ JSProperty *prop;
986
+
987
+ fun = GetCallObjectFunction(obj);
988
+ n = fun ? fun->countArgsAndVars() : 0;
989
+ if (n == 0)
990
+ return JS_TRUE;
991
+
992
+ mark = JS_ARENA_MARK(&cx->tempPool);
993
+
994
+ MUST_FLOW_THROUGH("out");
995
+ names = js_GetLocalNameArray(cx, fun, &cx->tempPool);
996
+ if (!names) {
997
+ ok = JS_FALSE;
998
+ goto out;
999
+ }
1000
+
1001
+ for (i = 0; i != n; ++i) {
1002
+ name = JS_LOCAL_NAME_TO_ATOM(names[i]);
1003
+ if (!name)
1004
+ continue;
1005
+
1006
+ /*
1007
+ * Trigger reflection by looking up the name of the argument or
1008
+ * variable.
1009
+ */
1010
+ ok = js_LookupProperty(cx, obj, ATOM_TO_JSID(name), &pobj, &prop);
1011
+ if (!ok)
1012
+ goto out;
1013
+
1014
+ /*
1015
+ * The call object will always have a property corresponding to the
1016
+ * argument or variable name because call_resolve creates the property
1017
+ * using JSPROP_PERMANENT.
1018
+ */
1019
+ JS_ASSERT(prop);
1020
+ JS_ASSERT(pobj == obj);
1021
+ OBJ_DROP_PROPERTY(cx, pobj, prop);
1022
+ }
1023
+ ok = JS_TRUE;
1024
+
1025
+ out:
1026
+ JS_ARENA_RELEASE(&cx->tempPool, mark);
1027
+ return ok;
1028
+ }
1029
+
1030
+ typedef enum JSCallPropertyKind {
1031
+ JSCPK_ARGUMENTS,
1032
+ JSCPK_ARG,
1033
+ JSCPK_VAR
1034
+ } JSCallPropertyKind;
1035
+
1036
+ static JSBool
1037
+ CallPropertyOp(JSContext *cx, JSObject *obj, jsid id, jsval *vp,
1038
+ JSCallPropertyKind kind, JSBool setter)
1039
+ {
1040
+ JSFunction *fun;
1041
+ JSStackFrame *fp;
1042
+ uintN i;
1043
+ jsval *array;
1044
+
1045
+ if (STOBJ_GET_CLASS(obj) != &js_CallClass)
1046
+ return JS_TRUE;
1047
+
1048
+ fun = GetCallObjectFunction(obj);
1049
+ fp = (JSStackFrame *) JS_GetPrivate(cx, obj);
1050
+
1051
+ if (kind == JSCPK_ARGUMENTS) {
1052
+ if (setter) {
1053
+ if (fp)
1054
+ SET_OVERRIDE_BIT(fp, CALL_ARGUMENTS);
1055
+ STOBJ_SET_SLOT(obj, JSSLOT_CALL_ARGUMENTS, *vp);
1056
+ } else {
1057
+ if (fp && !TEST_OVERRIDE_BIT(fp, CALL_ARGUMENTS)) {
1058
+ JSObject *argsobj;
1059
+
1060
+ argsobj = js_GetArgsObject(cx, fp);
1061
+ if (!argsobj)
1062
+ return JS_FALSE;
1063
+ *vp = OBJECT_TO_JSVAL(argsobj);
1064
+ } else {
1065
+ *vp = STOBJ_GET_SLOT(obj, JSSLOT_CALL_ARGUMENTS);
1066
+ }
1067
+ }
1068
+ return JS_TRUE;
1069
+ }
1070
+
1071
+ JS_ASSERT((int16) JSVAL_TO_INT(id) == JSVAL_TO_INT(id));
1072
+ i = (uint16) JSVAL_TO_INT(id);
1073
+ JS_ASSERT_IF(kind == JSCPK_ARG, i < fun->nargs);
1074
+ JS_ASSERT_IF(kind == JSCPK_VAR, i < fun->u.i.nvars);
1075
+
1076
+ if (!fp) {
1077
+ i += CALL_CLASS_FIXED_RESERVED_SLOTS;
1078
+ if (kind == JSCPK_VAR)
1079
+ i += fun->nargs;
1080
+ else
1081
+ JS_ASSERT(kind == JSCPK_ARG);
1082
+ return setter
1083
+ ? JS_SetReservedSlot(cx, obj, i, *vp)
1084
+ : JS_GetReservedSlot(cx, obj, i, vp);
1085
+ }
1086
+
1087
+ if (kind == JSCPK_ARG) {
1088
+ array = fp->argv;
1089
+ } else {
1090
+ JS_ASSERT(kind == JSCPK_VAR);
1091
+ array = fp->slots;
1092
+ }
1093
+ if (setter) {
1094
+ GC_POKE(cx, array[i]);
1095
+ array[i] = *vp;
1096
+ } else {
1097
+ *vp = array[i];
1098
+ }
1099
+ return JS_TRUE;
1100
+ }
1101
+
1102
+ static JSBool
1103
+ GetCallArguments(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
1104
+ {
1105
+ return CallPropertyOp(cx, obj, id, vp, JSCPK_ARGUMENTS, JS_FALSE);
1106
+ }
1107
+
1108
+ static JSBool
1109
+ SetCallArguments(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
1110
+ {
1111
+ return CallPropertyOp(cx, obj, id, vp, JSCPK_ARGUMENTS, JS_TRUE);
1112
+ }
1113
+
1114
+ JSBool
1115
+ js_GetCallArg(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
1116
+ {
1117
+ return CallPropertyOp(cx, obj, id, vp, JSCPK_ARG, JS_FALSE);
1118
+ }
1119
+
1120
+ static JSBool
1121
+ SetCallArg(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
1122
+ {
1123
+ return CallPropertyOp(cx, obj, id, vp, JSCPK_ARG, JS_TRUE);
1124
+ }
1125
+
1126
+ JSBool
1127
+ js_GetCallVar(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
1128
+ {
1129
+ return CallPropertyOp(cx, obj, id, vp, JSCPK_VAR, JS_FALSE);
1130
+ }
1131
+
1132
+ JSBool
1133
+ js_GetCallVarChecked(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
1134
+ {
1135
+ if (!CallPropertyOp(cx, obj, id, vp, JSCPK_VAR, JS_FALSE))
1136
+ return JS_FALSE;
1137
+
1138
+ return CheckForEscapingClosure(cx, obj, vp);
1139
+ }
1140
+
1141
+ static JSBool
1142
+ SetCallVar(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
1143
+ {
1144
+ return CallPropertyOp(cx, obj, id, vp, JSCPK_VAR, JS_TRUE);
1145
+ }
1146
+
1147
+ static JSBool
1148
+ call_resolve(JSContext *cx, JSObject *obj, jsval idval, uintN flags,
1149
+ JSObject **objp)
1150
+ {
1151
+ jsval callee;
1152
+ JSFunction *fun;
1153
+ jsid id;
1154
+ JSLocalKind localKind;
1155
+ JSPropertyOp getter, setter;
1156
+ uintN slot, attrs;
1157
+
1158
+ JS_ASSERT(STOBJ_GET_CLASS(obj) == &js_CallClass);
1159
+ JS_ASSERT(!STOBJ_GET_PROTO(obj));
1160
+
1161
+ if (!JSVAL_IS_STRING(idval))
1162
+ return JS_TRUE;
1163
+
1164
+ callee = STOBJ_GET_SLOT(obj, JSSLOT_CALLEE);
1165
+ if (JSVAL_IS_VOID(callee))
1166
+ return JS_TRUE;
1167
+ fun = GET_FUNCTION_PRIVATE(cx, JSVAL_TO_OBJECT(callee));
1168
+
1169
+ if (!js_ValueToStringId(cx, idval, &id))
1170
+ return JS_FALSE;
1171
+
1172
+ /*
1173
+ * Check whether the id refers to a formal parameter, local variable or
1174
+ * the arguments special name.
1175
+ *
1176
+ * We define all such names using JSDNP_DONT_PURGE to avoid an expensive
1177
+ * shape invalidation in js_DefineNativeProperty. If such an id happens to
1178
+ * shadow a global or upvar of the same name, any inner functions can
1179
+ * never access the outer binding. Thus it cannot invalidate any property
1180
+ * cache entries or derived trace guards for the outer binding. See also
1181
+ * comments in js_PurgeScopeChainHelper from jsobj.cpp.
1182
+ */
1183
+ localKind = js_LookupLocal(cx, fun, JSID_TO_ATOM(id), &slot);
1184
+ if (localKind != JSLOCAL_NONE && localKind != JSLOCAL_UPVAR) {
1185
+ JS_ASSERT((uint16) slot == slot);
1186
+
1187
+ /*
1188
+ * We follow 10.2.3 of ECMA 262 v3 and make argument and variable
1189
+ * properties of the Call objects enumerable.
1190
+ */
1191
+ attrs = JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_SHARED;
1192
+ if (localKind == JSLOCAL_ARG) {
1193
+ JS_ASSERT(slot < fun->nargs);
1194
+ getter = js_GetCallArg;
1195
+ setter = SetCallArg;
1196
+ } else {
1197
+ JS_ASSERT(localKind == JSLOCAL_VAR || localKind == JSLOCAL_CONST);
1198
+ JS_ASSERT(slot < fun->u.i.nvars);
1199
+ getter = js_GetCallVar;
1200
+ setter = SetCallVar;
1201
+ if (localKind == JSLOCAL_CONST)
1202
+ attrs |= JSPROP_READONLY;
1203
+
1204
+ /*
1205
+ * Use js_GetCallVarChecked if the local's value is a null closure.
1206
+ * This way we penalize performance only slightly on first use of a
1207
+ * null closure, not on every use.
1208
+ */
1209
+ jsval v;
1210
+ if (!CallPropertyOp(cx, obj, INT_TO_JSID((int16)slot), &v, JSCPK_VAR, JS_FALSE))
1211
+ return JS_FALSE;
1212
+ if (VALUE_IS_FUNCTION(cx, v) &&
1213
+ GET_FUNCTION_PRIVATE(cx, JSVAL_TO_OBJECT(v))->needsWrapper()) {
1214
+ getter = js_GetCallVarChecked;
1215
+ }
1216
+ }
1217
+ if (!js_DefineNativeProperty(cx, obj, id, JSVAL_VOID, getter, setter,
1218
+ attrs, SPROP_HAS_SHORTID, (int16) slot,
1219
+ NULL, JSDNP_DONT_PURGE)) {
1220
+ return JS_FALSE;
1221
+ }
1222
+ *objp = obj;
1223
+ return JS_TRUE;
1224
+ }
1225
+
1226
+ /*
1227
+ * Resolve arguments so that we never store a particular Call object's
1228
+ * arguments object reference in a Call prototype's |arguments| slot.
1229
+ */
1230
+ if (id == ATOM_TO_JSID(cx->runtime->atomState.argumentsAtom)) {
1231
+ if (!js_DefineNativeProperty(cx, obj, id, JSVAL_VOID,
1232
+ GetCallArguments, SetCallArguments,
1233
+ JSPROP_PERMANENT | JSPROP_SHARED,
1234
+ 0, 0, NULL, JSDNP_DONT_PURGE)) {
1235
+ return JS_FALSE;
1236
+ }
1237
+ *objp = obj;
1238
+ return JS_TRUE;
1239
+ }
1240
+
1241
+ /* Control flow reaches here only if id was not resolved. */
1242
+ return JS_TRUE;
1243
+ }
1244
+
1245
+ static JSBool
1246
+ call_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
1247
+ {
1248
+ JSStackFrame *fp;
1249
+
1250
+ if (type == JSTYPE_FUNCTION) {
1251
+ fp = (JSStackFrame *) JS_GetPrivate(cx, obj);
1252
+ if (fp) {
1253
+ JS_ASSERT(fp->fun);
1254
+ *vp = OBJECT_TO_JSVAL(fp->callee);
1255
+ }
1256
+ }
1257
+ return JS_TRUE;
1258
+ }
1259
+
1260
+ static uint32
1261
+ call_reserveSlots(JSContext *cx, JSObject *obj)
1262
+ {
1263
+ JSFunction *fun;
1264
+
1265
+ fun = GetCallObjectFunction(obj);
1266
+ return fun->countArgsAndVars();
1267
+ }
1268
+
1269
+ JS_FRIEND_DATA(JSClass) js_CallClass = {
1270
+ "Call",
1271
+ JSCLASS_HAS_PRIVATE |
1272
+ JSCLASS_HAS_RESERVED_SLOTS(CALL_CLASS_FIXED_RESERVED_SLOTS) |
1273
+ JSCLASS_NEW_RESOLVE | JSCLASS_IS_ANONYMOUS | JSCLASS_MARK_IS_TRACE,
1274
+ JS_PropertyStub, JS_PropertyStub,
1275
+ JS_PropertyStub, JS_PropertyStub,
1276
+ call_enumerate, (JSResolveOp)call_resolve,
1277
+ call_convert, JS_FinalizeStub,
1278
+ NULL, NULL,
1279
+ NULL, NULL,
1280
+ NULL, NULL,
1281
+ JS_CLASS_TRACE(args_or_call_trace), call_reserveSlots
1282
+ };
1283
+
1284
+ static JSBool
1285
+ fun_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
1286
+ {
1287
+ jsint slot;
1288
+ JSFunction *fun;
1289
+ JSStackFrame *fp;
1290
+ JSSecurityCallbacks *callbacks;
1291
+
1292
+ if (!JSVAL_IS_INT(id))
1293
+ return JS_TRUE;
1294
+ slot = JSVAL_TO_INT(id);
1295
+
1296
+ /*
1297
+ * Loop because getter and setter can be delegated from another class,
1298
+ * but loop only for ARGS_LENGTH because we must pretend that f.length
1299
+ * is in each function instance f, per ECMA-262, instead of only in the
1300
+ * Function.prototype object (we use JSPROP_PERMANENT with JSPROP_SHARED
1301
+ * to make it appear so).
1302
+ *
1303
+ * This code couples tightly to the attributes for the function_props[]
1304
+ * initializers above, and to js_SetProperty and js_HasOwnProperty.
1305
+ *
1306
+ * It's important to allow delegating objects, even though they inherit
1307
+ * this getter (fun_getProperty), to override arguments, arity, caller,
1308
+ * and name. If we didn't return early for slot != ARGS_LENGTH, we would
1309
+ * clobber *vp with the native property value, instead of letting script
1310
+ * override that value in delegating objects.
1311
+ *
1312
+ * Note how that clobbering is what simulates JSPROP_READONLY for all of
1313
+ * the non-standard properties when the directly addressed object (obj)
1314
+ * is a function object (i.e., when this loop does not iterate).
1315
+ */
1316
+ while (!(fun = (JSFunction *)
1317
+ JS_GetInstancePrivate(cx, obj, &js_FunctionClass, NULL))) {
1318
+ if (slot != ARGS_LENGTH)
1319
+ return JS_TRUE;
1320
+ obj = OBJ_GET_PROTO(cx, obj);
1321
+ if (!obj)
1322
+ return JS_TRUE;
1323
+ }
1324
+
1325
+ /* Find fun's top-most activation record. */
1326
+ for (fp = js_GetTopStackFrame(cx);
1327
+ fp && (fp->fun != fun || (fp->flags & JSFRAME_SPECIAL));
1328
+ fp = fp->down) {
1329
+ continue;
1330
+ }
1331
+
1332
+ switch (slot) {
1333
+ case CALL_ARGUMENTS:
1334
+ /* Warn if strict about f.arguments or equivalent unqualified uses. */
1335
+ if (!JS_ReportErrorFlagsAndNumber(cx,
1336
+ JSREPORT_WARNING | JSREPORT_STRICT,
1337
+ js_GetErrorMessage, NULL,
1338
+ JSMSG_DEPRECATED_USAGE,
1339
+ js_arguments_str)) {
1340
+ return JS_FALSE;
1341
+ }
1342
+ if (fp) {
1343
+ if (!js_GetArgsValue(cx, fp, vp))
1344
+ return JS_FALSE;
1345
+ } else {
1346
+ *vp = JSVAL_NULL;
1347
+ }
1348
+ break;
1349
+
1350
+ case ARGS_LENGTH:
1351
+ case FUN_ARITY:
1352
+ *vp = INT_TO_JSVAL((jsint)fun->nargs);
1353
+ break;
1354
+
1355
+ case FUN_NAME:
1356
+ *vp = fun->atom
1357
+ ? ATOM_KEY(fun->atom)
1358
+ : STRING_TO_JSVAL(cx->runtime->emptyString);
1359
+ break;
1360
+
1361
+ case FUN_CALLER:
1362
+ if (fp && fp->down && fp->down->fun) {
1363
+ JSFunction *caller = fp->down->fun;
1364
+ /*
1365
+ * See equivalent condition in args_getProperty for ARGS_CALLEE,
1366
+ * but here we do not want to throw, since this escape can happen
1367
+ * via foo.caller alone, without any debugger or indirect eval. And
1368
+ * it seems foo.caller is still used on the Web.
1369
+ */
1370
+ if (caller->needsWrapper()) {
1371
+ JSObject *wrapper = WrapEscapingClosure(cx, fp->down, FUN_OBJECT(caller), caller);
1372
+ if (!wrapper)
1373
+ return JS_FALSE;
1374
+ *vp = OBJECT_TO_JSVAL(wrapper);
1375
+ return JS_TRUE;
1376
+ }
1377
+
1378
+ *vp = OBJECT_TO_JSVAL(fp->down->callee);
1379
+ } else {
1380
+ *vp = JSVAL_NULL;
1381
+ }
1382
+ if (!JSVAL_IS_PRIMITIVE(*vp)) {
1383
+ callbacks = JS_GetSecurityCallbacks(cx);
1384
+ if (callbacks && callbacks->checkObjectAccess) {
1385
+ id = ATOM_KEY(cx->runtime->atomState.callerAtom);
1386
+ if (!callbacks->checkObjectAccess(cx, obj, id, JSACC_READ, vp))
1387
+ return JS_FALSE;
1388
+ }
1389
+ }
1390
+ break;
1391
+
1392
+ default:
1393
+ /* XXX fun[0] and fun.arguments[0] are equivalent. */
1394
+ if (fp && fp->fun && (uintN)slot < fp->fun->nargs)
1395
+ *vp = fp->argv[slot];
1396
+ break;
1397
+ }
1398
+
1399
+ return JS_TRUE;
1400
+ }
1401
+
1402
+ /*
1403
+ * ECMA-262 specifies that length is a property of function object instances,
1404
+ * but we can avoid that space cost by delegating to a prototype property that
1405
+ * is JSPROP_PERMANENT and JSPROP_SHARED. Each fun_getProperty call computes
1406
+ * a fresh length value based on the arity of the individual function object's
1407
+ * private data.
1408
+ *
1409
+ * The extensions below other than length, i.e., the ones not in ECMA-262,
1410
+ * are neither JSPROP_READONLY nor JSPROP_SHARED, because for compatibility
1411
+ * with ECMA we must allow a delegating object to override them. Therefore to
1412
+ * avoid entraining garbage in Function.prototype slots, they must be resolved
1413
+ * in non-prototype function objects, wherefore the lazy_function_props table
1414
+ * and fun_resolve's use of it.
1415
+ */
1416
+ #define LENGTH_PROP_ATTRS (JSPROP_READONLY|JSPROP_PERMANENT|JSPROP_SHARED)
1417
+
1418
+ static JSPropertySpec function_props[] = {
1419
+ {js_length_str, ARGS_LENGTH, LENGTH_PROP_ATTRS, fun_getProperty, JS_PropertyStub},
1420
+ {0,0,0,0,0}
1421
+ };
1422
+
1423
+ typedef struct LazyFunctionProp {
1424
+ uint16 atomOffset;
1425
+ int8 tinyid;
1426
+ uint8 attrs;
1427
+ } LazyFunctionProp;
1428
+
1429
+ /* NB: no sentinel at the end -- use JS_ARRAY_LENGTH to bound loops. */
1430
+ static LazyFunctionProp lazy_function_props[] = {
1431
+ {ATOM_OFFSET(arguments), CALL_ARGUMENTS, JSPROP_PERMANENT},
1432
+ {ATOM_OFFSET(arity), FUN_ARITY, JSPROP_PERMANENT},
1433
+ {ATOM_OFFSET(caller), FUN_CALLER, JSPROP_PERMANENT},
1434
+ {ATOM_OFFSET(name), FUN_NAME, JSPROP_PERMANENT},
1435
+ };
1436
+
1437
+ static JSBool
1438
+ fun_enumerate(JSContext *cx, JSObject *obj)
1439
+ {
1440
+ jsid prototypeId;
1441
+ JSObject *pobj;
1442
+ JSProperty *prop;
1443
+
1444
+ prototypeId = ATOM_TO_JSID(cx->runtime->atomState.classPrototypeAtom);
1445
+ if (!OBJ_LOOKUP_PROPERTY(cx, obj, prototypeId, &pobj, &prop))
1446
+ return JS_FALSE;
1447
+ if (prop)
1448
+ OBJ_DROP_PROPERTY(cx, pobj, prop);
1449
+ return JS_TRUE;
1450
+ }
1451
+
1452
+ static JSBool
1453
+ fun_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
1454
+ JSObject **objp)
1455
+ {
1456
+ JSFunction *fun;
1457
+ JSAtom *atom;
1458
+ uintN i;
1459
+
1460
+ if (!JSVAL_IS_STRING(id))
1461
+ return JS_TRUE;
1462
+
1463
+ fun = GET_FUNCTION_PRIVATE(cx, obj);
1464
+
1465
+ /*
1466
+ * No need to reflect fun.prototype in 'fun.prototype = ... '.
1467
+ */
1468
+ if (flags & JSRESOLVE_ASSIGNING)
1469
+ return JS_TRUE;
1470
+
1471
+ /*
1472
+ * Ok, check whether id is 'prototype' and bootstrap the function object's
1473
+ * prototype property.
1474
+ */
1475
+ atom = cx->runtime->atomState.classPrototypeAtom;
1476
+ if (id == ATOM_KEY(atom)) {
1477
+ JSObject *proto;
1478
+
1479
+ /*
1480
+ * Beware of the wacky case of a user function named Object -- trying
1481
+ * to find a prototype for that will recur back here _ad perniciem_.
1482
+ */
1483
+ if (fun->atom == CLASS_ATOM(cx, Object))
1484
+ return JS_TRUE;
1485
+
1486
+ /*
1487
+ * Make the prototype object to have the same parent as the function
1488
+ * object itself.
1489
+ */
1490
+ proto = js_NewObject(cx, &js_ObjectClass, NULL, OBJ_GET_PARENT(cx, obj),
1491
+ 0);
1492
+ if (!proto)
1493
+ return JS_FALSE;
1494
+
1495
+ /*
1496
+ * ECMA (15.3.5.2) says that constructor.prototype is DontDelete for
1497
+ * user-defined functions, but DontEnum | ReadOnly | DontDelete for
1498
+ * native "system" constructors such as Object or Function. So lazily
1499
+ * set the former here in fun_resolve, but eagerly define the latter
1500
+ * in JS_InitClass, with the right attributes.
1501
+ */
1502
+ if (!js_SetClassPrototype(cx, obj, proto,
1503
+ JSPROP_ENUMERATE | JSPROP_PERMANENT)) {
1504
+ cx->weakRoots.newborn[GCX_OBJECT] = NULL;
1505
+ return JS_FALSE;
1506
+ }
1507
+ *objp = obj;
1508
+ return JS_TRUE;
1509
+ }
1510
+
1511
+ for (i = 0; i < JS_ARRAY_LENGTH(lazy_function_props); i++) {
1512
+ LazyFunctionProp *lfp = &lazy_function_props[i];
1513
+
1514
+ atom = OFFSET_TO_ATOM(cx->runtime, lfp->atomOffset);
1515
+ if (id == ATOM_KEY(atom)) {
1516
+ if (!js_DefineNativeProperty(cx, obj,
1517
+ ATOM_TO_JSID(atom), JSVAL_VOID,
1518
+ fun_getProperty, JS_PropertyStub,
1519
+ lfp->attrs, SPROP_HAS_SHORTID,
1520
+ lfp->tinyid, NULL)) {
1521
+ return JS_FALSE;
1522
+ }
1523
+ *objp = obj;
1524
+ return JS_TRUE;
1525
+ }
1526
+ }
1527
+
1528
+ return JS_TRUE;
1529
+ }
1530
+
1531
+ static JSBool
1532
+ fun_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
1533
+ {
1534
+ switch (type) {
1535
+ case JSTYPE_FUNCTION:
1536
+ *vp = OBJECT_TO_JSVAL(obj);
1537
+ return JS_TRUE;
1538
+ default:
1539
+ return js_TryValueOf(cx, obj, type, vp);
1540
+ }
1541
+ }
1542
+
1543
+ #if JS_HAS_XDR
1544
+
1545
+ /* XXX store parent and proto, if defined */
1546
+ JSBool
1547
+ js_XDRFunctionObject(JSXDRState *xdr, JSObject **objp)
1548
+ {
1549
+ JSContext *cx;
1550
+ JSFunction *fun;
1551
+ uint32 firstword; /* flag telling whether fun->atom is non-null,
1552
+ plus for fun->u.i.skipmin, fun->u.i.wrapper,
1553
+ and 14 bits reserved for future use */
1554
+ uintN nargs, nvars, nupvars, n;
1555
+ uint32 localsword; /* word for argument and variable counts */
1556
+ uint32 flagsword; /* word for fun->u.i.nupvars and fun->flags */
1557
+ JSTempValueRooter tvr;
1558
+ JSBool ok;
1559
+
1560
+ cx = xdr->cx;
1561
+ if (xdr->mode == JSXDR_ENCODE) {
1562
+ fun = GET_FUNCTION_PRIVATE(cx, *objp);
1563
+ if (!FUN_INTERPRETED(fun)) {
1564
+ JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
1565
+ JSMSG_NOT_SCRIPTED_FUNCTION,
1566
+ JS_GetFunctionName(fun));
1567
+ return JS_FALSE;
1568
+ }
1569
+ if (fun->u.i.wrapper) {
1570
+ JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
1571
+ JSMSG_XDR_CLOSURE_WRAPPER,
1572
+ JS_GetFunctionName(fun));
1573
+ return JS_FALSE;
1574
+ }
1575
+ JS_ASSERT((fun->u.i.wrapper & ~1U) == 0);
1576
+ firstword = (fun->u.i.skipmin << 2) | (fun->u.i.wrapper << 1) | !!fun->atom;
1577
+ nargs = fun->nargs;
1578
+ nvars = fun->u.i.nvars;
1579
+ nupvars = fun->u.i.nupvars;
1580
+ localsword = (nargs << 16) | nvars;
1581
+ flagsword = (nupvars << 16) | fun->flags;
1582
+ } else {
1583
+ fun = js_NewFunction(cx, NULL, NULL, 0, JSFUN_INTERPRETED, NULL, NULL);
1584
+ if (!fun)
1585
+ return JS_FALSE;
1586
+ STOBJ_CLEAR_PARENT(FUN_OBJECT(fun));
1587
+ STOBJ_CLEAR_PROTO(FUN_OBJECT(fun));
1588
+ #ifdef __GNUC__
1589
+ nvars = nargs = nupvars = 0; /* quell GCC uninitialized warning */
1590
+ #endif
1591
+ }
1592
+
1593
+ /* From here on, control flow must flow through label out. */
1594
+ MUST_FLOW_THROUGH("out");
1595
+ JS_PUSH_TEMP_ROOT_OBJECT(cx, FUN_OBJECT(fun), &tvr);
1596
+ ok = JS_TRUE;
1597
+
1598
+ if (!JS_XDRUint32(xdr, &firstword))
1599
+ goto bad;
1600
+ if ((firstword & 1U) && !js_XDRStringAtom(xdr, &fun->atom))
1601
+ goto bad;
1602
+ if (!JS_XDRUint32(xdr, &localsword) ||
1603
+ !JS_XDRUint32(xdr, &flagsword)) {
1604
+ goto bad;
1605
+ }
1606
+
1607
+ if (xdr->mode == JSXDR_DECODE) {
1608
+ nargs = localsword >> 16;
1609
+ nvars = uint16(localsword);
1610
+ JS_ASSERT((flagsword & JSFUN_KINDMASK) >= JSFUN_INTERPRETED);
1611
+ nupvars = flagsword >> 16;
1612
+ fun->flags = uint16(flagsword);
1613
+ fun->u.i.skipmin = uint16(firstword >> 2);
1614
+ fun->u.i.wrapper = (firstword >> 1) & 1;
1615
+ }
1616
+
1617
+ /* do arguments and local vars */
1618
+ n = nargs + nvars + nupvars;
1619
+ if (n != 0) {
1620
+ void *mark;
1621
+ uintN i;
1622
+ uintN bitmapLength;
1623
+ uint32 *bitmap;
1624
+ jsuword *names;
1625
+ JSAtom *name;
1626
+ JSLocalKind localKind;
1627
+
1628
+ mark = JS_ARENA_MARK(&xdr->cx->tempPool);
1629
+
1630
+ /*
1631
+ * From this point the control must flow via the label release_mark.
1632
+ *
1633
+ * To xdr the names we prefix the names with a bitmap descriptor and
1634
+ * then xdr the names as strings. For argument names (indexes below
1635
+ * nargs) the corresponding bit in the bitmap is unset when the name
1636
+ * is null. Such null names are not encoded or decoded. For variable
1637
+ * names (indexes starting from nargs) bitmap's bit is set when the
1638
+ * name is declared as const, not as ordinary var.
1639
+ * */
1640
+ MUST_FLOW_THROUGH("release_mark");
1641
+ bitmapLength = JS_HOWMANY(n, JS_BITS_PER_UINT32);
1642
+ JS_ARENA_ALLOCATE_CAST(bitmap, uint32 *, &xdr->cx->tempPool,
1643
+ bitmapLength * sizeof *bitmap);
1644
+ if (!bitmap) {
1645
+ js_ReportOutOfScriptQuota(xdr->cx);
1646
+ ok = JS_FALSE;
1647
+ goto release_mark;
1648
+ }
1649
+ if (xdr->mode == JSXDR_ENCODE) {
1650
+ names = js_GetLocalNameArray(xdr->cx, fun, &xdr->cx->tempPool);
1651
+ if (!names) {
1652
+ ok = JS_FALSE;
1653
+ goto release_mark;
1654
+ }
1655
+ memset(bitmap, 0, bitmapLength * sizeof *bitmap);
1656
+ for (i = 0; i != n; ++i) {
1657
+ if (i < fun->nargs
1658
+ ? JS_LOCAL_NAME_TO_ATOM(names[i]) != NULL
1659
+ : JS_LOCAL_NAME_IS_CONST(names[i])) {
1660
+ bitmap[i >> JS_BITS_PER_UINT32_LOG2] |=
1661
+ JS_BIT(i & (JS_BITS_PER_UINT32 - 1));
1662
+ }
1663
+ }
1664
+ }
1665
+ #ifdef __GNUC__
1666
+ else {
1667
+ names = NULL; /* quell GCC uninitialized warning */
1668
+ }
1669
+ #endif
1670
+ for (i = 0; i != bitmapLength; ++i) {
1671
+ ok = JS_XDRUint32(xdr, &bitmap[i]);
1672
+ if (!ok)
1673
+ goto release_mark;
1674
+ }
1675
+ for (i = 0; i != n; ++i) {
1676
+ if (i < nargs &&
1677
+ !(bitmap[i >> JS_BITS_PER_UINT32_LOG2] &
1678
+ JS_BIT(i & (JS_BITS_PER_UINT32 - 1)))) {
1679
+ if (xdr->mode == JSXDR_DECODE) {
1680
+ ok = js_AddLocal(xdr->cx, fun, NULL, JSLOCAL_ARG);
1681
+ if (!ok)
1682
+ goto release_mark;
1683
+ } else {
1684
+ JS_ASSERT(!JS_LOCAL_NAME_TO_ATOM(names[i]));
1685
+ }
1686
+ continue;
1687
+ }
1688
+ if (xdr->mode == JSXDR_ENCODE)
1689
+ name = JS_LOCAL_NAME_TO_ATOM(names[i]);
1690
+ ok = js_XDRStringAtom(xdr, &name);
1691
+ if (!ok)
1692
+ goto release_mark;
1693
+ if (xdr->mode == JSXDR_DECODE) {
1694
+ localKind = (i < nargs)
1695
+ ? JSLOCAL_ARG
1696
+ : (i < nargs + nvars)
1697
+ ? (bitmap[i >> JS_BITS_PER_UINT32_LOG2] &
1698
+ JS_BIT(i & (JS_BITS_PER_UINT32 - 1))
1699
+ ? JSLOCAL_CONST
1700
+ : JSLOCAL_VAR)
1701
+ : JSLOCAL_UPVAR;
1702
+ ok = js_AddLocal(xdr->cx, fun, name, localKind);
1703
+ if (!ok)
1704
+ goto release_mark;
1705
+ }
1706
+ }
1707
+ ok = JS_TRUE;
1708
+
1709
+ release_mark:
1710
+ JS_ARENA_RELEASE(&xdr->cx->tempPool, mark);
1711
+ if (!ok)
1712
+ goto out;
1713
+
1714
+ if (xdr->mode == JSXDR_DECODE)
1715
+ js_FreezeLocalNames(cx, fun);
1716
+ }
1717
+
1718
+ if (!js_XDRScript(xdr, &fun->u.i.script, NULL))
1719
+ goto bad;
1720
+
1721
+ if (xdr->mode == JSXDR_DECODE) {
1722
+ *objp = FUN_OBJECT(fun);
1723
+ #ifdef CHECK_SCRIPT_OWNER
1724
+ fun->u.i.script->owner = NULL;
1725
+ #endif
1726
+ js_CallNewScriptHook(cx, fun->u.i.script, fun);
1727
+ }
1728
+
1729
+ out:
1730
+ JS_POP_TEMP_ROOT(cx, &tvr);
1731
+ return ok;
1732
+
1733
+ bad:
1734
+ ok = JS_FALSE;
1735
+ goto out;
1736
+ }
1737
+
1738
+ #else /* !JS_HAS_XDR */
1739
+
1740
+ #define js_XDRFunctionObject NULL
1741
+
1742
+ #endif /* !JS_HAS_XDR */
1743
+
1744
+ /*
1745
+ * [[HasInstance]] internal method for Function objects: fetch the .prototype
1746
+ * property of its 'this' parameter, and walks the prototype chain of v (only
1747
+ * if v is an object) returning true if .prototype is found.
1748
+ */
1749
+ static JSBool
1750
+ fun_hasInstance(JSContext *cx, JSObject *obj, jsval v, JSBool *bp)
1751
+ {
1752
+ jsval pval;
1753
+
1754
+ if (!OBJ_GET_PROPERTY(cx, obj,
1755
+ ATOM_TO_JSID(cx->runtime->atomState
1756
+ .classPrototypeAtom),
1757
+ &pval)) {
1758
+ return JS_FALSE;
1759
+ }
1760
+
1761
+ if (JSVAL_IS_PRIMITIVE(pval)) {
1762
+ /*
1763
+ * Throw a runtime error if instanceof is called on a function that
1764
+ * has a non-object as its .prototype value.
1765
+ */
1766
+ js_ReportValueError(cx, JSMSG_BAD_PROTOTYPE,
1767
+ -1, OBJECT_TO_JSVAL(obj), NULL);
1768
+ return JS_FALSE;
1769
+ }
1770
+
1771
+ return js_IsDelegate(cx, JSVAL_TO_OBJECT(pval), v, bp);
1772
+ }
1773
+
1774
+ static void
1775
+ TraceLocalNames(JSTracer *trc, JSFunction *fun);
1776
+
1777
+ static void
1778
+ DestroyLocalNames(JSContext *cx, JSFunction *fun);
1779
+
1780
+ static void
1781
+ fun_trace(JSTracer *trc, JSObject *obj)
1782
+ {
1783
+ JSFunction *fun;
1784
+
1785
+ /* A newborn function object may have a not yet initialized private slot. */
1786
+ fun = (JSFunction *) JS_GetPrivate(trc->context, obj);
1787
+ if (!fun)
1788
+ return;
1789
+
1790
+ if (FUN_OBJECT(fun) != obj) {
1791
+ /* obj is cloned function object, trace the original. */
1792
+ JS_CALL_TRACER(trc, FUN_OBJECT(fun), JSTRACE_OBJECT, "private");
1793
+ return;
1794
+ }
1795
+ if (fun->atom)
1796
+ JS_CALL_STRING_TRACER(trc, ATOM_TO_STRING(fun->atom), "atom");
1797
+ if (FUN_INTERPRETED(fun)) {
1798
+ if (fun->u.i.script)
1799
+ js_TraceScript(trc, fun->u.i.script);
1800
+ TraceLocalNames(trc, fun);
1801
+ }
1802
+ }
1803
+
1804
+ static void
1805
+ fun_finalize(JSContext *cx, JSObject *obj)
1806
+ {
1807
+ JSFunction *fun;
1808
+
1809
+ /* Ignore newborn and cloned function objects. */
1810
+ fun = (JSFunction *) JS_GetPrivate(cx, obj);
1811
+ if (!fun || FUN_OBJECT(fun) != obj)
1812
+ return;
1813
+
1814
+ /*
1815
+ * Null-check of u.i.script is required since the parser sets interpreted
1816
+ * very early.
1817
+ */
1818
+ if (FUN_INTERPRETED(fun)) {
1819
+ if (fun->u.i.script)
1820
+ js_DestroyScript(cx, fun->u.i.script);
1821
+ DestroyLocalNames(cx, fun);
1822
+ }
1823
+ }
1824
+
1825
+ static uint32
1826
+ fun_reserveSlots(JSContext *cx, JSObject *obj)
1827
+ {
1828
+ JSFunction *fun;
1829
+ uint32 nslots;
1830
+
1831
+ /*
1832
+ * We use JS_GetPrivate and not GET_FUNCTION_PRIVATE because during
1833
+ * js_InitFunctionClass invocation the function is called before the
1834
+ * private slot of the function object is set.
1835
+ */
1836
+ fun = (JSFunction *) JS_GetPrivate(cx, obj);
1837
+ nslots = 0;
1838
+ if (fun && FUN_INTERPRETED(fun) && fun->u.i.script) {
1839
+ if (fun->u.i.nupvars != 0)
1840
+ nslots = JS_SCRIPT_UPVARS(fun->u.i.script)->length;
1841
+ if (fun->u.i.script->regexpsOffset != 0)
1842
+ nslots += JS_SCRIPT_REGEXPS(fun->u.i.script)->length;
1843
+ }
1844
+ return nslots;
1845
+ }
1846
+
1847
+ /*
1848
+ * Reserve two slots in all function objects for XPConnect. Note that this
1849
+ * does not bloat every instance, only those on which reserved slots are set,
1850
+ * and those on which ad-hoc properties are defined.
1851
+ */
1852
+ JS_FRIEND_DATA(JSClass) js_FunctionClass = {
1853
+ js_Function_str,
1854
+ JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE | JSCLASS_HAS_RESERVED_SLOTS(2) |
1855
+ JSCLASS_MARK_IS_TRACE | JSCLASS_HAS_CACHED_PROTO(JSProto_Function),
1856
+ JS_PropertyStub, JS_PropertyStub,
1857
+ JS_PropertyStub, JS_PropertyStub,
1858
+ fun_enumerate, (JSResolveOp)fun_resolve,
1859
+ fun_convert, fun_finalize,
1860
+ NULL, NULL,
1861
+ NULL, NULL,
1862
+ js_XDRFunctionObject, fun_hasInstance,
1863
+ JS_CLASS_TRACE(fun_trace), fun_reserveSlots
1864
+ };
1865
+
1866
+ static JSBool
1867
+ fun_toStringHelper(JSContext *cx, uint32 indent, uintN argc, jsval *vp)
1868
+ {
1869
+ jsval fval;
1870
+ JSObject *obj;
1871
+ JSFunction *fun;
1872
+ JSString *str;
1873
+
1874
+ fval = JS_THIS(cx, vp);
1875
+ if (JSVAL_IS_NULL(fval))
1876
+ return JS_FALSE;
1877
+
1878
+ if (!VALUE_IS_FUNCTION(cx, fval)) {
1879
+ /*
1880
+ * If we don't have a function to start off with, try converting the
1881
+ * object to a function. If that doesn't work, complain.
1882
+ */
1883
+ if (!JSVAL_IS_PRIMITIVE(fval)) {
1884
+ obj = JSVAL_TO_OBJECT(fval);
1885
+ if (!OBJ_GET_CLASS(cx, obj)->convert(cx, obj, JSTYPE_FUNCTION,
1886
+ &fval)) {
1887
+ return JS_FALSE;
1888
+ }
1889
+ vp[1] = fval;
1890
+ }
1891
+ if (!VALUE_IS_FUNCTION(cx, fval)) {
1892
+ JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
1893
+ JSMSG_INCOMPATIBLE_PROTO,
1894
+ js_Function_str, js_toString_str,
1895
+ JS_GetTypeName(cx, JS_TypeOfValue(cx, fval)));
1896
+ return JS_FALSE;
1897
+ }
1898
+ }
1899
+
1900
+ obj = JSVAL_TO_OBJECT(fval);
1901
+ if (argc != 0) {
1902
+ indent = js_ValueToECMAUint32(cx, &vp[2]);
1903
+ if (JSVAL_IS_NULL(vp[2]))
1904
+ return JS_FALSE;
1905
+ }
1906
+
1907
+ JS_ASSERT(JS_ObjectIsFunction(cx, obj));
1908
+ fun = GET_FUNCTION_PRIVATE(cx, obj);
1909
+ if (!fun)
1910
+ return JS_TRUE;
1911
+ str = JS_DecompileFunction(cx, fun, (uintN)indent);
1912
+ if (!str)
1913
+ return JS_FALSE;
1914
+ *vp = STRING_TO_JSVAL(str);
1915
+ return JS_TRUE;
1916
+ }
1917
+
1918
+ static JSBool
1919
+ fun_toString(JSContext *cx, uintN argc, jsval *vp)
1920
+ {
1921
+ return fun_toStringHelper(cx, 0, argc, vp);
1922
+ }
1923
+
1924
+ #if JS_HAS_TOSOURCE
1925
+ static JSBool
1926
+ fun_toSource(JSContext *cx, uintN argc, jsval *vp)
1927
+ {
1928
+ return fun_toStringHelper(cx, JS_DONT_PRETTY_PRINT, argc, vp);
1929
+ }
1930
+ #endif
1931
+
1932
+ JS_REQUIRES_STACK JSBool
1933
+ js_fun_call(JSContext *cx, uintN argc, jsval *vp)
1934
+ {
1935
+ JSObject *obj;
1936
+ jsval fval, *argv, *invokevp;
1937
+ JSString *str;
1938
+ void *mark;
1939
+ JSBool ok;
1940
+
1941
+ obj = JS_THIS_OBJECT(cx, vp);
1942
+ if (!obj || !OBJ_DEFAULT_VALUE(cx, obj, JSTYPE_FUNCTION, &vp[1]))
1943
+ return JS_FALSE;
1944
+ fval = vp[1];
1945
+
1946
+ if (!VALUE_IS_FUNCTION(cx, fval)) {
1947
+ str = JS_ValueToString(cx, fval);
1948
+ if (str) {
1949
+ const char *bytes = js_GetStringBytes(cx, str);
1950
+
1951
+ if (bytes) {
1952
+ JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
1953
+ JSMSG_INCOMPATIBLE_PROTO,
1954
+ js_Function_str, js_call_str,
1955
+ bytes);
1956
+ }
1957
+ }
1958
+ return JS_FALSE;
1959
+ }
1960
+
1961
+ argv = vp + 2;
1962
+ if (argc == 0) {
1963
+ /* Call fun with its global object as the 'this' param if no args. */
1964
+ obj = NULL;
1965
+ } else {
1966
+ /* Otherwise convert the first arg to 'this' and skip over it. */
1967
+ if (!JSVAL_IS_PRIMITIVE(argv[0]))
1968
+ obj = JSVAL_TO_OBJECT(argv[0]);
1969
+ else if (!js_ValueToObject(cx, argv[0], &obj))
1970
+ return JS_FALSE;
1971
+ argc--;
1972
+ argv++;
1973
+ }
1974
+
1975
+ /* Allocate stack space for fval, obj, and the args. */
1976
+ invokevp = js_AllocStack(cx, 2 + argc, &mark);
1977
+ if (!invokevp)
1978
+ return JS_FALSE;
1979
+
1980
+ /* Push fval, obj, and the args. */
1981
+ invokevp[0] = fval;
1982
+ invokevp[1] = OBJECT_TO_JSVAL(obj);
1983
+ memcpy(invokevp + 2, argv, argc * sizeof *argv);
1984
+
1985
+ ok = js_Invoke(cx, argc, invokevp, 0);
1986
+ *vp = *invokevp;
1987
+ js_FreeStack(cx, mark);
1988
+ return ok;
1989
+ }
1990
+
1991
+ JS_REQUIRES_STACK JSBool
1992
+ js_fun_apply(JSContext *cx, uintN argc, jsval *vp)
1993
+ {
1994
+ JSObject *obj, *aobj;
1995
+ jsval fval, *invokevp, *sp;
1996
+ JSString *str;
1997
+ jsuint length;
1998
+ JSBool arraylike, ok;
1999
+ void *mark;
2000
+ uintN i;
2001
+
2002
+ if (argc == 0) {
2003
+ /* Will get globalObject as 'this' and no other arguments. */
2004
+ return js_fun_call(cx, argc, vp);
2005
+ }
2006
+
2007
+ obj = JS_THIS_OBJECT(cx, vp);
2008
+ if (!obj || !OBJ_DEFAULT_VALUE(cx, obj, JSTYPE_FUNCTION, &vp[1]))
2009
+ return JS_FALSE;
2010
+ fval = vp[1];
2011
+
2012
+ if (!VALUE_IS_FUNCTION(cx, fval)) {
2013
+ str = JS_ValueToString(cx, fval);
2014
+ if (str) {
2015
+ const char *bytes = js_GetStringBytes(cx, str);
2016
+
2017
+ if (bytes) {
2018
+ JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
2019
+ JSMSG_INCOMPATIBLE_PROTO,
2020
+ js_Function_str, js_apply_str,
2021
+ bytes);
2022
+ }
2023
+ }
2024
+ return JS_FALSE;
2025
+ }
2026
+
2027
+ /* Quell GCC overwarnings. */
2028
+ aobj = NULL;
2029
+ length = 0;
2030
+
2031
+ if (argc >= 2) {
2032
+ /* If the 2nd arg is null or void, call the function with 0 args. */
2033
+ if (JSVAL_IS_NULL(vp[3]) || JSVAL_IS_VOID(vp[3])) {
2034
+ argc = 0;
2035
+ } else {
2036
+ /* The second arg must be an array (or arguments object). */
2037
+ arraylike = JS_FALSE;
2038
+ if (!JSVAL_IS_PRIMITIVE(vp[3])) {
2039
+ aobj = JSVAL_TO_OBJECT(vp[3]);
2040
+ if (!js_IsArrayLike(cx, aobj, &arraylike, &length))
2041
+ return JS_FALSE;
2042
+ }
2043
+ if (!arraylike) {
2044
+ JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
2045
+ JSMSG_BAD_APPLY_ARGS, js_apply_str);
2046
+ return JS_FALSE;
2047
+ }
2048
+ }
2049
+ }
2050
+
2051
+ /* Convert the first arg to 'this' and skip over it. */
2052
+ if (!JSVAL_IS_PRIMITIVE(vp[2]))
2053
+ obj = JSVAL_TO_OBJECT(vp[2]);
2054
+ else if (!js_ValueToObject(cx, vp[2], &obj))
2055
+ return JS_FALSE;
2056
+
2057
+ /* Allocate stack space for fval, obj, and the args. */
2058
+ argc = (uintN)JS_MIN(length, ARRAY_INIT_LIMIT - 1);
2059
+ invokevp = js_AllocStack(cx, 2 + argc, &mark);
2060
+ if (!invokevp)
2061
+ return JS_FALSE;
2062
+
2063
+ /* Push fval, obj, and aobj's elements as args. */
2064
+ sp = invokevp;
2065
+ *sp++ = fval;
2066
+ *sp++ = OBJECT_TO_JSVAL(obj);
2067
+ for (i = 0; i < argc; i++) {
2068
+ ok = JS_GetElement(cx, aobj, (jsint)i, sp);
2069
+ if (!ok)
2070
+ goto out;
2071
+ sp++;
2072
+ }
2073
+
2074
+ ok = js_Invoke(cx, argc, invokevp, 0);
2075
+ *vp = *invokevp;
2076
+ out:
2077
+ js_FreeStack(cx, mark);
2078
+ return ok;
2079
+ }
2080
+
2081
+ #ifdef NARCISSUS
2082
+ static JS_REQUIRES_STACK JSBool
2083
+ fun_applyConstructor(JSContext *cx, uintN argc, jsval *vp)
2084
+ {
2085
+ JSObject *aobj;
2086
+ uintN length, i;
2087
+ void *mark;
2088
+ jsval *invokevp, *sp;
2089
+ JSBool ok;
2090
+
2091
+ if (JSVAL_IS_PRIMITIVE(vp[2]) ||
2092
+ (aobj = JSVAL_TO_OBJECT(vp[2]),
2093
+ OBJ_GET_CLASS(cx, aobj) != &js_ArrayClass &&
2094
+ OBJ_GET_CLASS(cx, aobj) != &js_ArgumentsClass)) {
2095
+ JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
2096
+ JSMSG_BAD_APPLY_ARGS, "__applyConstruct__");
2097
+ return JS_FALSE;
2098
+ }
2099
+
2100
+ if (!js_GetLengthProperty(cx, aobj, &length))
2101
+ return JS_FALSE;
2102
+
2103
+ if (length >= ARRAY_INIT_LIMIT)
2104
+ length = ARRAY_INIT_LIMIT - 1;
2105
+ invokevp = js_AllocStack(cx, 2 + length, &mark);
2106
+ if (!invokevp)
2107
+ return JS_FALSE;
2108
+
2109
+ sp = invokevp;
2110
+ *sp++ = vp[1];
2111
+ *sp++ = JSVAL_NULL; /* this is filled automagically */
2112
+ for (i = 0; i < length; i++) {
2113
+ ok = JS_GetElement(cx, aobj, (jsint)i, sp);
2114
+ if (!ok)
2115
+ goto out;
2116
+ sp++;
2117
+ }
2118
+
2119
+ ok = js_InvokeConstructor(cx, length, JS_TRUE, invokevp);
2120
+ *vp = *invokevp;
2121
+ out:
2122
+ js_FreeStack(cx, mark);
2123
+ return ok;
2124
+ }
2125
+ #endif
2126
+
2127
+ static JSFunctionSpec function_methods[] = {
2128
+ #if JS_HAS_TOSOURCE
2129
+ JS_FN(js_toSource_str, fun_toSource, 0,0),
2130
+ #endif
2131
+ JS_FN(js_toString_str, fun_toString, 0,0),
2132
+ JS_FN(js_apply_str, js_fun_apply, 2,0),
2133
+ JS_FN(js_call_str, js_fun_call, 1,0),
2134
+ #ifdef NARCISSUS
2135
+ JS_FN("__applyConstructor__", fun_applyConstructor, 1,0),
2136
+ #endif
2137
+ JS_FS_END
2138
+ };
2139
+
2140
+ static JSBool
2141
+ Function(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2142
+ {
2143
+ JSFunction *fun;
2144
+ JSObject *parent;
2145
+ JSStackFrame *fp, *caller;
2146
+ uintN i, n, lineno;
2147
+ JSAtom *atom;
2148
+ const char *filename;
2149
+ JSBool ok;
2150
+ JSString *str, *arg;
2151
+ JSTokenStream ts;
2152
+ JSPrincipals *principals;
2153
+ jschar *collected_args, *cp;
2154
+ void *mark;
2155
+ size_t arg_length, args_length, old_args_length;
2156
+ JSTokenType tt;
2157
+
2158
+ if (!JS_IsConstructing(cx)) {
2159
+ obj = js_NewObject(cx, &js_FunctionClass, NULL, NULL, 0);
2160
+ if (!obj)
2161
+ return JS_FALSE;
2162
+ *rval = OBJECT_TO_JSVAL(obj);
2163
+ } else {
2164
+ /*
2165
+ * The constructor is called before the private slot is initialized so
2166
+ * we must use JS_GetPrivate, not GET_FUNCTION_PRIVATE here.
2167
+ */
2168
+ if (JS_GetPrivate(cx, obj))
2169
+ return JS_TRUE;
2170
+ }
2171
+
2172
+ /*
2173
+ * NB: (new Function) is not lexically closed by its caller, it's just an
2174
+ * anonymous function in the top-level scope that its constructor inhabits.
2175
+ * Thus 'var x = 42; f = new Function("return x"); print(f())' prints 42,
2176
+ * and so would a call to f from another top-level's script or function.
2177
+ *
2178
+ * In older versions, before call objects, a new Function was adopted by
2179
+ * its running context's globalObject, which might be different from the
2180
+ * top-level reachable from scopeChain (in HTML frames, e.g.).
2181
+ */
2182
+ parent = OBJ_GET_PARENT(cx, JSVAL_TO_OBJECT(argv[-2]));
2183
+
2184
+ fun = js_NewFunction(cx, obj, NULL, 0, JSFUN_LAMBDA | JSFUN_INTERPRETED,
2185
+ parent, cx->runtime->atomState.anonymousAtom);
2186
+
2187
+ if (!fun)
2188
+ return JS_FALSE;
2189
+
2190
+ /*
2191
+ * Function is static and not called directly by other functions in this
2192
+ * file, therefore it is callable only as a native function by js_Invoke.
2193
+ * Find the scripted caller, possibly skipping other native frames such as
2194
+ * are built for Function.prototype.call or .apply activations that invoke
2195
+ * Function indirectly from a script.
2196
+ */
2197
+ fp = js_GetTopStackFrame(cx);
2198
+ JS_ASSERT(!fp->script && fp->fun && fp->fun->u.n.native == Function);
2199
+ caller = js_GetScriptedCaller(cx, fp);
2200
+ if (caller) {
2201
+ principals = JS_EvalFramePrincipals(cx, fp, caller);
2202
+ filename = js_ComputeFilename(cx, caller, principals, &lineno);
2203
+ } else {
2204
+ filename = NULL;
2205
+ lineno = 0;
2206
+ principals = NULL;
2207
+ }
2208
+
2209
+ /* Belt-and-braces: check that the caller has access to parent. */
2210
+ if (!js_CheckPrincipalsAccess(cx, parent, principals,
2211
+ CLASS_ATOM(cx, Function))) {
2212
+ return JS_FALSE;
2213
+ }
2214
+
2215
+ n = argc ? argc - 1 : 0;
2216
+ if (n > 0) {
2217
+ enum { OK, BAD, BAD_FORMAL } state;
2218
+
2219
+ /*
2220
+ * Collect the function-argument arguments into one string, separated
2221
+ * by commas, then make a tokenstream from that string, and scan it to
2222
+ * get the arguments. We need to throw the full scanner at the
2223
+ * problem, because the argument string can legitimately contain
2224
+ * comments and linefeeds. XXX It might be better to concatenate
2225
+ * everything up into a function definition and pass it to the
2226
+ * compiler, but doing it this way is less of a delta from the old
2227
+ * code. See ECMA 15.3.2.1.
2228
+ */
2229
+ state = BAD_FORMAL;
2230
+ args_length = 0;
2231
+ for (i = 0; i < n; i++) {
2232
+ /* Collect the lengths for all the function-argument arguments. */
2233
+ arg = js_ValueToString(cx, argv[i]);
2234
+ if (!arg)
2235
+ return JS_FALSE;
2236
+ argv[i] = STRING_TO_JSVAL(arg);
2237
+
2238
+ /*
2239
+ * Check for overflow. The < test works because the maximum
2240
+ * JSString length fits in 2 fewer bits than size_t has.
2241
+ */
2242
+ old_args_length = args_length;
2243
+ args_length = old_args_length + JSSTRING_LENGTH(arg);
2244
+ if (args_length < old_args_length) {
2245
+ js_ReportAllocationOverflow(cx);
2246
+ return JS_FALSE;
2247
+ }
2248
+ }
2249
+
2250
+ /* Add 1 for each joining comma and check for overflow (two ways). */
2251
+ old_args_length = args_length;
2252
+ args_length = old_args_length + n - 1;
2253
+ if (args_length < old_args_length ||
2254
+ args_length >= ~(size_t)0 / sizeof(jschar)) {
2255
+ js_ReportAllocationOverflow(cx);
2256
+ return JS_FALSE;
2257
+ }
2258
+
2259
+ /*
2260
+ * Allocate a string to hold the concatenated arguments, including room
2261
+ * for a terminating 0. Mark cx->tempPool for later release, to free
2262
+ * collected_args and its tokenstream in one swoop.
2263
+ */
2264
+ mark = JS_ARENA_MARK(&cx->tempPool);
2265
+ JS_ARENA_ALLOCATE_CAST(cp, jschar *, &cx->tempPool,
2266
+ (args_length+1) * sizeof(jschar));
2267
+ if (!cp) {
2268
+ js_ReportOutOfScriptQuota(cx);
2269
+ return JS_FALSE;
2270
+ }
2271
+ collected_args = cp;
2272
+
2273
+ /*
2274
+ * Concatenate the arguments into the new string, separated by commas.
2275
+ */
2276
+ for (i = 0; i < n; i++) {
2277
+ arg = JSVAL_TO_STRING(argv[i]);
2278
+ arg_length = JSSTRING_LENGTH(arg);
2279
+ (void) js_strncpy(cp, JSSTRING_CHARS(arg), arg_length);
2280
+ cp += arg_length;
2281
+
2282
+ /* Add separating comma or terminating 0. */
2283
+ *cp++ = (i + 1 < n) ? ',' : 0;
2284
+ }
2285
+
2286
+ /* Initialize a tokenstream that reads from the given string. */
2287
+ if (!js_InitTokenStream(cx, &ts, collected_args, args_length,
2288
+ NULL, filename, lineno)) {
2289
+ JS_ARENA_RELEASE(&cx->tempPool, mark);
2290
+ return JS_FALSE;
2291
+ }
2292
+
2293
+ /* The argument string may be empty or contain no tokens. */
2294
+ tt = js_GetToken(cx, &ts);
2295
+ if (tt != TOK_EOF) {
2296
+ for (;;) {
2297
+ /*
2298
+ * Check that it's a name. This also implicitly guards against
2299
+ * TOK_ERROR, which was already reported.
2300
+ */
2301
+ if (tt != TOK_NAME)
2302
+ goto after_args;
2303
+
2304
+ /*
2305
+ * Get the atom corresponding to the name from the token
2306
+ * stream; we're assured at this point that it's a valid
2307
+ * identifier.
2308
+ */
2309
+ atom = CURRENT_TOKEN(&ts).t_atom;
2310
+
2311
+ /* Check for a duplicate parameter name. */
2312
+ if (js_LookupLocal(cx, fun, atom, NULL) != JSLOCAL_NONE) {
2313
+ const char *name;
2314
+
2315
+ name = js_AtomToPrintableString(cx, atom);
2316
+ ok = name &&
2317
+ js_ReportCompileErrorNumber(cx, &ts, NULL,
2318
+ JSREPORT_WARNING |
2319
+ JSREPORT_STRICT,
2320
+ JSMSG_DUPLICATE_FORMAL,
2321
+ name);
2322
+ if (!ok)
2323
+ goto after_args;
2324
+ }
2325
+ if (!js_AddLocal(cx, fun, atom, JSLOCAL_ARG))
2326
+ goto after_args;
2327
+
2328
+ /*
2329
+ * Get the next token. Stop on end of stream. Otherwise
2330
+ * insist on a comma, get another name, and iterate.
2331
+ */
2332
+ tt = js_GetToken(cx, &ts);
2333
+ if (tt == TOK_EOF)
2334
+ break;
2335
+ if (tt != TOK_COMMA)
2336
+ goto after_args;
2337
+ tt = js_GetToken(cx, &ts);
2338
+ }
2339
+ }
2340
+
2341
+ state = OK;
2342
+ after_args:
2343
+ if (state == BAD_FORMAL && !(ts.flags & TSF_ERROR)) {
2344
+ /*
2345
+ * Report "malformed formal parameter" iff no illegal char or
2346
+ * similar scanner error was already reported.
2347
+ */
2348
+ JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
2349
+ JSMSG_BAD_FORMAL);
2350
+ }
2351
+ js_CloseTokenStream(cx, &ts);
2352
+ JS_ARENA_RELEASE(&cx->tempPool, mark);
2353
+ if (state != OK)
2354
+ return JS_FALSE;
2355
+ }
2356
+
2357
+ if (argc) {
2358
+ str = js_ValueToString(cx, argv[argc-1]);
2359
+ if (!str)
2360
+ return JS_FALSE;
2361
+ argv[argc-1] = STRING_TO_JSVAL(str);
2362
+ } else {
2363
+ str = cx->runtime->emptyString;
2364
+ }
2365
+
2366
+ return JSCompiler::compileFunctionBody(cx, fun, principals,
2367
+ JSSTRING_CHARS(str), JSSTRING_LENGTH(str),
2368
+ filename, lineno);
2369
+ }
2370
+
2371
+ JSObject *
2372
+ js_InitFunctionClass(JSContext *cx, JSObject *obj)
2373
+ {
2374
+ JSObject *proto;
2375
+ JSFunction *fun;
2376
+
2377
+ proto = JS_InitClass(cx, obj, NULL, &js_FunctionClass, Function, 1,
2378
+ function_props, function_methods, NULL, NULL);
2379
+ if (!proto)
2380
+ return NULL;
2381
+ fun = js_NewFunction(cx, proto, NULL, 0, JSFUN_INTERPRETED, obj, NULL);
2382
+ if (!fun)
2383
+ goto bad;
2384
+ fun->u.i.script = js_NewScript(cx, 1, 1, 0, 0, 0, 0, 0);
2385
+ if (!fun->u.i.script)
2386
+ goto bad;
2387
+ fun->u.i.script->code[0] = JSOP_STOP;
2388
+ *SCRIPT_NOTES(fun->u.i.script) = SRC_NULL;
2389
+ #ifdef CHECK_SCRIPT_OWNER
2390
+ fun->u.i.script->owner = NULL;
2391
+ #endif
2392
+ return proto;
2393
+
2394
+ bad:
2395
+ cx->weakRoots.newborn[GCX_OBJECT] = NULL;
2396
+ return NULL;
2397
+ }
2398
+
2399
+ JSFunction *
2400
+ js_NewFunction(JSContext *cx, JSObject *funobj, JSNative native, uintN nargs,
2401
+ uintN flags, JSObject *parent, JSAtom *atom)
2402
+ {
2403
+ JSFunction *fun;
2404
+
2405
+ if (funobj) {
2406
+ JS_ASSERT(HAS_FUNCTION_CLASS(funobj));
2407
+ OBJ_SET_PARENT(cx, funobj, parent);
2408
+ } else {
2409
+ funobj = js_NewObject(cx, &js_FunctionClass, NULL, parent, 0);
2410
+ if (!funobj)
2411
+ return NULL;
2412
+ }
2413
+ JS_ASSERT(JSVAL_IS_VOID(funobj->fslots[JSSLOT_PRIVATE]));
2414
+ fun = (JSFunction *) funobj;
2415
+
2416
+ /* Initialize all function members. */
2417
+ fun->nargs = nargs;
2418
+ fun->flags = flags & (JSFUN_FLAGS_MASK | JSFUN_KINDMASK | JSFUN_TRACEABLE);
2419
+ if ((flags & JSFUN_KINDMASK) >= JSFUN_INTERPRETED) {
2420
+ JS_ASSERT(!native);
2421
+ JS_ASSERT(nargs == 0);
2422
+ fun->u.i.nvars = 0;
2423
+ fun->u.i.nupvars = 0;
2424
+ fun->u.i.skipmin = 0;
2425
+ fun->u.i.wrapper = false;
2426
+ fun->u.i.script = NULL;
2427
+ #ifdef DEBUG
2428
+ fun->u.i.names.taggedAtom = 0;
2429
+ #endif
2430
+ } else {
2431
+ fun->u.n.extra = 0;
2432
+ fun->u.n.spare = 0;
2433
+ fun->u.n.clasp = NULL;
2434
+ if (flags & JSFUN_TRACEABLE) {
2435
+ #ifdef JS_TRACER
2436
+ JSTraceableNative *trcinfo =
2437
+ JS_FUNC_TO_DATA_PTR(JSTraceableNative *, native);
2438
+ fun->u.n.native = (JSNative) trcinfo->native;
2439
+ fun->u.n.trcinfo = trcinfo;
2440
+ #else
2441
+ fun->u.n.trcinfo = NULL;
2442
+ #endif
2443
+ } else {
2444
+ fun->u.n.native = native;
2445
+ fun->u.n.trcinfo = NULL;
2446
+ }
2447
+ JS_ASSERT(fun->u.n.native);
2448
+ }
2449
+ fun->atom = atom;
2450
+
2451
+ /* Set private to self to indicate non-cloned fully initialized function. */
2452
+ FUN_OBJECT(fun)->fslots[JSSLOT_PRIVATE] = PRIVATE_TO_JSVAL(fun);
2453
+ return fun;
2454
+ }
2455
+
2456
+ JSObject *
2457
+ js_CloneFunctionObject(JSContext *cx, JSFunction *fun, JSObject *parent)
2458
+ {
2459
+ /*
2460
+ * The cloned function object does not need the extra JSFunction members
2461
+ * beyond JSObject as it points to fun via the private slot.
2462
+ */
2463
+ JSObject *clone = js_NewObject(cx, &js_FunctionClass, NULL, parent,
2464
+ sizeof(JSObject));
2465
+ if (!clone)
2466
+ return NULL;
2467
+ clone->fslots[JSSLOT_PRIVATE] = PRIVATE_TO_JSVAL(fun);
2468
+ return clone;
2469
+ }
2470
+
2471
+ JSObject *
2472
+ js_NewFlatClosure(JSContext *cx, JSFunction *fun)
2473
+ {
2474
+ JS_ASSERT(FUN_FLAT_CLOSURE(fun));
2475
+
2476
+ JSObject *closure = js_CloneFunctionObject(cx, fun, cx->fp->scopeChain);
2477
+ if (!closure || fun->u.i.script->upvarsOffset == 0)
2478
+ return closure;
2479
+
2480
+ uint32 nslots = JSSLOT_FREE(&js_FunctionClass);
2481
+ JS_ASSERT(nslots == JS_INITIAL_NSLOTS);
2482
+ nslots += fun_reserveSlots(cx, closure);
2483
+ if (!js_ReallocSlots(cx, closure, nslots, JS_TRUE))
2484
+ return NULL;
2485
+
2486
+ JSUpvarArray *uva = JS_SCRIPT_UPVARS(fun->u.i.script);
2487
+ JS_ASSERT(uva->length <= size_t(closure->dslots[-1]));
2488
+
2489
+ uintN level = fun->u.i.script->staticLevel;
2490
+ for (uint32 i = 0, n = uva->length; i < n; i++)
2491
+ closure->dslots[i] = js_GetUpvar(cx, level, uva->vector[i]);
2492
+
2493
+ return closure;
2494
+ }
2495
+
2496
+ JSObject *
2497
+ js_NewDebuggableFlatClosure(JSContext *cx, JSFunction *fun)
2498
+ {
2499
+ JS_ASSERT(cx->fp->fun->flags & JSFUN_HEAVYWEIGHT);
2500
+ JS_ASSERT(!cx->fp->fun->optimizedClosure());
2501
+
2502
+ return WrapEscapingClosure(cx, cx->fp, FUN_OBJECT(fun), fun);
2503
+ }
2504
+
2505
+ JSFunction *
2506
+ js_DefineFunction(JSContext *cx, JSObject *obj, JSAtom *atom, JSNative native,
2507
+ uintN nargs, uintN attrs)
2508
+ {
2509
+ JSPropertyOp gsop;
2510
+ JSFunction *fun;
2511
+
2512
+ if (attrs & JSFUN_STUB_GSOPS) {
2513
+ /*
2514
+ * JSFUN_STUB_GSOPS is a request flag only, not stored in fun->flags or
2515
+ * the defined property's attributes. This allows us to encode another,
2516
+ * internal flag using the same bit, JSFUN_EXPR_CLOSURE -- see jsfun.h
2517
+ * for more on this.
2518
+ */
2519
+ attrs &= ~JSFUN_STUB_GSOPS;
2520
+ gsop = JS_PropertyStub;
2521
+ } else {
2522
+ gsop = NULL;
2523
+ }
2524
+ fun = js_NewFunction(cx, NULL, native, nargs, attrs, obj, atom);
2525
+ if (!fun)
2526
+ return NULL;
2527
+ if (!OBJ_DEFINE_PROPERTY(cx, obj, ATOM_TO_JSID(atom),
2528
+ OBJECT_TO_JSVAL(FUN_OBJECT(fun)),
2529
+ gsop, gsop,
2530
+ attrs & ~JSFUN_FLAGS_MASK, NULL)) {
2531
+ return NULL;
2532
+ }
2533
+ return fun;
2534
+ }
2535
+
2536
+ #if (JSV2F_CONSTRUCT & JSV2F_SEARCH_STACK)
2537
+ # error "JSINVOKE_CONSTRUCT and JSV2F_SEARCH_STACK are not disjoint!"
2538
+ #endif
2539
+
2540
+ JSFunction *
2541
+ js_ValueToFunction(JSContext *cx, jsval *vp, uintN flags)
2542
+ {
2543
+ jsval v;
2544
+ JSObject *obj;
2545
+
2546
+ v = *vp;
2547
+ obj = NULL;
2548
+ if (JSVAL_IS_OBJECT(v)) {
2549
+ obj = JSVAL_TO_OBJECT(v);
2550
+ if (obj && OBJ_GET_CLASS(cx, obj) != &js_FunctionClass) {
2551
+ if (!OBJ_DEFAULT_VALUE(cx, obj, JSTYPE_FUNCTION, &v))
2552
+ return NULL;
2553
+ obj = VALUE_IS_FUNCTION(cx, v) ? JSVAL_TO_OBJECT(v) : NULL;
2554
+ }
2555
+ }
2556
+ if (!obj) {
2557
+ js_ReportIsNotFunction(cx, vp, flags);
2558
+ return NULL;
2559
+ }
2560
+ return GET_FUNCTION_PRIVATE(cx, obj);
2561
+ }
2562
+
2563
+ JSObject *
2564
+ js_ValueToFunctionObject(JSContext *cx, jsval *vp, uintN flags)
2565
+ {
2566
+ JSFunction *fun;
2567
+ JSStackFrame *caller;
2568
+ JSPrincipals *principals;
2569
+
2570
+ if (VALUE_IS_FUNCTION(cx, *vp))
2571
+ return JSVAL_TO_OBJECT(*vp);
2572
+
2573
+ fun = js_ValueToFunction(cx, vp, flags);
2574
+ if (!fun)
2575
+ return NULL;
2576
+ *vp = OBJECT_TO_JSVAL(FUN_OBJECT(fun));
2577
+
2578
+ caller = js_GetScriptedCaller(cx, NULL);
2579
+ if (caller) {
2580
+ principals = JS_StackFramePrincipals(cx, caller);
2581
+ } else {
2582
+ /* No scripted caller, don't allow access. */
2583
+ principals = NULL;
2584
+ }
2585
+
2586
+ if (!js_CheckPrincipalsAccess(cx, FUN_OBJECT(fun), principals,
2587
+ fun->atom
2588
+ ? fun->atom
2589
+ : cx->runtime->atomState.anonymousAtom)) {
2590
+ return NULL;
2591
+ }
2592
+ return FUN_OBJECT(fun);
2593
+ }
2594
+
2595
+ JSObject *
2596
+ js_ValueToCallableObject(JSContext *cx, jsval *vp, uintN flags)
2597
+ {
2598
+ JSObject *callable = JSVAL_IS_OBJECT(*vp) ? JSVAL_TO_OBJECT(*vp) : NULL;
2599
+
2600
+ if (callable && js_IsCallable(callable, cx)) {
2601
+ *vp = OBJECT_TO_JSVAL(callable);
2602
+ return callable;
2603
+ }
2604
+ return js_ValueToFunctionObject(cx, vp, flags);
2605
+ }
2606
+
2607
+ void
2608
+ js_ReportIsNotFunction(JSContext *cx, jsval *vp, uintN flags)
2609
+ {
2610
+ JSStackFrame *fp;
2611
+ uintN error;
2612
+ const char *name, *source;
2613
+ JSTempValueRooter tvr;
2614
+
2615
+ for (fp = js_GetTopStackFrame(cx); fp && !fp->regs; fp = fp->down)
2616
+ continue;
2617
+ name = source = NULL;
2618
+ JS_PUSH_TEMP_ROOT_STRING(cx, NULL, &tvr);
2619
+ if (flags & JSV2F_ITERATOR) {
2620
+ error = JSMSG_BAD_ITERATOR;
2621
+ name = js_iterator_str;
2622
+ tvr.u.string = js_ValueToSource(cx, *vp);
2623
+ if (!tvr.u.string)
2624
+ goto out;
2625
+ tvr.u.string = js_QuoteString(cx, tvr.u.string, 0);
2626
+ if (!tvr.u.string)
2627
+ goto out;
2628
+ source = js_GetStringBytes(cx, tvr.u.string);
2629
+ if (!source)
2630
+ goto out;
2631
+ } else if (flags & JSV2F_CONSTRUCT) {
2632
+ error = JSMSG_NOT_CONSTRUCTOR;
2633
+ } else {
2634
+ error = JSMSG_NOT_FUNCTION;
2635
+ }
2636
+
2637
+ js_ReportValueError3(cx, error,
2638
+ (fp && fp->regs &&
2639
+ StackBase(fp) <= vp && vp < fp->regs->sp)
2640
+ ? vp - fp->regs->sp
2641
+ : (flags & JSV2F_SEARCH_STACK)
2642
+ ? JSDVG_SEARCH_STACK
2643
+ : JSDVG_IGNORE_STACK,
2644
+ *vp, NULL,
2645
+ name, source);
2646
+
2647
+ out:
2648
+ JS_POP_TEMP_ROOT(cx, &tvr);
2649
+ }
2650
+
2651
+ /*
2652
+ * When a function has between 2 and MAX_ARRAY_LOCALS arguments and variables,
2653
+ * their name are stored as the JSLocalNames.array.
2654
+ */
2655
+ #define MAX_ARRAY_LOCALS 8
2656
+
2657
+ JS_STATIC_ASSERT(2 <= MAX_ARRAY_LOCALS);
2658
+ JS_STATIC_ASSERT(MAX_ARRAY_LOCALS < JS_BITMASK(16));
2659
+
2660
+ /*
2661
+ * We use the lowest bit of the string atom to distinguish const from var
2662
+ * name when there is only single name or when names are stored as an array.
2663
+ */
2664
+ JS_STATIC_ASSERT((JSVAL_STRING & 1) == 0);
2665
+
2666
+ /*
2667
+ * When we use a hash table to store the local names, we use a singly linked
2668
+ * list to record the indexes of duplicated parameter names to preserve the
2669
+ * duplicates for the decompiler.
2670
+ */
2671
+ typedef struct JSNameIndexPair JSNameIndexPair;
2672
+
2673
+ struct JSNameIndexPair {
2674
+ JSAtom *name;
2675
+ uint16 index;
2676
+ JSNameIndexPair *link;
2677
+ };
2678
+
2679
+ struct JSLocalNameMap {
2680
+ JSDHashTable names;
2681
+ JSNameIndexPair *lastdup;
2682
+ };
2683
+
2684
+ typedef struct JSLocalNameHashEntry {
2685
+ JSDHashEntryHdr hdr;
2686
+ JSAtom *name;
2687
+ uint16 index;
2688
+ uint8 localKind;
2689
+ } JSLocalNameHashEntry;
2690
+
2691
+ static void
2692
+ FreeLocalNameHash(JSContext *cx, JSLocalNameMap *map)
2693
+ {
2694
+ JSNameIndexPair *dup, *next;
2695
+
2696
+ for (dup = map->lastdup; dup; dup = next) {
2697
+ next = dup->link;
2698
+ JS_free(cx, dup);
2699
+ }
2700
+ JS_DHashTableFinish(&map->names);
2701
+ JS_free(cx, map);
2702
+ }
2703
+
2704
+ static JSBool
2705
+ HashLocalName(JSContext *cx, JSLocalNameMap *map, JSAtom *name,
2706
+ JSLocalKind localKind, uintN index)
2707
+ {
2708
+ JSLocalNameHashEntry *entry;
2709
+ JSNameIndexPair *dup;
2710
+
2711
+ JS_ASSERT(index <= JS_BITMASK(16));
2712
+ #if JS_HAS_DESTRUCTURING
2713
+ if (!name) {
2714
+ /* A destructuring pattern does not need a hash entry. */
2715
+ JS_ASSERT(localKind == JSLOCAL_ARG);
2716
+ return JS_TRUE;
2717
+ }
2718
+ #endif
2719
+ JS_ASSERT(ATOM_IS_STRING(name));
2720
+ entry = (JSLocalNameHashEntry *)
2721
+ JS_DHashTableOperate(&map->names, name, JS_DHASH_ADD);
2722
+ if (!entry) {
2723
+ JS_ReportOutOfMemory(cx);
2724
+ return JS_FALSE;
2725
+ }
2726
+ if (entry->name) {
2727
+ JS_ASSERT(entry->name == name);
2728
+ JS_ASSERT(entry->localKind == JSLOCAL_ARG);
2729
+ dup = (JSNameIndexPair *) JS_malloc(cx, sizeof *dup);
2730
+ if (!dup)
2731
+ return JS_FALSE;
2732
+ dup->name = entry->name;
2733
+ dup->index = entry->index;
2734
+ dup->link = map->lastdup;
2735
+ map->lastdup = dup;
2736
+ }
2737
+ entry->name = name;
2738
+ entry->index = (uint16) index;
2739
+ entry->localKind = (uint8) localKind;
2740
+ return JS_TRUE;
2741
+ }
2742
+
2743
+ JSBool
2744
+ js_AddLocal(JSContext *cx, JSFunction *fun, JSAtom *atom, JSLocalKind kind)
2745
+ {
2746
+ jsuword taggedAtom;
2747
+ uint16 *indexp;
2748
+ uintN n, i;
2749
+ jsuword *array;
2750
+ JSLocalNameMap *map;
2751
+
2752
+ JS_ASSERT(FUN_INTERPRETED(fun));
2753
+ JS_ASSERT(!fun->u.i.script);
2754
+ JS_ASSERT(((jsuword) atom & 1) == 0);
2755
+ taggedAtom = (jsuword) atom;
2756
+ if (kind == JSLOCAL_ARG) {
2757
+ indexp = &fun->nargs;
2758
+ } else if (kind == JSLOCAL_UPVAR) {
2759
+ indexp = &fun->u.i.nupvars;
2760
+ } else {
2761
+ indexp = &fun->u.i.nvars;
2762
+ if (kind == JSLOCAL_CONST)
2763
+ taggedAtom |= 1;
2764
+ else
2765
+ JS_ASSERT(kind == JSLOCAL_VAR);
2766
+ }
2767
+ n = fun->countLocalNames();
2768
+ if (n == 0) {
2769
+ JS_ASSERT(fun->u.i.names.taggedAtom == 0);
2770
+ fun->u.i.names.taggedAtom = taggedAtom;
2771
+ } else if (n < MAX_ARRAY_LOCALS) {
2772
+ if (n > 1) {
2773
+ array = fun->u.i.names.array;
2774
+ } else {
2775
+ array = (jsuword *) JS_malloc(cx, MAX_ARRAY_LOCALS * sizeof *array);
2776
+ if (!array)
2777
+ return JS_FALSE;
2778
+ array[0] = fun->u.i.names.taggedAtom;
2779
+ fun->u.i.names.array = array;
2780
+ }
2781
+ if (kind == JSLOCAL_ARG) {
2782
+ /*
2783
+ * A destructuring argument pattern adds variables, not arguments,
2784
+ * so for the following arguments nvars != 0.
2785
+ */
2786
+ #if JS_HAS_DESTRUCTURING
2787
+ if (fun->u.i.nvars != 0) {
2788
+ memmove(array + fun->nargs + 1, array + fun->nargs,
2789
+ fun->u.i.nvars * sizeof *array);
2790
+ }
2791
+ #else
2792
+ JS_ASSERT(fun->u.i.nvars == 0);
2793
+ #endif
2794
+ array[fun->nargs] = taggedAtom;
2795
+ } else {
2796
+ array[n] = taggedAtom;
2797
+ }
2798
+ } else if (n == MAX_ARRAY_LOCALS) {
2799
+ array = fun->u.i.names.array;
2800
+ map = (JSLocalNameMap *) JS_malloc(cx, sizeof *map);
2801
+ if (!map)
2802
+ return JS_FALSE;
2803
+ if (!JS_DHashTableInit(&map->names, JS_DHashGetStubOps(),
2804
+ NULL, sizeof(JSLocalNameHashEntry),
2805
+ JS_DHASH_DEFAULT_CAPACITY(MAX_ARRAY_LOCALS
2806
+ * 2))) {
2807
+ JS_ReportOutOfMemory(cx);
2808
+ JS_free(cx, map);
2809
+ return JS_FALSE;
2810
+ }
2811
+
2812
+ map->lastdup = NULL;
2813
+ for (i = 0; i != MAX_ARRAY_LOCALS; ++i) {
2814
+ taggedAtom = array[i];
2815
+ uintN j = i;
2816
+ JSLocalKind k = JSLOCAL_ARG;
2817
+ if (j >= fun->nargs) {
2818
+ j -= fun->nargs;
2819
+ if (j < fun->u.i.nvars) {
2820
+ k = (taggedAtom & 1) ? JSLOCAL_CONST : JSLOCAL_VAR;
2821
+ } else {
2822
+ j -= fun->u.i.nvars;
2823
+ k = JSLOCAL_UPVAR;
2824
+ }
2825
+ }
2826
+ if (!HashLocalName(cx, map, (JSAtom *) (taggedAtom & ~1), k, j)) {
2827
+ FreeLocalNameHash(cx, map);
2828
+ return JS_FALSE;
2829
+ }
2830
+ }
2831
+ if (!HashLocalName(cx, map, atom, kind, *indexp)) {
2832
+ FreeLocalNameHash(cx, map);
2833
+ return JS_FALSE;
2834
+ }
2835
+
2836
+ /*
2837
+ * At this point the entry is added and we cannot fail. It is time
2838
+ * to replace fun->u.i.names with the built map.
2839
+ */
2840
+ fun->u.i.names.map = map;
2841
+ JS_free(cx, array);
2842
+ } else {
2843
+ if (*indexp == JS_BITMASK(16)) {
2844
+ JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
2845
+ (kind == JSLOCAL_ARG)
2846
+ ? JSMSG_TOO_MANY_FUN_ARGS
2847
+ : JSMSG_TOO_MANY_LOCALS);
2848
+ return JS_FALSE;
2849
+ }
2850
+ if (!HashLocalName(cx, fun->u.i.names.map, atom, kind, *indexp))
2851
+ return JS_FALSE;
2852
+ }
2853
+
2854
+ /* Update the argument or variable counter. */
2855
+ ++*indexp;
2856
+ return JS_TRUE;
2857
+ }
2858
+
2859
+ JSLocalKind
2860
+ js_LookupLocal(JSContext *cx, JSFunction *fun, JSAtom *atom, uintN *indexp)
2861
+ {
2862
+ uintN n, i, upvar_base;
2863
+ jsuword *array;
2864
+ JSLocalNameHashEntry *entry;
2865
+
2866
+ JS_ASSERT(FUN_INTERPRETED(fun));
2867
+ n = fun->countLocalNames();
2868
+ if (n == 0)
2869
+ return JSLOCAL_NONE;
2870
+ if (n <= MAX_ARRAY_LOCALS) {
2871
+ array = (n == 1) ? &fun->u.i.names.taggedAtom : fun->u.i.names.array;
2872
+
2873
+ /* Search from the tail to pick up the last duplicated name. */
2874
+ i = n;
2875
+ upvar_base = fun->countArgsAndVars();
2876
+ do {
2877
+ --i;
2878
+ if (atom == JS_LOCAL_NAME_TO_ATOM(array[i])) {
2879
+ if (i < fun->nargs) {
2880
+ if (indexp)
2881
+ *indexp = i;
2882
+ return JSLOCAL_ARG;
2883
+ }
2884
+ if (i >= upvar_base) {
2885
+ if (indexp)
2886
+ *indexp = i - upvar_base;
2887
+ return JSLOCAL_UPVAR;
2888
+ }
2889
+ if (indexp)
2890
+ *indexp = i - fun->nargs;
2891
+ return JS_LOCAL_NAME_IS_CONST(array[i])
2892
+ ? JSLOCAL_CONST
2893
+ : JSLOCAL_VAR;
2894
+ }
2895
+ } while (i != 0);
2896
+ } else {
2897
+ entry = (JSLocalNameHashEntry *)
2898
+ JS_DHashTableOperate(&fun->u.i.names.map->names, atom,
2899
+ JS_DHASH_LOOKUP);
2900
+ if (JS_DHASH_ENTRY_IS_BUSY(&entry->hdr)) {
2901
+ JS_ASSERT(entry->localKind != JSLOCAL_NONE);
2902
+ if (indexp)
2903
+ *indexp = entry->index;
2904
+ return (JSLocalKind) entry->localKind;
2905
+ }
2906
+ }
2907
+ return JSLOCAL_NONE;
2908
+ }
2909
+
2910
+ typedef struct JSLocalNameEnumeratorArgs {
2911
+ JSFunction *fun;
2912
+ jsuword *names;
2913
+ #ifdef DEBUG
2914
+ uintN nCopiedArgs;
2915
+ uintN nCopiedVars;
2916
+ #endif
2917
+ } JSLocalNameEnumeratorArgs;
2918
+
2919
+ static JSDHashOperator
2920
+ get_local_names_enumerator(JSDHashTable *table, JSDHashEntryHdr *hdr,
2921
+ uint32 number, void *arg)
2922
+ {
2923
+ JSLocalNameHashEntry *entry;
2924
+ JSLocalNameEnumeratorArgs *args;
2925
+ uint i;
2926
+ jsuword constFlag;
2927
+
2928
+ entry = (JSLocalNameHashEntry *) hdr;
2929
+ args = (JSLocalNameEnumeratorArgs *) arg;
2930
+ JS_ASSERT(entry->name);
2931
+ if (entry->localKind == JSLOCAL_ARG) {
2932
+ JS_ASSERT(entry->index < args->fun->nargs);
2933
+ JS_ASSERT(args->nCopiedArgs++ < args->fun->nargs);
2934
+ i = entry->index;
2935
+ constFlag = 0;
2936
+ } else {
2937
+ JS_ASSERT(entry->localKind == JSLOCAL_VAR ||
2938
+ entry->localKind == JSLOCAL_CONST ||
2939
+ entry->localKind == JSLOCAL_UPVAR);
2940
+ JS_ASSERT(entry->index < args->fun->u.i.nvars + args->fun->u.i.nupvars);
2941
+ JS_ASSERT(args->nCopiedVars++ < args->fun->u.i.nvars + args->fun->u.i.nupvars);
2942
+ i = args->fun->nargs;
2943
+ if (entry->localKind == JSLOCAL_UPVAR)
2944
+ i += args->fun->u.i.nvars;
2945
+ i += entry->index;
2946
+ constFlag = (entry->localKind == JSLOCAL_CONST);
2947
+ }
2948
+ args->names[i] = (jsuword) entry->name | constFlag;
2949
+ return JS_DHASH_NEXT;
2950
+ }
2951
+
2952
+ jsuword *
2953
+ js_GetLocalNameArray(JSContext *cx, JSFunction *fun, JSArenaPool *pool)
2954
+ {
2955
+ uintN n;
2956
+ jsuword *names;
2957
+ JSLocalNameMap *map;
2958
+ JSLocalNameEnumeratorArgs args;
2959
+ JSNameIndexPair *dup;
2960
+
2961
+ JS_ASSERT(fun->hasLocalNames());
2962
+ n = fun->countLocalNames();
2963
+
2964
+ if (n <= MAX_ARRAY_LOCALS)
2965
+ return (n == 1) ? &fun->u.i.names.taggedAtom : fun->u.i.names.array;
2966
+
2967
+ /*
2968
+ * No need to check for overflow of the allocation size as we are making a
2969
+ * copy of already allocated data. As such it must fit size_t.
2970
+ */
2971
+ JS_ARENA_ALLOCATE_CAST(names, jsuword *, pool, (size_t) n * sizeof *names);
2972
+ if (!names) {
2973
+ js_ReportOutOfScriptQuota(cx);
2974
+ return NULL;
2975
+ }
2976
+
2977
+ #if JS_HAS_DESTRUCTURING
2978
+ /* Some parameter names can be NULL due to destructuring patterns. */
2979
+ memset(names, 0, fun->nargs * sizeof *names);
2980
+ #endif
2981
+ map = fun->u.i.names.map;
2982
+ args.fun = fun;
2983
+ args.names = names;
2984
+ #ifdef DEBUG
2985
+ args.nCopiedArgs = 0;
2986
+ args.nCopiedVars = 0;
2987
+ #endif
2988
+ JS_DHashTableEnumerate(&map->names, get_local_names_enumerator, &args);
2989
+ for (dup = map->lastdup; dup; dup = dup->link) {
2990
+ JS_ASSERT(dup->index < fun->nargs);
2991
+ JS_ASSERT(args.nCopiedArgs++ < fun->nargs);
2992
+ names[dup->index] = (jsuword) dup->name;
2993
+ }
2994
+ #if !JS_HAS_DESTRUCTURING
2995
+ JS_ASSERT(args.nCopiedArgs == fun->nargs);
2996
+ #endif
2997
+ JS_ASSERT(args.nCopiedVars == fun->u.i.nvars + fun->u.i.nupvars);
2998
+
2999
+ return names;
3000
+ }
3001
+
3002
+ static JSDHashOperator
3003
+ trace_local_names_enumerator(JSDHashTable *table, JSDHashEntryHdr *hdr,
3004
+ uint32 number, void *arg)
3005
+ {
3006
+ JSLocalNameHashEntry *entry;
3007
+ JSTracer *trc;
3008
+
3009
+ entry = (JSLocalNameHashEntry *) hdr;
3010
+ JS_ASSERT(entry->name);
3011
+ trc = (JSTracer *) arg;
3012
+ JS_SET_TRACING_INDEX(trc,
3013
+ entry->localKind == JSLOCAL_ARG ? "arg" : "var",
3014
+ entry->index);
3015
+ JS_CallTracer(trc, ATOM_TO_STRING(entry->name), JSTRACE_STRING);
3016
+ return JS_DHASH_NEXT;
3017
+ }
3018
+
3019
+ static void
3020
+ TraceLocalNames(JSTracer *trc, JSFunction *fun)
3021
+ {
3022
+ uintN n, i;
3023
+ JSAtom *atom;
3024
+ jsuword *array;
3025
+
3026
+ JS_ASSERT(FUN_INTERPRETED(fun));
3027
+ n = fun->countLocalNames();
3028
+ if (n == 0)
3029
+ return;
3030
+ if (n <= MAX_ARRAY_LOCALS) {
3031
+ array = (n == 1) ? &fun->u.i.names.taggedAtom : fun->u.i.names.array;
3032
+ i = n;
3033
+ do {
3034
+ --i;
3035
+ atom = (JSAtom *) (array[i] & ~1);
3036
+ if (atom) {
3037
+ JS_SET_TRACING_INDEX(trc,
3038
+ i < fun->nargs ? "arg" : "var",
3039
+ i < fun->nargs ? i : i - fun->nargs);
3040
+ JS_CallTracer(trc, ATOM_TO_STRING(atom), JSTRACE_STRING);
3041
+ }
3042
+ } while (i != 0);
3043
+ } else {
3044
+ JS_DHashTableEnumerate(&fun->u.i.names.map->names,
3045
+ trace_local_names_enumerator, trc);
3046
+
3047
+ /*
3048
+ * No need to trace the list of duplicates in map->lastdup as the
3049
+ * names there are traced when enumerating the hash table.
3050
+ */
3051
+ }
3052
+ }
3053
+
3054
+ void
3055
+ DestroyLocalNames(JSContext *cx, JSFunction *fun)
3056
+ {
3057
+ uintN n;
3058
+
3059
+ n = fun->countLocalNames();
3060
+ if (n <= 1)
3061
+ return;
3062
+ if (n <= MAX_ARRAY_LOCALS)
3063
+ JS_free(cx, fun->u.i.names.array);
3064
+ else
3065
+ FreeLocalNameHash(cx, fun->u.i.names.map);
3066
+ }
3067
+
3068
+ void
3069
+ js_FreezeLocalNames(JSContext *cx, JSFunction *fun)
3070
+ {
3071
+ uintN n;
3072
+ jsuword *array;
3073
+
3074
+ JS_ASSERT(FUN_INTERPRETED(fun));
3075
+ JS_ASSERT(!fun->u.i.script);
3076
+ n = fun->nargs + fun->u.i.nvars + fun->u.i.nupvars;
3077
+ if (2 <= n && n < MAX_ARRAY_LOCALS) {
3078
+ /* Shrink over-allocated array ignoring realloc failures. */
3079
+ array = (jsuword *) JS_realloc(cx, fun->u.i.names.array,
3080
+ n * sizeof *array);
3081
+ if (array)
3082
+ fun->u.i.names.array = array;
3083
+ }
3084
+ #ifdef DEBUG
3085
+ // XXX no JS_DHashMarkTableImmutable on 1.9.1
3086
+ // if (n > MAX_ARRAY_LOCALS)
3087
+ // JS_DHashMarkTableImmutable(&fun->u.i.names.map->names);
3088
+ #endif
3089
+ }