johnson 1.2.0 → 2.0.0.pre0

Sign up to get free protection for your applications and to get access to all the features.
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
+ }