johnson 1.2.0 → 2.0.0.pre0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (782) hide show
  1. data/CHANGELOG.rdoc +8 -0
  2. data/Manifest.txt +762 -48
  3. data/README.rdoc +2 -1
  4. data/Rakefile +90 -18
  5. data/ext/spidermonkey/conversions.c +9 -2
  6. data/ext/spidermonkey/ruby_land_proxy.c +1 -1
  7. data/ext/spidermonkey/runtime.h +1 -1
  8. data/ext/tracemonkey/context.cc +125 -0
  9. data/ext/tracemonkey/context.h +19 -0
  10. data/ext/tracemonkey/conversions.cc +365 -0
  11. data/ext/tracemonkey/conversions.h +32 -0
  12. data/ext/tracemonkey/debugger.cc +234 -0
  13. data/ext/tracemonkey/debugger.h +10 -0
  14. data/ext/tracemonkey/extconf.rb +37 -0
  15. data/ext/tracemonkey/extensions.cc +37 -0
  16. data/ext/tracemonkey/extensions.h +12 -0
  17. data/ext/tracemonkey/global.cc +40 -0
  18. data/ext/tracemonkey/global.h +11 -0
  19. data/ext/tracemonkey/idhash.cc +16 -0
  20. data/ext/tracemonkey/idhash.h +8 -0
  21. data/ext/tracemonkey/immutable_node.cc +1199 -0
  22. data/ext/tracemonkey/immutable_node.cc.erb +559 -0
  23. data/ext/tracemonkey/immutable_node.h +22 -0
  24. data/ext/tracemonkey/jroot.h +215 -0
  25. data/ext/tracemonkey/js_land_proxy.cc +620 -0
  26. data/ext/tracemonkey/js_land_proxy.h +20 -0
  27. data/ext/tracemonkey/ruby_land_proxy.cc +618 -0
  28. data/ext/tracemonkey/ruby_land_proxy.h +38 -0
  29. data/ext/tracemonkey/runtime.cc +454 -0
  30. data/ext/tracemonkey/runtime.h +27 -0
  31. data/ext/tracemonkey/split_global.cc +392 -0
  32. data/ext/tracemonkey/split_global.h +11 -0
  33. data/ext/tracemonkey/tracemonkey.cc +23 -0
  34. data/ext/tracemonkey/tracemonkey.h +32 -0
  35. data/lib/johnson.rb +12 -4
  36. data/lib/johnson/error.rb +5 -0
  37. data/lib/johnson/js/prelude.js +16 -1
  38. data/lib/johnson/parser.rb +2 -1
  39. data/lib/johnson/runtime.rb +87 -26
  40. data/lib/johnson/spidermonkey/runtime.rb +7 -16
  41. data/lib/johnson/tracemonkey.rb +13 -0
  42. data/lib/johnson/tracemonkey/context.rb +10 -0
  43. data/lib/johnson/tracemonkey/debugger.rb +67 -0
  44. data/lib/johnson/tracemonkey/immutable_node.rb +282 -0
  45. data/lib/johnson/tracemonkey/js_land_proxy.rb +64 -0
  46. data/lib/johnson/tracemonkey/mutable_tree_visitor.rb +242 -0
  47. data/lib/johnson/tracemonkey/ruby_land_proxy.rb +17 -0
  48. data/lib/johnson/tracemonkey/runtime.rb +80 -0
  49. data/test/{johnson_test.rb → generic/johnson_test.rb} +1 -1
  50. data/test/{parser_test.rb → generic/parser_test.rb} +1 -1
  51. data/test/helper.rb +23 -4
  52. data/test/johnson/{browser_test.rb → generic/browser_test.rb} +1 -1
  53. data/test/johnson/{conversions → generic/conversions}/array_test.rb +1 -1
  54. data/test/johnson/{conversions → generic/conversions}/boolean_test.rb +1 -1
  55. data/test/johnson/{conversions → generic/conversions}/callable_test.rb +1 -1
  56. data/test/johnson/{conversions → generic/conversions}/file_test.rb +1 -1
  57. data/test/johnson/generic/conversions/helper.rb +1 -0
  58. data/test/johnson/{conversions → generic/conversions}/nil_test.rb +1 -1
  59. data/test/johnson/{conversions → generic/conversions}/number_test.rb +1 -1
  60. data/test/johnson/{conversions → generic/conversions}/regexp_test.rb +1 -1
  61. data/test/johnson/{conversions → generic/conversions}/string_test.rb +1 -1
  62. data/test/johnson/{conversions → generic/conversions}/struct_test.rb +1 -1
  63. data/test/johnson/{conversions → generic/conversions}/symbol_test.rb +1 -1
  64. data/test/johnson/{conversions → generic/conversions}/thread_test.rb +1 -1
  65. data/test/johnson/{custom_conversions_test.rb → generic/custom_conversions_test.rb} +1 -1
  66. data/test/johnson/generic/default_test.rb +12 -0
  67. data/test/johnson/{error_test.rb → generic/error_test.rb} +1 -1
  68. data/test/johnson/{extensions_test.rb → generic/extensions_test.rb} +1 -1
  69. data/test/johnson/generic/helper.rb +1 -0
  70. data/test/johnson/{nodes → generic/nodes}/array_literal_test.rb +1 -1
  71. data/test/johnson/{nodes → generic/nodes}/array_node_test.rb +1 -1
  72. data/test/johnson/{nodes → generic/nodes}/binary_node_test.rb +1 -1
  73. data/test/johnson/{nodes → generic/nodes}/bracket_access_test.rb +1 -1
  74. data/test/johnson/{nodes → generic/nodes}/delete_test.rb +1 -1
  75. data/test/johnson/{nodes → generic/nodes}/do_while_test.rb +1 -1
  76. data/test/johnson/{nodes → generic/nodes}/dot_accessor_test.rb +1 -1
  77. data/test/johnson/generic/nodes/export_test.rb +11 -0
  78. data/test/johnson/{nodes → generic/nodes}/for_test.rb +1 -1
  79. data/test/johnson/{nodes → generic/nodes}/function_test.rb +1 -1
  80. data/test/johnson/generic/nodes/helper.rb +1 -0
  81. data/test/johnson/{nodes → generic/nodes}/if_test.rb +16 -6
  82. data/test/johnson/generic/nodes/import_test.rb +15 -0
  83. data/test/johnson/{nodes → generic/nodes}/label_test.rb +1 -1
  84. data/test/johnson/{nodes → generic/nodes}/let_test.rb +1 -1
  85. data/test/johnson/{nodes → generic/nodes}/object_literal_test.rb +1 -1
  86. data/test/johnson/{nodes → generic/nodes}/return_test.rb +1 -1
  87. data/test/johnson/{nodes → generic/nodes}/semi_test.rb +1 -1
  88. data/test/johnson/{nodes → generic/nodes}/switch_test.rb +1 -1
  89. data/test/johnson/{nodes → generic/nodes}/ternary_test.rb +1 -1
  90. data/test/johnson/{nodes → generic/nodes}/throw_test.rb +1 -1
  91. data/test/johnson/{nodes → generic/nodes}/try_node_test.rb +36 -6
  92. data/test/johnson/{nodes → generic/nodes}/typeof_test.rb +1 -1
  93. data/test/johnson/{nodes → generic/nodes}/unary_node_test.rb +1 -1
  94. data/test/johnson/{nodes → generic/nodes}/void_test.rb +1 -1
  95. data/test/johnson/{nodes → generic/nodes}/while_test.rb +1 -1
  96. data/test/johnson/{nodes → generic/nodes}/with_test.rb +1 -1
  97. data/test/johnson/{prelude_test.rb → generic/prelude_test.rb} +1 -1
  98. data/test/johnson/{runtime_test.rb → generic/runtime_test.rb} +3 -6
  99. data/test/johnson/generic/version_test.rb +13 -0
  100. data/test/johnson/{visitors → generic/visitors}/dot_visitor_test.rb +1 -1
  101. data/test/johnson/{visitors → generic/visitors}/enumerating_visitor_test.rb +1 -1
  102. data/test/johnson/generic/visitors/helper.rb +1 -0
  103. data/test/johnson/spidermonkey/js_land_proxy_test.rb +1 -5
  104. data/test/johnson/spidermonkey/ruby_land_proxy_test.rb +11 -7
  105. data/test/johnson/tracemonkey/context_test.rb +21 -0
  106. data/test/johnson/tracemonkey/immutable_node_test.rb +34 -0
  107. data/test/johnson/tracemonkey/js_land_proxy_test.rb +273 -0
  108. data/test/johnson/tracemonkey/ruby_land_proxy_test.rb +274 -0
  109. data/test/johnson/tracemonkey/runtime_test.rb +41 -0
  110. data/test/johnson/tracemonkey/split_global_test.rb +32 -0
  111. data/vendor/spidermonkey/js.pkg +2 -0
  112. data/vendor/tracemonkey/Makefile.in +668 -0
  113. data/vendor/tracemonkey/Makefile.ref +483 -0
  114. data/vendor/tracemonkey/README.html +54 -0
  115. data/vendor/tracemonkey/SpiderMonkey.rsp +11 -0
  116. data/vendor/tracemonkey/Y.js +19 -0
  117. data/vendor/tracemonkey/aclocal.m4 +9 -0
  118. data/vendor/tracemonkey/bench.sh +5 -0
  119. data/vendor/tracemonkey/build/autoconf/acoutput-fast.pl +202 -0
  120. data/vendor/tracemonkey/build/autoconf/altoptions.m4 +154 -0
  121. data/vendor/tracemonkey/build/autoconf/config.guess +1537 -0
  122. data/vendor/tracemonkey/build/autoconf/config.sub +1595 -0
  123. data/vendor/tracemonkey/build/autoconf/install-sh +119 -0
  124. data/vendor/tracemonkey/build/autoconf/make-makefile +315 -0
  125. data/vendor/tracemonkey/build/autoconf/match-dir.sh +101 -0
  126. data/vendor/tracemonkey/build/autoconf/moznbytetype.m4 +136 -0
  127. data/vendor/tracemonkey/build/autoconf/nspr.m4 +82 -0
  128. data/vendor/tracemonkey/build/autoconf/pkg.m4 +59 -0
  129. data/vendor/tracemonkey/build/autoconf/update-makefile.sh +118 -0
  130. data/vendor/tracemonkey/build/cygwin-wrapper +75 -0
  131. data/vendor/tracemonkey/build/hcc +111 -0
  132. data/vendor/tracemonkey/build/hcpp +155 -0
  133. data/vendor/tracemonkey/build/unix/mddepend.pl +165 -0
  134. data/vendor/tracemonkey/build/unix/uniq.pl +63 -0
  135. data/vendor/tracemonkey/build/win32/pgomerge.py +40 -0
  136. data/vendor/tracemonkey/builtins.tbl +91 -0
  137. data/vendor/tracemonkey/call.js +13 -0
  138. data/vendor/tracemonkey/config.mk +206 -0
  139. data/vendor/tracemonkey/config/Makefile.in +106 -0
  140. data/vendor/tracemonkey/config/Moz/Milestone.pm +232 -0
  141. data/vendor/tracemonkey/config/autoconf.mk.in +362 -0
  142. data/vendor/tracemonkey/config/check-sync-dirs.py +103 -0
  143. data/vendor/tracemonkey/config/check-sync-exceptions +7 -0
  144. data/vendor/tracemonkey/config/config.mk +881 -0
  145. data/vendor/tracemonkey/config/fastcwd.pl +66 -0
  146. data/vendor/tracemonkey/config/gcc_hidden.h +2 -0
  147. data/vendor/tracemonkey/config/insure.mk +53 -0
  148. data/vendor/tracemonkey/config/make-system-wrappers.pl +59 -0
  149. data/vendor/tracemonkey/config/milestone.pl +112 -0
  150. data/vendor/tracemonkey/config/milestone.txt +13 -0
  151. data/vendor/tracemonkey/config/mkdepend/Makefile.in +84 -0
  152. data/vendor/tracemonkey/config/mkdepend/cppsetup.c +233 -0
  153. data/vendor/tracemonkey/config/mkdepend/def.h +184 -0
  154. data/vendor/tracemonkey/config/mkdepend/ifparser.c +551 -0
  155. data/vendor/tracemonkey/config/mkdepend/ifparser.h +83 -0
  156. data/vendor/tracemonkey/config/mkdepend/imakemdep.h +733 -0
  157. data/vendor/tracemonkey/config/mkdepend/include.c +337 -0
  158. data/vendor/tracemonkey/config/mkdepend/main.c +860 -0
  159. data/vendor/tracemonkey/config/mkdepend/mkdepend.man +382 -0
  160. data/vendor/tracemonkey/config/mkdepend/parse.c +686 -0
  161. data/vendor/tracemonkey/config/mkdepend/pr.c +124 -0
  162. data/vendor/tracemonkey/config/nfspwd.pl +50 -0
  163. data/vendor/tracemonkey/config/nsinstall.c +481 -0
  164. data/vendor/tracemonkey/config/nsinstall.py +155 -0
  165. data/vendor/tracemonkey/config/pathsub.c +247 -0
  166. data/vendor/tracemonkey/config/pathsub.h +74 -0
  167. data/vendor/tracemonkey/config/preprocessor.pl +671 -0
  168. data/vendor/tracemonkey/config/revdepth-nt.pl +48 -0
  169. data/vendor/tracemonkey/config/revdepth.pl +51 -0
  170. data/vendor/tracemonkey/config/rules.mk +2310 -0
  171. data/vendor/tracemonkey/config/static-checking-config.mk +21 -0
  172. data/vendor/tracemonkey/config/static-checking.js +92 -0
  173. data/vendor/tracemonkey/config/string-format.js +61 -0
  174. data/vendor/tracemonkey/config/system-headers +1035 -0
  175. data/vendor/tracemonkey/config/version.mk +85 -0
  176. data/vendor/tracemonkey/config/version_win.pl +442 -0
  177. data/vendor/tracemonkey/configure +14183 -0
  178. data/vendor/tracemonkey/configure.in +5363 -0
  179. data/vendor/tracemonkey/correct.sh +23 -0
  180. data/vendor/tracemonkey/correct/check-3d-morph.js +55 -0
  181. data/vendor/tracemonkey/correct/check-3d-raytrace.js +445 -0
  182. data/vendor/tracemonkey/correct/check-access-binary-trees.js +52 -0
  183. data/vendor/tracemonkey/correct/check-access-fannkuch.js +66 -0
  184. data/vendor/tracemonkey/correct/check-access-nbody.js +171 -0
  185. data/vendor/tracemonkey/correct/check-access-nsieve.js +40 -0
  186. data/vendor/tracemonkey/correct/check-bitops-3bit-bits-in-byte.js +35 -0
  187. data/vendor/tracemonkey/correct/check-bitops-bits-in-byte.js +24 -0
  188. data/vendor/tracemonkey/correct/check-bitops-bitwise-and.js +29 -0
  189. data/vendor/tracemonkey/correct/check-bitops-nsieve-bits.js +40 -0
  190. data/vendor/tracemonkey/correct/check-controlflow-recursive.js +27 -0
  191. data/vendor/tracemonkey/correct/check-date-format-tofte.js +302 -0
  192. data/vendor/tracemonkey/correct/check-date-format-xparb.js +421 -0
  193. data/vendor/tracemonkey/correct/check-mont.js +119 -0
  194. data/vendor/tracemonkey/dtoa.c +3335 -0
  195. data/vendor/tracemonkey/editline/Makefile.in +55 -0
  196. data/vendor/tracemonkey/editline/Makefile.ref +143 -0
  197. data/vendor/tracemonkey/editline/README +83 -0
  198. data/vendor/tracemonkey/editline/editline.3 +175 -0
  199. data/vendor/tracemonkey/editline/editline.c +1371 -0
  200. data/vendor/tracemonkey/editline/editline.h +135 -0
  201. data/vendor/tracemonkey/editline/sysunix.c +182 -0
  202. data/vendor/tracemonkey/editline/unix.h +82 -0
  203. data/vendor/tracemonkey/if.js +13 -0
  204. data/vendor/tracemonkey/imacro_asm.js.in +396 -0
  205. data/vendor/tracemonkey/imacros.c.out +1034 -0
  206. data/vendor/tracemonkey/imacros.jsasm +770 -0
  207. data/vendor/tracemonkey/javascript-trace.d +73 -0
  208. data/vendor/tracemonkey/jitstats.tbl +55 -0
  209. data/vendor/tracemonkey/js-config.h.in +82 -0
  210. data/vendor/tracemonkey/js-config.in +111 -0
  211. data/vendor/tracemonkey/js.mdp +0 -0
  212. data/vendor/tracemonkey/js.msg +312 -0
  213. data/vendor/tracemonkey/js3240.rc +79 -0
  214. data/vendor/tracemonkey/jsOS240.def +654 -0
  215. data/vendor/tracemonkey/jsapi.cpp +6005 -0
  216. data/vendor/tracemonkey/jsapi.h +2727 -0
  217. data/vendor/tracemonkey/jsarena.cpp +450 -0
  218. data/vendor/tracemonkey/jsarena.h +318 -0
  219. data/vendor/tracemonkey/jsarray.cpp +3664 -0
  220. data/vendor/tracemonkey/jsarray.h +238 -0
  221. data/vendor/tracemonkey/jsatom.cpp +1244 -0
  222. data/vendor/tracemonkey/jsatom.h +493 -0
  223. data/vendor/tracemonkey/jsbit.h +249 -0
  224. data/vendor/tracemonkey/jsbool.cpp +184 -0
  225. data/vendor/tracemonkey/jsbool.h +88 -0
  226. data/vendor/tracemonkey/jsbuiltins.cpp +415 -0
  227. data/vendor/tracemonkey/jsbuiltins.h +456 -0
  228. data/vendor/tracemonkey/jsclist.h +139 -0
  229. data/vendor/tracemonkey/jscntxt.cpp +1816 -0
  230. data/vendor/tracemonkey/jscntxt.h +1541 -0
  231. data/vendor/tracemonkey/jscompat.h +57 -0
  232. data/vendor/tracemonkey/jsconfig.mk +181 -0
  233. data/vendor/tracemonkey/jscpucfg.cpp +194 -0
  234. data/vendor/tracemonkey/jscpucfg.h +91 -0
  235. data/vendor/tracemonkey/jsdate.cpp +2465 -0
  236. data/vendor/tracemonkey/jsdate.h +129 -0
  237. data/vendor/tracemonkey/jsdbgapi.cpp +2017 -0
  238. data/vendor/tracemonkey/jsdbgapi.h +500 -0
  239. data/vendor/tracemonkey/jsdhash.cpp +876 -0
  240. data/vendor/tracemonkey/jsdhash.h +588 -0
  241. data/vendor/tracemonkey/jsdtoa.cpp +572 -0
  242. data/vendor/tracemonkey/jsdtoa.h +131 -0
  243. data/vendor/tracemonkey/jsdtracef.c +318 -0
  244. data/vendor/tracemonkey/jsdtracef.h +81 -0
  245. data/vendor/tracemonkey/jsemit.cpp +7292 -0
  246. data/vendor/tracemonkey/jsemit.h +802 -0
  247. data/vendor/tracemonkey/jsexn.cpp +1337 -0
  248. data/vendor/tracemonkey/jsexn.h +96 -0
  249. data/vendor/tracemonkey/jsfile.cpp +2747 -0
  250. data/vendor/tracemonkey/jsfile.h +56 -0
  251. data/vendor/tracemonkey/jsfile.msg +90 -0
  252. data/vendor/tracemonkey/jsfun.cpp +3089 -0
  253. data/vendor/tracemonkey/jsfun.h +366 -0
  254. data/vendor/tracemonkey/jsgc.cpp +3816 -0
  255. data/vendor/tracemonkey/jsgc.h +429 -0
  256. data/vendor/tracemonkey/jshash.cpp +477 -0
  257. data/vendor/tracemonkey/jshash.h +151 -0
  258. data/vendor/tracemonkey/jsify.pl +483 -0
  259. data/vendor/tracemonkey/jsinterp.cpp +7441 -0
  260. data/vendor/tracemonkey/jsinterp.h +666 -0
  261. data/vendor/tracemonkey/jsinvoke.cpp +42 -0
  262. data/vendor/tracemonkey/jsiter.cpp +1040 -0
  263. data/vendor/tracemonkey/jsiter.h +140 -0
  264. data/vendor/tracemonkey/jskeyword.tbl +124 -0
  265. data/vendor/tracemonkey/jskwgen.cpp +460 -0
  266. data/vendor/tracemonkey/jslibmath.h +69 -0
  267. data/vendor/tracemonkey/jslock.cpp +1512 -0
  268. data/vendor/tracemonkey/jslock.h +325 -0
  269. data/vendor/tracemonkey/jslocko.asm +60 -0
  270. data/vendor/tracemonkey/jslog2.cpp +111 -0
  271. data/vendor/tracemonkey/jslong.h +167 -0
  272. data/vendor/tracemonkey/jsmath.cpp +806 -0
  273. data/vendor/tracemonkey/jsmath.h +63 -0
  274. data/vendor/tracemonkey/jsnum.cpp +1374 -0
  275. data/vendor/tracemonkey/jsnum.h +280 -0
  276. data/vendor/tracemonkey/jsobj.cpp +6165 -0
  277. data/vendor/tracemonkey/jsobj.h +870 -0
  278. data/vendor/tracemonkey/json.cpp +1338 -0
  279. data/vendor/tracemonkey/json.h +108 -0
  280. data/vendor/tracemonkey/jsopcode.cpp +5484 -0
  281. data/vendor/tracemonkey/jsopcode.h +434 -0
  282. data/vendor/tracemonkey/jsopcode.tbl +591 -0
  283. data/vendor/tracemonkey/jsoplengen.cpp +121 -0
  284. data/vendor/tracemonkey/jsotypes.h +202 -0
  285. data/vendor/tracemonkey/jsparse.cpp +9257 -0
  286. data/vendor/tracemonkey/jsparse.h +900 -0
  287. data/vendor/tracemonkey/jsprf.cpp +1262 -0
  288. data/vendor/tracemonkey/jsprf.h +150 -0
  289. data/vendor/tracemonkey/jsproto.tbl +117 -0
  290. data/vendor/tracemonkey/jsprvtd.h +366 -0
  291. data/vendor/tracemonkey/jspubtd.h +585 -0
  292. data/vendor/tracemonkey/jsregexp.cpp +5051 -0
  293. data/vendor/tracemonkey/jsregexp.h +199 -0
  294. data/vendor/tracemonkey/jsreops.tbl +145 -0
  295. data/vendor/tracemonkey/jsscan.cpp +2040 -0
  296. data/vendor/tracemonkey/jsscan.h +467 -0
  297. data/vendor/tracemonkey/jsscope.cpp +1966 -0
  298. data/vendor/tracemonkey/jsscope.h +487 -0
  299. data/vendor/tracemonkey/jsscript.cpp +1932 -0
  300. data/vendor/tracemonkey/jsscript.h +345 -0
  301. data/vendor/tracemonkey/jsshell.msg +54 -0
  302. data/vendor/tracemonkey/jsstack.js +167 -0
  303. data/vendor/tracemonkey/jsstaticcheck.h +69 -0
  304. data/vendor/tracemonkey/jsstddef.h +87 -0
  305. data/vendor/tracemonkey/jsstdint.h +96 -0
  306. data/vendor/tracemonkey/jsstr.cpp +5277 -0
  307. data/vendor/tracemonkey/jsstr.h +702 -0
  308. data/vendor/tracemonkey/jstracer.cpp +10991 -0
  309. data/vendor/tracemonkey/jstracer.h +794 -0
  310. data/vendor/tracemonkey/jstypes.h +481 -0
  311. data/vendor/tracemonkey/jsutil.cpp +361 -0
  312. data/vendor/tracemonkey/jsutil.h +178 -0
  313. data/vendor/tracemonkey/jsversion.h +243 -0
  314. data/vendor/tracemonkey/jswince.asm +44 -0
  315. data/vendor/tracemonkey/jsxdrapi.cpp +800 -0
  316. data/vendor/tracemonkey/jsxdrapi.h +220 -0
  317. data/vendor/tracemonkey/jsxml.cpp +8327 -0
  318. data/vendor/tracemonkey/jsxml.h +305 -0
  319. data/vendor/tracemonkey/liveconnect/LiveConnect.dsp +157 -0
  320. data/vendor/tracemonkey/liveconnect/LiveConnectShell.dsp +120 -0
  321. data/vendor/tracemonkey/liveconnect/LiveConnectShell.dsw +44 -0
  322. data/vendor/tracemonkey/liveconnect/Makefile.in +105 -0
  323. data/vendor/tracemonkey/liveconnect/Makefile.ref +169 -0
  324. data/vendor/tracemonkey/liveconnect/README.html +712 -0
  325. data/vendor/tracemonkey/liveconnect/_jni/netscape_javascript_JSException.h +14 -0
  326. data/vendor/tracemonkey/liveconnect/_jni/netscape_javascript_JSObject.h +155 -0
  327. data/vendor/tracemonkey/liveconnect/classes/Makefile.in +89 -0
  328. data/vendor/tracemonkey/liveconnect/classes/Makefile.ref +57 -0
  329. data/vendor/tracemonkey/liveconnect/classes/netscape/Makefile.ref +47 -0
  330. data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/JSException.java +140 -0
  331. data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/JSObject.java +183 -0
  332. data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/JSProxy.java +58 -0
  333. data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/JSRunnable.java +70 -0
  334. data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/JSUtil.java +59 -0
  335. data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/Makefile.ref +53 -0
  336. data/vendor/tracemonkey/liveconnect/config/AIX4.1.mk +45 -0
  337. data/vendor/tracemonkey/liveconnect/config/AIX4.2.mk +45 -0
  338. data/vendor/tracemonkey/liveconnect/config/AIX4.3.mk +50 -0
  339. data/vendor/tracemonkey/liveconnect/config/HP-UXB.10.10.mk +43 -0
  340. data/vendor/tracemonkey/liveconnect/config/HP-UXB.10.20.mk +43 -0
  341. data/vendor/tracemonkey/liveconnect/config/HP-UXB.11.00.mk +43 -0
  342. data/vendor/tracemonkey/liveconnect/config/IRIX6.2.mk +43 -0
  343. data/vendor/tracemonkey/liveconnect/config/IRIX6.3.mk +43 -0
  344. data/vendor/tracemonkey/liveconnect/config/IRIX6.5.mk +43 -0
  345. data/vendor/tracemonkey/liveconnect/config/Linux_All.mk +73 -0
  346. data/vendor/tracemonkey/liveconnect/config/OSF1V4.0.mk +65 -0
  347. data/vendor/tracemonkey/liveconnect/config/OSF1V5.0.mk +62 -0
  348. data/vendor/tracemonkey/liveconnect/config/SunOS5.5.1.mk +55 -0
  349. data/vendor/tracemonkey/liveconnect/config/SunOS5.6.mk +39 -0
  350. data/vendor/tracemonkey/liveconnect/config/SunOS5.7.mk +39 -0
  351. data/vendor/tracemonkey/liveconnect/config/SunOS5.8.mk +39 -0
  352. data/vendor/tracemonkey/liveconnect/config/WINNT4.0.mk +53 -0
  353. data/vendor/tracemonkey/liveconnect/jsj.c +886 -0
  354. data/vendor/tracemonkey/liveconnect/jsj.msg +98 -0
  355. data/vendor/tracemonkey/liveconnect/jsj_JSObject.c +1377 -0
  356. data/vendor/tracemonkey/liveconnect/jsj_JavaArray.c +474 -0
  357. data/vendor/tracemonkey/liveconnect/jsj_JavaClass.c +737 -0
  358. data/vendor/tracemonkey/liveconnect/jsj_JavaMember.c +191 -0
  359. data/vendor/tracemonkey/liveconnect/jsj_JavaObject.c +1079 -0
  360. data/vendor/tracemonkey/liveconnect/jsj_JavaPackage.c +569 -0
  361. data/vendor/tracemonkey/liveconnect/jsj_array.c +207 -0
  362. data/vendor/tracemonkey/liveconnect/jsj_class.c +770 -0
  363. data/vendor/tracemonkey/liveconnect/jsj_convert.c +902 -0
  364. data/vendor/tracemonkey/liveconnect/jsj_field.c +421 -0
  365. data/vendor/tracemonkey/liveconnect/jsj_hash.c +488 -0
  366. data/vendor/tracemonkey/liveconnect/jsj_hash.h +161 -0
  367. data/vendor/tracemonkey/liveconnect/jsj_method.c +1825 -0
  368. data/vendor/tracemonkey/liveconnect/jsj_nodl.c +1 -0
  369. data/vendor/tracemonkey/liveconnect/jsj_private.h +677 -0
  370. data/vendor/tracemonkey/liveconnect/jsj_simpleapi.c +219 -0
  371. data/vendor/tracemonkey/liveconnect/jsj_utils.c +513 -0
  372. data/vendor/tracemonkey/liveconnect/jsjava.h +316 -0
  373. data/vendor/tracemonkey/liveconnect/netscape_javascript_JSObject.h +155 -0
  374. data/vendor/tracemonkey/liveconnect/nsCLiveconnect.cpp +785 -0
  375. data/vendor/tracemonkey/liveconnect/nsCLiveconnect.h +197 -0
  376. data/vendor/tracemonkey/liveconnect/nsCLiveconnectFactory.cpp +118 -0
  377. data/vendor/tracemonkey/liveconnect/nsCLiveconnectFactory.h +76 -0
  378. data/vendor/tracemonkey/liveconnect/nsILiveconnect.h +197 -0
  379. data/vendor/tracemonkey/liveconnect/nsISecureLiveconnect.h +94 -0
  380. data/vendor/tracemonkey/liveconnect/nsISecurityContext.h +136 -0
  381. data/vendor/tracemonkey/lock_SunOS.s +119 -0
  382. data/vendor/tracemonkey/mandelbrot-results.js +3 -0
  383. data/vendor/tracemonkey/math-partial-sums.js +32 -0
  384. data/vendor/tracemonkey/math-trace-tests.js +507 -0
  385. data/vendor/tracemonkey/md5.js +289 -0
  386. data/vendor/tracemonkey/nanojit/Assembler.cpp +1984 -0
  387. data/vendor/tracemonkey/nanojit/Assembler.h +375 -0
  388. data/vendor/tracemonkey/nanojit/Fragmento.cpp +651 -0
  389. data/vendor/tracemonkey/nanojit/Fragmento.h +237 -0
  390. data/vendor/tracemonkey/nanojit/LIR.cpp +2314 -0
  391. data/vendor/tracemonkey/nanojit/LIR.h +879 -0
  392. data/vendor/tracemonkey/nanojit/LIRopcode.tbl +252 -0
  393. data/vendor/tracemonkey/nanojit/Native.h +127 -0
  394. data/vendor/tracemonkey/nanojit/NativeARM.cpp +1742 -0
  395. data/vendor/tracemonkey/nanojit/NativeARM.h +844 -0
  396. data/vendor/tracemonkey/nanojit/NativeSparc.cpp +1130 -0
  397. data/vendor/tracemonkey/nanojit/NativeSparc.h +948 -0
  398. data/vendor/tracemonkey/nanojit/NativeThumb.cpp +1322 -0
  399. data/vendor/tracemonkey/nanojit/NativeThumb.h +525 -0
  400. data/vendor/tracemonkey/nanojit/Nativei386.cpp +1748 -0
  401. data/vendor/tracemonkey/nanojit/Nativei386.h +857 -0
  402. data/vendor/tracemonkey/nanojit/RegAlloc.cpp +183 -0
  403. data/vendor/tracemonkey/nanojit/RegAlloc.h +95 -0
  404. data/vendor/tracemonkey/nanojit/TraceTreeDrawer.cpp +306 -0
  405. data/vendor/tracemonkey/nanojit/TraceTreeDrawer.h +88 -0
  406. data/vendor/tracemonkey/nanojit/avmplus.cpp +56 -0
  407. data/vendor/tracemonkey/nanojit/avmplus.h +1016 -0
  408. data/vendor/tracemonkey/nanojit/nanojit.h +253 -0
  409. data/vendor/tracemonkey/perfect.js +39 -0
  410. data/vendor/tracemonkey/plify_jsdhash.sed +35 -0
  411. data/vendor/tracemonkey/prmjtime.cpp +869 -0
  412. data/vendor/tracemonkey/prmjtime.h +103 -0
  413. data/vendor/tracemonkey/ref-config/AIX4.1.mk +65 -0
  414. data/vendor/tracemonkey/ref-config/AIX4.2.mk +64 -0
  415. data/vendor/tracemonkey/ref-config/AIX4.3.mk +65 -0
  416. data/vendor/tracemonkey/ref-config/Darwin.mk +85 -0
  417. data/vendor/tracemonkey/ref-config/Darwin1.3.mk +81 -0
  418. data/vendor/tracemonkey/ref-config/Darwin1.4.mk +41 -0
  419. data/vendor/tracemonkey/ref-config/Darwin5.2.mk +81 -0
  420. data/vendor/tracemonkey/ref-config/Darwin5.3.mk +81 -0
  421. data/vendor/tracemonkey/ref-config/Darwin64.mk +72 -0
  422. data/vendor/tracemonkey/ref-config/HP-UXB.10.10.mk +77 -0
  423. data/vendor/tracemonkey/ref-config/HP-UXB.10.20.mk +77 -0
  424. data/vendor/tracemonkey/ref-config/HP-UXB.11.00.mk +80 -0
  425. data/vendor/tracemonkey/ref-config/IRIX.mk +87 -0
  426. data/vendor/tracemonkey/ref-config/IRIX5.3.mk +44 -0
  427. data/vendor/tracemonkey/ref-config/IRIX6.1.mk +44 -0
  428. data/vendor/tracemonkey/ref-config/IRIX6.2.mk +44 -0
  429. data/vendor/tracemonkey/ref-config/IRIX6.3.mk +44 -0
  430. data/vendor/tracemonkey/ref-config/IRIX6.5.mk +44 -0
  431. data/vendor/tracemonkey/ref-config/Linux_All.mk +105 -0
  432. data/vendor/tracemonkey/ref-config/Mac_OS10.0.mk +82 -0
  433. data/vendor/tracemonkey/ref-config/OSF1V4.0.mk +72 -0
  434. data/vendor/tracemonkey/ref-config/OSF1V5.0.mk +69 -0
  435. data/vendor/tracemonkey/ref-config/SunOS4.1.4.mk +101 -0
  436. data/vendor/tracemonkey/ref-config/SunOS5.10.mk +50 -0
  437. data/vendor/tracemonkey/ref-config/SunOS5.3.mk +91 -0
  438. data/vendor/tracemonkey/ref-config/SunOS5.4.mk +92 -0
  439. data/vendor/tracemonkey/ref-config/SunOS5.5.1.mk +44 -0
  440. data/vendor/tracemonkey/ref-config/SunOS5.5.mk +87 -0
  441. data/vendor/tracemonkey/ref-config/SunOS5.6.mk +89 -0
  442. data/vendor/tracemonkey/ref-config/SunOS5.7.mk +44 -0
  443. data/vendor/tracemonkey/ref-config/SunOS5.8.mk +44 -0
  444. data/vendor/tracemonkey/ref-config/SunOS5.9.mk +44 -0
  445. data/vendor/tracemonkey/ref-config/WINNT4.0.mk +118 -0
  446. data/vendor/tracemonkey/ref-config/WINNT5.0.mk +118 -0
  447. data/vendor/tracemonkey/ref-config/WINNT5.1.mk +118 -0
  448. data/vendor/tracemonkey/ref-config/WINNT5.2.mk +118 -0
  449. data/vendor/tracemonkey/ref-config/WINNT6.0.mk +118 -0
  450. data/vendor/tracemonkey/ref-config/dgux.mk +64 -0
  451. data/vendor/tracemonkey/resource.h +15 -0
  452. data/vendor/tracemonkey/rules.mk +206 -0
  453. data/vendor/tracemonkey/shell/Makefile.in +72 -0
  454. data/vendor/tracemonkey/shell/js.cpp +4719 -0
  455. data/vendor/tracemonkey/t/3d-cube.js +337 -0
  456. data/vendor/tracemonkey/t/3d-morph.js +54 -0
  457. data/vendor/tracemonkey/t/3d-raytrace.js +441 -0
  458. data/vendor/tracemonkey/t/access-binary-trees.js +50 -0
  459. data/vendor/tracemonkey/t/access-fannkuch.js +66 -0
  460. data/vendor/tracemonkey/t/access-nbody.js +169 -0
  461. data/vendor/tracemonkey/t/access-nsieve.js +38 -0
  462. data/vendor/tracemonkey/t/bitops-3bit-bits-in-byte.js +32 -0
  463. data/vendor/tracemonkey/t/bitops-bits-in-byte.js +21 -0
  464. data/vendor/tracemonkey/t/bitops-bitwise-and.js +28 -0
  465. data/vendor/tracemonkey/t/bitops-nsieve-bits.js +32 -0
  466. data/vendor/tracemonkey/t/controlflow-recursive.js +25 -0
  467. data/vendor/tracemonkey/t/crypto-aes.js +422 -0
  468. data/vendor/tracemonkey/t/crypto-md5.js +286 -0
  469. data/vendor/tracemonkey/t/crypto-sha1.js +224 -0
  470. data/vendor/tracemonkey/t/date-format-tofte.js +299 -0
  471. data/vendor/tracemonkey/t/date-format-xparb.js +417 -0
  472. data/vendor/tracemonkey/t/math-cordic.js +95 -0
  473. data/vendor/tracemonkey/t/math-partial-sums.js +33 -0
  474. data/vendor/tracemonkey/t/math-spectral-norm.js +51 -0
  475. data/vendor/tracemonkey/t/regexp-dna.js +1712 -0
  476. data/vendor/tracemonkey/t/string-base64.js +135 -0
  477. data/vendor/tracemonkey/t/string-fasta.js +85 -0
  478. data/vendor/tracemonkey/t/string-tagcloud.js +265 -0
  479. data/vendor/tracemonkey/t/string-unpack-code.js +68 -0
  480. data/vendor/tracemonkey/t/string-validate-input.js +89 -0
  481. data/vendor/tracemonkey/time.sh +13 -0
  482. data/vendor/tracemonkey/trace-test.js +5564 -0
  483. data/vendor/tracemonkey/v8/base.js +187 -0
  484. data/vendor/tracemonkey/v8/crypto.js +1689 -0
  485. data/vendor/tracemonkey/v8/deltablue.js +880 -0
  486. data/vendor/tracemonkey/v8/earley-boyer.js +4682 -0
  487. data/vendor/tracemonkey/v8/raytrace.js +3418 -0
  488. data/vendor/tracemonkey/v8/richards.js +539 -0
  489. data/vendor/tracemonkey/v8/run-crypto.js +44 -0
  490. data/vendor/tracemonkey/v8/run-deltablue.js +44 -0
  491. data/vendor/tracemonkey/v8/run-earley-boyer.js +44 -0
  492. data/vendor/tracemonkey/v8/run-raytrace.js +44 -0
  493. data/vendor/tracemonkey/v8/run-richards.js +44 -0
  494. data/vendor/tracemonkey/v8/run.js +49 -0
  495. data/vendor/tracemonkey/vprof/readme.txt +93 -0
  496. data/vendor/tracemonkey/vprof/vprof.cpp +360 -0
  497. data/vendor/tracemonkey/vprof/vprof.h +245 -0
  498. data/vendor/tracemonkey/xpconnect/Makefile.in +67 -0
  499. data/vendor/tracemonkey/xpconnect/crashtests/117307-1.html +20 -0
  500. data/vendor/tracemonkey/xpconnect/crashtests/193710.html +11 -0
  501. data/vendor/tracemonkey/xpconnect/crashtests/290162-1.html +5 -0
  502. data/vendor/tracemonkey/xpconnect/crashtests/326615-1.html +16 -0
  503. data/vendor/tracemonkey/xpconnect/crashtests/328553-1.html +13 -0
  504. data/vendor/tracemonkey/xpconnect/crashtests/346258-1.html +12 -0
  505. data/vendor/tracemonkey/xpconnect/crashtests/346512-1-frame1.xhtml +16 -0
  506. data/vendor/tracemonkey/xpconnect/crashtests/346512-1-frame2.xhtml +15 -0
  507. data/vendor/tracemonkey/xpconnect/crashtests/346512-1.xhtml +30 -0
  508. data/vendor/tracemonkey/xpconnect/crashtests/382133-1.html +3 -0
  509. data/vendor/tracemonkey/xpconnect/crashtests/386680-1.html +22 -0
  510. data/vendor/tracemonkey/xpconnect/crashtests/394810-1.html +4 -0
  511. data/vendor/tracemonkey/xpconnect/crashtests/400349-1.html +20 -0
  512. data/vendor/tracemonkey/xpconnect/crashtests/403356-1.html +13 -0
  513. data/vendor/tracemonkey/xpconnect/crashtests/418139-1.svg +22 -0
  514. data/vendor/tracemonkey/xpconnect/crashtests/420513-1.html +11 -0
  515. data/vendor/tracemonkey/xpconnect/crashtests/453935-1.html +37 -0
  516. data/vendor/tracemonkey/xpconnect/crashtests/462926.html +12 -0
  517. data/vendor/tracemonkey/xpconnect/crashtests/468552-1.html +18 -0
  518. data/vendor/tracemonkey/xpconnect/crashtests/471366-1.html +12 -0
  519. data/vendor/tracemonkey/xpconnect/crashtests/475185-1.html +13 -0
  520. data/vendor/tracemonkey/xpconnect/crashtests/475291-1.html +14 -0
  521. data/vendor/tracemonkey/xpconnect/crashtests/503286-1.html +23 -0
  522. data/vendor/tracemonkey/xpconnect/crashtests/crashtests.list +21 -0
  523. data/vendor/tracemonkey/xpconnect/idl/Makefile.in +78 -0
  524. data/vendor/tracemonkey/xpconnect/idl/XPCIDispatch.idl +51 -0
  525. data/vendor/tracemonkey/xpconnect/idl/mozIJSSubScriptLoader.idl +64 -0
  526. data/vendor/tracemonkey/xpconnect/idl/nsIActiveXSecurityPolicy.idl +67 -0
  527. data/vendor/tracemonkey/xpconnect/idl/nsIDispatchSupport.idl +119 -0
  528. data/vendor/tracemonkey/xpconnect/idl/nsIJSContextStack.idl +85 -0
  529. data/vendor/tracemonkey/xpconnect/idl/nsIJSRuntimeService.idl +51 -0
  530. data/vendor/tracemonkey/xpconnect/idl/nsIScriptError.idl +102 -0
  531. data/vendor/tracemonkey/xpconnect/idl/nsIScriptableInterfaces.idl +67 -0
  532. data/vendor/tracemonkey/xpconnect/idl/nsIXPCScriptNotify.idl +66 -0
  533. data/vendor/tracemonkey/xpconnect/idl/nsIXPCScriptable.idl +183 -0
  534. data/vendor/tracemonkey/xpconnect/idl/nsIXPCSecurityManager.idl +114 -0
  535. data/vendor/tracemonkey/xpconnect/idl/nsIXPConnect.idl +819 -0
  536. data/vendor/tracemonkey/xpconnect/idl/xpcIJSModuleLoader.idl +95 -0
  537. data/vendor/tracemonkey/xpconnect/idl/xpcIJSWeakReference.idl +49 -0
  538. data/vendor/tracemonkey/xpconnect/idl/xpccomponents.idl +254 -0
  539. data/vendor/tracemonkey/xpconnect/idl/xpcexception.idl +66 -0
  540. data/vendor/tracemonkey/xpconnect/idl/xpcjsid.idl +83 -0
  541. data/vendor/tracemonkey/xpconnect/loader/ISO8601DateUtils.jsm +176 -0
  542. data/vendor/tracemonkey/xpconnect/loader/Makefile.in +63 -0
  543. data/vendor/tracemonkey/xpconnect/loader/XPCOMUtils.jsm +267 -0
  544. data/vendor/tracemonkey/xpconnect/loader/mozJSComponentLoader.cpp +1717 -0
  545. data/vendor/tracemonkey/xpconnect/loader/mozJSComponentLoader.h +172 -0
  546. data/vendor/tracemonkey/xpconnect/loader/mozJSLoaderConstructors.h +101 -0
  547. data/vendor/tracemonkey/xpconnect/loader/mozJSSubScriptLoader.cpp +360 -0
  548. data/vendor/tracemonkey/xpconnect/loader/mozJSSubScriptLoader.h +66 -0
  549. data/vendor/tracemonkey/xpconnect/public/Makefile.in +54 -0
  550. data/vendor/tracemonkey/xpconnect/public/nsAXPCNativeCallContext.h +89 -0
  551. data/vendor/tracemonkey/xpconnect/public/nsAutoJSValHolder.h +168 -0
  552. data/vendor/tracemonkey/xpconnect/public/xpc_map_end.h +327 -0
  553. data/vendor/tracemonkey/xpconnect/sample/Makefile.in +71 -0
  554. data/vendor/tracemonkey/xpconnect/sample/README +39 -0
  555. data/vendor/tracemonkey/xpconnect/sample/xpcsample1.cpp +337 -0
  556. data/vendor/tracemonkey/xpconnect/sample/xpcsample1.idl +82 -0
  557. data/vendor/tracemonkey/xpconnect/sample/xpcsample1.js +21 -0
  558. data/vendor/tracemonkey/xpconnect/shell/Makefile.in +106 -0
  559. data/vendor/tracemonkey/xpconnect/shell/jsshell.msg +50 -0
  560. data/vendor/tracemonkey/xpconnect/shell/xpcshell.cpp +1817 -0
  561. data/vendor/tracemonkey/xpconnect/shell/xpcshellMacUtils.h +43 -0
  562. data/vendor/tracemonkey/xpconnect/shell/xpcshellMacUtils.mm +54 -0
  563. data/vendor/tracemonkey/xpconnect/src/Makefile.in +228 -0
  564. data/vendor/tracemonkey/xpconnect/src/README +3 -0
  565. data/vendor/tracemonkey/xpconnect/src/XPCCrossOriginWrapper.cpp +1186 -0
  566. data/vendor/tracemonkey/xpconnect/src/XPCDispConvert.cpp +593 -0
  567. data/vendor/tracemonkey/xpconnect/src/XPCDispInlines.h +667 -0
  568. data/vendor/tracemonkey/xpconnect/src/XPCDispInterface.cpp +383 -0
  569. data/vendor/tracemonkey/xpconnect/src/XPCDispObject.cpp +516 -0
  570. data/vendor/tracemonkey/xpconnect/src/XPCDispParamPropJSClass.cpp +223 -0
  571. data/vendor/tracemonkey/xpconnect/src/XPCDispParams.cpp +103 -0
  572. data/vendor/tracemonkey/xpconnect/src/XPCDispPrivate.h +1401 -0
  573. data/vendor/tracemonkey/xpconnect/src/XPCDispTearOff.cpp +547 -0
  574. data/vendor/tracemonkey/xpconnect/src/XPCDispTypeInfo.cpp +471 -0
  575. data/vendor/tracemonkey/xpconnect/src/XPCIDispatchClassInfo.cpp +139 -0
  576. data/vendor/tracemonkey/xpconnect/src/XPCIDispatchExtension.cpp +362 -0
  577. data/vendor/tracemonkey/xpconnect/src/XPCNativeWrapper.cpp +1350 -0
  578. data/vendor/tracemonkey/xpconnect/src/XPCNativeWrapper.h +88 -0
  579. data/vendor/tracemonkey/xpconnect/src/XPCSafeJSObjectWrapper.cpp +1148 -0
  580. data/vendor/tracemonkey/xpconnect/src/XPCSystemOnlyWrapper.cpp +718 -0
  581. data/vendor/tracemonkey/xpconnect/src/XPCWrapper.cpp +850 -0
  582. data/vendor/tracemonkey/xpconnect/src/XPCWrapper.h +394 -0
  583. data/vendor/tracemonkey/xpconnect/src/dom_quickstubs.qsconf +568 -0
  584. data/vendor/tracemonkey/xpconnect/src/nsDispatchSupport.cpp +348 -0
  585. data/vendor/tracemonkey/xpconnect/src/nsScriptError.cpp +201 -0
  586. data/vendor/tracemonkey/xpconnect/src/nsXPConnect.cpp +2609 -0
  587. data/vendor/tracemonkey/xpconnect/src/qsgen.py +1487 -0
  588. data/vendor/tracemonkey/xpconnect/src/xpc.msg +217 -0
  589. data/vendor/tracemonkey/xpconnect/src/xpcJSWeakReference.cpp +148 -0
  590. data/vendor/tracemonkey/xpconnect/src/xpcJSWeakReference.h +56 -0
  591. data/vendor/tracemonkey/xpconnect/src/xpccallcontext.cpp +579 -0
  592. data/vendor/tracemonkey/xpconnect/src/xpccomponents.cpp +4144 -0
  593. data/vendor/tracemonkey/xpconnect/src/xpccontext.cpp +115 -0
  594. data/vendor/tracemonkey/xpconnect/src/xpcconvert.cpp +2298 -0
  595. data/vendor/tracemonkey/xpconnect/src/xpcdebug.cpp +481 -0
  596. data/vendor/tracemonkey/xpconnect/src/xpcexception.cpp +502 -0
  597. data/vendor/tracemonkey/xpconnect/src/xpcforwards.h +114 -0
  598. data/vendor/tracemonkey/xpconnect/src/xpcinlines.h +772 -0
  599. data/vendor/tracemonkey/xpconnect/src/xpcjsid.cpp +1025 -0
  600. data/vendor/tracemonkey/xpconnect/src/xpcjsruntime.cpp +1342 -0
  601. data/vendor/tracemonkey/xpconnect/src/xpclog.cpp +128 -0
  602. data/vendor/tracemonkey/xpconnect/src/xpclog.h +101 -0
  603. data/vendor/tracemonkey/xpconnect/src/xpcmaps.cpp +761 -0
  604. data/vendor/tracemonkey/xpconnect/src/xpcmaps.h +713 -0
  605. data/vendor/tracemonkey/xpconnect/src/xpcmodule.cpp +136 -0
  606. data/vendor/tracemonkey/xpconnect/src/xpcprivate.h +4138 -0
  607. data/vendor/tracemonkey/xpconnect/src/xpcquickstubs.cpp +1128 -0
  608. data/vendor/tracemonkey/xpconnect/src/xpcquickstubs.h +480 -0
  609. data/vendor/tracemonkey/xpconnect/src/xpcruntimesvc.cpp +179 -0
  610. data/vendor/tracemonkey/xpconnect/src/xpcstack.cpp +342 -0
  611. data/vendor/tracemonkey/xpconnect/src/xpcstring.cpp +139 -0
  612. data/vendor/tracemonkey/xpconnect/src/xpcthreadcontext.cpp +599 -0
  613. data/vendor/tracemonkey/xpconnect/src/xpcthrower.cpp +399 -0
  614. data/vendor/tracemonkey/xpconnect/src/xpcvariant.cpp +850 -0
  615. data/vendor/tracemonkey/xpconnect/src/xpcwrappedjs.cpp +670 -0
  616. data/vendor/tracemonkey/xpconnect/src/xpcwrappedjsclass.cpp +2015 -0
  617. data/vendor/tracemonkey/xpconnect/src/xpcwrappednative.cpp +3482 -0
  618. data/vendor/tracemonkey/xpconnect/src/xpcwrappednativeinfo.cpp +945 -0
  619. data/vendor/tracemonkey/xpconnect/src/xpcwrappednativejsops.cpp +2003 -0
  620. data/vendor/tracemonkey/xpconnect/src/xpcwrappednativeproto.cpp +302 -0
  621. data/vendor/tracemonkey/xpconnect/src/xpcwrappednativescope.cpp +991 -0
  622. data/vendor/tracemonkey/xpconnect/tests/Makefile.in +75 -0
  623. data/vendor/tracemonkey/xpconnect/tests/TestXPC.cpp +785 -0
  624. data/vendor/tracemonkey/xpconnect/tests/chrome/Makefile.in +51 -0
  625. data/vendor/tracemonkey/xpconnect/tests/chrome/test_bug500931.xul +43 -0
  626. data/vendor/tracemonkey/xpconnect/tests/components/Makefile.in +85 -0
  627. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_array.cpp +388 -0
  628. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_attributes.cpp +305 -0
  629. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_calljs.cpp +135 -0
  630. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_child.cpp +225 -0
  631. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_const.cpp +76 -0
  632. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_domstring.cpp +118 -0
  633. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_echo.cpp +616 -0
  634. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_in.cpp +204 -0
  635. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_inout.cpp +171 -0
  636. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_module.cpp +77 -0
  637. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_multiple.cpp +554 -0
  638. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_noisy.cpp +154 -0
  639. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_out.cpp +335 -0
  640. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_overloaded.cpp +250 -0
  641. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_private.h +192 -0
  642. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_string.cpp +185 -0
  643. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_variant.cpp +355 -0
  644. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/StdAfx.cpp +12 -0
  645. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/StdAfx.h +28 -0
  646. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCDispUtilities.h +28 -0
  647. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.cpp +86 -0
  648. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.def +9 -0
  649. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.dsp +318 -0
  650. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.dsw +29 -0
  651. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.idl +454 -0
  652. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.rc +145 -0
  653. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispSimple.cpp +44 -0
  654. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispSimple.h +56 -0
  655. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispSimple.rgs +23 -0
  656. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestArrays.cpp +221 -0
  657. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestArrays.h +53 -0
  658. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestArrays.rgs +23 -0
  659. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestMethods.cpp +699 -0
  660. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestMethods.h +138 -0
  661. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestMethods.rgs +23 -0
  662. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestNoIDispatch.cpp +23 -0
  663. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestNoIDispatch.h +41 -0
  664. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestNoIDispatch.rgs +23 -0
  665. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestProperties.cpp +256 -0
  666. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestProperties.h +88 -0
  667. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestProperties.rgs +23 -0
  668. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOff.cpp +23 -0
  669. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOff.h +43 -0
  670. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOff.rgs +23 -0
  671. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOn.cpp +29 -0
  672. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOn.h +45 -0
  673. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOn.rgs +23 -0
  674. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestWrappedJS.cpp +177 -0
  675. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestWrappedJS.h +50 -0
  676. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestWrappedJS.rgs +23 -0
  677. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/resource.h +36 -0
  678. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/Arrays/XPCIDispatchArrayTests.js +54 -0
  679. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/Attributes/XPCIDispatchAttributeTests.js +150 -0
  680. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/General/XPCIDispatchInstantiations.js +122 -0
  681. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/General/XPCStress.js +58 -0
  682. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/Methods/XPCIDispatchMethodTests.js +376 -0
  683. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/shell.js +377 -0
  684. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedJS/General/XPCIDispatchTestWrappedJS.js +76 -0
  685. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedJS/shell.js +377 -0
  686. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/exectests.cmd +1 -0
  687. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/jsDriver.pl +1288 -0
  688. data/vendor/tracemonkey/xpconnect/tests/idl/Makefile.in +61 -0
  689. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest.idl +312 -0
  690. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest2.idl +51 -0
  691. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_attributes.idl +67 -0
  692. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_calljs.idl +59 -0
  693. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_const.idl +61 -0
  694. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_domstring.idl +59 -0
  695. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_in.idl +88 -0
  696. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_inout.idl +86 -0
  697. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_multiple.idl +77 -0
  698. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_out.idl +142 -0
  699. data/vendor/tracemonkey/xpconnect/tests/js/checkid.js +82 -0
  700. data/vendor/tracemonkey/xpconnect/tests/js/evaluate.js +311 -0
  701. data/vendor/tracemonkey/xpconnect/tests/js/exceptions-2.js +153 -0
  702. data/vendor/tracemonkey/xpconnect/tests/js/exceptions-3.js +194 -0
  703. data/vendor/tracemonkey/xpconnect/tests/js/exceptions-4.js +297 -0
  704. data/vendor/tracemonkey/xpconnect/tests/js/exceptions-5.js +343 -0
  705. data/vendor/tracemonkey/xpconnect/tests/js/exceptions.js +230 -0
  706. data/vendor/tracemonkey/xpconnect/tests/js/javascript.js +96 -0
  707. data/vendor/tracemonkey/xpconnect/tests/js/multiple-2.js +151 -0
  708. data/vendor/tracemonkey/xpconnect/tests/js/multiple-3.js +148 -0
  709. data/vendor/tracemonkey/xpconnect/tests/js/multiple-4.js +152 -0
  710. data/vendor/tracemonkey/xpconnect/tests/js/multiple.js +137 -0
  711. data/vendor/tracemonkey/xpconnect/tests/js/notscriptable.js +104 -0
  712. data/vendor/tracemonkey/xpconnect/tests/js/old/simpletest.js +36 -0
  713. data/vendor/tracemonkey/xpconnect/tests/js/old/speed.js +60 -0
  714. data/vendor/tracemonkey/xpconnect/tests/js/old/testxpc.js +464 -0
  715. data/vendor/tracemonkey/xpconnect/tests/js/old/threads.js +74 -0
  716. data/vendor/tracemonkey/xpconnect/tests/js/old/try.js +27 -0
  717. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_array.js +308 -0
  718. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_callcontext.js +68 -0
  719. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_echo.js +636 -0
  720. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_enum_and_sort.js +28 -0
  721. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_enum_constants.js +15 -0
  722. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_enum_create.js +200 -0
  723. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_exceptions.js +167 -0
  724. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_ids.js +135 -0
  725. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_observer.js +36 -0
  726. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_overloaded.js +14 -0
  727. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_primitives.js +141 -0
  728. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_propertybag.js +36 -0
  729. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_variant.js +339 -0
  730. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_variant_array.js +30 -0
  731. data/vendor/tracemonkey/xpconnect/tests/js/readonlyattributes.js +74 -0
  732. data/vendor/tracemonkey/xpconnect/tests/js/readwriteattributes.js +101 -0
  733. data/vendor/tracemonkey/xpconnect/tests/js/scriptable.js +120 -0
  734. data/vendor/tracemonkey/xpconnect/tests/js/testin.js +203 -0
  735. data/vendor/tracemonkey/xpconnect/tests/js/xpcfun.js +234 -0
  736. data/vendor/tracemonkey/xpconnect/tests/js/xpctest_primitives.js +200 -0
  737. data/vendor/tracemonkey/xpconnect/tests/mochitest/Makefile.in +66 -0
  738. data/vendor/tracemonkey/xpconnect/tests/mochitest/bug500931_helper.html +7 -0
  739. data/vendor/tracemonkey/xpconnect/tests/mochitest/inner.html +7 -0
  740. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug361111.xul +29 -0
  741. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug384632.html +32 -0
  742. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug390488.html +65 -0
  743. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug393269.html +46 -0
  744. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug396851.html +43 -0
  745. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug428021.html +41 -0
  746. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug446584.html +49 -0
  747. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug448587.html +31 -0
  748. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug462428.html +42 -0
  749. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug478438.html +66 -0
  750. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug484107.html +100 -0
  751. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug484459.html +36 -0
  752. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug500691.html +28 -0
  753. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_wrappers.html +116 -0
  754. data/vendor/tracemonkey/xpconnect/tests/unit/bogus_element_type.jsm +1 -0
  755. data/vendor/tracemonkey/xpconnect/tests/unit/bogus_exports_type.jsm +1 -0
  756. data/vendor/tracemonkey/xpconnect/tests/unit/bug451678_subscript.js +2 -0
  757. data/vendor/tracemonkey/xpconnect/tests/unit/component_import.js +144 -0
  758. data/vendor/tracemonkey/xpconnect/tests/unit/recursive_importA.jsm +44 -0
  759. data/vendor/tracemonkey/xpconnect/tests/unit/recursive_importB.jsm +45 -0
  760. data/vendor/tracemonkey/xpconnect/tests/unit/syntax_error.jsm +1 -0
  761. data/vendor/tracemonkey/xpconnect/tests/unit/test_bogus_files.js +88 -0
  762. data/vendor/tracemonkey/xpconnect/tests/unit/test_bug408412.js +51 -0
  763. data/vendor/tracemonkey/xpconnect/tests/unit/test_bug451678.js +52 -0
  764. data/vendor/tracemonkey/xpconnect/tests/unit/test_bug_442086.js +68 -0
  765. data/vendor/tracemonkey/xpconnect/tests/unit/test_import.js +127 -0
  766. data/vendor/tracemonkey/xpconnect/tests/unit/test_js_weak_references.js +63 -0
  767. data/vendor/tracemonkey/xpconnect/tests/unit/test_recursive_import.js +62 -0
  768. data/vendor/tracemonkey/xpconnect/tools/Makefile.in +49 -0
  769. data/vendor/tracemonkey/xpconnect/tools/idl/Makefile.in +53 -0
  770. data/vendor/tracemonkey/xpconnect/tools/idl/nsIXPCToolsCompiler.idl +60 -0
  771. data/vendor/tracemonkey/xpconnect/tools/idl/nsIXPCToolsProfiler.idl +57 -0
  772. data/vendor/tracemonkey/xpconnect/tools/js/CompileJSFiles.js +28 -0
  773. data/vendor/tracemonkey/xpconnect/tools/js/ListJSFiles.js +18 -0
  774. data/vendor/tracemonkey/xpconnect/tools/src/Makefile.in +76 -0
  775. data/vendor/tracemonkey/xpconnect/tools/src/nsXPCToolsCompiler.cpp +161 -0
  776. data/vendor/tracemonkey/xpconnect/tools/src/nsXPCToolsModule.cpp +65 -0
  777. data/vendor/tracemonkey/xpconnect/tools/src/nsXPCToolsProfiler.cpp +370 -0
  778. data/vendor/tracemonkey/xpconnect/tools/src/xpctools_private.h +236 -0
  779. metadata +782 -107
  780. data/test/johnson/nodes/export_test.rb +0 -9
  781. data/test/johnson/nodes/import_test.rb +0 -13
  782. data/test/johnson/version_test.rb +0 -13
@@ -0,0 +1,3482 @@
1
+ /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2
+ * vim: set ts=8 sw=4 et tw=78:
3
+ *
4
+ * ***** BEGIN LICENSE BLOCK *****
5
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6
+ *
7
+ * The contents of this file are subject to the Mozilla Public License Version
8
+ * 1.1 (the "License"); you may not use this file except in compliance with
9
+ * the License. You may obtain a copy of the License at
10
+ * http://www.mozilla.org/MPL/
11
+ *
12
+ * Software distributed under the License is distributed on an "AS IS" basis,
13
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14
+ * for the specific language governing rights and limitations under the
15
+ * License.
16
+ *
17
+ * The Original Code is Mozilla Communicator client code, released
18
+ * March 31, 1998.
19
+ *
20
+ * The Initial Developer of the Original Code is
21
+ * Netscape Communications Corporation.
22
+ * Portions created by the Initial Developer are Copyright (C) 1998
23
+ * the Initial Developer. All Rights Reserved.
24
+ *
25
+ * Contributor(s):
26
+ * John Bandhauer <jband@netscape.com> (original author)
27
+ *
28
+ * Alternatively, the contents of this file may be used under the terms of
29
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
30
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
31
+ * in which case the provisions of the GPL or the LGPL are applicable instead
32
+ * of those above. If you wish to allow use of your version of this file only
33
+ * under the terms of either the GPL or the LGPL, and not to allow others to
34
+ * use your version of this file under the terms of the MPL, indicate your
35
+ * decision by deleting the provisions above and replace them with the notice
36
+ * and other provisions required by the GPL or the LGPL. If you do not delete
37
+ * the provisions above, a recipient may use your version of this file under
38
+ * the terms of any one of the MPL, the GPL or the LGPL.
39
+ *
40
+ * ***** END LICENSE BLOCK ***** */
41
+
42
+ /* Wrapper object for reflecting native xpcom objects into JavaScript. */
43
+
44
+ #include "xpcprivate.h"
45
+ #include "nsCRT.h"
46
+ #include "XPCNativeWrapper.h"
47
+ #include "XPCWrapper.h"
48
+ #include "nsWrapperCache.h"
49
+
50
+ /***************************************************************************/
51
+
52
+ NS_IMPL_CYCLE_COLLECTION_CLASS(XPCWrappedNative)
53
+
54
+ NS_IMETHODIMP
55
+ NS_CYCLE_COLLECTION_CLASSNAME(XPCWrappedNative)::RootAndUnlinkJSObjects(void *p)
56
+ {
57
+ XPCWrappedNative *tmp = static_cast<XPCWrappedNative*>(p);
58
+ tmp->ExpireWrapper();
59
+ return NS_OK;
60
+ }
61
+
62
+
63
+ NS_IMETHODIMP
64
+ NS_CYCLE_COLLECTION_CLASSNAME(XPCWrappedNative)::Traverse(void *p,
65
+ nsCycleCollectionTraversalCallback &cb)
66
+ {
67
+ XPCWrappedNative *tmp = static_cast<XPCWrappedNative*>(p);
68
+ if(!tmp->IsValid())
69
+ return NS_OK;
70
+
71
+ #ifdef DEBUG_CC
72
+ char name[72];
73
+ XPCNativeScriptableInfo* si = tmp->GetScriptableInfo();
74
+ if(si)
75
+ JS_snprintf(name, sizeof(name), "XPCWrappedNative (%s)",
76
+ si->GetJSClass()->name);
77
+ else
78
+ JS_snprintf(name, sizeof(name), "XPCWrappedNative");
79
+
80
+ cb.DescribeNode(RefCounted, tmp->mRefCnt.get(), sizeof(XPCWrappedNative),
81
+ name);
82
+ #else
83
+ cb.DescribeNode(RefCounted, tmp->mRefCnt.get());
84
+ #endif
85
+
86
+ if(tmp->mRefCnt.get() > 1) {
87
+
88
+ // If our refcount is > 1, our reference to the flat JS object is
89
+ // considered "strong", and we're going to traverse it.
90
+ //
91
+ // If our refcount is <= 1, our reference to the flat JS object is
92
+ // considered "weak", and we're *not* going to traverse it.
93
+ //
94
+ // This reasoning is in line with the slightly confusing lifecycle rules
95
+ // for XPCWrappedNatives, described in a larger comment below and also
96
+ // on our wiki at http://wiki.mozilla.org/XPConnect_object_wrapping
97
+
98
+ JSObject *obj = nsnull;
99
+ nsresult rv = tmp->GetJSObject(&obj);
100
+ if(NS_SUCCEEDED(rv))
101
+ cb.NoteScriptChild(nsIProgrammingLanguage::JAVASCRIPT, obj);
102
+ }
103
+
104
+ // XPCWrappedNative keeps its native object alive.
105
+ cb.NoteXPCOMChild(tmp->GetIdentityObject());
106
+
107
+ tmp->NoteTearoffs(cb);
108
+
109
+ return NS_OK;
110
+ }
111
+
112
+ void
113
+ XPCWrappedNative::NoteTearoffs(nsCycleCollectionTraversalCallback& cb)
114
+ {
115
+ // Tearoffs hold their native object alive. If their JS object hasn't been
116
+ // finalized yet we'll note the edge between the JS object and the native
117
+ // (see nsXPConnect::Traverse), but if their JS object has been finalized
118
+ // then the tearoff is only reachable through the XPCWrappedNative, so we
119
+ // record an edge here.
120
+ XPCWrappedNativeTearOffChunk* chunk;
121
+ for(chunk = &mFirstChunk; chunk; chunk = chunk->mNextChunk)
122
+ {
123
+ XPCWrappedNativeTearOff* to = chunk->mTearOffs;
124
+ for(int i = XPC_WRAPPED_NATIVE_TEAROFFS_PER_CHUNK-1; i >= 0; i--, to++)
125
+ {
126
+ JSObject* jso = to->GetJSObject();
127
+ if(!jso)
128
+ {
129
+ cb.NoteXPCOMChild(to->GetNative());
130
+ }
131
+ }
132
+ }
133
+ }
134
+
135
+ #ifdef XPC_CHECK_CLASSINFO_CLAIMS
136
+ static void DEBUG_CheckClassInfoClaims(XPCWrappedNative* wrapper);
137
+ #else
138
+ #define DEBUG_CheckClassInfoClaims(wrapper) ((void)0)
139
+ #endif
140
+
141
+ #ifdef XPC_TRACK_WRAPPER_STATS
142
+ static int DEBUG_TotalWrappedNativeCount;
143
+ static int DEBUG_TotalLiveWrappedNativeCount;
144
+ static int DEBUG_TotalMaxWrappedNativeCount;
145
+ static int DEBUG_WrappedNativeWithProtoCount;
146
+ static int DEBUG_LiveWrappedNativeWithProtoCount;
147
+ static int DEBUG_MaxWrappedNativeWithProtoCount;
148
+ static int DEBUG_WrappedNativeNoProtoCount;
149
+ static int DEBUG_LiveWrappedNativeNoProtoCount;
150
+ static int DEBUG_MaxWrappedNativeNoProtoCount;
151
+ static int DEBUG_WrappedNativeTotalCalls;
152
+ static int DEBUG_WrappedNativeMethodCalls;
153
+ static int DEBUG_WrappedNativeGetterCalls;
154
+ static int DEBUG_WrappedNativeSetterCalls;
155
+ #define DEBUG_CHUNKS_TO_COUNT 4
156
+ static int DEBUG_WrappedNativeTearOffChunkCounts[DEBUG_CHUNKS_TO_COUNT+1];
157
+ static PRBool DEBUG_DumpedWrapperStats;
158
+ #endif
159
+
160
+ #ifdef DEBUG
161
+ static void DEBUG_TrackNewWrapper(XPCWrappedNative* wrapper)
162
+ {
163
+ #ifdef XPC_CHECK_WRAPPERS_AT_SHUTDOWN
164
+ if(wrapper->GetRuntime())
165
+ wrapper->GetRuntime()->DEBUG_AddWrappedNative(wrapper);
166
+ else
167
+ NS_ERROR("failed to add wrapper");
168
+ #endif
169
+ #ifdef XPC_TRACK_WRAPPER_STATS
170
+ DEBUG_TotalWrappedNativeCount++;
171
+ DEBUG_TotalLiveWrappedNativeCount++;
172
+ if(DEBUG_TotalMaxWrappedNativeCount < DEBUG_TotalLiveWrappedNativeCount)
173
+ DEBUG_TotalMaxWrappedNativeCount = DEBUG_TotalLiveWrappedNativeCount;
174
+
175
+ if(wrapper->HasProto())
176
+ {
177
+ DEBUG_WrappedNativeWithProtoCount++;
178
+ DEBUG_LiveWrappedNativeWithProtoCount++;
179
+ if(DEBUG_MaxWrappedNativeWithProtoCount < DEBUG_LiveWrappedNativeWithProtoCount)
180
+ DEBUG_MaxWrappedNativeWithProtoCount = DEBUG_LiveWrappedNativeWithProtoCount;
181
+ }
182
+ else
183
+ {
184
+ DEBUG_WrappedNativeNoProtoCount++;
185
+ DEBUG_LiveWrappedNativeNoProtoCount++;
186
+ if(DEBUG_MaxWrappedNativeNoProtoCount < DEBUG_LiveWrappedNativeNoProtoCount)
187
+ DEBUG_MaxWrappedNativeNoProtoCount = DEBUG_LiveWrappedNativeNoProtoCount;
188
+ }
189
+ #endif
190
+ }
191
+
192
+ static void DEBUG_TrackDeleteWrapper(XPCWrappedNative* wrapper)
193
+ {
194
+ #ifdef XPC_CHECK_WRAPPERS_AT_SHUTDOWN
195
+ nsXPConnect::GetRuntimeInstance()->DEBUG_RemoveWrappedNative(wrapper);
196
+ #endif
197
+ #ifdef XPC_TRACK_WRAPPER_STATS
198
+ DEBUG_TotalLiveWrappedNativeCount--;
199
+ if(wrapper->HasProto())
200
+ DEBUG_LiveWrappedNativeWithProtoCount--;
201
+ else
202
+ DEBUG_LiveWrappedNativeNoProtoCount--;
203
+
204
+ int extraChunkCount = wrapper->DEBUG_CountOfTearoffChunks() - 1;
205
+ if(extraChunkCount > DEBUG_CHUNKS_TO_COUNT)
206
+ extraChunkCount = DEBUG_CHUNKS_TO_COUNT;
207
+ DEBUG_WrappedNativeTearOffChunkCounts[extraChunkCount]++;
208
+ #endif
209
+ }
210
+ static void DEBUG_TrackWrapperCall(XPCWrappedNative* wrapper,
211
+ XPCWrappedNative::CallMode mode)
212
+ {
213
+ #ifdef XPC_TRACK_WRAPPER_STATS
214
+ DEBUG_WrappedNativeTotalCalls++;
215
+ switch(mode)
216
+ {
217
+ case XPCWrappedNative::CALL_METHOD:
218
+ DEBUG_WrappedNativeMethodCalls++;
219
+ break;
220
+ case XPCWrappedNative::CALL_GETTER:
221
+ DEBUG_WrappedNativeGetterCalls++;
222
+ break;
223
+ case XPCWrappedNative::CALL_SETTER:
224
+ DEBUG_WrappedNativeSetterCalls++;
225
+ break;
226
+ default:
227
+ NS_ERROR("bad value");
228
+ }
229
+ #endif
230
+ }
231
+
232
+ static void DEBUG_TrackShutdownWrapper(XPCWrappedNative* wrapper)
233
+ {
234
+ #ifdef XPC_TRACK_WRAPPER_STATS
235
+ if(!DEBUG_DumpedWrapperStats)
236
+ {
237
+ DEBUG_DumpedWrapperStats = PR_TRUE;
238
+ printf("%d WrappedNatives were constructed. "
239
+ "(%d w/ protos, %d w/o)\n",
240
+ DEBUG_TotalWrappedNativeCount,
241
+ DEBUG_WrappedNativeWithProtoCount,
242
+ DEBUG_WrappedNativeNoProtoCount);
243
+
244
+ printf("%d WrappedNatives max alive at one time. "
245
+ "(%d w/ protos, %d w/o)\n",
246
+ DEBUG_TotalMaxWrappedNativeCount,
247
+ DEBUG_MaxWrappedNativeWithProtoCount,
248
+ DEBUG_MaxWrappedNativeNoProtoCount);
249
+
250
+ printf("%d WrappedNatives alive now. "
251
+ "(%d w/ protos, %d w/o)\n",
252
+ DEBUG_TotalLiveWrappedNativeCount,
253
+ DEBUG_LiveWrappedNativeWithProtoCount,
254
+ DEBUG_LiveWrappedNativeNoProtoCount);
255
+
256
+ printf("%d calls to WrappedNatives. "
257
+ "(%d methods, %d getters, %d setters)\n",
258
+ DEBUG_WrappedNativeTotalCalls,
259
+ DEBUG_WrappedNativeMethodCalls,
260
+ DEBUG_WrappedNativeGetterCalls,
261
+ DEBUG_WrappedNativeSetterCalls);
262
+
263
+ printf("(wrappers / tearoffs): (");
264
+ int i;
265
+ for(i = 0; i < DEBUG_CHUNKS_TO_COUNT; i++)
266
+ {
267
+ printf("%d / %d, ",
268
+ DEBUG_WrappedNativeTearOffChunkCounts[i],
269
+ (i+1) * XPC_WRAPPED_NATIVE_TEAROFFS_PER_CHUNK);
270
+ }
271
+ printf("%d / more)\n", DEBUG_WrappedNativeTearOffChunkCounts[i]);
272
+ }
273
+ #endif
274
+ }
275
+ #else
276
+ #define DEBUG_TrackNewWrapper(wrapper) ((void)0)
277
+ #define DEBUG_TrackDeleteWrapper(wrapper) ((void)0)
278
+ #define DEBUG_TrackWrapperCall(wrapper, mode) ((void)0)
279
+ #define DEBUG_TrackShutdownWrapper(wrapper) ((void)0)
280
+ #endif
281
+
282
+ /***************************************************************************/
283
+
284
+ // static
285
+ nsresult
286
+ XPCWrappedNative::GetNewOrUsed(XPCCallContext& ccx,
287
+ nsISupports* Object,
288
+ XPCWrappedNativeScope* Scope,
289
+ XPCNativeInterface* Interface,
290
+ nsWrapperCache *cache,
291
+ JSBool isGlobal,
292
+ XPCWrappedNative** resultWrapper)
293
+ {
294
+ NS_ASSERTION(!cache || !cache->GetWrapper(),
295
+ "We assume the caller already checked if it could get the "
296
+ "wrapper from the cache.");
297
+
298
+ nsresult rv;
299
+
300
+ #ifdef DEBUG
301
+ NS_ASSERTION(!Scope->GetRuntime()->GetThreadRunningGC(),
302
+ "XPCWrappedNative::GetNewOrUsed called during GC");
303
+ {
304
+ nsWrapperCache *cache2 = nsnull;
305
+ CallQueryInterface(Object, &cache2);
306
+ NS_ASSERTION(!cache == !cache2, "Caller should pass in the cache!");
307
+ }
308
+ #endif
309
+
310
+ nsCOMPtr<nsISupports> identity;
311
+ #ifdef XPC_IDISPATCH_SUPPORT
312
+ // XXX This is done for the benefit of some warped COM implementations
313
+ // where QI(IID_IUnknown, a.b) == QI(IID_IUnknown, a). If someone passes
314
+ // in a pointer that hasn't been QI'd to IDispatch properly this could
315
+ // create multiple wrappers for the same object, creating a fair bit of
316
+ // confusion.
317
+ PRBool isIDispatch = Interface &&
318
+ Interface->GetIID()->Equals(NSID_IDISPATCH);
319
+ if(isIDispatch)
320
+ identity = Object;
321
+ else
322
+ #endif
323
+ identity = do_QueryInterface(Object);
324
+
325
+ if(!identity)
326
+ {
327
+ NS_ERROR("This XPCOM object fails in QueryInterface to nsISupports!");
328
+ return NS_ERROR_FAILURE;
329
+ }
330
+
331
+ XPCLock* mapLock = Scope->GetRuntime()->GetMapLock();
332
+
333
+ // We use an AutoMarkingPtr here because it is possible for JS gc to happen
334
+ // after we have Init'd the wrapper but *before* we add it to the hashtable.
335
+ // This would cause the mSet to get collected and we'd later crash. I've
336
+ // *seen* this happen.
337
+ AutoMarkingWrappedNativePtr wrapper(ccx);
338
+
339
+ Native2WrappedNativeMap* map = Scope->GetWrappedNativeMap();
340
+ { // scoped lock
341
+ XPCAutoLock lock(mapLock);
342
+ wrapper = map->Find(identity);
343
+ if(wrapper)
344
+ wrapper->AddRef();
345
+ }
346
+
347
+ if(wrapper)
348
+ {
349
+ if(Interface && !wrapper->FindTearOff(ccx, Interface, JS_FALSE, &rv))
350
+ {
351
+ NS_RELEASE(wrapper);
352
+ NS_ASSERTION(NS_FAILED(rv), "returning NS_OK on failure");
353
+ return rv;
354
+ }
355
+ DEBUG_CheckWrapperThreadSafety(wrapper);
356
+ *resultWrapper = wrapper;
357
+ return NS_OK;
358
+ }
359
+
360
+ // There is a chance that the object wants to have the self-same JSObject
361
+ // reflection regardless of the scope into which we are reflecting it.
362
+ // Many DOM objects require this. The scriptable helper specifies this
363
+ // in preCreate by indicating a 'parent' of a particular scope.
364
+ //
365
+ // To handle this we need to get the scriptable helper early and ask it.
366
+ // It is possible that we will then end up forwarding this entire call
367
+ // to this same function but with a different scope.
368
+
369
+ // If we are making a wrapper for the nsIClassInfo interface then
370
+ // We *don't* want to have it use the prototype meant for instances
371
+ // of that class.
372
+ JSBool isClassInfo = Interface &&
373
+ Interface->GetIID()->Equals(NS_GET_IID(nsIClassInfo));
374
+
375
+ nsCOMPtr<nsIClassInfo> info;
376
+
377
+ if(!isClassInfo)
378
+ info = do_QueryInterface(identity);
379
+
380
+ #ifdef XPC_IDISPATCH_SUPPORT
381
+ // If this is an IDispatch wrapper and it didn't give us a class info
382
+ // we'll provide a default one
383
+ if(isIDispatch && !info)
384
+ {
385
+ info = dont_AddRef(static_cast<nsIClassInfo*>
386
+ (XPCIDispatchClassInfo::GetSingleton()));
387
+ }
388
+ #endif
389
+
390
+ XPCNativeScriptableCreateInfo sciProto;
391
+ XPCNativeScriptableCreateInfo sciWrapper;
392
+
393
+ // Gather scriptable create info if we are wrapping something
394
+ // other than an nsIClassInfo object. We need to not do this for
395
+ // nsIClassInfo objects because often nsIClassInfo implementations
396
+ // are also nsIXPCScriptable helper implmentations, but the helper
397
+ // code is obviously intended for the implementation of the class
398
+ // described by the nsIClassInfo, not for the class info object
399
+ // itself.
400
+ if(!isClassInfo &&
401
+ NS_FAILED(GatherScriptableCreateInfo(identity, info.get(),
402
+ &sciProto, &sciWrapper)))
403
+ return NS_ERROR_FAILURE;
404
+
405
+ JSObject* parent = Scope->GetGlobalJSObject();
406
+
407
+ jsval newParentVal = JSVAL_NULL;
408
+ XPCMarkableJSVal newParentVal_markable(&newParentVal);
409
+ AutoMarkingJSVal newParentVal_automarker(ccx, &newParentVal_markable);
410
+ JSBool chromeOnly = JS_FALSE;
411
+
412
+ if(sciWrapper.GetFlags().WantPreCreate())
413
+ {
414
+ JSObject* plannedParent = parent;
415
+ nsresult rv = sciWrapper.GetCallback()->PreCreate(identity, ccx,
416
+ parent, &parent);
417
+ if(NS_FAILED(rv))
418
+ return rv;
419
+
420
+ chromeOnly = (rv == NS_SUCCESS_CHROME_ACCESS_ONLY);
421
+ rv = NS_OK;
422
+
423
+ NS_ASSERTION(!XPCNativeWrapper::IsNativeWrapper(parent),
424
+ "Parent should never be an XPCNativeWrapper here");
425
+
426
+ if(parent != plannedParent)
427
+ {
428
+ XPCWrappedNativeScope* betterScope =
429
+ XPCWrappedNativeScope::FindInJSObjectScope(ccx, parent);
430
+ if(betterScope != Scope)
431
+ return GetNewOrUsed(ccx, identity, betterScope, Interface,
432
+ cache, isGlobal, resultWrapper);
433
+
434
+ newParentVal = OBJECT_TO_JSVAL(parent);
435
+ }
436
+
437
+ // Take the performance hit of checking the hashtable again in case
438
+ // the preCreate call caused the wrapper to get created through some
439
+ // interesting path (the DOM code tends to make this happen sometimes).
440
+
441
+ { // scoped lock
442
+ XPCAutoLock lock(mapLock);
443
+ wrapper = map->Find(identity);
444
+ if(wrapper)
445
+ wrapper->AddRef();
446
+ }
447
+
448
+ if(wrapper)
449
+ {
450
+ if(Interface && !wrapper->FindTearOff(ccx, Interface, JS_FALSE, &rv))
451
+ {
452
+ NS_RELEASE(wrapper);
453
+ NS_ASSERTION(NS_FAILED(rv), "returning NS_OK on failure");
454
+ return rv;
455
+ }
456
+ DEBUG_CheckWrapperThreadSafety(wrapper);
457
+ *resultWrapper = wrapper;
458
+ return NS_OK;
459
+ }
460
+ }
461
+
462
+ AutoMarkingWrappedNativeProtoPtr proto(ccx);
463
+
464
+ // If there is ClassInfo (and we are not building a wrapper for the
465
+ // nsIClassInfo interface) then we use a wrapper that needs a prototype.
466
+
467
+ // Note that the security check happens inside FindTearOff - after the
468
+ // wrapper is actually created, but before JS code can see it.
469
+
470
+ if(info && !isClassInfo)
471
+ {
472
+ proto = XPCWrappedNativeProto::GetNewOrUsed(ccx, Scope, info, &sciProto,
473
+ JS_FALSE, isGlobal);
474
+ if(!proto)
475
+ return NS_ERROR_FAILURE;
476
+
477
+ proto->CacheOffsets(identity);
478
+
479
+ wrapper = new XPCWrappedNative(identity, proto);
480
+ if(!wrapper)
481
+ return NS_ERROR_FAILURE;
482
+ }
483
+ else
484
+ {
485
+ AutoMarkingNativeInterfacePtr iface(ccx, Interface);
486
+ if(!iface)
487
+ iface = XPCNativeInterface::GetISupports(ccx);
488
+
489
+ AutoMarkingNativeSetPtr set(ccx);
490
+ set = XPCNativeSet::GetNewOrUsed(ccx, nsnull, iface, 0);
491
+
492
+ if(!set)
493
+ return NS_ERROR_FAILURE;
494
+
495
+ wrapper = new XPCWrappedNative(identity, Scope, set);
496
+ if(!wrapper)
497
+ return NS_ERROR_FAILURE;
498
+
499
+ DEBUG_ReportShadowedMembers(set, wrapper, nsnull);
500
+ }
501
+
502
+ NS_ADDREF(wrapper);
503
+
504
+ NS_ASSERTION(!XPCNativeWrapper::IsNativeWrapper(parent),
505
+ "XPCNativeWrapper being used to parent XPCWrappedNative?");
506
+
507
+ if(!wrapper->Init(ccx, parent, isGlobal, &sciWrapper))
508
+ {
509
+ NS_RELEASE(wrapper);
510
+ return NS_ERROR_FAILURE;
511
+ }
512
+
513
+ if(Interface && !wrapper->FindTearOff(ccx, Interface, JS_FALSE, &rv))
514
+ {
515
+ // Second reference will be released by the FlatJSObject's finializer.
516
+ wrapper->Release();
517
+ NS_ASSERTION(NS_FAILED(rv), "returning NS_OK on failure");
518
+ return rv;
519
+ }
520
+
521
+ if(chromeOnly)
522
+ wrapper->SetNeedsChromeWrapper();
523
+
524
+
525
+ #if DEBUG_xpc_leaks
526
+ {
527
+ char* s = wrapper->ToString(ccx);
528
+ NS_ASSERTION(wrapper->GetFlatJSObject(), "eh?");
529
+ printf("Created wrapped native %s, flat JSObject is %p\n",
530
+ s, (void*)wrapper->GetFlatJSObject());
531
+ if(s)
532
+ JS_smprintf_free(s);
533
+ }
534
+ #endif
535
+
536
+ // Redundant wrapper must be killed outside of the map lock.
537
+ XPCWrappedNative* wrapperToKill = nsnull;
538
+
539
+ { // scoped lock
540
+ XPCAutoLock lock(mapLock);
541
+
542
+ // Deal with the case where the wrapper got created as a side effect
543
+ // of one of our calls out of this code (or on another thread).
544
+ XPCWrappedNative* wrapper2 = map->Add(wrapper);
545
+ if(!wrapper2)
546
+ {
547
+ NS_ERROR("failed to add our wrapper!");
548
+ wrapperToKill = wrapper;
549
+ wrapper = nsnull;
550
+ }
551
+ else if(wrapper2 != wrapper)
552
+ {
553
+ NS_ADDREF(wrapper2);
554
+ wrapperToKill = wrapper;
555
+ wrapper = wrapper2;
556
+ }
557
+ }
558
+
559
+ if(wrapperToKill)
560
+ {
561
+ // Second reference will be released by the FlatJSObject's finializer.
562
+ wrapperToKill->Release();
563
+ }
564
+ else if(wrapper)
565
+ {
566
+ if(cache)
567
+ cache->SetWrapper(wrapper);
568
+
569
+ // Our newly created wrapper is the one that we just added to the table.
570
+ // All is well. Call PostCreate as necessary.
571
+ XPCNativeScriptableInfo* si = wrapper->GetScriptableInfo();
572
+ if(si && si->GetFlags().WantPostCreate())
573
+ {
574
+ rv = si->GetCallback()->
575
+ PostCreate(wrapper, ccx, wrapper->GetFlatJSObject());
576
+ if(NS_FAILED(rv))
577
+ {
578
+ // PostCreate failed and that's Very Bad. We'll remove it from
579
+ // the map and mark it as invalid, but the PostCreate function
580
+ // may have handed the partially-constructed-and-now-invalid
581
+ // wrapper to someone before failing. Or, perhaps worse, the
582
+ // PostCreate call could have triggered code that reentered
583
+ // XPConnect and tried to wrap the same object. In that case
584
+ // *we* hand out the invalid wrapper since it is already in our
585
+ // map :(
586
+ NS_ERROR("PostCreate failed! This is known to cause "
587
+ "inconsistent state for some class types and may even "
588
+ "cause a crash in combination with a JS GC. Fix the "
589
+ "failing PostCreate ASAP!");
590
+
591
+ { // scoped lock
592
+ XPCAutoLock lock(mapLock);
593
+ map->Remove(wrapper);
594
+ }
595
+
596
+ // This would be a good place to tell the wrapper not to remove
597
+ // itself from the map when it dies... See bug 429442.
598
+
599
+ if(cache)
600
+ cache->ClearWrapper();
601
+ wrapper->Release();
602
+ return rv;
603
+ }
604
+ }
605
+ }
606
+
607
+ if(!wrapper)
608
+ return NS_ERROR_FAILURE;
609
+
610
+ DEBUG_CheckClassInfoClaims(wrapper);
611
+ *resultWrapper = wrapper;
612
+ return NS_OK;
613
+ }
614
+
615
+ // static
616
+ nsresult
617
+ XPCWrappedNative::GetUsedOnly(XPCCallContext& ccx,
618
+ nsISupports* Object,
619
+ XPCWrappedNativeScope* Scope,
620
+ XPCNativeInterface* Interface,
621
+ XPCWrappedNative** resultWrapper)
622
+ {
623
+ NS_ASSERTION(Object, "XPCWrappedNative::GetUsedOnly was called with a null Object");
624
+
625
+ XPCWrappedNative* wrapper;
626
+ nsWrapperCache* cache = nsnull;
627
+ CallQueryInterface(Object, &cache);
628
+ if(cache)
629
+ {
630
+ wrapper = static_cast<XPCWrappedNative*>(cache->GetWrapper());
631
+ if(!wrapper)
632
+ {
633
+ *resultWrapper = nsnull;
634
+ return NS_OK;
635
+ }
636
+ NS_ADDREF(wrapper);
637
+ }
638
+ else
639
+ {
640
+ nsCOMPtr<nsISupports> identity;
641
+ #ifdef XPC_IDISPATCH_SUPPORT
642
+ // XXX See GetNewOrUsed for more info on this
643
+ if(Interface->GetIID()->Equals(NSID_IDISPATCH))
644
+ identity = Object;
645
+ else
646
+ #endif
647
+ identity = do_QueryInterface(Object);
648
+
649
+ if(!identity)
650
+ {
651
+ NS_ERROR("This XPCOM object fails in QueryInterface to nsISupports!");
652
+ return NS_ERROR_FAILURE;
653
+ }
654
+
655
+ Native2WrappedNativeMap* map = Scope->GetWrappedNativeMap();
656
+
657
+ { // scoped lock
658
+ XPCAutoLock lock(Scope->GetRuntime()->GetMapLock());
659
+ wrapper = map->Find(identity);
660
+ if(!wrapper)
661
+ {
662
+ *resultWrapper = nsnull;
663
+ return NS_OK;
664
+ }
665
+ NS_ADDREF(wrapper);
666
+ }
667
+ }
668
+
669
+ nsresult rv;
670
+ if(Interface && !wrapper->FindTearOff(ccx, Interface, JS_FALSE, &rv))
671
+ {
672
+ NS_RELEASE(wrapper);
673
+ NS_ASSERTION(NS_FAILED(rv), "returning NS_OK on failure");
674
+ return rv;
675
+ }
676
+
677
+ *resultWrapper = wrapper;
678
+ return NS_OK;
679
+ }
680
+
681
+ // This ctor is used if this object will have a proto.
682
+ XPCWrappedNative::XPCWrappedNative(nsISupports* aIdentity,
683
+ XPCWrappedNativeProto* aProto)
684
+ : mMaybeProto(aProto),
685
+ mSet(aProto->GetSet()),
686
+ mFlatJSObject((JSObject*)JSVAL_ONE), // non-null to pass IsValid() test
687
+ mScriptableInfo(nsnull),
688
+ mWrapper(nsnull)
689
+ {
690
+ NS_ADDREF(mIdentity = aIdentity);
691
+
692
+ NS_ASSERTION(mMaybeProto, "bad ctor param");
693
+ NS_ASSERTION(mSet, "bad ctor param");
694
+
695
+ DEBUG_TrackNewWrapper(this);
696
+ }
697
+
698
+ // This ctor is used if this object will NOT have a proto.
699
+ XPCWrappedNative::XPCWrappedNative(nsISupports* aIdentity,
700
+ XPCWrappedNativeScope* aScope,
701
+ XPCNativeSet* aSet)
702
+
703
+ : mMaybeScope(TagScope(aScope)),
704
+ mSet(aSet),
705
+ mFlatJSObject((JSObject*)JSVAL_ONE), // non-null to pass IsValid() test
706
+ mScriptableInfo(nsnull),
707
+ mWrapper(nsnull)
708
+ {
709
+ NS_ADDREF(mIdentity = aIdentity);
710
+
711
+ NS_ASSERTION(aScope, "bad ctor param");
712
+ NS_ASSERTION(aSet, "bad ctor param");
713
+
714
+ DEBUG_TrackNewWrapper(this);
715
+ }
716
+
717
+ XPCWrappedNative::~XPCWrappedNative()
718
+ {
719
+ DEBUG_TrackDeleteWrapper(this);
720
+
721
+ XPCWrappedNativeProto* proto = GetProto();
722
+
723
+ if(mScriptableInfo &&
724
+ (!HasProto() ||
725
+ (proto && proto->GetScriptableInfo() != mScriptableInfo)))
726
+ {
727
+ delete mScriptableInfo;
728
+ }
729
+
730
+ XPCWrappedNativeScope *scope = GetScope();
731
+ if(scope)
732
+ {
733
+ Native2WrappedNativeMap* map = scope->GetWrappedNativeMap();
734
+
735
+ // scoped lock
736
+ XPCAutoLock lock(GetRuntime()->GetMapLock());
737
+
738
+ // Post-1.9 we should not remove this wrapper from the map if it is
739
+ // uninitialized.
740
+ map->Remove(this);
741
+ }
742
+
743
+ if(mIdentity)
744
+ {
745
+ XPCJSRuntime* rt = GetRuntime();
746
+ if(rt && rt->GetDoingFinalization())
747
+ {
748
+ if(!rt->DeferredRelease(mIdentity))
749
+ {
750
+ NS_WARNING("Failed to append object for deferred release.");
751
+ // XXX do we really want to do this???
752
+ NS_RELEASE(mIdentity);
753
+ }
754
+ }
755
+ else
756
+ {
757
+ NS_RELEASE(mIdentity);
758
+ }
759
+ }
760
+ }
761
+
762
+ // This is factored out so that it can be called publicly
763
+ // static
764
+ nsresult
765
+ XPCWrappedNative::GatherProtoScriptableCreateInfo(
766
+ nsIClassInfo* classInfo,
767
+ XPCNativeScriptableCreateInfo* sciProto)
768
+ {
769
+ NS_ASSERTION(classInfo, "bad param");
770
+ NS_ASSERTION(sciProto && !sciProto->GetCallback(), "bad param");
771
+
772
+ nsCOMPtr<nsISupports> possibleHelper;
773
+ nsresult rv = classInfo->GetHelperForLanguage(
774
+ nsIProgrammingLanguage::JAVASCRIPT,
775
+ getter_AddRefs(possibleHelper));
776
+ if(NS_SUCCEEDED(rv) && possibleHelper)
777
+ {
778
+ nsCOMPtr<nsIXPCScriptable> helper(do_QueryInterface(possibleHelper));
779
+ if(helper)
780
+ {
781
+ JSUint32 flags;
782
+ rv = helper->GetScriptableFlags(&flags);
783
+ if(NS_FAILED(rv))
784
+ flags = 0;
785
+
786
+ sciProto->SetCallback(helper);
787
+ sciProto->SetFlags(flags);
788
+ }
789
+ }
790
+ return NS_OK;
791
+ }
792
+
793
+ // static
794
+ nsresult
795
+ XPCWrappedNative::GatherScriptableCreateInfo(
796
+ nsISupports* obj,
797
+ nsIClassInfo* classInfo,
798
+ XPCNativeScriptableCreateInfo* sciProto,
799
+ XPCNativeScriptableCreateInfo* sciWrapper)
800
+ {
801
+ NS_ASSERTION(sciProto && !sciProto->GetCallback(), "bad param");
802
+ NS_ASSERTION(sciWrapper && !sciWrapper->GetCallback(), "bad param");
803
+
804
+ // Get the class scriptable helper (if present)
805
+ if(classInfo)
806
+ {
807
+ GatherProtoScriptableCreateInfo(classInfo, sciProto);
808
+
809
+ sciWrapper->SetCallback(sciProto->GetCallback());
810
+ sciWrapper->SetFlags(sciProto->GetFlags());
811
+
812
+ if(sciProto->GetFlags().DontAskInstanceForScriptable())
813
+ return NS_OK;
814
+ }
815
+
816
+ // Do the same for the wrapper specific scriptable
817
+ nsCOMPtr<nsIXPCScriptable> helper(do_QueryInterface(obj));
818
+ if(helper)
819
+ {
820
+ JSUint32 flags;
821
+ nsresult rv = helper->GetScriptableFlags(&flags);
822
+ if(NS_FAILED(rv))
823
+ flags = 0;
824
+
825
+ sciWrapper->SetCallback(helper);
826
+ sciWrapper->SetFlags(flags);
827
+
828
+ // A whole series of assertions to catch bad uses of scriptable flags on
829
+ // the siWrapper...
830
+
831
+ NS_ASSERTION(!(sciWrapper->GetFlags().WantPreCreate() &&
832
+ !sciProto->GetFlags().WantPreCreate()),
833
+ "Can't set WANT_PRECREATE on an instance scriptable "
834
+ "without also setting it on the class scriptable");
835
+
836
+ NS_ASSERTION(!(sciWrapper->GetFlags().DontEnumStaticProps() &&
837
+ !sciProto->GetFlags().DontEnumStaticProps() &&
838
+ sciProto->GetCallback() &&
839
+ !sciProto->GetFlags().DontSharePrototype()),
840
+ "Can't set DONT_ENUM_STATIC_PROPS on an instance scriptable "
841
+ "without also setting it on the class scriptable (if present and shared)");
842
+
843
+ NS_ASSERTION(!(sciWrapper->GetFlags().DontEnumQueryInterface() &&
844
+ !sciProto->GetFlags().DontEnumQueryInterface() &&
845
+ sciProto->GetCallback() &&
846
+ !sciProto->GetFlags().DontSharePrototype()),
847
+ "Can't set DONT_ENUM_QUERY_INTERFACE on an instance scriptable "
848
+ "without also setting it on the class scriptable (if present and shared)");
849
+
850
+ NS_ASSERTION(!(sciWrapper->GetFlags().DontAskInstanceForScriptable() &&
851
+ !sciProto->GetFlags().DontAskInstanceForScriptable()),
852
+ "Can't set DONT_ASK_INSTANCE_FOR_SCRIPTABLE on an instance scriptable "
853
+ "without also setting it on the class scriptable");
854
+
855
+ NS_ASSERTION(!(sciWrapper->GetFlags().ClassInfoInterfacesOnly() &&
856
+ !sciProto->GetFlags().ClassInfoInterfacesOnly() &&
857
+ sciProto->GetCallback() &&
858
+ !sciProto->GetFlags().DontSharePrototype()),
859
+ "Can't set CLASSINFO_INTERFACES_ONLY on an instance scriptable "
860
+ "without also setting it on the class scriptable (if present and shared)");
861
+
862
+ NS_ASSERTION(!(sciWrapper->GetFlags().AllowPropModsDuringResolve() &&
863
+ !sciProto->GetFlags().AllowPropModsDuringResolve() &&
864
+ sciProto->GetCallback() &&
865
+ !sciProto->GetFlags().DontSharePrototype()),
866
+ "Can't set ALLOW_PROP_MODS_DURING_RESOLVE on an instance scriptable "
867
+ "without also setting it on the class scriptable (if present and shared)");
868
+
869
+ NS_ASSERTION(!(sciWrapper->GetFlags().AllowPropModsToPrototype() &&
870
+ !sciProto->GetFlags().AllowPropModsToPrototype() &&
871
+ sciProto->GetCallback() &&
872
+ !sciProto->GetFlags().DontSharePrototype()),
873
+ "Can't set ALLOW_PROP_MODS_TO_PROTOTYPE on an instance scriptable "
874
+ "without also setting it on the class scriptable (if present and shared)");
875
+
876
+ NS_ASSERTION(!(sciWrapper->GetFlags().DontSharePrototype() &&
877
+ !sciProto->GetFlags().DontSharePrototype() &&
878
+ sciProto->GetCallback()),
879
+ "Can't set DONT_SHARE_PROTOTYPE on an instance scriptable "
880
+ "without also setting it on the class scriptable (if present and shared)");
881
+ }
882
+
883
+ return NS_OK;
884
+ }
885
+
886
+ void
887
+ XPCWrappedNative::TraceOtherWrapper(JSTracer* trc)
888
+ {
889
+ // Note: This isn't wrapped by a MapLock, however, this is normally called
890
+ // during GC, where nobody should be playing with the wrapper map anyway,
891
+ // so this should be OK.
892
+ JSObject *otherWrapper = GetScope()->GetWrapperMap()->Find(mFlatJSObject);
893
+ if(otherWrapper)
894
+ {
895
+ JS_CALL_OBJECT_TRACER(trc, otherWrapper,
896
+ "XPCWrappedNative::mOtherWrapper");
897
+ }
898
+ }
899
+
900
+ JSBool
901
+ XPCWrappedNative::Init(XPCCallContext& ccx, JSObject* parent, JSBool isGlobal,
902
+ const XPCNativeScriptableCreateInfo* sci)
903
+ {
904
+ // setup our scriptable info...
905
+
906
+ if(sci->GetCallback())
907
+ {
908
+ if(HasProto())
909
+ {
910
+ XPCNativeScriptableInfo* siProto = GetProto()->GetScriptableInfo();
911
+ if(siProto && siProto->GetCallback() == sci->GetCallback())
912
+ mScriptableInfo = siProto;
913
+ }
914
+ if(!mScriptableInfo)
915
+ {
916
+ mScriptableInfo =
917
+ XPCNativeScriptableInfo::Construct(ccx, isGlobal, sci);
918
+
919
+ if(!mScriptableInfo)
920
+ return JS_FALSE;
921
+
922
+ // If we have a one-off proto, then it should share our scriptable.
923
+ // This allows the proto's JSClass callbacks to do the right things
924
+ // (like respecting the DONT_ENUM_STATIC_PROPS flag) w/o requiring
925
+ // scriptable objects to have an nsIClassInfo.
926
+ if(HasProto() && !HasSharedProto())
927
+ GetProto()->SetScriptableInfo(mScriptableInfo);
928
+ }
929
+ }
930
+ XPCNativeScriptableInfo* si = mScriptableInfo;
931
+
932
+ // create our flatJSObject
933
+
934
+ JSClass* jsclazz = si ? si->GetJSClass() : &XPC_WN_NoHelper_JSClass.base;
935
+
936
+ if(isGlobal)
937
+ {
938
+ // Resolving a global object's class can cause us to create a global's
939
+ // JS class without the proper global flags. Notice that here and fix
940
+ // the problem.
941
+ if(!(jsclazz->flags & JSCLASS_IS_GLOBAL))
942
+ jsclazz->flags |= JSCLASS_GLOBAL_FLAGS;
943
+ }
944
+ else
945
+ NS_ASSERTION(!(jsclazz->flags & JSCLASS_IS_GLOBAL),
946
+ "Non-global object has the wrong flags");
947
+
948
+ NS_ASSERTION(jsclazz &&
949
+ jsclazz->name &&
950
+ jsclazz->flags &&
951
+ jsclazz->addProperty &&
952
+ jsclazz->delProperty &&
953
+ jsclazz->getProperty &&
954
+ jsclazz->setProperty &&
955
+ jsclazz->enumerate &&
956
+ jsclazz->resolve &&
957
+ jsclazz->convert &&
958
+ jsclazz->finalize, "bad class");
959
+
960
+ JSObject* protoJSObject = HasProto() ?
961
+ GetProto()->GetJSProtoObject() :
962
+ GetScope()->GetPrototypeNoHelper(ccx);
963
+
964
+ if (!protoJSObject) {
965
+ return JS_FALSE;
966
+ }
967
+
968
+ mFlatJSObject = xpc_NewSystemInheritingJSObject(ccx, jsclazz, protoJSObject,
969
+ parent);
970
+ if(!mFlatJSObject)
971
+ return JS_FALSE;
972
+
973
+ // In the current JS engine JS_SetPrivate can't fail. But if it *did*
974
+ // fail then we would not receive our finalizer call and would not be
975
+ // able to properly cleanup. So, if it fails we null out mFlatJSObject
976
+ // to indicate the invalid state of this object and return false.
977
+ if(!JS_SetPrivate(ccx, mFlatJSObject, this))
978
+ {
979
+ mFlatJSObject = nsnull;
980
+ return JS_FALSE;
981
+ }
982
+
983
+ // This reference will be released when mFlatJSObject is finalized.
984
+ // Since this reference will push the refcount to 2 it will also root
985
+ // mFlatJSObject;
986
+ NS_ASSERTION(1 == mRefCnt, "unexpected refcount value");
987
+ NS_ADDREF(this);
988
+
989
+ if(si && si->GetFlags().WantCreate() &&
990
+ NS_FAILED(si->GetCallback()->Create(this, ccx, mFlatJSObject)))
991
+ {
992
+ return JS_FALSE;
993
+ }
994
+
995
+ #ifdef XPC_CHECK_WRAPPER_THREADSAFETY
996
+ mThread = do_GetCurrentThread();
997
+
998
+ if(HasProto() && GetProto()->ClassIsMainThreadOnly() && !NS_IsMainThread())
999
+ DEBUG_ReportWrapperThreadSafetyError(ccx,
1000
+ "MainThread only wrapper created on the wrong thread", this);
1001
+ #endif
1002
+
1003
+ return JS_TRUE;
1004
+ }
1005
+
1006
+
1007
+ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(XPCWrappedNative)
1008
+ NS_INTERFACE_MAP_ENTRY(nsIXPConnectWrappedNative)
1009
+ NS_INTERFACE_MAP_ENTRY(nsIXPConnectJSObjectHolder)
1010
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPConnectWrappedNative)
1011
+ NS_INTERFACE_MAP_END_THREADSAFE
1012
+
1013
+ NS_IMPL_THREADSAFE_ADDREF(XPCWrappedNative)
1014
+ NS_IMPL_THREADSAFE_RELEASE(XPCWrappedNative)
1015
+
1016
+ /*
1017
+ * Wrapped Native lifetime management is messy!
1018
+ *
1019
+ * - At creation we push the refcount to 2 (only one of which is owned by
1020
+ * the native caller that caused the wrapper creation).
1021
+ * - During the JS GC Mark phase we mark any wrapper with a refcount > 1.
1022
+ * - The *only* thing that can make the wrapper get destroyed is the
1023
+ * finalization of mFlatJSObject. And *that* should only happen if the only
1024
+ * reference is the single extra (internal) reference we hold.
1025
+ *
1026
+ * - The wrapper has a pointer to the nsISupports 'view' of the wrapped native
1027
+ * object i.e... mIdentity. This is held until the wrapper's refcount goes
1028
+ * to zero and the wrapper is released.
1029
+ *
1030
+ * - The wrapper also has 'tearoffs'. It has one tearoff for each interface
1031
+ * that is actually used on the native object. 'Used' means we have either
1032
+ * needed to QueryInterface to verify the availability of that interface
1033
+ * of that we've had to QueryInterface in order to actually make a call
1034
+ * into the wrapped object via the pointer for the given interface.
1035
+ *
1036
+ * - Each tearoff's 'mNative' member (if non-null) indicates one reference
1037
+ * held by our wrapper on the wrapped native for the given interface
1038
+ * associated with the tearoff. If we release that reference then we set
1039
+ * the tearoff's 'mNative' to null.
1040
+ *
1041
+ * - We use the occasion of the JavaScript GCCallback for the JSGC_MARK_END
1042
+ * event to scan the tearoffs of all wrappers for non-null mNative members
1043
+ * that represent unused references. We can tell that a given tearoff's
1044
+ * mNative is unused by noting that no live XPCCallContexts hold a pointer
1045
+ * to the tearoff.
1046
+ *
1047
+ * - As a time/space tradeoff we may decide to not do this scanning on
1048
+ * *every* JavaScript GC. We *do* want to do this *sometimes* because
1049
+ * we want to allow for wrapped native's to do their own tearoff patterns.
1050
+ * So, we want to avoid holding references to interfaces that we don't need.
1051
+ * At the same time, we don't want to be bracketing every call into a
1052
+ * wrapped native object with a QueryInterface/Release pair. And we *never*
1053
+ * make a call into the object except via the correct interface for which
1054
+ * we've QI'd.
1055
+ *
1056
+ * - Each tearoff *can* have a mJSObject whose lazily resolved properties
1057
+ * represent the methods/attributes/constants of that specific interface.
1058
+ * This is optionally reflected into JavaScript as "foo.nsIFoo" when "foo"
1059
+ * is the name of mFlatJSObject and "nsIFoo" is the name of the given
1060
+ * interface associated with the tearoff. When we create the tearoff's
1061
+ * mJSObject we set it's parent to be mFlatJSObject. This way we know that
1062
+ * when mFlatJSObject get's collected there are no outstanding reachable
1063
+ * tearoff mJSObjects. Note that we must clear the private of any lingering
1064
+ * mJSObjects at this point because we have no guarentee of the *order* of
1065
+ * finalization within a given gc cycle.
1066
+ */
1067
+
1068
+ void
1069
+ XPCWrappedNative::FlatJSObjectFinalized(JSContext *cx)
1070
+ {
1071
+ if(!IsValid())
1072
+ return;
1073
+
1074
+ // Iterate the tearoffs and null out each of their JSObject's privates.
1075
+ // This will keep them from trying to access their pointers to the
1076
+ // dying tearoff object. We can safely assume that those remaining
1077
+ // JSObjects are about to be finalized too.
1078
+
1079
+ XPCWrappedNativeTearOffChunk* chunk;
1080
+ for(chunk = &mFirstChunk; chunk; chunk = chunk->mNextChunk)
1081
+ {
1082
+ XPCWrappedNativeTearOff* to = chunk->mTearOffs;
1083
+ for(int i = XPC_WRAPPED_NATIVE_TEAROFFS_PER_CHUNK-1; i >= 0; i--, to++)
1084
+ {
1085
+ JSObject* jso = to->GetJSObject();
1086
+ if(jso)
1087
+ {
1088
+ NS_ASSERTION(JS_IsAboutToBeFinalized(cx, jso), "bad!");
1089
+ JS_SetPrivate(cx, jso, nsnull);
1090
+ to->JSObjectFinalized();
1091
+ }
1092
+
1093
+ // We also need to release any native pointers held...
1094
+ nsISupports* obj = to->GetNative();
1095
+ if(obj)
1096
+ {
1097
+ #ifdef XP_WIN
1098
+ // Try to detect free'd pointer
1099
+ NS_ASSERTION(*(int*)obj != 0xdddddddd, "bad pointer!");
1100
+ NS_ASSERTION(*(int*)obj != 0, "bad pointer!");
1101
+ #endif
1102
+ XPCJSRuntime* rt = GetRuntime();
1103
+ if(rt)
1104
+ {
1105
+ if(!rt->DeferredRelease(obj))
1106
+ {
1107
+ NS_WARNING("Failed to append object for deferred release.");
1108
+ // XXX do we really want to do this???
1109
+ obj->Release();
1110
+ }
1111
+ }
1112
+ else
1113
+ {
1114
+ obj->Release();
1115
+ }
1116
+ to->SetNative(nsnull);
1117
+ }
1118
+
1119
+ to->SetInterface(nsnull);
1120
+ }
1121
+ }
1122
+
1123
+ GetScope()->GetWrapperMap()->Remove(mFlatJSObject);
1124
+
1125
+ if(IsWrapperExpired())
1126
+ {
1127
+ GetScope()->GetWrappedNativeMap()->Remove(this);
1128
+
1129
+ XPCWrappedNativeProto* proto = GetProto();
1130
+
1131
+ if(mScriptableInfo &&
1132
+ (!HasProto() ||
1133
+ (proto && proto->GetScriptableInfo() != mScriptableInfo)))
1134
+ {
1135
+ delete mScriptableInfo;
1136
+ mScriptableInfo = nsnull;
1137
+ }
1138
+
1139
+ mMaybeScope = nsnull;
1140
+ }
1141
+
1142
+ nsWrapperCache *cache = nsnull;
1143
+ CallQueryInterface(mIdentity, &cache);
1144
+ if(cache)
1145
+ cache->ClearWrapper();
1146
+
1147
+ // This makes IsValid return false from now on...
1148
+ mFlatJSObject = nsnull;
1149
+
1150
+ NS_ASSERTION(mIdentity, "bad pointer!");
1151
+ #ifdef XP_WIN
1152
+ // Try to detect free'd pointer
1153
+ NS_ASSERTION(*(int*)mIdentity != 0xdddddddd, "bad pointer!");
1154
+ NS_ASSERTION(*(int*)mIdentity != 0, "bad pointer!");
1155
+ #endif
1156
+
1157
+ // Note that it's not safe to touch mNativeWrapper here since it's
1158
+ // likely that it has already been finalized.
1159
+
1160
+ Release();
1161
+ }
1162
+
1163
+ void
1164
+ XPCWrappedNative::SystemIsBeingShutDown(JSContext* cx)
1165
+ {
1166
+ #ifdef DEBUG_xpc_hacker
1167
+ {
1168
+ printf("Removing root for still-live XPCWrappedNative %p wrapping:\n",
1169
+ static_cast<void*>(this));
1170
+ for(PRUint16 i = 0, i_end = mSet->GetInterfaceCount(); i < i_end; ++i)
1171
+ {
1172
+ nsXPIDLCString name;
1173
+ mSet->GetInterfaceAt(i)->GetInterfaceInfo()
1174
+ ->GetName(getter_Copies(name));
1175
+ printf(" %s\n", name.get());
1176
+ }
1177
+ }
1178
+ #endif
1179
+ DEBUG_TrackShutdownWrapper(this);
1180
+
1181
+ if(!IsValid())
1182
+ return;
1183
+
1184
+ // The long standing strategy is to leak some objects still held at shutdown.
1185
+ // The general problem is that propagating release out of xpconnect at
1186
+ // shutdown time causes a world of problems.
1187
+
1188
+ // We leak mIdentity (see above).
1189
+
1190
+ // short circuit future finalization
1191
+ JS_SetPrivate(cx, mFlatJSObject, nsnull);
1192
+ mFlatJSObject = nsnull; // This makes 'IsValid()' return false.
1193
+
1194
+ XPCWrappedNativeProto* proto = GetProto();
1195
+
1196
+ if(HasProto())
1197
+ proto->SystemIsBeingShutDown(cx);
1198
+
1199
+ if(mScriptableInfo &&
1200
+ (!HasProto() ||
1201
+ (proto && proto->GetScriptableInfo() != mScriptableInfo)))
1202
+ {
1203
+ delete mScriptableInfo;
1204
+ }
1205
+
1206
+ // cleanup the tearoffs...
1207
+
1208
+ XPCWrappedNativeTearOffChunk* chunk;
1209
+ for(chunk = &mFirstChunk; chunk; chunk = chunk->mNextChunk)
1210
+ {
1211
+ XPCWrappedNativeTearOff* to = chunk->mTearOffs;
1212
+ for(int i = XPC_WRAPPED_NATIVE_TEAROFFS_PER_CHUNK-1; i >= 0; i--, to++)
1213
+ {
1214
+ if(to->GetJSObject())
1215
+ {
1216
+ JS_SetPrivate(cx, to->GetJSObject(), nsnull);
1217
+ #ifdef XPC_IDISPATCH_SUPPORT
1218
+ if(to->IsIDispatch())
1219
+ delete to->GetIDispatchInfo();
1220
+ #endif
1221
+ to->SetJSObject(nsnull);
1222
+ }
1223
+ // We leak the tearoff mNative
1224
+ // (for the same reason we leak mIdentity - see above).
1225
+ to->SetNative(nsnull);
1226
+ to->SetInterface(nsnull);
1227
+ }
1228
+ }
1229
+
1230
+ if(mFirstChunk.mNextChunk)
1231
+ {
1232
+ delete mFirstChunk.mNextChunk;
1233
+ mFirstChunk.mNextChunk = nsnull;
1234
+ }
1235
+ }
1236
+
1237
+ /***************************************************************************/
1238
+
1239
+ // static
1240
+ nsresult
1241
+ XPCWrappedNative::ReparentWrapperIfFound(XPCCallContext& ccx,
1242
+ XPCWrappedNativeScope* aOldScope,
1243
+ XPCWrappedNativeScope* aNewScope,
1244
+ JSObject* aNewParent,
1245
+ nsISupports* aCOMObj,
1246
+ XPCWrappedNative** aWrapper)
1247
+ {
1248
+ XPCNativeInterface* iface =
1249
+ XPCNativeInterface::GetISupports(ccx);
1250
+
1251
+ if(!iface)
1252
+ return NS_ERROR_FAILURE;
1253
+
1254
+ nsresult rv;
1255
+ XPCWrappedNative* wrapper;
1256
+
1257
+ rv = XPCWrappedNative::GetUsedOnly(ccx, aCOMObj, aOldScope, iface, &wrapper);
1258
+ if(NS_FAILED(rv))
1259
+ return rv;
1260
+
1261
+ if(!wrapper || !wrapper->IsValid())
1262
+ {
1263
+ NS_IF_RELEASE(wrapper);
1264
+ *aWrapper = nsnull;
1265
+ return NS_OK;
1266
+ }
1267
+
1268
+ // ReparentWrapperIfFound is really only meant to be called from DOM code
1269
+ // which must happen only on the main thread. Bail if we're on some other
1270
+ // thread or have a non-main-thread-only wrapper.
1271
+ if (!XPCPerThreadData::IsMainThread(ccx) ||
1272
+ (wrapper->GetProto() &&
1273
+ !wrapper->GetProto()->ClassIsMainThreadOnly())) {
1274
+ NS_RELEASE(wrapper);
1275
+ return NS_ERROR_FAILURE;
1276
+ }
1277
+
1278
+ if(aOldScope != aNewScope)
1279
+ {
1280
+ // Oh, so now we need to move the wrapper to a different scope.
1281
+
1282
+ // First notify any XOWs.
1283
+ nsXPConnect* xpc = nsXPConnect::GetXPConnect();
1284
+ xpc->UpdateXOWs(ccx, wrapper, nsIXPConnect::XPC_XOW_CLEARSCOPE);
1285
+
1286
+ AutoMarkingWrappedNativeProtoPtr oldProto(ccx);
1287
+ AutoMarkingWrappedNativeProtoPtr newProto(ccx);
1288
+
1289
+ if(wrapper->HasProto())
1290
+ {
1291
+ oldProto = wrapper->GetProto();
1292
+ XPCNativeScriptableInfo *info = oldProto->GetScriptableInfo();
1293
+ XPCNativeScriptableCreateInfo ci(*info);
1294
+ newProto =
1295
+ XPCWrappedNativeProto::GetNewOrUsed(ccx, aNewScope,
1296
+ oldProto->GetClassInfo(),
1297
+ &ci,
1298
+ !oldProto->IsShared(),
1299
+ (info->GetJSClass()->flags & JSCLASS_IS_GLOBAL),
1300
+ oldProto->GetOffsetsMasked());
1301
+ if(!newProto)
1302
+ {
1303
+ NS_RELEASE(wrapper);
1304
+ return NS_ERROR_FAILURE;
1305
+ }
1306
+ }
1307
+
1308
+ if(!XPC_XOW_WrapperMoved(ccx, wrapper, aNewScope))
1309
+ {
1310
+ NS_RELEASE(wrapper);
1311
+ return NS_ERROR_FAILURE;
1312
+ }
1313
+
1314
+ Native2WrappedNativeMap* oldMap = aOldScope->GetWrappedNativeMap();
1315
+ Native2WrappedNativeMap* newMap = aNewScope->GetWrappedNativeMap();
1316
+
1317
+ { // scoped lock
1318
+ XPCAutoLock lock(aOldScope->GetRuntime()->GetMapLock());
1319
+
1320
+ oldMap->Remove(wrapper);
1321
+
1322
+ if(wrapper->HasProto())
1323
+ wrapper->SetProto(newProto);
1324
+
1325
+ // If the wrapper has no scriptable or it has a non-shared
1326
+ // scriptable, then we don't need to mess with it.
1327
+ // Otherwise...
1328
+
1329
+ if(wrapper->mScriptableInfo &&
1330
+ wrapper->mScriptableInfo == oldProto->GetScriptableInfo())
1331
+ {
1332
+ // The new proto had better have the same JSClass stuff as the
1333
+ // old one! We maintain a runtime wide unique map of this stuff.
1334
+ // So, if these don't match then the caller is doing something
1335
+ // bad here.
1336
+
1337
+ NS_ASSERTION(
1338
+ oldProto->GetScriptableInfo()->GetScriptableShared() ==
1339
+ newProto->GetScriptableInfo()->GetScriptableShared(),
1340
+ "Changing proto is also changing JSObject Classname or "
1341
+ "helper's nsIXPScriptable flags. This is not allowed!");
1342
+
1343
+ wrapper->mScriptableInfo = newProto->GetScriptableInfo();
1344
+ }
1345
+
1346
+ NS_ASSERTION(!newMap->Find(wrapper->GetIdentityObject()),
1347
+ "wrapper already in new scope!");
1348
+
1349
+ (void) newMap->Add(wrapper);
1350
+ }
1351
+
1352
+ // We only try to fixup the __proto__ JSObject if the wrapper
1353
+ // is directly using that of its XPCWrappedNativeProto.
1354
+
1355
+ if(wrapper->HasProto() &&
1356
+ STOBJ_GET_PROTO(wrapper->GetFlatJSObject()) ==
1357
+ oldProto->GetJSProtoObject())
1358
+ {
1359
+ if(!JS_SetPrototype(ccx, wrapper->GetFlatJSObject(),
1360
+ newProto->GetJSProtoObject()))
1361
+ {
1362
+ // this is bad, very bad
1363
+ NS_ERROR("JS_SetPrototype failed");
1364
+ NS_RELEASE(wrapper);
1365
+ return NS_ERROR_FAILURE;
1366
+ }
1367
+ }
1368
+ else
1369
+ {
1370
+ NS_WARNING("Moving XPConnect wrappedNative to new scope, "
1371
+ "but can't fixup __proto__");
1372
+ }
1373
+ }
1374
+
1375
+ // Now we can just fix up the parent and return the wrapper
1376
+
1377
+ if(!JS_SetParent(ccx, wrapper->GetFlatJSObject(), aNewParent))
1378
+ {
1379
+ NS_RELEASE(wrapper);
1380
+ return NS_ERROR_FAILURE;
1381
+ }
1382
+
1383
+ *aWrapper = wrapper;
1384
+ return NS_OK;
1385
+ }
1386
+
1387
+ #define IS_TEAROFF_CLASS(clazz) \
1388
+ ((clazz) == &XPC_WN_Tearoff_JSClass)
1389
+
1390
+ // static
1391
+ XPCWrappedNative*
1392
+ XPCWrappedNative::GetWrappedNativeOfJSObject(JSContext* cx,
1393
+ JSObject* obj,
1394
+ JSObject* funobj,
1395
+ JSObject** pobj2,
1396
+ XPCWrappedNativeTearOff** pTearOff)
1397
+ {
1398
+ NS_PRECONDITION(obj, "bad param");
1399
+
1400
+ JSObject* cur;
1401
+
1402
+ XPCWrappedNativeProto* proto = nsnull;
1403
+ nsIClassInfo* protoClassInfo = nsnull;
1404
+
1405
+ // If we were passed a function object then we need to find the correct
1406
+ // wrapper out of those that might be in the callee obj's proto chain.
1407
+
1408
+ if(funobj)
1409
+ {
1410
+ JSObject* funObjParent = STOBJ_GET_PARENT(funobj);
1411
+ NS_ASSERTION(funObjParent, "funobj has no parent");
1412
+
1413
+ JSClass* funObjParentClass = STOBJ_GET_CLASS(funObjParent);
1414
+
1415
+ if(IS_PROTO_CLASS(funObjParentClass))
1416
+ {
1417
+ NS_ASSERTION(STOBJ_GET_PARENT(funObjParent), "funobj's parent (proto) is global");
1418
+ proto = (XPCWrappedNativeProto*) xpc_GetJSPrivate(funObjParent);
1419
+ if(proto)
1420
+ protoClassInfo = proto->GetClassInfo();
1421
+ }
1422
+ else if(IS_WRAPPER_CLASS(funObjParentClass))
1423
+ {
1424
+ cur = funObjParent;
1425
+ goto return_wrapper;
1426
+ }
1427
+ else if(IS_TEAROFF_CLASS(funObjParentClass))
1428
+ {
1429
+ NS_ASSERTION(STOBJ_GET_PARENT(funObjParent), "funobj's parent (tearoff) is global");
1430
+ cur = funObjParent;
1431
+ goto return_tearoff;
1432
+ }
1433
+ else
1434
+ {
1435
+ NS_ERROR("function object has parent of unknown class!");
1436
+ return nsnull;
1437
+ }
1438
+ }
1439
+
1440
+ for(cur = obj; cur; cur = STOBJ_GET_PROTO(cur))
1441
+ {
1442
+ // this is on two lines to make the compiler happy given the goto.
1443
+ JSClass* clazz;
1444
+ clazz = STOBJ_GET_CLASS(cur);
1445
+
1446
+ if(IS_WRAPPER_CLASS(clazz))
1447
+ {
1448
+ return_wrapper:
1449
+ XPCWrappedNative* wrapper =
1450
+ (XPCWrappedNative*) xpc_GetJSPrivate(cur);
1451
+ if(proto && proto != wrapper->GetProto() &&
1452
+ (proto->GetScope() != wrapper->GetScope() ||
1453
+ !protoClassInfo || !wrapper->GetProto() ||
1454
+ protoClassInfo != wrapper->GetProto()->GetClassInfo()))
1455
+ continue;
1456
+ if(pobj2)
1457
+ *pobj2 = cur;
1458
+ return wrapper;
1459
+ }
1460
+
1461
+ if(IS_TEAROFF_CLASS(clazz))
1462
+ {
1463
+ return_tearoff:
1464
+ XPCWrappedNative* wrapper =
1465
+ (XPCWrappedNative*) xpc_GetJSPrivate(STOBJ_GET_PARENT(cur));
1466
+ if(proto && proto != wrapper->GetProto() &&
1467
+ (proto->GetScope() != wrapper->GetScope() ||
1468
+ !protoClassInfo || !wrapper->GetProto() ||
1469
+ protoClassInfo != wrapper->GetProto()->GetClassInfo()))
1470
+ continue;
1471
+ if(pobj2)
1472
+ *pobj2 = cur;
1473
+ XPCWrappedNativeTearOff* to =
1474
+ (XPCWrappedNativeTearOff*) xpc_GetJSPrivate(cur);
1475
+ if(!to)
1476
+ return nsnull;
1477
+ if(pTearOff)
1478
+ *pTearOff = to;
1479
+ return wrapper;
1480
+ }
1481
+
1482
+ // Unwrap any wrapper wrappers.
1483
+ JSObject *unsafeObj;
1484
+ if((unsafeObj = XPCWrapper::Unwrap(cx, cur)))
1485
+ return GetWrappedNativeOfJSObject(cx, unsafeObj, funobj, pobj2,
1486
+ pTearOff);
1487
+ }
1488
+
1489
+ // If we didn't find a wrapper using the given funobj and obj, try
1490
+ // again with obj's outer object, if it's got one.
1491
+
1492
+ JSClass *clazz = STOBJ_GET_CLASS(obj);
1493
+
1494
+ if((clazz->flags & JSCLASS_IS_EXTENDED) &&
1495
+ ((JSExtendedClass*)clazz)->outerObject)
1496
+ {
1497
+ JSObject *outer = ((JSExtendedClass*)clazz)->outerObject(cx, obj);
1498
+
1499
+ // Protect against infinite recursion through XOWs.
1500
+ JSObject *unsafeObj;
1501
+ clazz = STOBJ_GET_CLASS(outer);
1502
+ if(clazz == &sXPC_XOW_JSClass.base &&
1503
+ (unsafeObj = XPCWrapper::UnwrapXOW(cx, outer)))
1504
+ {
1505
+ outer = unsafeObj;
1506
+ }
1507
+
1508
+ if(outer && outer != obj)
1509
+ return GetWrappedNativeOfJSObject(cx, outer, funobj, pobj2,
1510
+ pTearOff);
1511
+ }
1512
+
1513
+ if(pobj2)
1514
+ *pobj2 = nsnull;
1515
+ return nsnull;
1516
+ }
1517
+
1518
+ JSBool
1519
+ XPCWrappedNative::ExtendSet(XPCCallContext& ccx, XPCNativeInterface* aInterface)
1520
+ {
1521
+ // This is only called while locked (during XPCWrappedNative::FindTearOff).
1522
+
1523
+ if(!mSet->HasInterface(aInterface))
1524
+ {
1525
+ AutoMarkingNativeSetPtr newSet(ccx);
1526
+ newSet = XPCNativeSet::GetNewOrUsed(ccx, mSet, aInterface,
1527
+ mSet->GetInterfaceCount());
1528
+ if(!newSet)
1529
+ return JS_FALSE;
1530
+
1531
+ mSet = newSet;
1532
+
1533
+ DEBUG_ReportShadowedMembers(newSet, this, GetProto());
1534
+ }
1535
+ return JS_TRUE;
1536
+ }
1537
+
1538
+ XPCWrappedNativeTearOff*
1539
+ XPCWrappedNative::LocateTearOff(XPCCallContext& ccx,
1540
+ XPCNativeInterface* aInterface)
1541
+ {
1542
+ XPCAutoLock al(GetLock()); // hold the lock throughout
1543
+
1544
+ for(
1545
+ XPCWrappedNativeTearOffChunk* chunk = &mFirstChunk;
1546
+ chunk != nsnull;
1547
+ chunk = chunk->mNextChunk)
1548
+ {
1549
+ XPCWrappedNativeTearOff* tearOff = chunk->mTearOffs;
1550
+ XPCWrappedNativeTearOff* const end = tearOff +
1551
+ XPC_WRAPPED_NATIVE_TEAROFFS_PER_CHUNK;
1552
+ for(
1553
+ tearOff = chunk->mTearOffs;
1554
+ tearOff < end;
1555
+ tearOff++)
1556
+ {
1557
+ if(tearOff->GetInterface() == aInterface)
1558
+ {
1559
+ return tearOff;
1560
+ }
1561
+ }
1562
+ }
1563
+ return nsnull;
1564
+ }
1565
+
1566
+ XPCWrappedNativeTearOff*
1567
+ XPCWrappedNative::FindTearOff(XPCCallContext& ccx,
1568
+ XPCNativeInterface* aInterface,
1569
+ JSBool needJSObject /* = JS_FALSE */,
1570
+ nsresult* pError /* = nsnull */)
1571
+ {
1572
+ XPCAutoLock al(GetLock()); // hold the lock throughout
1573
+
1574
+ nsresult rv = NS_OK;
1575
+ XPCWrappedNativeTearOff* to;
1576
+ XPCWrappedNativeTearOff* firstAvailable = nsnull;
1577
+
1578
+ XPCWrappedNativeTearOffChunk* lastChunk;
1579
+ XPCWrappedNativeTearOffChunk* chunk;
1580
+ for(lastChunk = chunk = &mFirstChunk;
1581
+ chunk;
1582
+ lastChunk = chunk, chunk = chunk->mNextChunk)
1583
+ {
1584
+ to = chunk->mTearOffs;
1585
+ XPCWrappedNativeTearOff* const end = chunk->mTearOffs +
1586
+ XPC_WRAPPED_NATIVE_TEAROFFS_PER_CHUNK;
1587
+ for(
1588
+ to = chunk->mTearOffs;
1589
+ to < end;
1590
+ to++)
1591
+ {
1592
+ if(to->GetInterface() == aInterface)
1593
+ {
1594
+ if(needJSObject && !to->GetJSObject())
1595
+ {
1596
+ AutoMarkingWrappedNativeTearOffPtr tearoff(ccx, to);
1597
+ rv = InitTearOffJSObject(ccx, to);
1598
+ // During shutdown, we don't sweep tearoffs. So make sure
1599
+ // to unmark manually in case the auto-marker marked us.
1600
+ // We shouldn't ever be getting here _during_ our
1601
+ // Mark/Sweep cycle, so this should be safe.
1602
+ to->Unmark();
1603
+ if(NS_FAILED(rv))
1604
+ to = nsnull;
1605
+ }
1606
+ goto return_result;
1607
+ }
1608
+ if(!firstAvailable && to->IsAvailable())
1609
+ firstAvailable = to;
1610
+ }
1611
+ }
1612
+
1613
+ to = firstAvailable;
1614
+
1615
+ if(!to)
1616
+ {
1617
+ XPCWrappedNativeTearOffChunk* newChunk =
1618
+ new XPCWrappedNativeTearOffChunk();
1619
+ if(!newChunk)
1620
+ {
1621
+ rv = NS_ERROR_OUT_OF_MEMORY;
1622
+ goto return_result;
1623
+ }
1624
+ lastChunk->mNextChunk = newChunk;
1625
+ to = newChunk->mTearOffs;
1626
+ }
1627
+
1628
+ {
1629
+ // Scope keeps |tearoff| from leaking across the return_result: label
1630
+ AutoMarkingWrappedNativeTearOffPtr tearoff(ccx, to);
1631
+ rv = InitTearOff(ccx, to, aInterface, needJSObject);
1632
+ // During shutdown, we don't sweep tearoffs. So make sure to unmark
1633
+ // manually in case the auto-marker marked us. We shouldn't ever be
1634
+ // getting here _during_ our Mark/Sweep cycle, so this should be safe.
1635
+ to->Unmark();
1636
+ if(NS_FAILED(rv))
1637
+ to = nsnull;
1638
+ }
1639
+
1640
+ return_result:
1641
+
1642
+ if(pError)
1643
+ *pError = rv;
1644
+ return to;
1645
+ }
1646
+
1647
+ nsresult
1648
+ XPCWrappedNative::InitTearOff(XPCCallContext& ccx,
1649
+ XPCWrappedNativeTearOff* aTearOff,
1650
+ XPCNativeInterface* aInterface,
1651
+ JSBool needJSObject)
1652
+ {
1653
+ // This is only called while locked (during XPCWrappedNative::FindTearOff).
1654
+
1655
+ // Determine if the object really does this interface...
1656
+
1657
+ const nsIID* iid = aInterface->GetIID();
1658
+ nsISupports* identity = GetIdentityObject();
1659
+ nsISupports* obj;
1660
+
1661
+ // If the scriptable helper forbids us from reflecting additional
1662
+ // interfaces, then don't even try the QI, just fail.
1663
+ if(mScriptableInfo &&
1664
+ mScriptableInfo->GetFlags().ClassInfoInterfacesOnly() &&
1665
+ !mSet->HasInterface(aInterface) &&
1666
+ !mSet->HasInterfaceWithAncestor(aInterface))
1667
+ {
1668
+ return NS_ERROR_NO_INTERFACE;
1669
+ }
1670
+
1671
+ // We are about to call out to unlock and other code.
1672
+ // So protect our intended tearoff.
1673
+
1674
+ aTearOff->SetReserved();
1675
+
1676
+ { // scoped *un*lock
1677
+ XPCAutoUnlock unlock(GetLock());
1678
+
1679
+ if(NS_FAILED(identity->QueryInterface(*iid, (void**)&obj)) || !obj)
1680
+ {
1681
+ aTearOff->SetInterface(nsnull);
1682
+ return NS_ERROR_NO_INTERFACE;
1683
+ }
1684
+
1685
+ // Guard against trying to build a tearoff for a shared nsIClassInfo.
1686
+ if(iid->Equals(NS_GET_IID(nsIClassInfo)))
1687
+ {
1688
+ nsCOMPtr<nsISupports> alternate_identity(do_QueryInterface(obj));
1689
+ if(alternate_identity.get() != identity)
1690
+ {
1691
+ NS_RELEASE(obj);
1692
+ aTearOff->SetInterface(nsnull);
1693
+ return NS_ERROR_NO_INTERFACE;
1694
+ }
1695
+ }
1696
+
1697
+ // Guard against trying to build a tearoff for an interface that is
1698
+ // aggregated and is implemented as a nsIXPConnectWrappedJS using this
1699
+ // self-same JSObject. The XBL system does this. If we mutate the set
1700
+ // of this wrapper then we will shadow the method that XBL has added to
1701
+ // the JSObject that it has inserted in the JS proto chain between our
1702
+ // JSObject and our XPCWrappedNativeProto's JSObject. If we let this
1703
+ // set mutation happen then the interface's methods will be added to
1704
+ // our JSObject, but calls on those methods will get routed up to
1705
+ // native code and into the wrappedJS - which will do a method lookup
1706
+ // on *our* JSObject and find the same method and make another call
1707
+ // into an infinite loop.
1708
+ // see: http://bugzilla.mozilla.org/show_bug.cgi?id=96725
1709
+
1710
+ // The code in this block also does a check for the double wrapped
1711
+ // nsIPropertyBag case.
1712
+
1713
+ nsCOMPtr<nsIXPConnectWrappedJS> wrappedJS(do_QueryInterface(obj));
1714
+ if(wrappedJS)
1715
+ {
1716
+ JSObject* jso = nsnull;
1717
+ if(NS_SUCCEEDED(wrappedJS->GetJSObject(&jso)) &&
1718
+ jso == GetFlatJSObject())
1719
+ {
1720
+ // The implementing JSObject is the same as ours! Just say OK
1721
+ // without actually extending the set.
1722
+ //
1723
+ // XXX It is a little cheesy to have FindTearOff return an
1724
+ // 'empty' tearoff. But this is the centralized place to do the
1725
+ // QI activities on the underlying object. *And* most caller to
1726
+ // FindTearOff only look for a non-null result and ignore the
1727
+ // actual tearoff returned. The only callers that do use the
1728
+ // returned tearoff make sure to check for either a non-null
1729
+ // JSObject or a matching Interface before proceeding.
1730
+ // I think we can get away with this bit of ugliness.
1731
+
1732
+ #ifdef DEBUG_xpc_hacker
1733
+ {
1734
+ // I want to make sure this only happens in xbl-like cases.
1735
+ // So, some debug code to verify that there is at least
1736
+ // *some* object between our JSObject and its inital proto.
1737
+ // XXX This is a pretty funky test. Someone might hack it
1738
+ // a bit if false positives start showing up. Note that
1739
+ // this is only going to run for the few people in the
1740
+ // DEBUG_xpc_hacker list.
1741
+ if(HasProto())
1742
+ {
1743
+ JSObject* proto = nsnull;
1744
+ JSObject* our_proto = GetProto()->GetJSProtoObject();
1745
+
1746
+ proto = STOBJ_GET_PROTO(jso);
1747
+
1748
+ NS_ASSERTION(proto && proto != our_proto,
1749
+ "!!! xpconnect/xbl check - wrapper has no special proto");
1750
+
1751
+ PRBool found_our_proto = PR_FALSE;
1752
+ while(proto && !found_our_proto) {
1753
+ proto = STOBJ_GET_PROTO(proto);
1754
+
1755
+ found_our_proto = proto == our_proto;
1756
+ }
1757
+
1758
+ NS_ASSERTION(found_our_proto,
1759
+ "!!! xpconnect/xbl check - wrapper has extra proto");
1760
+ }
1761
+ else
1762
+ {
1763
+ NS_WARNING("!!! xpconnect/xbl check - wrapper has no proto");
1764
+ }
1765
+ }
1766
+ #endif
1767
+ NS_RELEASE(obj);
1768
+ aTearOff->SetInterface(nsnull);
1769
+ return NS_OK;
1770
+ }
1771
+
1772
+ // Decide whether or not to expose nsIPropertyBag to calling
1773
+ // JS code in the double wrapped case.
1774
+ //
1775
+ // Our rule here is that when JSObjects are double wrapped and
1776
+ // exposed to other JSObjects then the nsIPropertyBag interface
1777
+ // is only exposed on an 'opt-in' basis; i.e. if the underlying
1778
+ // JSObject wants other JSObjects to be able to see this interface
1779
+ // then it must implement QueryInterface and not throw an exception
1780
+ // when asked for nsIPropertyBag. It need not actually *implement*
1781
+ // nsIPropertyBag - xpconnect will do that work.
1782
+
1783
+ nsXPCWrappedJSClass* clazz;
1784
+ if(iid->Equals(NS_GET_IID(nsIPropertyBag)) && jso &&
1785
+ NS_SUCCEEDED(nsXPCWrappedJSClass::GetNewOrUsed(ccx,*iid,&clazz))&&
1786
+ clazz)
1787
+ {
1788
+ JSObject* answer =
1789
+ clazz->CallQueryInterfaceOnJSObject(ccx, jso, *iid);
1790
+ NS_RELEASE(clazz);
1791
+ if(!answer)
1792
+ {
1793
+ NS_RELEASE(obj);
1794
+ aTearOff->SetInterface(nsnull);
1795
+ return NS_ERROR_NO_INTERFACE;
1796
+ }
1797
+ }
1798
+ }
1799
+
1800
+ nsIXPCSecurityManager* sm;
1801
+ sm = ccx.GetXPCContext()->GetAppropriateSecurityManager(
1802
+ nsIXPCSecurityManager::HOOK_CREATE_WRAPPER);
1803
+ if(sm && NS_FAILED(sm->
1804
+ CanCreateWrapper(ccx, *iid, identity,
1805
+ GetClassInfo(), GetSecurityInfoAddr())))
1806
+ {
1807
+ // the security manager vetoed. It should have set an exception.
1808
+ NS_RELEASE(obj);
1809
+ aTearOff->SetInterface(nsnull);
1810
+ return NS_ERROR_XPC_SECURITY_MANAGER_VETO;
1811
+ }
1812
+ }
1813
+ // We are relocked from here on...
1814
+
1815
+ // If this is not already in our set we need to extend our set.
1816
+ // Note: we do not cache the result of the previous call to HasInterface()
1817
+ // because we unlocked and called out in the interim and the result of the
1818
+ // previous call might not be correct anymore.
1819
+
1820
+ if(!mSet->HasInterface(aInterface) && !ExtendSet(ccx, aInterface))
1821
+ {
1822
+ NS_RELEASE(obj);
1823
+ aTearOff->SetInterface(nsnull);
1824
+ return NS_ERROR_NO_INTERFACE;
1825
+ }
1826
+
1827
+ aTearOff->SetInterface(aInterface);
1828
+ aTearOff->SetNative(obj);
1829
+ #ifdef XPC_IDISPATCH_SUPPORT
1830
+ // Are we building a tearoff for IDispatch?
1831
+ if(iid->Equals(NSID_IDISPATCH))
1832
+ {
1833
+ aTearOff->SetIDispatch(ccx);
1834
+ }
1835
+ #endif
1836
+ if(needJSObject && !InitTearOffJSObject(ccx, aTearOff))
1837
+ return NS_ERROR_OUT_OF_MEMORY;
1838
+
1839
+ return NS_OK;
1840
+ }
1841
+
1842
+ JSBool
1843
+ XPCWrappedNative::InitTearOffJSObject(XPCCallContext& ccx,
1844
+ XPCWrappedNativeTearOff* to)
1845
+ {
1846
+ // This is only called while locked (during XPCWrappedNative::FindTearOff).
1847
+
1848
+ JSObject* obj =
1849
+ xpc_NewSystemInheritingJSObject(ccx, &XPC_WN_Tearoff_JSClass,
1850
+ GetScope()->GetPrototypeJSObject(),
1851
+ mFlatJSObject);
1852
+
1853
+ if(!obj || !JS_SetPrivate(ccx, obj, to))
1854
+ return JS_FALSE;
1855
+
1856
+ to->SetJSObject(obj);
1857
+ return JS_TRUE;
1858
+ }
1859
+
1860
+ /***************************************************************************/
1861
+
1862
+ static JSBool Throw(uintN errNum, XPCCallContext& ccx)
1863
+ {
1864
+ XPCThrower::Throw(errNum, ccx);
1865
+ return JS_FALSE;
1866
+ }
1867
+
1868
+ enum SizeMode {GET_SIZE, GET_LENGTH};
1869
+
1870
+ /***************************************************************************/
1871
+
1872
+ static JSBool
1873
+ GetArraySizeFromParam(XPCCallContext& ccx,
1874
+ nsIInterfaceInfo* ifaceInfo,
1875
+ const nsXPTMethodInfo* methodInfo,
1876
+ const nsXPTParamInfo& paramInfo,
1877
+ uint16 vtblIndex,
1878
+ uint8 paramIndex,
1879
+ SizeMode mode,
1880
+ nsXPTCVariant* dispatchParams,
1881
+ JSUint32* result)
1882
+ {
1883
+ uint8 argnum;
1884
+ nsresult rv;
1885
+
1886
+ // XXX fixup the various exceptions that are thrown
1887
+
1888
+ if(mode == GET_SIZE)
1889
+ rv = ifaceInfo->GetSizeIsArgNumberForParam(vtblIndex, &paramInfo, 0, &argnum);
1890
+ else
1891
+ rv = ifaceInfo->GetLengthIsArgNumberForParam(vtblIndex, &paramInfo, 0, &argnum);
1892
+ if(NS_FAILED(rv))
1893
+ return Throw(NS_ERROR_XPC_CANT_GET_ARRAY_INFO, ccx);
1894
+
1895
+ const nsXPTParamInfo& arg_param = methodInfo->GetParam(argnum);
1896
+ const nsXPTType& arg_type = arg_param.GetType();
1897
+
1898
+ // The xpidl compiler ensures this. We reaffirm it for safety.
1899
+ if(arg_type.IsPointer() || arg_type.TagPart() != nsXPTType::T_U32)
1900
+ return Throw(NS_ERROR_XPC_CANT_GET_ARRAY_INFO, ccx);
1901
+
1902
+ *result = dispatchParams[argnum].val.u32;
1903
+
1904
+ return JS_TRUE;
1905
+ }
1906
+
1907
+
1908
+ static JSBool
1909
+ GetInterfaceTypeFromParam(XPCCallContext& ccx,
1910
+ nsIInterfaceInfo* ifaceInfo,
1911
+ const nsXPTMethodInfo* methodInfo,
1912
+ const nsXPTParamInfo& paramInfo,
1913
+ uint16 vtblIndex,
1914
+ uint8 paramIndex,
1915
+ const nsXPTType& datum_type,
1916
+ nsXPTCVariant* dispatchParams,
1917
+ nsID* result)
1918
+ {
1919
+ uint8 argnum;
1920
+ nsresult rv;
1921
+ uint8 type_tag = datum_type.TagPart();
1922
+
1923
+ // XXX fixup the various exceptions that are thrown
1924
+
1925
+ if(type_tag == nsXPTType::T_INTERFACE)
1926
+ {
1927
+ rv = ifaceInfo->GetIIDForParamNoAlloc(vtblIndex, &paramInfo, result);
1928
+ if(NS_FAILED(rv))
1929
+ return ThrowBadParam(NS_ERROR_XPC_CANT_GET_PARAM_IFACE_INFO, paramIndex, ccx);
1930
+ }
1931
+ else if(type_tag == nsXPTType::T_INTERFACE_IS)
1932
+ {
1933
+ rv = ifaceInfo->GetInterfaceIsArgNumberForParam(vtblIndex, &paramInfo, &argnum);
1934
+ if(NS_FAILED(rv))
1935
+ return Throw(NS_ERROR_XPC_CANT_GET_ARRAY_INFO, ccx);
1936
+
1937
+ const nsXPTParamInfo& arg_param = methodInfo->GetParam(argnum);
1938
+ const nsXPTType& arg_type = arg_param.GetType();
1939
+
1940
+ // The xpidl compiler ensures this. We reaffirm it for safety.
1941
+ if(!arg_type.IsPointer() || arg_type.TagPart() != nsXPTType::T_IID)
1942
+ return ThrowBadParam(NS_ERROR_XPC_CANT_GET_PARAM_IFACE_INFO, paramIndex, ccx);
1943
+
1944
+ nsID* p = (nsID*) dispatchParams[argnum].val.p;
1945
+ if(!p)
1946
+ return ThrowBadParam(NS_ERROR_XPC_CANT_GET_PARAM_IFACE_INFO, paramIndex, ccx);
1947
+ *result = *p;
1948
+ }
1949
+ return JS_TRUE;
1950
+ }
1951
+
1952
+ /***************************************************************************/
1953
+
1954
+ // static
1955
+ NS_SUPPRESS_STACK_CHECK JSBool
1956
+ XPCWrappedNative::CallMethod(XPCCallContext& ccx,
1957
+ CallMode mode /*= CALL_METHOD */)
1958
+ {
1959
+ NS_ASSERTION(ccx.GetXPCContext()->CallerTypeIsJavaScript(),
1960
+ "Native caller for XPCWrappedNative::CallMethod?");
1961
+
1962
+ nsresult rv = ccx.CanCallNow();
1963
+ if(NS_FAILED(rv))
1964
+ {
1965
+ // If the security manager is complaining then this is not really an
1966
+ // internal error in xpconnect. So, no reason to botch the assertion.
1967
+ NS_ASSERTION(rv == NS_ERROR_XPC_SECURITY_MANAGER_VETO,
1968
+ "hmm? CanCallNow failed in XPCWrappedNative::CallMethod. "
1969
+ "We are finding out about this late!");
1970
+ return Throw(rv, ccx);
1971
+ }
1972
+
1973
+ DEBUG_TrackWrapperCall(ccx.GetWrapper(), mode);
1974
+
1975
+ // From here on ALL exits are through 'goto done;'
1976
+
1977
+ #define PARAM_BUFFER_COUNT 8
1978
+
1979
+ nsXPTCVariant paramBuffer[PARAM_BUFFER_COUNT];
1980
+
1981
+ // Reserve space on the stack for one nsAutoString. We don't want
1982
+ // the string itself to be declared on the stack as that would
1983
+ // make the ctor and dtors run for each pass through this code,
1984
+ // and they're only needed in a fraction of all the calls that
1985
+ // come through here.
1986
+ char autoString[sizeof(nsAutoString)];
1987
+ PRBool autoStringUsed = PR_FALSE;
1988
+
1989
+ JSBool retval = JS_FALSE;
1990
+
1991
+ nsXPTCVariant* dispatchParams = nsnull;
1992
+ uint8 i;
1993
+ const nsXPTMethodInfo* methodInfo;
1994
+ uint8 requiredArgs;
1995
+ uint8 paramCount;
1996
+ jsval src;
1997
+ nsresult invokeResult;
1998
+ nsID param_iid;
1999
+ uintN err;
2000
+ nsIXPCSecurityManager* sm;
2001
+ JSBool foundDependentParam;
2002
+
2003
+ XPCJSRuntime* rt = ccx.GetRuntime();
2004
+ XPCContext* xpcc = ccx.GetXPCContext();
2005
+ nsISupports* callee = ccx.GetTearOff()->GetNative();
2006
+ XPCPerThreadData* tls = ccx.GetThreadData();
2007
+ uint16 vtblIndex = ccx.GetMethodIndex();
2008
+ nsIInterfaceInfo* ifaceInfo = ccx.GetInterface()->GetInterfaceInfo();
2009
+ jsval name = ccx.GetMember()->GetName();
2010
+ jsval* argv = ccx.GetArgv();
2011
+ PRUint32 argc = ccx.GetArgc();
2012
+
2013
+ ccx.SetRetVal(JSVAL_VOID);
2014
+
2015
+ tls->SetException(nsnull);
2016
+ xpcc->SetLastResult(NS_ERROR_UNEXPECTED);
2017
+
2018
+ // set up the method index and do the security check if needed
2019
+
2020
+ PRUint32 secFlag;
2021
+ PRUint32 secAction;
2022
+
2023
+ switch(mode)
2024
+ {
2025
+ case CALL_METHOD:
2026
+ secFlag = nsIXPCSecurityManager::HOOK_CALL_METHOD;
2027
+ secAction = nsIXPCSecurityManager::ACCESS_CALL_METHOD;
2028
+ break;
2029
+ case CALL_GETTER:
2030
+ secFlag = nsIXPCSecurityManager::HOOK_GET_PROPERTY;
2031
+ secAction = nsIXPCSecurityManager::ACCESS_GET_PROPERTY;
2032
+ break;
2033
+ case CALL_SETTER:
2034
+ secFlag = nsIXPCSecurityManager::HOOK_SET_PROPERTY;
2035
+ secAction = nsIXPCSecurityManager::ACCESS_SET_PROPERTY;
2036
+ break;
2037
+ default:
2038
+ NS_ASSERTION(0,"bad value");
2039
+ return JS_FALSE;
2040
+ }
2041
+
2042
+ sm = xpcc->GetAppropriateSecurityManager(secFlag);
2043
+ if(sm && NS_FAILED(sm->CanAccess(secAction, &ccx, ccx,
2044
+ ccx.GetFlattenedJSObject(),
2045
+ ccx.GetWrapper()->GetIdentityObject(),
2046
+ ccx.GetWrapper()->GetClassInfo(), name,
2047
+ ccx.GetWrapper()->GetSecurityInfoAddr())))
2048
+ {
2049
+ // the security manager vetoed. It should have set an exception.
2050
+ return JS_FALSE;
2051
+ }
2052
+
2053
+ // fast-path QueryInterface: we already know the signature and can avoid a
2054
+ // lot of work
2055
+ if(vtblIndex == 0)
2056
+ {
2057
+ if(argc < 1)
2058
+ {
2059
+ Throw(NS_ERROR_XPC_NOT_ENOUGH_ARGS, ccx);
2060
+ return JS_FALSE;
2061
+ }
2062
+ const nsID* iid;
2063
+ JSObject* obj;
2064
+ if(!JSVAL_IS_OBJECT(argv[0]) ||
2065
+ (!(obj = JSVAL_TO_OBJECT(argv[0]))) ||
2066
+ (!(iid = xpc_JSObjectToID(ccx, obj))))
2067
+ {
2068
+ ThrowBadParam(NS_ERROR_XPC_BAD_CONVERT_JS, 0, ccx);
2069
+ return JS_FALSE;
2070
+ }
2071
+
2072
+ nsISupports* qiresult = nsnull;
2073
+ {
2074
+ AutoJSSuspendNonMainThreadRequest req(ccx.GetJSContext());
2075
+ invokeResult = callee->QueryInterface(*iid, (void**) &qiresult);
2076
+ }
2077
+
2078
+ xpcc->SetLastResult(invokeResult);
2079
+
2080
+ if(NS_FAILED(invokeResult))
2081
+ {
2082
+ ThrowBadResult(invokeResult, ccx);
2083
+ return JS_FALSE;
2084
+ }
2085
+
2086
+ jsval v = JSVAL_NULL;
2087
+ retval = XPCConvert::NativeData2JS(ccx, &v, &qiresult,
2088
+ nsXPTType::T_INTERFACE_IS | XPT_TDP_POINTER,
2089
+ iid, ccx.GetCurrentJSObject(), &err);
2090
+ NS_IF_RELEASE(qiresult);
2091
+
2092
+ if(!retval)
2093
+ {
2094
+ ThrowBadParam(err, 0, ccx);
2095
+ return JS_FALSE;
2096
+ }
2097
+
2098
+ ccx.SetRetVal(v);
2099
+ return JS_TRUE;
2100
+ }
2101
+
2102
+ if(NS_FAILED(ifaceInfo->GetMethodInfo(vtblIndex, &methodInfo)))
2103
+ {
2104
+ Throw(NS_ERROR_XPC_CANT_GET_METHOD_INFO, ccx);
2105
+ goto done;
2106
+ }
2107
+
2108
+ // XXX ASSUMES that retval is last arg. The xpidl compiler ensures this.
2109
+ paramCount = methodInfo->GetParamCount();
2110
+ requiredArgs = paramCount;
2111
+ if(paramCount && methodInfo->GetParam(paramCount-1).IsRetval())
2112
+ requiredArgs--;
2113
+ if(argc < requiredArgs)
2114
+ {
2115
+ // skip over any optional arguments
2116
+ while(requiredArgs && methodInfo->GetParam(requiredArgs-1).IsOptional())
2117
+ requiredArgs--;
2118
+
2119
+ if(argc < requiredArgs) {
2120
+ Throw(NS_ERROR_XPC_NOT_ENOUGH_ARGS, ccx);
2121
+ goto done;
2122
+ }
2123
+ }
2124
+
2125
+ // setup variant array pointer
2126
+ if(paramCount > PARAM_BUFFER_COUNT)
2127
+ {
2128
+ if(!(dispatchParams = new nsXPTCVariant[paramCount]))
2129
+ {
2130
+ JS_ReportOutOfMemory(ccx);
2131
+ goto done;
2132
+ }
2133
+ }
2134
+ else
2135
+ dispatchParams = paramBuffer;
2136
+
2137
+ // iterate through the params to clear flags (for safe cleanup later)
2138
+ for(i = 0; i < paramCount; i++)
2139
+ {
2140
+ nsXPTCVariant* dp = &dispatchParams[i];
2141
+ dp->ClearFlags();
2142
+ dp->val.p = nsnull;
2143
+ }
2144
+
2145
+ // Iterate through the params doing conversions of independent params only.
2146
+ // When we later convert the dependent params (if any) we will know that
2147
+ // the params upon which they depend will have already been converted -
2148
+ // regardless of ordering.
2149
+ foundDependentParam = JS_FALSE;
2150
+ for(i = 0; i < paramCount; i++)
2151
+ {
2152
+ JSBool useAllocator = JS_FALSE;
2153
+ const nsXPTParamInfo& paramInfo = methodInfo->GetParam(i);
2154
+ const nsXPTType& type = paramInfo.GetType();
2155
+ uint8 type_tag = type.TagPart();
2156
+
2157
+ if(type.IsDependent())
2158
+ {
2159
+ foundDependentParam = JS_TRUE;
2160
+ continue;
2161
+ }
2162
+
2163
+ nsXPTCVariant* dp = &dispatchParams[i];
2164
+ dp->type = type;
2165
+
2166
+ if(type_tag == nsXPTType::T_INTERFACE)
2167
+ {
2168
+ dp->SetValIsInterface();
2169
+ }
2170
+
2171
+ // set 'src' to be the object from which we get the value and
2172
+ // prepare for out param
2173
+
2174
+ if((paramInfo.IsOut() || paramInfo.IsDipper()) &&
2175
+ !paramInfo.IsRetval()) {
2176
+ NS_ASSERTION(i < argc || paramInfo.IsOptional(),
2177
+ "Expected either enough arguments or an optional argument");
2178
+ jsval arg = i < argc ? argv[i] : JSVAL_NULL;
2179
+ if(JSVAL_IS_PRIMITIVE(arg) ||
2180
+ !JS_GetPropertyById(ccx, JSVAL_TO_OBJECT(arg),
2181
+ rt->GetStringID(XPCJSRuntime::IDX_VALUE),
2182
+ &src))
2183
+ {
2184
+ ThrowBadParam(NS_ERROR_XPC_NEED_OUT_OBJECT, i, ccx);
2185
+ goto done;
2186
+ }
2187
+ }
2188
+
2189
+ if(paramInfo.IsOut())
2190
+ {
2191
+ dp->SetPtrIsData();
2192
+ dp->ptr = &dp->val;
2193
+
2194
+ if(type.IsPointer() &&
2195
+ type_tag != nsXPTType::T_INTERFACE &&
2196
+ !paramInfo.IsShared())
2197
+ {
2198
+ useAllocator = JS_TRUE;
2199
+ dp->SetValIsAllocated();
2200
+ }
2201
+
2202
+ if(!paramInfo.IsIn())
2203
+ continue;
2204
+ }
2205
+ else
2206
+ {
2207
+ if(type.IsPointer())
2208
+ {
2209
+ switch(type_tag)
2210
+ {
2211
+ case nsXPTType::T_IID:
2212
+ dp->SetValIsAllocated();
2213
+ useAllocator = JS_TRUE;
2214
+ break;
2215
+
2216
+ case nsXPTType::T_ASTRING:
2217
+ // Fall through to the T_DOMSTRING case
2218
+
2219
+ case nsXPTType::T_DOMSTRING:
2220
+ if(paramInfo.IsDipper())
2221
+ {
2222
+ // Is an 'out' DOMString. Make a new nsAString
2223
+ // now and then continue in order to skip the call to
2224
+ // JSData2Native
2225
+
2226
+ if(!autoStringUsed)
2227
+ {
2228
+ // Our stack space for an nsAutoString is
2229
+ // still available, initialize the string
2230
+ // object (using placement new) and use
2231
+ // it.
2232
+ nsAutoString *s = (nsAutoString*)&autoString;
2233
+ new (s) nsAutoString();
2234
+ autoStringUsed = PR_TRUE;
2235
+
2236
+ // Don't call SetValIsDOMString because we don't
2237
+ // want to delete this pointer.
2238
+ dp->val.p = s;
2239
+ continue;
2240
+ }
2241
+
2242
+ dp->SetValIsDOMString();
2243
+ if(!(dp->val.p = new nsAutoString()))
2244
+ {
2245
+ JS_ReportOutOfMemory(ccx);
2246
+ goto done;
2247
+ }
2248
+ continue;
2249
+ }
2250
+ // else...
2251
+
2252
+ // Is an 'in' DOMString. Set 'useAllocator' to indicate
2253
+ // that JSData2Native should allocate a new
2254
+ // nsAString.
2255
+ dp->SetValIsDOMString();
2256
+ useAllocator = JS_TRUE;
2257
+ break;
2258
+
2259
+ case nsXPTType::T_UTF8STRING:
2260
+ // Fall through to the C string case for now...
2261
+ case nsXPTType::T_CSTRING:
2262
+ dp->SetValIsCString();
2263
+ if(paramInfo.IsDipper())
2264
+ {
2265
+ // Is an 'out' CString.
2266
+ if(!(dp->val.p = new nsCString()))
2267
+ {
2268
+ JS_ReportOutOfMemory(ccx);
2269
+ goto done;
2270
+ }
2271
+ continue;
2272
+ }
2273
+ // else ...
2274
+ // Is an 'in' CString.
2275
+ useAllocator = JS_TRUE;
2276
+ break;
2277
+ }
2278
+ }
2279
+
2280
+ // Do this *after* the above because in the case where we have a
2281
+ // "T_DOMSTRING && IsDipper()" then arg might be null since this
2282
+ // is really an 'out' param masquerading as an 'in' param.
2283
+ NS_ASSERTION(i < argc || paramInfo.IsOptional(),
2284
+ "Expected either enough arguments or an optional argument");
2285
+ src = i < argc ? argv[i] : JSVAL_NULL;
2286
+ }
2287
+
2288
+ if(type_tag == nsXPTType::T_INTERFACE &&
2289
+ NS_FAILED(ifaceInfo->GetIIDForParamNoAlloc(vtblIndex, &paramInfo,
2290
+ &param_iid)))
2291
+ {
2292
+ ThrowBadParam(NS_ERROR_XPC_CANT_GET_PARAM_IFACE_INFO, i, ccx);
2293
+ goto done;
2294
+ }
2295
+
2296
+ if(!XPCConvert::JSData2Native(ccx, &dp->val, src, type,
2297
+ useAllocator, &param_iid, &err))
2298
+ {
2299
+ ThrowBadParam(err, i, ccx);
2300
+ goto done;
2301
+ }
2302
+ }
2303
+
2304
+ // if any params were dependent, then we must iterate again to convert them.
2305
+ if(foundDependentParam)
2306
+ {
2307
+ for(i = 0; i < paramCount; i++)
2308
+ {
2309
+ const nsXPTParamInfo& paramInfo = methodInfo->GetParam(i);
2310
+ const nsXPTType& type = paramInfo.GetType();
2311
+
2312
+ if(!type.IsDependent())
2313
+ continue;
2314
+
2315
+ nsXPTType datum_type;
2316
+ JSUint32 array_count;
2317
+ JSUint32 array_capacity;
2318
+ JSBool useAllocator = JS_FALSE;
2319
+ PRBool isArray = type.IsArray();
2320
+
2321
+ PRBool isSizedString = isArray ?
2322
+ JS_FALSE :
2323
+ type.TagPart() == nsXPTType::T_PSTRING_SIZE_IS ||
2324
+ type.TagPart() == nsXPTType::T_PWSTRING_SIZE_IS;
2325
+
2326
+ nsXPTCVariant* dp = &dispatchParams[i];
2327
+ dp->type = type;
2328
+
2329
+ if(isArray)
2330
+ {
2331
+ dp->SetValIsArray();
2332
+
2333
+ if(NS_FAILED(ifaceInfo->GetTypeForParam(vtblIndex, &paramInfo, 1,
2334
+ &datum_type)))
2335
+ {
2336
+ Throw(NS_ERROR_XPC_CANT_GET_ARRAY_INFO, ccx);
2337
+ goto done;
2338
+ }
2339
+ }
2340
+ else
2341
+ datum_type = type;
2342
+
2343
+ if(datum_type.IsInterfacePointer())
2344
+ {
2345
+ dp->SetValIsInterface();
2346
+ }
2347
+
2348
+ // set 'src' to be the object from which we get the value and
2349
+ // prepare for out param
2350
+
2351
+ if(paramInfo.IsOut())
2352
+ {
2353
+ dp->SetPtrIsData();
2354
+ dp->ptr = &dp->val;
2355
+
2356
+ if(!paramInfo.IsRetval()) {
2357
+ NS_ASSERTION(i < argc || paramInfo.IsOptional(),
2358
+ "Expected either enough arguments or an optional argument");
2359
+ jsval arg = i < argc ? argv[i] : JSVAL_NULL;
2360
+ if(JSVAL_IS_PRIMITIVE(arg) ||
2361
+ !JS_GetPropertyById(ccx, JSVAL_TO_OBJECT(arg),
2362
+ rt->GetStringID(XPCJSRuntime::IDX_VALUE), &src))
2363
+ {
2364
+ ThrowBadParam(NS_ERROR_XPC_NEED_OUT_OBJECT, i, ccx);
2365
+ goto done;
2366
+ }
2367
+ }
2368
+
2369
+ if(datum_type.IsPointer() &&
2370
+ !datum_type.IsInterfacePointer() &&
2371
+ (isArray || !paramInfo.IsShared()))
2372
+ {
2373
+ useAllocator = JS_TRUE;
2374
+ dp->SetValIsAllocated();
2375
+ }
2376
+
2377
+ if(!paramInfo.IsIn())
2378
+ continue;
2379
+ }
2380
+ else
2381
+ {
2382
+ NS_ASSERTION(i < argc || paramInfo.IsOptional(),
2383
+ "Expected either enough arguments or an optional argument");
2384
+ src = i < argc ? argv[i] : JSVAL_NULL;
2385
+
2386
+ if(datum_type.IsPointer() &&
2387
+ datum_type.TagPart() == nsXPTType::T_IID)
2388
+ {
2389
+ useAllocator = JS_TRUE;
2390
+ dp->SetValIsAllocated();
2391
+ }
2392
+ }
2393
+
2394
+ if(datum_type.IsInterfacePointer() &&
2395
+ !GetInterfaceTypeFromParam(ccx, ifaceInfo, methodInfo, paramInfo,
2396
+ vtblIndex, i, datum_type,
2397
+ dispatchParams, &param_iid))
2398
+ goto done;
2399
+
2400
+ if(isArray || isSizedString)
2401
+ {
2402
+ if(!GetArraySizeFromParam(ccx, ifaceInfo, methodInfo, paramInfo,
2403
+ vtblIndex, i, GET_SIZE,
2404
+ dispatchParams, &array_capacity)||
2405
+ !GetArraySizeFromParam(ccx, ifaceInfo, methodInfo, paramInfo,
2406
+ vtblIndex, i, GET_LENGTH,
2407
+ dispatchParams, &array_count))
2408
+ goto done;
2409
+
2410
+ if(isArray)
2411
+ {
2412
+ if(array_count &&
2413
+ !XPCConvert::JSArray2Native(ccx, (void**)&dp->val, src,
2414
+ array_count, array_capacity,
2415
+ datum_type,
2416
+ useAllocator,
2417
+ &param_iid, &err))
2418
+ {
2419
+ // XXX need exception scheme for arrays to indicate bad element
2420
+ ThrowBadParam(err, i, ccx);
2421
+ goto done;
2422
+ }
2423
+ }
2424
+ else // if(isSizedString)
2425
+ {
2426
+ if(!XPCConvert::JSStringWithSize2Native(ccx,
2427
+ (void*)&dp->val,
2428
+ src,
2429
+ array_count, array_capacity,
2430
+ datum_type, useAllocator,
2431
+ &err))
2432
+ {
2433
+ ThrowBadParam(err, i, ccx);
2434
+ goto done;
2435
+ }
2436
+ }
2437
+ }
2438
+ else
2439
+ {
2440
+ if(!XPCConvert::JSData2Native(ccx, &dp->val, src, type,
2441
+ useAllocator, &param_iid,
2442
+ &err))
2443
+ {
2444
+ ThrowBadParam(err, i, ccx);
2445
+ goto done;
2446
+ }
2447
+ }
2448
+ }
2449
+ }
2450
+
2451
+
2452
+ // do the invoke
2453
+ {
2454
+ AutoJSSuspendNonMainThreadRequest req(ccx.GetJSContext());
2455
+ invokeResult = NS_InvokeByIndex(callee, vtblIndex, paramCount,
2456
+ dispatchParams);
2457
+ }
2458
+
2459
+ xpcc->SetLastResult(invokeResult);
2460
+
2461
+ if(NS_FAILED(invokeResult))
2462
+ {
2463
+ ThrowBadResult(invokeResult, ccx);
2464
+ goto done;
2465
+ }
2466
+ else if(JS_IsExceptionPending(ccx))
2467
+ {
2468
+ goto done;
2469
+ }
2470
+
2471
+ // now we iterate through the native params to gather and convert results
2472
+ for(i = 0; i < paramCount; i++)
2473
+ {
2474
+ const nsXPTParamInfo& paramInfo = methodInfo->GetParam(i);
2475
+ if(!paramInfo.IsOut() && !paramInfo.IsDipper())
2476
+ continue;
2477
+
2478
+ const nsXPTType& type = paramInfo.GetType();
2479
+ nsXPTCVariant* dp = &dispatchParams[i];
2480
+ jsval v = JSVAL_NULL;
2481
+ AUTO_MARK_JSVAL(ccx, &v);
2482
+ JSUint32 array_count;
2483
+ nsXPTType datum_type;
2484
+ PRBool isArray = type.IsArray();
2485
+ PRBool isSizedString = isArray ?
2486
+ JS_FALSE :
2487
+ type.TagPart() == nsXPTType::T_PSTRING_SIZE_IS ||
2488
+ type.TagPart() == nsXPTType::T_PWSTRING_SIZE_IS;
2489
+
2490
+ if(isArray)
2491
+ {
2492
+ if(NS_FAILED(ifaceInfo->GetTypeForParam(vtblIndex, &paramInfo, 1,
2493
+ &datum_type)))
2494
+ {
2495
+ Throw(NS_ERROR_XPC_CANT_GET_ARRAY_INFO, ccx);
2496
+ goto done;
2497
+ }
2498
+ }
2499
+ else
2500
+ datum_type = type;
2501
+
2502
+ if(isArray || isSizedString)
2503
+ {
2504
+ if(!GetArraySizeFromParam(ccx, ifaceInfo, methodInfo, paramInfo,
2505
+ vtblIndex, i, GET_LENGTH, dispatchParams,
2506
+ &array_count))
2507
+ goto done;
2508
+ }
2509
+
2510
+ if(datum_type.IsInterfacePointer() &&
2511
+ !GetInterfaceTypeFromParam(ccx, ifaceInfo, methodInfo, paramInfo,
2512
+ vtblIndex, i, datum_type, dispatchParams,
2513
+ &param_iid))
2514
+ goto done;
2515
+
2516
+ if(isArray)
2517
+ {
2518
+ if(!XPCConvert::NativeArray2JS(ccx, &v, (const void**)&dp->val,
2519
+ datum_type, &param_iid,
2520
+ array_count, ccx.GetCurrentJSObject(),
2521
+ &err))
2522
+ {
2523
+ // XXX need exception scheme for arrays to indicate bad element
2524
+ ThrowBadParam(err, i, ccx);
2525
+ goto done;
2526
+ }
2527
+ }
2528
+ else if(isSizedString)
2529
+ {
2530
+ if(!XPCConvert::NativeStringWithSize2JS(ccx, &v,
2531
+ (const void*)&dp->val,
2532
+ datum_type,
2533
+ array_count, &err))
2534
+ {
2535
+ ThrowBadParam(err, i, ccx);
2536
+ goto done;
2537
+ }
2538
+ }
2539
+ else
2540
+ {
2541
+ if(!XPCConvert::NativeData2JS(ccx, &v, &dp->val, datum_type,
2542
+ &param_iid,
2543
+ ccx.GetCurrentJSObject(), &err))
2544
+ {
2545
+ ThrowBadParam(err, i, ccx);
2546
+ goto done;
2547
+ }
2548
+ }
2549
+
2550
+ if(paramInfo.IsRetval())
2551
+ {
2552
+ if(!ccx.GetReturnValueWasSet())
2553
+ ccx.SetRetVal(v);
2554
+ }
2555
+ else if(i < argc)
2556
+ {
2557
+ // we actually assured this before doing the invoke
2558
+ NS_ASSERTION(JSVAL_IS_OBJECT(argv[i]), "out var is not object");
2559
+ if(!JS_SetPropertyById(ccx, JSVAL_TO_OBJECT(argv[i]),
2560
+ rt->GetStringID(XPCJSRuntime::IDX_VALUE), &v))
2561
+ {
2562
+ ThrowBadParam(NS_ERROR_XPC_CANT_SET_OUT_VAL, i, ccx);
2563
+ goto done;
2564
+ }
2565
+ }
2566
+ else
2567
+ {
2568
+ NS_ASSERTION(paramInfo.IsOptional(),
2569
+ "Expected either enough arguments or an optional argument");
2570
+ }
2571
+ }
2572
+
2573
+ retval = JS_TRUE;
2574
+ done:
2575
+ // iterate through the params (again!) and clean up
2576
+ // any alloc'd stuff and release wrappers of params
2577
+ if(dispatchParams)
2578
+ {
2579
+ for(i = 0; i < paramCount; i++)
2580
+ {
2581
+ nsXPTCVariant* dp = &dispatchParams[i];
2582
+ void* p = dp->val.p;
2583
+ if(!p)
2584
+ continue;
2585
+
2586
+ if(dp->IsValArray())
2587
+ {
2588
+ // going to have to cleanup the array and perhaps its contents
2589
+ if(dp->IsValAllocated() || dp->IsValInterface())
2590
+ {
2591
+ // we need to figure out how many elements are present.
2592
+ JSUint32 array_count;
2593
+
2594
+ const nsXPTParamInfo& paramInfo = methodInfo->GetParam(i);
2595
+ if(!GetArraySizeFromParam(ccx, ifaceInfo, methodInfo,
2596
+ paramInfo, vtblIndex,
2597
+ i, GET_LENGTH, dispatchParams,
2598
+ &array_count))
2599
+ {
2600
+ NS_ASSERTION(0,"failed to get array length, we'll leak here");
2601
+ continue;
2602
+ }
2603
+ if(dp->IsValAllocated())
2604
+ {
2605
+ void** a = (void**)p;
2606
+ for(JSUint32 k = 0; k < array_count; k++)
2607
+ {
2608
+ void* o = a[k];
2609
+ if(o) nsMemory::Free(o);
2610
+ }
2611
+ }
2612
+ else // if(dp->IsValInterface())
2613
+ {
2614
+ nsISupports** a = (nsISupports**)p;
2615
+ for(JSUint32 k = 0; k < array_count; k++)
2616
+ {
2617
+ nsISupports* o = a[k];
2618
+ NS_IF_RELEASE(o);
2619
+ }
2620
+ }
2621
+ }
2622
+ // always free the array itself
2623
+ nsMemory::Free(p);
2624
+ }
2625
+ else if(dp->IsValAllocated())
2626
+ nsMemory::Free(p);
2627
+ else if(dp->IsValInterface())
2628
+ ((nsISupports*)p)->Release();
2629
+ else if(dp->IsValDOMString())
2630
+ ccx.DeleteString((nsAString*)p);
2631
+ else if(dp->IsValUTF8String())
2632
+ delete (nsCString*) p;
2633
+ else if(dp->IsValCString())
2634
+ delete (nsCString*) p;
2635
+ }
2636
+ }
2637
+
2638
+ if (autoStringUsed) {
2639
+ // Our stack based nsAutoString was used, clean it up.
2640
+
2641
+ nsAutoString *s = (nsAutoString*)&autoString;
2642
+
2643
+ s->~nsAutoString();
2644
+ }
2645
+
2646
+ if(dispatchParams && dispatchParams != paramBuffer)
2647
+ delete [] dispatchParams;
2648
+
2649
+ return retval;
2650
+ }
2651
+
2652
+ /***************************************************************************/
2653
+ // interface methods
2654
+
2655
+ /* readonly attribute JSObjectPtr JSObject; */
2656
+ NS_IMETHODIMP XPCWrappedNative::GetJSObject(JSObject * *aJSObject)
2657
+ {
2658
+ *aJSObject = mFlatJSObject;
2659
+ return NS_OK;
2660
+ }
2661
+
2662
+ /* readonly attribute nsISupports Native; */
2663
+ NS_IMETHODIMP XPCWrappedNative::GetNative(nsISupports * *aNative)
2664
+ {
2665
+ // No need to QI here, we already have the correct nsISupports
2666
+ // vtable.
2667
+ *aNative = mIdentity;
2668
+ NS_ADDREF(*aNative);
2669
+ return NS_OK;
2670
+ }
2671
+
2672
+ /* readonly attribute JSObjectPtr JSObjectPrototype; */
2673
+ NS_IMETHODIMP XPCWrappedNative::GetJSObjectPrototype(JSObject * *aJSObjectPrototype)
2674
+ {
2675
+ *aJSObjectPrototype = HasProto() ?
2676
+ GetProto()->GetJSProtoObject() : GetFlatJSObject();
2677
+ return NS_OK;
2678
+ }
2679
+
2680
+ #ifndef XPCONNECT_STANDALONE
2681
+ nsIPrincipal*
2682
+ XPCWrappedNative::GetObjectPrincipal() const
2683
+ {
2684
+ nsIPrincipal* principal = GetScope()->GetPrincipal();
2685
+ #ifdef DEBUG
2686
+ nsCOMPtr<nsIScriptObjectPrincipal> objPrin(do_QueryInterface(mIdentity));
2687
+ NS_ASSERTION(!objPrin || objPrin->GetPrincipal() == principal,
2688
+ "Principal mismatch. Expect bad things to happen");
2689
+ #endif
2690
+ return principal;
2691
+ }
2692
+ #endif
2693
+
2694
+ /* readonly attribute nsIXPConnect XPConnect; */
2695
+ NS_IMETHODIMP XPCWrappedNative::GetXPConnect(nsIXPConnect * *aXPConnect)
2696
+ {
2697
+ if(IsValid())
2698
+ {
2699
+ nsIXPConnect* temp = GetRuntime()->GetXPConnect();
2700
+ NS_IF_ADDREF(temp);
2701
+ *aXPConnect = temp;
2702
+ }
2703
+ else
2704
+ *aXPConnect = nsnull;
2705
+ return NS_OK;
2706
+ }
2707
+
2708
+ /* XPCNativeInterface FindInterfaceWithMember (in JSVal name); */
2709
+ NS_IMETHODIMP XPCWrappedNative::FindInterfaceWithMember(jsval name, nsIInterfaceInfo * *_retval)
2710
+ {
2711
+ XPCNativeInterface* iface;
2712
+ XPCNativeMember* member;
2713
+
2714
+ if(GetSet()->FindMember(name, &member, &iface) && iface)
2715
+ {
2716
+ nsIInterfaceInfo* temp = iface->GetInterfaceInfo();
2717
+ NS_IF_ADDREF(temp);
2718
+ *_retval = temp;
2719
+ }
2720
+ else
2721
+ *_retval = nsnull;
2722
+ return NS_OK;
2723
+ }
2724
+
2725
+ /* XPCNativeInterface FindInterfaceWithName (in JSVal name); */
2726
+ NS_IMETHODIMP XPCWrappedNative::FindInterfaceWithName(jsval name, nsIInterfaceInfo * *_retval)
2727
+ {
2728
+ XPCNativeInterface* iface = GetSet()->FindNamedInterface(name);
2729
+ if(iface)
2730
+ {
2731
+ nsIInterfaceInfo* temp = iface->GetInterfaceInfo();
2732
+ NS_IF_ADDREF(temp);
2733
+ *_retval = temp;
2734
+ }
2735
+ else
2736
+ *_retval = nsnull;
2737
+ return NS_OK;
2738
+ }
2739
+
2740
+ inline nsresult UnexpectedFailure(nsresult rv)
2741
+ {
2742
+ NS_ERROR("This is not supposed to fail!");
2743
+ return rv;
2744
+ }
2745
+
2746
+ /* void refreshPrototype (); */
2747
+ NS_IMETHODIMP XPCWrappedNative::RefreshPrototype()
2748
+ {
2749
+ XPCCallContext ccx(NATIVE_CALLER);
2750
+ if(!ccx.IsValid())
2751
+ return UnexpectedFailure(NS_ERROR_FAILURE);
2752
+
2753
+ if(!HasProto())
2754
+ return NS_OK;
2755
+
2756
+ if(!GetFlatJSObject())
2757
+ return UnexpectedFailure(NS_ERROR_FAILURE);
2758
+
2759
+ AutoMarkingWrappedNativeProtoPtr oldProto(ccx);
2760
+ AutoMarkingWrappedNativeProtoPtr newProto(ccx);
2761
+
2762
+ oldProto = GetProto();
2763
+
2764
+ XPCNativeScriptableInfo *info = oldProto->GetScriptableInfo();
2765
+ XPCNativeScriptableCreateInfo ci(*info);
2766
+ newProto = XPCWrappedNativeProto::GetNewOrUsed(ccx, oldProto->GetScope(),
2767
+ oldProto->GetClassInfo(),
2768
+ &ci,
2769
+ !oldProto->IsShared(),
2770
+ (info->GetJSClass()->flags & JSCLASS_IS_GLOBAL),
2771
+ oldProto->GetOffsetsMasked());
2772
+ if(!newProto)
2773
+ return UnexpectedFailure(NS_ERROR_FAILURE);
2774
+
2775
+ // If nothing needs to change then we're done.
2776
+
2777
+ if(newProto.get() == oldProto.get())
2778
+ return NS_OK;
2779
+
2780
+ if(!JS_SetPrototype(ccx, GetFlatJSObject(), newProto->GetJSProtoObject()))
2781
+ return UnexpectedFailure(NS_ERROR_FAILURE);
2782
+
2783
+ SetProto(newProto);
2784
+
2785
+ if(mScriptableInfo == oldProto->GetScriptableInfo())
2786
+ mScriptableInfo = newProto->GetScriptableInfo();
2787
+
2788
+ return NS_OK;
2789
+ }
2790
+
2791
+ NS_IMETHODIMP XPCWrappedNative::GetSecurityInfoAddress(void*** securityInfoAddrPtr)
2792
+ {
2793
+ NS_ENSURE_ARG_POINTER(securityInfoAddrPtr);
2794
+ *securityInfoAddrPtr = GetSecurityInfoAddr();
2795
+ return NS_OK;
2796
+ }
2797
+
2798
+ /* void debugDump (in short depth); */
2799
+ NS_IMETHODIMP XPCWrappedNative::DebugDump(PRInt16 depth)
2800
+ {
2801
+ #ifdef DEBUG
2802
+ depth-- ;
2803
+ XPC_LOG_ALWAYS(("XPCWrappedNative @ %x with mRefCnt = %d", this, mRefCnt.get()));
2804
+ XPC_LOG_INDENT();
2805
+
2806
+ if(HasProto())
2807
+ {
2808
+ XPCWrappedNativeProto* proto = GetProto();
2809
+ if(depth && proto)
2810
+ proto->DebugDump(depth);
2811
+ else
2812
+ XPC_LOG_ALWAYS(("mMaybeProto @ %x", proto));
2813
+ }
2814
+ else
2815
+ XPC_LOG_ALWAYS(("Scope @ %x", GetScope()));
2816
+
2817
+ if(depth && mSet)
2818
+ mSet->DebugDump(depth);
2819
+ else
2820
+ XPC_LOG_ALWAYS(("mSet @ %x", mSet));
2821
+
2822
+ XPC_LOG_ALWAYS(("mFlatJSObject of %x", mFlatJSObject));
2823
+ XPC_LOG_ALWAYS(("mIdentity of %x", mIdentity));
2824
+ XPC_LOG_ALWAYS(("mScriptableInfo @ %x", mScriptableInfo));
2825
+
2826
+ if(depth && mScriptableInfo)
2827
+ {
2828
+ XPC_LOG_INDENT();
2829
+ XPC_LOG_ALWAYS(("mScriptable @ %x", mScriptableInfo->GetCallback()));
2830
+ XPC_LOG_ALWAYS(("mFlags of %x", (PRUint32)mScriptableInfo->GetFlags()));
2831
+ XPC_LOG_ALWAYS(("mJSClass @ %x", mScriptableInfo->GetJSClass()));
2832
+ XPC_LOG_OUTDENT();
2833
+ }
2834
+ XPC_LOG_OUTDENT();
2835
+ #endif
2836
+ return NS_OK;
2837
+ }
2838
+
2839
+ /***************************************************************************/
2840
+
2841
+ char*
2842
+ XPCWrappedNative::ToString(XPCCallContext& ccx,
2843
+ XPCWrappedNativeTearOff* to /* = nsnull */ ) const
2844
+ {
2845
+ #ifdef DEBUG
2846
+ # define FMT_ADDR " @ 0x%p"
2847
+ # define FMT_STR(str) str
2848
+ # define PARAM_ADDR(w) , w
2849
+ #else
2850
+ # define FMT_ADDR ""
2851
+ # define FMT_STR(str)
2852
+ # define PARAM_ADDR(w)
2853
+ #endif
2854
+
2855
+ char* sz = nsnull;
2856
+ char* name = nsnull;
2857
+
2858
+ XPCNativeScriptableInfo* si = GetScriptableInfo();
2859
+ if(si)
2860
+ name = JS_smprintf("%s", si->GetJSClass()->name);
2861
+ if(to)
2862
+ {
2863
+ const char* fmt = name ? " (%s)" : "%s";
2864
+ name = JS_sprintf_append(name, fmt,
2865
+ to->GetInterface()->GetNameString());
2866
+ }
2867
+ else if(!name)
2868
+ {
2869
+ XPCNativeSet* set = GetSet();
2870
+ XPCNativeInterface** array = set->GetInterfaceArray();
2871
+ PRUint16 count = set->GetInterfaceCount();
2872
+
2873
+ if(count == 1)
2874
+ name = JS_sprintf_append(name, "%s", array[0]->GetNameString());
2875
+ else if(count == 2 &&
2876
+ array[0] == XPCNativeInterface::GetISupports(ccx))
2877
+ {
2878
+ name = JS_sprintf_append(name, "%s", array[1]->GetNameString());
2879
+ }
2880
+ else
2881
+ {
2882
+ for(PRUint16 i = 0; i < count; i++)
2883
+ {
2884
+ const char* fmt = (i == 0) ?
2885
+ "(%s" : (i == count-1) ?
2886
+ ", %s)" : ", %s";
2887
+ name = JS_sprintf_append(name, fmt,
2888
+ array[i]->GetNameString());
2889
+ }
2890
+ }
2891
+ }
2892
+
2893
+ if(!name)
2894
+ {
2895
+ return nsnull;
2896
+ }
2897
+ const char* fmt = "[xpconnect wrapped %s" FMT_ADDR FMT_STR(" (native")
2898
+ FMT_ADDR FMT_STR(")") "]";
2899
+ if(si)
2900
+ {
2901
+ fmt = "[object %s" FMT_ADDR FMT_STR(" (native") FMT_ADDR FMT_STR(")") "]";
2902
+ }
2903
+ sz = JS_smprintf(fmt, name PARAM_ADDR(this) PARAM_ADDR(mIdentity));
2904
+
2905
+ JS_smprintf_free(name);
2906
+
2907
+
2908
+ return sz;
2909
+
2910
+ #undef FMT_ADDR
2911
+ #undef PARAM_ADDR
2912
+ }
2913
+
2914
+ /***************************************************************************/
2915
+
2916
+ #ifdef XPC_DETECT_LEADING_UPPERCASE_ACCESS_ERRORS
2917
+ // static
2918
+ void
2919
+ XPCWrappedNative::HandlePossibleNameCaseError(JSContext* cx,
2920
+ XPCNativeSet* set,
2921
+ XPCNativeInterface* iface,
2922
+ jsval name)
2923
+ {
2924
+ XPCCallContext ccx(JS_CALLER, cx);
2925
+ HandlePossibleNameCaseError(ccx, set, iface, name);
2926
+ }
2927
+
2928
+ // static
2929
+ void
2930
+ XPCWrappedNative::HandlePossibleNameCaseError(XPCCallContext& ccx,
2931
+ XPCNativeSet* set,
2932
+ XPCNativeInterface* iface,
2933
+ jsval name)
2934
+ {
2935
+ if(!ccx.IsValid())
2936
+ return;
2937
+
2938
+ JSString* oldJSStr;
2939
+ JSString* newJSStr;
2940
+ PRUnichar* oldStr;
2941
+ PRUnichar* newStr;
2942
+ XPCNativeMember* member;
2943
+ XPCNativeInterface* localIface;
2944
+
2945
+ /* PRUnichar->char->PRUnichar hack is to avoid pulling in i18n code. */
2946
+ if(JSVAL_IS_STRING(name) &&
2947
+ nsnull != (oldJSStr = JSVAL_TO_STRING(name)) &&
2948
+ nsnull != (oldStr = (PRUnichar*) JS_GetStringChars(oldJSStr)) &&
2949
+ oldStr[0] != 0 &&
2950
+ oldStr[0] >> 8 == 0 &&
2951
+ nsCRT::IsUpper((char)oldStr[0]) &&
2952
+ nsnull != (newStr = nsCRT::strdup(oldStr)))
2953
+ {
2954
+ newStr[0] = (PRUnichar) nsCRT::ToLower((char)newStr[0]);
2955
+ newJSStr = JS_NewUCStringCopyZ(ccx, (const jschar*)newStr);
2956
+ nsCRT::free(newStr);
2957
+ if(newJSStr && (set ?
2958
+ set->FindMember(STRING_TO_JSVAL(newJSStr), &member, &localIface) :
2959
+ NS_PTR_TO_INT32(iface->FindMember(STRING_TO_JSVAL(newJSStr)))))
2960
+ {
2961
+ // found it!
2962
+ const char* ifaceName = set ?
2963
+ localIface->GetNameString() :
2964
+ iface->GetNameString();
2965
+ const char* goodName = JS_GetStringBytes(newJSStr);
2966
+ const char* badName = JS_GetStringBytes(oldJSStr);
2967
+ char* locationStr = nsnull;
2968
+
2969
+ nsIException* e = nsnull;
2970
+ nsXPCException::NewException("", NS_OK, nsnull, nsnull, &e);
2971
+
2972
+ if(e)
2973
+ {
2974
+ nsresult rv;
2975
+ nsCOMPtr<nsIStackFrame> loc = nsnull;
2976
+ rv = e->GetLocation(getter_AddRefs(loc));
2977
+ if(NS_SUCCEEDED(rv) && loc) {
2978
+ loc->ToString(&locationStr); // failure here leaves it nsnull.
2979
+ }
2980
+ }
2981
+
2982
+ if(locationStr && ifaceName && goodName && badName )
2983
+ {
2984
+ printf("**************************************************\n"
2985
+ "ERROR: JS code at [%s]\n"
2986
+ "tried to access nonexistent property called\n"
2987
+ "\'%s\' on interface of type \'%s\'.\n"
2988
+ "That interface does however have a property called\n"
2989
+ "\'%s\'. Did you mean to access that lowercase property?\n"
2990
+ "Please fix the JS code as appropriate.\n"
2991
+ "**************************************************\n",
2992
+ locationStr, badName, ifaceName, goodName);
2993
+ }
2994
+ if(locationStr)
2995
+ nsMemory::Free(locationStr);
2996
+ }
2997
+ }
2998
+ }
2999
+ #endif
3000
+
3001
+ #ifdef XPC_CHECK_CLASSINFO_CLAIMS
3002
+ static void DEBUG_CheckClassInfoClaims(XPCWrappedNative* wrapper)
3003
+ {
3004
+ if(!wrapper || !wrapper->GetClassInfo())
3005
+ return;
3006
+
3007
+ nsISupports* obj = wrapper->GetIdentityObject();
3008
+ XPCNativeSet* set = wrapper->GetSet();
3009
+ PRUint16 count = set->GetInterfaceCount();
3010
+ for(PRUint16 i = 0; i < count; i++)
3011
+ {
3012
+ nsIClassInfo* clsInfo = wrapper->GetClassInfo();
3013
+ XPCNativeInterface* iface = set->GetInterfaceAt(i);
3014
+ nsIInterfaceInfo* info = iface->GetInterfaceInfo();
3015
+ const nsIID* iid;
3016
+ nsISupports* ptr;
3017
+
3018
+ info->GetIIDShared(&iid);
3019
+ nsresult rv = obj->QueryInterface(*iid, (void**)&ptr);
3020
+ if(NS_SUCCEEDED(rv))
3021
+ {
3022
+ NS_RELEASE(ptr);
3023
+ continue;
3024
+ }
3025
+ if(rv == NS_ERROR_OUT_OF_MEMORY)
3026
+ continue;
3027
+
3028
+ // Houston, We have a problem...
3029
+
3030
+ char* className = nsnull;
3031
+ char* contractID = nsnull;
3032
+ const char* interfaceName;
3033
+
3034
+ info->GetNameShared(&interfaceName);
3035
+ clsInfo->GetContractID(&contractID);
3036
+ if(wrapper->GetScriptableInfo())
3037
+ {
3038
+ wrapper->GetScriptableInfo()->GetCallback()->
3039
+ GetClassName(&className);
3040
+ }
3041
+
3042
+
3043
+ printf("\n!!! Object's nsIClassInfo lies about its interfaces!!!\n"
3044
+ " classname: %s \n"
3045
+ " contractid: %s \n"
3046
+ " unimplemented interface name: %s\n\n",
3047
+ className ? className : "<unknown>",
3048
+ contractID ? contractID : "<unknown>",
3049
+ interfaceName);
3050
+
3051
+ #ifdef XPC_ASSERT_CLASSINFO_CLAIMS
3052
+ NS_ERROR("Fix this QueryInterface or nsIClassInfo");
3053
+ #endif
3054
+
3055
+ if(className)
3056
+ nsMemory::Free(className);
3057
+ if(contractID)
3058
+ nsMemory::Free(contractID);
3059
+ }
3060
+ }
3061
+ #endif
3062
+
3063
+ #ifdef XPC_REPORT_SHADOWED_WRAPPED_NATIVE_MEMBERS
3064
+ static void DEBUG_PrintShadowObjectInfo(const char* header,
3065
+ XPCNativeSet* set,
3066
+ XPCWrappedNative* wrapper,
3067
+ XPCWrappedNativeProto* proto)
3068
+
3069
+ {
3070
+ if(header)
3071
+ printf("%s\n", header);
3072
+
3073
+ printf(" XPCNativeSet @ 0x%p for the class:\n", (void*)set);
3074
+
3075
+ char* className = nsnull;
3076
+ char* contractID = nsnull;
3077
+
3078
+ nsIClassInfo* clsInfo = proto ? proto->GetClassInfo() : nsnull;
3079
+ if(clsInfo)
3080
+ clsInfo->GetContractID(&contractID);
3081
+
3082
+ XPCNativeScriptableInfo* si = wrapper ?
3083
+ wrapper->GetScriptableInfo() :
3084
+ proto->GetScriptableInfo();
3085
+ if(si)
3086
+ si->GetCallback()->GetClassName(&className);
3087
+
3088
+ printf(" classname: %s \n"
3089
+ " contractid: %s \n",
3090
+ className ? className : "<unknown>",
3091
+ contractID ? contractID : "<unknown>");
3092
+
3093
+ if(className)
3094
+ nsMemory::Free(className);
3095
+ if(contractID)
3096
+ nsMemory::Free(contractID);
3097
+
3098
+ printf(" claims to implement interfaces:\n");
3099
+
3100
+ PRUint16 count = set->GetInterfaceCount();
3101
+ for(PRUint16 i = 0; i < count; i++)
3102
+ {
3103
+ XPCNativeInterface* iface = set->GetInterfaceAt(i);
3104
+ nsIInterfaceInfo* info = iface->GetInterfaceInfo();
3105
+ const char* interfaceName;
3106
+ info->GetNameShared(&interfaceName);
3107
+ printf(" %s\n", interfaceName);
3108
+ }
3109
+ }
3110
+
3111
+ static void ReportSingleMember(jsval ifaceName,
3112
+ jsval memberName)
3113
+ {
3114
+ if(JSVAL_IS_STRING(memberName))
3115
+ printf("%s::%s", JS_GetStringBytes(JSVAL_TO_STRING(ifaceName)),
3116
+ JS_GetStringBytes(JSVAL_TO_STRING(memberName)));
3117
+ else
3118
+ printf("%s", JS_GetStringBytes(JSVAL_TO_STRING(ifaceName)));
3119
+ }
3120
+
3121
+ static void ShowHeader(JSBool* printedHeader,
3122
+ const char* header,
3123
+ XPCNativeSet* set,
3124
+ XPCWrappedNative* wrapper,
3125
+ XPCWrappedNativeProto* proto)
3126
+ {
3127
+ if(!*printedHeader)
3128
+ {
3129
+ DEBUG_PrintShadowObjectInfo(header, set, wrapper, proto);
3130
+ *printedHeader = JS_TRUE;
3131
+ }
3132
+
3133
+ }
3134
+
3135
+ static void ShowOneShadow(jsval ifaceName1,
3136
+ jsval memberName1,
3137
+ jsval ifaceName2,
3138
+ jsval memberName2)
3139
+ {
3140
+ ReportSingleMember(ifaceName1, memberName1);
3141
+ printf(" shadows ");
3142
+ ReportSingleMember(ifaceName2, memberName2);
3143
+ printf("\n");
3144
+ }
3145
+
3146
+ static void ShowDuplicateInterface(jsval ifaceName)
3147
+ {
3148
+ printf(" ! %s appears twice in the nsIClassInfo interface set!\n",
3149
+ JS_GetStringBytes(JSVAL_TO_STRING(ifaceName)));
3150
+ }
3151
+
3152
+ static JSBool InterfacesAreRelated(XPCNativeInterface* iface1,
3153
+ XPCNativeInterface* iface2)
3154
+ {
3155
+ nsIInterfaceInfo* info1 = iface1->GetInterfaceInfo();
3156
+ nsIInterfaceInfo* info2 = iface2->GetInterfaceInfo();
3157
+
3158
+ NS_ASSERTION(info1 != info2, "should not have different iface!");
3159
+
3160
+ PRBool match;
3161
+
3162
+ return
3163
+ (NS_SUCCEEDED(info1->HasAncestor(iface2->GetIID(), &match)) && match) ||
3164
+ (NS_SUCCEEDED(info2->HasAncestor(iface1->GetIID(), &match)) && match);
3165
+ }
3166
+
3167
+ static JSBool MembersAreTheSame(XPCNativeInterface* iface1,
3168
+ PRUint16 memberIndex1,
3169
+ XPCNativeInterface* iface2,
3170
+ PRUint16 memberIndex2)
3171
+ {
3172
+ nsIInterfaceInfo* info1 = iface1->GetInterfaceInfo();
3173
+ nsIInterfaceInfo* info2 = iface2->GetInterfaceInfo();
3174
+
3175
+ XPCNativeMember* member1 = iface1->GetMemberAt(memberIndex1);
3176
+ XPCNativeMember* member2 = iface2->GetMemberAt(memberIndex2);
3177
+
3178
+ PRUint16 index1 = member1->GetIndex();
3179
+ PRUint16 index2 = member2->GetIndex();
3180
+
3181
+ // If they are both constants, then we'll just be sure that they are equivalent.
3182
+
3183
+ if(member1->IsConstant())
3184
+ {
3185
+ if(!member2->IsConstant())
3186
+ return JS_FALSE;
3187
+
3188
+ const nsXPTConstant* constant1;
3189
+ const nsXPTConstant* constant2;
3190
+
3191
+ return NS_SUCCEEDED(info1->GetConstant(index1, &constant1)) &&
3192
+ NS_SUCCEEDED(info2->GetConstant(index2, &constant2)) &&
3193
+ constant1->GetType() == constant2->GetType() &&
3194
+ constant1->GetValue() == constant2->GetValue();
3195
+ }
3196
+
3197
+ // Else we make sure they are of the same 'type' and return true only if
3198
+ // they are inherited from the same interface.
3199
+
3200
+ if(member1->IsMethod() != member2->IsMethod() ||
3201
+ member1->IsWritableAttribute() != member2->IsWritableAttribute() ||
3202
+ member1->IsReadOnlyAttribute() != member2->IsReadOnlyAttribute())
3203
+ {
3204
+ return JS_FALSE;
3205
+ }
3206
+
3207
+ const nsXPTMethodInfo* mi1;
3208
+ const nsXPTMethodInfo* mi2;
3209
+
3210
+ return NS_SUCCEEDED(info1->GetMethodInfo(index1, &mi1)) &&
3211
+ NS_SUCCEEDED(info2->GetMethodInfo(index2, &mi2)) &&
3212
+ mi1 == mi2;
3213
+ }
3214
+
3215
+ void DEBUG_ReportShadowedMembers(XPCNativeSet* set,
3216
+ XPCWrappedNative* wrapper,
3217
+ XPCWrappedNativeProto* proto)
3218
+ {
3219
+ // NOTE: Either wrapper or proto could be null...
3220
+
3221
+ if(!(proto || wrapper) || !set || set->GetInterfaceCount() < 2)
3222
+ return;
3223
+
3224
+ NS_ASSERTION(proto || wrapper, "bad param!");
3225
+ XPCJSRuntime* rt = proto ? proto->GetRuntime() : wrapper->GetRuntime();
3226
+
3227
+ // a quicky hack to avoid reporting info for the same set too often
3228
+ static int nextSeenSet = 0;
3229
+ static const int MAX_SEEN_SETS = 128;
3230
+ static XPCNativeSet* SeenSets[MAX_SEEN_SETS];
3231
+ for(int seen = 0; seen < MAX_SEEN_SETS; seen++)
3232
+ if(set == SeenSets[seen])
3233
+ return;
3234
+ SeenSets[nextSeenSet] = set;
3235
+
3236
+ #ifdef off_DEBUG_jband
3237
+ static int seenCount = 0;
3238
+ printf("--- adding SeenSets[%d] = 0x%p\n", nextSeenSet, set);
3239
+ DEBUG_PrintShadowObjectInfo(nsnull, set, wrapper, proto);
3240
+ #endif
3241
+ int localNext = nextSeenSet+1;
3242
+ nextSeenSet = localNext < MAX_SEEN_SETS ? localNext : 0;
3243
+
3244
+ XPCNativeScriptableInfo* si = wrapper ?
3245
+ wrapper->GetScriptableInfo() :
3246
+ proto->GetScriptableInfo();
3247
+
3248
+ // We just want to skip some classes...
3249
+ if(si)
3250
+ {
3251
+ // Add any classnames to skip to this (null terminated) array...
3252
+ static const char* skipClasses[] = {
3253
+ "Window",
3254
+ "HTMLDocument",
3255
+ "HTMLCollection",
3256
+ "Event",
3257
+ "ChromeWindow",
3258
+ nsnull
3259
+ };
3260
+
3261
+ static PRBool warned = JS_FALSE;
3262
+ if(!warned)
3263
+ {
3264
+ printf("!!! XPConnect won't warn about Shadowed Members of...\n ");
3265
+ for(const char** name = skipClasses; *name; name++)
3266
+ printf("%s %s", name == skipClasses ? "" : ",", *name);
3267
+ printf("\n");
3268
+ warned = JS_TRUE;
3269
+ }
3270
+
3271
+ PRBool quit = JS_FALSE;
3272
+ char* className = nsnull;
3273
+ si->GetCallback()->GetClassName(&className);
3274
+ if(className)
3275
+ {
3276
+ for(const char** name = skipClasses; *name; name++)
3277
+ {
3278
+ if(!strcmp(*name, className))
3279
+ {
3280
+ quit = JS_TRUE;
3281
+ break;
3282
+ }
3283
+ }
3284
+ nsMemory::Free(className);
3285
+ }
3286
+ if(quit)
3287
+ return;
3288
+ }
3289
+
3290
+ const char header[] =
3291
+ "!!!Object wrapped by XPConnect has members whose names shadow each other!!!";
3292
+
3293
+ JSBool printedHeader = JS_FALSE;
3294
+
3295
+ jsval QIName = rt->GetStringJSVal(XPCJSRuntime::IDX_QUERY_INTERFACE);
3296
+
3297
+ PRUint16 ifaceCount = set->GetInterfaceCount();
3298
+ PRUint16 i, j, k, m;
3299
+
3300
+ // First look for duplicate interface entries
3301
+
3302
+ for(i = 0; i < ifaceCount; i++)
3303
+ {
3304
+ XPCNativeInterface* ifaceOuter = set->GetInterfaceAt(i);
3305
+ for(k = i+1; k < ifaceCount; k++)
3306
+ {
3307
+ XPCNativeInterface* ifaceInner = set->GetInterfaceAt(k);
3308
+ if(ifaceInner == ifaceOuter)
3309
+ {
3310
+ ShowHeader(&printedHeader, header, set, wrapper, proto);
3311
+ ShowDuplicateInterface(ifaceOuter->GetName());
3312
+ }
3313
+ }
3314
+ }
3315
+
3316
+ // Now scan for shadowing names
3317
+
3318
+ for(i = 0; i < ifaceCount; i++)
3319
+ {
3320
+ XPCNativeInterface* ifaceOuter = set->GetInterfaceAt(i);
3321
+ jsval ifaceOuterName = ifaceOuter->GetName();
3322
+
3323
+ PRUint16 memberCountOuter = ifaceOuter->GetMemberCount();
3324
+ for(j = 0; j < memberCountOuter; j++)
3325
+ {
3326
+ XPCNativeMember* memberOuter = ifaceOuter->GetMemberAt(j);
3327
+ jsval memberOuterName = memberOuter->GetName();
3328
+
3329
+ if(memberOuterName == QIName)
3330
+ continue;
3331
+
3332
+ for(k = i+1; k < ifaceCount; k++)
3333
+ {
3334
+ XPCNativeInterface* ifaceInner = set->GetInterfaceAt(k);
3335
+ jsval ifaceInnerName = ifaceInner->GetName();
3336
+
3337
+ // Reported elsewhere.
3338
+ if(ifaceInner == ifaceOuter)
3339
+ continue;
3340
+
3341
+ // We consider this not worth reporting because callers will
3342
+ // almost certainly be getting what they expect.
3343
+ if(InterfacesAreRelated(ifaceInner, ifaceOuter))
3344
+ continue;
3345
+
3346
+ if(ifaceInnerName == memberOuterName)
3347
+ {
3348
+ ShowHeader(&printedHeader, header, set, wrapper, proto);
3349
+ ShowOneShadow(ifaceInnerName, JSVAL_NULL,
3350
+ ifaceOuterName, memberOuterName);
3351
+ }
3352
+
3353
+ PRUint16 memberCountInner = ifaceInner->GetMemberCount();
3354
+
3355
+ for(m = 0; m < memberCountInner; m++)
3356
+ {
3357
+ XPCNativeMember* memberInner = ifaceInner->GetMemberAt(m);
3358
+ jsval memberInnerName = memberInner->GetName();
3359
+
3360
+ if(memberInnerName == QIName)
3361
+ continue;
3362
+
3363
+ if(memberOuterName == memberInnerName &&
3364
+ !MembersAreTheSame(ifaceOuter, j, ifaceInner, m))
3365
+
3366
+ {
3367
+ ShowHeader(&printedHeader, header, set, wrapper, proto);
3368
+ ShowOneShadow(ifaceOuterName, memberOuterName,
3369
+ ifaceInnerName, memberInnerName);
3370
+ }
3371
+ }
3372
+ }
3373
+ }
3374
+ }
3375
+ }
3376
+ #endif
3377
+
3378
+ #ifdef XPC_CHECK_WRAPPER_THREADSAFETY
3379
+ void DEBUG_ReportWrapperThreadSafetyError(XPCCallContext& ccx,
3380
+ const char* msg,
3381
+ const XPCWrappedNative* wrapper)
3382
+ {
3383
+ XPCPerThreadData* tls = ccx.GetThreadData();
3384
+ if(1 != tls->IncrementWrappedNativeThreadsafetyReportDepth())
3385
+ return;
3386
+
3387
+ printf("---------------------------------------------------------------\n");
3388
+ printf("!!!!! XPConnect wrapper thread use error...\n");
3389
+
3390
+ char* wrapperDump = wrapper->ToString(ccx);
3391
+ if(wrapperDump)
3392
+ {
3393
+ printf(" %s\n wrapper: %s\n", msg, wrapperDump);
3394
+ JS_smprintf_free(wrapperDump);
3395
+ }
3396
+ else
3397
+ printf(" %s\n wrapper @ 0x%p\n", msg, (void *)wrapper);
3398
+
3399
+ printf(" JS call stack...\n");
3400
+ xpc_DumpJSStack(ccx, JS_TRUE, JS_TRUE, JS_TRUE);
3401
+ printf("---------------------------------------------------------------\n");
3402
+
3403
+ tls->ClearWrappedNativeThreadsafetyReportDepth();
3404
+ }
3405
+
3406
+ void DEBUG_CheckWrapperThreadSafety(const XPCWrappedNative* wrapper)
3407
+ {
3408
+ XPCWrappedNativeProto* proto = wrapper->GetProto();
3409
+ if(proto && proto->ClassIsThreadSafe())
3410
+ return;
3411
+
3412
+ PRBool val;
3413
+ if(proto && proto->ClassIsMainThreadOnly())
3414
+ {
3415
+ if(!NS_IsMainThread())
3416
+ {
3417
+ XPCCallContext ccx(NATIVE_CALLER);
3418
+ DEBUG_ReportWrapperThreadSafetyError(ccx,
3419
+ "Main Thread Only wrapper accessed on another thread", wrapper);
3420
+ }
3421
+ }
3422
+ else if(NS_SUCCEEDED(wrapper->mThread->IsOnCurrentThread(&val)) && !val)
3423
+ {
3424
+ XPCCallContext ccx(NATIVE_CALLER);
3425
+ DEBUG_ReportWrapperThreadSafetyError(ccx,
3426
+ "XPConnect WrappedNative is being accessed on multiple threads but "
3427
+ "the underlying native xpcom object does not have a "
3428
+ "nsIClassInfo with the 'THREADSAFE' flag set", wrapper);
3429
+ }
3430
+ }
3431
+ #endif
3432
+
3433
+ NS_IMPL_THREADSAFE_ISUPPORTS1(XPCJSObjectHolder, nsIXPConnectJSObjectHolder)
3434
+
3435
+ NS_IMETHODIMP
3436
+ XPCJSObjectHolder::GetJSObject(JSObject** aJSObj)
3437
+ {
3438
+ NS_PRECONDITION(aJSObj, "bad param");
3439
+ NS_PRECONDITION(mJSObj, "bad object state");
3440
+ *aJSObj = mJSObj;
3441
+ return NS_OK;
3442
+ }
3443
+
3444
+ XPCJSObjectHolder::XPCJSObjectHolder(XPCCallContext& ccx, JSObject* obj)
3445
+ : mJSObj(obj)
3446
+ {
3447
+ ccx.GetRuntime()->AddObjectHolderRoot(this);
3448
+ }
3449
+
3450
+ XPCJSObjectHolder::~XPCJSObjectHolder()
3451
+ {
3452
+ RemoveFromRootSet(nsXPConnect::GetRuntimeInstance()->GetJSRuntime());
3453
+ }
3454
+
3455
+ void
3456
+ XPCJSObjectHolder::TraceJS(JSTracer *trc)
3457
+ {
3458
+ JS_SET_TRACING_DETAILS(trc, PrintTraceName, this, 0);
3459
+ JS_CallTracer(trc, mJSObj, JSTRACE_OBJECT);
3460
+ }
3461
+
3462
+ #ifdef DEBUG
3463
+ // static
3464
+ void
3465
+ XPCJSObjectHolder::PrintTraceName(JSTracer* trc, char *buf, size_t bufsize)
3466
+ {
3467
+ JS_snprintf(buf, bufsize, "XPCJSObjectHolder[0x%p].mJSObj",
3468
+ trc->debugPrintArg);
3469
+ }
3470
+ #endif
3471
+
3472
+ // static
3473
+ XPCJSObjectHolder*
3474
+ XPCJSObjectHolder::newHolder(XPCCallContext& ccx, JSObject* obj)
3475
+ {
3476
+ if(!obj)
3477
+ {
3478
+ NS_ASSERTION(0, "bad param");
3479
+ return nsnull;
3480
+ }
3481
+ return new XPCJSObjectHolder(ccx, obj);
3482
+ }