johnson 1.2.0 → 2.0.0.pre0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (782) hide show
  1. data/CHANGELOG.rdoc +8 -0
  2. data/Manifest.txt +762 -48
  3. data/README.rdoc +2 -1
  4. data/Rakefile +90 -18
  5. data/ext/spidermonkey/conversions.c +9 -2
  6. data/ext/spidermonkey/ruby_land_proxy.c +1 -1
  7. data/ext/spidermonkey/runtime.h +1 -1
  8. data/ext/tracemonkey/context.cc +125 -0
  9. data/ext/tracemonkey/context.h +19 -0
  10. data/ext/tracemonkey/conversions.cc +365 -0
  11. data/ext/tracemonkey/conversions.h +32 -0
  12. data/ext/tracemonkey/debugger.cc +234 -0
  13. data/ext/tracemonkey/debugger.h +10 -0
  14. data/ext/tracemonkey/extconf.rb +37 -0
  15. data/ext/tracemonkey/extensions.cc +37 -0
  16. data/ext/tracemonkey/extensions.h +12 -0
  17. data/ext/tracemonkey/global.cc +40 -0
  18. data/ext/tracemonkey/global.h +11 -0
  19. data/ext/tracemonkey/idhash.cc +16 -0
  20. data/ext/tracemonkey/idhash.h +8 -0
  21. data/ext/tracemonkey/immutable_node.cc +1199 -0
  22. data/ext/tracemonkey/immutable_node.cc.erb +559 -0
  23. data/ext/tracemonkey/immutable_node.h +22 -0
  24. data/ext/tracemonkey/jroot.h +215 -0
  25. data/ext/tracemonkey/js_land_proxy.cc +620 -0
  26. data/ext/tracemonkey/js_land_proxy.h +20 -0
  27. data/ext/tracemonkey/ruby_land_proxy.cc +618 -0
  28. data/ext/tracemonkey/ruby_land_proxy.h +38 -0
  29. data/ext/tracemonkey/runtime.cc +454 -0
  30. data/ext/tracemonkey/runtime.h +27 -0
  31. data/ext/tracemonkey/split_global.cc +392 -0
  32. data/ext/tracemonkey/split_global.h +11 -0
  33. data/ext/tracemonkey/tracemonkey.cc +23 -0
  34. data/ext/tracemonkey/tracemonkey.h +32 -0
  35. data/lib/johnson.rb +12 -4
  36. data/lib/johnson/error.rb +5 -0
  37. data/lib/johnson/js/prelude.js +16 -1
  38. data/lib/johnson/parser.rb +2 -1
  39. data/lib/johnson/runtime.rb +87 -26
  40. data/lib/johnson/spidermonkey/runtime.rb +7 -16
  41. data/lib/johnson/tracemonkey.rb +13 -0
  42. data/lib/johnson/tracemonkey/context.rb +10 -0
  43. data/lib/johnson/tracemonkey/debugger.rb +67 -0
  44. data/lib/johnson/tracemonkey/immutable_node.rb +282 -0
  45. data/lib/johnson/tracemonkey/js_land_proxy.rb +64 -0
  46. data/lib/johnson/tracemonkey/mutable_tree_visitor.rb +242 -0
  47. data/lib/johnson/tracemonkey/ruby_land_proxy.rb +17 -0
  48. data/lib/johnson/tracemonkey/runtime.rb +80 -0
  49. data/test/{johnson_test.rb → generic/johnson_test.rb} +1 -1
  50. data/test/{parser_test.rb → generic/parser_test.rb} +1 -1
  51. data/test/helper.rb +23 -4
  52. data/test/johnson/{browser_test.rb → generic/browser_test.rb} +1 -1
  53. data/test/johnson/{conversions → generic/conversions}/array_test.rb +1 -1
  54. data/test/johnson/{conversions → generic/conversions}/boolean_test.rb +1 -1
  55. data/test/johnson/{conversions → generic/conversions}/callable_test.rb +1 -1
  56. data/test/johnson/{conversions → generic/conversions}/file_test.rb +1 -1
  57. data/test/johnson/generic/conversions/helper.rb +1 -0
  58. data/test/johnson/{conversions → generic/conversions}/nil_test.rb +1 -1
  59. data/test/johnson/{conversions → generic/conversions}/number_test.rb +1 -1
  60. data/test/johnson/{conversions → generic/conversions}/regexp_test.rb +1 -1
  61. data/test/johnson/{conversions → generic/conversions}/string_test.rb +1 -1
  62. data/test/johnson/{conversions → generic/conversions}/struct_test.rb +1 -1
  63. data/test/johnson/{conversions → generic/conversions}/symbol_test.rb +1 -1
  64. data/test/johnson/{conversions → generic/conversions}/thread_test.rb +1 -1
  65. data/test/johnson/{custom_conversions_test.rb → generic/custom_conversions_test.rb} +1 -1
  66. data/test/johnson/generic/default_test.rb +12 -0
  67. data/test/johnson/{error_test.rb → generic/error_test.rb} +1 -1
  68. data/test/johnson/{extensions_test.rb → generic/extensions_test.rb} +1 -1
  69. data/test/johnson/generic/helper.rb +1 -0
  70. data/test/johnson/{nodes → generic/nodes}/array_literal_test.rb +1 -1
  71. data/test/johnson/{nodes → generic/nodes}/array_node_test.rb +1 -1
  72. data/test/johnson/{nodes → generic/nodes}/binary_node_test.rb +1 -1
  73. data/test/johnson/{nodes → generic/nodes}/bracket_access_test.rb +1 -1
  74. data/test/johnson/{nodes → generic/nodes}/delete_test.rb +1 -1
  75. data/test/johnson/{nodes → generic/nodes}/do_while_test.rb +1 -1
  76. data/test/johnson/{nodes → generic/nodes}/dot_accessor_test.rb +1 -1
  77. data/test/johnson/generic/nodes/export_test.rb +11 -0
  78. data/test/johnson/{nodes → generic/nodes}/for_test.rb +1 -1
  79. data/test/johnson/{nodes → generic/nodes}/function_test.rb +1 -1
  80. data/test/johnson/generic/nodes/helper.rb +1 -0
  81. data/test/johnson/{nodes → generic/nodes}/if_test.rb +16 -6
  82. data/test/johnson/generic/nodes/import_test.rb +15 -0
  83. data/test/johnson/{nodes → generic/nodes}/label_test.rb +1 -1
  84. data/test/johnson/{nodes → generic/nodes}/let_test.rb +1 -1
  85. data/test/johnson/{nodes → generic/nodes}/object_literal_test.rb +1 -1
  86. data/test/johnson/{nodes → generic/nodes}/return_test.rb +1 -1
  87. data/test/johnson/{nodes → generic/nodes}/semi_test.rb +1 -1
  88. data/test/johnson/{nodes → generic/nodes}/switch_test.rb +1 -1
  89. data/test/johnson/{nodes → generic/nodes}/ternary_test.rb +1 -1
  90. data/test/johnson/{nodes → generic/nodes}/throw_test.rb +1 -1
  91. data/test/johnson/{nodes → generic/nodes}/try_node_test.rb +36 -6
  92. data/test/johnson/{nodes → generic/nodes}/typeof_test.rb +1 -1
  93. data/test/johnson/{nodes → generic/nodes}/unary_node_test.rb +1 -1
  94. data/test/johnson/{nodes → generic/nodes}/void_test.rb +1 -1
  95. data/test/johnson/{nodes → generic/nodes}/while_test.rb +1 -1
  96. data/test/johnson/{nodes → generic/nodes}/with_test.rb +1 -1
  97. data/test/johnson/{prelude_test.rb → generic/prelude_test.rb} +1 -1
  98. data/test/johnson/{runtime_test.rb → generic/runtime_test.rb} +3 -6
  99. data/test/johnson/generic/version_test.rb +13 -0
  100. data/test/johnson/{visitors → generic/visitors}/dot_visitor_test.rb +1 -1
  101. data/test/johnson/{visitors → generic/visitors}/enumerating_visitor_test.rb +1 -1
  102. data/test/johnson/generic/visitors/helper.rb +1 -0
  103. data/test/johnson/spidermonkey/js_land_proxy_test.rb +1 -5
  104. data/test/johnson/spidermonkey/ruby_land_proxy_test.rb +11 -7
  105. data/test/johnson/tracemonkey/context_test.rb +21 -0
  106. data/test/johnson/tracemonkey/immutable_node_test.rb +34 -0
  107. data/test/johnson/tracemonkey/js_land_proxy_test.rb +273 -0
  108. data/test/johnson/tracemonkey/ruby_land_proxy_test.rb +274 -0
  109. data/test/johnson/tracemonkey/runtime_test.rb +41 -0
  110. data/test/johnson/tracemonkey/split_global_test.rb +32 -0
  111. data/vendor/spidermonkey/js.pkg +2 -0
  112. data/vendor/tracemonkey/Makefile.in +668 -0
  113. data/vendor/tracemonkey/Makefile.ref +483 -0
  114. data/vendor/tracemonkey/README.html +54 -0
  115. data/vendor/tracemonkey/SpiderMonkey.rsp +11 -0
  116. data/vendor/tracemonkey/Y.js +19 -0
  117. data/vendor/tracemonkey/aclocal.m4 +9 -0
  118. data/vendor/tracemonkey/bench.sh +5 -0
  119. data/vendor/tracemonkey/build/autoconf/acoutput-fast.pl +202 -0
  120. data/vendor/tracemonkey/build/autoconf/altoptions.m4 +154 -0
  121. data/vendor/tracemonkey/build/autoconf/config.guess +1537 -0
  122. data/vendor/tracemonkey/build/autoconf/config.sub +1595 -0
  123. data/vendor/tracemonkey/build/autoconf/install-sh +119 -0
  124. data/vendor/tracemonkey/build/autoconf/make-makefile +315 -0
  125. data/vendor/tracemonkey/build/autoconf/match-dir.sh +101 -0
  126. data/vendor/tracemonkey/build/autoconf/moznbytetype.m4 +136 -0
  127. data/vendor/tracemonkey/build/autoconf/nspr.m4 +82 -0
  128. data/vendor/tracemonkey/build/autoconf/pkg.m4 +59 -0
  129. data/vendor/tracemonkey/build/autoconf/update-makefile.sh +118 -0
  130. data/vendor/tracemonkey/build/cygwin-wrapper +75 -0
  131. data/vendor/tracemonkey/build/hcc +111 -0
  132. data/vendor/tracemonkey/build/hcpp +155 -0
  133. data/vendor/tracemonkey/build/unix/mddepend.pl +165 -0
  134. data/vendor/tracemonkey/build/unix/uniq.pl +63 -0
  135. data/vendor/tracemonkey/build/win32/pgomerge.py +40 -0
  136. data/vendor/tracemonkey/builtins.tbl +91 -0
  137. data/vendor/tracemonkey/call.js +13 -0
  138. data/vendor/tracemonkey/config.mk +206 -0
  139. data/vendor/tracemonkey/config/Makefile.in +106 -0
  140. data/vendor/tracemonkey/config/Moz/Milestone.pm +232 -0
  141. data/vendor/tracemonkey/config/autoconf.mk.in +362 -0
  142. data/vendor/tracemonkey/config/check-sync-dirs.py +103 -0
  143. data/vendor/tracemonkey/config/check-sync-exceptions +7 -0
  144. data/vendor/tracemonkey/config/config.mk +881 -0
  145. data/vendor/tracemonkey/config/fastcwd.pl +66 -0
  146. data/vendor/tracemonkey/config/gcc_hidden.h +2 -0
  147. data/vendor/tracemonkey/config/insure.mk +53 -0
  148. data/vendor/tracemonkey/config/make-system-wrappers.pl +59 -0
  149. data/vendor/tracemonkey/config/milestone.pl +112 -0
  150. data/vendor/tracemonkey/config/milestone.txt +13 -0
  151. data/vendor/tracemonkey/config/mkdepend/Makefile.in +84 -0
  152. data/vendor/tracemonkey/config/mkdepend/cppsetup.c +233 -0
  153. data/vendor/tracemonkey/config/mkdepend/def.h +184 -0
  154. data/vendor/tracemonkey/config/mkdepend/ifparser.c +551 -0
  155. data/vendor/tracemonkey/config/mkdepend/ifparser.h +83 -0
  156. data/vendor/tracemonkey/config/mkdepend/imakemdep.h +733 -0
  157. data/vendor/tracemonkey/config/mkdepend/include.c +337 -0
  158. data/vendor/tracemonkey/config/mkdepend/main.c +860 -0
  159. data/vendor/tracemonkey/config/mkdepend/mkdepend.man +382 -0
  160. data/vendor/tracemonkey/config/mkdepend/parse.c +686 -0
  161. data/vendor/tracemonkey/config/mkdepend/pr.c +124 -0
  162. data/vendor/tracemonkey/config/nfspwd.pl +50 -0
  163. data/vendor/tracemonkey/config/nsinstall.c +481 -0
  164. data/vendor/tracemonkey/config/nsinstall.py +155 -0
  165. data/vendor/tracemonkey/config/pathsub.c +247 -0
  166. data/vendor/tracemonkey/config/pathsub.h +74 -0
  167. data/vendor/tracemonkey/config/preprocessor.pl +671 -0
  168. data/vendor/tracemonkey/config/revdepth-nt.pl +48 -0
  169. data/vendor/tracemonkey/config/revdepth.pl +51 -0
  170. data/vendor/tracemonkey/config/rules.mk +2310 -0
  171. data/vendor/tracemonkey/config/static-checking-config.mk +21 -0
  172. data/vendor/tracemonkey/config/static-checking.js +92 -0
  173. data/vendor/tracemonkey/config/string-format.js +61 -0
  174. data/vendor/tracemonkey/config/system-headers +1035 -0
  175. data/vendor/tracemonkey/config/version.mk +85 -0
  176. data/vendor/tracemonkey/config/version_win.pl +442 -0
  177. data/vendor/tracemonkey/configure +14183 -0
  178. data/vendor/tracemonkey/configure.in +5363 -0
  179. data/vendor/tracemonkey/correct.sh +23 -0
  180. data/vendor/tracemonkey/correct/check-3d-morph.js +55 -0
  181. data/vendor/tracemonkey/correct/check-3d-raytrace.js +445 -0
  182. data/vendor/tracemonkey/correct/check-access-binary-trees.js +52 -0
  183. data/vendor/tracemonkey/correct/check-access-fannkuch.js +66 -0
  184. data/vendor/tracemonkey/correct/check-access-nbody.js +171 -0
  185. data/vendor/tracemonkey/correct/check-access-nsieve.js +40 -0
  186. data/vendor/tracemonkey/correct/check-bitops-3bit-bits-in-byte.js +35 -0
  187. data/vendor/tracemonkey/correct/check-bitops-bits-in-byte.js +24 -0
  188. data/vendor/tracemonkey/correct/check-bitops-bitwise-and.js +29 -0
  189. data/vendor/tracemonkey/correct/check-bitops-nsieve-bits.js +40 -0
  190. data/vendor/tracemonkey/correct/check-controlflow-recursive.js +27 -0
  191. data/vendor/tracemonkey/correct/check-date-format-tofte.js +302 -0
  192. data/vendor/tracemonkey/correct/check-date-format-xparb.js +421 -0
  193. data/vendor/tracemonkey/correct/check-mont.js +119 -0
  194. data/vendor/tracemonkey/dtoa.c +3335 -0
  195. data/vendor/tracemonkey/editline/Makefile.in +55 -0
  196. data/vendor/tracemonkey/editline/Makefile.ref +143 -0
  197. data/vendor/tracemonkey/editline/README +83 -0
  198. data/vendor/tracemonkey/editline/editline.3 +175 -0
  199. data/vendor/tracemonkey/editline/editline.c +1371 -0
  200. data/vendor/tracemonkey/editline/editline.h +135 -0
  201. data/vendor/tracemonkey/editline/sysunix.c +182 -0
  202. data/vendor/tracemonkey/editline/unix.h +82 -0
  203. data/vendor/tracemonkey/if.js +13 -0
  204. data/vendor/tracemonkey/imacro_asm.js.in +396 -0
  205. data/vendor/tracemonkey/imacros.c.out +1034 -0
  206. data/vendor/tracemonkey/imacros.jsasm +770 -0
  207. data/vendor/tracemonkey/javascript-trace.d +73 -0
  208. data/vendor/tracemonkey/jitstats.tbl +55 -0
  209. data/vendor/tracemonkey/js-config.h.in +82 -0
  210. data/vendor/tracemonkey/js-config.in +111 -0
  211. data/vendor/tracemonkey/js.mdp +0 -0
  212. data/vendor/tracemonkey/js.msg +312 -0
  213. data/vendor/tracemonkey/js3240.rc +79 -0
  214. data/vendor/tracemonkey/jsOS240.def +654 -0
  215. data/vendor/tracemonkey/jsapi.cpp +6005 -0
  216. data/vendor/tracemonkey/jsapi.h +2727 -0
  217. data/vendor/tracemonkey/jsarena.cpp +450 -0
  218. data/vendor/tracemonkey/jsarena.h +318 -0
  219. data/vendor/tracemonkey/jsarray.cpp +3664 -0
  220. data/vendor/tracemonkey/jsarray.h +238 -0
  221. data/vendor/tracemonkey/jsatom.cpp +1244 -0
  222. data/vendor/tracemonkey/jsatom.h +493 -0
  223. data/vendor/tracemonkey/jsbit.h +249 -0
  224. data/vendor/tracemonkey/jsbool.cpp +184 -0
  225. data/vendor/tracemonkey/jsbool.h +88 -0
  226. data/vendor/tracemonkey/jsbuiltins.cpp +415 -0
  227. data/vendor/tracemonkey/jsbuiltins.h +456 -0
  228. data/vendor/tracemonkey/jsclist.h +139 -0
  229. data/vendor/tracemonkey/jscntxt.cpp +1816 -0
  230. data/vendor/tracemonkey/jscntxt.h +1541 -0
  231. data/vendor/tracemonkey/jscompat.h +57 -0
  232. data/vendor/tracemonkey/jsconfig.mk +181 -0
  233. data/vendor/tracemonkey/jscpucfg.cpp +194 -0
  234. data/vendor/tracemonkey/jscpucfg.h +91 -0
  235. data/vendor/tracemonkey/jsdate.cpp +2465 -0
  236. data/vendor/tracemonkey/jsdate.h +129 -0
  237. data/vendor/tracemonkey/jsdbgapi.cpp +2017 -0
  238. data/vendor/tracemonkey/jsdbgapi.h +500 -0
  239. data/vendor/tracemonkey/jsdhash.cpp +876 -0
  240. data/vendor/tracemonkey/jsdhash.h +588 -0
  241. data/vendor/tracemonkey/jsdtoa.cpp +572 -0
  242. data/vendor/tracemonkey/jsdtoa.h +131 -0
  243. data/vendor/tracemonkey/jsdtracef.c +318 -0
  244. data/vendor/tracemonkey/jsdtracef.h +81 -0
  245. data/vendor/tracemonkey/jsemit.cpp +7292 -0
  246. data/vendor/tracemonkey/jsemit.h +802 -0
  247. data/vendor/tracemonkey/jsexn.cpp +1337 -0
  248. data/vendor/tracemonkey/jsexn.h +96 -0
  249. data/vendor/tracemonkey/jsfile.cpp +2747 -0
  250. data/vendor/tracemonkey/jsfile.h +56 -0
  251. data/vendor/tracemonkey/jsfile.msg +90 -0
  252. data/vendor/tracemonkey/jsfun.cpp +3089 -0
  253. data/vendor/tracemonkey/jsfun.h +366 -0
  254. data/vendor/tracemonkey/jsgc.cpp +3816 -0
  255. data/vendor/tracemonkey/jsgc.h +429 -0
  256. data/vendor/tracemonkey/jshash.cpp +477 -0
  257. data/vendor/tracemonkey/jshash.h +151 -0
  258. data/vendor/tracemonkey/jsify.pl +483 -0
  259. data/vendor/tracemonkey/jsinterp.cpp +7441 -0
  260. data/vendor/tracemonkey/jsinterp.h +666 -0
  261. data/vendor/tracemonkey/jsinvoke.cpp +42 -0
  262. data/vendor/tracemonkey/jsiter.cpp +1040 -0
  263. data/vendor/tracemonkey/jsiter.h +140 -0
  264. data/vendor/tracemonkey/jskeyword.tbl +124 -0
  265. data/vendor/tracemonkey/jskwgen.cpp +460 -0
  266. data/vendor/tracemonkey/jslibmath.h +69 -0
  267. data/vendor/tracemonkey/jslock.cpp +1512 -0
  268. data/vendor/tracemonkey/jslock.h +325 -0
  269. data/vendor/tracemonkey/jslocko.asm +60 -0
  270. data/vendor/tracemonkey/jslog2.cpp +111 -0
  271. data/vendor/tracemonkey/jslong.h +167 -0
  272. data/vendor/tracemonkey/jsmath.cpp +806 -0
  273. data/vendor/tracemonkey/jsmath.h +63 -0
  274. data/vendor/tracemonkey/jsnum.cpp +1374 -0
  275. data/vendor/tracemonkey/jsnum.h +280 -0
  276. data/vendor/tracemonkey/jsobj.cpp +6165 -0
  277. data/vendor/tracemonkey/jsobj.h +870 -0
  278. data/vendor/tracemonkey/json.cpp +1338 -0
  279. data/vendor/tracemonkey/json.h +108 -0
  280. data/vendor/tracemonkey/jsopcode.cpp +5484 -0
  281. data/vendor/tracemonkey/jsopcode.h +434 -0
  282. data/vendor/tracemonkey/jsopcode.tbl +591 -0
  283. data/vendor/tracemonkey/jsoplengen.cpp +121 -0
  284. data/vendor/tracemonkey/jsotypes.h +202 -0
  285. data/vendor/tracemonkey/jsparse.cpp +9257 -0
  286. data/vendor/tracemonkey/jsparse.h +900 -0
  287. data/vendor/tracemonkey/jsprf.cpp +1262 -0
  288. data/vendor/tracemonkey/jsprf.h +150 -0
  289. data/vendor/tracemonkey/jsproto.tbl +117 -0
  290. data/vendor/tracemonkey/jsprvtd.h +366 -0
  291. data/vendor/tracemonkey/jspubtd.h +585 -0
  292. data/vendor/tracemonkey/jsregexp.cpp +5051 -0
  293. data/vendor/tracemonkey/jsregexp.h +199 -0
  294. data/vendor/tracemonkey/jsreops.tbl +145 -0
  295. data/vendor/tracemonkey/jsscan.cpp +2040 -0
  296. data/vendor/tracemonkey/jsscan.h +467 -0
  297. data/vendor/tracemonkey/jsscope.cpp +1966 -0
  298. data/vendor/tracemonkey/jsscope.h +487 -0
  299. data/vendor/tracemonkey/jsscript.cpp +1932 -0
  300. data/vendor/tracemonkey/jsscript.h +345 -0
  301. data/vendor/tracemonkey/jsshell.msg +54 -0
  302. data/vendor/tracemonkey/jsstack.js +167 -0
  303. data/vendor/tracemonkey/jsstaticcheck.h +69 -0
  304. data/vendor/tracemonkey/jsstddef.h +87 -0
  305. data/vendor/tracemonkey/jsstdint.h +96 -0
  306. data/vendor/tracemonkey/jsstr.cpp +5277 -0
  307. data/vendor/tracemonkey/jsstr.h +702 -0
  308. data/vendor/tracemonkey/jstracer.cpp +10991 -0
  309. data/vendor/tracemonkey/jstracer.h +794 -0
  310. data/vendor/tracemonkey/jstypes.h +481 -0
  311. data/vendor/tracemonkey/jsutil.cpp +361 -0
  312. data/vendor/tracemonkey/jsutil.h +178 -0
  313. data/vendor/tracemonkey/jsversion.h +243 -0
  314. data/vendor/tracemonkey/jswince.asm +44 -0
  315. data/vendor/tracemonkey/jsxdrapi.cpp +800 -0
  316. data/vendor/tracemonkey/jsxdrapi.h +220 -0
  317. data/vendor/tracemonkey/jsxml.cpp +8327 -0
  318. data/vendor/tracemonkey/jsxml.h +305 -0
  319. data/vendor/tracemonkey/liveconnect/LiveConnect.dsp +157 -0
  320. data/vendor/tracemonkey/liveconnect/LiveConnectShell.dsp +120 -0
  321. data/vendor/tracemonkey/liveconnect/LiveConnectShell.dsw +44 -0
  322. data/vendor/tracemonkey/liveconnect/Makefile.in +105 -0
  323. data/vendor/tracemonkey/liveconnect/Makefile.ref +169 -0
  324. data/vendor/tracemonkey/liveconnect/README.html +712 -0
  325. data/vendor/tracemonkey/liveconnect/_jni/netscape_javascript_JSException.h +14 -0
  326. data/vendor/tracemonkey/liveconnect/_jni/netscape_javascript_JSObject.h +155 -0
  327. data/vendor/tracemonkey/liveconnect/classes/Makefile.in +89 -0
  328. data/vendor/tracemonkey/liveconnect/classes/Makefile.ref +57 -0
  329. data/vendor/tracemonkey/liveconnect/classes/netscape/Makefile.ref +47 -0
  330. data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/JSException.java +140 -0
  331. data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/JSObject.java +183 -0
  332. data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/JSProxy.java +58 -0
  333. data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/JSRunnable.java +70 -0
  334. data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/JSUtil.java +59 -0
  335. data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/Makefile.ref +53 -0
  336. data/vendor/tracemonkey/liveconnect/config/AIX4.1.mk +45 -0
  337. data/vendor/tracemonkey/liveconnect/config/AIX4.2.mk +45 -0
  338. data/vendor/tracemonkey/liveconnect/config/AIX4.3.mk +50 -0
  339. data/vendor/tracemonkey/liveconnect/config/HP-UXB.10.10.mk +43 -0
  340. data/vendor/tracemonkey/liveconnect/config/HP-UXB.10.20.mk +43 -0
  341. data/vendor/tracemonkey/liveconnect/config/HP-UXB.11.00.mk +43 -0
  342. data/vendor/tracemonkey/liveconnect/config/IRIX6.2.mk +43 -0
  343. data/vendor/tracemonkey/liveconnect/config/IRIX6.3.mk +43 -0
  344. data/vendor/tracemonkey/liveconnect/config/IRIX6.5.mk +43 -0
  345. data/vendor/tracemonkey/liveconnect/config/Linux_All.mk +73 -0
  346. data/vendor/tracemonkey/liveconnect/config/OSF1V4.0.mk +65 -0
  347. data/vendor/tracemonkey/liveconnect/config/OSF1V5.0.mk +62 -0
  348. data/vendor/tracemonkey/liveconnect/config/SunOS5.5.1.mk +55 -0
  349. data/vendor/tracemonkey/liveconnect/config/SunOS5.6.mk +39 -0
  350. data/vendor/tracemonkey/liveconnect/config/SunOS5.7.mk +39 -0
  351. data/vendor/tracemonkey/liveconnect/config/SunOS5.8.mk +39 -0
  352. data/vendor/tracemonkey/liveconnect/config/WINNT4.0.mk +53 -0
  353. data/vendor/tracemonkey/liveconnect/jsj.c +886 -0
  354. data/vendor/tracemonkey/liveconnect/jsj.msg +98 -0
  355. data/vendor/tracemonkey/liveconnect/jsj_JSObject.c +1377 -0
  356. data/vendor/tracemonkey/liveconnect/jsj_JavaArray.c +474 -0
  357. data/vendor/tracemonkey/liveconnect/jsj_JavaClass.c +737 -0
  358. data/vendor/tracemonkey/liveconnect/jsj_JavaMember.c +191 -0
  359. data/vendor/tracemonkey/liveconnect/jsj_JavaObject.c +1079 -0
  360. data/vendor/tracemonkey/liveconnect/jsj_JavaPackage.c +569 -0
  361. data/vendor/tracemonkey/liveconnect/jsj_array.c +207 -0
  362. data/vendor/tracemonkey/liveconnect/jsj_class.c +770 -0
  363. data/vendor/tracemonkey/liveconnect/jsj_convert.c +902 -0
  364. data/vendor/tracemonkey/liveconnect/jsj_field.c +421 -0
  365. data/vendor/tracemonkey/liveconnect/jsj_hash.c +488 -0
  366. data/vendor/tracemonkey/liveconnect/jsj_hash.h +161 -0
  367. data/vendor/tracemonkey/liveconnect/jsj_method.c +1825 -0
  368. data/vendor/tracemonkey/liveconnect/jsj_nodl.c +1 -0
  369. data/vendor/tracemonkey/liveconnect/jsj_private.h +677 -0
  370. data/vendor/tracemonkey/liveconnect/jsj_simpleapi.c +219 -0
  371. data/vendor/tracemonkey/liveconnect/jsj_utils.c +513 -0
  372. data/vendor/tracemonkey/liveconnect/jsjava.h +316 -0
  373. data/vendor/tracemonkey/liveconnect/netscape_javascript_JSObject.h +155 -0
  374. data/vendor/tracemonkey/liveconnect/nsCLiveconnect.cpp +785 -0
  375. data/vendor/tracemonkey/liveconnect/nsCLiveconnect.h +197 -0
  376. data/vendor/tracemonkey/liveconnect/nsCLiveconnectFactory.cpp +118 -0
  377. data/vendor/tracemonkey/liveconnect/nsCLiveconnectFactory.h +76 -0
  378. data/vendor/tracemonkey/liveconnect/nsILiveconnect.h +197 -0
  379. data/vendor/tracemonkey/liveconnect/nsISecureLiveconnect.h +94 -0
  380. data/vendor/tracemonkey/liveconnect/nsISecurityContext.h +136 -0
  381. data/vendor/tracemonkey/lock_SunOS.s +119 -0
  382. data/vendor/tracemonkey/mandelbrot-results.js +3 -0
  383. data/vendor/tracemonkey/math-partial-sums.js +32 -0
  384. data/vendor/tracemonkey/math-trace-tests.js +507 -0
  385. data/vendor/tracemonkey/md5.js +289 -0
  386. data/vendor/tracemonkey/nanojit/Assembler.cpp +1984 -0
  387. data/vendor/tracemonkey/nanojit/Assembler.h +375 -0
  388. data/vendor/tracemonkey/nanojit/Fragmento.cpp +651 -0
  389. data/vendor/tracemonkey/nanojit/Fragmento.h +237 -0
  390. data/vendor/tracemonkey/nanojit/LIR.cpp +2314 -0
  391. data/vendor/tracemonkey/nanojit/LIR.h +879 -0
  392. data/vendor/tracemonkey/nanojit/LIRopcode.tbl +252 -0
  393. data/vendor/tracemonkey/nanojit/Native.h +127 -0
  394. data/vendor/tracemonkey/nanojit/NativeARM.cpp +1742 -0
  395. data/vendor/tracemonkey/nanojit/NativeARM.h +844 -0
  396. data/vendor/tracemonkey/nanojit/NativeSparc.cpp +1130 -0
  397. data/vendor/tracemonkey/nanojit/NativeSparc.h +948 -0
  398. data/vendor/tracemonkey/nanojit/NativeThumb.cpp +1322 -0
  399. data/vendor/tracemonkey/nanojit/NativeThumb.h +525 -0
  400. data/vendor/tracemonkey/nanojit/Nativei386.cpp +1748 -0
  401. data/vendor/tracemonkey/nanojit/Nativei386.h +857 -0
  402. data/vendor/tracemonkey/nanojit/RegAlloc.cpp +183 -0
  403. data/vendor/tracemonkey/nanojit/RegAlloc.h +95 -0
  404. data/vendor/tracemonkey/nanojit/TraceTreeDrawer.cpp +306 -0
  405. data/vendor/tracemonkey/nanojit/TraceTreeDrawer.h +88 -0
  406. data/vendor/tracemonkey/nanojit/avmplus.cpp +56 -0
  407. data/vendor/tracemonkey/nanojit/avmplus.h +1016 -0
  408. data/vendor/tracemonkey/nanojit/nanojit.h +253 -0
  409. data/vendor/tracemonkey/perfect.js +39 -0
  410. data/vendor/tracemonkey/plify_jsdhash.sed +35 -0
  411. data/vendor/tracemonkey/prmjtime.cpp +869 -0
  412. data/vendor/tracemonkey/prmjtime.h +103 -0
  413. data/vendor/tracemonkey/ref-config/AIX4.1.mk +65 -0
  414. data/vendor/tracemonkey/ref-config/AIX4.2.mk +64 -0
  415. data/vendor/tracemonkey/ref-config/AIX4.3.mk +65 -0
  416. data/vendor/tracemonkey/ref-config/Darwin.mk +85 -0
  417. data/vendor/tracemonkey/ref-config/Darwin1.3.mk +81 -0
  418. data/vendor/tracemonkey/ref-config/Darwin1.4.mk +41 -0
  419. data/vendor/tracemonkey/ref-config/Darwin5.2.mk +81 -0
  420. data/vendor/tracemonkey/ref-config/Darwin5.3.mk +81 -0
  421. data/vendor/tracemonkey/ref-config/Darwin64.mk +72 -0
  422. data/vendor/tracemonkey/ref-config/HP-UXB.10.10.mk +77 -0
  423. data/vendor/tracemonkey/ref-config/HP-UXB.10.20.mk +77 -0
  424. data/vendor/tracemonkey/ref-config/HP-UXB.11.00.mk +80 -0
  425. data/vendor/tracemonkey/ref-config/IRIX.mk +87 -0
  426. data/vendor/tracemonkey/ref-config/IRIX5.3.mk +44 -0
  427. data/vendor/tracemonkey/ref-config/IRIX6.1.mk +44 -0
  428. data/vendor/tracemonkey/ref-config/IRIX6.2.mk +44 -0
  429. data/vendor/tracemonkey/ref-config/IRIX6.3.mk +44 -0
  430. data/vendor/tracemonkey/ref-config/IRIX6.5.mk +44 -0
  431. data/vendor/tracemonkey/ref-config/Linux_All.mk +105 -0
  432. data/vendor/tracemonkey/ref-config/Mac_OS10.0.mk +82 -0
  433. data/vendor/tracemonkey/ref-config/OSF1V4.0.mk +72 -0
  434. data/vendor/tracemonkey/ref-config/OSF1V5.0.mk +69 -0
  435. data/vendor/tracemonkey/ref-config/SunOS4.1.4.mk +101 -0
  436. data/vendor/tracemonkey/ref-config/SunOS5.10.mk +50 -0
  437. data/vendor/tracemonkey/ref-config/SunOS5.3.mk +91 -0
  438. data/vendor/tracemonkey/ref-config/SunOS5.4.mk +92 -0
  439. data/vendor/tracemonkey/ref-config/SunOS5.5.1.mk +44 -0
  440. data/vendor/tracemonkey/ref-config/SunOS5.5.mk +87 -0
  441. data/vendor/tracemonkey/ref-config/SunOS5.6.mk +89 -0
  442. data/vendor/tracemonkey/ref-config/SunOS5.7.mk +44 -0
  443. data/vendor/tracemonkey/ref-config/SunOS5.8.mk +44 -0
  444. data/vendor/tracemonkey/ref-config/SunOS5.9.mk +44 -0
  445. data/vendor/tracemonkey/ref-config/WINNT4.0.mk +118 -0
  446. data/vendor/tracemonkey/ref-config/WINNT5.0.mk +118 -0
  447. data/vendor/tracemonkey/ref-config/WINNT5.1.mk +118 -0
  448. data/vendor/tracemonkey/ref-config/WINNT5.2.mk +118 -0
  449. data/vendor/tracemonkey/ref-config/WINNT6.0.mk +118 -0
  450. data/vendor/tracemonkey/ref-config/dgux.mk +64 -0
  451. data/vendor/tracemonkey/resource.h +15 -0
  452. data/vendor/tracemonkey/rules.mk +206 -0
  453. data/vendor/tracemonkey/shell/Makefile.in +72 -0
  454. data/vendor/tracemonkey/shell/js.cpp +4719 -0
  455. data/vendor/tracemonkey/t/3d-cube.js +337 -0
  456. data/vendor/tracemonkey/t/3d-morph.js +54 -0
  457. data/vendor/tracemonkey/t/3d-raytrace.js +441 -0
  458. data/vendor/tracemonkey/t/access-binary-trees.js +50 -0
  459. data/vendor/tracemonkey/t/access-fannkuch.js +66 -0
  460. data/vendor/tracemonkey/t/access-nbody.js +169 -0
  461. data/vendor/tracemonkey/t/access-nsieve.js +38 -0
  462. data/vendor/tracemonkey/t/bitops-3bit-bits-in-byte.js +32 -0
  463. data/vendor/tracemonkey/t/bitops-bits-in-byte.js +21 -0
  464. data/vendor/tracemonkey/t/bitops-bitwise-and.js +28 -0
  465. data/vendor/tracemonkey/t/bitops-nsieve-bits.js +32 -0
  466. data/vendor/tracemonkey/t/controlflow-recursive.js +25 -0
  467. data/vendor/tracemonkey/t/crypto-aes.js +422 -0
  468. data/vendor/tracemonkey/t/crypto-md5.js +286 -0
  469. data/vendor/tracemonkey/t/crypto-sha1.js +224 -0
  470. data/vendor/tracemonkey/t/date-format-tofte.js +299 -0
  471. data/vendor/tracemonkey/t/date-format-xparb.js +417 -0
  472. data/vendor/tracemonkey/t/math-cordic.js +95 -0
  473. data/vendor/tracemonkey/t/math-partial-sums.js +33 -0
  474. data/vendor/tracemonkey/t/math-spectral-norm.js +51 -0
  475. data/vendor/tracemonkey/t/regexp-dna.js +1712 -0
  476. data/vendor/tracemonkey/t/string-base64.js +135 -0
  477. data/vendor/tracemonkey/t/string-fasta.js +85 -0
  478. data/vendor/tracemonkey/t/string-tagcloud.js +265 -0
  479. data/vendor/tracemonkey/t/string-unpack-code.js +68 -0
  480. data/vendor/tracemonkey/t/string-validate-input.js +89 -0
  481. data/vendor/tracemonkey/time.sh +13 -0
  482. data/vendor/tracemonkey/trace-test.js +5564 -0
  483. data/vendor/tracemonkey/v8/base.js +187 -0
  484. data/vendor/tracemonkey/v8/crypto.js +1689 -0
  485. data/vendor/tracemonkey/v8/deltablue.js +880 -0
  486. data/vendor/tracemonkey/v8/earley-boyer.js +4682 -0
  487. data/vendor/tracemonkey/v8/raytrace.js +3418 -0
  488. data/vendor/tracemonkey/v8/richards.js +539 -0
  489. data/vendor/tracemonkey/v8/run-crypto.js +44 -0
  490. data/vendor/tracemonkey/v8/run-deltablue.js +44 -0
  491. data/vendor/tracemonkey/v8/run-earley-boyer.js +44 -0
  492. data/vendor/tracemonkey/v8/run-raytrace.js +44 -0
  493. data/vendor/tracemonkey/v8/run-richards.js +44 -0
  494. data/vendor/tracemonkey/v8/run.js +49 -0
  495. data/vendor/tracemonkey/vprof/readme.txt +93 -0
  496. data/vendor/tracemonkey/vprof/vprof.cpp +360 -0
  497. data/vendor/tracemonkey/vprof/vprof.h +245 -0
  498. data/vendor/tracemonkey/xpconnect/Makefile.in +67 -0
  499. data/vendor/tracemonkey/xpconnect/crashtests/117307-1.html +20 -0
  500. data/vendor/tracemonkey/xpconnect/crashtests/193710.html +11 -0
  501. data/vendor/tracemonkey/xpconnect/crashtests/290162-1.html +5 -0
  502. data/vendor/tracemonkey/xpconnect/crashtests/326615-1.html +16 -0
  503. data/vendor/tracemonkey/xpconnect/crashtests/328553-1.html +13 -0
  504. data/vendor/tracemonkey/xpconnect/crashtests/346258-1.html +12 -0
  505. data/vendor/tracemonkey/xpconnect/crashtests/346512-1-frame1.xhtml +16 -0
  506. data/vendor/tracemonkey/xpconnect/crashtests/346512-1-frame2.xhtml +15 -0
  507. data/vendor/tracemonkey/xpconnect/crashtests/346512-1.xhtml +30 -0
  508. data/vendor/tracemonkey/xpconnect/crashtests/382133-1.html +3 -0
  509. data/vendor/tracemonkey/xpconnect/crashtests/386680-1.html +22 -0
  510. data/vendor/tracemonkey/xpconnect/crashtests/394810-1.html +4 -0
  511. data/vendor/tracemonkey/xpconnect/crashtests/400349-1.html +20 -0
  512. data/vendor/tracemonkey/xpconnect/crashtests/403356-1.html +13 -0
  513. data/vendor/tracemonkey/xpconnect/crashtests/418139-1.svg +22 -0
  514. data/vendor/tracemonkey/xpconnect/crashtests/420513-1.html +11 -0
  515. data/vendor/tracemonkey/xpconnect/crashtests/453935-1.html +37 -0
  516. data/vendor/tracemonkey/xpconnect/crashtests/462926.html +12 -0
  517. data/vendor/tracemonkey/xpconnect/crashtests/468552-1.html +18 -0
  518. data/vendor/tracemonkey/xpconnect/crashtests/471366-1.html +12 -0
  519. data/vendor/tracemonkey/xpconnect/crashtests/475185-1.html +13 -0
  520. data/vendor/tracemonkey/xpconnect/crashtests/475291-1.html +14 -0
  521. data/vendor/tracemonkey/xpconnect/crashtests/503286-1.html +23 -0
  522. data/vendor/tracemonkey/xpconnect/crashtests/crashtests.list +21 -0
  523. data/vendor/tracemonkey/xpconnect/idl/Makefile.in +78 -0
  524. data/vendor/tracemonkey/xpconnect/idl/XPCIDispatch.idl +51 -0
  525. data/vendor/tracemonkey/xpconnect/idl/mozIJSSubScriptLoader.idl +64 -0
  526. data/vendor/tracemonkey/xpconnect/idl/nsIActiveXSecurityPolicy.idl +67 -0
  527. data/vendor/tracemonkey/xpconnect/idl/nsIDispatchSupport.idl +119 -0
  528. data/vendor/tracemonkey/xpconnect/idl/nsIJSContextStack.idl +85 -0
  529. data/vendor/tracemonkey/xpconnect/idl/nsIJSRuntimeService.idl +51 -0
  530. data/vendor/tracemonkey/xpconnect/idl/nsIScriptError.idl +102 -0
  531. data/vendor/tracemonkey/xpconnect/idl/nsIScriptableInterfaces.idl +67 -0
  532. data/vendor/tracemonkey/xpconnect/idl/nsIXPCScriptNotify.idl +66 -0
  533. data/vendor/tracemonkey/xpconnect/idl/nsIXPCScriptable.idl +183 -0
  534. data/vendor/tracemonkey/xpconnect/idl/nsIXPCSecurityManager.idl +114 -0
  535. data/vendor/tracemonkey/xpconnect/idl/nsIXPConnect.idl +819 -0
  536. data/vendor/tracemonkey/xpconnect/idl/xpcIJSModuleLoader.idl +95 -0
  537. data/vendor/tracemonkey/xpconnect/idl/xpcIJSWeakReference.idl +49 -0
  538. data/vendor/tracemonkey/xpconnect/idl/xpccomponents.idl +254 -0
  539. data/vendor/tracemonkey/xpconnect/idl/xpcexception.idl +66 -0
  540. data/vendor/tracemonkey/xpconnect/idl/xpcjsid.idl +83 -0
  541. data/vendor/tracemonkey/xpconnect/loader/ISO8601DateUtils.jsm +176 -0
  542. data/vendor/tracemonkey/xpconnect/loader/Makefile.in +63 -0
  543. data/vendor/tracemonkey/xpconnect/loader/XPCOMUtils.jsm +267 -0
  544. data/vendor/tracemonkey/xpconnect/loader/mozJSComponentLoader.cpp +1717 -0
  545. data/vendor/tracemonkey/xpconnect/loader/mozJSComponentLoader.h +172 -0
  546. data/vendor/tracemonkey/xpconnect/loader/mozJSLoaderConstructors.h +101 -0
  547. data/vendor/tracemonkey/xpconnect/loader/mozJSSubScriptLoader.cpp +360 -0
  548. data/vendor/tracemonkey/xpconnect/loader/mozJSSubScriptLoader.h +66 -0
  549. data/vendor/tracemonkey/xpconnect/public/Makefile.in +54 -0
  550. data/vendor/tracemonkey/xpconnect/public/nsAXPCNativeCallContext.h +89 -0
  551. data/vendor/tracemonkey/xpconnect/public/nsAutoJSValHolder.h +168 -0
  552. data/vendor/tracemonkey/xpconnect/public/xpc_map_end.h +327 -0
  553. data/vendor/tracemonkey/xpconnect/sample/Makefile.in +71 -0
  554. data/vendor/tracemonkey/xpconnect/sample/README +39 -0
  555. data/vendor/tracemonkey/xpconnect/sample/xpcsample1.cpp +337 -0
  556. data/vendor/tracemonkey/xpconnect/sample/xpcsample1.idl +82 -0
  557. data/vendor/tracemonkey/xpconnect/sample/xpcsample1.js +21 -0
  558. data/vendor/tracemonkey/xpconnect/shell/Makefile.in +106 -0
  559. data/vendor/tracemonkey/xpconnect/shell/jsshell.msg +50 -0
  560. data/vendor/tracemonkey/xpconnect/shell/xpcshell.cpp +1817 -0
  561. data/vendor/tracemonkey/xpconnect/shell/xpcshellMacUtils.h +43 -0
  562. data/vendor/tracemonkey/xpconnect/shell/xpcshellMacUtils.mm +54 -0
  563. data/vendor/tracemonkey/xpconnect/src/Makefile.in +228 -0
  564. data/vendor/tracemonkey/xpconnect/src/README +3 -0
  565. data/vendor/tracemonkey/xpconnect/src/XPCCrossOriginWrapper.cpp +1186 -0
  566. data/vendor/tracemonkey/xpconnect/src/XPCDispConvert.cpp +593 -0
  567. data/vendor/tracemonkey/xpconnect/src/XPCDispInlines.h +667 -0
  568. data/vendor/tracemonkey/xpconnect/src/XPCDispInterface.cpp +383 -0
  569. data/vendor/tracemonkey/xpconnect/src/XPCDispObject.cpp +516 -0
  570. data/vendor/tracemonkey/xpconnect/src/XPCDispParamPropJSClass.cpp +223 -0
  571. data/vendor/tracemonkey/xpconnect/src/XPCDispParams.cpp +103 -0
  572. data/vendor/tracemonkey/xpconnect/src/XPCDispPrivate.h +1401 -0
  573. data/vendor/tracemonkey/xpconnect/src/XPCDispTearOff.cpp +547 -0
  574. data/vendor/tracemonkey/xpconnect/src/XPCDispTypeInfo.cpp +471 -0
  575. data/vendor/tracemonkey/xpconnect/src/XPCIDispatchClassInfo.cpp +139 -0
  576. data/vendor/tracemonkey/xpconnect/src/XPCIDispatchExtension.cpp +362 -0
  577. data/vendor/tracemonkey/xpconnect/src/XPCNativeWrapper.cpp +1350 -0
  578. data/vendor/tracemonkey/xpconnect/src/XPCNativeWrapper.h +88 -0
  579. data/vendor/tracemonkey/xpconnect/src/XPCSafeJSObjectWrapper.cpp +1148 -0
  580. data/vendor/tracemonkey/xpconnect/src/XPCSystemOnlyWrapper.cpp +718 -0
  581. data/vendor/tracemonkey/xpconnect/src/XPCWrapper.cpp +850 -0
  582. data/vendor/tracemonkey/xpconnect/src/XPCWrapper.h +394 -0
  583. data/vendor/tracemonkey/xpconnect/src/dom_quickstubs.qsconf +568 -0
  584. data/vendor/tracemonkey/xpconnect/src/nsDispatchSupport.cpp +348 -0
  585. data/vendor/tracemonkey/xpconnect/src/nsScriptError.cpp +201 -0
  586. data/vendor/tracemonkey/xpconnect/src/nsXPConnect.cpp +2609 -0
  587. data/vendor/tracemonkey/xpconnect/src/qsgen.py +1487 -0
  588. data/vendor/tracemonkey/xpconnect/src/xpc.msg +217 -0
  589. data/vendor/tracemonkey/xpconnect/src/xpcJSWeakReference.cpp +148 -0
  590. data/vendor/tracemonkey/xpconnect/src/xpcJSWeakReference.h +56 -0
  591. data/vendor/tracemonkey/xpconnect/src/xpccallcontext.cpp +579 -0
  592. data/vendor/tracemonkey/xpconnect/src/xpccomponents.cpp +4144 -0
  593. data/vendor/tracemonkey/xpconnect/src/xpccontext.cpp +115 -0
  594. data/vendor/tracemonkey/xpconnect/src/xpcconvert.cpp +2298 -0
  595. data/vendor/tracemonkey/xpconnect/src/xpcdebug.cpp +481 -0
  596. data/vendor/tracemonkey/xpconnect/src/xpcexception.cpp +502 -0
  597. data/vendor/tracemonkey/xpconnect/src/xpcforwards.h +114 -0
  598. data/vendor/tracemonkey/xpconnect/src/xpcinlines.h +772 -0
  599. data/vendor/tracemonkey/xpconnect/src/xpcjsid.cpp +1025 -0
  600. data/vendor/tracemonkey/xpconnect/src/xpcjsruntime.cpp +1342 -0
  601. data/vendor/tracemonkey/xpconnect/src/xpclog.cpp +128 -0
  602. data/vendor/tracemonkey/xpconnect/src/xpclog.h +101 -0
  603. data/vendor/tracemonkey/xpconnect/src/xpcmaps.cpp +761 -0
  604. data/vendor/tracemonkey/xpconnect/src/xpcmaps.h +713 -0
  605. data/vendor/tracemonkey/xpconnect/src/xpcmodule.cpp +136 -0
  606. data/vendor/tracemonkey/xpconnect/src/xpcprivate.h +4138 -0
  607. data/vendor/tracemonkey/xpconnect/src/xpcquickstubs.cpp +1128 -0
  608. data/vendor/tracemonkey/xpconnect/src/xpcquickstubs.h +480 -0
  609. data/vendor/tracemonkey/xpconnect/src/xpcruntimesvc.cpp +179 -0
  610. data/vendor/tracemonkey/xpconnect/src/xpcstack.cpp +342 -0
  611. data/vendor/tracemonkey/xpconnect/src/xpcstring.cpp +139 -0
  612. data/vendor/tracemonkey/xpconnect/src/xpcthreadcontext.cpp +599 -0
  613. data/vendor/tracemonkey/xpconnect/src/xpcthrower.cpp +399 -0
  614. data/vendor/tracemonkey/xpconnect/src/xpcvariant.cpp +850 -0
  615. data/vendor/tracemonkey/xpconnect/src/xpcwrappedjs.cpp +670 -0
  616. data/vendor/tracemonkey/xpconnect/src/xpcwrappedjsclass.cpp +2015 -0
  617. data/vendor/tracemonkey/xpconnect/src/xpcwrappednative.cpp +3482 -0
  618. data/vendor/tracemonkey/xpconnect/src/xpcwrappednativeinfo.cpp +945 -0
  619. data/vendor/tracemonkey/xpconnect/src/xpcwrappednativejsops.cpp +2003 -0
  620. data/vendor/tracemonkey/xpconnect/src/xpcwrappednativeproto.cpp +302 -0
  621. data/vendor/tracemonkey/xpconnect/src/xpcwrappednativescope.cpp +991 -0
  622. data/vendor/tracemonkey/xpconnect/tests/Makefile.in +75 -0
  623. data/vendor/tracemonkey/xpconnect/tests/TestXPC.cpp +785 -0
  624. data/vendor/tracemonkey/xpconnect/tests/chrome/Makefile.in +51 -0
  625. data/vendor/tracemonkey/xpconnect/tests/chrome/test_bug500931.xul +43 -0
  626. data/vendor/tracemonkey/xpconnect/tests/components/Makefile.in +85 -0
  627. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_array.cpp +388 -0
  628. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_attributes.cpp +305 -0
  629. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_calljs.cpp +135 -0
  630. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_child.cpp +225 -0
  631. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_const.cpp +76 -0
  632. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_domstring.cpp +118 -0
  633. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_echo.cpp +616 -0
  634. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_in.cpp +204 -0
  635. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_inout.cpp +171 -0
  636. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_module.cpp +77 -0
  637. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_multiple.cpp +554 -0
  638. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_noisy.cpp +154 -0
  639. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_out.cpp +335 -0
  640. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_overloaded.cpp +250 -0
  641. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_private.h +192 -0
  642. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_string.cpp +185 -0
  643. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_variant.cpp +355 -0
  644. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/StdAfx.cpp +12 -0
  645. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/StdAfx.h +28 -0
  646. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCDispUtilities.h +28 -0
  647. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.cpp +86 -0
  648. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.def +9 -0
  649. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.dsp +318 -0
  650. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.dsw +29 -0
  651. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.idl +454 -0
  652. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.rc +145 -0
  653. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispSimple.cpp +44 -0
  654. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispSimple.h +56 -0
  655. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispSimple.rgs +23 -0
  656. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestArrays.cpp +221 -0
  657. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestArrays.h +53 -0
  658. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestArrays.rgs +23 -0
  659. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestMethods.cpp +699 -0
  660. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestMethods.h +138 -0
  661. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestMethods.rgs +23 -0
  662. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestNoIDispatch.cpp +23 -0
  663. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestNoIDispatch.h +41 -0
  664. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestNoIDispatch.rgs +23 -0
  665. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestProperties.cpp +256 -0
  666. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestProperties.h +88 -0
  667. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestProperties.rgs +23 -0
  668. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOff.cpp +23 -0
  669. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOff.h +43 -0
  670. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOff.rgs +23 -0
  671. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOn.cpp +29 -0
  672. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOn.h +45 -0
  673. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOn.rgs +23 -0
  674. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestWrappedJS.cpp +177 -0
  675. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestWrappedJS.h +50 -0
  676. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestWrappedJS.rgs +23 -0
  677. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/resource.h +36 -0
  678. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/Arrays/XPCIDispatchArrayTests.js +54 -0
  679. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/Attributes/XPCIDispatchAttributeTests.js +150 -0
  680. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/General/XPCIDispatchInstantiations.js +122 -0
  681. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/General/XPCStress.js +58 -0
  682. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/Methods/XPCIDispatchMethodTests.js +376 -0
  683. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/shell.js +377 -0
  684. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedJS/General/XPCIDispatchTestWrappedJS.js +76 -0
  685. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedJS/shell.js +377 -0
  686. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/exectests.cmd +1 -0
  687. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/jsDriver.pl +1288 -0
  688. data/vendor/tracemonkey/xpconnect/tests/idl/Makefile.in +61 -0
  689. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest.idl +312 -0
  690. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest2.idl +51 -0
  691. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_attributes.idl +67 -0
  692. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_calljs.idl +59 -0
  693. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_const.idl +61 -0
  694. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_domstring.idl +59 -0
  695. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_in.idl +88 -0
  696. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_inout.idl +86 -0
  697. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_multiple.idl +77 -0
  698. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_out.idl +142 -0
  699. data/vendor/tracemonkey/xpconnect/tests/js/checkid.js +82 -0
  700. data/vendor/tracemonkey/xpconnect/tests/js/evaluate.js +311 -0
  701. data/vendor/tracemonkey/xpconnect/tests/js/exceptions-2.js +153 -0
  702. data/vendor/tracemonkey/xpconnect/tests/js/exceptions-3.js +194 -0
  703. data/vendor/tracemonkey/xpconnect/tests/js/exceptions-4.js +297 -0
  704. data/vendor/tracemonkey/xpconnect/tests/js/exceptions-5.js +343 -0
  705. data/vendor/tracemonkey/xpconnect/tests/js/exceptions.js +230 -0
  706. data/vendor/tracemonkey/xpconnect/tests/js/javascript.js +96 -0
  707. data/vendor/tracemonkey/xpconnect/tests/js/multiple-2.js +151 -0
  708. data/vendor/tracemonkey/xpconnect/tests/js/multiple-3.js +148 -0
  709. data/vendor/tracemonkey/xpconnect/tests/js/multiple-4.js +152 -0
  710. data/vendor/tracemonkey/xpconnect/tests/js/multiple.js +137 -0
  711. data/vendor/tracemonkey/xpconnect/tests/js/notscriptable.js +104 -0
  712. data/vendor/tracemonkey/xpconnect/tests/js/old/simpletest.js +36 -0
  713. data/vendor/tracemonkey/xpconnect/tests/js/old/speed.js +60 -0
  714. data/vendor/tracemonkey/xpconnect/tests/js/old/testxpc.js +464 -0
  715. data/vendor/tracemonkey/xpconnect/tests/js/old/threads.js +74 -0
  716. data/vendor/tracemonkey/xpconnect/tests/js/old/try.js +27 -0
  717. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_array.js +308 -0
  718. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_callcontext.js +68 -0
  719. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_echo.js +636 -0
  720. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_enum_and_sort.js +28 -0
  721. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_enum_constants.js +15 -0
  722. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_enum_create.js +200 -0
  723. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_exceptions.js +167 -0
  724. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_ids.js +135 -0
  725. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_observer.js +36 -0
  726. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_overloaded.js +14 -0
  727. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_primitives.js +141 -0
  728. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_propertybag.js +36 -0
  729. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_variant.js +339 -0
  730. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_variant_array.js +30 -0
  731. data/vendor/tracemonkey/xpconnect/tests/js/readonlyattributes.js +74 -0
  732. data/vendor/tracemonkey/xpconnect/tests/js/readwriteattributes.js +101 -0
  733. data/vendor/tracemonkey/xpconnect/tests/js/scriptable.js +120 -0
  734. data/vendor/tracemonkey/xpconnect/tests/js/testin.js +203 -0
  735. data/vendor/tracemonkey/xpconnect/tests/js/xpcfun.js +234 -0
  736. data/vendor/tracemonkey/xpconnect/tests/js/xpctest_primitives.js +200 -0
  737. data/vendor/tracemonkey/xpconnect/tests/mochitest/Makefile.in +66 -0
  738. data/vendor/tracemonkey/xpconnect/tests/mochitest/bug500931_helper.html +7 -0
  739. data/vendor/tracemonkey/xpconnect/tests/mochitest/inner.html +7 -0
  740. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug361111.xul +29 -0
  741. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug384632.html +32 -0
  742. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug390488.html +65 -0
  743. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug393269.html +46 -0
  744. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug396851.html +43 -0
  745. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug428021.html +41 -0
  746. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug446584.html +49 -0
  747. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug448587.html +31 -0
  748. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug462428.html +42 -0
  749. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug478438.html +66 -0
  750. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug484107.html +100 -0
  751. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug484459.html +36 -0
  752. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug500691.html +28 -0
  753. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_wrappers.html +116 -0
  754. data/vendor/tracemonkey/xpconnect/tests/unit/bogus_element_type.jsm +1 -0
  755. data/vendor/tracemonkey/xpconnect/tests/unit/bogus_exports_type.jsm +1 -0
  756. data/vendor/tracemonkey/xpconnect/tests/unit/bug451678_subscript.js +2 -0
  757. data/vendor/tracemonkey/xpconnect/tests/unit/component_import.js +144 -0
  758. data/vendor/tracemonkey/xpconnect/tests/unit/recursive_importA.jsm +44 -0
  759. data/vendor/tracemonkey/xpconnect/tests/unit/recursive_importB.jsm +45 -0
  760. data/vendor/tracemonkey/xpconnect/tests/unit/syntax_error.jsm +1 -0
  761. data/vendor/tracemonkey/xpconnect/tests/unit/test_bogus_files.js +88 -0
  762. data/vendor/tracemonkey/xpconnect/tests/unit/test_bug408412.js +51 -0
  763. data/vendor/tracemonkey/xpconnect/tests/unit/test_bug451678.js +52 -0
  764. data/vendor/tracemonkey/xpconnect/tests/unit/test_bug_442086.js +68 -0
  765. data/vendor/tracemonkey/xpconnect/tests/unit/test_import.js +127 -0
  766. data/vendor/tracemonkey/xpconnect/tests/unit/test_js_weak_references.js +63 -0
  767. data/vendor/tracemonkey/xpconnect/tests/unit/test_recursive_import.js +62 -0
  768. data/vendor/tracemonkey/xpconnect/tools/Makefile.in +49 -0
  769. data/vendor/tracemonkey/xpconnect/tools/idl/Makefile.in +53 -0
  770. data/vendor/tracemonkey/xpconnect/tools/idl/nsIXPCToolsCompiler.idl +60 -0
  771. data/vendor/tracemonkey/xpconnect/tools/idl/nsIXPCToolsProfiler.idl +57 -0
  772. data/vendor/tracemonkey/xpconnect/tools/js/CompileJSFiles.js +28 -0
  773. data/vendor/tracemonkey/xpconnect/tools/js/ListJSFiles.js +18 -0
  774. data/vendor/tracemonkey/xpconnect/tools/src/Makefile.in +76 -0
  775. data/vendor/tracemonkey/xpconnect/tools/src/nsXPCToolsCompiler.cpp +161 -0
  776. data/vendor/tracemonkey/xpconnect/tools/src/nsXPCToolsModule.cpp +65 -0
  777. data/vendor/tracemonkey/xpconnect/tools/src/nsXPCToolsProfiler.cpp +370 -0
  778. data/vendor/tracemonkey/xpconnect/tools/src/xpctools_private.h +236 -0
  779. metadata +782 -107
  780. data/test/johnson/nodes/export_test.rb +0 -9
  781. data/test/johnson/nodes/import_test.rb +0 -13
  782. data/test/johnson/version_test.rb +0 -13
@@ -0,0 +1,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
+ }